/* ============================================================
   APRESIA — sistem desain: malam, krem, dan satu tinta emas.

   Dirombak dari tema terang. Alasannya bukan selera: Apresia dipakai saat
   orang sedang siaran malam, overlay-nya hidup di atas video gelap, dan
   papan perolehannya tampil di layar panggung. Tema gelap bukan gaya di sini,
   melainkan keadaan tempat produk ini benar-benar dipakai.

   Tiga tinta, dan hanya tiga:

   • KREM — seluruh teks. Bukan putih: putih murni di atas latar gelap terbaca
     menyilaukan dan membuat huruf tampak lebih tipis daripada seharusnya.
   • EMAS — uang. Dipakai sangat hemat; begitu ia muncul di mana-mana, ia
     berhenti berarti apa-apa. Aturannya: emas hanya untuk angka rupiah,
     tindakan utama, dan penanda bagian.
   • UNGU — merek. Dinaikkan terangnya dari ungu terang lama, karena warna
     yang pas di atas kertas putih akan tenggelam di atas malam.

   Nama token lama dipetakan ke tinta baru di bawah, jadi lima puluh halaman
   aplikasi ikut berganti tanpa satu pun disentuh.
   ============================================================ */
:root{
  /* ---- dasar: violet-hitam hangat, bukan abu netral ---- */
  --malam:#0C0918; --malam-2:#120F22; --malam-3:#1A1430; --malam-4:#241C42;
  --tepi:#2A2148; --tepi-2:#3A2F63; --tepi-3:#4C3F80;

  /* ---- tinta ---- */
  --krem:#F3EDE1; --krem-2:#BDB3CE; --krem-3:#8A80A3;

  /* ---- aksen ---- */
  --emas:#E9BC55; --emas-2:#C89A33; --emas-mud:#2E2312;
  --ungu:#9B8BFF; --ungu-mud:#241D4C;
  /* Isian tombol beraksen, terpisah dari warna teksnya. Satu nilai tidak
     bisa memikul keduanya: yang cukup terang untuk dibaca sebagai teks di
     atas latar gelap terlalu terang untuk memangku teks putih. */
  --ungu-isi:#6D5AE6;
  /* Tosca: hal yang berlangsung SEKARANG. Dipakai halaman muka dan
     halaman kreator; ditanam di sini supaya nilainya tidak hilang saat
     tema terang dipilih. */
  --laju:#2BAE9B;
  --hijau:#4FD494; --hijau-mud:#123528;
  --merah:#F47C7C; --merah-mud:#3A1B1F;
  --kuningT:#E9B44C; --kuning-mud:#33280F;

  /* ---- tinta gambar: palet untuk ilustrasi tangan di _gambar.blade.php ----
     Gambarnya dulu tinta gelap di atas kertas terang. Di tema malam urutannya
     dibalik: garisnya jadi krem, kertasnya jadi bidang gelap yang terangkat.
     Warna aksennya dinaikkan terangnya supaya tetap terbaca di atas malam. */
  --tinta:var(--krem); --tinta-3:var(--krem-3);
  --kertas:var(--malam-3); --kertas-2:var(--malam-4); --kertas-3:var(--tepi);
  --biru:#6C74E8; --biru-mud:var(--tepi);
  --jingga:#E2894E; --kuning:var(--emas);

  /* ---- nama lama dipetakan ke tinta baru ----
     Inilah yang membuat seluruh aplikasi ikut berganti: satu berkas yang
     menentukan rupanya, bukan lima puluh. */
  --bg:var(--malam); --shell:var(--malam-2); --card:var(--malam-3);
  --card2:var(--malam-4); --raised:var(--malam-4);
  --line:var(--tepi); --line2:var(--tepi-2); --line3:var(--tepi-3);
  --txt:var(--krem); --mut:var(--krem-2); --dim:var(--krem-3);
  --cy:var(--ungu); --cy-deep:var(--ungu-mud);
  --gn:var(--hijau); --am:var(--kuningT); --rd:var(--merah);
  --pk:#F07BB5; --vi:#B49BFF;
  --field:#171229; --inset:#171229;
  --grad:linear-gradient(135deg,#8B7BF0,#5D8BE8);

  /* ---- huruf ----
     Tiga peran, tiga rupa. Archivo memikul judul; Instrument Serif miring
     membawa separuh kalimat judul — pergantian rupa di tengah kalimat itulah
     yang membuat judulnya punya suara, bukan sekadar besar. Plus Jakarta Sans
     (Tokotype, dibuat untuk identitas Jakarta) memikul teks isi. */
  --sans:"Plus Jakarta Sans","Segoe UI",Arial,sans-serif;
  --tampil:"Archivo","Plus Jakarta Sans",Arial,sans-serif;
  --serif:"Instrument Serif",Georgia,serif;
  --mono:"JetBrains Mono",ui-monospace,Menlo,monospace;

  --r-sm:9px; --r:13px; --r-lg:18px;
  /* Di atas latar gelap, bayangan hampir tak terlihat. Yang memisahkan
     bidang di sini cahaya tepi, bukan bayangan. */
  --sh-1:0 1px 2px rgba(0,0,0,.4);
  --sh-2:0 18px 40px -18px rgba(0,0,0,.7);
  --sh-3:0 28px 60px -24px rgba(0,0,0,.8);
  --kilau:inset 0 1px 0 rgba(255,255,255,.055);
  --ring:0 0 0 3px rgba(155,139,255,.35);
  /* Permukaan buram: bilah navigasi yang mengambang di atas isi. */
  --kaca:rgba(18,15,34,.86);
  --sorot:rgba(255,255,255,.05);
  --lapis-tinta:linear-gradient(180deg,rgba(36,28,66,.55),rgba(12,9,24,0));
  --lam-1:rgba(155,139,255,.16);
  --lam-2:rgba(233,188,85,.09);
  /* Mengikat kendali bawaan peramban — kotak centang, bilah gulir,
     pemilih tanggal — ke tema yang dipilih, bukan ke setelan sistem. */
  /* Emas punya dua pekerjaan yang tidak bisa dirangkap satu nilai:
     sebagai TEKS ia harus cukup gelap untuk terbaca, sebagai BIDANG ia
     harus cukup terang untuk terlihat emas. Di tema malam keduanya
     kebetulan sama; di tema terang tidak, dan di situlah pasangan ini
     mulai berguna. */
  --emas-isi:var(--emas); --emas-isi-2:#F3CB72; --emas-atas:var(--malam);
  color-scheme:dark;
}

/* ============================================================
   TEMA TERANG

   Hanya token dasar yang ditulis ulang di sini. Seluruh nama turunan
   (--bg, --card, --txt, --tinta, --kertas, dan kawan-kawan) sudah menunjuk
   ke token dasar lewat var(), jadi mereka ikut berpindah sendiri. Itulah
   sebabnya blok ini pendek: temanya ditentukan di satu tempat, bukan lima
   puluh halaman.

   Satu keputusan yang tidak bisa dibalik begitu saja: emas. Emas malam
   (#E9BC55) di atas kertas putih hanya punya kontras 1,8:1 — terbaca sebagai
   kuning pudar, bukan sebagai uang. Jadi di tema terang emasnya diturunkan
   nadanya sampai gelap, dan perannya tetap sama persis: hanya untuk angka
   rupiah, tindakan utama, dan penanda bagian.

   Temanya dipasang sebagai atribut, bukan lewat prefers-color-scheme saja,
   supaya pilihan orangnya menang atas setelan sistem. Berkas ini tidak
   memilih; skrip kecil di <head> yang memutuskan sebelum cat pertama.
   ============================================================ */
:root[data-theme="light"]{
  /* ---- dasar ---- */
  --malam:#F5F6FB; --malam-2:#FFFFFF; --malam-3:#FFFFFF; --malam-4:#F1F3F9;
  --tepi:#E7EAF3; --tepi-2:#D9DEEC; --tepi-3:#C2C9DE;

  /* ---- tinta ---- */
  /* Nada paling redup dinaikkan dari #79829C: ia dipakai untuk metadata
     mono 10-11px, dan pada ukuran itu 3,8:1 di atas kertas putih terlalu
     tipis untuk dibaca. #646C88 membawanya ke 5,2:1. */
  --krem:#161A2C; --krem-2:#5A6480; --krem-3:#646C88;

  /* ---- aksen ---- */
  --emas:#8C6209; --emas-2:#6B4A05; --emas-mud:#FBF1D9;
  --ungu:#5B4DE0; --ungu-mud:#EEEBFC;
  --ungu-isi:#5B4DE0; --laju:#0E7C6E;
  --hijau:#047857; --hijau-mud:#DCFCE7;
  --merah:#DC2626; --merah-mud:#FEE2E2;
  --kuningT:#B45309; --kuning-mud:#FEF3C7;

  /* ---- tinta gambar: kembali ke urutan aslinya, tinta gelap di atas kertas ---- */
  --biru:#4F7FE8; --biru-mud:#E7EEFC;
  --jingga:#7C3AED;

  /* ---- nama lama yang ditulis harfiah ---- */
  --pk:#DB2777; --vi:#7C3AED;
  --field:#FBFCFE; --inset:#F4F6FB;
  --grad:linear-gradient(135deg,#7C3AED,#4F7FE8);

  /* Di atas kertas, yang memisahkan bidang adalah bayangan — bukan cahaya
     tepi. Jadi kilaunya dimatikan dan bayangannya dihidupkan kembali. */
  --sh-1:0 1px 2px rgba(20,26,48,.06), 0 1px 1px rgba(20,26,48,.04);
  --sh-2:0 14px 34px -14px rgba(24,30,64,.22);
  --sh-3:0 22px 48px -22px rgba(24,30,64,.30);
  --kilau:none;
  --ring:0 0 0 3px rgba(91,77,224,.22);
  --kaca:rgba(255,255,255,.86);
  --sorot:rgba(22,26,44,.05);
  --lapis-tinta:linear-gradient(180deg,rgba(124,58,237,.07),rgba(245,246,251,0));
  --lam-1:rgba(124,58,237,.10);
  --lam-2:rgba(140,98,9,.06);
  --emas-isi:#C8961F; --emas-isi-2:#B5851A; --emas-atas:#1A1206;
  color-scheme:light;
}

/* ============================================================
   TEMA MUKA — biru laut, indigo pekat, tosca

   Dipakai halaman muka DAN halaman daftar kreator, dan itu alasan ia tinggal
   di sini, bukan di landing.css: landing.css hanya dimuat halaman muka.

   Dipasang di <html>, bukan di pembungkus di dalam badan. Nama turunan
   (--bg, --card, --txt, dan kawan-kawan) dihitung di :root dari token dasar;
   menimpa token dasar di keturunannya tidak mengubah nama turunan yang sudah
   terlanjur dihitung, dan hasilnya halaman yang separuh berganti warna.
   Caranya sama persis dengan tema terang di atas: patok token dasarnya di
   akar, sisanya ikut sendiri.

   :not([data-theme="light"]) — temanya hanya menimpa tema gelap. Tema terang
   punya paletnya sendiri yang sudah dingin dan sudah diukur; menimpanya
   dengan hitam-biru laut berarti sakelar temanya berhenti bekerja di dua
   halaman ini.

   Tiap pasangan warna teks diukur, bukan dikira. #7A8499 dipakai sebagai
   teks redup karena #6E7890 yang lebih dekat ke rujukannya hanya mencapai
   4,48:1 di atas #070A12 — lewat sedikit di bawah ambang AA, dan "lewat
   sedikit" tetap berarti ada yang tidak bisa membacanya.
   ============================================================ */
:root.tema-muka:not([data-theme="light"]){
  --malam:#070A12; --malam-2:#0C1019; --malam-3:#111726; --malam-4:#19202F;
  --tepi:#1C2333; --tepi-2:#283145; --tepi-3:#3A4560;

  --krem:#EFF3FA;    /* 16,7:1 di atas --malam */
  --krem-2:#A4AEC4;  /*  8,0:1 di atas --malam-3 */
  --krem-3:#7A8499;  /*  5,3:1 di atas --malam */

  /* Indigo punya DUA nilai, dan itu bukan kemewahan. #7B5CFA yang persis
     seperti rujukannya duduk tepat di tengah: putih di atasnya 4,42:1 dan
     tinta gelap 4,32:1 — dua-duanya gagal AA untuk teks biasa. Jadi isian
     tombolnya diturunkan sampai putih lolos (6,7:1), dan teks beraksen
     dinaikkan sampai ia lolos di atas latar (6,8:1). */
  --ungu:#9A86FF; --ungu-isi:#5B3FD6; --ungu-mud:#15163A;
  --emas:#E9B949; --emas-2:#C8992F; --emas-mud:#2A2110;

  /* Tosca punya tugas, bukan warna yang ditambahkan supaya halamannya
     terlihat lebih ramai: hanya untuk hal yang berlangsung sekarang atau
     seketika. */
  --laju:#4FD6C4;

  /* Beberapa nilai di :root ditulis sebagai warna jadi, bukan var() ke token
     dasar, jadi ia tidak ikut berpindah sendiri dan harus disebut ulang. */
  --field:#0E1422; --inset:#0E1422;
  --kaca:rgba(12,16,25,.86);
  --ring:0 0 0 3px rgba(154,134,255,.35);
  --lam-1:rgba(154,134,255,.16);
  --lam-2:rgba(233,185,73,.09);
  --lapis-tinta:linear-gradient(180deg,rgba(25,32,47,.55),rgba(7,10,18,0));
  --grad:linear-gradient(135deg,#7B5CFA,#4E7BD8);
  --pk:#F07BB5; --vi:#B4A6FF;
}

/* ── TEMA MUKA, SISI TERANG ──
   Blok di atas hanya menimpa tema gelap. Yang perlu ditulis di sini cuma
   nilai yang BUKAN token dasar — token dasar tema terang sudah ada dan sudah
   diukur, jadi halaman ini ikut sendiri.

   Yang tersisa: dua warna sorot judul hero, dan bidang miring latarnya.
   Warna sorotnya diturunkan karena emas #DCA81C di atas kertas #F5F6FB cuma
   2,01:1 — gagal bahkan untuk teks besar. */
:root.tema-muka[data-theme="light"] .lp{
  --hero-iris:#5B4DE0;   /* 5,9:1 di atas kertas */
  --hero-emas:#8C6209;   /* 5,0:1 di atas kertas */
}

/* Bidang miringnya dinaikkan kepekatannya di tema terang. Pada 10% di atas
   kertas #F5F6FB ia tidak terlihat sama sekali, dan seksi pertamanya jadi
   bidang putih kosong tanpa arah. */
:root.tema-muka[data-theme="light"] .lp-bidang .kiri{
  background: linear-gradient(180deg, rgb(14 124 110 / .13), transparent 58%, rgb(91 77 224 / .13));
}
:root.tema-muka[data-theme="light"] .lp-bidang .kanan{
  background: linear-gradient(180deg, rgb(140 98 9 / .12), transparent 70%);
}

/* Dua bidang miring yang membentang seluruh halaman.

   Di badan, bukan di pembungkus isi: halaman daftar kreator dan halaman muka
   membungkus isinya dengan cara yang berbeda, dan satu-satunya bidang yang
   dimiliki keduanya adalah badannya sendiri. Seksi yang punya latar sendiri
   menutupnya, dan itu memang yang diinginkan — bidangnya muncul di seksi yang
   latarnya tembus lalu hilang di seksi berikutnya, seperti cahaya yang jatuh
   di sebagian ruangan saja. */
:root.tema-muka:not([data-theme="light"]) body{
  background:
    linear-gradient(104deg, transparent 0 37%, rgb(91 63 214 / .07) 37% 53%, transparent 53%),
    linear-gradient(104deg, transparent 0 64%, rgb(79 214 196 / .028) 64% 72%, transparent 72%),
    var(--bg);
  background-attachment: fixed;
}

/* Tombol utama ikut aksen halaman, bukan emas.

   Emas adalah warna tindakan utama di seluruh aplikasi, dan di dua halaman
   ini ia bertabrakan dengan aturan yang dipegang halaman muka: emas berarti
   "ini sejumlah uang". Tombol "Daftar" bukan sejumlah uang, dan tombol emas
   yang berdiri di sebelah angka emas membuat keduanya terbaca satu jenis.

   Putih di atas #5B3FD6 mencapai 6,7:1; di atas indigo yang lebih terang ia
   gagal AA, dan itu sebabnya isian tombolnya memakai nilai yang lebih gelap
   daripada warna teks beraksennya. */
:root.tema-muka:not([data-theme="light"]) .btn.pri{
  background:var(--ungu-isi); color:#FFFFFF;
  box-shadow:0 10px 26px -12px rgba(91,63,214,.55);
}
:root.tema-muka:not([data-theme="light"]) .btn.pri:hover{
  background:#6D4FE6;
  box-shadow:0 14px 32px -12px rgba(91,63,214,.65);
}
:root.tema-muka:not([data-theme="light"]) .btn.pri:active{
  box-shadow:0 4px 12px -8px rgba(91,63,214,.5);
}

/* ============================================================
   PERMUKAAN YANG SELALU GELAP

   Apa pun yang menumpang di atas video siaran tidak boleh ikut berganti
   tema: overlay OBS, papan perolehan suara di layar panggung, dan layar
   siaran di peragaan halaman muka. Kalau ikut terang, teksnya hilang di
   siaran orang — dan yang menonton siaran itu tidak pernah memilih tema.

   Caranya sama seperti tema: token dasarnya dipatok di sini, dan seluruh
   isinya ikut tanpa satu pun selektor anak perlu ditulis ulang.
   ============================================================ */
.layar-gelap{
  --malam:#0C0918; --malam-2:#120F22; --malam-3:#1A1430; --malam-4:#241C42;
  --tepi:#2A2148; --tepi-2:#3A2F63; --tepi-3:#4C3F80;
  --krem:#F3EDE1; --krem-2:#BDB3CE; --krem-3:#8A80A3;
  --emas:#E9BC55; --emas-2:#C89A33; --ungu:#9B8BFF;
  --hijau:#4FD494; --merah:#F47C7C;
  --txt:var(--krem); --mut:var(--krem-2); --dim:var(--krem-3);
  --bg:var(--malam); --card:var(--malam-3); --card2:var(--malam-4); --raised:var(--malam-4);
  --line:var(--tepi); --line2:var(--tepi-2); --line3:var(--tepi-3);
  --cy:var(--ungu); --gn:var(--hijau); --rd:var(--merah);
  color:var(--krem);
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--malam);color:var(--krem);font-family:var(--sans);
  font-size:14px;line-height:1.6;-webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
::selection{background:var(--emas-isi);color:var(--emas-atas)}
a{color:var(--ungu);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
button{font-family:var(--sans)}
input[type=checkbox],input[type=radio],progress{accent-color:var(--cy)}
.mono{font-family:var(--mono)}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
/* Angka rupiah selalu emas. Satu aturan, berlaku di mana pun ia muncul. */
.rp{color:var(--emas);font-family:var(--mono);font-variant-numeric:tabular-nums}
:is(a,button,[role="button"],input,select,textarea,.switch):focus-visible{
  outline:none;box-shadow:var(--ring);border-radius:8px
}
@media (prefers-reduced-motion: reduce){ *{animation-duration:.001s !important;transition-duration:.001s !important;scroll-behavior:auto !important} }

/* icon SVG */
.ic{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex:none;vertical-align:-3px}
.ic.lg{width:22px;height:22px}
.ic.sm{width:15px;height:15px}

@keyframes rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.rise{animation:rise .32s ease both}

/* Penanda kecil: pil lembut mengikuti tema. */
.cap{
  display:inline-flex;align-items:center;gap:7px;padding:6px 14px;border-radius:99px;
  background:var(--ungu-mud);border:1px solid var(--tepi-2);color:var(--vi);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;font-weight:600;
}

/* ============ APP CHROME (topbar) ============ */
.appbar{
  display:flex;align-items:center;gap:16px;height:56px;padding:0 20px;
  background:var(--kaca);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);position:sticky;top:0;z-index:60;
}
.brandlink{display:flex;align-items:center;gap:9px;color:var(--txt);font-weight:800;font-size:15px;letter-spacing:-.01em}
.brandlink:hover{text-decoration:none}
.logo{width:30px;height:30px;display:flex;align-items:center;justify-content:center;flex:none}
.logo svg{width:100%;height:100%;display:block}
.crumb{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--dim);min-width:0;white-space:nowrap;overflow:hidden}
.crumb b{color:var(--mut);font-weight:600}
.crumb .sep{opacity:.5}
.abar-sp{flex:1}
.gsearch{display:flex;align-items:center;gap:8px;background:var(--field);border:1px solid var(--line);border-radius:10px;padding:7px 12px;min-width:230px;color:var(--dim);font-size:12.5px;cursor:text}
.gsearch:hover{border-color:var(--line2)}
/* Kotak carinya kini borang sungguhan, jadi input-nya perlu dibuat menyatu
   dengan kotaknya alih-alih membawa bingkai bawaan peramban. */
.gsearch input{flex:1;min-width:0;background:none;border:0;outline:none;padding:0;
  font-family:var(--sans);font-size:12.5px;color:var(--txt)}
.gsearch input::placeholder{color:var(--dim)}
.gsearch:focus-within{border-color:var(--cy)}
.gsearch kbd{margin-left:auto;font-family:var(--mono);font-size:9.5px;border:1px solid var(--line2);border-radius:5px;padding:1px 5px;color:var(--dim)}
.iconbtn{position:relative;display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:10px;border:1px solid transparent;background:none;color:var(--mut);cursor:pointer;transition:.18s}
.iconbtn:hover{background:var(--card);color:var(--txt);border-color:var(--line)}
.iconbtn .dot{position:absolute;top:8px;right:9px;width:8px;height:8px;border-radius:50%;background:var(--rd);border:2px solid var(--shell)}
.avabtn{display:flex;align-items:center;gap:9px;background:none;border:1px solid transparent;border-radius:99px;padding:3px 10px 3px 3px;cursor:pointer;color:var(--txt);transition:.18s}
.avabtn:hover{background:var(--card);border-color:var(--line)}
.avabtn .nm{font-size:12.5px;font-weight:700}
.avabtn .rl{display:block;font-size:9.5px;color:var(--dim);font-weight:500;text-align:left}
.ava{width:32px;height:32px;border-radius:50%;background:var(--grad);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12px;color:var(--malam);flex:none}
.ava.lg{width:64px;height:64px;font-size:22px}
.ava.md{width:44px;height:44px;font-size:15px}
.ava.biz{background:linear-gradient(135deg,#34D399,#0E7490)}
/* dropdown */
.dd{position:relative}
.dd-menu{
  position:absolute;right:0;top:calc(100% + 8px);min-width:230px;background:var(--card2);
  border:1px solid var(--line2);border-radius:14px;box-shadow:var(--sh-2);padding:6px;z-index:80;
  display:none;
}
.dd.open .dd-menu{display:block;animation:rise .18s ease}
.dd-menu .mi{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:none;border:0;color:var(--txt);font-size:12.5px;font-weight:600;padding:9px 11px;border-radius:9px;cursor:pointer}
.dd-menu .mi:hover{background:var(--raised);text-decoration:none}
.dd-menu .mi .ic{color:var(--mut)}
.dd-menu .mi.danger,.dd-menu .mi.danger .ic{color:var(--rd)}
.dd-menu .sep{height:1px;background:var(--line);margin:5px 8px}
.dd-menu .hd{padding:9px 11px 7px;font-size:11px;color:var(--dim)}
.dd-menu .hd b{display:block;color:var(--txt);font-size:12.5px}
.notif{display:flex;gap:10px;padding:10px 11px;border-radius:9px;font-size:12px;color:var(--mut);align-items:flex-start}
.notif:hover{background:var(--raised)}
.notif .ic{margin-top:1px}
.notif b{color:var(--txt);display:block;font-size:12px}
.notif time{display:block;margin-top:3px;font-size:10px;color:var(--dim)}

/* env chip kecil (pengganti pill MOCKUP yang mencolok) */
.env{font-family:var(--mono);font-size:8.5px;letter-spacing:.14em;color:var(--am);border:1px solid var(--tepi-2);background:var(--kuning-mud);border-radius:99px;padding:2px 8px;font-weight:600}

/* ============ SIDEBAR (Merchant Center) ============ */
.app{display:flex;min-height:100vh}
aside.nav{width:238px;flex:none;background:var(--shell);border-right:1px solid var(--line);padding:14px 12px;position:sticky;top:0;height:100vh;overflow-y:auto;display:flex;flex-direction:column}
.brand{display:flex;align-items:center;gap:10px;padding:6px 8px 16px}
.brand .logo{width:34px;height:34px;border-radius:10px}
.brand b{font-size:15.5px;letter-spacing:-.01em;line-height:1.15}
.brand small{display:block;font-size:10px;color:var(--dim);font-weight:600}
.nav .grp{font-family:var(--mono);font-size:9px;letter-spacing:.16em;color:var(--dim);margin:14px 10px 6px}
.nav button.item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:none;border:0;color:var(--mut);padding:9px 11px;border-radius:10px;font-size:13px;font-weight:600;cursor:pointer;transition:.15s}
.nav button.item .ic{color:var(--dim);transition:.15s}
.nav button.item:hover{background:var(--card);color:var(--txt)}
.nav button.item:hover .ic{color:var(--mut)}
.nav button.item.on{background:var(--ungu-mud);color:var(--vi);box-shadow:inset 2px 0 0 var(--ungu)}
.nav button.item.on .ic{color:var(--cy)}
.nav .navfoot{margin-top:auto;padding:12px 8px 4px;border-top:1px solid var(--line)}
main.stage{flex:1;min-width:0;background:var(--bg)}
.screen{display:none;padding:26px 30px 70px;max-width:1180px;margin:0 auto}
.screen.on{display:block;animation:rise .3s ease}
.wrap{max-width:1180px;margin:0 auto;padding:26px 30px 70px}

/* page head */
.phead{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;margin-bottom:20px}
.phead .grow{flex:1;min-width:240px}
h1.h{font-size:22px;font-weight:800;letter-spacing:-.015em;margin:0 0 4px;text-wrap:balance}
.sub{color:var(--mut);font-size:12.5px;margin:0}
.sub+*{margin-top:16px}

/* ============ PRIMITIVES ============ */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:18px;box-shadow:var(--sh-1),var(--kilau)}
.card.tight{padding:14px}
.card.pop{background:var(--card2);border-color:var(--line2)}
h3.sec{font-size:14px;font-weight:800;margin:0 0 12px;display:flex;align-items:center;gap:8px}
h3.sec .ic{color:var(--cy)}
.lbl{font-family:var(--mono);font-size:9px;letter-spacing:.15em;color:var(--dim);text-transform:uppercase;margin:0 0 8px}
.row{display:flex;gap:14px;flex-wrap:wrap}
.grow{flex:1;min-width:260px}
.hr{height:1px;background:var(--line);margin:14px 0;border:0}
.muted{color:var(--mut)} .dim{color:var(--dim)}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:10px;
  border:1px solid var(--line2);background:var(--card2);color:var(--txt);
  padding:9px 16px;font-size:13px;font-weight:700;cursor:pointer;white-space:nowrap;
  transition:transform .16s cubic-bezier(.2,.9,.3,1.1),border-color .18s,background .18s,box-shadow .18s;
}
.btn:hover{border-color:var(--line3);background:var(--raised);text-decoration:none;transform:translateY(-1px)}
.btn:active{transform:translateY(1px)}
.btn.pri{background:var(--emas-isi);border-color:transparent;color:var(--emas-atas);font-weight:800}
.btn.pri:hover{background:var(--emas-isi-2)}
.btn.ok{background:var(--gn);border-color:transparent;color:var(--malam);font-weight:800}
.btn.ghost{background:none;border-color:transparent}
.btn.ghost:hover{background:var(--card);border-color:var(--line)}
.btn.sm{padding:6px 12px;font-size:11.5px;border-radius:8px;gap:6px}
.btn.sm .ic{width:14px;height:14px}
.btn.danger{color:var(--rd);border-color:var(--merah-mud)}
.btn.danger:hover{background:var(--merah-mud);border-color:var(--rd)}
.btn.blok{width:100%}

.badge{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9.5px;padding:2.5px 9px;border-radius:99px;font-weight:600;letter-spacing:.03em;vertical-align:1px}
.badge i{width:6px;height:6px;border-radius:50%;background:currentColor;display:inline-block}
.b-cy{background:var(--ungu-mud);color:var(--vi)} .b-gn{background:var(--hijau-mud);color:var(--gn)}
.b-am{background:var(--kuning-mud);color:var(--am)} .b-rd{background:var(--merah-mud);color:var(--rd)}
.b-mut{background:var(--raised);color:var(--mut)} .b-pk{background:#3A1A2C;color:var(--pk)}
.b-vi{background:var(--ungu-mud);color:var(--vi)}

input.in,textarea.in,select.in{width:100%;background:var(--field);border:1px solid var(--line2);border-radius:10px;color:var(--txt);padding:10px 13px;font-size:13px;font-family:var(--sans);outline:none;transition:.15s}
input.in::placeholder,textarea.in::placeholder{color:var(--dim)}
input.in:hover,textarea.in:hover{border-color:var(--line3)}
input.in:focus,textarea.in:focus,select.in:focus{border-color:var(--cy);box-shadow:var(--ring)}
.field{margin-bottom:13px}
.field label{display:block;font-size:11.5px;font-weight:700;color:var(--mut);margin-bottom:6px}
.check{display:flex;gap:9px;align-items:flex-start;font-size:11.5px;color:var(--mut);cursor:pointer}
.check input{accent-color:var(--cy);margin-top:2px}

/* Sakelar ini hampir selalu diikuti label teks, tapi kotaknya dipatok 38px
   dan rel-nya dipasang inset:0 — jadi teksnya jatuh DI LUAR kotak dan menimpa
   sakelar di sebelahnya. Tidak terlihat selama labelnya pendek; begitu label
   Inggris yang lebih panjang masuk, tiga sakelar bertumpuk jadi satu gumpalan.
   Sekarang kotaknya ikut lebar labelnya, dan relnya jadi anak berukuran tetap. */
.switch{position:relative;display:inline-flex;align-items:center;gap:9px;
  min-height:21px;flex:none;cursor:pointer;font-size:12.5px;color:var(--mut)}
.switch input{position:absolute;left:0;top:0;opacity:0;width:38px;height:21px;margin:0;cursor:pointer}
.switch i{position:relative;flex:none;width:38px;height:21px;background:var(--tepi-2);
  border-radius:99px;transition:.18s;pointer-events:none}
.switch i:before{content:"";position:absolute;top:3px;left:3px;width:15px;height:15px;border-radius:50%;background:var(--krem);transition:.18s}
.switch input:checked + i{background:var(--emas-isi)}
.switch input:checked + i:before{left:20px;background:var(--malam)}

.toast{position:fixed;bottom:22px;left:50%;transform:translateX(-50%) translateY(90px);z-index:300;opacity:0;background:var(--malam-4);border:1px solid var(--line2);color:var(--txt);border-radius:12px;padding:11px 18px;font-size:12.5px;font-weight:600;transition:.28s cubic-bezier(.2,.9,.3,1.2);max-width:min(560px,90vw);box-shadow:var(--sh-2);display:flex;gap:9px;align-items:center}
.toast .ic{color:var(--gn)}
.toast.on{transform:translateX(-50%) translateY(0);opacity:1}

.modal-back{position:fixed;inset:0;background:rgba(28,34,64,.38);backdrop-filter:blur(5px);z-index:100;display:none;align-items:center;justify-content:center;padding:20px}
.modal-back.on{display:flex}
.modal{background:var(--card2);border:1px solid var(--line2);border-radius:var(--r-lg);max-width:430px;width:100%;padding:24px;position:relative;box-shadow:var(--sh-2);animation:rise .22s ease}
.modal .x{position:absolute;top:12px;right:12px}

table.t{border-collapse:collapse;width:100%;font-size:12.5px}
table.t th{font-family:var(--mono);font-size:9px;letter-spacing:.12em;color:var(--dim);text-align:left;padding:9px 10px;border-bottom:1px solid var(--line2);text-transform:uppercase;white-space:nowrap}
table.t td{padding:10px;border-bottom:1px solid var(--line);vertical-align:middle}
table.t tbody tr{transition:.12s}
table.t tbody tr:hover{background:var(--malam-4)}
table.t tr:last-child td{border-bottom:0}
.tblwrap{overflow-x:auto}

.kv{display:flex;justify-content:space-between;gap:12px;font-size:12px;padding:6px 0;border-bottom:1px dashed var(--line)}
.kv:last-child{border-bottom:0}
.kv b{font-family:var(--mono);font-weight:600;text-align:right}

.statgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(185px,1fr));gap:12px;margin-bottom:14px}
.stat{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:14px 16px;box-shadow:var(--sh-1);transition:.18s}
.stat:hover{border-color:var(--line2);box-shadow:var(--sh-2);transform:translateY(-2px)}
.stat .top{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px}
.stat .l{font-size:11px;color:var(--mut);font-weight:600}
.stat .icw{width:30px;height:30px;border-radius:9px;background:var(--cy-deep);display:flex;align-items:center;justify-content:center}
.stat .icw .ic{width:15px;height:15px;color:var(--cy)}
.stat .v{font-family:var(--mono);font-size:21px;font-weight:600;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.stat .d{font-family:var(--mono);font-size:10px;color:var(--gn);margin-top:3px;display:flex;align-items:center;gap:4px}
.stat .d .ic{width:11px;height:11px}


/* ============ HALAMAN PUBLIK (bersama) ============
   Dipakai halaman muka, jelajah, dan papan suara langsung. */
.lnav{
  display:flex;align-items:center;gap:22px;height:64px;
  padding:0 max(20px,calc(50vw - 620px));background:var(--kaca);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:60;
}
.lnav a.nl{color:var(--mut);font-size:13px;font-weight:600;white-space:nowrap}
.lnav a.nl:hover{color:var(--txt);text-decoration:none}
.lnav .nl.on{color:var(--cy);font-weight:700}

/* Kartu jelajah: satu petak per survey / event / program undian. */
.fgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:14px}
.fcard{
  position:relative;display:block;background:var(--card);border:1px solid var(--line);
  border-radius:var(--r);padding:18px;color:var(--txt);box-shadow:var(--sh-1);
  transition:transform .2s cubic-bezier(.2,.9,.3,1),border-color .2s,box-shadow .2s;
}
.fcard:hover{transform:translateY(-3px);border-color:var(--line2);box-shadow:var(--sh-2);text-decoration:none}
.fcard .icw{
  width:38px;height:38px;border-radius:11px;display:flex;align-items:center;
  justify-content:center;margin-bottom:12px;
}
.fcard b{display:block;font-size:14.5px;line-height:1.35;margin-bottom:6px;padding-right:26px}
.fcard p{margin:0;font-size:12.5px;line-height:1.6;color:var(--mut)}
/* Panah sudut: diam sampai kartunya disentuh, lalu bergeser sedikit keluar. */
.fcard .go{
  position:absolute;top:16px;right:16px;color:var(--dim);
  transition:transform .2s cubic-bezier(.2,.9,.3,1.3),color .2s;
}
.fcard:hover .go{color:var(--cy);transform:translate(3px,-3px)}

/* ============ DONASI PUBLIK ============ */
.creator-head{display:flex;gap:16px;align-items:center;margin-bottom:20px;flex-wrap:wrap}
.qa-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-bottom:12px}
.qa{background:var(--field);border:1px solid var(--line2);border-radius:10px;padding:10px 4px;text-align:center;font-weight:800;cursor:pointer;font-size:13px;transition:.15s}
.qa small{display:block;font-weight:600;color:var(--dim);font-size:9px}
.qa:hover{border-color:var(--line3)}
.qa.on{border-color:var(--emas);background:var(--emas-mud);color:var(--emas);box-shadow:inset 0 0 0 1px var(--emas)}
.pay-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.pay{display:flex;align-items:center;gap:10px;background:var(--field);border:1px solid var(--line2);border-radius:11px;padding:10px 12px;cursor:pointer;transition:.15s}
.pay:hover{border-color:var(--line3)}
.pay.on{border-color:var(--ungu);background:var(--ungu-mud);box-shadow:inset 0 0 0 1px var(--ungu)}
/* Plat lambang kanal. Lebarnya 44, bukan persegi 32: lambang QRIS dan DANA
   berupa tulisan yang lebar, dan dipaksa masuk kotak persegi keduanya
   mengecil sampai tidak terbaca lagi sebagai nama. Lebih lebar dari itu dan
   nama kanalnya sendiri yang terpotong — "ShopeePay" jadi "Shopee…".

   Dasarnya putih tetap, bukan token tema. Keempat lambangnya berwarna dan
   dirancang untuk dasar terang; di atas kartu gelap, DANA yang biru dan
   ShopeePay yang jingga tua hampir hilang. */
/* Isinya tinggal nama kanalnya. Boleh melipat sampai dua baris — "Virtual
   Account" tidak muat sebaris di ubin selebar ini, dan nama yang dipotong
   elipsis ("Virtual Ac…") lebih buruk daripada nama yang melipat.

   Yang menjaga petaknya tetap rata bukan larangan melipat, melainkan tinggi
   minimum yang sama untuk semua ubin: yang satu baris dan yang dua baris
   sama-sama setinggi platnya. */
.pay{min-height:54px}
.pay .isi{min-width:0}
.pay .isi > b{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.3}

/* Keterangan di bawah petak, bukan di dalam ubinnya. */
.pay-catatan{
  margin:9px 0 0;display:flex;flex-wrap:wrap;gap:4px 14px;
  font-size:11px;line-height:1.5;color:var(--dim)}
.pay-catatan b{color:var(--mut);font-weight:600}

.pay .pico{width:44px;height:30px;border-radius:7px;flex:none;
  display:flex;align-items:center;justify-content:center;padding:4px 5px;
  background:#FFFFFF;box-shadow:inset 0 0 0 1px rgba(0,0,0,.06)}
.pay .pico img{max-width:100%;max-height:100%;display:block}
.pay .pico .ic{width:20px;height:20px}
.pay b{font-size:12.5px}
.pay small{display:block;color:var(--dim);font-size:10px}
.sumline{display:flex;justify-content:space-between;font-size:12.5px;color:var(--mut);padding:3px 0}
.sumline.tot{color:var(--txt);font-weight:800;font-size:15px;border-top:1px dashed var(--line2);margin-top:6px;padding-top:10px}
.gift-note{display:flex;gap:9px;align-items:center;background:var(--hijau-mud);border:1px solid var(--gn);border-radius:10px;padding:9px 13px;font-size:11.5px;color:var(--gn);margin-top:12px}
.feed{max-height:330px;overflow-y:auto}
.feed .f{display:flex;gap:10px;padding:11px 0;border-bottom:1px solid var(--line);align-items:flex-start}
.feed .f:last-child{border-bottom:0}
.feed .amt{font-family:var(--mono);font-weight:600;color:var(--gn);white-space:nowrap;font-size:12.5px}
.feed .who b{font-size:13px}
.feed .who p{margin:2px 0 0;color:var(--mut);font-size:12px}
.livechip{display:inline-flex;align-items:center;gap:7px;font-size:11.5px;font-weight:700;color:var(--rd);background:var(--merah-mud);border:1px solid var(--rd);border-radius:99px;padding:5px 12px}
.livechip .dot{width:7px;height:7px;border-radius:50%;background:var(--rd);animation:pulse 1.4s infinite}

/* Kotak QR sengaja tetap terang. Pemindai butuh modul gelap di atas dasar
   terang; membalikkannya membuat QR-nya tidak terbaca sebagian alat. */
/* Kotak kode QR di halaman pembayaran.

   Dulu ia bukan kotak melainkan KISI: 21×21 sel CSS yang diisi <i> untuk
   menggambar sesuatu yang menyerupai kode QR. Kodenya sekarang sungguhan dan
   datang sebagai satu SVG — yang membawa ukuran alaminya sendiri, 240px,
   sementara kisinya meninggalkan kotak 196px. Yang terjadi bukan kode yang
   terpotong melainkan kode yang meluber keluar kotak putihnya dan menimpa
   keterangan kedaluwarsa di bawahnya.

   Tingginya sekarang mengikuti isinya, bukan dipatok: kode QR selalu persegi,
   dan tinggi tetap hanya menunggu satu versi kode yang nisbahnya tidak
   kebetulan cocok. */
.qrbox{
  width:232px;margin:18px auto 10px;padding:12px;line-height:0;
  background:#FFFFFF;border-radius:16px;box-shadow:var(--sh-2)}
.qrbox svg{width:100%;height:auto;display:block}
.paywait{display:flex;align-items:center;justify-content:center;gap:8px;color:var(--am);font-size:12px;font-weight:600}
.paywait .dot{width:8px;height:8px;border-radius:50%;background:var(--am);animation:pulse 1s infinite}
@keyframes pulse{50%{opacity:.25}}
.paid-ok{display:none;text-align:center}
.paid-ok .okc{width:56px;height:56px;border-radius:50%;background:rgba(52,211,153,.15);display:flex;align-items:center;justify-content:center;margin:4px auto 10px}
.paid-ok .okc .ic{width:28px;height:28px;color:var(--gn)}

/* ============ OVERLAY OBS ============ */
/* Token tampilan overlay. Nilai di sini adalah BAWAAN; kalau kreator sudah
   menyetel temanya, halaman overlay menimpanya lewat style di #obsStage.
   Warnanya harfiah dan tidak ikut tema terang/gelap aplikasi: overlay selalu
   digubah di atas gambar siaran, bukan di atas halaman Apresia. */
.obs{--ov-font:"Plus Jakarta Sans",Arial,sans-serif;--ov-teks:#F3EDE1;--ov-teks-2:#BDB3CE;
  --ov-aksen:#9B8BFF;--ov-panel:rgba(12,9,24,.88);--ov-tepi:#3A2F63;--ov-radius:12px;
  --ov-skala:1;--ov-bayang:0 1px 3px rgba(0,0,0,.85), 0 0 10px rgba(0,0,0,.55);
  font-family:var(--ov-font);
  position:relative;color:var(--ov-teks);border-radius:var(--r-lg);overflow:hidden;border:1px solid #3A2F63;height:520px;background:linear-gradient(160deg,#1A1430 0%,#0C0918 45%,#150F28 100%);box-shadow:var(--sh-2)}
.obs .game{position:absolute;inset:0;background:radial-gradient(circle at 70% 30%, rgba(129,140,248,.10), transparent 45%),radial-gradient(circle at 20% 80%, rgba(244,114,182,.08), transparent 40%)}
.obs .hud{position:absolute;left:14px;top:12px;font-family:var(--mono);font-size:10px;color:#8A80A3}
.ov-alert{position:absolute;left:50%;top:52px;transform:translateX(-50%) scale(.85);opacity:0;transition:.3s cubic-bezier(.2,.9,.3,1.25);z-index:5;background:var(--ov-panel);border:1.5px solid var(--ov-aksen);border-radius:calc(var(--ov-radius) + 4px);padding:16px 26px;text-align:center;min-width:330px;width:var(--papan-lebar,auto);box-shadow:0 0 44px color-mix(in srgb, var(--ov-aksen) 35%, transparent)}
.ov-alert.show{opacity:1;transform:translateX(-50%) scale(1)}
.ov-alert .who{font-size:calc(17px * var(--ov-skala));font-weight:800;color:var(--ov-teks);text-shadow:var(--ov-bayang)}
.ov-alert .who span{color:var(--ov-aksen)}
.ov-alert .msg{color:var(--ov-teks-2);font-size:calc(12.5px * var(--ov-skala));margin-top:4px;text-shadow:var(--ov-bayang)}
.ov-alert .tts{margin-top:8px;font-family:var(--mono);font-size:9.5px;color:var(--gn)}
.ov-milestone{position:absolute;left:14px;bottom:64px;width:var(--papan-lebar,290px);background:rgba(12,9,24,.9);border:1px solid var(--line);border-radius:12px;padding:10px 12px;backdrop-filter:blur(4px)}
/* Di dalam panggung, tampilannya ikut tema milik kreator. Di luar panggung —
   halaman donasi publik memakai kelas yang sama untuk bilah milestone-nya —
   token --ov-* tidak ada, dan aturan yang memakainya akan batal diam-diam:
   bilah progresnya sempat menjadi transparan sepenuhnya karena ini. */
.obs .ov-milestone{background:var(--ov-panel);border-color:var(--ov-tepi);
  border-radius:var(--ov-radius);color:var(--ov-teks)}
.ov-milestone .bar{height:9px;border-radius:99px;background:var(--inset);margin-top:7px;overflow:hidden}
.obs .ov-milestone .bar{background:var(--ov-tepi)}
.ov-milestone .bar i{display:block;height:100%;width:68%;background:var(--grad);border-radius:99px}
.obs .ov-milestone .bar i{background:var(--ov-aksen)}
.ov-run{position:absolute;left:0;right:0;bottom:0;width:var(--papan-lebar,100%);background:var(--ov-panel);border-top:1px solid var(--ov-tepi);padding:6px 0;overflow:hidden;white-space:nowrap}
.ov-run .track{display:inline-block;padding-left:100%;animation:marq 18s linear infinite;font-size:calc(11px * var(--ov-skala));color:var(--ov-aksen);text-shadow:var(--ov-bayang)}
@keyframes marq{to{transform:translateX(-100%)}}
.ov-lead{position:absolute;right:16px;top:52px;width:var(--papan-lebar,190px);background:rgba(12,9,24,.9);border:1px solid var(--line);border-radius:12px;padding:10px 12px;font-size:11.5px;backdrop-filter:blur(4px)}
.obs .ov-lead{background:var(--ov-panel);border-color:var(--ov-tepi);
  border-radius:var(--ov-radius);font-size:calc(11.5px * var(--ov-skala))}
/* Nominal tidak boleh patah. Papan selebar 190px membuat "1,00 jt" pecah
   jadi dua baris — "1,00" di atas, "jt" di bawah — dan yang terbaca penonton
   bukan angka lagi. Namanya yang mengalah: ia dipotong dengan elipsis. */
.ov-lead .r{display:flex;justify-content:space-between;align-items:baseline;gap:8px;
  padding:3px 0;color:var(--mut)}
.ov-lead .r b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-lead .r .num{flex:none;white-space:nowrap}
.obs .ov-lead .r{color:var(--ov-teks-2)}
.ov-lead .r b{color:var(--txt);font-weight:600}
.obs .ov-lead .r b{color:var(--ov-teks)}
/* Kotak media share.

   Rasionya dikunci 16:9 lewat aspect-ratio, bukan tinggi tetap. Sebelumnya
   kotaknya 297×150 — 1,98:1 — sementara videonya 16:9, jadi YouTube
   menambahkan pita hitam tebal di kiri dan kanan setiap kali. Yang terlihat
   penonton bukan videonya, melainkan bingkai hitam dengan video kecil di
   tengahnya. */
.ov-media{position:absolute;left:50%;top:170px;transform:translateX(-50%);width:330px;pointer-events:none;
  display:none;z-index:4;background:#000;border:1.5px solid var(--ov-aksen);
  border-radius:var(--ov-radius);overflow:hidden;
  box-shadow:0 0 40px color-mix(in srgb, var(--ov-aksen) 28%, transparent)}
.ov-media .vid{position:relative;aspect-ratio:16/9;background:#000;
  display:flex;align-items:center;justify-content:center}
/* Facebook digambar SDK-nya sendiri, dan selalu pada ukuran ASLI videonya:
   satu Reels tegak keluar 327×581 di dalam kotak 327×184, jadi yang tampak
   hanya sepertiga atasnya. Diukur di overlay sungguhan, bukan diduga — yang
   tampil dahi orang, bukan videonya.

   Kotak media overlay 16:9, dan bentuknya tidak boleh ikut berubah mengikuti
   kiriman orang asing: ukuran dan posisinya sudah diatur kreator di konsol.
   Jadi pembungkusnya yang dikecilkan sampai muat — lihat muatkanFacebook(). */
.ov-media .vid .fb-video{position:absolute;inset:0;overflow:hidden}
.ov-media .vid .fb-video>span{position:absolute;top:0;left:0}
.ov-media .vid iframe{position:absolute;inset:0;width:100%;height:100%;border:0;
  /* Tanpa tetikus tidak ada hover, dan tanpa hover YouTube tidak pernah
     memunculkan bilah judul maupun tombol putar/jedanya. Sekaligus menjamin
     videonya tidak bisa terjeda oleh klik yang tidak disengaja. */
  pointer-events:none}
.ov-media .vid .ic{width:38px;height:38px;color:var(--ov-aksen);opacity:.7}
/* Kelasnya `ket`, bukan `cap`.

   `.cap` sudah dipakai sebagai pil kecil berwarna ungu di tempat lain, dan
   aturan itu membawa display:inline-flex serta border-radius:99px. Keterangan
   media share karenanya tampil sebagai pil mengambang di bawah video — bukan
   pita selebar kotaknya — dan aturan di sini tidak pernah menimpanya karena
   hanya mengubah warna dan padding. */
.ov-media .ket{display:block;padding:6px 10px;font-size:calc(10px * var(--ov-skala));
  font-family:var(--mono);letter-spacing:.04em;color:var(--ov-teks-2);
  background:var(--ov-panel);border-top:1px solid var(--ov-tepi);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ── latar panggung: terang atau gelap ──
   Overlay digubah di atas gambar siaran, dan gambar siaran tidak selalu
   gelap. Panggung yang selamanya gelap membuat garis luar teks dan kepekatan
   panel disetel dengan satu-satunya keadaan yang tidak pernah mengujinya. */
.obs.terang{
  border-color:#CDD4E4;
  background:linear-gradient(160deg,#F4F7FD 0%,#E6EBF6 45%,#FBF7F0 100%)}
.obs.terang .game{
  background:radial-gradient(circle at 70% 30%, rgba(99,102,241,.16), transparent 45%),
             radial-gradient(circle at 20% 80%, rgba(244,114,182,.14), transparent 40%)}
.obs.terang .hud{color:#6B6480}

.latar-pilih{
  display:inline-flex;gap:2px;padding:2px;flex:none;
  border-radius:999px;border:1px solid var(--line2);background:var(--field)}
.latar-pilih button{
  display:inline-flex;align-items:center;gap:6px;cursor:pointer;border:0;
  background:none;font-family:inherit;font-size:11.5px;font-weight:600;
  color:var(--mut);padding:5px 11px;border-radius:999px;
  transition:background .16s,color .16s}
.latar-pilih button:hover{color:var(--txt)}
.latar-pilih button.on{
  background:var(--raised);color:var(--txt);box-shadow:inset 0 0 0 1px var(--line2)}
/* Petaknya memperlihatkan latar yang dipilihnya, bukan ikon yang
   menggambarkannya — tidak ada matahari dan bulan di sprite ini, dan yang
   ditanyakan tombolnya memang "latarnya seperti apa". */
.latar-pilih i{width:12px;height:12px;border-radius:50%;flex:none}
.latar-pilih [data-latar=gelap] i{
  background:linear-gradient(135deg,#1A1430,#0C0918);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.16)}
.latar-pilih [data-latar=terang] i{
  background:linear-gradient(135deg,#FBFCFF,#E2E7F3);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.18)}

/* --- letak papan yang diseret ------------------------------------------- */
/* Geseran dipasang lewat --geser-x/--geser-y, bukan `transform` inline.
   Kotak alert memakai transform yang sama untuk animasi munculnya — ia mengecil
   lalu membesar — dan transform inline dari skrip seret akan menghapus animasi
   itu diam-diam. Di sini keduanya dirangkai: geseran di depan, skala di
   belakang. Nilai bawaannya = letak rancangan papan, jadi papan yang belum
   pernah diseret tidak berubah sedikit pun. */
.obs .ov-lead,.obs .ov-antre,.obs .ov-milestone,.obs .ov-run,.obs .ov-qr{
  transform:translate(var(--geser-x,0),var(--geser-y,0))}
/* Kotak kode di halaman klaim.

   Besar, berjarak, dan monospace — diketik dari ingatan beberapa detik
   sesudah melihatnya di layar seberang, sering sambil berjalan. Yang mahal
   di sini bukan keindahan melainkan salah ketik yang tidak terlihat. */
.in.kode-besar{
  font-family:var(--mono);font-size:34px;font-weight:700;letter-spacing:.3em;
  text-align:center;padding:14px 10px;width:100%;
}
.in.kode-besar::placeholder{letter-spacing:.3em;opacity:.3}

/* ─────────────────────── Tonton & Klaim ───────────────────────

   Papan iklan muncul sebentar lalu hilang. Semua ukurannya memakai
   var(--ov-skala) seperti papan lain, supaya kreator yang mengecilkan
   panggungnya tidak mendapat satu papan yang tetap besar sendiri.

   Lebar QR-nya tetap dalam piksel panggung, bukan persen: kode QR yang
   mengecil mengikuti lebar papan berhenti bisa dipindai pada satu titik,
   dan titik itu tidak terlihat sampai ada yang mencoba memindainya. */
.ov-iklan{
  /* Di atas papan yang menetap, di bawah kotak alert (z-index 5).

     Papan ini muncul beberapa detik lalu hilang, dan yang dibawanya QR yang
     harus sempat dipindai orang. Tanpa z-index ia digambar menurut urutannya
     di panggung — dan di sana ia berdiri sebelum milestone, jadi milestone
     menutupinya. Diukur di pratinjau, bukan dikira: kotaknya benar-benar
     bertabrakan dan yang menang papan yang menetap.

     Alert tetap di atasnya. Kalau donasi dan kode iklan datang bersamaan,
     yang berhak atas perhatian penonton lebih dulu adalah orang yang baru
     saja mengirim uang. */
  z-index:4;
  position:absolute;left:50%;top:60%;display:flex;
  gap:calc(12px * var(--ov-skala));align-items:center;
  padding:calc(12px * var(--ov-skala)) calc(14px * var(--ov-skala));
  border-radius:var(--ov-radius);
  background:var(--ov-panel);
  border:1px solid var(--ov-tepi);
  width:var(--papan-lebar,auto);
  /* Pergeseran hasil seret dan skala animasi dirangkai dalam SATU transform,
     persis seperti .ov-alert. Memakai properti `translate` terpisah untuk
     animasinya akan menghapus posisi yang sudah ditata kreator tanpa
     bersuara — PanggungService::posisi() mengirim pergeserannya sebagai
     --geser-x/--geser-y justru supaya jebakan itu bisa dihindari. */
  transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(.92);
  opacity:0;transition:.28s cubic-bezier(.2,.9,.3,1.25);
}
.ov-iklan.tampil{opacity:1;transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(1)}
.ov-iklan[hidden]{display:none}
/* ─────────────────────────────────────────────────────────────────────
   Isi papan iklan.

   Semua kelas di dalamnya berawalan `ik-`, dan itu bukan selera penamaan.
   Sebelumnya isinya bernama .qr .isi .logo .brand .kode .poin .bar — nama
   yang semuanya sudah dipakai komponen LAIN di berkas ini, dan tiga di
   antaranya benar-benar bocor ke papan:

     .brand   { padding:6px 8px 16px }   → 22px udara liar di antara logo,
                                           nama brand, dan kodenya, plus 8px
                                           indentasi yang membuat nama brand
                                           tidak sejajar dengan apa pun
     .logo    { width:30px;height:30px } → dikalahkan .ov-iklan .logo, tapi
                                           display dan flex-nya tetap lewat
     .bar > i { transition:width .35s }  → bilah hitung mundur jadi TERTINGGAL
                                           dari waktu sebenarnya, persis yang
                                           dilarang komentar di bawah

   Yang ketiga bukan soal kerapian. Aturan papan tidak menyetel `transition`,
   jadi ia tidak menimpanya — dan `.ov-iklan .bar i` yang lebih kuat tetap
   kalah untuk properti yang tidak disebutnya. Jenis kegagalan yang tidak
   muncul di mana pun kecuali sebagai "kok begini ya".

   Awalan `ik-` membuat seluruh keluarga masalah ini tidak bisa terjadi lagi,
   bukan menambal ketiga instansnya satu per satu.
   ───────────────────────────────────────────────────────────────────── */

/* Setinggi kolom isinya, bukan 96px tetap.

   Dua alasan, dan yang kedua lebih penting daripada rupanya: kartu jadi
   seimbang alih-alih menyisakan pita kosong di atas dan bawah QR, DAN kode
   QR yang lebih besar lebih mudah dipindai dari rekaman siaran — yang sampai
   ke mata penonton bukan QR ini melainkan hasil kompresi video atas QR ini. */
.ov-iklan .ik-qr{
  width:calc(116px * var(--ov-skala));height:calc(116px * var(--ov-skala));
  flex:none;background:var(--qr-latar,#fff);border-radius:calc(10px * var(--ov-skala));
  padding:calc(6px * var(--ov-skala));display:flex;align-items:center;justify-content:center;
}
.ov-iklan .ik-qr svg{width:100%;height:100%;display:block}
.ov-iklan .ik-qr .ic{width:40%;height:40%;color:#0C0918;opacity:.35}

.ov-iklan .ik-isi{
  display:flex;flex-direction:column;align-items:flex-start;
  gap:calc(4px * var(--ov-skala));
  min-width:calc(136px * var(--ov-skala));
  /* Batas atas, dan ini bukan kehati-hatian teoretis. Nama brand boleh
     sampai 80 karakter, dan tanpa batas ini ia merentang kolom: diukur di
     papan sungguhan, nama 55 karakter membuat papan melar dari 294 ke 534
     piksel.

     Yang rusak bukan papannya melainkan letaknya. Kreator menata posisi papan
     di pratinjau dengan satu kampanye, lalu kampanye berikutnya menggeser
     seluruh papan keluar dari tempat yang ia pilih — dan tidak ada yang
     menghubungkan kejadian itu dengan panjang nama brand. */
  max-width:calc(180px * var(--ov-skala));
}

/* Logo brand. Tingginya yang dipatok, lebarnya mengikuti — berkasnya
   disimpan dengan nisbah aslinya (GambarIklan memuat, tidak memotong), jadi
   memaksa lebar akan merentang wordmark dan menggepengkan lambang persegi.

   max-width menjaga wordmark yang sangat panjang tidak mendorong lebar
   seluruh papan melewati sisi layar. object-fit:contain yang menengahkannya
   di dalam batas itu kalau sampai kena. */
.ov-iklan .ik-logo{
  /* 26px, bukan 17px. Pada 17px baris kedua wordmark — yang hampir selalu
     berisi kategorinya, "COFFEE", "STUDIO", "LABS" — menjadi noda sebelum
     video dikompresi, apalagi sesudah. Masih di bawah kodenya yang 38px:
     yang harus terbaca dari seberang ruangan tetap kodenya. */
  height:calc(26px * var(--ov-skala));
  /* Setara min-width .ik-isi, jadi logo selebar apa pun tidak pernah
     mendorong lebar papan melewati yang sudah ditata kreator di pratinjau. */
  width:auto;max-width:calc(136px * var(--ov-skala));
  object-fit:contain;object-position:left center;
  display:block;
}
.ov-iklan .ik-logo[hidden]{display:none}

.ov-iklan .ik-brand{
  /* Satu baris, dipotong kalau tidak muat. Dibiarkan membungkus, nama panjang
     menambah tinggi papan — dan tinggi yang berubah-ubah menggeser papan yang
     dijangkarkan dari bawah. Nama yang terpotong masih bisa dibaca penonton;
     papan yang pindah tempat tidak bisa diperbaiki siapa pun dari sana. */
  align-self:stretch;max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-size:calc(10px * var(--ov-skala));letter-spacing:.09em;text-transform:uppercase;
  /* Dipatok, tidak diwarisi. Panggung mewariskan line-height 1.6 dari body,
     dan pada teks 10px itu menyisakan 6px udara yang tidak dimaksudkan
     siapa pun. */
  line-height:1.3;
  color:var(--ov-teks-2);
}

/* Kode adalah satu-satunya hal di papan ini yang harus terbaca dari seberang
   ruangan, lewat kamera, dalam beberapa detik. Karena itu ia yang paling
   besar, bukan nama brandnya. */
.ov-iklan .ik-kode{
  font-family:var(--mono);font-size:calc(40px * var(--ov-skala));font-weight:700;
  line-height:1.05;letter-spacing:.14em;color:var(--ov-aksen);
  /* Jarak huruf menempel juga SESUDAH angka terakhir, jadi tepi kanannya
     menggantung .14em lebih jauh daripada baris lain di kolom yang sama.
     Tidak kelihatan sebagai kesalahan, cuma sebagai kolom yang tidak rapi. */
  margin-right:-.14em;
}

.ov-iklan .ik-uji{
  margin-top:calc(1px * var(--ov-skala));
  padding:calc(1px * var(--ov-skala)) calc(6px * var(--ov-skala));
  border-radius:99px;border:1px solid var(--ov-aksen);
  font-family:var(--mono);font-size:calc(8.5px * var(--ov-skala));
  letter-spacing:.14em;color:var(--ov-aksen);
}
.ov-iklan .ik-uji[hidden]{display:none}

.ov-iklan .ik-poin{font-size:calc(11.5px * var(--ov-skala));line-height:1.3;color:var(--ov-teks);opacity:.85}

.ov-iklan .ik-bar{
  /* Melebar penuh kolomnya. Sebagai anak flex yang align-items-nya
     flex-start, ia akan menyusut ke nol tanpa baris ini — bilah selebar nol
     tidak menggambar apa pun, dan tidak ada yang akan menyebutnya rusak. */
  align-self:stretch;
  height:calc(3px * var(--ov-skala));border-radius:99px;
  margin-top:calc(3px * var(--ov-skala));
  background:var(--ov-tepi);overflow:hidden;
}
.ov-iklan .ik-bar i{
  display:block;height:100%;width:100%;border-radius:99px;
  background:var(--ov-aksen);
  /* Tanpa transisi: lebarnya disetel tiap 100 ms, dan transisi di atas
     pembaruan secepat itu membuat bilahnya tertinggal dari waktu sebenarnya.
     Ditulis tegas, bukan dibiarkan kosong — dibiarkan kosong, ia pernah
     mewarisi transition dari `.bar > i` milik komponen lain. */
  transition:none;
}
.obs .ov-alert{transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(.85)}
.obs .ov-alert.show{transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(1)}

/* Pratinjau menggambar SEMUA papan, termasuk yang sakelarnya mati dan kotak
   alert yang di siaran baru muncul saat ada donasi. Letak tidak bisa ditata
   untuk sesuatu yang tidak kelihatan. Yang redup adalah yang tidak akan tampil
   di siaran apa adanya sekarang — bedanya harus terbaca sekali lihat. */
.obs.atur .mati{opacity:.32}
.obs.atur .ov-alert.mati{opacity:.2}

/* Di pratinjau kotak alert berdiri pada ukuran PENUHNYA, bukan pada skala .85
   tempat animasinya bermula. Kotak yang digambar 15% lebih kecil daripada
   yang akan tampil di siaran membuat setiap ukuran dan letak yang ditata di
   sini meleset sebesar itu juga — termasuk hitungan pegangan ubah lebar, yang
   mengukur dari kotak di layar.

   Animasi munculnya tidak hilang: ia pindah dari transisi ke keyframe, yang
   punya keadaan awalnya sendiri dan tidak perlu kotaknya mengkerut selama
   menunggu. */
.obs.atur .ov-alert{opacity:.5;transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(1)}
.obs.atur .ov-alert.show{opacity:1;animation:ov-muncul .32s cubic-bezier(.2,.9,.3,1.25) both}

/* Papan iklan di PRATINJAU, dengan alasan yang sama seperti kotak alert di
   atasnya: di siaran ia lahir tak terlihat dan baru muncul saat ada kode,
   tapi letak tidak bisa ditata untuk sesuatu yang tidak kelihatan.

   Tanpa aturan ini hasilnya terbalik dan membingungkan: papan yang MATI
   tampak (kelas .mati memberinya opacity .32) sementara papan yang NYALA
   lenyap (tidak ada .mati, jadi opacity:0 dasarnya yang berlaku). Kreator
   yang menyalakannya justru melihatnya hilang — dilaporkan persis begitu.

   Skala ikut dikembalikan ke 1: tanpa itu papannya tergambar mengecil,
   seukuran yang tidak pernah benar-benar tampil di siaran. */
.obs.atur .ov-iklan{opacity:.55;transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(1)}
.obs.atur .ov-iklan.mati{opacity:.25}
.obs.atur .ov-iklan.tampil{opacity:1}
@keyframes ov-muncul{
  from{transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(.85)}
  to{transform:translate(var(--geser-x,-50%),var(--geser-y,0)) scale(1)}}

/* Panggung, keadaannya, dan tombol-tombolnya adalah SATU benda, jadi
   digambar sebagai satu kotak: kepala di atas, panggung menempel penuh ke
   tepinya, bilah alat di bawah. Sebelumnya bilah alat mengambang telanjang di
   antara dua kartu, dan yang dikendalikannya jadi tidak jelas. */
.panggung{padding:0;overflow:hidden}
.panggung>.kepala{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:10px 14px;border-bottom:1px solid var(--line)}
.panggung>.kepala .tajuk{font-family:var(--mono);font-size:9px;letter-spacing:.15em;
  color:var(--dim);text-transform:uppercase;margin-right:auto}
.panggung .obs{border-radius:0;border-left:0;border-right:0;box-shadow:none}
/* Keterangan 1920×1080 pindah ke kepala kartu, jadi yang di dalam panggung
   dimatikan: dua label yang sama berjarak 30px, dan yang di dalam menindih
   pojok kiri atas — tempat papan antrean mabar berjangkar. */
.panggung .obs .hud{display:none}
.obs-tools{display:flex;gap:8px;flex-wrap:wrap;align-items:center;
  padding:10px 14px;border-top:1px solid var(--line)}
.obs-tools .petunjuk{flex:1;min-width:210px;display:flex;align-items:center;gap:6px;
  font-size:11.5px;color:var(--dim)}
.obs-tools .tombol{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.conn{display:inline-flex;align-items:center;gap:7px;font-family:var(--mono);font-size:10px;color:var(--gn)}
.conn .dot{width:7px;height:7px;border-radius:50%;background:var(--gn);animation:pulse 1.6s infinite}

.obs .lbl{color:var(--ov-teks-2);opacity:.75;font-family:var(--ov-font)}
.obs .muted,.obs .dim{color:var(--ov-teks-2)}

/* ============ DASHBOARD ============ */
.blur{filter:blur(9px)}
.wgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}
.wg{background:var(--field);border:1px solid var(--line2);border-radius:12px;padding:13px;transition:.15s}
.wg:hover{border-color:var(--line3)}
.wg .top2{display:flex;justify-content:space-between;align-items:center;margin-bottom:7px}
.wg .wt{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:700}
.wg .wt .ic{width:15px;height:15px;color:var(--cy)}
.wg small{color:var(--dim);font-size:10px;display:block;line-height:1.45}
svg.chart{width:100%;height:150px;display:block}
.codebox{font-family:var(--mono);font-size:11px;color:var(--mut);background:var(--inset);border:1px solid var(--line2);border-radius:9px;padding:9px 12px;overflow-x:auto;white-space:nowrap}

/* ============ TABS / SURVEY ============ */
.tabs{display:flex;gap:2px;margin-bottom:18px;border-bottom:1px solid var(--line)}
.tabs button{display:flex;align-items:center;gap:7px;background:none;border:0;border-bottom:2px solid transparent;color:var(--mut);font-weight:700;font-size:13px;padding:9px 15px;cursor:pointer;transition:.15s;margin-bottom:-1px}
.tabs button:hover{color:var(--txt)}
.tabs button.on{color:var(--cy);border-bottom-color:var(--cy)}
.tabpane{display:none}.tabpane.on{display:block;animation:rise .25s ease}
.q{background:var(--field);border:1px solid var(--line2);border-radius:12px;padding:13px 15px;margin-bottom:10px;display:flex;gap:12px;align-items:flex-start;transition:.15s}
.q:hover{border-color:var(--line3)}
.q .no{font-family:var(--mono);color:var(--dim);font-size:11px;padding-top:2px}
.q b{font-size:13px}
.q .meta{margin-top:6px;display:flex;gap:6px;flex-wrap:wrap}
.bar-row{display:flex;align-items:center;gap:10px;margin:8px 0;font-size:12px}
.bar-row .cap{width:130px;color:var(--mut)}
.bar-row .bar{flex:1;height:9px;background:var(--inset);border-radius:99px;overflow:hidden}
.bar-row .bar i{display:block;height:100%;background:var(--grad);border-radius:99px}
.bar-row .pv{font-family:var(--mono);font-size:11px;width:42px;text-align:right}

/* ============ VOTING ============ */
.kand{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px}
.kd{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:16px 14px;text-align:center;transition:.18s}
.kd:hover{border-color:var(--line2);transform:translateY(-2px)}
.kd .kava{width:58px;height:58px;border-radius:50%;margin:0 auto 9px;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:19px;color:var(--malam);box-shadow:var(--sh-1)}
.kd .votes{font-family:var(--mono);font-size:12px;color:var(--cy);margin:4px 0 10px}
.vpk{display:flex;gap:8px;flex-wrap:wrap}
.vp{flex:1;min-width:100px;background:var(--field);border:1px solid var(--line2);border-radius:12px;padding:11px;text-align:center;cursor:pointer;transition:.15s}
.vp:hover{border-color:var(--line3)}
.vp.on{border-color:var(--ungu);background:var(--ungu-mud);box-shadow:inset 0 0 0 1px var(--ungu)}
.vp b{font-size:16px}
.vp small{display:block;color:var(--dim);font-size:10px}
.vp .pr{font-family:var(--mono);font-size:11px;color:var(--gn);margin-top:4px}
.cdown{font-family:var(--mono);color:var(--am);font-size:12px}

/* ============ UNDIAN ============ */
.steps{display:flex;overflow-x:auto;padding-bottom:6px}
.stp{flex:1;min-width:102px;text-align:center;position:relative;padding-top:6px}
.stp .cir{width:28px;height:28px;border-radius:50%;margin:0 auto 7px;display:flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:11px;background:var(--inset);color:var(--dim);border:1px solid var(--line2);position:relative;z-index:1}
.stp .cir .ic{width:13px;height:13px}
.stp.done .cir{background:var(--hijau-mud);color:var(--gn);border-color:var(--gn)}
.stp.now .cir{background:var(--cy-deep);color:var(--cy);border-color:var(--cy);box-shadow:0 0 0 4px rgba(91,77,224,.14)}
.stp:not(:first-child):before{content:"";position:absolute;top:19px;left:-50%;width:100%;height:1.5px;background:var(--line2)}
.stp.done:before{background:var(--gn)}
.stp small{font-size:9.8px;color:var(--mut);display:block;line-height:1.3}
.kupon{display:flex;gap:8px;flex-wrap:wrap}
.kp{font-family:var(--mono);font-size:11px;background:var(--field);border:1px dashed var(--line3);border-radius:8px;padding:6px 11px;color:var(--cy)}
.hashbox{font-family:var(--mono);font-size:10.5px;color:var(--mut);background:var(--inset);border:1px solid var(--line2);border-radius:10px;padding:10px 12px;word-break:break-all}

/* ============ OPS ============ */
.alertrow{display:flex;gap:12px;align-items:flex-start;background:var(--field);border:1px solid var(--line2);border-radius:12px;padding:13px;margin-bottom:10px;transition:.15s}
.alertrow:hover{border-color:var(--line3)}
.alertrow .sev{width:4px;border-radius:99px;align-self:stretch;flex:none}

@media (max-width:880px){
  aside.nav{display:none}
  .screen,.wrap{padding:18px 14px 60px}
  .qa-grid{grid-template-columns:repeat(3,1fr)}
  .gsearch{display:none}
  .crumb{display:none}
}

/* link sidebar (Laravel) meniru button.item */
aside.nav a.item{display:flex;align-items:center;gap:10px;width:100%;color:var(--mut);padding:9px 11px;border-radius:10px;font-size:13px;font-weight:600;transition:.15s}
aside.nav a.item .ic{color:var(--dim);transition:.15s}
aside.nav a.item:hover{background:var(--card);color:var(--txt);text-decoration:none}
aside.nav a.item:hover .ic{color:var(--mut)}
aside.nav a.item.on{background:var(--ungu-mud);color:var(--vi);box-shadow:inset 2px 0 0 var(--ungu)}
aside.nav a.item.on .ic{color:var(--cy)}

/* ── sub-menu ──
   Satu-satunya kelompok bertingkat di menu ini: lima papan overlay.

   Garis tegak di kiri, bukan lekukan saja. Lekukan sendirian mudah terbaca
   sebagai kesalahan penataan; garis mengatakan "yang ini milik yang di atas"
   tanpa satu kata pun.

   Ikonnya sengaja tidak ada. Lima ikon kecil berjajar di bawah satu ikon
   besar membuat keduanya terbaca setara — dan yang harus terbaca justru
   bahwa mereka TIDAK setara. */
/* ── kelompok menu yang bisa diciutkan ──
   Memakai <details>/<summary>, jadi buka-tutupnya bawaan peramban. */
aside.nav .navgrup{margin:0}
aside.nav .navgrup > summary{
  display:flex;align-items:center;gap:10px;width:100%;
  color:var(--mut);padding:9px 11px;border-radius:10px;
  font-size:13px;font-weight:600;cursor:pointer;transition:.15s;
  list-style:none}
/* Segitiga bawaan dibuang di kedua mesin peramban. Tanpa ini ia berdiri di
   kiri ikon dan mendorong seluruh baris keluar dari kesejajaran dengan menu
   lain yang tidak punya anak. */
aside.nav .navgrup > summary::-webkit-details-marker{display:none}
aside.nav .navgrup > summary::marker{content:''}
aside.nav .navgrup > summary .ic{color:var(--dim);transition:.15s}
aside.nav .navgrup > summary .grow{flex:1;min-width:0}
aside.nav .navgrup > summary:hover{background:var(--card);color:var(--txt)}
aside.nav .navgrup > summary:hover .ic{color:var(--mut)}
aside.nav .navgrup > summary.on{
  background:var(--ungu-mud);color:var(--vi);box-shadow:inset 2px 0 0 var(--ungu)}
aside.nav .navgrup > summary.on .ic{color:var(--cy)}
/* Fokus papan ketik harus terlihat: ini satu-satunya kendali di menu ini yang
   tidak berpindah halaman, jadi tidak ada perubahan lain yang menandainya. */
aside.nav .navgrup > summary:focus-visible{outline:2px solid var(--ungu);outline-offset:-2px}

/* Anak panah menghadap bawah saat tertutup, ke atas saat terbentang —
   arahnya mengatakan ke mana isinya akan pergi, bukan di mana ia sekarang. */
aside.nav .navgrup .chev{
  flex:none;width:14px;height:14px;opacity:.6;transition:rotate .18s ease}
aside.nav .navgrup[open] .chev{rotate:180deg}

aside.nav .subnav{
  display:flex;flex-direction:column;gap:1px;
  margin:2px 0 4px 22px;padding-left:11px;
  border-left:1px solid var(--line2)}

/* Wajib disembunyikan dengan tangan.

   Peramban menyembunyikan isi <details> yang tertutup lewat aturan bawaannya
   sendiri — dan aturan bawaan kalah dari aturan mana pun di berkas ini.
   `display:flex` di atas cukup untuk mengalahkannya, jadi tanpa baris ini
   menunya tetap terbentang saat diciutkan: panahnya berputar, keadaannya
   tersimpan, dan tidak ada satu pun yang bergerak di layar. */
aside.nav .navgrup:not([open]) > .subnav{display:none}
aside.nav .subitem{
  padding:6px 10px;border-radius:8px;
  font-size:12.5px;font-weight:600;color:var(--dim);
  transition:color .15s,background .15s}
aside.nav .subitem:hover{color:var(--txt);background:var(--card);text-decoration:none}
aside.nav .subitem.on{color:var(--vi);background:var(--ungu-mud)}

.appbar form{display:flex}

/* ============================================================
   POLISH PASS — kedalaman, hierarki, dan detail interaksi
   ============================================================ */

/* --- scrollbar: tipis & gelap, tidak lagi batang putih --- */
*{scrollbar-width:thin;scrollbar-color:var(--tepi-3) transparent}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--tepi-2);border-radius:99px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--tepi-3);background-clip:content-box}

/* --- kartu: kedalaman lebih kaya + angkat halus saat hover --- */
.card{transition:border-color .18s, transform .18s, box-shadow .18s}
.card:hover{border-color:var(--line2)}
.stat{position:relative;overflow:hidden}
.stat::after{                       /* garis merek tipis di tepi atas */
  content:"";position:absolute;inset:0 0 auto;height:2px;
  background:var(--grad);opacity:.55
}
.stat:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}

/* --- angka besar: hierarki lebih tegas --- */
.stat .v{font-size:23px;letter-spacing:-.02em;line-height:1.15}
.stat .l{letter-spacing:.005em}
h1.h{letter-spacing:-.02em}

/* --- progress bar: nilai kecil tetap terbaca + glow --- */
.ov-milestone .bar{box-shadow:inset 0 1px 2px rgba(20,26,48,.10)}
.obs .ov-milestone .bar{box-shadow:inset 0 1px 2px rgba(0,0,0,.5)}
.ov-milestone .bar i{min-width:8px;box-shadow:0 0 10px rgba(124,58,237,.35);transition:width .6s cubic-bezier(.2,.9,.3,1)}

/* --- tombol: kedalaman & umpan balik tekan --- */
.btn{position:relative}
.btn.pri{box-shadow:0 10px 26px -12px rgba(233,188,85,.45)}
.btn.pri:hover{box-shadow:0 14px 32px -12px rgba(233,188,85,.55)}
.btn.pri:active{box-shadow:0 4px 12px -8px rgba(233,188,85,.4)}
.btn:disabled,.btn[disabled]{opacity:.42;cursor:not-allowed;filter:grayscale(.35)}
.btn:disabled:hover,.btn[disabled]:hover{border-color:var(--line2);background:var(--card2);transform:none}

/* --- empty state --- */
.empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;
  padding:30px 18px;text-align:center;color:var(--dim)}
.empty .ew{width:42px;height:42px;border-radius:13px;background:var(--inset);border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center}
.empty .ew .ic{width:19px;height:19px;color:var(--line3)}
.empty b{color:var(--mut);font-size:13px;font-weight:700}
.empty p{margin:0;font-size:11.5px;max-width:34ch;line-height:1.5}

/* --- grafik area --- */
.chartwrap{position:relative}
.chartwrap .gline{stroke:var(--line);stroke-width:1;stroke-dasharray:3 5}
.chartwrap .axis{font-family:var(--mono);font-size:9px;fill:var(--dim)}
.chartwrap .dot{transition:r .15s}
.chartwrap:hover .dot{r:4.5}

/* --- tabel: kepala lengket saat digulir --- */
.tblwrap{border-radius:10px}
table.t thead th{position:sticky;top:0;background:var(--card);z-index:1}
table.t td .badge{vertical-align:0}

/* --- daftar transaksi: garis waktu halus --- */
.feed .f{position:relative;padding-left:2px}
.feed .amt{font-size:13px;letter-spacing:-.01em}

/* --- kandidat voting: peringkat & interaksi --- */
.kd{position:relative}
.kd .rank{position:absolute;top:10px;left:12px;font-family:var(--mono);font-size:10px;
  color:var(--dim);border:1px solid var(--line2);border-radius:99px;padding:1px 7px}
.kd.lead{border-color:var(--emas);box-shadow:0 0 0 3px var(--emas-mud)}
.kd.lead .rank{color:var(--am);border-color:rgba(251,191,36,.5)}



/* --- ringkasan angka pada kartu saldo --- */
.moneybig{font-family:var(--mono);font-weight:600;letter-spacing:-.02em;font-variant-numeric:tabular-nums}

/* --- pemisah bagian --- */
.sechead{display:flex;align-items:center;gap:10px;margin:26px 0 14px}
.sechead h2{font-size:15px;font-weight:800;margin:0;letter-spacing:-.01em;white-space:nowrap}
.sechead .rule{flex:1;height:1px;background:linear-gradient(90deg,var(--line),transparent)}

/* kartu tidak dipaksa setinggi tetangganya saat isinya sedikit */
.row.start{align-items:flex-start}

/* ---- utilitas panel dalam (dipakai kotak URL overlay, cuplikan kode, ringkasan biaya) ---- */
.inset{background:var(--inset);border:1px solid var(--line);border-radius:10px}
.chip{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:999px;
  background:var(--raised);border:1px solid var(--line);font-size:11px;font-weight:600;color:var(--mut)}
.chip.on{background:var(--cy-deep);border-color:#CFC7F8;color:var(--cy)}

/* baris pembuat pertanyaan / kandidat / hadiah */
.builder{border:1px solid var(--line);border-radius:12px;padding:12px;margin-bottom:10px;background:var(--card2)}
.builder .bh{display:flex;gap:8px;align-items:center;margin-bottom:10px}
.builder .bn{width:26px;height:26px;border-radius:8px;background:var(--cy-deep);color:var(--cy);
  display:grid;place-items:center;font-size:11px;font-weight:700;flex:none}

/* Bilah progres mandiri — sebelumnya hanya ada versi bersarang di .bar-row dan .obs,
   sehingga pemakaian langsung (mis. progres survey) tampil tanpa gaya. */
.bar{height:9px;background:var(--inset);border-radius:99px;overflow:hidden;margin:5px 0}
.bar>i{display:block;height:100%;background:var(--grad);border-radius:99px;transition:width .35s ease}

/* Tautan navigasi publik yang sedang aktif */
.lnav .nl.on{color:var(--cy);font-weight:700}

/* ============ PAPAN PEROLEHAN SUARA LANGSUNG ============ */
.lb{display:flex;gap:13px;align-items:center;padding:13px 0;border-bottom:1px solid var(--line);
  transition:background .3s}
.lb:last-child{border-bottom:0}
.lb .pos{font-family:var(--mono);font-size:12px;color:var(--dim);min-width:30px;text-align:right}
.lb .lbtop{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}
.lb .nm{font-size:14px}
.lb .sc{margin-left:auto;font-size:12.5px;color:var(--mut);white-space:nowrap}
.lb.lead .pos{color:var(--am);font-weight:700}
.lb.lead .nm{color:var(--cy)}
.lb.lead .bar i{background:linear-gradient(90deg,#F59E0B,#7C3AED)}
.lb .bar{height:11px}

/* overlay siaran untuk papan suara — gelap, ringkas, siap ditumpangkan di video */
.vlive{font-family:var(--sans);color:#F3EDE1;padding:18px;max-width:520px}
.vlive .hd{display:flex;align-items:center;gap:9px;margin-bottom:12px}
.vlive .hd b{font-size:15px;letter-spacing:-.01em}
.vlive .hd .tot{margin-left:auto;font-family:var(--mono);font-size:12px;color:#BDB3CE}
.vlive .row2{display:flex;gap:11px;align-items:center;padding:9px 11px;border-radius:12px;
  background:rgba(12,18,32,.72);border:1px solid rgba(255,255,255,.09);margin-bottom:8px;
  backdrop-filter:blur(6px)}
.vlive .row2.lead{border-color:rgba(245,158,11,.55);box-shadow:0 0 0 1px rgba(245,158,11,.25)}
.vlive .row2 .p{font-family:var(--mono);font-size:12px;color:#8A80A3;min-width:22px}
.vlive .row2 .n{font-size:13.5px;font-weight:700}
.vlive .row2 .v{margin-left:auto;font-family:var(--mono);font-size:12.5px;color:#BDB3CE}
.vlive .row2 .b{height:6px;background:rgba(255,255,255,.12);border-radius:99px;overflow:hidden;margin-top:5px}
.vlive .row2 .b i{display:block;height:100%;background:linear-gradient(90deg,#7C3AED,#4F7FE8);
  border-radius:99px;transition:width .5s ease}
.vlive .row2.lead .b i{background:linear-gradient(90deg,#F59E0B,#7C3AED)}

/* Kendali simulator pada halaman pembayaran. Menyatu dengan kartu, tetapi
   keterangannya tetap jelas agar tidak dikira pembayaran sungguhan. */
.simblok{margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
.simblok small{display:block;margin-top:9px;font-size:10.5px;color:var(--dim);
  line-height:1.55;text-align:center}
/* ── penyaji survey (SurveyJS v3) ───────────────────────────────────────────
   SurveyJS v3 menurunkan hampir seluruh temanya dari segelintir token akar,
   dan mendefinisikannya lewat :where() sehingga bobotnya nol. Jadi cukup
   menimpa akarnya di sini: ketika palet Apresia berubah, penyaji ikut berubah
   tanpa satu pun selektor komponen perlu disentuh.

   Penimpaan harus ikut mengenai .sd-root-modern, bukan pembungkusnya saja:
   penyaji menulis ulang token yang sama di elemen akarnya sendiri, dan nilai
   dari elemen yang lebih dalam selalu menang berapa pun bobot selektornya. */
.sjs-wrap,.sjs-wrap .sd-root-modern{
  --sjs2-color-project-brand-600:var(--cy);
  --sjs2-palette-gray-000:var(--card);
  --sjs2-palette-gray-100:var(--inset);
  --sjs2-palette-gray-150:var(--raised);
  --sjs2-palette-gray-200:var(--line);
  --sjs2-palette-gray-250:var(--line2);
  --sjs2-palette-gray-300:var(--line2);
  --sjs2-palette-gray-900:var(--txt);
  --sjs2-palette-red-600:var(--rd);
  --sjs2-palette-green-600:var(--gn);
  --sjs2-palette-yellow-600:var(--am);
  --sjs2-typography-font-family-text:var(--sans);
  --sjs2-typography-font-family-code:var(--mono);
  --sjs2-base-unit-radius:7px;

  /* nama token lama masih dibaca sebagian komponen warisan */
  --sjs-primary-backcolor:var(--cy);
  --sjs-primary-forecolor:#fff;
  --sjs-general-backcolor:var(--card);
  --sjs-general-forecolor:var(--txt);
  --sjs-border-default:var(--line2);
  --sjs-font-family:var(--sans);
}
/* Penyaji sudah berada di dalam kartu Apresia — latar dan bayangannya sendiri
   membuat halaman terlihat bertumpuk tanpa menambah kejelasan. */
.sjs-wrap .sd-root-modern{background:transparent}
.sjs-wrap .sd-container-modern__title{background:transparent;box-shadow:none;padding-left:0;padding-right:0}
.sjs-wrap .sd-body{padding-left:0;padding-right:0}
.sjs-wrap .sd-element--with-frame{box-shadow:none;border:1px solid var(--line)}
.sjs-wrap .sd-action-bar{padding-left:0;padding-right:0}
.sjs-wrap .sd-progress__bar{background:var(--grad)}

/* ═══════════════════════════ SAKELAR TEMA ═══════════════════════════ */
/* Disembunyikan secara bawaan dan hanya dibuka kalau JavaScript hidup —
   sakelar mati di layar lebih buruk daripada tidak ada sakelar. Dipakai
   sebagai kelas, bukan atribut, supaya bilah aplikasi yang baru disusun
   JavaScript belakangan pun ikut terbuka tanpa perlu dicatat. */
.tema-b{display:none}
html.js .tema-b{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:34px;height:34px;padding:0;border-radius:10px;cursor:pointer;
  background:transparent;border:1px solid var(--line);color:var(--mut);
  transition:color .2s,background .2s,border-color .2s;
}
.tema-b:hover{color:var(--txt);background:var(--sorot);border-color:var(--line2)}
.tema-b svg{
  width:17px;height:17px;stroke:currentColor;fill:none;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;
}
/* Yang tampil adalah tujuannya: di tema malam ditawarkan matahari. */
.tema-b .tema-ke-gelap{display:none}
:root[data-theme="light"] .tema-b .tema-ke-terang{display:none}
:root[data-theme="light"] .tema-b .tema-ke-gelap{display:block}

/* Halaman masuk dan daftar tidak punya bilah apa pun, jadi sakelarnya
   berdiri sendiri di pojok. */
.tema-b.pojok{position:fixed;top:18px;right:18px;z-index:80;background:var(--card)}

/* ═══════════════════════════ PEMILIH BAHASA ═══════════════════════════ */
.bhs{
  display:inline-flex;align-items:center;gap:2px;flex:none;
  padding:3px;border-radius:9px;border:1px solid var(--line);
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;
}
.bhs a,.bhs .bhs-on{
  padding:4px 7px;border-radius:6px;line-height:1;text-decoration:none;
  transition:color .18s,background .18s;
}
.bhs a{color:var(--dim)}
.bhs a:hover{color:var(--txt);background:var(--sorot);text-decoration:none}
.bhs .bhs-on{color:var(--emas);background:var(--emas-mud);font-weight:700}

/* Halaman masuk & daftar tidak punya bilah apa pun, jadi pemilih bahasa dan
   sakelar temanya berdiri berdampingan di pojok. */
.auth-pilih{position:fixed;top:18px;right:18px;z-index:80;display:flex;align-items:center;gap:8px}

/* ---- Grafik transaksi (ringkasan merchant) ------------------------------
   Sakelar rentang + batang dua arah. Warnanya diambil dari token tema,
   bukan ditulis harfiah, supaya grafiknya ikut berganti saat tema ditukar —
   grafik lama di Studio masih memakai heksadesimal dan itulah sebabnya ia
   terlihat asing di tema terang. */
.segmen{display:inline-flex;gap:2px;padding:2px;background:var(--inset);
  border:1px solid var(--line);border-radius:99px}
.segmen .seg{border:0;background:none;color:var(--mut);font:inherit;font-size:11.5px;
  font-weight:600;padding:5px 12px;border-radius:99px;cursor:pointer;transition:.15s}
.segmen .seg:hover{color:var(--txt)}
/* Pil aktif memakai warna merek, bukan sekadar lapisan yang lebih terang:
   --card2 dan --inset hampir sama gelapnya di kedua tema, jadi segmen yang
   sedang dipilih praktis tak terlihat. */
.segmen .seg.on{background:var(--cy-deep);color:var(--cy)}
.segmen .seg:focus-visible{outline:none;box-shadow:var(--ring)}
/* Segmen sebagai pilihan borang: radionya tetap ada untuk papan ketik dan
   pembaca layar, hanya tidak digambar. Tanda aktif dan cincin fokusnya
   dibaca dari radionya sendiri, jadi tidak ada JavaScript yang harus ingat
   menyalin keadaan itu ke kelas. */
.segmen label.seg{position:relative}
.segmen label.seg input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}
.segmen label.seg:has(input:checked){background:var(--cy-deep);color:var(--cy)}
.segmen label.seg:has(input:focus-visible){box-shadow:var(--ring)}

.grafik-angka{display:flex;flex-wrap:wrap;gap:22px;margin:10px 0 12px}
.grafik-angka .lbl{display:block;margin-bottom:1px}
.grafik-angka b{font-size:15px;font-weight:600}

svg.grafik{width:100%;height:190px;display:block}
svg.grafik .gl{stroke:var(--line);stroke-width:1;stroke-dasharray:3 5}
svg.grafik .gl.nol{stroke:var(--line2);stroke-dasharray:none}
svg.grafik .masuk{fill:var(--gn)}
svg.grafik .keluar{fill:var(--rd)}
svg.grafik .sorot{fill:transparent}
svg.grafik .btg:hover .sorot{fill:var(--sorot)}
svg.grafik .btg:hover .masuk,svg.grafik .btg:hover .keluar{filter:brightness(1.25)}

.grafik-kaki{display:flex;justify-content:space-between;font-family:var(--mono);
  font-size:10px;color:var(--dim);padding:0 4px;margin-top:2px}

/* ---- Overlay: main bareng ------------------------------------------------
   Dua elemen, dua tugas. Papan antrean diam di tepi kiri atas sepanjang
   siaran; kotak panggilan hanya muncul saat kreator memanggil seseorang.
   Warnanya harfiah, bukan token tema: overlay selalu digubah di atas gambar
   siaran yang gelap, dan ia tidak pernah ikut tema terang. */
.ov-antre{position:absolute;left:14px;top:14px;width:var(--papan-lebar,210px);z-index:4;
  background:var(--ov-panel);border:1px solid var(--ov-tepi);border-radius:var(--ov-radius);
  padding:10px 12px;backdrop-filter:blur(4px);color:var(--ov-teks);font-family:var(--ov-font)}
.ov-antre .kepala{display:flex;align-items:baseline;gap:8px;margin-bottom:7px}
.ov-antre .judul{flex:1;font-size:calc(10px * var(--ov-skala));letter-spacing:.05em;
  text-transform:uppercase;color:var(--ov-teks-2);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ov-antre .cacah{font-size:calc(10px * var(--ov-skala));color:var(--ov-aksen);font-weight:700}
.ov-antre .main{margin-bottom:7px;padding-bottom:6px;border-bottom:1px solid var(--ov-tepi)}
.ov-antre .tag{font-size:calc(8.5px * var(--ov-skala));letter-spacing:.14em;
  color:var(--ov-aksen);margin-bottom:3px}
.ov-antre .r{display:flex;align-items:center;gap:7px;font-size:calc(12px * var(--ov-skala));
  padding:2px 0;text-shadow:var(--ov-bayang)}
.ov-antre .r .no{font-size:calc(10px * var(--ov-skala));color:var(--ov-teks-2);
  width:16px;text-align:right;opacity:.8;flex:none}
.ov-antre .r b{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.ov-antre .r.tunda b{opacity:.55;text-decoration:line-through}
.ov-antre .r.kosong b{font-weight:400;opacity:.6}
/* Titik kecil untuk yang sudah dipanggil tapi belum menyahut — kreator perlu
   tahu siapa yang sedang ditunggu tanpa membuka konsol. */
.ov-antre .r .pgl{color:var(--ov-aksen);font-size:8px;flex:none;animation:pulse 1.4s infinite}
.ov-antre .r .ft{font-size:calc(8.5px * var(--ov-skala));color:var(--ov-panel);
  background:var(--ov-aksen);border-radius:4px;padding:1px 4px;margin-left:auto;flex:none;
  font-weight:700;text-shadow:none}
.ov-antre .sisa{margin-top:5px;font-size:calc(9.5px * var(--ov-skala));
  color:var(--ov-teks-2);opacity:.75}

/* Papan besar: mengisi browser source-nya sendiri, jadi tidak lagi
   mengambang di sudut dan boleh bernapas. */
.obs-mabar{padding:12px;font-family:var(--ov-font)}
.ov-antre.besar{padding:16px 18px;border-radius:calc(var(--ov-radius) + 4px)}
.ov-antre.besar .kepala{margin-bottom:11px}
.ov-antre.besar .judul{font-size:calc(13px * var(--ov-skala))}
.ov-antre.besar .cacah{font-size:calc(13px * var(--ov-skala))}
.ov-antre.besar .r{font-size:calc(17px * var(--ov-skala));padding:5px 0;gap:10px}
.ov-antre.besar .r .no{font-size:calc(13px * var(--ov-skala));width:24px}
.ov-antre.besar .tag{font-size:calc(10px * var(--ov-skala));margin-bottom:5px}
.ov-antre.besar .r .ft{font-size:calc(10px * var(--ov-skala));padding:2px 6px}
.ov-antre.besar .r .pgl{font-size:11px}
.ov-antre.besar .sisa{margin-top:9px;font-size:calc(12px * var(--ov-skala))}

/* Tidak pernah menadah tetikus. Kotak ini tembus pandang sampai ada giliran
   yang dipanggil, tapi badannya tetap membentang di tengah panggung — dan di
   pratinjau ia menelan seretan kotak alert yang berdiri persis di bawahnya.
   Yang tidak terlihat tidak boleh bisa diklik. */
.ov-panggil{position:absolute;left:50%;top:52px;transform:translateX(-50%) scale(.85);pointer-events:none;
  opacity:0;transition:.3s cubic-bezier(.2,.9,.3,1.25);z-index:6;text-align:center;
  background:var(--ov-panel);border:1.5px solid var(--ov-aksen);border-radius:calc(var(--ov-radius) + 4px);
  padding:16px 30px;min-width:330px;box-shadow:0 0 44px color-mix(in srgb, var(--ov-aksen) 35%, transparent);color:var(--ov-teks)}
.ov-panggil.show{opacity:1;transform:translateX(-50%) scale(1)}
.ov-panggil .tag{font-size:calc(10px * var(--ov-skala));letter-spacing:.14em;color:var(--ov-aksen)}
.ov-panggil .nm{font-size:calc(19px * var(--ov-skala));font-weight:800;margin-top:3px;text-shadow:var(--ov-bayang)}
.ov-panggil .ak{font-size:calc(11px * var(--ov-skala));color:var(--ov-teks-2);margin-top:5px}

/* ---- Penggeser & pemilih warna -------------------------------------------
   Keduanya dipakai panel tampilan overlay. Kendali bawaan browser dipakai
   apa adanya sebelumnya, jadi penggesernya tampil biru terang — satu-satunya
   biru di seluruh aplikasi, di tengah layar yang emas dan ungu. */
.geser{display:flex;align-items:center;gap:10px}
.geser input[type=range]{-webkit-appearance:none;appearance:none;flex:1;min-width:80px;
  height:4px;border-radius:99px;background:var(--line2);outline:none;cursor:pointer}
.geser input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;
  width:15px;height:15px;border-radius:50%;background:var(--cy);
  border:2px solid var(--card);box-shadow:var(--sh-1);cursor:pointer;transition:transform .15s}
.geser input[type=range]::-webkit-slider-thumb:hover{transform:scale(1.18)}
.geser input[type=range]::-moz-range-thumb{width:13px;height:13px;border-radius:50%;
  background:var(--cy);border:2px solid var(--card);cursor:pointer}
.geser input[type=range]:focus-visible{box-shadow:var(--ring)}
.geser .nilai{font-family:var(--mono);font-size:11px;color:var(--txt);
  min-width:42px;text-align:right;font-variant-numeric:tabular-nums}

.warna-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(126px,1fr));gap:12px}
.warna input[type=color]{-webkit-appearance:none;appearance:none;display:block;width:100%;
  height:30px;padding:0;border:1px solid var(--line);border-radius:9px;background:none;cursor:pointer}
.warna input[type=color]::-webkit-color-swatch-wrapper{padding:3px}
.warna input[type=color]::-webkit-color-swatch{border:0;border-radius:6px}
.warna input[type=color]::-moz-color-swatch{border:0;border-radius:6px}
.warna .hex{width:100%;margin-top:6px;font-family:var(--mono);font-size:11px;padding:6px 8px;
  text-transform:uppercase}
/* Tinggi keterangan dikunci supaya kelima kartunya berakhir pada garis yang
   sama walau ada yang keterangannya dua baris. */
.warna small{display:block;margin-top:5px;font-size:10px;line-height:1.45;
  color:var(--dim);min-height:28px}

/* Baris judul kelompok di dalam kartu pengaturan. */
.stel-judul{display:flex;align-items:center;gap:9px;margin:18px 0 10px}
.stel-judul:first-of-type{margin-top:4px}
.stel-judul span{font-family:var(--mono);font-size:9px;letter-spacing:.15em;
  color:var(--dim);text-transform:uppercase;white-space:nowrap}
.stel-judul i{flex:1;height:1px;background:var(--line);display:block}

/* ---- Seret widget overlay (hanya di pratinjau) ---------------------------- */
.bisa-seret{cursor:grab;touch-action:none}
.bisa-seret:hover{outline:1px dashed var(--ov-aksen);outline-offset:3px}
.bisa-seret.sedang-seret{cursor:grabbing;outline:1px solid var(--ov-aksen);
  outline-offset:3px;opacity:.92;transition:none}

/* ============================================================
   HALAMAN DUKUNGAN PUBLIK
   Satu layar, satu tugas: mengantar orang dari "mau kasih" ke
   "sudah bayar". Sebelumnya tombol bayarnya duduk 1.224px dari
   puncak halaman di layar ponsel — 492px HARUS digulir sebelum
   ia kelihatan sama sekali.
   ============================================================ */

/* Penjaga terakhir. Gulir menyamping di halaman yang dibuka dari tautan bio
   adalah cacat yang paling mudah kembali tanpa ketahuan — satu teks yang tidak
   boleh patah sudah cukup. */
body{overflow-x:hidden}

/* --- kepala halaman --- */
.kreator-kepala{display:flex;gap:16px;align-items:center;margin-bottom:16px;flex-wrap:wrap}
.kreator-kepala .ava{flex:none}
.kreator-kepala h1{margin:0;font-size:clamp(20px,4.4vw,27px);letter-spacing:-.02em;
  display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.kreator-kepala .bio{margin:5px 0 0;color:var(--mut);font-size:13px;line-height:1.55;max-width:52ch}
.kreator-angka{display:flex;gap:18px;margin-top:9px;flex-wrap:wrap}
.kreator-angka div{display:flex;flex-direction:column;gap:1px}
.kreator-angka b{font-family:var(--mono);font-size:14px;letter-spacing:-.01em}
.kreator-angka span{font-size:10px;color:var(--dim);letter-spacing:.06em;text-transform:uppercase}

/* --- kolom --- */
.dukung-kolom{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  gap:16px;align-items:start}
/* Tanpa satu pun kartu samping, borangnya memakai seluruh lebar. Kisi dua
   kolom yang salah satunya kosong tetap menyisakan lubang di sebelah borang,
   dan yang terlihat bukan halaman yang lebih sederhana melainkan halaman
   yang separuhnya gagal dimuat. */
.dukung-kolom.penuh{grid-template-columns:minmax(0,1fr)}
.dukung-kolom > *{min-width:0}
.dukung-sisi{position:sticky;top:78px;display:flex;flex-direction:column;gap:14px}

/* --- langkah bernomor: urutannya terbaca sebelum dibaca --- */
.langkah{display:flex;align-items:center;gap:9px;margin:20px 0 10px;flex-wrap:wrap}
.langkah:first-of-type{margin-top:4px}
.langkah i{width:20px;height:20px;border-radius:99px;flex:none;display:grid;place-items:center;
  background:var(--ungu-mud);color:var(--vi);font-family:var(--mono);font-size:10px;font-weight:700;
  font-style:normal}
.langkah b{font-size:13px;letter-spacing:-.01em;min-width:0}
.langkah span{margin-left:auto;font-size:11px;color:var(--dim);white-space:nowrap}

/* --- nominal cepat --- */
.qa-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(86px,1fr));gap:8px;margin-bottom:10px}
.qa{position:relative;background:var(--field);border:1px solid var(--line2);border-radius:12px;
  padding:13px 6px;text-align:center;font-weight:800;cursor:pointer;font-size:14px;transition:.15s;
  min-height:52px;display:grid;place-content:center}

/* --- dua kolom yang rapat pada layar lebar, menumpuk di ponsel --- */
.baris-isian{display:grid;grid-template-columns:1fr 1fr;gap:12px}

/* --- kanal pembayaran: ubin ringkas, bukan kartu tinggi --- */
.pay-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:9px}
.pay{display:flex;align-items:center;gap:9px;background:var(--field);border:1px solid var(--line2);
  border-radius:11px;padding:9px 10px;cursor:pointer;transition:.15s;min-width:0}
.pay .isi{min-width:0}
/* Nama kanal boleh melipat sampai dua baris. Aturan nowrap + elipsis di
   sini menang atas aturan sebelumnya karena ditulis belakangan, dan yang
   terlihat "Virtual Ac…" — padahal tingginya sudah disediakan untuk dua
   baris. */
.pay b{font-size:12px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.3;white-space:normal}
.pay small{display:block;color:var(--dim);font-size:10px;white-space:nowrap}

/* --- ringkasan --- */
.ringkas{background:var(--inset);border:1px solid var(--line);border-radius:13px;padding:12px 14px;margin-top:6px}

/* --- bilah bayar yang menempel di ponsel --- */
.bayar-tempel{position:fixed;left:0;right:0;bottom:0;z-index:60;display:none;
  gap:12px;align-items:center;padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  background:var(--kaca);backdrop-filter:blur(14px);border-top:1px solid var(--line2)}
.bayar-tempel .angka{min-width:0}
.bayar-tempel .angka span{display:block;font-size:10px;color:var(--dim);letter-spacing:.06em;text-transform:uppercase}
.bayar-tempel .angka b{font-family:var(--mono);font-size:16px;letter-spacing:-.01em}
.bayar-tempel .btn{margin-left:auto;flex:none}

@media (max-width:880px){
  /* `minmax(0,1fr)`, bukan `1fr`: kolom 1fr tetap melebar mengikuti isinya
     yang paling lebar, dan satu baris teks yang tidak boleh patah sudah
     cukup membuat seluruh halaman bisa digulir ke samping. */
  .dukung-kolom{grid-template-columns:minmax(0,1fr)}
  .dukung-sisi{position:static}
  .baris-isian{grid-template-columns:1fr}
  .qa-grid{grid-template-columns:repeat(3,1fr)}
  .bayar-tempel{display:flex}
  /* ruang supaya bilah tempel tidak menutup isi terakhir halaman */
  .wrap{padding-bottom:96px}
  /* tombol di dalam borang tidak perlu ada dua kali di layar sempit */
  .bayar-dalam{display:none}
  /* Gulir di dalam gulir adalah jebakan di layar sentuh: jari yang menyapu
     umpan dukungan berhenti di dalam kotaknya alih-alih melanjutkan halaman. */
  .feed{max-height:none !important;overflow:visible}
  /* Sasaran sentuh di dalam borang dukungan tidak boleh lebih pendek dari
     jempol. Yang di bilah aplikasi dibiarkan — itu wilayah lain. */
  #donateForm .btn.sm{min-height:40px;padding-left:14px;padding-right:14px}
}

/* --- pemutar siaran di halaman dukungan ---------------------------------
   Videonya milik platform, bukan milik Apresia. Kotak ini cuma bingkainya. */
.siaran-kotak{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;margin-bottom:16px;box-shadow:var(--sh-2)}
.siaran-bingkai{position:relative;aspect-ratio:16/9;background:#000}
.siaran-bingkai iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.siaran-kaki{display:flex;align-items:center;gap:10px;padding:10px 14px;flex-wrap:wrap;
  font-size:12.5px;color:var(--mut)}
.siaran-kaki .grow{min-width:0}
/* Tanpa pemutar yang bisa disematkan — TikTok dan Instagram tidak punya, dan
   siaran yang penyematannya dimatikan kreator juga tidak. Yang tampil spanduk
   LIVE dengan tautan menonton, bukan kotak hitam yang menyerupai pemutar
   rusak. */
.siaran-kotak.tanpa-pemutar{background:linear-gradient(120deg,var(--card2),var(--card));
  border-color:var(--line2)}
.siaran-kotak.tanpa-pemutar .siaran-kaki{padding:14px}

/* --- halaman tonton ------------------------------------------------------
   Pemutar mendominasi, borang dukungan mendampingi. Di ponsel keduanya
   menumpuk dengan pemutar di atas: orang membuka halaman ini untuk menonton
   dulu, memberi kemudian. */
.tonton-kepala{display:flex;gap:12px;align-items:center;margin-bottom:14px}
.tonton-kepala .ava{width:40px;height:40px;font-size:15px}
.tonton-kolom{display:grid;grid-template-columns:minmax(0,1.9fr) minmax(0,1fr);
  gap:16px;align-items:start}
.tonton-kolom > *{min-width:0}
/* Pemutar kiri atas, umpan dukungan di bawahnya, borang di kanan membentang
   dua baris. Umpan sengaja jadi anak grid tersendiri — bukan bersarang di
   kolom pemutar — supaya di ponsel ia bisa turun ke BAWAH borang. Penonton
   yang menekan "Lanjutkan" di bilah tempel tidak boleh dilempar ke kolom isian
   yang terkubur di bawah daftar dukungan orang lain. */
.tonton-utama{grid-column:1;grid-row:1}
.tonton-sisi{grid-column:2;grid-row:1 / span 2;
  position:sticky;top:78px;display:flex;flex-direction:column;gap:14px}
.tonton-umpan{grid-column:1;grid-row:2}
.siaran-bingkai.besar{border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);
  box-shadow:var(--sh-2)}

@media (max-width:980px){
  .tonton-kolom{display:flex;flex-direction:column}
  .tonton-sisi{position:static}
  .tonton-utama{order:1} .tonton-sisi{order:2} .tonton-umpan{order:3}
}

/* Nama dan pesan donatur adalah teks yang diketik orang asing: satu kata
   panjang tanpa spasi sudah cukup membuat baris umpan tidak bisa menyusut,
   dan bersamanya seluruh halaman jadi bisa digulir ke samping. */
.feed .who{min-width:0}
.feed .who b,.feed .who p{overflow-wrap:anywhere}

/* --- pegangan ubah ukuran (hanya di pratinjau) --------------------------- */
/* Papan yang bisa diseret TIDAK dipaksa position:relative di sini.
   `.bisa-seret` ditulis sesudah `.ov-lead`/`.ov-antre` dengan kekhususan yang
   sama, jadi position:relative menimpa position:absolute milik papan: begitu
   skrip seret memasang kelasnya, papan pendukung lepas dari jangkar
   `right:16px`-nya, jatuh ke aliran normal di pojok kiri atas, dan tergunting
   tepi panggung. Keduanya sudah absolute — sudah jadi induk posisi buat
   pegangan ubah lebar — jadi aturan ini tidak pernah dibutuhkan. */
.gagang{position:absolute;right:-3px;bottom:-3px;width:14px;height:14px;
  border-right:2px solid var(--ov-aksen);border-bottom:2px solid var(--ov-aksen);
  border-bottom-right-radius:4px;cursor:ew-resize;opacity:0;transition:opacity .15s}
.bisa-seret:hover .gagang,.bisa-seret.sedang-ukur .gagang{opacity:.9}
.bisa-seret.sedang-ukur{outline:1px solid var(--ov-aksen);outline-offset:3px}

/* --- baris pengaturan widget di halaman pratinjau ------------------------ */
.widget-baris{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;
  padding:10px 0;border-bottom:1px solid var(--line)}
.widget-baris:last-of-type{border-bottom:0}
.widget-baris .switch{padding-bottom:6px}
.widget-baris .nama{display:flex;align-items:center;gap:7px;font-size:12.5px;font-weight:600;
  min-width:150px;padding-bottom:7px}
.widget-baris .nama .ic{color:var(--cy)}
.widget-baris .kolom{display:flex;flex-direction:column;gap:3px}
.widget-baris .kolom .lbl{margin:0}
.widget-baris .kolom.sempit .in{width:78px}
.widget-baris .kolom.lebar{flex:1;min-width:160px}
.widget-baris .kolom.lebar .in{width:100%}

/* ═══════════════════ KODE QR DI OVERLAY ═══════════════════
   Alamat halaman dukungan, dipasang di layar siaran. Penonton memindainya
   dari ponsel sendiri dan sampai di sana tanpa mengetik apa pun.

   Bidang kodenya putih tetap, dan itu bukan pilihan gaya: pemindai membaca
   modul gelap di atas dasar terang. Kode gelap di atas panel gelap akan ikut
   tema kreator dengan rapi dan tidak terbaca satu alat pun. */
.ov-qr{
  --qr-pad:9px;
  position:absolute;right:16px;bottom:92px;width:var(--papan-lebar,158px);
  display:flex;flex-direction:column;align-items:center;
}
/* Padding 4px, bukan 6px. Zona sunyi empat modul sekarang ikut di dalam
   SVG-nya sendiri (lihat KodeQr::svg), jadi putih di sini tinggal tugas rupa —
   dan tiap piksel yang tidak dipakainya kembali jadi modul yang lebih besar. */
.ov-qr .kode{
  background:var(--qr-latar,#FFFFFF);border-radius:6px;padding:4px;
  width:100%;line-height:0;color:#0C0918;position:relative}
.ov-qr .kode svg{width:100%;height:auto;display:block}
.ov-qr .ket{
  font-family:var(--ov-font);font-size:calc(10.5px * var(--ov-skala));
  line-height:1.35;text-align:center;position:relative;
}

/* Bingkainya digambar di ::before, bukan di kotaknya sendiri.

   Yang membedakan: clip-path dan mask yang dipakai bingkai sobek, tiket, dan
   siku memotong kotak berikut seluruh isinya — termasuk pegangan seret dan
   pegangan ubah lebar di konsol. Sebagai lapisan sendiri di belakang, yang
   terpotong cuma bidangnya. */
.ov-qr::before{content:'';position:absolute;inset:0;pointer-events:none}

/* ── sepuluh bingkai ── */

/* Kodenya saja, melayang di atas siaran. */
.ov-qr.bingkai-tanpa{gap:6px}
.ov-qr.bingkai-tanpa .ket{color:var(--ov-teks-2);text-shadow:var(--ov-bayang);margin-top:6px}

/* Panel bertema, ajakan di dalamnya. */
.ov-qr.bingkai-kartu{padding:var(--qr-pad);gap:7px}
.ov-qr.bingkai-kartu::before{
  background:var(--ov-panel);border:1px solid var(--ov-tepi);border-radius:var(--ov-radius)}
.ov-qr.bingkai-kartu .ket{color:var(--ov-teks-2);text-shadow:var(--ov-bayang)}

/* Papan nama: kakinya jadi pita beraksen. Bentuk yang sama dipakai penanda
   meja di kafe, dan itu yang paling cepat dikenali orang sebagai "pindai
   saya". Versi terbaliknya menaruh pita itu di kepala — berguna kalau papan
   dipasang di kaki layar, karena pitanya jadi lebih jauh dari tepi bawah. */
.ov-qr.bingkai-pita,.ov-qr.bingkai-pita-atas{padding:var(--qr-pad) var(--qr-pad) 0}
.ov-qr.bingkai-pita-atas{flex-direction:column-reverse;padding:0 var(--qr-pad) var(--qr-pad)}
.ov-qr.bingkai-pita::before,.ov-qr.bingkai-pita-atas::before{
  background:var(--ov-panel);border:1px solid var(--ov-tepi);border-radius:var(--ov-radius)}
.ov-qr.bingkai-pita .ket,.ov-qr.bingkai-pita-atas .ket{
  width:calc(100% + var(--qr-pad) * 2);padding:7px var(--qr-pad);
  background:var(--ov-aksen);color:var(--ov-panel);font-weight:700;letter-spacing:.01em}
.ov-qr.bingkai-pita .ket{
  margin:var(--qr-pad) calc(var(--qr-pad) * -1) 0;
  border-radius:0 0 var(--ov-radius) var(--ov-radius)}
.ov-qr.bingkai-pita-atas .ket{
  margin:0 calc(var(--qr-pad) * -1) var(--qr-pad);
  border-radius:var(--ov-radius) var(--ov-radius) 0 0}

/* Empat siku, tanpa panel — seperti bidikan kamera. Keempatnya satu bingkai
   yang tengah-tengah sisinya dilubangi topeng, bukan empat kotak terpisah:
   sudutnya jadi selalu sejajar berapa pun lebar papannya. */
.ov-qr.bingkai-sudut{padding:7px;gap:7px}
.ov-qr.bingkai-sudut::before{
  border:2px solid var(--ov-aksen);border-radius:6px;
  -webkit-mask:linear-gradient(#000 0 0) 0 0/16px 16px no-repeat,
       linear-gradient(#000 0 0) 100% 0/16px 16px no-repeat,
       linear-gradient(#000 0 0) 0 100%/16px 16px no-repeat,
       linear-gradient(#000 0 0) 100% 100%/16px 16px no-repeat;
  mask:linear-gradient(#000 0 0) 0 0/16px 16px no-repeat,
       linear-gradient(#000 0 0) 100% 0/16px 16px no-repeat,
       linear-gradient(#000 0 0) 0 100%/16px 16px no-repeat,
       linear-gradient(#000 0 0) 100% 100%/16px 16px no-repeat}
.ov-qr.bingkai-sudut .ket{color:var(--ov-teks-2);text-shadow:var(--ov-bayang)}

/* Ponsel: tepinya tebal, dan ada lubang suara di kepalanya. Lubang itu yang
   membuat bentuknya terbaca sebagai ponsel dan bukan sekadar kartu bersudut
   tumpul. */
.ov-qr.bingkai-ponsel{padding:15px 9px 11px;gap:7px}
.ov-qr.bingkai-ponsel::before{
  background:var(--ov-panel);border:2.5px solid var(--ov-teks-2);border-radius:13px}
.ov-qr.bingkai-ponsel::after{
  content:'';position:absolute;top:7px;left:50%;transform:translateX(-50%);
  width:26px;height:3px;border-radius:2px;background:var(--ov-teks-2);opacity:.75}
.ov-qr.bingkai-ponsel .ket{color:var(--ov-teks-2);text-shadow:var(--ov-bayang)}

/* Gelembung pesan: satu sudut dibiarkan tajam dan diberi ekor di bawahnya. */
.ov-qr.bingkai-gelembung{padding:var(--qr-pad);gap:7px;margin-bottom:7px}
.ov-qr.bingkai-gelembung::before{
  background:var(--ov-panel);border:1px solid var(--ov-tepi);
  border-radius:var(--ov-radius) var(--ov-radius) var(--ov-radius) 3px}
.ov-qr.bingkai-gelembung::after{
  content:'';position:absolute;left:0;bottom:-7px;width:0;height:0;
  border:0 solid transparent;border-right-width:11px;border-top:8px solid var(--ov-panel)}
.ov-qr.bingkai-gelembung .ket{color:var(--ov-teks-2);text-shadow:var(--ov-bayang)}

/* Tiket: bertakik di kiri dan kanan, dengan garis putus-putus di atas
   ajakannya. Kedua takik dari dua topeng bundar yang DIIRISKAN — ditumpuk
   biasa, keduanya saling menutup dan tidak ada yang terpotong. */
.ov-qr.bingkai-tiket{padding:var(--qr-pad);gap:0}
.ov-qr.bingkai-tiket::before{
  background:var(--ov-panel);border-radius:var(--ov-radius);
  -webkit-mask:radial-gradient(circle 6px at 0 72%, #0000 97%, #000),
       radial-gradient(circle 6px at 100% 72%, #0000 97%, #000);
  -webkit-mask-composite:source-in;
  mask:radial-gradient(circle 6px at 0 72%, #0000 97%, #000),
       radial-gradient(circle 6px at 100% 72%, #0000 97%, #000);
  mask-composite:intersect}
.ov-qr.bingkai-tiket .ket{
  width:100%;margin-top:8px;padding-top:8px;
  border-top:1px dashed var(--ov-tepi);
  color:var(--ov-teks-2);text-shadow:var(--ov-bayang)}

/* Struk: tepi bawahnya sobek. Giginya jalur potong bersudut tetap — bukan
   gradien berulang, supaya jumlah giginya tidak berubah-ubah ikut lebar
   papan dan menyisakan setengah gigi di ujung. */
.ov-qr.bingkai-sobek{padding:var(--qr-pad) var(--qr-pad) 15px}
.ov-qr.bingkai-sobek::before{
  background:var(--ov-panel);border-radius:var(--ov-radius) var(--ov-radius) 0 0;
  -webkit-clip-path:polygon(0 0,100% 0,100% calc(100% - 7px),95.83% 100%,91.67% calc(100% - 7px),87.50% 100%,83.33% calc(100% - 7px),79.17% 100%,75.00% calc(100% - 7px),70.83% 100%,66.67% calc(100% - 7px),62.50% 100%,58.33% calc(100% - 7px),54.17% 100%,50.00% calc(100% - 7px),45.83% 100%,41.67% calc(100% - 7px),37.50% 100%,33.33% calc(100% - 7px),29.17% 100%,25.00% calc(100% - 7px),20.83% 100%,16.67% calc(100% - 7px),12.50% 100%,8.33% calc(100% - 7px),4.17% 100%,0.00% calc(100% - 7px));clip-path:polygon(0 0,100% 0,100% calc(100% - 7px),95.83% 100%,91.67% calc(100% - 7px),87.50% 100%,83.33% calc(100% - 7px),79.17% 100%,75.00% calc(100% - 7px),70.83% 100%,66.67% calc(100% - 7px),62.50% 100%,58.33% calc(100% - 7px),54.17% 100%,50.00% calc(100% - 7px),45.83% 100%,41.67% calc(100% - 7px),37.50% 100%,33.33% calc(100% - 7px),29.17% 100%,25.00% calc(100% - 7px),20.83% 100%,16.67% calc(100% - 7px),12.50% 100%,8.33% calc(100% - 7px),4.17% 100%,0.00% calc(100% - 7px))}
.ov-qr.bingkai-sobek .ket{margin-top:7px;color:var(--ov-teks-2);text-shadow:var(--ov-bayang)}

/* Polaroid: bidang putihnya lebar di bawah kode, ajakannya ditulis di situ.
   Putihnya tetap putih, tidak ikut tema — polaroid yang gelap bukan polaroid,
   dan warnanya di sini tidak menyentuh kodenya sama sekali. */
.ov-qr.bingkai-polaroid{padding:8px 8px 20px;gap:9px}
.ov-qr.bingkai-polaroid::before{
  background:#F7F5F0;border-radius:3px;box-shadow:0 2px 10px rgba(0,0,0,.35)}
.ov-qr.bingkai-polaroid .ket{
  color:#33302B;font-style:italic;font-weight:600;
  font-size:calc(11.5px * var(--ov-skala))}








/* ── sakelar kartu halaman publik ──
   Kotak centang yang dijadikan petak, bukan sederet sakelar. Ketiganya
   dipilih bersamaan sebagai satu keputusan — "apa yang berdiri di samping
   borangku" — dan tiga baris sakelar terbaca sebagai tiga keputusan terpisah
   yang kebetulan bertetangga. */
.kartu-tampil{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(196px,1fr));
  gap:9px;margin-top:4px}
/* ── Hasil kampanye iklan ─────────────────────────────────────────────
   Bilah wallet: satu batang, beberapa segmen. Nilainya ditulis di keterangan
   di bawahnya, bukan di dalam segmennya — segmen yang kecil tidak muat
   menampung angkanya, dan angka yang terpotong lebih buruk daripada angka
   yang pindah satu baris. */
.wallet-bar{
  display:flex;height:16px;border-radius:99px;overflow:hidden;
  background:var(--inset);border:1px solid var(--line2);
}
.wallet-bar span{display:block;height:100%}
.wallet-kunci{display:flex;gap:16px;flex-wrap:wrap;margin-top:10px;font-size:12px;color:var(--mut)}
.wallet-kunci span{display:flex;align-items:center;gap:6px}
.wallet-kunci i{width:9px;height:9px;border-radius:3px;flex:none}

/* Tiga hitungan siaran berjajar. Satu kolom di ponsel, tiga di layar lebar —
   dijejalkan mendatar di layar sempit, keterangan tiap keadaan menyusut jadi
   dua kata, dan justru keterangan itulah yang membedakan "siaran" dari
   "siaran tapi tidak menerima kode". */
.siaran-hitung{display:grid;gap:14px;grid-template-columns:1fr}
@media (min-width:620px){.siaran-hitung{grid-template-columns:repeat(3,1fr)}}

/* Grafik klaim per kode. Batang CSS, bukan pustaka grafik: delapan sampai dua
   puluh batang dengan satu garis acuan tidak membutuhkan 60 KB JavaScript yang
   harus ikut dimuat tiap halaman ini dibuka. */
.grafik-kode{
  position:relative;display:flex;align-items:flex-end;gap:10px;
  height:240px;padding:26px 4px 0;overflow-x:auto;
}
.grafik-kode .btg{
  flex:1 1 0;min-width:40px;height:100%;
  display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:6px;
}
/* Angkanya di ATAS batang, bukan di dalamnya: batang pendek tidak muat
   menampungnya, dan angka yang berpindah posisi tergantung tingginya membuat
   deretnya tidak bisa dibaca mendatar. */
.grafik-kode .btg b{font-family:var(--mono);font-size:13px;color:var(--mut);line-height:1}
.grafik-kode .btg span{
  display:block;width:100%;max-width:56px;border-radius:8px 8px 0 0;
  background:var(--gn);min-height:2px;
}
.grafik-kode .btg small{font-family:var(--mono);font-size:11px;color:var(--dim)}
.grafik-kode .batas{
  position:absolute;left:4px;right:4px;height:0;
  border-top:2px dashed var(--rd);opacity:.75;pointer-events:none;
}

/* ── Pembelian Kredit ─────────────────────────────────────────────────
   Petak metode pembayaran. Satu kolom di layar sempit, dua di layar lebar:
   tiga pilihan berjajar mendatar di ponsel membuat keterangan tiap metode
   menyusut jadi dua kata, dan keterangan itulah yang membedakannya. */
.metode-grid{display:grid;gap:9px;grid-template-columns:1fr}
@media (min-width:560px){.metode-grid{grid-template-columns:1fr 1fr}}

/* Blok konversi: yang dibayar di kiri, yang diterima di kanan, panah di
   antaranya. Dua angka bersebelahan dengan satuan berbeda adalah satu-satunya
   bentuk yang membuat nisbahnya terbaca tanpa dijelaskan. */
.konversi{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  margin-top:12px;padding:12px 14px;border-radius:12px;
}
.konversi .panah{width:16px;height:16px;color:var(--dim);flex:none}
.konversi .num{font-size:19px;font-weight:700;margin-top:2px}
.konversi .bayar{color:var(--txt)}
.konversi .dapat{color:var(--cy)}
/* Panah menunjuk ke bawah saat kedua sisinya terpaksa bertumpuk — panah
   mendatar di atas tumpukan vertikal menunjuk ke tempat yang salah. */
@media (max-width:420px){.konversi .panah{transform:rotate(90deg)}}

.kartu-pilih{
  display:flex;align-items:flex-start;gap:10px;cursor:pointer;
  padding:11px 12px;border-radius:var(--r);
  border:1px solid var(--line2);background:var(--field);
  transition:border-color .16s,background .16s}
.kartu-pilih:hover{border-color:var(--line3)}
.kartu-pilih input{position:absolute;opacity:0;width:0;height:0}
.kartu-pilih .tanda{
  flex:none;width:19px;height:19px;margin-top:1px;border-radius:6px;
  border:1px solid var(--line3);background:var(--inset);
  display:flex;align-items:center;justify-content:center;
  color:transparent;transition:.16s}
.kartu-pilih .tanda .ic{width:12px;height:12px}
.kartu-pilih input:checked ~ .tanda{
  background:var(--ungu);border-color:var(--ungu);color:#fff}
.kartu-pilih input:checked ~ .isi b{color:var(--txt)}
/* Fokus papan ketik harus terlihat: kotak centangnya disembunyikan, jadi
   cincin bawaan peramban ikut hilang bersamanya. */
.kartu-pilih input:focus-visible ~ .tanda{outline:2px solid var(--ungu);outline-offset:2px}
.kartu-pilih .isi{display:flex;flex-direction:column;gap:3px;min-width:0}
.kartu-pilih .isi b{
  display:flex;align-items:center;gap:7px;
  font-size:12.5px;font-weight:700;color:var(--mut);transition:color .16s}
.kartu-pilih .isi b .ic{width:14px;height:14px;color:var(--dim);flex:none}
.kartu-pilih .isi small{font-size:11px;line-height:1.45;color:var(--dim)}

/* ═══════════════════ LATAR HALAMAN KREATOR ═══════════════════
   Gambar pilihan kreator di belakang seluruh halaman profilnya.

   Dipatok (fixed), jadi ia diam saat halamannya digulir — isi halaman lewat
   di atasnya seperti lewat di depan jendela. Latar yang ikut bergulir habis
   di layar pertama dan menyisakan warna kosong di sisa halaman yang panjang,
   dan halaman donasi memang panjang.

   z-index negatif, bukan urutan DOM: bilah atas halaman menempel dan punya
   konteks tumpukannya sendiri, dan tanpa ini latarnya menutupi bilah itu. */
.latar-halaman{position:fixed;inset:0;z-index:-1;overflow:hidden;background:var(--bg)}
.latar-halaman img{width:100%;height:100%;object-fit:cover;display:block}

/* Latar yang ikut bergerak saat halaman digulir — lebih lambat daripada
   isinya, seperti pemandangan jauh dari jendela kereta.

   Kotaknya tetap dipatok; yang bergerak GAMBARNYA di dalam kotak itu. Kalau
   kotaknya yang dilepas, latarnya habis di layar pertama dan sisa halaman
   yang panjang tinggal warna kosong — dan halaman donasi memang panjang.

   Gerakannya diikatkan ke gulungan orangnya lewat animation-timeline, bukan
   dijalankan sendiri oleh waktu. Bedanya menentukan di halaman ini: latar
   yang bergerak sendiri terus-menerus di belakang borang pembayaran adalah
   gangguan yang tidak bisa dihentikan siapa pun. Yang diikat ke gulir hanya
   bergerak saat tangannya bergerak — berhenti berarti berhenti.

   Diperbesar 1.28, dan angkanya bukan selera. `translate` dan `scale` adalah
   properti terpisah yang dipasang berurutan — geser dulu, baru diperbesar —
   jadi geseran 8% sampai ke mata sebagai 8 × 1.28 = 10,2% dari tinggi
   kotaknya. Kelebihan dari pembesaran 1.28 adalah 14% di atas dan 14% di
   bawah. Selama yang pertama lebih kecil daripada yang kedua, tepi kotaknya
   tidak pernah tersingkap; kalau tidak, yang merambat masuk bukan pemandangan
   melainkan bidang kosong.

   Dua pagar, sama dengan pola di landing.css: seluruhnya di dalam @supports,
   jadi peramban tanpa linimasa gulir mendapat latar diam dan tidak kehilangan
   apa pun selain gerakannya; dan seluruhnya di dalam prefers-reduced-motion,
   karena yang meminta diam berhak mendapat diam. */
@media (prefers-reduced-motion:no-preference){
@supports (animation-timeline:scroll(root)){
  .latar-halaman img{
    scale:1.28;
    animation:latarLewat linear both;
    animation-timeline:scroll(root);
  }
}
}
@keyframes latarLewat{
  from{translate:0 8%}
  to{translate:0 -8%}
}

/* Selubung yang meluruh ke warna bawaan Apresia.

   Gambarnya tetap TERLIHAT — itu memang gunanya diunggah. Yang dijaga
   selubung ini bukan gambarnya melainkan tulisan di luar kartu: remah roti di
   bilah atas, dan teks kecil yang berdiri langsung di atas halaman.

   Sempat jauh lebih pekat, sampai 52% di kepala dan warna bawaan penuh di
   kaki — dan yang tersisa dari gambar kreatornya cuma bayangan. Kreator yang
   mengunggah latar ingin latarnya terlihat; kalau tidak, ia tidak akan
   mengunggah apa pun.

   Yang menanggung keterbacaan isi halaman bukan selubung ini melainkan kartu
   yang menaunginya: borang donasi, papan pendukung, dan daftar dukungan
   semuanya berdiri di atas bidang pekat sendiri. Itu yang membuat selubungnya
   boleh setipis ini.

   Tema terang tetap mendapat yang lebih pekat: tulisan gelap di atas foto
   terang hilang jauh lebih cepat daripada tulisan terang di atas foto
   gelap. */
.latar-halaman::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--bg) 30%, transparent) 0%,
    color-mix(in srgb, var(--bg) 46%, transparent) 34%,
    color-mix(in srgb, var(--bg) 66%, transparent) 68%,
    color-mix(in srgb, var(--bg) 84%, transparent) 100%)}

/* Tema terang memerlukan selubung yang lebih pekat: tulisan gelap di atas
   foto terang hilang jauh lebih cepat daripada tulisan terang di atas foto
   gelap. */
:root[data-theme="light"] .latar-halaman::after{
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--bg) 42%, transparent) 0%,
    color-mix(in srgb, var(--bg) 58%, transparent) 34%,
    color-mix(in srgb, var(--bg) 76%, transparent) 68%,
    color-mix(in srgb, var(--bg) 90%, transparent) 100%)}

/* ═══════════════════ KEPALA HALAMAN PROFIL ═══════════════════
   Sampul melintang, lalu avatar yang menindih tepi bawahnya. Catatan
   panjangnya di resources/views/components/panji.blade.php. */
.profil{
  background:var(--card);border:1px solid var(--line2);border-radius:var(--r-lg);
  overflow:hidden;margin-bottom:16px;box-shadow:var(--sh-2)}

.profil-sampul{
  position:relative;aspect-ratio:1600/330;min-height:118px;max-height:230px;
  background:var(--panji-warna,var(--grad))}

/* Lanskapnya mengambil warna dari gradien kreatornya lewat currentColor —
   tinta gelap di atas gradien apa pun, bukan warna yang ikut tema: kepala
   ini selalu digubah di atas warna pekat. */
.panji-latar{position:absolute;inset:0;color:#0C0918}
.panji-gambar{position:absolute;inset:0;width:100%;height:100%;display:block}
/* Sampul unggahan menutup lanskapnya sepenuhnya. Sempat tepi bawahnya
   diluruhkan agar menyatu dengan halaman — dan yang terjadi sampul kreator
   dipotong separuh oleh gradien yang tidak pernah ia minta. */
.panji-sampul{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}

.profil-milestone{
  position:absolute;left:0;right:0;bottom:0;height:4px;background:rgba(0,0,0,.34)}
.profil-milestone i{
  display:block;height:100%;background:#fff;box-shadow:0 0 12px rgba(255,255,255,.5);
  transition:width .8s cubic-bezier(.2,.9,.3,1)}

.profil-tubuh{padding:0 24px 22px}

/* Avatar menindih tepi sampul, tombol dukung sejajar di ujung kanan. */
.profil-atas{
  display:flex;align-items:flex-end;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin-top:-46px}
/* position+z-index bukan hiasan: bilah milestone diposisikan absolut di
   dalam sampulnya, jadi tanpa ini ia tergambar DI ATAS avatar — segaris
   putih tipis yang memotong sudut wajah kreatornya. */
.profil .ava.xl{
  position:relative;z-index:1;
  width:104px;height:104px;font-size:38px;border-radius:24px;
  box-shadow:0 0 0 4px var(--card), 0 8px 26px rgba(0,0,0,.4)}
.profil-dukung{margin-bottom:6px}

.profil-nama{
  margin:14px 0 0;display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  font-family:var(--tampil);font-weight:800;letter-spacing:-.025em;
  font-size:clamp(22px,4.6vw,34px);line-height:1.1;color:var(--txt)}

.profil-meta{
  margin:7px 0 0;display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  font-size:13px;color:var(--mut)}
.profil-meta .tag{font-family:var(--mono);font-size:12.5px;color:var(--dim)}
/* Pemisahnya menempel pada butir SESUDAHNYA, jadi saat barisnya terbungkus
   ia ikut turun bersama butirnya — bukan tertinggal menggantung di ujung. */
.profil-meta > span + span::before{content:'·';margin-right:9px;opacity:.55}

.profil-bio{margin:11px 0 0;color:var(--mut);font-size:13.5px;line-height:1.6;max-width:62ch}

/* Kanal sebagai tombol bundar. Warnanya baru muncul saat disentuh: empat
   lambang merek berwarna penuh berjajar merebut perhatian dari nama
   kreatornya, yang justru satu-satunya alasan halaman ini dibuka. */
.profil-kanal{display:flex;gap:9px;flex-wrap:wrap;margin-top:15px}
.profil-kanal a{
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:50%;flex:none;
  border:1px solid var(--line2);background:var(--field);color:var(--mut);
  transition:color .16s,border-color .16s,background .16s,transform .16s}
.profil-kanal a:hover{
  color:var(--kanal-warna,var(--txt));border-color:var(--kanal-warna,var(--line3));
  background:var(--raised);transform:translateY(-1px)}
.profil-kanal svg{width:19px;height:19px;display:block}

/* ── saat kreator siaran ──
   Punggungan yang jauh melayang lebih lambat daripada yang dekat. Bukan
   hiasan: ia mengatakan hal yang tidak bisa dikatakan sampul statis.

   Digeser lewat `translate`, bukan `transform`, supaya tidak menimpa
   transform lain yang mungkin dipasang di elemen yang sama. */
@media (prefers-reduced-motion: no-preference){
  .profil.siaran .panji-lapis{animation:panjiLayang linear infinite alternate}
  .profil.siaran .panji-lapis.l0{animation-duration:44s;--layang:10px}
  .profil.siaran .panji-lapis.l1{animation-duration:34s;--layang:18px}
  .profil.siaran .panji-lapis.l2{animation-duration:26s;--layang:27px}
  .profil.siaran .panji-lapis.l3{animation-duration:19s;--layang:38px}
}
@keyframes panjiLayang{
  from{translate:calc(var(--layang) * -1) 0}
  to{translate:var(--layang) 0}
}

@media (max-width:560px){
  .profil-tubuh{padding:0 16px 18px}
  .profil-atas{margin-top:-38px}
  .profil .ava.xl{width:84px;height:84px;font-size:31px;border-radius:20px}
  /* Tombolnya tetap sebaris dengan avatar, tidak melebar penuh: selebar
     penuh ia berdiri DI ANTARA wajah kreator dan namanya, dan yang terbaca
     bukan lagi satu kepala halaman melainkan dua blok yang tidak
     berhubungan. Di 375px keduanya masih muat berdampingan. */
  .profil-dukung{margin-bottom:2px;padding-left:16px;padding-right:16px}
}

/* ═══════════════════ FOTO PROFIL KREATOR ═══════════════════ */

/* Avatar berfoto memakai lingkaran yang sama dengan yang berinisial —
   ukurannya, bulatnya, dan flex:none-nya semua dari .ava. Yang ditambah di
   sini hanya pemotongannya. */
.ava.berfoto{overflow:hidden;background:var(--inset);padding:0}
.ava.berfoto img{
  width:100%;height:100%;display:block;object-fit:cover;border-radius:inherit}

.foto-atur{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:4px 0 0}
/* Kotak berkas bawaan peramban disembunyikan dari mata, bukan dari papan
   ketik: `display:none` membuatnya tidak bisa dicapai Tab sama sekali, dan
   label di atasnya berhenti bekerja bagi yang tidak memakai tetikus. */
.foto-berkas{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}
.foto-berkas:focus-visible + *,
label.btn:has(+ .foto-berkas:focus-visible){outline:2px solid var(--ungu);outline-offset:2px}
.foto-atur label.btn{cursor:pointer}
.foto-ket{display:block;margin:11px 0 0;line-height:1.6;max-width:62ch}

/* Petak intip sampul di konsol: panji yang sama, dikecilkan. Bukan gambar
   tiruan — kalau tiruan, ia akan menyimpang dari panji sungguhan pada
   perubahan berikutnya, dan yang melihat selisihnya kreator, di halaman
   publiknya sendiri. */
.sampul-atur{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin:6px 0 0}
.sampul-intip{
  position:relative;overflow:hidden;flex:1;min-width:210px;max-width:340px;
  height:86px;border-radius:10px;background:var(--panji-warna,var(--grad));
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.18)}
.sampul-intip .panji-latar{color:#0C0918}
/* Petak intip latar: gambarnya, selubungnya, dan sebuah kotak yang mewakili
   kartu halaman. Tanpa kotak itu yang terlihat cuma gambar gelap, dan yang
   ditanyakan kreator — "masih terbaca tidak isinya nanti?" — tidak terjawab. */
.latar-intip{
  position:relative;overflow:hidden;flex:1;min-width:210px;max-width:340px;
  height:86px;border-radius:10px;background:var(--bg);
  box-shadow:inset 0 0 0 1px var(--line2)}
.latar-intip img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.latar-intip::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--bg) 52%, transparent) 0%,
    color-mix(in srgb, var(--bg) 93%, transparent) 55%,
    var(--bg) 82%)}
.latar-kartu{
  position:absolute;left:14px;right:14px;top:22px;bottom:0;z-index:1;
  border-radius:7px 7px 0 0;background:var(--card);
  box-shadow:0 -1px 0 var(--line2), 0 -8px 20px rgba(0,0,0,.3);
  display:flex;align-items:center;justify-content:center;
  font-size:10px;color:var(--dim)}
.sampul-nama{
  position:absolute;left:11px;bottom:9px;z-index:1;color:#fff;
  font-family:var(--tampil);font-weight:800;font-size:14px;letter-spacing:-.02em;
  text-shadow:0 1px 3px rgba(0,0,0,.5)}

/* Pasangan medan borang yang muat sendiri.

   Dipakai menggantikan `row` dengan kotak berlebar tetap. Kolom kartunya bisa
   selebar 340px, dan di situ kotak 150px di sebelah kotak yang melar tidak
   pernah muat berdua: barisnya terbungkus, dan yang tertinggal satu kotak
   sempit berdiri sendirian — terbaca sebagai cacat, bukan sebagai pilihan. */
.bidang{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
  gap:12px;align-items:end}
.bidang > div{min-width:0}
.bidang .in{width:100%}

.foto-aksi{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.foto-aksi form{display:contents}

/* Intip logo brand: gambar yang sama di atas dua latar.

   Dua, bukan satu, dan bukan demi kerapian. Logo berlatar putih — yang
   didapat begitu saja dari JPEG mana pun — tidak kelihatan bermasalah di
   kartu terang dan menjadi kotak putih menyala di papan siaran yang gelap.
   Satu petak saja berarti separuh brand tidak pernah melihat masalahnya
   sampai kodenya tayang di depan penonton orang lain. */
.logo-intip{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px}
.logo-intip .petak{
  flex:1 1 180px;min-width:150px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  padding:16px 14px;border-radius:12px;border:1px solid var(--line2);
}
.logo-intip .petak img{height:38px;width:auto;max-width:100%;object-fit:contain;display:block}
.logo-intip .petak .lbl{font-size:10px;letter-spacing:.08em;text-transform:uppercase}
/* Warnanya dituliskan apa adanya, BUKAN lewat token tema.

   --malam-3 menjadi #FFFFFF di tema terang, dan petak "gelap" yang ikut
   memutih justru menyembunyikan satu-satunya hal yang ia ada untuk
   ditunjukkan. Yang ditiru di sini bukan tema konsol brand, melainkan papan
   siaran — dan papan itu gelap bagi penonton berapa pun tema yang dipakai
   brand saat mengunggah. Angkanya diambil dari --ov-panel di atas, dipadatkan
   karena ia di sana setengah tembus di atas video. */
.logo-intip .gelap{background:#0C0918}
.logo-intip .gelap .lbl{color:#8A80A3}
.logo-intip .terang{background:#fff}
.logo-intip .terang .lbl{color:#6B6878}

/* Nama widget di tabel tidak dipatahkan jadi tiga baris. "Papan antrean main
   bareng" di kolom selebar 90px menjadi menara setinggi empat baris yang
   memaksa seluruh barisnya ikut tinggi. */
/* Tabel widget overlay: delapan kolom di kartu selebar 688px.

   Bantalannya dipersempit dan hanya di sini. Sepuluh piksel di kiri-kanan
   delapan kolom sudah 160 piksel — seperempat lebar kartunya habis untuk
   ruang kosong, dan yang terdorong keluar kolom terakhir: tombol simpannya.
   Dengan enam piksel, seluruh delapan kolom muat tanpa satu pun tergulir. */
.t-widget th,.t-widget td{padding-left:6px;padding-right:6px}
.t-widget th:first-child,.t-widget td:first-child{padding-left:9px}
.t-widget th:last-child,.t-widget td:last-child{padding-right:9px}

/* Kolom aksi dipatok di tepi kanan.

   Delapan kolom tidak akan pernah muat di kartu selebar 688px tanpa memeras
   isinya sampai tidak terbaca, jadi tabelnya memang bergulir mendatar — dan
   yang pertama terdorong keluar pandangan justru tombol simpannya. Tabel yang
   perubahannya tidak bisa disimpan tanpa menggulir dulu ke kanan adalah tabel
   yang perubahannya akan hilang.

   Latar pekat wajib: tanpa itu isi kolom yang lewat di bawahnya terbaca
   menembus tombolnya. */
.t-widget th:last-child,.t-widget td:last-child{
  position:sticky;right:0;background:var(--card);
  box-shadow:-10px 0 12px -10px rgba(0,0,0,.5)}
.t-widget tbody tr:hover td:last-child{background:var(--malam-4)}
.t-widget .w-simpan{padding-left:9px;padding-right:9px}

/* Nama widget di tabel tidak dipatahkan jadi menara. "Papan antrean main
   bareng" di kolom selebar 90px menjadi empat baris yang memaksa seluruh
   barisnya ikut tinggi. */
.t td.w-nama{min-width:104px}
.t td.w-nama b{display:block;line-height:1.35}


/* ═══════════════════ PAGINASI ═══════════════════
   Cacah barisnya di kiri, tombolnya di kanan. Yang ditanyakan orang di kaki
   tabel bukan "halaman berapa ini" melainkan "ada berapa seluruhnya", jadi
   angkanya yang dibaca duluan. */
.pagi{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap}
.pagi-cacah{margin:0;font-size:12px;color:var(--mut)}
.pagi-cacah b{color:var(--txt);font-weight:700;font-family:var(--mono);font-size:11.5px}

.pagi-nav{display:flex;align-items:center;gap:4px;margin:0;padding:0;list-style:none}
.pagi-t{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:32px;height:32px;padding:0 9px;border-radius:9px;
  border:1px solid var(--line2);background:var(--field);
  font-size:12.5px;font-weight:600;color:var(--mut);text-decoration:none;
  font-family:var(--mono);
  transition:border-color .16s,background .16s,color .16s}
a.pagi-t:hover{border-color:var(--line3);color:var(--txt)}
.pagi-t.kini{
  border-color:var(--ungu);background:var(--ungu-mud);color:var(--txt);
  box-shadow:inset 0 0 0 1px var(--ungu)}
/* Ujung yang tidak bisa dituju tetap digambar, tidak dihilangkan: deret
   tombol yang berubah panjang tiap ganti halaman membuat tombol berikutnya
   bergeser ke bawah kursor yang baru saja menekannya. */
.pagi-t.mati{opacity:.4;cursor:default}
/* Ikon panahnya digambar sebaris di tampilannya, jadi ukurannya dipatok di
   sini — bukan diwarisi dari kelas kerangka yang tidak dimuat aplikasi ini. */
.pagi-t .ic{width:15px;height:15px;flex:none}
.pagi-sela{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:20px;height:32px;color:var(--dim);font-size:12.5px}

@media (max-width:560px){
  .pagi{justify-content:center}
  .pagi-cacah{width:100%;text-align:center}
}

/* ═══════════════════ URL BROWSER SOURCE ═══════════════════
   Disalin sekali saat memasang OBS, lalu dilewati setiap kali kreator kembali
   untuk menata papan. Karena itu ia dipadatkan sampai satu baris per URL:
   nama, keterangan singkat, kotak, dan tombol salin sejajar.

   Kisinya di KARTUNYA, bukan di tiap baris, dan barisnya `display:contents`.
   Kisi per baris membuat lebar kolom namanya dihitung ulang tiap baris —
   "Tip overlay all boards" dan "Queue board separate, optional" panjangnya
   berbeda, jadi kedua kotak URL-nya berakhir tidak sejajar, meleset enam
   puluh piksel. Satu kisi bersama membuat ketiga kolomnya sepakat sendiri,
   berapa pun panjang namanya dalam bahasa mana pun. */
.url-obs{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  gap:8px 10px;align-items:center}
.url-obs .baris{display:contents}
.url-obs .nm{
  font-size:12.5px;font-weight:700;color:var(--txt);white-space:nowrap}
/* Keterangannya ikut di baris yang sama, bukan di bawahnya — sebaris di
   bawah nama akan mengembalikan tinggi yang baru saja dihemat. */
.url-obs .nm em{font-style:normal;font-weight:400;font-size:11px;color:var(--dim)}
.url-obs .in{font-size:12px;padding-top:7px;padding-bottom:7px}
.url-obs .cat{
  grid-column:1 / -1;margin:2px 0 0;font-size:11.5px;line-height:1.55;color:var(--dim)}

/* Varian untuk kartu sempit — kolom samping selebar 340px, bukan layar
   sempit. Tiga kolom di situ menyisakan kotak URL selebar kata "http", dan
   tautan yang tidak bisa dibaca tidak bisa diperiksa sebelum disalin. */
.url-obs.sempit{grid-template-columns:minmax(0,1fr) auto;gap:7px 8px}
.url-obs.sempit .nm{grid-column:1 / -1}

/* Di layar sempit namanya naik sendiri ke atas kotaknya. Tiga kolom di lebar
   360px membuat kotak URL-nya tinggal selebar dua tiga huruf. */
@media (max-width:620px){
  .url-obs{grid-template-columns:minmax(0,1fr) auto;gap:7px 8px}
  .url-obs .nm{grid-column:1 / -1}
  .url-obs .nm + .in{margin-top:0}
}

/* ═══════════════════ GAYA PANEL PER PAPAN ═══════════════════
   Delapan gaya, satu kosakata untuk kelima papan. Kelas `papan` menandai yang
   ikut aturan ini, jadi gaya yang sama tidak perlu ditulis lima kali untuk
   lima papan yang bentuk dasarnya berbeda-beda.

   Dibaringkan di bawah `.obs` dengan dua kelas, jadi kekhususannya (0,3,0)
   mengungguli aturan dasar tiap papan — `.obs .ov-lead` dan kawan-kawannya
   yang (0,2,0) — tanpa satu pun !important.

   Tiap pemilih punya kembaran ber-`.pnl`, dipakai petak contoh dan jendela
   pratinjau di konsol. Bukan salinan gayanya, melainkan pemilih kedua untuk
   aturan yang sama: petak contoh yang digambar sendiri akan menyimpang dari
   panggungnya suatu hari, dan yang melihat selisihnya kreator, di siaran.

   Warnanya tidak disebut di sini sama sekali. Papan membaca --ov-* dari
   panggung, dan papan yang temanya ditimpa membawa tokennya sendiri di
   atribut gaya; gaya panel cuma mengurus BENTUK. Itu yang membuat delapan
   gaya × tiga warna tidak menjadi dua puluh empat aturan. */

.obs .papan.gaya-kartu,
.pnl .papan.gaya-kartu{
  background:var(--ov-panel);border:1px solid var(--ov-tepi);
  border-radius:var(--ov-radius);box-shadow:none}

.obs .papan.gaya-tegas,
.pnl .papan.gaya-tegas{
  background:var(--ov-panel);border:2px solid var(--ov-aksen);
  border-radius:var(--ov-radius);backdrop-filter:none;box-shadow:none}

/* Panel nyaris bening. Buramnya yang membuat tulisan tetap terbaca di atas
   gambar siaran yang ramai — tanpa itu, gaya ini cuma teks di atas apa pun
   yang kebetulan lewat. */
.obs .papan.gaya-kaca,
.pnl .papan.gaya-kaca{
  background:color-mix(in srgb, var(--ov-panel) 45%, transparent);
  border:1px solid color-mix(in srgb, var(--ov-teks) 22%, transparent);
  border-radius:var(--ov-radius);backdrop-filter:blur(10px);box-shadow:none}

/* Tanpa panel, satu batang aksen di kiri. Papan paling ringan yang masih
   punya tepi — berguna saat gambar siarannya sudah ramai sendiri. */
.obs .papan.gaya-garis,
.pnl .papan.gaya-garis{
  background:none;border:0;border-left:3px solid var(--ov-aksen);
  border-radius:0;backdrop-filter:none;box-shadow:none;padding-left:11px}

/* Pita aksen di kepala papan. Digambar dengan ::before supaya tidak ada satu
   pun papan yang markup-nya perlu diubah untuk menerimanya. */
.obs .papan.gaya-pita,
.pnl .papan.gaya-pita{
  background:var(--ov-panel);border:1px solid var(--ov-tepi);
  border-radius:var(--ov-radius);box-shadow:none;overflow:hidden}
.obs .papan.gaya-pita::before,
.pnl .papan.gaya-pita::before{
  content:'';position:absolute;left:0;right:0;top:0;height:3px;
  background:var(--ov-aksen)}

.obs .papan.gaya-kapsul,
.pnl .papan.gaya-kapsul{
  background:var(--ov-panel);border:1px solid var(--ov-tepi);
  border-radius:999px;box-shadow:none;padding-left:16px;padding-right:16px}

/* Cahaya aksen di sekeliling. Untuk papan yang memang ingin dilihat lebih
   dulu daripada yang lain. */
.obs .papan.gaya-sorot,
.pnl .papan.gaya-sorot{
  background:var(--ov-panel);border:1px solid var(--ov-aksen);
  border-radius:var(--ov-radius);
  box-shadow:0 0 26px color-mix(in srgb, var(--ov-aksen) 42%, transparent)}

/* Tulisannya saja. Garis luar teksnya yang menanggung keterbacaan, dan itu
   sebabnya gaya ini memaksa --ov-bayang menyala meski kreator mematikannya
   untuk panggung: tanpa panel dan tanpa garis luar, papan ini menghilang di
   atas gambar siaran yang terang. */
.obs .papan.gaya-tanpa,
.pnl .papan.gaya-tanpa{
  background:none;border:0;border-radius:0;backdrop-filter:none;box-shadow:none;
  padding-left:0;padding-right:0;
  --ov-bayang:0 1px 3px rgba(0,0,0,.85), 0 0 10px rgba(0,0,0,.55)}

/* Running text membentang di kaki panggung; ia bertepi atas, bukan berpanel
   penuh, dan beberapa gaya harus mengalah pada bentuk itu. */
.obs .ov-run.papan.gaya-kartu,
.obs .ov-run.papan.gaya-tegas,
.obs .ov-run.papan.gaya-kaca,
.obs .ov-run.papan.gaya-pita,
.pnl .ov-run.papan.gaya-kartu,
.pnl .ov-run.papan.gaya-tegas,
.pnl .ov-run.papan.gaya-kaca,
.pnl .ov-run.papan.gaya-pita{
  border-width:1px 0 0;border-radius:0}
.obs .ov-run.papan.gaya-tegas,
.pnl .ov-run.papan.gaya-tegas{border-top-width:2px}
.obs .ov-run.papan.gaya-kapsul,
.pnl .ov-run.papan.gaya-kapsul{border-radius:999px;margin:0 10px;width:auto;left:0;right:0}
.obs .ov-run.papan.gaya-garis,
.pnl .ov-run.papan.gaya-garis{border-left-width:3px;border-top:0;padding-left:11px}

/* Kotak alert punya animasi muncul yang memakai transform, dan gaya kapsul
   yang memaksa padding mendatar akan menggeser titik tengahnya. Lebarnya
   yang mengalah. */
.obs .ov-alert.papan.gaya-kapsul,
.pnl .ov-alert.papan.gaya-kapsul{padding-left:34px;padding-right:34px}


/* ═══════════════════ PEMILIH TEMA PAPAN ═══════════════════ */

/* Lima papan, satu kartu. Lima kartu berjajar akan membuat halaman pratinjau
   dua kali lebih panjang, dan yang dicari kreator selalu satu papan saja —
   yang sedang mengganggunya. */
.desain-tab{display:flex;flex-wrap:wrap;gap:6px;margin:2px 0 16px}
.desain-tab button{
  display:flex;align-items:center;gap:7px;cursor:pointer;
  padding:8px 13px;border-radius:999px;border:1px solid var(--line2);
  background:var(--field);color:var(--mut);font-size:12.5px;font-weight:600;
  font-family:inherit;transition:border-color .16s,background .16s,color .16s}
.desain-tab button:hover{border-color:var(--line3);color:var(--txt)}
.desain-tab button.on{
  border-color:var(--ungu);background:var(--ungu-mud);color:var(--txt);
  box-shadow:inset 0 0 0 1px var(--ungu)}
.desain-tab .ic{width:15px;height:15px}
.desain-tab .mati-tanda{
  width:6px;height:6px;border-radius:50%;background:var(--dim);flex:none}
.desain-tab button.nyala .mati-tanda{background:var(--gn)}

.desain-panel{display:none}
.desain-panel.on{display:block}

/* Jendela pratinjau dan petak contoh memakai latar panggung yang sama —
   papan overlay selalu digubah di atas gambar siaran yang gelap, dan menilai
   warnanya di atas kertas konsol yang terang berarti menilai yang salah. */
.pnl{
  background:linear-gradient(145deg,#1B1533 0%,#241B3E 45%,#121020 100%);
  color:var(--ov-teks,#F3EDE1);font-family:var(--ov-font,inherit)}
.papan-jendela{
  border-radius:calc(var(--r) - 3px);padding:20px 16px;margin-bottom:13px;
  display:flex;align-items:center;justify-content:center;min-height:150px;
  overflow:hidden}

/* Papan yang dikloning ke jendela pratinjau dilepas dari letak panggungnya:
   di sana ia berdiri di tengah kotaknya sendiri, bukan menempel di sudut
   1920×1080.

   Satu kelas penanda, bukan daftar nama papan. Daftar itu dulu menyebut
   kelimanya satu per satu, dan papan keenam yang terlewat tetap memakai
   position:absolute dengan top:60% — ia meluber keluar jendelanya dan
   mendarat di atas tombol simpan, yang lalu dilaporkan "tidak bisa diklik".
   Penandanya dipasang skrip yang mengkloning papannya; papan berikutnya
   tidak perlu menambahkan apa pun di sini. */
.papan-jendela .papan-klon{
  position:relative;inset:auto;left:auto;right:auto;top:auto;bottom:auto;
  transform:none;opacity:1;margin:0;width:100%;max-width:230px;min-width:0;z-index:auto}
.papan-jendela .papan-klon.ov-alert{min-width:0;padding-left:16px;padding-right:16px}
/* Papan iklan berisi kode QR yang ukurannya dipatok untuk panggung 1920×1080.
   Di jendela selebar 230px ia harus ikut mengecil, kalau tidak kodenya saja
   sudah selebar seluruh papannya. */
.papan-jendela .ov-iklan{gap:8px;padding:10px}
.papan-jendela .ov-iklan .ik-qr{width:52px;height:52px;padding:3px}
/* Jendela pratinjau mini punya skalanya sendiri, dan logonya harus ikut.
   Dibiarkan 26px di sebelah teks 9px, ia jadi satu-satunya benda berukuran
   penuh di dalam papan yang sudah dikecilkan — dan papan contohnya berhenti
   mewakili papan sungguhan, yang justru satu-satunya gunanya. */
.papan-jendela .ov-iklan .ik-isi{min-width:0;max-width:124px}
.papan-jendela .ov-iklan .ik-logo{height:16px;max-width:124px}
.papan-jendela .ov-iklan .ik-kode{font-size:22px;letter-spacing:.1em}
.papan-jendela .ov-iklan .ik-brand,.papan-jendela .ov-iklan .ik-poin{font-size:9px}
.papan-jendela .ov-iklan .ik-bar{margin-top:2px}
.papan-jendela .papan-klon.ov-run{max-width:100%}
.papan-jendela .ov-run .track{animation-duration:9s}

/* Petak contoh tiap gaya: kotak kecil berisi satu judul dan dua baris, dibuat
   dengan aturan gaya yang sama persis dengan papan sungguhan. Isinya penanda
   tempat; bentuk panelnya yang sedang dipilih, bukan isinya. */
.gaya-mini{
  display:flex;align-items:center;justify-content:center;margin-bottom:8px;
  border-radius:6px;padding:12px 10px;min-height:66px;overflow:hidden}
.gaya-mini .papan{
  width:100%;padding:7px 9px;font-family:var(--ov-font,inherit);
  --ov-skala:1;--ov-radius:8px}
.gaya-mini .papan i{
  display:block;height:3px;border-radius:2px;background:var(--ov-aksen);
  width:46%;margin-bottom:5px}
.gaya-mini .papan u{
  display:block;height:3px;border-radius:2px;text-decoration:none;
  background:var(--ov-teks);opacity:.55;margin-top:4px}
.gaya-mini .papan u.pendek{width:62%}

.desain-warna{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:12px;margin-top:4px}
.desain-warna .warna{display:flex;flex-direction:column;gap:5px}
.desain-warna .lbl{margin:0}
.desain-warna small{font-size:11px;color:var(--dim);line-height:1.4}
.desain-warna .in.hex{font-family:var(--mono);font-size:11.5px;text-transform:uppercase}
.desain-warna input[type=color]{
  width:100%;height:32px;padding:0;border:1px solid var(--line2);
  border-radius:8px;background:var(--field);cursor:pointer}

/* Tombol "ikut tema panggung" mengosongkan warnanya, dan mengosongkan itulah
   keadaan bawaannya — bukan warna tema yang disalin ke dalam papan. Papan
   yang warnanya disalin berhenti mengikuti tema panggung berikutnya. */
.desain-balik{
  display:inline-flex;align-items:center;gap:6px;margin-top:10px;cursor:pointer;
  background:none;border:0;padding:0;font-family:inherit;
  font-size:11.5px;color:var(--mut);text-decoration:underline;
  text-underline-offset:3px;text-decoration-color:var(--line3)}
.desain-balik:hover{color:var(--txt)}
.desain-balik .ic{width:13px;height:13px}
.desain-warisan{
  margin:9px 0 0;font-size:11px;line-height:1.55;color:var(--dim);font-family:var(--mono)}

/* ═══════════════════ PINDAIAN KODE QR DI STUDIO ═══════════════════ */
.qr-stat{display:flex;align-items:center;gap:20px;margin-top:16px;flex-wrap:wrap}
.qr-gbr{
  background:#FFFFFF;border-radius:12px;padding:9px;width:104px;height:104px;flex:none;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.07)}
.qr-gbr svg{width:100%;height:100%;display:block}
.qr-angka{display:flex;gap:26px;flex-wrap:wrap}
.qr-angka b{
  display:block;font-family:var(--tampil);font-weight:800;font-size:34px;
  line-height:1.05;letter-spacing:-.03em;color:var(--txt)}
.qr-angka span{
  display:flex;align-items:center;gap:6px;margin-top:4px;
  font-size:12px;color:var(--mut)}
.qr-angka span .ic{width:14px;height:14px;color:var(--dim)}
.qr-terakhir{margin:16px 0 0;font-size:12.5px;line-height:1.6;color:var(--mut)}
.qr-terakhir b{color:var(--txt);font-weight:600}

/* ═══════════════════ PEMILIH DESAIN KODE QR ═══════════════════ */

/* Pengaturannya di kiri, pratinjaunya menempel di kanan. Sebelumnya satu
   kolom, dan satu-satunya pratinjau ada di panggung jauh di atas kartu ini:
   memilih di kaki halaman lalu menggulir ke atas untuk melihat akibatnya,
   sepuluh kali untuk bingkai dan dua belas kali untuk bentuk. */
.desain-atur{display:grid;grid-template-columns:minmax(0,1fr) 252px;gap:24px;align-items:start}
.desain-sisi{position:sticky;top:16px;align-self:start}
.desain-sisi-dalam{
  border:1px solid var(--line2);border-radius:var(--r);padding:14px;background:var(--field)}
@media (max-width:900px){
  .desain-atur{grid-template-columns:1fr}
  .desain-sisi{position:static}
}

/* Jendela pratinjau: latar gelap, karena kode ini hidup di atas siaran dan
   bukan di atas kertas konsol. */
.qr-jendela{
  border-radius:calc(var(--r) - 3px);padding:20px 16px;margin-bottom:13px;
  background:linear-gradient(145deg,#1B1533 0%,#241B3E 45%,#121020 100%);
  display:flex;justify-content:center;align-items:center;min-height:186px}
.qr-jendela .ov-qr{position:relative;right:auto;bottom:auto;width:142px;max-width:100%}
.qr-jendela .ov-qr.menunggu{opacity:.4}
.qr-jendela .ov-qr,.qr-mini .ov-qr{transition:opacity .15s}

.desain-pilih{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-top:4px}
.desain-pilih.rapat{grid-template-columns:repeat(auto-fill,minmax(122px,1fr));gap:8px}
.desain-opsi{
  display:flex;flex-direction:column;gap:3px;cursor:pointer;
  padding:12px 13px 13px;border-radius:var(--r);border:1px solid var(--line2);
  background:var(--field);transition:border-color .16s,background .16s}
.desain-pilih.rapat .desain-opsi{padding:9px 10px 10px}
.desain-opsi:hover{border-color:var(--line3)}
.desain-opsi.on{border-color:var(--ungu);background:var(--ungu-mud);box-shadow:inset 0 0 0 1px var(--ungu)}
.desain-nama{font-size:12.5px;font-weight:700;color:var(--txt)}
.desain-ket{font-size:11px;line-height:1.45;color:var(--dim)}

/* Petak contoh tiap bingkai adalah bingkai itu sendiri, dikecilkan, dengan
   tema overlay kreator sendiri. Sempat dibuat dari kotak CSS yang ditiru —
   dan sepuluh bingkai yang bedanya cuma letak pita dan bentuk tepi mustahil
   dibedakan lewat tiruan. */
.qr-mini{
  display:flex;justify-content:center;align-items:center;margin-bottom:8px;
  border-radius:6px;padding:11px 6px;min-height:74px;
  background:linear-gradient(145deg,#1B1533,#241B3E 70%)}
.qr-mini .ov-qr{--qr-pad:5px;position:relative;right:auto;bottom:auto;width:54px}
.qr-mini .ov-qr .kode{padding:3px;border-radius:3px}
.qr-mini .ov-qr .ket{font-size:5.5px;line-height:1.25}
.qr-mini .ov-qr.bingkai-ponsel{padding:9px 5px 7px}
.qr-mini .ov-qr.bingkai-ponsel::after{top:4px;width:15px;height:2px}
.qr-mini .ov-qr.bingkai-polaroid{padding:5px 5px 13px}
.qr-mini .ov-qr.bingkai-sobek{padding:5px 5px 10px}
.qr-mini .ov-qr.bingkai-sudut{padding:4px}
.qr-mini .ov-qr.bingkai-sudut::before{
  -webkit-mask-size:9px 9px;mask-size:9px 9px}

/* Petak contoh bentuk modul digambar penggambar yang sama dengan kodenya
   sendiri — lihat KodeQr::contoh(). */
.qr-petak{display:block;width:34px;height:34px;margin-bottom:8px;color:var(--txt)}
.qr-petak svg{width:100%;height:100%;display:block}

.desain-golongan{
  margin:15px 0 8px;font-size:10.5px;font-weight:800;letter-spacing:.07em;
  text-transform:uppercase;color:var(--mut)}
.desain-golongan.rewel{color:var(--am)}
.desain-kabar{margin:2px 0 4px;font-size:11.5px;line-height:1.65;color:var(--dim);max-width:64ch}

.qr-kontras,.qr-tangguh{
  margin:0 0 8px;font-size:11.5px;line-height:1.55;color:var(--gn);
  font-family:var(--mono);letter-spacing:.01em}
.qr-tangguh{color:var(--mut);margin-bottom:13px}
.qr-kontras.kurang{color:var(--rd)}
.qr-tangguh.kurang{color:var(--am)}

/* ═══════════════════════════ KARTU KREATOR ═══════════════════════════
   Ubin potret untuk komponen <x-kartu-kreator>. Dipakai petak di halaman muka
   dan halaman daftar kreator, jadi aturannya tinggal di sini — bukan di
   landing.css yang hanya dimuat satu halaman.

   Fotonya yang jadi kartunya, bukan avatar kecil di dalam kartu: yang membuat
   deret ini meyakinkan adalah wajah orangnya, dan wajah selebar 32px tidak
   meyakinkan siapa pun.

   Seluruh kartu adalah <a>: sasaran sentuhnya selebar kartu, dan hanya ada
   satu elemen yang menerima fokus papan ketik. */

.kk-petak {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.4vw, 18px);
  justify-content: start;
}
@media (max-width: 1100px) { .kk-petak { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 760px)  { .kk-petak { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.kk-kartu {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: 20px;
  overflow: hidden;
  background: var(--card2);
  border: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  isolation: isolate;
  transition: border-color .42s ease, transform .42s cubic-bezier(.16, 1, .3, 1);
}
.kk-kartu:hover { border-color: var(--cy); transform: translateY(-4px); }
.kk-kartu:focus-visible { outline: 2px solid var(--emas); outline-offset: 3px; }

.kk-foto {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .7s cubic-bezier(.16, 1, .3, 1);
}
.kk-kartu:hover .kk-foto,
.kk-kartu:focus-visible .kk-foto { transform: scale(1.05); }

.kk-kartu.tanpa-foto { background: var(--gradien, var(--card2)); }
.kk-inisial {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--tampil);
  font-size: clamp(64px, 9vw, 104px);
  font-weight: 800;
  letter-spacing: -.04em;
  color: rgba(12, 9, 24, .34);
  line-height: 1;
}

/* Gelap di kaki kartu supaya namanya terbaca di atas foto apa pun. Dua
   perhentian, bukan satu: gradien satu langkah menutupi terlalu banyak foto
   untuk mencapai kepekatan yang sama di bagian bawahnya. */
.kk-scrim {
  position: absolute; inset: 30% 0 0;
  background: linear-gradient(to bottom,
    rgba(12, 9, 24, 0) 0%, rgba(12, 9, 24, .62) 52%, rgba(12, 9, 24, .95) 100%);
  pointer-events: none;
}

.kk-isi {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: clamp(14px, 1.6vw, 20px);
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
/* Nama panjang dipotong, tidak dibungkus: ubin yang tingginya ikut berubah
   karena satu nama lebih panjang membuat barisnya bergerigi. */
.kk-nama {
  font-family: var(--tampil);
  font-size: clamp(17px, 1.5vw, 20px);
  font-weight: 800; letter-spacing: -.02em;
  color: #F3EDE1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kk-user {
  font-size: 13px; color: rgba(243, 237, 225, .64);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kk-tautan {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 9px;
  font-size: 13px; font-weight: 700;
  color: var(--vi);
}
.kk-tautan .ic { width: 15px; height: 15px; transition: transform .42s cubic-bezier(.16, 1, .3, 1); }
.kk-kartu:hover .kk-tautan .ic,
.kk-kartu:focus-visible .kk-tautan .ic { transform: translateX(4px); }

.kk-live {
  position: absolute;
  top: 12px; left: 12px;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--tampil);
  font-size: 10.5px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: #FFE9E9;
  background: rgba(196, 50, 60, .92);
  border-radius: 999px;
  padding: 5px 11px;
  backdrop-filter: blur(6px);
}
.kk-live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
@media (prefers-reduced-motion: no-preference) {
  .kk-live::before { animation: kkKedip 1.8s ease-in-out infinite; }
}
@keyframes kkKedip { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* Dua kolom tetap dipertahankan di layar tersempit: satu ubin potret selebar
   layar tingginya hampir satu layar penuh, dan enam ubin seperti itu berubah
   jadi enam kali menggulir untuk membaca enam nama. */
@media (max-width: 520px) {
  .kk-petak { gap: 10px; }
  .kk-nama { font-size: 15px; }
  .kk-tautan { font-size: 12px; margin-top: 6px; }
}

/* Borang pencarian di halaman daftar kreator. */
.kreator-saring {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  margin: 0 0 20px;
}
.kreator-saring .in { flex: 1 1 260px; min-width: 0; }
.kreator-sakelar {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 0 15px; min-height: 44px;
  border-radius: 999px; border: 1px solid var(--line2);
  background: var(--shell); color: var(--mut);
  font-size: 14px; font-weight: 600; cursor: pointer;
  transition: border-color .18s ease, color .18s ease, background .18s ease;
}
.kreator-sakelar:hover { border-color: var(--line3); color: var(--txt); }
.kreator-sakelar:has(input:checked) { border-color: var(--cy); color: var(--txt); background: var(--cy-deep); }
.kreator-sakelar b {
  font-family: var(--tampil); font-size: 12px; font-weight: 800;
  color: var(--emas); font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════ KAKI SITUS ═══════════════════════════
   Satu kaki untuk halaman muka dan halaman publik lainnya. Dulu ia tinggal
   di landing.css, dan landing.css hanya dimuat halaman muka — kaki yang sama
   di halaman lain akan tampil tanpa satu pun gaya.

   Tokennya global semua, BUKAN token .lp. --aksen dan --t-cepat hanya hidup
   di dalam .lp, dan kaki di luar .lp akan kehilangan warna sorot serta
   transisinya tanpa melempar galat apa pun. */

.kaki-situs {
  border-top: 1px solid var(--tepi);
  padding-block: 44px 54px;
  background: var(--malam-2);
}

/* Pias kiri-kanannya mengikuti pias halaman yang memuatnya.

   Halaman muka memakai --tepi-h (clamp 20-56px); halaman jelajah memakai
   .wrap dengan 30px tetap. Satu angka tetap di sini akan membuat kakinya
   bergeser dari isi di atasnya di salah satu dari keduanya. */
.kaki-in {
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: var(--tepi-h, 30px);
}
.kaki-situs .kaki-in { display: flex; flex-wrap: wrap; gap: 26px 48px; align-items: flex-start; }
.kaki-situs .merek { flex: 1 1 250px; min-width: 0; }
.kaki-situs .merek .tanda {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--tampil); font-size: 17px; font-weight: 800;
  color: var(--krem); text-decoration: none; margin-bottom: 10px;
}
.kaki-situs .merek .tanda .ic { width: 26px; height: 26px; }
.kaki-situs .merek .kecil { margin: 0; font-size: 13.5px; color: var(--krem-2); line-height: 1.6; }
.kaki-situs nav { display: flex; flex-direction: column; gap: 9px; min-width: 150px; }
.kaki-situs nav b {
  font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--krem-3); font-weight: 700; margin-bottom: 3px;
}
.kaki-situs nav a {
  font-size: 14.5px; color: var(--krem-2); text-decoration: none;
  transition: color .15s ease;
}
.kaki-situs nav a:hover { color: var(--ungu); }

/* Baris bawah: tahun dan status perizinan. Dua span, bukan satu kalimat
   panjang — di ponsel keduanya turun jadi dua baris sendiri, dan status
   perizinan yang menyambung di tengah baris tahun terbaca seperti catatan
   kaki hak cipta. */
.kaki-situs .bawah {
  /* flex-basis 100%: pembungkusnya juga flex, dan anak tunggal di flex baris
     selebar isinya saja — garis atasnya akan berhenti di ujung kalimat, bukan
     di ujung kolom. */
  flex: 1 1 100%;
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  border-top: 1px solid var(--tepi);
  margin: 32px 0 0;
  padding-top: 22px;
  font-size: 13px;
  color: var(--krem-3);
}
