/*!
 * Aula CodeLibri · hoja compartida
 * (c) 2026 CodeLibri — Elisa Espinoza Castillo y Luis E. Maldonado Gil
 *
 * La usan el catálogo, la vista de presentación, las páginas sueltas y el
 * panel. Vidrio sobre gradiente, en la paleta de la marca: morado profundo
 * #241246 y violeta #6c55f6. El texto nunca va sobre el gradiente desnudo,
 * siempre sobre una superficie, para que el contraste no dependa de dónde
 * caiga el color.
 *
 * Desde el 15 de septiembre de 2026 todas las páginas —catálogo, visor,
 * aviso, 404 y también el panel— van en la interfaz con barra lateral, al
 * final y colgada entera de body.app. Lo de arriba son los tokens, la
 * base, el texto del aviso y las ventanas. Lo propio del panel vive en
 * admin/assets/panel.css.
 */

:root{
  --sans:"Poppins","Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;

  --g1:#efe9ff; --g2:#e6f3ff; --g3:#ffeef7;
  --b1:#8b6cf6; --b2:#4fc3e8; --b3:#f48fb1;

  --vidrio:rgba(255,255,255,.62);
  --vidrio-2:rgba(255,255,255,.44);
  --vidrio-linea:rgba(255,255,255,.85);
  --tarjeta:rgba(255,255,255,.78);
  --tarjeta-linea:rgba(255,255,255,.9);
  --sombra:0 24px 70px rgba(36,18,70,.16);
  --sombra-2:0 6px 20px rgba(36,18,70,.08);

  --txt:#1a1430; --txt-2:#4a4366; --txt-3:#6b6486;
  --acento:#5a43e0; --acento-suave:rgba(90,67,224,.12);
  --linea:rgba(36,18,70,.10);
  --barra:rgba(36,18,70,.32); --barra-viva:rgba(36,18,70,.48);
}
html[data-theme="dark"]{
  --g1:#150f2e; --g2:#12112a; --g3:#1b1236;
  --b1:#6c55f6; --b2:#2b6f8f; --b3:#7a2f63;

  --vidrio:rgba(28,24,58,.58);
  --vidrio-2:rgba(20,17,44,.5);
  --vidrio-linea:rgba(255,255,255,.12);
  --tarjeta:rgba(255,255,255,.07);
  --tarjeta-linea:rgba(255,255,255,.12);
  --sombra:0 24px 70px rgba(0,0,0,.45);
  --sombra-2:0 6px 20px rgba(0,0,0,.25);

  --txt:#efecfa; --txt-2:#c2bbdd; --txt-3:#a49dc2;
  --acento:#a998ff; --acento-suave:rgba(169,152,255,.16);
  --linea:rgba(255,255,255,.10);
  --barra:rgba(255,255,255,.28); --barra-viva:rgba(255,255,255,.44);
}

*{box-sizing:border-box;margin:0;padding:0}
body{
  min-height:100vh;font-family:var(--sans);color:var(--txt);line-height:1.55;
  -webkit-font-smoothing:antialiased;padding:26px 26px 48px;
  background:linear-gradient(150deg,var(--g1) 0%,var(--g2) 48%,var(--g3) 100%);
  background-attachment:fixed
}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:2px solid var(--acento);outline-offset:3px;border-radius:8px}

/* ── barras de desplazamiento ──
   La del sistema es un bloque gris que corta el vidrio por la mitad. Se
   pintan con los tonos de la hoja y hacen falta las dos formas: la
   estandar, que ademas se hereda, y la de WebKit, que sigue siendo la
   unica que entienden Safari y los Chrome de hace nada.

   El truco del borde transparente con background-clip deja la barra fina
   sin encoger el blanco al que hay que apuntar: se ven seis pixeles, pero
   se agarran doce. */
/* Ojo con estas dos: scrollbar-color se hereda y basta declararlo arriba,
   pero scrollbar-width NO se hereda. Puesto solo en html, la ventana salia
   fina y la columna y la rejilla —que son las que de verdad desplazan—
   seguian con la barra gorda del sistema. */
html{scrollbar-color:var(--barra) transparent}
*{scrollbar-width:thin}

::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:var(--barra);border-radius:20px;
  border:3px solid transparent;background-clip:content-box
}
::-webkit-scrollbar-thumb:hover{background:var(--barra-viva);background-clip:content-box}
::-webkit-scrollbar-corner{background:transparent}

/* Rótulo que solo existe para quien escucha la página. No se usa display
   ni visibility: eso también lo retiraría del lector. */
.oculto-visual{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0
}

/* ── saltar al contenido ──
   Va el primero de la página y fuera de la vista hasta que recibe el foco.
   Sin él, llegar al catálogo con el teclado obliga a recorrer la columna
   entera de tópicos, rutas y autoría en cada visita. */
.saltar{
  position:fixed;top:12px;left:12px;z-index:200;
  padding:10px 16px;border-radius:12px;font-size:14px;font-weight:500;
  color:var(--txt);background:var(--tarjeta);
  border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-2);
  -webkit-backdrop-filter:blur(20px) saturate(150%);
  backdrop-filter:blur(20px) saturate(150%);
  transform:translateY(-200%);transition:transform .15s ease
}
.saltar:focus{transform:none}
/* Nada de contorno donde el foco ya está anunciado por el propio salto. */
#contenido:focus{outline:none}

.fondo{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none}
.fondo span{position:absolute;border-radius:50%;filter:blur(90px);opacity:.5}
.fondo .m1{width:52vw;height:52vw;left:-12vw;top:-14vw;background:var(--b1)}
.fondo .m2{width:44vw;height:44vw;right:-10vw;top:12vh;background:var(--b2);opacity:.42}
.fondo .m3{width:40vw;height:40vw;left:24vw;bottom:-18vw;background:var(--b3);opacity:.38}

/* ── páginas de texto largo ──
   El aviso de privacidad y lo que venga detrás: esto se lee, no se ojea,
   así que se acota la medida y respira más que una tarjeta. */
.legal{max-width:80ch}
.legal h2{font-size:17px;font-weight:600;margin:30px 0 6px;color:var(--txt)}
.legal p,.legal li{color:var(--txt-2);font-size:15px;line-height:1.7}
.legal p{margin-top:10px}
.legal ul{margin:12px 0 0;padding-left:20px;display:flex;flex-direction:column;gap:10px}
.legal strong{color:var(--txt);font-weight:600}
.legal a{color:var(--acento);text-decoration:underline;text-underline-offset:2px}
.legal code{font-family:ui-monospace,Consolas,monospace;font-size:13.5px}

/* ── modal ── */
.modal{
  position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:24px;
  background:rgba(14,10,32,.5);opacity:0;transition:opacity .18s ease
}
/* Sin esto, el atributo hidden no vale nada: una regla de autor con
   display gana a la del navegador y la capa invisible se queda encima
   tragándose todos los clics de la página. */
.modal[hidden]{display:none}
.modal.on{opacity:1}
.modal .caja{
  position:relative;width:min(520px,100%);padding:30px 32px 28px;border-radius:20px;
  background:var(--tarjeta);border:1px solid var(--tarjeta-linea);
  box-shadow:0 30px 80px rgba(20,10,50,.35);
  -webkit-backdrop-filter:blur(30px) saturate(150%);
  backdrop-filter:blur(30px) saturate(150%)
}
.modal h2{font-size:20px;font-weight:600;letter-spacing:-.01em}
.modal .nombres{margin-top:16px;display:flex;flex-direction:column;gap:5px}
.modal .nombres span{font-size:15px;color:var(--txt);font-weight:500}
.modal .nombres em{
  display:block;font-style:normal;font-size:12.5px;color:var(--txt-3);
  font-weight:400;margin-top:5px
}
.modal p{margin-top:18px;padding-top:16px;border-top:1px solid var(--linea);font-size:13.5px;color:var(--txt-2)}
/* El aviso es largo: la ventana se ensancha y lo que se desplaza es su
   cuerpo, no la caja entera. Así la × se queda siempre a la vista y el
   foco puede entrar en ella sin arrastrar el texto detrás. */
.caja-legal{
  width:min(680px,100%);max-height:82vh;padding:0;text-align:left;
  display:flex;flex-direction:column;overflow:hidden
}
.caja-legal .cabecera-legal{
  flex:none;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:22px 26px 14px;border-bottom:1px solid var(--linea)
}
.caja-legal .cabecera-legal h2{margin:0}
.modal .caja-legal .cerrar{position:static;flex:none}
.caja-legal .cuerpo-legal{
  overflow-y:auto;overscroll-behavior:contain;padding:2px 26px 24px;scrollbar-gutter:stable
}
.caja-legal .cuerpo-legal h2:first-of-type{margin-top:18px}
.caja-legal .pie-legal{margin-top:26px;padding-top:16px;border-top:1px solid var(--linea);font-size:13.5px}

.caja-qr{width:min(340px,100%);text-align:center}
.caja-qr img{
  display:block;width:260px;height:260px;margin:18px auto 0;border-radius:12px;
  background:#fff;padding:10px;border:1px solid var(--tarjeta-linea)
}
.caja-qr .direccion{
  margin-top:14px;padding-top:0;border-top:0;font-size:12px;color:var(--txt-3);word-break:break-all
}
/* ── cómo citar ──
   Más ancha que la del QR porque una referencia APA no cabe en tres
   líneas, y el BibTeX menos. */
.caja-citar{width:min(620px,100%)}
.caja-citar .etiqueta-cita{
  margin-top:20px;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--acento);font-weight:600
}
.caja-citar .etiqueta-cita:first-of-type{margin-top:16px}
/* Sangría francesa, que es como APA quiere las referencias. */
.caja-citar .cita{
  margin-top:8px;font-size:14.5px;line-height:1.55;color:var(--txt);
  padding-left:26px;text-indent:-26px
}
.caja-citar .cita em{font-style:italic}
.caja-citar .bibtex{
  margin-top:8px;padding:14px 16px;border-radius:10px;overflow-x:auto;
  background:var(--tarjeta);border:1px solid var(--tarjeta-linea);
  font-family:ui-monospace,Consolas,"SFMono-Regular",monospace;
  font-size:12.5px;line-height:1.5;color:var(--txt-2);white-space:pre
}
.caja-citar .boton-suave{margin-top:12px}
.caja-citar .aviso-cita{
  margin-top:22px;padding-top:14px;border-top:1px solid var(--linea);
  font-size:12.5px;color:var(--txt-3);line-height:1.45
}

.modal .cerrar{position:absolute;top:14px;right:16px;font-size:22px;line-height:1;opacity:.5}
.modal .cerrar:hover{opacity:1}

@media (prefers-reduced-motion:reduce){.modal{transition:none}}


/* ═══════════════════════════════════════════════════════════════
   LA INTERFAZ CON BARRA LATERAL · body.app

   Pantalla completa, barra lateral fija y barra superior con el buscador
   y el ecosistema. Todo cuelga de body.app, así que el visor, el aviso,
   el 404 y el panel, que siguen con el marco de arriba, no se enteran.

   El lenguaje visual es el de la referencia que Luis pasó el 15 de
   septiembre de 2026: lienzo casi blanco, vidrio solo en las dos barras,
   secciones sueltas sobre el lienzo, superficies planas con filete y
   sombra corta, esquinas de 8 px en controles y 16 en tarjetas, e Inter.
   Los colores, de la paleta del Figma de CodeLibri.
   ═══════════════════════════════════════════════════════════════ */

/* La paleta del Figma (Design System → Paleta de Color), paso a paso. Es la
   misma en los dos temas: lo que cambia con el tema son los tokens de uso
   de body.app, más abajo. */
:root{
  --primary-50:#f0eefe;--primary-100:#d1cafc;--primary-200:#bbb1fb;--primary-300:#9d8df9;--primary-400:#8977f8;
  --primary-500:#6c55f6;--primary-600:#624de0;--primary-700:#4d3caf;--primary-800:#3b2f87;--primary-900:#2d2467;
  --secondary-50:#e8fdfa;--secondary-100:#b6faef;--secondary-200:#93f7e7;--secondary-300:#62f4db;--secondary-400:#44f1d5;
  --secondary-500:#15eeca;--secondary-600:#13d9b8;--secondary-700:#0fa98f;--secondary-800:#0c836f;--secondary-900:#096455;
  --secondary2-50:#ffecf4;--secondary2-100:#ffc5db;--secondary2-200:#ffa9ca;--secondary2-300:#ff82b2;--secondary2-400:#ff69a3;
  --secondary2-500:#ff448c;--secondary2-600:#e83e7f;--secondary2-700:#b53063;--secondary2-800:#8c254d;--secondary2-900:#6b1d3b;
  --text-50:#eaeaeb;--text-100:#bfbfc0;--text-200:#a09fa2;--text-300:#747478;--text-400:#59595d;
  --text-500:#302f35;--text-600:#2c2b30;--text-700:#222126;--text-800:#1a1a1d;--text-900:#141416;

  /* Los degradados de la casa, con los tres colores en su paso 500, tal
     como están en la referencia. Decisión de Luis del 15 de septiembre de
     2026, con las cifras delante: el texto blanco sobre el extremo menta
     queda en 1.49:1 y sobre el rosa en 3.25:1. Está medido y aceptado; no
     es un descuido que haya que corregir. */
  --grad-marca:linear-gradient(90deg,var(--secondary-500),var(--primary-500),var(--secondary2-500));
  --grad-explorar:linear-gradient(90deg,var(--primary-500),var(--secondary-500));
  --grad-dona:linear-gradient(90deg,var(--primary-500),var(--secondary2-500));
}

body.app{
  --sans:"Inter","Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;
  padding:0;background:var(--fondo);
  --fondo:#fafbfc;
  --mancha-1:rgba(108,85,246,.07);--mancha-2:rgba(21,238,202,.07);
  --vidrio:rgba(255,255,255,.75);--vidrio-linea:rgba(255,255,255,.6);
  --tarjeta:#ffffff;--tarjeta-linea:rgba(20,20,22,.07);
  --linea:rgba(20,20,22,.08);--linea-2:rgba(20,20,22,.16);
  --campo:rgba(244,245,247,.7);--flotar:rgba(20,20,22,.04);
  --sombra:0 12px 24px -8px rgba(108,85,246,.16);
  --sombra-2:0 1px 2px rgba(20,20,22,.05);
  --sombra-menu:0 18px 40px -14px rgba(20,20,22,.22);
  /* Los grises de texto son los del Figma. El tercero, text-300, da 4.65:1
     sobre blanco: vale en tarjetas y barras, que son blancas; lo que va
     suelto sobre el lienzo usa text-400. */
  --txt:var(--text-900);--txt-2:var(--text-400);--txt-3:var(--text-300);
  --acento:var(--primary-600);--acento-suave:rgba(108,85,246,.10);
  --rotulo-nuevo:var(--secondary2-700);
  --riel:#eef0f3;--perilla:#fdb813;
  /* 290 y no 280: cuando la ventana es baja y la barra lateral desplaza,
     su barra de 10 px se come ese ancho y los tópicos largos se partían
     en dos renglones. */
  --lat:290px;--alto-sup:72px;
}
html[data-theme="dark"] body.app{
  --fondo:var(--text-900);
  --mancha-1:rgba(108,85,246,.16);--mancha-2:rgba(21,238,202,.07);
  --vidrio:rgba(26,26,29,.74);--vidrio-linea:rgba(255,255,255,.06);
  --tarjeta:var(--text-700);--tarjeta-linea:rgba(255,255,255,.07);
  --linea:rgba(255,255,255,.08);--linea-2:rgba(255,255,255,.18);
  --campo:rgba(255,255,255,.05);--flotar:rgba(255,255,255,.05);
  --sombra:0 14px 30px -10px rgba(0,0,0,.7);
  --sombra-2:0 1px 2px rgba(0,0,0,.4);
  --sombra-menu:0 18px 40px -14px rgba(0,0,0,.8);
  --txt:var(--text-50);--txt-2:var(--text-100);--txt-3:var(--text-200);
  --acento:var(--primary-300);--acento-suave:rgba(137,119,248,.16);
  --rotulo-nuevo:var(--secondary2-300);
  --riel:var(--text-600);--perilla:var(--primary-200);
}
/* Aquí el atributo hidden manda siempre: varias piezas llevan display
   propio y, sin esto, esconderlas desde el guion no hacía nada. */
.app [hidden]{display:none!important}
.app .ico{flex:none}

/* ── barras de desplazamiento ──
   Todas iguales: la de la página, la de la barra lateral, la de los
   carruseles y la de las ventanas. Finas, del color del filete y sin las
   flechas de Windows; se marcan un poco más al pasar por encima de lo que
   desplazan. Se ven seis píxeles y se agarran diez: el borde transparente
   con background-clip adelgaza el dibujo sin encoger el blanco.

   Chrome solo atiende a ::-webkit-scrollbar si el elemento no declara
   scrollbar-color ni scrollbar-width, y la regla general de arriba los
   declara para todo: aquí se devuelven a auto.

   La barra de la página es otra cosa: Chrome no le aplica
   html::-webkit-scrollbar, ni con :has() ni sin él —medido—, solo la
   regla global de arriba del todo. Esa ya pinta seis píxeles sobre doce;
   lo único que cambia es el color, que sale de --barra, y por eso aquí se
   redefine --barra en <html> cuando la página es de la interfaz nueva.
   Firefox no conoce los pseudoelementos y se queda con la forma estándar,
   en el @supports del final. */
html:has(> body.app),.app,.app *{scrollbar-width:auto;scrollbar-color:auto}
html:has(> body.app){--barra:rgba(20,20,22,.1);--barra-viva:rgba(20,20,22,.2)}
html[data-theme="dark"]:has(> body.app){--barra:rgba(255,255,255,.1);--barra-viva:rgba(255,255,255,.2)}
.app ::-webkit-scrollbar{width:10px;height:10px}
.app ::-webkit-scrollbar-button{display:none}
.app ::-webkit-scrollbar-track,.app ::-webkit-scrollbar-corner{background:transparent}
.app ::-webkit-scrollbar-thumb{background:var(--linea);border:2px solid transparent;background-clip:content-box;border-radius:999px}
.app ::-webkit-scrollbar-thumb:hover,
.app .lat:hover::-webkit-scrollbar-thumb,
.app .fila:hover .carrusel::-webkit-scrollbar-thumb,
.app .carrusel:focus-visible::-webkit-scrollbar-thumb{background:var(--linea-2);background-clip:content-box}
@supports not selector(::-webkit-scrollbar){
  html:has(> body.app){scrollbar-width:thin;scrollbar-color:rgba(20,20,22,.2) transparent}
  html[data-theme="dark"]:has(> body.app){scrollbar-color:rgba(255,255,255,.2) transparent}
  .app *{scrollbar-width:thin;scrollbar-color:var(--linea) transparent}
  .app .lat:hover,.app .fila:hover .carrusel{scrollbar-color:var(--linea-2) transparent}
}

.app .fondo span{filter:blur(110px);opacity:1}
.app .fondo .m1{width:44vw;height:44vw;left:-8vw;top:-12vw;background:var(--mancha-1)}
.app .fondo .m2{width:52vw;height:52vw;right:-14vw;top:auto;bottom:4vh;background:var(--mancha-2)}
.app .fondo .m3{display:none}

/* ── controles ──
   El secundario es blanco con filete y sombra corta; el principal y el de
   donar llevan los degradados de la casa. */
.app .plano{background:var(--tarjeta);border:1px solid var(--linea);box-shadow:var(--sombra-2);color:var(--txt);transition:transform .15s ease,box-shadow .2s ease,border-color .2s ease,opacity .2s ease}
.app .plano:hover{transform:translateY(-1px);border-color:var(--linea-2);box-shadow:0 4px 12px -4px rgba(20,20,22,.14)}
.app .plano:active{transform:none}
.app .plano[aria-disabled="true"]{opacity:.4;cursor:default;transform:none;box-shadow:none}
.app .redondo{width:40px;height:40px;border-radius:8px;display:inline-grid;place-items:center;color:var(--txt-2)}
.app .pastilla{height:40px;padding:0 14px;border-radius:8px;display:inline-flex;align-items:center;gap:8px;font-size:14px;font-weight:600}
.app .boton{height:42px;padding:0 20px;border-radius:8px;display:inline-flex;align-items:center;gap:8px;font-size:14px;font-weight:600}
.app .boton .ico,.app .pastilla .ico{color:var(--txt-3)}
.app .cuadro{width:36px;height:36px;border-radius:8px;display:inline-grid;place-items:center;flex:none;background:var(--primary-50);color:var(--primary-600)}
html[data-theme="dark"] .app .cuadro{background:rgba(108,85,246,.18);color:var(--primary-300)}
/* Un producto del ecosistema con el color de su tono en el sistema, el mismo
   que en la Guía SAT: llega en --tono y --tono-oscuro desde
   inc/sistema/ecosistema.json. Dibujo en el tono, fondo en él al 10%. */
.app .cuadro[style*="--tono"]{color:var(--tono);background:color-mix(in srgb,var(--tono) 10%,transparent)}
html[data-theme="dark"] .app .cuadro[style*="--tono"]{color:var(--tono-oscuro);background:color-mix(in srgb,var(--tono-oscuro) 10%,transparent)}

.app .primario,.app .cta,.app .dona{
  display:inline-flex;align-items:center;gap:8px;border-radius:8px;color:#fff;font-weight:600;white-space:nowrap;
  box-shadow:0 4px 14px rgba(108,85,246,.39);transition:transform .15s ease,box-shadow .2s ease,opacity .2s ease
}
.app .primario:hover,.app .cta:hover,.app .dona:hover{transform:translateY(-2px);box-shadow:0 6px 20px rgba(108,85,246,.5)}
.app .primario{height:42px;padding:0 24px;font-size:14px;background:var(--grad-explorar)}
.app .primario:hover{opacity:.92}
.app .cta{height:40px;padding:0 20px;font-size:14px;background:var(--grad-dona)}
.app .dona{background:var(--grad-dona)}
.app .primario .ico,.app .cta .ico,.app .dona .ico{color:#fff}
.app .solo-movil{display:none}

/* ═══ disposición ═══ */
.app .armazon{display:grid;grid-template-columns:var(--lat) minmax(0,1fr);min-height:100vh}

/* ── barra lateral ── */
.app .lat{
  position:sticky;top:0;height:100vh;overflow-y:auto;display:flex;flex-direction:column;
  padding:0 16px 18px;background:var(--vidrio);border-right:1px solid var(--linea);
  box-shadow:4px 0 24px -12px rgba(20,20,22,.06);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:50
}
/* La franja de la marca mide lo mismo que la barra superior, para que las
   dos rayas queden a la misma altura. */
.app .marca{display:flex;align-items:center;gap:10px;flex:none;height:var(--alto-sup);margin:0 -16px 20px;padding:0 24px;border-bottom:1px solid var(--linea)}
.app .marca img{width:32px;height:32px;border-radius:8px;box-shadow:var(--sombra-2)}
.app .marca b{display:inline;font-size:19px;font-weight:700;letter-spacing:-.025em;line-height:1}
.app .marca em{display:inline;font-style:normal;font-size:11px;font-weight:500;letter-spacing:.04em;text-transform:uppercase;color:var(--txt-3);margin-left:5px}
.app .grupo{display:grid;gap:2px}
.app .grupo a{
  display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:8px;
  font-size:14px;font-weight:500;color:var(--txt-2);transition:background .15s,color .15s
}
.app .grupo a > span:not(.avatar){flex:1;min-width:0;line-height:1.3}
.app .grupo a .ico{color:var(--txt-3)}
.app .grupo a b{margin-left:4px;font-size:11.5px;font-weight:500;color:var(--txt-3);font-variant-numeric:tabular-nums}
.app .grupo a:hover{background:var(--flotar);color:var(--txt)}
.app .grupo a.on{background:var(--acento-suave);color:var(--acento);font-weight:600}
.app .grupo a.on .ico,.app .grupo a.on b{color:var(--acento)}
.app .lat .rotulo{margin:26px 12px 10px;font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--txt-3)}

/* Iniciales de autoría en el tono de una familia de la marca. */
.app .avatar{width:24px;height:24px;border-radius:50%;display:inline-grid;place-items:center;font-size:10px;font-weight:700;flex:none;border:1px solid transparent}
.app .avatar.f-primario{background:var(--primary-50);border-color:var(--primary-100);color:var(--primary-700)}
.app .avatar.f-secundario{background:var(--secondary-50);border-color:var(--secondary-100);color:var(--secondary-900)}
.app .avatar.f-secundario2{background:var(--secondary2-50);border-color:var(--secondary2-100);color:var(--secondary2-700)}
html[data-theme="dark"] .app .avatar.f-primario{background:rgba(108,85,246,.2);border-color:transparent;color:var(--primary-200)}
html[data-theme="dark"] .app .avatar.f-secundario{background:rgba(21,238,202,.14);border-color:transparent;color:var(--secondary-300)}
html[data-theme="dark"] .app .avatar.f-secundario2{background:rgba(255,68,140,.16);border-color:transparent;color:var(--secondary2-200)}

.app .tarjeta-lat:empty{display:none}
.app .tarjeta-lat .apoyo,.app .tarjeta-lat .seguir{
  display:block;padding:16px;border-radius:12px;background:var(--tarjeta);
  border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-2)
}
.app .apoyo .t{font-size:14px;font-weight:600}
.app .apoyo .d{font-size:13px;color:var(--txt-2);line-height:1.45;margin:4px 0 12px}
.app .apoyo .boton{height:36px;padding:0 14px;font-size:13px}
.app .tarjeta-lat .seguir{display:flex;align-items:center;gap:12px}
.app .seguir b{display:block;font-size:14px;font-weight:600}
.app .seguir small{font-size:12.5px;color:var(--txt-2);line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.app .seguir:hover b{color:var(--acento)}
.app .anillo{flex:none}
.app .anillo circle{fill:none;stroke:var(--linea);stroke-width:5}
.app .anillo circle.v{stroke:var(--primary-500);stroke-linecap:round;transform:rotate(-90deg);transform-origin:50% 50%}
.app .anillo text{font-size:11px;font-weight:600;text-anchor:middle;fill:var(--txt)}

/* ── barra superior ── */
.app .principal{min-width:0;display:flex;flex-direction:column}
.app .superior{
  position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:16px;
  height:var(--alto-sup);padding:0 32px;background:var(--vidrio);border-bottom:1px solid var(--linea);
  box-shadow:0 4px 24px -12px rgba(20,20,22,.06);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)
}
/* min-width:0 en la caja y width:100% en el campo: un input trae un ancho
   propio de unos 170 px y, sin esto, en el teléfono empujaba el botón de
   apoyo fuera de la pantalla. */
.app .buscador{
  flex:1;min-width:0;max-width:448px;display:flex;align-items:center;gap:10px;height:40px;padding:0 14px;border-radius:8px;
  background:var(--campo);border:1px solid var(--linea);box-shadow:inset 0 1px 2px rgba(20,20,22,.03);color:var(--txt-3);
  transition:border-color .2s ease,box-shadow .2s ease
}
.app .buscador input{flex:1;width:100%;min-width:0;border:0;background:none;font:inherit;font-size:14px;color:var(--txt);outline:none;text-overflow:ellipsis}
.app .buscador input::placeholder{color:var(--txt-3)}
/* El foco lo enseña la caja entera, con el anillo violeta de la referencia:
   el campo va sin borde dentro de ella y su propio contorno quedaría
   cortado. */
.app .buscador:focus-within{border-color:var(--primary-500);box-shadow:0 0 0 3px rgba(108,85,246,.3)}
.app .sup-acciones{margin-left:auto;display:flex;align-items:center;gap:16px}

.app .eco{position:relative}
/* Opaco a propósito: vive dentro de la barra superior, que ya es de
   vidrio, y un backdrop-filter anidado solo ve lo que hay dentro de su
   padre, no la página. */
.app .eco-menu{
  position:absolute;right:0;top:calc(100% + 10px);width:340px;padding:8px;border-radius:12px;
  background:var(--tarjeta);border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-menu)
}
.app .eco-t{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--txt-3);padding:8px 10px 6px}
.app .eco-menu a{display:flex;align-items:center;gap:12px;padding:10px;border-radius:8px;transition:background .15s}
.app .eco-menu a:hover,.app .eco-menu a:focus-visible{background:var(--acento-suave)}
.app .eco-menu a > span:nth-child(2){flex:1;min-width:0}
.app .eco-menu b{display:block;font-size:14px;font-weight:600}
.app .eco-menu small{display:block;font-size:12.5px;color:var(--txt-2);line-height:1.35}
.app .eco-menu > a > .ico{color:var(--txt-3)}

/* Interruptor de tema: la perilla es el sol, amarillo, a la izquierda; en
   oscuro se va a la derecha, sobre la luna, y se vuelve lila. */
.app .interruptor{
  position:relative;width:64px;height:32px;border-radius:999px;flex:none;
  background:var(--riel);border:1px solid var(--tarjeta);box-shadow:inset 0 2px 4px rgba(20,20,22,.07)
}
.app .interruptor .riel{position:absolute;inset:0;display:flex;align-items:center;justify-content:space-between;padding:0 8px;color:var(--txt-3)}
.app .interruptor .perilla{
  position:absolute;top:3px;left:3px;width:24px;height:24px;border-radius:50%;
  background:var(--perilla);box-shadow:0 2px 4px rgba(253,184,19,.35);
  transition:transform .25s cubic-bezier(.3,.7,.3,1),background .25s ease
}
.app .interruptor[aria-checked="true"] .perilla{transform:translateX(32px);box-shadow:0 2px 6px rgba(0,0,0,.45)}
.app .interruptor:focus-visible{border-radius:999px}

/* ── contenido ──
   Un carril con mínimo cero: sin él, la rejilla toma el ancho natural del
   carrusel más largo —veintiséis tarjetas en fila— y estira todo lo demás
   con él. Las secciones no llevan caja: el aire entre ellas las separa. */
.app main{padding:40px 32px 56px;display:grid;grid-template-columns:minmax(0,1fr);gap:52px}
/* Las anclas quedan por debajo de la barra superior, que es fija. */
.app #todo,.app #rutas,.app #continuar{scroll-margin-top:calc(var(--alto-sup) + 20px)}

/* «Lo más nuevo» con tope de ancho: es un aviso al lado de la descripción,
   no el protagonista. En una pantalla de 2 000 px llegaba a 660. */
.app .hero{display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,400px);gap:48px;align-items:center}
.app .hero-topico{grid-template-columns:minmax(0,1fr)}
.app .hero-texto{max-width:56rem}
.app .migas{display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:13px;font-weight:500;color:var(--txt-2);margin-bottom:24px}
.app .migas [aria-hidden]{color:var(--text-100)}
.app .migas a:hover{color:var(--txt)}
.app .migas b{font-weight:500;color:var(--txt);background:var(--tarjeta);border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-2);padding:2px 8px;border-radius:6px}
.app .hero h1{font-size:clamp(38px,4.2vw,54px);font-weight:800;letter-spacing:-.035em;line-height:1.05;color:var(--txt)}
.app .degradado{background:var(--grad-marca);-webkit-background-clip:text;background-clip:text;color:transparent}
.app .bajada{font-size:17px;color:var(--txt-2);max-width:46em;margin-top:20px;line-height:1.65}
.app .cifras{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin-top:22px}
.app .cifras:empty{display:none}
.app .cifras li{font-size:13px;color:var(--txt-2);padding:4px 12px;border-radius:999px;background:var(--tarjeta);border:1px solid var(--tarjeta-linea)}
.app .cifras b{color:var(--txt);font-weight:700}
.app .hero-bot{display:flex;flex-wrap:wrap;gap:12px;margin-top:32px}

.app .destacada{
  display:flex;flex-direction:column;overflow:hidden;background:var(--tarjeta);
  border:1px solid var(--tarjeta-linea);border-radius:16px;box-shadow:var(--sombra-2);
  transition:box-shadow .3s ease,border-color .3s ease
}
.app .destacada:hover{box-shadow:var(--sombra);border-color:rgba(108,85,246,.22)}
.app .dest-img{position:relative;display:block;aspect-ratio:16/9;overflow:hidden;border-bottom:1px solid var(--tarjeta-linea)}
.app .dest-img img{position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:cover;display:block;transition:transform .5s ease}
.app .destacada:hover .dest-img img{transform:scale(1.03)}
.app .dest-cuerpo{padding:16px 18px 18px}
.app .dest-rot{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--rotulo-nuevo)}
.app .dest-cuerpo h2{font-size:17px;font-weight:700;letter-spacing:-.015em;line-height:1.3;margin:6px 0 6px}
.app .dest-cuerpo h2 a:hover{color:var(--acento)}
.app .dest-cuerpo p{font-size:13.5px;color:var(--txt-2);line-height:1.5;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.app .dest-cuerpo .dest-meta{display:flex;gap:14px;margin-top:10px;font-size:12.5px;color:var(--txt-3)}

/* ── filas con carrusel ── */
.app #filas{display:grid;grid-template-columns:minmax(0,1fr);gap:52px}
.app .fila,.app .rejilla-sec{min-width:0}
.app .fila-cab{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:22px}
.app .fila-cab h2{font-size:20px;font-weight:700;letter-spacing:-.02em;line-height:1.25}
.app .fila-cab p{font-size:14px;color:var(--txt-2);margin-top:4px}
.app .fila-acc{display:flex;align-items:center;gap:8px;flex:none}
.app .ver-todo{display:inline-flex;align-items:center;gap:4px;font-size:14px;font-weight:600;color:var(--acento);margin-right:8px}
.app .ver-todo .ico{transition:transform .2s ease}
.app .ver-todo:hover .ico{transform:translateX(3px)}
.app .fila .redondo{width:36px;height:36px}
.app .fila.sin-flechas .redondo{display:none}
.app .carrusel{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(256px,280px);gap:24px;
  overflow-x:auto;scroll-snap-type:x mandatory;padding:4px 6px 18px;margin:0 -6px
}
.app .carrusel > *{scroll-snap-align:start}
/* La barra del carrusel sigue la regla común de más arriba; solo se aparta
   un poco de los bordes para no tocar las esquinas de las tarjetas. */
.app .carrusel::-webkit-scrollbar-track{margin:0 8px}
.app .carrusel:focus-visible{outline-offset:-2px;border-radius:16px}
.app .rejilla{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:24px}

/* ── tarjeta ──
   Con posición propia: los rótulos para lector de pantalla van en absoluto
   y, sin un ancestro posicionado dentro del carrusel, se colocaban respecto
   a la página y la ensanchaban 2 700 px por la derecha. */
.app .tarj{
  position:relative;display:flex;flex-direction:column;background:var(--tarjeta);border:1px solid var(--tarjeta-linea);
  border-radius:16px;overflow:hidden;box-shadow:var(--sombra-2);transition:box-shadow .3s ease,border-color .3s ease
}
.app .tarj:hover{box-shadow:var(--sombra);border-color:rgba(108,85,246,.22)}
.app .tarj-img{position:relative;display:block;aspect-ratio:16/9;overflow:hidden;border-bottom:1px solid var(--tarjeta-linea)}
.app .tarj-img img{position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:cover;display:block}

/* La portadilla: lo que se ve sin portada. Sale de los colores de la pieza
   y va siempre debajo de la imagen, que la tapa si llega. El z-index:0 le
   da su propia capa: sin él, las letras —que llevan z-index para quedar
   sobre las formas— se pintaban también encima de la portada. */
.app .portadilla{position:absolute;inset:0;z-index:0;display:grid;place-items:center;overflow:hidden;background:var(--p1)}
.app .portadilla::before{content:"";position:absolute}
.app .portadilla b{position:relative;z-index:1;line-height:1;user-select:none}
.app .portadilla.clara{background:color-mix(in srgb,var(--p1) 16%,#fff)}
.app .portadilla.clara b{
  font-family:"Iowan Old Style","Palatino Linotype","Book Antiqua",Georgia,serif;
  font-size:48px;font-weight:700;letter-spacing:-.01em;color:color-mix(in srgb,var(--p1) 80%,#fff)
}
.app .portadilla.clara.larga b{font-size:38px}
.app .portadilla.oscura{background:color-mix(in srgb,var(--p2) 78%,#0b0b12)}
.app .portadilla.oscura::after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(135deg,rgba(255,255,255,.04) 0 2px,transparent 2px 10px)}
.app .portadilla.oscura b{font-family:ui-monospace,"Cascadia Code",Consolas,"SFMono-Regular",monospace;font-size:38px;font-weight:700;color:color-mix(in srgb,var(--p1) 55%,var(--p2))}
.app .portadilla.forma-0::before{width:64%;aspect-ratio:1;border-radius:50%;right:-18%;bottom:-40%;background:color-mix(in srgb,var(--p1) 20%,transparent)}
.app .portadilla.forma-1::before{width:46%;aspect-ratio:1;left:-8%;top:-10%;clip-path:polygon(0 0,100% 50%,0 100%);background:color-mix(in srgb,var(--p1) 16%,transparent)}
.app .portadilla.forma-2::before{inset:20% 14%;border-radius:12px;border:1.5px solid color-mix(in srgb,var(--p1) 26%,transparent)}
html[data-theme="dark"] .app .portadilla.clara{background:color-mix(in srgb,var(--p1) 20%,#1a1a1d)}
html[data-theme="dark"] .app .portadilla.clara b{color:color-mix(in srgb,var(--p1) 70%,#1a1a1d)}

.app .insignia{position:absolute;left:12px;top:12px;z-index:2;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;background:var(--secondary-500);color:var(--text-900);padding:4px 8px;border-radius:6px}
.app .tarj .paso{position:absolute;display:grid;place-items:center;border-radius:50%;top:12px;left:12px;z-index:2;width:28px;height:28px;font-size:13px;font-weight:700;color:var(--primary-700);background:#fff;box-shadow:0 2px 6px rgba(20,20,22,.2);-webkit-backdrop-filter:none;backdrop-filter:none}
.app .tarj .avance{position:absolute;left:0;right:0;bottom:0;z-index:2;height:4px;background:rgba(20,20,22,.18)}
.app .tarj .avance i{display:block;height:100%;width:0;background:var(--grad-explorar);box-shadow:none}

.app .tarj-cuerpo{display:flex;flex-direction:column;padding:18px 20px 16px;flex:1}
.app .chip{
  align-self:flex-start;margin-bottom:12px;font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  padding:4px 10px;border-radius:6px;background:var(--tarjeta);border:1px solid var(--tarjeta-linea);box-shadow:0 1px 2px rgba(20,20,22,.03)
}
/* El texto de la etiqueta va en el paso de su familia que se lee a 10 px:
   el menta 500 de la referencia daba 1.49:1 sobre blanco. */
.app .chip.f-primario{color:var(--primary-600)}
.app .chip.f-secundario{color:var(--secondary-900)}
.app .chip.f-secundario2{color:var(--secondary2-700)}
html[data-theme="dark"] .app .chip{background:rgba(255,255,255,.03)}
html[data-theme="dark"] .app .chip.f-primario{color:var(--primary-300)}
html[data-theme="dark"] .app .chip.f-secundario{color:var(--secondary-400)}
html[data-theme="dark"] .app .chip.f-secundario2{color:var(--secondary2-300)}
.app .tarj h3{font-size:16.5px;font-weight:700;letter-spacing:-.01em;line-height:1.35;color:var(--txt);transition:color .2s ease;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.app .tarj:hover h3{color:var(--acento)}
.app .tarj p{margin:6px 0 16px;font-size:13.5px;color:var(--txt-2);line-height:1.5;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* Si el autor y la medida no caben juntos —un video de más de una hora—,
   la medida baja de renglón en vez de cortar el nombre. */
.app .tarj-pie{margin-top:auto;padding-top:13px;border-top:1px solid var(--tarjeta-linea);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:4px 12px}
.app .tarj-pie .por{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;color:var(--txt-2)}
/* Con dos autores o más los nombres pasan a dos renglones y la medida se
   queda a su lado: a quien firma no se le corta el nombre. */
.app .tarj-pie .por.varios{flex:1 1 0;white-space:normal;line-height:1.4}
.app .dato{display:flex;align-items:center;gap:6px;flex:none;font-size:13px;font-weight:500;color:var(--txt-3);white-space:nowrap;font-variant-numeric:tabular-nums}
.app .dato .ico{color:var(--txt-3)}
.app .dato .reanudar{color:var(--acento);font-weight:600}

/* ── tarjetas de ruta ──
   Horizontales y compactas, con el icono del tópico dominante en un
   recuadro de su familia: se distinguen de un vistazo de las de
   contenido. Tres por fila y sin carrusel. */
.app .rutas-rejilla{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.app .ruta-tarj{
  display:flex;align-items:center;gap:16px;padding:16px;background:var(--tarjeta);
  border:1px solid var(--tarjeta-linea);border-radius:16px;box-shadow:0 2px 8px -4px rgba(20,20,22,.06);
  transition:border-color .3s ease,box-shadow .3s ease
}
.app .ruta-tarj:hover{border-color:var(--linea-2);box-shadow:0 8px 16px -6px rgba(20,20,22,.1)}
.app .ruta-ico{width:56px;height:56px;border-radius:14px;display:grid;place-items:center;flex:none;transition:transform .3s ease}
.app .ruta-tarj:hover .ruta-ico{transform:scale(1.05)}
.app .f-primario .ruta-ico{background:var(--primary-50);color:var(--primary-600)}
.app .f-secundario .ruta-ico{background:var(--secondary-50);color:var(--secondary-800)}
.app .f-secundario2 .ruta-ico{background:var(--secondary2-50);color:var(--secondary2-600)}
html[data-theme="dark"] .app .f-primario .ruta-ico{background:rgba(108,85,246,.18);color:var(--primary-300)}
html[data-theme="dark"] .app .f-secundario .ruta-ico{background:rgba(21,238,202,.12);color:var(--secondary-400)}
html[data-theme="dark"] .app .f-secundario2 .ruta-ico{background:rgba(255,68,140,.14);color:var(--secondary2-300)}
.app .ruta-txt{min-width:0}
.app .ruta-txt b{display:block;font-size:15px;font-weight:700;letter-spacing:-.01em;line-height:1.3;color:var(--txt);transition:color .2s ease}
.app .ruta-tarj:hover .ruta-txt b{color:var(--acento)}
.app .ruta-txt small{display:block;margin-top:3px;font-size:13px;font-weight:500;color:var(--txt-2)}

/* ── lo que devuelve el buscador ── */
.app #vacio{padding:14px 4px;color:var(--txt-2)}
.app #laminas-halladas{margin-top:28px}
.app .titulo-laminas{font-size:16px;font-weight:700;margin-bottom:12px}


/* ── pie ──
   Fuera del <main>, para que sea el pie de la página y no del contenido, y
   con franja de vidrio como la barra de arriba. */
.app .pie{
  margin:auto 0 0;padding:18px 32px;border-top:1px solid var(--linea);background:var(--vidrio);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  display:flex;flex-wrap:wrap;gap:10px 22px;align-items:center;font-size:13px;color:var(--txt-2)
}
.app .pie a,.app .pie button{font-size:13px;color:var(--txt-2);text-decoration:underline;text-decoration-color:var(--linea-2);text-underline-offset:3px}
.app .pie a:hover,.app .pie button:hover{color:var(--acento);text-decoration-color:currentColor}

/* ═══════════════ EL VISOR · ver.php ═══════════════
   La pieza manda. Todo el visor comparte un ancho de columna que hace
   caber la lámina entera en la ventana: con la barra plegada, en una
   pantalla ancha la lámina salía más alta que la ventana y había que
   desplazar para ver su pie. La cabecera, el índice y lo relacionado se
   alinean a ese mismo ancho. Los 220 px son lo que ocupa por encima de la
   lámina con el título en dos renglones —margen, cabecera y hueco— más un
   respiro abajo. */
.app main.visor{gap:20px;--ancho:min(100%,max(720px,calc((100vh - var(--alto-sup) - 220px) * 16 / 9)))}
.app main.visor > *{width:100%;max-width:var(--ancho);margin-inline:auto}

.app .visor-cabecera{display:flex;align-items:flex-end;justify-content:space-between;gap:16px 24px;flex-wrap:wrap}
.app .visor-titulo{min-width:0;flex:1 1 380px}
.app .visor-titulo .migas{margin-bottom:12px}
.app .visor-titulo h1{font-size:clamp(24px,2.4vw,32px);font-weight:800;letter-spacing:-.03em;line-height:1.15}
.app .visor-meta{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:8px;font-size:14px;color:var(--txt-2)}
.app .visor-meta a{font-weight:500}
.app .visor-meta a:hover{color:var(--acento)}

.app .acciones{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.app .accion{
  display:inline-flex;align-items:center;gap:7px;height:36px;padding:0 12px;border-radius:8px;
  font-size:13px;font-weight:600;color:var(--txt);background:var(--tarjeta);
  border:1px solid var(--linea);box-shadow:var(--sombra-2);
  transition:border-color .2s ease,transform .15s ease,background .2s ease
}
.app .accion:hover{border-color:var(--linea-2);transform:translateY(-1px)}
.app .accion svg{color:var(--txt-3);flex:none}
.app .accion b{font-weight:700;font-variant-numeric:tabular-nums}
.app .accion.solo-icono{width:36px;padding:0;justify-content:center}
.app .accion[disabled]{opacity:.6;cursor:default;transform:none}
/* Me gusta marcado: rosa de la casa y el corazón relleno. */
.app .accion.marcado{color:var(--secondary2-700);background:var(--secondary2-50);border-color:rgba(255,68,140,.4)}
.app .accion.marcado svg{color:var(--secondary2-600);fill:currentColor}
html[data-theme="dark"] .app .accion.marcado{color:var(--secondary2-200);background:rgba(255,68,140,.14);border-color:rgba(255,68,140,.35)}
html[data-theme="dark"] .app .accion.marcado svg{color:var(--secondary2-300)}
.app .vistas{display:inline-flex;align-items:center;gap:7px;height:36px;padding:0 6px;border:0;border-radius:0;font-size:13px;font-weight:600;color:var(--txt-2)}
.app .vistas svg{color:var(--txt-3)}

.app .escenario{
  position:relative;border-radius:16px;overflow:hidden;background:#000;
  border:1px solid var(--tarjeta-linea);box-shadow:0 14px 34px -14px rgba(20,20,22,.3);
  aspect-ratio:16/9
}
.app .escenario iframe{width:100%;height:100%;border:0;display:block}
.app .escenario:fullscreen{border-radius:0;border:0;aspect-ratio:auto;height:100vh}
/* Un documento no es un lienzo: no tiene proporción fija y se desplaza. La
   caja 16:9 lo dejaba en un buzón apaisado, leyéndose por una rendija. En
   un móvil «100vh» cuenta también lo que tapa la barra de direcciones;
   «dvh» mide lo que de verdad se ve, y el respaldo va delante. */
.app .escenario.documento{
  aspect-ratio:auto;min-height:520px;background:var(--tarjeta);
  height:calc(100vh - var(--alto-sup) - 190px);height:calc(100dvh - var(--alto-sup) - 190px)
}

/* Cuando la ficha existe pero su archivo no aparece. Se avisa en vez de
   dejar un marco en blanco, que no dice si el fallo es del sitio o de la
   conexión. */
.app .falta-archivo{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:40px;text-align:center;gap:10px}
.app .falta-archivo h2{font-size:20px;font-weight:700}
.app .falta-archivo p{font-size:14.5px;color:var(--txt-2);max-width:52ch;line-height:1.5}

/* ── el botón que trae el video ──
   Ocupa el escenario entero con la portada, que se sirve desde este mismo
   dominio. Hasta que alguien pulsa aquí, la página no ha hecho ni una
   petición a Google; el marco de YouTube lo crea el guion y sustituye a
   este botón. El aviso de abajo dice justo eso, antes de pulsar. */
.app .reproducir{
  position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;
  display:grid;place-items:center;align-content:center;cursor:pointer;background:#000;font:inherit;color:#fff
}
.app .reproducir img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.7;transition:opacity .2s ease}
.app .reproducir:hover img,.app .reproducir:focus-visible img{opacity:.88}
.app .reproducir .marca-play{position:relative;z-index:1;line-height:0;transition:transform .2s ease}
.app .reproducir:hover .marca-play{transform:scale(1.06)}
.app .reproducir .rotulo-play{position:relative;z-index:1;margin-top:12px;font-size:15px;font-weight:600;text-shadow:0 2px 12px rgba(0,0,0,.65)}
.app .reproducir .aviso-play{
  position:absolute;left:0;right:0;bottom:0;z-index:1;padding:10px 18px;font-size:12px;line-height:1.45;text-align:left;
  color:rgba(255,255,255,.88);background:rgba(20,20,22,.62);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)
}

/* ── el teléfono en vertical: oculto salvo donde hace falta ── */
.app .girar{display:none}

/* ── índice de láminas ──
   En una pantalla grande es una referencia para saltar; en un teléfono es
   lo primero que se puede leer de verdad, y por eso más abajo se coloca
   delante del escenario. La misma lista sirve a las láminas que encuentra
   el buscador del catálogo. */
.app .indice-laminas h2{font-size:18px;font-weight:700;letter-spacing:-.015em;margin-bottom:12px}
.app .laminas-lista{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:10px}
.app .laminas-lista a{display:block;padding:12px 14px;border-radius:12px;background:var(--tarjeta);border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-2);transition:border-color .2s ease}
.app .laminas-lista a:hover{border-color:rgba(108,85,246,.35)}
.app .laminas-lista b{display:block;font-size:14px;font-weight:600}
.app .laminas-lista span{display:block;margin-top:2px;font-size:12.5px;color:var(--txt-3)}

/* ── la ruta en la que va la pieza ── */
.app .en-ruta{
  display:flex;align-items:center;justify-content:space-between;gap:14px 20px;flex-wrap:wrap;
  padding:14px 16px;border-radius:16px;background:var(--tarjeta);border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-2)
}
.app .nombre-ruta{display:flex;align-items:center;gap:14px;min-width:0}
.app .nombre-ruta .ruta-ico{width:48px;height:48px;border-radius:12px}
.app .nombre-ruta .rotulo{display:block;font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--txt-3)}
.app .nombre-ruta b{display:block;font-size:15px;font-weight:700;line-height:1.3;transition:color .2s ease}
.app .nombre-ruta:hover b{color:var(--acento)}
.app .pasos{display:flex;gap:8px;flex-wrap:wrap}
.app .pasos a{max-width:300px}
.app .pasos a span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.app .pasos .boton{height:42px}

/* ── tópicos, autoría y huella ── */
.app .pie-visor{display:flex;align-items:center;justify-content:space-between;gap:12px 20px;flex-wrap:wrap}
.app .topicos{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.app .topicos .chip{margin:0}
.app a.chip{transition:border-color .2s ease}
.app a.chip:hover{border-color:currentColor}
.app .mas-de{font-size:13px;font-weight:600;color:var(--acento);margin-left:4px}
/* Con dos autores van dos enlaces seguidos: el hueco los separa. */
.app .mas-de + .mas-de{margin-left:14px}
.app .mas-de:hover{text-decoration:underline;text-underline-offset:3px}
/* En el gris secundario y no en el terciario: va sobre el lienzo sin
   tarjeta, y ahí el terciario se quedaba en 4.48:1. */
.app .huella{font-family:ui-monospace,"Cascadia Code",Consolas,monospace;font-size:12px;letter-spacing:.02em;color:var(--txt-2)}

.app .relacionado{margin-top:28px}

/* ── el aviso flotante: copiado, continuar donde se quedó ── */
.app #aviso{
  position:fixed;left:50%;bottom:26px;z-index:120;display:flex;align-items:center;gap:10px;
  padding:10px 12px 10px 16px;border-radius:12px;font-size:13.5px;
  background:var(--tarjeta);border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-menu);
  opacity:0;pointer-events:none;transform:translateX(-50%) translateY(10px);transition:opacity .2s ease,transform .2s ease
}
.app #aviso.on{opacity:1;transform:translateX(-50%) translateY(0)}
.app #aviso .boton{height:32px;padding:0 12px;font-size:13px}

/* Los botones de las ventanas —copiar la cita, abrir el aviso en su
   página— con la forma de los secundarios de aquí. */
.app .boton-suave{
  display:inline-flex;align-items:center;height:34px;padding:0 14px;border-radius:8px;font-size:13px;font-weight:600;
  color:var(--txt);background:var(--tarjeta);border:1px solid var(--linea);box-shadow:var(--sombra-2)
}
.app .boton-suave:hover{border-color:var(--linea-2);color:var(--txt)}
.app .modal .caja{border-radius:16px;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:var(--sombra-menu)}

/* ── la página del aviso de privacidad ── */
/* Con medida de lectura: a todo el ancho, el renglón pasaba de 150
   caracteres y se perdía la vuelta. */
.app .hoja-legal{
  padding:8px 36px 32px;border-radius:16px;background:var(--tarjeta);
  border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-2);max-width:58rem
}
.app .hoja-legal > h2:first-child{margin-top:26px}

/* ── la barra lateral plegada a iconos ──
   Nace así en el visor. Los rótulos se apartan a la vista pero no del
   lector, y cada icono dice su nombre al pasar el puntero (lo pone el
   guion). En pantalla estrecha no se pliega: allí la barra es cajón. */
.app .armazon{transition:grid-template-columns .25s ease}
.app .lat-pie{margin-top:auto;padding-top:20px;display:grid;gap:6px}
.app .plegar{display:none}
@media (min-width:901px){
  .app .plegar{
    display:flex;align-items:center;gap:10px;width:100%;padding:9px 12px;border-radius:8px;
    font-size:13px;font-weight:500;color:var(--txt-2);text-align:left
  }
  .app .plegar:hover{background:var(--flotar);color:var(--txt)}
  .app .plegar .ico{color:var(--txt-3);transition:transform .25s ease}
  html:not(.lat-abierta) body.plegada{--lat:76px}
  html:not(.lat-abierta) .plegada .lat{padding:0 10px 14px;overflow-x:hidden}
  html:not(.lat-abierta) .plegada .marca{justify-content:center;padding:0;margin:0 -10px 16px}
  html:not(.lat-abierta) .plegada .marca > span,
  html:not(.lat-abierta) .plegada .grupo a > span:not(.avatar),
  html:not(.lat-abierta) .plegada .plegar span{
    position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap
  }
  html:not(.lat-abierta) .plegada .grupo a{justify-content:center;padding:10px 0;gap:0}
  html:not(.lat-abierta) .plegada .grupo a b{display:none}
  /* el rótulo de grupo queda como raya, pero sigue nombrando su lista */
  html:not(.lat-abierta) .plegada .lat .rotulo{height:1px;margin:14px 12px;overflow:hidden;color:transparent;background:var(--linea)}
  html:not(.lat-abierta) .plegada .tarjeta-lat{display:none}
  html:not(.lat-abierta) .plegada .plegar{justify-content:center;padding:10px 0}
  html:not(.lat-abierta) .plegada .plegar .ico{transform:scaleX(-1)}
}

/* ═══ el visor en el teléfono en vertical ═══
   Medido en un teléfono de 375 px: el marco quedaba en 315×176 y ahí no
   se lee una lámina pensada para proyector. Se cambia por la invitación,
   y el índice sube justo detrás para que haya algo que leer de verdad.
   Negativos a propósito: lo que no lleva «order» vale 0, así que numerar
   desde 1 habría mandado el pie y los relacionados por delante. */
@media (max-width:720px) and (orientation:portrait){
  .app main.visor > .visor-cabecera{order:-3}
  .app main.visor > .girar{order:-2}
  /* Solo las láminas se apartan: un vídeo o un PDF no tienen panel que
     los sustituya, y ocultarlos dejaría la ficha vacía. */
  .app main.visor.con-laminas > .escenario{display:none}
  .app main.visor > .escenario{order:-2}
  .app main.visor > .indice-laminas{order:-1}

  .app main.visor > .girar{
    display:flex;flex-direction:column;gap:12px;padding:22px 20px;border-radius:16px;
    background:var(--tarjeta);border:1px solid var(--tarjeta-linea);box-shadow:var(--sombra-2)
  }
  .app .girar h2{font-size:19px;font-weight:700;line-height:1.25}
  .app .girar p{font-size:14.5px;color:var(--txt-2);line-height:1.5}
  .app .girar-botones{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:4px}
  .app .girar-nota{font-size:13px;color:var(--txt-3)}

  /* Quien pide verla así recupera el escenario. No se le quita la decisión
     a nadie: solo se cambia lo que se ofrece primero. */
  .app main.visor.tal-cual > .girar{display:none}

  /* Al devolver el escenario se le da proporción vertical, no el 16/9 de
     siempre. La presentación no mira el teléfono: mira su propio marco, y
     solo se recompone si ese marco es más alto que ancho. Con 16/9 creía
     estar apaisada y no recomponía: medido, el marco quedaba en 318×179 y
     el cuerpo del texto en 3.1 px. En vertical se recompone y se lee. Cabe
     entero bajo la barra de arriba, que se queda fija. */
  .app main.visor.con-laminas.tal-cual > .escenario{
    display:block;aspect-ratio:auto;min-height:420px;height:calc(100dvh - var(--alto-sup) - 32px)
  }
}

/* ═══ el visor en el teléfono de lado ═══
   Con 375 px de alto no caben a la vez el cromo de la ficha y una lámina
   de 16/9. Medido: el escenario arrancaba en y=123 y el título de la
   portada caía en y=407, treinta y dos por debajo del pliegue, así que la
   lámina llegaba en blanco. La pantalla entera es para la lámina: la barra
   de arriba se aparta (las migas llevan de vuelta) y el título de la ficha
   y los botones pasan justo debajo. */
@media (max-height:520px) and (orientation:landscape){
  .app.visor-pagina .superior{display:none}
  .app main.visor{padding-top:3px}
  .app main.visor > .escenario{order:-1;width:min(100%,calc((100dvh - 6px) * 16 / 9));max-width:none;margin-inline:auto}
  .app .visor-cabecera{gap:8px}
  .app .visor-titulo h1{font-size:15px;line-height:1.2}
  .app .visor-titulo .migas{margin-bottom:4px}
  .app .visor-meta{display:none}
  .app .acciones{gap:6px}
  .app .acciones .accion{height:32px;padding:0 10px;font-size:12px}
  /* Un documento sí sabe desplazarse por dentro. Los 520 px de alto mínimo
     dejaban 267 fuera y obligaban a mover la página además del PDF: dos
     superficies para lo mismo. Se le da la pantalla y él se encarga. */
  .app .escenario.documento{height:calc(100dvh - 16px);min-height:0}
}

/* ═══ pantallas medianas: la descripción se apila ═══
   La portada de «Lo más nuevo» pasa a un lado, pero conserva su 16:9 y
   queda centrada en su columna. Estirada al alto del texto se recortaba
   por los lados, y una portada es una lámina: cortada no se lee. */
@media (max-width:1180px){
  .app .hero{grid-template-columns:minmax(0,1fr);gap:28px}
  .app .rutas-rejilla{grid-template-columns:repeat(2,minmax(0,1fr))}
  .app .destacada{flex-direction:row;align-items:center;max-width:760px}
  .app .dest-img{width:44%;flex:none;margin:16px 0 16px 16px;border-radius:12px;border-bottom:0}
}

/* ═══ pantallas estrechas: la barra lateral pasa a cajón ═══
   Cerrado, el cajón queda fuera de la vista pero también fuera del
   tabulador: con solo moverlo de sitio, el teclado seguía entrando en
   él y el foco desaparecía por la izquierda. La visibilidad cambia al
   terminar la animación al cerrar y al empezarla al abrir. */
@media (max-width:900px){
  body.app{--alto-sup:60px}
  .app .armazon{grid-template-columns:minmax(0,1fr)}
  .app .lat{
    position:fixed;left:0;top:0;bottom:0;width:min(86vw,300px);height:auto;
    transform:translateX(-102%);visibility:hidden;
    transition:transform .25s ease,visibility 0s linear .25s;
    box-shadow:var(--sombra-menu);background:var(--tarjeta)
  }
  .app .lat.abierta{transform:none;visibility:visible;transition:transform .25s ease}
  .app .velo-lat{position:fixed;inset:0;z-index:45;background:rgba(20,20,22,.35)}
  .app .solo-movil{display:inline-grid}
  .app .superior{padding:0 14px;gap:10px}
  /* El rótulo se aparta a la vista, pero no del lector: sin él, el botón
     del ecosistema se habría quedado sin nombre. */
  .app .pastilla .txt,.app .cta .txt{
    position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap
  }
  .app .pastilla{width:40px;padding:0;justify-content:center}
  .app .cta{width:40px;padding:0;justify-content:center}
  .app .sup-acciones{gap:10px}
  .app main{padding:24px 16px 32px;gap:36px}
  .app #filas{gap:36px}
  .app .destacada{flex-direction:column;align-items:stretch}
  .app .dest-img{width:auto;margin:0;border-radius:0;border-bottom:1px solid var(--tarjeta-linea)}
  .app .fila-acc .redondo{display:none}
  .app .carrusel{grid-auto-columns:minmax(240px,78vw);gap:16px}
  .app .eco-menu{position:fixed;left:12px;right:12px;top:calc(var(--alto-sup) + 8px);width:auto}
  .app .pie{padding:14px 16px}
}
@media (max-width:640px){
  .app .rutas-rejilla{grid-template-columns:minmax(0,1fr);gap:12px}
}
@media (max-width:520px){
  .app .interruptor{width:56px}
  .app .interruptor[aria-checked="true"] .perilla{transform:translateX(24px)}
  .app .redondo,.app .pastilla,.app .cta{width:38px;height:38px}
  .app .buscador{height:38px;padding:0 10px}
  .app .hero h1{font-size:34px}
}
@media (prefers-reduced-motion:reduce){
  .app *{transition:none!important;scroll-behavior:auto!important}
}
