/* ============================================================================
   TURNAMEN — layar Choose Match, Choose Map, Lobi, dan panel hasil.
   Rancangannya di GDD §57.17 (tiga layar sebelum main) dan §57.18 (panel hasil
   babak, jeda, panel juara); laporan pembangunannya di §57.19.

   BERKAS TERPISAH, bukan tambahan di css/style.css. Alasannya bukan kerapian:
   seluruh isi berkas ini melayani satu mode yang simulasinya BELUM ADA (§57.2
   dan §57.7 sama sekali belum dibangun), jadi ia berpeluang besar berubah
   bentuk lagi sebelum sempat dipakai sungguhan. Dipisah, perubahan sebesar apa
   pun di sini tidak pernah bisa merusak Quick Match yang sudah jalan dan sudah
   diukur — dan kalau rancangannya dibatalkan, yang dihapus satu berkas, bukan
   dicari-cari di tengah 3.000 baris milik mode lain.

   Yang TIDAK ditulis ulang di sini: bentuk kartu (`.kartu`), keping kuning
   (`.keping`), tombol (`.tbl`), kartu dialog (`.kotak`), dan seluruh papan
   peringkat (`.hasil-*`). Semuanya dipinjam apa adanya dari css/style.css,
   termasuk penyetelan kepadatan `@media` miliknya — itu sebabnya panel hasil
   turnamen memakai nama kelas yang sama persis dengan kartu hasil Quick Match.
   ============================================================================ */

/* ---- deret tiga kartu (Choose Match & Choose Map) ------------------------
   GRID tiga lajur, bukan flex. Bedanya terasa waktu nama kartunya tidak sama
   panjang ("Small" vs "Large", "Hutan" vs "Gurun"): flex membagi lebar menurut
   isi, jadi kartu bernama panjang jadi lebih lebar dan ketiganya terbaca
   sebagai tiga benda berbeda ukuran. Grid `1fr` membuat ketiganya selebar sama
   apa pun isinya. */
.tur-deret {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(8px, 1.6vw, 16px);
  width: 100%;
  /* 860 → 700 px. Pada 860 kartunya selebar 270 px dan potret arenanya sendiri
     200 px — lebih besar daripada potret yang sama di komidi Quick Match, dan
     cukup besar untuk membuat tiga kartu memenuhi layar sampai ke tepi tanpa
     ada yang berdiri di sekelilingnya. Dipendekkan, ketiganya jadi sekelompok
     benda di tengah layar, bukan tiga papan yang menempel di dinding. */
  max-width: min(700px, 100%);
  align-items: start;
  /* JARAK KE JUDUL LAYAR. `.layar` memang punya `gap` sendiri (10–20 px), tapi
     yang dipisahkannya kepala layar dari `.layar-isi` — dan `.layar-isi.tunggal`
     memusatkan isinya di seluruh sisa tinggi, jadi begitu kartunya setinggi
     ruang yang tersisa, jarak itu habis dan deret kartu berdiri menempel di
     bawah "PILIH TURNAMEN". Terukur pada 1109x517 sebelum baris ini ada: 10 px.
     `margin-top` di sini yang benar-benar dijamin, karena ia bagian dari tinggi
     deretnya sendiri. */
  margin-top: clamp(6px, 2.2vh, 20px);
}

/* Kartu + tombol kakinya. Dulu keduanya satu tombol; sekarang tiap kartu punya
   tombolnya sendiri di bawahnya — biaya masuk di layar turnamen, dan
   TERPILIH / TERSEDIA / harga di layar peta — dan tombol di dalam tombol bukan
   HTML yang sah. */
/* Jarak kartu ke tombol di kakinya DILEBARKAN (5-10 → 10-18 px). Pada jarak
   lama, tombol intan duduk cukup dekat untuk terbaca sebagai bagian bawah
   kartu — padahal seluruh sebab ia dipindah keluar (lihat `gambarMatch()`)
   justru supaya ia terbaca sebagai tombol yang berdiri sendiri. */
.tur-sel {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: clamp(10px, 2.2vh, 18px);
  min-width: 0;
}
/* Pembungkus KARTUNYA SAJA, dan ia ada untuk satu hal: jadi acuan `position`
   tudung gembok. Tudung yang mengacu ke `.tur-sel` akan ikut menutupi tombol di
   kaki kartu — dan tombol harga yang tertutup lapisan gelapnya sendiri adalah
   satu-satunya tombol yang justru harus paling terbaca di kartu itu. */
.tur-badan {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Kartu itu sendiri TOMBOL. Seluruh permukaannya bisa ditekan — di HP, sasaran
   sentuh selebar kartu jauh lebih mudah dikenai daripada tombol kecil, dan
   tidak ada satu pun bagian kartu ini yang berarti sesuatu selain "pilih yang
   ini".

   BAYANGANNYA KUNING, bukan hitam, dan ketiga kartu di kedua layar memakai
   kuning yang sama. Versi sebelumnya memberi tiap ukuran turnamen warna
   sendiri — Small hijau, Medium biru, Large merah — dan warna itu tidak pernah
   berhasil berarti apa pun: ia tidak menyebut mana yang lebih mahal, mana yang
   lebih lama, atau mana yang terpilih. Yang tersisa cuma tiga kartu yang
   terlihat milik tiga permainan berbeda.

   Kuning justru bahasa yang sudah dipakai di seluruh permainan ini untuk "ini
   yang berharga": keping intan, tombol berangkat, kartu komidi yang aktif. Kartu
   yang berpendar kuning di atas arena hijau gelap terbaca sebagai barang yang
   dipajang — dan itu memang yang sedang dilakukan kedua layar ini. */
.tur-kartu {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: clamp(4px, 0.9vh, 8px);
  padding: clamp(6px, 1.2vh, 10px);
  border: 3px solid var(--garis);
  border-radius: clamp(10px, 1.9vh, 15px);
  background: var(--kartu);
  color: #1b2030;
  cursor: pointer;
  text-align: center;
}
/* KARTU TIDAK PUNYA KEADAAN TERPILIH LAGI, dan tidak punya umpan balik tekan.
   Pendar kuning yang dulu berdiri di sini — beserta bayangan pejal di
   bawahnya — dicabut atas permintaan langsung: keduanya membuat ketiga kartu
   terbaca seperti benda yang menyala sendiri di atas arena, padahal yang
   diminta layar ini cuma memperlihatkan tiga pilihan dengan tenang.

   Di layar Choose Competition, kartu memang tidak perlu keadaan terpilih sama
   sekali: menekannya langsung berpindah layar, jadi tidak pernah ada momen
   pemain melihat kartu "yang sedang terpilih". Di layar Choose Map, yang
   menjawab pertanyaan itu tombol SELECTED hijau di kaki kartunya — satu tempat
   untuk satu kabar, pola yang sama yang sudah dipakai `.tur-pilih`.

   Aturannya sengaja ditinggalkan KOSONG sebagai catatan, bukan dihapus: kelas
   `.terpilih` masih dipasang js/turnamen.js, dan yang membaca berkas ini perlu
   tahu bahwa diamnya kartu itu keputusan, bukan aturan yang belum ditulis. */

/* ---- gambar di kepala kartu ---------------------------------------------
   Persegi dengan nisbah tetap, jadi tinggi kartunya tidak ikut berubah waktu
   isinya berganti. `aspect-ratio` dan bukan tinggi tetap: di layar pendek
   lebar kartu mengecil, dan gambar bertinggi tetap akan berubah nisbah — arena
   yang di layar lebar bundar jadi lonjong di HP. */
.tur-gambar {
  position: relative;
  /* 4:3 → 16:11. Kartunya sekarang lebih sempit, dan potret setinggi 3/4
     lebarnya membuat gambar tetap jadi bagian kartu yang paling memakan
     tinggi — tiga kartu jangkung berisi satu gambar besar dan dua baris teks
     kecil di bawahnya. Sedikit lebih lebar dari tinggi, kartunya jadi
     sebanding: gambar, nama, lalu dua baris angka. */
  aspect-ratio: 16 / 11;
  overflow: hidden;
  border: 3px solid var(--garis);
  border-radius: clamp(6px, 1.3vh, 10px);
  background: #2f4a2a;
}
.tur-gambar svg,
.tur-gambar img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Keping "2 TIM" di pojok gambar kartu turnamen. Setengah ukuran percobaan
   sebelumnya: pada 16–21 px ia berdiri sebesar nama kartunya sendiri, dan dua
   tulisan sebesar itu di satu kartu berarti kartunya punya dua judul. Yang
   disebutkannya toh sudah terbaca dari gambarnya — benteng di potret arenanya
   memang bisa dihitung — jadi tugas keping ini cuma memastikan, bukan
   mengumumkan. */
.tur-lencana {
  position: absolute;
  top: clamp(5px, 1.2vh, 9px);
  left: clamp(5px, 1.2vw, 9px);
  display: flex;
  align-items: center;
  gap: clamp(2px, 0.5vw, 5px);
  padding: clamp(2px, 0.5vh, 4px) clamp(6px, 1.2vw, 10px);
  border: 2px solid var(--garis);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.94);
  font-size: clamp(8px, 1.5vh, 10.5px);
  font-weight: 900;
  letter-spacing: 0.7px;
  line-height: 1;
  color: #1b2030;
}
/* Deret ikon cuaca di pojok gambar kartu peta. Ia BUKAN keping lagi: sejak tiap
   ikon punya lingkarannya sendiri, keping di sekelilingnya jadi kotak putih
   berisi empat kotak putih. Yang tersisa cuma barisnya. */
.tur-lencana-ikon {
  padding: 0;
  border: none;
  background: none;
  gap: clamp(3px, 0.6vw, 5px);
}

/* ---- tulisan di badan kartu ---------------------------------------------
   Nama kartu dipatok `--fs-tombol`, satu tingkat DI ATAS `--fs-label` yang
   dipakai versi pertama. Terukur di layar penuh, nama setinggi label berdiri
   sama besar dengan tulisan "TIDAK DIPILIH" di bawahnya — dua tulisan sederajat
   di satu kartu berarti kartunya tidak punya judul. */
.tur-kartu-nama {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: clamp(5px, 1.1vw, 10px);
  font-size: var(--fs-tombol);
  font-weight: 900;
  letter-spacing: var(--lc-kapital);
  text-transform: uppercase;
  line-height: 1.1;
}
/* "(1 vs 7)" — SEBARIS dengan namanya, dan setebal serta sebesar namanya pula.
   Percobaan sebelumnya mengecilkannya jadi keterangan abu-abu 10 px, dan di
   sana ia hilang: justru angka INILAH yang membedakan ketiga kartu satu sama
   lain, sementara nama Small/Medium/Large cuma melabelinya. Yang menyebut mana
   induk mana keterangan sekarang TANDA KURUNGNYA, bukan perbedaan ukuran.

   `text-transform: none` supaya "vs" tetap huruf kecil: induknya kapital
   seluruhnya, dan "1 VS 7" terbaca sebagai singkatan sesuatu, bukan sebagai
   kata "lawan". Warnanya sedikit lebih pudar dari namanya — satu-satunya
   perbedaan yang tersisa, dan cukup untuk menjaga urutan bacanya. */
.tur-kartu-nama i {
  flex-shrink: 0;
  font-style: normal;
  font-size: inherit;
  font-weight: inherit;
  letter-spacing: var(--lc-biasa);
  text-transform: none;
  color: #55607a;
  font-variant-numeric: tabular-nums;
}

/* ---- baris statistik -----------------------------------------------------
   Inilah yang mengisi ruang kosong di bawah gambar, dan isinya sengaja bukan
   hiasan: jumlah babak, hadiah juara, ciri medan. Ketiganya angka yang memang
   dipakai pemain untuk memilih, dan sebelum baris ini ada, satu-satunya cara
   mengetahuinya adalah membuka GDD. */
.tur-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: clamp(4px, 1vh, 8px) clamp(6px, 1.2vw, 10px);
  border-radius: clamp(6px, 1.3vh, 10px);
  background: #eef1f6;
}
.tur-stat-baris {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: clamp(9px, 1.7vh, 11.5px);
  font-weight: 800;
  letter-spacing: var(--lc-biasa);
  color: #6b7590;
  /* Title Case lewat CSS, bukan lewat teks yang ditulis besar di
     js/turnamen.js: labelnya ("Round", "Champion Reward", "Weather")
     berasal dari satu tempat, dan yang menentukan RUPA tulisan memang
     berkas ini. Bukan ALL CAPS — ini label baris (Map/Round/Reward/
     Entrance Fee), bukan heading atau header kolom tabel. */
  text-transform: capitalize;
}
.tur-stat-baris b {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: #1b2030;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}
.tur-stat-baris b svg { width: 11px; height: 11px; flex-shrink: 0; }

/* ---- deret ikon di baris statistik ---------------------------------------
   Cuaca dan rintangan disebut sebagai IKON, bukan sebagai angka dan daftar
   nama. Versi sebelumnya menulis "Rintangan 3" lalu "Yang berdiri pohon, batu,
   sungai" — dan baris kedua itulah yang paling sering terpotong di HP, persis
   baris yang isinya paling berguna. Ikon tidak bisa terpotong di tengah kata,
   dan tiga arena berdampingan jadi bisa dibandingkan tanpa membaca satu huruf
   pun.

   Nama panjangnya tidak hilang: ia pindah ke `title` tiap ikon (js/turnamen.js),
   jadi yang memakai tetikus atau pembaca layar tetap mendapat "pasir lembut"
   dan bukan sekadar sebuah gambar gundukan. */
.tur-ikon-deret {
  display: inline-flex;
  align-items: center;
  gap: clamp(3px, 0.6vw, 5px);
}
/* SATU IKON SATU LINGKARAN. Sebelumnya keempatnya berjejer telanjang di atas
   satu keping panjang, dan di sana ikon yang bentuknya mirip — mendung, hujan,
   badai, ketiganya awan — melebur jadi satu gumpalan yang harus dihitung
   dengan menyipit. Lingkaran bergaris tepi memberi tiap ikon batasnya sendiri,
   jadi "tiga cuaca" dan "empat cuaca" bisa dibedakan sekilas tanpa membaca satu
   huruf pun.

   Lingkaran, bukan kotak membulat seperti keping lain di layar ini: kotak
   membulat sudah dipakai keping harga, keping tim, dan tombol. Ikon jenis
   medan bukan sesuatu yang bisa ditekan, dan bentuk yang berbeda adalah cara
   paling murah menyebut itu. */
.tur-ikon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-sizing: border-box;
  width: clamp(19px, 3.4vh, 24px);
  height: clamp(19px, 3.4vh, 24px);
  padding: clamp(2px, 0.4vh, 3px);
  border: 2px solid var(--garis);
  border-radius: 50%;
  background: #fff;
  color: #4a5570;
}
.tur-ikon svg { display: block; width: 100%; height: 100%; }
/* Lingkaran di pojok gambar lebih besar daripada di baris statistik: ia berdiri
   di atas potret arena berwarna penuh, bukan di atas bidang abu-abu rata. */
.tur-lencana-ikon .tur-ikon {
  width: clamp(24px, 4.2vh, 30px);
  height: clamp(24px, 4.2vh, 30px);
  padding: clamp(3px, 0.6vh, 5px);
  background: rgba(255, 255, 255, 0.94);
}
/* Warna tiap cuaca dan tiap rintangan. Bukan hiasan: empat ikon cuaca kelabu
   yang berjejer di satu keping cuma terbaca sebagai empat awan yang mirip,
   sementara kuning-kelabu-biru-ungu terbaca sebagai TANGGA — dari terang ke
   buruk, urutan yang memang dipegang `CUACA_URUT` di js/peta.js. */
.tur-ikon.cu-cerah { color: #e09400; }
.tur-ikon.cu-mendung { color: #78839a; }
.tur-ikon.cu-hujan { color: #2f7fd0; }
.tur-ikon.cu-badai { color: #5b4bb0; }
.tur-ikon.ri-pohon { color: #2f8340; }
.tur-ikon.ri-batu { color: #6e7480; }
.tur-ikon.ri-sungai { color: #2f8ad0; }
.tur-ikon.ri-kaktus { color: #3f9450; }
.tur-ikon.ri-salju { color: #6ba6cf; }
.tur-ikon.ri-pasir { color: #c19236; }

/* ---- tombol intan --------------------------------------------------------
   Dua tempat, satu bentuk: biaya masuk di bawah kartu turnamen, dan harga
   arena di atas tudung gembok kartu peta. Keduanya benar-benar TOMBOL sekarang
   — yang pertama berangkat ke layar peta, yang kedua membuka dialog beli.

   SATU SETENGAH KALI ukuran keping harga yang lama, seluruhnya: sisipan, huruf,
   dan lambang intannya. Ia satu-satunya benda di layar ini yang harus ditekan
   dengan sengaja, dan keping selebar 60 px di bawah kartu setinggi 300 px
   terbaca sebagai label harga, bukan sebagai jalan keluar layarnya. */
/* SATU BENTUK untuk kedua tombol kaki kartu — harga intan DAN
   SELECTED/AVAILABLE/SOON. Keduanya menempati petak yang sama persis di bawah
   kartu, dan sampai putaran ini yang satu kuning setinggi 1,5x huruf sementara
   yang lain kelabu setinggi 1,15x: dua tombol yang berdiri di tempat yang sama
   dengan dua ukuran berbeda membuat deret tiga kartu terlihat bergerigi tiap
   kali salah satu arenanya dibeli. Sekarang keduanya dituliskan sekali di
   sini, dan yang membedakan cuma WARNA ISINYA (lihat ragam di bawah).

   DIPENDEKKAN jadi 74% lebar kartunya, tidak lagi `align-self: stretch`.
   Melebar penuh dulu dipilih supaya tidak ada pita kosong di kiri-kanan
   tombol; yang terjadi sesudahnya, tombol selebar kartu berhenti terbaca
   sebagai tombol dan mulai terbaca sebagai KAKI kartunya — satu balok
   memanjang yang menempel di bawah, bukan benda yang ditekan.

   `width` persen (bukan `max-content`) tetap menjaga alasan aslinya: ketiga
   tombol dalam satu deret lahir dari lebar kolom yang sama, jadi lebarnya
   tetap sama rata walau labelnya "300" di satu kartu dan "AVAILABLE" di
   kartu sebelahnya. `min-width` menahan kasus ekstrem di kolom tersempit. */
/* KEDUANYA SELEBAR ANGKA YANG SAMA, bukan 74% dari kartunya masing-masing
   (§57.41.15). Selama lebarnya pecahan kartu, tombol Choose Map dan tombol
   Choose Competition mustahil sama besar: kartu arena dan kartu jenis
   turnamen berbeda lebar, jadi 74% dari keduanya juga berbeda. Dan begitu
   "Entrance Fee :" masuk ke tombol yang satu, pecahan yang sama juga jadi
   terlalu sempit untuknya. Sekarang keduanya `min(100%, 15.5em)` — satu angka
   mutlak yang dipakai bersama, dengan `100%` sebagai pagar supaya ia tidak
   pernah melewati kartunya sendiri di layar sempit. */
.tur-masuk,
.tur-pilih {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: clamp(5px, 1vw, 9px);
  align-self: center;
  width: min(100%, 15.5em);
  min-width: 96px;
  max-width: 100%;
  padding: clamp(6px, 1.4vh, 10px) clamp(8px, 1.6vw, 13px);
  border: 3px solid var(--garis);
  /* KOTAK, bukan pil. Radiusnya sengaja SAMA dengan potret arena di dalam
     kartunya (`.tur-gambar`), jadi kartu dan tombol kakinya terbaca sebagai
     dua benda dari satu keluarga bentuk — pil di bawah kotak terbaca sebagai
     benda yang datang dari layar lain. */
  border-radius: clamp(6px, 1.3vh, 10px);
  background: #eef1f6;
  color: #47526b;
  font-family: inherit;
  font-size: calc(var(--fs-kecil) * 1.15);
  font-weight: 900;
  letter-spacing: var(--lc-kapital);
  font-variant-numeric: tabular-nums;
  /* 1,35 dan bukan 1 — inilah yang menyamakan TINGGI kedua ragamnya. Dengan
     `line-height: 1`, kotak baris tombol berteks (AVAILABLE) setinggi hurufnya
     saja sementara tombol berintan setinggi lambangnya, dan selisih ~4 px itu
     persis kembali jadi deret kaki bergerigi yang baru saja dihilangkan. Angka
     ini dipakai bersama ukuran lambang di bawah (1,35em juga), jadi keduanya
     mustahil menyimpang. */
  line-height: 1.35;
  cursor: pointer;
}
/* Batunya HITAM, sewarna tulisan dan garis tepinya. Sempat emas selama satu
   putaran supaya harga masih terbaca berbeda dari AVAILABLE sesudah tombol
   kuningnya dicabut; emas itu sekarang ikut dicabut atas permintaan langsung
   ("buat icon diamond berwarna hitam semua"). Yang membedakan harga dari
   AVAILABLE tinggal ADANYA lambang itu sendiri — dan itu memang pembeda yang
   cukup: kartu berlambang intan berarti menagih, yang tidak berarti tidak. */
.tur-masuk svg {
  /* `em`, bukan `clamp(px)` — lihat catatan `line-height` di atas: lambang yang
     diukur dalam piksel bisa melampaui kotak baris tombol di sebelahnya dan
     membuat kedua tombol berbeda tinggi. */
  width: 1.35em;
  height: 1.35em;
  flex-shrink: 0;
  color: var(--garis);
}
/* Intan tidak cukup. Yang memerah TULISAN dan BATUNYA, bukan seluruh tombol:
   isian merah pejal mengembalikan persis blok berwarna yang baru saja
   dihilangkan dari tombol ini. Tetap bisa ditekan — dialognya sendiri yang
   menolak, dan dialog itu pula yang menyebutkan kurangnya berapa. */
.tur-masuk.kurang { color: var(--merah-bawah); }

/* ---- tudung arena terkunci ----------------------------------------------
   Yang belum dibeli DIGELAPKAN seluruhnya, dengan gembok berdiri terang di
   tengah. §32.6 dua kali menolak mengelabukan yang terkunci, dan aturan itu
   tidak dilanggar di sini: yang digelapkan GAMBARNYA, sementara benda yang
   justru harus terbaca — sebab terkuncinya — malah jadi satu-satunya yang
   terang di kartu itu. Kartu yang cuma diredam rata membuat gemboknya ikut
   pudar bersama isinya.

   Isinya CUMA gembok. Harganya duduk di kaki kartu bersama "TERPILIH" dan
   "TERSEDIA" milik dua kartu sebelahnya, dan itulah sebab `.tur-badan` ada:
   tudung yang mengacu ke `.tur-sel` akan ikut menggelapkan tombol itu.

   `pointer-events: none`: menekan bagian gelap kartu tidak boleh melakukan apa
   pun — arenanya memang terkunci, dan satu-satunya jalan masuk tombol
   harganya. */
.tur-tudung {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: clamp(11px, 2.2vh, 18px);
  background: rgba(9, 13, 21, 0.62);
  pointer-events: none;
}
.tur-gembok {
  display: block;
  width: clamp(30px, 6.4vh, 48px);
  height: clamp(30px, 6.4vh, 48px);
  color: #fff;
}
.tur-gembok svg { display: block; width: 100%; height: 100%; }

/* ---- tombol keadaan di kaki kartu peta -----------------------------------
   TERPILIH / TERSEDIA / SEGERA, dan tombol harga di sebelahnya. Keempat bunyi
   itu berdiri di TEMPAT YANG SAMA di ketiga kartu, dan itu seluruh gunanya:
   selama keadaan terkunci diumumkan di tengah kartu sementara keadaan terpilih
   diumumkan di kakinya, mata harus mencari dua kali untuk membandingkan tiga
   arena yang berjejer.

   Ukurannya sepadan dengan tombol intan di sebelahnya (`.tur-masuk`), jadi
   ketiga kaki kartu tetap sama tinggi apa pun keadaannya — tanpa itu, deret
   tiga kartu jadi bergerigi tiap kali salah satunya dibeli. */
/* Bentuk dasarnya sudah ditulis bersama `.tur-masuk` di atas — yang tersisa di
   sini cuma ketiga ragam warnanya. */
/* TERPILIH hijau — warna yang sama dengan tombol berangkat `.tbl.utama` dan tab
   cuaca yang aktif, jadi "hijau = yang ini sedang berlaku" berarti satu hal
   saja di seluruh permainan. */
.tur-pilih.ya {
  background: var(--hijau);
  color: #06240f;
}
/* Arena yang belum digambar sama sekali: tidak bisa dipilih dan tidak bisa
   dibeli, jadi ia SATU-SATUNYA yang bukan tombol. Bentuk tombol pada sesuatu
   yang tidak bisa ditekan adalah bentuk yang berbohong. */
.tur-pilih.segera {
  background: #d7dded;
  color: #3c455c;
  cursor: default;
}

/* ============================================================================
   LOBI
   ============================================================================ */

.tur-lobi-kartu {
  flex: 1 1 auto;
  min-height: 0;
}

/* §57.63 — RUANG KOSONG DI LOBI CUSTOM DITUTUP, diminta langsung ("panjangnya
   dikurangi agar tidak terkesan ada bagian yang kosong").

   Sebabnya `.tur-daftar { flex: 1 1 0 }`: daftar peserta MELAR mengisi
   seluruh sisa tinggi kartu. Dengan empat slot di panel setinggi 547 px,
   terukur ada ±100 px ruang menganga antara baris WAITING terakhir dan kaki
   panel — ruang yang tidak memuat apa pun dan tidak menunggu apa pun.

   YANG DIPENDEKKAN DAFTARNYA, BUKAN KARTUNYA. Percobaan pertama memendekkan
   kartu (`flex: 0 1 auto`) dan itu SALAH secara terukur: kartunya memang
   menyusut 547 → 479 px, tapi dasarnya lalu berhenti 68 px DI ATAS dasar
   komidi — merusak kesejajaran yang diminta di kalimat yang sama. Kedua
   permintaan itu cuma bisa dipenuhi bersamaan kalau kartunya tetap setinggi
   kolom dan yang berhenti melar isinya.

   Hasilnya: daftar setinggi isinya, ruang sisa jatuh SESUDAHNYA sebagai satu
   pita di atas kaki panel — dan kaki panel tetap menempel di dasar kartu,
   sejajar dengan dasar komidi di kolom kiri.

   Cuma di lobi CUSTOM: Competition bisa memuat DELAPAN peserta (Large) dan
   memang membutuhkan tinggi penuh itu. */
#layar-kustom-lobi .tur-daftar { flex: 0 1 auto; }
/* Kaki panel didorong ke DASAR kartu. Tanpa ini, daftar yang berhenti melar
   menyeret kaki ikut naik bersamanya dan ruang kosongnya cuma berpindah dari
   ATAS kaki ke BAWAH kaki — yang terlihat sama saja, cuma dengan garis
   pemisah di tempat yang salah. */
#layar-kustom-lobi .tur-kaki { margin-top: auto; }

/* ---- label status di bawah model 3D --------------------------------------
   `.potret-nama` dasarnya kuning (css/style.css) — dipakai apa adanya waktu
   bangsa yang sedang dilihat bisa dipilih (DIPILIH). Dua rupa di bawah ini
   cuma untuk dua kabar sebaliknya, dan keduanya lahir dari `labelBangsa()` di
   js/turnamen.js: DIPAKAI berarti orang lain sudah memegangnya, harga
   berlambang intan berarti belum dibeli. Diberi nama beda dari kuning supaya
   "kuning = ini pilihanmu" tetap satu arti di seluruh permainan. */
#tur-nama-bangsa.status-dipakai,
#kustom-nama-bangsa.status-dipakai { background: #d7dded; color: #4a5570; }
#tur-nama-bangsa.status-kunci,
#kustom-nama-bangsa.status-kunci {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: #fff;
  color: var(--garis);
}
#tur-nama-bangsa.status-kunci svg { width: clamp(11px, 2vh, 14px); height: clamp(11px, 2vh, 14px); }

/* ---- kepala panel DUA TINGKAT (§57.42.2) ----------------------------------
   Tingkat 1 JUDUL KEADAAN di tengah, tingkat 2 tiga FAKTA PERTANDINGAN
   sejajar. Keduanya berdiri di sini dan bukan sebagai baris tabel di bawah
   karena tidak satu pun dari ketiganya milik seorang peserta — memaksakannya
   jadi baris peserta berarti ada "pemain" bernama Salju.

   Susunan lama (nama arena di kiri, keping "MEDIUM" melayang di kanan)
   dicabut seluruhnya. Sebabnya bukan bentuk melainkan isi: keping itu menyebut
   nama INTERNAL ukuran turnamen, dan pemain tidak pernah memilih kata
   "Medium" — yang ia pilih adalah lawan sebanyak tiga. "1 vs 3" mengatakan hal
   yang sama dengan satuan yang memang ia kenali. */
/* KOTAK, bukan dua baris telanjang di atas tabel (§57.42.8). Kedua baris di
   dalamnya — judul keadaan dan tiga fakta pertandingan — adalah keterangan
   yang TIDAK berubah sepanjang lobi, sementara tabel di bawahnya berubah tiap
   detik. Membungkusnya jadi satu benda menyatakan pembagian itu dengan
   bentuk, bukan cuma dengan jarak.

   Latarnya LEBIH GELAP daripada kartu di belakangnya (`--kartu` = #e7ebf3),
   bukan lebih terang seperti `.baris-info` di layar Quick Match. Bedanya
   disengaja: baris info di sana adalah HASIL yang menonjol di atas kartu,
   kotak ini adalah LATAR tempat tabel peserta berdiri — dan yang jadi latar
   harus mundur, bukan maju. */
/* §57.49  SATU TINGGI UNTUK SELURUH PANEL LOBI ---------------------------
   Diminta langsung: baris judul "Gathering…", baris fakta (1 vs N · arena ·
   bangsa), tombol Start, kotak kode, dan hitung mundur semuanya SETINGGI
   satu baris kotak pemain.

   Tingginya ditulis SEKALI di sini sebagai token, bukan diketik ulang di
   enam aturan — supaya keenamnya tidak diam-diam menyimpang begitu ukuran
   baris pemain disetel.

   ANGKANYA lahir dari LEBAR bendera, bukan tingginya, dan itu sempat salah
   sekali di sini: `.tur-p-panji` menulis `width: clamp(38px, 7.2vh, 56px)`
   dengan `aspect-ratio: 3 / 2`, jadi TINGGI benderanya dua-pertiga lebar
   itu. Rumus pertama memakai lebarnya apa adanya dan menghasilkan 72,2 px
   di 1280x720 — terukur, sementara baris pemain yang sedang ditiru cuma
   54,9 px. Faktor 2/3-nya sekarang ditulis di rumus.

   Sisanya sisipan `.tur-p` dua sisi (`clamp(4px, 1vh, 8px)`) dan garis
   3 px dua sisi.

   `--baris-lobi` dipasang pada `.tur-lobi-kepala` DAN `.tur-kaki` karena
   keduanya bukan saudara — yang satu di dalam kartu, yang lain di kakinya. */
.tur-lobi-kepala,
.tur-kaki {
  --baris-lobi: calc(clamp(38px, 7.2vh, 56px) * 2 / 3 + 2 * clamp(4px, 1vh, 8px) + 6px);
}

.tur-lobi-kepala {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  min-width: 0;
  border: 3px solid var(--garis);
  border-radius: clamp(8px, 1.6vh, 13px);
  background: #d3daea;
  overflow: hidden;
}
/* JUDUL KEADAAN. Di tengah dan jauh lebih besar daripada versi lamanya (dulu
   10-13 px), dan itu satu keputusan bukan dua: di tengah ia jadi kepala panel
   yang punya dua sisi seimbang; besar ia berhenti terbaca sebagai keterangan
   kecil yang menempel pada sesuatu.

   Batas atasnya 19 px, bukan 26: kalimatnya PANJANG (lima kata), dan pada 26
   px ia patah dua baris di kartu 460 px lalu mendorong tabel peserta turun
   satu baris penuh. Yang dijaga di sini "jelas lebih besar daripada baris
   fakta di bawahnya", bukan angka tertentu. */
.tur-kumpul {
  /* §57.49: SETINGGI satu baris kotak pemain. `display: flex` + `place`
     dipakai, bukan `line-height` sebesar tingginya: kalimatnya boleh patah
     dua baris di layar sempit, dan `line-height` raksasa akan memisahkan
     kedua barisnya sejauh satu baris pemain masing-masing. Flex memusatkan
     apa pun yang ada di dalamnya, satu baris maupun dua. */
  box-sizing: border-box;
  min-height: var(--baris-lobi);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(4px, 1vh, 8px) clamp(8px, 1.6vw, 14px);
  border-bottom: 3px solid rgba(27, 32, 48, 0.16);
  font-size: clamp(12px, 2.6vh, 19px);
  font-weight: 900;
  letter-spacing: var(--lc-biasa);
  line-height: 1.15;
  color: #1b2030;
}
/* TIGA PETAK SAMA LEBAR, bukan flex yang lebarnya mengikuti isi: nama arena
   ("Hutan") dan nama bangsa ("Tiongkok") berbeda panjang, dan petak yang
   melar mengikuti isinya membuat garis pemisahnya berpindah tiap kali pemain
   menggeser komidi bangsa — sepasang garis tegak yang bergoyang di kepala
   panel. Grid tiga kolom membuat kedua garis itu diam. */
.tur-fakta {
  /* §57.49: setinggi baris kotak pemain juga. `align-items: center` memusatkan
     ketiga petaknya tegak lurus di dalam tinggi baru itu — tanpa itu ketiga
     tulisan menempel di garis atas dan ruang tambahannya menganga di bawah. */
  box-sizing: border-box;
  min-height: var(--baris-lobi);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: center;
  padding: clamp(5px, 1.2vh, 9px) 0;
}
.tur-fakta span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  font-size: var(--fs-kecil);
  font-weight: 900;
  letter-spacing: var(--lc-kapital);
  color: #1b2030;
  /* Title Case, bukan ALL CAPS (bukan heading/tombol) — lihat blok
     konsolidasi di ujung css/style.css untuk prinsipnya. */
  text-transform: capitalize;
}
/* Garis tegak DI ANTARA petak, bukan di tepi luarnya — `+ span` melewatkan
   petak pertama dengan sendirinya, jadi tidak ada garis kedua yang menempel
   pada garis tepi kotak yang sudah mengelilinginya. */
.tur-fakta span + span { border-left: 3px solid rgba(27, 32, 48, 0.16); }

/* ---- tabel peserta: SATU tabel, satu baris per slot -----------------------
   Kotak petak lama (empat sebaris di atas + petak persegi di bawah) digantikan
   satu tabel supaya bangsa milik pemain berdiri SATU kali di panel ini,
   sebagai barisnya sendiri — bukan sekali di kotak "BANGSA" dan sekali lagi
   di petak "kamu". Dua lajur berdampingan cuma dipakai kalau pesertanya lebih
   dari empat DAN layarnya cukup lebar (lihat `gambarLobi()`), pola yang sama
   dengan papan hasil babak (`gambarPapanTur`); kalau tidak, satu lajur saja. */
.tur-daftar {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  gap: clamp(4px, 0.9vw, 8px);
  overflow-y: auto;
}
.tur-daftar-lajur {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(4px, 0.9vh, 7px);
}
.tur-p {
  display: flex;
  align-items: center;
  gap: clamp(7px, 1.4vw, 12px);
  min-width: 0;
  padding: clamp(4px, 1vh, 8px) clamp(7px, 1.4vw, 12px);
  border: 3px solid var(--garis);
  border-radius: clamp(8px, 1.6vh, 13px);
  background: #eef1f6;
}
/* Bendera bernisbah 3:4 — nisbah yang SAMA dengan panji di komidi bangsa
   (`.komidi-kartu img`), jadi bendera yang sama tidak berubah bentuk waktu
   pemain memindahkan pandangan dari strip pilihan ke tabel peserta. Kotak
   bujur sangkar yang dipakai versi sebelumnya memotong panjinya atas-bawah.

   Tingginya yang menentukan tinggi baris, dan itu disengaja: bendera inilah
   yang membedakan delapan baris ini sekilas, jadi ia yang diberi ruang lebih
   dulu dan teksnya yang menyesuaikan. */
.tur-p-panji {
  width: clamp(38px, 7.2vh, 56px);
  aspect-ratio: 3 / 2;
  border: 2px solid var(--garis);
  border-radius: 5px;
  overflow: hidden;
  flex-shrink: 0;
}
.tur-p-panji img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  image-rendering: pixelated;
}
/* Username dan nama bangsa SEBARIS: "Bimo (ROMAWI)". Bertumpuk, tiap baris
   setinggi dua baris teks dan benderanya terjepit jadi petak yang warnanya
   tidak lagi terbaca — padahal bendera itu yang membedakan kedelapan baris. */
.tur-p-nama {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: clamp(11.5px, 2.4vh, 16px);
  font-weight: 900;
  letter-spacing: var(--lc-biasa);
  color: #1b2030;
  /* Title Case, bukan ALL CAPS: nama pemain/"Waiting…" bukan heading atau
     tombol. */
  text-transform: capitalize;
}
/* Nama bangsa dalam kurung — sengaja SEUKURAN usernamenya, cuma lebih ringan
   dan lebih pudar. Dikecilkan, ia jatuh jadi catatan kaki yang harus disipitkan
   di baris setinggi 13 px; membedakannya dari nama pemain sudah cukup
   dikerjakan tanda kurung dan warnanya. Tanda kurungnya sendiri mengikuti kartu
   turnamen ("(1 vs 3)") — satu cara yang sama untuk keterangan yang menempel
   pada nama di depannya. */
.tur-p-nama i {
  margin-left: 0.4em;
  font-style: normal;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #8792a8;
  /* Title Case, bukan ALL CAPS — nama bangsa dalam kurung, bukan
     heading/tombol. */
  text-transform: capitalize;
}
/* Baris pemain sendiri. TANPA bayangan atau lingkar luar: baris-baris ini
   berjajar rapat, dan lingkar yang meluber ke luar tepinya memakan celah antar
   baris sehingga tetangga atas-bawahnya ikut terdorong. Yang menandainya latar
   biru muda beserta tanda KAMU di ujung kanan — dua penanda di dalam baris,
   jadi tidak ada satu piksel pun yang keluar dari kotaknya sendiri. */
.tur-p.kamu { background: #dbe6ff; }
/* Baris kosong: garis putus-putus, tanpa isian. Ia menyebut "belum ada", dan
   baris pejal abu-abu tidak pernah bisa menyebut itu — ia cuma terbaca
   seperti baris yang gagal dimuat. */
.tur-p.kosong { border-style: dashed; background: transparent; }
.tur-p.kosong .tur-p-panji { border-style: dashed; background: rgba(255, 255, 255, 0.5); }
.tur-p.kosong .tur-p-nama { font-weight: 800; color: #8792a8; }

/* Tanda KAMU/AI/AFK di ujung kanan baris. Wajib ada, bukan hiasan: §57.10
   menjanjikan pemain bisa "lihat sendiri siapa yang sungguhan sebelum mulai",
   §57.13 menuntut pemain AFK tetap memakai namanya tapi ditandai, dan baris
   milik pemain sendiri harus cepat ditemukan di tabel berisi delapan baris
   yang serupa. Tiga kabar berbeda, tiga warna berbeda — biru untuk "ini kamu",
   abu-abu untuk "ini bot sejak awal", merah untuk "ini orang yang
   menghilang". */
.tur-tanda {
  flex-shrink: 0;
  padding: 1px clamp(5px, 1vw, 8px);
  border: 2px solid var(--garis);
  border-radius: 999px;
  font-size: clamp(8.5px, 1.6vh, 11px);
  font-weight: 900;
  letter-spacing: 0.6px;
  /* Title Case, bukan ALL CAPS ('YOU'/'AFK' ditulis besar langsung di
     js/turnamen.js) — status singkat, bukan heading/tombol. */
  text-transform: capitalize;
}
/* Teks GELAP di atas biru, bukan putih — sekeluarga dengan tanda AI dan AFK di
   bawahnya, dan putih di atas `--biru` cuma terukur 2,9:1 pada huruf setinggi
   9 px. */
.tur-tanda.kamu { background: var(--biru); color: #06214a; }
.tur-tanda.ai { background: #d7dded; color: #4a5570; }
.tur-tanda.afk { background: var(--merah); color: #2b0a06; }

/* ---- lobi: kaki (keterangan + hitung mundur) ----------------------------- */
.tur-kaki {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(7px, 1.5vw, 13px);
  padding-top: clamp(4px, 1vh, 9px);
  border-top: 3px solid #dfe4ee;
}
.tur-status {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* §57.64: DISAMAKAN dengan `.tur-p-nama` di tabel tepat di atasnya, dulu
     `--fs-kecil`. Terukur sebelum diperbaiki: 11,5 px lawan 16 px — "Waiting
     (1/5)" terbaca sebagai catatan kaki di bawah tabel yang hurufnya setengah
     lebih besar, padahal ia menghitung ISI tabel itu dan seharusnya terbaca
     sebagai bagian dari kelompok yang sama.
     `--fs-kecil` tetap benar untuk keping dan label di tempat lain; yang
     salah cuma pemakaiannya di sini, di sebelah teks yang jauh lebih besar. */
  font-size: clamp(11.5px, 2.4vh, 16px);
  font-weight: 800;
  letter-spacing: var(--lc-biasa);
  color: #6b7590;
  /* Title Case, bukan ALL CAPS (status, bukan heading/tombol). */
  text-transform: capitalize;
}
/* Hitung mundur: angka tabular supaya lebarnya tidak berkedut tiap detik.
   Tanpa `tabular-nums`, "0:19" dan "0:18" bisa berbeda lebar beberapa piksel
   dan kotaknya terlihat bergetar sekali per detik. */
/* START THE WAR menempati tempat hitung mundur sebelum jamnya berjalan
   (§57.41.11). Ukurannya sengaja sepadan dengan hitung mundur yang
   menggantikannya, bukan setinggi tombol besar layar lain: baris kaki panel
   ini sempit, dan tombol yang lebih tinggi dari barisnya akan mendorong
   seluruh kartu bertambah tinggi sekali lalu menyusut lagi. */
/* §57.50: SATU PETAK, SATU ELEMEN. Dua catatan lama di sini (§57.42.2 dan
   §57.49) sama-sama berisi usaha menyamakan ukuran tombol START dengan
   kotak hitung mundur yang menggantikannya — angka pembentuk yang disalin
   persis, lalu tinggi yang harus dinaikkan bersama-sama — semuanya demi
   satu tujuan: baris kaki tidak melompat pada detik pertukaran.

   Tujuan itu sekarang dijamin oleh struktur, bukan oleh kedisiplinan
   menyalin angka: elemennya cuma SATU (`#tur-b-mulai`), dan `.mundur`
   mengubah warna serta perilakunya saja. Ukuran yang berbeda antara dua
   keadaan tidak mungkin lagi terjadi karena tidak ada dua kotak.

   `min-height` + flex, bukan sisipan yang digemukkan: sisipan harus
   dihitung ulang tiap kali ukuran hurufnya berubah, `min-height` tidak. */
.tur-b-mulai {
  box-sizing: border-box;
  min-height: var(--baris-lobi);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* §57.49: KAPITAL. Terlihat di tangkapan layar, tidak terlihat di angka mana
   pun — "Start" berhuruf kecil berdiri di antara "WAITING (1/4)", "JOIN WAR",
   dan kode room yang semuanya kapital, jadi satu-satunya tombol yang
   memberangkatkan pertandingan justru yang paling tidak terbaca sebagai
   tombol. Lewat `text-transform`, bukan mengubah markahnya: kata yang sama
   dipakai dua lobi, dan huruf besar di sini keputusan TAMPILAN.

   §57.50: `min-width: 0` yang dulu menyertai aturan ini SUDAH DIBUANG —
   angkanya sekarang ditulis sekali saja di blok bawah. Dua `min-width`
   pada selektor yang sama persis adalah tabrakan cascade yang cuma
   dimenangkan oleh urutan baris, dan itu jenis kesalahan yang tidak
   terlihat waktu membaca satu bloknya saja. Alasan lamanya (keterangan di
   kiri terukur menyusut habis sampai 0 px karena tombol menolak mengecil)
   sudah tidak berlaku: yang turun baris waktu ruangnya kurang sekarang
   keterangan itu sendiri, bukan tombolnya yang dipaksa mengecil. */
.tur-b-mulai {
  text-transform: uppercase;
  letter-spacing: var(--lc-kapital);
}
.tur-b-mulai {
  flex-shrink: 0;
  /* §57.50: LEBAR MINIMUM, supaya tombolnya tidak mengkerut pada detik
     tulisannya berganti dari "START" jadi "0:30" — terukur 11,4 px lebih
     sempit tanpa ini, dan keterangan di kirinya ikut bergeser sejauh itu.
     Menggabungkan kedua elemen menghapus lompatan TINGGI; lompatan LEBAR
     butuh angka ini karena isinya memang berbeda panjang. */
  min-width: clamp(72px, 11vw, 96px);
  padding: clamp(3px, 0.9vh, 7px) clamp(9px, 1.8vw, 15px);
  border: 3px solid var(--garis);
  border-radius: clamp(7px, 1.5vh, 11px);
  background: var(--hijau);
  color: #04240f;
  font-size: var(--fs-label);
  font-weight: 900;
  letter-spacing: var(--lc-biasa);
  cursor: pointer;
  transition: transform 0.08s;
}
.tur-b-mulai:active { transform: translateY(2px); }
.tur-b-mulai[hidden] { display: none; }

/* §57.50: KEADAAN hitung mundur dari tombol yang sama, bukan kotak kedua.
   Yang ditulis di sini cuma yang BERBEDA dari keadaan START di atas — warna,
   angka tabular, dan matinya kursor. Ukuran, sisipan, garis, dan sudutnya
   diwarisi apa adanya, jadi tidak ada lagi angka yang bisa lepas sinkron.

   `tabular-nums` supaya lebarnya tidak berkedut tiap detik: tanpa itu "0:19"
   dan "0:18" bisa berbeda beberapa piksel dan kotaknya terlihat bergetar
   sekali per detik. Di dalam satu tombol bersama, kedutan itu akan MENGGESER
   seluruh isi baris kaki, bukan cuma kotaknya sendiri. */
.tur-b-mulai.mundur {
  background: var(--kuning);
  color: #2b1f00;
  cursor: default;
  font-variant-numeric: tabular-nums;
}
/* Tombol yang sedang menghitung tidak boleh ikut turun 2 px waktu ditekan —
   ia bukan tombol lagi, dan geraknya menjanjikan sesuatu terjadi. */
.tur-b-mulai.mundur:active { transform: none; }
/* Sepuluh detik terakhir jadi merah. Satu-satunya perubahan keadaan di layar
   ini yang benar-benar mendesak, dan warna menyampaikannya tanpa menambah
   tulisan apa pun. */
.tur-b-mulai.mundur.mepet { background: var(--merah); color: #2b0a06; }

/* ============================================================================
   CUSTOM
   ============================================================================ */

.kustom-lobi-kartu { gap: clamp(5px, 1.1vh, 9px); }

.kustom-kaki {
  /* §57.49: kaki lobi custom sudah punya token tingginya sendiri sejak
     awal — yang berubah cuma NILAINYA, dari `clamp(36px, 7.3vh, 46px)`
     (terukur 46 px) jadi tinggi satu baris kotak pemain (terukur 54,9 px),
     supaya kotak kode, tombol, dan hitung mundur sejajar dengan daftar
     peserta tepat di atasnya. Seluruh aturan di bawah yang membaca
     `--kaki-h` ikut naik tanpa disentuh satu per satu. */
  --kaki-h: var(--baris-lobi);
  align-items: stretch;
  gap: clamp(6px, 1.2vw, 10px);
  padding-top: clamp(6px, 1.3vh, 10px);
  /* §57.70 — `flex-end` dari §57.69 DICABUT, dikoreksi langsung: yang
     diminta bukan Waiting dan grup tombol berdempetan jadi satu blok,
     melainkan Waiting tetap mepet KIRI dan grup tombol mepet KANAN dengan
     celah kosong di ANTARA keduanya — persis perilaku `space-between`
     warisan `.tur-kaki`. `flex-end` kemarin salah baca masalahnya: bukan
     `space-between`-nya yang salah, tapi grup tombol yang gagal melebar
     (diperbaiki lewat `flex-grow` di `.kustom-room`, lihat di sana) —
     begitu grup itu melebar sendiri, `space-between` sudah cukup untuk
     mendorong Waiting ke kiri dan grup ke kanan tanpa perlu `flex-end`. */
  justify-content: space-between;
  /* §57.50: yang BOLEH turun baris sekarang keterangan di kiri, bukan
     JOIN WAR. Ketiga kotak (kode room, JOIN, START) diminta tetap sebaris
     dan setinggi satu sama lain, jadi kelompok itu tidak boleh lagi jadi
     tempat menyerah waktu ruangnya kurang — dan ruangnya MEMANG kurang di
     640x360 (terhitung 333,6 px dibutuhkan, 302,5 px tersedia).

     Keterangan "WAITING (1/5)" yang paling pantas mengalah: ia satu baris
     tulisan tanpa kotak, jadi turun baris tidak mengubah bentuknya sama
     sekali, sementara JOIN yang turun baris kemarin terukur gepeng jadi
     16,5 px tinggi — setengah tinggi tetangganya. */
  /* §57.60: `wrap` DICABUT, diminta langsung — keterangan harus sebaris
     dengan kotak kode dan kedua tombol, tidak boleh turun ke baris sendiri.
     Ini membalik kompromi §57.50 di atas, dan yang membuat pembalikan itu
     mungkin adalah ruang yang baru dibebaskan: kotak kode dipendekkan dari
     156 px ke ±128 px (§57.60 di `.kustom-room-kode`), jadi kaki panel
     mendapat ±28 px yang dulu tidak ada waktu kompromi itu dibuat.

     Keterangan tetap yang pertama mengalah kalau ruangnya masih kurang,
     tapi caranya sekarang MENGECIL (lihat `min-width` di bawah), bukan
     turun baris — bentuk barisnya karena itu tidak pernah berubah. */
  flex-wrap: nowrap;
}

/* §57.50: `min-width` dan lebar dasar SELEBAR KALIMATNYA, dan boleh
   melar mengisi sisa baris. Dulu `1 1 clamp(82px, ...)` dengan izin
   menyusut tanpa batas, dan itulah yang membuatnya terukur habis sampai
   0 px di layar sempit. Sekarang kalau ia tidak muat sebaris dengan
   ketiga kotak, yang terjadi bukan ia mengecil melainkan seluruh
   kelompok kotak turun ke baris di bawahnya. */
.kustom-kaki .tur-status {
  /* §57.60: `min-width` TIDAK LAGI `max-content`. Sejak kaki berhenti
     membungkus (`flex-wrap: nowrap` di atas), `max-content` berarti
     keterangan menolak mengecil sampai seberapa pun sempitnya layar — dan
     yang menanggung penolakan itu kotak kode dan kedua tombol di
     sebelahnya, yang justru tidak boleh mengecil lagi.

     Batas bawahnya sekarang selebar "WAITING (1/5)" pada ukuran huruf
     terkecilnya. Di bawah itu ia dipotong elipsis alih-alih memaksa
     tetangganya menyusut: pecahan peserta masih terbaca separuh, sementara
     kode room yang terpotong tidak bisa didapat dari mana pun lagi. */
  /* §57.69 — `flex-grow` DIMATIKAN (1 -> 0), dan INI yang sebenarnya
     membuat kotak kode/JOIN WAR/START tidak pernah memanjang meski
     `flex-basis`-nya sudah dinaikkan berkali-kali (§57.64/§57.65/§57.68).
     Dilaporkan langsung: "potong kustom status yang margin kanannya
     mengambil banyak ruang... hanya ada ruang kosong yang menyebabkan
     ketiga tombol tidak bisa memanjangkan diri" — dan itu tepat.

     Terukur sebelum ini di 1158x506: `.kustom-kaki` 467,7 px, keterangan
     "Waiting" MELAR jadi 121,7 px (jauh lebih lebar daripada teksnya
     sendiri) karena `flex-grow: 1`, sementara `.kustom-room` di sebelahnya
     cuma `flex: 0 1 auto` — TIDAK PERNAH ikut tumbuh. Sisa 336 px yang
     didapat room tidak cukup untuk basis gabungan kode+join+start (402 px),
     jadi ketiganya MENYUSUT proporsional lewat `flex-shrink`, dan JOIN —
     basis terbesar — menyusut paling banyak: 168 px yang ditulis di CSS
     jadi 108 px yang benar-benar dirender. `computedStyle` memang melapor
     168 px; yang dibaca layar `getBoundingClientRect()` 108 px. Itu sebabnya
     tiga putaran menaikkan angka `flex-basis` (§57.64, §57.65, §57.68)
     semuanya TIDAK TERLIHAT di layar — bukan gagal diterapkan, tapi
     dikalahkan penyusutan yang terjadi SESUDAHNYA.

     Keterangan sekarang selebar isinya saja (`flex: 0 1 auto`, ditulis di
     bawah), dan seluruh ruang lega jatuh ke `.kustom-room` — tempat yang
     memang butuh ruang lebih, karena isinya TIGA kotak sementara keterangan
     cuma satu baris teks pendek. */
  flex: 0 1 auto;
  min-width: clamp(64px, 8vw, 94px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  align-self: stretch;
  display: flex;
  align-items: center;
  height: var(--kaki-h);
  /* §57.64 — DISAMAKAN dengan `.tur-p-nama` di tabel peserta tepat di atasnya,
     diminta langsung ("perbesar tulisan waiting seukuran waiting di baris
     player").

     Aturan dasar `.tur-status` sudah dinaikkan lebih dulu, dan TIDAK CUKUP:
     blok ini berkekhususan lebih tinggi (0,2,0 lawan 0,1,0) sehingga
     `clamp(9px, 1.7vh, 11.5px)` di sini yang menang dan "Waiting (1/5)" tetap
     11,5 px sementara "Waiting…" di baris peserta 16 px. Perangkap yang sama
     dengan `body.hp .tbl` beberapa aturan di bawah. */
  font-size: clamp(11.5px, 2.4vh, 16px);
  letter-spacing: 0.25px;
  line-height: 1;
}

.kustom-room {
  /* §57.49: BOLEH MENYUSUT (`flex-shrink: 1`), dulu `0`. Kaki lobi custom
     memuat empat benda — keterangan, kode room, tombol, hitung mundur — dan
     kode room yang terlebar (terukur 228 px dari 290 px total di 640x360).
     Selama ia menolak menyusut, tekanannya jatuh seluruhnya ke keterangan di
     kiri, yang terukur habis sampai 0 px: "WAITING (1/5)" LENYAP dari layar
     sempit sementara kode room berdiri utuh selebar dua tombol.

     Yang terpotong lebih dulu sekarang kode room — dan itu yang benar: ia
     punya tombol salinnya sendiri di sebelahnya, sementara pecahan peserta
     tidak tertulis di mana pun lagi di layar ini. */
  /* §57.50: `align-items: stretch` di sini yang membuat ketiga kotak
     setinggi satu sama lain — tinggi mereka DITURUNKAN dari baris ini,
     bukan ditulis tiga kali dengan angka yang kebetulan sama. Menambah
     kotak keempat kelak otomatis ikut. */
  /* §57.69: `flex-grow` 0 -> 1, supaya kelompok tiga kotak yang menyerap
     ruang lega kaki panel, bukan `.kustom-kaki .tur-status` di sebelahnya.

     §57.70 (lanjutan) — `flex-grow` DIMATIKAN LAGI (1 -> 0), dikoreksi
     langsung: "ketika layarnya semakin panjang, panjang kotak/tombolnya
     kan juga memanjang... apakah tidak ada cara untuk menyesuaikan panjang
     tombol/kotak agar tidak terasa terlalu panjang". `flex-grow: 1` di sini
     persis penyebabnya — kelompok ini melebar mengikuti SISA RUANG panel,
     jadi di layar lebar (1280px) tiga kotak di dalamnya ikut melebar jauh
     melebihi kebutuhan hurufnya, membuat jarak isi-ke-tepi kotak terasa
     berlebihan meski hurufnya sendiri tidak berubah ukuran.

     Ruang lega kaki panel sekarang jatuh ke CELAH kosong (lewat
     `justify-content: space-between` milik `.kustom-kaki`), bukan ke
     lebar kotak — kelompok ini berhenti selebar isinya sendiri
     (`flex-basis` clamp tiap anak), didorong ke kanan panel oleh
     `space-between`, TIDAK ikut memanjang lagi walau layarnya makin
     lebar. Ini kebalikan tepat dari alasan §57.69 di atas, dan itu
     disengaja: §57.69 memecahkan "tombol tidak bisa memanjang", §57.70
     memecahkan masalah sebaliknya sesudah kotaknya justru dilebarkan
     sendiri lewat `flex-basis` (lihat `.kustom-room-kode`/`.kustom-room >
     .tbl`) — begitu lebarnya sudah cukup dari `flex-basis`, `flex-grow`
     tidak dibutuhkan lagi dan cuma menambah lebar yang tidak diminta. */
  flex: 0 1 auto;
  display: flex;
  align-items: stretch;
  /* §57.70 — `justify-content: flex-end` ditambahkan, diminta langsung
     (tombol START masih menggantung ~66-154 px dari tepi kanan panel
     meski `.kustom-kaki` sudah `space-between`). Sebabnya: `flex-grow: 1`
     di atas membuat KOTAK ini melebar, tapi ruang lebih itu jatuh sebagai
     celah KOSONG di kanan tiga anaknya, karena `.kustom-room` sendiri
     tidak punya `justify-content` (baku ke `flex-start` — anak-anaknya
     menempel kiri KOTAK, bukan kiri PANEL). Mendorong anak-anaknya ke
     kanan KOTAK inilah yang membuat START akhirnya menyentuh tepi kanan
     PANEL, karena kotaknya sendiri sudah melebar sampai ke sana. */
  justify-content: flex-end;
  gap: clamp(5px, 1vw, 8px);
  min-width: 0;
  /* Kelompok ini TIDAK PERNAH membungkus (dulu boleh, di media query
     layar pendek). Isinya yang diminta sebaris. */
  flex-wrap: nowrap;
  /* §57.49: `min-height`, bukan `height`. Di layar pendek blok ini
     MEMBUNGKUS (JOIN turun ke baris kedua, lihat media query di bawah), dan
     tinggi pasti membuat baris kedua itu keluar dari kotaknya sendiri —
     terukur: isi 77 px di dalam kotak 38 px, luber tegak 42 px yang tidak
     terlihat sebagai tumpang-tindih mendatar mana pun. */
  min-height: var(--kaki-h);
}

.kustom-room-kode {
  /* §57.49: `0 1` — lebar dasarnya tetap sama, tapi ia boleh dipangkas waktu
     kaki kehabisan ruang (lihat catatan `.kustom-room` di atas).

     `min-width` BUKAN 0, dan itu perbaikan atas percobaan pertama: dengan
     `min-width: 0` ia menyusut sampai kodenya tinggal satu titik-titik di
     640x360 — terlihat di tangkapan layar, dan kode room yang tidak terbaca
     adalah satu-satunya hal di panel ini yang tidak bisa didapat dari tempat
     lain. Batas bawahnya lebar enam huruf `tabular-nums` plus tombol salin
     di sebelahnya. */
  /* §57.50: DIPERPENDEK, diminta langsung. Dulu 126-152 px dengan batas
     bawah 104-126 px, dan itu kotak terlebar di kaki panel padahal isinya
     enam huruf. Angka barunya diukur dari isinya: enam huruf `tabular-nums`
     pada ukuran terbesarnya (17 px) terukur ~62 px, ditambah tombol salin
     (32 px), celah, dan sisipan dua sisi. Batas bawahnya menjaga keenam
     huruf tetap utuh — kode room yang terpotong adalah satu-satunya hal di
     panel ini yang tidak bisa didapat dari tempat lain.

     Dua percobaan pertama (112-132 lalu 124-142 px) TERLALU PENDEK, dan
     angka-angkanya tidak mengatakannya: kodenya terpotong tapi
     `text-overflow: clip` memotongnya DIAM-DIAM — tidak ada luber, tidak
     ada tumpang-tindih, lebar kotaknya persis seperti yang diminta.
     Ketahuan cuma dari tangkapan layar.

     Yang lebih menipu lagi: mengukur kode yang KEBETULAN sedang tampil
     memberi angka yang berbeda-beda tiap muat ulang, karena kodenya acak
     dan hurufnya tidak sama lebar ("W" jauh lebih lebar daripada "1")
     meski `tabular-nums` menyamakan ANGKAnya. Yang menentukan lebar kotak
     karena itu kode TERLEBAR yang mungkin — enam "W" dari `ABJAD_KODE` —
     dan itu diukur langsung dengan mengganti isi elemennya di enam
     kemungkinan terlebar, bukan dikira-kira.

     Angka sekarang menyisakan ruang pada ketiga lebar layar yang diuji
     (sisa 1,7 / 12,5 / 1,0 px untuk "WWWWWW"). Masih lebih pendek daripada
     152 px sebelumnya — yang diminta — tapi tidak sependek yang sempat
     terlihat "berhasil" waktu yang diukur cuma satu kode beruntung. */
  /* §57.60: DIPERPENDEK LAGI (156 px -> ±128 px), diminta langsung: kotak
     kode masih benda terlebar di kaki panel — 156 px lawan 96 px milik JOIN
     dan START — padahal isinya enam huruf, jadi ia terbaca sebagai kotak
     yang kebesaran untuk isinya, bukan sebagai satu kelompok dengan kedua
     tombol di sebelahnya.

     Yang membuat pemendekan ini AMAN (dan tidak melanggar peringatan
     panjang di atas) satu temuan pengukuran: keenam kemungkinan terlebar
     diukur ulang lewat `scrollWidth`, dan "WWWWWW", "MMMMMM", "888888",
     "ABC234" SEMUANYA terukur 91,0 px — persis sama. Font yang benar-benar
     dipakai di sini menyamakan lebar SELURUH huruf, bukan cuma angkanya
     seperti yang diasumsikan `tabular-nums`. Jadi tidak ada "kode beruntung"
     lagi: satu angka berlaku untuk semua kode yang mungkin, dan lebar kotak
     bisa disetel ketat tanpa risiko huruf terpotong diam-diam.

     Anggarannya sekarang: teks 91 px (pada ukuran huruf yang juga ikut
     turun, lihat di bawah) + ikon salin + celah + sisipan dua sisi. Sisipan
     dan celah dirapatkan karena ruang kosong di kiri-kanan teks itulah yang
     paling terlihat sebagai kelonggaran di tangkapan layar. */
  /* §57.65: DIPERPENDEK SEKALI LAGI (±130 px -> ±116 px), diminta langsung,
     dan ruang yang dibebaskannya PINDAH ke JOIN WAR di sebelahnya (lihat
     `.kustom-room > .tbl`) — jadi ini bukan dua permintaan terpisah
     melainkan satu pemindahan lebar di dalam kaki yang total lebarnya tidak
     berubah sedikit pun.

     Batas amannya tetap temuan §57.60 yang sudah terbukti: SEMUA kode yang
     mungkin terukur sama lebar (91 px pada 14 px), karena font di sini
     menyamakan lebar seluruh huruf, bukan cuma angkanya. Anggaran barunya
     91 px teks + 26 px ikon salin + 4 px celah + 2x5 px sisipan + 2x3 px
     garis = 137 px pada ukuran huruf terbesar — di atas 116 px, jadi
     `.kustom-room-kode b` yang mengecil lebih dulu lewat `clamp`-nya
     sendiri, bukan kodenya yang terpotong. Yang TIDAK boleh dilakukan di
     sini adalah menurunkan `min-width` di bawah lebar enam huruf pada
     ukuran huruf terkecilnya — di situlah pemotongan diam-diam yang
     diperingatkan §57.50 kembali mungkin terjadi. */
  /* §57.69 — DILEBARKAN SECUKUPNYA (±118 -> ±126 px), konsekuensi wajib dari
     huruf kode yang dibesarkan ke `var(--fs-label)` (lihat `.kustom-room-kode
     b` di bawah).

     Angkanya diukur, bukan ditaksir: "WWWWWW" pada huruf terbesarnya (15 px,
     berat 900, tanpa jarak huruf — persis pengaturan kode room) terukur
     85,2 px lewat `getBoundingClientRect()` sungguhan. Anggarannya 85,2 px
     teks + 26 px ikon salin + 3 px celah + 2×3 px sisipan + 2×3 px garis =
     126,2 px.

     SENGAJA LEBIH SEMPIT daripada percobaan pertama (140 px): kartu lobi
     custom terbukti SAMA LEBAR dengan kartu lobi kompetisi (467,7 px kaki
     panel di keduanya, diukur langsung), padahal custom harus memuat TIGA
     kotak sementara kompetisi cuma satu START. Kotak kode karena itu
     TIDAK BISA selebar JOIN/START tanpa memangkas keduanya sampai lebih
     sempit daripada label "JOIN WAR"-nya sendiri — pemilik proyek diminta
     memilih, dan jawabannya huruf besar diutamakan, kode boleh lebih
     ramping daripada dua tetangganya. */
  /* §57.69 — DILEBARKAN LAGI (±126 -> ±139 px), diminta langsung: hurufnya
     harus sebesar START (15 px) TANPA terpotong — jadi kotaknya yang mengalah
     melebar, bukan hurufnya yang mengalah mengecil (dua percobaan sebelumnya
     memilih arah itu dan keduanya dicabut).

     Angkanya diukur dari ruang isi SUNGGUHAN, bukan taksiran border+padding:
     kotak 105,3 px lama punya `clientWidth` cuma 52 px (overhead ikon salin +
     sisipan + celah + garis makan 53,3 px, jauh lebih banyak daripada
     taksiran tangan sebelumnya). "WWWWWW" pada 15 px terukur 85,2 px lewat
     `getBoundingClientRect()`. Kotak total yang dibutuhkan: 85,2 + 53,3 =
     138,5 px, dibulatkan ke 139. */
  /* §57.70 — DIPERPANJANG (±139 -> ±168 px), lalu DIKOREKSI DUA KALI setelah
     dilaporkan "masih kepanjangan" bahkan sesudah koreksi tipis pertama
     (±168 -> ±150 px, ternyata tidak cukup). Kembali ke ANGKA ASLI §57.69:
     139 px adalah batas hitung dari kebutuhan sungguhan — "WWWWWW" pada
     `var(--fs-label)` 15 px terukur 85,2 px + overhead ikon salin/sisipan/
     garis 53,3 px = 138,5 px, dibulatkan 139. Di bawah ini huruf terpotong
     diam-diam; di atasnya cuma ruang kosong berlebih yang persis dikeluhkan
     ("kepanjangan"). Menambah margin ekstra di atas angka hitungan adalah
     kesalahannya — kembalikan pas ke batas hitungannya, jangan lebih. */
  /* Batas bawah `min-width` dinaikkan 96 -> 102 px sesudah luber terukur
     langsung di 640x360: huruf di layar sempit ini TIDAK ikut mengecil
     sejauh percobaan lama (tetap 11 px dari `var(--fs-label)`, bukan
     9,5 px), jadi kebutuhannya beda dari batas bawah yang dihitung dari
     layar lebar. Terukur: isi kotak 55 px vs "WWWWWW" pada 11 px = 54,7 px
     (mepet 0,3 px) — cukup untuk meluber begitu kode acak kebetulan sedikit
     lebih lebar dari "W" biasa (font tidak selalu menyamakan lebar semua
     huruf persis, lihat catatan §57.60 di bawah). 102 px memberi ±6 px sisa
     aman tanpa kembali melebar berlebihan. */
  flex: 0 1 clamp(108px, 13.5vw, 139px);
  min-width: clamp(108px, 13vw, 139px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(3px, 0.6vw, 5px);
  padding: 0 clamp(5px, 0.9vw, 7px);
  border: 3px solid var(--garis);
  border-radius: clamp(9px, 1.8vh, 13px);
  background: #eef1f6;
}

/* §57.50: kodenya MENGECIL supaya muat, tidak dipotong.
   `text-overflow: clip` yang dulu di sini memotong DIAM-DIAM — tanpa
   elipsis, tanpa luber, tanpa tumpang-tindih — jadi kode yang tinggal lima
   huruf terlihat sama sahnya dengan yang enam. Ketahuan cuma dari tangkapan
   layar, dan cuma pada kode yang kebetulan berhuruf lebar.

   Yang menentukan ukuran kotak bukan kode yang sedang tampil melainkan yang
   TERLEBAR yang mungkin: abjadnya 32 huruf (`ABJAD_KODE` di js/kustom.js)
   dan "WWWWWW" terukur 103,2 px sementara slotnya 71 px — kurang 32 px.
   Melebarkan kotaknya sejauh itu mengembalikannya jadi benda terlebar di
   kaki panel, yang justru diminta diperpendek.

   Jadi hurufnya yang mengalah: `font-stretch` + `letter-spacing` yang lebih
   rapat menampung huruf lebar, dan sisipan nol di ujung memberi sisa. Kode
   room yang seluruh gunanya untuk DIBACA dan diketik ulang orang lain tidak
   boleh kehilangan satu huruf pun. */
.kustom-room-kode b {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-align: center;
  /* §57.60: 15,5 px -> 14 px. Kode room dulu berhuruf lebih BESAR daripada
     label kedua tombol di sebelahnya (JOIN 13 px, START 13,5 px), padahal
     ketiganya satu kelompok yang setinggi sama — yang membuat kotak kode
     terbaca menonjol tanpa alasan. Sekarang ketiganya sekelas, dan kodenya
     tetap yang paling tebal (900) sehingga masih jelas mana yang harus
     dibaca dan diketik ulang. */
  /* §57.65: 14 -> 11,5 px, dan ini KONSEKUENSI WAJIB dari pemendekan kotaknya
     di atas — bukan penghalusan terpisah. Terukur sesudah kotak dipendekkan
     ke 116 px: "WWWWWW" pada 14 px meminta 91 px sementara ruang isi kotaknya
     tinggal 73 px, jadi 18 px terpotong DIAM-DIAM oleh `overflow: hidden`
     tepat di baris atas — tanpa elipsis, tanpa luber, tanpa satu tanda pun di
     layar. Persis jebakan yang sudah memakan dua percobaan di §57.50, dan
     satu-satunya cara menemukannya tetap sama: mengganti isinya dengan enam
     "W" lalu membandingkan `scrollWidth` dengan `clientWidth`, bukan
     mempercayai kode acak yang kebetulan sedang tampil.

     Yang mengalah hurufnya, bukan kotaknya, karena memendekkan kotak itulah
     yang diminta. 11,5 px memberi "WWWWWW" ±75 px — muat, dengan sisa. Ia
     sekarang sedikit lebih kecil daripada label JOIN/START di sebelahnya
     (12 px), dan itu bisa diterima: bobot 900 dan `tabular-nums` tetap
     membuatnya benda paling menonjol di dalam kotaknya sendiri. */
  /* §57.69 — DIBESARKAN sampai SAMA PERSIS dengan `var(--fs-label)` (token
     START/JOIN), diminta langsung dua kali: "dibesarkan seperti tulisan di
     tombol start", lalu diperjelas lagi "harus sesuai tulisan di tombol
     start... asalkan jangan sampai tulisan keluar dari kotak, kotak kode
     juga bisa kamu panjangkan".

     Tiga percobaan sebelumnya (dicatat lalu dicabut) semuanya memilih
     MENGECILKAN HURUF supaya muat di kotak yang lebarnya dianggap tetap.
     Arahnya terbalik: yang seharusnya mengalah KOTAKNYA. `.kustom-room-kode`
     di atas sudah dilebarkan ke ±139 px (diukur dari kebutuhan sungguhan
     "WWWWWW" pada 15 px + overhead ikon-sisipan-celah-garis), jadi huruf di
     sini sekarang boleh memakai token yang sama tanpa syarat khusus. */
  font-size: var(--fs-label);
  font-weight: 900;
  /* §57.65: jarak huruf DINOLKAN. Pada enam huruf, 0,2 px per huruf berarti
     1,2 px — kecil, tapi sisa ruangnya sesudah kotak dipendekkan juga cuma
     beberapa piksel, dan 1,2 px itu yang menentukan huruf keenam terpotong
     atau tidak. Kode room dibaca sebagai satu blok untuk diketik ulang, bukan
     sebagai kata; merenggangkannya tidak menambah keterbacaan apa pun yang
     sebanding dengan huruf yang hilang. */
  letter-spacing: 0;
  color: #1b2030;
  font-variant-numeric: tabular-nums;
}

.kustom-ikon {
  /* §57.60: ikut mengecil bersama kotaknya (32 -> 28 px). Tombol salin
     setinggi 32 px di dalam kotak setinggi 55 px terbaca sebagai kotak
     kedua yang berdiri di dalam kotak pertama; pada 28 px ia kembali
     terbaca sebagai lampiran kodenya. */
  width: clamp(23px, 4.2vh, 28px);
  height: clamp(23px, 4.2vh, 28px);
  display: grid;
  place-items: center;
  border: 2.5px solid var(--garis);
  border-radius: 8px;
  background: var(--kuning);
  color: #2b1f00;
  cursor: pointer;
  transition: transform 0.08s, filter 0.12s;
}
.kustom-ikon:hover { filter: brightness(1.06); }
.kustom-ikon:active { transform: translateY(2px); }
.kustom-ikon[hidden] { display: none; }
.kustom-ikon svg { display: block; width: 67%; height: 67%; }

.kustom-room > .tbl {
  /* §57.49: `0 1`, bukan `0 0`. Kaki lobi custom memuat EMPAT benda dan di
     640x360 keempatnya tidak muat sebaris: dengan lebar yang menolak
     menyusut, JOIN WAR terukur tertimpa tombol START di sebelahnya —
     terlihat di tangkapan layar, tidak terlihat di angka luber mana pun
     (keduanya masih di dalam kaki, cuma saling menumpuk).

     `min-width` menjaga labelnya tetap terbaca sesudah dipangkas; di bawah
     itu yang menyusut kode room, lalu keterangan di kiri. Urutan menyerah
     itu disengaja: START tidak pernah boleh mengecil (satu-satunya jalan
     berangkat), kode room punya batas bawahnya sendiri, dan pecahan peserta
     yang paling murah dikorbankan. */
  /* §57.64 — LUBER TEKS DIPERBAIKI, dilaporkan langsung ("tulisannya ada yang
     keluar tombol") dan terukur sesudahnya di beberapa lebar layar sekaligus:
     lebar teks "JOIN WAR" dikurangi lebar kotak isinya = -4,2 px di 1280,
     -11,9 px di 820, lalu +20,0 px di 760 ke bawah. Positif berarti teksnya
     benar-benar berdiri di luar tombolnya — huruf terakhir menembus tepi dan
     jatuh di atas tombol START di sebelahnya.

     Catatan §57.49 di bawah sudah mengenali gejalanya dan menambal dari sisi
     LEBAR (`flex: 0 1` + `min-width`). Tambalan itu benar tapi tidak cukup:
     `min-width` menahan tombol pada 72 px di layar sempit, sementara "JOIN
     WAR" pada 10,5 px masih menuntut ±90 px, dan `white-space: nowrap`
     melarangnya melipat. Yang tersisa cuma satu jalan keluar bagi teksnya —
     keluar dari kotak.

     Jadi yang mengalah sekarang UKURAN HURUFNYA, lewat batas bawah `clamp`
     yang diturunkan (10,5 -> 9 px) DAN `vw` yang ikut menyusut bersama lebar
     layar, bukan cuma `vh`. Label dua kata di tombol selebar 72 px memang
     harus lebih kecil daripada label yang sama di tombol 116 px; itu bukan
     kompromi melainkan hal yang benar.

     `min-width: 0` mencabut lantai lebar-isi bawaan flex supaya `flex: 0 1`
     di atasnya benar-benar bisa memangkas, dan `overflow: hidden` menjadi
     jaring pengaman terakhir: kalau suatu hari ada label yang lebih panjang
     lagi, ia terpotong DI DALAM tombolnya sendiri — cacat yang terbaca
     sebagai "terpotong", bukan sebagai dua tombol yang saling menimpa. */
  /* §57.64 (lanjutan) — DIPERPANJANG dan HURUFNYA DIBESARKAN, diminta
     langsung. Lebar dasar 96-116 -> 116-138 px dan huruf 13 -> 15 px di batas
     atas. Keduanya harus jalan bersama: membesarkan huruf tanpa memperpanjang
     tombol mengembalikan persis luber yang baru saja dihabiskan, dan
     memperpanjang tanpa membesarkan huruf meninggalkan label kecil yang
     mengambang di kotak lega. Batas bawahnya tidak ikut naik — di layar
     sempit yang berlaku blok `max-height: 470px` di bawah, dan di sanalah
     luber dulu terjadi. */
  /* §57.65: DIPERPANJANG LAGI (138 -> 152 px), memakai persis 14 px yang baru
     dilepas kotak kode di sebelahnya. Ini pasangan dari pemendekan di
     `.kustom-room-kode`, bukan penambahan lebar baru: total lebar kaki tidak
     bertambah, jadi keterangan "Waiting (n/n)" di kiri tidak kehilangan
     ruang dan urutan mengalah yang ditetapkan §57.49 tetap utuh.

     Batas bawah tetap tidak diangkat, alasan yang sama dengan §57.64: di
     layar sempit yang berlaku blok `max-height: 470px`, dan menaikkan batas
     bawah di sini akan mengembalikan luber yang sudah dihabiskan di sana. */
  /* §57.68: DIPERPANJANG LAGI (152 -> 168 px), diminta langsung ("perpanjang
     tombol join war"). Ruangnya dari kotak kode yang ikut diperpendek di
     `.kustom-room-kode` — total lebar kaki tidak bertambah. */
  /* §57.70 — DIPERPANJANG (±168 -> ±196 px), lalu DIKOREKSI DUA KALI setelah
     dilaporkan "masih kepanjangan" bahkan sesudah koreksi tipis pertama
     (±196 -> ±172 px, ternyata tidak cukup). Kembali dekat ANGKA ASLI
     §57.68 (168 px) yang sudah pernah terverifikasi pas dengan huruf
     `var(--fs-label)` penuh tanpa luber DAN tanpa ruang kosong berlebih —
     menambah margin ekstra di atas angka terverifikasi itu adalah
     kesalahannya, bukan sesuatu yang perlu ditambal lagi. */
  /* Batas bawah `min-width` dinaikkan 72 -> 80 px sesudah luber terukur
     langsung di 640x360, sebab yang sama dengan `.kustom-room-kode` di
     atas: huruf tetap 11 px (`var(--fs-label)`) alih-alih ikut mengecil ke
     8 px seperti percobaan lama. Terukur: isi kotak 66 px vs "JOIN WAR"
     pada 11 px = 69 px — meluber 3 px. 80 px memberi ±5 px sisa aman. */
  flex: 0 1 clamp(116px, 16.5vw, 168px);
  min-width: clamp(80px, 10vw, 108px);
  border-radius: clamp(9px, 1.8vh, 13px);
  /* §57.68 — HURUFNYA MEMAKAI TOKEN YANG SAMA dengan tombol START lobi
     kompetisi (`.tur-b-mulai` -> `var(--fs-label)`), diminta langsung.

     `clamp` yang ditulis tangan di sini menghasilkan angka yang BERBEDA dari
     acuannya justru di layar menengah — terukur di 900x500: acuan 12 px,
     yang ini 11 px, karena suku `1.7vw`-nya mengecil lebih cepat daripada
     `2.4vh` milik token. Memakai tokennya langsung membuat keduanya mustahil
     menyimpang lagi, sekarang maupun waktu tokennya disetel ulang nanti —
     itu keuntungan yang tidak dimiliki angka yang disalin. */
  font-size: var(--fs-label);
  font-weight: 900;
  white-space: nowrap;
  overflow: hidden;
}
/* SISIPAN ditulis terpisah dengan `body.hp` di depannya, dan itu WAJIB, bukan
   kerapian: `body.hp .tbl` di css/style.css berkekhususan (0,2,1) sementara
   `.kustom-room > .tbl` cuma (0,2,0), jadi sisipan 11px/12px miliknya
   MENGALAHKAN apa pun yang ditulis di aturan di atas.

   Terukur waktu cacatnya dilacak: tombol 59,7 px dengan sisipan 12 px dua sisi
   plus garis 3 px dua sisi menyisakan ruang isi cuma 29,7 px — sementara "JOIN
   WAR" pada 8 px menuntut 42,6 px. Jadi yang meluber bukan hurufnya (huruf
   sudah muat sejak dikecilkan) melainkan SISIPANNYA yang tidak pernah ikut
   mengecil. Menurunkan ukuran huruf lagi tidak akan pernah menyelesaikannya —
   dan itu sebabnya percobaan 9,5 -> 8 px cuma memindahkan luber dari +20,0 ke
   +12,9 alih-alih menghabiskannya. */
.kustom-room > .tbl,
body.hp .kustom-room > .tbl { padding: 0 clamp(5px, 1vw, 10px); }

/* §57.50: `height` DIBUANG, diganti `min-height` yang diwarisi dari
   `.tur-b-mulai` + `align-items: stretch` induknya. Tinggi pasti di sini
   akan MELAWAN peregangan itu: kalau JOIN di sebelahnya kebetulan lebih
   tinggi (huruf lebih besar, sisipan berbeda), START tetap terpaku pada
   angkanya sendiri dan barisnya jadi tidak rata lagi — persis cacat yang
   sedang diperbaiki.

   `min-width` disamakan dengan JOIN supaya keduanya tidak berbeda lebar
   tanpa alasan, DAN supaya tombolnya tidak menyusut waktu tulisannya
   berganti jadi "0:05": terukur 11,4 px lebih sempit daripada "START",
   dan kotak yang mengkerut pada detik pertukaran adalah cacat yang sama
   dengan yang membuat kedua elemen ini digabung sejak awal. */
.kustom-kaki .tur-b-mulai {
  /* §57.64: `min-width` dan ukuran huruf DISAMAKAN dengan `.kustom-room > .tbl`
     di atas — termasuk pengecilan `vw`-nya. Catatan di atas sudah menyebut
     alasan menyamakan `min-width`; alasan yang sama berlaku untuk hurufnya:
     kalau cuma JOIN yang mengecil di layar sempit, dua tombol yang berdiri
     bersebelahan dan sama tingginya berakhir berbeda ukuran huruf, dan
     ketimpangan itu terbaca sebagai salah satunya salah. "START" sendiri jauh
     lebih pendek daripada "JOIN WAR" (terukur luber -16,1 px di 640) jadi ia
     tidak pernah menuntut pengecilan; ia mengecil demi kerapian barisnya. */
  /* §57.64: START ikut naik bersama JOIN (13,5 -> 15 px) tapi lebarnya TIDAK
     ikut diperpanjang — "START" satu kata pendek, dan memberinya lebar yang
     sama dengan "JOIN WAR" membuat labelnya mengambang di tengah kotak yang
     kelewat lega. Yang harus sama tingginya dan ukuran hurufnya; lebarnya
     memang boleh mengikuti isi masing-masing. */
  flex: 0 1 clamp(96px, 13vw, 116px);
  min-width: clamp(64px, 10vw, 96px);
  padding-block: 0;
  border-radius: clamp(9px, 1.8vh, 13px);
  /* §57.68: token yang sama dengan JOIN di atas dan dengan acuannya sendiri
     (`.tur-b-mulai` lobi kompetisi). Lihat catatan lengkapnya di sana. */
  font-size: var(--fs-label);
}
.kustom-kaki .tur-b-mulai[hidden] { display: none; }

.kustom-join-tirai {
  position: fixed;
  z-index: 56;
}

.kotak.lebar.kustom-join-kotak {
  width: min(760px, 96vw);
  gap: clamp(6px, 1.2vh, 9px);
  overflow: hidden;
}

/* §57.49: judul panel ini naik dari 15 px bawaan `.kotak-judul` ke tingkat
   judul yang sesungguhnya. Pada ukuran lama ia lebih kecil daripada kotak
   kode di bawahnya, jadi satu-satunya tulisan yang menerangkan panel ini
   justru yang paling akhir terbaca mata.

   Naik lewat `vh`, bukan angka mati: panel ini muncul di atas layar lobi
   yang tingginya sudah dipadatkan dua kali (§57.42.7), dan judul setinggi
   angka mati akan memakan ruang yang sama di HP mendatar 360 px seperti di
   layar penuh. Kapitalnya dari markah, bukan `text-transform`, supaya yang
   terbaca di berkas sama dengan yang terbaca di layar. */
.kustom-join-kotak .kotak-judul {
  font-size: clamp(19px, 3.6vh, 27px);
  font-weight: 900;
  letter-spacing: 0.06em;
}

.kustom-cari {
  display: flex;
  gap: clamp(7px, 1.4vw, 11px);
}

.kustom-cari input {
  flex: 1 1 auto;
  min-width: 0;
  height: clamp(36px, 7vh, 46px);
  padding: 0 clamp(10px, 2vw, 14px);
  border: 3px solid var(--garis);
  border-radius: 12px;
  background: #eef1f6;
  color: #1b2030;
  font: inherit;
  font-size: clamp(18px, 4vh, 25px);
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.kustom-cari input:focus { outline: none; box-shadow: 0 0 0 3px rgba(255, 210, 63, 0.75); }
.kustom-cari .tbl {
  flex: 0 0 clamp(78px, 12vw, 104px);
  padding-inline: 8px;
  font-weight: 900;
}

.kustom-room-list {
  --room-row-h: clamp(46px, 9.3vh, 56px);
  --room-head-h: clamp(14px, 2.6vh, 20px);
  display: flex;
  flex-direction: column;
  gap: clamp(4px, 0.7vh, 6px);
  flex: 0 1 auto;
  /* §57.63 — TINGGI MENGIKUTI ISI, dibatasi dari atas. Diminta langsung
     ("panjang panelnya dikurangi agar tidak terkesan ada bagian yang
     kosong").

     Sebelumnya `height: clamp(214px, 34vh, 244px)` — tinggi PASTI, apa pun
     isinya. Terukur di 1280x720: dengan dua room, daftar setinggi 244 px
     memuat isi setinggi 244 px… tapi dengan NOL room ia tetap 244 px, dan
     panel JOIN THE WAR terbuka sebagai kotak 407 px yang sebagian besarnya
     bidang kosong. Itulah "bagian yang kosong" itu.

     `max-height` menggantikan `height`: daftar pendek setinggi isinya, daftar
     panjang berhenti di batas yang sama seperti dulu lalu menggulir — jadi
     yang berubah cuma keadaan yang selama ini salah, dan keadaan yang sudah
     benar (banyak room) tidak tersentuh sama sekali. `flex: 0 1 auto` supaya
     ia masih boleh menyusut di layar pendek. */
  /* Batasnya dihitung dari EMPAT BARIS UTUH plus kepala tabel dan celahnya,
     bukan dari angka piksel bulat. Sebabnya terukur: `clamp(214px, 34vh,
     244px)` mendarat di 244 px, dan 244 px jatuh persis di TENGAH baris
     keempat — barisnya terpotong mendatar di tepi bawah daftar, yang terbaca
     sebagai cacat gambar alih-alih sebagai daftar yang bisa digulir.

     Disusun dari peubah yang sama yang menentukan tinggi barisnya sendiri
     (`--room-row-h`, `--room-head-h`), jadi ia tidak bisa menyimpang pada
     hari salah satu angka itu disetel. */
  max-height: calc(var(--room-head-h) + var(--room-row-h) * 4
                   + clamp(4px, 0.7vh, 6px) * 4);
  min-height: 0;
  overflow-y: auto;
  padding-right: 2px;
}

.kustom-room-head,
.kustom-room-row {
  display: grid;
  grid-template-columns: 24px 76px minmax(70px, 1fr) 72px 82px 86px 78px;
  align-items: center;
  gap: clamp(5px, 0.9vw, 8px);
}

.kustom-room-head {
  /* §57.64 — LENGKET DI PUNCAK DAFTAR, diminta langsung.
     Baris ini anak dari `.kustom-room-list` yang `overflow-y: auto`, jadi
     tanpa `sticky` ia tergulir keluar bersama isinya: begitu pemain menggulir
     ke room kelima, kolom NO/CODE/USER/MAP/WARBANDS/MEMBERS tidak ada lagi di
     layar dan keenam angka di tiap baris kehilangan namanya.

     Butuh latar SENDIRI (daftarnya sendiri tembus pandang di atas kartu), dan
     `z-index` supaya baris yang lewat di bawahnya tidak menimpa — baris punya
     latar `#eef1f6` sendiri, dan tanpa penumpukan yang tegas urutannya
     ditentukan urutan dokumen, yang justru menaruh baris DI ATAS kepala.
     Sisipan bawah + celah negatif menutup jarak yang tadinya dikerjakan `gap`
     induk, supaya baris pertama tidak mengintip di bawah kepala. */
  position: sticky;
  top: 0;
  z-index: 2;
  height: var(--room-head-h);
  /* Sisipan tegak MENUTUP CELAH `gap` induk. Tanpa ini, baris yang lewat di
     bawah kepala mengintip di jalur setinggi `gap` (4-6 px) antara dasar
     kepala dan baris berikutnya — terlihat di tangkapan layar sebagai
     potongan baris yang melayang menempel di bawah nama kolom. Sisipannya
     dibuat dari peubah `gap` yang sama, jadi keduanya tidak bisa menyimpang. */
  padding: 0 clamp(7px, 1.4vw, 11px) clamp(4px, 0.7vh, 6px);
  box-sizing: content-box;
  background: var(--kartu, #e7ebf3);
  color: #6b7590;
  font-size: clamp(8.5px, 1.55vh, 10.5px);
  font-weight: 900;
  letter-spacing: var(--lc-kapital);
}

.kustom-room-row {
  min-height: var(--room-row-h);
  padding: 0 clamp(7px, 1.4vw, 11px);
  border: 3px solid var(--garis);
  border-radius: clamp(8px, 1.6vh, 13px);
  background: #eef1f6;
  color: #1b2030;
  font-size: clamp(11.5px, 2.2vh, 15px);
  font-weight: 900;
}
.kustom-room-row span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1;
  align-self: center;
}
.kustom-room-row .no {
  text-align: center;
  color: #6b7590;
  font-variant-numeric: tabular-nums;
}
.kustom-room-row .kode {
  color: #17233a;
  letter-spacing: 0.7px;
  font-variant-numeric: tabular-nums;
}
.kustom-room-row .host { color: #17233a; }
.kustom-room-row .tbl {
  align-self: center;
  height: calc(var(--room-row-h) - 14px);
  padding: 0 6px;
  font-size: clamp(11px, 2.1vh, 14px);
  font-weight: 900;
}

.kustom-room-kosong {
  padding: clamp(12px, 2.5vh, 18px);
  border: 3px dashed rgba(16, 20, 28, 0.28);
  border-radius: clamp(8px, 1.6vh, 13px);
  background: #eef1f6;
  color: #6b7590;
  text-align: center;
  font-size: clamp(11px, 2vh, 14px);
  font-weight: 900;
  letter-spacing: var(--lc-kapital);
}

@media (max-width: 680px) {
  .kustom-room-head,
  .kustom-room-row {
    grid-template-columns: 22px 68px minmax(58px, 1fr) 62px 68px 70px 68px;
    gap: 4px;
  }
  .kustom-room-head { font-size: 7.8px; }
  .kustom-room-row { font-size: 10.5px; }
  .kustom-room-row .tbl { font-size: 10.5px; }
}

/* ============================================================================
   PANEL HASIL TURNAMEN (§57.18)
   ============================================================================ */

/* `.tirai` bawaan dirancang untuk hidup DI DALAM `#hud` — ia `position:
   absolute` dengan `z-index: 5`, dan kedua angka itu benar selama induknya
   memang lapisan pertandingan yang menutupi layar. Panel turnamen berdiri
   langsung di bawah `body` supaya bisa terbit di atas menu MAUPUN di atas
   pertandingan (lihat catatan di index.html), jadi keduanya harus disetel
   ulang: `fixed` supaya acuannya jendela dan bukan tinggi body, dan lapisan
   yang benar-benar di atas `#menu`.

   Terukur sebelum diperbaiki: panel hasil tergambar DI BELAKANG kartu lobi —
   `z-index: 5` kalah dari menu, dan yang terlihat cuma potongan papan yang
   menyembul di kiri kartu. */
.tur-tirai {
  position: fixed;
  z-index: 50;
}

/* Lebarnya DIPERSEMPIT dari 560 px. Panel Small cuma berisi dua baris, dan dua
   baris selebar 560 px meninggalkan pita kosong sepanjang nama bangsa di kedua
   sisinya — persis keluhan "terlalu memanjang". Sekarang lebarnya mengikuti
   jumlah lajur papannya: satu lajur cukup 460 px, dua lajur (Large) baru
   melebar. */
.kotak.lebar.tur-hasil-kotak {
  width: min(460px, 94vw);
  gap: clamp(6px, 1.4vh, 11px);
  text-align: left;
}
/* JARAK KHUSUS DI DUA SAMBUNGAN (§57.42.7), bukan `gap` panel yang dinaikkan
   rata. Panel ini punya tiga bagian dengan derajat berbeda — kepala, papan,
   kaki — dan yang diminta terlihat adalah PEMISAHAN ketiganya, bukan panel
   yang seluruh isinya renggang. Kalau `gap`-nya sendiri yang dinaikkan, jarak
   antar-BARIS peserta di dalam papan ikut melebar dan papannya pecah jadi
   daftar yang mengambang.

   Karena `.kotak` memakai flex-gap, sisipan di bawah ini BERTUMPUK di atas
   gap-nya — itulah yang membuat kedua sambungan ini satu tingkat lebih jauh
   daripada jarak di dalam tiap bagian. */
.tur-hasil-kotak .tur-kepala { margin-bottom: clamp(4px, 1.2vh, 10px); }
.tur-hasil-kotak .hasil-papan { margin-bottom: clamp(3px, 1vh, 8px); }
.kotak.lebar.tur-hasil-kotak.banyak { width: min(800px, 94vw); }

/* ---- kepala panel: keping kesiapan MENGAMBANG di pojok, judul DI TENGAH ---
   Kepingnya `position: absolute` alih-alih ikut alur — dua baris (keping lalu
   judul di bawahnya) membuat kepala panel lebih tinggi dari perlu dan judulnya
   turun terlalu jauh dari tepi atas panel. Mengambang di atas judul, tingginya
   kembali SATU baris seperti sebelum kepala panel dipecah dua.

   `.tur-kepala-teks` diberi sisipan kiri-kanan supaya judul tetap di tengah
   PANEL, bukan di tengah sisa ruang sesudah keping — sisipannya SIMETRIS jadi
   pusatnya tidak bergeser, cuma lebarnya yang berkurang sedikit. */
.tur-kepala {
  position: relative;
}
.tur-kepala-teks {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  /* DIPERSEMPIT dari 40-60 px (§57.42.7). Sisipan simetris ini ada supaya
     judul tetap di tengah PANEL walau keping kesiapan mengambang di pojok
     kanan — tapi ia memakan 120 px dari panel selebar 460 px, dan sesudah
     judulnya dibesarkan "CHAMPIONSHIP ROUND" patah dua baris karena sisipan
     ini, bukan karena panelnya sempit. Kepingnya sendiri cuma ±34 px. */
  padding: 0 clamp(26px, 5vw, 38px);
}
/* Judul panel turnamen tetap lebih kecil dari judul kartu hasil Quick Match
   (30-46 px) — di sana judulnya satu kata ("MENANG") dan memang satu-satunya
   yang dibaca pada detik pertama; di sini ia kalimat tiga kata yang harus
   berbagi baris dengan penghitung kesiapan.

   TAPI DINAIKKAN dari 17-25 px ke 22-33 px (§57.42.7). Angka lama disetel
   waktu tombol kaki panel masih sekelas tombol dialog kecil; sesudah ketiganya
   dibesarkan, judul 25 px berdiri di atas baris tombol yang hampir sebesar
   dirinya sendiri, dan panel jadi kehilangan urutan bacanya. Yang dijaga
   bukan angkanya melainkan JARAK antara judul dan tombol — judul harus tetap
   jelas yang paling besar di panel. */
.tur-hasil-kotak .hasil-judul {
  font-size: clamp(19px, 3.8vh, 27px);
  letter-spacing: 1.2px;
  line-height: 1.1;
  text-align: center;
  text-shadow:
    -1.5px -1.5px 0 var(--garis), 1.5px -1.5px 0 var(--garis),
    -1.5px 1.5px 0 var(--garis), 1.5px 1.5px 0 var(--garis);
  color: #fff;
}
.tur-hasil-kotak .hasil-judul.seri { color: #c3ccdb; }
.tur-hasil-kotak .hasil-judul.menang { color: var(--kuning); }
/* Teks DAN ikon cuaca berdampingan sebagai satu keping tengah — `.tur-ikon`
   dipakai apa adanya (lingkaran bergaris tepi berwarna per-cuaca), cuma
   diperkecil di sini supaya sepadan dengan huruf 9.5-11.5 px di sebelahnya. */
.tur-hasil-kotak .hasil-sebab {
  margin-top: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  /* Dinaikkan dari 9,5-11,5 px (§57.42.7) bersama judulnya. Pada ukuran lama
     ia sudah lebih kecil daripada teks di dalam kepala tabel di bawahnya —
     jadi baris yang seharusnya menjelaskan panel justru jadi tulisan terkecil
     di seluruh panel. */
  font-size: clamp(11.5px, 2.2vh, 14px);
  text-align: center;
}
.tur-hasil-kotak .hasil-sebab[hidden] { display: none; }
.tur-hasil-kotak .hasil-sebab .tur-ikon {
  width: clamp(13px, 2.2vh, 16px);
  height: clamp(13px, 2.2vh, 16px);
  padding: 1.5px;
  border-width: 1.5px;
}
/* Penghitung kesiapan MENGAMBANG di pojok kanan atas panel, SEBARIS dengan
   judul (lihat `.tur-kepala` di atas) — keping, bukan tulisan telanjang. Ia
   satu-satunya angka di kepala panel, dan tulisan kelabu kecil yang berdiri
   sendirian bergaris tepi tebal terbaca seperti sisa tata letak, bukan
   seperti kabar. Sengaja "2/4" TANPA kata "siap": kata itu sudah ada di
   tombol SIAP di kaki panel, dan keping ini cuma kabar sampingan yang
   seharusnya sekilas dibaca, bukan dieja. */
.tur-siap-hitung {
  position: absolute;
  top: 0;
  right: 0;
  padding: clamp(3px, 0.7vh, 5px) clamp(7px, 1.4vw, 11px);
  border: 2px solid var(--garis);
  border-radius: 999px;
  background: #eef1f6;
  font-size: clamp(8.5px, 1.6vh, 10.5px);
  font-weight: 900;
  letter-spacing: 0.6px;
  color: #5b667e;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ---- papan: kolom yang berbeda dari Quick Match --------------------------
   Lima kolom di hasil babak (peringkat, warna, bangsa, BABAK, TOTAL), lima di
   panel juara (peringkat, warna, bangsa, TOTAL, HADIAH). Kolom ORANG yang ada
   di Quick Match TIDAK ADA di keduanya: §56.2 memutuskan prajurit hidup tidak
   menentukan apa pun di turnamen, dan kolom yang tidak menentukan apa pun cuma
   memancing pertanyaan ("kenapa yang orangnya lebih banyak ada di bawah?")
   yang aturannya tidak lagi jawab.

   Kolom panah naik/turun DIBUANG pula. Ia enak dilihat di layar lebar, tapi ia
   kolom keenam pada baris yang sudah padat — dan yang dikorbankannya lebar
   nama bangsa, satu-satunya kolom yang isinya tidak bisa dipendekkan. */
/* LIMA kolom: NO, WARBAND+USER, ROUND, ALIVE, TOTAL
   (§57.42.6, dirapatkan jadi lima di §57.43.8). Titik warna yang dulu jadi
   kolom kedua sudah masuk ke dalam kolom WARBAND sebagai panji, dan nama ORANG
   berdiri di bawah nama BANGSA di dalam sel yang sama — dua kabar yang dulu
   berdesakan di satu baris, dan yang satu (bangsanya) bahkan tidak pernah
   tertulis sama sekali.

   ALIVE JADI KOLOMNYA SENDIRI. Sebelumnya ia angka kecil yang DITEMPELKAN di
   dalam keping TOTAL ("⚑1 2"), dan bentuk itu membuat dua besaran yang sama
   sekali berbeda terbaca sebagai satu skor gabungan — persis kebalikan dari
   yang diaturannya katakan (§56.2/§57.41.6: bendera SELALU dibandingkan lebih
   dulu, selamat cuma memutus seri di antara bendera yang sudah sama persis).
   Berdiri di kolom sendiri, keduanya bisa dibaca dan dijumlahkan sendiri-
   sendiri, dan kepala kolom di atasnya menamai keduanya.

   LIMA KOLOM SEJAK §57.43.8, bukan enam: WARBAND dan USER dirapatkan jadi satu
   sel yang isinya bertumpuk (`.hasil-baris .siapa` di css/style.css). Kolom
   USER yang dulu berdiri sendiri berlebar tetap 44 px, dan username sepuluh
   huruf meluber melewatinya lalu menabrak kolom angka di sebelahnya. */
.tur-tabel .hasil-baris,
.tur-tabel .hasil-kepala {
  grid-template-columns: 18px minmax(0, 1fr) 38px 40px 48px;
}
.juara .tur-tabel .hasil-baris,
.juara .tur-tabel .hasil-kepala {
  grid-template-columns: 18px minmax(0, 1fr) 40px 48px 58px;
}

/* Keping TOTAL — bentuk yang sama persis dengan keping bendera Quick Match
   (`.hasil-baris .bd`), termasuk pencabutan garis tepi hitamnya (§57.40). Ia
   yang menentukan peringkat, jadi ia satu-satunya yang diberi warna; kolom
   ROUND di sebelahnya sengaja dibiarkan angka telanjang. */
.tur-tabel .tot {
  padding: 2px 0;
  border-radius: 5px;
  background: #ffcf3f;
  color: var(--garis);
  font-weight: 900;
}
/* Angka babak ini: redup, karena ia yang PALING cepat basi — begitu babak
   berikutnya jalan, yang tersisa maknanya cuma TOTAL. */
.tur-tabel .bbk { color: #6b7590; }

/* ALIVE sebagai KOLOM SENDIRI (§57.42.6), bukan lagi angka tempelan di dalam
   keping TOTAL. Angka telanjang tanpa keping, sama dengan kolom ROUND: yang
   berhak berkeping cuma besaran yang MENENTUKAN peringkat, dan jumlah selamat
   tidak pernah bisa mengalahkan bendera — ia cuma memutus seri di antara
   bendera yang sudah sama persis. Bentuk yang berbeda itulah yang menyatakan
   perbedaan derajat itu tanpa satu kata penjelas pun.

   SELALU tertulis, tidak lagi cuma waktu ada seri. Kolom yang isinya kadang
   ada kadang tidak membuat pemain mengira angkanya hilang, bukan mengira
   aturannya sedang tidak berlaku. */
.tur-tabel .slmt {
  font-style: normal;
  font-weight: 800;
  color: #6b7590;
}
/* Yang benderanya SERI dengan baris lain: di sinilah kolom ini benar-benar
   memutuskan sesuatu, jadi di sinilah — dan cuma di sini — ia diberi warna. */
.tur-tabel .slmt.penentu { color: #1b2030; font-weight: 900; }

/* REWARD tanpa keping — sama dengan `.hasil-baris .hdh` di css/style.css, dan
   dengan alasan yang sama: sesudah barisnya kehilangan bingkai, keping di
   dalam kolom yang sudah bernama cuma menambah bingkai di dalam bingkai. */
.tur-tabel .hdh {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: #1b2030;
}
.tur-tabel .hdh svg { width: 11px; height: 11px; flex-shrink: 0; }
/* Slot AI dari awal dan slot AFK: tanda pisah, tanpa pil. Kotak berwarna
   berisi "—" akan terbaca seperti hadiah bernilai nol yang tetap diberikan;
   yang benar adalah tidak ada penerima sama sekali (§57.13, §57.1). */
.tur-tabel .hdh.nihil {
  border: none;
  background: none;
  color: #a8b0c2;
}
/* Nama yang ditandai AFK di papan. Tandanya ikut ke sini supaya papan hasil
   dan daftar lobi menyebut hal yang sama dengan cara yang sama. Ia menempel
   pada USER sekarang, bukan pada nama bangsa: yang AFK orangnya. */
.tur-tabel .us small {
  margin-left: 4px;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.5px;
  color: #c0392b;
}

/* ---- podium DICABUT (§57.44.4) -------------------------------------------
   Tiga baris teratas dulu diberi emas/perak/perunggu, dan baris pemain
   ditandai cuma lewat warna namanya. Susunan itu terbalik: papan ini SUDAH
   terurut menurun, jadi logam mewarnai ulang kabar yang sudah disampaikan
   posisi barisnya sendiri — sementara satu-satunya kabar yang tidak bisa
   dibaca dari urutan, "yang mana aku", justru jadi paling sulit dilihat karena
   tiga baris di atasnya berwarna lebih kuat.

   Sekarang SATU-SATUNYA baris berwarna adalah baris pemain, dan aturannya
   ditulis sekali di css/style.css (`§57.44.4`) supaya papan Quick Match dan
   papan turnamen mustahil menyimpang. Kelas `emas`/`perak`/`perunggu` sudah
   tidak pernah ditulis js/turnamen.js lagi, jadi aturannya dihapus di sini
   alih-alih dibiarkan menganggur menunggu ditulis ulang tanpa sengaja. */

/* ---- kaki panel: KELUAR/KEMBALI kiri, DETAIL tengah, SIAP/lanjut kanan ---
   Lebar sama rata (`flex: 1 1 0`), pola yang sama dengan `.hasil-nav` Quick
   Match: ketengahan tombol tengah sifat susunannya sendiri, bukan angka yang
   dihitung, dan tetap benar walau DETAIL disembunyikan (Small, Medium) —
   dua tombol yang tersisa otomatis membagi baris jadi dua, bukan tiga. */
/* Sama dengan `.hasil-aksi` di css/style.css: kaki panel satu tingkat lebih
   jauh dari papannya daripada jarak bagian lain, supaya panelnya terbaca
   sebagai judul / papan / kaki dan bukan satu tumpukan berjarak rata. */
/* DI TENGAH, bukan `space-between` (§57.43.9). Yang lama memaku tombol terluar
   ke tepi panel, jadi jarak antar-tombol diputuskan lebar PANEL — terukur di
   panel juara 412 px berisi dua tombol 168 px: celah di tengahnya 84 px, dan
   yang terlihat bukan sepasang tombol melainkan dua tombol yang tidak saling
   berhubungan. Lebarnya sendiri diurus `.hasil-nav, .tur-nav .tbl` di
   css/style.css, satu aturan untuk kedua panel. */
.tur-nav {
  margin-top: clamp(2px, 0.9vh, 7px);
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: clamp(5px, 1vw, 9px);
}
.tur-nav[hidden] { display: none; }
/* Sisipan kiri-kanan DIPERSEMPIT dari bawaan `.tbl` (14px): tiga tombol
   sama lebar di panel 460 px cuma dapat ±133 px masing-masing, dan pada
   lebar itu "MAIN LAGI ♦80" cuma muat satu baris kalau sisipannya dikecilkan
   — terukur, bukan ditaksir (lihat §57.23.11 GDD).

   Sisipan TEGAK-nya justru dinaikkan (10 → 13 px) bersama ukuran hurufnya
   (§57.42.7): yang harus disesuaikan dengan judul yang membesar adalah
   TINGGI tombol, dan tinggi tombol datang dari sisipan tegak — bukan dari
   sisipan mendatar yang justru harus tetap sempit demi label terpanjangnya. */
/* DICABUT di §57.43.9 dan digantikan `.hasil-nav, .tur-nav .tbl` di
   css/style.css, yang memberi ketiganya lebar dasar yang SAMA lalu memusatkan
   gugusnya. `flex: 1 1 0` di sini melakukan kebalikannya: ia menyuruh tiap
   tombol memakan sepertiga baris, jadi lebarnya diputuskan lebar PANEL — dan
   di panel dua-lajur ketiganya melar sampai 203 px sambil meninggalkan lubang
   di tengah. Sisipan tegak 13 px dan huruf 14 px yang disetel §57.42.7 tetap
   dipegang, cuma pindah ke aturan bersama itu.

   Aturan ini sengaja TIDAK dihapus melainkan dikosongkan isinya jadi catatan:
   berkas ini dimuat SESUDAH css/style.css, jadi apa pun yang ditulis di sini
   menang — dan yang berikutnya menambahkan aturan `.tur-nav .tbl` di sini
   perlu tahu bahwa ia sedang menimpa keputusan yang sudah diambil. */
/* §57.64 — KETIGANYA SAMA PANJANG, mengikuti YANG TERPANJANG. Diminta
   langsung ("kamu ambil tombol yang terpanjang sebagai acuan panjang").

   `flex-basis: auto` + `flex-grow: 1` yang dipakai `.hasil-nav` di
   css/style.css TIDAK cukup di sini: ia memberi tiap tombol lebar LABELNYA
   lalu membagi sisa ruang merata DI ATAS dasar yang berbeda-beda, jadi yang
   berlabel panjang tetap berakhir lebih lebar. Itu memang yang diminta di
   sana (§57.63, supaya "SAVE STREAK" tidak pecah dua baris) dan justru
   kebalikan dari yang diminta di sini.

   `flex-basis: 0` menyamakan titik tolaknya, sehingga sisa ruang dibagi rata
   dan ketiganya berakhir persis sama lebar.

   `min-width: max-content` SEMPAT DIPAKAI di sini dan justru MEMBATALKAN
   penyamaan itu — terukur: LEAVE 123, PLAYERS DETAIL 152, PLAY AGAIN 171 px.
   Sebabnya lantai `max-content` berlaku PER TOMBOL, jadi tiap tombol berhenti
   di lebar labelnya masing-masing dan yang berlabel panjang tetap lebih
   lebar; yang diminta justru kebalikannya.

   `min-width: 0` menyamakan ketiganya (133 px) tapi menukar cacatnya dengan
   cacat kedua: "PLAY AGAIN ◇50" — label terpanjang — MELUBER keluar tombol
   133 px-nya, terlihat di tangkapan layar panel juara. Sama-panjang memang
   berarti "selebar yang terpanjang", dan tanpa satu pun lantai, flex bebas
   memangkas ketiganya di bawah lebar itu.

   Lantai BERSAMA setebal label terpanjang (176 px) juga salah, dan terukur
   kenapa: 176 x 3 + dua celah = 546 px di panel yang cuma ±460 px, jadi
   barisnya meluber dan tombol terluar terpotong di kedua tepi panel.

   Yang benar membiarkan LEBAR PANEL yang memutuskan: `flex: 1 1 0` menyamakan
   ketiganya di sepertiga baris (terukur 133 px di panel 460 px), dan yang
   mengalah untuk memuat label terpanjang adalah SISIPAN lalu UKURAN HURUFNYA.

   Ukuran hurufnya memang harus ikut mengalah, dan itu terukur: sesudah
   sisipan dipangkas 14 -> 10 px, ruang isi tiap tombol 106,7 px sementara
   "PLAY AGAIN ◇50" pada 14 px masih menuntut 144,5 px — kurang 37,8 px yang
   tidak mungkin ditutup sisipan berapa pun. Tiga tombol sama panjang di panel
   selebar ini hanya bisa memuat label terpanjangnya pada huruf yang lebih
   kecil; itu bukan kompromi melainkan aritmetika.

   `min(1.9vh, 1.05vw)` membuatnya menyusut mengikuti LEBAR juga, bukan cuma
   tinggi — panel ini melebar di layar besar dan menyempit di HP, dan yang
   menentukan muat-tidaknya label memang lebar. Batas atas 14 px menjaga agar
   di layar lebar ukurannya tidak berubah dari sebelumnya.

   `white-space: nowrap` menutup sisanya, alasan yang sama dengan
   `.hasil-nav`: tanpa itu, tombol yang dipangkas di layar sempit memecah
   labelnya jadi dua baris di dalam kotaknya sendiri. */
.tur-nav .tbl {
  flex: 1 1 0;
  min-width: 0;
  padding-inline: clamp(5px, 0.9vw, 9px);
  font-size: clamp(8.5px, min(1.5vh, 0.82vw), 11px);
  white-space: nowrap;
}
.tur-nav .tbl b { font-variant-numeric: tabular-nums; }

/* §57.49  LAMBANG INTAN DI "PLAY AGAIN" DUDUK TERLALU TINGGI ---------------
   CACAT SUNGGUHAN, terukur: pusat ikon berdiri 4,38 px — 0,292em — DI ATAS
   pusat optik angka di sebelahnya pada 1280x720. Terlihat jelas: berlian
   melayang di dekat garis atas huruf sementara "50" duduk di garis dasarnya.

   Dua sebab menumpuk, dan keduanya masuk akal di tempat asalnya:

   1. `.tbl .ik-intan { transform: translateY(-0.1em) }` (css/style.css
      §57.45) mengangkatnya DENGAN SENGAJA. Koreksi itu ditulis untuk lambang
      yang berdiri di dalam wadah `inline-flex` (`.hrg`, `.tbl-besar`), tempat
      flex sudah memusatkannya lebih dulu dan yang tersisa cuma penghalusan.
   2. `.tbl` sendiri BUKAN flex — ia `line-height: 1` biasa, jadi ikon
      dijajarkan sebagai gambar sebaris terhadap GARIS DASAR. Di sana
      `translateY` bukan lagi penghalusan; ia geseran mentah yang menumpuk di
      atas ikon yang memang sudah lebih tinggi (1,05em) daripada angka yang
      didampinginya (tinggi angka cuma ±0,73em).

   Yang diperbaiki SEBABNYA, bukan gejalanya: tombol berharga dijadikan
   `inline-flex` yang memusatkan isinya, lalu geseran §57.45 dimatikan DI
   DALAMNYA — bukan ditambahi angka ajaib ketiga yang harus disetel ulang tiap
   kali ukuran huruf tombol berubah. `align-items: center` memusatkan terhadap
   KOTAK BARIS, dan karena kotak baris angka dan ikon sekarang sama-sama
   dipusatkan flex, keduanya sejajar di ukuran huruf berapa pun.

   `gap` diberi 0 pada `<b>`-nya sendiri: kurungnya "(" dan ")" harus tetap
   merapat ke isinya — pelajaran §57.44.5, ketika `gap` di tombol UNLOCK
   membuatnya terbaca "UNLOCK ( 300 )".

   `display: flex`, BUKAN `inline-flex`: tombol-tombol ini anak dari
   `.tur-nav` yang membagi lebar lewat aturan bersama `.hasil-nav, .tur-nav
   .tbl` (§57.43.9). `inline-flex` membuat tombolnya menyusut ke lebar isinya
   dan "PLAY AGAIN" langsung patah dua baris — terlihat di tangkapan layar,
   tidak terlihat di angka mana pun. `white-space: nowrap` menjaga labelnya
   utuh kalau lebar yang dibagikan itu menyempit. */
.tur-nav .tbl {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.42em;
  white-space: nowrap;
}
.tur-nav .tbl b { display: inline-flex; align-items: center; gap: 0; }
.tur-nav .tbl .ik-intan { transform: none; vertical-align: 0; }
/* Sisa waktu di DALAM tombol SIAP, bukan kotak terpisah. §57.18: 15 detik itu
   jeda, bukan tenggat AFK — ia cuma memberi tahu kapan babak berikutnya mulai
   sendiri kalau tombol ini tidak ditekan. Kotak hitung mundur yang berdiri
   sendiri akan terbaca seperti ancaman; angka di dalam tombolnya terbaca
   sebagai keterangan tombol itu. */
.tur-b-siap b {
  margin-left: 5px;
  opacity: 0.75;
}
/* Sesudah ditekan: tombolnya padam jadi "MENUNGGU", karena yang ditunggu bukan
   lagi pemain ini. */
.tur-b-siap.sudah {
  background: #d7dded;
  color: #6b7590;
  cursor: default;
}
/* Lambang intan di dalam tombol MAIN LAGI. */
.tur-nav .tbl svg {
  width: 12px;
  height: 12px;
  vertical-align: -2px;
  margin-right: 2px;
}

/* §57.68: BLOK ALAT PRATINJAU DICABUT, diminta langsung. Aturannya sengaja
   tidak memakai satu pun peubah atau kelas milik permainan sejak awal, jadi
   pencabutannya tidak menyeret apa pun. Pasangannya sudah ikut dibuang:
   `#prat-bilah` di index.html dan `pasangPratinjau()` di js/turnamen.js. */
/* ---- HP mendatar pendek --------------------------------------------------
   `.kotak` sudah dibatasi `max-height: calc(100dvh - 24px)` dan boleh digulir,
   jadi panel yang kepanjangan TIDAK meluber ke luar layar — ia menggulir. Itu
   justru yang harus dicegah: kartu hasil yang barisnya harus digulir untuk
   dilihat adalah cacat yang sama yang sudah dicatat berkali-kali di
   css/style.css. */
@media (max-height: 470px) {
  .tur-hasil-kotak .hasil-judul { font-size: clamp(15px, 3.4vh, 21px); }
  .hasil-nav .tbl,
  .tur-nav .tbl { padding: 8px 4px; font-size: 12.5px; }

  /* Kartu peta dirampingkan. Terukur sebelum blok ini: pada 892x412, deret
     kartu peta meluber 7 px keluar `.layar-isi` dan jarak ke judul layar
     tersisa 14 px — dua gejala dari satu sebab, karena `.layar-isi.tunggal`
     memusatkan isinya dan yang kelebihan tinggi memakan jarak itu dari kedua
     ujungnya sekaligus.

     Yang dipotong RUANG, bukan isi: lingkaran ikon mengecil, sisipan merapat,
     tapi keempat ikon cuaca, ketiga ikon rintangan, dan tombol kakinya semua
     tetap berdiri. Membuang salah satunya akan menghemat lebih banyak dan
     sekaligus menghapus alasan kartu itu ada. */
  .tur-kartu { gap: clamp(4px, 0.9vh, 7px); padding: clamp(5px, 1.2vh, 9px); }
  .tur-sel { gap: clamp(4px, 1vh, 8px); }
  .tur-stat { padding: clamp(3px, 0.8vh, 6px) clamp(5px, 1vw, 8px); }
  .tur-ikon { width: clamp(17px, 3vh, 21px); height: clamp(17px, 3vh, 21px); }
  .tur-lencana-ikon .tur-ikon { width: clamp(21px, 3.6vh, 26px); height: clamp(21px, 3.6vh, 26px); }
  .tur-masuk,
  .tur-pilih { padding: clamp(5px, 1.2vh, 9px) clamp(12px, 2.4vw, 20px); }

  /* Tabel peserta dirampingkan. Terukur pada susunan kotak yang mendahuluinya:
     di 640x360 dengan Large (delapan peserta), baris terbawah terpotong dan
     hanya bisa dilihat dengan menggulir — sebagian peserta tidak terlihat di
     layar yang justru gunanya memperlihatkan siapa saja pesertanya.

     Yang dipotong RUANG, bukan isi: sisipan merapat dan benderanya mengecil,
     tapi username, nama bangsa, dan tanda statusnya semua tetap berdiri.
     Membuang salah satunya akan menghemat lebih banyak dan sekaligus menghapus
     alasan baris itu ada. */
  .tur-p { padding: 3px clamp(5px, 1vw, 8px); gap: clamp(5px, 1vw, 8px); }
  .tur-p-panji { width: clamp(30px, 5.6vh, 38px); }
  .tur-p-nama { font-size: clamp(10px, 2vh, 13px); }
  .tur-tanda { padding: 0 4px; }
  /* §57.49: token tinggi baris IKUT DIPADATKAN di sini. Blok ini mengecilkan
     bendera (`clamp(30px, 5.6vh, 38px)`) dan merapatkan sisipan `.tur-p` jadi
     3 px, jadi baris pemain menyusut — tapi `--baris-lobi` dihitung dari
     angka versi LEBAR dan tidak ikut menyusut. Terukur di 640x360: baris
     pemain 32 px sementara baris judul dan kaki tetap 39,3 px, yaitu
     kesejajaran yang baru saja dipasang lepas lagi justru di layar yang
     paling sempit. Rumusnya sama persis, angkanya yang mengikuti blok ini. */
  .tur-lobi-kepala,
  .tur-kaki {
    --baris-lobi: calc(clamp(30px, 5.6vh, 38px) * 2 / 3 + 2 * 3px + 6px);
  }
  .tur-kumpul { padding: 3px 8px; font-size: clamp(11px, 2.4vh, 14px); }
  .tur-fakta { padding: 3px 0; }
  .tur-kaki { padding-top: 3px; }

  /* §57.50: aturan pembungkus `.kustom-room` yang dulu ada di sini SUDAH
     DIBUANG. Isinya solusi lama untuk kaki yang kekurangan 30 px di
     640x360: JOIN WAR diturunkan ke barisnya sendiri di dalam blok room.
     Solusi itu memang memisahkan kedua tombol yang tadinya saling menimpa,
     tapi menyisakan cacat yang cuma terlihat sesudah diukur ulang — JOIN
     yang turun baris terukur setinggi 16,5 px, kurang dari setengah tinggi
     kode room (31 px) dan START (32 px) di sebelahnya, karena sebagai
     satu-satunya isi baris kedua ia tidak punya saudara yang meregangkannya.

     Pemilik proyek meminta ketiga kotak itu justru SEBARIS dan setinggi
     satu sama lain, jadi yang mengalah sekarang keterangan "WAITING (n/n)"
     di kiri (lihat `flex-wrap` pada `.kustom-kaki`). Ruangnya tetap kurang
     — aritmetikanya tidak berubah — yang berubah adalah SIAPA yang turun
     baris, dan sebaris tulisan tanpa kotak turun baris tanpa berubah
     bentuk sedikit pun. */
  .tur-daftar { gap: 3px; }
  .tur-daftar-lajur { gap: 3px; }

  /* §57.60: kaki lobi custom sekarang TIDAK BOLEH membungkus (keempat
     bendanya diminta sebaris), jadi ruang yang kurang di layar tersempit
     harus dibayar dengan mengecil, bukan dengan turun baris. Terukur di
     640x360 sesudah `flex-wrap: nowrap` dipasang: START luber 38 px keluar
     dari kaki.

     Yang dipangkas di sini batas-batas bawah yang di layar lebar memang
     tidak pernah tercapai — jadi 1280 dan 900 tidak berubah sedikit pun
     (diverifikasi: 130 px dan 122 px, sama seperti sebelum blok ini ada).
     Urutan mengalahnya tetap seperti yang ditetapkan §57.49: keterangan
     lebih dulu, lalu kode room, dan START tidak pernah kehilangan labelnya. */
  /* §57.70 — seluruh pemendekan kode/JOIN di blok layar-pendek ini DICABUT,
     diminta langsung ("kotak kode dan tombol join war diperpanjang").
     Angka-angka di sini (78/80px kode, 76/70px JOIN, huruf 7,5-11px) semua
     dihitung waktu kotak dasarnya jauh lebih sempit dan hurufnya boleh
     mengecil sendiri lewat clamp — begitu aturan dasar dilebarkan ke
     ±168px/±196px dan hurufnya dikunci ke `var(--fs-label)` penuh, blok
     override ini tinggal MENGECILKAN KEMBALI apa yang baru saja dilebarkan,
     persis di layar pendek (≤470px tinggi) tempat perbaikan itu paling
     dibutuhkan. `gap: 4px` dipertahankan (masih hemat ruang tanpa memangkas
     kotak), tapi lebar/huruf kode & JOIN sekarang mengikuti aturan dasar
     sepenuhnya, sama seperti di layar tinggi. */
  .kustom-kaki { gap: 4px; }
  .kustom-room { gap: 4px; }
  /* §57.70 — SELURUH override huruf/lebar kode & JOIN di blok layar-pendek
     ini DICABUT (font-size 7,5px kode; flex-basis/min-width/font-size 76-
     70px/11px JOIN). Riwayat §57.64/§57.65/§57.68 di atas menjelaskan
     kenapa angka-angka itu tadinya perlu — kotak dasarnya waktu itu memang
     terlalu sempit untuk huruf token penuh di layar pendek. Sekarang aturan
     dasar `.kustom-room-kode`/`.kustom-room > .tbl` sudah dilebarkan
     (min-width 112px/76px) tepat supaya `var(--fs-label)` muat tanpa syarat
     khusus di lebar berapa pun — jadi blok override ini tidak lagi
     dibutuhkan, dan MEMPERTAHANKANNYA berarti mengecilkan kembali diam-diam
     apa yang baru saja diperpanjang, persis di layar pendek. Kode & JOIN
     sekarang memakai huruf dan lebar aturan dasar di semua tinggi layar. */
  .kustom-ikon { width: 20px; height: 20px; }
  /* Keterangan "Waiting (n/n)" DISAMAKAN dengan `.tur-status` lobi kompetisi
     (11,5 px), diminta langsung. Terukur 8,6 px sebelum ini. */
  .kustom-kaki .tur-status { font-size: 11.5px; min-width: 44px; }
}
@media (max-height: 400px) {
  .kotak.lebar.tur-hasil-kotak { gap: 5px; }
}

/* §57.71 — kaki lobi custom (kode room + JOIN WAR + START) MENGECIL di layar
   yang lebarnya sendiri sempit, bukan cuma yang tingginya pendek (breakpoint
   `max-height: 470px` di atas tidak cukup: dilaporkan dan diukur langsung,
   panel di layar ~568px lebar x 320px tinggi — TIDAK masuk breakpoint tinggi
   manapun kalau tingginya justru di atas 470 — tetap tumpang tindih).

   DITULIS DI SINI, SETELAH `@media (max-height: 470px)` di atas — bukan di
   dekat definisi dasarnya seperti percobaan pertama — dan itu BUKAN pilihan
   kerapian: `@media (max-height: 470px)` berisi `.kustom-kaki .tur-status {
   font-size: 11.5px; min-width: 44px; }` yang berkekhususan SAMA PERSIS
   dengan aturan blok ini, dan pada viewport yang memenuhi KEDUA kondisi
   (mis. 480x270 — lebar <640px DAN tinggi <470px), yang ditulis lebih
   belakang di file yang menang, TERLEPAS media query mana yang "lebih
   spesifik". Percobaan pertama menaruh blok ini SEBELUM baris 2231 lama
   dan seluruh override `.tur-status` di sini kalah total — kekacauan yang
   sama dengan [[reference_aturan_kembar_urutan]], kali ini antar dua
   `@media` berbeda kondisi, bukan dua aturan biasa.

   Kaki panel `.kustom-kaki` BUKAN selebar viewport — ia anak `.kolom-kanan`
   yang berbagi tempat dengan gambar karakter di kiri, terukur konsisten
   ~0,47x lebar viewport pada berbagai lebar (267,5/568=0,471; 480x=222,1/
   480=0,463; 414x=184,8/414=0,446).

   Diukur langsung sebelum perbaikan di 568x320: kaki panel 267,5 px, empat
   elemen (Waiting 55,8 + kode 108 + JOIN 80 + START 64 + 3 gap 12 = 319,8 px)
   menuntut 52,3 px LEBIH dari yang tersedia — kode room akhirnya berdiri
   MENIMPA keterangan "Waiting (n/n)" karena `.kustom-kaki .tur-status` sudah
   di batas bawahnya sendiri (§57.60) dan `.kustom-room` sudah berhenti
   tumbuh (§57.70), jadi tidak ada lagi yang bisa mengalah lewat lebar.

   Yang mengalah di sini HURUFNYA (dipilih langsung: "huruf kode/JOIN/START
   sedikit mengecil di layar tersempit saja"), DIKUNCI ke satu angka tetap
   (7px) bukan `clamp(vw)` — clamp berbasis vw membuat kebutuhan lebar teks
   dan `min-width` sama-sama bergerak, dan menghitung keduanya sekaligus
   supaya tetap cukup di semua titik ternyata salah kalkulasi (percobaan
   kedua menyisakan huruf terpotong diam-diam 15-28px, ketahuan cuma lewat
   `scrollWidth` vs `clientWidth`).

   Diukur di 414px lebar (breakpoint yang paling menekan): overhead kode
   (ikon salin + sisipan + garis) 38,6 px, "WWWWWW" pada 7 px = 39,8 px →
   kebutuhan 78,4 px, dibulatkan ke atas 84 px untuk sisa aman. Overhead
   JOIN 6 px, "JOIN WAR" pada 7 px = 49,5 px → kebutuhan 55,5 px, dibulatkan
   64 px. START selalu lebih pendek dari JOIN (satu kata vs dua), memakai
   `min-width` yang sama dengan JOIN aman tanpa terpotong. */
@media (max-width: 640px) {
  /* `gap` DIPERKETAT (4px bawaan -> 2px di kaki, 3px di dalam room). */
  .kustom-kaki { gap: 2px; }
  .kustom-room { gap: 3px; }
  /* `min-width` dihitung PAS dari kebutuhan sungguhan, bukan dibulatkan
     longgar: overhead kode (ikon salin+sisipan+garis, KONSTAN terlepas
     font-size) 38,6 px + "WWWWWW" pada 7px 39,8px = 78,4px, dibulatkan ke
     atas 79px. Overhead JOIN 6px + "JOIN WAR" pada 7px 49,5px = 55,5px,
     dibulatkan 56px. Diverifikasi lewat `scrollWidth` vs `clientWidth`
     langsung di browser, bukan dihitung tangan sampai akhir (lihat
     [[reference_ukur_bukan_taksir_ruang_isi]]) — dua percobaan pertama di
     breakpoint ini (84/64px lalu bulatan lain) meleset karena dibulatkan
     terlalu longgar ATAU ketat tanpa verifikasi ulang. */
  .kustom-room-kode { flex-basis: 79px; min-width: 79px; }
  .kustom-room-kode b { font-size: 7px; }
  .kustom-room > .tbl,
  .kustom-kaki .tur-b-mulai { flex-basis: 56px; min-width: 56px; font-size: 7px; }
  /* `.tur-status` menyerap SISA kekurangan (§57.60 sudah menetapkan ia yang
     mengalah lebih dulu): batas bawahnya diturunkan sampai selebar "..."
     elipsis minimal. */
  .kustom-kaki .tur-status { min-width: 24px; font-size: 9px; }
}

/* Breakpoint KEDUA untuk viewport yang bahkan lebih sempit: bahkan dengan
   angka pas di atas, total kebutuhan (status 24 + kode 79 + join 56 +
   start 56 + gap ±11 = 226 px) masih melebihi kaki panel di bawah ±540px
   (kaki 222 px di 480px lebar, 185 px di 414px lebar).

   Dua langkah dipakai bersamaan di sini, keduanya dihitung PAS lewat
   rasio linear font-size->lebar-teks yang sudah diukur (bukan ditaksir):
   (1) huruf kode/JOIN turun sekali lagi ke 6,5 px (kebutuhan kode 75,6px
   dibulatkan 76px, JOIN 52,0px dibulatkan 52px) — di bawah ini keterbacaan
   mulai dipertaruhkan, jadi 6,5 px dipatok sebagai batas akhir; (2)
   `.tur-status` diturunkan ke `min-width: 0` sepenuhnya, aman karena
   `text-overflow: ellipsis` (§57.60) memotongnya rapi, bukan merusak.

   Total sesudahnya: 0 + 76 + 52 + 52 + gap(1+2×2=5) = 185px, vs kaki
   184,8px di viewport 414px — pas dengan toleransi sub-piksel, dan lega
   37px di viewport 480px. */
@media (max-width: 540px) {
  .kustom-kaki .tur-status { min-width: 0; flex-shrink: 3; }
  .kustom-kaki { gap: 1px; }
  .kustom-room { gap: 2px; }
  .kustom-room-kode { flex-basis: 76px; min-width: 76px; }
  .kustom-room-kode b { font-size: 6.5px; }
  .kustom-room > .tbl,
  .kustom-kaki .tur-b-mulai { flex-basis: 52px; min-width: 52px; font-size: 6.5px; }
}

/* ======================================================================
   §57.44.4 — papan turnamen ikut enam kolom.

   DITULIS DI SINI, bukan di css/style.css, dan itu bukan pilihan gaya:
   berkas ini dimuat SESUDAH style.css, jadi `.tur-tabel .hasil-baris` di sini
   dan `.tur-tabel .hasil-baris` di sana berkekhususan sama persis dan yang
   belakangan menang. Terukur waktu aturannya sempat ditulis di style.css:
   kepala kolom menerima enam nama sementara kisinya masih lima lajur, dan
   nama keenam ("TOTAL"/"REWARD") turun ke baris kedua di dalam kepala.
   ====================================================================== */
.tur-tabel .hasil-baris,
.tur-tabel .hasil-kepala {
  grid-template-columns: 18px minmax(0, 1fr) minmax(0, 1fr) 38px 40px 48px;
}
.juara .tur-tabel .hasil-baris,
.juara .tur-tabel .hasil-kepala {
  grid-template-columns: 18px minmax(0, 1fr) minmax(0, 1fr) 40px 48px 58px;
}
/* Kolom ROUND dan ALIVE ikut hitam-tebal seperti seluruh isi tabel (§57.44.4).
   Kelabu #6b7590 yang dipakai sebelumnya adalah warna untuk keterangan
   sampingan, dan di papan hasil tidak ada satu pun kolom yang sampingan. */
.tur-tabel .bbk,
.tur-tabel .slmt,
.tur-tabel .slmt.penentu {
  color: #10141c;
  font-weight: 900;
  font-size: var(--tabel-fs);
}
.tur-tabel .us {
  color: #10141c;
  font-weight: 900;
  font-size: var(--tabel-fs);
  text-align: center;
}
.tur-tabel .hasil-baris.kamu .us,
.tur-tabel .hasil-baris.kamu .nm { color: #123a72; }
.tur-tabel .hdh { font-size: var(--tabel-fs); font-weight: 900; }
.tur-tabel .hdh.nihil { color: #9a4d58; font-size: calc(var(--tabel-fs) * 0.86); }
/* Judul dan kalimat di bawahnya ikut naik bersama tabelnya. Panel ini berlatar
   GELAP — jadi "paling terbaca" di sini berarti paling TERANG, kebalikan dari
   kartu hasil Quick Match yang berlatar terang. Aturan yang sama (kalimat
   penjelas harus menang atas latarnya), dua ground yang berbeda. */
.tur-hasil-kotak .hasil-judul { font-size: clamp(22px, 4.4vh, 31px); }
.tur-hasil-kotak .hasil-sebab {
  font-size: clamp(12.5px, 2.4vh, 15px);
  color: #e4ebf8;
  font-weight: 800;
}

/* ---- 57.45.6  SUB-JUDUL PANEL BABAK YANG TIDAK PERNAH TERLIHAT ---------
   CACAT SUNGGUHAN, dan sebabnya satu warna yang menjadi yatim.

   §57.44.4 menulis `color: #e4ebf8` untuk baris ini dengan catatan "kotak
   turnamen berlatar GELAP, jadi yang paling terbaca justru yang paling
   terang". Catatan itu benar waktu ditulis. Yang tidak ikut disetel: putaran
   yang sama menyeragamkan seluruh kartu keputusan ke bentuk `.kotak`, dan
   `.kotak` berlatar `var(--kartu)` yang TERANG.

   Terukur: teks rgb(228,235,248) di atas latar rgb(231,235,243). Selisih
   ketiga salurannya 3, 0, dan 5 — praktis warna yang sama. Yang tersisa
   terlihat di panel cuma lingkaran ikon cuaca di sebelahnya, karena ikon itu
   punya garis tepi berwarnanya sendiri. Itulah "tulisan di bawah headings yang
   hilang": ia tidak pernah dihapus, ia cuma tidak pernah bisa dilihat.

   Diseragamkan ke warna yang dipakai kartu Quick Match (`#10141c`), bukan
   diberi warna ketiga: kedua panel sekarang berlatar sama, jadi tidak ada lagi
   alasan tintanya berbeda. */
.tur-hasil-kotak .hasil-sebab { color: #10141c; }

/* Kisi papan turnamen ikut aturan §57.45.6 yang sama dengan papan Quick Match.
   Ditulis ulang DI SINI dan bukan dibiarkan diwarisi karena berkas ini dimuat
   belakangan dan sudah memegang `.tur-tabel .slmt` berkekhususan sama — celah
   yang persis sama pernah membuat kisi enam kolom §57.44.4 kalah tanpa suara. */
.tur-tabel .slmt {
  display: block;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---- 57.45.10  DASAR PANEL LOBI SEJAJAR DENGAN DASAR KARTU KOMIDI ------
   Terukur di 1280x720: dasar `.tur-lobi-kartu` di y=665,3 sementara dasar
   kartu bangsa di komidi kiri di y=644,3 — meleset 21 px, dan 21 px itu
   persis tinggi ruang patokan (18 px) ditambah sisipan jalurnya (3 px).

   Sebabnya bukan tinggi panelnya melainkan apa yang dianggap "dasar kolom":
   kedua kolom memang berakhir di garis yang sama, tapi yang terlihat mata di
   kolom kiri BUKAN tepi kolomnya melainkan tepi bawah kartu bangsa — di
   bawahnya cuma ruang kosong untuk tanda panah patokan.

   Pola perbaikannya sudah ada di css/style.css sejak §47.1
   (`.menu-kaki.rapat { margin-bottom: var(--ruang-patokan) }`), dipasang untuk
   layar Quick Match dengan keluhan yang sama persis. Lobi tidak pernah ikut
   memakainya. Ditambah sisipan `.komidi-jalur` supaya yang disejajarkan
   benar-benar KARTU-nya, bukan jalur yang membungkusnya. */
/* §57.63 — LOBI CUSTOM IKUT, dan itu memperbaiki kelalaian bukan menambah
   gaya baru. Aturan di atas dipatok ke `#layar-tur-lobi` waktu lahir, jadi
   lobi Custom — yang memakai `.tur-lobi-kartu` yang sama persis, kolom yang
   sama, dan komidi yang sama — tidak pernah kebagian. Terukur di 1280x720
   sebelum diperbaiki: dasar kartunya y=665 sementara dasar jalur komidi
   y=647, meleset 18 px dengan `margin-bottom: 0px`.

   Pemilihnya sekarang menyebut KEDUA layar, bukan dilepas jadi `.tur-lobi-
   kartu` telanjang: kartu yang sama juga dipakai di tempat lain yang tidak
   berpasangan dengan komidi, dan aturan tanpa cakupan akan menggeser mereka
   juga. */
#layar-tur-lobi .tur-lobi-kartu,
#layar-kustom-lobi .tur-lobi-kartu {
  margin-bottom: calc(var(--ruang-patokan) + 3px);
}
