/* ═══════════════════════════════════════════════════════════
   MEJORAS — se carga después de estilos.css y lo corrige.
   Todo lo que cambió en la auditoría del 9 de agosto de 2026
   vive acá, para que el diff sea legible y se pueda revertir
   sin tocar las 4700 líneas originales.
   ═══════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────
   1 · ESCALA TIPOGRÁFICA
   Había etiquetas de 9.9px. Nada baja de 12px, y las
   versalitas espaciadas —que se leen peor— arrancan en 13px.
   ─────────────────────────────────────────────────────────── */
:root {
  --txt-micro: 0.78rem;  /* 12.5px · etiquetas sueltas */
  --txt-mini:  0.82rem;  /* 13.1px · versalitas espaciadas */
  --txt-ui:    0.9rem;   /* 14.4px · botones y formularios */
  --medida:    68ch;     /* medida de línea de la prosa larga */

  /* ── Movimiento ──────────────────────────────────────────
     Había catorce cubic-bezier distintos, varios a décimas
     unos de otros: (0.2,0.6,0.2,1), (0.2,0.7,0.2,1),
     (0.2,0.8,0.2,1), (0.22,0.61,0.36,1), (0.16,1,0.3,1).
     Todos querían ser la misma curva. Ahora lo son.       */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);      /* entra y sale */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);     /* se mueve en pantalla */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);      /* cajones y paneles */

  --dur-pulsar:  160ms;  /* respuesta al clic */
  --dur-control: 220ms;  /* botones, enlaces, pestañas */
  --dur-panel:   320ms;  /* cajón de compra, acordeones */
  --dur-modal:   420ms;  /* modal y lector */

  /* El único color de error del sitio. Un ladrillo apagado y no un rojo
     de alarma: tiene que convivir con la tinta y el ámbar sin parecer
     que se cayó de otra paleta.
     Medido: 6.31:1 sobre la tarjeta blanca y 5.38:1 sobre --paper-warm,
     así que sirve para texto (AA pide 4.5) y para el borde de un campo
     (que pide 3). */
  --error: #a63d2e;
}

.book-genre,
.otro-genre,
.libro-seccion-label,
.banco-label,
.resenia-autor,
.confirmar-nota,
.tarjeta-info {
  font-size: var(--txt-mini);
  letter-spacing: 0.12em;
}

.btn-copiar,
.copy-btn,
.btn-whatsapp,
.compra-tab-btn,
.libro-details summary,
.reader-cta-note {
  font-size: var(--txt-ui);
}

.libro-details summary {
  letter-spacing: 0.14em;
  padding-block: 0.95rem;
}

footer small { font-size: var(--txt-micro); }

/* `hidden` perdía contra cualquier regla con display: la opción de tarjeta
   se mostraba igual sin link de Payhip detrás. */
[hidden] { display: none !important; }

/* Los avisos de pago no pueden ser letra chica: son instrucciones. */
.compra-panel-inner p {
  font-size: var(--txt-ui) !important;
  line-height: 1.27 !important;
  color: var(--paper-deep) !important;
}

/* ───────────────────────────────────────────────────────────
   2 · SALTAR AL CONTENIDO
   ─────────────────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -120%);
  z-index: 100000;
  background: var(--amber);
  color: var(--ink);
  font-family: var(--ui);
  font-size: var(--txt-ui);
  letter-spacing: 0.08em;
  padding: 0.75rem 1.5rem;
  border-radius: 0 0 3px 3px;
  text-decoration: none;
  transition: transform 180ms ease;
}
.skip-link:focus {
  transform: translate(-50%, 0);
}

/* ───────────────────────────────────────────────────────────
   3 · NAVEGACIÓN
   En escritorio las siete secciones entran en la barra. La
   hamburguesa escondía el sitio entero detrás de un clic.
   ─────────────────────────────────────────────────────────── */
.nav-links {
  display: none;
  list-style: none;
  gap: clamp(1.1rem, 2.2vw, 2.2rem);
  align-items: center;
  margin: 0;
  padding: 0;
}
.nav-links a {
  font-family: var(--ui);
  font-size: var(--txt-mini);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-deep);
  text-decoration: none;
  padding: 0.4rem 0;
  position: relative;
  transition: color 200ms ease;
}
.nav-links a:hover { color: var(--paper); }
.nav-links a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--amber);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 260ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after { transform: scaleX(1); }
.nav-links a[aria-current="page"] { color: var(--amber); }

@media (min-width: 920px) {
  .nav-links { display: flex; }
  .menu-toggle { display: none; }
  .nav { gap: 2rem; }
}

/* El menú lateral solo existe en móvil. */
@media (min-width: 920px) {
  .menu-panel, .menu-backdrop { display: none; }
}

/* ───────────────────────────────────────────────────────────
   4 · FOCO VISIBLE
   Se navegaba con teclado a ciegas.
   ─────────────────────────────────────────────────────────── */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ───────────────────────────────────────────────────────────
   5 · PÁGINA DE LIBRO
   El título solo existía pintado en la portada. La sinopsis
   corría a 100 caracteres por línea y sin aire entre párrafos.
   ─────────────────────────────────────────────────────────── */
.migaja {
  font-family: var(--ui);
  font-size: var(--txt-micro);
  letter-spacing: 0.1em;
  color: var(--paper-muted);
  padding: calc(var(--navbar-h, 5.8rem) + 1.5rem) var(--pad-x) 0;
  max-width: var(--max-w);
  margin: 0 auto;
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.migaja a {
  color: var(--paper-muted);
  text-decoration: none;
  transition: color var(--dur-control) var(--ease-out);
}
.migaja a:hover { color: var(--amber); text-decoration: underline; }
.migaja [aria-current="page"] { color: var(--paper-deep); }

/* La migaja ya empuja el contenido: la vista no vuelve a hacerlo. */
.pagina-interior .view.libro-view { padding-top: 1.5rem; }

.libro-titulo-visible {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(2rem, 4.2vw, 3.1rem);
  line-height: 0.95;
  color: var(--paper);
  margin: 0 0 0.5rem;
  text-wrap: balance;
}

.sinopsis-extendida {
  max-width: var(--medida);
}
.sinopsis-extendida p + p {
  margin-top: 1.15em;
}

/* Con la prosa acotada a 68ch, una cita flotando al 45% dejaba la columna
   restante en veinte caracteres. Pasa a ser un bloque entre párrafos. */
.pull-quote-inline {
  float: none;
  max-width: none;
  margin: 2rem 0;
  padding: 0.25rem 0 0.25rem 1.75rem;
}
.pull-quote-inline blockquote { font-size: clamp(1.25rem, 2vw, 1.6rem); line-height: 1.01; }

/* La columna derecha terminaba mucho antes que la izquierda. */
@media (min-width: 900px) {
  .libro-layout { align-items: start; }
}

/* ───────────────────────────────────────────────────────────
   6 · TRANSICIÓN ENTRE PÁGINAS
   Reemplaza el telón que movía el router de la SPA. Ahora son
   páginas de verdad, así que la transición la hace el navegador.
   ─────────────────────────────────────────────────────────── */
@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: salir-pagina 220ms cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
  animation: entrar-pagina 320ms cubic-bezier(0, 0, 0.2, 1) both;
}
@keyframes salir-pagina {
  to { opacity: 0; transform: translateY(-8px); }
}
@keyframes entrar-pagina {
  from { opacity: 0; transform: translateY(10px); }
}

/* El nombre del autor en la barra no debe parpadear entre páginas. */
.nav .brand { view-transition-name: marca; }

/* ───────────────────────────────────────────────────────────
   7 · INTRO
   La coreografía duraba 3.9 s. Comprimida a 1.3 s, con los
   mismos movimientos.
   ─────────────────────────────────────────────────────────── */
.intro-curtain {
  transition: opacity 600ms cubic-bezier(0.6, 0, 0.4, 1),
              filter 600ms cubic-bezier(0.6, 0, 0.4, 1);
}
.intro-renglon-line { animation-duration: 500ms; animation-delay: 80ms; }
.intro-quote-word   { animation-duration: 340ms; }
.intro-quote-word:nth-child(1) { animation-delay: 380ms; }
.intro-quote-word:nth-child(2) { animation-delay: 470ms; }
.intro-quote-word:nth-child(3) { animation-delay: 560ms; }
.intro-quote-word:nth-child(4) { animation-delay: 650ms; }
.intro-quote-word-underline { animation-duration: 320ms; animation-delay: 830ms; }
.intro-signature { animation-duration: 380ms; animation-delay: 950ms; }
.intro-skip { animation-delay: 260ms; }

/* ───────────────────────────────────────────────────────────
   8 · HOME — LOS LIBROS
   La portada del sitio no mostraba ni un libro: había que
   abrir el menú para descubrir que existían.
   ─────────────────────────────────────────────────────────── */
/* La portada ya no es una pantalla aislada: abajo están los libros, así que
   deja de forzar 100vh y con eso desaparece la franja negra vacía. */
#view-inicio { min-height: auto; }
#view-inicio .hero-grid { padding-block: clamp(2.5rem, 5.5vw, 4.5rem); }

/* La rayita de "seguí bajando" quedó apagada desde que la portada dejó
   de ocupar la pantalla entera sola — hay más contenido abajo (la
   librería scrolleable, etc.) que ya lo deja claro sin el hint. */
#view-inicio .scroll-hint { display: none; }

/* ───────────────────────────────────────────────────────────
   9 · PÁGINA 404
   ─────────────────────────────────────────────────────────── */
.pagina-404 {
  min-height: 70vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: calc(var(--navbar-h, 5.8rem) + 3rem) var(--pad-x) 5rem;
  max-width: 46rem;
  margin: 0 auto;
}
.pagina-404-codigo {
  font-family: var(--ui);
  font-size: var(--txt-mini);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--amber);
  margin-bottom: 1.6rem;
}
.pagina-404-titulo {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.9rem, 4.4vw, 3rem);
  line-height: 0.95;
  color: var(--paper);
  text-wrap: balance;
}
.pagina-404-texto {
  font-family: var(--body);
  font-size: 1.12rem;
  line-height: 1.27;
  color: var(--paper-deep);
  margin-top: 1.4rem;
  max-width: 34rem;
}
.pagina-404-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  margin-top: 2.6rem;
}
.pagina-404-acciones .btn { text-decoration: none; }

/* ═══════════════════════════════════════════════════════════
   11 · MOVIMIENTO
   Auditoría del 9 de agosto de 2026 sobre las 4755 líneas de
   estilos.css. Lo que sigue corrige lo que encontró.
   ═══════════════════════════════════════════════════════════ */

/* ── 11.1 · Fuera `transition: all` ─────────────────────────
   Estaba en los 21 controles del sitio. Anima propiedades que
   nadie pidió y las saca de la GPU: cada botón repintaba de
   más. Se declara exactamente lo que cambia.               */
.intro-skip,
.menu-toggle,
.inicio-enter,
.btn,
.contacto-email,
.social a,
.reader-mute,
.reader-close,
.reader-nav,
.buy-modal-close,
.buy-confirm-btn,
.buy-option,
.buy-copy-btn,
.qr-lightbox-close,
.qr-lightbox-download,
.confirmar-submit,
.btn-copiar,
.btn-whatsapp,
.press-toggle,
.novedades-cta-btn,
.boton-payhip {
  transition:
    background-color var(--dur-control) var(--ease-out),
    border-color     var(--dur-control) var(--ease-out),
    color            var(--dur-control) var(--ease-out),
    opacity          var(--dur-control) var(--ease-out),
    transform        var(--dur-pulsar)  var(--ease-out);
}

/* Las barras de la hamburguesa sí se mueven: van por transform. */
.menu-toggle .bar {
  transition:
    transform var(--dur-control) var(--ease-in-out),
    opacity   var(--dur-control) var(--ease-out);
}

/* ── 11.2 · Respuesta al clic ───────────────────────────────
   En 4755 líneas había un solo `:active`. En un sitio donde
   el gesto que importa es "Llévate el libro", ningún botón
   acusaba recibo del clic.                                 */
.btn:active,
.buy-option:active,
.buy-confirm-btn:active,
.confirmar-submit:active,
.btn-copiar:active,
.btn-whatsapp:active,
.boton-payhip:active,
.novedades-cta-btn:active,
.compra-tab-btn:active,
.reader-nav:active,
.qr-lightbox-download:active {
  transform: scale(0.97);
}

/* Los controles chicos y redondos se hunden un poco menos. */
.menu-toggle:active,
.reader-close:active,
.reader-mute:active,
.buy-modal-close:active,
.qr-lightbox-close:active {
  transform: scale(0.92);
}

/* ── 11.3 · El hover es solo para quien tiene puntero ───────
   En táctil, tocar dispara un hover que se queda pegado: las
   tarjetas de la portada quedaban levantadas después del tap. */
@media (hover: hover) and (pointer: fine) {
  .otro-libro:hover { transform: translateY(-4px); }
}
@media not all and (hover: hover) {
  .otro-libro:hover { transform: none; }
}

/* ── 11.4 · Nada de animar el layout ────────────────────────
   El menú animaba `padding-left` y el subrayado animaba
   `width`: las dos disparan reflow en cada fotograma.      */
.menu-links a {
  transition:
    color     var(--dur-control) var(--ease-out),
    transform var(--dur-control) var(--ease-out),
    opacity   var(--dur-control) var(--ease-out);
  padding-left: 0 !important;
}
.menu-links a:hover,
.menu-links a.current,
.menu-links a[aria-current="page"] { transform: translateX(1.5rem); }

.menu-links a::before {
  width: 1rem;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-control) var(--ease-out);
}
.menu-links a:hover::before,
.menu-links a.current::before,
.menu-links a[aria-current="page"]::before { transform: scaleX(1); }

/* ── 11.5 · (era el cajón de compra) ────────────────────────
   Se le arregló la animación y después resultó que nadie podía
   abrirlo: `toggleCompra` no se llamaba desde ningún lado desde
   que la compra pasó al modal. El cajón ya no se publica, así
   que sus estilos tampoco hacen falta acá.                 */

/* ── 11.6a · El punto activo del carrusel ───────────────────
   Se ensanchaba animando `width`, que fuerza reflow del grupo
   entero. La misma pastilla, con scaleX.                   */
.carousel-dot {
  transition:
    background-color 240ms var(--ease-out),
    transform        240ms var(--ease-out);
}
.carousel-dot.is-active { transform: scaleX(2.6); border-radius: 3px; }

/* ── 11.6b · La barra de progreso del lector ────────────────
   Animar `width` en algo que se actualiza en cada página del
   lector es repintar la barra completa cada vez.           */
.reader-progress-fill {
  width: 100% !important;
  transform-origin: left;
  transform: scaleX(var(--avance, 0));
  transition: transform 350ms var(--ease-out);
}

/* ── 11.7 · Duraciones dentro de presupuesto ────────────────
   .btn tardaba 350ms y .inicio-enter 400ms en responder a un
   hover. Por encima de 300ms un control se siente lento.   */
.inicio-enter,
.hero-cta,
.carousel-cta {
  transition:
    background-color var(--dur-control) var(--ease-out),
    border-color     var(--dur-control) var(--ease-out),
    color            var(--dur-control) var(--ease-out),
    transform        var(--dur-pulsar)  var(--ease-out);
}

/* Las flechitas que se corren al pasar el mouse, con una sola
   curva en vez de cinco parecidas. */
.btn-primary svg,
.buy-confirm-arrow,
.buy-option-arrow,
.confirmar-submit-arrow,
.hero-cta-arrow,
.carousel-cta-arrow,
.press-cta-arrow,
.inicio-enter svg {
  transition: transform var(--dur-control) var(--ease-out);
}

/* ───────────────────────────────────────────────────────────
   12 · MOVIMIENTO REDUCIDO
   Menos movimiento, no menos información: se conservan color
   y opacidad, se quitan los desplazamientos.
   ─────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .nav-links a::after,
  .skip-link { transition: none; }

  .menu-links a:hover,
  .menu-links a.current,
  .menu-links a[aria-current="page"] { transform: none; }

  .btn:active,
  .buy-option:active,
  .buy-confirm-btn:active,
  .confirmar-submit:active,
  .menu-toggle:active,
  .reader-close:active { transform: none; }

  .libro-compra-drawer { transition-duration: 1ms; }

  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

/* ═══════════════════════════════════════════════════════════
   13 · PANEL PRIVADO (/admin/)
   No lo ve nadie más que Lester, pero es la pantalla desde la
   que despacha cada venta: tiene que ser clara a las once de
   la noche y desde el celular.
   ═══════════════════════════════════════════════════════════ */
.admin-inner {
  max-width: 40rem;
  margin: 0 auto;
  padding: calc(var(--navbar-h, 5.8rem) + 3rem) var(--pad-x) 5rem;
}
.admin-header { margin-bottom: 2.5rem; }
.admin-eyebrow {
  font-family: var(--ui);
  font-size: var(--txt-mini);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--amber);
  display: block;
  margin-bottom: 0.9rem;
}
.admin-title {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  line-height: 0.95;
  color: var(--paper);
}
.admin-nota {
  font-family: var(--body);
  font-size: 1.05rem;
  line-height: 1.27;
  color: var(--paper-deep);
  margin-top: 1rem;
  max-width: 34rem;
}

.admin-campo { margin-bottom: 1.6rem; }
.admin-label {
  display: block;
  font-family: var(--ui);
  font-size: var(--txt-mini);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-muted);
  margin-bottom: 0.6rem;
}
.admin-input,
.admin-select,
.admin-textarea {
  width: 100%;
  font-family: var(--ui);
  font-size: 1rem;
  color: var(--paper);
  background: var(--ink-input);
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  transition: border-color var(--dur-control) var(--ease-out);
}
.admin-input:focus,
.admin-select:focus,
.admin-textarea:focus { border-color: var(--amber); }
.admin-textarea {
  font-family: var(--body);
  font-size: 1.02rem;
  line-height: 1.2;
  resize: vertical;
  margin-bottom: 1.4rem;
}
.admin-select-wrap { position: relative; }
.admin-select { appearance: none; padding-right: 2.5rem; }
.admin-select-wrap::after {
  content: '';
  position: absolute;
  right: 1rem;
  top: 50%;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--paper-muted);
  border-bottom: 1.5px solid var(--paper-muted);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
.admin-ayuda {
  font-family: var(--ui);
  font-size: var(--txt-micro);
  line-height: 1.2;
  color: var(--paper-muted);
  margin-top: 0.5rem;
}
.admin-enviar { width: 100%; margin-top: 0.6rem; justify-content: center; }

.admin-error {
  font-family: var(--ui);
  font-size: var(--txt-ui);
  color: #e8a0a0;
  background: rgba(232, 160, 160, 0.08);
  border: 1px solid rgba(232, 160, 160, 0.3);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  margin-top: 1.2rem;
}

.admin-resultado {
  border-top: 1px solid var(--rule-soft);
  padding-top: 2.5rem;
}
.admin-resultado-titulo {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: 1.8rem;
  color: var(--amber);
}
.admin-resultado-libro {
  font-family: var(--body);
  font-size: 1.1rem;
  color: var(--paper-deep);
  margin: 0.4rem 0 1.8rem;
}
.admin-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-bottom: 1.2rem;
}
.admin-acciones .btn { text-decoration: none; }
.admin-otro {
  display: block;
  margin-top: 2rem;
  background: none;
  border: none;
  padding: 0;
  font-family: var(--ui);
  font-size: var(--txt-ui);
  color: var(--paper-muted);
  text-decoration: underline;
  text-underline-offset: 4px;
  cursor: pointer;
  transition: color var(--dur-control) var(--ease-out);
}
.admin-otro:hover { color: var(--amber); }

/* ── Panel de tres pestañas (una sola clave) ──────────────── */
.admin-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.6rem;
  border-bottom: 1px solid var(--rule-soft);
  margin: 0.6rem 0 2.2rem;
}
.admin-tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0 0 0.8rem;
  margin-bottom: -1px;
  font-family: var(--ui);
  font-size: var(--txt-ui);
  color: var(--paper-muted);
  cursor: pointer;
  transition: color var(--dur-control) var(--ease-out),
              border-color var(--dur-control) var(--ease-out);
}
.admin-tab:hover { color: var(--paper); }
.admin-tab.is-active { color: var(--paper); border-bottom-color: var(--amber); }
.admin-tab:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }

.admin-panel-nota { margin-top: 0; margin-bottom: 2rem; }

/* ── El QR generado ───────────────────────────────────────── */
.admin-qr {
  width: 100%;
  max-width: 16rem;
  margin: 0 auto 1.6rem;
  padding: 1rem;
  background: #fff;                 /* blanco: es lo que escanea al imprimir */
  border-radius: 4px;
}
.admin-qr svg { display: block; width: 100%; height: auto; }

/* ── Comentarios por moderar ──────────────────────────────── */
.admin-comentarios { display: grid; gap: 1rem; margin-top: 1.4rem; }
.com-resumen {
  font-family: var(--ui);
  font-size: var(--txt-ui);
  color: var(--amber);
  margin: 0 0 0.4rem;
}
.com-tarjeta {
  background: var(--ink-input);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 1.1rem 1.2rem;
  transition: opacity var(--dur-control) var(--ease-out);
}
.com-tarjeta--publicado { border-color: var(--rule-soft); opacity: 0.82; }
.com-tarjeta--ocupada { opacity: 0.5; pointer-events: none; }
.com-meta {
  font-family: var(--ui);
  font-size: var(--txt-micro);
  color: var(--paper-muted);
  margin: 0 0 0.6rem;
}
.com-meta strong { color: var(--paper); font-weight: 600; }
.com-texto {
  font-family: var(--body);
  font-size: 1.08rem;
  line-height: 1.2;
  color: var(--paper-deep);
  margin: 0 0 1rem;
  white-space: pre-line;
}
.com-acciones { display: flex; align-items: center; gap: 1rem; }
.com-btn { padding: 0.5rem 1.2rem; font-size: var(--txt-micro); }
.com-borrar {
  background: none;
  border: none;
  padding: 0;
  font-family: var(--ui);
  font-size: var(--txt-micro);
  color: var(--paper-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color var(--dur-control) var(--ease-out);
}
.com-borrar:hover { color: #e8a0a0; }
.com-badge {
  font-family: var(--ui);
  font-size: var(--txt-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--wa, #3d9a5a);
}

/* ── «Lo que dicen sus lectores» (página de Antes del recreo) ──
   Los comentarios aprobados de los alumnos del plan lector. La
   sección la enciende assets/js/lectores.js solo si hay alguno. */
.lectores-wrap {
  margin-top: clamp(3rem, 8vw, 5rem);
  padding-top: clamp(2.4rem, 6vw, 3.6rem);
  border-top: 1px solid var(--rule-soft);
}
.lectores { max-width: 60rem; margin: 0 auto; }
.lectores-lista {
  display: grid;
  gap: 1.4rem;
  margin-top: 1.6rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
}
.lector {
  margin: 0;
  padding: 1.4rem 1.5rem;
  background: var(--ink-input);
  border: 1px solid var(--rule);
  border-radius: 4px;
}
.lector-texto {
  font-family: var(--body);
  font-size: 1.16rem;
  line-height: 1.22;
  color: var(--paper-deep);
  margin: 0 0 1rem;
  quotes: '«' '»';
}
.lector-texto::before { content: open-quote; color: var(--amber); }
.lector-texto::after  { content: close-quote; color: var(--amber); }
.lector-pie {
  font-family: var(--ui);
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.6rem;
  align-items: baseline;
}
.lector-quien { font-size: var(--txt-ui); color: var(--amber); font-weight: 600; }
.lector-obra { font-size: var(--txt-micro); color: var(--paper-muted); }

/* Antes iba como style="" en la plantilla; los atributos de estilo obligan a
   abrir style-src con 'unsafe-inline'. */
.menu-footer-correo { margin-top: 0.8rem; }

/* ═══════════════════════════════════════════════════════════
   14 · CLASES QUE REEMPLAZAN ATRIBUTOS style=
   Un solo style="" en el HTML obliga a abrir style-src con
   'unsafe-inline' en la CSP. Sacándolos todos, la política
   puede quedar en 'self' a secas.
   ═══════════════════════════════════════════════════════════ */
.icono-11 { width: 11px; height: 11px; }
.icono-12 { width: 12px; height: 12px; }
.icono-13 { width: 13px; height: 13px; }
.oculto { display: none; }
.enlace-inline { display: inline-flex; margin-top: 0.5rem; }
.separado-arriba { margin-top: 2.5rem; }
.parrafo-destacado {
  font-size: 1.2rem;
  line-height: 1.31;
  color: var(--paper-deep);
  font-style: italic;
  max-width: 440px;
}
.separado-arriba-2 { margin-top: 2rem; }

/* ═══════════════════════════════════════════════════════════
   PÁGINA /comprar/ — el paso previo a Mercado Pago

   Hereda el mismo lenguaje que /confirmar-pago/: tarjeta clara
   sobre el fondo del sitio, etiquetas en versalitas, foco ámbar.
   Es la misma clase de página —un formulario corto en medio de
   una compra— y no tenía por qué inventarse otro aspecto.
   ═══════════════════════════════════════════════════════════ */
.view-comprar {
  padding: clamp(90px, 14vh, 150px) clamp(18px, 5vw, 32px) clamp(60px, 10vh, 110px);
}
.comprar-inner {
  max-width: 30rem;
  margin: 0 auto;
}
.comprar-header {
  text-align: center;
  margin-bottom: clamp(28px, 5vh, 44px);
}

/* El libro que se está comprando, para que nadie pague a ciegas. */
.comprar-libro {
  display: flex;
  gap: clamp(14px, 3vw, 22px);
  align-items: center;
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: 6px;
  padding: clamp(16px, 3vw, 22px);
  box-shadow: 0 4px 24px rgba(20, 12, 6, 0.08);
  margin-bottom: 18px;
}
.comprar-portada {
  display: block;
  width: 88px;
  height: auto;
  border-radius: 2px;
  box-shadow: 0 3px 14px rgba(20, 12, 6, 0.22);
}
.comprar-libro-datos { min-width: 0; }
.comprar-genero {
  font-family: var(--ui);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 4px;
}
.comprar-titulo {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.15rem, 3.4vw, 1.45rem);
  line-height: 0.95;
  color: var(--ink);
  margin: 0;
}
.comprar-precio {
  font-family: var(--ui);
  font-size: 1.05rem;
  color: var(--ink);
  margin: 10px 0 2px;
}
.comprar-formato {
  font-family: var(--ui);
  font-size: 0.7rem;
  color: var(--ink-muted);
  margin: 0;
}

.comprar-form {
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: 6px;
  padding: clamp(22px, 4vw, 32px);
  box-shadow: 0 4px 24px rgba(20, 12, 6, 0.08);
}
.comprar-label {
  display: block;
  font-family: var(--body, system-ui);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 65%, transparent);
  margin-bottom: 6px;
  font-weight: 500;
}
.comprar-input {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid color-mix(in srgb, var(--ink) 18%, transparent);
  border-radius: 3px;
  background: var(--paper-warm);
  color: var(--ink);
  font-family: var(--body, system-ui);
  font-size: 0.92rem;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
  -webkit-appearance: none;
  appearance: none;
  box-sizing: border-box;
}
.comprar-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--amber-soft) 80%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--amber-soft) 18%, transparent);
}
.comprar-ayuda {
  font-family: var(--ui);
  font-size: 0.72rem;
  line-height: 1.16;
  color: var(--ink-muted);
  margin: 8px 0 22px;
}
/* El error se marca en el campo, no solo en el texto de abajo.
   Antes el mensaje cambiaba y la casilla quedaba idéntica: el ojo se
   enteraba de que algo estaba mal, pero no de dónde.

   Tres señales a la vez y ninguna depende del color sola: el borde, el
   símbolo delante del texto y `aria-invalid` en el campo. En pantalla
   hay gente que no distingue el rojo del gris. */
.comprar-ayuda--error {
  color: var(--error);
  font-weight: 500;
}
.comprar-ayuda--error::before {
  content: '⚠ ';
}

.comprar-input--error,
.comprar-input--error:focus {
  border-color: var(--error);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--error) 14%, transparent);
}

/* Un temblor corto. Solo ocurre cuando alguien se equivocó, así que no
   se repite nunca en el uso normal; y es chico —tres píxeles— porque
   la señal ya la dan el borde y el símbolo: esto solo lleva el ojo. */
.comprar-input--error { animation: comprar-tiembla 180ms ease-in-out both; }

@keyframes comprar-tiembla {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-3px); }
  75%      { transform: translateX(3px); }
}

.comprar-boton {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 15px 24px;
  border: none;
  border-radius: 3px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--ui);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.25s ease, opacity 0.25s ease;
}
.comprar-boton:hover { background: color-mix(in srgb, var(--ink) 88%, var(--amber)); }
.comprar-boton:disabled { opacity: 0.6; cursor: progress; }
.comprar-legal {
  font-family: var(--ui);
  font-size: 0.68rem;
  line-height: 1.2;
  color: var(--ink-muted);
  margin: 16px 0 0;
  text-align: center;
}

/* Cuando la tarjeta no está disponible, la salida no es un callejón. */
.comprar-alterna {
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: 6px;
  padding: clamp(22px, 4vw, 32px);
  text-align: center;
}
.comprar-alterna-texto {
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.24;
  color: var(--ink);
  margin: 0 0 20px;
}
.comprar-alterna-btn {
  display: inline-block;
  padding: 13px 26px;
  background: var(--ink);
  color: var(--paper);
  text-decoration: none;
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 3px;
}

@media (max-width: 420px) {
  .comprar-libro { flex-direction: column; text-align: center; }
  .comprar-portada { width: 108px; }
}

/* ── La entrada de /comprar/ ────────────────────────────────
   El bloque del libro y el formulario arrancan con `hidden` y el
   script los descubre — el segundo recién cuando contesta
   /api/comprar. Sin nada que salve ese salto, el formulario
   aparece de golpe debajo de un libro que ya estaba: el clásico
   contenido que se teletransporta.

   Como `hidden` saca el elemento del render, la animación arranca
   sola en cuanto se lo quita. No hace falta tocar el script.

   Escalonado corto y en un solo sentido: es un paso intermedio de
   una compra, no un momento para lucirse. Termina en 400 ms.
   ─────────────────────────────────────────────────────────── */
.comprar-libro   { animation: comprar-entra 340ms var(--ease-out) both; }
.comprar-form,
.comprar-alterna { animation: comprar-entra 340ms var(--ease-out) 60ms both; }

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

/* El botón ya tenía color al pasar el mouse, pero nada al apretarlo.
   Es la única respuesta táctil de la página y va corta. */
.comprar-boton:active:not(:disabled),
.comprar-alterna-btn:active { transform: scale(0.98); }
.comprar-alterna-btn { transition: transform var(--dur-pulsar) var(--ease-out); }

@media (prefers-reduced-motion: reduce) {
  .comprar-libro, .comprar-form, .comprar-alterna {
    animation: comprar-aparece 180ms ease both;
  }
  .comprar-boton:active:not(:disabled),
  .comprar-alterna-btn:active { transform: none; }
  /* El borde y el símbolo siguen marcando el error; se va el temblor. */
  .comprar-input--error { animation: none; }
  @keyframes comprar-aparece { from { opacity: 0; } to { opacity: 1; } }
}

/* ═══════════════════════════════════════════════════════════
   PÁGINAS LEGALES — /privacidad/ y /terminos/

   Prosa larga y nada más, así que lo único que importa acá es la
   medida de línea y el aire entre bloques. Se reusa `--medida`
   (68ch), que es la misma con la que se lee la sinopsis.
   ═══════════════════════════════════════════════════════════ */
.view-legal {
  padding: clamp(90px, 14vh, 150px) clamp(18px, 5vw, 32px) clamp(70px, 12vh, 120px);
}
.legal-inner {
  max-width: var(--medida);
  margin: 0 auto;
}
.legal-header {
  text-align: center;
  margin-bottom: clamp(32px, 6vh, 56px);
}
.legal-fecha {
  font-family: var(--ui);
  font-size: var(--txt-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-muted);
  margin-top: 0.9rem;
}

.legal-cuerpo {
  font-family: var(--body);
  font-size: 1.05rem;
  line-height: 1.31;
  color: var(--paper-deep);
  /* El tope va acá y no en el contenedor de arriba: `ch` se resuelve
     contra el tamaño de letra del elemento donde se escribe, y puesto
     en `.legal-inner` —que hereda 16px— salía bastante más ancho.

     Y `ch` es el ancho del cero, que en Cormorant es mucho más gordo
     que la letra promedio: con 66ch entraban 82 caracteres reales por
     renglón. Medido con una frase de verdad, 56ch da los ~68 que se
     leen cómodos. El número que importa es el segundo. */
  max-width: 56ch;
  margin-inline: auto;
}
.legal-cuerpo p { margin: 0 0 1.15em; }
.legal-cuerpo strong { color: var(--paper); font-weight: 500; }

/* ───────────────────────────────────────────────────────────
   9 · 100vh EN SAFARI DE iPHONE
   `100vh` en Safari mide la pantalla con la barra de direcciones
   OCULTA, que es más alta que lo que el usuario ve al entrar. En
   toda sección que fuerza una altura mínima de pantalla completa,
   eso deja un tramo de scroll vacío del alto de esa barra —el
   mismo síntoma que ya se había resuelto una vez para #view-inicio
   más arriba en este archivo. `dvh` mide la pantalla real y cae
   bien en todo navegador de 2022 en adelante; la línea con `vh` va
   primero como respaldo y la sobreescribe donde `dvh` no existe.
   ─────────────────────────────────────────────────────────── */
body { min-height: 100dvh; }
.view { min-height: 100dvh; }
.menu-panel { height: 100dvh; }
.view-confirmar { min-height: calc(100dvh - 80px); }
.view-novedades.active { min-height: calc(100dvh - 200px); }
.view-prensa { min-height: calc(100dvh - 80px); }

/* La entrada da el tono: es la única que va en cursiva y algo mayor. */
.legal-entrada {
  font-size: 1.2rem;
  font-style: italic;
  color: var(--paper);
  padding-bottom: 1.4em;
  margin-bottom: 1.6em;
  border-bottom: 1px solid color-mix(in srgb, var(--rule) 55%, transparent);
}

.legal-cuerpo h2 {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.25rem, 2.6vw, 1.55rem);
  line-height: 0.95;
  color: var(--paper);
  margin: 2.2em 0 0.7em;
}

.legal-lista {
  margin: 0 0 1.15em;
  padding-left: 1.1em;
}
.legal-lista li { margin-bottom: 0.5em; }
.legal-lista li::marker { color: var(--amber); }

.legal-cuerpo a {
  color: var(--amber);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--amber) 38%, transparent);
  transition: border-color var(--dur-control) var(--ease-out);
}
.legal-cuerpo a:hover { border-bottom-color: var(--amber); }

.legal-contacto {
  margin-top: 2.4em;
  padding-top: 1.4em;
  border-top: 1px solid color-mix(in srgb, var(--rule) 55%, transparent);
  font-family: var(--ui);
  font-size: var(--txt-ui);
}

/* ── Los enlaces legales del pie ──────────────────────────── */
.footer-legal {
  margin-top: 1.1rem;
  display: flex;
  gap: 0.6rem;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  font-family: var(--ui);
  font-size: var(--txt-micro);
  letter-spacing: 0.1em;
  color: var(--paper-muted);
}
.footer-legal a {
  color: var(--paper-muted);
  text-decoration: none;
  /* 44px de alto tocable. Con solo padding vertical quedaban en 32,
     que en un pulgar es un blanco chico — y son letra pequeña, que ya
     de por sí cuesta acertar. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.35rem;
  transition: color var(--dur-control) var(--ease-out);
}
.footer-legal a:hover { color: var(--amber); }

/* ═══════════════════════════════════════════════════════════
   ÁREAS TÁCTILES EN TELÉFONO

   Medido a 390 px: el sitio no desborda y no tiene texto chico,
   pero casi todos sus controles quedaban por debajo de los 44 px
   que necesita un pulgar. Los puntos del carrusel median 6, y el
   botón de copiar el número de Yape —que se aprieta en mitad de
   una compra, muchas veces con una mano— median 21.

   Dos técnicas, según el caso:

   · En los botones, `min-height`. Cambia la caja, pero son
     elementos que ya tenían aire alrededor.
   · En los enlaces de texto y en los puntos, un `::after` que
     extiende SOLO la zona sensible. Así el dibujo no cambia ni un
     píxel — un punto de 6 px tiene que verse de 6 px— pero el
     dedo acierta igual.

   No se toca nada en escritorio: con un mouse, 21 px se aciertan
   sin problema y agrandarlo solo desordenaría el diseño.
   ═══════════════════════════════════════════════════════════ */
@media (pointer: coarse) {

  /* Botones: crecen de verdad. */
  .buy-copy-btn,
  .buy-confirm-btn,
  .buy-modal-close,
  .reader-close,
  .reader-nav,
  .reader-mute,
  .carousel-cta,
  .hero-cta,
  .btn {
    min-height: 44px;
  }
  /* Los que son solo un icono también necesitan ancho. */
  .buy-modal-close,
  .reader-close,
  .reader-mute {
    min-width: 44px;
  }
  /* Con min-height, lo de adentro tiene que volver a centrarse. */
  .buy-copy-btn,
  .buy-confirm-btn,
  .buy-modal-close,
  .reader-close,
  .reader-mute,
  .carousel-cta,
  .hero-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Enlaces de texto y puntos: se agranda la zona, no el dibujo. */
  .brand,
  .migaja a,
  .carousel-dot,
  .footer-legal a {
    position: relative;
  }
  /* El botón de cerrar de la promo ya es position:absolute — no
     necesita el position:relative de arriba, alcanza con el ::after. */
  .promo-card-close::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
    z-index: 1;
  }

  .brand::after,
  .migaja a::after,
  .carousel-dot::after {
    content: '';
    position: absolute;
    /* Centra un área de 44px sobre el elemento, mida lo que mida. */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: max(100%, 44px);
    height: 44px;
    /* Que no tape lo que tiene al lado ni se vea en ningún caso. */
    z-index: 1;
  }
  /* Los puntos van pegados: si cada uno reclama 44px de ancho se
     pisan entre sí y el dedo cae en el vecino. Solo se estira el alto. */
  .carousel-dot::after {
    width: 100%;
    min-width: 24px;
  }
}

/* ───────────────────────────────────────────────────────────
   10 · BONIFICACIONES — /bonificaciones/
   Mismo lenguaje visual que /comprar/ (tarjeta blanca sobre el
   fondo oscuro): es el mismo gesto —completar unos datos y
   mandar algo— así que reusa esa forma en vez de inventar otra.
   ─────────────────────────────────────────────────────────── */
.view-bonif {
  padding: clamp(90px, 14vh, 150px) clamp(18px, 5vw, 32px) clamp(60px, 10vh, 110px);
}
.bonif-inner { max-width: 30rem; margin: 0 auto; }
.bonif-header { text-align: center; margin-bottom: clamp(28px, 5vh, 44px); }
.bonif-sub {
  font-family: var(--body);
  font-size: 1.05rem;
  line-height: 1.2;
  color: var(--paper-muted);
  margin: 14px 0 0;
}

.bonif-libro {
  display: flex;
  gap: clamp(14px, 3vw, 22px);
  align-items: center;
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: 6px;
  padding: clamp(14px, 3vw, 18px);
  box-shadow: 0 4px 24px rgba(20, 12, 6, 0.08);
  margin-bottom: 18px;
}
.bonif-portada-caja img {
  display: block;
  width: 72px;
  height: auto;
  border-radius: 2px;
  box-shadow: 0 3px 14px rgba(20, 12, 6, 0.22);
}
.bonif-genero {
  font-family: var(--ui);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 4px;
}
.bonif-titulo {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.1rem, 3.2vw, 1.35rem);
  line-height: 0.95;
  color: var(--ink);
  margin: 0;
}

.bonif-form {
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: 6px;
  padding: clamp(22px, 4vw, 32px);
  box-shadow: 0 4px 24px rgba(20, 12, 6, 0.08);
  display: grid;
  gap: 1.15rem;
}
.bonif-form .campo { display: grid; gap: 0.4rem; }
.bonif-form label {
  font-family: var(--body, system-ui);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 65%, transparent);
  font-weight: 500;
}
.bonif-form select,
.bonif-form input[type="text"] {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid color-mix(in srgb, var(--ink) 18%, transparent);
  border-radius: 3px;
  background: var(--paper-warm);
  color: var(--ink);
  font-family: var(--body, system-ui);
  font-size: 0.95rem;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
  appearance: none;
  box-sizing: border-box;
}
.bonif-form input[type="file"] {
  font-family: var(--ui);
  font-size: 0.78rem;
  color: var(--ink-muted);
}
.bonif-form select:focus,
.bonif-form input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--amber-soft) 80%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--amber-soft) 18%, transparent);
}
.bonif-ayuda {
  font-family: var(--ui);
  font-size: var(--txt-micro, 0.78rem);
  line-height: 1.12;
  color: var(--ink-muted);
  margin: 0;
}
.bonif-preview { margin-top: 0.6rem; }
.bonif-preview img {
  display: block;
  max-width: 100%;
  max-height: 220px;
  border-radius: 4px;
  border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent);
}
.bonif-boton {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 15px 24px;
  border: none;
  border-radius: 3px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--ui);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.25s ease, opacity 0.25s ease;
}
.bonif-boton:hover { background: color-mix(in srgb, var(--ink) 88%, var(--amber)); }
.bonif-boton:disabled { opacity: 0.6; cursor: progress; }
.bonif-error {
  font-family: var(--ui);
  font-size: 0.78rem;
  color: var(--error);
  font-weight: 500;
}
.bonif-error::before { content: '⚠ '; }

.bonif-listo {
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: 6px;
  padding: clamp(22px, 4vw, 32px);
  text-align: center;
}
.bonif-listo h2 {
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: 1.5rem;
  color: var(--ink);
  margin: 0 0 10px;
}
.bonif-listo p {
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.2;
  color: var(--ink-muted);
  margin: 0;
}

@media (max-width: 420px) {
  .bonif-libro { flex-direction: column; text-align: center; }
}

/* El aviso dentro del modal de compra que lleva a /bonificaciones/. */
.buy-bonificacion-note {
  font-family: var(--ui);
  font-size: var(--txt-micro, 0.78rem);
  text-align: center;
  color: color-mix(in srgb, var(--ink) 62%, transparent);
  margin: 10px 0 0;
  line-height: 1.05;
}
.buy-bonificacion-note a {
  color: var(--amber-deep, var(--amber));
  font-weight: 600;
}

/* Zoom sobre la portada al pasar el mouse (drift-zoom, ver assets/js/zoom-portada.js).
   Mientras se muestra, se congela el tilt en 3D: rotar la portada mientras
   se rastrea el detalle con el cursor se veía inestable. */
.libro-cover-frame.zoom-activo,
.libro-col-izq .libro-cover-frame.zoom-activo {
  transform: none !important;
}
.drift-zoom-pane-loader {
  background-color: var(--ink);
}

/* ───────────────────────────────────────────────────────────
   PROMO — aviso de "Última conexión" tras la cortina de
   apertura, modal centrado con fondo oscurecido — el tratamiento
   original, agrandado a pedido (más presencia en pantalla que la
   primera versión: tarjeta y portada más grandes, tipografía más
   grande). Sin `border` (ghost-card ya sacado) y con el botón de
   cerrar con zona táctil de 44px vía `::after` (ver más abajo,
   sección de áreas táctiles).
   ─────────────────────────────────────────────────────────── */
.promo-overlay {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-modal) var(--ease-out);
}
.promo-overlay.is-visible { opacity: 1; pointer-events: auto; }
.promo-overlay.is-leaving { opacity: 0; }
.promo-overlay[hidden] { display: none; }

.promo-card {
  position: relative;
  width: 100%;
  max-width: 560px;
  padding: 56px 48px 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  background: var(--ink);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
  transform: scale(0.96) translateY(10px);
  transition: transform var(--dur-modal) var(--ease-out);
}
.promo-overlay.is-visible .promo-card { transform: scale(1) translateY(0); }

.promo-card-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--amber-soft) 40%, transparent);
  color: var(--paper-muted);
  font-family: var(--ui);
  font-size: 1.3rem;
  line-height: 0.75;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color var(--dur-control) var(--ease-out), border-color var(--dur-control) var(--ease-out);
}
.promo-card-close:hover,
.promo-card-close:focus-visible {
  color: var(--paper-warm);
  border-color: var(--amber-soft);
}
.promo-card-close:focus-visible { outline: 2px solid var(--amber-soft); outline-offset: 2px; }

.promo-card-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-decoration: none;
}
.promo-card-cover {
  width: 240px;
  height: auto;
  aspect-ratio: 896 / 1200;
  object-fit: cover;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
}
.promo-card-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.promo-card-eyebrow {
  font-family: var(--ui);
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber-soft);
}
.promo-card-title {
  font-family: var(--display);
  font-style: italic;
  font-size: clamp(2rem, 3.6vw, 2.6rem);
  line-height: 0.95;
  color: var(--paper-warm);
}
.promo-card-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 13px 26px;
  border: 1px solid color-mix(in srgb, var(--amber-soft) 55%, transparent);
  font-family: var(--ui);
  font-size: 0.88rem;
  letter-spacing: 0.04em;
  color: var(--paper-warm);
  transition: gap var(--dur-control) var(--ease-out), border-color var(--dur-control) var(--ease-out), background-color var(--dur-control) var(--ease-out);
}
.promo-card-link:hover .promo-card-cta,
.promo-card-link:focus-visible .promo-card-cta {
  gap: 10px;
  border-color: var(--amber-soft);
  background: color-mix(in srgb, var(--amber-soft) 12%, transparent);
}
.promo-card-link:focus-visible { outline: 2px solid var(--amber-soft); outline-offset: 4px; }

@media (max-width: 600px) {
  .promo-card { padding: 40px 28px 32px; }
  .promo-card-cover { width: 180px; }
}
@media (prefers-reduced-motion: reduce) {
  .promo-overlay { transition: opacity 250ms ease; }
  .promo-card { transition: none; transform: none; }
}
