=== DATOS EPG PHP ===
109:function pz_hora36($ts){
139:$epgNow = "Sin información";
140:$epgNext = "Sin información";
152:        $epgNow = base64_decode($epg["epg_listings"][0]["title"]);
156:        $epgNext = base64_decode($epg["epg_listings"][1]["title"]);
276:.epgNextTime{font-size:12px;font-weight:700;color:#cdefff}
486:              $nowTitle = $epg[0] ?? $epgNow ?? "No information";
487:              $nextTitle = $epg[1] ?? $epgNext ?? "No information";
488:              $startTs = intval($epg[2] ?? 0);
489:              $endTs = intval($epg[3] ?? 0);
490:              $nextStartTs = intval($epg[4] ?? 0);
491:              $nextEndTs = intval($epg[5] ?? 0);
494:              $progress = 0;
495:              $remainMin = 0;
496:              if ($startTs > 0 && $endTs > $startTs) {
497:                  $progress = max(0, min(100, intval((($nowTs - $startTs) / ($endTs - $startTs)) * 100)));
498:                  $remainMin = max(0, intval(ceil(($endTs - $nowTs) / 60)));
501:              if (!function_exists("pz_hora_epg")) {
502:                function pz_hora_epg($ts) {
518:              <?php if ($startTs > 0 && $endTs > 0): ?>
519:              <div class="epgTimeSimple"><?=pz_hora_epg($startTs)?> - <?=pz_hora_epg($endTs)?></div>
522:                <div class="epgBarMini"><div class="epgBarFill" style="width:<?=$progress?>%"></div></div>
523:                <span><?=$remainMin?> min</span>
528:              <div class="epgNextTime"><?=pz_hora_epg($nextStartTs)?> - <?=pz_hora_epg($nextEndTs)?></div>
554:       data-now="<?=htmlspecialchars($epgNow ?? "No information")?>"
555:       data-next="<?=htmlspecialchars($epgNext ?? "No information")?>"
572:                        <small><?=pz_hora36($st)?> - <?=pz_hora36($en)?></small>
582:                    <small><?=pz_hora36($pr["start"])?> - <?=pz_hora36($pr["end"])?></small>

=== HTML TOP 430-500 ===

/* FORCE NOINFO LEFT FINAL */
.prog36.noinfo{
  display:block!important;
  text-align:left!important;
  justify-content:flex-start!important;
  align-items:flex-start!important;
  padding:8px 12px!important;
  color:#fff!important;
}
.prog36.noinfo b{
  display:block!important;
  text-align:left!important;
  color:#fff!important;
}
.prog36.noinfo small{
  display:block!important;
  text-align:left!important;
  color:#cdefff!important;
}

</style>
</head>
<body>


<div class="app">
    <aside class="side">
        <div class="logo"><span>puntoz</span> TV</div>
        <div class="nav active navFocus">▣ TV EN VIVO</div>
        <div class="nav navFocus">⌂ Inicio</div>
        <div class="nav navFocus">🎬 Movies</div>
        <div class="nav navFocus">▤ TV Shows</div>
        <div class="nav navFocus">⚙ Settings</div>
    </aside>

    <section class="cats">
        <h1>All playlists</h1>
        <a class="cat navFocus <?=$cat===''?'active':''?>" href="tv_clean.php">All channels</a>
        <?php foreach($cats as $c): ?>
        <a class="cat navFocus <?=((string)$cat===(string)$c["category_id"])?'active':''?>" href="tv_clean.php?cat=<?=urlencode($c["category_id"])?><?=$keepEpg?>">
            <?=htmlspecialchars($c["category_name"] ?? "Sin nombre")?>
        </a>
        <?php endforeach; ?>
    </section>

    <main class="main">
        <section class="top">
            <div class="videoBox navFocus" tabindex="0">
                <?php if($playUrl): ?>
                <video id="mainVideo" class="navFocus" tabindex="0" autoplay playsinline src="<?=htmlspecialchars($playUrl)?>"></video>
                <?php endif; ?>
            </div>
            <div class="info"><a class="refreshEpg navFocus" href="<?=htmlspecialchars($_SERVER["PHP_SELF"])?>?<?=htmlspecialchars(http_build_query(array_merge($_GET, ["epg_refresh"=>time()])))?>">↻ Actualizar EPG</a>
<?php if(isset($_GET["epg_refresh"])): ?><div class="toast">Guía actualizada OK</div><?php endif; ?>
            <?php
              $nowTitle = $epg[0] ?? $epgNow ?? "No information";
              $nextTitle = $epg[1] ?? $epgNext ?? "No information";
              $startTs = intval($epg[2] ?? 0);
              $endTs = intval($epg[3] ?? 0);
              $nextStartTs = intval($epg[4] ?? 0);
              $nextEndTs = intval($epg[5] ?? 0);
              $nowTs = time();

              $progress = 0;
              $remainMin = 0;
              if ($startTs > 0 && $endTs > $startTs) {
                  $progress = max(0, min(100, intval((($nowTs - $startTs) / ($endTs - $startTs)) * 100)));
                  $remainMin = max(0, intval(ceil(($endTs - $nowTs) / 60)));
              }


=== JS FINAL 760-840 ===
    }
},true);
</script>

<script>
document.addEventListener('DOMContentLoaded',function(){
    const v=document.getElementById('mainVideo');
    if(v){
        v.muted=false;
        v.volume=1.0;
        v.addEventListener('dblclick',function(){
            if(v.requestFullscreen) v.requestFullscreen();
            else if(v.webkitRequestFullscreen) v.webkitRequestFullscreen();
        });
    }
});
</script>

<script>
let lastRow = null;
let lastTime = 0;

function abrirFullscreenActual(){
    const v=document.getElementById('mainVideo');
    const focused=document.querySelector('.focus.row');
    const active=document.querySelector('.row.active');

    let url = "";

    if(focused && focused.getAttribute('data-play')) url = focused.getAttribute('data-play');
    else if(active && active.getAttribute('data-play')) url = active.getAttribute('data-play');
    else if(v && v.currentSrc) url = v.currentSrc;
    else if(v && v.src) url = v.src;

    if(!url) return;

    if(window.PuntozAndroid && PuntozAndroid.abrirFullscreen){
        PuntozAndroid.abrirFullscreen(url);
        return;
    }

    if(v.requestFullscreen) v.requestFullscreen();
    else if(v.webkitRequestFullscreen) v.webkitRequestFullscreen();
}

document.addEventListener('keydown',function(e){
    if(e.key !== 'Enter') return;

    const el=document.querySelector('.focus');

    if(el && el.classList.contains('videoBox')){
        e.preventDefault();
        abrirFullscreenActual();
        return;
    }

    if(el && el.classList.contains('row')){
        const now=Date.now();

        if(lastRow === el && (now-lastTime) < 700){
            e.preventDefault();
            if(typeof quickPlay === 'function') quickPlay(el);
            setTimeout(abrirFullscreenActual,250);
            return;
        }

        lastRow = el;
        lastTime = now;
    }
},true);

document.addEventListener('dblclick',function(e){
    const row=e.target.closest('.row');
    if(row){
        if(typeof quickPlay === 'function') quickPlay(row);
        setTimeout(abrirFullscreenActual,250);
    }
},true);
</script>


