:root{
  --bg:#0b0e14; --card:#141926; --line:#232c42; --txt:#e8ecf4; --dim:#8b94a9;
  --acc:#e8a33d; --acc2:#7fd4ff;
}
*{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
body{margin:0; background:var(--bg); color:var(--txt);
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif; font-size:15px;}
header{display:flex; justify-content:space-between; align-items:center;
  padding:12px 16px; border-bottom:1px solid var(--line);
  position:sticky; top:0; background:var(--bg); z-index:10;}
.brand{font-weight:700; font-size:17px;}
.brand span{color:var(--acc);}
.ver{font-size:11px; color:var(--dim); background:var(--card);
  padding:4px 10px; border-radius:20px; border:1px solid var(--line);}
main{padding:12px; max-width:640px; margin:0 auto;
  display:flex; flex-direction:column;}
.card{background:var(--card); border:1px solid var(--line); border-radius:14px;
  padding:14px; margin-bottom:12px;}
.card.dim{opacity:.75;}
.card h2{margin:0 0 6px; font-size:15px;}
.hint{margin:0 0 10px; color:var(--dim); font-size:13px; line-height:1.45;}
.info{margin-top:10px; font-size:13px; color:var(--acc2); min-height:18px; line-height:1.5;}
.rowlabel{display:block; margin:10px 0 4px; font-size:13px; color:var(--dim);}
.rowlabel b{color:var(--txt);}
input[type=range]{width:100%; margin:6px 0 10px; accent-color:var(--acc); height:28px;}
.filebtn{display:inline-block; background:var(--acc); color:#1a1206; font-weight:700;
  padding:11px 18px; border-radius:10px; cursor:pointer; font-size:14px;}
.btnrow{display:flex; gap:10px; margin:8px 0;}
button{background:#223052; color:var(--txt); border:1px solid var(--line);
  padding:11px 14px; border-radius:10px; font-size:14px; cursor:pointer; flex:1;}
button:disabled{opacity:.4;}
button.on{background:var(--acc); color:#1a1206; border-color:var(--acc); font-weight:700;}
#preview{width:100%; border-radius:10px; background:#000; display:block; cursor:pointer;}
#playerWrap{position:sticky; top:6px; z-index:30; background:var(--card);
  border:1px solid var(--line); border-radius:14px; padding:8px; margin:0 0 10px;}
#transport{display:flex; align-items:center; gap:8px; margin-top:8px;}
#transport button{flex:0 0 auto; padding:9px 14px;}
#loopBar{flex:1; min-width:0;}
#loopTime{font-size:12px; color:var(--dim); min-width:88px; text-align:right;}
#modetoggle{display:flex; gap:8px; margin-top:8px;}
.mbtn{flex:1; padding:8px 6px; font-size:13px; background:#1a2133;}
.mbtn.on{background:var(--acc); color:#1a1206; border-color:var(--acc); font-weight:700;}
.mbtn:disabled{opacity:.35;}
.fgrid{display:grid; grid-template-columns:repeat(3,1fr); gap:8px; margin-bottom:6px;}
.fbtn{background:#1a2133; border:2px solid var(--line); border-radius:10px;
  padding:10px 4px; font-size:12px; color:var(--txt); cursor:pointer;}
.fbtn.on{border-color:var(--acc); background:var(--acc); color:#1a1206; font-weight:700;}
.fbtn.on small{color:#1a1206;}
.fbtn small{display:block; color:var(--dim); font-size:10px; margin-top:2px;}
.txt{display:block; width:100%; background:#0b0e14; color:var(--txt);
  border:1px solid var(--line); border-radius:10px; padding:11px 12px;
  font-size:14px; margin:4px 0 6px;}
select.txt{appearance:auto;}
.chk{display:flex; align-items:center; gap:8px; font-size:13px; color:var(--dim);
  margin:8px 0;}
.chk input{width:18px; height:18px; accent-color:var(--acc);}
.dlbtn{display:inline-block; background:var(--acc); color:#1a1206; font-weight:700;
  padding:12px 20px; border-radius:10px; text-decoration:none; margin-top:8px;}
.trackcard{background:#1a2133; border:1px solid var(--line); border-radius:12px;
  padding:12px; margin-bottom:12px;}
.tchead{display:flex; justify-content:space-between; align-items:center;
  margin-bottom:8px;}
.tstat{font-size:12px; color:var(--dim);}
.tinfo{min-height:20px;}
.trackcard .btnrow{display:flex; gap:8px; margin-top:8px;}
.trackcard .trender{flex:1;}
.trackcard .tremove{background:#3a1f1f;}

/* ===== Panel kolom (landscape: scroll independen) =====
   Portrait: kedua panel display:contents → daun-daunnya jadi flex item
   langsung dari main; urutan visual dikembalikan pakai flex order,
   hasilnya 100% sama seperti sebelum ada wrapper.
   (Kompensasi flex: margin vertikal tidak collapse, jadi margin-top
   #playerWrap dinolkan agar jarak antar-elemen tetap sama.) */
.pane-left,.pane-right{display:contents;}
.sec-foot{order:1;} #playerWrap{order:2;} .sec-loop{order:3;}
.menu-pane{order:4;} .sec-overlay{order:5;} .sec-track{order:6;} .sec-queue{order:7;}

/* ===== LANDSCAPE (HP diputar, lebar ≥640px) =====
   App-shell: tinggi dikunci setinggi layar, body TIDAK scroll —
   tiap kolom punya scroll SENDIRI-SENDIRI (independen): scroll kolom
   kanan ke bawah tidak menggerakkan preview di kolom kiri, dan
   sebaliknya. Preview natural 16:9, tanpa sticky, tanpa satuan
   viewport dinamis (bebas jitter resize saat address bar gerak). */
@media (orientation: landscape) and (min-width: 640px){
  html,body{height:100%;}
  body{display:flex; flex-direction:column; overflow:hidden; overflow-x:clip;}
  header{flex:0 0 auto;}
  main{flex:1; min-height:0; width:100%; max-width:1180px;
    display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
    grid-template-rows:minmax(0,1fr); column-gap:12px;}
  .pane-left,.pane-right{display:block; overflow-y:auto; min-height:0;
    scrollbar-width:thin;}
  .pane-left{grid-column:1;}
  .pane-right{grid-column:2;}
  .menu-pane{display:contents;}
  #playerWrap{position:static;}
  #modeHint{display:none;}
  .fgrid{grid-template-columns:repeat(4,1fr);}
  .fbtn{font-size:11px; padding:9px 3px;}
  /* strip progress ikut di bawah (tengah, lebih lebar); tampil HANYA saat
     class .show ditambahkan JS selama render/join jalan. Menu bar tetap
     tersembunyi di landscape — kolom tetap seperti sebelumnya. */
  #progStrip.show{display:flex; position:fixed; left:50%;
    transform:translateX(-50%); width:min(720px,94vw); bottom:12px;
    border:1px solid var(--line); border-radius:10px;}
  body.strip-on .pane-right{padding-bottom:64px;}
}

/* card bisa di-minimize: tap judul card */
.card h2{cursor:pointer; user-select:none; display:flex; justify-content:space-between; align-items:center;}
.card .chev{font-size:14px; opacity:.55; flex:none; margin-left:8px;}
.card.collapsed > :not(h2){display:none;}

/* ===== header kanan: versi + tombol opsi ===== */
.head-right{display:flex; gap:8px; align-items:center;}
.obtn{flex:none; padding:8px 12px;}
#opsiPanel{margin:0 12px 12px; flex:none;}
#opsiPanel{display:none;}
#opsiPanel.opsi-on{display:block;}
/* ===== progress antrian ===== */
#queueBar{height:10px; background:#0b0e14; border:1px solid var(--line);
  border-radius:6px; overflow:hidden; margin-top:8px;}
#queueBarFill{height:100%; width:0%; background:var(--acc);}
/* ===== progress gabung/loop file luar ===== */
#extJoinBar{height:10px; background:#0b0e14; border:1px solid var(--line);
  border-radius:6px; overflow:hidden; margin-top:8px;}
#extJoinBarFill{height:100%; width:0%; background:var(--acc);}
.qrow{display:flex; justify-content:space-between; gap:8px;
  font-size:13px; padding:4px 0; border-bottom:1px solid var(--line);}
.qrow .qtitle{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.qrow .qst{color:var(--dim); flex:none;}
/* ===== kartu track bisa di-minimize ===== */
.trackcard .tchev{flex:none; padding:6px 10px; font-size:13px;}
.trackcard .thead-title{flex:1; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; min-width:0;}
.trackcard .tdl-head{flex:none;}
.trackcard .tdl-head .dlbtn{margin-top:0; padding:8px 12px;}

/* expander Adjust per-track (collapsed by default) */
.tadj-head{display:flex; align-items:center; gap:8px; margin-top:8px;}
.tadj-head span{flex:1; font-size:13px; color:var(--dim);}
.tadj-chev{flex:none; padding:6px 10px; font-size:13px;}
.tadj-body .rowlabel{margin-top:6px;}
.tpos-head{display:flex; align-items:center; gap:8px; margin-top:8px;}
.tpos-head span{flex:1; font-size:13px; color:var(--dim);}
.tpos-body .rowlabel{margin-top:6px;}
.trackcard.collapsed .tbody{display:none;}
.trackcard .tchead{justify-content:flex-start; gap:8px;}
.trackcard .tstat{flex:none;}

/* ===== player bisa di-minimize (chevron di bar transport) =====
   Saat minimize: canvas + mode + hint sembunyi, tinggal bar transport
   (play + waktu + tombol balik). Berlaku portrait & landscape. */
#playerWrap.min #prevWrap{display:none;}
#playerWrap.min #modetoggle{display:none;}
#playerWrap.min #modeHint{display:none;}
#btnMinPlayer{flex:0 0 auto; padding:9px 10px; font-size:13px;}

/* ===== grup overlay bisa dilipat (title / watermark) =====
   Saklar OFF → body grup sembunyi otomatis; chevron = lipat manual.
   Berlaku portrait & landscape (bukan bagian sistem menu). */
.ogrp-head{display:flex; align-items:center; gap:8px;}
.ogrp-head .chk{flex:1;}
.ogrp-head .ogrp-label{flex:1; font-size:13px; color:var(--txt); font-weight:700;}
.ogrp-chev{flex:none; padding:6px 10px; font-size:13px;}
.ogrp.grp-collapsed .ogrp-body{display:none;}

/* ===== slider Adjust: gutter scroll + kunci =====
   Slider Adjust TIDAK selebar penuh card: 28px kosong di kanan tiap baris
   jadi pegangan scroll (menyentuh area itu tidak menggeser slider).
   Berlaku slider section + per-track. Saat terkunci, slider disabled + redup. */
.sec-adjust input[type=range], .tadj{width:calc(100% - 28px);}
.sec-adjust h2 .h2-actions{margin-left:auto; display:flex; align-items:center;}
#btnAdjLock{flex:none; padding:6px 10px; font-size:13px;}
body.adj-locked .sec-adjust input[type=range], body.adj-locked .tadj{opacity:.45;}

/* ===== strip progress + menu bawah: base (tersembunyi) =====
   Menu bar HANYA tampil di portrait non-agent (lihat blok portrait di bawah).
   Strip tampil saat class .show ditambahkan JS, HANYA selama render/join jalan. */
#menuBar{display:none;}
#progStrip{display:none; align-items:center; gap:8px; background:#1a2133;
  border-top:1px solid var(--line); padding:8px 12px; z-index:40;}
#progStrip .ps-bar{flex:1 1 auto; min-width:40px; height:8px; background:#0b0e14;
  border-radius:4px; overflow:hidden;}
#psFill{height:100%; width:0%; background:var(--acc);}
#psText{flex:0 1 auto; min-width:0; max-width:48%; font-size:12px; color:var(--txt);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
#psStop{flex:none; padding:8px 12px;}

/* ===== PORTRAIT MENU SHELL (v2026.10.22-m): app-shell + menu bawah =====
   HANYA berlaku di portrait NON-agent (body:not(.agent-mode)) — media query
   portrait dan landscape saling eksklusif, jadi blok landscape di atas TIDAK
   tersentuh sama sekali, dan mode agen tetap pakai layout scroll lama.
   Struktur portrait: header | player | loop maker | AREA CARD (1 card aktif,
   scroll internal, display + relative) | strip (kondisional) | menu.
   Card pindah = hide/show DOM (bukan re-render) — tidak ada reset isi.
   FIX STRUKTURAL 2026-10-28: tanpa animasi (display tidak bisa
   ditransisikan; slide/fade dimatikan di -y dan bug tetap). TIDAK ADA
   backdrop blur. */
@media (orientation: portrait){
  html{height:100%;}
  body:not(.agent-mode){height:100%; height:100dvh; display:flex; flex-direction:column;
    overflow:hidden; overflow-x:clip;}
  body:not(.agent-mode) header{flex:0 0 auto;}
  body:not(.agent-mode) main{flex:1; min-height:0; width:100%; max-width:640px;
    padding:12px 12px 68px; display:flex; flex-direction:column;}
  body:not(.agent-mode) .pane-left{display:block; flex:none;}
  body:not(.agent-mode) .pane-right{display:block; position:relative; flex:1;
    min-height:0; overflow:hidden;}
  body:not(.agent-mode) #playerWrap{position:static;}
  /* FIX STRUKTURAL 2026-10-28 (bug menu, terbukti -z): pane nonaktif =
     display:none — kotaknya hilang total, jadi tidak menyumbang overflow
     ke wadah (sebelumnya: absolut + translateY(100%) bikin scrollHeight
     ≈ 2x tinggi pane → wadah kegeser ke maxScroll). Pane aktif = normal
     flow relative; sizing lama dipertahankan (height:auto +
     max-height:100% + overflow-y:auto) agar konten panjang tetap scroll
     internal. Tanpa animasi (display tidak bisa ditransisikan). */
  body:not(.agent-mode) .pane-right > section, body:not(.agent-mode) .pane-right > .menu-pane{display:none; position:relative; height:auto; max-height:100%; margin:0; overflow-y:auto;}
  body:not(.agent-mode) .pane-right > section.menu-on, body:not(.agent-mode) .pane-right > .menu-pane.menu-on{display:block;}
  body:not(.agent-mode) #menuBar{display:flex; position:fixed; left:0; right:0;
    bottom:0; height:56px; background:var(--card);
    border-top:1px solid var(--line); z-index:40;}
  body:not(.agent-mode) .mitem{flex:1; display:flex; flex-direction:column;
    align-items:center; justify-content:center; gap:1px; background:none;
    border:none; border-radius:0; color:var(--dim); font-size:11px;
    padding:6px 2px 4px; position:relative;}
  body:not(.agent-mode) .mitem .mi{font-size:20px; line-height:1;}
  body:not(.agent-mode) .mitem.on{color:var(--acc); font-weight:700;}
  body:not(.agent-mode) .mitem .badge{display:none; position:absolute; top:4px;
    right:6px; min-width:16px; height:16px; padding:0 4px; border-radius:8px;
    background:var(--acc); color:#1a1206; font-size:10px; font-weight:700;
    line-height:16px; text-align:center; font-style:normal;}
  body:not(.agent-mode) .mitem .badge.on{display:inline-block;}
  body:not(.agent-mode) .mitem .badge.dot{width:8px; height:8px; min-width:8px;
    padding:0; border-radius:50%;}
  body:not(.agent-mode) #progStrip.show{display:flex; position:fixed; left:0;
    right:0; bottom:56px;}
  /* panel diagnosa menu (?diag=menu): overlay fixed, tidak mengubah layout
     app sama sekali; hanya tampil bila flag diag ada. */
  #diagPanel{position:fixed; top:0; left:0; right:0; z-index:9999;
    background:rgba(0,0,0,.94); color:#e8ecf4; font:11px/1.5 monospace;
    max-height:46vh; overflow-y:auto; padding:8px; border-bottom:2px solid var(--acc);}
  #diagPanel pre{margin:6px 0; padding:6px; background:#141926; border:1px solid var(--line);
    border-radius:8px; white-space:pre-wrap; word-break:break-all;}
  #diagPanel button{flex:0 0 auto; padding:6px 10px; font-size:12px;}
  body:not(.agent-mode).strip-on main{padding-bottom:112px;}
  /* panel Opsi portrait = dropdown overlay di bawah header, slide-DOWN
     (transform + opacity, 220ms, easing iOS — sama seperti menu). Fixed +
     visibility (bukan display) agar transisi jalan; main tidak menyusut.
     z-index 9 = di bawah header (10), di atas konten main. top di-set JS
     (tinggi header); fallback top:auto = posisi statis di bawah header. */
  body:not(.agent-mode) #opsiPanel{display:block; position:fixed; left:12px; right:12px;
    margin:0; z-index:9; max-height:70vh; overflow-y:auto;
    transform:translateY(-100%); opacity:0; visibility:hidden; pointer-events:none;
    transition:transform .22s cubic-bezier(0.32,0.72,0,1),
      opacity .22s cubic-bezier(0.32,0.72,0,1), visibility 0s linear .22s;}
  body:not(.agent-mode) #opsiPanel.opsi-on{transform:translateY(0); opacity:1;
    visibility:visible; pointer-events:auto;
    transition:transform .22s cubic-bezier(0.32,0.72,0,1),
      opacity .22s cubic-bezier(0.32,0.72,0,1), visibility 0s linear 0s;}
}

/* ===== mode agen (?agent=1): input file tampil agar agen browser bisa upload =====
   Normalnya input file pakai atribut hidden (klik via label) — tapi input hidden
   tidak ada di accessibility tree sehingga agen browser kena target_blocked.
   Class agent-mode HANYA ditambahkan main.js bila URL mengandung ?agent=1. */
.agent-mode input[type=file]{display:block; margin:8px 0;}
/* Multi-footage v1: daftar klip + tombol hapus per klip */
.footrow{display:flex; gap:8px; align-items:center; margin:4px 0;}
.footname{flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px;}
.xbtn{flex:none; width:28px; height:28px; border-radius:8px; border:1px solid var(--line, #ddd); background:transparent; cursor:pointer; display:inline-flex; align-items:center; justify-content:center; line-height:1; padding:0; font-size:16px;}
#footModeRow{margin-top:8px;}
