/* Badminton Club — kerangka halaman.
   Mobile  : full-bleed, 100% lebar × tinggi layar.
   Desktop : artboard 393×852 di tengah, sisanya --gap (token DS untuk ruang
             di luar artboard). Batasnya GARIS, bukan bayangan — DS tanpa shadow.

   100dvh, bukan 100vh: di Safari iOS 100vh menghitung layar TANPA bilah alamat,
   jadi halaman selalu kelebihan ~60px dan ikut ter-scroll walau isinya muat.

   Ambang 768px = tablet ke atas. Di bawah itu layar memang selebar ponsel,
   membingkainya jadi 393 malah menyisakan pinggiran kosong. */

/* tokens.css / typography.css TIDAK menyetel box-sizing. Tanpa baris ini
   .app jadi 443×902 (393+48 padding+2 border), bukan 393×852. */
*, *::before, *::after { box-sizing: border-box; }

/* Atribut hidden HARUS menang atas display dari kelas.
   Aturan bawaan browser `[hidden] { display: none }` spesifisitasnya cuma 0,1,0
   dan kalah dari `.sheet { display: flex }`. Akibatnya elemen yang di-set
   `el.hidden = true` tetap terlihat, padahal propertinya sudah true — persis
   yang bikin bottom sheet tidak mau tertutup. */
[hidden] { display: none !important; }

html { height: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--surface);
}

/* .app TIDAK ikut scroll. Yang scroll cuma .app-main, supaya header dan bottom
   nav tetap menempel — perilaku app, bukan halaman web. Karena itu height,
   bukan min-height: kalau min-height, .app ikut memanjang mengikuti isi dan
   nav-nya terdorong ke bawah layar. */
.app {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100dvh;
  background: var(--surface);
  color: var(--primary);
  overflow: hidden;
}

/* Kolom header + konten. Ada supaya waktu .app dibalik jadi row (landscape),
   header tidak ikut jadi kolom sempit di sebelah nav. */
.app-col {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* min-height: 0 WAJIB. Default flex item itu min-height: auto, artinya dia
   menolak mengecil di bawah tinggi isinya — overflow-y tidak pernah aktif dan
   isi yang panjang malah mendorong nav keluar frame. */
/* Keterangan sementara: data belum sampai server. Pakai --caution, bukan
   --negative: tidak ada yang rusak, cuma belum selesai. Tanpa ikon dan tanpa
   tombol tutup — penanda yang bisa ditutup akan ditutup sekali lalu tidak
   pernah terlihat lagi, padahal keadaannya belum berubah. */
.local-note {
  flex: 0 0 auto;
  padding: var(--gap-item-loose) var(--gap-layout-tight);
  font: var(--text-body-5r);
  color: var(--caution);
  /* --surface-caution, nama token yang benar di DS; jangan dikarang jadi
     --caution-low. */
  background: var(--surface-caution);
  border-bottom: 1px solid var(--surface-border);
}

.app-main {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}

/* ── Jarak 4px header–konten dan konten–menu bawah (14 Sep 2026) ──
   Jaraknya sungguhan, bukan garis: latar frame memakai --gap, dan setiap
   bagian di dalamnya (header, konten, menu bawah) berlatar --surface, jadi
   4px di antaranya terlihat sebagai celah. Hanya di bawah header dan di atas
   menu bawah; bagian lain di dalam kolom (kepala halaman, tab) tetap
   menempel satu sama lain. */
.app { background: var(--gap); }
/* :where() = prioritas nol, jadi latar milik elemen itu sendiri tetap menang
   (misalnya pita kuning .local-note). */
:where(.app-col) > :where(*) { background: var(--surface); }
/* Garis bawah header dan garis atas menu bawah dihapus: celah 4px sudah
   memisahkan (14 Sep 2026). */
.app-col > .hd { margin-bottom: 4px; border-bottom: 0; }
.app > .nav { margin-top: 4px; border-top: 0; }

@media (min-width: 768px) {
  body {
    display: grid;
    place-items: center;
    background: var(--gap);
  }

  .app {
    /* 393 × 852 = layar iPhone 15 / 16 Pro (diputuskan 13 Sep 2026; dulu 873). */
    width: 393px;
    height: 852px;
    /* Layar pendek (laptop 768p, browser + dock) tidak cukup 852. Tanpa clamp
       ini artboard-nya terpotong di atas dan bawah sekaligus karena di-center. */
    max-height: calc(100dvh - 48px);
    border: 1px solid var(--surface-border);
    border-radius: var(--radius-modal);
  }
}

/* =====================================================================
   Header — flush, tanpa garis bawah.
   Catatan: di mockup bit garis pemisah header dihapus karena jelek di mobile;
   aturan itu diikuti di sini. Bottom nav TETAP bergaris karena tanpa itu
   deretan ikonnya mengambang di atas konten yang lewat di belakangnya.
   ===================================================================== */

.hd {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--gap-item-loose);
  /* 60px termasuk garis bawah 1px (diputuskan 13 Sep 2026): semua header punya
     pemisah tipis dengan isi di bawahnya. */
  box-sizing: border-box;
  height: 60px;
  padding: 0 var(--gap-item-loose) 0 var(--gap-layout-tight);
  background: var(--surface);
  border-bottom: 1px solid var(--surface-border);
}

/* Tombol yang berdiri di KIRI judul (panah kembali) dibuat menempel tepi kiri,
   menambal padding kiri header yang memang disiapkan untuk teks. */
.hd .icbtn-lead { margin-left: calc(var(--gap-layout-tight) * -1 + var(--gap-item-base)); }

.hd-title {
  font: var(--text-heading-1);
  color: var(--primary);
  margin-right: auto;
}

/* Ikon yang berdiri sendiri (tanpa label) pakai --icon, bukan warna teks. */
.icbtn {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--icon);
  border-radius: var(--radius-field);
  cursor: pointer;
}
.icbtn:hover { background: var(--surface-hover); }

/* =====================================================================
   Bottom nav
   ===================================================================== */

/* Tanpa zoom ketuk-dua-kali (dan tanpa jeda 300ms menunggunya). Zoom cubit
   dikunci lewat meta viewport dan gate.js. */
html { touch-action: manipulation; }

/* ── Kepala standar tab utama (shell.js) ──
   Bell dan avatar di kanan. Kalau kepala halaman sudah punya tombol yang
   didorong ke kanan (gear Club settings), kelompok ini menempel di sebelahnya. */
.hd-actions { margin-left: auto; display: flex; align-items: center; gap: var(--gap-item-tight); }
#settings-link ~ .hd-actions { margin-left: 0; }
.hd-bell { position: relative; }
.bell-dot {
  position: absolute;
  top: 9px;
  right: 10px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--negative);
}
.hd-me { display: grid; place-items: center; width: 40px; height: 40px; }

/* ── Kepala standar (header data-hd="std", 15 Sep 2026) ──
   Logo di tengah; kiri avatar, atau Back kalau halamannya punya Back yang
   sedang tampil; kanan lonceng. Judul dan logo milik halaman disembunyikan. */
/* Halaman yang sedang jadi form (.is-form, misalnya tulis balasan forum) tetap
   memakai kepala lama: judul, tombol tutup, dan tombol Post. */
.hd[data-hd="std"] { position: relative; }
.app:not(.is-form) .hd[data-hd="std"] > .hd-title,
.app:not(.is-form) .hd[data-hd="std"] > .hd-logo,
.app:not(.is-form) .hd[data-hd="std"] > .hd-stack { display: none; }
/* Tepi yang TERLIHAT (gambar avatar, panah Back, garis lonceng) jatuh tepat 16px
   dari tepi layar, lurus dengan kartu di bawahnya. Header diberi padding 16 di
   kedua sisi, lalu tiap kotak ikon 40px digeser sebesar ruang kosong di
   dalamnya: avatar 32 → -4, panah 20 → -10, lonceng 22 → -9. */
.hd[data-hd="std"] { padding-left: var(--gap-layout-tight); padding-right: var(--gap-layout-tight); }
.hd-left { display: flex; align-items: center; margin-left: -4px; }
.hd[data-hd="std"] > .icbtn-lead { margin-left: -10px; }
.hd[data-hd="std"] > .hd-actions { margin-right: -9px; }
.hd[data-hd="std"]:has(> .icbtn-lead:not([hidden])) > .hd-left { display: none; }
.hd-brand { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: flex; align-items: center; color: var(--primary); }
.hd-brand svg { height: 20px; width: auto; display: block; }
/* Tombol tambahan milik halaman (misalnya … moderasi forum) di kanan, menempel lonceng. */
.hd[data-hd="std"] > #hd-right { margin-left: auto; }
.hd[data-hd="std"] > #hd-right ~ .hd-actions { margin-left: 0; }
.hd-me img { width: 32px; height: 32px; border-radius: 50%; display: block; background: var(--emphasis); object-fit: cover; }
/* Avatar tamu: lingkaran --emphasis 32px dengan ikon orang. */
.hd-guest { display: none; width: 32px; height: 32px; border-radius: 50%; background: var(--emphasis); color: var(--icon); place-items: center; }
.hd-me.is-guest .hd-guest { display: grid; }
/* Halaman akun yang dibuka tamu: isi halaman disembunyikan, tinggal empty state. */
.app-main.is-guest > :not(.guest-empty) { display: none !important; }
.nt-row { align-items: flex-start; }
.nt-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--gap-item-tight); }
.nt-title { font: var(--text-body-3b); color: var(--primary); }
.nt-text { font: var(--text-body-5r); color: var(--secondary); white-space: normal; }
.nt-dot { flex: 0 0 auto; width: 8px; height: 8px; margin-top: 6px; border-radius: 50%; background: var(--brand); }
.inbox-empty { display: block; padding: var(--gap-section-base) 0; font: var(--text-body-4r); color: var(--secondary); }

.nav {
  flex: 0 0 auto;
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--surface-border);
  /* Home indicator iPhone menutupi ~34px paling bawah. Tanpa baris ini label
     tab tertimpa garis itu di perangkat asli, walau di browser terlihat aman. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.nav-item {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--gap-item-base);
  height: 56px;
  padding: 0;
  border: 0;
  background: transparent;
  font: var(--text-label-sb);
  /* Ikon nempel label, jadi warnanya ikut warna teks lewat currentColor —
     bukan --icon. */
  color: var(--tertiary);
  cursor: pointer;
  position: relative;
  /* Item nav bisa berupa <a> (punya halaman) atau <button> (belum), jadi
     garis bawah tautan dimatikan di sini. */
  text-decoration: none;
}

.nav-item[aria-current="page"] { color: var(--brand); }

/* Label tab disembunyikan SECARA VISUAL saja, teksnya tetap ada di DOM supaya
   pembaca layar dan aria-label tetap punya nama tab. Dihapus dari markup, nama
   tabnya hilang sama sekali dan ikon tanpa nama tidak terbaca.
   position: absolute bikin dia keluar dari flow, jadi gap 4px di .nav-item
   tidak menyisakan ruang kosong.

   Balikin labelnya: set data-nav="labels" di <body>. */
.nav-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  white-space: nowrap;
  clip-path: inset(50%);
}

body[data-nav="labels"] .nav-label {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
}

/* =====================================================================
   Devbar — alat uji DI LUAR frame, desktop saja: rotasi + terang/gelap.
   Disuntik oleh shell.js supaya tiap halaman baru tidak perlu menyalin
   markup-nya. Ini alat bantu, bukan bagian produk: dia hidup di atas --gap,
   di luar .app, dan tidak pernah muncul di mobile.
   ===================================================================== */

.devbar { display: none; }

@media (min-width: 768px) {
  .devbar {
    position: fixed;
    top: 16px;
    right: 16px;
    display: flex;
    gap: var(--gap-item-loose);
  }

  .devbar button {
    display: inline-flex;
    align-items: center;
    gap: var(--gap-item-loose);
    height: 36px;
    padding: 0 var(--gap-section-base);
    font: var(--text-body-4b);
    color: var(--primary);
    background: var(--surface);
    border: 1px solid var(--surface-border);
    border-radius: var(--radius-field);
    cursor: pointer;
  }
  .devbar button:hover { background: var(--surface-hover); }

  /* Landscape: 393×852 ditukar jadi 852×393. max-width ikut dipasang karena
     852 lebih lebar dari jendela browser yang disempitkan. */
  body[data-orient="landscape"] .app {
    width: 852px;
    height: 393px;
    max-width: calc(100vw - 48px);
    flex-direction: row;
  }

  /* Nav pindah jadi rail kiri. Di DOM dia tetap elemen terakhir — urutan itu
     yang benar buat pembaca layar pada tata letak bottom nav — jadi posisinya
     digeser pakai order, bukan dengan memindah markup. */
  body[data-orient="landscape"] .nav {
    order: -1;
    flex-direction: column;
    /* Ditengahkan vertikal. Waktu mendatar cuma empat item di kolom setinggi
       layar, dan kalau ditumpuk dari atas sisanya jadi ruang kosong panjang di
       bawah yang bikin rail-nya terlihat terpotong. */
    justify-content: center;
    width: 72px;
    border-top: 0;
    border-right: 1px solid var(--surface-border);
    padding-bottom: 0;
    /* Landscape memindahkan safe area ke sisi kiri/kanan, bukan bawah. */
    padding-left: env(safe-area-inset-left, 0px);
  }

  body[data-orient="landscape"] .nav-item {
    flex: 0 0 auto;
    width: 100%;
  }
}

/* ── Tarik untuk refresh (shell.js) ──
   Lingkaran 36px di bawah header, tanpa bayangan: dibedakan oleh garis
   wadahnya. Ikon --icon; lewat ambang jadi --primary, tanda boleh dilepas.
   Tarik-refresh bawaan Chrome dimatikan supaya tidak dobel. */
html, body { overscroll-behavior-y: none; }
.ptr {
  position: absolute;
  left: 50%;
  z-index: 12;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--surface-border);
  color: var(--icon);
  pointer-events: none;
}
.ptr.is-ready { color: var(--primary); }
.ptr.is-busy svg { animation: ptr-spin .7s linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ptr.is-busy svg { animation: none; } }

/* ── Tutorial (tutorial.js) ──
   Empat panel gelap mengelilingi elemen yang disorot (warna --overlay, sama
   dengan latar sheet), garis brand di tepinya, tanpa bayangan. Kartu langkah
   menempel di bawah, atau di atas kalau elemennya di separuh bawah layar. */
.tut-dim { position: absolute; z-index: 1000; background: var(--overlay); }
.tut-ring {
  position: absolute;
  z-index: 1000;
  border: 2px solid var(--brand);
  border-radius: var(--radius-field);
  pointer-events: none;
}
.tut-card {
  position: absolute;
  left: var(--gap-layout-tight);
  right: var(--gap-layout-tight);
  bottom: calc(var(--gap-layout-tight) + env(safe-area-inset-bottom, 0px));
  z-index: 1001;
  display: flex;
  flex-direction: column;
  gap: var(--gap-item-loose);
  padding: var(--gap-section-base);
  background: var(--modal);
  border: 1px solid var(--modal-border);
  border-radius: var(--radius-card);
}
.tut-card.is-top { bottom: auto; top: var(--gap-layout-tight); }
.tut-top { display: flex; align-items: center; justify-content: space-between; min-height: 24px; }
.tut-count { font: var(--text-body-5b); color: var(--secondary); }
.tut-text { font: var(--text-body-3b); color: var(--primary); }
.tut-acts { display: flex; gap: var(--gap-item-loose); }
.tut-acts > * { flex: 1 1 0; }
