/* ============ Kleis TV — design tokens ============ */
:root{
  --bg: #0a0d12;
  --bg-elev: #12161d;
  --bg-elev-2: #1a1f29;
  --border: #262c38;
  --text: #e9ecf1;
  --text-dim: #8e97a8;
  --text-faint: #565f70;
  --accent: #f2a93b;
  --accent-dim: rgba(242,169,59,.14);
  --accent-glow: rgba(242,169,59,.35);
  --danger: #ff5c5c;
  --radius: 14px;
  --radius-sm: 9px;
  --font-display: 'Space Grotesk', 'Inter', system-ui, sans-serif;
  --font-body: 'Inter', system-ui, -apple-system, sans-serif;
}

*{ box-sizing: border-box; }

/* Garantisce che l'attributo HTML `hidden` nasconda SEMPRE l'elemento,
   anche quando una regola più sotto (es. `.login-screen{ display:flex }`)
   imposterebbe altrimenti un valore di display diverso. Senza questa
   regola, a parità di specificità il CSS dell'autore vince su quello del
   browser: l'attributo `hidden` verrebbe impostato correttamente da JS ma
   ignorato a schermo, mostrando login e app sovrapposti. */
[hidden]{ display:none !important; }
html,body{ height:100%; }
body{
  margin:0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
button, input, select{ font-family: inherit; color: inherit; }
:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }

.brand{ display:flex; align-items:baseline; gap:6px; font-family: var(--font-display); }
.brand-mark{ font-weight:700; letter-spacing:.06em; font-size:1.1rem; }
.brand-sub{ font-weight:500; color: var(--accent); letter-spacing:.14em; font-size:.85rem; }
.brand--compact .brand-mark{ font-size:1rem; }

/* ============ Login ============ */
.login-screen{
  position:fixed; inset:0;
  display:flex; align-items:center; justify-content:center;
  padding: 24px;
}
.login-bg{
  position:absolute; inset:0; z-index:0;
  background:
    radial-gradient(ellipse 900px 500px at 50% -10%, rgba(242,169,59,.10), transparent 60%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.02) 0 1px, transparent 1px 64px),
    var(--bg);
}
.login-card{
  position:relative; z-index:1;
  width:100%; max-width:380px;
  background: linear-gradient(180deg, var(--bg-elev), var(--bg-elev-2));
  border:1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px 28px 28px;
  box-shadow: 0 20px 60px rgba(0,0,0,.45);
  display:flex; flex-direction:column; align-items:stretch;
}
.login-card .brand{ margin-bottom: 22px; }
.eyebrow{
  margin:0 0 6px; text-transform:uppercase; letter-spacing:.14em;
  font-size:.7rem; color: var(--accent); font-weight:600;
}
.login-card h1{ margin:0 0 6px; font-family: var(--font-display); font-size:1.4rem; }
.login-hint{ margin:0 0 22px; color: var(--text-dim); font-size:.85rem; line-height:1.4; }

.code-input{
  width:100%;
  background: var(--bg);
  border:1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  font-size:1.1rem;
  letter-spacing:.3em;
  text-align:center;
  color: var(--text);
  transition: border-color .15s, box-shadow .15s;
}
.code-input::placeholder{ color: var(--text-faint); letter-spacing:.3em; }
.code-input:focus{ border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-dim); outline:none; }

.remember{
  display:flex; align-items:center; gap:10px;
  margin:16px 2px 20px; padding:6px 2px;
  font-size:.85rem; color: var(--text-dim);
  cursor:pointer; user-select:none;
}
.remember input{ accent-color: var(--accent); width:20px; height:20px; }

.btn-primary{
  border:none; cursor:pointer;
  background: var(--accent);
  color:#1a1305;
  font-weight:600; font-size:.95rem;
  border-radius: var(--radius-sm);
  padding: 15px 16px;
  min-height: 48px;
  transition: filter .15s, transform .05s;
}
.btn-primary:hover{ filter:brightness(1.08); }
.btn-primary:active{ transform: scale(.98); }

.login-error{
  margin:14px 0 0; color: var(--danger); font-size:.82rem; text-align:center;
}

/* ============ App shell ============ */
.app-screen{ min-height:100%; display:flex; flex-direction:column; }

.topbar{
  position:sticky; top:0; z-index:20;
  display:flex; align-items:center; justify-content:space-between;
  gap:12px;
  padding: 12px 18px;
  background: rgba(10,13,18,.85);
  backdrop-filter: blur(10px);
  border-bottom:1px solid var(--border);
}
.topbar-controls{ display:flex; align-items:center; gap:10px; flex:1; justify-content:flex-end; flex-wrap:wrap; }

.select-wrap select{
  background: var(--bg-elev-2);
  border:1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  min-height: 48px;
  font-size:.85rem;
  min-width: 120px;
  cursor:pointer;
}

.icon-btn{
  background: var(--bg-elev-2);
  border:1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  width:48px; height:48px;
  display:inline-flex; align-items:center; justify-content:center;
  cursor:pointer; font-size:1.1rem;
  transition: border-color .15s, color .15s;
}
.icon-btn:hover{ border-color: var(--accent); color: var(--accent); }

.search-wrap{
  position:relative; display:flex; align-items:center;
  background: var(--bg-elev-2);
  border:1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0 12px;
  min-width: 160px;
  min-height: 48px;
  flex: 1 1 180px;
  max-width: 280px;
}
.search-icon{ color: var(--text-faint); flex-shrink:0; }
.search-wrap input{
  background:transparent; border:none; outline:none;
  padding: 13px 8px; width:100%; font-size:.9rem; color: var(--text);
}
.search-wrap input::placeholder{ color: var(--text-faint); }

/* ============ Main layout ============ */
.app-main{
  flex:1;
  display:grid;
  grid-template-columns: 1fr;
  gap: 18px;
  padding: 16px;
}
/* Gli elementi grid/flex hanno di default min-width:auto (non 0): si
   rifiutano di restringersi sotto la larghezza "naturale" del loro
   contenuto. Con 1641 canali nella griglia, quel contenuto naturale può
   essere enorme — senza questa regola l'intera colonna (player compreso,
   essendo width:100% del suo contenitore) veniva spinta a migliaia di
   pixel di larghezza su schermi stretti, con conseguenze imprevedibili
   su cosa risultasse effettivamente visibile a schermo. */
.app-main > *{ min-width:0; }
@media (min-width: 960px){
  .app-main{
    grid-template-columns: minmax(0, 1.5fr) minmax(320px, 1fr);
    align-items:start;
  }
  .player-col{ position:sticky; top:74px; }
}

/* ============ Player ============ */
.player-wrap{
  position:relative;
  width:100%;
  aspect-ratio: 16/9;
  background: #000;
  border-radius: var(--radius);
  overflow:hidden;
  border:1px solid var(--border);
  display:flex;
  align-items:center;
  justify-content:center;
}
/* Sotto i 960px (schermo verticale/portrait, es. il display 17" dell'auto)
   l'aspect-ratio 16:9 a piena larghezza potrebbe comunque occupare più
   della metà schermo se lo schermo è molto largo per essere verticale.
   Questo tetto tiene il player nella porzione superiore, lasciando
   sempre spazio alla griglia canali sotto. Il canvas dentro (vedi regola
   successiva) si ridimensiona di conseguenza senza deformarsi, perché
   resta l'unico meccanismo a governare le sue proporzioni. */
@media (max-width: 959px){
  .player-wrap{ max-height: 45vh; }
}
/* Il canvas riceve i fotogrammi JPEG dal server via WebSocket: le sue
   dimensioni "reali" (attributi width/height) vengono impostate dal JS
   al primo frame, in modo che il CSS qui sotto lo scali mantenendo le
   proporzioni, esattamente come farebbe un <img> o un <video>. */
.player-wrap canvas{
  max-width:100%;
  max-height:100%;
  display:block;
  /* Forza il canvas su un proprio livello di composizione GPU stabile.
     Senza questo, su alcune combinazioni Chrome/scheda grafica il canvas
     può disegnare correttamente al suo interno (dati giusti) ma restare
     "non composto" a schermo — un vero fermo immagine nero — finché
     qualcosa non forza un ricalcolo del layout (es. ridimensionare la
     finestra). transform: translateZ(0) è la scorciatoia standard per
     spingere l'elemento su un compositor layer dedicato invece di
     lasciarlo all'euristica del browser. */
  transform: translateZ(0);
}

.player-overlay{
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:10px; color: var(--text-faint);
  background: radial-gradient(ellipse at 50% 40%, rgba(242,169,59,.06), transparent 65%);
  pointer-events:none;
}
.ph-icon{
  width:52px; height:52px; border-radius:50%;
  border:1px solid var(--border);
  display:flex; align-items:center; justify-content:center;
  font-size:1.1rem; color: var(--accent);
}
.player-overlay p{ margin:0; font-size:.85rem; }

.now-playing{
  position:absolute; top:12px; left:12px;
  display:flex; align-items:center; gap:8px;
  background: rgba(10,13,18,.72);
  backdrop-filter: blur(6px);
  border:1px solid var(--border);
  border-radius: 999px;
  padding: 6px 12px 6px 10px;
  font-size:.8rem; font-weight:500;
  max-width: calc(100% - 24px);
}
.now-playing span#now-playing-name{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.live-dot{
  position: relative;
  width:8px; height:8px; border-radius:50%; background: var(--accent);
  flex-shrink:0;
}
/* L'anello che si espande è un elemento a parte, animato solo con
   transform/opacity invece di box-shadow. box-shadow costringe il
   browser a ricalcolare stile e ridisegnare ad ogni fotogramma
   dell'animazione (60 volte al secondo, per sempre, canale acceso o
   no) — un costo scoperto solo osservando una registrazione reale
   delle prestazioni: era lì anche quando il video andava a scatti per
   altri motivi, sommandosi a quelli. transform/opacity invece li
   gestisce la GPU per conto suo, a costo praticamente zero per la CPU.
*/
.live-dot::after{
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 1.8s infinite;
}
@keyframes pulse{
  0%{ transform: scale(1); opacity: .6; }
  70%{ transform: scale(3.5); opacity: 0; }
  100%{ transform: scale(3.5); opacity: 0; }
}

.player-fs-btn{ position:absolute; bottom:12px; right:12px; background: rgba(10,13,18,.72); }
.player-mute-btn{ position:absolute; bottom:12px; right:68px; background: rgba(10,13,18,.72); }

.player-status{
  color: var(--text-dim); font-size:.82rem; margin: 10px 2px 0;
}

.player-error{
  color: var(--danger); font-size:.82rem; margin: 10px 2px 0;
}

/* ============ Category chips ============ */
.chips{
  display:flex; gap:10px; overflow-x:auto; padding-bottom:4px;
  scrollbar-width: thin;
}
.chip{
  flex-shrink:0; cursor:pointer; user-select:none;
  background: var(--bg-elev-2);
  border:1px solid var(--border);
  color: var(--text-dim);
  border-radius: 999px;
  padding: 13px 18px;
  min-height: 48px;
  display:inline-flex; align-items:center;
  font-size:.8rem; font-weight:500;
  transition: all .15s;
  white-space:nowrap;
}
.chip:hover{ color: var(--text); }
.chip.active{
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}

/* ============ Channel grid ============ */
.grid-header{
  display:flex; justify-content:space-between; align-items:center;
  margin: 10px 2px 10px;
  color: var(--text-dim); font-size:.78rem;
}

.channel-grid{
  display:grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 10px;
}
@media (min-width: 960px){
  .channel-grid{ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
}

.channel-card{
  background: var(--bg-elev);
  border:1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 8px 9px;
  cursor:pointer;
  display:flex; flex-direction:column; align-items:center; gap:8px;
  text-align:center;
  transition: border-color .15s, transform .08s, box-shadow .15s;
}
.channel-card:hover{ border-color: var(--text-faint); transform: translateY(-1px); }
.channel-card.active{
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 6px 20px rgba(242,169,59,.12);
  background: var(--accent-dim);
}

.channel-logo{
  width:100%; aspect-ratio:1;
  border-radius:8px;
  background: var(--bg-elev-2);
  display:flex; align-items:center; justify-content:center;
  overflow:hidden;
}
.channel-logo img{ width:100%; height:100%; object-fit:contain; padding:6px; }
.channel-logo .fallback{
  font-family: var(--font-display); font-weight:700; font-size:1.1rem; color: var(--text-faint);
}

.channel-name{
  font-size:.76rem; line-height:1.25;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden; color: var(--text);
  overflow-wrap:anywhere; word-break:break-word;
}

.empty-state{ color: var(--text-dim); font-size:.85rem; text-align:center; padding: 30px 0; }

/* ============ Scrollbars ============ */
::-webkit-scrollbar{ height:6px; width:6px; }
::-webkit-scrollbar-thumb{ background: var(--border); border-radius:3px; }

/* ============ Reduced motion ============ */
@media (prefers-reduced-motion: reduce){
  .live-dot::after{ animation:none; }
  .channel-card{ transition:none; }
}
