/* ══════════════════════════════════════════════════════════════════════
   QVATUBE — Inicio (hero + reseñas + estadísticas)
   ══════════════════════════════════════════════════════════════════════ */

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero { padding: 6px 20px 14px; text-align: center; }

.hero-logo { display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
.hero-logo-img { height: 64px; width: auto; display: block; }

.hero-tagline {
  font-family: var(--f-display); font-size: 17px; letter-spacing: 0.4px;
  color: var(--text); margin-bottom: 10px;
}

.hero-desc {
  color: var(--text-2); font-size: 13px; line-height: 1.6;
  max-width: 380px; margin: 0 auto 20px;
}

/* Fila única con los dos llamados a la acción, mitad y mitad (mismo
   max-width:360px que el recuadro de arriba). */
.hero-actions {
  display: flex; gap: 8px; max-width: 360px; margin: 0 auto;
}
.hero-suggest-btn, .hero-telegram-btn {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 12px 6px; border: none; border-radius: var(--r); cursor: pointer;
  text-decoration: none; font-weight: 700; font-size: 13px; white-space: nowrap;
}
.hero-suggest-btn span, .hero-telegram-btn span { overflow: hidden; text-overflow: ellipsis; }
.hero-suggest-btn svg, .hero-telegram-btn svg, .hero-suggest-btn .icon { flex-shrink: 0; }
/* "Sugerir contenido": accent sólido de la marca. */
.hero-suggest-btn { background: var(--accent); color: var(--accent-ink); }
/* "Súbelo tú mismo": azul de Telegram (se lee "te lleva a Telegram"). */
.hero-telegram-btn { background: #229ED9; color: #fff; }
.hero-suggest-btn:active, .hero-telegram-btn:active { transform: scale(.98); }
/* Segunda fila (WhatsApp + APK): misma forma que la de arriba. WhatsApp en
   su verde de marca; la app en claro para que no se confunda con el acento
   ni con el azul de Telegram. */
.hero-actions-more { margin-top: 8px; }
.hero-whatsapp-btn, .hero-apk-btn {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 12px 6px; border: none; border-radius: var(--r); cursor: pointer;
  text-decoration: none; font-weight: 700; font-size: 13px; white-space: nowrap;
  font-family: inherit;
}
.hero-whatsapp-btn span, .hero-apk-btn span { overflow: hidden; text-overflow: ellipsis; }
.hero-whatsapp-btn svg, .hero-apk-btn svg, .hero-whatsapp-btn .icon, .hero-apk-btn .icon { flex-shrink: 0; }
.hero-whatsapp-btn { background: #25D366; color: #06210f; }
.hero-apk-btn { background: #f5f4f0; color: #0a0a0b; }
.hero-whatsapp-btn:active, .hero-apk-btn:active { transform: scale(.98); }
.hero-telegram-hint {
  max-width: 360px; margin: 8px auto 0; color: var(--text-2); font-size: 11px; line-height: 1.5;
}

/* ── Banner de colaboraciones (debajo del Hero) ──────────────────────────
   Ver loadCollabBanners/renderCollabCard en app.js — administrable desde
   /admin → Colaboraciones. Cada foto (redonda, recortada a cuadrado en el
   servidor — ver services/collab_images.py) lleva su nombre centrado
   justo debajo, con una "X" estilizada (sin círculo de fondo, solo el
   trazo con glow) entre ambas. El glow de arriba y el de la propia
   tarjeta laten suavemente (animation) para que el bloque se sienta vivo
   sin ser invasivo — respeta prefers-reduced-motion (ver tokens.css). */
.collab-banner-wrap { margin: 12px 20px 0; display: flex; flex-direction: column; gap: 12px; }
.collab-card {
  position: relative; overflow: hidden; padding: 28px 18px 22px;
  border-radius: var(--r-lg); border: 1px solid var(--border);
  background: linear-gradient(160deg, var(--surface-2), var(--surface) 75%);
  text-align: center;
  animation: collab-card-glow 5s ease-in-out infinite;
}
.collab-card::before {
  content: ''; position: absolute; top: -70%; left: 50%;
  width: 300px; height: 260px;
  background: radial-gradient(ellipse, rgba(255,61,26,.26), transparent 70%);
  pointer-events: none;
  animation: collab-glow-pulse 5s ease-in-out infinite;
}
@keyframes collab-card-glow {
  0%, 100% { box-shadow: 0 0 0 1px rgba(255,61,26,.06), 0 0 22px rgba(255,61,26,.06); }
  50%      { box-shadow: 0 0 0 1px rgba(255,61,26,.14), 0 0 42px rgba(255,61,26,.22); }
}
@keyframes collab-glow-pulse {
  0%, 100% { opacity: .55; transform: translateX(-50%) scale(1) rotate(0deg); }
  50%      { opacity: 1;   transform: translateX(-56%) scale(1.3) rotate(6deg); }
}
.collab-row {
  position: relative; z-index: 1;
  display: flex; align-items: flex-start; justify-content: center; gap: 26px; margin-bottom: 14px;
}
.collab-person { display: flex; flex-direction: column; align-items: center; gap: 9px; width: 88px; min-width: 0; }
.collab-avatar {
  width: 76px; height: 76px; border-radius: 50%; overflow: hidden; flex-shrink: 0;
  background: var(--surface-2); border: 2px solid var(--border);
  box-shadow: 0 0 0 1px var(--border-soft), 0 4px 16px rgba(0,0,0,.35);
}
.collab-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.collab-person-name {
  font-family: var(--f-display); font-size: 14.5px; letter-spacing: .3px; color: var(--text);
  line-height: 1.25; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.collab-x-mark {
  position: relative; z-index: 1; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent); margin-top: 24px;
  filter: drop-shadow(0 0 8px rgba(255,61,26,.55));
  animation: collab-x-pulse 2.6s ease-in-out infinite;
}
@keyframes collab-x-pulse {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 6px rgba(255,61,26,.45)); }
  50%      { transform: scale(1.15); filter: drop-shadow(0 0 14px rgba(255,61,26,.85)); }
}
.collab-desc {
  position: relative; z-index: 1;
  color: var(--text-2); font-size: 12.5px; line-height: 1.6;
  max-width: 380px; margin: 6px auto 0;
}
/* Ver _formatRichText() en app.js — **negrita** en la descripción, escrita
   desde el <textarea> plano del admin, se resuelve a esto. */
.collab-desc strong { color: var(--text); font-weight: 700; }

/* ── Opiniones (al fondo de Inicio, después de Estadísticas) ────────────
   Ver loadTestimonials/renderTestimonialCard en app.js — administrable
   desde /admin → Opiniones. A diferencia de la tarjeta de colaboración
   (vertical, dos personas), acá es una sola fila horizontal: foto
   redonda + nombre en tipografía normal a la izquierda, descripción en
   itálica al lado — mismo criterio de recorte a cuadrado en el servidor
   que collab-avatar (ver services/testimonial_images.py). */
.testimonials-wrap { display: flex; flex-direction: column; gap: 12px; }
.testimonial-card {
  display: flex; align-items: center; gap: 16px;
  padding: 16px 18px; border-radius: var(--r-lg); border: 1px solid var(--border);
  background: var(--surface-2);
}
.testimonial-person {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  width: 76px; flex-shrink: 0;
}
.testimonial-photo {
  width: 64px; height: 64px; border-radius: 50%; overflow: hidden; flex-shrink: 0;
  background: var(--surface); border: 2px solid var(--border);
  box-shadow: 0 0 0 1px var(--border-soft);
}
.testimonial-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.testimonial-name {
  font-family: var(--f-body); font-style: normal; font-weight: 600; font-size: 12.5px;
  color: var(--text); text-align: center; line-height: 1.25;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.testimonial-desc {
  flex: 1; min-width: 0;
  color: var(--text-2); font-style: italic; font-size: 13px; line-height: 1.6;
}

/* ── Colaboradores oficiales ───────────────────────────────────────────
   Ver loadOfficialPartners/renderPartnerCard en app.js. A diferencia de
   .testimonial-card (foto+nombre en fila, para una cita corta), acá la
   tarjeta es vertical y centrada porque hay un botón abajo — layout de
   "perfil" en vez de layout de "cita". */
.partners-wrap { display: flex; flex-direction: column; gap: 12px; padding: 0 20px; }
.partner-card {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px;
  padding: 22px 18px; border-radius: var(--r-lg); border: 1px solid var(--border); background: var(--surface-2);
}
.partner-photo {
  width: 72px; height: 72px; border-radius: 50%; overflow: hidden; flex-shrink: 0;
  background: var(--surface); border: 2px solid var(--border);
}
.partner-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.partner-name { font-family: var(--f-display); font-size: 15px; color: var(--text); }
.partner-desc { color: var(--text-2); font-size: 12.5px; line-height: 1.6; max-width: 380px; }
.partner-cta {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 4px;
  padding: 9px 20px; border-radius: 999px; background: var(--accent); color: #fff;
  font-weight: 700; font-size: 12.5px; text-decoration: none;
}
.partner-cta:active { transform: scale(.97); }

/* ── Seguir donde quedaste ────────────────────────────────────────────
   Ver renderContinueCard/loadContinueWatching en app.js — reutiliza
   .card/.card-media/.recent-row del catálogo (layout.css), esto solo
   ajusta el espaciado del bloque como sección propia del home. */
.continue-row-wrap { margin-bottom: 8px; }
/* Título de "Recomendaciones": siempre en UNA línea. En temporada suma
   ": Especial <temporada>" resaltado con el color de acento. */
.reco-title span:not(.genre-ico) { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.reco-title .reco-season { font-style: normal; color: var(--accent); }
/* En esta fila las tarjetas no llevan los botones de "ya visto" ni de
   favorito de la esquina superior (en el catálogo normal sí): acá solo se
   muestra el detalle y se abre la ficha. */
#recoRow .card-watch, #recoRow .card-favorite { display: none; }
.hero-feature span { color: var(--text); }

/* ── Banner de descarga del APK ─────────────────────────────────────────
   A propósito más llamativo que el resto de la home (gradiente del
   acento + glow), porque es justo lo que pidió Andrés: que salte a la
   vista entre el hero y "Cómo funciona", no que se confunda con una
   tarjeta informativa más. */
.apk-banner {
  position: relative; overflow: hidden; margin: 10px 20px 0;
  display: flex; align-items: center; gap: 14px; padding: 16px 18px;
  border-radius: var(--r-lg); border: 1px solid rgba(255,61,26,.35);
  background: linear-gradient(135deg, rgba(255,61,26,.16), rgba(255,61,26,.04) 60%, transparent);
}
.apk-banner-glow {
  position: absolute; inset: -40% -20% auto auto; width: 160px; height: 160px;
  background: radial-gradient(circle, rgba(255,61,26,.35), transparent 70%);
  pointer-events: none;
}
.apk-banner-icon {
  flex-shrink: 0; width: 46px; height: 46px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.apk-banner-text { flex: 1; min-width: 0; text-align: left; }
.apk-banner-title { font-family: var(--f-display); font-size: 16px; letter-spacing: .3px; color: var(--text); }
.apk-banner-sub { font-size: 11.5px; color: var(--text-2); margin-top: 2px; line-height: 1.4; }
.apk-banner-btn {
  flex-shrink: 0; display: flex; align-items: center; gap: 7px;
  background: var(--accent); color: var(--accent-ink); font-weight: 700; font-size: 12.5px;
  padding: 10px 14px; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 6px 18px rgba(255,61,26,.35);
}
.apk-banner-btn:active { transform: scale(.96); }

@media (max-width: 420px) {
  .apk-banner { flex-wrap: wrap; }
  .apk-banner-btn { width: 100%; justify-content: center; }
}

/* ── Banner de la comunidad de WhatsApp ──────────────────────────────────
   Mismo patrón visual que .apk-banner de arriba, y AHORA también la misma
   paleta (acento naranja del sitio) en vez de verde — pedido explícito de
   Andrés: el verde desentonaba con el resto de la web. Vive en la primera
   sección de Inicio, justo debajo del hero — antes estaba al fondo de la
   página junto a reseñas/estadísticas y pedía bajar de más. */
.whatsapp-banner {
  position: relative; overflow: hidden; margin: 10px 20px 0;
  display: flex; align-items: center; gap: 14px; padding: 16px 18px;
  border-radius: var(--r-lg); border: 1px solid rgba(255,61,26,.35);
  background: linear-gradient(135deg, rgba(255,61,26,.16), rgba(255,61,26,.04) 60%, transparent);
}
.whatsapp-banner-glow {
  position: absolute; inset: -40% -20% auto auto; width: 160px; height: 160px;
  background: radial-gradient(circle, rgba(255,61,26,.35), transparent 70%);
  pointer-events: none;
}
.whatsapp-banner-icon {
  flex-shrink: 0; width: 46px; height: 46px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.whatsapp-banner-text { flex: 1; min-width: 0; text-align: left; }
.whatsapp-banner-title { font-family: var(--f-display); font-size: 16px; letter-spacing: .3px; color: var(--text); }
.whatsapp-banner-sub { font-size: 11.5px; color: var(--text-2); margin-top: 2px; line-height: 1.4; }
.whatsapp-banner-btn {
  flex-shrink: 0; display: flex; align-items: center; gap: 7px;
  background: var(--accent); color: var(--accent-ink); font-weight: 700; font-size: 12.5px;
  padding: 10px 14px; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 6px 18px rgba(255,61,26,.35);
}
.whatsapp-banner-btn:active { transform: scale(.96); }

@media (max-width: 420px) {
  .whatsapp-banner { flex-wrap: wrap; }
  .whatsapp-banner-btn { width: 100%; justify-content: center; }
}

/* ── Bloques informativos nuevos (Cómo funciona / Compatibilidad / Antes
   de empezar) ────────────────────────────────────────────────────────
   Arrancan invisibles y se revelan con fade+slide al entrar en pantalla
   (ver setupHomeReveal en app.js) — mismo mecanismo (clase agregada por
   IntersectionObserver) que .home-secondary usa por tap, pero disparado
   por scroll en vez de por click. */
.home-info-block[data-reveal] {
  opacity: 0; transform: translateY(18px);
  transition: opacity .6s ease, transform .6s ease;
}
.home-info-block.revealed { opacity: 1; transform: translateY(0); }

/* ── Cómo funciona: pasos numerados ──────────────────────────────────── */
.how-steps { display: flex; flex-direction: column; gap: 10px; padding: 0 20px; }
.how-step {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r);
  padding: 13px 14px;
}
.how-step-num {
  flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--f-display); font-size: 14px; line-height: 1;
}
.how-step-title { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 3px; }
.how-step-desc { font-size: 12px; color: var(--text-2); line-height: 1.5; }

/* ── Compatible con cualquier pantalla ───────────────────────────────── */
.device-row { display: flex; gap: 10px; padding: 0 20px; }
.device-chip {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r);
  padding: 14px 8px; color: var(--text); font-size: 12px; font-weight: 500;
}
.device-chip .icon { color: var(--accent); }
.device-hint { font-size: 11.5px; color: var(--text-3); text-align: center; margin: 10px 20px 0; line-height: 1.5; }

/* ── Antes de empezar: tarjeta de avisos ─────────────────────────────── */
.notice-card {
  margin: 0 20px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r);
  padding: 14px 16px;
}
.notice-list { list-style: none; display: flex; flex-direction: column; gap: 12px; }
.notice-list li { display: flex; gap: 10px; align-items: flex-start; }
.notice-list .icon { color: var(--accent); flex-shrink: 0; margin-top: 1px; }
.notice-list span { font-size: 12.5px; color: var(--text-2); line-height: 1.55; }

/* ── Flecha para revelar reseñas/estadísticas ────────────────────────────
   Circular, con un glow pulsante en el color de marca — la idea es que
   se note sin gritar, invitando a bajar en vez de arrancar la home con
   todo (reseñas + stats) ya visible de una. Ver revealHomeSecondary en
   app.js. rgba() hardcodeado (no color-mix) por compatibilidad con los
   navegadores viejos de Smart TV. */
.home-scroll-arrow-wrap {
  display: flex; justify-content: center; margin-top: 30px;
  transition: opacity .5s ease;
}
.home-scroll-arrow-wrap.used { opacity: .35; }
.home-scroll-arrow {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: transform .15s ease;
  animation: home-arrow-pulse 2.4s ease-in-out infinite;
}
.home-scroll-more:active .home-scroll-arrow { transform: scale(.9); }
/* Botón "Ver más": etiqueta visible arriba + círculo con la flecha. Todo
   el conjunto es el botón (tocar el texto o la flecha hace lo mismo). */
.home-scroll-more {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--text); font: inherit;
}
.home-scroll-more-label { font-size: 14px; font-weight: 600; letter-spacing: .2px; }
@keyframes home-arrow-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(255,61,26,.55), 0 4px 20px rgba(255,61,26,.4); }
  70%  { box-shadow: 0 0 0 16px rgba(255,61,26,0), 0 4px 20px rgba(255,61,26,.4); }
  100% { box-shadow: 0 0 0 0 rgba(255,61,26,0), 0 4px 20px rgba(255,61,26,.4); }
}

/* ── Sección secundaria (reseñas + estadísticas) ─────────────────────────
   Arranca oculta (home-secondary-hidden = display:none) y se revela con
   fade + slide hacia arriba al tocar la flecha (ver revealHomeSecondary
   en app.js), que primero saca "-hidden" y fuerza un reflow antes de
   agregar ".show" — así el navegador SÍ anima la transición en vez de
   saltar directo al estado final (pasar de display:none a visible no es
   animable por sí solo). */
.home-secondary {
  opacity: 0; transform: translateY(18px);
  transition: opacity .5s ease, transform .5s ease;
}
.home-secondary.home-secondary-hidden { display: none; }
.home-secondary.show { opacity: 1; transform: translateY(0); }

/* ── Reseñas ──────────────────────────────────────────────────────────── */
.reviews-section { padding: 0 20px; text-align: left; }

.reviews-summary { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.reviews-avg { font-family: var(--f-display); font-size: 34px; color: var(--accent); line-height: 1; }
.reviews-stars { color: var(--accent); font-size: 15px; letter-spacing: 2px; }
.reviews-count { font-size: 11.5px; color: var(--text-2); margin-top: 2px; }

.review-card {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r);
  padding: 12px 14px; margin-bottom: 8px;
}
.review-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.review-avatar {
  width: 24px; height: 24px; border-radius: 50%; object-fit: cover; flex-shrink: 0;
}
.review-avatar-fallback {
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent); font-weight: 700; font-size: 11px;
}
.review-name {
  font-size: 12.5px; font-weight: 600; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.review-stars { color: var(--accent); font-size: 11px; letter-spacing: 1px; flex-shrink: 0; }
.review-comment { font-size: 12.5px; color: var(--text-2); line-height: 1.55; }

.review-form { margin-top: 16px; }
.star-picker { display: flex; gap: 8px; justify-content: center; font-size: 30px; margin-bottom: 10px; }
.star-picker span { color: var(--border); cursor: pointer; transition: color .15s ease; }
.star-picker span.active { color: var(--accent); }
.review-form textarea {
  width: 100%; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 11px; color: var(--text); font-family: var(--f-body); font-size: 13px; resize: vertical; min-height: 64px;
  outline: none;
}
.review-form textarea:focus { border-color: var(--accent); }

/* ── Estadísticas ─────────────────────────────────────────────────────── */
.stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; padding: 0 20px; }
.stat-card {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r);
  padding: 16px 10px; text-align: center;
}
.stat-value { font-family: var(--f-display); font-size: 25px; color: var(--accent); }
.stat-label { font-size: 10.5px; color: var(--text-2); margin-top: 4px; }

/* ── Pie de página (solo Inicio, al final del todo) ──────────────────────
   Copyright + enlace a Términos/Privacidad (ver showWelcome() en app.js
   y web/static/terms.html). El enlace en rojo/acento es lo único
   "clickeable" a propósito, como en cualquier web normal. */
.site-footer {
  text-align: center; padding: 26px 20px 4px; margin-top: 8px;
  border-top: 1px solid var(--border-soft);
}
.site-footer p { font-size: 11.5px; color: var(--text-3); margin-bottom: 8px; }
.site-footer-link { color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }

/* ── Filas por género (Acción, Comedia, Terror, Ciencia ficción...) ─────
   Mismo estilo que "Seguir donde quedaste" / "Recomendaciones" (reutilizan
   .continue-row-wrap, .section-title, .recent-row y las tarjetas normales
   del catálogo), solo que cada fila lleva SU color: app.js fija
   --genre-accent (#rrggbb) y --genre-rgb ("r,g,b") en cada fila. Se usa
   rgba(var(--genre-rgb)) y no color-mix() para que se vea igual en
   celulares Android y Smart TVs viejos. Ver loadGenreRows() en app.js. */
.genre-rows { min-height: 1px; }
.genre-row { margin-bottom: 14px; padding-top: 2px; }
.genre-title { position: relative; align-items: center; }
.genre-ico {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 8px; color: var(--genre-accent, var(--accent));
  background: rgba(var(--genre-rgb, 255, 61, 26), .16);
  box-shadow: inset 0 0 0 1px rgba(var(--genre-rgb, 255, 61, 26), .38);
}
.genre-name { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* La línea que "corta" el título nace del color del género y se apaga. */
.genre-title::after { background: linear-gradient(90deg, rgba(var(--genre-rgb, 255, 61, 26), .6), transparent); }
/* Borde fino del color del género en cada póster. Va DENTRO de la tarjeta
   (capa ::after) y no como box-shadow: el sombreado de 1px queda por fuera
   de la tarjeta y .recent-row (overflow-x:auto, sin padding arriba) lo
   recortaba en el borde superior, dejando la línea "rota" arriba. */
.genre-row .card-media { box-shadow: none; }
.genre-row .card-media::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  border: 1px solid rgba(var(--genre-rgb, 255, 61, 26), .42);
}
/* Igual que en Recomendaciones: sin los botones de "visto" y "favorito". */
.genre-row .card-watch, .genre-row .card-favorite { display: none; }

/* ══════════════════════════════════════════════════════════════════════
   Esqueletos de carga (Inicio)
   Bloques gris oscuro con un brillo que pasa (keyframes `shimmer`, ver
   layout.css). Ocupan el MISMO espacio que el contenido real para que, al
   llegar los datos, nada se mueva. Los arma app.js (skel*Html) y, para el
   primer pintado, index.html (#bootSkel, #onlineBanner, #catTabs).
   ══════════════════════════════════════════════════════════════════════ */
.sk-bar, .sk-box, .sk-btn, .sk-hero-block {
  position: relative; overflow: hidden; background: var(--surface);
}
.sk-bar::after, .sk-box::after, .sk-btn::after, .sk-hero-block::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.05) 50%, transparent 70%);
  background-size: 250% 100%; animation: shimmer 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .sk-bar::after, .sk-box::after, .sk-btn::after, .sk-hero-block::after,
  .card-skeleton { animation: none; }
}

/* Filas en esqueleto: color neutro (el !important gana al style inline que
   les pone el color de su género; al quitar data-skel vuelve el real). */
.genre-row[data-skel] { --genre-accent: #3a3a3f !important; --genre-rgb: 58, 58, 63 !important; }
.genre-row[data-skel] .card-media::after { border-color: transparent; }
.genre-title .genre-ico.sk-box { background: var(--surface); box-shadow: none; }
.genre-title .sk-name { display: block; width: 150px; height: 14px; border-radius: 4px; }
.sk-card { pointer-events: none; }
.sk-card-title { margin-top: 7px; height: 31.7px; display: flex; flex-direction: column; justify-content: center; gap: 5px; }
.sk-card-title .sk-bar { display: block; height: 9px; border-radius: 4px; }
.sk-card-title .sk-bar:last-child { width: 62%; }
.sk-card-sub { margin-top: 2px; height: 13px; display: flex; align-items: center; }
.sk-card-sub .sk-bar { display: block; width: 45%; height: 8px; border-radius: 4px; }

/* Botones del hero en esqueleto: usan las MISMAS clases que los reales
   (mismo alto exacto) pero grises y sin texto visible. */
.hero-actions .sk-btn { background: var(--surface); color: transparent; pointer-events: none; cursor: default; }
.sk-ico { display: block; width: 16px; height: 16px; flex-shrink: 0; }

/* Hero inicial (index.html #bootSkel): mismas medidas que showWelcome. */
.sk-hero-block { border-radius: 5px; }
.sk-desc { display: flex; flex-direction: column; gap: 7.8px; padding: 3.9px 0; max-width: 380px; margin: 0 auto 20px; }
.sk-desc > i { display: block; height: 13px; }
.sk-desc > i:last-child { width: 55%; }

/* Barra "conectados / viendo / nuevo hoy / hoy" (header): alto FIJO, esté
   cargando o no, para que al llegar los números el header no crezca y
   empuje todo el contenido hacia abajo. */
.online-banner { height: 20px; overflow-y: hidden; }
.online-banner .sk-pill { display: block; width: 64px; height: 8px; border-radius: 4px; flex-shrink: 0; }

/* Barra inferior: círculos grises hasta que buildTabs() pone los íconos. */
.cat-btn .sk-tab { display: block; width: 21px; height: 21px; border-radius: 50%; }

/* Cuadrícula de esqueletos de las secciones de contenido (skelGridHtml en
   app.js): misma .grid que las tarjetas reales; en pantallas anchas hay más
   columnas, así que se recorta a un poco más que el alto de la pantalla. */
.grid-skel { max-height: 120vh; overflow: hidden; }
.az-group-divider .sk-letter { display: block; width: 18px; height: 17px; border-radius: 4px; }

/* ── Esqueletos del panel de información (series, películas, álbumes) ──
   El panel es más claro que --surface, así que se usa --surface-2. */
.info-panel .sk-bar, .info-panel .sk-btn { background: var(--surface-2); }
.info-panel .sk-btn { color: transparent; border-color: transparent; pointer-events: none; }
.info-panel .auth-btn.sk-btn, .info-panel .auth-btn.secondary.sk-btn { background: var(--surface-2); color: transparent; border-color: transparent; }
.sk-circle { display: block; flex-shrink: 0; border-radius: 50%; }
.sk-yr { height: 15px; margin-bottom: 12px; display: flex; align-items: center; }
.sk-yr .sk-bar { width: 72px; height: 10px; border-radius: 4px; }
.sk-ln { height: 21.6px; display: flex; align-items: center; }            /* 13.5px × 1.6 */
.sk-ln .sk-bar { height: 11px; border-radius: 4px; }
.cast-title .sk-cast-title { display: inline-block; width: 110px; height: 10px; border-radius: 4px; vertical-align: middle; }
.sk-cn, .sk-cc { display: flex; align-items: center; justify-content: center; }
.sk-cn { height: 13px; } .sk-cc { height: 11px; }
.sk-cn .sk-bar { width: 80%; height: 8px; border-radius: 4px; }
.sk-cc .sk-bar { width: 58%; height: 7px; border-radius: 4px; }
.sk-note { margin-top: 8px; height: 13px; display: flex; align-items: center; justify-content: center; }
.sk-note .sk-bar { width: 170px; height: 8px; border-radius: 4px; }
.sk-t1 { height: 16px; display: flex; align-items: center; }
.sk-t2 { height: 13px; margin-top: 2px; display: flex; align-items: center; }
.sk-t1 .sk-bar { height: 10px; border-radius: 4px; }
.sk-t2 .sk-bar { height: 8px; border-radius: 4px; }

/* ── Esqueletos del "Ver más" (Home 2) ─────────────────────────────────────
   Se arman con las mismas clases de las tarjetas reales (skel*Html en app.js);
   aquí solo se fijan las alturas de las barras para que ocupen lo mismo que
   el texto. Las barras usan --surface (más oscuro que las tarjetas --surface-2). */
.sk-line { display: block; height: 11px; border-radius: 4px; }
.sk-desc2 { width: 100%; max-width: 380px; display: flex; flex-direction: column; gap: 8px; padding: 4px 0; }
.sk-desc2 .sk-line { height: 12px; }
.sk-desc2 .sk-line:last-child { width: 60%; }
.sk-partner, .sk-collab, .sk-testimonial, .sk-stat, .review-card[aria-hidden] { pointer-events: none; }
.sk-partner .partner-name { height: 18px; }
.sk-cta { display: block; width: 116px; height: 35px; border-radius: 999px; margin-top: 4px; }
/* La tarjeta de colaboración real tiene un destello animado: el esqueleto no. */
.collab-card.sk-collab { animation: none; background: var(--surface-2); }
.collab-card.sk-collab::before { display: none; }
.sk-collab .collab-person-name { height: 18px; }
.sk-collab .sk-desc2 { margin: 6px auto 0; }
.sk-x { display: block; flex-shrink: 0; width: 26px; height: 26px; margin-top: 24px; border-radius: 50%; }
.sk-testimonial .sk-desc2 { flex: 1; min-width: 0; padding: 0; }
.sk-stat .sk-line { display: block; }
.review-avatar.sk-box { display: block; }


/* ── Modal "Descargas" (Lite / completa / PC) ───────────────────────────
   Reusa .modal-overlay / .modal-box (player.css). Tarjetas con los tokens
   del sitio; la caja puede scrollear en pantallas bajitas. */
.dl-modal-box { max-height: 90vh; overflow-y: auto; }
.dl-list { display: flex; flex-direction: column; gap: 10px; margin: 16px 0 12px; text-align: left; }
.dl-card {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r);
  padding: 14px; display: flex; flex-direction: column; gap: 10px;
}
.dl-card-head { display: flex; align-items: center; gap: 10px; }
.dl-card-ico {
  width: 36px; height: 36px; flex-shrink: 0; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent);
}
.dl-card-title { font-family: var(--f-display); font-size: 16px; letter-spacing: .3px; color: var(--text); line-height: 1.2; }
.dl-card-meta { font-size: 11px; color: var(--text-3); margin-top: 2px; }
.dl-card-desc { font-size: 12px; line-height: 1.5; color: var(--text-2); margin: 0; }
.dl-card .auth-btn {
  margin-top: 0; display: flex; align-items: center; justify-content: center; gap: 6px;
  text-decoration: none; width: 100%;
}
.dl-card.is-soon { opacity: .85; border-style: dashed; }


/* ── Transición entre secciones (selectCatAnimated en app.js) ───────────
   View Transitions: SOLO #content se anima (deslizamiento corto en la
   dirección del cambio + fundido cruzado sin "bache" oscuro: las dos capas
   se suman con mix-blend-mode plus-lighter, que es el valor por defecto del
   navegador); cabecera y barra inferior quedan fijas y vivas (la píldora
   de la barra sigue animándose). Todo corre en el compositor. */
#content { view-transition-name: qva-content; }
::view-transition-old(root) { display: none; }
::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
::view-transition-old(qva-content),
::view-transition-new(qva-content) { animation-duration: .26s; animation-fill-mode: both; }
::view-transition-old(qva-content) { animation-name: qvaFadeOut, qvaSlideOutNext; animation-timing-function: linear, cubic-bezier(.4,0,.2,1); }
::view-transition-new(qva-content) { animation-name: qvaFadeIn, qvaSlideInNext; animation-timing-function: linear, cubic-bezier(.22,1,.36,1); }
html[data-vt-dir="prev"]::view-transition-old(qva-content) { animation-name: qvaFadeOut, qvaSlideOutPrev; }
html[data-vt-dir="prev"]::view-transition-new(qva-content) { animation-name: qvaFadeIn, qvaSlideInPrev; }
@keyframes qvaFadeOut { to { opacity: 0; } }
@keyframes qvaFadeIn { from { opacity: 0; } }
@keyframes qvaSlideOutNext { to { transform: translate3d(-28px, 0, 0); } }
@keyframes qvaSlideInNext { from { transform: translate3d(28px, 0, 0); } }
@keyframes qvaSlideOutPrev { to { transform: translate3d(28px, 0, 0); } }
@keyframes qvaSlideInPrev { from { transform: translate3d(-28px, 0, 0); } }
/* La capa de la View Transition se pinta POR ENCIMA de toda la página (top
   layer), incluidas las barras fijas: la foto de #content mide de la
   cabecera al borde inferior, o sea que también cubría .bottom-nav y, con el
   fundido, la barra se veía transparente (se rompía la inmersión). Dos
   arreglos: (1) el grupo de #content se recorta justo encima de la barra
   inferior; (2) lo que flota sobre el contenido (mini-player e índice A-Z)
   tiene nombre propio — así se captura aparte, queda por encima de
   #content (orden de pintado) y sigue vivo, sin animación. */
::view-transition-group(qva-content) { clip-path: inset(0 0 var(--bottom-nav-h, 60px) 0); }
.mini-player.show { view-transition-name: qva-mini; }
.az-index { view-transition-name: qva-az; }
::view-transition-group(qva-mini), ::view-transition-group(qva-az) { animation: none; }
::view-transition-old(qva-mini), ::view-transition-old(qva-az) { display: none; }
::view-transition-new(qva-mini), ::view-transition-new(qva-az) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* Respaldo sin View Transitions (WebViews viejos): deslizamiento corto del
   contenedor, sin bajar tanto la opacidad (antes dejaba un parpadeo oscuro). */
@keyframes gestureInNext { from { opacity: .7; transform: translate3d(18px, 0, 0); } to { opacity: 1; transform: none; } }
@keyframes gestureInPrev { from { opacity: .7; transform: translate3d(-18px, 0, 0); } to { opacity: 1; transform: none; } }
.content.gesture-in-next { animation: gestureInNext .2s cubic-bezier(.22,1,.36,1); }
.content.gesture-in-prev { animation: gestureInPrev .2s cubic-bezier(.22,1,.36,1); }
/* Mientras se arrastra un panel hacia abajo, sin rebote nativo ni pull-to-refresh. */
.info-panel, .auth-panel, .dl-modal-box { overscroll-behavior: contain; }

/* Arranque en la última sección (caché inteligente): no se enseña el
   esqueleto de Inicio un instante antes de pintar la sección guardada. */
html.boot-resume #bootSkel { display: none; }
