<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#0a0a0f">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>Sonora</title>
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=DM+Sans:wght@400;500;600&family=DM+Mono:wght@500&display=swap" rel="stylesheet">
<style>
/* ═══════════════════════════════════════════════════════ RESET & VARS */
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
:root{
  --bg:#0a0a0f;--sur:#111118;--panel:#16161f;--card:#1c1c28;
  --bdr:#2a2a3a;--acc:#00e5a0;--acc2:#7c6ff7;--acc3:#ff4d6d;
  --txt:#f0f0f8;--mut:#6b6b85;--dim:#3a3a52
}
html,body{height:100%;overflow:hidden}
body{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--txt);display:flex;flex-direction:column}

/* ═══════════════════════════════════════════════════════ TOPBAR */
.topbar{
  background:var(--sur);border-bottom:1px solid var(--bdr);
  padding:9px 12px;display:flex;align-items:center;gap:8px;
  flex-shrink:0;z-index:40
}
/* Logo — esconde texto no mobile, mantém ícone */
.logo{font-family:'Bebas Neue',sans-serif;font-size:20px;letter-spacing:3px;color:var(--acc);
  display:flex;align-items:center;gap:5px;flex-shrink:0;white-space:nowrap;transition:color .3s}
.logo-txt{transition:all .2s}
.logo-dot{width:5px;height:5px;background:currentColor;border-radius:50%;animation:pu 2s infinite;margin-top:3px}
@keyframes pu{0%,100%{opacity:1}50%{opacity:.3}}
@media(max-width:600px){.logo-txt{display:none}.logo{font-size:22px}}

/* Search — largura máxima no mobile */
.search-wrap{flex:1;position:relative;min-width:0}
.search-wrap .si-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--mut);pointer-events:none;z-index:1}
.si{
  width:100%;background:var(--panel);border:1px solid var(--bdr);border-radius:50px;
  padding:11px 50px 11px 40px;font-family:'DM Sans',sans-serif;font-size:16px;
  color:var(--txt);outline:none;transition:border-color .2s;-webkit-appearance:none
}
.si:focus{border-color:var(--acc);background:var(--card)}
.si::placeholder{color:var(--mut)}
.sbtn{
  position:absolute;right:5px;top:50%;transform:translateY(-50%);
  background:var(--acc);color:#000;border:none;border-radius:50px;
  width:38px;height:34px;display:flex;align-items:center;justify-content:center;
  cursor:pointer;touch-action:manipulation;flex-shrink:0
}
@media(max-width:600px){.si{padding:12px 48px 12px 38px}}

/* Topbar right */
.tbr{display:flex;align-items:center;gap:6px;flex-shrink:0}
.wl-btn{background:none;border:1px solid var(--bdr);border-radius:8px;color:var(--mut);
  cursor:pointer;padding:7px;display:flex;align-items:center;transition:all .2s;flex-shrink:0}
.wl-btn.on{border-color:var(--acc);color:var(--acc);background:rgba(0,229,160,.08)}
.av-btn{width:32px;height:32px;border-radius:50%;overflow:hidden;cursor:pointer;flex-shrink:0;
  border:2px solid var(--bdr);background:var(--acc2);display:flex;align-items:center;
  justify-content:center;font-size:15px;transition:border-color .2s}
.av-btn:hover{border-color:var(--acc)}
.av-btn img{width:100%;height:100%;object-fit:cover;display:block}
.lout-btn{background:none;border:none;color:var(--mut);cursor:pointer;display:flex;padding:4px}
@media(max-width:480px){.wl-btn{display:none}}

/* ═══════════════════════════════════════════════════════ LAYOUT */
.body-wrap{flex:1;display:flex;overflow:hidden}

/* ─── SIDEBAR ─── */
.sidebar{
  width:192px;background:var(--sur);border-right:1px solid var(--bdr);
  display:flex;flex-direction:column;padding:12px 0;flex-shrink:0;overflow-y:auto
}
@media(max-width:680px){.sidebar{display:none}}
.sidebar::-webkit-scrollbar{width:3px}
.sidebar::-webkit-scrollbar-thumb{background:var(--dim);border-radius:4px}
.nl{font-size:10px;font-weight:700;letter-spacing:2px;color:var(--mut);
  text-transform:uppercase;padding:0 14px;margin:10px 0 3px}
.ni{display:flex;align-items:center;gap:8px;padding:9px 9px;margin:1px 5px;
  border-radius:8px;cursor:pointer;font-size:13px;font-weight:500;color:var(--mut);transition:all .15s}
.ni:hover,.ni.act{background:var(--card);color:var(--acc)}
.pi{display:flex;align-items:center;gap:8px;padding:7px 9px;margin:1px 5px;
  border-radius:8px;cursor:pointer;font-size:12px;color:var(--mut);transition:all .15s}
.pi:hover{background:var(--card);color:var(--acc)}
.pth{width:26px;height:26px;border-radius:5px;background:var(--card);
  display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0}
/* Playlist sidebar */
.pl-si{display:flex;align-items:center;gap:7px;padding:7px 9px;margin:1px 5px;
  border-radius:8px;cursor:pointer;font-size:12px;color:var(--mut);transition:all .15s;min-width:0}
.pl-si:hover,.pl-si.act{background:var(--card);color:var(--acc)}
.pl-si-em{width:24px;height:24px;border-radius:5px;background:var(--card);border:1px solid var(--bdr);
  display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0}
.pl-si-nm{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.pl-si-ct{font-size:10px;color:var(--dim);flex-shrink:0}
.new-pl-btn{display:flex;align-items:center;gap:6px;padding:7px 9px;margin:1px 5px;border-radius:8px;
  cursor:pointer;font-size:12px;color:var(--acc);background:none;
  border:1px dashed rgba(0,229,160,.28);font-family:'DM Sans',sans-serif;
  width:calc(100% - 10px);transition:all .2s}
.new-pl-btn:hover{background:rgba(0,229,160,.06)}

/* ─── MAIN ─── */
.main{flex:1;overflow-y:auto;padding:14px;scroll-behavior:smooth}
.main::-webkit-scrollbar{width:4px}
.main::-webkit-scrollbar-thumb{background:var(--dim);border-radius:4px}
.pg{display:none}.pg.act{display:block}
.stitle{font-family:'Bebas Neue',sans-serif;font-size:clamp(17px,4vw,21px);
  letter-spacing:2px;margin-bottom:12px;display:flex;align-items:center;gap:6px}
.stitle span{color:var(--acc)}
.tab-row{display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap}
.tab{padding:5px 13px;border-radius:20px;border:1px solid var(--bdr);background:none;
  color:var(--mut);font-family:'DM Sans',sans-serif;font-size:12px;font-weight:500;
  cursor:pointer;transition:all .2s;touch-action:manipulation}
.tab.act{background:var(--acc);color:#000;border-color:var(--acc);font-weight:700}

/* Music cards */
.rg{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:12px;margin-bottom:18px}
@media(max-width:400px){.rg{grid-template-columns:repeat(2,1fr);gap:8px}}
.rc{background:var(--panel);border:1px solid var(--bdr);border-radius:12px;overflow:hidden;
  cursor:pointer;transition:all .2s;position:relative}
.rc:hover{border-color:var(--acc);transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,229,160,.1)}
.rt{width:100%;aspect-ratio:16/9;position:relative;background:linear-gradient(135deg,var(--card),var(--panel));overflow:hidden}
.rt img{width:100%;height:100%;object-fit:cover;display:block}
.rt-ph{width:100%;height:100%;display:flex;align-items:center;justify-content:center;
  font-size:30px;background:linear-gradient(135deg,#1c1c40,#2a1c40)}
.rt-dur{position:absolute;bottom:5px;right:6px;background:rgba(0,0,0,.75);color:#fff;
  font-size:10px;font-family:monospace;padding:2px 6px;border-radius:4px}
.play-over{position:absolute;inset:0;background:rgba(0,0,0,.45);display:flex;
  align-items:center;justify-content:center;opacity:0;transition:opacity .2s}
.rc:hover .play-over{opacity:1}
.play-circ{width:42px;height:42px;background:var(--acc);border-radius:50%;
  display:flex;align-items:center;justify-content:center;color:#000}
.rc-apl{position:absolute;top:6px;right:6px;background:rgba(0,0,0,.75);border:none;
  border-radius:6px;color:#fff;cursor:pointer;padding:3px 7px;font-size:10px;
  display:flex;align-items:center;gap:3px;opacity:0;transition:opacity .2s;z-index:5;
  font-family:'DM Sans',sans-serif;font-weight:600}
.rc:hover .rc-apl{opacity:1}
.ri{padding:9px 10px 11px;cursor:pointer}
.rtitle{font-size:12px;font-weight:600;line-height:1.4;margin-bottom:3px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.rch{font-size:11px;color:var(--mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Queue */
.ql{display:flex;flex-direction:column;gap:2px}
.qi{display:flex;align-items:center;gap:9px;padding:8px 8px;border-radius:8px;cursor:pointer;transition:all .15s}
.qi:hover,.qi.act{background:var(--panel)}
.qn{font-family:'DM Mono',monospace;font-size:11px;color:var(--mut);width:16px;text-align:center;flex-shrink:0}
.qi.act .qn{color:var(--acc)}
.qth{width:38px;height:38px;border-radius:6px;overflow:hidden;background:var(--card);flex-shrink:0}
.qth img{width:100%;height:100%;object-fit:cover}
.qm{flex:1;min-width:0}
.qname{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.qart{font-size:11px;color:var(--mut)}
.qi.act .qname{color:var(--acc)}

/* Favs */
.fav-list{display:flex;flex-direction:column;gap:4px}
.fav-item{display:flex;align-items:center;gap:10px;padding:9px 10px;background:var(--panel);
  border:1px solid var(--bdr);border-radius:10px;cursor:pointer;transition:all .15s}
.fav-item:hover{border-color:var(--acc);background:var(--card)}
.fav-th{width:42px;height:42px;border-radius:8px;overflow:hidden;flex-shrink:0;background:var(--card)}
.fav-th img{width:100%;height:100%;object-fit:cover}
.fav-inf{min-width:0;flex:1}
.fav-tit{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fav-ch{font-size:11px;color:var(--mut)}
.fav-rm{background:none;border:none;color:var(--mut);cursor:pointer;padding:4px;
  display:flex;flex-shrink:0;border-radius:50%;transition:color .15s}
.fav-rm:hover{color:var(--acc3)}

/* Playlist page */
.pl-hdr{display:flex;align-items:center;gap:14px;margin-bottom:18px;
  background:var(--panel);border:1px solid var(--bdr);border-radius:14px;padding:16px;flex-wrap:wrap}
.pl-cov{width:72px;height:72px;border-radius:12px;background:linear-gradient(135deg,var(--acc2),var(--acc));
  display:flex;align-items:center;justify-content:center;font-size:36px;flex-shrink:0}
.pl-meta{flex:1;min-width:120px}
.pl-meta-nm{font-family:'Bebas Neue',sans-serif;font-size:22px;letter-spacing:2px;margin-bottom:3px}
.pl-meta-ct{font-size:12px;color:var(--mut)}
.pl-acts{display:flex;gap:8px;flex-wrap:wrap}
.pl-tl{display:flex;flex-direction:column;gap:3px}
.pl-tr{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:10px;
  cursor:pointer;transition:all .15s;background:var(--panel);border:1px solid var(--bdr);margin-bottom:3px}
.pl-tr:hover{border-color:var(--acc);background:var(--card)}
.pl-tr-n{font-family:'DM Mono',monospace;font-size:11px;color:var(--mut);width:20px;text-align:center;flex-shrink:0}
.pl-tr-th{width:40px;height:40px;border-radius:6px;overflow:hidden;flex-shrink:0;background:var(--card)}
.pl-tr-th img{width:100%;height:100%;object-fit:cover}
.pl-tr-inf{flex:1;min-width:0}
.pl-tr-tit{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pl-tr-art{font-size:11px;color:var(--mut)}
.pl-tr-dur{font-family:'DM Mono',monospace;font-size:10px;color:var(--mut);flex-shrink:0}
.pl-tr-rm{background:none;border:none;color:var(--mut);cursor:pointer;padding:5px;
  display:flex;border-radius:50%;transition:color .15s;flex-shrink:0}
.pl-tr-rm:hover{color:var(--acc3)}
.pl-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:48px 20px;gap:12px;color:var(--mut);text-align:center}

/* ─── NOW PLAYING ─── */
.np-panel{width:250px;background:var(--sur);border-left:1px solid var(--bdr);
  display:flex;flex-direction:column;flex-shrink:0}
@media(max-width:900px){.np-panel{display:none}}
.npp{flex:1;display:flex;flex-direction:column;align-items:center;padding:18px 14px 14px;overflow-y:auto}
.npp::-webkit-scrollbar{display:none}
.aaw{width:210px;height:210px;border-radius:16px;overflow:hidden;
  background:linear-gradient(135deg,var(--card),var(--panel));position:relative;
  box-shadow:0 12px 36px rgba(0,0,0,.5);margin-bottom:14px;flex-shrink:0;transition:box-shadow .5s}
.aaw.playing{box-shadow:0 12px 48px rgba(0,229,160,.22)}
.aaw img{width:100%;height:100%;object-fit:cover;display:block}
.aaw .ph{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:64px}
.np-tit{font-weight:700;font-size:14px;text-align:center;line-height:1.3;padding:0 4px;width:100%;margin-bottom:3px}
.np-art{font-size:12px;color:var(--mut);text-align:center;margin-bottom:14px}
.np-acts{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin-bottom:10px}
.ib{background:none;border:none;color:var(--mut);cursor:pointer;padding:6px;
  border-radius:50%;transition:all .15s;display:flex;position:relative}
.ib:hover{color:var(--txt);transform:scale(1.1)}
.ib.act{color:var(--acc)}

/* ─── BOTTOM BAR ─── */
.bb{background:var(--sur);border-top:1px solid var(--bdr);padding:0 12px;
  display:flex;align-items:center;gap:8px;height:74px;flex-shrink:0;z-index:40}
.ci{display:flex;align-items:center;gap:8px;width:clamp(110px,24%,200px);flex-shrink:0;min-width:0}
.cth{width:44px;height:44px;border-radius:8px;overflow:hidden;background:var(--card);flex-shrink:0}
.cth img{width:100%;height:100%;object-fit:cover;display:block}
.cth .cph{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:18px}
.cm{min-width:0;flex:1}
.ct{font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ca{font-size:11px;color:var(--mut)}
.fav-il{background:none;border:none;color:var(--mut);cursor:pointer;padding:4px;
  display:flex;flex-shrink:0;transition:color .15s}
.fav-il.act{color:var(--acc3)}
.fav-il.act svg{fill:currentColor}
/* Controls */
.ctrls{flex:1;display:flex;flex-direction:column;align-items:center;gap:7px;min-width:0}
.crow{display:flex;align-items:center;gap:9px}
.cb{background:none;border:none;color:var(--mut);cursor:pointer;padding:4px;border-radius:50%;
  transition:color .15s;display:flex;align-items:center;justify-content:center;touch-action:manipulation}
.cb:hover,.cb.act{color:var(--acc)}
.ppb{width:40px;height:40px;background:var(--txt);border:none;border-radius:50%;color:#000;
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  transition:background .15s;flex-shrink:0;touch-action:manipulation}
.ppb:hover,.ppb:active{background:var(--acc)}
.pr{display:flex;align-items:center;gap:7px;width:100%;max-width:420px}
.tl{font-family:'DM Mono',monospace;font-size:10px;color:var(--mut);flex-shrink:0;min-width:28px;text-align:center}
.pt{flex:1;height:4px;background:var(--dim);border-radius:4px;cursor:pointer;transition:height .15s}
.pt:hover{height:6px}
.pf{height:100%;background:var(--txt);border-radius:4px;transition:width .4s linear;pointer-events:none}
.pt:hover .pf{background:var(--acc)}
.vr{display:flex;align-items:center;gap:7px;width:88px;flex-shrink:0}
@media(max-width:560px){.vr{display:none}}
.vt{flex:1;height:4px;background:var(--dim);border-radius:4px;cursor:pointer}
.vf{height:100%;background:var(--dim);border-radius:4px;transition:width .1s}
.vt:hover .vf{background:var(--txt)}
.dl-btn{background:none;border:1px solid var(--bdr);border-radius:8px;color:var(--mut);
  cursor:pointer;padding:7px 9px;display:flex;align-items:center;gap:5px;
  font-size:12px;font-weight:600;transition:all .2s;flex-shrink:0}
.dl-btn:hover{border-color:var(--acc);color:var(--acc)}
@media(max-width:700px){.dl-btn span{display:none}.dl-btn{padding:7px}}

/* ─── MOBILE NAV ─── */
.mob-nav{display:none;background:var(--sur);border-top:1px solid var(--bdr);
  padding:6px 0 max(6px,env(safe-area-inset-bottom));flex-shrink:0}
@media(max-width:680px){.mob-nav{display:flex}}
.mn{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;background:none;
  border:none;color:var(--mut);cursor:pointer;font-family:'DM Sans',sans-serif;
  font-size:10px;font-weight:500;padding:5px 2px;transition:color .15s;touch-action:manipulation}
.mn.act{color:var(--acc)}

/* ─── AUDIO INDICATOR ─── */
.audio-mode{display:flex;align-items:center;gap:5px;font-size:10px;font-weight:600;
  padding:3px 8px;border-radius:20px;flex-shrink:0;transition:all .3s}
.audio-mode.html5{background:rgba(0,229,160,.12);color:var(--acc);border:1px solid rgba(0,229,160,.25)}
.audio-mode.iframe{background:rgba(124,111,247,.1);color:var(--acc2);border:1px solid rgba(124,111,247,.2)}
.audio-mode .abar{display:flex;gap:2px;align-items:flex-end;height:12px}
.audio-mode .abar span{width:3px;background:currentColor;border-radius:2px;animation:eq 1.2s ease-in-out infinite}
.audio-mode .abar span:nth-child(2){animation-delay:.15s}
.audio-mode .abar span:nth-child(3){animation-delay:.3s}
@keyframes eq{0%,100%{height:4px}50%{height:12px}}
.audio-mode:not(.playing) .abar span{animation:none;height:4px}

/* ─── MODALS ─── */
.mbg{position:fixed;inset:0;background:rgba(0,0,0,.72);backdrop-filter:blur(4px);z-index:300;
  display:flex;align-items:center;justify-content:center;padding:16px;
  opacity:0;pointer-events:none;transition:opacity .2s}
.mbg.open{opacity:1;pointer-events:all}
.mbox{background:var(--panel);border:1px solid var(--bdr);border-radius:18px;padding:24px;
  width:100%;max-width:400px;position:relative;transform:translateY(12px);
  transition:transform .2s;max-height:90dvh;overflow-y:auto}
.mbg.open .mbox{transform:translateY(0)}
.mt2{font-family:'Bebas Neue',sans-serif;font-size:20px;letter-spacing:2px;margin-bottom:4px}
.ms2{font-size:13px;color:var(--mut);margin-bottom:18px}
.mf{margin-bottom:12px}
.mf label{display:block;font-size:10px;font-weight:700;letter-spacing:1.5px;
  text-transform:uppercase;color:var(--mut);margin-bottom:5px}
.mf input{width:100%;background:var(--card);border:1px solid var(--bdr);border-radius:8px;
  padding:12px 13px;font-family:'DM Sans',sans-serif;font-size:15px;color:var(--txt);
  outline:none;transition:border-color .2s;-webkit-appearance:none}
.mf input:focus{border-color:var(--acc)}
.xbtn{position:absolute;top:14px;right:14px;background:none;border:none;color:var(--mut);
  cursor:pointer;padding:4px;border-radius:6px;display:flex}
.mfoot{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}
.btn-c{padding:10px 16px;border-radius:8px;border:1px solid var(--bdr);background:var(--card);
  color:var(--txt);font-family:'DM Sans',sans-serif;font-size:13px;cursor:pointer}
.btn-ok{padding:10px 16px;border-radius:8px;border:none;background:var(--acc);color:#000;
  font-family:'DM Sans',sans-serif;font-size:13px;font-weight:700;cursor:pointer}
/* Emoji grid */
.egrid{display:grid;grid-template-columns:repeat(8,1fr);gap:5px;margin-top:8px}
.eopt{background:var(--card);border:1px solid var(--bdr);border-radius:7px;font-size:19px;
  padding:6px;cursor:pointer;text-align:center;transition:all .15s;touch-action:manipulation}
.eopt:hover,.eopt.sel{background:rgba(0,229,160,.12);border-color:var(--acc)}
/* Profile */
.av-prev{width:80px;height:80px;border-radius:50%;overflow:hidden;background:var(--card);
  margin:0 auto 14px;border:3px solid var(--acc);display:flex;align-items:center;
  justify-content:center;font-size:36px}
.av-prev img{width:100%;height:100%;object-fit:cover}
.upload-z{border:2px dashed var(--bdr);border-radius:10px;padding:16px;text-align:center;
  cursor:pointer;transition:all .2s;position:relative}
.upload-z:hover{border-color:var(--acc);background:rgba(0,229,160,.04)}
.upload-z input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%;height:100%}
/* Add-to-playlist dropdown */
.atp-wrap{position:relative;display:inline-flex}
.atp-menu{position:absolute;bottom:calc(100% + 8px);right:0;background:var(--panel);
  border:1px solid var(--bdr);border-radius:12px;min-width:210px;
  box-shadow:0 8px 24px rgba(0,0,0,.5);z-index:100;overflow:hidden;display:none}
.atp-menu.open{display:block;animation:fadeUp .15s ease}
@keyframes fadeUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.atp-hdr{padding:8px 14px;font-size:10px;font-weight:700;letter-spacing:1.5px;
  text-transform:uppercase;color:var(--mut);border-bottom:1px solid var(--bdr)}
.atp-item{display:flex;align-items:center;gap:8px;padding:10px 14px;cursor:pointer;
  font-size:13px;color:var(--txt);transition:background .15s;white-space:nowrap}
.atp-item:hover{background:var(--card)}

/* LOADING / EMPTY / TOAST */
.loading{display:flex;align-items:center;justify-content:center;padding:32px;gap:8px;color:var(--mut)}
.spin{width:20px;height:20px;border:2px solid var(--dim);border-top-color:var(--acc);
  border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.es{display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:40px 16px;gap:10px;color:var(--mut);text-align:center;font-size:13px}
.retry-btn{color:var(--acc);background:none;border:1px solid var(--acc);border-radius:8px;
  cursor:pointer;font-size:12px;font-family:'DM Sans',sans-serif;padding:6px 14px;margin-top:4px}
.toast{position:fixed;bottom:86px;right:14px;left:14px;max-width:280px;margin:0 auto;
  background:var(--card);border:1px solid var(--bdr);border-radius:12px;padding:11px 14px;
  font-size:13px;transform:translateY(12px);opacity:0;transition:all .28s;
  z-index:500;pointer-events:none;text-align:center}
@media(min-width:480px){.toast{left:auto;margin:0;text-align:left}}
.toast.show{transform:translateY(0);opacity:1}

/* Hidden iframe YT fallback */
/* sem iframe de vídeo */
</style>
</head>
<body>

<!-- Auth guard -->
<script>
(async function(){
  try{
    var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'me'})});
    var d=await r.json();
    if(!d.ok||d.role!=='client'){document.body.style.display='none';location.href='login.php';return;}
    if(d.site_name){document.title=d.site_name;var el=document.getElementById('logo-name');if(el)el.textContent=d.site_name;}
    if(d.site_logo){var el=document.getElementById('logo-icon');if(el)el.textContent=d.site_logo;}
    if(d.site_color)document.documentElement.style.setProperty('--acc',d.site_color);
    // Avatar salvo
    if(d.avatar_path){
      localStorage.setItem('snr_avatar_url',d.avatar_path);
      var ab=document.getElementById('av-btn');
      if(ab)ab.innerHTML='<img src="'+d.avatar_path+'" onerror="this.parentNode.innerHTML=\'<span>'+( d.avatar||'🎵')+'</span>\'">';
    }
    window._SESSION=d;
    loadFavs();loadPlaylists();
  }catch(e){document.body.style.display='none';location.href='login.php';}
})();
</script>

<!-- ─── TOPBAR ─── -->
<div class="topbar">
  <div class="logo">
    <span id="logo-icon">🎵</span>
    <div class="logo-dot"></div>
    <span class="logo-txt" id="logo-name">SONORA</span>
  </div>

  <div class="search-wrap">
    <svg class="si-icon" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
    <input class="si" id="si" type="search" placeholder="Buscar músicas, artistas..." onkeydown="if(event.key==='Enter')doSearch()" autocomplete="off">
    <button class="sbtn" onclick="doSearch()" aria-label="Buscar">
      <svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
    </button>
  </div>

  <div class="tbr">
    <!-- Audio mode indicator -->
    <div class="audio-mode html5" id="audio-mode" title="Modo de reprodução">
      <div class="abar"><span></span><span></span><span></span></div>
      <span id="audio-mode-lbl">ÁUDIO</span>
    </div>
    <button class="wl-btn" id="wl-btn" onclick="toggleWakeLock()" title="Manter tela ativa">
      <svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></svg>
    </button>
    <div class="av-btn" id="av-btn" onclick="openProfile()" title="Perfil">
      <span id="av-txt">🎵</span>
    </div>
    <button class="lout-btn" onclick="logout()" title="Sair">
      <svg width="17" height="17" fill="currentColor" viewBox="0 0 24 24"><path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"/></svg>
    </button>
  </div>
</div>

<!-- ─── BODY ─── -->
<div class="body-wrap">

  <!-- SIDEBAR -->
  <aside class="sidebar">
    <div class="nl">Menu</div>
    <div class="ni act" id="ni-home" onclick="showPage('home')"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>Início</div>
    <div class="ni" id="ni-search" onclick="showPage('search');setTimeout(function(){document.getElementById('si').focus();},80)"><svg width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>Pesquisar</div>
    <div class="ni" id="ni-favs" onclick="showPage('favs')"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>Favoritos</div>
    <div class="ni" id="ni-queue" onclick="showPage('queue')"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M3 18h12v-2H3v2zm0-5h12v-2H3v2zm0-7v2h12V6H3zm14 9l-1.4-1.4L19.2 11l-3.6-2.6L17 7l5 4-5 4z"/></svg>Fila</div>
    <div class="nl">Estilos</div>
    <div class="pi" onclick="quickS('funk brasileiro')"><div class="pth">🔥</div>Funk</div>
    <div class="pi" onclick="quickS('samba pagode')"><div class="pth">🎶</div>Samba</div>
    <div class="pi" onclick="quickS('lofi hip hop')"><div class="pth">☁️</div>Lo-Fi</div>
    <div class="pi" onclick="quickS('rock nacional')"><div class="pth">🎸</div>Rock</div>
    <div class="pi" onclick="quickS('workout treino')"><div class="pth">⚡</div>Workout</div>
    <div class="nl">Playlists</div>
    <button class="new-pl-btn" onclick="openCreatePl()"><svg width="13" height="13" fill="currentColor" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>Nova playlist</button>
    <div id="sb-pl"></div>
  </aside>

  <!-- MAIN -->
  <main class="main">
    <div class="pg act" id="pg-home">
      <div class="stitle">Descobrir <span>🎵</span></div>
      <div class="tab-row">
        <button class="tab act" onclick="fg(this,'musicas populares brasil 2024')">Popular</button>
        <button class="tab" onclick="fg(this,'funk brasileiro lançamento')">Funk</button>
        <button class="tab" onclick="fg(this,'pop internacional hits')">Pop</button>
        <button class="tab" onclick="fg(this,'rock nacional classico')">Rock</button>
        <button class="tab" onclick="fg(this,'samba pagode 2024')">Samba</button>
        <button class="tab" onclick="fg(this,'lofi chill relaxing')">Lo-Fi</button>
        <button class="tab" onclick="fg(this,'eletronica dance music')">Dance</button>
      </div>
      <div class="rg" id="home-grid"><div class="loading"><div class="spin"></div></div></div>
    </div>
    <div class="pg" id="pg-search">
      <div class="stitle" id="st">Resultados <span></span></div>
      <div class="rg" id="sr"><div class="es"><p>Digite algo para buscar</p></div></div>
    </div>
    <div class="pg" id="pg-favs">
      <div class="stitle">Favoritos <span>❤️</span></div>
      <div class="fav-list" id="fav-list"><div class="es"><p>Nenhum favorito<br><small>Toque ❤️ em qualquer música</small></p></div></div>
    </div>
    <div class="pg" id="pg-queue">
      <div class="stitle">Fila <span>📋</span></div>
      <div class="ql" id="ql"><div class="es"><p>Nenhuma música na fila</p></div></div>
    </div>
    <div class="pg" id="pg-playlist">
      <div id="pl-view"><div class="es"><p>Selecione uma playlist</p></div></div>
    </div>
  </main>

  <!-- NOW PLAYING -->
  <div class="np-panel">
    <div class="npp">
      <div class="aaw" id="aaw"><div class="ph" id="aph">🎵</div><img id="aimg" src="" style="display:none" onerror="this.style.display='none';document.getElementById('aph').style.display='flex'"></div>
      <div class="np-tit" id="npt">Nenhuma música</div>
      <div class="np-art" id="npa">Selecione para tocar</div>
      <div class="np-acts">
        <button class="ib" id="fav-np" onclick="toggleFav()" title="Favoritar (F)"><svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg></button>
        <button class="ib" onclick="if(cur)addQ(cur)" title="Fila"><svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M3 18h12v-2H3v2zm0-5h12v-2H3v2zm0-7v2h12V6H3zm14 9l-1.4-1.4L19.2 11l-3.6-2.6L17 7l5 4-5 4z"/></svg></button>
        <div class="atp-wrap"><button class="ib" onclick="toggleAtp('np')" title="+ Playlist"><svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M14 10H3v2h11v-2zm0-4H3v2h11V6zm4 8v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM3 16h7v-2H3v2z"/></svg></button><div class="atp-menu" id="atp-np"></div></div>
        <button class="ib" onclick="dlTrack()" title="Download"><svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg></button>
        <button class="ib" onclick="if(cur)window.open('https://youtube.com/watch?v='+cur.id,'_blank')" title="YouTube"><svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-2.74 12.76 12.76 0 0 0-8.07 0A4.83 4.83 0 0 1 4.41 6.69 48.91 48.91 0 0 0 4 12a48.91 48.91 0 0 0 .41 5.31 4.83 4.83 0 0 1 3.77 2.74 12.76 12.76 0 0 0 8.07 0 4.83 4.83 0 0 1 3.77-2.74A48.91 48.91 0 0 0 20 12a48.91 48.91 0 0 0-.41-5.31zM9.75 15.02V8.98L15.5 12z"/></svg></button>
      </div>
    </div>
  </div>
</div>

<!-- ─── BOTTOM BAR ─── -->
<div class="bb">
  <div class="ci">
    <div class="cth" id="cth"><div class="cph">🎵</div></div>
    <div class="cm"><div class="ct" id="ct">—</div><div class="ca" id="ca">—</div></div>
    <button class="fav-il" id="fav-il" onclick="toggleFav()"><svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg></button>
  </div>
  <div class="ctrls">
    <div class="crow">
      <button class="cb" id="shbtn" onclick="tShuffle()"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg></button>
      <button class="cb" onclick="prev()"><svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M6 6h2v12H6zm3.5 6 8.5 6V6z"/></svg></button>
      <button class="ppb" onclick="tPlay()">
        <svg id="pli" width="19" height="19" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
        <svg id="pai" width="19" height="19" fill="currentColor" viewBox="0 0 24 24" style="display:none"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
      </button>
      <button class="cb" onclick="next()"><svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zm2-8.14L11.03 12 8 14.14V9.86zM16 6h2v12h-2z"/></svg></button>
      <button class="cb" id="rpbtn" onclick="tRepeat()"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z"/></svg></button>
    </div>
    <div class="pr">
      <span class="tl" id="tc">0:00</span>
      <div class="pt" id="prog" onclick="seek(event)"><div class="pf" id="pf" style="width:0%"></div></div>
      <span class="tl" id="td">0:00</span>
    </div>
  </div>
  <div style="display:flex;align-items:center;gap:6px;flex-shrink:0">
    <div class="vr">
      <button class="cb" onclick="tMute()"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg></button>
      <div class="vt" id="vtk"><div class="vf" id="vf" style="width:80%"></div></div>
    </div>
    <button class="dl-btn" onclick="dlTrack()"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg><span>Download</span></button>
  </div>
</div>

<!-- MOBILE NAV -->
<nav class="mob-nav">
  <button class="mn act" id="mn-home" onclick="showPage('home')"><svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>Início</button>
  <button class="mn" id="mn-search" onclick="showPage('search');setTimeout(function(){document.getElementById('si').focus();},150)"><svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>Buscar</button>
  <button class="mn" id="mn-favs" onclick="showPage('favs')"><svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>Favs</button>
  <button class="mn" id="mn-queue" onclick="showPage('queue')"><svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M3 18h12v-2H3v2zm0-5h12v-2H3v2zm0-7v2h12V6H3zm14 9l-1.4-1.4L19.2 11l-3.6-2.6L17 7l5 4-5 4z"/></svg>Fila</button>
  <button class="mn" id="mn-playlist" onclick="showPage('playlist')"><svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></svg>Listas</button>
</nav>

<!-- MODAL: Criar/Renomear Playlist -->
<div class="mbg" id="pl-modal">
  <div class="mbox">
    <button class="xbtn" onclick="closePlModal()"><svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
    <div class="mt2" id="pl-mt">Nova Playlist</div>
    <div class="ms2" id="pl-ms">Dê um nome e escolha um emoji</div>
    <input type="hidden" id="pl-mid">
    <div class="mf"><label>Nome</label><input type="text" id="pl-mn" placeholder="Minha playlist..." maxlength="40" onkeydown="if(event.key==='Enter')savePl()"></div>
    <div class="mf"><label>Emoji</label><div class="egrid" id="egrid"></div></div>
    <div class="mfoot"><button class="btn-c" onclick="closePlModal()">Cancelar</button><button class="btn-ok" onclick="savePl()">Salvar</button></div>
  </div>
</div>

<!-- MODAL: Perfil -->
<div class="mbg" id="prof-modal">
  <div class="mbox">
    <button class="xbtn" onclick="closeProfile()"><svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
    <div class="mt2">Meu Perfil</div>
    <div class="ms2" id="prof-name">—</div>
    <div class="av-prev" id="av-prev"><span id="av-prev-txt">🎵</span></div>
    <div class="upload-z">
      <input type="file" id="av-file" accept="image/*" onchange="handleAvUpload(this)">
      <svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" style="color:var(--mut);margin-bottom:6px"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
      <div style="font-size:13px;color:var(--mut)">Clique para escolher foto</div>
      <div style="font-size:11px;color:var(--dim);margin-top:4px">JPG, PNG ou WEBP · Máx 3MB</div>
    </div>
    <div id="av-status" style="font-size:12px;color:var(--mut);text-align:center;margin-top:8px;min-height:18px"></div>
  </div>
</div>

<!-- iframe YouTube oculto — áudio real -->
<div id="yt-iframe-wrap" style="position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;pointer-events:none;opacity:0"></div>

<div class="toast" id="toast"><span id="tmsg"></span></div>

<script>
// ════════════════════════════════════════════════════════════════════════════
// SESSION
// ════════════════════════════════════════════════════════════════════════════
var SESS = null;
var NAME = localStorage.getItem('snr_name') || '';
var AVTR = localStorage.getItem('snr_avatar') || '🎵';
document.getElementById('av-txt').textContent = AVTR;
var savedAU = localStorage.getItem('snr_avatar_url');
if (savedAU) {
  var ab = document.getElementById('av-btn');
  ab.innerHTML = '<img src="'+savedAU+'" onerror="this.parentNode.innerHTML=\'<span>'+AVTR+'</span>\'">';
}
async function logout(){
  await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'logout'})});
  localStorage.clear(); location.href='login.php';
}

// ════════════════════════════════════════════════════════════════════════════
// WAKE LOCK
// ════════════════════════════════════════════════════════════════════════════
var wakeLock=null;
async function toggleWakeLock(){
  if(wakeLock){wakeLock.release();wakeLock=null;document.getElementById('wl-btn').classList.remove('on');showT('Tela pode apagar');return;}
  try{
    wakeLock=await navigator.wakeLock.request('screen');
    document.getElementById('wl-btn').classList.add('on');showT('🔆 Tela não vai apagar');
    wakeLock.addEventListener('release',function(){wakeLock=null;document.getElementById('wl-btn').classList.remove('on');});
  }catch(e){showT('Wake Lock não disponível');}
}
document.addEventListener('visibilitychange',async function(){
  if(wakeLock!==null&&document.visibilityState==='visible'){
    try{wakeLock=await navigator.wakeLock.request('screen');}catch(e){}
  }
});

// ════════════════════════════════════════════════════════════════════════════
// AUDIO ENGINE
// Estratégia em camadas:
// 1. HTML5 <audio> com stream direto (via api.php?action=stream_audio)
//    → funciona em segundo plano no mobile (tratado como áudio puro)
// 2. Se o servidor não tiver yt-dlp, fallback para YouTube IFrame
//    → Media Session API garante controles na tela de bloqueio
// ════════════════════════════════════════════════════════════════════════════
// ════════════════════════════════════════════════════════════════════════════
// ENGINE HÍBRIDO — YouTube IFrame (áudio real) + <audio> silencioso (background)
//
// Como funciona:
//   1. YouTube IFrame toca a música (sempre disponível, sem CORS)
//   2. Um <audio> com WAV silencioso em loop "engana" o browser:
//      o browser vê uma sessão de áudio ativa e não suspende ao apagar a tela
//   3. Media Session API registra os metadados → aparecem na tela de bloqueio
//      e nos controles do fone de ouvido / Bluetooth
//
// É exatamente como Spotify Web Player e outros players profissionais fazem.
// ════════════════════════════════════════════════════════════════════════════

var ytPlayer = null, ytReady = false;
var cur = null, Q = [], qi = -1;
var playing = false, shuffle = false, repeat = false, muted = false, vol = 80;
var pint = null;

// ── Áudio silencioso — mantém sessão de áudio ativa no browser ───────────────
// WAV de 1s silencioso em base64 (44 bytes — não usa rede)
var SILENT_SRC = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=';
var keepAlive = (function(){
  var el = null;
  return {
    start: function(){
      if(el) return;
      el = document.createElement('audio');
      el.src    = SILENT_SRC;
      el.loop   = true;
      el.volume = 0.001;
      el.setAttribute('playsinline','');
      el.setAttribute('webkit-playsinline','');
      document.body.appendChild(el);
      el.play().catch(function(){});
    },
    stop: function(){
      if(!el) return;
      el.pause(); el.src=''; el.remove(); el=null;
    }
  };
})();

// ── YouTube IFrame API ────────────────────────────────────────────────────────
function loadYtIframe(){
  if(document.getElementById('yt-player')) return;
  var wrap = document.getElementById('yt-iframe-wrap');
  var div  = document.createElement('div'); div.id='yt-player'; wrap.appendChild(div);
  var s    = document.createElement('script'); s.src='https://www.youtube.com/iframe_api'; document.head.appendChild(s);
}
function onYouTubeIframeAPIReady(){
  ytPlayer = new YT.Player('yt-player',{
    height:'1', width:'1',
    playerVars:{ autoplay:0, controls:0, disablekb:1, fs:0, modestbranding:1, rel:0, iv_load_policy:3, origin:location.origin },
    events:{
      onReady: function(){ ytReady=true; ytPlayer.setVolume(muted?0:vol); setupMS(); },
      onStateChange: function(e){
        if(e.data===YT.PlayerState.PLAYING){ playing=true;  keepAlive.start(); updUI(); startProg(); updMS(); }
        else if(e.data===YT.PlayerState.PAUSED){  playing=false; updUI(); stopProg(); updMS(); }
        else if(e.data===YT.PlayerState.ENDED){   playing=false; updUI(); stopProg(); repeat?ytPlayer.playVideo():next(); }
      },
      onError: function(){ showT('Erro ao carregar — tentando próxima'); setTimeout(next,1500); }
    }
  });
}

function playTrack(t){
  cur = t;
  var ex = Q.findIndex(function(x){ return x.id===t.id; });
  if(ex<0){ Q.push(t); qi=Q.length-1; } else qi=ex;
  updCur(t); renderQ();

  // Metadados na Media Session ANTES de iniciar (iOS exige para tela de bloqueio)
  if('mediaSession' in navigator){
    try{
      navigator.mediaSession.metadata = new MediaMetadata({
        title:   t.title   || 'Sonora',
        artist:  t.channel || '',
        album:   'Sonora',
        artwork: t.thumb ? [{src:t.thumb, sizes:'512x512', type:'image/jpeg'}] : []
      });
    }catch(e){}
  }

  loadYtIframe();
  if(ytReady && ytPlayer){
    ytPlayer.loadVideoById({videoId: t.id});
  } else {
    var tries=0;
    var iv=setInterval(function(){
      if(ytReady && ytPlayer){ clearInterval(iv); ytPlayer.loadVideoById({videoId:t.id}); }
      if(++tries>30) clearInterval(iv);
    },300);
  }
}

function tPlay(){
  if(!cur) return;
  if(!ytReady || !ytPlayer) return;
  playing ? ytPlayer.pauseVideo() : ytPlayer.playVideo();
}
function prev(){ if(!Q.length)return; qi=shuffle?~~(Math.random()*Q.length):qi>0?qi-1:Q.length-1; playTrack(Q[qi]); }
function next(){ if(!Q.length)return; qi=shuffle?~~(Math.random()*Q.length):qi<Q.length-1?qi+1:0; playTrack(Q[qi]); }
function addQ(t){ if(!t)return; if(!Q.find(function(x){return x.id===t.id;})){ Q.push(t); renderQ(); showT('Adicionado à fila'); }else showT('Já está na fila'); }

function updateProgress(){
  if(!ytReady||!ytPlayer) return;
  try{
    var c=ytPlayer.getCurrentTime(), d=ytPlayer.getDuration();
    if(d>0){
      document.getElementById('pf').style.width=(c/d*100)+'%';
      document.getElementById('tc').textContent=fmt(c);
      document.getElementById('td').textContent=fmt(d);
    }
  }catch(e){}
}
function startProg(){ clearInterval(pint); pint=setInterval(function(){ updateProgress(); updMS(); },500); }
function stopProg(){  clearInterval(pint); }

function seek(e){
  var r=document.getElementById('prog').getBoundingClientRect();
  var pct=(e.clientX-r.left)/r.width;
  if(ytReady&&ytPlayer){ try{ ytPlayer.seekTo(ytPlayer.getDuration()*pct,true); }catch(e2){} }
}
function fmt(s){ s=Math.floor(s); return Math.floor(s/60)+':'+(s%60).toString().padStart(2,'0'); }

// Volume
document.getElementById('vtk').addEventListener('click',function(e){
  vol=Math.max(0,Math.min(100,(e.offsetX/this.offsetWidth)*100));
  document.getElementById('vf').style.width=vol+'%';
  if(ytReady&&ytPlayer) ytPlayer.setVolume(muted?0:vol);
});
function tMute(){
  muted=!muted;
  if(ytReady&&ytPlayer){ muted?ytPlayer.mute():ytPlayer.unMute(); }
  document.getElementById('vf').style.width=muted?'0%':vol+'%';
}
function tShuffle(){ shuffle=!shuffle; document.getElementById('shbtn').classList.toggle('act',shuffle); showT(shuffle?'Aleatório ativado':'Desativado'); }
function tRepeat(){  repeat=!repeat;  document.getElementById('rpbtn').classList.toggle('act',repeat);  showT(repeat?'Repetição ativada':'Desativada'); }

// Download
async function dlTrack(){
  if(!cur){showT('Nenhuma música tocando');return;}
  showT('⬇ Preparando...');
  window.open('https://cobalt.tools/#'+encodeURIComponent('https://www.youtube.com/watch?v='+cur.id),'_blank');
}

// ════════════════════════════════════════════════════════════════════════════
// MEDIA SESSION API — controles na tela de bloqueio / fone de ouvido
// ════════════════════════════════════════════════════════════════════════════
function setupMS(){
  if(!('mediaSession' in navigator)) return;
  navigator.mediaSession.setActionHandler('play',          function(){ if(ytReady&&ytPlayer) ytPlayer.playVideo(); });
  navigator.mediaSession.setActionHandler('pause',         function(){ if(ytReady&&ytPlayer) ytPlayer.pauseVideo(); });
  navigator.mediaSession.setActionHandler('previoustrack', prev);
  navigator.mediaSession.setActionHandler('nexttrack',     next);
  navigator.mediaSession.setActionHandler('seekto', function(d){
    if(d.seekTime!==undefined && ytReady&&ytPlayer) try{ ytPlayer.seekTo(d.seekTime,true); }catch(e){}
  });
  navigator.mediaSession.setActionHandler('seekbackward', function(d){
    if(ytReady&&ytPlayer) try{ ytPlayer.seekTo(Math.max(0,ytPlayer.getCurrentTime()-(d.seekOffset||10)),true); }catch(e){}
  });
  navigator.mediaSession.setActionHandler('seekforward', function(d){
    if(ytReady&&ytPlayer) try{ ytPlayer.seekTo(ytPlayer.getCurrentTime()+(d.seekOffset||10),true); }catch(e){}
  });
}
setupMS();

function updMS(){
  if(!('mediaSession' in navigator)||!cur) return;
  try{
    navigator.mediaSession.playbackState = playing ? 'playing' : 'paused';
    if(ytReady&&ytPlayer){
      var dur=0, pos=0;
      try{ dur=ytPlayer.getDuration()||0; pos=ytPlayer.getCurrentTime()||0; }catch(e){}
      if(dur>0) try{ navigator.mediaSession.setPositionState({duration:dur, playbackRate:1, position:Math.min(pos,dur)}); }catch(e){}
    }
    document.getElementById('audio-mode').classList.toggle('playing', playing);
  }catch(ex){}
}

// ════════════════════════════════════════════════════════════════════════════
// UI
// ════════════════════════════════════════════════════════════════════════════
function updUI(){
  document.getElementById('pli').style.display=playing?'none':'';
  document.getElementById('pai').style.display=playing?'':'none';
  document.getElementById('aaw').classList.toggle('playing',playing);
  document.getElementById('audio-mode').classList.toggle('playing',playing);
}
function debugStream(videoId){
  console.log('[Sonora] ytReady:', ytReady, '| ytPlayer:', !!ytPlayer, '| playing:', playing, '| cur:', cur&&cur.id);
  showT('Ver console (F12)');
}
function updCur(t){
  ['ct','npt'].forEach(function(id){document.getElementById(id).textContent=t.title||'';});
  ['ca','npa'].forEach(function(id){document.getElementById(id).textContent=t.channel||'';});
  var img=document.getElementById('aimg'),ph=document.getElementById('aph'),cth=document.getElementById('cth');
  if(t.thumb){img.src=t.thumb;img.style.display='block';ph.style.display='none';
    cth.innerHTML='<img src="'+t.thumb+'" style="width:100%;height:100%;object-fit:cover;display:block" onerror="this.parentNode.innerHTML=\'<div class=cph>🎵</div>\'">';}
  else{img.style.display='none';ph.style.display='flex';cth.innerHTML='<div class="cph">🎵</div>';}
  updFavUI(); updMS();
}
function renderQ(){
  var el=document.getElementById('ql');
  if(!Q.length){el.innerHTML='<div class="es"><p>Nenhuma música na fila</p></div>';return;}
  el.innerHTML=Q.map(function(t,i){
    return '<div class="qi'+(i===qi?' act':'')+'" onclick="playTrack(Q['+i+'])">'+
      '<div class="qn">'+(i===qi?'♪':i+1)+'</div>'+
      '<div class="qth">'+(t.thumb?'<img src="'+t.thumb+'" loading="lazy" onerror="this.style.display=\'none\'">':'')+'</div>'+
      '<div class="qm"><div class="qname">'+esc(t.title)+'</div><div class="qart">'+esc(t.channel||'')+'</div></div>'+
      '<span style="font-family:monospace;font-size:10px;color:var(--mut);flex-shrink:0">'+(t.duration||'')+'</span></div>';
  }).join('');
}

// ════════════════════════════════════════════════════════════════════════════
// FAVORITOS
// ════════════════════════════════════════════════════════════════════════════
var favs=[];
async function loadFavs(){
  try{var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'favs_get'})});var d=await r.json();if(d.ok){favs=d.favs||[];renderFavs();}}catch(e){}
}
async function toggleFav(){
  if(!cur){showT('Nenhuma música tocando');return;}
  try{var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'favs_toggle',track:cur})});var d=await r.json();if(!d.ok)return;favs=d.favs||[];renderFavs();updFavUI();showT(d.action==='added'?'❤️ Favoritado':'💔 Removido');}catch(e){}
}
function isFav(){return!!(cur&&favs.some(function(f){return f.id===cur.id;}));}
function updFavUI(){
  var on=isFav();
  ['fav-np','fav-il'].forEach(function(id){var el=document.getElementById(id);if(!el)return;el.classList.toggle('act',on);var svg=el.querySelector('svg');if(svg)svg.setAttribute('fill',on?'currentColor':'none');});
}
function renderFavs(){
  var el=document.getElementById('fav-list');
  if(!favs.length){el.innerHTML='<div class="es"><p>Nenhum favorito<br><small>Toque ❤️ em qualquer música</small></p></div>';return;}
  el.innerHTML=favs.map(function(f){
    return '<div class="fav-item" onclick=\'playTrack('+JSON.stringify(f).replace(/'/g,"&#39;")+')\'><div class="fav-th">'+(f.thumb?'<img src="'+f.thumb+'" loading="lazy" onerror="this.style.display=\'none\'">':'')+'</div><div class="fav-inf"><div class="fav-tit">'+esc(f.title)+'</div><div class="fav-ch">'+esc(f.channel||'')+'</div></div><button class="fav-rm" onclick="event.stopPropagation();rmFav(\''+f.id+'\')" title="Remover"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg></button></div>';
  }).join('');
}
async function rmFav(id){var t=favs.find(function(f){return f.id===id;});if(!t)return;var p=cur;cur=t;await toggleFav();cur=p;updFavUI();}

// ════════════════════════════════════════════════════════════════════════════
// PLAYLISTS
// ════════════════════════════════════════════════════════════════════════════
var pls=[],curPlId=null,plMode='create',selE='🎵';
var EMOJIS=['🎵','🎶','🔥','❤️','⚡','🌊','☁️','🎸','🎤','🎧','🌟','💫','🎺','🥁','🎹','🎻','🎃','🌈','🏖','🌙','🦋','🐉','🚀','💎','🏆','🎮','🌸','🍀'];

async function loadPlaylists(){
  try{var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'pl_list'})});var d=await r.json();if(d.ok){pls=d.playlists||[];renderSbPl();}}catch(e){}
}
function renderSbPl(){
  var el=document.getElementById('sb-pl');if(!el)return;
  if(!pls.length){el.innerHTML='<div style="padding:6px 14px;font-size:11px;color:var(--dim)">Nenhuma playlist</div>';return;}
  el.innerHTML=pls.map(function(p){
    return '<div class="pl-si'+(curPlId===p.id?' act':'')+'" onclick="openPlPage(\''+p.id+'\')"><div class="pl-si-em">'+esc(p.emoji||'🎵')+'</div><span class="pl-si-nm">'+esc(p.name)+'</span><span class="pl-si-ct">'+(p.tracks?p.tracks.length:0)+'</span></div>';
  }).join('');
}
function openPlPage(id){curPlId=id;var pl=pls.find(function(p){return p.id===id;});if(!pl)return;showPage('playlist');renderPlPage(pl);renderSbPl();}
function renderPlPage(pl){
  var el=document.getElementById('pl-view');var tracks=pl.tracks||[];
  el.innerHTML='<div class="pl-hdr"><div class="pl-cov">'+esc(pl.emoji||'🎵')+'</div><div class="pl-meta"><div class="pl-meta-nm">'+esc(pl.name)+'</div><div class="pl-meta-ct">'+tracks.length+' música'+(tracks.length!==1?'s':'')+'</div></div><div class="pl-acts">'+
    (tracks.length?'<button style="padding:8px 14px;border-radius:8px;background:var(--acc);color:#000;border:none;font-family:\'DM Sans\',sans-serif;font-size:13px;font-weight:700;cursor:pointer;display:flex;align-items:center;gap:6px" onclick="playAllPl(\''+pl.id+'\')"><svg width="14" height="14" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>Tocar tudo</button>':'')+
    '<button style="padding:8px 12px;border-radius:8px;background:var(--card);color:var(--txt);border:1px solid var(--bdr);font-family:\'DM Sans\',sans-serif;font-size:13px;cursor:pointer;display:flex;align-items:center;gap:5px" onclick="openRenamePl(\''+pl.id+'\')"><svg width="13" height="13" fill="currentColor" viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>Renomear</button>'+
    '<button style="padding:8px 12px;border-radius:8px;background:rgba(255,77,109,.1);color:var(--acc3);border:1px solid rgba(255,77,109,.2);font-family:\'DM Sans\',sans-serif;font-size:13px;cursor:pointer;display:flex;align-items:center;gap:5px" onclick="delPl(\''+pl.id+'\')"><svg width="13" height="13" fill="currentColor" viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>Excluir</button>'+
  '</div></div>'+
  (tracks.length===0?'<div class="pl-empty"><div style="font-size:48px;opacity:.35">🎵</div><p>Playlist vazia</p><p style="font-size:12px">Busque músicas e toque "+ Playlist"</p></div>':
  '<div class="pl-tl">'+tracks.map(function(t,i){var d=JSON.stringify(t).replace(/'/g,"&#39;");return '<div class="pl-tr" onclick=\'playTrack('+d+')\"><div class="pl-tr-n">'+(i+1)+'</div><div class="pl-tr-th">'+(t.thumb?'<img src="'+t.thumb+'" loading="lazy" onerror="this.style.display=\'none\'">':'')+'</div><div class="pl-tr-inf"><div class="pl-tr-tit">'+esc(t.title)+'</div><div class="pl-tr-art">'+esc(t.channel||'')+'</div></div><span class="pl-tr-dur">'+(t.duration||'')+'</span><button class="pl-tr-rm" onclick="event.stopPropagation();rmTrack(\''+pl.id+'\',\''+t.id+'\')" title="Remover"><svg width="15" height="15" fill="currentColor" viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg></button></div>';}).join('')+'</div>');
}
function playAllPl(id){var pl=pls.find(function(p){return p.id===id;});if(!pl||!pl.tracks||!pl.tracks.length){showT('Playlist vazia');return;}Q=[];qi=-1;pl.tracks.forEach(function(t){Q.push(t);});qi=0;playTrack(Q[0]);showT('▶ '+esc(pl.name));}
function openCreatePl(){plMode='create';document.getElementById('pl-mt').textContent='Nova Playlist';document.getElementById('pl-ms').textContent='Dê um nome e escolha um emoji';document.getElementById('pl-mid').value='';document.getElementById('pl-mn').value='';selE='🎵';renderEG();document.getElementById('pl-modal').classList.add('open');setTimeout(function(){document.getElementById('pl-mn').focus();},80);}
function openRenamePl(id){var pl=pls.find(function(p){return p.id===id;});if(!pl)return;plMode='rename';document.getElementById('pl-mt').textContent='Renomear';document.getElementById('pl-ms').textContent='Altere o nome ou emoji';document.getElementById('pl-mid').value=id;document.getElementById('pl-mn').value=pl.name;selE=pl.emoji||'🎵';renderEG();document.getElementById('pl-modal').classList.add('open');setTimeout(function(){document.getElementById('pl-mn').focus();},80);}
function closePlModal(){document.getElementById('pl-modal').classList.remove('open');}
document.getElementById('pl-modal').addEventListener('click',function(e){if(e.target===this)closePlModal();});
function renderEG(){document.getElementById('egrid').innerHTML=EMOJIS.map(function(e){return '<div class="eopt'+(e===selE?' sel':'')+'" onclick="selEF(\''+e+'\')">'+e+'</div>';}).join('');}
function selEF(e){selE=e;document.querySelectorAll('.eopt').forEach(function(el){el.classList.toggle('sel',el.textContent===e);});}
async function savePl(){
  var name=document.getElementById('pl-mn').value.trim();var id=document.getElementById('pl-mid').value;
  if(!name){showT('⚠ Digite um nome');return;}
  var action=plMode==='create'?'pl_create':'pl_rename';var body={action:action,name:name,emoji:selE};if(id)body.id=id;
  try{var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});var d=await r.json();if(!d.ok){showT('⚠ '+d.error);return;}pls=d.playlists||[];closePlModal();renderSbPl();if(plMode==='create'&&d.playlist)openPlPage(d.playlist.id);else{var pl=pls.find(function(p){return p.id===curPlId;});if(pl)renderPlPage(pl);}showT(plMode==='create'?'✓ Playlist criada':'✓ Renomeada');}catch(e){showT('⚠ Erro ao salvar');}
}
async function delPl(id){var pl=pls.find(function(p){return p.id===id;});if(!confirm('Excluir "'+( pl?pl.name:'')+'"?'))return;try{var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'pl_delete',id:id})});var d=await r.json();if(!d.ok){showT('⚠ '+d.error);return;}pls=d.playlists||[];curPlId=null;renderSbPl();showPage('home');showT('✓ Excluída');}catch(e){}}
async function addToPl(plId,track){try{var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'pl_track_add',id:plId,track:track})});var d=await r.json();if(!d.ok){showT('⚠ '+d.error);return;}pls=d.playlists||[];renderSbPl();var pl=pls.find(function(p){return p.id===plId;});showT('✓ Adicionado a "'+(pl?pl.name:'')+'"');if(curPlId===plId&&pl)renderPlPage(pl);}catch(e){showT('⚠ Erro');}}
async function rmTrack(plId,tid){try{var r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:'pl_track_remove',id:plId,track_id:tid})});var d=await r.json();if(!d.ok){showT('⚠ '+d.error);return;}pls=d.playlists||[];renderSbPl();var pl=pls.find(function(p){return p.id===plId;});if(pl)renderPlPage(pl);showT('✓ Removida');}catch(e){}}

// Add-to-playlist dropdown
function toggleAtp(key){
  if(!cur){showT('Nenhuma música tocando');return;}
  var menu=document.getElementById('atp-'+key);if(!menu)return;
  var open=menu.classList.contains('open');
  document.querySelectorAll('.atp-menu').forEach(function(m){m.classList.remove('open');});
  if(!open){buildAtp(menu,cur);menu.classList.add('open');setTimeout(function(){document.addEventListener('click',function h(e){if(!menu.contains(e.target)){menu.classList.remove('open');document.removeEventListener('click',h);}});},10);}
}
function buildAtp(menu,track){
  if(!pls.length){menu.innerHTML='<div class="atp-hdr">Suas playlists</div><div class="atp-item" onclick="openCreatePl()"><svg width="14" height="14" fill="currentColor" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>Criar playlist</div>';return;}
  menu.innerHTML='<div class="atp-hdr">Adicionar à...</div>'+pls.map(function(p){var t=JSON.stringify(track).replace(/'/g,"&#39;");return '<div class="atp-item" onclick=\'addToPl("'+p.id+'",'+t+');document.querySelectorAll(".atp-menu").forEach(function(m){m.classList.remove("open");})\'>'+esc(p.emoji||'🎵')+' '+esc(p.name)+' <span style="font-size:11px;color:var(--mut);margin-left:auto">'+(p.tracks?p.tracks.length:0)+'</span></div>';}).join('')+'<div style="border-top:1px solid var(--bdr)"><div class="atp-item" onclick="openCreatePl()"><svg width="14" height="14" fill="currentColor" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>Nova playlist</div></div>';
}

// ════════════════════════════════════════════════════════════════════════════
// AVATAR / PERFIL
// ════════════════════════════════════════════════════════════════════════════
function openProfile(){
  document.getElementById('prof-name').textContent=NAME||'Minha conta';
  var saved=localStorage.getItem('snr_avatar_url');
  var prev=document.getElementById('av-prev');
  if(saved) prev.innerHTML='<img src="'+saved+'" style="width:100%;height:100%;object-fit:cover" onerror="this.parentNode.innerHTML=\'<span style=font-size:36px>'+AVTR+'</span>\'">';
  else prev.innerHTML='<span style="font-size:36px">'+AVTR+'</span>';
  document.getElementById('av-status').textContent='';
  document.getElementById('prof-modal').classList.add('open');
}
function closeProfile(){document.getElementById('prof-modal').classList.remove('open');}
document.getElementById('prof-modal').addEventListener('click',function(e){if(e.target===this)closeProfile();});

async function handleAvUpload(input){
  var file=input.files[0];if(!file)return;
  if(file.size>3*1024*1024){showT('⚠ Imagem muito grande (máx 3MB)');return;}
  var reader=new FileReader();reader.onload=function(e){var prev=document.getElementById('av-prev');prev.innerHTML='<img src="'+e.target.result+'" style="width:100%;height:100%;object-fit:cover">';};reader.readAsDataURL(file);
  document.getElementById('av-status').textContent='Enviando...';
  var fd=new FormData();fd.append('avatar',file);fd.append('action','avatar_upload');
  try{
    var r=await fetch('api.php',{method:'POST',body:fd});var d=await r.json();
    if(!d.ok){document.getElementById('av-status').textContent='⚠ '+d.error;return;}
    var url=d.avatar_url;localStorage.setItem('snr_avatar_url',url);
    var ab=document.getElementById('av-btn');ab.innerHTML='<img src="'+url+'" onerror="this.parentNode.innerHTML=\'<span>'+AVTR+'</span>\'">';
    document.getElementById('av-status').textContent='✓ Foto atualizada!';showT('✓ Foto de perfil atualizada');
  }catch(e){document.getElementById('av-status').textContent='⚠ Erro ao enviar';}
}

// ════════════════════════════════════════════════════════════════════════════
// BUSCA
// ════════════════════════════════════════════════════════════════════════════
async function doSearch(){
  var q=document.getElementById('si').value.trim();if(!q)return;
  showPage('search');document.getElementById('st').innerHTML='Resultados para <span>"'+esc(q)+'"</span>';
  var c=document.getElementById('sr');c.innerHTML='<div class="loading"><div class="spin"></div> Buscando...</div>';
  try{
    var r=await fetch('search.php?q='+encodeURIComponent(q)+'&limit=18',{signal:AbortSignal.timeout(18000)});
    if(!r.ok)throw new Error('HTTP '+r.status);var d=await r.json();if(!d.success)throw new Error(d.error||'Erro');
    renderCards(d.results,c);
  }catch(e){c.innerHTML='<div class="es"><p style="color:var(--acc3)">'+esc(e.message)+'</p><button class="retry-btn" onclick="doSearch()">Tentar novamente</button></div>';}
}
function quickS(q){document.getElementById('si').value=q;showPage('search');doSearch();}

async function loadHome(){
  var c=document.getElementById('home-grid');c.innerHTML='<div class="loading"><div class="spin"></div></div>';
  try{var r=await fetch('search.php?q=musicas+populares+brasil+2024&limit=12',{signal:AbortSignal.timeout(18000)});var d=await r.json();if(!d.success)throw new Error(d.error);renderCards(d.results,c);}
  catch(e){c.innerHTML='<div class="es"><p>'+esc(e.message)+'</p><button class="retry-btn" onclick="loadHome()">Tentar novamente</button></div>';}
}
function fg(btn,q){
  document.querySelectorAll('.tab-row .tab').forEach(function(t){t.classList.remove('act');});btn.classList.add('act');
  var c=document.getElementById('home-grid');c.innerHTML='<div class="loading"><div class="spin"></div></div>';
  fetch('search.php?q='+encodeURIComponent(q)+'&limit=12',{signal:AbortSignal.timeout(18000)}).then(function(r){return r.json();}).then(function(d){if(!d.success)throw new Error(d.error);renderCards(d.results,c);}).catch(function(e){c.innerHTML='<div class="es"><p>'+esc(e.message)+'</p><button class="retry-btn" onclick="loadHome()">↺</button></div>';});
}
function renderCards(items,container){
  if(!items||!items.length){container.innerHTML='<div class="es"><p>Nenhum resultado encontrado</p></div>';return;}
  container.innerHTML=items.map(function(item){
    var data=JSON.stringify(item).replace(/'/g,"&#39;").replace(/\\/g,'\\\\');
    return '<div class="rc">'+
      '<div class="rt">'+
        (item.thumb?'<img src="'+item.thumb+'" loading="lazy" onerror="this.parentNode.innerHTML=\'<div class=rt-ph>🎵</div>\'">':'<div class="rt-ph">🎵</div>')+
        '<div class="play-over" onclick=\'playTrack('+data+')\'>'+
          '<div class="play-circ"><svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg></div>'+
        '</div>'+
        (item.duration&&item.duration!=='--:--'?'<div class="rt-dur">'+item.duration+'</div>':'')+
        '<button class="rc-apl" onclick=\'event.stopPropagation();showCardAtp(this,'+data+')\'><svg width="10" height="10" fill="currentColor" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>+ Lista</button>'+
      '</div>'+
      '<div class="ri" onclick=\'playTrack('+data+')\'>'+
        '<div class="rtitle">'+esc(item.title)+'</div>'+
        '<div class="rch">'+esc(item.channel||'')+'</div>'+
      '</div>'+
    '</div>';
  }).join('');
}
function showCardAtp(btn,track){
  var menu=document.getElementById('atp-np');
  buildAtp(menu,track);
  var rect=btn.getBoundingClientRect();
  menu.style.position='fixed';menu.style.left='auto';
  menu.style.right=(window.innerWidth-rect.right)+'px';
  menu.style.bottom=(window.innerHeight-rect.top+4)+'px';
  menu.classList.add('open');
  setTimeout(function(){document.addEventListener('click',function h(e){if(!menu.contains(e.target)&&e.target!==btn){menu.classList.remove('open');document.removeEventListener('click',h);}});},10);
}

// ════════════════════════════════════════════════════════════════════════════
// PAGES / NAV
// ════════════════════════════════════════════════════════════════════════════
function showPage(name){
  document.querySelectorAll('.pg').forEach(function(p){p.classList.remove('act');});
  var pg=document.getElementById('pg-'+name);if(pg)pg.classList.add('act');
  document.querySelectorAll('.ni').forEach(function(x){x.classList.remove('act');});
  var ni=document.getElementById('ni-'+name);if(ni)ni.classList.add('act');
  document.querySelectorAll('.mn').forEach(function(x){x.classList.remove('act');});
  var mn=document.getElementById('mn-'+name);if(mn)mn.classList.add('act');
  if(name==='queue')renderQ();
}

// ════════════════════════════════════════════════════════════════════════════
// KEYBOARD
// ════════════════════════════════════════════════════════════════════════════
document.addEventListener('keydown',function(e){
  if(e.target.tagName==='INPUT'||e.target.tagName==='TEXTAREA')return;
  if(e.code==='Space'){e.preventDefault();tPlay();}
  else if(e.code==='ArrowRight')next();
  else if(e.code==='ArrowLeft')prev();
  else if(e.code==='KeyM')tMute();
  else if(e.code==='KeyF')toggleFav();
  else if(e.code==='KeyS')tShuffle();
});

// Volume click
document.getElementById('vtk').addEventListener('click',function(e){
  vol=Math.max(0,Math.min(100,(e.offsetX/this.offsetWidth)*100));
  document.getElementById('vf').style.width=vol+'%';
  if(ytReady&&ytPlayer) ytPlayer.setVolume(muted?0:vol);
});

// ════════════════════════════════════════════════════════════════════════════
// UTILS
// ════════════════════════════════════════════════════════════════════════════
function esc(s){return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}
var tT;
function showT(m){var el=document.getElementById('toast');document.getElementById('tmsg').textContent=m;el.classList.add('show');clearTimeout(tT);tT=setTimeout(function(){el.classList.remove('show');},2600);}

// INIT
loadHome();
</script>
</body>
</html>
