/* ==========================================================================
   MAGNETBR STREAMING - PREMIUM NETFLIX DARK DESIGN SYSTEM
   ==========================================================================
   A fonte Outfit é carregada por <link> no <head> do index.html, não por
   @import aqui: @import só começa a baixar depois que ESTE arquivo terminou de
   baixar e ser lido, encadeando duas viagens de rede antes do primeiro texto
   aparecer. Com <link> + preconnect as duas descem em paralelo.
   ========================================================================== */

:root {
  --bg-color: #0c0c0c;
  --bg-gradient: radial-gradient(circle at top center, #180507 0%, #0c0c0c 70%);
  --card-bg: #181818;
  --card-bg-hover: #232323;
  --nav-bg: rgba(12, 12, 12, 0.85);
  --accent-red: #E50914;
  --accent-red-hover: #ff1e27;
  --text-main: #FFFFFF;
  --text-muted: #999999;
  --text-dimmed: #cccccc;
  --glass-bg: rgba(255, 255, 255, 0.05);
  --glass-border: rgba(255, 255, 255, 0.08);
  --card-radius: 8px;
  --transition-fast: 0.2s ease;
  --transition-smooth: 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  --shadow-premium: 0 15px 35px rgba(0, 0, 0, 0.8);

  /* ---- Escala de espaçamento (base 4px) ----------------------------------
     Antes cada componente escolhia seu próprio valor no olho (0.35rem, 0.6rem,
     0.9rem, 1.2rem...). Uma escala fixa é o que faz blocos diferentes da página
     parecerem parte do mesmo produto. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;

  /* ---- Escala tipográfica fluida -----------------------------------------
     clamp(mínimo, preferido, máximo) faz o texto crescer junto com a tela em vez
     de pular de degrau em degrau nos breakpoints. O título do hero, por exemplo,
     era declarado três vezes (4.2rem, 2.8rem @900px, 2.2rem @768px) — --text-hero
     cobre a faixa inteira sozinho. */
  --text-xs:   clamp(0.70rem, 0.68rem + 0.10vw, 0.75rem);
  --text-sm:   clamp(0.80rem, 0.77rem + 0.15vw, 0.875rem);
  --text-base: clamp(0.95rem, 0.92rem + 0.15vw, 1rem);
  --text-lg:   clamp(1.05rem, 1.00rem + 0.25vw, 1.15rem);
  --text-xl:   clamp(1.25rem, 1.15rem + 0.50vw, 1.5rem);
  --text-2xl:  clamp(1.60rem, 1.35rem + 1.20vw, 2.2rem);
  --text-3xl:  clamp(2.00rem, 1.50rem + 2.50vw, 2.8rem);
  --text-hero: clamp(2.20rem, 1.40rem + 4.00vw, 4.2rem);

  /* ---- Raios ---- */
  --radius-sm: 4px;
  --radius-md: 8px;   /* mesmo valor de --card-radius, mantido para compatibilidade */
  --radius-lg: 12px;
  --radius-xl: 18px;
  --radius-pill: 999px;

  /* ---- Elevação ---- */
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 15px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.6);
  --shadow-xl: 0 24px 60px rgba(0, 0, 0, 0.75);
  --shadow-red: 0 8px 30px rgba(229, 9, 20, 0.28);

  /* ---- Camadas ----------------------------------------------------------
     Os z-index estavam espalhados como números soltos (10, 100, 999, 1000, 2000,
     8000, 9000, 9500, 9998, 9999, 10000, 10001) — impossível saber o que fica
     acima do quê sem caçar no arquivo inteiro. */
  --z-card-hover: 100;
  --z-navbar: 1000;
  --z-search: 1010;
  --z-modal: 2000;
  --z-player: 3000;
  --z-player-ui: 10000;

  /* ---- Movimento ---- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast: 160ms;
  --dur-base: 240ms;
  --dur-slow: 480ms;

  /* ---- Foco visível ---- */
  --focus-ring: 0 0 0 3px rgba(229, 9, 20, 0.55), 0 0 0 5px rgba(255, 255, 255, 0.15);
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-font-smoothing: antialiased;
}

/* A fonte vem do body por herança em vez do seletor universal: aplicar
   font-family em `*` obriga o navegador a resolver a fonte para cada elemento
   individualmente e impede qualquer trecho de usar outra família (código
   monoespaçado, por exemplo) sem uma briga de especificidade. */
body {
  font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* Campos de formulário e botões não herdam fonte por padrão — sem isto eles
   voltariam para a fonte do sistema assim que o `*` deixasse de forçar. */
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

body {
  background: var(--bg-color);
  background-image: var(--bg-gradient);
  background-attachment: fixed;
  color: var(--text-main);
  overflow-x: hidden;
  min-height: 100vh;
}

/* Custom Scrollbar */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: #0c0c0c;
}
::-webkit-scrollbar-thumb {
  background: #252525;
  border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--accent-red);
}

/* ==========================================================================
   FOCO VISÍVEL E ESTADOS DE PRESSÃO
   Antes disto o site tinha `outline: none` em 3 lugares (linha ~283 aqui,
   ~869 aqui, e auth.css) sem NENHUM substituto para o resto da interface —
   ou seja, zero indicação visual ao navegar por Tab. Especificidade zero via
   `:where()` de propósito: nenhuma regra abaixo precisa ser tocada, porque
   qualquer seletor mais específico já escrito no resto do arquivo continua
   ganhando (é o caso do `.search-input:focus` mais abaixo, que já tem seu
   próprio brilho e continua funcionando exatamente como antes).
   ========================================================================== */

:where(a, button, select, input, textarea, [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* Cliques com mouse/toque nunca deveriam acionar :focus-visible (o navegador já
   decide isso sozinho), mas alguns navegadores mais antigos tratam <select> e
   <button> como sempre "teclado" — esta regra garante que só sobra o anel
   quando :focus-visible realmente casa. */
:where(a, button, select, input, textarea):focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}

/* O estado :focus-visible do .media-card (que é <div>, sem foco nativo) é definido junto com
   :hover, mais abaixo — mesma transformação/sombra, mais o anel do :where() acima por cima,
   para navegar por teclado revelar o card do jeito que o mouse já revela. */

/* Sobre fundo branco (.btn-primary) o anel vermelho/branco padrão perde
   contraste — inverte para um anel escuro por dentro. */
.btn-primary:focus-visible {
  box-shadow: 0 0 0 3px rgba(12, 12, 12, 0.7), 0 0 0 5px var(--accent-red);
}

/* Estados de :active ficam no FIM do arquivo, não aqui — ver a seção "ESTADOS DE PRESSÃO"
   perto do final. Motivo: :hover de cada componente (.btn-primary:hover, .category-pill:hover
   etc.) é declarado bem mais abaixo, com a mesma especificidade de classe+pseudo-classe. Em
   empate de especificidade, quem vem DEPOIS no arquivo vence — colocar :active aqui em cima
   fazia :hover ganhar sempre que o mouse estava sobre o elemento no instante do clique, ou
   seja, o feedback de pressão nunca aparecia de verdade. */

/* Movimento reduzido: honra a preferência do sistema para toda transição e
   animação CSS do site — o motion.js (GSAP) trata o próprio caso à parte. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Navbar */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  padding: 1.5rem 4%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 1000;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 100%);
  transition: all var(--transition-smooth);
}

.navbar.scrolled {
  background-color: var(--nav-bg);
  backdrop-filter: blur(25px);
  -webkit-backdrop-filter: blur(25px);
  padding: 0.9rem 4%;
  border-bottom: 1px solid var(--glass-border);
}

.navbar-brand {
  display: flex;
  align-items: center;
  text-decoration: none;
  font-size: 2.1rem;
  font-weight: 900;
  color: var(--accent-red);
  letter-spacing: -1.5px;
  transition: transform var(--transition-fast);
}

.navbar-brand:hover {
  transform: scale(1.02);
}

.navbar-brand span {
  color: #fff;
  font-weight: 500;
  letter-spacing: -0.5px;
  margin-left: 2px;
}

.nav-links {
  display: flex;
  list-style: none;
  gap: 1.8rem;
  align-items: center;
}

.mobile-nav-links {
  display: none;
}

.nav-links a {
  color: var(--text-dimmed);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
  position: relative;
  padding: 4px 0;
  transition: color var(--transition-fast);
}

.nav-links a:hover,
.nav-links a.active {
  color: #fff;
}

.nav-links a::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0;
  height: 2px;
  background: var(--accent-red);
  transition: all var(--transition-fast);
  transform: translateX(-50%);
}

.nav-links a:hover::after,
.nav-links a.active::after {
  width: 100%;
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.search-toggle-btn {
  display: none;
  background: none;
  border: none;
  color: var(--text-dimmed);
  cursor: pointer;
  padding: 8px;
  align-items: center;
  justify-content: center;
  transition: color var(--transition-fast), transform var(--transition-fast);
}

.search-toggle-btn:hover {
  color: #fff;
  transform: scale(1.05);
}

.search-close-btn {
  display: none;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 1.6rem;
  align-items: center;
  justify-content: center;
  padding: 4px;
  transition: color var(--transition-fast);
}

.search-close-btn:hover {
  color: #fff;
}

.search-box {
  position: relative;
  display: flex;
  align-items: center;
}

.search-input {
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid var(--glass-border);
  color: #fff;
  padding: 0.6rem 1.2rem 0.6rem 2.6rem;
  border-radius: 30px;
  font-size: 0.9rem;
  outline: none;
  width: 240px;
  transition: all var(--transition-smooth);
}

.search-input:focus {
  width: 320px;
  border-color: var(--accent-red);
  background: rgba(0, 0, 0, 0.8);
  box-shadow: 0 0 15px rgba(229, 9, 20, 0.25);
}

.search-icon {
  position: absolute;
  left: 14px;
  color: var(--text-muted);
  pointer-events: none;
  font-size: 0.95rem;
}

.btn-admin {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  color: #fff;
  padding: 0.5rem 1.2rem;
  border-radius: 30px;
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
  transition: all var(--transition-fast);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.btn-admin:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
  box-shadow: 0 4px 15px rgba(229, 9, 20, 0.4);
}

/* Hero Banner */
.hero {
  position: relative;
  height: 85vh;
  min-height: 600px;
  display: flex;
  align-items: center;
  padding: 0 4%;
  background-size: cover;
  background-position: center top;
  margin-bottom: 1.5rem;
  overflow: hidden;
}

.hero-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(0deg, var(--bg-color) 0%, rgba(12, 12, 12, 0.2) 60%, rgba(12, 12, 12, 0.7) 100%),
              linear-gradient(90deg, var(--bg-color) 0%, rgba(12, 12, 12, 0.5) 45%, rgba(12, 12, 12, 0) 100%);
}

.hero-content {
  position: relative;
  z-index: 10;
  max-width: 700px;
  margin-top: 50px;
  /* Sem animation aqui: a entrada agora é feita pelo GSAP (src/js/motion.js), que anima com
     gsap.from() — o estado de repouso do elemento (sem GSAP) já é totalmente visível, então se
     o script não carregar (CDN bloqueado, adblock) o conteúdo nunca fica invisível, só perde a
     entrada suave. Uma animação CSS daria exatamente esse risco: o "from{opacity:0}" precisaria
     do "to{opacity:1}" rodar até o fim para o conteúdo aparecer. */
}

.hero-badge {
  display: inline-block;
  background: linear-gradient(135deg, var(--accent-red) 0%, #b80710 100%);
  color: #fff;
  padding: 0.35rem 1rem;
  font-size: 0.75rem;
  font-weight: 800;
  border-radius: 4px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  margin-bottom: 1.2rem;
  box-shadow: 0 4px 10px rgba(229, 9, 20, 0.3);
}

.hero-title {
  /* Fluido: cobre sozinho os três tamanhos que antes eram declarados em separado (aqui e nas
     duas media queries mais abaixo), crescendo junto com a tela em vez de saltar de degrau em
     degrau. */
  font-size: var(--text-hero);
  font-weight: 900;
  line-height: 1.05;
  margin-bottom: 1.2rem;
  letter-spacing: -1px;
  text-shadow: 0 4px 15px rgba(0, 0, 0, 0.7);
}

.hero-overview {
  font-size: 1.15rem;
  color: var(--text-dimmed);
  line-height: 1.6;
  margin-bottom: 2rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
}

.hero-actions {
  display: flex;
  gap: 1.2rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.9rem 2.2rem;
  font-size: 1.1rem;
  font-weight: 800;
  border-radius: var(--radius-md);
  border: none;
  cursor: pointer;
  transition: transform var(--dur-base) var(--ease-out),
              background-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}

/* Estado de "resolvendo em qual episódio começar" do botão Assistir do hero (série) —
   sem isto, disabled ficava com a mesma aparência de clicável e o clique parecia não ter
   feito nada até a rede responder. */
.btn:disabled {
  opacity: 0.65;
  cursor: default;
  pointer-events: none;
}

.btn-primary {
  position: relative;
  /* isolation + overflow:hidden contêm o brilho do ::after dentro da forma arredondada do
     botão, sem vazar quadrado por cima do border-radius. */
  overflow: hidden;
  isolation: isolate;
  background-color: #ffffff;
  color: #0c0c0c;
  box-shadow: 0 4px 15px rgba(255, 255, 255, 0.15);
}

.btn-primary:hover {
  background-color: #e2e2e2;
  transform: scale(1.05);
}

/* Varredura de brilho no hover — só em dispositivos com mouse de verdade: no toque não existe
   "passar por cima" antes de clicar, então o efeito nunca terminaria de rodar. */
@media (hover: hover) and (pointer: fine) {
  .btn-primary::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.65) 50%, transparent 65%);
    transform: translateX(-120%);
    transition: transform var(--dur-slow) var(--ease-out);
  }

  .btn-primary:hover::after,
  .btn-primary:focus-visible::after {
    transform: translateX(120%);
  }
}

.btn-secondary {
  background-color: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.btn-secondary:hover {
  background-color: rgba(255, 255, 255, 0.22);
  transform: scale(1.05);
}

/* Sections & Carousels */
.catalog-section {
  padding: 0 4%;
  margin-bottom: 3.5rem;
  position: relative;
}

.section-title {
  font-size: var(--text-xl);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin-bottom: 1.2rem;
  color: #fff;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.carousel-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.carousel-container {
  width: 100%;
  overflow: hidden;
  /* Sem isto o card nas duas pontas do carrossel é cortado por uma borda reta e dura pelo
     overflow:hidden acima — a máscara esmaece a arte na borda em vez de simplesmente serrar,
     o mesmo truque visual que a Netflix usa nas fileiras dela. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 2.5%, #000 97.5%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 2.5%, #000 97.5%, transparent 100%);
}

.carousel {
  display: flex;
  gap: 1.2rem;
  overflow-x: auto;
  scroll-behavior: smooth;
  padding: 1rem 0;
  -webkit-overflow-scrolling: touch;
}

.carousel::-webkit-scrollbar {
  display: none;
}

/* Carousel Control Buttons */
.carousel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 45px;
  height: 60px;
  background: rgba(12, 12, 12, 0.7);
  border: 1px solid var(--glass-border);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 10;
  font-size: 1.5rem;
  border-radius: 4px;
  /* Fica sutilmente visível por padrão (não 0) — em telas de toque sem mouse (ex: tablet na
     faixa ~900-1024px, acima do breakpoint mobile que já esconde isto) o :hover nunca dispara,
     então uma seta que só aparece no hover fica invisível e sem nenhum jeito de navegar. */
  opacity: 0.55;
  transition: all var(--transition-fast);
  backdrop-filter: blur(5px);
}

.carousel-wrapper:hover .carousel-btn {
  opacity: 1;
}

.carousel-btn:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
}

.carousel-btn.prev {
  left: -20px;
}

.carousel-btn.next {
  right: -20px;
}

/* Media Card */
.media-card {
  flex: 0 0 calc(16.666% - 1rem);
  min-width: 180px;
  /* Sem isto, num monitor ultrawide (3440px+) 16.666% vira ~570px por pôster — maior que a tela
     inteira de um celular. O card para de crescer a partir daqui e o excesso de espaço da tela
     larga sobra como respiro entre os cards, não como cards gigantes. */
  max-width: 260px;
  background-color: var(--card-bg);
  border-radius: var(--card-radius);
  overflow: hidden;
  cursor: pointer;
  position: relative;
  /* Por propriedade, não `all`: `all` obriga o navegador a observar toda propriedade animável
     do elemento (incluindo as que nunca mudam, como border-radius) a cada frame — sem efeito
     visual a mais, só custo de repaint em fileiras com muitos cards. */
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) ease,
              background-color var(--dur-base) ease,
              border-color var(--dur-fast) linear;
  box-shadow: var(--shadow-md);
  border: 1px solid rgba(255, 255, 255, 0.02);
  will-change: transform;
  transform: translateZ(0);
}

/* :focus-visible reaproveita a mesma revelação do :hover — é <div>, sem foco nativo, então
   navegar por teclado precisa parecer exatamente com passar o mouse por cima. */
.media-card:hover,
.media-card:focus-visible {
  outline: none;
  /* Levemente mais contido que antes (1.08/-8px): o valor antigo fazia o card invadir os
     vizinhos na fileira, especialmente nos dois primeiros/últimos do carrossel. */
  transform: scale(1.05) translateY(-6px);
  z-index: var(--z-card-hover);
  box-shadow: var(--shadow-lg), 0 0 25px rgba(229, 9, 20, 0.25);
  background-color: var(--card-bg-hover);
  border-color: rgba(229, 9, 20, 0.4);
}

.poster-img {
  width: 100%;
  aspect-ratio: 2/3;
  object-fit: cover;
  display: block;
  transition: transform var(--transition-smooth);
}

/* Antes ficava sempre visível embaixo do pôster (empurrando a altura do card) — igual à Netflix,
   agora fica só a arte por padrão e as informações aparecem sobrepostas ao pôster, num degradê,
   apenas ao passar o mouse/focar. Position absolute tira o .card-info do fluxo normal, então a
   altura do .media-card passa a ser só a do .card-media-wrapper (a arte). */
.card-info {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0.9rem;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.92) 0%, rgba(0, 0, 0, 0) 100%);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--transition-fast), transform var(--transition-fast);
  pointer-events: none;
}

.media-card:hover .card-info {
  opacity: 1;
  transform: translateY(0);
}

/* Em toque (celular/tablet sem mouse) o :hover nunca dispara — mesmo motivo já tratado no
   .carousel-btn (ver comentário acima). Sem isto, título/nota/ano do card ficariam
   permanentemente invisíveis pra quem usa toque, que é a maior parte do tráfego de streaming. */
@media (hover: none) {
  .card-info {
    position: static;
    opacity: 1;
    transform: none;
    background: var(--card-bg);
  }
}

.card-title {
  font-size: 0.95rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 0.4rem;
}

/* Card Media Wrapper & Overlay */
.card-media-wrapper {
  position: relative;
  width: 100%;
  aspect-ratio: 2/3;
  overflow: hidden;
  background: #121212;
}

/* Fileira "Top 10 Hoje" — número grande no canto do pôster, estilo Netflix. Contorno preto via
   text-stroke em vez de só text-shadow, pra ficar legível mesmo sobre um pôster claro. */
.rank-number {
  position: absolute;
  left: 2px;
  bottom: -4px;
  z-index: 2;
  font-size: 4rem;
  font-weight: 800;
  line-height: 1;
  color: var(--accent-red);
  -webkit-text-stroke: 2px #000;
  paint-order: stroke fill;
  text-shadow: 0 4px 10px rgba(0, 0, 0, 0.6);
  pointer-events: none;
  font-family: inherit;
}

/* Barra de progresso da fileira "Continuar Assistindo" — mesmo raciocínio visual da Netflix,
   fixa na base do pôster, sempre visível (não é hover-reveal como o .card-info). */
.card-progress-track {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: rgba(255, 255, 255, 0.25);
}

.card-progress-fill {
  height: 100%;
  background: var(--accent-red);
}

.card-play-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--transition-fast);
}

.media-card:hover .card-play-overlay {
  opacity: 1;
}

.play-circle-btn {
  width: 48px;
  height: 48px;
  background: #ffffff;
  color: #000;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  padding-left: 3px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
  transform: scale(0.8);
  transition: transform var(--transition-fast);
}

.media-card:hover .play-circle-btn {
  transform: scale(1);
}

.match-score {
  color: #46d369;
  font-weight: 800;
  font-size: 0.8rem;
}

.badge-hd {
  border: 1px solid rgba(255, 255, 255, 0.4);
  color: var(--text-dimmed);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.5px;
}

.card-year {
  color: var(--text-muted);
  font-size: 0.75rem;
}

/* Modal Detalhes - Netflix style grid */
.modal-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(15px);
  -webkit-backdrop-filter: blur(15px);
  z-index: 2000;
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.modal-backdrop.active {
  opacity: 1;
  pointer-events: all;
}

.modal-content {
  background: #181818;
  width: 92%;
  max-width: 900px;
  max-height: 92vh;
  border-radius: 12px;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.9);
  border: 1px solid var(--glass-border);
  transform: scale(0.9) translateY(40px);
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.modal-backdrop.active .modal-content {
  transform: scale(1) translateY(0);
}

.modal-close {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 40px;
  height: 40px;
  background: rgba(12, 12, 12, 0.8);
  border: 1px solid var(--glass-border);
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 20;
  font-size: 1.5rem;
  transition: all var(--transition-fast);
}

.modal-close:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
}

.modal-hero {
  position: relative;
  height: 400px;
  background-size: cover;
  background-position: center top;
}

.modal-hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, #181818 0%, rgba(24, 24, 24, 0.2) 60%, rgba(24, 24, 24, 0.7) 100%);
}

.modal-body {
  padding: 2.5rem 3rem;
}

.modal-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 2.5rem;
}

.modal-title {
  font-size: 2.8rem;
  font-weight: 900;
  margin-bottom: 0.8rem;
  letter-spacing: -1px;
}

.modal-meta-row {
  display: flex;
  gap: 1.2rem;
  align-items: center;
  font-size: 0.95rem;
  color: var(--text-dimmed);
  margin-bottom: 1.5rem;
}

.modal-meta-row .badge {
  border: 1px solid var(--glass-border);
  padding: 3px 8px;
  border-radius: 4px;
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.8rem;
  letter-spacing: 0.5px;
}

.modal-overview {
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--text-dimmed);
  margin-bottom: 2rem;
}

/* Season / Episode Selector */
.server-btn {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--glass-border);
  color: #fff;
  padding: 0.6rem 1.2rem;
  /* Mesmo motivo do .category-pill — abaixo da altura mínima recomendada de toque (~44px). */
  min-height: 44px;
  border-radius: 30px;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  transition: all var(--transition-fast);
}

.server-btn:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
  transform: translateY(-2px);
  box-shadow: 0 4px 15px rgba(229, 9, 20, 0.4);
}

.season-selector-container {
  margin-top: 2rem;
  border-top: 1px solid var(--glass-border);
  padding-top: 2rem;
}

.select-season {
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  border: 1px solid var(--glass-border);
  padding: 0.7rem 1.5rem;
  border-radius: 6px;
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 1.5rem;
  outline: none;
  cursor: pointer;
  transition: border var(--transition-fast);
}

.select-season:focus {
  border-color: var(--accent-red);
}

.episodes-grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.episode-card {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  background: rgba(255, 255, 255, 0.02);
  padding: 1rem;
  border-radius: 8px;
  cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.03);
  transition: all var(--transition-fast);
}

.episode-card:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(229, 9, 20, 0.3);
  transform: translateY(-2px);
}

.episode-num {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--text-muted);
  width: 40px;
  text-align: center;
}

.episode-still-wrapper {
  position: relative;
  flex-shrink: 0;
}

.episode-still {
  width: 150px;
  aspect-ratio: 16/9;
  object-fit: cover;
  border-radius: 6px;
  background: #111;
  box-shadow: 0 4px 10px rgba(0,0,0,0.5);
  display: block;
}

.episode-play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  pointer-events: none;
}

.episode-play-overlay svg {
  width: 40px;
  height: 40px;
  padding: 10px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  transition: transform var(--transition-fast), background var(--transition-fast);
}

.episode-card:hover .episode-play-overlay svg,
.episode-card:focus-visible .episode-play-overlay svg {
  background: var(--accent-red);
  transform: scale(1.08);
}

/* "Onde eu parei" — episódio concluído só tem o selo, em andamento só tem a barra, nunca
   assistido não tem nada. Mesma cor/altura já usada no progresso dos cards de pôster. */
.episode-watched-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.65);
  color: var(--accent-red);
  font-size: 0.85rem;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}

.episode-progress-track {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 0 0 6px 6px;
  overflow: hidden;
}

.episode-progress-fill {
  height: 100%;
  background: var(--accent-red);
}

.episode-info {
  flex: 1;
}

.episode-title {
  font-weight: 700;
  font-size: 1.05rem;
  margin-bottom: 0.4rem;
}

.episode-overview {
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ==========================================
   RESULTADOS DA BUSCA
   ========================================== */

.search-results-section {
  padding: 6rem 4% 3rem; /* respeita a navbar fixa */
  min-height: 60vh;
}

/* Página de Categorias (Filmes/Séries) — mesmo espaçamento da busca, já que as duas ficam no
   topo do #mainContent substituindo a navegação normal. */
.categories-page-section {
  padding: 6rem 4% 3rem;
  min-height: 60vh;
}

.search-results-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
  flex-wrap: wrap;
}

.search-results-head .section-title {
  margin-bottom: 0.2rem;
}

.search-results-count {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.btn-clear-search {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--glass-border);
  color: #fff;
  font-size: 0.85rem;
  font-weight: 700;
  padding: 0.5rem 1.1rem;
  border-radius: 30px;
  cursor: pointer;
  flex-shrink: 0;
  transition: all var(--transition-fast);
}

.btn-clear-search:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
}

/* Grade em vez de carrossel: numa busca a pessoa quer varrer tudo de uma vez,
   não empurrar uma fila para o lado. */
.search-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1.2rem;
}

/* O .media-card é dimensionado para o carrossel (flex-basis fixo); na grade quem
   manda é a coluna. Sem anular o max-width do carrossel aqui, cada card ficaria
   travado em 260px dentro de uma coluna de grade mais larga (telas grandes com
   poucos resultados), sobrando um vão vazio do lado direito de cada célula. */
.search-grid .media-card {
  flex: none;
  min-width: 0;
  max-width: none;
  width: 100%;
}

.search-empty {
  color: var(--text-muted);
  font-size: 1rem;
  padding: 3rem 0;
  text-align: center;
}

.search-skeleton {
  border-radius: var(--card-radius);
  background: linear-gradient(90deg, #1a1a1a 25%, #232323 50%, #1a1a1a 75%);
  background-size: 200% 100%;
  animation: searchShimmer 1.2s infinite;
  aspect-ratio: 2 / 3;
}

@keyframes searchShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ==========================================================================
   ESQUELETOS (skeleton loading)
   .search-skeleton acima já existia e continua intocado (é criado direto pelo JS da busca);
   .skeleton é a versão genérica nova, usada nos carrosséis da Home e no hero — mesmo efeito
   visual, um keyframe próprio (@mfShimmer) só para não depender de nada que já existia.
   ========================================================================== */

.skeleton {
  border-radius: var(--card-radius);
  background: linear-gradient(90deg, #1a1a1a 25%, #232323 50%, #1a1a1a 75%);
  background-size: 200% 100%;
  animation: mfShimmer 1.4s ease-in-out infinite;
}

@keyframes mfShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Card-fantasma do carrossel — mesma largura/proporção do .media-card real, pra reservar o
   espaço exato e a fileira não "crescer" quando os cards de verdade chegam. */
.skeleton-card {
  flex: 0 0 calc(16.666% - 1rem);
  min-width: 180px;
  max-width: 260px;
  aspect-ratio: 2 / 3;
}

/* Esqueleto do hero: em vez de trocar o DOM por blocos-fantasma, usa o texto placeholder que
   já está no HTML (index.html) e só o deixa transparente sobre um fundo animado — a área
   ocupada é exatamente a mesma que o título/sinopse reais vão ocupar, sem salto de layout
   quando o conteúdo chega. showHeroSlide() remove .is-loading assim que o primeiro slide real
   é preenchido. */
.hero.is-loading .hero-badge,
.hero.is-loading .hero-title,
.hero.is-loading .hero-overview {
  color: transparent;
  text-shadow: none;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.06) 25%, rgba(255, 255, 255, 0.14) 50%, rgba(255, 255, 255, 0.06) 75%);
  background-size: 200% 100%;
  animation: mfShimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius-sm);
  /* Sem isto o gradiente do badge (linear-gradient(135deg, var(--accent-red)...)) some por
     baixo do shimmer só visualmente por cima — na prática background-size:200% já cobre, mas
     box-shadow vermelho do badge continua aparecendo sem isso; zera pra não vazar cor da marca
     num elemento que ainda não tem conteúdo de verdade. */
  box-shadow: none;
}

.hero.is-loading .hero-actions {
  opacity: 0.35;
  pointer-events: none;
}

/* Custom Video Player Overlay */
.player-modal {
  position: fixed;
  inset: 0;
  width: 100vw;
  /* 100vh no celular conta a barra de endereço do navegador: o player fica mais alto que a
     área visível e a parte de baixo dos controles some. dvh acompanha a barra ao esconder. */
  height: 100vh;
  height: 100dvh;
  max-height: 100dvh;
  background: #000;
  z-index: 3000;
  display: none;
  flex-direction: column;
  overflow: hidden;
}

.player-modal.active {
  display: flex;
}

.player-header {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  min-height: 60px;
  flex-shrink: 0;
  /* Recorte de câmera / barra de status: em paisagem o notch fica na lateral, exatamente
     onde ficam o "Voltar" e os botões da direita. A primeira linha é o fallback para
     navegadores sem env() — sem ela a regra inteira seria descartada por eles. */
  padding: 0.8rem 1.8rem;
  padding: calc(0.8rem + env(safe-area-inset-top)) calc(1.8rem + env(safe-area-inset-right))
           0.8rem calc(1.8rem + env(safe-area-inset-left));
  display: flex;
  align-items: center;
  gap: 1.2rem;
  z-index: 10000;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.95) 0%, rgba(0, 0, 0, 0.6) 50%, rgba(0, 0, 0, 0) 100%);
  border-bottom: none;
  transition: opacity 0.3s ease, visibility 0.3s ease;
  opacity: 0;
  visibility: hidden;
}

.player-header.visible {
  opacity: 1;
  visibility: visible;
}

.nav-icon {
  display: none;
}

.modal-info-col {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  border-left: 1px solid var(--glass-border);
  padding-left: 2rem;
}

.btn-back {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid var(--glass-border);
  color: #fff;
  font-size: 1rem;
  font-weight: 700;
  padding: 0.4rem 1.1rem;
  border-radius: 30px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-shrink: 0;
  transition: all var(--transition-fast);
}

.btn-back:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
  transform: scale(1.05);
}

.player-title {
  font-size: 1.2rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 40vw;
}

.player-server-selector {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

#serverSelectDropdown {
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  padding: 8px 15px;
  border: 1px solid var(--glass-border);
  border-radius: 30px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.player-icon-btn {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid var(--glass-border);
  color: #fff;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: all var(--transition-fast);
}

.player-icon-btn:hover {
  background: rgba(255, 255, 255, 0.2);
}

/* Travado durante o anúncio obrigatório — ver setServerSwitchLocked() em player.js */
#serverSelectDropdown:disabled,
.player-icon-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* O botão de folha é só do mobile; no desktop o <select> já resolve bem. */
#serverSheetBtn {
  display: none;
}

/* ==========================================
   PLAYER — ESTADO DE CARREGAMENTO
   ========================================== */

.player-loading {
  position: absolute;
  inset: 0;
  z-index: 9000;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 2rem;
  text-align: center;
  background: #000;
}

.player-loading.active {
  display: flex;
}

.player-loading-spinner {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.15);
  border-top-color: var(--accent-red);
  animation: playerSpin 0.8s linear infinite;
}

@keyframes playerSpin {
  to { transform: rotate(360deg); }
}

.player-loading-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: #fff;
  max-width: 80vw;
}

.player-loading-step {
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Aviso não-intrusivo de troca automática de servidor — some sozinho, não bloqueia o vídeo
   nem os controles (diferente do .player-loading, que cobre a tela inteira). */
.player-toast {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%) translateY(-12px);
  z-index: 9500;
  background: rgba(20, 20, 20, 0.92);
  border: 1px solid rgba(229, 9, 20, 0.5);
  color: #fff;
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.player-toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ==========================================
   PLAYER — GESTO DE DUPLO TOQUE (±10s)
   ========================================== */

.seek-hint {
  position: absolute;
  top: 50%;
  transform: translateY(-50%) scale(0.85);
  z-index: 8000;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-size: 0.8rem;
  font-weight: 700;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.seek-hint-left { left: 12%; }
.seek-hint-right { right: 12%; }

.seek-hint.show {
  opacity: 1;
  transform: translateY(-50%) scale(1);
}

/* ==========================================
   PLAYER — FOLHA DE SERVIDORES (MOBILE)
   ========================================== */

.player-sheet-backdrop {
  position: absolute;
  inset: 0;
  z-index: 10001;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}

.player-sheet-backdrop.active {
  opacity: 1;
  visibility: visible;
}

.player-sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10002;
  max-height: 70%;
  display: flex;
  flex-direction: column;
  background: #141414;
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
  border-top: 1px solid var(--glass-border);
  padding-bottom: env(safe-area-inset-bottom);
  transform: translateY(100%);
  visibility: hidden;
  transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1), visibility 0.28s;
}

.player-sheet.active {
  transform: translateY(0);
  visibility: visible;
}

.player-sheet-grip {
  width: 40px;
  height: 4px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.25);
  margin: 10px auto 4px;
  flex-shrink: 0;
}

.player-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 1.2rem 0.8rem;
  font-size: 1rem;
  font-weight: 700;
  color: #fff;
  flex-shrink: 0;
}

.player-sheet-close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 1.1rem;
  cursor: pointer;
  padding: 4px 8px;
}

.player-sheet-list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0 0.8rem 1rem;
}

.player-sheet-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  /* 52px de altura: alvo de toque confortável, acima do mínimo de 44px. */
  min-height: 52px;
  padding: 0.7rem 1rem;
  margin-bottom: 6px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid transparent;
  border-radius: 12px;
  color: #fff;
  font-size: 0.95rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.player-sheet-item.current {
  border-color: var(--accent-red);
  background: rgba(229, 9, 20, 0.15);
}

.player-sheet-item .sheet-item-check {
  margin-left: auto;
  color: var(--accent-red);
  font-weight: 700;
  opacity: 0;
}

.player-sheet-item.current .sheet-item-check {
  opacity: 1;
}

.artplayer-container {
  flex: 1;
  min-height: 0;
  width: 100%;
  height: 100%;
  position: relative;
  background: #000;
  overflow: hidden;
}

/* O ArtPlayer não define object-fit no próprio <video> — sem isto ele herda o padrão do
   navegador (fill), que estica/distorce a imagem pra preencher o container sempre que a
   proporção do vídeo não bate exatamente com a caixa (autoSize:false não redimensiona o player
   pra acompanhar o vídeo). Mais visível no celular, onde o container vira uma caixa 16:9 fixa.
   contain preserva a proporção real, sem cortar nem distorcer nada — só sobra tarja preta. */
.artplayer-container .art-video {
  object-fit: contain;
}

.artplayer-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100% !important;
  border: none;
}

/* Responsividade */
@media (max-width: 900px) {
  .media-card {
    flex: 0 0 calc(33.333% - 1rem);
  }
  /* .hero-title não tem mais override de font-size aqui: --text-hero (clamp) já interpola
     suavemente por esta largura sozinho — este step fixo em 2.8rem foi removido de propósito
     (era exatamente a duplicação que a escala fluida existe para eliminar). */
  .modal-grid {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
  .modal-info-col {
    border-left: none;
    border-top: 1px solid var(--glass-border);
    padding-left: 0;
    padding-top: 1.5rem;
  }
}

@media (max-width: 768px) {
  main {
    padding-bottom: 80px; /* Espaço para a barra de navegação inferior */
  }

  .navbar {
    padding: 0.8rem 4%;
    background-color: rgba(12, 12, 12, 0.95) !important;
    backdrop-filter: blur(25px);
    -webkit-backdrop-filter: blur(25px);
    border-bottom: 1px solid var(--glass-border);
  }

  .navbar-brand {
    font-size: 1.6rem;
    letter-spacing: -1px;
  }

  .desktop-nav-links {
    display: none !important;
  }

  .mobile-nav-links {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 64px;
    background: rgba(8, 8, 10, 0.97);
    backdrop-filter: blur(30px);
    -webkit-backdrop-filter: blur(30px);
    border-top: 1px solid var(--glass-border);
    display: flex;
    justify-content: space-around;
    align-items: center;
    padding: 0.2rem 1rem;
    z-index: 999;
    gap: 0;
  }

  .mobile-nav-links li {
    flex: 1;
    display: flex;
    justify-content: center;
  }

  .mobile-nav-links li a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-muted);
    gap: 4px;
    padding: 6px 0;
    width: 100%;
  }

  .mobile-nav-links a::after {
    display: none;
  }

  .mobile-nav-links a:hover,
  .mobile-nav-links a.active {
    color: #fff;
  }

  .mobile-nav-links a.active .nav-icon {
    color: var(--accent-red);
  }

  .nav-icon {
    display: block;
    transition: color var(--transition-fast);
  }

  .nav-profile-name {
    display: none; /* Mantém apenas avatar na barra superior móvel */
  }

  .hero {
    height: 55vh;
    min-height: 380px;
    padding: 0 4%;
    margin-bottom: 1rem;
  }

  .hero-title {
    /* font-size não é mais sobrescrito aqui: --text-hero (clamp) já chega em 2.2rem sozinho
       nesta largura — exatamente o valor que estava fixo aqui — e continua diminuindo suave
       abaixo disso, em vez de ficar travado em 2.2rem até a tela zerar. */
    line-height: 1.1;
  }

  .hero-overview {
    font-size: 0.95rem;
    line-height: 1.5;
    margin-bottom: 1.5rem;
    -webkit-line-clamp: 3;
  }

  .btn {
    padding: 0.75rem 1.5rem;
    font-size: 0.95rem;
  }

  .carousel-btn {
    display: none !important; /* Esconde setas em dispositivos móveis */
  }

  /* Busca Mobile */
  .search-results-section {
    padding: 5rem 4% 2rem;
  }

  .categories-page-section {
    padding: 5rem 4% 2rem;
  }

  /* Dois por linha no celular: o pôster fica grande o bastante para reconhecer o
     título de relance e ainda cabem 4 resultados sem rolar. */
  .search-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.8rem;
  }

  .search-results-head .section-title {
    font-size: 1.2rem;
  }

  /* Detalhes Modal */
  .modal-content {
    width: 95%;
    max-height: 88vh;
  }

  .modal-hero {
    height: 240px;
  }

  .modal-body {
    padding: 1.5rem 1.2rem;
  }

  .modal-title {
    font-size: 2rem;
  }

  .select-season {
    width: 100%;
  }

  /* Ajuste para o player no celular em pé (Portrait) */
  @media (orientation: portrait) {
    .player-modal {
      justify-content: center;
      background: #000;
    }

    .artplayer-container {
      width: 100%;
      height: auto !important;
      aspect-ratio: 16 / 9;
      flex: none;
    }
  }

  /* Player Mobile */
  .player-header {
    padding: 0.6rem 1rem;
    padding: calc(0.6rem + env(safe-area-inset-top)) calc(1rem + env(safe-area-inset-right))
             0.6rem calc(1rem + env(safe-area-inset-left));
    gap: 0.8rem;
    min-height: 50px;
  }

  .player-title {
    font-size: 0.95rem;
    /* 30vw cortava quase todo título em celular; o flex já limita pelo espaço que sobra. */
    max-width: none;
    flex: 1;
    min-width: 0;
  }

  .btn-back,
  .player-icon-btn {
    /* Alvos de toque de 40px — abaixo disso erra o dedo com o vídeo rodando atrás. */
    width: 40px;
    height: 40px;
    min-width: 40px;
    padding: 0;
    justify-content: center;
    border-radius: 50%;
    font-size: 1rem;
  }

  .btn-back span {
    display: none; /* Exibe apenas a seta "←" em celulares */
  }

  .player-server-selector {
    gap: 8px;
  }

  #headerSkipIntroBtn {
    padding: 6px 10px;
    font-size: 11px;
  }

  /* No celular a escolha de servidor vira folha; o <select> nativo sai de cena. */
  #serverSelectDropdown {
    display: none;
  }

  #serverSheetBtn {
    display: flex;
  }

  /* Controles nativos do ArtPlayer: os tamanhos padrão são pensados para mouse. */
  .artplayer-container .art-controls {
    height: 52px;
  }

  .artplayer-container .art-control {
    min-width: 44px;
  }

  .artplayer-container .art-icon svg {
    width: 24px;
    height: 24px;
  }

  /* Barra de progresso mais grossa: com o dedo é praticamente impossível pegar 4px. */
  .artplayer-container .art-progress .art-control-progress {
    height: 18px;
  }

  .artplayer-container .art-progress .art-progress-indicator {
    width: 14px;
    height: 14px;
    margin-left: -7px;
  }

  /* Em paisagem o notch fica na lateral e come o início dos controles. */
  .artplayer-container .art-bottom {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
    padding-bottom: env(safe-area-inset-bottom);
  }

  .seek-hint {
    width: 84px;
    height: 84px;
  }

  /* Pesquisa Mobile */
  .search-toggle-btn {
    display: flex;
  }

  .search-box {
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #0c0c0c;
    align-items: center;
    padding: 0 4%;
    z-index: 1010;
    animation: fadeInNavbarSearch 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  }

  .search-box.active {
    display: flex;
  }

  .search-box .search-input {
    width: 100% !important;
    max-width: 100%;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid var(--glass-border);
    border-radius: 30px;
    padding: 0.6rem 2.8rem;
    font-size: 0.95rem;
  }

  .search-box .search-input:focus {
    box-shadow: 0 0 15px rgba(229, 9, 20, 0.2);
    border-color: var(--accent-red);
  }

  .search-box .search-icon {
    left: calc(4% + 16px);
  }

  .search-box .search-close-btn {
    display: flex;
    position: absolute;
    right: calc(4% + 12px);
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
  }
}

@media (max-width: 600px) {
  .media-card {
    flex: 0 0 calc(50% - 0.6rem);
    min-width: 130px;
  }
  .modal-body {
    padding: 1.5rem 1rem;
  }
  .episode-card {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.8rem;
  }
  .episode-still-wrapper {
    width: 100%;
  }
  .episode-still {
    width: 100%;
  }
}

@keyframes fadeInNavbarSearch {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Categories Bar Styling */
.categories-section {
  padding: 1.5rem 4% 0.5rem 4%;
  position: relative;
  z-index: 10;
}

.categories-bar {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  overflow-x: auto;
  padding: 0.5rem 0;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.categories-bar::-webkit-scrollbar {
  display: none;
}

/* Setas ← → da barra de categorias — com 19 pills a barra estoura a largura no desktop e a
   scrollbar é escondida de propósito, então sem isto não dá pra rolar com o mouse. Ficam FORA da
   .categories-bar (que é recriada por JS), então sobrevivem a cada re-render. */
.categories-bar-wrapper {
  position: relative;
}

.categories-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(12, 12, 12, 0.9);
  border: 1px solid var(--glass-border);
  color: #fff;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

/* O atributo hidden perderia pro display:flex acima sem isto. */
.categories-arrow[hidden] {
  display: none;
}

.categories-arrow:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
}

.categories-arrow.prev {
  left: -4px;
  box-shadow: 14px 0 14px 6px var(--bg-color);
}

.categories-arrow.next {
  right: -4px;
  box-shadow: -14px 0 14px 6px var(--bg-color);
}

/* Mesmo critério das setas dos carrosséis: no toque a pessoa já arrasta com o dedo. */
@media (max-width: 768px), (hover: none) {
  .categories-arrow {
    display: none !important;
  }
}

.category-pill {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  color: var(--text-dimmed);
  padding: 0.6rem 1.4rem;
  /* Altura mínima de toque recomendada (~44px) — a altura calculada só pelo padding/texto
     ficava em ~36px, abaixo do recomendado num dos filtros mais usados do catálogo. */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  border-radius: 30px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease-out),
              background-color var(--dur-base) ease,
              border-color var(--dur-base) ease,
              box-shadow var(--dur-base) ease;
  backdrop-filter: blur(10px);
}

.category-pill:hover {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.25);
  transform: translateY(-2px);
}

/* Borda interna clara em vez de só o vermelho chapado — dá profundidade sem
   precisar de outra cor, e continua legível sobre qualquer fundo atrás dela. */
.category-pill.active {
  background: var(--accent-red);
  color: #fff;
  border-color: var(--accent-red);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.25), var(--shadow-red);
}

.hero-badge-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 1.2rem;
  flex-wrap: wrap;
}

.hero-sub-badge {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  padding: 0.25rem 0.7rem;
  font-size: 0.7rem;
  font-weight: 700;
  border-radius: 4px;
  letter-spacing: 0.5px;
  backdrop-filter: blur(5px);
}

.audio-badge {
  background: rgba(70, 211, 105, 0.15);
  border-color: rgba(70, 211, 105, 0.4);
  color: #46d369;
}

.categories-header {
  margin-bottom: 0.8rem;
}

.categories-title {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 1px;
}

/* Netflix Style Footer */
.footer {
  padding: 4rem 4% 3rem 4%;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  margin-top: 5rem;
  background: #080808;
  color: var(--text-muted);
}

.footer-content {
  max-width: 1000px;
  margin: 0 auto;
}

.footer-brand {
  font-size: 1.8rem;
  font-weight: 900;
  color: var(--accent-red);
  margin-bottom: 0.8rem;
  letter-spacing: -1px;
}

.footer-brand span {
  color: #fff;
}

.footer-desc {
  font-size: 0.95rem;
  margin-bottom: 2rem;
  color: var(--text-muted);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem 3rem;
  margin-bottom: 2.5rem;
}

.footer-links a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.85rem;
  transition: color var(--transition-fast);
}

.footer-links a:hover {
  color: #fff;
}

.footer-copyright {
  font-size: 0.8rem;
  /* Era #555 sobre fundo quase preto (~2.8:1) — abaixo do mínimo de contraste recomendado
     (4.5:1). --text-muted já é usado em várias outras partes do site e passa confortavelmente. */
  color: var(--text-muted);
}

/* Hero Slider Controls */
.hero-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 55px;
  height: 55px;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 100;
  font-size: 1.6rem;
  transition: all var(--transition-fast);
  /* Mesmo motivo do .carousel-btn acima — só aparecer no :hover deixa a seta invisível (e sem
     nenhum outro jeito de trocar de slide manualmente) em qualquer tela sem mouse. */
  opacity: 0.55;
  user-select: none;
}
.hero:hover .hero-arrow {
  opacity: 1;
}
.hero-arrow:hover {
  background: var(--accent-red);
  border-color: var(--accent-red);
  transform: translateY(-50%) scale(1.1);
  box-shadow: 0 0 15px rgba(229, 9, 20, 0.5);
}
.hero-arrow.prev {
  left: 3%;
}
.hero-arrow.next {
  right: 3%;
}

.hero-dots {
  position: absolute;
  bottom: 25px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 12px;
  z-index: 100;
}
.hero-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  cursor: pointer;
  transition: all var(--transition-fast);
}
.hero-dot:hover {
  background: rgba(255, 255, 255, 0.7);
}
.hero-dot.active {
  background: var(--accent-red);
  transform: scale(1.25);
  box-shadow: 0 0 10px rgba(229, 9, 20, 0.6);
}

/* ==========================================
   CUSTOM ARTPLAYER STYLING & AD LOCKING
   ========================================== */

/* Ocultação dos Controles e UI Nativa do Player durante Anúncio */
/* O ArtPlayer v5 identifica a camada pela classe "art-layer-<nome>" (não existe data-name),
   por isso a exceção precisa ser .art-layer-vastAdLayer — senão o próprio anúncio some. */
.artplayer-container.vast-ad-active .art-controls,
.artplayer-container.vast-ad-active .art-state,
.artplayer-container.vast-ad-active .art-loading,
.artplayer-container.vast-ad-active .art-mask,
.artplayer-container.vast-ad-active .art-layer:not(.art-layer-vastAdLayer) {
  display: none !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

/* Estilo do Botão de Tela Cheia no Cabeçalho */
#headerFullscreenBtn:hover {
  background: var(--accent-red) !important;
  border-color: var(--accent-red) !important;
  transform: scale(1.05);
}

#headerFullscreenBtn:active {
  transform: scale(0.95);
}

/* Container de Banner 728x90 no topo, antes do hero — discreto de propósito (sem borda/sombra
   pesada), já que fica isolado antes de qualquer conteúdo, diferente dos outros que ficam
   "dentro" do fluxo do catálogo. */
.ad-leaderboard-container {
  margin: 1rem auto !important;
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  min-height: 90px;
  width: 90% !important;
  max-width: 728px !important;
  overflow: hidden !important;
}

/* Container de Banner de Anúncios (Catalog Page) */
.ad-banner-container {
  margin: 3rem auto 1.5rem auto !important;
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  min-height: 250px;
  width: 90% !important;
  max-width: 320px !important;
  overflow: hidden !important;
  background: rgba(255, 255, 255, 0.02) !important;
  border-radius: 12px !important;
  border: 1px solid rgba(255, 255, 255, 0.05) !important;
  padding: 10px !important;
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.6) !important;
}

/* Espaço extra no mobile para evitar sobreposição com barra inferior */
@media (max-width: 768px) {
  .ad-banner-container {
    margin-bottom: 5.5rem !important;
  }
}

/* Container de Banner de Transição (Details Modal) */
.ad-transition-container {
  margin: 1.2rem auto !important;
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  min-height: 50px;
  width: 100% !important;
  max-width: 320px !important;
  overflow: hidden !important;
  background: rgba(255, 255, 255, 0.01) !important;
  border-radius: 8px !important;
  border: 1px solid rgba(255, 255, 255, 0.03) !important;
  padding: 4px !important;
}

/* ==========================================================================
   ESTADOS DE PRESSÃO (:active)
   Fica de propósito no fim do arquivo: cada :hover destes componentes é
   declarado lá em cima, perto de cada seção, com a mesma especificidade
   classe+pseudo-classe. Em empate de especificidade quem vem depois no
   arquivo vence — então isto só funciona (visualmente "afundar" o botão
   durante o clique, por cima do :hover que já está ativo) por estar aqui.
   Antes desta fase só existia UM :active no site inteiro (#headerFullscreenBtn,
   que já ganha de qualquer :hover por ser seletor de ID).
   ========================================================================== */

.btn:active,
.category-pill:active,
.carousel-btn:active,
.btn-clear-search:active,
.hero-arrow:active,
.server-btn:active,
.player-icon-btn:active,
.modal-close:active,
.btn-back:active {
  transform: scale(0.96);
  transition-duration: var(--dur-fast);
}

.media-card:active {
  transform: scale(1.03) translateY(-4px);
  transition-duration: var(--dur-fast);
}





/* Convite do Discord — cartão sobre a página ao entrar (ver maybeShowDiscordPrompt em app.js) */
.discord-prompt {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: rgba(0, 0, 0, 0.7);
}

.discord-prompt[hidden] {
  display: none;
}

.discord-prompt-card {
  width: 100%;
  max-width: 420px;
  padding: var(--space-6);
  background: var(--card-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  text-align: center;
}

.discord-prompt-title {
  margin: 0 0 var(--space-3);
  font-size: var(--text-xl);
  color: var(--text-main);
}

.discord-prompt-text {
  margin: 0 0 var(--space-5);
  font-size: var(--text-base);
  color: var(--text-dimmed);
  line-height: 1.5;
}

.discord-prompt-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.discord-prompt-join,
.discord-prompt-later {
  display: block;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-fast);
}

.discord-prompt-join {
  background: var(--accent-red);
  color: var(--text-main);
  border: none;
}

.discord-prompt-join:hover {
  background: var(--accent-red-hover);
}

.discord-prompt-later {
  background: transparent;
  color: var(--text-dimmed);
  border: 1px solid var(--glass-border);
}

.discord-prompt-later:hover {
  background: var(--glass-bg);
}
