/*
 * 10 pés, piso Chromium 53 (webOS 4.0): flexbox sim, grid/gap com cautela — aqui só margin.
 * O cursor é a classe `is-focused` que o FocusDom aplica; nada de :hover, nada de :focus nativo.
 * As cores saem de theme.css (a tradução fiel do tema do Android) — aqui, nenhuma cor solta.
 */
* { box-sizing: border-box; }

/*
 * ESCALA DE 10 PÉS — a peça que faltava para bater a proporção do Android (ADR-0011, Apêndice C
 * item 4). O app Android TV desenha num canvas LÓGICO de 960×540 dp (a TV de 1080p roda em
 * densidade 2.0 = xhdpi/320dpi), então 1 dp ocupa 1/960 da largura. A casca web, porém, desenha em
 * 1920 CSS px (a TV reporta innerWidth=1920), onde 1 px ocupa 1/1920 — METADE da fração de tela. Por
 * isso todo elemento saía ~50% menor que no Android, com a proporção "de desktop" que o Bruno pegou.
 *
 * `zoom: 2` no ELEMENTO RAIZ resolve com uma linha: o Blink reduz o canvas lógico para 1920/2 = 960
 * e pinta tudo 2×. Assim 1 CSS px passa a valer 1 dp do Android, e os valores deste arquivo — que
 * foram autorados ~1:1 com os `.dp`/`.sp` do código Android — caem no lugar (pane de categorias
 * 300px→300dp, thumb 44px→44dp, aba 16px→16sp, padding 48px→48dp…). Full-width se re-ajusta (sem
 * overflow: scrollWidth segue 1920); o player continua cobrindo a tela; foco/scroll intactos.
 * TEM de ser no raiz (`html`): no `#root` (filho) o zoom transbordaria em vez de reduzir o canvas.
 * `zoom` é legado mas universal no Blink/WebKit desde sempre — seguro no piso Chromium 53.
 * Regra viva: valor novo de CSS = o `.dp`/`.sp` do Android **em px, 1:1** (o zoom faz o resto).
 */
html { zoom: 2; }

/*
 * Corolário do zoom: a altura EFETIVA também cai pela metade (1080→540). Telas verticalmente densas
 * — o login e a Busca trazem um teclado NA TELA (divergência: o Android usa o IME do sistema), a
 * Settings é uma pilha de cartões — passam a exceder 540 e precisam ROLAR. Num container de scroll
 * que é flex-column, porém, o flexbox ENCOLHE os filhos p/ caber (logo/abas/teclado viravam 4–37px,
 * sobrepostos) em vez de rolar. Travar `flex-shrink: 0` nos filhos preserva a altura natural e deixa
 * o scroll (nativo ou o `ensureVisible` da main) trazer o foco à vista. Em container de scroll que é
 * bloco (Live/Home/VOD), a regra é inócua (flex-shrink não se aplica). Só o zoom expôs isto.
 */
[data-scroll='y'] > * { flex-shrink: 0; }

/*
 * Container de scroll TEM de ser o `offsetParent` dos filhos: o `ensureVisible` da main calcula
 * `offsetTop/offsetLeft`, que são relativos ao ancestral POSICIONADO mais próximo — sem isto, um
 * container não-posicionado (`.rails`, episódios da série) fazia a conta sair deslocada pela altura
 * do que há ACIMA dele (a barra de topo) e o scroll "encalhava" ~28px abaixo do topo: era o título
 * da primeira categoria recortado ao voltar (bug pego pelo Bruno na TV real; o login nunca sofreu
 * porque `.login-content` já era `position: relative`).
 */
[data-scroll] { position: relative; }

/*
 * Navega-se por FOCO (D-pad), nunca arrastando uma barra — então a barra de rolagem nativa só suja a
 * tela. O webOS 4.x (LG) desenha uma barra cinza grossa e feia nas Configurações; o Tizen (Samsung)
 * já a esconde. Some com ela em TODO container de scroll, uniformizando as duas TVs (pego no QA da LG).
 */
[data-scroll]::-webkit-scrollbar { width: 0; height: 0; display: none; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  /* Gradiente de catálogo do Android: bgTop → bgDeep. */
  background: linear-gradient(180deg, var(--bg-top), var(--bg-deep) 60%);
  color: var(--text-high);
  font-family: var(--font-brand);
  font-size: 16px;
}

#root { height: 100%; display: flex; flex-direction: column; }

/* ---- marca (logo = mark + wordmark), porte fiel de Brand.kt ---- */
.brand-logo {
  display: flex;
  align-items: center;
}
.brand-mark {
  display: block;
  margin-right: 10px;
}
.brand-word {
  font-weight: 800; /* ExtraBold */
  letter-spacing: 0.2px;
}
.brand-word-antena { color: var(--text-high); }
.brand-word-play {
  color: var(--accent);
  margin-left: 6px;
}

/* ---- topo (marca) — legado; a barra de navegação a substitui nas telas com hub ---- */
.home-top {
  flex-shrink: 0;
  padding: 28px 56px 16px 56px;
}

/* ---- barra de navegação de topo (hub) — porte do CatalogTopBar ---- */
.nav-bar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  padding: 16px 32px 10px; /* 48→32: com a aba Animes ligada são 6 abas — precisa caber em 960 */
}
/* `gap` em flex é Chrome 84 — acima até da LG validada (79) e do piso 53/56. Em contêiner flex o
   espaçamento aqui é SEMPRE margem entre irmãos (`> * + *`); `gap` só seria seguro em grid (57+),
   que a casca não usa. */
.nav-bar > * + * { margin-left: 14px; }
.nav-tabs {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  overflow: hidden; /* com muitas abas, a faixa corta em vez de empurrar as pílulas/relógio */
}
.nav-tabs > * + * { margin-left: 8px; }
.nav-pills {
  flex-shrink: 0;
  display: flex;
  align-items: center;
}
.nav-pills > * + * { margin-left: 8px; }
/* Relógio + data no canto direito (o `CatalogTopBar` do Android). */
.nav-clock {
  flex-shrink: 0;
  margin-left: 16px;
  text-align: right;
  line-height: 1.1;
}
.nav-clock-time { font-size: 18px; font-weight: 800; color: var(--text-high); }
.nav-clock-date { font-size: 11px; color: var(--text-med); }
.nav-tab,
.nav-pill {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  padding: 11px 13px; /* Android usa 16; 13 deixa as 6 abas (com Animes) caberem em 960 */
  border-radius: 99px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-med);
  border: 2px solid transparent;
  white-space: nowrap;
}
.nav-tab > * + *,
.nav-pill > * + * { margin-left: 8px; } /* ícone ↔ rótulo, como o Tab do Android */
/* Pílulas SÓ ÍCONE (Buscar/Config) — o IconPill circular de 46dp do Android; e a aba Início também
   fica só no ícone (pedido do dono: o texto era redundante e a barra estourava a largura na TV). */
.nav-pill,
.nav-tab.is-icon-only {
  width: 46px;
  height: 46px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
}
.nav-pill > * + *,
.nav-tab.is-icon-only > * + * { margin-left: 0; }
.nav-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  display: block; /* herda `color` do item via currentColor (foco/ativo) */
}
.nav-pill .nav-icon { width: 21px; height: 21px; } /* IconPill do Android: ícone 21 */
.nav-tab.is-active {
  color: var(--text-high);
  background: var(--surface-2);
}
.nav-tab.is-focused,
.nav-pill.is-focused {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent-soft);
}

/* ---- rails ---- */
.rails {
  flex: 1 1 auto;
  overflow: hidden;
  padding: 4px 56px 0 56px;
}
.rail { margin-bottom: 18px; } /* = 18dp do Android (era 34, o dono achou o vão grande demais) */
.rail-title {
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 14px 0;
}
.rail-items {
  position: relative;
  display: flex;
  align-items: flex-start;
  overflow: hidden;
  padding: 10px 4px;
  min-height: 258px; /* arte 198 + gap 8 + título 34 + folga do foco */
}
/* Trilho de card 16:9 (o AO VIVO do HUB): 129 de card + folga do foco — sem isto herdava a altura do
   pôster retrato e abria um vão morto entre as categorias. */
.rail-items.is-live { min-height: 149px; }

/* Card = arte (retrato 2:3) EM CIMA + título ABAIXO (o `PosterCard` do Android). A célula é a coluna;
   a ARTE (`.poster`) é o nó focável (só ela escala no foco, o título embaixo fica parado). */
.poster-cell {
  flex-shrink: 0;
  width: 132px; /* largura FIXA: o título com ellipsis se limita a ela (nowrap num inline-flex alargava a célula e "quebrava" o card — QA do dono) */
  margin-right: 16px;
  display: -webkit-box;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  flex-direction: column;
}
.poster-cell .poster { margin-right: 0; width: 100%; } /* a arte preenche a célula; o espaçamento mora na célula */
/* Pôster retrato 2:3, menor que antes (pedido do dono: card menor = cabe mais na tela). */
.poster {
  position: relative;
  flex-shrink: 0;
  width: 132px;
  height: 198px;
  margin-right: 16px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-2);
  border: 3px solid transparent;
  transition: -webkit-transform 0.15s ease;
  transition: transform 0.15s ease;
}
.poster-img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}
/* Sem capa (ou onerror): um gradiente da marca + a ASSINATURA (mark) centralizada, nunca caixa vazia. */
.poster-fallback {
  background: linear-gradient(135deg, var(--surface-2), var(--accent-dim));
}
.poster-fallback .poster-img { display: none; }
/* Os ARCOS da marca: escondidos quando há capa; no fallback preenchem o card como textura (saindo do
   canto inferior-direito, como nos cards institucionais). Sem logo — não reivindicamos o conteúdo. */
.poster-mark { display: none; }
.poster-fallback .poster-mark {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}
/* Título ABAIXO da arte, UMA linha com "…" (o `PosterCard` do Android — 2 linhas variavam a altura
   dos cards e "quebravam" o trilho/grade; QA do dono). A largura fixa da célula guia o ellipsis. */
.poster-title {
  display: block;
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.25;
  color: var(--text-high);
}
/* Cursor de 10 pés: o accent da marca (borda + leve escala), como no Android. */
.poster.is-focused {
  border-color: var(--accent);
  -webkit-transform: scale(1.07);
  transform: scale(1.07);
}
/* Badge de nota no canto do pôster. A cor segue o TEMA (`--accent`, reescrito por `applyTheme`) —
   igual ao Android, onde a nota é azul no tema padrão e acompanha a troca de tema (QA do dono). */
.poster-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 2px 7px;
  border-radius: 6px;
  background: rgba(7, 11, 18, 0.82);
  color: var(--accent);
  font-size: 12px;
  font-weight: 800;
}

/* ---- Retomada: barra de progresso no rodapé + dica de remover (só no card focado) ---- */
/* A barra fica no fundo da arte (o `ContinueCard` do Android). O preenchimento é o accent do tema. */
.poster-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 5px;
  background: rgba(0, 0, 0, 0.55);
}
.poster-progress-fill {
  height: 100%;
  background: var(--accent);
}
/* Dica "segure OK p/ remover": escondida, aparece só no card de retomada FOCADO, acima da barra. */
.poster-hint {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 5px;
  padding: 4px 6px;
  background: rgba(7, 11, 18, 0.82);
  color: var(--text-high);
  font-size: 10px;
  line-height: 1.2;
  text-align: center;
}
.poster-continue.is-focused .poster-hint { display: block; }

/* Banner do ZAPPING: mostra o canal de destino enquanto se passa por eles (◀ ▶ / P+ P−). Fica por
   cima do vídeo e some quando a tela remonta no canal escolhido. */
.zap-banner {
  position: absolute;
  top: 40px;
  left: 56px;
  max-width: 640px;
  padding: 10px 18px;
  border-radius: 10px;
  background: rgba(7, 11, 18, 0.86);
  border: 2px solid var(--accent);
  color: var(--text-high);
  font-size: 20px;
  font-weight: 700;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  z-index: 5;
}

/* Faixa SANDBOX — só existe no pacote de teste (env.js com `env: 'sandbox'`). Fica FORA do #root e
   por cima de tudo: nenhuma tela a apaga, e um pacote de teste nunca passa por produção. */
.sandbox-badge {
  position: fixed;
  top: 0;
  right: 0;
  padding: 4px 10px;
  border-bottom-left-radius: 8px;
  background: #b3261e;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.4px;
  z-index: 99;
  pointer-events: none;
}

/* Setas de ZAPPING para o PONTEIRO (Magic Remote da LG). Com o cursor na tela o anel do controle vira
   ponteiro e a seta não chega ao app (medido no aparelho) — clicar é o gesto que sempre funciona.
   Aparecem com o ponteiro e somem com ele; num controle sem ponteiro (Tizen) nunca aparecem. */
.zap-arrow {
  position: absolute;
  top: 50%;
  margin-top: -34px;
  width: 68px;
  height: 68px;
  line-height: 68px;
  text-align: center;
  border-radius: 34px;
  background: rgba(7, 11, 18, 0.62);
  border: 2px solid rgba(255, 255, 255, 0.28);
  color: var(--text-high);
  font-size: 30px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
  z-index: 6;
}
.zap-arrow.is-prev { left: 28px; }
.zap-arrow.is-next { right: 28px; }
.zap-arrow.is-on {
  opacity: 1;
  pointer-events: auto;
}
.zap-arrow.is-on:hover {
  background: var(--accent);
  border-color: var(--accent);
}

/* Barra de BOTÕES do player para o ponteiro: pausar · opções · voltar (o que a linha de dica só
   descrevia). Mesma vida das setas de zapping — aparece com o cursor, some com ele. */
.player-pointer-bar {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
  z-index: 6;
}
.player-pointer-bar.is-on {
  opacity: 1;
  pointer-events: auto;
}
.player-pointer-btn {
  display: flex;
  align-items: center;
  margin: 0 6px; /* sem `gap`: o piso é Chromium 53 */
  padding: 10px 16px;
  border-radius: 26px;
  background: rgba(7, 11, 18, 0.72);
  border: 2px solid rgba(255, 255, 255, 0.28);
  color: var(--text-high);
}
.player-pointer-btn:hover {
  background: var(--accent);
  border-color: var(--accent);
}
.player-pointer-glyph {
  font-size: 18px;
  margin-right: 8px;
}
.player-pointer-label {
  font-size: 17px;
  font-weight: 700;
}
/* Setas ◀▶ clicáveis da folha de opções (a linha selecionada), para quem navega de ponteiro. */
.player-sheet-arrow {
  padding: 0 8px;
  cursor: pointer;
}
.player-sheet-arrow:hover { color: var(--accent); }

/* ---- Grátis (o HUB): cabeçalho + badge AO VIVO no card + iframe do YouTube ao vivo ---- */
.hub-head { padding: 6px 0 14px 0; }
.hub-title { font-size: 26px; font-weight: 800; margin: 0; color: var(--text-high); }
.hub-subtitle { margin-top: 4px; font-size: 15px; color: var(--text-med); }
/* Card institucional AO VIVO (o `LiveCard` do Android): 16:9, arcos de textura, nome centrado. */
.hub-live {
  position: relative;
  flex-shrink: 0;
  width: 230px;
  height: 129px; /* 16:9 */
  margin-right: 16px;
  border-radius: 12px;
  overflow: hidden;
  background: linear-gradient(180deg, var(--surface-2), var(--surface-1));
  border: 3px solid transparent;
  transition: -webkit-transform 0.15s ease;
  transition: transform 0.15s ease;
}
.hub-live.is-focused {
  border-color: var(--accent);
  -webkit-transform: scale(1.05);
  transform: scale(1.05);
}
.hub-live .brand-arcs { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.hub-live-name {
  position: absolute;
  left: 14px;
  right: 14px;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  text-align: center;
  color: var(--text-high);
  font-size: 17px;
  font-weight: 800;
}
.hub-live-genre {
  position: absolute;
  left: 10px;
  bottom: 8px;
  color: var(--text-med);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
}
/* Badge "AO VIVO" no canto superior esquerdo do card. */
.hub-live-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 2px 7px;
  border-radius: 6px;
  background: #d21f2f;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
}
/* ---- Infantil: herói (série em destaque, rotativo) + os trilhos reusam .rail/.poster ---- */
.kids { flex: 1 1 auto; min-height: 0; } /* preenche a altura sob a barra de topo */
.kids-page { height: 100%; overflow: hidden; padding: 8px 0 0; } /* viewport de scroll (scrollTop) */
.kids-hero {
  position: relative;
  height: 320px;
  margin: 0 56px 28px; /* inset horizontal alinhado com as rails */
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface-1);
}
.kids-hero-backdrop {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0; /* `inset` é Chrome 87 — acima do piso e da LG (79) */
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.kids-hero.kids-hero-noimg .kids-hero-backdrop { display: none; }
.kids-hero.kids-hero-noimg {
  background: linear-gradient(120deg, var(--bg-top), var(--accent-dim));
}
.kids-hero::after {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background: linear-gradient(90deg, rgba(7, 11, 18, 0.92) 0%, rgba(7, 11, 18, 0.5) 45%, rgba(7, 11, 18, 0) 100%);
}
.kids-hero-body {
  position: absolute;
  left: 40px;
  bottom: 28px;
  right: 45%;
  z-index: 1;
}
.kids-hero-kicker {
  color: var(--accent-soft);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  margin-bottom: 6px;
}
.kids-hero-title {
  margin: 0 0 10px;
  font-size: 34px;
  font-weight: 800;
  color: var(--text-high);
}
.kids-hero-plot {
  margin: 0;
  font-size: 16px;
  line-height: 1.45;
  color: var(--text-med);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kids-status {
  color: var(--text-med);
  font-size: 18px;
  padding: 40px 4px;
}

/* Placeholder enquanto a seção carrega (shimmer por rail). */
.rail-shimmer {
  width: 156px;
  height: 234px;
  border-radius: 10px;
  background: linear-gradient(100deg, var(--surface-1) 30%, var(--surface-2) 50%, var(--surface-1) 70%);
  background-size: 200% 100%;
  -webkit-animation: shimmer 1.3s linear infinite;
  animation: shimmer 1.3s linear infinite;
}
@-webkit-keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ---- Welcome / Entrar (tela institucional: arcos + logo + opções) ---- */
.welcome {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
}
/* A assinatura de arcos: fundo, atrás de tudo, sem capturar foco. */
.brand-arcs {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.welcome-content {
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 8%;
  text-align: center;
}
.welcome-tagline {
  font-size: 22px;
  color: var(--text-med);
  margin: 22px 0 44px 0;
}
.welcome-options {
  display: flex;
  justify-content: center;
}
/* ---- menu lateral da TV ao vivo (porte do NavDrawer.kt, estilo TiviMate) ---- */
/* Rail de 72px fixo à esquerda; expande p/ 236px POR CIMA do conteúdo enquanto o foco está nele.
   O conteúdo da Live reserva o gutter de 72px (margin-left) e NÃO se move na expansão. */
.nav-drawer {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 30;
  width: 72px;
  display: flex;
  flex-direction: column;
  padding: 18px 0;
  box-sizing: border-box;
  background: var(--bg-deep);
  border-right: 1px solid rgba(255, 255, 255, 0.08);
  transition: width 0.18s ease, background-color 0.18s ease;
  overflow: hidden;
}
.nav-drawer.is-expanded {
  width: 236px;
  background: var(--surface-2);
}
/* Navegação por MOUSE (cursor da LG / Magic Remote): passar por cima EXPANDE o drawer, como o foco
   faz pelo controle. Só CSS `:hover` — sem JS, seguro no piso Chromium 53. */
.nav-drawer:hover {
  width: 236px;
  background: var(--surface-2);
}
.nav-drawer:hover .drawer-label { display: inline; }
.nav-drawer:hover .drawer-item .nav-icon { margin-left: 12px; }
.nav-drawer:hover .drawer-pro { display: inline-flex; }
.drawer-top {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto; /* a lista pode não caber em 540dp — rola, como no Android */
  overflow-x: hidden;
}
.drawer-top::-webkit-scrollbar { display: none; } /* rolagem só por foco — sem barra visível */
.drawer-bottom { flex-shrink: 0; padding-top: 6px; } /* Recarregar/Config fixos no rodapé */
.drawer-top > * + *,
.drawer-bottom > * + * { margin-top: 6px; }
.drawer-item {
  display: flex;
  align-items: center;
  padding: 12px 0;
  margin: 0 6px;
  border-radius: 14px;
  color: var(--text-med);
  white-space: nowrap;
}
.drawer-item .nav-icon { flex-shrink: 0; margin-left: 19px; } /* centraliza no rail de 72 */
.nav-drawer.is-expanded .drawer-item .nav-icon { margin-left: 12px; }
.drawer-item.is-focused {
  background: var(--accent);
  color: var(--bg-deep);
}
.drawer-label {
  display: none;
  margin-left: 16px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-high);
  overflow: hidden;
  text-overflow: ellipsis;
}
.nav-drawer.is-expanded .drawer-label { display: inline; }
.drawer-item.is-focused .drawer-label { color: var(--bg-deep); font-weight: 700; }
/* Escopado com 2 classes p/ vencer o `.pro-badge { display:inline-flex }` (vem depois no cascade). */
.nav-drawer .drawer-pro { display: none; margin-left: 8px; }
.nav-drawer.is-expanded .drawer-pro { display: inline-flex; }
/* A casca da Live com drawer: root relativo + gutter para o rail colapsado. FLEX COLUMN é vital:
   o `.live` dimensiona por `flex: 1` — sem isso a altura fica livre, os painéis nunca estouram e o
   scroll de categorias/canais MORRE (regressão pega no QA da LG, 2026-07-20). */
.live-drawer-shell {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.live-drawer-shell > .live { margin-left: 72px; width: auto; }

/* ---- herói "EM DESTAQUE" da Home (porte do HeroSection; base visual do kids-hero) ---- */
.home-hero {
  position: relative;
  height: 300px;
  margin: 6px 56px 24px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface-1);
  border: 3px solid transparent;
  flex-shrink: 0;
}
.home-hero.is-focused { border-color: var(--accent); }
.home-hero-backdrop {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  transition: opacity 0.45s ease; /* fade-in ao trocar de slide (o crossfade do Android, enxuto) */
}
.home-hero.home-hero-noimg .home-hero-backdrop { display: none; }
/* Scrim HORIZONTAL: escurece a esquerda p/ o texto do herói (o gradiente lateral do Android). */
.home-hero::after {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: 1;
  background: linear-gradient(90deg, rgba(7, 11, 18, 0.92) 0%, rgba(7, 11, 18, 0.55) 45%, rgba(7, 11, 18, 0.05) 100%);
}
.home-hero-body {
  position: absolute;
  left: 36px;
  bottom: 26px;
  right: 42%;
  z-index: 2;
}
.home-hero-badge {
  display: inline-block;
  margin-bottom: 8px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 2px;
  color: var(--accent-soft);
}
.home-hero-title {
  margin: 0 0 8px;
  font-size: 30px;
  font-weight: 800;
  color: var(--text-high);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.home-hero-meta {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent-soft);
}
.home-hero-plot {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-med);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* Dots no fluxo do corpo, abaixo dos botões (o `CarouselDots` do Android, canto inferior esquerdo). */
.home-hero-dots {
  display: flex;
  margin-top: 12px;
  z-index: 2;
}
.home-hero-dots > * + * { margin-left: 6px; }
.home-hero-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.28);
}
.home-hero-dot.is-active { background: var(--accent-soft); }

/* ---- esqueleto do herói (pré-load, estilo Android): reserva o espaço e mostra um placeholder até a
   arte chegar; o conteúdo real preenche NO LUGAR, sem empurrar as rails.
   IMPORTANTE (perf): ESTÁTICO — NÃO animar o elemento de tela cheia (o shimmer de `background-position`
   num elemento de 960×410 repintava todo frame e travava a GPU fraca da TV; o progresso já aparece nas
   rails carregando abaixo). Só uma pulsação de OPACIDADE (composite, barata) nas 2 barrinhas. ---- */
@keyframes skel-pulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.85; }
}
.home-hero.is-loading { background: var(--surface-1); }
/* Enquanto carrega, o conteúdo real fica invisível e só as barras de esqueleto aparecem. */
.home-hero.is-loading .home-hero-backdrop,
.home-hero.is-loading .home-hero-body { visibility: hidden; }
.home-hero:not(.is-loading) .home-hero-skel { display: none; }
.home-hero-skel {
  position: absolute;
  left: 48px;
  z-index: 2;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.09);
  animation: skel-pulse 1.4s infinite ease-in-out;
}
.home-hero-skel-title { bottom: 150px; width: 340px; height: 34px; }
.home-hero-skel-btn { bottom: 40px; width: 150px; height: 46px; border-radius: 24px; }

/* ---- herói de TELA CHEIA (Home completa + trilhos de Filmes/Séries): a barra de topo vira um
   header cinematográfico transparente SOBRE o backdrop, e o herói ocupa a largura toda, ATRÁS dela
   — igual ao Android TV (pedido do dono, 2026-07-20). Só quando o root tem `.screen-hero`. ---- */
/* A barra é sempre overlay nessas telas. SÓLIDA quando NÃO há herói (as rails ganham folga no topo
   p/ não ficar sob ela); TRANSPARENTE (header cinematográfico) quando o herói está no ar (`.has-hero`,
   que o `HeroCarousel` liga ao montar e desliga no colapso do brokenArt). */
.screen-hero > .nav-bar {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 4;
  background: #070b12;
}
.screen-hero.has-hero > .nav-bar {
  background: linear-gradient(to bottom, rgba(7, 11, 18, 0.92) 0%, rgba(7, 11, 18, 0) 100%);
}
.screen-hero > .nav-bar {
  transition: -webkit-transform 0.2s ease;
  transition: transform 0.2s ease;
}
/* Rolou para baixo: a barra SAI de cena (desliza pra cima) — como no Android TV, o menu não fica
   pinado/sólido sobre o conteúdo (pedido do dono). Volta quando o foco sobe até ela: focar a barra
   via CIMA leva o scroll ao topo (`ensureVisible`), `is-scrolled` sai e ela desliza de volta. */
.screen-hero.is-scrolled > .nav-bar {
  -webkit-transform: translateY(-100%);
  transform: translateY(-100%);
  pointer-events: none;
}
.screen-hero [data-scroll='y'] { padding-top: 72px; } /* folga p/ a barra overlay (sem herói) */
.screen-hero.has-hero [data-scroll='y'] { padding-top: 0; } /* com herói, ele ocupa o topo atrás da barra */
.screen-hero .home-hero {
  margin: 0 -56px 24px -56px; /* escapa o padding de 56 das rails → largura de tela cheia */
  width: auto;
  height: 410px;
  border: none;
  border-radius: 0;
}
/* A Infantil hospeda o herói no `.kids-page` (sem o padding de 56 das rails) → não precisa do -56. */
.screen-hero .kids-page > .home-hero { margin-left: 0; margin-right: 0; }
/* Scrim VERTICAL: escurece o topo (legibilidade da barra) e o rodapé (transição p/ as rails). */
.screen-hero .home-hero::before {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: 1;
  background: linear-gradient(to bottom, rgba(7, 11, 18, 0.72) 0%, rgba(7, 11, 18, 0) 24%, rgba(7, 11, 18, 0) 40%, rgba(7, 11, 18, 0.55) 72%, rgba(7, 11, 18, 0.92) 90%, rgba(7, 11, 18, 1) 100%);
}
.screen-hero .home-hero-body { left: 48px; bottom: 34px; right: 40%; }

/* "Ver tudo": TILE no canto inferior direito, maior e com layout próprio (o `SeeAllTile` do Android;
   segue no mesmo container de foco — DIREITA a partir de Detalhes o alcança). */
/* "Ver tudo": PILL HORIZONTAL (o `SeeAllTile` do Android) — mini-grade 30×30 de 4 capas + rótulo AO
   LADO. Fundo translúcido; preenche o accent no foco. NÃO é a caixa grande com label sobreposto. */
.home-hero-seeall {
  position: absolute;
  right: 48px;
  bottom: 40px;
  z-index: 2;
  display: flex;
  align-items: center;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.12);
}
.home-hero-seeall-thumbs {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  margin-right: 10px;
  display: flex;
  flex-wrap: wrap; /* 2×2 — `flex-wrap` em vez de grid/gap (piso 53) */
  border-radius: 5px;
  overflow: hidden;
}
.home-hero-seeall-thumb {
  width: 50%;
  height: 50%;
  object-fit: cover;
  background: var(--surface-2);
}
.home-hero-seeall-label {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-high);
  white-space: nowrap;
}
.home-hero-seeall.is-focused { background: var(--accent); }
.home-hero-seeall.is-focused .home-hero-seeall-label { color: var(--on-accent); }

/* ---- visão de trilhos de Filmes/Séries/Animes (porte do MoviesScreen/SeriesScreen) ---- */
.vodr {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.vodr .rails { flex: 1 1 auto; min-height: 0; }
.vodr-status { padding: 60px 0; text-align: center; color: var(--text-med); font-size: 16px; }
.vodr-hero-btns { display: flex; margin-top: 14px; }
.vodr-hero-btns > * + * { margin-left: 10px; }
.vodr-btn {
  padding: 9px 18px;
  border-radius: 99px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-high);
  background: rgba(255, 255, 255, 0.1);
  border: 2px solid transparent;
  white-space: nowrap;
}
.vodr-btn-primary { background: rgba(255, 255, 255, 0.16); }
.vodr-btn.is-focused { background: var(--accent); color: var(--on-accent); border-color: var(--accent-soft); }

/* ---- Guia de programação (grade TiviMate — porte do EpgGuideScreen) ---- */
.guide {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  padding: 16px 24px 0;
  box-sizing: border-box;
}
.guide-chips {
  display: flex;
  flex-shrink: 0;
  overflow: hidden;
  margin-bottom: 12px;
}
.guide-chips > * + * { margin-left: 8px; }
.guide-chip {
  flex-shrink: 0;
  padding: 8px 16px;
  border-radius: 99px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-med);
  background: var(--surface-1);
  border: 2px solid transparent;
  white-space: nowrap;
}
.guide-chip.is-selected { border-color: var(--accent-dim); color: var(--text-high); }
.guide-chip.is-focused { background: var(--accent); color: var(--on-accent); }
.guide-status { padding: 60px 0; text-align: center; color: var(--text-med); font-size: 16px; }
.guide-grid { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.guide-head { display: flex; height: 30px; flex-shrink: 0; }
.guide-corner { width: 184px; flex-shrink: 0; }
.guide-hours-vp { flex: 1 1 auto; overflow: hidden; position: relative; }
.guide-hours { position: relative; height: 100%; }
.guide-hour { position: absolute; top: 5px; font-size: 12px; color: var(--text-med); }
.guide-viewport { flex: 1 1 auto; min-height: 0; overflow: hidden; }
.guide-line { display: flex; height: 64px; box-sizing: border-box; border-bottom: 1px solid rgba(255, 255, 255, 0.05); }
.guide-name {
  width: 184px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  padding-right: 12px;
  box-sizing: border-box;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-high);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.guide-cells-vp { flex: 1 1 auto; overflow: hidden; position: relative; }
.guide-cells { position: relative; height: 100%; }
.guide-cell {
  position: absolute;
  top: 6px;
  bottom: 6px;
  border-radius: 8px;
  background: var(--surface-1);
  padding: 0 10px;
  box-sizing: border-box;
  overflow: hidden;
  display: flex;
  align-items: center;
}
.guide-cell-title { font-size: 14px; color: var(--text-high); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.guide-cell.is-now { background: rgba(76, 141, 255, 0.2); border: 1px solid var(--accent-dim); }
.guide-cell.is-focused { background: var(--accent); }
.guide-cell.is-focused .guide-cell-title { color: var(--on-accent); font-weight: 700; }
.guide-cell-fill {
  left: 0;
  right: 0;
  width: auto;
  background: transparent;
  border: 1px dashed rgba(255, 255, 255, 0.12);
  color: var(--text-med);
  font-size: 13px;
}
.guide-cell-fill.is-focused { background: var(--accent); color: var(--on-accent); border-color: transparent; }
.guide-detail {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 40;
  background: rgba(4, 7, 12, 0.78);
  display: flex;
  align-items: center;
  justify-content: center;
}
.guide-detail-card {
  width: 520px;
  max-width: 86%;
  background: var(--surface-2);
  border-radius: 14px;
  padding: 26px 30px;
}
.guide-detail-title { margin: 0 0 6px; font-size: 22px; font-weight: 800; color: var(--text-high); }
.guide-detail-time { font-size: 14px; color: var(--accent-soft); margin-bottom: 12px; }
.guide-detail-desc { font-size: 15px; line-height: 1.5; color: var(--text-med); margin: 0 0 20px; max-height: 130px; overflow: hidden; }
.guide-detail-btn {
  display: inline-block;
  padding: 10px 24px;
  border-radius: 99px;
  font-size: 15px;
  font-weight: 700;
  background: var(--accent);
  color: var(--on-accent);
}

/* ---- Multiview (2 canais lado a lado — porte simplificado do MultiviewScreen) ---- */
.multiview {
  position: relative;
  display: flex;
  width: 100%;
  height: 100%;
  background: #000;
}
.mv-status {
  position: absolute;
  top: 44%;
  left: 0;
  right: 0;
  text-align: center;
  color: var(--text-med);
  font-size: 16px;
  z-index: 5;
}
.mv-tile {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  border: 3px solid transparent;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mv-tile.is-focused { border-color: var(--accent); }
.mv-video { width: 100%; height: 100%; object-fit: contain; background: #000; }
.mv-empty {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  color: var(--text-med);
}
.mv-empty-text { margin-top: 10px; font-size: 15px; font-weight: 600; }
.mv-name {
  position: absolute;
  left: 12px;
  bottom: 12px;
  padding: 4px 10px;
  border-radius: 8px;
  background: rgba(4, 7, 12, 0.72);
  color: var(--text-high);
  font-size: 14px;
  font-weight: 600;
  max-width: 70%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.mv-audio-badge {
  position: absolute;
  top: 12px;
  right: 12px;
  padding: 2px 8px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--pro-gold), var(--pro-gold-deep));
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
}
.mv-picker,
.mv-menu {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 40;
  background: rgba(4, 7, 12, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
}
.mv-picker-card {
  width: 640px;
  max-width: 88%;
  height: 420px;
  background: var(--surface-2);
  border-radius: 14px;
  padding: 22px 26px;
  display: flex;
  flex-direction: column;
}
.mv-picker-title { margin: 0 0 14px; font-size: 20px; font-weight: 800; color: var(--text-high); flex-shrink: 0; }
.mv-picker-panes { flex: 1 1 auto; min-height: 0; display: flex; }
.mv-picker-panes > * + * { margin-left: 18px; }
.mv-picker-cats { width: 240px; flex-shrink: 0; overflow-y: auto; overflow-x: hidden; }
.mv-picker-chans { flex: 1 1 auto; min-width: 0; overflow-y: auto; overflow-x: hidden; }
.mv-picker-cats::-webkit-scrollbar,
.mv-picker-chans::-webkit-scrollbar { display: none; }
.mv-picker-row {
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-med);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mv-picker-row.is-selected { color: var(--text-high); }
.mv-picker-row.is-focused { background: var(--accent); color: var(--on-accent); }
.mv-menu-card { width: 320px; background: var(--surface-2); border-radius: 14px; padding: 14px; }
.mv-menu-row {
  padding: 12px 16px;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-high);
}
.mv-menu-row.is-focused { background: var(--accent); color: var(--on-accent); }

/* ---- estados de erro (F5.2) ---- */
/* Rede fora na Home: substitui as rails; OK re-carrega (a dica está no próprio texto). */
.screen-failed {
  padding: 80px 56px;
  text-align: center;
  color: var(--text-med);
  font-size: 16px;
}
/* Boot com sessão salva + painel fora + sem cache: mensagem + botão sobre a base da Welcome. */
.boot-error-msg {
  max-width: 520px;
  margin: 22px 0 28px 0;
  font-size: 18px;
  line-height: 1.5;
  color: var(--text-med);
}
.boot-error-retry {
  padding: 12px 28px;
  border-radius: 99px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text-high);
  background: var(--surface-1);
  border: 2px solid transparent;
}
.boot-error-retry.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}

/* Faixa da cortesia no paywall: o que a pessoa tem hoje e até quando, ACIMA do QR de compra.
   Quem está em teste é quem mais precisa ver como assinar — por isso não vira "recibo". */
.paywall-trial-banner {
  border-radius: 12px;
  background: rgba(214, 178, 92, 0.12);
  padding: 10px 14px;
  margin-bottom: 14px;
}
.paywall-trial-plan {
  font-size: 15px;
  font-weight: 800;
  color: var(--pro-gold, #d6b25c);
}
.paywall-trial-ends {
  font-size: 13px;
  color: var(--text-med);
}

/* Card dos avisos da cortesia de 7 dias: CENTRALIZADO, por cima da tela que está atrás — ver o app
   funcionando é parte da mensagem (sobretudo no "acabou", em que a TV ao vivo segue rodando), por
   isso o véu é leve e não apaga o fundo. Sem `gap` de flex nem `inset` de propósito: um chegou no
   Chrome 84 e o outro no 87, e o piso é 53/56 (ver compat.ts). */
.trial-scrim {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(3, 7, 14, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 40;
}
.trial-card {
  position: relative;
  overflow: hidden; /* recorta os arcos na borda arredondada */
  width: 380px;
  padding: 24px 26px 22px 26px;
  border-radius: 18px;
  background: var(--surface-1);
  border: 1px solid var(--accent-soft);
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.6);
}
.trial-card-content {
  position: relative;
  z-index: 1; /* acima dos arcos, que são fundo */
}
.trial-card-title {
  font-size: 21px;
  font-weight: 800;
  color: var(--text-high);
  margin-top: 12px;
}
.trial-card-body {
  margin-top: 6px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--text-med);
}
.trial-card-actions {
  display: flex;
  flex-direction: row;
  margin-top: 14px;
}
.trial-card-actions > * + * {
  margin-left: 10px;
}
.trial-card-btn {
  padding: 9px 18px;
  border-radius: 99px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-high);
  background: var(--surface-2);
  border: 2px solid transparent;
}
.trial-card-btn.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}

/* Aviso legal (o `welcome_legal_disclaimer` do Android): pequeno, discreto, sob os cartões. */
.welcome-legal {
  max-width: 640px;
  margin-top: 36px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-med);
  opacity: 0.75;
}
.welcome-card {
  width: 360px;
  margin: 0 14px;
  padding: 28px 30px;
  text-align: left;
  border-radius: 14px;
  background: var(--surface-1);
  border: 3px solid transparent;
}
.welcome-card.is-focused {
  border-color: var(--accent);
  background: var(--surface-2);
}
.welcome-card-title { font-size: 24px; font-weight: 700; margin-bottom: 8px; }
.welcome-card-sub { font-size: 16px; color: var(--text-med); line-height: 1.35; }

/* ---- Entrar (institucional: arcos + logo + abas + campos + teclado na tela + botão) ---- */
.login {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
}
.login-content {
  position: relative;
  z-index: 1;
  height: 100%;
  overflow-y: auto; /* rede de segurança; o layout de 2 colunas cabe sem rolar */
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px 4% 16px 4%;
  text-align: center;
}

/* Formulário à esquerda + teclado à direita: com o teclado NA TELA (o IME do sistema não existe no
   piso), a coluna única estourava a altura e ROLAVA — digitar escondia o próprio campo (bug pego na
   TV). Lado a lado, campo e teclado ficam SEMPRE visíveis juntos, sem scroll. */
.login-row {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 100%;
  margin-top: 6px;
}
.login-row > * + * { margin-left: 28px; }
.login-form-col {
  width: 380px;
  flex-shrink: 0;
}
.login-kb-col {
  flex-shrink: 0;
}

/* Abas Xtream | M3U (a Tab do Android, em pílula). */
.login-tabs {
  display: flex;
  justify-content: center;
  margin: 14px 0 4px 0;
}
.login-tab {
  padding: 8px 22px;
  margin: 0 6px;
  border-radius: 22px;
  border: 2px solid transparent;
  color: var(--text-med);
  font-weight: 600;
}
.login-tab.is-selected {
  color: var(--text-high);
  background: var(--surface-2);
}
.login-tab.is-focused {
  border-color: var(--accent);
  color: var(--text-high);
}

.login-subtitle {
  color: var(--text-med);
  font-size: 16px;
  margin: 6px 0 12px 0;
}

/* Campos (só destacam ao navegar; digitar é OK → teclado). Largura = a coluna do formulário. */
.login-fields {
  width: 100%;
}
.login-field {
  position: relative;
  text-align: left;
  padding: 8px 16px;
  margin-bottom: 12px;
  border-radius: 10px;
  border: 2px solid var(--surface-2);
  background: var(--surface-1);
}
.login-field.is-focused {
  border-color: var(--accent);
}
/* Campo ATIVO = o que o teclado edita: contorno vivo + cursor. */
.login-field.is-active {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.login-field-label {
  font-size: 13px;
  color: var(--text-med);
}
.login-field-value {
  min-height: 24px;
  font-size: 18px;
  color: var(--text-high);
  word-break: break-all;
}
.login-field.is-active .login-field-value::after {
  content: '▏';
  color: var(--accent-soft);
}

/* O "mostrar senha" DENTRO do campo, encostado na direita — mas ainda um item de foco próprio (ver
   o comentário em login-view.ts). `position:absolute` sobre a linha da senha, que ganhou
   `position:relative`; a linha reserva `padding-right` para o texto do olho nunca cobrir a senha. */
.login-field-secret { position: relative; padding-right: 160px; }
.login-toggle {
  position: absolute;
  right: 8px;
  top: 50%;
  margin-top: -15px;
  max-width: 148px;
  text-align: right;
  padding: 6px 10px;
  font-size: 13px !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border-radius: 8px;
  border: 2px solid transparent;
  color: var(--text-med);
  font-size: 15px;
}
/* Foco PREENCHIDO, não só contorno: o campo da senha já tem borda de "ativo", e um contorno fino
   sobre uma borda parecida some a 3 metros — foi o que fez o dono achar que o foco nem chegava. */
.login-toggle.is-focused {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
}

.login-status {
  min-height: 22px;
  margin: 4px 0;
  font-size: 15px;
  color: var(--text-med);
}
.login-status.is-error {
  color: var(--error);
}
.login-status.is-loading {
  color: var(--accent-soft);
}

/* Teclado na tela compartilhado (Entrar + Busca): grade de 10 colunas que casa com o FocusEngine.
   Largura FIXA 460 = 10 teclas de caractere (46) = 5 teclas de ação (92); assim o visual bate com
   as `columns: 10` declaradas (senão o cima/baixo desalinha). Encolhido de 680→460 quando o zoom 2
   chegou: no canvas de 960 o teclado precisa dividir a tela com os campos (Entrar) / resultados
   (Busca) SEM rolar — teclado que rola esconde o campo que se está digitando (bug pego na TV). */
.kb-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  width: 460px;
  max-width: 100%;
  margin: 6px auto 0 auto;
}
.kb-key {
  height: 44px;
  margin: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  border: 2px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-size: 17px;
}
.kb-key-char {
  width: 40px;
}
.kb-key-action {
  width: 86px;
  font-size: 13px;
  color: var(--text-med);
}
.kb-key.is-focused {
  border-color: var(--accent);
  background: var(--surface-1);
  color: var(--text-high);
  -webkit-transform: scale(1.06);
  transform: scale(1.06);
}
/* Shift travado. */
.kb-key-shift.is-on {
  background: var(--accent-dim);
  color: var(--text-high);
}

/* Botão Entrar (o Button do Android). */
.login-actions {
  display: flex;
  justify-content: center;
  margin-top: 14px;
}
.login-submit {
  width: 100%;
  padding: 14px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--accent-dim);
  color: var(--text-high);
  font-weight: 700;
  font-size: 18px;
}
.login-submit.is-focused {
  border-color: var(--accent-soft);
  background: var(--accent);
  color: var(--on-accent);
}

.login-hint {
  margin-top: 12px;
  font-size: 13px;
  color: var(--text-med);
}

/* ---- TV ao vivo (3 painéis: categorias · canais · preview + EPG) ---- */
.live {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.live-status { display: none; }
.live-status.is-visible {
  display: block;
  padding: 44px 56px;
  color: var(--text-med);
  font-size: 20px;
}
.live-status.is-error { color: var(--error); }

.live-panes {
  flex: 1 1 auto;
  display: flex;
  overflow: hidden;
}
.live-pane {
  height: 100%;
  overflow: hidden;
  padding: 20px 0;
  display: flex;
  flex-direction: column;
}
.pane-title {
  flex-shrink: 0;
  padding: 0 22px 10px 22px;
  font-size: 13px;
  letter-spacing: 1px;
  color: var(--text-med);
}

/* Painel 1 — categorias. */
.live-cats-pane {
  width: 300px;
  flex-shrink: 0;
  background: var(--surface-1);
}
.live-cats { overflow: hidden; padding: 0 10px; }
.live-cat {
  padding: 12px 16px;
  margin: 2px 0;
  border-radius: 8px;
  border: 2px solid transparent;
  color: var(--text-high);
}
.live-cat.is-selected {
  color: var(--accent);
  background: var(--surface-2);
  font-weight: 600;
}
.live-cat.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

/* Painel 2 — canais. */
/* `flex-basis: 0` (não `auto`): com o zoom, os nomes de canal 2× maiores inflavam a base "auto" (=
   largura do conteúdo) e espremiam o preview p/ ~15% (era 40%). Com base 0, canais e preview dividem
   o espaço restante pela razão de grow (1 : 1.35), como no Android. */
.live-channels-pane { flex: 1 1 0; min-width: 0; }
.live-channels { overflow: hidden; padding: 0 10px; }
.live-channel {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  margin: 2px 0;
  border-radius: 8px;
  border: 2px solid transparent;
}
.live-channel.is-focused {
  background: var(--surface-2);
  border-color: var(--accent);
}
.live-thumb {
  position: relative;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  margin-right: 12px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface-1);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  font-size: 14px;
  font-weight: 700;
}
.live-thumb img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.live-channel-name {
  color: var(--text-high);
  font-size: 17px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live-empty {
  padding: 16px 12px;
  color: var(--text-med);
  line-height: 1.4;
}

/* Painel 3 — preview (mini 16:9, placeholder até a F3) + grade.
   `> * { flex-shrink: 0 }`: o painel é flex-column e, quando o conteúdo excede a altura, o flexbox
   esmagava o nome/botão/grade a ~0px (o "nome some" que o Bruno pegou na TV) — a mesma classe de bug
   do login. Com os filhos protegidos, quem cede é SÓ a lista de EPG (flex + min-height 0): ela mostra
   quantas linhas couberem, cortando por LINHA inteira, nunca esmagando os vizinhos. */
.live-preview {
  flex: 1.35 1 0;
  min-width: 0;
  padding: 20px 24px;
}
.live-preview > * { flex-shrink: 0; }
.live-preview .live-epg {
  flex: 1 1 auto;
  min-height: 0;
}
.live-mini {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 sem aspect-ratio (piso Chromium 53) */
  border-radius: 12px;
  background: #000;
  margin-bottom: 16px;
}
.live-mini-caption {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-med);
  font-size: 14px;
}
.live-preview-name {
  font-size: 24px;
  font-weight: 700;
  color: var(--text-high);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live-preview-hint {
  margin: 4px 0 14px 0;
  font-size: 14px;
  color: var(--accent);
}
/* Botão ★ Favoritar do canal focado (alcançado com DIREITA a partir dos canais). */
.live-fav {
  display: inline-flex;
  align-items: center;
  margin-bottom: 18px;
  padding: 10px 18px;
  border-radius: 10px;
  border: 2px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-weight: 600;
}
.live-fav-star { margin-right: 8px; color: var(--accent); }
.live-fav.is-fav-on { background: var(--accent-dim); }
.live-fav.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}
.live-fav.is-focused .live-fav-star { color: var(--on-accent); }
.live-epg { overflow: hidden; }
.live-epg-row {
  display: flex;
  align-items: center;
  padding: 6px 0;
}
.live-epg-time {
  width: 60px;
  flex-shrink: 0;
  color: var(--text-med);
  font-size: 15px;
}
.live-epg-name {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-med);
  font-size: 15px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live-epg-row.is-now .live-epg-time,
.live-epg-row.is-now .live-epg-name {
  color: var(--text-high);
  font-weight: 600;
}
.live-epg-badge {
  flex-shrink: 0;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 4px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 700;
}
.live-epg-empty {
  color: var(--text-med);
  font-size: 15px;
}
.live-epg-shimmer {
  height: 60px;
  border-radius: 8px;
  background: linear-gradient(100deg, var(--surface-1) 30%, var(--surface-2) 50%, var(--surface-1) 70%);
  background-size: 200% 100%;
  -webkit-animation: shimmer 1.3s linear infinite;
  animation: shimmer 1.3s linear infinite;
}

/* ---- VOD "ver por categoria" (seletor + grade de pôsteres) ---- */
.vod {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.vod-panes {
  flex: 1 1 auto;
  display: flex;
  overflow: hidden;
}
.vod-grid-pane {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  padding: 20px 0;
  display: flex;
  flex-direction: column;
}
/* Cabeçalho da grade: título+contador à ESQUERDA, botão de ordenar à DIREITA (pedido do dono).
   Alinhado à largura da grade (650) p/ o botão casar a coluna direita dos pôsteres. */
.vod-grid-head {
  flex-shrink: 0;
  width: 650px;
  max-width: 100%;
  margin: 0 auto;
  /* Recuo à direita (16) põe o botão UM POUCO ANTES da borda do último card (a célula tem 6 de
     margem); o 6 à esquerda alinha o título com a borda visual do 1º pôster. */
  padding: 0 16px 10px 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.vod-grid-head .pane-title {
  padding: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vod-sort-btn {
  flex-shrink: 0;
  margin-left: 12px;
  padding: 7px 14px;
  border-radius: 8px;
  border: 2px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}
.vod-sort-btn.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}
/* Menu de ordenação: overlay ancorado no canto superior direito do painel (`.vod` é relative). */
.vod-sort-menu {
  position: absolute;
  top: 58px;
  right: 20px;
  z-index: 50;
  min-width: 190px;
  padding: 8px;
  border-radius: 12px;
  background: var(--surface-1);
  border: 1px solid var(--surface-2);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.55);
}
.vod-sort-menu-title {
  padding: 4px 12px 8px 12px;
  font-size: 12px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-med);
}
.vod-sort-row {
  padding: 11px 14px;
  margin: 2px 0;
  border-radius: 8px;
  border: 2px solid transparent;
  color: var(--text-high);
  font-size: 14px;
  white-space: nowrap;
}
.vod-sort-row.is-selected {
  color: var(--accent);
  font-weight: 700;
}
.vod-sort-row.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
  font-weight: 700;
}
/* Largura FIXA = exatamente 5 colunas: o layout visual TEM de casar com as `columns: 5` declaradas no
   FocusEngine, ou o cima/baixo da grade desalinha. O painel da grade é ~660 (960 − sidebar 300), então
   o pôster encolhe p/ 118 (+12 de margem = 130 × 5 = 650) — antes eram 156 e só cabiam 3 (o "3 de 3"
   do QA), com o foco esperando 5. Igual ao Android (grade de 5, pôster ~120dp). */
.vod-grid {
  width: 650px;
  max-width: 100%;
  margin: 0 auto;
  padding: 4px 0 20px 0;
  overflow: hidden;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
}
/* A célula é o item da grade (espaçamento nela); encolhe p/ caber 5 colunas (130 × 5 = 650). */
.vod-grid .poster-cell {
  width: 118px;
  margin: 6px;
  margin-bottom: 14px;
}
.vod-grid .poster {
  height: 177px;
  margin: 0;
}

/* ---- Detalhe de filme (backdrop + scrim + pôster + corpo) ---- */
.detail {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
}
/* ⛔ TELA CHEIA e SEM RECORTE (2026-10-02). Era `height: 62%` + `object-fit: cover`: a imagem terminava a 62% da
   altura com o scrim ainda a ~85% ali (um DEGRAU horizontal atravessando a tela) e o `cover` cortava a arte. O
   painel manda backdrop 16:9 (1280×720 em 14 de 14 amostrados), então numa tela 16:9 o `contain` cobre a mesma
   área — e, quando a arte foge da proporção, mostra tudo em vez de cortar. É o tratamento da Roku (`scaleToFit`)
   e o que o Android TV recebeu em 2026-09-03; aqui esperou a revisão da Samsung voltar (decisão do dono). */
.detail-backdrop {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 100%;
  overflow: hidden;
}
.detail-backdrop-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0.5;
}
/* O backdrop desce para o fundo do catálogo, deixando o texto legível. */
.detail-scrim {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(180deg, rgba(7, 11, 18, 0.3) 0%, rgba(7, 11, 18, 0.75) 45%, var(--bg-deep) 85%);
}
.detail-content {
  position: relative;
  z-index: 1;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: flex-end;
  padding: 0 56px 46px 56px;
}
.detail-poster {
  position: relative;
  width: 200px;
  height: 300px;
  flex-shrink: 0;
  margin-right: 32px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--surface-2);
  /* Destaca o pôster como CARTÃO sobre o backdrop (senão some no fundo — achado do QA). */
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.55);
}
.detail-poster-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.detail-poster.poster-fallback {
  background: linear-gradient(135deg, var(--surface-2), var(--accent-dim));
}
.detail-poster.poster-fallback .detail-poster-img {
  display: none;
}
.detail-body {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 820px;
}
.detail-title {
  margin: 0 0 10px 0;
  font-size: 40px;
  font-weight: 800;
  color: var(--text-high);
}
.detail-meta {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
  color: var(--text-med);
  font-size: 16px;
}
.detail-rating {
  margin-left: 14px;
  color: var(--pro-gold);
  font-weight: 700;
}
.detail-plot {
  max-width: 760px;
  margin-bottom: 16px;
  color: var(--text-high);
  font-size: 17px;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 4; /* piso Chromium 53 já suporta */
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.detail-people {
  margin-bottom: 22px;
  color: var(--text-med);
  font-size: 14px;
}
.detail-actions { display: flex; align-items: center; }
.detail-actions > * + * { margin-left: 16px; } /* separa o Voltar do botão Assistir */
.detail-watch .pro-badge { margin-left: 10px; } /* o selo Pro DENTRO do Assistir, colado ao rótulo */
.detail-watch {
  display: inline-flex;
  align-items: center;
  padding: 12px 28px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--accent-dim);
  color: var(--text-high);
  font-weight: 700;
  font-size: 18px;
}
.detail-watch-icon { margin-right: 10px; }
.detail-watch.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}
.detail-pro-note {
  margin-top: 14px;
  max-width: 620px;
  color: var(--pro-gold); /* dourado, igual ao aviso de Pro do Android (QA) */
  font-size: 13px;
}
/* Crédito do título grátis (fonte + licença), no detalhe do HUB. Discreto de propósito: informação
   legal obrigatória, não chamada de atenção — mesma hierarquia do `labelMedium` do Android. */
.detail-credit {
  margin-top: 14px;
  max-width: 620px;
  color: var(--text-med);
  font-size: 13px;
}
/* Título original, quando difere do exibido (só em pt). */
.detail-original-title {
  margin-top: -4px;
  color: var(--text-med);
  font-size: 18px;
}
/* Botão "‹ Voltar" nos detalhes (paridade com o Android): secundário/outline. No filme fica ao lado
   do Assistir (.detail-actions); na série, na coluna esquerda sob o elenco. */
.detail-back {
  display: inline-flex;
  align-items: center;
  padding: 12px 24px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: rgba(255, 255, 255, 0.1);
  color: var(--text-high);
  font-weight: 700;
  font-size: 16px;
}
.series-body .detail-back { margin-top: 6px; }
.detail-back.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}

/* ---- Busca (teclado à esquerda + resultados em rails à direita) ---- */
.search {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
  display: flex;
}
.search-left {
  width: 446px; /* 400 do teclado compacto + os paddings — a MAIOR parte da tela é dos resultados */
  flex-shrink: 0;
  padding: 24px 16px 16px 30px;
  display: flex;
  flex-direction: column;
}
/* Na Busca o teclado é COMPACTO (400 = 10×40 char = 5×80 ação): ele é coadjuvante — o protagonista
   é o resultado (feedback do dono: o teclado tomava mais espaço que os resultados). */
.search .kb-grid { width: 400px; }
.search .kb-key { height: 40px; margin: 2px; font-size: 15px; }
.search .kb-key-char { width: 36px; }
.search .kb-key-action { width: 76px; font-size: 12px; }
.search-field {
  display: flex;
  align-items: center;
  margin-bottom: 14px;
  padding: 12px 18px;
  border-radius: 10px;
  background: var(--surface-1);
  border: 2px solid var(--surface-2);
}
.search-field-icon {
  margin-right: 12px;
  font-size: 22px;
  color: var(--text-med);
}
.search-field-text {
  font-size: 20px;
  color: var(--text-high);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.search-field-text.is-placeholder { color: var(--text-med); }
/* cursor de digitação (o campo não é focável; a query é sempre o alvo do teclado) */
.search-field-text::after {
  content: '▏';
  color: var(--accent-soft);
}
.search-field-text.is-placeholder::after { content: ''; }

.search-results {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  padding: 24px 40px 0 24px;
}
.search-message {
  padding: 24px 0;
  color: var(--text-med);
  font-size: 17px;
  line-height: 1.4;
}

/* ---- Detalhe de série (cabeçalho à esquerda + temporadas/episódios à direita) ---- */
.series-content {
  position: relative;
  z-index: 1;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  padding: 0 48px 40px 56px;
}
.series-body {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 720px;
  padding-right: 32px;
}
/* na série a sinopse pode ser mais longa que a do filme */
.series-body .detail-plot {
  -webkit-line-clamp: 5;
  max-width: 680px;
}
.series-episodes {
  width: 480px;
  flex-shrink: 0;
  height: 80%;
  display: flex;
  flex-direction: column;
}
.series-episodes-title {
  flex-shrink: 0;
  margin-bottom: 12px;
  font-size: 22px;
  font-weight: 700;
  color: var(--text-high);
}
.series-seasons {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
}
.series-season-chip {
  padding: 8px 18px;
  margin: 0 8px 10px 0;
  border-radius: 20px;
  border: 2px solid transparent;
  background: var(--surface-1);
  color: var(--text-med);
  font-size: 15px;
}
.series-season-chip.is-selected {
  background: var(--surface-2);
  color: var(--text-high);
  font-weight: 600;
}
.series-season-chip.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
  font-weight: 600;
}
.series-episode-list {
  flex: 1 1 auto;
  overflow: hidden;
}
.series-episode {
  display: flex;
  align-items: center;
  padding: 12px 14px;
  margin-bottom: 8px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-2);
}
.series-episode.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
}
.series-episode-num {
  width: 32px;
  flex-shrink: 0;
  color: var(--accent);
  font-weight: 700;
  font-size: 16px;
}
.series-episode-title {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-high);
  font-size: 16px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.series-episode.is-focused .series-episode-num,
.series-episode.is-focused .series-episode-title {
  color: var(--on-accent);
}
/* A barrinha do episódio (docs/product/fim-do-video-e-proximo-episodio.md, regra 3): pela metade = barra de
   acento + "Restante: N min"; assistido = barra cheia e APAGADA + "✓ Assistido" (sem a palavra, "assisti" e
   "parei no último minuto" seriam a mesma barra). Sem andamento, nada aparece. */
.series-episode-main {
  flex: 1 1 auto;
  min-width: 0;
}
.series-episode-main .series-episode-title {
  display: block;
}
.series-episode-bar {
  display: none;
  position: relative;
  height: 4px;
  margin-top: 6px;
  border-radius: 99px;
  background: rgba(147, 163, 184, 0.3);
}
.series-episode.has-progress .series-episode-bar {
  display: block;
}
.series-episode-bar-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 4px;
  width: 0;
  border-radius: 99px;
  background: var(--accent);
}
.series-episode.is-watched .series-episode-bar-fill {
  background: var(--text-med);
  opacity: 0.55;
}
.series-episode-state {
  flex-shrink: 0;
  margin-left: 12px;
  color: var(--text-med);
  font-size: 13px;
  white-space: nowrap;
}
/* Na linha focada o fundo é o acento: a barra de acento sumiria nele, então as cores INVERTEM (a lição da TV
   Android, SeriesDetailScreen.kt). */
.series-episode.is-focused .series-episode-bar {
  background: rgba(0, 0, 0, 0.25);
}
.series-episode.is-focused .series-episode-bar-fill,
.series-episode.is-focused.is-watched .series-episode-bar-fill {
  background: var(--on-accent);
  opacity: 1;
}
.series-episode.is-focused .series-episode-state {
  color: var(--on-accent);
}
.series-episode-empty {
  padding: 20px 2px;
  color: var(--text-med);
  font-size: 16px;
}
.series-episode-skeleton {
  height: 46px;
  margin-bottom: 8px;
  border-radius: 10px;
  background: linear-gradient(100deg, var(--surface-1) 30%, var(--surface-2) 50%, var(--surface-1) 70%);
  background-size: 200% 100%;
  -webkit-animation: shimmer 1.3s linear infinite;
  animation: shimmer 1.3s linear infinite;
}

/* ---- Configurações (página rolável de cartões) ---- */
.settings {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
}
.settings-page {
  position: relative;
  z-index: 1;
  height: 100%;
  overflow-y: auto;
  padding: 30px 64px 40px 64px;
}
.settings-title {
  margin: 0 0 4px 0;
  font-size: 30px;
  font-weight: 800;
  color: var(--text-high);
}
/* Dica "↩ para retornar" abaixo do título (paridade com o Android). */
.settings-hint {
  margin: 0 0 18px 0;
  color: var(--text-med);
  font-size: 15px;
}
.settings-card {
  max-width: 820px;
  margin-bottom: 14px;
  padding: 20px;
  border-radius: 14px;
  border: 2px solid transparent;
  background: var(--surface-1);
}
.settings-card.is-focused {
  border-color: var(--accent);
  background: var(--surface-2);
}
.settings-card-title {
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--accent);
}
.settings-row {
  display: flex;
  padding: 6px 0;
}
.settings-row-label {
  width: 200px;
  flex-shrink: 0;
  color: var(--text-med);
  font-size: 16px;
}
.settings-row-value {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-high);
  font-size: 16px;
  font-weight: 500;
  word-break: break-all;
}
.settings-note {
  color: var(--text-med);
  font-size: 15px;
  line-height: 1.5;
}
/* Preferência liga/desliga (focável — OK alterna). */
.settings-toggle {
  display: flex;
  align-items: center;
  padding: 12px 14px;
  margin: 4px -14px;
  border-radius: 10px;
  border: 3px solid transparent;
}
.settings-toggle-label {
  flex: 1 1 auto;
  color: var(--text-high);
  font-size: 16px;
  font-weight: 500;
}
/* Rótulo + subtítulo empilhados (ex.: "Modo infantil" + o que ele faz). */
.settings-toggle-text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}
.settings-toggle-text > * + * { margin-top: 2px; }
.settings-toggle-text .settings-toggle-label { flex: 0 0 auto; }
.settings-toggle-sub {
  color: var(--text-med);
  font-size: 13px;
  font-weight: 400;
}
.settings-toggle.is-focused .settings-toggle-sub { color: var(--on-accent); }
.settings-toggle-value {
  flex-shrink: 0;
  padding: 3px 12px;
  border-radius: 99px;
  background: var(--surface-2);
  color: var(--text-med);
  font-size: 14px;
  font-weight: 700;
}
.settings-toggle.is-on .settings-toggle-value {
  background: var(--accent-dim);
  color: var(--text-high);
}
.settings-toggle.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
}
.settings-toggle.is-focused .settings-toggle-label { color: var(--on-accent); }
.settings-toggle.is-focused .settings-toggle-value {
  background: var(--on-accent);
  color: var(--text-high);
}
.settings-toggle.is-disabled .settings-toggle-label { color: var(--text-med); }
/* Desabilitado E focado (ex.: "Remover PIN" sem PIN): o texto TAMBÉM escurece sobre o accent aceso —
   senão a regra is-disabled (cinza, acima) vencia a is-focused e o rótulo sumia (achado do dono). */
.settings-toggle.is-disabled.is-focused .settings-toggle-label { color: var(--on-accent); }

/* Seletor de tema — uma linha por preset (bolinha da cor · rótulo · ● no ativo · selo PRO). */
.settings-theme-row {
  display: flex;
  align-items: center;
  padding: 11px 14px;
  margin: 4px -14px;
  border-radius: 10px;
  border: 3px solid transparent;
}
.settings-theme-dot {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  margin-right: 12px;
  box-shadow: 0 0 0 2px var(--surface-2); /* anel p/ a bolinha escura não sumir no fundo */
}
.settings-theme-label {
  flex: 1 1 auto;
  color: var(--text-high);
  font-size: 16px;
  font-weight: 500;
}
.settings-theme-pro {
  flex-shrink: 0;
  padding: 2px 8px;
  border-radius: 5px;
  background: var(--pro-gold); /* ouro Pro — nunca lê como foco */
  color: #2a1a06;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.5px;
}
.settings-theme-row.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
}
.settings-theme-row.is-focused .settings-theme-label { color: var(--on-accent); }
.settings-theme-row.is-focused .settings-theme-dot { box-shadow: 0 0 0 2px var(--on-accent); }

/* ---- PinPad (controle parental) — overlay modal, numpad de D-pad ---- */
/* Fundo do portão de PIN (a trava infantil) — o PinPad cobre por cima com seu overlay escuro. */
.pin-gate {
  position: relative;
  height: 100%;
}

/* O popup de saída da tela-raiz (`exit-confirm.ts`): a Return Key Policy da Samsung exige confirmar antes de
   encerrar. Mesmo molde do PinPad (overlay escuro + cartão); sem `inset` (Chrome 87, acima do piso). */
.exit-confirm {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(5, 8, 14, 0.86);
}
.exit-confirm-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 34px 44px;
  border-radius: 18px;
  background: var(--surface-1);
}
.exit-confirm-title {
  font-size: 24px;
  font-weight: 700;
  color: var(--text-high);
}
.exit-confirm-buttons {
  display: flex;
  margin-top: 26px;
}
.exit-confirm-buttons > * + * { margin-left: 14px; }
.exit-confirm-button {
  min-width: 140px;
  padding: 12px 26px;
  border-radius: 12px;
  border: 2px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-size: 17px;
  font-weight: 700;
  text-align: center;
}
.exit-confirm-button.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
  color: var(--on-accent);
}
.pinpad {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(5, 8, 14, 0.86);
}
.pinpad-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 34px 40px;
  border-radius: 18px;
  background: var(--surface-1);
}
.pinpad-lock { font-size: 32px; }
.pinpad-title {
  margin-top: 8px;
  font-size: 22px;
  font-weight: 700;
  color: var(--text-high);
}
.pinpad-subtitle {
  margin-top: 4px;
  font-size: 14px;
  color: var(--text-med);
}
.pinpad-dots {
  display: flex;
  margin: 20px 0 6px 0;
}
.pinpad-dot {
  width: 16px;
  height: 16px;
  margin: 0 7px;
  border-radius: 50%;
  background: var(--surface-2);
}
.pinpad-dot.is-filled { background: var(--accent); }
.pinpad-dot.is-error { background: var(--error); }
.pinpad-error {
  min-height: 20px;
  color: var(--error);
  font-size: 14px;
}
.pinpad-grid {
  display: flex;
  flex-wrap: wrap;
  width: 252px; /* casa com columns:3 — cada tecla ocupa 70+12=82px, 3 por linha = 246–328px */
  margin-top: 10px;
}
.pinpad-key {
  width: 70px;
  height: 70px;
  margin: 6px;
  border-radius: 14px;
  border: 3px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-size: 26px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pinpad-key.is-action {
  font-size: 22px;
  color: var(--text-med);
}
.pinpad-key.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}

/* ---- cartão-ação das Configurações (navega para outra tela) ---- */
.settings-action-card { border: 3px solid transparent; }
.settings-action {
  display: flex;
  align-items: center;
}
.settings-action-label {
  flex: 1 1 auto;
  color: var(--text-high);
  font-size: 16px;
  font-weight: 600;
}
.settings-action-chevron {
  color: var(--accent);
  font-size: 22px;
  font-weight: 700;
}
.settings-action-card.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
}
.settings-action-card.is-focused .settings-action-label,
.settings-action-card.is-focused .settings-action-chevron,
.settings-action-card.is-focused .settings-card-title { color: var(--on-accent); }
/* O subtítulo (`.settings-note`) também escurece no foco — senão fica ilegível (text-med claro)
   sobre o fundo accent aceso, como no cartão "Minhas listas" (achado do dono na TV, 2026-07-23). */
.settings-action-card.is-focused .settings-note { color: var(--on-accent); }

/* ---- Organizar canais (B4) ---- */
.organize {
  flex: 1 1 auto;
  overflow: hidden;
  padding: 28px 56px 0 56px;
  display: flex;
  flex-direction: column;
}
.organize-title {
  font-size: 30px;
  font-weight: 800;
  margin: 0;
}
.organize-hint {
  margin: 6px 0 18px 0;
  color: var(--text-med);
  font-size: 15px;
}
.organize-status {
  color: var(--text-med);
  font-size: 16px;
  padding: 20px 0;
}
.organize-list {
  flex: 1 1 auto;
  overflow: hidden;
  max-width: 720px;
}
.organize-row {
  display: flex;
  align-items: center;
  padding: 13px 16px;
  margin-bottom: 6px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-1);
}
.organize-dot {
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  margin-right: 14px;
  border-radius: 50%;
  background: var(--accent);
}
.organize-row.is-cat-hidden .organize-dot { background: rgba(147, 163, 184, 0.4); }
.organize-name {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-high);
  font-size: 17px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.organize-row.is-cat-hidden .organize-name { color: var(--text-med); }
.organize-state {
  flex-shrink: 0;
  margin-left: 14px;
  color: var(--accent);
  font-size: 14px;
  font-weight: 700;
}
.organize-row.is-cat-hidden .organize-state { color: var(--text-med); }
.organize-row.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
}
.organize-row.is-focused .organize-name,
.organize-row.is-focused .organize-state { color: var(--on-accent); }
.organize-row.is-focused .organize-dot { background: var(--on-accent); }
.settings-actions {
  margin-top: 8px;
}
.settings-signout {
  display: inline-block;
  padding: 12px 30px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-2);
  color: var(--error);
  font-weight: 700;
  font-size: 17px;
}
.settings-signout.is-focused {
  background: var(--error);
  color: var(--bg-deep);
  border-color: var(--error);
}

/* ---- cartão da conta Antena Play (F4: device-code + Pro) ---- */
.settings-account-status {
  color: var(--text-med);
  font-size: 15px;
  line-height: 1.4;
  margin-bottom: 12px;
}
.settings-account-status.is-pro { color: var(--pro-gold); font-weight: 700; } /* dourado, como o Android */
.settings-account-action {
  display: inline-block;
  margin-right: 10px; /* respira quando "Ver benefícios" e "Sair da conta" ficam lado a lado */
  padding: 10px 26px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-weight: 700;
  font-size: 16px;
}
/* Ação primária ("Ver benefícios"): azul cheio como o botão do Android, mesmo sem foco. */
.settings-account-action.is-primary {
  background: var(--accent);
  color: var(--on-accent);
}
.settings-account-action.is-focused {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent-soft);
}

/* ---- tela "Entrar" da conta (device-code + QR, F4) ---- */
.activation { position: relative; height: 100%; overflow: hidden; }
.activation-content {
  position: relative;
  z-index: 1;
  height: 100%;
  box-sizing: border-box;
  padding: 44px 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Sem isto o conteúdo grudava no TOPO e sobrava um terço morto embaixo (medido na LG: o bloco
     terminava em 401 de 540). Numa tela de 10 pés isso lê como layout quebrado. */
  justify-content: center;
}
.activation-title {
  font-size: 30px;
  font-weight: 800;
  color: var(--text-high);
  margin: 18px 0 22px;
}
.activation-body { width: 100%; max-width: 900px; }
.activation-status { text-align: center; color: var(--text-med); font-size: 20px; padding: 40px 0; }
.activation-status.is-error { color: var(--error); }
.activation-await { display: flex; align-items: center; justify-content: center; }
.activation-await > * + * { margin-left: 48px; }
.activation-qr { flex-shrink: 0; padding: 14px; background: #fff; border-radius: 14px; }
.qr-canvas { display: block; }
.activation-info { max-width: 420px; }
.activation-instruction { color: var(--text-med); font-size: 18px; line-height: 1.5; margin-bottom: 16px; }
.activation-url { color: var(--text-high); font-size: 20px; font-weight: 700; margin-bottom: 20px; }
.activation-code-label { color: var(--text-med); font-size: 14px; text-transform: uppercase; letter-spacing: 1px; }
/* O código é para ser LIDO e DIGITADO no celular. Com 44px e 4px de tracking ele estourava a coluna e
   os dois grupos pareciam texto quebrado (QA do dono na LG); some com o espaço do meio e o usuário
   ainda tenta digitá-lo. Agora vem numa caixa própria, com tracking suficiente para separar os
   caracteres e nada além disso. */
.activation-code {
  display: inline-block;
  margin-top: 6px;
  padding: 8px 16px;
  border-radius: 12px;
  background: var(--surface-1);
  color: var(--accent);
  font-size: 38px;
  font-weight: 800;
  letter-spacing: 3px;
}
.activation-title-sm { font-size: 22px; font-weight: 700; color: var(--text-high); text-align: center; margin-bottom: 8px; }
/* 5 aparelhos (~310px) estouravam a TELA e o `max-height: 320` não rolava (cabiam nele, sem overflow
   INTERNO — só a tela cortava). 240 força a rolagem DENTRO da lista e ainda cabe na viewport: o foco
   (`data-scroll`) e a roda do Magic Remote (`armPointerScroll`) arrastam o item à vista (o "SM-S918B
   cortado" do QA do dono). */
.activation-devices { margin-top: 16px; max-height: 240px; overflow-y: auto; }
.activation-device {
  display: flex;
  align-items: center;
  padding: 14px 18px;
  margin: 6px 0;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-1);
}
.activation-device.is-focused { background: var(--accent); border-color: var(--accent-soft); }
.activation-device-name { flex: 1 1 auto; color: var(--text-high); font-size: 17px; }
.activation-device.is-focused .activation-device-name { color: var(--on-accent); }
.activation-device-action { color: var(--accent); font-weight: 700; }
.activation-device.is-focused .activation-device-action { color: var(--on-accent); }
.activation-retry {
  display: inline-block;
  margin-top: 20px;
  padding: 12px 30px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-weight: 700;
  font-size: 17px;
}
.activation-retry.is-focused { background: var(--accent); color: var(--on-accent); border-color: var(--accent-soft); }

/* ---- paywall (F4: venda pelo site via QR do webLoginLink) ---- */
.paywall { position: relative; height: 100%; overflow: hidden; }
.paywall-content {
  position: relative;
  z-index: 1;
  height: 100%;
  box-sizing: border-box;
  padding: 34px 64px;
  display: flex;
  flex-direction: column;
}
.paywall-head { display: flex; align-items: center; }
.paywall-head > * + * { margin-left: 14px; }
.paywall-pill {
  padding: 2px 10px;
  border-radius: 6px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 1px;
}
.paywall-headline { margin: 14px 0 6px; font-size: 32px; font-weight: 800; color: var(--text-high); }
.paywall-sub { color: var(--text-med); font-size: 18px; margin-bottom: 18px; }
/* O `overflow: hidden` aqui existia para a LISTA de benefícios não estourar a tela — mas ele cortava
   também a NOTA do QR, que passa uns 15px do quadro (medido na LG: a coluna acaba em 446 e a nota
   terminaria em ~461, com 60px LIVRES logo abaixo). O corte agora é só da lista, que já rola sozinha
   (`.paywall-benefits` tem `overflow-y: auto`); a coluna do QR usa o espaço que sobra. */
.paywall-columns { flex: 1 1 auto; display: flex; overflow: visible; min-height: 0; }
.paywall-columns > * + * { margin-left: 40px; }
/* `overflow-y: auto` é rede de segurança: 9 itens compactos cabem, mas es-419 (rótulos ~20% maiores)
   pode quebrar linha e estourar — aí rola em vez de CORTAR o último (achado do QA do dono). */
.paywall-benefits { flex: 1 1 auto; min-height: 0; max-height: 100%; margin: 0; padding: 0; list-style: none; overflow-y: auto; }
/* Benefício = ✓ DOURADO num círculo gold-suave + rótulo (o `Benefit` do Android; antes era um ✓
   azul cru à esquerda). O círculo é o `::before` como item flex (line-height centra o ✓). */
.paywall-benefit {
  display: flex;
  align-items: center;
  padding: 4px 0;
  color: var(--text-high);
  font-size: 16px;
}
.paywall-benefit::before {
  content: '✓';
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  margin-right: 12px;
  border-radius: 50%;
  background: rgba(233, 199, 126, 0.16); /* --pro-gold #e9c77e a 0.16 = o ProGold.copy(alpha=0.16) do Android */
  color: var(--pro-gold);
  font-weight: 800;
  font-size: 13px;
  line-height: 22px;
  text-align: center;
}
.paywall-right { width: 440px; flex-shrink: 0; }
.paywall-right-title { font-size: 20px; font-weight: 700; color: var(--text-high); margin-bottom: 12px; }
.paywall-status { color: var(--text-med); font-size: 17px; margin-bottom: 14px; }
/* O `qrcode-generator` escolhe o tamanho do canvas pelo TAMANHO DO DADO (medido na LG: 159px num
   quadro de 176 útil), então ele NUNCA preenche a caixa — sem centrar, o QR encosta no canto e sobra
   uma faixa branca em L (o "não alinha com o fundo branco" do QA do dono). Centrar resolve sem
   escalar o canvas, que borraria os módulos e é o que faz leitor de celular falhar. */
.paywall-qr {
  width: 184px;
  height: 184px;
  padding: 10px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border-radius: 12px;
}
.paywall-qr.is-placeholder {
  background: var(--surface-1);
  color: var(--text-med);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 14px;
}
/* A nota vinha CORTADA na TV (o `.paywall-columns` tem `overflow: hidden` e a coluna estourava por
   poucos px): título + QR de 200 + duas linhas de 15/1.45 não cabiam nos 280 disponíveis. Com o QR
   em 184 e a nota mais compacta, a frase inteira cabe. */
.paywall-qr-note { margin-top: 12px; color: var(--text-med); font-size: 14px; line-height: 1.35; }
.paywall-qr-fallback { margin-top: 8px; color: var(--text-med); font-size: 13px; }
.paywall-receipt {
  padding: 22px;
  border-radius: 14px;
  background: var(--surface-1);
  border: 2px solid var(--accent-soft);
}
.paywall-receipt-title { color: var(--text-med); font-size: 14px; text-transform: uppercase; letter-spacing: 1px; }
.paywall-receipt-plan { color: var(--accent); font-size: 28px; font-weight: 800; margin-top: 6px; }
/* Onde gerenciar, pela origem da compra (`manageSubscription`) — só texto, a TV não abre navegador. */
.paywall-receipt-manage { margin-top: 12px; color: var(--text-med); font-size: 14px; line-height: 1.4; }
.paywall-signin {
  display: inline-block;
  padding: 12px 30px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-weight: 700;
  font-size: 17px;
}
.paywall-signin.is-focused { background: var(--accent); color: var(--on-accent); border-color: var(--accent-soft); }
.paywall-close {
  align-self: flex-start;
  margin-top: 14px;
  padding: 10px 26px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-2);
  color: var(--text-med);
  font-weight: 700;
  font-size: 16px;
}
.paywall-close.is-focused { background: var(--accent); color: var(--on-accent); border-color: var(--accent-soft); }

/* ---- selo PRO canônico (cadeado + "PRO", espelho do ProBadge do Android) ---- */
.pro-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 7px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--pro-gold), var(--pro-gold-deep));
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
  vertical-align: middle;
  flex-shrink: 0;
}
.pro-badge > * + * { margin-left: 3px; }
.pro-badge-lock {
  width: 11px;
  height: 11px;
  display: block;
}

/* ---- linha de status — ESCONDIDA por pedido do dono (2026-07-19): quem navega está com o
   controle na mão, a dica só toma espaço. O elemento continua no DOM (as telas ainda escrevem
   nele) como canal de debug: reexibir é apagar este display quando precisar diagnosticar na TV. */
.status {
  display: none;
  flex-shrink: 0;
  padding: 10px 56px 16px 56px;
  font-size: 14px;
  color: var(--text-med);
}

/* ---- player em tela cheia (F3) — porte do PlayerScreen.kt ---- */
.player {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #000;
  overflow: hidden;
}
.player-video {
  width: 100%;
  height: 100%;
  display: block;
  background: #000;
  object-fit: contain; /* "Ajustar" do Android é o default; proporção/zoom é fatia futura */
}

/* Spinner de carga (texto simples — o piso Chromium 53 não tem animação garantida). */
.player-spinner {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  margin-top: -12px;
  text-align: center;
  color: var(--text-high);
  font-size: 17px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
}

/* Chip de pausa central: dois traços desenhados (a identidade v0.2 não usa emoji). */
.player-pause-chip {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 84px;
  height: 84px;
  margin: -42px 0 0 -42px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
}
.player-pause-bar {
  display: inline-block;
  width: 9px;
  height: 30px;
  margin: 0 4px;
  border-radius: 3px;
  background: var(--text-high);
}

/* Erro / fim de reprodução: mensagem central sobre o preto (só VOLTAR sai). */
.player-error {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 60px;
}
.player-error-text {
  color: var(--text-high);
  font-size: 20px;
  font-weight: 600;
  max-width: 640px;
}
.player-error-hint {
  margin-top: 14px;
  color: var(--text-med);
  font-size: 14px;
}

/* OSD de baixo sobre um gradiente de legibilidade. */
.player-osd {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 60px 40px 26px 40px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.88) 100%);
}
.player-osd-top {
  display: flex;
  align-items: center;
}
.player-badge {
  flex-shrink: 0;
  margin-right: 12px;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--error);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.3px;
}
.player-titles {
  flex: 1 1 auto;
  min-width: 0;
}
.player-title {
  color: var(--text-high);
  font-size: 22px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.player-subtitle {
  margin-top: 2px;
  color: var(--text-med);
  font-size: 15px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.player-hint {
  flex-shrink: 0;
  margin-left: 16px;
  color: var(--text-med);
  font-size: 13px;
}
/* As TECLAS da dica desenhadas como tecla — antes só o ▲ tinha ícone e OK/VOLTAR eram palavra solta.
   `inline-block` com largura fixa: o chip é redondo e alinha com o texto da linha. */
.player-key {
  display: inline-block;
  min-width: 22px;
  height: 22px;
  line-height: 20px;
  padding: 0 6px;
  margin: 0 4px;
  vertical-align: middle;
  text-align: center;
  border-radius: 11px;
  border: 1px solid rgba(255, 255, 255, 0.42);
  background: rgba(255, 255, 255, 0.1);
  color: var(--text-high);
  font-size: 11px;
}
.player-key-word {
  margin-right: 4px;
}

/* Barra de progresso (só VOD). */
.player-progress {
  margin-top: 14px;
}
.player-bar {
  position: relative;
  height: 5px;
  border-radius: 99px;
  background: rgba(147, 163, 184, 0.3);
}
.player-bar-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 5px;
  width: 0;
  border-radius: 99px;
  background: var(--accent);
}
.player-bar-knob {
  position: absolute;
  top: 50%;
  left: 0;
  width: 13px;
  height: 13px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: var(--text-high);
}
.player-times {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-size: 13px;
}
.player-time-pos { color: var(--text-high); }
.player-time-dur { color: var(--text-med); }

/* "Próximo episódio" (docs/product/fim-do-video-e-proximo-episodio.md, regra 4): aparece nos créditos, no canto
   de baixo à direita, e TOMA O FOCO (decisão do dono na TV Android). Com o foco é o acento cheio; sem, a
   superfície translúcida — o usuário vê que ▼ o traz de volta. */
.player-next {
  position: absolute;
  right: 40px;
  bottom: 40px;
  display: flex;
  align-items: center;
  padding: 12px 22px;
  border-radius: 12px;
  border: 3px solid transparent;
  background: rgba(14, 21, 32, 0.9);
  color: var(--text-high);
  font-size: 17px;
  font-weight: 700;
}
.player-next.is-above-osd {
  bottom: 150px;
}
.player-next.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
  color: var(--on-accent);
}
.player-next-glyph {
  margin-right: 10px;
  font-size: 14px;
}

/* Badges dos ajustes ativos (topo-esquerda). */
.player-badges {
  position: absolute;
  top: 24px;
  left: 24px;
  display: flex;
}
.player-badge-chip {
  margin-right: 8px;
  padding: 4px 10px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.55);
  color: var(--text-high);
  font-size: 13px;
  font-weight: 700;
}

/* Folha de opções (proporção/velocidade/soneca) — à direita, como o OptionsSheet do Android. */
.player-sheet {
  position: absolute;
  top: 50%;
  right: 40px;
  width: 340px;
  transform: translateY(-50%);
  padding: 22px;
  border-radius: 16px;
  background: rgba(14, 21, 32, 0.97); /* --surface-1 com alfa */
}
.player-sheet-title {
  color: var(--text-high);
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 12px;
}
.player-sheet-row {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  margin-bottom: 6px;
  border-radius: 10px;
  background: var(--surface-2);
}
.player-sheet-row.is-selected {
  background: var(--accent);
}
.player-sheet-label {
  flex: 1 1 auto;
  color: var(--text-high);
  font-size: 16px;
  font-weight: 600;
}
.player-sheet-row.is-selected .player-sheet-label { color: var(--on-accent); }
.player-sheet-value {
  color: var(--accent);
  font-size: 16px;
  font-weight: 700;
}
.player-sheet-row.is-selected .player-sheet-value { color: var(--on-accent); }
.player-sheet-hint {
  margin-top: 8px;
  color: var(--text-med);
  font-size: 12px;
}

/* --- Minhas listas ------------------------------------------------------------------------- */
/* Espelha o `.organize` (mesma família de tela de gestão). Sem `gap` de flex: o piso é Chromium
   53/79 e a LG 79 não tem `gap` em flex — margem entre irmãos é a forma que funciona nas duas TVs. */
.lists {
  flex: 1 1 auto;
  overflow: hidden;
  padding: 28px 56px 0 56px;
  display: flex;
  flex-direction: column;
}
.lists-title {
  font-size: 30px;
  font-weight: 800;
  margin: 0;
}
.lists-hint {
  margin: 6px 0 18px 0;
  color: var(--text-med);
  font-size: 15px;
}
.lists-list {
  flex: 0 1 auto; /* o botão "Adicionar" segue as linhas, não fica solto no fim da tela */
  overflow: hidden;
  max-width: 860px;
}
.lists-empty {
  color: var(--text-med);
  font-size: 16px;
  padding: 12px 0 20px 0;
}
.lists-row {
  display: flex;
  align-items: center;
  padding: 13px 16px;
  margin-bottom: 8px;
  border-radius: 10px;
  background: var(--surface-1);
}
.lists-row-info {
  flex: 1 1 auto;
  min-width: 0;
}
.lists-row-name-line {
  display: flex;
  align-items: center;
}
.lists-row-name {
  color: var(--text-high);
  font-size: 18px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lists-row-chip {
  flex-shrink: 0;
  margin-left: 10px;
  padding: 2px 9px;
  border-radius: 6px;
  background: rgba(240, 185, 11, 0.16);
  color: var(--pro-gold);
  font-size: 12px;
  font-weight: 700;
}
.lists-row-sub {
  margin-top: 3px;
  color: var(--text-med);
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Linha do userInfo da lista ativa (status · expira · conexões) — levemente destacada. */
.lists-row-info-line {
  margin-top: 4px;
  color: var(--text-high);
  font-size: 13px;
  font-weight: 600;
}
.lists-row-actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  margin-left: 16px;
}
.lists-btn {
  margin-left: 8px;
  padding: 8px 16px;
  border-radius: 8px;
  border: 3px solid transparent;
  background: var(--surface-2);
  color: var(--text-high);
  font-size: 15px;
  font-weight: 600;
}
.lists-btn.is-focused {
  background: var(--accent);
  border-color: var(--accent-soft);
  color: var(--on-accent);
}
.lists-add {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  margin: 4px 0 24px 0;
  padding: 12px 18px;
  max-width: 860px;
  border-radius: 10px;
  border: 3px solid transparent;
  background: var(--surface-1);
}
.lists-add-label {
  color: var(--text-high);
  font-size: 17px;
  font-weight: 600;
  margin-right: 10px;
}
.lists-add.is-focused {
  border-color: var(--accent);
  background: var(--surface-2);
}

/* A folha do alvo NAVEGADOR — o que só existe num PC e o pacote das TVs não leva.
   O `build.mjs` deste diretório a cola no FIM do `style.css` da casca (a mesma ordem de cascata de quando
   estas regras moravam lá); o `pkg/build.mjs` das TVs copia o `style.css` da casca como está, sem isto.

   As regras não usam `gap` de flex nem `inset` porque nasceram na folha das TVs, cujo piso é o Chromium 53;
   aqui esse piso não vale. */

/* ---- Player de PC ----------------------------------------------------------------------------------
   "Voltar", pausar, volume, ajustes e tela cheia como botões: o mouse não tem OK nem VOLTAR. Quem cria
   estes elementos é a `BrowserPlayerView` (`player-view.ts`), que marca a tela com `.player.is-pc`. */
.player.is-idle { cursor: none; }
.player.is-pc .player-video { cursor: pointer; }
.player.is-idle .player-video { cursor: none; }
.player-pc-back {
  position: absolute;
  top: 20px;
  left: 24px;
  display: flex;
  align-items: center;
  padding: 7px 16px 7px 10px;
  border-radius: 22px;
  background: rgba(7, 11, 18, 0.66);
  border: 2px solid rgba(255, 255, 255, 0.24);
  color: var(--text-high);
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  z-index: 7;
}
.player-pc-back .player-icon { margin-right: 6px; }
.player-pc-back:hover,
.player-pc-btn:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.player-pc-bar {
  display: flex;
  align-items: center;
  margin-top: 12px;
}
.player-pc-btn {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-right: 8px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.1);
  border: 2px solid transparent;
  color: var(--text-high);
  cursor: pointer;
}
.player-pc-fullscreen { margin-right: 0; }
.player-pc-spacer { flex: 1 1 auto; }
.player-icon { display: block; }
/* O volume: a área de clique é mais alta do que o traço (22 px contra 5), para o ponteiro acertar. */
.player-pc-volume {
  flex-shrink: 0;
  position: relative;
  width: 110px;
  height: 22px;
  cursor: pointer;
}
.player-pc-volume-track {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 5px;
  margin-top: -3px;
  border-radius: 99px;
  background: rgba(147, 163, 184, 0.3);
}
.player-pc-volume-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 5px;
  width: 0;
  border-radius: 99px;
  background: var(--text-high);
}
/* A barra de progresso vira clicável: a mesma folga de clique, sem engrossar o traço. */
.player.is-pc .player-bar { cursor: pointer; }
.player.is-pc .player-bar::before {
  content: '';
  position: absolute;
  top: -10px;
  bottom: -10px;
  left: 0;
  right: 0;
}
/* O que morava no canto do "Voltar" sai do caminho; e o "Próximo episódio" sobe a altura da fila nova. */
.player.is-pc .player-badges { top: 26px; left: 170px; }
.player.is-pc ~ .zap-banner { top: 76px; left: 24px; }
.player.is-pc.is-sheet-open ~ .zap-arrow { display: none; }
/* "Tentar de novo", debaixo da mensagem de erro. */
.player-pc-retry {
  margin-top: 18px;
  padding: 10px 26px;
  border-radius: 22px;
  background: var(--accent);
  border: 2px solid var(--accent);
  color: var(--on-accent);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}
.player-pc-retry:hover { border-color: var(--text-high); }
/* O aviso de som (áudio que o navegador não toca · transmissão que veio muda): no alto, ao centro, fora
   do caminho do "Voltar" e dos badges. */
.player-notice {
  position: absolute;
  top: 22px;
  left: 50%;
  max-width: 560px;
  transform: translateX(-50%);
  padding: 9px 18px;
  border-radius: 10px;
  background: rgba(7, 11, 18, 0.86);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: var(--text-high);
  font-size: 15px;
  font-weight: 600;
  text-align: center;
  z-index: 6;
}
/* No PC a linha de cima é do "Voltar" e dos badges: o aviso desce para não disputar o lugar com eles. */
.player.is-pc .player-notice { top: 70px; }
.player.is-pc .player-next.is-above-osd { bottom: 205px; }
