  :root{
    --bg:#0b0c10;
    --bg-soft:#0f1015;
    --bg-elev:rgba(21,23,29,0.62);
    --bg-elev-2:rgba(28,31,38,0.72);
    --bg-elev-solid:#15171d;
    --border:rgba(255,255,255,0.08);
    --border-strong:rgba(255,255,255,0.16);
    --text:#f3f4f7;
    --text-dim:#9398a6;
    --accent:#e50914;
    /* Antes #ff2d3c: como fondo de gradiente con texto blanco encima (.btn-primary, .new-ribbon,
       #btnRecomendar.active) el extremo más claro del gradiente daba solo 3.69:1 de contraste con
       blanco -- por debajo del 4.5:1 que pide WCAG AA para texto normal (el texto de esos casos es
       chico, 9-14px, no cuenta como "texto grande"). Este tono es apenas más profundo: mismo matiz,
       casi el mismo impacto visual, pero 4.6:1+ con blanco en todo el gradiente. */
    --accent-2:#eb0011;
    --accent-dim:#7a0610;
    --accent-glow:rgba(229,9,20,0.45);
    --gold:#f5c518;
    --amber:#caa53a;
    --blue:#4a90d9;
    --purple:#9d7cd8;
    --gray:#5a6472;
    --danger:#ff5c5c;
    --radius:14px;
    --radius-sm:9px;
    --radius-lg:20px;
    --blur:20px;
    --vignette-strength: 220px;
    --vignette-alpha: 0.6;
    /* shadow-soft llevaba SOLO sombra negra -- invisible contra el fondo casi negro (--bg) de este
       tema, que es justo por lo que la app se sentía "plana"/"emplastada" en reposo aunque ya se
       usara box-shadow:var(--shadow-soft) en tarjetas, avatares y modales (ver panel-poster,
       profile-circle, detail-poster, etc). La sombra solo se notaba al hover, cuando además se le
       sumaba un borde claro (ver .panel-item:hover .panel-poster). Agregar ese mismo borde de 1px
       también en reposo es lo que de verdad da profundidad sobre un fondo oscuro -- la sombra casi
       no se ve, el borde sí. No cambia tamaños ni disposición, solo hace visible el relieve que ya
       existía en el código. */
    --shadow-soft: 0 10px 30px rgba(0,0,0,0.35), 0 0 0 1px rgba(255,255,255,0.055);
    --shadow-lift: 0 22px 46px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06);
  }
  body[data-theme="light"]{
    --bg:#eef0f3;
    --bg-soft:#f6f7f9;
    --bg-elev:rgba(255,255,255,0.72);
    --bg-elev-2:rgba(255,255,255,0.88);
    --bg-elev-solid:#ffffff;
    --border:rgba(15,17,20,0.09);
    --border-strong:rgba(15,17,20,0.16);
    --text:#14161a;
    --text-dim:#5c6470;
    --vignette-alpha: 0.04;
    --shadow-soft: 0 10px 26px rgba(20,22,26,0.10), 0 0 0 1px rgba(15,17,20,0.055);
    --shadow-lift: 0 20px 40px rgba(20,22,26,0.16), 0 0 0 1px rgba(15,17,20,0.06);
  }
  /* Ley de accesibilidad de la UE (EN 301 549, obligatoria desde jun-2025) y estándar de facto en
     2026: si la persona tiene "reducir movimiento" activado en su sistema operativo, apagamos toda
     animación/transición/scroll suave de la app. html{scroll-behavior:smooth} de abajo también
     queda cubierto por el media query aparte que sigue después de este bloque. */
  @media (prefers-reduced-motion: reduce){
    *, *::before, *::after{
      animation-duration:0.001ms !important;
      animation-iteration-count:1 !important;
      transition-duration:0.001ms !important;
      scroll-behavior:auto !important;
    }
  }
  *{box-sizing:border-box;}
  ::selection{background:var(--accent);color:#fff;}
  button:focus-visible, a:focus-visible, [tabindex]:focus-visible{
    outline:2px solid var(--accent);
    outline-offset:2px;
    border-radius:6px;
  }
  html{scroll-behavior:smooth;}
  body{
    margin:0;
    font-family:'Plus Jakarta Sans','Manrope',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
    background:
      radial-gradient(ellipse 1100px 620px at 12% -8%, rgba(229,9,20,0.14), transparent 60%),
      radial-gradient(ellipse 900px 560px at 100% 0%, rgba(157,124,216,0.10), transparent 55%),
      var(--bg);
    background-attachment:fixed;
    color:var(--text);
    min-height:100vh;
    position:relative;
    -webkit-font-smoothing:antialiased;
  }
  body[data-theme="light"]{ background: radial-gradient(ellipse 1100px 620px at 12% -8%, rgba(229,9,20,0.06), transparent 60%), var(--bg); background-attachment:fixed; }
  ::-webkit-scrollbar{width:11px;height:11px;}
  ::-webkit-scrollbar-track{background:transparent;}
  ::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:20px;border:3px solid var(--bg);}
  .cine-title{font-family:'Bebas Neue', sans-serif; letter-spacing:1.5px;}

  #vignette{
    position:fixed;inset:0;
    pointer-events:none;
    z-index:1;
    box-shadow: inset 0 0 var(--vignette-strength) rgba(0,0,0,var(--vignette-alpha));
  }
  #grain{
    position:fixed;inset:0;
    pointer-events:none;
    z-index:1;
    opacity:0.03;
    background-image: repeating-linear-gradient(0deg, #fff 0px, transparent 1px, transparent 2px, #fff 3px), repeating-linear-gradient(90deg, #fff 0px, transparent 1px, transparent 2px, #fff 3px);
    mix-blend-mode: overlay;
  }
  body[data-theme="light"] #grain{display:none;}

  header{
    padding:20px 36px;
    border-bottom:1px solid transparent;
    position:sticky;
    top:0;
    background:linear-gradient(180deg, rgba(6,7,9,0.85) 0%, rgba(6,7,9,0.45) 55%, transparent 100%);
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
    z-index:10;
    /* border-color estaba afuera de esta lista — como el borde de abajo pasa de transparent a
       var(--border) exactamente en el mismo momento que se activa "header-compact", sin
       transición esa parte del cambio se sentía como que "aparecía de golpe" en vez de acompañar
       el resto del efecto (fondo, sombra, blur) que sí se ve suave. */
    transition:padding .25s ease, background .3s ease, box-shadow .3s ease, backdrop-filter .3s ease, border-color .3s ease;
  }
  body[data-theme="light"] header{background:linear-gradient(180deg, rgba(255,255,255,0.7) 0%, rgba(255,255,255,0.25) 55%, transparent 100%);}
  header.header-compact{padding:12px 36px;background:rgba(7,8,10,0.86);backdrop-filter:blur(var(--blur)) saturate(160%);-webkit-backdrop-filter:blur(var(--blur)) saturate(160%);box-shadow:0 8px 30px rgba(0,0,0,0.35);border-bottom-color:var(--border);}
  body[data-theme="light"] header.header-compact{background:rgba(255,255,255,0.9);box-shadow:0 8px 24px rgba(20,22,26,0.10);}
  header.header-compact .logo-img{height:42px;}
  .logo-img{height:60px;display:block;transition:height .25s ease;cursor:pointer;filter:drop-shadow(0 4px 14px rgba(229,9,20,0.25));}
  @keyframes logoBounce{0%{transform:scale(1) rotate(0);}30%{transform:scale(1.12) rotate(-3deg);}55%{transform:scale(0.96) rotate(2deg);}75%{transform:scale(1.05) rotate(-1deg);}100%{transform:scale(1) rotate(0);}}
  .logo-img.logo-bounce{animation:logoBounce .5s ease;}
  /* Tablero de clics al logo, estilo aeropuerto/split-flap — discreto a propósito: chico, apagado,
     pegado al logo, no un dashboard. Cada dígito es su propia "ficha" que voltea (ver flapDigit)
     solo cuando ese dígito cambia. */
  .logo-group{display:flex;flex-direction:column;align-items:flex-start;gap:3px;}
  .click-board{display:flex;align-items:center;gap:5px;opacity:0.85;}
  .click-board-digits{display:flex;gap:2px;}
  .flap-digit{position:relative;width:13px;height:18px;background:#15151a;border:1px solid rgba(255,255,255,0.1);border-radius:3px;display:flex;align-items:center;justify-content:center;font-family:'Courier New',monospace;font-weight:700;font-size:10.5px;line-height:1;color:var(--gold);box-shadow:inset 0 1px 3px rgba(0,0,0,0.55);perspective:60px;}
  .flap-digit::after{content:"";position:absolute;left:0;right:0;top:50%;height:1px;background:rgba(0,0,0,0.6);}
  .flap-digit.flap-anim{animation:flapDigit .32s ease;}
  @keyframes flapDigit{0%{transform:rotateX(0deg);}48%{transform:rotateX(-90deg);}52%{transform:rotateX(90deg);}100%{transform:rotateX(0deg);}}
  .click-board-label{font-size:8.5px;letter-spacing:1.5px;text-transform:uppercase;color:var(--text-dim);}
  @media (max-width:600px){ .click-board{display:none;} }
  .header-top{display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;}
  .brand-group{display:flex;align-items:center;gap:34px;flex-wrap:wrap;}
  .header-icons{display:flex;align-items:center;gap:10px;}
  .icon-toggle{
    background:var(--bg-elev);
    backdrop-filter:blur(12px);
    -webkit-backdrop-filter:blur(12px);
    border:1px solid var(--border);
    color:var(--text-dim);
    width:36px;height:36px;
    border-radius:50%;
    cursor:pointer;
    display:flex;align-items:center;justify-content:center;
    font-size:14px;
    flex-shrink:0;
    position:relative;
    transition:color .15s, border-color .15s, transform .15s, background .15s;
  }
  .icon-toggle:hover{color:var(--text);border-color:var(--border-strong);transform:translateY(-1px);}
  .icon-toggle.discreet{opacity:0.6;}
  .icon-toggle.discreet:hover{opacity:1;}
  .buzon-badge{position:absolute;top:-3px;right:-3px;background:var(--accent);color:#fff;font-size:9.5px;font-weight:800;border-radius:50%;min-width:16px;height:16px;display:flex;align-items:center;justify-content:center;padding:0 3px;line-height:1;box-shadow:0 0 0 2px var(--bg);}

  header p{margin:0;color:var(--text-dim);font-size:13px;}

  .stats{display:none;}
  .stat{background:var(--bg-elev);backdrop-filter:blur(14px);border:1px solid var(--border);border-radius:var(--radius);padding:10px 16px;min-width:90px;}
  .stat .n{font-size:20px;font-weight:800;}
  .stat .l{font-size:11px;color:var(--text-dim);text-transform:uppercase;letter-spacing:0.5px;}
  .stat.warn{border-color:var(--amber);}

  .toolbar{display:flex;flex-direction:column;gap:14px;margin-top:20px;}
  input, select, textarea, button{font-family:inherit;font-size:13px;}

  .search-row{display:flex;gap:10px;align-items:center;}
  .searchbar{position:relative;display:flex;align-items:center;flex:1 1 auto;min-width:0;}
  .searchbar .search-icon{position:absolute;left:16px;font-size:13px;opacity:0.5;pointer-events:none;color:var(--text-dim);display:flex;}
  .searchbar input[type=text]{width:100%;background:var(--bg-elev);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border:1px solid var(--border);border-radius:var(--radius-lg);padding:13px 16px 13px 42px;color:var(--text);transition:border-color .15s, box-shadow .15s, background .15s;}
  .searchbar input[type=text]::placeholder{color:var(--text-dim);}
  .searchbar input[type=text]:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-glow);background:var(--bg-elev-2);}
  /* Rediseño 2026-09-24: el botón de filtros ya no vive junto a la barra de búsqueda -- ahora es
     icon-only (#btnToggleFiltros usa .icon-toggle, igual que los accesos rápidos de la cabecera)
     y vive en su propia fila (.filter-controls-row), alineado a la izquierda, con el panel
     colgando de él como flotante -- ver .filter-trigger-wrap/.filterbar más abajo. */
  #btnToggleFiltros.active{border-color:var(--accent);color:var(--accent);background:var(--accent-glow);}
  .filter-btn-badge{position:absolute;top:-3px;right:-3px;background:var(--accent);color:#fff;font-size:9.5px;font-weight:800;border-radius:50%;min-width:16px;height:16px;display:flex;align-items:center;justify-content:center;padding:0 3px;line-height:1;box-shadow:0 0 0 2px var(--bg);}

  .filter-controls-row{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;flex-wrap:wrap;}
  .filter-trigger-wrap{position:relative;flex:0 0 auto;display:flex;align-items:center;gap:6px;}
  /* Ronda 11: el botón de "x" vive al lado del de Filtros (no encima ni flotando) -- un poco más
     chico y apagado por default para no competir visualmente con el de Filtros, que es el
     protagonista de los dos. .filterbar sigue colgando de .filter-trigger-wrap (position:relative
     de arriba), sin que el nuevo botón le estorbe -- top:calc(100% + 8px) se sigue midiendo desde
     el wrap completo, no desde #btnToggleFiltros solo. */
  .filter-clear-btn{width:30px;height:30px;font-size:11px;opacity:0.75;}
  .filter-clear-btn:hover{opacity:1;border-color:#e5484d;color:#e5484d;}
  /* El panel cuelga del botón como un flotante (position:absolute) en vez de empujar contenido
     hacia abajo como antes -- por eso, sin importar cuántos filtros se abran, NUNCA puede chocar
     con los controles de densidad/vista de lista que quedaron a la derecha en la misma fila (ese
     era justo el riesgo que había que evitar, pedido explícito). left:0 lo abre "hacia su
     derecha" desde el botón, tal como se pidió. */
  .filterbar{
    display:none;gap:9px;flex-wrap:wrap;align-items:center;
    position:absolute;top:calc(100% + 8px);left:0;
    background:var(--bg-elev-solid);
    backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
    border:1px solid var(--border);
    border-radius:16px;
    padding:14px;
    box-shadow:0 16px 40px rgba(0,0,0,0.45);
    z-index:55;
    width:max-content;
    max-width:min(680px, calc(100vw - 32px));
  }
  .filterbar.open{display:flex;}
  @media (max-width:600px){ .filterbar{left:auto;right:0;} }
  .filterbar select{
    -webkit-appearance:none;-moz-appearance:none;appearance:none;
    background-color:var(--bg-elev);
    backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7' fill='none'><path d='M1 1l4 4 4-4' stroke='%2393989e' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat:no-repeat;
    background-position:right 12px center;
    border:1px solid var(--border);
    border-radius:999px;
    padding:9px 30px 9px 15px;
    color:var(--text);
    flex:0 1 auto;
    min-width:118px;
    cursor:pointer;
    font-weight:600;
    transition:border-color .15s, background .15s, transform .12s;
  }
  .filterbar select:hover{border-color:var(--border-strong);}
  .filterbar select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-glow);}
  .filterbar select option{background:var(--bg-elev-solid);color:var(--text);}

  /* Dropdowns de filtro estilizados: el <select> nativo sigue existiendo (guarda el valor real y
     dispara "change" como siempre — todo el JS de filtros sigue intacto), pero se oculta visualmente
     con clip, y en su lugar se muestra este botón + lista, para que la lista desplegada no se vea
     con la apariencia del sistema operativo (el look "de 1998" que rompía con el resto de la interfaz). */
  .cselect-wrap{position:relative;flex:0 1 auto;}
  .cselect-wrap select{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
  .cselect-trigger{
    -webkit-appearance:none;-moz-appearance:none;appearance:none;
    display:flex;align-items:center;gap:8px;
    background-color:var(--bg-elev);
    backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    border:1px solid var(--border);
    border-radius:999px;
    padding:9px 14px;
    color:var(--text);
    font-family:inherit;font-size:13px;font-weight:600;
    cursor:pointer;
    min-width:118px;
    white-space:nowrap;
    transition:border-color .15s, background .15s;
  }
  .cselect-trigger:hover{border-color:var(--border-strong);}
  .cselect-trigger.open{border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-glow);}
  .cselect-trigger .cselect-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .cselect-trigger .cselect-chev{margin-left:auto;flex:0 0 auto;display:flex;color:var(--text-dim);transition:transform .15s;}
  .cselect-trigger.open .cselect-chev{transform:rotate(180deg);}
  .cselect-list{position:absolute;top:calc(100% + 6px);left:0;min-width:100%;max-height:280px;overflow-y:auto;background:var(--bg-elev-solid);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--border);border-radius:14px;padding:6px;box-shadow:0 16px 36px rgba(0,0,0,0.45);z-index:60;display:none;}
  .cselect-list.open{display:block;}
  .cselect-item{padding:9px 12px;border-radius:9px;cursor:pointer;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .1s;}
  .cselect-item:hover{background:var(--bg-elev-2);}
  .cselect-item.active{background:var(--accent);color:#fff;font-weight:700;}
  /* Variante de selección múltiple (filtro de País): checkbox por país, cualquier combinación de
     seleccionados se muestra sin cerrar la lista — a diferencia de .cselect-item, que es de
     selección única y sí cierra al elegir. */
  .cselect-item-check{display:flex;align-items:center;gap:9px;padding:8px 12px;border-radius:9px;cursor:pointer;font-size:13px;}
  .cselect-item-check:hover{background:var(--bg-elev-2);}
  .cselect-item-check.active{background:var(--bg-elev-2);font-weight:700;}
  .cselect-item-check input[type=checkbox]{accent-color:var(--accent);width:15px;height:15px;flex:0 0 auto;cursor:pointer;}
  .cselect-item-check span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  /* Ronda 10, pedido explícito: el conteo de películas por país, entre paréntesis, siempre visible
     y nunca se corta -- por eso va en su propio span con flex-shrink:0 y margin-left:auto (empuja el
     número al extremo derecho del renglón), separado del nombre del país que sí puede truncarse con
     "…" si el país es muy largo. */
  .cselect-item-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .cselect-item-count{flex-shrink:0;margin-left:auto;padding-left:8px;font-size:11.5px;font-weight:400;color:var(--text-dim);font-variant-numeric:tabular-nums;}
  .cselect-item-check.active .cselect-item-count{color:var(--text-dim);}
  .cselect-item-clear{text-align:center;font-size:11.5px;font-weight:700;color:var(--accent);cursor:pointer;padding:9px;border-top:1px solid var(--border);margin-top:4px;border-radius:0 0 9px 9px;}
  .cselect-item-clear:hover{background:var(--bg-elev-2);}

  .actionbar{display:flex;gap:9px;flex-wrap:wrap;align-items:center;justify-content:flex-end;}
  .density-control{display:flex;align-items:center;gap:7px;color:var(--text-dim);margin-right:4px;}
  .density-icon{display:flex;flex-shrink:0;}
  .density-icon-sm svg{width:10px;height:10px;}
  .density-icon-lg svg{width:16px;height:16px;}
  #densitySlider{width:80px;accent-color:var(--accent);cursor:pointer;}
  .btn{border:none;border-radius:999px;padding:10px 18px;cursor:pointer;font-weight:700;font-size:13px;letter-spacing:0.1px;transition:filter .15s, transform .12s, box-shadow .2s, background .15s;display:inline-flex;align-items:center;gap:6px;text-decoration:none;}
  a.btn{text-decoration:none;}
  .btn:hover{filter:brightness(1.12);transform:translateY(-1px);}
  .btn:active{transform:translateY(0);}
  .btn-primary{background:linear-gradient(135deg, var(--accent-2), var(--accent));color:#fff;box-shadow:0 8px 24px var(--accent-glow);}
  .btn-primary:hover{box-shadow:0 10px 30px var(--accent-glow);}
  #btnRecomendar.active{background:linear-gradient(135deg, var(--accent-2), var(--accent));color:#fff;border-color:var(--accent);}
  .btn-secondary{background:var(--bg-elev-2);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);color:var(--text);border:1px solid var(--border);}
  .btn-secondary:hover{border-color:var(--border-strong);}
  .btn-ghost{background:transparent;color:var(--text-dim);border:1px solid var(--border);}
  .btn-ghost:hover{color:var(--text);border-color:var(--border-strong);}
  .btn-danger{background:linear-gradient(135deg,#ff5c5c,var(--accent));color:#fff;}
  #detailImdb{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
  /* Mismo padding/radio que .detail-chip (10.5px/4px 10px) a propósito -- antes traían medidas
     ligeramente distintas y, apiladas una sobre la sinopsis (género, calificación, reacciones de
     la familia), se sentían como 3 sistemas de pastilla sin relación entre sí. El color saturado
     se queda (a diferencia del chip neutro): SÍ son distintas -- son enlaces a IMDb/RT -- y
     conviene que resalten más que un género o una reacción. */
  .rating-badge{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:800;padding:4px 10px;border-radius:999px;line-height:1.4;box-shadow:var(--shadow-soft);}
  .rating-badge-imdb{background:linear-gradient(135deg,#ffd84d,var(--gold));color:#000;}
  .rating-badge-rt-fresh{background:#fa320a;color:#fff;}
  .rating-badge-rt-rotten{background:#4a8f3c;color:#fff;}
  .rating-badge-link{display:inline-flex;text-decoration:none;transition:transform .15s ease,filter .15s ease;}
  .rating-badge-link:hover{transform:translateY(-1px);filter:brightness(1.08);}
  .rating-link{color:var(--text-dim);font-size:11.5px;text-decoration:none;}
  .rating-link:hover{color:var(--text);text-decoration:underline;}

  main{padding:32px 36px 64px;position:relative;z-index:2;}

  /* ---------- Hero cinemático (full-bleed, se traslapa con el header) ---------- */
  .hero{
    position:relative;
    overflow:hidden;
    margin:-108px 0 0;
    min-height:86vh;
    max-height:920px;
    display:flex;
    align-items:flex-end;
    background-size:cover;
    background-position:center 8%;
    z-index:2;
  }
  .hero-bg{
    position:absolute;
    inset:-14px;
    background-size:cover;
    /* Sesgado hacia arriba (8% en vez de centrado) — el cuadro es muy alto (hasta 920px) frente al
       backdrop horizontal típico de TMDB, así que un recorte centrado corta caras/cabezas que
       suelen estar en la mitad superior de la imagen. */
    background-position:center 8%;
    z-index:0;
    transition:transform .15s ease-out, opacity .35s ease;
    will-change:transform;
  }
  /* Mientras se busca el backdrop panorámico real de TMDB, el hero muestra el poster
     desenfocado (o el degradado, si no hay poster) como respaldo — este pulso suave le dice
     al ojo "esto todavía está cargando algo mejor" en vez de quedarse una imagen estática que
     parece ya definitiva. Se le quita la clase en cuanto llega la respuesta (haya o no backdrop). */
  .hero-bg-loading{ animation: heroBgPulse 1.8s ease-in-out infinite; }
  @keyframes heroBgPulse{ 0%,100%{ opacity:1; } 50%{ opacity:.72; } }
  /* Tráiler en autoplay (opcional, ver intentarAutoplayTrailerHero): mismo recuadro y mismo
     z-index que .hero-bg (0) -- va DEBAJO de .hero::before/::after (1), no al mismo nivel. Antes
     estaba en z-index:1 (empatado con esos degradados) y, por el orden de pintado de los ::before/
     ::after generados, el degradado fuerte de ::before (el que difumina los lados y arriba) se
     quedaba TAPADO por el video en vez de encima -- solo el degradado más simple de ::after (abajo)
     se alcanzaba a ver, por eso el corte del video contra la interfaz se notaba tanto. El iframe se
     sobredimensiona con el truco clásico de "cover" para YouTube (min-width/min-height basados en
     16:9) para que rellene el recuadro panorámico del Hero sin barras negras. */
  .hero-trailer-wrap{position:absolute;inset:-14px;z-index:0;overflow:hidden;pointer-events:none;}
  .hero-trailer-frame{position:absolute;top:50%;left:50%;width:100%;height:100%;min-width:177.78vh;min-height:56.25vw;transform:translate(-50%,-50%);border:0;}
  .hero::before{
    content:"";position:absolute;inset:0;
    background:
      linear-gradient(90deg, rgba(6,7,9,0.92) 0%, rgba(6,7,9,0.55) 34%, rgba(6,7,9,0.05) 64%, transparent 88%),
      linear-gradient(0deg, rgba(6,7,9,0.98) 0%, rgba(6,7,9,0.6) 34%, rgba(6,7,9,0.08) 68%, transparent 100%),
      linear-gradient(180deg, rgba(6,7,9,0.55) 0%, transparent 30%);
    z-index:1;
  }
  .hero::after{
    content:"";position:absolute;inset:0;
    /* Un poco más ancho y con un escalón intermedio (antes saltaba directo de -6% a transparent en
       24%) para que la disolución hacia el fondo se sienta más gradual, sobre todo con el tráiler
       de fondo -- es la orilla donde más se notaba el corte. */
    background:linear-gradient(0deg, var(--bg) -6%, rgba(6,7,9,0.5) 16%, transparent 32%);
    z-index:1;pointer-events:none;
  }
  .hero-content{position:relative;padding:150px 44px 56px;z-index:2;max-width:820px;}
  .hero-eyebrow{font-family:'Bebas Neue',sans-serif;font-size:14px;text-transform:uppercase;letter-spacing:2.5px;color:var(--gold);font-weight:400;margin-bottom:12px;display:flex;align-items:center;gap:8px;}
  .hero-eyebrow::before{content:"";width:20px;height:2px;background:var(--gold);display:inline-block;border-radius:2px;}
  .hero-title{font-family:'Plus Jakarta Sans',sans-serif;font-weight:800;font-size:56px;color:#fff;margin:0 0 16px;line-height:1.0;letter-spacing:-1px;text-shadow:0 6px 30px rgba(0,0,0,0.5);cursor:pointer;display:inline-flex;align-items:baseline;gap:12px;flex-wrap:wrap;}
  /* Ronda 9: quitamos el botón "+"/"Ver ficha completa" (se confundía con el bookmark de al lado) y
     en su lugar el título (y el fondo del Hero) abren la ficha directo, igual que cualquier póster
     del resto de la app. Este hint es deliberadamente discreto pero SIEMPRE visible (no solo al
     :hover) -- así se nota mejor en celular, donde no hay hover de verdad. */
  .hero-title-hint{font-family:'Plus Jakarta Sans',sans-serif;font-weight:600;font-size:14px;letter-spacing:0;color:rgba(255,255,255,0.45);text-shadow:none;transition:color .15s;}
  .hero-title:hover .hero-title-hint{color:rgba(255,255,255,0.75);}
  .hero-bg{transition:filter .25s;}
  .hero-meta-line{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:22px;}
  .hero-pill{color:rgba(255,255,255,0.92);font-size:12.5px;font-weight:700;letter-spacing:0.2px;background:rgba(255,255,255,0.1);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.18);border-radius:999px;padding:5px 13px;line-height:1.3;}
  .hero-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:30px;}
  .hero-play-btn{background:linear-gradient(135deg,#fff,#e9e9e9);color:#0b0c10;border:none;border-radius:999px;padding:14px 30px;font-weight:800;font-size:15px;display:inline-flex;align-items:center;gap:9px;cursor:pointer;box-shadow:0 10px 30px rgba(0,0,0,0.4);transition:transform .15s, filter .15s;}
  .hero-play-btn:hover{transform:translateY(-2px) scale(1.02);filter:brightness(1.04);}
  .hero-icon-btn{width:48px;height:48px;border-radius:50%;background:rgba(255,255,255,0.09);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border:1.5px solid rgba(255,255,255,0.28);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s, transform .15s, border-color .15s;flex-shrink:0;}
  .hero-info-row{display:flex;flex-wrap:wrap;gap:34px;padding-top:26px;border-top:1px solid rgba(255,255,255,0.14);max-width:1000px;}
  .hero-info-col{flex:1 1 220px;min-width:200px;}
  .hero-info-label{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:1px;color:rgba(255,255,255,0.5);margin-bottom:8px;}
  .hero-info-plot{flex:2 1 320px;}
  .hero-info-plot p{color:rgba(255,255,255,0.86);font-size:13.5px;line-height:1.6;margin:0;display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;}
  .hero-info-rating{flex:0 1 120px;}
  .hero-rating-box{display:inline-flex;align-items:baseline;gap:7px;border:1.5px solid rgba(255,255,255,0.32);border-radius:10px;padding:7px 14px;color:rgba(255,255,255,0.75);font-size:12.5px;font-weight:700;letter-spacing:0.3px;}
  .hero-rating-box b{font-size:20px;font-weight:800;color:var(--gold);}
  .hero-info-cast .cast-row{margin-top:0;}
  .hero-info-cast .cast-name{color:rgba(255,255,255,0.75);}
  .hero-info-cast .cast-avatar{background:rgba(255,255,255,0.1);border-color:rgba(255,255,255,0.2);color:#fff;}
  .hero-info-cast .cast-avatar.director{background:rgba(229,9,20,0.35);border-color:rgba(229,9,20,0.5);}
  .hero-icon-btn:hover{background:rgba(255,255,255,0.18);transform:translateY(-2px);}
  .hero-icon-btn.active{background:var(--accent);border-color:var(--accent);}
  .hero-icon-btn.active.heart-active{background:#e5304a;border-color:#e5304a;}
  .hero-dots{display:flex;align-items:center;gap:7px;margin-top:22px;}
  .hero-dot{width:7px;height:7px;padding:0;border-radius:50%;border:none;background:rgba(255,255,255,0.28);cursor:pointer;transition:background .2s ease;}
  .hero-dot:hover{background:rgba(255,255,255,0.55);}
  /* renderHero() reconstruye TODO el hero (hero.innerHTML=...) en cada cambio de candidata — los
     puntitos son elementos nuevos cada vez, no los mismos de antes con una clase distinta, así que
     un CSS transition normal no tendría "antes" del cual animar y no se vería nada. Por eso el
     rebote va con @keyframes: una animación autocontenida (define su propio inicio Y fin) que sí
     se dispara sola al insertarse un elemento nuevo. Se reproduce UNA vez al volverse activo y se
     queda quieto — no es un bucle ni "baila" todo el tiempo. */
  .hero-dot.active{background:#fff;width:20px;border-radius:4px;animation:heroDotPop .4s cubic-bezier(.34,1.56,.64,1);}
  @keyframes heroDotPop{ from{width:7px;border-radius:50%;} to{width:20px;border-radius:4px;} }

  /* Pedido explícito (2026-10-01): "Nuevo en Natflix"/"Estrenos recientes" se sentían tímidos.
     La razón de fondo es tipográfica, no de tamaño nada más: Bebas Neue es un display font de UN
     SOLO peso (no tiene variante bold -- Google Fonts solo la sirve en 400), así que por más que
     subiera el tamaño, el trazo seguía siendo delgado comparado con las portadas a todo color
     debajo. Sirve perfecto para el "eyebrow" chico (RECOMENDADO PARA TI) porque ahí el trabajo de
     un display condensado es ser una etiqueta discreta -- pero como encabezado de sección necesita
     cargar peso visual real.
     Cambia a Plus Jakarta Sans 800 (el mismo peso/familia que .hero-title) en vez de Bebas Neue,
     siguiendo cómo las apps de streaming grandes tratan sus encabezados de fila -- es la diferencia
     real entre Netflix (categorías en mayúsculas chicas y con tracking, pensadas para no competir
     con el hero) y Apple TV+/Disney+/Max (encabezados de fila en sans-serif bold grande, sin
     mayúsculas, compitiendo de tú a tú con las imágenes). Aquí nos conviene más la segunda: ya
     tenemos un "eyebrow" tipo Netflix arriba del hero, así que el encabezado de CADA sección ahora
     usa el mismo peso tipográfico que el título del hero (Plus Jakarta Sans 800), más grande
     (26px) y en mayúsculas/minúsculas normales -- no mayúsculas sostenidas, que es precisamente lo
     que hacía lucir "chico" a un display font sin bold real. */
  /* flex-wrap:wrap agregado en la ronda 10 -- lo usa .proximamente-drag-hint (flex-basis:100%) para
     caer en su propio renglón debajo del título en vez de apretujarse al lado del contador; no
     afecta a ningún otro .section-title porque ninguno más trae un hijo con flex-basis:100%, así
     que siguen en una sola línea exactamente igual que antes. */
  .section-title{font-family:'Plus Jakarta Sans', sans-serif;font-weight:800;font-size:26px;margin:0 0 12px;color:#fff;letter-spacing:-0.3px;text-transform:none;padding-bottom:0;border-bottom:none;display:flex;align-items:center;flex-wrap:wrap;gap:10px;text-shadow:0 2px 12px rgba(0,0,0,0.35);}
  .section-title svg{color:var(--accent);flex-shrink:0;width:20px;height:20px;filter:drop-shadow(0 0 6px var(--accent-glow));}
  /* Explica en una línea discreta qué define la selección de esa semana (criterio + cuántas hay
     en total) — se pidió después de que la categoría "Historia" resultara sorprendentemente chica
     y no quedara claro por qué esas películas y no otras. */
  #weeklyGenreTitle{margin-bottom:3px;}
  .weekly-genre-subtitle{font-size:11.5px;color:var(--text-dim);margin:0 0 14px;padding-left:26px;}
  /* Paneles de admin colapsables (En mantenimiento / Faltan seeders): ocultos por default, con un
     conteo a la vista y una flechita que gira al abrir — antes la lista completa de botones
     siempre estaba desplegada, ocupando pantalla aunque nadie la estuviera revisando. */
  .section-title-toggle{background:none;border:none;padding:0;width:100%;cursor:pointer;margin:0;}
  .collapsible-count{font-family:'Plus Jakarta Sans',sans-serif;font-size:11.5px;font-weight:700;letter-spacing:0;text-transform:none;color:var(--text-dim);background:var(--bg-elev-2);border:1px solid var(--border);border-radius:999px;padding:2px 10px;}
  /* El conteo y la flechita viajan juntos, pegados uno al otro, en vez de la flecha sola volando
     hasta la orilla del botón (que ocupa el ancho completo del panel) — así se lee de un
     vistazo que ambos son parte del mismo control de colapsar/expandir. */
  .collapsible-count-chev{display:flex;align-items:center;gap:6px;}
  #mantenimientoAdminTitleText,#faltanSeedersAdminTitleText{display:inline-flex;align-items:center;gap:8px;}
  .collapsible-chev{display:flex;color:var(--text-dim);transition:transform .15s;flex-shrink:0;}
  .section-title-toggle.open .collapsible-chev{transform:rotate(180deg);}
  .collapsible-row{display:none;margin-top:12px;}
  .collapsible-row.open{display:flex;flex-wrap:wrap;}

  /* Pedido explícito (2026-10-01): "dale aire", "desemplastar" -- 38px entre secciones hacía que
     un scroll normal encadenara un carrusel justo detrás de otro sin pausa visual real entre
     temas. Subir a 58px es la diferencia que de verdad se siente al navegar (no un ajuste de 2-3px
     que nadie nota): cada sección respira como su propio bloque antes de que empiece el siguiente.
     No cambia layout ni contenido, solo el espacio vertical entre bloques. */
  .panel{margin-bottom:58px;}

  /* Pleca de "¿Tienes alguna petición?" — a propósito se ve distinta a un panel normal (fondo con
     degradado del color de acento, borde, ícono grande) para que no pase desapercibida entre el
     resto de las secciones y sí invite a nutrir la biblioteca. */
  /* BUG REAL encontrado (2026-10-04, reporte directo: "se queda atrás del próximamente"): backdrop-
     filter (como transform/opacity) crea su PROPIO contexto de apilamiento -- el z-index:60 de
     .request-autocomplete-list (ver más abajo) queda atrapado DENTRO de ese contexto, sin poder
     competir con nada fuera de .request-banner. Como .request-banner en sí no tenía position ni
     z-index propios, quedaba en el nivel "automático" de su contenedor (main), y #proximamentePanel
     -- que viene justo después en el HTML -- se pintaba encima de él (y por lo tanto encima de su
     dropdown, atrapado adentro) cada vez que el dropdown bajaba lo suficiente para encimarse con la
     fila de Próximamente. position:relative + z-index aquí saca a TODO .request-banner (dropdown
     incluido) del flujo automático y lo pone por encima de cualquier panel no posicionado después
     de él, sin tener que tocarle el z-index a nada más. */
  .request-banner{
    margin-bottom:58px;
    position:relative;z-index:1;
    display:flex;align-items:center;gap:16px;flex-wrap:wrap;
    background:linear-gradient(120deg, var(--accent-glow), transparent 65%), var(--bg-elev);
    backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    border:1px solid var(--accent);
    border-radius:var(--radius-lg);
    padding:20px 22px;
  }
  .request-banner-icon{flex:0 0 auto;width:46px;height:46px;border-radius:50%;background:var(--accent);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 0 0 6px var(--accent-glow);}
  .request-banner-icon svg{width:22px;height:22px;}
  .request-banner-text{flex:1 1 240px;min-width:200px;}
  .request-banner-title{font-family:'Bebas Neue', sans-serif;font-size:20px;letter-spacing:1px;text-transform:uppercase;margin:0 0 3px;color:var(--text);}
  .request-banner-sub{font-size:12.5px;color:var(--text-dim);margin:0;}
  .request-banner-form{flex:1 1 320px;min-width:240px;display:flex;gap:8px;flex-wrap:wrap;}
  /* El input ahora vive dentro de .request-autocomplete-wrap (position:relative, para anclar el
     dropdown de sugerencias) en vez de ser hijo directo de .request-banner-form -- por eso el
     wrap hereda el flex:1/min-width que antes tenía el input, y el input pasa a width:100%. */
  .request-autocomplete-wrap{position:relative;flex:1;min-width:200px;}
  .request-banner-form input[type=text]{width:100%;background:var(--bg-elev-2);border:1px solid var(--border);border-radius:8px;padding:11px 13px;color:var(--text);}
  .request-banner-form input[type=text]:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-glow);}
  .request-autocomplete-list{
    display:none;
    position:absolute;top:calc(100% + 6px);left:0;right:0;
    background:var(--bg-elev-solid);
    backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
    border:1px solid var(--border);
    border-radius:12px;
    padding:6px;
    max-height:320px;overflow-y:auto;
    box-shadow:0 16px 40px rgba(0,0,0,0.45);
    z-index:60;
  }
  .request-autocomplete-list.open{display:block;}
  /* .request-autocomplete-item es un <button> (mejor accesibilidad/foco que un div con onclick) --
     sin este reset trae el estilo nativo del navegador encima (fondo blanco, borde, fuente del
     sistema), que se nota horrible sobre el panel oscuro. */
  .request-autocomplete-item{
    appearance:none;-webkit-appearance:none;border:none;background:none;
    font:inherit;color:inherit;width:100%;
    display:flex;align-items:center;gap:10px;padding:7px 8px;border-radius:8px;cursor:pointer;text-align:left;
  }
  .request-autocomplete-item:hover, .request-autocomplete-item.active{background:var(--bg-elev-2);}
  .request-autocomplete-poster{flex:0 0 auto;width:32px;height:46px;border-radius:5px;background-size:cover;background-position:center;background-color:var(--bg-elev-2);}
  .request-autocomplete-info{min-width:0;flex:1;}
  .request-autocomplete-title{font-size:13px;font-weight:700;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .request-autocomplete-meta{font-size:11px;color:var(--text-dim);}
  .request-autocomplete-note{padding:9px 10px;font-size:12px;color:var(--text-dim);}
  @media (max-width:600px){ .request-banner{padding:16px;} .request-banner-form{flex-basis:100%;} }
  /* padding-top agregado para que respire igual que .activity-row debajo de su título -- antes
     .panel-row arrancaba pegado al texto mientras .activity-row sí tenía 18px, inconsistente
     entre carruseles según cuál plantilla usara cada sección. */
  .panel-row{display:flex;gap:14px;overflow-x:auto;padding-top:16px;padding-bottom:10px;scroll-snap-type:x proximity;}
  .panel-row::-webkit-scrollbar{height:6px;}
  /* 130px -> 152px (#39, pedido explícito "con cautela" -- item 14 del menú). Destacados y
     .activity-row ya habían recibido su propio agrandado en una ronda anterior (ver sus
     comentarios más abajo) -- .panel-row (Continuar viendo / Tu lista de seguimiento / Vistas
     recientemente / Próximamente) era la familia de carruseles que se había quedado sin ese
     tratamiento. Aumento moderado (~17%), no el salto grande de Destacados -- el usuario avisó
     que si se siente demasiado grande le da reversa, así que mejor subir poco y parejo que de más. */
  /* BUG REAL encontrado (2026-10-04, reporte directo: "al poner el cursor encima hace un
     brincoteo raro el poster, como si detectara over and out muchas en bucle"): el hover de
     .panel-item aplicaba translateY(-4px) sobre SÍ MISMO -- el mismo elemento que detecta :hover
     era el que se movía. Con el cursor cerca del borde inferior, ese -4px podía bastar para que el
     borde de abajo de la caja se corriera hacia arriba y quedara POR ENCIMA de donde seguía el
     cursor -- el cursor "se salía" de la caja sin haberse movido él, disparando mouseleave, la caja
     regresaba a su lugar (el cursor volvía a quedar adentro), disparaba mouseenter otra vez, y así
     en bucle. (.card/.activity-card no tienen este problema: ahí el hover combina scale() con el
     translateY, y el crecimiento del scale gana por encima del corrimiento del translate en las
     dos direcciones -- la caja siempre CRECE hacia donde está el cursor, nunca se encoge.) Arreglo:
     el translateY ahora se aplica solo al PÓSTER DE ADENTRO (.panel-poster), nunca a .panel-item
     -- la caja que de verdad detecta :hover se queda del mismo tamaño/posición siempre, así que no
     hay forma de que el cursor "se salga" solo por el efecto visual del hover. */
  .panel-item{flex:0 0 auto;width:152px;cursor:pointer;position:relative;scroll-snap-align:start;}
  .panel-item-actions{position:absolute;top:6px;right:6px;display:flex;gap:4px;opacity:0;transition:opacity .15s;z-index:6;}
  .panel-item:hover .panel-item-actions{opacity:1;}
  .panel-poster-box{position:relative;}
  .panel-poster{position:relative;overflow:hidden;aspect-ratio:2/3;width:100%;border-radius:10px;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.85);font-weight:700;font-size:12px;text-align:center;padding:6px;background-size:cover;background-position:center;box-shadow:var(--shadow-soft);transition:box-shadow .25s ease, transform .25s ease;}
  .panel-item:hover .panel-poster{transform:translateY(-4px);box-shadow:0 16px 32px rgba(0,0,0,0.5), 0 0 0 1px var(--border-strong);}
  .panel-poster-badge-bell{position:absolute;bottom:7px;right:7px;z-index:4;width:22px;height:22px;border-radius:50%;background:var(--gold);color:#000;display:flex;align-items:center;justify-content:center;box-shadow:0 3px 8px rgba(0,0,0,0.4);pointer-events:none;}
  .panel-caption{font-size:11px;color:var(--text-dim);margin-top:7px;line-height:1.3;}
  .panel-caption b{color:var(--text);}
  /* "Vistas recientemente por la familia" — estilo Letterboxd: mini avatar + nombre de quién la
     vio, sobrepuestos al pie del poster con degradado, y abajo su calificación (si puso una) y
     la fecha. */
  .recent-viewer-bar{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;gap:6px;padding:14px 8px 7px;background:linear-gradient(to top, rgba(0,0,0,0.85), rgba(0,0,0,0));}
  .recent-viewer-avatar{width:20px;height:20px;border-radius:5px;background-size:cover;background-position:center;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:9.5px;font-weight:800;color:#fff;box-shadow:0 0 0 1.5px rgba(255,255,255,0.3);}
  .recent-viewer-name{font-size:11px;font-weight:700;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .recent-meta-row{display:flex;align-items:center;margin-top:7px;gap:6px;}
  .mini-stars{display:flex;font-size:12px;color:var(--border-strong);}
  .mini-stars .star{position:relative;display:inline-block;line-height:1;}
  .mini-stars .star-fill{position:absolute;left:0;top:0;overflow:hidden;white-space:nowrap;color:var(--gold);}
  .recent-date{font-size:10.5px;color:var(--text-dim);margin-left:auto;flex-shrink:0;}
  /* Ronda 9 -- "Vistas recientemente por la familia" rediseñada a propósito: es la ÚNICA fila de
     toda la app que usa este formato de "chip" compacto (estilo diario/Letterboxd) en vez del mismo
     .panel-item de póster alto que ya usan Continuar viendo / Tu lista / etc. Primer intento de esto
     lo hice como lista VERTICAL -- quedó mal, se sentía larga y con espacios muertos en vez de
     "compacta" (feedback directo del usuario, con captura). El mockup que sí se aprobó (ver
     natflix_propuestas_hero_y_recientes.png) es una fila HORIZONTAL de chips angostos de ~230x62 --
     eso es lo que esto implementa: .recent-diary-row sigue siendo una fila horizontal con scroll
     como cualquier .panel-row (línea 483 arriba), nomás que cada chip es su propia tarjetita
     compacta en vez del póster alto de las demás filas. */
  .recent-diary-row{gap:12px;}
  .diary-chip{flex:0 0 auto;display:flex;align-items:center;gap:10px;width:auto;min-width:200px;max-width:300px;cursor:pointer;padding:9px 12px;border-radius:12px;background:var(--bg-elev);border:1px solid rgba(255,255,255,0.07);transition:background .15s ease, transform .15s ease;scroll-snap-align:start;}
  .diary-chip:hover{background:var(--bg-elev-solid);transform:translateY(-2px);}
  .diary-chip-thumb{position:relative;flex-shrink:0;width:46px;height:46px;border-radius:9px;overflow:hidden;background-size:cover;background-position:center;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.85);font-weight:700;font-size:7px;line-height:1.1;text-align:center;padding:3px;}
  .diary-chip-avatar{position:absolute;bottom:-3px;right:-3px;width:18px;height:18px;border-radius:50%;background-size:cover;background-position:center;display:flex;align-items:center;justify-content:center;font-size:8px;font-weight:800;color:#fff;box-shadow:0 0 0 2px var(--bg-elev);}
  .diary-chip-info{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:4px;}
  /* El título SÍ puede ser largo (es el único dato sin tope natural), así que es el único que se
     trunca con "…" -- nombre/estrellas/fecha son casi siempre cortos (nombre de perfil, hasta 5
     estrellas, "hace N días") y antes se estaban recortando ellos por error (ver bug de abajo). */
  .diary-chip-title{font-size:13.5px;font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:190px;}
  /* BUG REAL encontrado (reporte directo del usuario, con captura: "Nat" se veía como "N."): con
     flex-shrink:0 en las estrellas y la fecha, TODO el encogimiento cuando la línea no cabía caía
     encima de .diary-chip-viewer (el único con flex-shrink permitido) -- lo achicaba hasta recortar
     el nombre con "…", aunque "Nat"/"Dani" miden una fracción de lo que sobraba de ancho. Arreglo:
     el nombre ya NO se encoge ni se trunca (los nombres de perfil son cortos y fijos), y en vez de
     eso el chip crece lo que haga falta (width:auto con tope en max-width de arriba) para que la
     línea completa quepa siempre sin recortar nada que no sea el título. */
  .diary-chip-meta{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-dim);white-space:nowrap;}
  .diary-chip-viewer{font-weight:700;color:var(--text-dim);white-space:nowrap;flex-shrink:0;}
  .diary-chip-dot{opacity:0.55;flex-shrink:0;}
  .diary-chip-meta .mini-stars{flex-shrink:0;}
  .diary-chip-meta .recent-date{margin-left:0;flex-shrink:0;}
  /* Ronda 10 tenía aquí bloques por fecha, cada uno con su propio encabezado ("HOY"/"AYER"/"ESTA
     SEMANA") y su propia fila horizontal completa debajo. Ronda 12c, pedido explícito con captura
     ("por qué no haces diferentes niveles solo cuando sea necesario... hacer 3 renglones cuando
     perfectamente cabe en uno"): con pocos chips por bloque, eso eran 2-3 filas casi vacías
     apiladas una sobre otra solo para separar "Hoy" de "Ayer" de "Esta semana". Se quitaron esos
     encabezados y las filas por separado -- ahora TODOS los chips van en una sola fila horizontal
     (ver renderRecentPanel en app.js), y cada chip ya trae su propia fecha relativa adentro
     (.diary-chip-meta .recent-date, ver más arriba) -- no hace falta un encabezado grande aparte
     para saber si algo fue "hoy" o "ayer", ya lo dice el chip mismo.
     Chip combinado ("Dani vio 3 películas"): miniaturas apiladas en abanico en vez de repetir el
     chip completo por cada vista -- mismo tamaño de caja que .diary-chip-thumb (46x46) para que no
     brinque el alto de la fila al mezclarse con chips sencillos. */
  .diary-chip-thumb-stack{overflow:visible;background:none;}
  .diary-chip-stack-poster{position:absolute;top:0;width:36px;height:46px;border-radius:7px;background-size:cover;background-position:center;box-shadow:0 2px 6px rgba(0,0,0,0.45), 0 0 0 2px var(--bg-elev);}
  .diary-chip-stack-poster:nth-child(1){left:10px;z-index:3;}
  .diary-chip-stack-poster:nth-child(2){left:5px;top:2px;z-index:2;filter:brightness(0.82);}
  .diary-chip-stack-poster:nth-child(3){left:0;top:4px;z-index:1;filter:brightness(0.65);}
  .diary-chip-group:hover .diary-chip-stack-poster{background-color:var(--bg-elev-solid);}
  .diary-chip-stack-more{position:absolute;left:0;bottom:-2px;z-index:4;background:var(--bg-elev-solid);color:var(--text);font-size:9px;font-weight:800;border-radius:999px;padding:1px 5px;box-shadow:0 0 0 2px var(--bg-elev);}

  /* Ronda 11, pedido explícito: modal de #diaryGroupOverlay -- lista cada película del chip
     combinado como su propia fila clickeable (ver abrirDiaryGroupOverlay). Son <button>, así que
     llevan el mismo reset de apariencia nativa que ya usan las sugerencias de autocompletado. */
  #diaryGroupList{max-height:50vh;overflow-y:auto;display:flex;flex-direction:column;gap:4px;margin:4px 0 2px;}
  .diary-group-item{
    appearance:none;border:none;background:none;font-family:inherit;color:inherit;width:100%;text-align:left;cursor:pointer;
    display:flex;align-items:center;gap:12px;padding:8px;border-radius:10px;transition:background .15s ease;
  }
  .diary-group-item:hover{background:var(--bg-elev);}
  .diary-group-item-poster{flex-shrink:0;width:42px;height:58px;border-radius:7px;background-size:cover;background-position:center;background-color:var(--bg-elev);display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.85);font-weight:700;font-size:7px;line-height:1.1;text-align:center;padding:3px;}
  .diary-group-item-info{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:4px;}
  .diary-group-item-title{font-size:13.5px;font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .diary-group-item-meta{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-dim);}

  .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--card-min-width,170px),1fr));gap:20px;}
  .card-title-row{display:none;}
  /* Vista de lista: filas angostas con un poster chico a la izquierda y el título siempre visible
     a la derecha — útil cuando quieres leer nombres rápido en vez de reconocer portadas. */
  .grid.list-view{display:flex;flex-direction:column;gap:6px;}
  .grid.list-view .card{flex-direction:row;align-items:center;gap:14px;padding:6px 14px 6px 6px;animation:none;}
  .grid.list-view .card:hover{transform:none;box-shadow:none;border-color:var(--border);}
  .grid.list-view .poster{width:44px;flex:0 0 44px;aspect-ratio:2/3;border-radius:6px;}
  .grid.list-view .card-title-row{display:flex;align-items:baseline;gap:8px;font-size:14px;color:var(--text);flex:1;min-width:0;cursor:pointer;}
  .grid.list-view .card-title-row b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .grid.list-view .card-title-row span{font-weight:400;color:var(--text-dim);font-size:12px;flex-shrink:0;}
  .grid.list-view .new-ribbon{display:none;}

  .card{
    background:var(--bg-elev);
    backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
    border:1px solid var(--border);
    border-radius:var(--radius);
    overflow:hidden;
    display:flex;
    flex-direction:column;
    position:relative;
    animation:fadeInUp .3s ease both;
    transition:transform .28s cubic-bezier(.2,.8,.2,1), box-shadow .28s ease, border-color .28s ease, z-index 0s;
    /* El slider de densidad (--card-min-width) puede bajar hasta 90px -- ahí los 4 botones de
       acción (30px c/u + separación) ya no caben y se recortan/traslapan contra el borde de la
       tarjeta. container-type deja que el @container de abajo reaccione al ancho REAL de cada
       tarjeta ya renderizada, sin depender de adivinar cuántas columnas caben en la pantalla. */
    container-type: inline-size;
  }
  /* Por debajo de este ancho, mejor sin botones que con ellos encimados -- se sigue pudiendo
     hacer todo (marcar vista, favorita, etc.) abriendo la ficha con un clic en el póster. */
  @container (max-width: 158px){
    .card-actions, .card-edit-btn, .card-select-badge{ display:none !important; }
  }
  .card:hover{transform:scale(1.08) translateY(-4px);box-shadow:0 26px 50px rgba(0,0,0,0.55), 0 0 0 1px var(--border-strong);z-index:5;border-color:var(--border-strong);}
  @keyframes fadeInUp{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:translateY(0);}}
  .card.st-pendiente{box-shadow:inset 3px 0 0 var(--amber);}
  .card.st-vista{box-shadow:inset 3px 0 0 var(--accent);}
  .card.st-favorita{box-shadow:inset 3px 0 0 var(--blue);}
  .card.st-descartada{box-shadow:inset 3px 0 0 var(--gray);}
  .card.st-enpausa{box-shadow:inset 3px 0 0 var(--purple);}
  .card:hover.st-pendiente{box-shadow:inset 3px 0 0 var(--amber), 0 26px 50px rgba(0,0,0,0.55), 0 0 0 1px var(--border-strong);}
  .card:hover.st-vista{box-shadow:inset 3px 0 0 var(--accent), 0 26px 50px rgba(0,0,0,0.55), 0 0 0 1px var(--border-strong);}
  .card:hover.st-favorita{box-shadow:inset 3px 0 0 var(--blue), 0 26px 50px rgba(0,0,0,0.55), 0 0 0 1px var(--border-strong);}
  .card:hover.st-descartada{box-shadow:inset 3px 0 0 var(--gray), 0 26px 50px rgba(0,0,0,0.55), 0 0 0 1px var(--border-strong);}
  .card:hover.st-enpausa{box-shadow:inset 3px 0 0 var(--purple), 0 26px 50px rgba(0,0,0,0.55), 0 0 0 1px var(--border-strong);}


  .poster, .activity-poster, .detail-poster, .panel-poster, .history-poster{
    background: linear-gradient(90deg, var(--bg-elev) 25%, var(--bg-elev-2) 50%, var(--bg-elev) 75%);
    background-size: 200% 100%;
    animation: shimmer 1.6s infinite;
  }
  @keyframes shimmer{
    0%{background-position:200% 0;}
    100%{background-position:-200% 0;}
  }
  .poster{aspect-ratio:2/3;width:100%;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.85);font-weight:700;font-size:15px;text-align:center;padding:10px;background-size:cover;background-position:center;cursor:pointer;overflow:hidden;position:relative;
    /* Zoom sutil al hover — nada de video (preview LIGERO, decisión de siempre). Ojo: esto ANTES
       duraba 3.2s a propósito ("Ken Burns"), pero en la práctica se sentía como que no iba a dejar
       de crecer nunca y competía con los datos del hover (card-hover-info, justo abajo) en vez de
       dejarte leerlos tranquilo. .5s es suficientemente rápido para no distraer. */
    transition:transform .5s cubic-bezier(.25,.46,.45,.94);
  }
  .card:hover .poster{transform:scale(1.12);}
  /* Info que aparece encima del poster al hacer hover — justo arriba de los íconos de
     vista/guardar/recomendar, en la misma franja con degradado — para no tener que abrir la ficha
     nomás para ver la calificación, el género o la duración. */
  .card-hover-info{position:absolute;left:0;right:0;bottom:54px;padding:0 10px;display:flex;flex-wrap:wrap;gap:5px;opacity:0;transition:opacity .2s ease;z-index:6;pointer-events:none;}
  .card:hover .card-hover-info{opacity:1;}
  .card-hover-info span{background:rgba(10,10,12,0.72);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);color:#fff;font-size:10px;font-weight:700;padding:3px 7px;border-radius:20px;display:inline-flex;align-items:center;gap:3px;white-space:nowrap;}
  .grid.list-view .card-hover-info{display:none;}
  .new-ribbon{position:absolute;top:10px;left:-4px;background:linear-gradient(135deg,var(--accent-2),var(--accent));color:#fff;font-size:9px;font-weight:800;letter-spacing:0.6px;padding:3px 9px;border-radius:3px;z-index:2;text-transform:uppercase;box-shadow:0 4px 12px var(--accent-glow);}
  .poster-mantenimiento{filter:grayscale(1) brightness(0.55);}
  .cinta-mantenimiento{position:absolute;top:50%;left:-8px;right:-8px;background:var(--amber);color:#000;font-size:10px;font-weight:800;letter-spacing:0.5px;padding:4px 0;text-align:center;transform:translateY(-50%) rotate(-8deg);text-transform:uppercase;box-shadow:0 2px 6px rgba(0,0,0,0.4);z-index:3;}
  /* Duotono azul para "Próximamente" — a propósito NO es blanco y negro (se confundiría con
     "en mantenimiento") ni a color completo (daría a entender que ya está disponible). */
  .poster-proximamente{filter:grayscale(0.5) brightness(0.76) sepia(0.32) hue-rotate(182deg) saturate(1.4);}
  .proximamente-poster-wrap{display:flex;flex-direction:column;align-items:center;}
  .proximamente-poster-box{position:relative;width:100%;}
  .icon-btn.proximamente-bell{position:absolute;bottom:7px;right:7px;z-index:4;width:26px;height:26px;}
  .icon-btn.proximamente-bell:hover{background:var(--gold);border-color:var(--gold);color:#000;}
  .proximamente-caption{margin-top:6px;font-size:11px;font-weight:600;color:var(--text-dim);text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;opacity:0;pointer-events:none;transition:opacity .15s ease;}
  .proximamente-poster-box:has(.proximamente-bell:hover) ~ .proximamente-caption{opacity:1;}
  /* Ronda 10, pedido explícito: drag and drop para reordenar "Próximamente" (solo admin) -- ver
     initProximamenteDragDrop/reordenarProximamente en app.js. El cursor de "agarrar" se pone en
     TODA la tarjeta (no un handle aparte) porque ya no compite con nada clicable salvo el póster y
     la campanita, que igual siguen funcionando normal (HTML5 drag no bloquea click). */
  .proximamente-draggable{cursor:grab;}
  .proximamente-draggable:active{cursor:grabbing;}
  .proximamente-draggable.dragging{opacity:0.4;}
  .proximamente-draggable.drag-over{outline:2px dashed var(--accent);outline-offset:4px;border-radius:12px;}
  .proximamente-drag-hint{flex-basis:100%;font-size:11px;font-weight:600;color:var(--text-dim);text-transform:none;letter-spacing:0;}


  .badge{display:inline-block;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.4px;padding:2px 7px;border-radius:20px;margin-top:4px;width:fit-content;}
  .card-actions{position:absolute;left:0;right:0;bottom:0;display:flex;justify-content:center;gap:7px;padding:16px 8px 10px;background:linear-gradient(to top, rgba(0,0,0,0.85), rgba(0,0,0,0.4) 65%, transparent);opacity:0;transition:opacity .2s;z-index:6;}
  .card:hover .card-actions{opacity:1;}
  /* Esquina superior DERECHA a propósito — en la izquierda se encimaba con el letrero "Nuevo"
     (.new-ribbon) y con el check de selección múltiple (.card-select-badge). Se corre un poco más
     abajo (top:38px en vez de 8px) para no taparse tampoco con el check de "ya vista"
     (.poster-vista-badge), que vive en esa misma esquina. */
  .card-edit-btn{position:absolute;top:38px;right:7px;opacity:0;transition:opacity .15s;z-index:6;}
  .card:hover .card-edit-btn{opacity:1;}
  /* Antes el "track" (la parte sin ver) era blanco casi transparente (16% opacidad) directo sobre
     el poster — contra un poster claro por ahí abajo, la barra prácticamente desaparecía y no
     había forma de distinguir cuánto llevabas visto. Ahora el track es oscuro casi opaco (mismo
     contraste sin importar qué tan claro sea el poster de fondo) y trae una sombra hacia arriba
     que oscurece un poco el borde inferior del poster, como si la barra tuviera su propio
     "colchón" en vez de flotar directo sobre la imagen. */
  .progress-track{position:absolute;left:0;right:0;bottom:0;height:5px;background:rgba(8,9,11,0.68);z-index:4;box-shadow:0 -16px 18px -12px rgba(0,0,0,0.6);}
  .progress-fill{height:100%;background:linear-gradient(90deg,var(--accent-2),var(--accent));box-shadow:0 0 8px var(--accent-glow), 0 0 0 1px rgba(0,0,0,0.3);}
  #floatingActivityMenu{position:fixed;z-index:400;background:var(--bg-elev-solid);backdrop-filter:blur(20px);border:1px solid var(--border);border-radius:12px;padding:6px;flex-direction:column;gap:2px;box-shadow:var(--shadow-lift);min-width:190px;}
  #posterTooltip{position:fixed;z-index:410;background:rgba(16,17,21,0.92);backdrop-filter:blur(10px);color:var(--text);font-size:12px;font-weight:600;padding:7px 12px;border-radius:8px;pointer-events:none;opacity:0;transition:opacity .15s, transform .15s;white-space:nowrap;max-width:260px;overflow:hidden;text-overflow:ellipsis;box-shadow:0 10px 24px rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.1);}
  #posterTooltip.visible{opacity:1;}
  #posterTooltip .tooltip-year{color:var(--text-dim);font-weight:500;opacity:0.85;}
  #posterTooltip.rich{white-space:normal;max-width:280px;overflow:visible;text-overflow:clip;line-height:1.42;}
  #posterTooltip .tooltip-title{font-weight:800;margin-bottom:3px;}
  #posterTooltip .tooltip-sinopsis{color:var(--text-dim);font-weight:500;font-size:11.5px;}
  #posterTooltip::after{content:"";position:absolute;left:50%;transform:translateX(-50%);border:5px solid transparent;}
  #posterTooltip.below::after{bottom:100%;border-bottom-color:rgba(16,17,21,0.92);}
  #posterTooltip:not(.below)::after{top:100%;border-top-color:rgba(16,17,21,0.92);}
  .activity-menu-item{display:flex;align-items:center;gap:8px;background:none;border:none;color:var(--text-dim);font-size:12.5px;padding:9px 10px;border-radius:8px;cursor:pointer;text-align:left;white-space:nowrap;width:100%;transition:background .15s, color .15s;}
  .activity-menu-item:hover{background:var(--bg-elev-2);color:var(--text);}
  .activity-menu-item.active{color:var(--accent);font-weight:700;}
  .lista-picker-row{display:flex;align-items:center;gap:10px;padding:8px 6px;border-radius:8px;}
  .lista-picker-row:hover{background:var(--bg-elev-2);}
  .lista-picker-check{flex-shrink:0;width:22px;height:22px;border-radius:6px;border:1.5px solid var(--border);background:var(--bg-elev);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;}
  .lista-picker-check.active{background:var(--accent);border-color:var(--accent);}
  .lista-picker-nombre{flex:1;min-width:0;font-size:13px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;}
  .lista-picker-row .icon-btn{width:26px;height:26px;background:none;border:none;color:var(--text-dim);backdrop-filter:none;}
  .lista-picker-row .icon-btn:hover{color:#e5304a;background:var(--bg-elev-2);transform:none;}
  .listas-header-sub{color:var(--text-dim);font-size:12.5px;margin-bottom:16px;}
  .listas-crear-row{display:flex;gap:8px;max-width:420px;margin-bottom:8px;}
  .listas-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));gap:18px;margin-top:20px;}
  .lista-card{background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;display:flex;flex-direction:column;transition:transform .2s ease, box-shadow .2s ease;}
  .lista-card:hover{transform:translateY(-3px);box-shadow:0 14px 30px rgba(0,0,0,0.4);}
  .lista-card-covers{aspect-ratio:16/9;cursor:pointer;background:var(--bg-elev-2);}
  .lista-card-covers-grid{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;width:100%;height:100%;gap:1px;}
  .lista-card-cover{background-size:cover;background-position:center;background-color:var(--bg-elev-2);}
  .lista-card-covers-empty{width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:var(--text-dim);opacity:.35;font-size:26px;}
  .lista-card-body{padding:11px 13px 4px;}
  .lista-card-nombre{display:block;font-weight:700;font-size:14px;color:var(--text);cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .lista-card-nombre-wrap input{width:100%;background:var(--bg-elev-2);border:1px solid var(--accent);border-radius:6px;padding:5px 8px;color:var(--text);font-size:14px;font-weight:700;}
  .lista-card-count{font-size:11.5px;color:var(--text-dim);margin-top:3px;}
  .lista-card-actions{display:flex;gap:4px;padding:6px 8px 8px;justify-content:flex-end;}
  .lista-card-actions .icon-btn{width:28px;height:28px;background:none;border:none;color:var(--text-dim);backdrop-filter:none;font-size:12px;}
  .lista-card-actions .icon-btn:hover{color:var(--text);background:var(--bg-elev-2);transform:none;}
  .icon-btn{background:rgba(12,13,16,0.62);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,0.12);color:#fff;width:30px;height:30px;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;transition:background .15s,transform .15s,border-color .15s;}
  .icon-btn:hover{background:rgba(30,31,36,0.9);transform:scale(1.1);border-color:rgba(255,255,255,0.28);}
  .icon-btn.active{background:var(--accent);color:#fff;border-color:var(--accent);}
  .icon-btn.st-check.active{background:#2fbf71;border-color:#2fbf71;}
  .icon-btn.st-bookmark.active{background:#d9a92b;border-color:#d9a92b;}
  .icon-btn.st-thumb.active{background:#3b82f6;border-color:#3b82f6;}
  /* Pop breve del ícono recién tocado (marcar vista/guardar/recomendar) — ver marcarPulsoTarjeta()
     y render(): la clase solo se agrega en el primer render() después del toque, así que la
     animación se reproduce una vez y no cada vez que la tarjeta se vuelve a dibujar por otra razón. */
  @keyframes iconPop{0%{transform:scale(1);}35%{transform:scale(1.38);}65%{transform:scale(0.9);}100%{transform:scale(1);}}
  .icon-btn.icon-pop{animation:iconPop .38s cubic-bezier(.34,1.56,.64,1);}

  /* Diferenciar de un vistazo qué ya viste — el borde de color (arriba) ya lo hacía sutilmente,
     esto lo refuerza: el poster de algo YA VISTO se ve un poco apagado (menos que compita por tu
     atención con lo que todavía no ves) y trae una palomita discreta en la esquina. */
  .poster-vista{filter:saturate(0.8) brightness(0.88);}
  .card:hover .poster-vista{filter:saturate(0.92) brightness(0.96);}
  .poster-vista-badge{position:absolute;top:8px;right:8px;width:22px;height:22px;border-radius:50%;background:rgba(10,10,12,0.72);border:1.5px solid rgba(255,255,255,0.4);color:#2fbf71;display:flex;align-items:center;justify-content:center;z-index:3;pointer-events:none;}

  /* Placeholder de "sin poster todavía" — antes era nomás el título crudo flotando sobre el
     degradado; con el ícono de rollo de película arriba se ve más a propósito ("esto es un
     placeholder", no "algo se rompió") en vez de texto suelto sin contexto. */
  .poster-noimg{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;width:100%;height:100%;}
  .poster-noimg-icon{opacity:0.5;}
  .poster-noimg-icon svg{width:26px;height:26px;}
  .poster-noimg-title{line-height:1.3;opacity:0.92;}

  /* "Recomendaciones de tu familia" — posters más chicos que el resto de las filas horizontales
     (Agregadas, Estrenos, Selección semanal, que sí comparten .activity-card a su tamaño normal),
     para que quepan más recomendaciones sin que la fila se sienta tan pesada. */
  #recomendadasRow.activity-row .activity-card{flex:0 0 100px;}
  /* A 100px de ancho los 3 íconos de .reaction-row (30px c/u) ya no caben a su tamaño normal --
     se achican un poco solo aquí para que seguir cupiendo los 3 sin encimarse ni envolver línea. */
  #recomendadasRow .reaction-row{gap:4px;padding-left:4px;padding-right:4px;}
  #recomendadasRow .reaction-row .icon-btn{width:26px;height:26px;}

  .empty{text-align:center;padding:90px 20px;color:var(--text-dim);}
  .empty .big{margin-bottom:14px;color:var(--text-dim);opacity:0.4;}
  .empty .big svg{width:52px;height:52px;}

  .overlay{position:fixed;inset:0;background:rgba(5,6,8,0.72);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:none;align-items:flex-start;justify-content:center;padding:40px 16px;overflow-y:auto;z-index:100;}
  .overlay.open{display:flex;animation:overlayIn .18s ease;}
  @keyframes overlayIn{from{opacity:0;}to{opacity:1;}}
  .modal{background:var(--bg-elev-2);backdrop-filter:blur(28px) saturate(160%);-webkit-backdrop-filter:blur(28px) saturate(160%);border:1px solid var(--border-strong);border-radius:var(--radius-lg);padding:26px;width:100%;max-width:460px;box-shadow:var(--shadow-lift);animation:modalIn .22s cubic-bezier(.2,.8,.2,1);}
  @keyframes modalIn{from{opacity:0;transform:translateY(14px) scale(.98);}to{opacity:1;transform:translateY(0) scale(1);}}
  .modal.wide{max-width:640px;}
  @media (min-width:1200px){
    .modal.wide{max-width:940px;}
  }
  .modal h2{margin:0 0 16px;font-size:18px;}
  .modal-note{font-size:11.5px;color:var(--text-dim);margin:-8px 0 14px;line-height:1.4;}
  .taste-quiz-chips{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:6px;}
  .taste-chip{background:var(--bg-elev);border:1px solid var(--border);color:var(--text-dim);font-size:12.5px;font-weight:700;padding:8px 15px;border-radius:999px;cursor:pointer;transition:background .15s, border-color .15s, color .15s;font-family:inherit;}
  .taste-chip:hover{border-color:var(--border-strong);color:var(--text);}
  .taste-chip.active{background:var(--accent);border-color:var(--accent);color:#fff;}
  /* "Mi espacio": mismo lenguaje visual que .view-tab (los tabs Inicio/Biblioteca de arriba), para
     que se sienta como la misma app y no un componente aparte. */
  .modal-tabs{max-width:560px;}
  .mi-espacio-tabs{display:flex;gap:22px;border-bottom:1px solid var(--border);margin:-4px 0 16px;}
  .mi-espacio-tab{position:relative;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-dim);padding:0 0 10px;margin-bottom:-1px;font-weight:800;font-size:12.5px;letter-spacing:0.4px;text-transform:uppercase;cursor:pointer;transition:color .15s;font-family:inherit;}
  .mi-espacio-tab:hover{color:var(--text);}
  .mi-espacio-tab.active{color:var(--text);border-bottom-color:var(--accent);}
  #tabMiEspacioBuzon{padding-right:14px;}
  .field{margin-bottom:13px;}
  .field label{display:block;font-size:11px;color:var(--text-dim);margin-bottom:5px;text-transform:uppercase;letter-spacing:0.5px;font-weight:700;}
  .field input, .field select, .field textarea{width:100%;background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius-sm);padding:10px 12px;color:var(--text);transition:border-color .15s, box-shadow .15s;}
  .field input:focus, .field select:focus, .field textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-glow);}
  .field input:disabled, .field select:disabled{opacity:0.5;cursor:not-allowed;}
  .field textarea{resize:vertical;min-height:56px;}
  .row2{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
  .star-picker{display:flex;gap:5px;font-size:24px;color:var(--border-strong);touch-action:none;}
  .star-picker .star{position:relative;display:inline-block;cursor:pointer;transition:transform .12s;line-height:1;}
  .star-picker .star:hover{transform:scale(1.15);}
  .star-picker .star-bg{display:block;}
  .star-picker .star-fill{position:absolute;left:0;top:0;overflow:hidden;white-space:nowrap;width:0%;color:var(--gold);text-shadow:0 0 12px rgba(245,197,24,0.5);}
  .modal-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:20px;flex-wrap:wrap;}
  .checkbox-row{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--text-dim);margin-bottom:12px;}
  .checkbox-row input{width:auto;accent-color:var(--accent);}
  .toggle-switches-row{display:flex;gap:8px;margin-bottom:12px;}
  .toggle-switch-btn{flex:1 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:12px 6px;border-radius:var(--radius-sm);border:1.5px solid var(--border-strong);background:rgba(255,255,255,0.03);color:var(--text-dim);font-size:10.5px;font-weight:700;letter-spacing:0.2px;cursor:pointer;transition:background .15s,border-color .15s,color .15s;font-family:inherit;text-align:center;}
  .toggle-switch-btn svg{width:19px;height:19px;}
  .toggle-switch-btn:hover{border-color:rgba(255,255,255,0.32);color:var(--text);}
  .toggle-switch-btn.active{background:#4a6b70;border-color:#4a6b70;color:#fff;}
  .toggle-switch-btn.is-disabled{opacity:0.4;pointer-events:none;}
  [data-tip]{position:relative;}
  [data-tip]::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background:rgba(16,17,21,0.95);color:var(--text);font-size:11px;font-weight:600;line-height:1.35;padding:6px 10px;border-radius:7px;white-space:normal;max-width:200px;width:max-content;text-align:center;pointer-events:none;opacity:0;transition:opacity .15s ease;box-shadow:0 8px 20px rgba(0,0,0,0.45);border:1px solid rgba(255,255,255,0.1);z-index:60;}
  [data-tip]:hover::after{opacity:1;}

  .spinner{width:13px;height:13px;border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;display:inline-block;animation:spin .7s linear infinite;vertical-align:-2px;margin-right:6px;}
  @keyframes spin{to{transform:rotate(360deg);}}

  footer{padding:22px 36px 44px;color:var(--text-dim);font-size:11.5px;border-top:1px solid var(--border);position:relative;z-index:2;}

  #profilePhotoInput{display:none;}

  /* Fondo nuevo (2026-10-01): antes era un degradado de 2 tonos fijo -- se veía igual sin importar
     qué biblioteca tuvieras, cero personalidad de Natflix. .profile-backdrop pinta un mosaico
     borroso de pósters reales de tu catálogo (ver renderProfileBackdrop en app.js) y el ::before
     de abajo le pone encima el scrim oscuro + el mismo resplandor rojo de marca que ya existía,
     para que el texto y los avatares seguro queden legibles encima sin importar qué tan clara
     salga una portada. overflow:hidden recorta el mosaico (que se dibuja 10% más grande que la
     pantalla) para que el blur no deje un borde transparente visible en las orillas. */
  .profile-screen{position:fixed;inset:0;overflow:hidden;background:#08090a;display:flex;align-items:center;justify-content:center;z-index:300;}
  .profile-screen::before{content:"";position:absolute;inset:0;z-index:1;background:
      radial-gradient(ellipse 1000px 650px at 50% -10%, rgba(229,9,20,0.22), transparent 60%),
      linear-gradient(180deg, rgba(8,9,10,0.5) 0%, rgba(8,9,10,0.82) 58%, #08090a 100%);}
  #profileOverlay{z-index:350;}
  .profile-screen.hidden{display:none;}
  .profile-backdrop{position:absolute;inset:-6%;z-index:0;display:grid;grid-template-columns:repeat(auto-fill, minmax(150px, 1fr));grid-auto-rows:1fr;gap:3px;filter:blur(24px) saturate(1.15) brightness(0.8);transform:scale(1.08);}
  .profile-backdrop-tile{background-size:cover;background-position:center;min-height:150px;}
  @keyframes profileScreenIn{ from{opacity:0;transform:translateY(16px) scale(0.98);} to{opacity:1;transform:none;} }
  .profile-screen-content{position:relative;z-index:2;animation:profileScreenIn .55s cubic-bezier(.2,.8,.2,1) both;}
  .profile-screen-logo{height:38px;display:block;margin:0 auto 22px;filter:drop-shadow(0 4px 16px rgba(0,0,0,0.55));}
  .profile-screen h1{font-family:'Plus Jakarta Sans',sans-serif;font-weight:800;font-size:30px;margin-bottom:38px;text-align:center;letter-spacing:-0.5px;text-shadow:0 2px 14px rgba(0,0,0,0.4);}
  /* 112->124 y 28->32: la escala de la ronda 1 se sentía modesta comparada con Netflix/Disney+/Max
     (sus avatares de selección corren más grandes, con más aire entre ellos) -- este es el mismo
     tratamiento (cuadrado, degradado+inicial o foto), solo con más presencia en pantalla. */
  .profile-grid{display:flex;gap:32px;flex-wrap:wrap;justify-content:center;max-width:920px;}
  .profile-avatar{width:124px;display:flex;flex-direction:column;align-items:center;gap:11px;cursor:pointer;position:relative;}
  /* Pedido explícito (2026-09-24): los avatares de perfil deben verse CUADRADOS, no redondos --
     antes tenían 20px de radio (20% de los 100px del círculo), que a este tamaño se seguía
     sintiendo bastante redondeado. 10px alcanza para que las esquinas no se vean filosas de más
     pero el cuadrado ya se lee claramente como cuadrado. Todo lo que representa a un PERFIL
     (esta tarjeta, el mini-avatar del header, el avatar en "vistas recientemente" y el picker de
     avatares ilustrados) cambia igual, para que se sienta un solo lenguaje visual -- lo que NO
     cambia son avatares de OTRA cosa (reparto de una película, insignias circulares de acción),
     esos no son "avatares de perfil" y no rompían ninguna armonía.
  */
  .profile-circle{width:112px;height:112px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:38px;font-weight:800;color:#fff;text-shadow:0 2px 6px rgba(0,0,0,0.35);outline:3px solid transparent;outline-offset:3px;transition:outline .18s, transform .18s, box-shadow .25s ease;background-size:cover;background-position:center;position:relative;box-shadow:var(--shadow-soft);}
  .profile-avatar:hover .profile-circle{outline-color:#fff;transform:translateY(-3px);box-shadow:var(--shadow-lift);}
  .admin-dot{position:absolute;bottom:-3px;right:-3px;background:var(--gold);color:#000;font-size:9px;font-weight:800;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;border:2px solid var(--bg);}
  .profile-name{font-size:13px;color:var(--text-dim);text-align:center;font-weight:600;}
  .profile-avatar:hover .profile-name{color:var(--text);}
  /* Antes siempre visible -- en reposo, con 4+ perfiles en pantalla, esos puntitos suspendidos
     arriba de cada avatar se sentían como ruido visual (el "emplastado" del que habla el usuario).
     Igual que .card-actions en la Biblioteca, solo aparece al pasar el mouse por la tarjeta -- el
     botón sigue siendo exactamente el mismo, con el mismo onclick, nada más se queda quieto hasta
     que hace falta. En touch (sin hover real) sigue apareciendo siempre vía la media query de abajo,
     para no esconder la única forma de llegar a esas opciones en celular. */
  .profile-mini-actions{position:absolute;top:-8px;right:4px;display:flex;gap:4px;z-index:5;opacity:0;transform:translateY(3px);transition:opacity .15s ease, transform .15s ease;}
  .profile-avatar:hover .profile-mini-actions,.profile-avatar:focus-within .profile-mini-actions{opacity:1;transform:translateY(0);}
  .profile-mini-actions .icon-btn{background:rgba(30,30,32,0.92);border:1px solid rgba(255,255,255,0.15);}
  @media (hover:none){ .profile-mini-actions{opacity:1;transform:none;} }
  .add-profile{opacity:0.65;transition:opacity .15s;}
  .add-profile:hover{opacity:1;}
  .add-profile .profile-circle{background:transparent;border:2px dashed var(--border-strong);font-size:30px;font-weight:400;color:var(--text-dim);box-shadow:none;}
  .avatar-lib-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:9px;margin-top:9px;}
  .avatar-lib-item{width:100%;aspect-ratio:1;border-radius:8px;border:2px solid transparent;cursor:pointer;padding:0;background:var(--bg-elev-2);overflow:hidden;transition:border-color .15s, transform .15s;line-height:0;}
  .avatar-lib-item svg{width:100%;height:100%;display:block;}
  .avatar-lib-item:hover{transform:translateY(-2px);}
  .avatar-lib-item.selected{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow);}

  .current-profile{display:flex;align-items:center;gap:9px;cursor:pointer;padding:5px 14px 5px 5px;border-radius:999px;border:1px solid var(--profile-accent, var(--border-strong));background:var(--bg-elev);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);flex-shrink:0;transition:border-color .15s, transform .15s;}
  .current-profile:hover{transform:translateY(-1px);}
  .current-profile .mini-circle{width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:800;color:#fff;background-size:cover;background-position:center;flex-shrink:0;box-shadow:0 0 0 2px var(--bg-elev);}
  .current-profile .mini-name{font-size:13px;font-weight:700;color:var(--text);}

  #toast{position:fixed;bottom:26px;left:50%;transform:translateX(-50%) translateY(20px);background:var(--bg-elev-solid);border:1px solid var(--border-strong);color:var(--text);padding:12px 20px;border-radius:12px;font-size:13px;font-weight:600;opacity:0;pointer-events:none;transition:opacity .25s, transform .25s;z-index:200;box-shadow:var(--shadow-lift);max-width:min(90vw,420px);text-align:center;}
  #bulkActionBar{position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(140%);background:var(--bg-elev-solid);border:1px solid var(--border-strong);border-radius:14px;padding:10px 14px;display:flex;align-items:center;gap:8px;z-index:120;box-shadow:var(--shadow-lift);transition:transform .25s;}
  #bulkActionBar.visible{transform:translateX(-50%) translateY(0);}
  #bulkActionBar .bulk-count{font-size:12px;color:var(--text-dim);white-space:nowrap;margin-right:4px;}
  .card-select-badge{display:none;position:absolute;top:8px;left:8px;width:22px;height:22px;border-radius:50%;background:rgba(10,10,12,.72);border:2px solid rgba(255,255,255,.55);align-items:center;justify-content:center;z-index:3;color:transparent;cursor:pointer;}
  .grid.selection-mode .card-select-badge{display:flex;}
  .grid.selection-mode .card-actions,.grid.selection-mode .card-edit-btn,.grid.selection-mode .card-hover-info{display:none !important;}
  .card.selected .card-select-badge{background:var(--accent,#e50914);border-color:var(--accent,#e50914);color:#fff;}
  .card.selected{outline:2px solid var(--accent,#e50914);outline-offset:-2px;border-radius:8px;}
  #btnToggleSeleccion.active{background:var(--accent,#e50914);border-color:var(--accent,#e50914);color:#fff;}
  #toast.show{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto;}

  .confetti-piece{position:fixed;top:-10px;width:8px;height:8px;z-index:400;pointer-events:none;animation:confettiFall 0.85s ease-in forwards;}
  @keyframes confettiFall{to{transform:translateY(100vh) rotate(400deg);opacity:0.3;}}

  /* Antes iba pegado a la derecha, cerca del riel fijo A-Z (.az-nav, position:fixed;right:8px) —
     ahí es donde de verdad se sentía "encimado con todo". Alineado a la izquierda, junto al
     borde del grid, queda su propio espacio sin pelearse con nada más. Trae una barrita de
     "% vistas" de lo que se está mostrando — se recalcula solita cada vez que cambian los
     filtros, porque usa exactamente la misma lista ya filtrada que arma el conteo "X de Y".
     Texto y barra van dentro de una sola tarjetita (fondo + borde) en vez de flotar sueltos uno
     lejos del otro — así se leen como una sola cosa, no dos piezas desconectadas. */
  /* Recuadro más angosto (4/5 del ancho anterior) y el % alineado a su borde derecho — mismo
     patrón "etiqueta a la izquierda, valor a la derecha" de una fila de estadística. */
  .movie-count-display{font-size:12.5px;color:var(--text-dim);font-weight:600;margin:0 0 18px;padding:12px 16px;background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius);max-width:336px;}
  .movie-count-row{display:flex;align-items:baseline;justify-content:space-between;gap:6px;margin-bottom:9px;flex-wrap:wrap;}
  .movie-count-main{display:flex;align-items:baseline;gap:6px;}
  .movie-count-label{color:var(--text-dim);}
  .movie-count-pct{color:var(--accent);font-weight:800;}
  .movie-count-bar-track{background:var(--bg-elev-2);border-radius:999px;height:6px;overflow:hidden;}
  .movie-count-bar-fill{background:linear-gradient(90deg,var(--accent-2),var(--accent));height:100%;border-radius:999px;min-width:2px;transition:width .3s ease;}
  /* Sorpréndeme junto al contador (pedido explícito, sección 25 del README): cuadrado real gracias
     a aspect-ratio:1 + align-items:stretch en el wrap -- toma la altura que ya tenga la tarjeta
     del contador (texto + barra) y saca su ancho de ahí mismo, así que nunca hay que sincronizar
     números a mano entre los dos. El texto "Sorpréndeme" vive superpuesto y en opacity:0 -- solo
     se ve en hover/focus, tal como se pidió (nada de texto permanente, el dado ya lo dice todo). */
  .movie-count-wrap{display:flex;align-items:stretch;gap:12px;margin-bottom:18px;}
  .movie-count-wrap .movie-count-display{margin-bottom:0;flex:1;min-width:0;}
  /* Primer intento (2026-09-24) metía el texto "Sorpréndeme" ADENTRO del botón cuadrado
     (position:absolute;inset:0) -- a ese tamaño no cabía y se cortaba horrible. Ahora el texto
     vive AFUERA, como una pastilla/tooltip que sale de atrás del botón hacia arriba (pedido
     explícito) -- por eso ya no lleva overflow:hidden (lo necesitaba antes para recortar el
     texto que se salía; ahora nada adentro necesita recortarse, y recortarlo habría cortado
     también la pastilla nueva). Arranca superpuesta y detrás del botón (bottom:6px, opacity:0,
     un pelín más chica) y en hover/focus sube y se revela -- de ahí la sensación de "salir de
     atrás". El triangulito de abajo (::after) la ancla visualmente al botón, como un globo de
     diálogo.
  */
  .btn-surprise-square{flex:0 0 auto;aspect-ratio:1;position:relative;display:flex;align-items:center;justify-content:center;background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius);color:var(--accent);cursor:pointer;transition:border-color .15s ease, background .15s ease, transform .15s ease;}
  .btn-surprise-square:hover, .btn-surprise-square:focus-visible{border-color:var(--accent);background:var(--bg-elev-2);transform:translateY(-1px);outline:none;}
  .btn-surprise-square svg{width:26px;height:26px;transition:transform .15s ease;}
  /* El dado se revuelve en bucle SOLO mientras dura el hover/focus -- para dar la idea de que
     está randomizando y ya casi te avienta una película -- y se detiene solo en cuanto quitas el
     mouse (:hover deja de aplicar), así que no es la clase de loop-sin-fin que ya evitamos en
     otras partes (backdrop de la ficha, posters de la cuadrícula): este es un gesto pedido a
     propósito, acotado 100% a la interacción activa del usuario. */
  .btn-surprise-square:hover svg, .btn-surprise-square:focus-visible svg{animation:diceShake .65s ease-in-out infinite;}
  @keyframes diceShake{
    0%,100%{transform:rotate(0deg) scale(1);}
    20%{transform:rotate(-18deg) scale(1.06);}
    40%{transform:rotate(14deg) scale(1.06);}
    60%{transform:rotate(-10deg) scale(1.03);}
    80%{transform:rotate(8deg) scale(1.03);}
  }
  @media (prefers-reduced-motion: reduce){ .btn-surprise-square:hover svg, .btn-surprise-square:focus-visible svg{animation:none;} }
  .btn-surprise-label{
    position:absolute;left:50%;bottom:6px;
    transform:translate(-50%,0) scale(0.85);
    opacity:0;
    white-space:nowrap;
    background:var(--bg-elev-solid);
    color:var(--text);
    font-size:11.5px;font-weight:800;line-height:1;
    padding:8px 14px;
    border-radius:999px;
    border:1px solid var(--border);
    box-shadow:0 10px 26px rgba(0,0,0,0.45);
    pointer-events:none;
    z-index:20;
    transition:bottom .2s cubic-bezier(.2,.8,.2,1), transform .2s cubic-bezier(.2,.8,.2,1), opacity .18s ease;
  }
  .btn-surprise-label::after{
    content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);
    border:6px solid transparent;border-top-color:var(--bg-elev-solid);
  }
  .btn-surprise-square:hover .btn-surprise-label, .btn-surprise-square:focus-visible .btn-surprise-label{
    bottom:calc(100% + 12px);
    transform:translate(-50%,0) scale(1);
    opacity:1;
  }
  @media (max-width:600px){ .movie-count-wrap .movie-count-display{max-width:none;} }

  /* ============ Barra de controles propia del reproductor (app.js: abrirReproductorTorrent) ============
     Reemplaza por completo los controles nativos del navegador -- 3 rondas tratando de adivinar
     dónde dibuja el navegador SU barra (para alinearnos y saber cuándo se esconde) confirmaron que
     no hay manera real de hacerlo desde afuera: vive en un shadow DOM cerrado sin ninguna API para
     leer su tamaño, posición, ni su propio criterio para ocultarse. Dibujándola nosotros, todo eso
     se vuelve exacto en vez de una aproximación -- y de paso ya se puede vestir con la paleta de
     Natflix (rojo de acento en vez del azul/gris genérico de cualquier navegador). */
  .np-controls{
    position:absolute;left:0;right:0;bottom:0;z-index:8;
    padding:22px 18px 12px;
    background:linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.6) 45%, rgba(0,0,0,0) 100%);
    transition:opacity .25s ease, transform .25s ease;
  }
  .np-controls.np-oculto{opacity:0;pointer-events:none;transform:translateY(6px);}
  @media (prefers-reduced-motion: reduce){ .np-controls.np-oculto{transform:none;} }

  /* Barra de progreso: un <input type=range> transparente (da arrastre + teclado + accesibilidad
     gratis) montado sobre 2 franjas propias -- el fondo tenue (todo el largo), lo ya bufferizado
     (gris claro) y lo ya visto (rojo de acento, con su resplandor) -- porque el range nativo no
     puede pintar 2 colores de "avance" distintos él solo. */
  .np-seek-wrap{position:relative;height:16px;display:flex;align-items:center;margin-bottom:4px;}
  .np-seek-wrap::before{content:"";position:absolute;left:0;right:0;height:4px;border-radius:3px;top:50%;transform:translateY(-50%);background:rgba(255,255,255,0.22);}
  .np-seek-buffered, .np-seek-fill{position:absolute;left:0;height:4px;border-radius:3px;top:50%;transform:translateY(-50%);}
  .np-seek-buffered{background:rgba(255,255,255,0.38);width:0%;}
  .np-seek-fill{background:var(--accent);width:0%;box-shadow:0 0 8px var(--accent-glow);}
  .np-seek-input{-webkit-appearance:none;appearance:none;position:relative;display:block;width:100%;height:16px;background:transparent;margin:0;cursor:pointer;}
  .np-seek-input::-webkit-slider-runnable-track{background:transparent;height:16px;}
  .np-seek-input::-moz-range-track{background:transparent;height:16px;}
  .np-seek-input::-webkit-slider-thumb{-webkit-appearance:none;width:13px;height:13px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 3px rgba(0,0,0,0.4);margin-top:0;transition:transform .12s ease;}
  .np-seek-input::-moz-range-thumb{width:13px;height:13px;border-radius:50%;background:var(--accent);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0.4);transition:transform .12s ease;}
  .np-seek-wrap:hover .np-seek-input::-webkit-slider-thumb, .np-seek-input:focus-visible::-webkit-slider-thumb{transform:scale(1.3);}
  .np-seek-wrap:hover .np-seek-input::-moz-range-thumb, .np-seek-input:focus-visible::-moz-range-thumb{transform:scale(1.3);}
  .np-seek-input:focus-visible{outline:none;}

  /* Fila de íconos: play/pausa + ±10s + contador a la izquierda (pegados de verdad ahora, por fin
     -- son literalmente hermanos en el mismo div), CC/volumen/pantalla completa a la derecha. */
  .np-row{display:flex;align-items:center;justify-content:space-between;gap:8px;}
  .np-row-left, .np-row-right{display:flex;align-items:center;gap:3px;}
  .np-icon-btn{background:transparent;border:none;color:#fff;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .15s ease, color .15s ease;}
  .np-icon-btn svg{width:16px;height:16px;}
  .np-icon-btn:hover, .np-icon-btn:focus-visible{background:rgba(255,255,255,0.14);color:var(--accent);outline:none;}
  .np-play-btn{width:36px;height:36px;}
  .np-play-btn svg{width:18px;height:18px;}
  .np-time{color:#fff;font-size:12px;font-variant-numeric:tabular-nums;opacity:.92;margin-left:4px;white-space:nowrap;}
  /* Pulso al tocar ±10 -- puro feedback de "sí registró el toque", una sola vuelta (no en bucle,
     a diferencia del diceShake del botón Sorpréndeme: este no depende de que sigas interactuando,
     así que si fuera infinite se quedaría animando solo). Se reinicia en JS quitando y reponiendo
     esta clase (ver pulsar() en abrirReproductorTorrent). */
  .np-skip.skip-pulse{animation:skipPulse .3s ease-out;}
  @keyframes skipPulse{
    0%{transform:scale(1);}
    40%{transform:scale(0.78);}
    100%{transform:scale(1);}
  }
  @media (prefers-reduced-motion: reduce){ .np-skip.skip-pulse{animation:none;} }

  /* Menú de CC -- ahora disponible para TODA la familia, no solo el admin (antes lo resolvía el
     CC nativo del navegador, que desapareció junto con sus controles). */
  .np-cc-wrap{position:relative;}
  .np-cc-menu{position:absolute;bottom:calc(100% + 10px);right:0;background:rgba(15,17,20,0.94);backdrop-filter:blur(6px);border:1px solid rgba(255,255,255,0.16);border-radius:10px;min-width:170px;max-width:260px;padding:6px;display:none;box-shadow:0 12px 30px rgba(0,0,0,0.5);z-index:9;}
  .np-cc-menu.np-abierto{display:block;}
  .np-cc-item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:none;border:none;color:#fff;border-radius:7px;padding:8px 9px;font-size:12px;line-height:1.35;cursor:pointer;word-break:break-word;}
  .np-cc-item:hover, .np-cc-item:focus-visible{background:rgba(255,255,255,0.1);outline:none;}
  .np-cc-item.np-activo{background:rgba(229,9,20,0.22);}
  .np-cc-check{flex-shrink:0;width:14px;display:flex;color:var(--accent);}

  @media (max-width:480px){
    .np-controls{padding:16px 10px 8px;}
    .np-icon-btn{width:28px;height:28px;}
    .np-icon-btn svg{width:14px;height:14px;}
    .np-play-btn{width:32px;height:32px;}
    .np-play-btn svg{width:16px;height:16px;}
    .np-time{font-size:11px;}
  }

  /* Antes era .15s -- se sentía más como un corte que como un crossfade. Con más duración +
     un empujoncito vertical leve (translateY) la transición entre Inicio y Biblioteca se percibe
     como un cambio de vista real en vez de un parpadeo — ver switchPage(), que ya traía toda la
     coreografía (display:none retrasado, doble rAF) pero corriendo sobre esta misma transición. */
  #viewInicio, #viewBiblioteca{transition:opacity .32s ease, transform .32s ease;}
  .page-fade-out{opacity:0;transform:translateY(6px);}

  #loadingOverlay{position:fixed;inset:0;background:var(--bg);z-index:500;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px;}
  .loading-logo{height:56px;animation:loadingPulse 1.6s ease-in-out infinite;}
  @keyframes loadingPulse{0%,100%{opacity:0.4;}50%{opacity:1;}}
  .skeleton-profile-grid{display:flex;gap:32px;flex-wrap:wrap;justify-content:center;max-width:920px;}
  .skeleton-profile-avatar{width:124px;display:flex;flex-direction:column;align-items:center;gap:11px;}
  .skeleton-circle, .skeleton-line{background:linear-gradient(90deg, var(--bg-elev) 25%, var(--bg-elev-2) 50%, var(--bg-elev) 75%);background-size:200% 100%;animation:shimmer 1.6s infinite;}
  /* 112px: mismo tamaño que .profile-circle real (ver sección de .profile-screen) -- si uno de
     los dos cambia, el otro se queda viendo distinto al cargar vs. ya cargado. */
  .skeleton-circle{width:112px;height:112px;border-radius:20px;}
  .skeleton-line{width:64px;height:11px;border-radius:5px;}

  #introOverlay{position:fixed;inset:0;background:#000;z-index:600;display:none;align-items:center;justify-content:center;}
  #introOverlay.active{display:flex;}
  #introVideo{width:100%;height:100%;object-fit:contain;background:#000;}
  #btnSkipIntro{position:absolute;bottom:26px;right:26px;background:rgba(255,255,255,0.12);border:1px solid rgba(255,255,255,0.35);color:#fff;padding:9px 18px;border-radius:20px;font-size:13px;font-weight:600;cursor:pointer;backdrop-filter:blur(4px);z-index:2;transition:background .15s;}
  #btnSkipIntro:hover{background:rgba(255,255,255,0.25);}
  #btnUnmuteIntro{position:absolute;bottom:26px;left:26px;background:rgba(255,255,255,0.12);border:1px solid rgba(255,255,255,0.35);color:#fff;padding:9px 18px;border-radius:20px;font-size:13px;font-weight:600;cursor:pointer;backdrop-filter:blur(4px);z-index:2;}
  #btnUnmuteIntro:hover{background:rgba(255,255,255,0.25);}
  @media (max-width:600px){
    #btnSkipIntro,#btnUnmuteIntro{bottom:16px;padding:8px 14px;font-size:12px;}
    #btnSkipIntro{right:16px;}
    #btnUnmuteIntro{left:16px;}
  }


  #posterLightbox{position:fixed;inset:0;background:rgba(0,0,0,0.92);backdrop-filter:blur(4px);z-index:400;display:none;align-items:center;justify-content:center;padding:40px;}
  #posterLightbox img{max-width:90vw;max-height:90vh;border-radius:var(--radius);box-shadow:0 20px 60px rgba(0,0,0,0.6);}
  #btnClosePosterLightbox{position:absolute;top:20px;right:20px;background:rgba(255,255,255,0.12);color:#fff;border:1px solid rgba(255,255,255,0.25);}

  .detail-poster{position:relative;width:100%;border-radius:14px;margin-bottom:14px;aspect-ratio:2/3;background-size:cover;background-position:center;cursor:pointer;box-shadow:var(--shadow-soft);}
  .detail-play-btn{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:56px;height:56px;border-radius:50%;background:rgba(20,20,20,0.5);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);border:2px solid rgba(255,255,255,0.85);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0.9;transition:opacity .15s, transform .15s, background .15s;}
  .detail-play-btn svg{width:20px;height:20px;margin-left:3px;}
  .detail-play-btn:hover{opacity:1;transform:translate(-50%,-50%) scale(1.1);background:var(--accent);border-color:var(--accent);}
  #detailOverlay{backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);}
  .detail-plot{font-size:13px;line-height:1.6;color:var(--text);margin:12px 0;}
  .curator-note{font-size:12.5px;line-height:1.55;color:var(--text-dim);font-style:italic;margin:0 0 14px;padding:10px 12px;border-left:2px solid var(--gold);background:var(--bg-elev);border-radius:0 8px 8px 0;}
  .detail-row{font-size:11.5px;color:var(--text-dim);margin-bottom:4px;}
  .detail-row b{color:var(--text);}
  .detail-badges{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 10px;}
  .detail-chip{font-size:10.5px;font-weight:700;padding:4px 10px;border-radius:999px;background:var(--bg-elev-2);border:1px solid var(--border);color:var(--text-dim);}
  /* Reacciones de la familia (reactionSummary) reusan esta misma pastilla -- antes salían como
     texto suelto con un ícono, sin relación visual con los chips de género de arriba. */
  .detail-chip-reaction{display:inline-flex;align-items:center;gap:5px;}
  .cast-row{display:flex;flex-wrap:wrap;gap:14px;margin-top:12px;}
  .cast-chip{display:flex;flex-direction:column;align-items:center;gap:6px;width:64px;}
  .cast-avatar{width:44px;height:44px;border-radius:50%;background:linear-gradient(160deg, var(--bg-elev-2), var(--bg-elev));border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:14px;color:var(--text);}
  .cast-avatar.director{background:linear-gradient(160deg, rgba(229,9,20,0.35), rgba(229,9,20,0.08));border-color:rgba(229,9,20,0.4);color:#fff;}
  .cast-name{font-size:9.5px;color:var(--text-dim);text-align:center;line-height:1.25;}

  /* ---------- Ficha de película inmersiva (detailOverlay) ---------- */
  .detail-modal{padding:0;overflow:hidden;}
  .detail-body{padding:26px;}
  @media (max-width:600px){ .detail-body{padding:18px;} }
  /* background-position con sesgo a la parte superior (12% en vez de centrado) por la misma razón
     que .hero-bg — evita cortar cabezas en un recuadro panorámico corto. La transición es de
     opacity (background-image no se puede animar) — ver aplicarBackdropDetalleSiSigueVigente(). */
  .detail-backdrop{position:relative;width:100%;height:260px;background-size:cover;background-position:center 12%;background-color:var(--bg-elev-solid);transition:opacity .35s ease;overflow:hidden;}
  @media (max-width:600px){ .detail-backdrop{height:170px;} }
  /* Antes el fondo se quedaba estático al abrir la ficha -- se ve más vivo con un acercamiento
     FINITO al abrir (una sola vez, se detiene solo). A propósito NO es un loop continuo: ya
     probamos eso en los posters del grid (ver @keyframes de más abajo, cerca de posterZoom) y lo
     revertimos porque un zoom sin fin competía con la atención del usuario en vez de dejarlo leer
     tranquilo -- aquí hay texto encima todo el tiempo, así que aplica la misma lección. Se
     reinicia en cada apertura quitando y volviendo a poner esta clase (ver openDetail()).
     transform-origin:center + overflow:hidden en el padre evita que el ligero exceso de zoom
     asome fuera del recuadro mientras se asienta. */
  .detail-backdrop.backdrop-settle{animation:detailBackdropSettle .9s cubic-bezier(.2,.7,.2,1);transform-origin:center;}
  @keyframes detailBackdropSettle{ from{ transform:scale(1.06); } to{ transform:scale(1); } }
  @media (prefers-reduced-motion: reduce){ .detail-backdrop.backdrop-settle{ animation:none; } }
  .detail-backdrop::before{content:"";position:absolute;inset:0;background:linear-gradient(0deg, var(--bg-elev-2) 0%, rgba(8,8,11,0.4) 55%, rgba(8,8,11,0.18) 100%);}
  .detail-backdrop-close{position:absolute;top:14px;right:14px;width:34px;height:34px;border-radius:50%;background:rgba(10,10,14,0.55);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.25);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:2;}
  .detail-backdrop-close:hover{background:rgba(10,10,14,0.8);}
  .detail-backdrop-content{position:absolute;left:0;right:0;bottom:0;padding:20px 26px;z-index:1;}
  @media (max-width:600px){ .detail-backdrop-content{padding:12px 18px;} }
  .detail-backdrop-content .cine-title{color:#fff;text-shadow:0 4px 18px rgba(0,0,0,0.65);margin:0 0 6px;font-size:26px;}
  @media (max-width:600px){ .detail-backdrop-content .cine-title{font-size:20px;} }
  .detail-row-light{color:rgba(255,255,255,0.85) !important;}
  .detail-row-light b{color:#fff !important;}
  .detail-row-light .detail-chip{background:rgba(255,255,255,0.14);border-color:rgba(255,255,255,0.22);color:#fff;}
  .detail-notes-btn{display:inline-flex;align-items:center;gap:6px;margin:6px 0;font-size:12px;padding:6px 12px;}
  /* "Tu registro personal": estado/calificación/mensaje directo en la ficha, para que nadie
     (admin incluido) tenga que pasar por "Editar película" solo para eso — ver la nota junto a
     openDetail() sobre por qué esto hacía falta: antes, el botón Editar era admin-only en la
     ficha, así que el resto de la familia no tenía NINGÚN lugar donde poner su calificación o
     su mensaje. */
  /* .detail-top-row: poster a la izquierda, sinopsis a la derecha. */
  .detail-top-row{display:grid;grid-template-columns:170px 1fr;gap:20px;align-items:start;}
  @media (max-width:560px){ .detail-top-row{grid-template-columns:1fr;} .detail-top-row .detail-poster{width:150px;margin:0 auto;} }
  .detail-top-row .detail-plot{margin:0;}
  .detail-top-row #detailActors{margin-top:14px;}
  /* .detail-bottom-row: registro personal a 2/3 de ancho, botones de acción apilados en vertical
     en el 1/3 restante — así lo pidió el usuario explícitamente. */
  .detail-bottom-row{display:grid;grid-template-columns:2fr 1fr;gap:18px;align-items:start;margin-top:18px;}
  @media (max-width:700px){ .detail-bottom-row{grid-template-columns:1fr;} }
  /* Ficha de una película "próximamente": sin registro personal, solo queda el botón Cerrar —
     una sola columna centrada y angosta en vez del ancho pensado para dos columnas. */
  .detail-bottom-row-solo{grid-template-columns:1fr;justify-items:center;}
  .detail-bottom-row-solo .detail-actions-vertical{max-width:220px;width:100%;}
  .detail-actions-vertical{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:8px;margin-top:0;}
  .detail-actions-vertical .btn{width:100%;justify-content:center;}
  /* "Eliminar" solo tenía el texto en rojo sobre un btn-ghost normal -- se veía casi igual que
     Recomendar/Listas/Editar, sin avisar que es la acción destructiva del grupo. Se le da su propio
     tratamiento (tinte + borde en --danger) para que se note de un vistazo sin mover ni renombrar
     nada -- sigue siendo el mismo botón, mismo onclick, mismo lugar en la columna. */
  #btnDetailDelete{color:var(--danger);border-color:rgba(255,92,92,0.35);background:rgba(255,92,92,0.08);}
  #btnDetailDelete:hover{color:#fff;background:var(--danger);border-color:var(--danger);}
  .detail-personal{margin:0;padding:14px 16px;background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius);}
  /* Tráiler: botón propio en la esquina inferior derecha de la imagen del backdrop, para que
     resalte en vez de perderse como texto plano junto a IMDb/RT (como vivía antes). */
  .detail-trailer-link{position:absolute;right:14px;bottom:14px;z-index:2;display:inline-flex;align-items:center;gap:6px;background:var(--gold);color:#000;font-weight:700;font-size:13px;line-height:1;padding:9px 16px;border-radius:999px;text-decoration:none;box-shadow:0 4px 14px rgba(0,0,0,0.35);transition:transform .15s ease, box-shadow .15s ease, background .15s ease;}
  .detail-trailer-link:hover{background:#fff;transform:translateY(-1px);box-shadow:0 6px 18px rgba(0,0,0,0.45);}
  .detail-trailer-link svg{position:relative;top:-0.5px;}
  @media (max-width:600px){ .detail-trailer-link{right:10px;bottom:10px;padding:7px 13px;font-size:12px;} }
  /* Estado y calificación uno junto al otro, mensaje en su propia fila completa debajo — con el
     panel a 2/3 del modal (ver .detail-bottom-row) ya no cabían las tres columnas lado a lado sin
     apretar demasiado el mensaje. */
  .detail-personal-row{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start;}
  .detail-personal-notas-field{grid-column:1 / -1;}
  @media (max-width:420px){ .detail-personal-row{grid-template-columns:1fr;} .detail-personal-notas-field{grid-column:auto;} }
  .detail-personal .star-picker{padding-top:2px;}
  .detail-personal-notas-field textarea{min-height:64px;}
  .detail-personal-notas-field #btnGuardarPersonal{margin-top:8px;display:block;margin-left:auto;}
  /* Botón flotante de agregar película (solo admin) -- ver el comentario junto a #btnFloatingAdd
     en index.html sobre por qué vive fuera de .toolbar y con z-index por debajo de .overlay. */
  .fab-add{position:fixed;right:22px;bottom:22px;width:52px;height:52px;border-radius:14px;background:var(--accent);color:#fff;border:none;display:none;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 10px 26px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.08);z-index:60;transition:transform .15s ease, box-shadow .15s ease, background .15s ease;}
  .fab-add:hover{transform:translateY(-2px) scale(1.05);box-shadow:0 14px 32px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.12);}
  .fab-add svg{width:22px;height:22px;}
  @media (max-width:600px){ .fab-add{right:14px;bottom:74px;width:46px;height:46px;} }
  .detail-similares-panel{margin-top:22px;padding-top:18px;border-top:1px solid var(--border);}
  .detail-similares-panel .section-title{font-size:16px;margin-bottom:10px;}
  .nota-entry{padding:12px 0;border-bottom:1px solid var(--border);}
  .nota-entry:last-child{border-bottom:none;}
  .nota-entry-nombre{font-size:12px;font-weight:800;color:var(--accent);margin-bottom:4px;}
  .nota-entry-texto{font-size:13px;line-height:1.55;color:var(--text);white-space:pre-wrap;}


  .history-item, .trash-item{display:flex;align-items:center;gap:12px;padding:9px 0;border-bottom:1px solid var(--border);}
  .history-item:last-child, .trash-item:last-child{border-bottom:none;}
  .history-poster{width:42px;aspect-ratio:2/3;border-radius:6px;background-size:cover;background-position:center;flex-shrink:0;background-color:var(--bg-elev-2);}

  .view-tabs{display:flex;gap:26px;}
  .view-tab{background:none;border:none;border-bottom:2px solid transparent;color:var(--text-dim);padding:5px 0;margin-bottom:-1px;font-weight:800;font-size:13px;letter-spacing:0.5px;text-transform:uppercase;cursor:pointer;transition:color .15s;}
  .view-tab:hover{color:var(--text);}
  .view-tab.active{color:var(--text);border-bottom-color:var(--profile-accent, var(--accent));}

  .activity-row{display:flex;gap:16px;overflow-x:auto;padding-top:18px;padding-bottom:10px;scroll-snap-type:x proximity;}
  .activity-row::-webkit-scrollbar{height:6px;}
  /* 150px -> 168px: mismo espíritu "menos tarjetas pero con más presencia" que ya se aplicó a
     Destacados, aquí en una versión moderada porque esta sí sigue siendo una fila de scroll
     horizontal densa (no tendría sentido agrandarla al nivel de Destacados). */
  .activity-row .activity-card{flex:0 0 168px;scroll-snap-align:start;}
  .activity-card{background:var(--bg-elev);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid var(--border);border-radius:var(--radius);overflow:visible;position:relative;display:flex;flex-direction:column;box-shadow:var(--shadow-soft);transition:transform .25s cubic-bezier(.2,.8,.2,1), box-shadow .25s ease, border-color .25s ease;}
  .activity-card:hover{transform:scale(1.06) translateY(-4px);box-shadow:0 22px 44px rgba(0,0,0,0.5), 0 0 0 1px var(--border-strong);z-index:4;border-color:var(--border-strong);}
  .activity-poster{aspect-ratio:2/3;width:100%;background-size:cover;background-position:center;cursor:pointer;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.85);font-weight:700;font-size:13px;text-align:center;padding:8px;border-radius:var(--radius);overflow:hidden;position:relative;}
  /* Antes .reaction-row vivía en su propia franja (.activity-body) siempre visible debajo del
     póster -- ahora es un overlay con degradado DENTRO del póster, oculto hasta el hover, igual
     que .card-actions en Biblioteca y .destacada-actions en Destacados. Unifica el "lenguaje" de
     las 3 variantes de tarjeta de la app en una sola idea: la imagen manda, las acciones aparecen
     cuando las buscas. */
  .reaction-row{position:absolute;left:0;right:0;bottom:0;display:flex;justify-content:center;gap:6px;padding:14px 6px 8px;background:linear-gradient(to top, rgba(0,0,0,0.85), rgba(0,0,0,0.35) 65%, transparent);opacity:0;transition:opacity .2s ease;z-index:3;}
  .activity-card:hover .reaction-row{opacity:1;}
  .activity-attrib{font-size:10.5px;line-height:1.35;color:var(--text-dim);font-weight:600;margin-top:8px;padding:0 2px;}

  /* "Para ti" como vista completa (#37): mismo .activity-card de siempre, nomás en cuadrícula
     (wrap) en vez de una sola fila con scroll horizontal -- por eso NO se le pone flex-basis fijo
     aquí, el ancho de columna de la cuadrícula ya lo controla. */
  .activity-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(150px, 1fr));gap:18px;padding-top:4px;padding-bottom:10px;}
  .paratipage-header{padding-top:18px;}
  .paratipage-sub{font-size:12.5px;color:var(--text-dim);margin-top:2px;}

  /* ---------- Ronda 10: "Para ti" con 3 modos (Swipe / Encuesta rápida / Tarjetas con razón) --
     pedido explícito, "la versión con esteroides del botón 'Sorpréndeme'". Reemplaza la fila de
     chips de mood/ocasión de antes (#12) -- esos mismos moods ahora viven DENTRO del modo
     Encuesta rápida, como la primera pregunta, en vez de ser el único filtro disponible. --------- */
  /* Ronda 12, pedido explícito ("no me gusta que se descuadren/desalineen los botones cuando
     aparece... continuar donde te quedaste"): era align-items:center -- con el chip de Swipe más
     alto que los otros 2 (chip + el link de "Continuar" debajo), centrar cada wrap dentro de la
     fila los dejaba a alturas visualmente distintas entre sí. flex-start alinea las 3 cajas por
     arriba siempre, venga o no el link de abajo -- la altura extra del de Swipe ahora solo se nota
     POR DEBAJO de la fila, nunca descuadrando a los otros 2. */
  .paratipage-modes{display:flex;flex-wrap:wrap;gap:12px;padding:16px 0 22px;align-items:flex-start;}
  .mode-chip-wrap{display:flex;flex-direction:column;align-items:flex-start;gap:7px;}
  .mode-chip{
    display:flex;align-items:center;gap:12px;
    background:var(--bg-elev);border:1px solid var(--border);border-radius:14px;
    padding:12px 18px 12px 14px;cursor:pointer;text-align:left;font-family:inherit;color:inherit;
    transition:background .15s, border-color .15s, transform .15s;
  }
  .mode-chip:hover{border-color:var(--border-strong);transform:translateY(-1px);}
  .mode-chip.active{background:var(--accent);border-color:var(--accent);}
  .mode-chip-icon{flex:0 0 auto;width:34px;height:34px;border-radius:50%;background:var(--accent-glow);color:var(--accent);display:flex;align-items:center;justify-content:center;}
  .mode-chip.active .mode-chip-icon{background:rgba(255,255,255,0.22);color:#fff;}
  .mode-chip-icon svg{width:16px;height:16px;}
  /* Ronda 11, pedido explícito: ya no hay línea de descripción debajo del título -- cada chip es
     solo ícono + nombre (ver renderParaTiModeRow). .mode-chip-text/.mode-chip-desc quedaron sin uso. */
  .mode-chip-title{font-size:13.5px;font-weight:800;color:var(--text);}
  .mode-chip.active .mode-chip-title{color:#fff;}
  /* Ronda 13: se quitó el botón "Continuar donde te quedaste" (.mode-continue-chip) -- pedido
     explícito de Daniel, ya no tenía utilidad con lotes de Swipe de tamaño fijo. */

  .paratipage-intro{text-align:center;padding:70px 20px;color:var(--text-dim);}
  .paratipage-intro-icon{margin-bottom:12px;opacity:0.4;}
  .paratipage-intro-icon svg{width:40px;height:40px;}
  .paratipage-intro-text{font-size:13px;}

  /* --- Modo Swipe: una tarjeta grande centrada, con botones pasar/ver/me-interesa debajo -- el
     patrón "una cosa a la vez, decides y avanzas" es justo el punto, por eso NO es una cuadrícula
     como las otras dos. --- */
  .swipe-stage{display:flex;flex-direction:column;align-items:center;padding:10px 0 30px;}
  .swipe-progress{font-size:11.5px;font-weight:700;color:var(--text-dim);margin-bottom:14px;letter-spacing:0.5px;}
  .swipe-card{width:min(280px, 80vw);background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;box-shadow:0 20px 50px rgba(0,0,0,0.4);}
  .swipe-card-poster{width:100%;aspect-ratio:2/3;background-size:cover;background-position:center;background-color:var(--bg-elev-2);display:flex;align-items:center;justify-content:center;font-weight:800;color:var(--text-dim);cursor:pointer;position:relative;}
  .swipe-card-info{padding:14px 16px 16px;}
  .swipe-card-title{font-size:15px;font-weight:800;color:var(--text);margin-bottom:3px;}
  .swipe-card-meta{font-size:11.5px;color:var(--text-dim);}
  .swipe-actions{display:flex;align-items:center;gap:16px;margin-top:22px;}
  .swipe-btn{
    display:flex;align-items:center;justify-content:center;
    width:54px;height:54px;border-radius:50%;border:1px solid var(--border);background:var(--bg-elev);
    cursor:pointer;color:var(--text);transition:transform .12s, border-color .12s, background .12s;
  }
  .swipe-btn:hover{transform:scale(1.08);}
  .swipe-btn svg{width:20px;height:20px;}
  .swipe-btn-pass{color:var(--text-dim);}
  .swipe-btn-pass:hover{border-color:#e5484d;color:#e5484d;}
  .swipe-btn-info{width:42px;height:42px;}
  .swipe-btn-info svg{width:15px;height:15px;}
  .swipe-btn-like{background:var(--accent);border-color:var(--accent);color:#fff;}
  .swipe-btn-like:hover{background:var(--accent);filter:brightness(1.1);}
  .swipe-done{text-align:center;padding:60px 20px;}
  .swipe-done-icon{display:inline-flex;align-items:center;justify-content:center;width:52px;height:52px;border-radius:50%;background:var(--accent-glow);color:var(--accent);margin-bottom:16px;}
  .swipe-done-icon svg{width:22px;height:22px;}
  .swipe-done-title{font-size:16px;font-weight:800;color:var(--text);margin-bottom:5px;}
  .swipe-done-sub{font-size:12.5px;color:var(--text-dim);margin-bottom:18px;}

  /* --- Encuesta rápida ---------------------------------------------------------------------
     Ronda 12, pedido explícito ("se siente todo improvisado, no como un add-on especializado"):
     cada pregunta ahora vive dentro de una tarjeta propia (.survey-card, mismo lenguaje visual de
     superficie elevada + borde que ya usan .activity-card/.mode-chip) en vez de botones sueltos
     flotando directo sobre el fondo de la página, y trae un indicador de progreso arriba ("Paso 1
     de 3" + 3 barritas) para que se sienta como un flujo con principio y fin, no una fila de chips
     más. --------------------------------------------------------------------------------------- */
  /* BUG REAL encontrado (2026-10-04, reporte directo "céntralo, se ve mal tirado a la izquierda"):
     max-width:560px sin margin:auto deja la tarjeta pegada al borde izquierdo del contenedor (el
     comportamiento normal de un bloque que no llena su ancho) -- con pantallas anchas se veía un
     bloque angosto flotando a la izquierda con todo el resto vacío a la derecha. margin:0 auto la
     centra horizontalmente dentro de #paraTiContent sin tocar su ancho máximo. */
  .survey-card{max-width:560px;margin:0 auto;background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius);padding:26px 26px 22px;box-shadow:var(--shadow-soft);}
  .survey-back{display:flex;align-items:center;gap:4px;background:none;border:none;font-family:inherit;cursor:pointer;color:var(--text-dim);font-size:11.5px;font-weight:700;margin-bottom:14px;padding:0;}
  .survey-back:hover{color:var(--text);}
  .survey-back svg{width:9px;height:9px;transform:rotate(90deg);}
  .survey-progress{display:flex;gap:6px;margin-bottom:9px;}
  .survey-progress-dot{height:4px;flex:1;border-radius:999px;background:var(--border);transition:background .2s ease;}
  .survey-progress-dot.done{background:var(--accent);opacity:0.5;}
  .survey-progress-dot.active{background:var(--accent);}
  .survey-step-label{font-size:10.5px;font-weight:800;letter-spacing:1.3px;text-transform:uppercase;color:var(--text-dim);margin-bottom:14px;}
  .survey-question{font-family:'Bebas Neue', sans-serif;font-size:25px;letter-spacing:0.5px;color:var(--text);margin-bottom:18px;text-wrap:balance;}
  .survey-options{display:flex;flex-wrap:wrap;gap:10px;}
  .survey-option-btn{
    display:flex;align-items:center;gap:10px;flex:1 1 calc(50% - 5px);min-width:150px;
    background:var(--bg-elev-2, var(--bg));border:1px solid var(--border);border-radius:12px;
    padding:13px 16px;font-family:inherit;font-size:13.5px;font-weight:700;color:var(--text);text-align:left;
    cursor:pointer;transition:background .15s, border-color .15s, transform .15s;
  }
  /* Circulito vacío a la izquierda, mismo gesto visual que un radio button real -- refuerza que
     esto es una pregunta de verdad con una respuesta que vas a elegir, no un botón cualquiera. */
  .survey-option-btn::before{content:"";width:15px;height:15px;flex-shrink:0;border-radius:50%;border:2px solid var(--border-strong);transition:border-color .15s;}
  .survey-option-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-glow);transform:translateY(-1px);}
  .survey-option-btn:hover::before{border-color:var(--accent);}
  .survey-results-header{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius);padding:14px 18px;margin-bottom:18px;}
  .survey-results-resumen{display:flex;flex-wrap:wrap;gap:7px;}
  .survey-resumen-chip{font-size:11.5px;font-weight:700;color:var(--text);background:var(--accent-glow);border:1px solid rgba(229,72,77,0.35);border-radius:999px;padding:4px 11px;}

  /* Ronda 11, pedido explícito: "Selección personalizada" ya no repite la razón como texto chiquito
     bajo cada tarjeta (eso se sentía repetido con 12+ tarjetas) -- ahora la razón es el TÍTULO de
     una sección, una vez, y las tarjetas de ese grupo van debajo. */
  .personalizada-seccion{margin-bottom:24px;}
  .personalizada-seccion:last-child{margin-bottom:0;}
  .personalizada-seccion-titulo{font-family:'Bebas Neue', sans-serif;font-size:19px;letter-spacing:0.4px;color:var(--text);margin-bottom:10px;}
  /* Pedido explícito: con varias secciones apiladas, los pósters a su tamaño normal (mínimo 150px)
     armaban demasiadas filas y obligaban a scrollear de más para algo que debería ser rápido de
     ojear. Pósters más chicos aquí (mínimo 108px en vez de 150px, gap más angosto) -- caben más
     por fila, bajan las filas totales, sin tocar .activity-grid en ningún otro lado de la app
     (Swipe/Encuesta siguen a su tamaño normal, ahí no hay el mismo problema de "muchas secciones
     apiladas"). */
  .personalizada-seccion .activity-grid{grid-template-columns:repeat(auto-fill, minmax(108px, 1fr));gap:12px;}
  .personalizada-seccion .activity-attrib{font-size:9.5px;}

  /* Presencia en vivo (#38): pastilla discreta en texto, no un banner llamativo -- un punto
     verde pulsando (mismo verde que ya usa #subEstadoPill para "guardado") + una sola línea. */
  .presencia-badge{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text-dim);background:var(--bg-elev);border:1px solid var(--border);border-radius:999px;padding:7px 14px;margin-bottom:16px;width:fit-content;}
  .presencia-badge b{color:var(--text);font-weight:700;}
  .presencia-dot{width:7px;height:7px;border-radius:50%;background:#2fbf71;flex-shrink:0;box-shadow:0 0 0 0 rgba(47,191,113,0.55);animation:presenciaPulse 2s infinite;}
  @keyframes presenciaPulse{
    0%{box-shadow:0 0 0 0 rgba(47,191,113,0.55);}
    70%{box-shadow:0 0 0 5px rgba(47,191,113,0);}
    100%{box-shadow:0 0 0 0 rgba(47,191,113,0);}
  }
  @media (prefers-reduced-motion: reduce){ .presencia-dot{animation:none;} }

  /* Destacados: bloque especial con formato propio, nada compartido con .activity-card. Tarjetas
     panorámicas que entre las 4 ocupan todo el ancho (grid, no scroll horizontal), con imagen de
     fondo tipo backdrop (no el póster vertical que ya se repite en Nuevo en Natflix/Estrenos — ver
     aplicarBackdropDestacadaSiSigueVigente), numeral en un chip de vidrio en la esquina superior
     derecha (nada de números gigantes que se cortan) y los botones flotando directo sobre la
     imagen — sin ninguna franja opaca abajo, solo un degradado para que el título se lea. */
  /* auto-fit (no un número fijo de columnas) a propósito: con repeat(4,1fr) fijo, cuando alguna
     categoría no tiene con qué llenarse (por ejemplo no hay nada "aclamado" esta semana) las 2 o 3
     tarjetas que sí salen se quedaban apretadas en las primeras columnas con un hueco vacío al
     lado -- se veía triste. Así, las que hay siempre se reparten para llenar todo el ancho, sean
     2, 3 o 4 -- y sigue siendo responsivo solo: en pantallas angostas caben menos columnas de
     260px, así que se acomodan solas sin necesitar media queries aparte. */
  /* Pedido explícito (2026-10-01): "cuadros grandes, no rectangulitos" -- antes eran 16:9
     (rectángulos anchos y bajitos, 2 por fila en desktop) con minmax(260px,1fr), que a ese ancho
     salían como tarjetas de ~540x300 -- grandes en papel pero de proporción "achatada", sin
     presencia. Ahora son cuadradas de verdad (aspect-ratio 1/1) y el mínimo de columna sube a
     280px, así que en vez de 2 rectángulos anchos salen 3 cuadros grandes y sólidos por fila en
     desktop (siguen repartiéndose para llenar el ancho completo entre 1-4, responsivo, sin media
     queries aparte -- mismo mecanismo de auto-fit que ya traía). */
  .destacados-grid{display:grid;grid-template-columns:repeat(auto-fit, minmax(280px, 1fr));gap:20px;padding-top:18px;padding-bottom:10px;}
  .destacada-card{position:relative;aspect-ratio:1/1;border-radius:var(--radius);overflow:hidden;cursor:pointer;background:var(--bg-elev-2);border:1px solid var(--border);box-shadow:var(--shadow-soft);transition:transform .25s cubic-bezier(.2,.8,.2,1), box-shadow .25s ease;}
  .destacada-card:hover{transform:scale(1.03);box-shadow:0 22px 44px rgba(0,0,0,0.5), 0 0 0 1px var(--border-strong);}
  .destacada-bg{position:absolute;inset:0;background-size:cover;background-position:center;transition:opacity .4s ease, filter .4s ease;}
  .destacada-scrim{position:absolute;inset:0;background:linear-gradient(0deg, rgba(6,6,9,0.9) 0%, rgba(6,6,9,0.32) 46%, rgba(6,6,9,0.05) 70%);pointer-events:none;}
  /* Numeral grande "hueco" (puro stroke) como antes -- pero esta vez arriba a la izquierda y SIN
     ningún offset negativo: la tarjeta de Destacados es overflow:hidden (para recortar la imagen de
     fondo en las esquinas redondeadas), así que colgarlo fuera del borde como la primera vez lo
     recortaba a la mitad. Contenido dentro de la tarjeta, no se corta nunca. Tamaño subido de 50px a
     72px para que siga viéndose proporcional en el cuadro más grande. */
  .destacada-rank{position:absolute;top:10px;left:14px;font-size:72px;font-weight:800;line-height:1;color:rgba(10,10,14,0.4);-webkit-text-stroke:2.5px rgba(255,255,255,0.92);text-shadow:0 4px 14px rgba(0,0,0,0.5);z-index:3;pointer-events:none;user-select:none;}
  .destacada-bottom{position:absolute;left:0;right:0;bottom:0;padding:18px;display:flex;align-items:flex-end;justify-content:space-between;gap:10px;z-index:2;}
  .destacada-title{color:#fff;font-weight:700;font-size:17px;text-shadow:0 2px 8px rgba(0,0,0,0.6);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
  .destacada-actions{display:flex;gap:8px;flex:0 0 auto;}

  .bubble-stack{position:absolute;top:-12px;left:10px;display:flex;z-index:6;}
  .bubble{width:27px;height:27px;border-radius:50%;background-size:cover;background-position:center;background-color:var(--bg-elev-2);border:2px solid var(--bg-elev-solid);margin-right:-9px;box-shadow:0 3px 10px rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:#fff;position:relative;animation:floatBubble 2.6s ease-in-out infinite;}
  .bubble:nth-child(2n){animation-delay:.35s;}
  .bubble:nth-child(3n){animation-delay:.7s;}
  .bubble-emoji{position:absolute;bottom:-3px;right:-3px;background:var(--bg-elev-solid);border-radius:50%;line-height:1;padding:2px;color:var(--accent);display:flex;}
  .bubble-emoji svg{width:9px;height:9px;}
  @keyframes floatBubble{0%,100%{transform:translateY(0);}50%{transform:translateY(-5px);}}

  .az-nav{position:fixed;right:8px;top:50%;transform:translateY(-50%);display:none;flex-direction:column;gap:1px;z-index:50;background:var(--bg-elev-2);backdrop-filter:blur(14px);border:1px solid var(--border);border-radius:20px;padding:6px 3px;}
  .az-nav button{background:none;border:none;color:var(--text-dim);font-size:9.5px;width:18px;height:14px;cursor:pointer;border-radius:3px;line-height:14px;padding:0;font-weight:700;}
  .az-nav button:hover:not(:disabled){color:var(--accent);background:var(--bg-elev-solid);}
  .az-nav button:disabled{opacity:0.22;cursor:default;}
  @media (max-width:760px){ .az-nav{display:none !important;} }

  #mobileBottomNav{display:none;position:fixed;left:0;right:0;bottom:0;z-index:250;background:var(--bg-elev-solid);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border-top:1px solid var(--border);padding:6px 10px calc(6px + env(safe-area-inset-bottom));justify-content:space-around;align-items:center;}
  /* padding horizontal bajado de 22px a 14px (#37): con la pestaña nueva de "Para ti" ya son 4
     botones en vez de 3 -- con el padding viejo se apretaban demasiado en pantallas angostas. */
  .mobile-nav-btn{background:none;border:none;color:var(--text-dim);display:flex;flex-direction:column;align-items:center;gap:2px;font-size:10.5px;font-weight:600;padding:6px 14px;cursor:pointer;border-radius:10px;transition:color .15s;}
  .mobile-nav-btn svg{width:20px;height:20px;}
  .mobile-nav-btn.active{color:var(--accent);}

  @media (max-width:600px){
    header{padding:16px 16px 14px;}
    main{padding:20px 16px 48px;}
    .filterbar.open{display:grid;grid-template-columns:1fr 1fr;}
    .filterbar select{width:100%;min-width:0;}
    .filterbar .cselect-wrap{width:100%;min-width:0;}
    .filterbar .cselect-trigger{width:100%;min-width:0;}
    .cselect-list{left:0;right:0;min-width:0;}
    /* Ya no hace falta estirar los botones del actionbar a 2 columnas -- desde el rediseño solo
       quedan 2 controles ahí (densidad + vista de lista), caben bien en su tamaño normal. */
    .profile-circle{width:86px;height:86px;font-size:30px;}
    .profile-avatar{width:86px;}
    .profile-screen-logo{height:30px;margin-bottom:16px;}
    .profile-screen h1{font-size:24px;margin-bottom:28px;}
    .profile-backdrop{grid-template-columns:repeat(auto-fill, minmax(90px, 1fr));}
    .profile-backdrop-tile{min-height:90px;}
    .modal{padding:18px;}
    .hero-title{font-size:30px;}
    .hero{min-height:auto;margin-top:-90px;}
    .hero-content{padding:110px 20px 30px;}
    .hero-info-row{gap:20px;}
    /* La navegación se muda a la barra inferior — los tabs de arriba (Inicio/Biblioteca) se
       esconden para no duplicarla, y se le deja aire al fondo de la página para que la barra fija
       no tape lo último del contenido. */
    .view-tabs{display:none;}
    body{padding-bottom:64px;}
    #mobileBottomNav{display:flex;}
    #bulkActionBar{bottom:72px;}
    #toast{bottom:78px;}
  }
