/* =========================================================================
   main.css — hoja de estilos única del sitio público.

   PORTADA DESDE comparalibros.com: es el mismo sistema de diseño, con el azul
   cambiado por el rojo del tema y la tipografía de jamelguetes (Baloo 2 +
   Plus Jakarta Sans) en lugar de la Montserrat autoalojada de allí.

   El color, la tipografía y la geometría salen de custom properties
   `--theme-*` que el servidor inyecta en un <style> del <head> a partir del
   preset de /admin/apariencia. Los literales de color del original se han
   mapeado a esos tokens uno a uno: si quedara alguno suelto, cambiar de tema
   dejaría esa pieza con la paleta anterior y el editor de Apariencia sería
   decorativo.

   Los `--ui-*` son la capa derivada (esquinas, sombras, tintes del acento) y
   se construyen SIEMPRE a partir de los `--theme-*`, para que el admin siga
   mandando sobre toda la interfaz y no sólo sobre la mitad.

   Móvil primero; breakpoints en 640 / 720 / 980 / 1080 px.
   ========================================================================= */

:root {
  /* Fallbacks (preset Confeti) por si la inyección de tema fallase. */
  --theme-bg: #FFFDF8;
  --theme-surface: #ffffff;
  --theme-surface-alt: #FFF4E6;
  --theme-ink: #1F1B2E;
  --theme-ink-soft: #524D68;
  --theme-ink-muted: #8B879C;
  --theme-border: #EFE6DA;
  --theme-accent: #F0562D;
  --theme-accent-soft: #FFE8E1;
  --theme-success: #12855C;
  --theme-danger: #D62B1F;
  --theme-radius: 14px;
  --theme-radius-lg: 24px;
  --theme-shadow: 0 1px 2px rgba(31, 27, 46, 0.06), 0 10px 28px rgba(31, 27, 46, 0.08);
  --theme-shadow-sm: 0 1px 2px rgba(31, 27, 46, 0.06);
  --theme-font-heading: "Baloo 2", "Plus Jakarta Sans", system-ui, sans-serif;
  --theme-font-body: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --theme-font-mono: "JetBrains Mono", "Menlo", monospace;
  --theme-density-scale: 1;

  /* Aliases hacia atrás para que `admin.css` siga funcionando sin tocar
     todos sus tokens. */
  --color-bg: var(--theme-bg);
  --color-surface: var(--theme-surface);
  --color-border: var(--theme-border);
  --color-text: var(--theme-ink);
  --color-muted: var(--theme-ink-muted);
  --color-accent: var(--theme-accent);
  --color-accent-hover: var(--theme-accent);
  --color-success: var(--theme-success);
  --color-danger: var(--theme-danger);
  --radius: var(--theme-radius);
  --shadow-sm: var(--theme-shadow-sm);
  --shadow-md: var(--theme-shadow);
  --font-sans: var(--theme-font-body);

  /* Espaciado escalable por densidad. */
  --pad-xs: calc(0.25rem * var(--theme-density-scale));
  --pad-sm: calc(0.5rem * var(--theme-density-scale));
  --pad-md: calc(1rem * var(--theme-density-scale));
  --pad-lg: calc(1.5rem * var(--theme-density-scale));
  --pad-xl: calc(2.5rem * var(--theme-density-scale));

  /* ---- Tokens derivados para la capa visual "pro" (inspirada en el
     directorio de gasolineras pero en azul). Se construyen a partir de los
     `--theme-*` para respetar el sistema de temas y los overrides del admin. */
  --ui-accent: var(--theme-accent);
  --ui-accent-strong: color-mix(in srgb, var(--theme-accent) 82%, #000 18%);
  --ui-accent-soft: var(--theme-accent-soft);
  --ui-accent-tint: color-mix(in srgb, var(--theme-accent) 22%, #fff);
  --ui-accent-ring: color-mix(in srgb, var(--theme-accent) 30%, transparent);

  /* ESCALA ÚNICA DE REDONDEO. Antes había dos en paralelo —`--theme-radius` a
     4 px y `--ui-radius-md` a 12 px— conviviendo en la misma tarjeta, más nueve
     literales sueltos (3, 5, 9, 10, 11, 14 px…) y el mismo token escrito con
     tres fallbacks distintos (`--ui-radius-lg, 14px` / `, 16px` / `, 18px`).
     De ahí que cada caja tuviera su propia esquina.
     Los cuatro pasos derivan de `--theme-radius-lg`, que es lo que inyecta el
     preset de tema desde la BD (services/site-config/index.ts): así el admin
     sigue mandando y toda la interfaz escala junta en vez de por partes. Con el
     valor actual (8) salen 8/12/18/24, exactamente los de hoy. */
  --ui-radius-sm: var(--theme-radius-lg);
  --ui-radius-md: calc(var(--theme-radius-lg) * 1.5);
  --ui-radius-lg: calc(var(--theme-radius-lg) * 2.25);
  --ui-radius-xl: calc(var(--theme-radius-lg) * 3);
  --ui-radius-pill: 999px;
  /* Radio de TODOS los botones de accion (comprar, anadir a la comparativa,
     barra movil). Existe para que no vuelva a pasar lo de agosto-2026: cada
     CTA habia elegido su esquina por su cuenta —8px en la comparativa, 12 en
     el rail, 18 en la barra movil y pildora en dos sitios— y el tema `planeta`
     parcheaba UNO solo, asi que en produccion convivian cuatro esquinas
     distintas en la misma pantalla. Se cambia aqui y se mueven todos. */
  --ui-radius-cta: var(--ui-radius-pill);

  --ui-shadow-sm: 0 1px 2px rgba(31, 27, 46, 0.05), 0 1px 3px rgba(31, 27, 46, 0.04);
  --ui-shadow-md: 0 6px 22px rgba(31, 27, 46, 0.08), 0 2px 6px rgba(31, 27, 46, 0.05);
  --ui-shadow-lg: 0 22px 50px rgba(31, 27, 46, 0.14), 0 4px 12px rgba(31, 27, 46, 0.06);
  --ui-shadow-accent: 0 12px 30px color-mix(in srgb, var(--theme-accent) 32%, transparent);

  /* Icono de lupa (data-uri) para máscaras CSS en el buscador del hero. */
  --ui-search-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; }

html { font-size: 16px; }

body {
  margin: 0;
  font-family: var(--theme-font-body);
  color: var(--theme-ink);
  background-color: var(--theme-bg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Decoración de fondo según tema. */

body.theme-pizarra {
  background-image:
    linear-gradient(var(--theme-border) 1px, transparent 1px),
    linear-gradient(90deg, var(--theme-border) 1px, transparent 1px);
  background-size: 24px 24px, 24px 24px;
  background-position: -1px -1px;
}


h1, h2, h3, h4, h5, h6 {
  font-family: var(--theme-font-heading);
  color: var(--theme-ink);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

p { margin: 0 0 0.85rem; }

a {
  color: var(--theme-accent);
  text-decoration: none;
}
a:hover, a:focus { text-decoration: underline; }

code, pre, .mono { font-family: var(--theme-font-mono); }

::selection {
  background: var(--theme-accent);
  color: var(--theme-surface);
}

/* ----------------------------- Layout shell ----------------------------- */

.container {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

main.container {
  padding-top: var(--pad-lg);
  padding-bottom: var(--pad-xl);
  min-height: 60vh;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* -------------------------------- Header -------------------------------- */

/* El header es sticky (~70 px): sin esto, los saltos de ancla («Compara las
   3 tiendas ↓» de la ficha, #comprar y #mix de la lista…) alinean el destino
   con el borde superior de la ventana y el menú fijo se come el principio de
   la sección (12-ago-2026). Aplica a toda ancla y scrollIntoView del
   documento; 84 px = header + un poco de aire. */
html { scroll-padding-top: 84px; }

.site-header {
  background: var(--theme-surface);
  border-bottom: 1px solid var(--theme-border);
  position: sticky;
  top: 0;
  z-index: 20;
  /* Sin `backdrop-filter`: el fondo ya es opaco, así que el desenfoque no se
     veía y sólo añadía una capa de composición que el navegador rehace en
     cada scroll. */
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-top: 0.85rem;
  padding-bottom: 0.85rem;
  flex-wrap: wrap;
}

.site-header__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--theme-font-heading);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--theme-ink);
  letter-spacing: -0.01em;
}
.site-header__brand:hover, .site-header__brand:focus {
  text-decoration: none;
  color: var(--theme-ink);
}

.site-header__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--ui-radius-sm);
  background: var(--theme-accent-soft);
  font-size: 1.1rem;
}
.site-header__logo-mark { width: 1.35rem; height: 1.35rem; }
.site-footer__logo-mark { width: 1.3rem; height: 1.3rem; color: #fff; }

.site-header__brand-tagline {
  color: var(--theme-ink-muted);
  font-size: 0.78rem;
  font-weight: 400;
  font-family: var(--theme-font-body);
  letter-spacing: 0.01em;
}

.site-header__nav {
  display: none;
  gap: 1.1rem;
  margin-left: auto;
  font-size: 0.92rem;
  align-items: center;
}
.site-header__nav a {
  color: var(--theme-ink-soft);
  font-weight: 500;
}
.site-header__nav a:hover { color: var(--theme-accent); text-decoration: none; }
@media (min-width: 720px) { .site-header__nav { display: inline-flex; } }

/* ---- Menú hamburguesa (móvil < 720px). CSS-only por la CSP estricta: un
   checkbox oculto controla el desplegable; el <label> es el botón. ---- */
.site-header__nav-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.site-header__burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  width: 2.6rem;
  height: 2.6rem;
  flex: none;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface);
  color: var(--theme-ink);
  cursor: pointer;
}
.site-header__burger:hover { border-color: var(--theme-accent); color: var(--theme-accent); }
.site-header__burger-icon { width: 1.4rem; height: 1.4rem; }
.site-header__burger-icon--close { display: none; }
.site-header__nav-toggle:checked ~ .site-header__burger .site-header__burger-icon--open { display: none; }
.site-header__nav-toggle:checked ~ .site-header__burger .site-header__burger-icon--close { display: inline; }
/* Panel desplegable a todo el ancho, justo bajo la cabecera (sticky = posicionada). */
.site-header__nav-toggle:checked ~ .site-header__nav {
  display: flex;
  flex-direction: column;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  gap: 0.1rem;
  padding: 0.5rem 1rem 0.9rem;
  background: var(--theme-surface);
  border-bottom: 1px solid var(--theme-border);
  box-shadow: 0 14px 22px rgba(31, 27, 46, 0.12);
}
.site-header__nav-toggle:checked ~ .site-header__nav a { padding: 0.65rem 0.5rem; border-radius: var(--ui-radius-sm); }
.site-header__nav-toggle:checked ~ .site-header__nav a:hover { background: var(--theme-accent-soft); }
@media (min-width: 720px) {
  .site-header__burger { display: none; }
  /* En escritorio el nav vuelve a su sitio aunque el checkbox quedara marcado. */
  .site-header__nav-toggle:checked ~ .site-header__nav {
    position: static; flex-direction: row; padding: 0; gap: 1.1rem;
    background: none; border: 0; box-shadow: none;
  }
}

/* CTA "Comparar lista": único llamado a la acción del header. En móvil queda
   pegado a la derecha (la marca a la izquierda); en >=720px va tras el nav. */
.site-header__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
  padding: 0.5rem 1rem;
  border-radius: var(--ui-radius-cta);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font-family: var(--theme-font-body);
  font-weight: 600;
  font-size: 0.9rem;
  white-space: nowrap;
  line-height: 1.3;
}
.site-header__cta:hover, .site-header__cta:focus {
  filter: brightness(0.93);
  color: var(--theme-surface);
  text-decoration: none;
}
.site-header__cta svg { width: 1rem; height: 1rem; }
@media (min-width: 720px) { .site-header__cta { margin-left: 0.75rem; } }

/* MÓVIL: la cabecera en UNA fila. Con `flex-wrap: wrap` y el rótulo del CTA
   visible, marca (183 px) + hamburguesa (42) + CTA (209) + huecos (32) pedían
   466 px sobre los ~260 útiles de un móvil de 320-390 px, así que el CTA saltaba
   a una segunda fila y la cabecera —que es `sticky`— se comía 126 px de alto
   medidos en producción. Sin el rótulo baja a 59 px. `nowrap` es deliberado: con
   `wrap` el navegador prefiere partir la fila antes que encoger la marca. */
@media (max-width: 719px) {
  .site-header__inner {
    flex-wrap: nowrap;
    gap: 0.5rem;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
  }
  /* `min-width: 0` para que la marca sí pueda encoger: por defecto un item flex
     no baja de su ancho de contenido y sería ella la que fuerza el desbordamiento. */
  .site-header__brand { font-size: 1rem; min-width: 0; flex: 0 1 auto; }
  .site-header__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .site-header__logo { width: 1.75rem; height: 1.75rem; flex: none; }
  .site-header__cta { margin-left: auto; padding: 0.5rem 0.65rem; gap: 0.3rem; flex: none; }
  .site-header__cta-label { display: none; }
  .site-header__burger { width: 2.4rem; height: 2.4rem; margin-left: 0; }
}
/* Por debajo de 380 px (iPhone SE y compañía) sólo el logotipo: «ComparaLi…»
   cortado a media palabra se lee peor que no poner el nombre, y el logo ya
   enlaza a la home con su `aria-label`. */
@media (max-width: 379px) {
  .site-header__name { display: none; }
}
.site-header__cta-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.35rem;
  height: 1.35rem;
  padding: 0 0.4rem;
  border-radius: var(--ui-radius-pill);
  background: rgba(255, 255, 255, 0.28);
  font-size: 0.8rem;
  font-weight: 800;
}

/* --------------------------------- Buttons ------------------------------ */

.button {
  padding: 0.55rem 1.1rem;
  border: 0;
  border-radius: var(--ui-radius-cta);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font-family: var(--theme-font-body);
  font-weight: 600;
  cursor: pointer;
  font-size: 0.95rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  text-align: center;
  line-height: 1.5;
  transition: filter 0.12s ease;
}
.button:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }

.button--ghost {
  background: transparent;
  color: var(--theme-ink);
  border: 1px solid var(--theme-border);
}
.button--ghost:hover { color: var(--theme-accent); border-color: var(--theme-accent); }

.button--soft {
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
}

.button--dark {
  background: var(--theme-ink);
  color: var(--theme-surface);
}

/* --------------------------------- Hero --------------------------------- */

.hero {
  position: relative;
  text-align: center;
  padding: clamp(2rem, 6vw, 3.75rem) 0 clamp(1.5rem, 4vw, 2.5rem);
}
.hero::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0.5rem;
  width: 56px;
  height: 4px;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  transform: translateX(-50%);
  opacity: 0.85;
}
body.theme-pizarra .hero::before { display: none; }

.hero__eyebrow {
  display: inline-block;
  margin: 0 0 0.75rem;
  padding: 0.2rem 0.65rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.hero__title {
  font-family: var(--theme-font-heading);
  font-size: clamp(2rem, 5.2vw, 3.4rem);
  margin: 0 0 0.85rem;
  line-height: 1.05;
  letter-spacing: -0.025em;
}
.hero__title strong { color: var(--theme-accent); font-weight: 700; }

.hero__lead {
  font-size: clamp(1rem, 1.6vw, 1.18rem);
  color: var(--theme-ink-soft);
  /* 720 y no 640: con 640 la entradilla caía en TRES líneas en escritorio y
     empujaba la caja de búsqueda 30 px hacia abajo. En dos líneas se lee mejor
     y el ancho sigue por debajo del límite de legibilidad (~75 caracteres). */
  max-width: 720px;
  margin: 0 auto 1.4rem;
}

/* Píldora «gratis» del hero. Iba como última frase de la entradilla y ahí no la
   leía nadie: es la primera duda del que llega, así que sale del párrafo y se
   pinta con contraste invertido (superficie clara sobre la banda del hero) para
   que gane al texto que la rodea sin robarle el sitio al comparador. */
.hero__free {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.15rem 0.45rem;
  margin: 0 auto;
  padding: 0.45rem 1.05rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  border: 1px solid color-mix(in srgb, var(--theme-accent) 35%, var(--theme-border));
  box-shadow: var(--ui-shadow-sm);
  color: var(--theme-ink);
  font-size: 0.95rem;
  line-height: 1.35;
}
.hero__free strong {
  color: var(--theme-accent);
  font-weight: 800;
  letter-spacing: 0.01em;
}
.hero__free-icon {
  width: 1.05rem;
  height: 1.05rem;
  color: var(--theme-accent);
  flex-shrink: 0;
}

.hero__search {
  display: flex;
  gap: 0.5rem;
  max-width: 660px;
  margin: 0 auto;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 0.4rem;
  box-shadow: var(--theme-shadow);
}

.hero__search input {
  flex: 1;
  padding: 0.85rem 1rem;
  border: 0;
  border-radius: var(--ui-radius-sm);
  font: inherit;
  font-size: 1rem;
  background: transparent;
  color: var(--theme-ink);
}
.hero__search input:focus { outline: none; }

.hero__search button {
  padding: 0.85rem 1.4rem;
  border: 0;
  border-radius: var(--ui-radius-cta);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font: inherit;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
}
.hero__search button:hover { filter: brightness(0.93); }

.hero__hint {
  margin: 0.85rem auto 0;
  color: var(--theme-ink-muted);
  font-size: 0.85rem;
  max-width: 660px;
}
.hero__hint a { color: var(--theme-ink-soft); border-bottom: 1px dashed currentColor; }

/* ------------------- Enlazado interno por categorías -------------------- */
/* Nubes de chips en la home (curso / asignatura / editorial) y cabeceras de
   los hubs (/cursos, /asignaturas, /editoriales). Comparten .category-cloud
   y .category-chip para un look consistente. */

.home-categories {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
  padding: 0.5rem 0 2.5rem;
}

.home-categories__group {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.35rem 1.5rem 1.6rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-sm);
}

.home-categories__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.home-categories__title {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: clamp(1.1rem, 1.8vw, 1.3rem);
  font-weight: 700;
}

.home-categories__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  flex: none;
  border-radius: var(--ui-radius-md);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
}
.home-categories__icon svg { width: 1.1rem; height: 1.1rem; }

.home-categories__all {
  font-weight: 600;
  white-space: nowrap;
  color: var(--theme-accent);
}

.category-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
}

/* --- Cursos agrupados por etapa (home) --------------------------------- */
/* Cada etapa lleva su color para escanearse de un vistazo («busco 3º dentro
   del bloque Primaria»). MISMA paleta que las .stage-card del hub /cursos:
   un color por etapa en toda la web. Como esos tonos son de filete decorativo
   y no dan AA de texto pequeño, el texto usa --stage-ink (el tono oscurecido)
   y el color puro queda para bordes, fondos tintados y rellenos de hover.
   OJO: NO llamar a esto .stage-card — esa clase es del hub /cursos. */

.home-categories__group--courses {
  background: linear-gradient(160deg, var(--theme-accent-soft), var(--theme-surface-alt) 60%);
  border-color: color-mix(in srgb, var(--theme-accent) 20%, var(--theme-border));
}

.home-stages {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.75rem;
}
/* Las etapas se reparten el ancho entero de la tarjeta (14-ago-2026): con los
   anchos naturales la fila terminaba a media caja y el hueco de la derecha
   parecía un bloque a medio cargar. `flex-grow` con base `auto` reparte SOLO el
   sobrante a partes iguales, así que Primaria (seis cursos) sigue siendo la más
   ancha y FP la más estrecha; no las iguala. */
.home-stages > * { flex: 1 1 auto; }

.home-stage {
  --stage-color: var(--theme-accent);
  --stage-ink: color-mix(in srgb, var(--stage-color) 65%, var(--theme-ink));
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.85rem;
  border: 1px solid color-mix(in srgb, var(--stage-color) 35%, transparent);
  border-radius: var(--ui-radius-md);
  background: linear-gradient(135deg, color-mix(in srgb, var(--stage-color) 11%, #fff), color-mix(in srgb, var(--stage-color) 3%, #fff));
  box-shadow: var(--ui-shadow-sm);
}

.home-stage[data-stage='infantil'] { --stage-color: #E0763F; }
.home-stage[data-stage='primaria'] { --stage-color: var(--theme-success); }
.home-stage[data-stage='eso'] { --stage-color: var(--theme-accent); }
.home-stage[data-stage='bachillerato'] { --stage-color: #6D4AC8; }
.home-stage[data-stage='fp'] { --stage-color: #B8811C; }
.home-stage[data-stage='universidad'] { --stage-color: #0E7490; }

.home-stage__label {
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--stage-ink);
  white-space: nowrap;
}

.home-stage__years {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.home-stage__year {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.2rem;
  height: 2.2rem;
  padding: 0 0.5rem;
  border: 1px solid color-mix(in srgb, var(--stage-color) 45%, transparent);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  color: var(--stage-ink);
  font-size: 0.94rem;
  font-weight: 700;
  line-height: 1;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.home-stage__year:hover,
.home-stage__year:focus-visible {
  background: var(--stage-ink);
  border-color: var(--stage-ink);
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--stage-color) 35%, transparent);
}

/* Etapas de un solo curso (Infantil, FP, Universidad): la tarjeta es el enlace. */
a.home-stage {
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease, background-color 0.15s ease;
}
a.home-stage:hover,
a.home-stage:focus-visible {
  border-color: var(--stage-color);
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--stage-color) 30%, transparent);
}

/* Categorías agrupadas bajo epígrafes en /categorias (auditoría de
   categorización 11-ago-2026). */
.category-groups {
  display: flex;
  flex-direction: column;
  gap: 1.85rem;
}
.category-group__title {
  margin: 0 0 0.85rem;
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--theme-ink, var(--theme-ink));
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--theme-border, var(--theme-border));
}
.category-chip__count {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--theme-ink-muted, #94a3b8);
  font-variant-numeric: tabular-nums;
}
.category-chip:hover .category-chip__count,
.category-chip:focus-visible .category-chip__count { color: inherit; }

.category-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem 0.5rem 0.95rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.2;
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.category-chip:hover,
.category-chip:focus-visible {
  border-color: var(--theme-accent);
  color: var(--theme-accent);
  background: var(--theme-accent-soft);
  text-decoration: none;
  box-shadow: 0 3px 10px color-mix(in srgb, var(--theme-accent) 18%, transparent);
  transform: translateY(-1px);
}

/* Marcas de texto en /editoriales: primeras del listado y marcadas — son lo
   que se viene a buscar a ese hub. */
.category-chip--brand {
  border-color: color-mix(in srgb, var(--theme-accent) 45%, transparent);
  background: var(--theme-accent-soft);
  font-weight: 600;
}

/* Buscador de editoriales del hub (formulario GET, sin JS: CSP-safe). */
.hub-search {
  display: flex;
  gap: 0.5rem;
  max-width: 560px;
  margin: 0.25rem 0 1rem;
}

.hub-search__input {
  flex: 1;
  min-width: 0;
  padding: 0.6rem 1rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font: inherit;
  font-size: 0.95rem;
}
.hub-search__input:focus {
  outline: 2px solid color-mix(in srgb, var(--theme-accent) 55%, transparent);
  outline-offset: 1px;
  border-color: var(--theme-accent);
}

.hub-search__btn {
  padding: 0.6rem 1.25rem;
  border: none;
  border-radius: var(--ui-radius-cta, var(--ui-radius-pill));
  background: var(--theme-accent);
  color: #fff;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.15s ease, transform 0.15s ease;
}
.hub-search__btn:hover { filter: brightness(1.08); transform: translateY(-1px); }

.hub-search__status {
  margin: -0.4rem 0 1rem;
  font-size: 0.92rem;
  color: var(--theme-ink-soft);
}

.category-chip__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6rem;
  height: 1.45rem;
  padding: 0 0.45rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
  font-size: 0.74rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.category-chip:hover .category-chip__count,
.category-chip:focus-visible .category-chip__count {
  background: var(--theme-accent);
  color: #fff;
}

/* ---- Barra del listado: recuento a la izquierda, orden a la derecha. ----
   Existe aquí y no en comparalibros porque allí las colecciones no se ordenan
   (una lista de curso trae su propio orden). En juguetes «de más barato a más
   caro» es lo primero que se busca en un listado. */
.collection-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1rem;
  margin: 0 0 1.1rem;
}
.collection-toolbar__count {
  margin: 0;
  color: var(--theme-ink-muted);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}
.collection-sort { display: flex; align-items: center; gap: 0.5rem; }
.collection-sort select {
  appearance: none;
  padding: 0.5rem 2.1rem 0.5rem 0.9rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background-color: var(--theme-surface);
  /* La flecha son dos gradientes y no un SVG: una petición menos, y sin fichero
     externo que se olvide de seguir al tema. */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--theme-ink-muted) 50%),
    linear-gradient(135deg, var(--theme-ink-muted) 50%, transparent 50%);
  background-position: calc(100% - 1.05rem) 55%, calc(100% - 0.75rem) 55%;
  background-size: 0.32rem 0.32rem, 0.32rem 0.32rem;
  background-repeat: no-repeat;
  color: var(--theme-ink);
  font-size: 0.9rem;
  cursor: pointer;
}
.collection-sort select:hover { border-color: var(--theme-accent); }
.collection-sort__submit {
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  cursor: pointer;
}

/* Subsecciones de una categoría (/categoria/ocio-y-deporte → Deportes, Juegos…).
   No tenían NI UNA regla propia: la nube de chips caía pegada a la barra de
   filtros y se leía como parte de ella. Son cosas distintas y conviene que se
   note —estas NAVEGAN a otra categoría, los filtros ACOTAN la página actual—,
   así que van en su propia caja, con rótulo y con aire por debajo. */
.collection-subcats {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin: 0.75rem 0 1.9rem;
  padding: 1.2rem 1.4rem 1.35rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
}

.collection-subcats__heading {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--theme-ink-soft);
}

/* El chip base lleva el padding derecho corto porque se diseñó con la burbuja
   del recuento pegada al borde. Aquí no hay recuento —decisión de Rafael el
   10-ago-2026—, así que se equilibra o los nombres quedan descentrados. */
.collection-subcats .category-chip {
  padding: 0.5rem 0.95rem;
  background: var(--theme-surface);
}

@media (max-width: 640px) {
  .collection-subcats {
    padding: 1rem 1rem 1.15rem;
    margin-bottom: 1.5rem;
  }
}

/* ------------------------------- Hubs ----------------------------------- */
/* Páginas índice de taxonomía (/cursos, /asignaturas, /editoriales). */

.hub {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
  padding: 0.5rem 0 2.5rem;
}

.hub__intro {
  /* A todo el ancho del contenedor. El tope de 68ch es la medida cómoda para
     leer PÁRRAFOS seguidos, y aquí es una entradilla de tres líneas sobre una
     página que debajo ya usa el ancho entero: la restricción sólo servía para
     dejar medio contenedor en blanco. El texto largo de más abajo
     (`.collection-seo-body`) conserva el suyo, que ahí sí hace falta. */
  color: var(--theme-ink-soft);
  font-size: 1.05rem;
  line-height: 1.6;
}

.hub__intro h1 {
  margin: 0 0 0.5rem;
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  color: var(--theme-ink);
}

.hub__intro p { margin: 0; }

.hub__group {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

/* --------------------- Prosa SEO de colección/hub ----------------------- */
/* Bloque de texto largo (descripciones generadas) con ancho de lectura
   cómodo. Estiliza los hijos directos para no exigir clases por nodo. */

.collection-seo-body {
  max-width: none;
  color: var(--theme-ink-soft);
  line-height: 1.7;
  font-size: 1rem;
}

.collection-seo-body > * + * { margin-top: 0.9rem; }

.collection-seo-body h2 {
  margin: 1.6rem 0 0.6rem;
  font-size: clamp(1.2rem, 2.2vw, 1.5rem);
  color: var(--theme-ink);
}

.collection-seo-body h2:first-child { margin-top: 0; }

.collection-seo-body p { margin: 0; }

.collection-seo-body ul {
  margin: 0;
  padding-left: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.collection-seo-body li { padding-left: 0.15rem; }

.collection-seo-body a {
  color: var(--theme-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.collection-seo-body a:hover { text-decoration: none; }

.features {
  padding: 1.5rem 0 2.5rem;
}

.features__title {
  font-size: clamp(1.4rem, 2.5vw, 1.75rem);
  margin: 0 0 1.25rem;
  text-align: center;
}

.features__grid {
  list-style: none;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin: 0;
  padding: 0;
}

.features__item {
  position: relative;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 1.25rem 1.25rem 1.4rem;
  box-shadow: var(--theme-shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.features__item:hover {
  transform: translateY(-2px);
  box-shadow: var(--theme-shadow);
  border-color: color-mix(in srgb, var(--theme-accent) 35%, var(--theme-border));
}

.features__item h3 {
  margin: 0;
  font-size: 1.08rem;
}

.features__item p {
  margin: 0;
  color: var(--theme-ink-soft);
  font-size: 0.95rem;
}

.features__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--ui-radius-sm);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
  font-size: 1.15rem;
  margin-bottom: 0.25rem;
}

/* ------------------------------ How it works ---------------------------- */

/* Sin tarjeta (14-ago-2026). El fondo de la página y el de esta sección eran el
   MISMO blanco puro, así que el relleno no separaba nada y toda la caja la
   dibujaba un filete de 0,67 px: un recuadro que no encierra nada distinto es
   ruido, y con la banda de cifras justo debajo eran dos seguidos y la home
   parecía un formulario. Las secciones se separan por aire, como ya hacían la
   franja de librerías y las categorías. */
.how-it-works {
  /* Más aire abajo que arriba: sin el marco de la tarjeta, el botón «Ver cómo
     funciona en detalle» quedaba pegado a la banda de cifras y las dos
     secciones se leían como una. Los márgenes verticales contiguos colapsan al
     mayor, así que este 4,5rem es el hueco real entre ambas. */
  margin: 2.75rem 0 4.5rem;
  padding: 0;
}
.how-it-works h2 { margin: 0 0 1.25rem; font-size: 1.35rem; }
.how-it-works__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* Más aire entre pasos: con 1,25rem y tres columnas de texto el bloque se
     leía como un párrafo partido en tres, no como tres pasos. */
  gap: 1.9rem 2.1rem;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.how-it-works__step {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}
/* Disco con el icono del paso; el número queda de chapa encima, encadenando el
   orden sin robarle el sitio al icono. */
.how-it-works__badge {
  position: relative;
  flex: 0 0 3rem;
  height: 3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
}
.how-it-works__icon { width: 1.55rem; height: 1.55rem; }
/* Chapa del número, AL LADO DEL TÍTULO. Estuvo `position: absolute` mientras
   vivía encima del disco del icono; al mudarse dentro del <h3> se quedó
   colgando del contenedor de posicionamiento más cercano y los tres números se
   fueron al pie de la página, invisibles. Aquí va estática, como un hijo más
   del flex del título. */
.how-it-works__num {
  flex: none;
  width: 1.35rem;
  height: 1.35rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font-family: var(--theme-font-heading);
  font-weight: 700;
  font-size: 0.72rem;
  line-height: 1;
}
.how-it-works__step h3 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.3rem;
  font-size: 1rem;
}
.how-it-works__step p { margin: 0; color: var(--theme-ink-soft); font-size: 0.92rem; line-height: 1.55; }

/* --- Ilustración del paso: sólo de 720 px para arriba. En un móvil de 390 px
   subía el bloque de 664 a 927 px de alto (+40%) y empujaba el resto de la home
   justo donde el scroll pesa; ahí se queda el disco con el icono. --- */
.how-it-works .step-art { display: none; }
@media (min-width: 720px) {
  .how-it-works__step { flex-direction: column; align-items: flex-start; gap: 0.55rem; }
  .how-it-works .step-art { display: block; width: 128px; height: 96px; }
  .how-it-works__badge { display: none; }
}
/* Paleta de las ilustraciones por clases y no a fuego en el SVG: así siguen al
   preset del tema. Cada una declara primero el hex de reserva por si el
   navegador no soporta `color-mix`. */
.step-art { color: var(--theme-accent); }
.step-art .art-fill { fill: currentColor; }
.step-art .art-white { fill: #fff; }
.step-art .art-deep {
  fill: var(--ui-accent-strong);
  fill: color-mix(in srgb, currentColor 72%, #000);
}
.step-art .art-tint {
  fill: #fbd9cf;
  fill: color-mix(in srgb, currentColor 22%, #fff);
}
.step-art .art-tint2 {
  fill: color-mix(in srgb, var(--theme-accent) 38%, #fff);
  fill: color-mix(in srgb, currentColor 45%, #fff);
}
.step-art .art-on-fill { fill: rgba(255, 255, 255, 0.42); }
.step-art .art-paper {
  fill: #fff;
  stroke: var(--ui-accent-strong);
  stroke: color-mix(in srgb, currentColor 72%, #000);
  stroke-width: 2.5;
}
.step-art .art-ghost {
  fill: #fff;
  stroke: color-mix(in srgb, var(--theme-accent) 38%, #fff);
  stroke: color-mix(in srgb, currentColor 45%, #fff);
  stroke-width: 2.6;
}
.step-art .art-handle {
  fill: none;
  stroke: var(--ui-accent-strong);
  stroke: color-mix(in srgb, currentColor 72%, #000);
  stroke-width: 3.2;
  stroke-linecap: round;
}
.step-art .art-spine {
  stroke: color-mix(in srgb, var(--theme-accent) 38%, #fff);
  stroke: color-mix(in srgb, currentColor 45%, #fff);
  stroke-width: 2.2;
}
.step-art .art-tint-line {
  stroke: #fbd9cf;
  stroke: color-mix(in srgb, currentColor 22%, #fff);
  stroke-width: 2.2;
  stroke-linecap: round;
}
.step-art .art-ok {
  fill: var(--theme-success, var(--theme-success));
  stroke: #fff;
  stroke-width: 3;
}
.step-art .art-coin { fill: #F2A93B; stroke: #fff; stroke-width: 3; }
/* Puntero del paso «eliges tú»: relleno oscuro y filo blanco para que se
   recorte sobre la etiqueta azul que está señalando. */
.step-art .art-cursor {
  fill: var(--ui-accent-strong);
  fill: color-mix(in srgb, currentColor 72%, #000);
  stroke: #fff;
  stroke-width: 2.2;
  stroke-linejoin: round;
}
.step-art .art-deep-line {
  fill: none;
  stroke: var(--ui-accent-strong);
  stroke: color-mix(in srgb, currentColor 72%, #000);
}
.step-art .art-white-line {
  fill: none;
  stroke: #fff;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ----------------------------- Book detail ------------------------------ */

.book-detail__header {
  display: grid;
  gap: 1.75rem;
  grid-template-columns: 1fr;
  margin-bottom: 1.5rem;
  padding: 1.5rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--theme-shadow-sm);
}
@media (min-width: 720px) {
  .book-detail__header {
    grid-template-columns: 300px 1fr;
    padding: 2rem;
  }
}

.book-detail__cover {
  position: relative;
  min-width: 0;
}
/* min-width:0 deja que las columnas del grid encojan: sin esto, la fila de
   chips (que no envuelve) ensancha la columna y desborda la ficha en móvil,
   empujando la portada fuera del viewport. */
.book-detail__meta {
  min-width: 0;
}
.book-detail__cover img {
  width: 100%;
  max-width: 300px;
  height: auto;
  /* Reserve the box before the remote Amazon cover loads — without a fixed
     ratio the browser can't, and the LCP image shifts title/price/offers down
     on load (CLS). Matches the fallback's 2/3 below. */
  aspect-ratio: 2 / 3;
  object-fit: contain;
  border-radius: var(--ui-radius-sm);
  box-shadow: var(--theme-shadow);
  display: block;
  background: var(--theme-bg);
}
.book-detail__cover::after {
  content: "";
  position: absolute;
  inset: -6px;
  border: 1px dashed var(--theme-border);
  border-radius: calc(var(--ui-radius-sm) + 6px);
  pointer-events: none;
  opacity: 0.5;
}
body.theme-pizarra .book-detail__cover::after { display: none; }

.book-detail__cover-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 2 / 3;
  width: 100%;
  max-width: 300px;
  font-size: 3.5rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  color: var(--theme-ink-muted);
}

.book-detail__title {
  font-size: clamp(1.55rem, 3.2vw, 2.15rem);
  margin: 0 0 0.3rem;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

/* ISBN destacado bajo el título: es el dato con el que se identifica el libro
   (las listas del colegio vienen en ISBN). Antes era un chip apagado al final de
   una fila con scroll horizontal. `user-select: all` para poder copiarlo de un
   clic sin necesitar JS, que la CSP no permitiría inline. */
.book-detail__isbn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.7rem;
  padding: 0.3rem 0.7rem 0.3rem 0.55rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
}
.book-detail__isbn-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--theme-accent);
}
.book-detail__isbn-value {
  font-family: var(--theme-font-mono);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--theme-ink);
  user-select: all;
}

.book-detail__subtitle {
  color: var(--theme-ink-soft);
  margin: 0 0 0.75rem;
  font-size: 1.05rem;
}

/* Precio ganador en el hero (auditoría UX 11-ago-2026): el dato nº 1 de quien
   llega de un anuncio, visible sin scroll también en móvil, donde el rail de
   compra queda por debajo del primer viewport. Enlaza a la comparativa. */
.book-detail__from {
  margin: 0.15rem 0 0.7rem;
}
.book-detail__from a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  text-decoration: none;
  color: inherit;
}
.book-detail__from-label {
  font-size: 0.95rem;
  color: var(--theme-ink-soft, var(--theme-ink-soft));
}
.book-detail__from-price {
  font-size: 1.9rem;
  font-weight: 800;
  color: var(--theme-accent, var(--theme-accent));
}
.book-detail__from-extra {
  font-size: 0.92rem;
  color: var(--theme-ink-soft, var(--theme-ink-soft));
}
/* El «Compara las N tiendas» tiene que LEERSE como enlace (feedback de Rafael,
   11-ago-2026): color de acento y subrayado siempre, no solo en hover. */
.book-detail__from-cta {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--theme-accent, var(--theme-accent));
  text-decoration: underline;
  text-underline-offset: 3px;
}
.book-detail__from a:hover .book-detail__from-cta { text-decoration-thickness: 2px; }

.book-detail__authors {
  margin: 0 0 0.5rem;
  color: var(--theme-ink-soft);
  font-size: 0.98rem;
}

.book-detail__publisher {
  margin: 0 0 1rem;
  font-size: 0.92rem;
}
.book-detail__publisher a {
  color: var(--theme-ink-soft);
  font-weight: 600;
  border-bottom: 1px solid transparent;
}
.book-detail__publisher a:hover { color: var(--theme-accent); border-bottom-color: currentColor; text-decoration: none; }

.book-chips {
  list-style: none;
  display: flex;
  flex-wrap: nowrap;
  gap: 0.4rem;
  margin: 0 0 1.25rem;
  padding: 0 0 0.15rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.book-chips::-webkit-scrollbar { display: none; }
.book-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.28rem 0.65rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--theme-ink-soft);
  white-space: nowrap;
}
.book-chip--isbn {
  font-family: var(--theme-font-mono);
  font-weight: 500;
  color: var(--theme-ink-muted);
}

/* --------------------------------- Offers ------------------------------- */

.offers {
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--theme-shadow-sm);
}

.offers__title {
  margin: 0 0 1.1rem;
  font-size: 1.25rem;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}
.offers__title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--theme-border);
  margin-left: 0.4rem;
}

.offers__empty {
  color: var(--theme-ink-soft);
  margin: 0;
  padding: 1.5rem;
  background: var(--theme-bg);
  border-radius: var(--ui-radius-sm);
  border: 1px dashed var(--theme-border);
  text-align: center;
}

/* Aviso de ahorro.
   Primera version: recuadro verde con emoji de saco de dinero y la cifra
   enterrada en una frase. Leia a publicidad.
   Segunda: la cifra suelta sobre una barra lateral, sin fondo. Peor: «3,60 EUR»
   flotando bajo el titulo se lee como si fuera un precio hasta que llegas a la
   linea de abajo, o sea que el dato no se entendia solo.
   Esta: el fondo vuelve —agrupa las tres piezas y las separa de la tabla— y la
   etiqueta va ARRIBA, para que se sepa que es el numero antes de leerlo. */
.offers__savings {
  margin: 0 0 1.1rem;
  padding: 0.7rem 0.95rem;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "tag  tag"
    "cifra texto";
  align-items: baseline;
  column-gap: 0.6rem;
  row-gap: 0.15rem;
  background: color-mix(in srgb, var(--theme-success) 8%, #fff);
  border: 1px solid color-mix(in srgb, var(--theme-success) 22%, transparent);
  border-left: 3px solid var(--theme-success);
  border-radius: var(--ui-radius-sm);
}
.offers__savings-tag {
  grid-area: tag;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--theme-success) 70%, #000 30%);
}
.offers__savings-figure {
  grid-area: cifra;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.1;
  color: color-mix(in srgb, var(--theme-success) 78%, #000 22%);
  font-variant-numeric: tabular-nums;
}
.offers__savings-label {
  grid-area: texto;
  font-size: 0.85rem;
  color: var(--theme-muted, var(--theme-ink-soft));
}
/* En pantallas estrechas la explicacion no cabe al lado de la cifra sin partirse
   en tres lineas raquiticas: pasa debajo. */
@media (max-width: 520px) {
  .offers__savings {
    grid-template-columns: 1fr;
    grid-template-areas: "tag" "cifra" "texto";
  }
}

.offers__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.offer {
  display: grid;
  gap: 0.5rem 1rem;
  grid-template-columns: 1fr;
  padding: 1.4rem 1.6rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-bg);
  align-items: center;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  /* Toda la tarjeta lleva a la tienda: la navegación la delega row-link.js al
     botón real (el stretched-link con ::after bloqueaba seleccionar texto y
     dejaba zonas muertas según el apilamiento del tema). El cursor avisa. */
  cursor: pointer;
}
.offer:hover {
  border-color: color-mix(in srgb, var(--theme-accent) 35%, var(--theme-border));
  box-shadow: var(--ui-shadow-sm);
}

@media (min-width: 640px) {
  .offer {
    /* La ultima columna es la del boton de compra. Se ensancha de 16,5 a 21 rem
       porque es el elemento que genera el ingreso y porque a 16,5 los nombres
       largos ("Comprar en El Corte Ingles") partian en dos lineas, que es
       justo lo que hace que un CTA se lea como apretado. */
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.9fr) minmax(0, 0.95fr) 21rem;
    align-items: center;
  }
}
/* Móvil (<640px): compacta cada oferta — librería arriba a todo el ancho,
   precio y total en dos columnas, y el botón de comprar a todo el ancho. Y
   centramos la portada, que en una sola columna quedaba descolgada. */
@media (max-width: 639px) {
  /* Precio a la izquierda y TOTAL alineado al borde derecho, centrados entre
   * sí en vertical: el layout 1fr/1fr con align start dejaba el precio
   * flotando arriba y el total descolgado hacia el centro (12-ago-2026). */
  .offer { grid-template-columns: 1fr auto; align-items: center; }
  .offer__merchant { grid-column: 1 / -1; }
  .offer__totals { justify-self: end; align-items: flex-end; text-align: right; }
  .offer__cta { grid-column: 1 / -1; }
  .offer__button { display: flex; justify-content: center; }
  .book-detail__cover { display: flex; justify-content: center; }
}

.offer--best {
  /* Realce sobrio, no un contorno de color. Antes llevaba borde de acento +
     fondo + un anillo de 3px, y el tema `planeta` anadia OTRO anillo encima: dos
     halos azules sobre fondo azul, que es lo que hacia que la fila ganadora
     pareciera un aviso de error en vez de una recomendacion.
     Ahora: filete de acento en el borde izquierdo —que marca la fila sin rodear
     nada—, un tinte de fondo muy leve y una sombra suave que la levanta del
     resto. El resto del borde se queda neutro como en las demas filas. */
  border-color: var(--theme-border);
  border-left: 3px solid var(--theme-accent);
  background: color-mix(in srgb, var(--theme-accent-soft) 55%, var(--theme-surface));
  box-shadow: 0 2px 10px color-mix(in srgb, var(--theme-accent) 10%, transparent);
}

.offer__merchant {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
}

.offer__swatch {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: var(--ui-radius-sm);
  display: inline-block;
  border: 1px solid color-mix(in srgb, currentColor 15%, transparent);
}
.offer__logo {
  width: 1.5rem;
  height: 1.5rem;
  object-fit: contain;
  border-radius: var(--ui-radius-sm);
  flex: none;
}

.offer__merchant-name {
  font-weight: 600;
  font-size: 0.98rem;
}

.offer__badge {
  background: var(--theme-accent);
  color: var(--theme-surface);
  border-radius: var(--ui-radius-pill);
  padding: 0.15rem 0.7rem;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.offer__pricing {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.offer__price {
  font-size: 1.05rem;
  /* Montserrat 800, igual que el rail de compra: el precio es el dato por el que
     la gente entra, y en monoespaciada quedaba mas apagado que el resto de la
     tarjeta. `tabular-nums` mantiene las cifras alineadas entre filas, que era
     lo unico que aportaba la monoespaciada. */
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-family: var(--theme-font-heading);
  letter-spacing: -0.01em;
}

.offer__price-original {
  text-decoration: line-through;
  color: var(--theme-ink-muted);
  font-size: 0.85rem;
  font-family: var(--theme-font-heading);
}

.offer__shipping {
  font-size: 0.82rem;
  color: var(--theme-ink-muted);
}

.offer__totals {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.offer__total-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--theme-ink-muted);
}

.offer__total {
  font-size: 1.3rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--theme-ink);
  font-family: var(--theme-font-heading);
  letter-spacing: -0.02em;
}

.offer__delta {
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--theme-danger);
  font-family: var(--theme-font-heading);
}
.offer__delta--best { color: var(--theme-success); }

.offer__delivery {
  font-size: 0.78rem;
  color: var(--theme-ink-muted);
}

.offer__cta {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
}

.offer__button {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  /* Altura mínima generosa + padding vertical pequeño: así el `min-height`
     domina y TODOS los botones miden lo mismo, tanto si el nombre cabe en una
     línea como si se ajusta a dos ("Casa del Libro"). */
  padding: 0.7rem 1.1rem;
  min-height: 3.9rem;
  /* El color de marca del comercio llega por `style` inline (merchantColorHex);
     este `background` es el respaldo si el comercio no tiene color. */
  background: var(--theme-accent);
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.22);
  border-radius: var(--ui-radius-cta);
  font-weight: 700;
  text-align: center;
  /* Sin `nowrap`: si el nombre del comercio es largo ("Casa del Libro") el
     texto se ajusta a dos líneas en vez de desbordar el botón/columna. */
  line-height: 1.2;
  /* Sube de 0,94 a 1,02 rem: es el unico texto de la fila que tiene que ganar
     al precio en jerarquia visual. Con la columna a 21 rem el nombre mas largo
     entra en una linea, asi que el ajuste a dos queda solo de red de seguridad. */
  font-size: 1.02rem;
  letter-spacing: -0.01em;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.14);
  transition: transform 0.12s ease, filter 0.12s ease, box-shadow 0.12s ease;
}
.offer__button-logo {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border-radius: 50%;
  background: #fff;
  padding: 2px;
  object-fit: contain;
}
.offer__button:hover, .offer__button:focus {
  filter: brightness(0.95);
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 5px 14px rgba(0, 0, 0, 0.2);
}

.offer__condition {
  font-size: 0.72rem;
  color: var(--theme-ink-muted);
  text-align: center;
}

.offers__disclaimer {
  margin: 1.1rem 0 0;
  color: var(--theme-ink-muted);
  font-size: 0.82rem;
}

/* ---------------------------- Book description -------------------------- */

.book-description {
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--theme-shadow-sm);
}
.book-description h2 { margin: 0 0 0.75rem; font-size: 1.2rem; }
.book-description p { margin: 0 0 0.85rem; color: var(--theme-ink-soft); }

/* ------------------------------ Breadcrumbs ----------------------------- */

.breadcrumbs { margin: 0 0 1rem; }
.breadcrumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.4rem;
  margin: 0;
  padding: 0;
  font-size: 0.84rem;
  color: var(--theme-ink-muted);
}
.breadcrumbs li { display: inline-flex; align-items: center; gap: 0.4rem; min-width: 0; }
.breadcrumbs a { color: var(--theme-ink-soft); }
.breadcrumbs a:hover { color: var(--theme-accent); text-decoration: none; }
.breadcrumbs__sep { color: var(--theme-ink-muted); }
.breadcrumbs [aria-current="page"] {
  color: var(--theme-ink-muted);
  max-width: 22rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ----------------------------- Ficha técnica ---------------------------- */

.book-specs {
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--theme-shadow-sm);
}
.book-specs__title { margin: 0 0 1rem; font-size: 1.2rem; }
.book-specs__grid {
  display: grid;
  gap: 0.85rem 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin: 0;
}
.book-specs__grid > div { display: flex; flex-direction: column; }
.book-specs__grid dt {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--theme-ink-muted);
  margin: 0;
  font-weight: 500;
}
.book-specs__grid dd {
  margin: 0.15rem 0 0;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--theme-ink);
}
.book-specs__grid dd a { color: var(--theme-accent); }
.book-specs__cat { grid-column: 1 / -1; }

/* --------------------- Cross-sell: comparar lista entera ---------------- */

.cross-compare {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  justify-content: space-between;
  background: var(--theme-accent-soft);
  border: 1px solid color-mix(in srgb, var(--theme-accent) 22%, transparent);
  border-radius: var(--ui-radius-lg);
  padding: 1.1rem 1.4rem;
  margin-bottom: 1.5rem;
}
.cross-compare__text { color: var(--theme-ink-soft); font-size: 0.95rem; max-width: 46ch; }
.cross-compare__text strong { display: block; color: var(--theme-ink); font-size: 1.02rem; margin-bottom: 0.1rem; }
.cross-compare__cta {
  flex: none;
  padding: 0.65rem 1.2rem;
  background: var(--theme-accent);
  color: var(--theme-surface);
  border-radius: var(--ui-radius-pill);
  font-weight: 700;
  white-space: nowrap;
}
.cross-compare__cta:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }

/* Añadir a la comparativa (carrito de la ficha) */
.add-compare {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.85rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 1.1rem 1.4rem;
  margin-bottom: 1rem;
}
.add-compare__text { color: var(--theme-ink-soft); font-size: 0.95rem; }
.add-compare__text strong { display: block; color: var(--theme-ink); font-size: 1.02rem; margin-bottom: 0.1rem; }
.add-compare__form { flex: none; margin: 0; max-width: 100%; }
/* En móvil el rótulo «+ Añadir a la comparativa» pide más ancho del que queda
   dentro de la tarjeta (medido: 326 px de borde derecho en un viewport de 308),
   y con `align-items: flex-start` el formulario no encoge. A pantalla completa
   deja de salirse y de paso el CTA gana área táctil. */
@media (max-width: 719px) {
  .add-compare { padding: 1rem; }
  .add-compare__form { align-self: stretch; }
  .add-compare__btn { display: block; width: 100%; text-align: center; }
}
.add-compare__btn {
  padding: 0.65rem 1.3rem;
  background: var(--theme-accent);
  color: var(--theme-surface);
  border: 0;
  border-radius: var(--ui-radius-cta);
  font: inherit;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}
/* El CTA de «ya añadido» es un <a>, no un <button>: sin esto heredaba el
   subrayado y el color de enlace del layout y dejaba de parecer un boton. */
a.add-compare__btn { text-decoration: none; }
a.add-compare__btn:hover { text-decoration: none; }
.add-compare__hint {
  margin: 0.55rem 0 0;
  font-size: 0.85rem;
  color: var(--theme-ink-muted);
}
.add-compare__btn:hover { filter: brightness(0.93); }
.add-compare--ok .add-compare__btn { background: #16a34a; }

/* --------------------------- Related books ------------------------------ */

.related { margin: 0 0 1.5rem; }
.related__title {
  margin: 0 0 1rem;
  font-size: 1.25rem;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}
.related__title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--theme-border);
}
/* -- Carril de relacionados ------------------------------------------------
   8 tarjetas en el DOM, ~4 a la vista. Sin JS por la CSP: `overflow-x` +
   `scroll-snap`, que en movil se arrastra con el dedo de forma nativa y en
   escritorio se mueve con rueda horizontal, teclado o arrastre.

   El `padding` vertical NO es decorativo: el hover de `.book-card` levanta la
   tarjeta 3px y le pone sombra (el tema `planeta` la sube a -3px en :4059), y
   sin holgura el `overflow` recortaria las dos cosas.

   `overscroll-behavior-x: contain` evita que al llegar al final del carril el
   gesto siga y dispare el "atras" del navegador. */
.related__rail {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* `mandatory` y no `proximity`: con proximity el carril se queda a medio
     camino entre dos tarjetas y parece roto. Mandatory da el enganche seco de
     un swipe nativo. */
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding: 6px 4px 10px;
  margin: 0 -4px;
  /* La barra de scroll del sistema (gris, con sus flechitas en Windows) es lo
     que estropeaba la seccion. Se oculta en los tres motores. El carril NO
     queda sin salida: sigue enfocable por teclado, se arrastra con el dedo, y
     el trozo de la tarjeta siguiente es la senal de que hay mas.
     Coste en rendimiento: cero. Es scroll nativo, sin JS ni listeners. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.related__rail::-webkit-scrollbar { width: 0; height: 0; }
/* Quien haya pedido menos animacion no quiere el desplazamiento suave. */
@media (prefers-reduced-motion: reduce) {
  .related__rail { scroll-behavior: auto; }
}
.related__rail:focus-visible {
  outline: 2px solid var(--theme-accent);
  outline-offset: 3px;
  border-radius: var(--ui-radius-sm);
}
/* Especificidad 0,2,0: gana a `.book-grid` (0,1,0) sin depender del orden del
   fichero, que es donde nos hemos tropezado antes. */
.related__rail .book-grid--rail {
  display: flex;
  gap: 1rem;
}
.related__rail .book-grid--rail > * {
  /* 4 a la vista MENOS un pellizco, para que asome la quinta. Sin ese trozo
     visible nada indica que haya mas libros detras: con 4 exactas y la barra
     de scroll ya oculta, la seccion parecia terminada ahi. */
  flex: 0 0 calc((100% - 3rem) / 4 - 1.1rem);
  scroll-snap-align: start;
}
@media (max-width: 900px) {
  .related__rail .book-grid--rail > * { flex-basis: calc((100% - 1rem) / 2); }
}
@media (max-width: 560px) {
  /* 1,3 tarjetas: el trozo de la siguiente es lo que le dice al visitante que
     hay mas y que esto se desliza. Con 1 exacta parece que no hay nada detras. */
  .related__rail .book-grid--rail > * { flex-basis: 78%; }
}

/* -- Flechas del carril ----------------------------------------------------
   Las inyecta `rail-nav.js`; sin JS no existen y el carril se maneja igual con
   el dedo, la rueda o el teclado. `has-rail-nav` la pone el propio script, asi
   que si no se ejecuta no queda hueco reservado ni botones muertos. */
.related__viewport { position: relative; }

.rail-nav {
  position: absolute;
  top: calc(50% - 1.6rem); /* centrado sobre las portadas, no sobre el titulo */
  z-index: 2;
  width: 2.5rem;
  height: 2.5rem;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  border: 1px solid var(--theme-border);
  border-radius: 50%;
  background: var(--theme-surface, #fff);
  color: inherit;
  box-shadow: 0 2px 8px rgb(0 0 0 / 12%);
}
.has-rail-nav .rail-nav { display: flex; }
.rail-nav--prev { left: -0.6rem; }
.rail-nav--next { right: -0.6rem; }
.rail-nav:hover:not(:disabled) { background: var(--theme-surface-alt, #f4f4f4); }
.rail-nav:focus-visible {
  outline: 2px solid var(--theme-accent);
  outline-offset: 2px;
}
/* En el extremo se apaga en vez de desaparecer: si se va, el otro boton salta
   de sitio y el raton pierde el objetivo justo cuando mas se usa. */
.rail-nav:disabled { opacity: 0.35; cursor: default; }

/* La flecha, dibujada con dos bordes: un glifo tipografico cambia de forma y de
   peso entre sistemas y aqui hay que casar dos botones simetricos. */
.rail-nav span {
  width: 0.55rem;
  height: 0.55rem;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
}
.rail-nav--prev span { transform: rotate(-135deg); margin-left: 0.2rem; }
.rail-nav--next span { transform: rotate(45deg); margin-right: 0.2rem; }

/* En tactil sobran: ahi el gesto natural es arrastrar, y los botones tapan
   portada. Se ocultan por PUNTERO, no por ancho: un portatil tactil de 15"
   sigue teniendo raton. */
@media (hover: none) and (pointer: coarse) {
  .has-rail-nav .rail-nav { display: none; }
}

/* ------------------- Sticky buy bar (mobile only) ----------------------- */

.buybar { display: none; }
@media (max-width: 719px) {
  .buybar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom));
    background: var(--theme-surface);
    border-top: 1px solid var(--theme-border);
    box-shadow: 0 -6px 20px rgba(31, 27, 46, 0.12);
  }
  .buybar__info { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
  .buybar__label { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--theme-ink-muted); }
  .buybar__price {
    font-family: var(--theme-font-heading);
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    font-size: 1.2rem;
    color: var(--theme-accent);
  }
  .buybar__merchant { font-size: 0.74rem; color: var(--theme-ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Botón secundario «+ Lista» en la barra sticky: compacto (contorno, no
     relleno) para no competir con «Comprar», que es el ingreso. Empuja a
     «Comprar» al extremo con su propio margin-left:auto. */
  .buybar__add-form { display: contents; }
  .buybar__add {
    margin-left: auto;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.62rem 0.85rem;
    border: 1.5px solid var(--theme-accent);
    border-radius: var(--ui-radius-cta);
    background: transparent;
    color: var(--theme-accent);
    font: inherit;
    font-weight: 700;
    font-size: 0.9rem;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
  }
  .buybar__add span { font-size: 1.05em; line-height: 1; }
  .buybar__add--done { border-color: var(--theme-border); color: var(--theme-ink-muted); }
  /* Con el «+ Lista» presente, «Comprar» ya no necesita el margin-left:auto
     (lo aporta el botón de lista); si no hay lista, lo recupera él. */
  .buybar__add ~ .buybar__cta,
  .buybar__add-form ~ .buybar__cta { margin-left: 0.5rem; }
  .buybar__cta {
    margin-left: auto;
    /* Encoge y recorta con elipsis en vez de salirse. En `/lista` el rotulo es
       «Como comprar en <libreria>», y con `flex: none` una libreria de nombre
       largo lo llevaba a 321 px dentro de un viewport de 308 (medido en prod con
       Casa del Libro). El nombre no cabe siempre; salirse de la pantalla, nunca. */
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0.7rem 1.4rem;
    background: var(--theme-accent);
    color: var(--theme-surface);
    border-radius: var(--ui-radius-cta);
    font-weight: 700;
  }
  .buybar__cta:hover, .buybar__cta:focus { color: var(--theme-surface); text-decoration: none; }
  /* Hueco para que la barra fija no tape el último contenido del artículo. */
  .book-detail { padding-bottom: 4.5rem; }
}

/* ---------------------------- Status pages ------------------------------ */

.status-page {
  text-align: center;
  padding: 4rem 1rem;
}
.status-page__code {
  font-family: var(--theme-font-mono);
  font-size: 5rem;
  font-weight: 700;
  margin: 0;
  color: var(--theme-accent);
  letter-spacing: -0.04em;
  line-height: 1;
}
.status-page__title { margin: 0.5rem 0 0.75rem; font-size: 1.6rem; }
.status-page__message { color: var(--theme-ink-soft); max-width: 540px; margin: 0 auto 1.5rem; }
.status-page__actions { margin: 0; }

/* -------------------------------- Footer -------------------------------- */

.site-footer {
  background: var(--theme-surface);
  border-top: 1px solid var(--theme-border);
  margin-top: 3rem;
}

.site-footer__inner {
  padding: 2.5rem 1rem 2rem;
  display: grid;
  gap: 1.75rem 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .site-footer__inner { grid-template-columns: 1fr 1fr; }
  .site-footer__brandcol { grid-column: 1 / -1; }
}
@media (min-width: 860px) {
  .site-footer__inner { grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr; }
  .site-footer__brandcol { grid-column: auto; }
}

.site-footer__brand-row { display: flex; align-items: center; gap: 0.55rem; margin-bottom: 0.6rem; }
.site-footer__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--ui-radius-md);
  background: var(--theme-accent-soft);
  font-size: 1.1rem;
}
.site-footer__brand { margin: 0; font-family: var(--theme-font-heading); font-weight: 800; color: var(--theme-ink); }
.site-footer__tagline { margin: 0 0 0.6rem; color: var(--theme-ink-soft); max-width: 340px; }
.site-footer__compare { margin: 0; color: var(--theme-ink-muted); font-size: 0.82rem; max-width: 340px; }

.site-footer__col { display: flex; flex-direction: column; gap: 0.55rem; }
.site-footer__links { display: flex; flex-direction: column; gap: 0.55rem; }
.site-footer__toggle { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.site-footer__heading {
  display: block;
  margin: 0 0 0.35rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--theme-ink-muted);
}
.site-footer__col a { color: var(--theme-ink-soft); font-size: 0.92rem; }
.site-footer__col a:hover { color: var(--theme-accent); text-decoration: none; }

/* Reabrir el banner de cookies es una ACCIÓN, no una navegación, así que va en
   un <button> —lo contrario deja un enlace que no lleva a ninguna parte para
   quien navegue con teclado o lector de pantalla— y aquí se le quita el aspecto
   de control para que no desentone entre sus vecinos. */
.site-footer__linkish {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  text-align: left;
  cursor: pointer;
  color: var(--theme-ink-soft);
  font-size: 0.92rem;
  font-family: inherit;
}
.site-footer__linkish:hover { color: var(--theme-accent); }

/* MÓVIL: acordeón. En una columna el pie son 18 enlaces apilados con sus cuatro
   rótulos; plegado son cuatro filas. Los enlaces siguen en el HTML —sólo se
   ocultan con `display: none`, no se quitan—, así que el enlazado interno, que
   es de lo poco que reparte autoridad hacia los hubs, no cambia. */
@media (max-width: 639px) {
  .site-footer__inner { grid-template-columns: 1fr; gap: 0; }
  .site-footer__brandcol { padding-bottom: 1.25rem; }
  .site-footer__col { gap: 0; border-top: 1px solid var(--theme-border); }
  .site-footer__heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0;
    padding: 0.95rem 0.1rem;
    font-size: 0.78rem;
    cursor: pointer;
  }
  /* El signo es el único indicio de que la fila se abre, así que se dibuja con
     `content` y no con un SVG por sección. */
  .site-footer__heading::after {
    content: "+";
    font-size: 1.15rem;
    font-weight: 400;
    line-height: 1;
    transition: transform 0.18s ease;
  }
  .site-footer__toggle:checked ~ .site-footer__heading::after { content: "−"; }
  .site-footer__links { display: none; padding: 0 0.1rem 1rem; }
  .site-footer__toggle:checked ~ .site-footer__links { display: flex; }
  .site-footer__col a { padding: 0.2rem 0; }
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  justify-content: space-between;
  align-items: baseline;
  padding: 1.1rem 1rem 1.6rem;
  border-top: 1px solid var(--theme-border);
}
.site-footer__meta {
  margin: 0;
  font-size: 0.78rem;
  color: var(--theme-ink-muted);
  max-width: 720px;
}
.site-footer__made { margin: 0; font-size: 0.78rem; color: var(--theme-ink-muted); white-space: nowrap; }

/* --------------------------- Search results UI -------------------------- */

/* Sólo envuelve el <h1> y la línea de "resultados para…" — el buscador vive
   aparte, en `.search-sticky`. Así que la tarjeta blanca con borde y sombra no
   enmarcaba nada: era una caja vacía alrededor de un título. Sin fondo, el
   encabezado se lee como lo que es y el peso visual se lo llevan los libros. */
.search-header {
  margin-bottom: 1.5rem;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
}
.search-header__form {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  /* OJO: el aspecto real en produccion NO se decide aqui. El tema `planeta`
     redefine este formulario mas abajo con `body.theme-confeti .search-header__form`,
     que gana por especificidad. Si quieres cambiar como se ve el buscador, hazlo
     ALLI — tocar solo esta regla no produce ningun efecto visible. */
}
.search-header__form input {
  flex: 1;
  /* `min-width: 0` o el buscador se rompe en móvil: `flex: 1` da base 0, pero el
     `min-width: auto` por defecto de un item flex lo ancla al ancho intrínseco de
     un <input> (~215 px por su `size` implícito), así que no encogía y empujaba
     al botón fuera. Medido en producción a 323 px de viewport: el botón acababa
     en x=399, 76 px fuera de la pantalla. */
  min-width: 0;
  padding: 0.75rem 1.1rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  font: inherit;
  font-size: 1.05rem;
  background: transparent;
  color: var(--theme-ink);
}
.search-header__form input:focus { outline: none; }
.search-header__form button {
  padding: 0.75rem 1.6rem;
  font-weight: 700;
  background: var(--theme-accent);
  color: var(--theme-surface);
  border: 0;
  /* Pildora, para que encaje dentro del contorno redondeado del formulario:
     con el radio cuadrado de antes asomaban las esquinas. */
  border-radius: var(--ui-radius-pill);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
/* El botón se lleva 112 px de la cápsula, y en un móvil estrecho eso dejaba el
   campo en 71 px — no cabe ni «ISBN, títul». Se le recorta el aire lateral al
   botón, que es lo prescindible: el input es donde se escribe. */
@media (max-width: 480px) {
  .search-header__form button,
  body.theme-confeti .search-header__form button { padding: 0.75rem 1.05rem; }
}
.search-header__meta { margin: 0; color: var(--theme-ink-soft); font-size: 0.92rem; }

/* Desplegable de búsqueda en vivo (as-you-type), poblado por live-search.js. */
.live-search-root { position: relative; }
.live-search__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 50;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-lg, 0 16px 40px rgba(8, 30, 60, 0.16));
  max-height: min(70vh, 28rem);
  overflow-y: auto;
  padding: 0.35rem;
}
/* Fila = enlace a la ficha + botón de añadir. El botón no puede ir dentro del
   <a>, así que la fila los pone uno al lado del otro y el enlace se queda con
   todo el espacio sobrante. */
.live-search__row { display: flex; align-items: center; gap: 0.25rem; }
.live-search__item {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--ui-radius-md);
  color: var(--theme-ink);
  text-decoration: none;
  flex: 1 1 auto;
  min-width: 0;
}
/* Selector con el panel delante A PROPÓSITO: el desplegable se inserta DENTRO
   del <form> del buscador, así que `body.theme-confeti .search-header__form
   button` —el botón «Buscar», azul, en píldora y con 1,7 rem de padding
   lateral— ganaba por especificidad y deformaba el «+». `padding: 0` explícito
   por lo mismo. */
.live-search__panel .live-search__add {
  flex: none;
  padding: 0;
  width: 2rem;
  height: 2rem;
  min-width: 0;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--theme-accent) 40%, var(--theme-border));
  background: var(--theme-surface);
  color: var(--theme-accent);
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.live-search__panel .live-search__add:hover:not([disabled]) {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: #fff;
}
.live-search__panel .live-search__add[disabled] { opacity: 0.55; cursor: progress; }
.live-search__item:hover,
.live-search__item.is-active {
  background: var(--theme-accent-soft);
  text-decoration: none;
}
.live-search__cover {
  width: 32px;
  height: 44px;
  object-fit: contain;
  border-radius: var(--ui-radius-sm);
  flex-shrink: 0;
  background: var(--theme-surface-alt);
}
.live-search__cover--ph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
}
.live-search__text { display: flex; flex-direction: column; min-width: 0; }
.live-search__title {
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.live-search__authors {
  font-size: 0.8rem;
  color: var(--theme-ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.live-search__empty { padding: 0.7rem 0.6rem; color: var(--theme-ink-muted); font-size: 0.9rem; }

.search-layout {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
}
/* La columna lateral de facetas se retiro el 08-ago-2026: ver .facet-bar. */

.search-facets {
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 1.25rem;
  align-self: start;
  box-shadow: var(--theme-shadow-sm);
}
/* -- Filtros plegables en movil ------------------------------------------
   En pantallas estrechas el panel tenia hasta 63 enlaces en 5 grupos, todos
   desplegados y ENCIMA de los resultados: habia que recorrerlos enteros para
   llegar al primer libro. Se pliegan tras un boton. Sin JS (la CSP es
   `script-src 'self'`): el estado lo lleva un checkbox y lo lee `:checked`.
   A partir de 980px —donde el panel ya es una columna lateral propia y no
   estorba— el boton se esconde y el cuerpo vuelve a estar siempre visible. */
.facets-toggle {
  /* Fuera de la vista pero NO `display:none` ni `hidden`: asi sigue estando en
     el arbol de accesibilidad y se puede alcanzar y accionar con el teclado. */
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.facets-toggle__label {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  /* 44px de alto: objetivo tactil comodo. */
  min-height: 44px;
  padding: 0 0.9rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-md);
  background: var(--theme-surface-alt, var(--theme-surface));
  color: var(--theme-ink);
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}
.facets-toggle__label svg { width: 18px; height: 18px; display: block; }
.facets-toggle__text { flex: 1; }
.facets-toggle__chevron { transition: transform 0.2s ease; }
.facets-toggle:checked ~ .facets-toggle__label .facets-toggle__chevron {
  transform: rotate(180deg);
}
.facets-toggle:focus-visible ~ .facets-toggle__label {
  outline: 2px solid var(--theme-accent);
  outline-offset: 2px;
}
.search-facets__body { display: none; }
.facets-toggle:checked ~ .search-facets__body {
  display: block;
  margin-top: 1rem;
  /* Abierto tampoco debe empujar los resultados fuera de la pantalla: el panel
     se desplaza por dentro. */
  max-height: 60vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
@media (max-width: 979px) {
  /* Plegado, la tarjeta no es mas que el boton: sin esto el padding de columna
     lateral la dejaba como un bloque hueco de 70px encima de los resultados. */
  .search-facets { padding: 0.6rem; }
}
@media (min-width: 980px) {
  .facets-toggle__label { display: none; }
  .search-facets__body { display: block; max-height: none; overflow: visible; }
}
.search-facets section { margin-bottom: 1.25rem; }
.search-facets section:last-child { margin-bottom: 0; }
.search-facets h2 {
  margin: 0 0 0.5rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--theme-ink-muted);
  font-family: var(--theme-font-body);
}
.search-facets ul { list-style: none; margin: 0; padding: 0; }
.search-facets li { margin: 0.2rem 0; font-size: 0.92rem; }
.search-facets li a { color: var(--theme-ink-soft); }
.search-facets li a:hover { color: var(--theme-accent); }
.search-facets__stock p { margin: 0; }
.facet-count { color: var(--theme-ink-muted); font-size: 0.82rem; margin-left: 0.25rem; }

.search-results__empty {
  padding: 2rem;
  background: var(--theme-surface);
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-lg);
  text-align: center;
}
.search-results__empty p { color: var(--theme-ink-soft); }

.book-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 900px) {
  .book-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 640px) {
  .book-grid { grid-template-columns: repeat(2, 1fr); }
}

.book-card {
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  overflow: hidden;
  box-shadow: var(--theme-shadow-sm);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
  display: flex;
  flex-direction: column;
}
.book-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--theme-shadow);
  border-color: color-mix(in srgb, var(--theme-accent) 35%, var(--theme-border));
}

.book-card__link { display: flex; flex-direction: column; flex: 1 1 auto; color: inherit; }
.book-card__link:hover { text-decoration: none; color: inherit; }

.book-card__cover {
  display: block;
  width: 100%;
  /* CUADRADA, no 2/3: la caja vertical es la proporción de una portada de libro,
     y una foto de juguete no lo es. Amazon publica sus imágenes de producto en
     un lienzo cuadrado con fondo blanco, así que 1/1 encaja sin franjas.

     Y `contain`, no `cover`: las fotos de los feeds vienen con proporciones muy
     dispares —una caja de LEGO es apaisada y un muñeco es alto—, y recortarlas
     a cuadrado corta justo por donde está lo que distingue una referencia de
     otra: el número de set, la variante de color, las piezas que incluye. La
     franja vacía es fea; esconder de qué juguete se trata es un error de
     producto. */
  aspect-ratio: 1 / 1;
  object-fit: contain;
  padding: 0.4rem;
  background: var(--theme-surface);
}
.book-card__cover--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.5rem;
  color: var(--theme-ink-muted);
}

.book-card__body { padding: 0.85rem 0.9rem 0.95rem; text-align: center; display: flex; flex-direction: column; flex: 1 1 auto; }
.book-card__title {
  margin: 0 0 0.4rem;
  font-size: 0.95rem;
  line-height: 1.3;
  font-family: var(--theme-font-heading);
  color: var(--theme-ink);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(0.95rem * 1.3 * 3);
}
.book-card__authors { margin: 0 0 0.15rem; color: var(--theme-ink-soft); font-size: 0.82rem; }
.book-card__publisher { margin: 0 0 0.5rem; color: var(--theme-ink-muted); font-size: 0.78rem; }
.book-card__price { margin: auto 0 0.55rem; font-size: 1.25rem; font-weight: 700; line-height: 1.1; }
.book-card__price strong { font-family: var(--theme-font-body); font-weight: 700; }
.book-card__price--empty { display: block; margin: 0; color: var(--theme-ink-muted); font-size: 0.85rem; font-weight: 500; }
/* «desde» delante del importe. Va SIEMPRE que hay precio: el número es el
   mínimo con envío entre varias tiendas, y enseñarlo pelado prometería un
   importe que puede no ser el de la tienda a la que se acabe entrando. */
.book-card__from {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--theme-ink-muted);
  text-transform: lowercase;
  letter-spacing: 0.01em;
}
/* Marca del juguete, ENCIMA del título: en un catálogo donde media rejilla se
   llama «Set de construcción 1200 piezas», la marca es lo primero que la gente
   reconoce. */
.book-card__brand {
  margin: 0 0 0.2rem;
  color: var(--theme-ink-muted);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
/* Botón verde "N precios" — señal de comparativa (estilo comparador). */
.book-card__prices {
  display: block;
  padding: 0.55rem 0.75rem;
  background: var(--theme-accent);
  color: #fff;
  border-radius: var(--ui-radius-sm);
  font-weight: 700;
  font-size: 0.92rem;
  text-align: center;
}
.book-card:hover .book-card__prices { filter: brightness(0.93); }
.book-card__merchant {
  margin: 0.55rem 0 0;
  color: var(--theme-ink-soft);
  font-size: 0.76rem;
  font-style: italic;
  line-height: 1.3;
}

.pagination {
  margin-top: 1.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  font-size: 0.92rem;
}
/* Paginacion numerada en pildoras. La actual va rellena de color de marca y
   los demas numeros en superficie con borde: el usuario ve de un vistazo
   donde esta y cuantas paginas quedan, y llega a cualquiera de un clic. */
.pagination__pages {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.pagination__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 2,5 rem = 40 px: por encima del minimo tactil comodo en movil. */
  min-width: 2.5rem;
  height: 2.5rem;
  padding: 0 0.7rem;
  border: 1px solid var(--theme-border);
  /* Radio fijo, no 999px: con pildoras el «1» sale circulo y el «240» ovalo,
     y la fila queda con dos formas distintas. Con esquinas redondeadas todos
     los numeros son la misma figura mida lo que mida. */
  border-radius: var(--ui-radius-md);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  color: var(--theme-ink);
  background: var(--theme-surface);
  transition: border-color 0.18s ease, background-color 0.18s ease, color 0.18s ease;
}
.pagination__page:hover {
  border-color: color-mix(in srgb, var(--theme-accent) 45%, var(--theme-border));
  background: color-mix(in srgb, var(--theme-accent-soft) 60%, var(--theme-surface));
  color: var(--theme-accent);
  text-decoration: none;
}
.pagination__page--current {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: #fff;
  cursor: default;
}
/* La actual es un <span> y no lleva a ninguna parte, asi que el puntero encima
   no debe cambiarla. Sin esto heredaba el fondo palido del :hover de arriba
   conservando el color blanco del texto: el numero desaparecia al pasar por
   encima. Es el mismo motivo por el que se fija tambien el color. */
.pagination__page--current:hover {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: #fff;
}
.pagination__gap {
  padding: 0 0.15rem;
  color: var(--theme-ink-muted);
  user-select: none;
}
.pagination__step {
  display: inline-flex;
  align-items: center;
  height: 2.5rem;
  padding: 0 0.95rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-md);
  font-weight: 600;
  text-decoration: none;
  color: var(--theme-ink);
  background: var(--theme-surface);
  transition: border-color 0.18s ease, background-color 0.18s ease, color 0.18s ease;
}
.pagination__step:hover {
  border-color: color-mix(in srgb, var(--theme-accent) 45%, var(--theme-border));
  background: color-mix(in srgb, var(--theme-accent-soft) 60%, var(--theme-surface));
  color: var(--theme-accent);
  text-decoration: none;
}
/* En movil los rotulos Anterior/Siguiente se comen la fila: quedan los numeros,
   que es lo que de verdad permite saltar. */
@media (max-width: 460px) {
  .pagination__step { display: none; }
}
/* Aqui vivia un `.pagination a { ... }` de la paginacion anterior (la de
   «Anterior / Pagina 6 de 15 / Siguiente»). Al llegar la numerada dejo de
   describir nada y paso a estorbar: `.pagination a` tiene mas especificidad
   (0,1,1) que `.pagination__page` (0,1,0) y ademas iba despues, asi que le
   sobreescribia el radio y el padding a TODOS los enlaces. La pagina actual,
   que es un <span>, no la alcanzaba — y por eso salia redonda mientras las
   demas salian cuadradas. */
.pagination__status { color: var(--theme-ink-muted); }

/* -------------------------- Preguntas frecuentes ------------------------- */
/* `<details>` nativo: la CSP prohibe JS inline y el contenido de un <details>
   cerrado si lo indexa Google, asi que no hace falta nada mas. */
.faq {
  margin: 2.5rem 0 0;
  padding-top: 1.75rem;
  border-top: 1px solid var(--theme-border);
}
.faq__title { margin: 0 0 1rem; font-size: 1.35rem; }
.faq__item {
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface);
  margin-bottom: 0.6rem;
  overflow: hidden;
}
.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  /* Alto comodo para el dedo; el summary entero es el area de toque. */
  padding: 0.9rem 1.1rem;
  font-weight: 600;
  color: var(--theme-ink);
  cursor: pointer;
  list-style: none;
}
/* El triangulo por defecto se quita en los dos motores y se sustituye por un
   signo propio que ademas indica el estado. */
.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { content: ''; }
.faq__q::after {
  content: '+';
  flex: none;
  font-size: 1.35rem;
  font-weight: 400;
  line-height: 1;
  color: var(--theme-accent);
  transition: transform 0.18s ease;
}
.faq__item[open] .faq__q::after { content: '\2212'; }
.faq__q:hover { background: color-mix(in srgb, var(--theme-accent-soft) 45%, var(--theme-surface)); }
.faq__item:focus-within .faq__q { outline: 2px solid var(--theme-accent); outline-offset: -2px; }
.faq__a { padding: 0 1.1rem 1.1rem; }
.faq__a p { margin: 0; color: var(--theme-ink-soft); line-height: 1.65; }

/* ------------------------------- List page ------------------------------ */

/* Sin tarjeta (petición de Rafael, 14-ago-2026): el título de la lista no es una
   pieza de contenido que compita con las de abajo —las tarjetas blancas son las
   que SÍ hay que mirar y comparar—, así que va plano sobre el fondo. */
.list-detail__header {
  margin-bottom: 1.5rem;
  padding: 0;
}
.list-detail__header h1 { margin: 0 0 0.4rem; font-size: clamp(1.4rem, 3vw, 1.85rem); }
.list-detail__meta { margin: 0; color: var(--theme-ink-soft); font-size: 0.92rem; }

.list-cdl-highlight, .list-mix, .list-buys, .list-matrix, .list-items {
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--theme-shadow-sm);
}
.list-cdl-highlight h2, .list-mix h2, .list-buys h2, .list-matrix h2, .list-items h2 {
  margin: 0 0 0.85rem;
  font-size: 1.2rem;
}
.list-cdl-highlight__meta, .list-mix__lead, .list-buys__lead {
  margin: 0 0 1rem;
  color: var(--theme-ink-soft);
  font-size: 0.95rem;
}
.list-cdl-highlight__cta {
  display: inline-block;
  padding: 0.65rem 1.2rem;
  background: var(--theme-accent);
  color: var(--theme-surface);
  border-radius: var(--ui-radius-cta);
  font-weight: 600;
}
.list-cdl-highlight__cta:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }
.list-cdl-highlight__missing, .list-mix__unassigned {
  margin: 0.85rem 0 0;
  color: var(--theme-ink-muted);
  font-size: 0.85rem;
}

/* Mix óptimo como desplegable: cabecera-resumen clicable (compra libro a libro). */
.list-mix > summary.list-mix__summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
  list-style: none;
  font-weight: 700;
  font-size: 1.05rem;
}
.list-mix > summary.list-mix__summary::-webkit-details-marker { display: none; }
.list-mix__summary-label { color: var(--theme-ink); }
.list-mix__summary-total { margin-left: auto; color: var(--theme-ink-soft); font-family: var(--theme-font-heading); font-size: 0.95rem; font-weight: 600; }
.list-mix__summary-total strong { color: var(--theme-accent); }
.list-mix > summary.list-mix__summary::after {
  content: "";
  flex-shrink: 0;
  width: 0.6rem;
  height: 0.6rem;
  margin-left: 0.5rem;
  border-right: 2px solid var(--theme-ink-muted);
  border-bottom: 2px solid var(--theme-ink-muted);
  transform: rotate(45deg);
  transition: transform 0.2s ease;
}
.list-mix[open] > summary.list-mix__summary::after { transform: rotate(-135deg); }
.list-mix[open] > .list-mix__groups { margin-top: 1.1rem; }

.list-mix__groups { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.list-mix-group {
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  padding: 0.85rem 1rem;
  background: var(--theme-bg);
}
.list-mix-group__head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: baseline;
  margin-bottom: 0.5rem;
}
.list-mix-group__swatch {
  display: inline-block;
  width: 0.85rem;
  height: 0.85rem;
  border-radius: var(--ui-radius-sm);
}
.list-mix-group__name { font-weight: 600; }
.list-mix-group__count { color: var(--theme-ink-muted); font-size: 0.85rem; }
.list-mix-group__total { margin-left: auto; color: var(--theme-ink-soft); font-size: 0.92rem; font-family: var(--theme-font-heading); }
.list-mix-group__total strong { color: var(--theme-ink); }
.list-mix-group__items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.9rem; }
.list-mix-group__items a { color: var(--theme-ink-soft); }
.list-mix-group__items a:hover { color: var(--theme-accent); }

/* ---- Quick-wins de /lista: ahorro, compartir, mix legible, buybar ------- */

/* Banner de ahorro cuantificado (el "gancho" de la lista). */
.list-savings {
  margin: 0 0 1.5rem;
  padding: 1rem 1.25rem;
  background: color-mix(in srgb, var(--theme-success) 10%, #fff);
  border: 1px solid color-mix(in srgb, var(--theme-success) 28%, transparent);
  border-radius: var(--ui-radius-sm);
}
.list-savings__headline {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.55rem;
  font-size: 1.05rem;
  color: color-mix(in srgb, var(--theme-success) 78%, #000 22%);
}
.list-savings__lead { font-weight: 600; }
.list-savings__amount {
  font-family: var(--theme-font-heading);
  font-weight: 800;
  font-size: 1.5rem;
  color: var(--theme-success);
}
.list-savings__pct {
  font-weight: 700;
  font-size: 0.8rem;
  padding: 0.1rem 0.5rem;
  border-radius: var(--ui-radius-pill);
  background: color-mix(in srgb, var(--theme-success) 18%, #fff);
}
.list-savings__detail { color: color-mix(in srgb, var(--theme-success) 55%, var(--theme-ink) 45%); font-size: 0.95rem; }
.list-savings__detail strong { font-weight: 700; }
.list-savings__mix { margin: 0.5rem 0 0; font-size: 0.92rem; color: color-mix(in srgb, var(--theme-success) 65%, var(--theme-ink) 35%); }
.list-savings__mix strong { font-weight: 800; color: var(--theme-success); }

/* Acciones de la cabecera: botones de compartir. */
.list-detail__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.list-share-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.95rem;
  border-radius: var(--ui-radius-pill);
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  line-height: 1;
}
.list-share-btn:hover { border-color: var(--theme-accent); color: var(--theme-accent); text-decoration: none; }
.list-share-btn__icon { width: 1rem; height: 1rem; flex-shrink: 0; }
.list-detail__share-label { font-size: 0.85rem; font-weight: 600; color: var(--theme-ink-muted); margin-right: 0.15rem; }
/* Botones de compartir con color de marca; el hover solo oscurece un poco. */
.list-share-btn--wa { background: #25d366; border-color: #25d366; color: #fff; }
.list-share-btn--wa:hover { filter: brightness(0.95); color: #fff; border-color: #25d366; }
.list-share-btn--tg { background: #229ed9; border-color: #229ed9; color: #fff; }
.list-share-btn--tg:hover { filter: brightness(0.95); color: #fff; border-color: #229ed9; }
.list-share-btn--x { background: #000; border-color: #000; color: #fff; }
.list-share-btn--x:hover { filter: brightness(1.25); color: #fff; border-color: #000; }
.list-share-btn--fb { background: #1877f2; border-color: #1877f2; color: #fff; }
.list-share-btn--fb:hover { filter: brightness(0.95); color: #fff; border-color: #1877f2; }
.list-share-btn--copy.is-copied { background: var(--theme-success); border-color: var(--theme-success); color: #fff; }

/* Panel "Guarda o comparte tu lista": propósito + copiar-enlace prominente +
   redes como acción secundaria. El copiar lo maneja list-share.js vía
   [data-copy-url] (sin JS inline, CSP-safe). */
.list-share {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin-top: 1.1rem;
  padding: 1.1rem 1.2rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-md);
}
.list-share__intro { display: flex; gap: 0.7rem; align-items: flex-start; }
.list-share__intro-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
}
.list-share__intro-icon svg { width: 1.15rem; height: 1.15rem; }
.list-share__title { margin: 0; font-weight: 700; color: var(--theme-ink); font-size: 1rem; }
.list-share__hint { margin: 0.15rem 0 0; color: var(--theme-ink-soft); font-size: 0.88rem; line-height: 1.5; }
.list-share__copy { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.list-share__url {
  flex: 1 1 240px;
  min-width: 0;
  padding: 0.62rem 0.85rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  color: var(--theme-ink-soft);
  font-family: var(--theme-font-mono);
  font-size: 0.85rem;
}
.list-share__url:focus { outline: 2px solid var(--ui-accent-ring); outline-offset: 1px; }
.list-share__copy-btn {
  flex: 0 0 auto;
  padding: 0.62rem 1.3rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: #fff;
  font-weight: 700;
  font-size: 0.9rem;
  cursor: pointer;
  transition: filter 0.15s ease, background 0.15s ease;
}
.list-share__copy-btn:hover { filter: brightness(1.07); }
.list-share__copy-btn.is-copied { background: var(--theme-success); }
.list-share__socials { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.list-share__socials-label { font-size: 0.82rem; font-weight: 600; color: var(--theme-ink-muted); margin-right: 0.1rem; }

/* Mix óptimo legible: miniatura + título en lugar del ISBN crudo. */
/* ============ /lista: veredicto, tabla de librerías y lista de la compra ====
   Reordenación del 08-ago-2026. La página abría pidiendo que la compartieras y
   el primer enlace que gana dinero estaba a 1,3 pantallas de scroll; ahora abre
   con la respuesta y el botón. */

.list-verdict {
  background: var(--theme-accent-soft);
  border: 1px solid color-mix(in srgb, var(--theme-accent) 28%, var(--theme-border));
  border-radius: var(--ui-radius-lg);
  padding: 1.5rem 1.5rem 1.6rem;
  margin: 0 0 1.5rem;
  text-align: center;
}
.list-verdict__eyebrow {
  margin: 0 0 0.35rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--theme-ink-soft);
}
.list-verdict__store {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  font-size: clamp(1.35rem, 3.5vw, 1.8rem);
  line-height: 1.15;
}
.list-verdict__logo { border-radius: var(--ui-radius-sm); flex: none; }
.list-verdict__total { margin: 0 0 0.9rem; display: flex; flex-direction: column; gap: 0.15rem; align-items: center; }
.list-verdict__amount {
  font-family: var(--theme-font-heading);
  font-weight: 800;
  font-size: clamp(2.1rem, 6vw, 3rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--theme-accent);
  font-variant-numeric: tabular-nums;
}
.list-verdict__ship { font-size: 0.85rem; color: var(--theme-ink-muted); }
.list-verdict__facts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem 1.4rem;
  margin: 0 0 1.2rem;
  font-size: 0.92rem;
  color: var(--theme-ink-soft);
}
.list-verdict__fact strong { color: var(--theme-ink); }
.list-verdict__fact--save strong { color: var(--theme-success, var(--theme-success)); }
.list-verdict__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.7rem;
  background: var(--theme-accent);
  color: var(--theme-surface);
  border-radius: var(--ui-radius-pill);
  font-weight: 700;
  font-size: 1.02rem;
}
.list-verdict__cta:hover, .list-verdict__cta:focus { color: var(--theme-surface); text-decoration: none; filter: brightness(0.93); }
.list-verdict__cta svg { width: 1.05rem; height: 1.05rem; }
.list-verdict__mixhint { margin: 1rem 0 0; font-size: 0.9rem; color: var(--theme-ink-soft); }

/* --- Tabla comparativa. Sustituye a cuatro tarjetas de 714 px que servían para
   comparar cuatro números; en columna se comparan de un vistazo. --- */
/* --- Matriz libro × librería: cada celda es el precio con su enlace. --- */
.list-matrix { margin: 0 0 1.75rem; }
.list-matrix__title { margin: 0 0 0.85rem; font-size: 1.2rem; }
.list-matrix__scroll { overflow-x: auto; }
.list-matrix__table { width: 100%; border-collapse: collapse; font-size: 0.94rem; }
.list-matrix__table th,
.list-matrix__table td { padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--theme-border); text-align: left; vertical-align: middle; }
.list-matrix__table thead th {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--theme-ink-muted);
  font-weight: 700;
  white-space: nowrap;
}
.list-matrix__table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.list-matrix__store { display: inline-flex; align-items: center; gap: 0.4rem; }
.list-matrix__store img { border-radius: var(--ui-radius-sm); flex: none; }
.list-matrix__book { display: flex; align-items: center; gap: 0.6rem; min-width: 14rem; }
.list-matrix__cover {
  flex: none;
  width: 28px;
  height: 40px;
  object-fit: cover;
  border-radius: var(--ui-radius-sm);
}
.list-matrix__cover--ph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--theme-accent-soft);
  font-size: 0.95rem;
}
.list-matrix__booktext { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.list-matrix__booklink { font-weight: 600; color: var(--theme-ink); text-decoration: none; }
a.list-matrix__booklink:hover { text-decoration: underline; }
/* El precio es un BOTÓN, y el más barato de cada fila va en sólido: es el
 * «destacado del proveedor» que se pidió — el fondo de celda de antes se
 * confundía con un simple estilado y en los empates parecía un error. */
.list-matrix__price {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.4rem 0.85rem;
  border: 1.5px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  font-weight: 700;
  color: var(--theme-accent);
  text-decoration: none;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.list-matrix__price:hover { background: var(--theme-accent-soft); border-color: var(--theme-accent); }
.list-matrix__table td.is-best .list-matrix__price {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: var(--theme-surface);
}
.list-matrix__cellstore { display: none; }
.list-matrix__none { color: var(--theme-ink-muted); }
.list-matrix__note { margin: 0.8rem 0 0; font-size: 0.85rem; color: var(--theme-ink-muted); }
.list-matrix__table tbody tr.is-bought { opacity: 0.55; }
.list-matrix__table tbody tr.is-bought .list-matrix__booklink { text-decoration: line-through; }
.list-mix-item.is-bought { opacity: 0.55; }
.list-mix-item.is-bought .list-mix-item__title { text-decoration: line-through; }

/* --- El diálogo de compartir al completar la lista (`list-celebrate`, NO
 * `list-share`: esa clase es de la sección «Guarda o comparte tu lista» y la
 * colisión vistió aquella sección de popup — 12-ago-2026). --- */
.list-celebrate {
  max-width: 24rem;
  border: 0;
  border-radius: var(--ui-radius-lg);
  padding: 1.6rem 1.5rem;
  text-align: center;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.22);
}
.list-celebrate:not([open]) { display: none; }
.list-celebrate::backdrop { background: rgba(15, 30, 45, 0.55); }
.list-celebrate__emoji { margin: 0; font-size: 2.2rem; line-height: 1; }
.list-celebrate__title { margin: 0.5rem 0 0.4rem; font-size: 1.25rem; }
.list-celebrate__body { margin: 0 0 1.1rem; font-size: 0.92rem; color: var(--theme-ink-soft); }
.list-celebrate__actions { display: flex; flex-direction: column; gap: 0.55rem; }
.list-celebrate__wa,
.list-celebrate__copy {
  display: block;
  width: 100%;
  padding: 0.65rem 1rem;
  border-radius: var(--ui-radius-pill);
  font-weight: 700;
  font-size: 0.95rem;
  text-decoration: none;
  cursor: pointer;
}
.list-celebrate__wa { background: var(--theme-accent); color: var(--theme-surface); border: 0; }
.list-celebrate__wa:hover { opacity: 0.92; }
.list-celebrate__copy { background: var(--theme-surface); color: var(--theme-accent); border: 1.5px solid var(--theme-accent); }
.list-celebrate__copy:hover { background: var(--theme-accent-soft); }
.list-celebrate__close {
  background: none;
  border: 0;
  padding: 0.4rem;
  color: var(--theme-ink-muted);
  font-size: 0.85rem;
  cursor: pointer;
  text-decoration: underline;
}

/* En móvil la matriz no cabe ni con scroll: cada libro pasa a ser una
 * tarjeta con sus botones de tienda (los guiones de «no lo tiene» sobran). */
@media (max-width: 720px) {
  .list-matrix__scroll { overflow-x: visible; }
  .list-matrix__table, .list-matrix__table tbody { display: block; }
  .list-matrix__table thead { display: none; }
  .list-matrix__table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    border: 1px solid var(--theme-border);
    border-radius: var(--ui-radius-md);
    background: var(--theme-surface);
    padding: 0.85rem;
    margin: 0 0 0.75rem;
  }
  .list-matrix__table th, .list-matrix__table td { border: 0; padding: 0; }
  .list-matrix__table th[scope="row"] { flex-basis: 100%; }
  .list-matrix__book { min-width: 0; }
  .list-matrix__none { display: none; }
  .list-matrix__cellstore {
    display: inline;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
}

/* --- La lista de la compra. Abierta, no en acordeón: el CTA anterior tenía
   forma de botón de compra y lo único que hacía era desplegar un cajón. --- */
.list-buys__lead { margin: 0 0 1.1rem; color: var(--theme-ink-soft); }
.list-shop {
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  margin-bottom: 0.75rem;
  background: var(--theme-surface);
}
.list-shop--best { border-color: color-mix(in srgb, var(--theme-accent) 40%, var(--theme-border)); }
.list-shop__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.9rem 1.1rem;
  cursor: pointer;
  list-style: none;
  font-weight: 600;
}
.list-shop__head::-webkit-details-marker { display: none; }
/* Nada decía que estas filas se abren: se ocultó el marcador nativo y no se
   puso nada en su lugar, así que las librerías cerradas parecían un ranking
   muerto —nombre, progreso y total— en vez de la puerta a sus libros. Galón que
   gira al abrir (el mismo del mix, para que el gesto se aprenda una vez) y la
   fila entera se tiñe al pasar por encima (14-ago-2026). */
.list-shop__head::after {
  content: "";
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  margin-left: -0.2rem;
  border-right: 2px solid var(--theme-ink-muted);
  border-bottom: 2px solid var(--theme-ink-muted);
  transform: translateY(-0.15rem) rotate(45deg);
  transition: transform 0.2s ease, border-color 0.2s ease;
}
.list-shop[open] > .list-shop__head::after { transform: translateY(0.1rem) rotate(-135deg); }
/* `inherit` y no un valor fijo: la cabecera es el primer hijo de una caja
   redondeada, y sin esto el fondo del hover pinta esquinas cuadradas por fuera
   del borde. Abierta, sólo redondea arriba. */
.list-shop__head { border-radius: inherit; }
.list-shop[open] > .list-shop__head { border-radius: var(--ui-radius-lg) var(--ui-radius-lg) 0 0; }
.list-shop__head:hover { background: var(--theme-surface-alt); }
.list-shop__head:hover::after { border-color: var(--theme-accent); }
.list-shop__head:focus-visible { outline: 2px solid var(--ui-accent-ring); outline-offset: -2px; }
.list-shop__store { display: inline-flex; align-items: center; gap: 0.5rem; min-width: 0; }
.list-shop__store img { border-radius: var(--ui-radius-sm); flex: none; }
.list-shop__store span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* `margin-left: auto` porque el galón de `::after` es un tercer hijo del flex:
   con el `space-between` a secas, el precio se habría ido al centro. */
.list-shop__meta { display: flex; align-items: center; gap: 0.85rem; flex: none; margin-left: auto; }
.list-shop__progress { font-size: 0.82rem; font-weight: 600; color: var(--theme-ink-muted); }
.list-shop__progress.is-complete { color: var(--theme-success, var(--theme-success)); }
.list-shop__total { font-variant-numeric: tabular-nums; font-weight: 700; }
.list-shop__items { list-style: none; margin: 0; padding: 0 1.1rem 0.9rem; display: flex; flex-direction: column; gap: 0.35rem; }
.list-shop__item {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.5rem;
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface-alt);
}
/* Comprado: se atenúa pero NO se esconde — quien vuelve necesita ver la lista
   entera para saber que ya no le falta nada. */
.list-shop__item.is-bought { opacity: 0.55; }
.list-shop__item.is-bought .list-shop__title { text-decoration: line-through; }
.list-shop__tick {
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--theme-border);
  border-radius: 50%;
  background: var(--theme-surface);
  color: transparent;
  cursor: pointer;
  padding: 0;
}
.list-shop__tick svg { width: 0.85rem; height: 0.85rem; }
.list-shop__item.is-bought .list-shop__tick {
  background: var(--theme-success, var(--theme-success));
  border-color: var(--theme-success, var(--theme-success));
  color: #fff;
}
.list-shop__cover { width: 32px; height: 44px; object-fit: contain; border-radius: var(--ui-radius-sm); flex: none; background: var(--theme-surface); }
.list-shop__cover--ph { display: inline-flex; align-items: center; justify-content: center; font-size: 1rem; }
.list-shop__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.list-shop__title { color: var(--theme-ink); font-size: 0.92rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-shop__title:hover { color: var(--theme-accent); }
.list-shop__price { font-size: 0.85rem; color: var(--theme-ink-muted); font-variant-numeric: tabular-nums; }
/* El ISBN como CHIP: es el dato con el que un padre coteja la lista impresa
 * del colegio, y en gris perdido no se encontraba (petición 12-ago). */
.list-shop__isbn, .list-mix-item__isbn, .list-matrix__isbn {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--theme-ink-soft);
  background: var(--theme-surface-alt);
  border-radius: var(--ui-radius-sm);
  padding: 0.12rem 0.5rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.list-shop__isbn, .list-matrix__isbn { align-self: flex-start; }
.list-mix-item__isbn { flex: none; }
.list-shop__buy {
  flex: none;
  padding: 0.45rem 1rem;
  background: var(--theme-accent);
  color: var(--theme-surface);
  border-radius: var(--ui-radius-pill);
  font-size: 0.88rem;
  font-weight: 700;
}
.list-shop__buy:hover, .list-shop__buy:focus { color: var(--theme-surface); text-decoration: none; filter: brightness(0.93); }
.list-shop__missing { margin: 0 1.1rem 0.9rem; font-size: 0.85rem; color: var(--theme-ink-muted); }

@media (max-width: 560px) {
  .list-shop__meta { gap: 0.5rem; }
  .list-shop__progress { font-size: 0.74rem; }
  .list-shop__buy { padding: 0.45rem 0.75rem; }
}

.list-mix-item { display: flex; align-items: center; gap: 0.6rem; }
.list-mix-item__cover {
  flex: none;
  width: 30px;
  height: 42px;
  object-fit: cover;
  border-radius: var(--ui-radius-sm);
  background: var(--theme-bg);
}
.list-mix-item__cover--ph { display: inline-flex; align-items: center; justify-content: center; font-size: 1rem; }
.list-mix-group__items .list-mix-item__title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--theme-ink);
  font-weight: 500;
}
.list-mix-group__items .list-mix-item__title:hover { color: var(--theme-accent); }

/* Responsive de la lista (12-ago-2026, capturas de Rafael): en móvil el
 * título del mix quedaba a 0 px entre el chip de ISBN, el precio y el botón
 * —desaparecía—, y el de la checklist se truncaba a diez caracteres por el
 * nowrap de escritorio. Va DESPUÉS de las reglas base para ganar en cascada. */
@media (max-width: 720px) {
  .list-shop__title {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }
  .list-shop__store { min-width: 0; }
  .list-mix-item { flex-wrap: wrap; row-gap: 0.35rem; }
  .list-mix-group__items .list-mix-item__title {
    flex: 1 1 calc(100% - 40px);
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }
  .list-mix-item__isbn { order: 2; }
  .list-mix-item__price { order: 3; margin-left: auto; }
  .list-mix-item__buy { order: 4; }
}
.list-mix-item__price { flex: none; font-family: var(--theme-font-heading); font-weight: 600; color: var(--theme-ink); }
.list-mix-group__items .list-mix-item__buy {
  flex: none;
  padding: 0.35rem 0.8rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font-size: 0.82rem;
  font-weight: 700;
}
.list-mix-group__items .list-mix-item__buy:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }

/* Campo opcional "nombre de la lista" en /comparar. */
.compare-form__name {
  display: block;
  width: 100%;
  margin-top: 0.6rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font: inherit;
  font-size: 0.95rem;
}
.compare-form__name:focus { outline: 2px solid color-mix(in srgb, var(--theme-accent) 45%, transparent); outline-offset: 1px; border-color: var(--theme-accent); }

/* Hueco para que la buybar fija no tape el final de la lista en móvil. */
@media (max-width: 719px) {
  .list-detail { padding-bottom: 4.5rem; }
}

/* ---- Editar lista: añadir libro, quitar, y "los añadiremos pronto". ----- */
.list-add {
  margin: 0 0 1.5rem;
  padding: 0.9rem 1.1rem;
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-bg);
}
.list-add__label { display: block; font-weight: 600; font-size: 0.9rem; margin-bottom: 0.5rem; }
.list-add__row { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.list-add__input {
  flex: 1 1 240px;
  min-width: 0;
  padding: 0.6rem 0.85rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font: inherit;
}
.list-add__input:focus { outline: 2px solid color-mix(in srgb, var(--theme-accent) 45%, transparent); outline-offset: 1px; border-color: var(--theme-accent); }
.list-add__submit {
  flex: none;
  padding: 0.6rem 1.3rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.list-add__submit:hover { filter: brightness(0.93); }

/* Lista ajena (compartida o histórica sin dueño): aviso + CTA «crear mi copia». */
.list-foreign {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  margin-top: 1rem;
  padding: 0.85rem 1rem;
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-accent-soft);
}
.list-foreign__note {
  margin: 0;
  flex: 1 1 16rem;
  color: var(--theme-ink-soft);
  font-size: 0.92rem;
}
.list-foreign__form { margin: 0; }
.list-foreign__btn {
  padding: 0.55rem 1.2rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.list-foreign__btn:hover { filter: brightness(0.93); }

/* Aviso de un solo uso tras clonar una lista compartida: «esta es tu copia». */
.list-forked-note {
  margin: 0 0 1.25rem;
  padding: 0.7rem 1rem;
  border: 1px solid var(--theme-border);
  border-left: 4px solid var(--theme-accent);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font-size: 0.95rem;
  box-shadow: var(--theme-shadow-sm);
}

/* ---- Mis listas (/mis-listas) ---- */
.mylists { max-width: 46rem; margin: 0 auto; }
.mylists__header { margin-bottom: 1.25rem; }
.mylists__header h1 { margin: 0 0 0.35rem; }
.mylists__lead { margin: 0; color: var(--theme-ink-soft); }
.mylists__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.mylists__item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.15rem 0.85rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  box-shadow: var(--theme-shadow-sm);
}
.mylists__item.is-active { border-color: var(--theme-accent); }
.mylists__link { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; padding: 0.6rem 0; }
.mylists__link:hover { text-decoration: none; }
.mylists__name { color: var(--theme-ink); font-weight: 700; }
.mylists__link:hover .mylists__name { color: var(--theme-accent); }
.mylists__meta { color: var(--theme-ink-soft); font-size: 0.85rem; }
.mylists__badge {
  flex: none;
  padding: 0.2rem 0.6rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
  font-size: 0.78rem;
  font-weight: 700;
}
.mylists__empty {
  padding: 1.5rem;
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-lg);
  background: var(--theme-surface);
  text-align: center;
}
.mylists__empty-text { margin: 0 0 1rem; color: var(--theme-ink-soft); }
/* Dejó de ser un enlace a /comparar para ser un POST que suelta la comparativa
   activa, así que ahora es un <button>: hereda tipografía y pierde el borde.
   OJO al orden: este `margin: 0` (que sólo quiere anular el margen que algunos
   navegadores dan al <form>) tiene la misma especificidad que la separación de
   `.mylists__actions`, así que si va DESPUÉS se la come y el botón queda pegado
   a la última lista. Por eso el margen de la fila de acciones se declara aquí
   abajo, y no antes. */
.mylists__new { margin: 0; }
.mylists__actions { margin-top: 1.25rem; }
.mylists__new-btn {
  display: inline-block;
  font: inherit;
  padding: 0.6rem 1.3rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font-weight: 700;
  cursor: pointer;
}
.mylists__new-btn:hover { filter: brightness(0.93); text-decoration: none; color: var(--theme-surface); }
.mylists__new-btn:focus-visible { outline: 2px solid var(--ui-accent-ring); outline-offset: 2px; }
.mylists__note { margin-top: 1.25rem; color: var(--theme-ink-muted); font-size: 0.85rem; }

/* ---- Interstitial «¿dónde añadimos estos libros?» ---- */
.cmp-decide { max-width: 40rem; margin: 0 auto; text-align: center; }
.cmp-decide__title { margin: 0 0 0.6rem; }
.cmp-decide__lead { margin: 0 0 1.5rem; color: var(--theme-ink-soft); }
.cmp-decide__options { display: grid; gap: 0.85rem; }
.cmp-decide__option {
  margin: 0;
  padding: 1.1rem 1.25rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--theme-shadow-sm);
}
.cmp-decide__btn {
  display: inline-block;
  width: 100%;
  padding: 0.7rem 1.3rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.cmp-decide__btn:hover { border-color: var(--theme-accent); color: var(--theme-accent); }
.cmp-decide__btn--primary {
  border-color: var(--theme-accent);
  background: var(--theme-accent);
  color: var(--theme-surface);
}
.cmp-decide__btn--primary:hover { filter: brightness(0.93); color: var(--theme-surface); }
.cmp-decide__hint { margin: 0.55rem 0 0; color: var(--theme-ink-soft); font-size: 0.88rem; }
.cmp-decide__links { margin-top: 1.25rem; font-size: 0.9rem; color: var(--theme-ink-soft); }

/* Banner «envíanos tu lista» de las colecciones de curso/asignatura: banda
   clicable entera, delgada, entre el H1 y el buscador pegajoso. */
.collection-sendlist {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin: 0 0 1rem;
  padding: 0.85rem 1.1rem;
  background: var(--theme-accent-soft);
  border: 1px solid color-mix(in srgb, var(--theme-accent) 35%, var(--theme-border));
  border-radius: var(--ui-radius-md);
  color: var(--theme-ink);
}
.collection-sendlist:hover { text-decoration: none; border-color: var(--theme-accent); }
.collection-sendlist__icon { flex: none; width: 1.7rem; height: 1.7rem; color: var(--theme-accent); }
.collection-sendlist__text { flex: 1 1 auto; min-width: 0; font-size: 0.92rem; line-height: 1.4; color: var(--theme-ink-soft); }
.collection-sendlist__text strong { display: block; color: var(--theme-ink); }
.collection-sendlist__cta {
  flex: none;
  padding: 0.5rem 1.1rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: #fff;
  font-weight: 700;
  font-size: 0.9rem;
  white-space: nowrap;
}
.collection-sendlist:hover .collection-sendlist__cta { filter: brightness(0.93); }
@media (max-width: 640px) {
  .collection-sendlist { flex-wrap: wrap; }
  .collection-sendlist__cta { margin-left: auto; }
}

/* Enlace de vuelta a Mis listas en la cabecera de la lista (solo dueño). */
.list-detail__mylists { margin: 0 0 0.5rem; font-size: 0.85rem; }
.list-detail__mylists a { color: var(--theme-accent); font-weight: 600; }

/* «Crear otra lista» en la cabecera: acción secundaria, en fantasma, para que no
   compite con el veredicto («Ver tus libros en X»), que es lo que convierte. */
.list-detail__new { margin: 0.6rem 0 0; }
.list-detail__new-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  color: var(--theme-accent);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.list-detail__new-btn:hover { border-color: var(--theme-accent); background: var(--theme-accent-soft); }
.list-detail__new-btn:focus-visible { outline: 2px solid var(--ui-accent-ring); outline-offset: 2px; }

/* Renombrar la lista (details CSS-only en la cabecera, solo dueño). */
.list-rename { margin-top: 0.75rem; }
.list-rename__summary {
  display: inline-block;
  cursor: pointer;
  color: var(--theme-accent);
  font-size: 0.88rem;
  font-weight: 600;
}
.list-rename__summary:hover { text-decoration: underline; }
.list-rename__form { display: flex; gap: 0.5rem; margin-top: 0.6rem; max-width: 28rem; }
.list-rename__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  font: inherit;
}
.list-rename__submit {
  flex: none;
  padding: 0.5rem 1.1rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.list-rename__submit:hover { filter: brightness(0.93); }

/* Lista sin libros catalogados: que nunca sea una página muerta. */
.list-empty {
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  background: var(--theme-surface);
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-lg);
}
.list-empty__title { margin: 0 0 0.5rem; font-size: 1.15rem; }
.list-empty__text { margin: 0 0 1rem; color: var(--theme-ink-soft); }
.list-empty__alt { margin: 0.85rem 0 0; font-size: 0.9rem; }
.list-empty .list-add { margin-top: 0; }

/* Botón borrar en Mis listas + insignia de publicada. */
.mylists__delete { margin: 0; flex: none; }
.mylists__badge--promoted { background: var(--theme-surface-alt); color: var(--theme-ink-soft); }

/* Botón quitar (esquina del item; el item es un grid, así que va absoluto). */
.list-item { position: relative; }
.list-item__title { padding-right: 1.6rem; }
.list-item__remove { position: absolute; top: 0.4rem; right: 0.4rem; margin: 0; }
.list-item__remove-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0;
  border: 1px solid var(--theme-border);
  border-radius: 50%;
  background: var(--theme-surface);
  color: var(--theme-ink-muted);
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
}
.list-item__remove-btn:hover { border-color: #d23; color: #d23; background: color-mix(in srgb, #d23 8%, #fff); }

.list-contents { margin: 1.25rem 0; }
.list-contents__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 0 0 0.6rem;
}
.list-contents__title { font-size: 1.05rem; margin: 0; }
.list-contents__clear { margin: 0; }
.list-contents__clear-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.85rem;
  border-radius: var(--ui-radius-pill);
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  color: var(--theme-ink-soft);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}
.list-contents__clear-btn:hover {
  border-color: var(--theme-danger);
  color: var(--theme-danger);
  background: #fdf1f1;
}
.list-contents__clear-btn svg { width: 0.95rem; height: 0.95rem; }
.list-contents__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.list-contents__item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.65rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
}
.list-contents__cover { width: 36px; height: 50px; object-fit: cover; border-radius: var(--ui-radius-sm); flex: none; }
.list-contents__cover--ph { display: inline-flex; align-items: center; justify-content: center; background: var(--theme-accent-soft); font-size: 1.1rem; }
.list-contents__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.list-contents__name { color: var(--theme-ink); font-size: 0.92rem; font-weight: 600; }
.list-contents__name:hover { color: var(--theme-accent); text-decoration: none; }
.list-contents__isbn {
  align-self: flex-start;
  padding: 0.12rem 0.5rem;
  border-radius: var(--ui-radius-sm);
  background: var(--theme-accent-soft);
  color: var(--theme-ink-soft);
  font-weight: 700;
  font-size: 0.82rem;
  font-family: var(--theme-font-mono);
  letter-spacing: 0.04em;
}
.list-contents__remove { flex: none; margin: 0; }

.list-missing { margin-top: 1.5rem; }
.list-missing__lead { color: var(--theme-ink-muted); font-size: 0.9rem; margin: 0 0 0.75rem; }
.list-missing__items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.list-missing__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-sm);
}
.list-missing__item form { margin: 0; }
.list-missing__isbn { font-family: var(--theme-font-mono); font-size: 0.88rem; }

.list-buys__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.list-buy-card {
  flex: 1 1 240px;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  padding: 1rem 1.1rem;
  background: var(--theme-bg);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.list-buy-card--best {
  border-color: var(--theme-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--theme-accent) 12%, transparent);
}
.list-buy-card--cdl { border-style: dashed; }
/* La opción "comprar todo de una vez" destaca: la librería más barata ocupa
   todo el ancho como tarjeta-héroe; el resto fluyen en la rejilla debajo. */
.list-buys__grid .list-buy-card--best {
  flex-basis: 100%;
  background: color-mix(in srgb, var(--theme-accent) 6%, var(--theme-surface));
}
.list-buys__grid .list-buy-card--best .list-buy-card__total dd { font-size: 1.4rem; }
.list-buys__grid .list-buy-card--best .list-buy-card__cta { padding: 0.8rem 1.2rem; font-size: 1rem; }
.list-buy-card__head { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.list-buy-card__swatch { display: inline-block; width: 0.85rem; height: 0.85rem; border-radius: var(--ui-radius-sm); }
.list-buy-card__logo { width: 22px; height: 22px; object-fit: contain; flex: none; border-radius: var(--ui-radius-sm); }
.list-buy-card__merchant { font-weight: 600; }
.list-buy-card__badge {
  background: var(--theme-accent);
  color: var(--theme-surface);
  border-radius: var(--ui-radius-pill);
  padding: 0.1rem 0.65rem;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.list-buy-card__stats { margin: 0; display: grid; gap: 0.35rem 0.75rem; grid-template-columns: 1fr 1fr; }
.list-buy-card__stats > div { display: flex; flex-direction: column; }
.list-buy-card__stats dt {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--theme-ink-muted);
  margin: 0;
}
.list-buy-card__stats dd { margin: 0; font-weight: 600; font-family: var(--theme-font-heading); }
.list-buy-card__total dd { color: var(--theme-accent); font-size: 1.15rem; }
.list-buy-card__cta {
  display: inline-block;
  padding: 0.55rem 0.95rem;
  background: var(--theme-accent);
  color: var(--theme-surface);
  border-radius: var(--ui-radius-cta);
  font-weight: 600;
  font-size: 0.9rem;
  text-align: center;
}
.list-buy-card__cta:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }
.list-buy-card__missing { font-size: 0.85rem; color: var(--theme-ink-muted); }
.list-buy-card__missing summary { cursor: pointer; }
.list-buy-card__missing ul { margin: 0.4rem 0 0; padding-left: 1.25rem; }

/* Librerías sin cesta multi-ítem (Awin): el CTA es un <summary> que despliega
   los N libros, cada uno con su enlace afiliado. CSP-safe (sin JS). */
.list-buy-card__shop, .list-cdl-highlight__shop { display: flex; flex-direction: column; gap: 0.6rem; }
.list-buy-card__cta--shop { cursor: pointer; list-style: none; }
.list-buy-card__cta--shop::-webkit-details-marker { display: none; }
.list-cdl-highlight__shop > summary.list-cdl-highlight__cta { cursor: pointer; list-style: none; }
.list-cdl-highlight__shop > summary.list-cdl-highlight__cta::-webkit-details-marker { display: none; }
.list-buy-card__shop-note, .list-cdl-highlight__shop-note {
  font-size: 0.82rem;
  color: var(--theme-ink-muted);
  margin: 0;
}
.list-buy-card__items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.45rem; }
.list-buy-card__item { display: flex; align-items: center; gap: 0.6rem; font-size: 0.9rem; }
.list-buy-card__item-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--theme-ink);
  font-weight: 500;
}
.list-buy-card__item-title:hover { color: var(--theme-accent); }
.list-buy-card__item-price { flex: none; font-family: var(--theme-font-heading); font-weight: 600; color: var(--theme-ink); }
.list-buy-card__item-buy {
  flex: none;
  padding: 0.35rem 0.8rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font-size: 0.82rem;
  font-weight: 700;
}
.list-buy-card__item-buy:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }

.list-matrix__scroll { overflow-x: auto; }
.list-matrix__table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.list-matrix__table th, .list-matrix__table td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--theme-border);
  text-align: left;
}
.list-matrix__table thead th {
  background: var(--theme-bg);
  color: var(--theme-ink-muted);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
}
.list-matrix__cell { font-family: var(--theme-font-heading); }
.list-matrix__cell--empty { color: var(--theme-ink-muted); }
.list-matrix__book { font-weight: 500; }

.list-items__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.list-item {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: 80px 1fr;
  padding: 0.85rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-bg);
}
.list-item--pending { opacity: 0.7; }
.list-item__cover {
  width: 80px;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface-alt);
}
.list-item__cover--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.75rem;
  color: var(--theme-ink-muted);
}
.list-item__title { margin: 0 0 0.2rem; font-size: 0.98rem; }
.list-item__authors, .list-item__isbn { margin: 0; color: var(--theme-ink-muted); font-size: 0.82rem; }
.list-item__offers { list-style: none; margin: 0.5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.list-item__offer { display: flex; gap: 0.5rem; align-items: center; font-size: 0.85rem; }
.list-item__offer-merchant { color: var(--theme-ink-soft); }
.list-item__offer-price { font-family: var(--theme-font-heading); font-weight: 600; margin-left: auto; }
/* Era un «Ir» en texto plano de 0,82rem: el enlace más débil del sitio estaba
   justo donde ocurre la conversión, con menos peso visual que el precio que
   tiene al lado. Pasa a botón compacto — no puede crecer más porque hay hasta
   cuatro por libro y la fila es estrecha en móvil. */
.list-item__offer-link {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--theme-accent);
  border-radius: var(--ui-radius-pill);
  color: var(--theme-accent);
  background: transparent;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.list-item__offer-link::after {
  content: '›';
  font-size: 1.05em;
  line-height: 1;
}

.list-item__offer-link:hover,
.list-item__offer-link:focus-visible {
  background: var(--theme-accent);
  color: #fff;
  text-decoration: none;
  box-shadow: 0 2px 8px color-mix(in srgb, var(--theme-accent) 30%, transparent);
}
.list-item__empty { color: var(--theme-ink-muted); font-size: 0.85rem; margin: 0.4rem 0 0; }

/* ------------------------- Best price card (ISBN) ----------------------- */

.best-price-card {
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-accent);
  border-radius: var(--ui-radius-lg);
  padding: 1.25rem;
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--theme-accent) 10%, transparent);
}
.best-price-card__label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--theme-ink-muted);
}
.best-price-card__price {
  font-family: var(--theme-font-heading);
  font-size: 2.25rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--theme-accent);
  margin: 0;
}
.best-price-card__merchant { color: var(--theme-ink-soft); font-size: 0.95rem; margin: 0; }
.best-price-card__savings {
  margin: 0;
  font-size: 0.88rem;
  color: color-mix(in srgb, var(--theme-success) 78%, #000 22%);
  font-weight: 600;
}
.best-price-card__savings strong { font-weight: 800; }
.best-price-card__cta {
  margin-top: 0.5rem;
  padding: 0.7rem 1rem;
  background: var(--theme-accent);
  color: var(--theme-surface);
  text-align: center;
  border-radius: var(--ui-radius-cta);
  font-weight: 600;
}
.best-price-card__cta:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }
.best-price-card__foot { margin: 0; text-align: center; font-size: 0.82rem; }
.best-price-card__foot a { color: var(--theme-ink-soft); }
.best-price-card__foot a:hover { color: var(--theme-accent); }
.best-price-card--empty { border-color: var(--theme-border); box-shadow: none; }
.best-price-card--empty .best-price-card__merchant { color: var(--theme-ink-muted); }

/* =========================================================================
   CAPA UI "PRO" — componentes reutilizables (eyebrow, section-head, botones
   pill, chips, banda de estadísticas, hero-pill, landing del comparador).
   Inspirada en el directorio de gasolineras pero construida sobre los tokens
   `--theme-*` del proyecto. Es transversal a todos los presets; la capa
   `body.theme-confeti` de más abajo la refina para el look azul por defecto.
   ========================================================================= */

/* Eyebrow: etiqueta superior en mayúsculas con tracking amplio. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--theme-font-body);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--theme-accent);
}

/* Section head: eyebrow + título + (opcional) descripción + CTA a la derecha. */
.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  margin: 0 0 1.5rem;
}
.section-head__text { min-width: 0; }
.section-head__title {
  font-family: var(--theme-font-heading);
  font-weight: 700;
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0.35rem 0 0;
  color: var(--theme-ink);
}
.section-head__title em { font-style: normal; color: var(--theme-accent); }
.section-head__desc {
  margin: 0.6rem 0 0;
  color: var(--theme-ink-soft);
  font-size: 0.98rem;
  max-width: 42rem;
  line-height: 1.55;
}
.section-head--center { justify-content: center; text-align: center; }
.section-head--center .section-head__text { display: flex; flex-direction: column; align-items: center; }
.section-head--center .section-head__desc { margin-inline: auto; }

/* Botones pill (estilo directorio). */
.btn-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.72rem 1.4rem;
  border-radius: var(--ui-radius-pill);
  font-family: var(--theme-font-body);
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.btn-pill svg { width: 1.05em; height: 1.05em; }
.btn-pill--accent {
  background: var(--theme-accent);
  color: #fff;
  box-shadow: var(--ui-shadow-accent);
}
.btn-pill--accent:hover,
.btn-pill--accent:focus {
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 16px 38px color-mix(in srgb, var(--theme-accent) 38%, transparent);
}
.btn-pill--outline {
  background: var(--theme-surface);
  color: var(--theme-ink);
  border-color: var(--theme-border);
  box-shadow: var(--ui-shadow-sm);
}
.btn-pill--outline:hover,
.btn-pill--outline:focus {
  color: var(--theme-accent);
  border-color: var(--theme-accent);
  text-decoration: none;
  transform: translateY(-1px);
}
.btn-pill--ghost-light {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.32);
  backdrop-filter: blur(4px);
}
.btn-pill--ghost-light:hover,
.btn-pill--ghost-light:focus {
  background: rgba(255, 255, 255, 0.26);
  color: #fff;
  text-decoration: none;
}

/* Chips / pills informativas pequeñas. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.7rem;
  border-radius: var(--ui-radius-pill);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--theme-surface-alt);
  color: var(--theme-ink-soft);
  border: 1px solid var(--theme-border);
}
.chip--accent { background: var(--theme-accent-soft); color: var(--theme-accent); border-color: transparent; }
.chip--success { background: color-mix(in srgb, var(--theme-success) 14%, #fff); color: var(--theme-success); border-color: transparent; }

/* Banda oscura de estadísticas (números clave) — equivalente al "averages
   strip" del directorio. */
.stats-band {
  position: relative;
  overflow: hidden;
  background: var(--theme-ink);
  color: #fff;
  border-radius: var(--ui-radius-xl);
  padding: 1.6rem 1.75rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1.25rem;
}
.stats-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255, 255, 255, 0.06) 1px, transparent 1px);
  background-size: 20px 20px;
  pointer-events: none;
}
.stats-band__item { position: relative; display: flex; flex-direction: column; gap: 0.25rem; }
.stats-band__value {
  font-family: var(--theme-font-heading);
  font-weight: 800;
  font-size: 1.7rem;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.stats-band__label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
.stats-band__meta { font-size: 0.78rem; color: rgba(255, 255, 255, 0.5); }

/* =========================================================================
   COMPARADOR DE LISTA — landing `/comparar`.
   El textarea es el protagonista: hero amplio, tarjeta blanca elevada.
   ========================================================================= */
.compare-landing {
  margin: 0;
}
.compare-landing__eyebrow {
  display: flex;
  justify-content: center;
  margin-bottom: 0.85rem;
}
.compare-landing__title {
  font-family: var(--theme-font-heading);
  font-weight: 600;
  font-size: clamp(1.8rem, 4.5vw, 2.9rem);
  line-height: 1.06;
  letter-spacing: -0.025em;
  margin: 0 0 0.6rem;
  text-align: center;
}
.compare-landing__lead {
  text-align: center;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  color: var(--theme-ink-soft);
  max-width: 46rem;
  margin: 0 auto 1.75rem;
}
.compare-landing__error {
  max-width: 44rem;
  margin: 0 auto 1.25rem;
  padding: 0.85rem 1.1rem;
  border-radius: var(--ui-radius-md);
  background: color-mix(in srgb, var(--theme-danger) 10%, #fff);
  border: 1px solid color-mix(in srgb, var(--theme-danger) 35%, transparent);
  color: var(--theme-danger);
  font-weight: 600;
  text-align: center;
}
/* Confirmación de «Crear otra lista» (?nueva=1): mismo hueco que el error, pero
   en verde de «hecho», no en rojo de «algo va mal». */
.compare-landing__fresh {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  max-width: 44rem;
  margin: 0 auto 1.25rem;
  padding: 0.75rem 1.1rem;
  border-radius: var(--ui-radius-md);
  background: color-mix(in srgb, var(--theme-success, var(--theme-success)) 10%, #fff);
  border: 1px solid color-mix(in srgb, var(--theme-success, var(--theme-success)) 32%, transparent);
  color: color-mix(in srgb, var(--theme-success, var(--theme-success)) 78%, #000);
  font-size: 0.92rem;
  text-align: left;
}
.compare-landing__fresh svg { flex: none; }
.compare-card {
  max-width: 48rem;
  margin: 0 auto;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-xl);
  box-shadow: var(--ui-shadow-lg);
  padding: clamp(1.25rem, 3vw, 2rem);
}
.compare-card__steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 0 0 1.1rem;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
  color: var(--theme-ink-muted);
}
.compare-card__steps li { display: inline-flex; align-items: center; gap: 0.4rem; }
.compare-card__steps b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
  font-size: 0.75rem;
  font-weight: 800;
}
.compare-form { display: flex; flex-direction: column; gap: 0.9rem; }
.compare-form__label {
  font-size: 0.92rem;
  color: var(--theme-ink-soft);
  line-height: 1.5;
}
.compare-form__textarea {
  width: 100%;
  min-height: 190px;
  resize: vertical;
  padding: 1rem 1.1rem;
  border: 1.5px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  background: var(--theme-bg);
  color: var(--theme-ink);
  font-family: var(--theme-font-mono);
  font-size: 0.98rem;
  line-height: 1.7;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
/* En la HOME la caja nace pequeña; en /comparar se queda alta.
   Son dos momentos distintos: a /comparar se llega con la lista ya copiada y
   una caja grande invita a pegarla, pero en la home el visitante todavía está
   entendiendo qué es esto, y 190 px de textarea vacío empujaban la franja de
   librerías y las categorías fuera del viewport (medido a 1512x795).
   `field-sizing: content` la hace crecer al escribir donde está soportado; el
   `min-height` es el suelo para el resto. */
.hero .compare-form__textarea {
  min-height: 96px;
  field-sizing: content;
}

.compare-form__textarea::placeholder { color: var(--theme-ink-muted); }
.compare-form__textarea:focus {
  outline: none;
  border-color: var(--theme-accent);
  box-shadow: 0 0 0 4px var(--ui-accent-ring);
}
.compare-form__submit {
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 0.95rem 1.6rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: #fff;
  font-family: var(--theme-font-body);
  font-weight: 700;
  font-size: 1.05rem;
  cursor: pointer;
  box-shadow: var(--ui-shadow-accent);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.compare-form__submit-icon { width: 1.2rem; height: 1.2rem; flex-shrink: 0; }
.compare-form__submit:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 38px color-mix(in srgb, var(--theme-accent) 38%, transparent);
}
.compare-landing__alt {
  text-align: center;
  margin: 1.5rem auto 0;
  color: var(--theme-ink-soft);
  font-size: 0.95rem;
}

/* Banda «te lo hacemos nosotros» bajo el comparador del hero. Translúcida sobre
   la banda azul: tiene que verse sin competir con la tarjeta blanca, que es la
   acción principal. Una sola línea en escritorio para no deshacer lo que se
   ganó al compactar el hero. */
.hero-handoff {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  flex-wrap: wrap;
  max-width: 48rem;
  margin: 1.1rem auto 0;
  padding: 0.7rem 1rem;
  border-radius: var(--ui-radius-lg);
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  text-align: left;
}
.hero-handoff__icon { width: 1.5rem; height: 1.5rem; flex: none; color: var(--theme-accent); }
/* Encogible: sin esto el bloque de texto pide su ancho natural, no cabe con el
   icono y el botón, y el botón se cae a una segunda fila. */
.hero-handoff__text { flex: 1 1 14rem; margin: 0; font-size: 0.92rem; line-height: 1.4; color: var(--theme-ink-soft); }
.hero-handoff__text strong { display: block; color: var(--theme-ink); font-size: 0.98rem; }
.hero-handoff__cta {
  flex: none;
  padding: 0.5rem 1.1rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font-weight: 700;
  font-size: 0.92rem;
  white-space: nowrap;
}
.hero-handoff__cta:hover { filter: brightness(0.93); color: var(--theme-surface); text-decoration: none; }
@media (max-width: 719px) {
  .hero-handoff { flex-direction: column; text-align: center; gap: 0.6rem; padding: 0.9rem; }
  /* El eje principal pasa a ser vertical, así que aquel `flex-basis: 14rem` del
     texto deja de ser ancho y se convierte en ALTURA: la banda se iba a 336 px.
     En columna cada hijo ocupa lo que ocupa. */
  .hero-handoff__text { flex: 0 1 auto; }
  .hero-handoff__cta { width: 100%; text-align: center; }
}

/* Tira de confianza / "trust" debajo de un hero o landing. */
.trust-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem 1.4rem;
  margin: 1.5rem auto 0;
  padding: 0;
  list-style: none;
  max-width: 52rem;
}
.trust-row li {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.88rem;
  color: var(--theme-ink-soft);
  font-weight: 600;
}
.trust-row svg { width: 1.05rem; height: 1.05rem; color: var(--theme-accent); flex-shrink: 0; }

/* MÓVIL: tres columnas, no tres filas. Apiladas se comían media pantalla del
   hero, que es donde está el formulario. En columnas con el ✓ encima ocupan un
   tercio y se leen como argumentos en vez de como tres botones que no lo son. */
@media (max-width: 719px) {
  .trust-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.5rem;
    align-items: start;
  }
  .trust-row li {
    flex-direction: column;
    gap: 0.3rem;
    text-align: center;
    font-size: 0.74rem;
    line-height: 1.25;
  }
}

/* =========================================================================
   Página "Cómo funciona" (/como-funciona): hero centrado + 4 pasos + CTA.
   ========================================================================= */
/* Botón blanco para usar sobre fondos de marca (hero/CTA azules). */
.btn-pill--light {
  background: #fff;
  color: var(--theme-accent);
  box-shadow: 0 10px 28px rgba(8, 30, 60, 0.22);
}
.btn-pill--light:hover,
.btn-pill--light:focus {
  color: var(--theme-accent);
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: 0 14px 34px rgba(8, 30, 60, 0.28);
}

/* Hero con degradado de marca (mismo lenguaje que el hero de la home). */
.howto-hero {
  text-align: center;
  margin-top: 0.5rem;
  padding: clamp(2.5rem, 6vw, 4rem) clamp(1.25rem, 4vw, 2.5rem);
  background: var(--pl-hero, linear-gradient(135deg, color-mix(in srgb, var(--theme-accent) 82%, #fff) 0%, var(--theme-accent) 52%, var(--ui-accent-strong) 100%));
  border-radius: var(--ui-radius-xl);
  color: #fff;
  box-shadow: var(--ui-shadow);
}
.howto-hero__eyebrow {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.88);
  padding: 0.32rem 0.9rem;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--ui-radius-pill);
}
.howto-hero__title {
  font-family: var(--theme-font-heading);
  font-weight: 600;
  font-size: clamp(1.8rem, 4.5vw, 2.9rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 1rem auto 0.9rem;
  max-width: 22ch;
  color: #fff;
}
.howto-hero__lead {
  font-size: clamp(1.02rem, 1.7vw, 1.18rem);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.92);
  margin: 0 auto;
  max-width: 44rem;
}
.howto-hero__actions { margin-top: 1.6rem; }

/* Los pasos iban en CUATRO COLUMNAS estrechas. Para el publico de esta pagina
   —gente que no usa comparadores— eso es lo contrario de claro: cuatro cajas en
   paralelo se leen como cuatro opciones, no como una secuencia, y obligan a
   apretar el texto. En una sola columna se lee como lo que es, «primero esto,
   luego esto», y cabe explicar cada paso sin telegrafiar. */
.howto-steps {
  list-style: none;
  margin: clamp(2rem, 5vw, 3.25rem) auto;
  padding: 0;
  display: grid;
  gap: 1.25rem;
  /* UNA tarjeta por fila. El 2x2 que probé antes dejaba huecos por
     construcción: los pasos miden 608, 278, 278 y 389 px de alto, así que al
     emparejarlos siempre quedaba media fila vacía al lado del corto. Sin vecina
     no hay hueco posible; el ancho se aprovecha DENTRO de cada tarjeta, con el
     reparto en bandas de abajo. */
  grid-template-columns: 1fr;
}
/* Tres bandas: [título] [explicación] [lo que verás]. Así una tarjeta de ancho
   completo no deja el texto colgando a la izquierda con 800 px de blanco a la
   derecha, y de paso cada banda vuelve a una medida de lectura sana (~650 px la
   del cuerpo). Lo que ocupa dos columnas —las tres formas del paso 1, el aviso
   del paso 4— se declara abajo con `grid-column`. */
.howto-step {
  position: relative;
  display: grid;
  grid-template-columns: minmax(11rem, 1fr) 1.7fr 1.1fr;
  column-gap: clamp(1.25rem, 2.5vw, 2.25rem);
  row-gap: 0.7rem;
  align-items: start;
  padding: 2rem 1.5rem 1.6rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-xl);
  box-shadow: var(--ui-shadow-sm);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.howto-step:hover {
  transform: translateY(-3px);
  box-shadow: var(--ui-shadow);
  border-color: color-mix(in srgb, var(--theme-accent) 30%, var(--theme-border));
}
.howto-step__num {
  position: absolute;
  top: -0.9rem;
  left: 1.35rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: #fff;
  font-weight: 800;
  font-size: 1rem;
  box-shadow: var(--ui-shadow-accent);
}
/* Los iconos abstractos (un codigo de barras, una balanza, un cubo 3D) se han
   quitado del marcado: no ilustraban nada que el titulo no dijera mejor, y en
   una columna unica ocupaban el sitio del texto que si hace falta. */
/* La ilustración encabeza la banda del título; la explicación y «lo que verás»
   pasan a ocupar las dos filas para que no queden huecos a su derecha. */
.howto-step .step-art {
  grid-column: 1;
  grid-row: 1;
  width: 112px;
  height: 84px;
  margin-bottom: 0.2rem;
}
.howto-step__title {
  grid-column: 1;
  grid-row: 2;
  font-family: var(--theme-font-heading);
  font-size: 1.22rem;
  font-weight: 700;
  line-height: 1.25;
  margin: 0.3rem 0 0;
  color: var(--theme-ink);
}
.howto-step__body {
  grid-column: 2;
  grid-row: 1 / span 2;
  margin: 0;
  /* 1.02rem y no 0.94: buena parte de quien llega a esta pagina lee con gafas.
     Es la razon por la que existe la pagina; la tipografia va a juego. */
  font-size: 1.02rem;
  line-height: 1.65;
  color: var(--theme-ink-soft);
}
/* Las tres formas de empezar el paso 1. Cada una con su titular en negro para
   que se vea que son ALTERNATIVAS, no tres cosas que hay que hacer. */
.howto-step__ways {
  /* De borde a borde de la tarjeta, no sólo las bandas de la derecha: al pasar
     de 3 cajas de 330 px a 3 de 440 el texto cabe en menos líneas y la altura
     de cada caja baja de 247 a 174 px —justo lo que mide su texto—, así que
     desaparece el hueco que quedaba dentro de las dos cortas. Y de paso llena
     el blanco que quedaba bajo el título, en la banda izquierda. */
  grid-column: 1 / -1;
  list-style: none;
  margin: 0.2rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.7rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  /* Cada caja hasta donde llega su texto. A ancho completo las tres miden ya lo
     mismo, pero en los anchos intermedios la tercera se alarga y con el
     estirado por defecto las otras dos heredaban su altura y se quedaban con un
     blanco dentro. */
  align-items: start;
}
.howto-step__ways li {
  padding: 0.75rem 0.9rem;
  background: var(--theme-surface-alt);
  border-radius: var(--ui-radius-lg);
  font-size: 0.99rem;
  line-height: 1.55;
  color: var(--theme-ink-soft);
}
.howto-step__ways strong {
  display: block;
  color: var(--theme-ink);
  margin-bottom: 0.15rem;
}
/* «Lo que veras»: la frase que le dice a la persona que lo que le ha salido en
   pantalla es lo correcto. Es lo que quita la duda de «me he equivocado». */
.howto-step__see {
  /* En su propia banda a la derecha: el separador deja de ser una línea de
     puntos arriba y pasa a serlo a la izquierda, que es por donde ahora limita
     con la explicación. */
  grid-column: 3;
  grid-row: 1 / span 2;
  margin: 0.3rem 0 0;
  padding: 0 0 0 clamp(1rem, 2vw, 1.5rem);
  border-left: 1px dashed var(--theme-border);
  font-size: 0.96rem;
  line-height: 1.55;
  color: var(--theme-ink-soft);
}
.howto-step__see span {
  display: inline-block;
  margin-right: 0.4rem;
  font-weight: 700;
  color: var(--theme-accent);
}
.howto-step__warn {
  grid-column: 2 / -1;
  margin: 0.3rem 0 0;
  padding: 0.75rem 0.9rem;
  border-left: 3px solid var(--theme-accent);
  background: var(--theme-accent-soft);
  border-radius: 0 var(--ui-radius) var(--ui-radius) 0;
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--theme-ink);
}

/* Por debajo de 900 px las tres bandas no caben sin estrangular el texto: cada
   paso vuelve a ser una columna y «lo que verás» recupera su línea de puntos
   arriba, que es donde vuelve a separar. */
@media (max-width: 899px) {
  .howto-step { grid-template-columns: 1fr; }
  .howto-step .step-art,
  .howto-step__title,
  .howto-step__body,
  .howto-step__ways,
  .howto-step__warn,
  .howto-step__see {
    grid-column: 1;
    grid-row: auto;
  }
  .howto-step__see {
    grid-row: auto;
    padding: 0.7rem 0 0;
    border-left: 0;
    border-top: 1px dashed var(--theme-border);
  }
}

/* Bloque «que es esta web», antes de los pasos. Responde el miedo de fondo
   («¿que me vais a cobrar y a quien le compro?») antes de explicar nada. */
.howto-what {
  margin: clamp(1.5rem, 4vw, 2.25rem) auto 0;
  padding: 1.5rem 1.6rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-top: 4px solid var(--theme-accent);
  border-radius: var(--ui-radius-xl);
}
.howto-what__title {
  margin: 0 0 0.9rem;
  font-family: var(--theme-font-heading);
  font-size: 1.15rem;
}
/* Los tres puntos en columnas al ensanchar la caja: apilados a 1.392 px de
   ancho serían tres renglones larguísimos con un hueco enorme debajo. */
.howto-what__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.85rem 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}
.howto-what__list li {
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--theme-ink-soft);
}
.howto-what__list strong { color: var(--theme-ink); }

/* Salida para quien ha leido todo y sigue sin verlo claro. Mandarle otra vez a
   la herramienta no le sirve: aqui se le ofrece que lo hagamos nosotros. */
.howto-help {
  margin: clamp(1.5rem, 4vw, 2.25rem) auto clamp(2rem, 5vw, 3rem);
  padding: 1.4rem 1.6rem;
  background: var(--theme-surface-alt);
  border-radius: var(--ui-radius-xl);
  text-align: center;
}
.howto-help__title { margin: 0 0 0.5rem; font-family: var(--theme-font-heading); font-size: 1.1rem; }
.howto-help__body { margin: 0 0 1rem; font-size: 1rem; line-height: 1.6; color: var(--theme-ink-soft); }
.howto-help__actions {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  justify-content: center;
}
.howto-help__link {
  font-weight: 700;
  color: var(--theme-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.howto-help__link--soft { font-weight: 500; color: var(--theme-ink-soft); }

.howto-benefits {
  list-style: none;
  margin: clamp(2rem, 5vw, 3rem) 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 760px) { .howto-benefits { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .howto-benefits { grid-template-columns: 1fr; } }
.howto-benefit {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 1rem 1.1rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
}
.howto-benefit svg {
  flex: none;
  width: 1.4rem;
  height: 1.4rem;
  color: var(--theme-accent);
  margin-top: 0.1rem;
}
/* 0.92rem y no 0.85 (~13,6 px): esta pagina existe para quien se maneja peor
   con internet, que suele coincidir con quien lee con gafas. */
.howto-benefit span { display: flex; flex-direction: column; font-size: 0.92rem; line-height: 1.45; color: var(--theme-ink-soft); }
.howto-benefit strong { color: var(--theme-ink); font-size: 0.95rem; margin-bottom: 0.1rem; }

.howto-cta {
  text-align: center;
  margin: clamp(1.5rem, 4vw, 2.5rem) 0 0;
  padding: clamp(2rem, 5vw, 3rem) clamp(1.25rem, 4vw, 2.5rem);
  background: var(--pl-hero, linear-gradient(135deg, color-mix(in srgb, var(--theme-accent) 82%, #fff) 0%, var(--theme-accent) 52%, var(--ui-accent-strong) 100%));
  border-radius: var(--ui-radius-xl);
  color: #fff;
  box-shadow: var(--ui-shadow);
}
.howto-cta__title {
  font-family: var(--theme-font-heading);
  font-weight: 800;
  font-size: clamp(1.4rem, 3vw, 2rem);
  line-height: 1.2;
  margin: 0 0 0.7rem;
  color: #fff;
}
.howto-cta__lead {
  margin: 0 auto 1.4rem;
  max-width: 38rem;
  font-size: 1.02rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.92);
}
.howto-cta__note {
  margin: 1rem 0 0;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.8);
}

/* =========================================================================
   HOME — bloque destacado del comparador de lista (función estrella) y
   variantes visuales de la home.
   ========================================================================= */
.home-compare {
  position: relative;
  overflow: hidden;
  margin: 2.5rem 0;
  padding: clamp(1.75rem, 4vw, 2.75rem);
  border-radius: var(--ui-radius-xl);
  background: var(--theme-ink);
  color: #fff;
  display: grid;
  gap: 1.5rem 2.5rem;
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 860px) {
  .home-compare { grid-template-columns: 1.1fr 0.9fr; }
}
.home-compare::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255, 255, 255, 0.06) 1px, transparent 1px);
  background-size: 22px 22px;
  pointer-events: none;
}
.home-compare__body { position: relative; }
/* Píldora verde en vez de versalitas sueltas (14-ago-2026): sobre el navy, un
   antetítulo en blanco al 85% se leía como un pie de foto —lo mismo que el
   resto del texto, sólo que más pequeño— y no destacaba el bloque, que es lo
   único que hace ahí. El verde es el único color cálido de la paleta que no
   compite con el azul de marca ni con el blanco del CTA principal, y la
   caja-píldora le da el peso que la versalita no tenía.
   `text-transform: none` a propósito: en píldora, las mayúsculas forzadas
   apretaban el texto contra los bordes y perdían legibilidad a 0,72rem. */
.home-compare__eyebrow {
  padding: 0.35rem 0.95rem;
  border-radius: var(--ui-radius-pill);
  background: #2ecf90;
  color: #0c3448;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  opacity: 1;
}
.home-compare__title {
  font-family: var(--theme-font-heading);
  font-weight: 800;
  font-size: clamp(1.55rem, 3vw, 2.2rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0.5rem 0 0.6rem;
  color: #fff;
}
.home-compare__title em {
  font-style: normal;
  color: #fff;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.5);
  text-underline-offset: 5px;
  text-decoration-thickness: 3px;
}
.home-compare__lead {
  margin: 0 0 1.25rem;
  color: rgba(255, 255, 255, 0.86);
  font-size: 1.02rem;
  line-height: 1.6;
  max-width: 32rem;
}
.home-compare__actions { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.home-compare__visual {
  position: relative;
  background: var(--theme-surface);
  color: var(--theme-ink);
  border-radius: var(--ui-radius-lg);
  padding: 1.1rem 1.2rem;
  box-shadow: var(--ui-shadow-lg);
}
.home-compare__visual-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--theme-ink-muted);
}
.home-compare__dot { width: 0.6rem; height: 0.6rem; border-radius: var(--ui-radius-pill); background: var(--theme-accent); }
.home-compare__line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--theme-border);
  font-size: 0.92rem;
}
.home-compare__line:last-child { border-bottom: 0; }
.home-compare__isbn { font-family: var(--theme-font-mono); color: var(--theme-ink-soft); }
.home-compare__price { font-family: var(--theme-font-mono); font-weight: 700; color: var(--theme-accent); }
.home-compare__best {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 2px solid var(--theme-border);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.home-compare__best-label { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-ink-muted); }
.home-compare__best-value { font-family: var(--theme-font-mono); font-weight: 800; font-size: 1.4rem; color: var(--theme-ink); letter-spacing: -0.02em; }

/* =========================================================================
   HOME — hero "comparador": el comparador completo (pestañas + textarea) como
   protagonista del hero. Reutiliza .compare-card y el componente .ctabs__*
   (con ids `hmode-*`). Transversal a todos los presets; planeta lo refina.
   ========================================================================= */
.hero--compare { text-align: center; }
.hero__head { margin: 0 0 1.6rem; }
.hero__head .hero__title { margin-bottom: 0.6rem; }
.hero__head .hero__lead { margin-bottom: 0; }
.hero__head .hero__free { margin-top: 0.95rem; }

/* La tarjeta blanca del comparador centrada dentro del hero. `position` + `z-index`
   crean un contexto de apilado por ENCIMA de las secciones que siguen al hero
   (home-vprops, franja de librerías): sin esto el desplegable del buscador en
   vivo (position:absolute) quedaba tapado por esas secciones al desplegarse. */
.hero-compare-card {
  max-width: 44rem;
  text-align: left;
  position: relative;
  z-index: 40;
}
.hero-compare-card__pretitle {
  margin: 0 0 0.7rem;
  text-align: center;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--theme-ink-muted);
}

/* Explicación plegable "¿No sabes qué es el ISBN?" (sin JS). */
/* "¿Qué es el ISBN?" — modal CSS-only (checkbox-hack, sin JS por la CSP).
   El checkbox oculto controla la visibilidad del overlay vía `:checked ~`. */
.isbn-help__toggle {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  opacity: 0;
  pointer-events: none;
}
.isbn-help__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.9rem;
  width: fit-content;
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--theme-accent);
}
.isbn-help__link-icon { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }
.isbn-help__link:hover { text-decoration: underline; }
.isbn-help__overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 200;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
}
.isbn-help__toggle:checked ~ .isbn-help__overlay { display: flex; }
.isbn-help__backdrop {
  position: absolute;
  inset: 0;
  border: 0;
  background: rgba(8, 30, 60, 0.55);
  cursor: pointer;
}
.isbn-help__dialog {
  position: relative;
  width: min(30rem, 100%);
  padding: 1.7rem 1.5rem 1.5rem;
  background: var(--theme-surface);
  border-radius: var(--ui-radius-md);
  box-shadow: var(--ui-shadow-lg);
  animation: isbn-help-in 0.16s ease-out;
}
@keyframes isbn-help-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.isbn-help__close {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--ui-radius-pill);
  color: var(--theme-ink-soft);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.isbn-help__close svg { width: 1.1rem; height: 1.1rem; }
.isbn-help__close:hover { background: var(--theme-surface-alt); color: var(--theme-ink); }
.isbn-help__title {
  margin: 0 1.8rem 0.55rem 0;
  font-family: var(--theme-font-heading);
  font-weight: 600;
  font-size: 1.2rem;
  color: var(--theme-ink);
}
.isbn-help__text {
  margin: 0;
  color: var(--theme-ink-soft);
  font-size: 0.95rem;
  line-height: 1.6;
}
/* Dibujo de la contraportada con el código de barras. Tamaño contenido: el
   diálogo tiene que caber entero en un móvil sin scroll interno. */
.isbn-help__figure { margin: 0.9rem 0; text-align: center; }
.isbn-help__art { display: block; width: 100%; max-width: 17rem; height: auto; margin: 0 auto; }
.isbn-help__caption {
  margin-top: 0.4rem;
  color: var(--theme-ink-muted);
  font-size: 0.82rem;
}
.isbn-help__art .ih-cover {
  fill: var(--theme-surface);
  stroke: var(--theme-border);
  stroke-width: 2;
}
.isbn-help__art .ih-spine { fill: var(--theme-accent-soft); }
.isbn-help__art .ih-line { fill: var(--theme-border); }
.isbn-help__art .ih-line-soft {
  fill: var(--theme-surface-alt);
  fill: color-mix(in srgb, var(--theme-border) 55%, #fff);
}
.isbn-help__art .ih-box {
  fill: #fff;
  stroke: var(--theme-accent);
  stroke-width: 2;
}
.isbn-help__art .ih-bar rect { fill: var(--theme-ink); }
.isbn-help__art .ih-code {
  fill: var(--theme-ink);
  font-family: var(--theme-font-mono);
  font-size: 11px;
  font-weight: 600;
}

/* =========================================================================
   Tema "Planeta" — look inspirado en planetadelibros.com: blanco, Montserrat,
   azul editorial (var(--theme-accent)), footer azul marino, bandas azules a sangre,
   tarjetas limpias centradas en la portada. Capa ADITIVA scopeada a
   `body.theme-confeti`: no afecta a los presets cuaderno/ticker/patio.
   ========================================================================= */
body.theme-confeti {
  /* Antes #16284b/#20335c: un navy violáceo que no pertenecía a la paleta y
     sólo aparecía en este bloque. Ahora es un tono OSCURO del azul de marca
     (var(--theme-accent)), así que unifica sin renunciar al contraste — si fuera el mismo
     azul del hero, la página sería una plancha azul sin jerarquía. */
  /* Fondo de las bandas oscuras (bloque «por qué comparar», CTA de cierre y
     pie). NO es un tono oscuro del acento, y es deliberado: el hero ya es una
     plancha roja a sangre, y repetir el mismo color en las otras tres bandas
     dejaría la página sin jerarquía —todo grita igual—. Sale del `ink` del
     tema, que es el morado oscuro de la paleta, así que contrasta con el rojo
     sin traer un color de fuera. Sigue al preset: cambiar el tema desde el
     admin mueve también estas bandas. */
  --pl-navy: color-mix(in srgb, var(--theme-ink) 94%, #000);
  --pl-navy-2: color-mix(in srgb, var(--theme-ink) 76%, var(--theme-accent));
  --pl-accent-strong: var(--ui-accent-strong);
  --pl-hero: linear-gradient(135deg, color-mix(in srgb, var(--theme-accent) 82%, #fff) 0%, var(--theme-accent) 52%, var(--ui-accent-strong) 100%);
  background: #ffffff;
  overflow-x: clip;
  font-weight: 400;
}
body.theme-confeti h1, body.theme-confeti h2, body.theme-confeti h3 { letter-spacing: -0.02em; }

/* Header limpio y blanco con marca azul */
body.theme-confeti .site-header { backdrop-filter: none; box-shadow: 0 1px 0 var(--theme-border); }
body.theme-confeti .site-header__logo { background: var(--theme-accent); color: #fff; border-radius: var(--ui-radius-sm); }
body.theme-confeti .site-header__name { color: var(--theme-accent); font-weight: 800; }
body.theme-confeti .site-header__nav a { font-weight: 600; color: var(--theme-ink); }
body.theme-confeti .site-header__nav a:hover { color: var(--theme-accent); }

/* Hero: banda azul a sangre con buscador blanco tipo "pill" */
body.theme-confeti .hero {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-top: calc(-1 * var(--pad-lg));
  /* El `padding` NO va aquí: más abajo hay otro `body.theme-confeti .hero` (el
     del hero protagonista) con la misma especificidad que, por orden de
     aparición, pisaba a este. El que se declaraba aquí llevaba tiempo sin
     aplicarse —con su comentario de «medido a 1512x795» y todo—, así que el
     valor bueno vive en un único sitio: busca «Hero protagonista». */
  background: var(--pl-hero);
  color: #fff;
}
body.theme-confeti .hero::before { display: none; }
body.theme-confeti .hero__eyebrow { background: rgba(255, 255, 255, 0.18); color: #fff; }
body.theme-confeti .hero__title { color: #fff; font-weight: 600; }
body.theme-confeti .hero__title strong {
  color: #fff;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.55);
  text-underline-offset: 5px;
  text-decoration-thickness: 3px;
}
body.theme-confeti .hero__lead { color: rgba(255, 255, 255, 0.93); }
body.theme-confeti .hero__search {
  background: #fff;
  border: 0;
  border-radius: var(--ui-radius-pill);
  padding: 0.4rem 0.4rem 0.4rem 0.65rem;
  box-shadow: 0 16px 38px rgba(8, 30, 60, 0.30);
}
body.theme-confeti .hero__search button { border-radius: var(--ui-radius-cta); background: var(--theme-accent); }
body.theme-confeti .hero__search button:hover { background: var(--pl-accent-strong); filter: none; }
body.theme-confeti .hero__hint { color: rgba(255, 255, 255, 0.92); }
body.theme-confeti .hero__hint a { color: #fff; border-bottom-color: rgba(255, 255, 255, 0.6); }

/* Títulos de sección centrados y en negrita (estilo Planeta) */
body.theme-confeti .features__title,
body.theme-confeti .how-it-works h2,
body.theme-confeti .collection__title,
body.theme-confeti .section-title {
  text-align: center;
  font-weight: 600;
  color: var(--theme-ink);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
}

/* Tarjetas de "por qué usarnos" limpias */
body.theme-confeti .features__item {
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-md);
  box-shadow: none;
  transition: border-color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
}
body.theme-confeti .features__item:hover {
  border-color: var(--theme-accent);
  box-shadow: 0 10px 26px rgba(31, 27, 46, 0.10);
  transform: translateY(-2px);
}
body.theme-confeti .features__icon { background: var(--theme-accent-soft); color: var(--theme-accent); }
body.theme-confeti .how-it-works__num { background: var(--theme-accent); color: #fff; }

/* Tarjetas de libro: limpias, foco en la portada */
body.theme-confeti .book-card { border: 1px solid var(--theme-border); border-radius: var(--ui-radius-md); box-shadow: none; }
body.theme-confeti .book-card:hover { box-shadow: 0 12px 28px rgba(31, 27, 46, 0.12); border-color: color-mix(in srgb, var(--theme-accent) 30%, var(--theme-border)); }
body.theme-confeti .book-card__price strong { font-family: var(--theme-font-heading); font-weight: 800; font-variant-numeric: tabular-nums; }

/* Footer azul marino con columnas (estilo Planeta) */
body.theme-confeti .site-footer {
  background: var(--pl-navy);
  border-top: 0;
  color: rgba(255, 255, 255, 0.80);
  margin-top: 3rem;
  padding-top: 0.5rem;
}
body.theme-confeti .site-footer__inner {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr;
  gap: 1.75rem 2rem;
  align-items: start;
  padding-top: 2.75rem;
  padding-bottom: 1.75rem;
}
body.theme-confeti .site-footer__logo {
  background: rgba(255, 255, 255, 0.12);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
}
body.theme-confeti .site-footer__brand { color: #fff; font-weight: 800; font-size: 1.15rem; }
body.theme-confeti .site-footer__tagline { color: rgba(255, 255, 255, 0.7); max-width: 320px; }
body.theme-confeti .site-footer__compare { color: rgba(255, 255, 255, 0.46); max-width: 320px; }
body.theme-confeti .site-footer__col { display: flex; flex-direction: column; gap: 0.55rem; }
body.theme-confeti .site-footer__heading {
  margin: 0 0 0.35rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: color-mix(in srgb, var(--theme-accent) 55%, #fff);
}
body.theme-confeti .site-footer__col a { color: rgba(255, 255, 255, 0.82); font-size: 0.92rem; }
body.theme-confeti .site-footer__col a:hover { color: #fff; text-decoration: none; }
body.theme-confeti .site-footer__bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  padding: 1.2rem 1rem 1.7rem;
}
body.theme-confeti .site-footer__meta { color: rgba(255, 255, 255, 0.52); }
body.theme-confeti .site-footer__made { color: rgba(255, 255, 255, 0.52); }
@media (max-width: 859px) {
  body.theme-confeti .site-footer__inner { grid-template-columns: 1fr 1fr; }
  body.theme-confeti .site-footer__brandcol { grid-column: 1 / -1; }
}
/* El acordeón necesita una sola columna: en dos, cada sección lleva su filete
   superior y la rejilla los desalinea. Va aquí porque `body.theme-confeti` gana
   por especificidad a la regla base del mismo breakpoint. */
@media (max-width: 639px) {
  body.theme-confeti .site-footer__inner { grid-template-columns: 1fr; gap: 0; }
  body.theme-confeti .site-footer__col { border-top: 1px solid rgba(255, 255, 255, 0.14); }
  body.theme-confeti .site-footer__heading { color: #fff; }
}
@media (max-width: 460px) {
  body.theme-confeti .site-footer__inner { grid-template-columns: 1fr; }
}

/* =========================================================================
   PLANETA · refinamiento "pro" (rediseño 2026).
   Eleva el preset azul al nivel del directorio de gasolineras: lavado de
   color superior, hero potente con buscador protagonista, header pulido,
   tarjetas con sombras en capas, landing del comparador y home destacando
   la función estrella (pegar la lista de ISBN).
   ========================================================================= */

/* Lavado de color superior + textura de puntos, a sangre y sutil. Imita el
   `body::before` del directorio para dar profundidad al hero sin recargar. */
body.theme-confeti { position: relative; }
body.theme-confeti::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 560px;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(circle, rgba(20, 136, 200, 0.08) 1px, transparent 1px) 0 0 / 22px 22px,
    linear-gradient(180deg, var(--theme-accent-soft) 0%, rgba(238, 246, 252, 0) 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
}
body.theme-confeti main.container,
body.theme-confeti .site-footer { position: relative; z-index: 1; }

/* ---- Header pulido: blanco sólido, marca con icono en degradado,
   navegación con realce y CTA "Comparar lista" destacado. */
body.theme-confeti .site-header {
  /* Sticky en todas las anchuras: por encima del hero a sangre (que vive en
     main.container con z-index:1), tanto en desktop como en móvil. */
  position: sticky;
  top: 0;
  z-index: 30;
  /* Blanco opaco, sin translucidez. Con el 0.86 anterior el contenido se
     transparentaba al hacer scroll por debajo del header —portadas y titulares
     asomando tras la navegación— y el `backdrop-filter` obligaba al navegador a
     recomponer la franja en cada scroll. Opaco no necesita blur ninguno. */
  background: #fff;
  box-shadow: 0 1px 0 var(--theme-border);
}
body.theme-confeti .site-header__inner { gap: 1.1rem; }
body.theme-confeti .site-header__logo {
  background: linear-gradient(135deg, color-mix(in srgb, var(--theme-accent) 82%, #fff) 0%, var(--theme-accent) 55%, var(--pl-accent-strong) 100%);
  color: #fff;
  border-radius: var(--ui-radius-md);
  box-shadow: 0 4px 12px rgba(20, 136, 200, 0.32);
}
body.theme-confeti .site-header__name { font-weight: 800; letter-spacing: -0.02em; color: var(--theme-ink); }
body.theme-confeti .site-header__nav { gap: 0.25rem; }
body.theme-confeti .site-header__nav a {
  padding: 0.45rem 0.7rem;
  border-radius: var(--ui-radius-md);
  font-weight: 600;
  color: var(--theme-ink-soft);
  transition: color 0.14s ease, background-color 0.14s ease;
}
body.theme-confeti .site-header__nav a:hover { background: var(--theme-accent-soft); color: var(--theme-accent); text-decoration: none; }

/* CTA destacado del header (Comparar lista) — pill de acento con sombra. */
body.theme-confeti .site-header__cta {
  border-radius: var(--ui-radius-pill);
  padding: 0.55rem 1.1rem;
  font-weight: 700;
  box-shadow: var(--ui-shadow-accent);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
body.theme-confeti .site-header__cta:hover {
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
  background: var(--pl-accent-strong);
  filter: none;
}

/* ---- Hero protagonista: banda azul a sangre, titular grande, buscador
   pill ancho y elevado, botones secundarios y tira de confianza. */
body.theme-confeti .hero {
  /* Arriba lo mínimo: el hero abre la página, no necesita respiración por
     encima —la da el header— y cada píxel de aquí retrasa el comparador, que es
     lo que se ha venido a usar. De 5,25rem (84 px a 1512) a 2rem (32 px).
     Abajo se conserva más aire porque ahí sí separa de la tarjeta blanca. */
  padding: clamp(1.25rem, 2.2vw, 2rem) 1rem clamp(2rem, 4vw, 3rem);
  /* SIN `overflow: hidden`: recortaba el desplegable del buscador en vivo.
     Medido en producción, el panel pide 448 px y dentro del hero sólo caben
     148: se comía 300 px, o sea 5 de las 8 sugerencias, cortando la tercera por
     la mitad. Y no se arreglaba con `z-index` —ya se intentó, ver el comentario
     de `.hero > .hero-compare-card`—: el recorte de un ancestro no lo levanta
     ningún apilamiento. Lo único que había dentro que pudiera desbordar es el
     `::after` del patrón de puntos, y va con `inset: 0`, así que no desborda. */
}
body.theme-confeti .hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255, 255, 255, 0.08) 1px, transparent 1px);
  background-size: 22px 22px;
  pointer-events: none;
}
body.theme-confeti .hero > * { position: relative; z-index: 1; }
/* La tarjeta del buscador debe quedar por encima de sus hermanos del hero (la
   .trust-row, que va después en el DOM) para que el desplegable de autocompletado
   no quede tapado. Este selector gana en especificidad a la regla `.hero > *`.
   `main.container` es un contexto de apilado en z-index:1 < 30 del header sticky,
   así que subir la tarjeta aquí nunca la solapa con el header. */
body.theme-confeti .hero > .hero-compare-card { z-index: 40; }
body.theme-confeti .hero__eyebrow {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.22);
  padding: 0.32rem 0.85rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  backdrop-filter: blur(4px);
}
body.theme-confeti .hero__title {
  font-size: clamp(2.1rem, 5.6vw, 3.75rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  margin-bottom: 1.1rem;
}
body.theme-confeti .hero__lead {
  font-size: clamp(1.02rem, 1.7vw, 1.25rem);
  color: rgba(255, 255, 255, 0.94);
  max-width: 40rem;
  margin-bottom: 2rem;
}

/* Buscador del hero: pill blanco grande con icono de lupa. */
body.theme-confeti .hero__search {
  max-width: 720px;
  padding: 0.5rem 0.5rem 0.5rem 1.25rem;
  border-radius: var(--ui-radius-pill);
  box-shadow: 0 22px 50px rgba(8, 30, 60, 0.28), 0 4px 14px rgba(8, 30, 60, 0.12);
  border: 1.5px solid rgba(255, 255, 255, 0.5);
  align-items: center;
  gap: 0.4rem;
}
body.theme-confeti .hero__search::before {
  content: "";
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  background: var(--theme-ink-muted);
  -webkit-mask: var(--ui-search-icon) center / contain no-repeat;
  mask: var(--ui-search-icon) center / contain no-repeat;
}
body.theme-confeti .hero__search input {
  font-size: 1.08rem;
  padding: 0.95rem 0.5rem;
}
body.theme-confeti .hero__search button {
  padding: 0.95rem 1.85rem;
  border-radius: var(--ui-radius-pill);
  font-size: 1.05rem;
  font-weight: 700;
  flex-shrink: 0;
}
body.theme-confeti .hero__search button:hover { background: var(--pl-accent-strong); filter: none; }

/* Acciones secundarias bajo el buscador del hero. */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  justify-content: center;
  margin: 1.5rem auto 0;
}
body.theme-confeti .hero__hint { margin-top: 1.4rem; }

/* La tira de confianza dentro del hero azul: texto e iconos en blanco. */
body.theme-confeti .hero .trust-row li {
  color: #fff;
  background: rgba(255, 255, 255, 0.13);
  border: 1px solid rgba(255, 255, 255, 0.22);
  padding: 0.45rem 0.95rem;
  border-radius: var(--ui-radius-pill);
  backdrop-filter: blur(4px);
}
body.theme-confeti .hero .trust-row svg { color: #fff; }
/* En columnas la píldora sobra: tres cajas con borde y fondo dentro de una
   rejilla se leen como botones, y no son pulsables. Queda el ✓ y el texto. */
@media (max-width: 719px) {
  body.theme-confeti .hero .trust-row li {
    background: none;
    border: 0;
    padding: 0;
    backdrop-filter: none;
  }
}

/* ---- Hero "comparador" (home): tarjeta blanca del comparador sobre la banda
   azul. La tarjeta hereda la sombra fuerte de `.compare-card` en planeta. */
body.theme-confeti .hero--compare .hero__title {
  font-size: clamp(1.9rem, 4.8vw, 3.1rem);
  margin-bottom: 0.7rem;
}
/* Entradilla más pequeña y más ancha: a 1,35rem dentro de 40rem caía en TRES
   líneas y el bloque de texto pesaba más que el propio titular. A ~1,1rem en
   54rem entra en dos, se lee igual (sigue por debajo del límite de ~75
   caracteres por línea) y sube el comparador. */
body.theme-confeti .hero--compare .hero__lead {
  font-size: clamp(0.98rem, 1.3vw, 1.12rem);
  max-width: 54rem;
  margin-bottom: 0;
}

/* El H1 de la home en UNA línea también en el móvil.
   Medido en producción con Montserrat 600 y letter-spacing -0,03em (iframes de
   320/360/390/430/719 px sobre la home real): «Comparador de libros de texto»
   necesita ≤6,1vw a 320 px y el margen sólo crece con el ancho (6,5vw a 719).
   El suelo de la clamp de arriba —1,9rem = 30,4 px— lo partía en TRES líneas a
   360 px. 5,9vw entra en todo el rango con ~3% de holgura.
   ⚠️ Va calibrado a un titular de ~30 caracteres: si se alarga desde
   /admin/content hay que volver a medir. */
@media (max-width: 719px) {
  .hero--compare .hero__title,
  body.theme-confeti .hero--compare .hero__title {
    font-size: 5.9vw;
  }
  /* La píldora de «gratis» no puede comerse el alto del hero: es donde está el
     formulario, que es lo que convierte. */
  .hero__free {
    font-size: 0.82rem;
    padding: 0.4rem 0.8rem;
    gap: 0.1rem 0.35rem;
  }
  .hero__free-icon { width: 0.95rem; height: 0.95rem; }
}

body.theme-confeti .hero-compare-card {
  box-shadow: 0 30px 60px rgba(8, 30, 60, 0.30), var(--ui-shadow-md);
}
body.theme-confeti .hero-compare-card .compare-form__submit:hover { background: var(--pl-accent-strong); }

/* Tarjetas de libro un punto más suaves y con elevación al hover. */
body.theme-confeti .book-card { border-radius: var(--ui-radius-md); box-shadow: var(--ui-shadow-sm); }
body.theme-confeti .book-card:hover {
  box-shadow: var(--ui-shadow-md);
  border-color: var(--ui-accent-tint);
  transform: translateY(-3px);
}
body.theme-confeti .book-card__price strong { color: var(--theme-accent); }

/* "Por qué usarnos": iconos en círculo de acento, tarjetas limpias. */
body.theme-confeti .features { padding-top: 2.5rem; }
body.theme-confeti .features__item { border-radius: var(--ui-radius-lg); padding: 1.4rem 1.35rem 1.5rem; }
body.theme-confeti .features__icon {
  width: 2.6rem;
  height: 2.6rem;
  border-radius: var(--ui-radius-md);
  font-size: 1.25rem;
}

/* "Cómo funciona": números en círculo de acento, tarjeta envolvente suave. */
/* Aquí vivía la tarjeta del preset (radio + sombra). Se queda sólo el centrado
   del titular: el marco se retiró en la regla base, y repetirlo aquí —con más
   especificidad— lo habría resucitado. */
body.theme-confeti .how-it-works {
  text-align: center;
}
body.theme-confeti .how-it-works > .eyebrow { justify-content: center; margin-bottom: 0.4rem; }
body.theme-confeti .how-it-works__steps { text-align: left; margin-top: 1.9rem; }
/* La elevación pasa del número al disco del icono: en una chapa de 1,35rem esa
   sombra era una mancha, y en el disco da el relieve que tenía el bloque. */
body.theme-confeti .how-it-works__badge {
  background: color-mix(in srgb, var(--theme-accent) 12%, #fff);
  box-shadow: 0 6px 16px rgba(20, 136, 200, 0.18);
}
body.theme-confeti .how-it-works__num {
  background: linear-gradient(135deg, color-mix(in srgb, var(--theme-accent) 82%, #fff) 0%, var(--theme-accent) 60%, var(--pl-accent-strong) 100%);
}

/* ---- Bloque destacado del comparador de lista en la home (función estrella).
   Ya tiene base transversal en .home-compare; aquí solo afinamos el azul. */
body.theme-confeti .home-compare {
  background: linear-gradient(135deg, var(--pl-navy) 0%, var(--pl-navy-2) 100%);
}
body.theme-confeti .home-compare__title em { text-decoration-color: rgba(127, 180, 221, 0.7); }
body.theme-confeti .home-compare .btn-pill--accent {
  background: #fff;
  color: var(--pl-navy);
  box-shadow: 0 12px 30px rgba(8, 30, 60, 0.3);
}
body.theme-confeti .home-compare .btn-pill--accent:hover { background: var(--theme-accent-soft); color: var(--pl-navy); }

/* ---- Landing `/comparar`: hero azul a sangre + tarjeta del textarea
   superpuesta. El textarea es el protagonista. */
body.theme-confeti .compare-landing {
  position: relative;
}
body.theme-confeti .compare-landing::before {
  content: "";
  position: absolute;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  top: calc(-1 * var(--pad-lg));
  width: 100vw;
  height: 320px;
  z-index: 0;
  background: var(--pl-hero);
  -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
}
body.theme-confeti .compare-landing > * { position: relative; z-index: 1; }
body.theme-confeti .compare-landing__eyebrow { color: #fff; }
body.theme-confeti .compare-landing__title { color: #fff; padding-top: clamp(1rem, 3vw, 2rem); }
body.theme-confeti .compare-landing__lead { color: rgba(255, 255, 255, 0.95); }
body.theme-confeti .compare-card { box-shadow: 0 30px 60px rgba(8, 30, 60, 0.22), var(--ui-shadow-md); }
body.theme-confeti .compare-form__submit:hover { background: var(--pl-accent-strong); }

/* ---- Banda de estadísticas: en planeta usamos el navy editorial. */
body.theme-confeti .stats-band {
  background: linear-gradient(135deg, var(--pl-navy) 0%, var(--pl-navy-2) 100%);
}
body.theme-confeti .stats-band__value { color: #fff; }

/* ---- Página de ficha (ISBN): cabecera con sutil degradado y mejor
   jerarquía del bloque "mejor precio". */
body.theme-confeti .book-detail__header { border-radius: var(--ui-radius-xl); box-shadow: var(--ui-shadow-sm); }
body.theme-confeti .best-price-card {
  border-radius: var(--ui-radius-lg);
  background: linear-gradient(135deg, var(--theme-accent-soft) 0%, #fff 100%);
  box-shadow: var(--ui-shadow-md);
}
body.theme-confeti .best-price-card__cta { border-radius: var(--ui-radius-cta); padding: 0.8rem 1.1rem; font-weight: 700; }
body.theme-confeti .best-price-card__cta:hover { background: var(--pl-accent-strong); filter: none; }

/* ---- Comparativa de ofertas (ISBN): mejor "oferta ganadora". */
body.theme-confeti .offers,
body.theme-confeti .book-description,
body.theme-confeti .book-specs {
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-sm);
}
body.theme-confeti .offer { border-radius: var(--ui-radius-md); }
body.theme-confeti .offer--best {
  /* Sin el anillo de 3px: se sumaba al de la regla base y dejaba un doble halo.
     Aqui solo la sombra suave del tema. */
  box-shadow: var(--ui-shadow-sm);
}
/* El radio ya lo pone `--ui-radius-cta` para todos los botones; aqui solo
   queda el peso tipografico propio del tema. */
body.theme-confeti .offer__button { font-weight: 700; }
body.theme-confeti .offer__button:hover { filter: brightness(0.92); }

/* ---- Cross-sell, related y buybar coherentes con el azul editorial. */
body.theme-confeti .cross-compare {
  border-radius: var(--ui-radius-lg);
  background: linear-gradient(135deg, var(--theme-accent-soft) 0%, #fff 70%);
  border-color: var(--ui-accent-tint);
}
body.theme-confeti .cross-compare__cta:hover { background: var(--pl-accent-strong); filter: none; }
body.theme-confeti .buybar__cta:hover { background: var(--pl-accent-strong); }

/* ---- Página de lista: tarjetas "comprar todo en X" más vendedoras. */
body.theme-confeti .list-cdl-highlight,
body.theme-confeti .list-mix,
body.theme-confeti .list-buys,
body.theme-confeti .list-matrix,
body.theme-confeti .list-items {
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-sm);
}
body.theme-confeti .list-cdl-highlight {
  background: linear-gradient(135deg, var(--theme-accent-soft) 0%, #fff 60%);
  border-color: var(--ui-accent-tint);
}
body.theme-confeti .list-cdl-highlight__cta,
body.theme-confeti .list-buy-card__cta {
  border-radius: var(--ui-radius-pill);
  font-weight: 700;
}
body.theme-confeti .list-cdl-highlight__cta:hover,
body.theme-confeti .list-buy-card__cta:hover { background: var(--pl-accent-strong); filter: none; }
body.theme-confeti .list-buy-card { border-radius: var(--ui-radius-md); }
body.theme-confeti .list-buy-card--best { box-shadow: 0 0 0 3px var(--ui-accent-ring), var(--ui-shadow-sm); }
body.theme-confeti .list-buy-card__cta--cart {
  background: linear-gradient(135deg, color-mix(in srgb, var(--theme-accent) 82%, #fff) 0%, var(--theme-accent) 60%, var(--pl-accent-strong) 100%);
}

/* ---- Búsqueda: cabecera con pill de búsqueda y facetas más limpias. */
/* El tema no vuelve a poner la tarjeta: sin fondo no hay nada que redondear ni
   que sombrear. (Esta regla ganaba por especificidad a la base.) */
body.theme-confeti .search-header { border-radius: 0; box-shadow: none; }
/* El buscador es la accion principal de estas paginas —quien llega con un ISBN en
   la mano viene exactamente a eso— y se camuflaba: un filete de 1px del mismo gris
   que el resto de tarjetas, sobre fondo casi blanco, en una pagina llena de
   tarjetas iguales. Se le da contorno en color de marca, mas cuerpo y sombra. */
body.theme-confeti .search-header__form {
  background: var(--theme-surface);
  border: 2px solid color-mix(in srgb, var(--theme-accent) 38%, var(--theme-border));
  border-radius: var(--ui-radius-pill);
  padding: 0.4rem 0.4rem 0.4rem 1.15rem;
  gap: 0.4rem;
  box-shadow: 0 2px 12px color-mix(in srgb, var(--theme-accent) 14%, transparent);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
body.theme-confeti .search-header__form:focus-within {
  border-color: var(--theme-accent);
  box-shadow: 0 3px 18px color-mix(in srgb, var(--theme-accent) 28%, transparent);
}
body.theme-confeti .search-header__form input { font-size: 1.05rem; padding: 0.75rem 0.4rem; }
body.theme-confeti .search-header__form button { padding: 0.75rem 1.7rem; }
body.theme-confeti .search-header__form input { border: 0; background: transparent; }
body.theme-confeti .search-header__form input:focus { outline: none; }
body.theme-confeti .search-header__form button { border-radius: var(--ui-radius-cta); font-weight: 700; }
body.theme-confeti .search-facets { border-radius: var(--ui-radius-lg); box-shadow: var(--ui-shadow-sm); }

/* ---- Responsive del hero/landing en móvil. */
@media (max-width: 640px) {
  body.theme-confeti .hero__search { padding: 0.4rem 0.4rem 0.4rem 1rem; }
  body.theme-confeti .hero__search input { font-size: 1rem; padding: 0.8rem 0.4rem; }
  body.theme-confeti .hero__search button { padding: 0.8rem 1.2rem; font-size: 0.98rem; }
  body.theme-confeti .hero__search::before { width: 18px; height: 18px; }
}

/* ---------------------------------------------------------------------------
   Pestañas ISBN/Título (CSS-only, sin JS por CSP) + fila de librerías
--------------------------------------------------------------------------- */
.ctabs__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  opacity: 0;
  pointer-events: none;
}
.ctabs__bar {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0.3rem;
  width: 100%;
  margin: 0 0 1.3rem;
  padding: 0.34rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
}
/* Las inactivas se pintan como PASTILLAS y no como texto suelto sobre la barra
   (14-ago-2026): con la activa rellena de azul y las otras dos en texto plano,
   sólo se leía como pulsable la que ya estaba pulsada. El hover ya avisaba,
   pero en el móvil —donde más se usa esta caja— no hay hover que valga. Fondo
   blanco y borde tenue: tres botones a la vista, uno encendido. */
.ctabs__tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.62rem 0.4rem;
  border-radius: var(--ui-radius-pill);
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--theme-ink-soft);
  cursor: pointer;
  user-select: none;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.ctabs__tab-icon { width: 1.15rem; height: 1.15rem; flex-shrink: 0; }
.ctabs__tab:hover { color: var(--theme-accent); background: var(--theme-accent-soft); border-color: color-mix(in srgb, var(--theme-accent) 45%, var(--theme-border)); }
@media (max-width: 480px) {
  .ctabs__tab { font-size: 0.82rem; gap: 0.3rem; padding: 0.58rem 0.25rem; }
  .ctabs__tab-icon { width: 1rem; height: 1rem; }
}
/* Las tres pestañas se salían de su propia barra: `grid-auto-columns: 1fr` es
   `minmax(auto, 1fr)`, y ese `auto` impide que una columna baje de su ancho de
   contenido — la más larga («Sube tu lista») fijaba el ancho de las tres y la
   barra pedía 232 px dentro de 217 (medido en producción). `minmax(0, 1fr)` sí
   las deja encoger; el icono, que es decorativo porque el <span> ya lleva el
   texto, se retira antes que el rótulo. */
@media (max-width: 480px) {
  .ctabs__bar { grid-auto-columns: minmax(0, 1fr); }
  .ctabs__tab {
    min-width: 0;
    font-size: 0.8rem;
    padding: 0.5rem 0.2rem;
    line-height: 1.15;
    text-align: center;
    /* Heredaba `nowrap`, así que el rótulo no podía ajustarse y se salía de su
       propia columna aunque la rejilla ya la dejase encoger. En el móvil más
       estrecho «Sube tu lista» parte en dos líneas; la rejilla iguala el alto de
       las tres pestañas, así que no descuadra. */
    white-space: normal;
  }
  .ctabs__tab > span { min-width: 0; }
  .ctabs__tab-icon { display: none; }
}
.ctabs__panel { display: none; }
#cmode-isbn:checked ~ .ctabs__panel--isbn,
#cmode-titulo:checked ~ .ctabs__panel--titulo,
#cmode-foto:checked ~ .ctabs__panel--foto,
#hmode-isbn:checked ~ .ctabs__panel--isbn,
#hmode-titulo:checked ~ .ctabs__panel--titulo,
#hmode-foto:checked ~ .ctabs__panel--foto { display: block; }
#cmode-isbn:checked ~ .ctabs__bar label[for="cmode-isbn"],
#cmode-titulo:checked ~ .ctabs__bar label[for="cmode-titulo"],
#cmode-foto:checked ~ .ctabs__bar label[for="cmode-foto"],
#hmode-isbn:checked ~ .ctabs__bar label[for="hmode-isbn"],
#hmode-titulo:checked ~ .ctabs__bar label[for="hmode-titulo"],
#hmode-foto:checked ~ .ctabs__bar label[for="hmode-foto"] {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--theme-accent) 35%, transparent);
}
/* Permite enlazar directamente a la pestaña Foto/PDF con `/comparar#cmode-foto`
   (p. ej. desde la home). `:target` activa el panel sin JS; gana al `:checked`
   por defecto porque aparece después en la cascada. */
#cmode-foto:target ~ .ctabs__panel { display: none; }
#cmode-foto:target ~ .ctabs__panel--foto { display: block; }
#cmode-foto:target ~ .ctabs__bar label[for="cmode-foto"] {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--theme-accent) 35%, transparent);
}
.ctabs__radio:focus-visible ~ .ctabs__bar label {
  outline: 2px solid var(--ui-accent-ring);
  outline-offset: 2px;
}

.compare-title-form__row {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.compare-title-form__input {
  flex: 1 1 240px;
  padding: 0.95rem 1.1rem;
  font-size: 1.05rem;
  border: 1px solid color-mix(in srgb, var(--theme-ink-muted) 30%, #fff);
  border-radius: var(--ui-radius-md);
  background: var(--theme-surface);
}
.compare-title-form__input:focus-visible {
  outline: none;
  border-color: var(--theme-accent);
  box-shadow: 0 0 0 4px var(--ui-accent-ring);
}

/* --- Pestaña Foto/PDF: zona de subida arrastrar-y-soltar --- */
.compare-upload { display: flex; flex-direction: column; gap: 0.9rem; }
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 2.25rem 1.25rem;
  text-align: center;
  border: 2px dashed color-mix(in srgb, var(--theme-accent) 45%, var(--theme-border));
  border-radius: var(--ui-radius-xl);
  background: var(--theme-accent-soft);
  color: var(--theme-ink-soft);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.dropzone:hover {
  border-color: var(--theme-accent);
  background: color-mix(in srgb, var(--theme-accent) 12%, var(--theme-surface));
  box-shadow: var(--ui-shadow-sm);
}
.dropzone__icon {
  width: 2.75rem;
  height: 2.75rem;
  color: var(--theme-accent);
}
.dropzone__title {
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--theme-ink);
}
.dropzone__hint { font-size: 0.9rem; color: var(--theme-ink-muted); }
.dropzone__cta {
  margin-top: 0.35rem;
  padding: 0.55rem 1.25rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  color: var(--theme-accent);
  font-weight: 700;
  font-size: 0.92rem;
}
/* El <input type=file> real ocupa toda la zona pero invisible: así un clic
   en cualquier punto del dropzone abre el selector, sin necesidad de JS. */
.dropzone__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  opacity: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
/* Mostramos el nombre del fichero elegido vía pseudo-contenido no es posible
   sin JS; el navegador ya indica el archivo bajo el botón nativo si se hace
   visible. Mantenemos foco accesible con teclado sobre la etiqueta. */
.dropzone__input:focus-visible ~ .dropzone__cta,
.dropzone:focus-within {
  outline: 2px solid var(--ui-accent-ring);
  outline-offset: 2px;
}
/* Variante COMPACTA del dropzone: para cuando el adjunto es un campo más de un
   formulario (y encima opcional, como en /envianos-tu-lista) y no la acción
   principal de la página. En fila en vez de en columna y sin el hueco central,
   baja de ~150 px de alto a ~56 sin perder nada de lo que aporta el componente:
   nombre y peso del fichero, arrastrar y soltar, y la cámara en el móvil.
   Fondo blanco y no el tinte de acento: aquí la tarjeta que lo contiene ya es
   azul clara, y tinte sobre tinte deja el recuadro invisible. */
.dropzone--compact {
  flex-direction: row;
  justify-content: flex-start;
  gap: 0.7rem;
  padding: 0.65rem 0.9rem;
  text-align: left;
  border-radius: var(--ui-radius-md);
  background: var(--theme-surface);
}
.dropzone--compact:hover { background: var(--theme-surface); border-color: var(--theme-accent); }
.dropzone--compact .dropzone__icon { width: 1.5rem; height: 1.5rem; }
.dropzone--compact .dropzone__title { font-size: 0.95rem; font-weight: 600; }
.dropzone--compact .dropzone__cta {
  margin: 0 0 0 auto;
  padding: 0.4rem 0.95rem;
  font-size: 0.85rem;
  white-space: nowrap;
}
@media (max-width: 559px) {
  /* En pantallas estrechas el rótulo y el botón no caben en una línea; el
     recuadro pasa a dos filas antes de que el texto se estrangule. */
  .dropzone--compact { flex-wrap: wrap; }
  .dropzone--compact .dropzone__cta { margin-left: 2.2rem; }
}

/* Botón "hacer una foto": lo inyecta `upload-feedback.js` sólo en dispositivos
   con cámara (puntero grueso + soporte de `capture`), delante del dropzone. Va
   con contorno y no relleno porque el relleno sólido es del botón de enviar: el
   paso siguiente sigue siendo "Subir y comparar". */
.dropzone__camera {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  font: inherit;
  padding: 0.9rem 1rem;
  border-radius: var(--ui-radius-pill);
  border: 2px solid var(--theme-accent);
  background: var(--theme-surface);
  color: var(--theme-accent);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.2;
  cursor: pointer;
}
.dropzone__camera:active { background: var(--theme-accent-soft); }
.dropzone__camera:focus-visible {
  outline: 2px solid var(--ui-accent-ring);
  outline-offset: 2px;
}
.dropzone__camera-icon { width: 1.3rem; height: 1.3rem; flex-shrink: 0; }
.compare-upload__note {
  margin: 0;
  font-size: 0.85rem;
  color: var(--theme-ink-muted);
  line-height: 1.5;
}

.merchants-strip {
  text-align: center;
  padding: clamp(2.5rem, 6vw, 4rem) 1rem;
}
.merchants-strip__label {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  font-size: clamp(0.84rem, 1.4vw, 0.98rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--theme-ink-muted);
  margin: 0 0 clamp(1.25rem, 2.5vw, 1.75rem);
}
/* Líneas finas a ambos lados del rótulo: lo enmarcan y le dan presencia sin
   robar protagonismo a los logos (que son el foco de la franja). */
.merchants-strip__label::before,
.merchants-strip__label::after {
  content: "";
  width: clamp(1.25rem, 5vw, 3rem);
  height: 1px;
  background: var(--theme-border);
}
.merchants-strip__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.9rem 1.1rem;
  margin: 0;
  padding: 0;
}

/* MÓVIL: carrusel horizontal en vez de columna. Con `wrap` las cuatro librerías
   se apilan una debajo de otra y la franja se come media pantalla — y es una
   sección de refuerzo, no el contenido. En una sola fila con scroll se ve que
   hay más a la derecha: medido en producción, de 4 filas apiladas a 69 px de
   alto con 731 px de recorrido. Sin sangrado por márgenes negativos: se probó y
   metía 8 px de scroll horizontal en la página. */
@media (max-width: 719px) {
  .merchants-strip__list {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    padding: 0.5rem 0.25rem;
    gap: 0.65rem;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .merchants-strip__list::-webkit-scrollbar { display: none; }
  .merchants-strip__item {
    flex: none;
    scroll-snap-align: start;
    padding: 0.7rem 1.1rem;
    font-size: 1rem;
  }
}

/* "Logos" wordmark de cada librería como chips con el color de marca aproximado.
   NO usamos los logos oficiales (copyright): son wordmarks tipográficos sobre
   chip claro con sombra suave, para dar aspecto de fila de partners.
   TODO: sustituir por los assets oficiales del kit de afiliado de cada librería
   (Amazon Associates / Awin: Casa del Libro, Fnac, El Corte Inglés, Agapea…)
   cuando estén disponibles; bastará con cambiar el contenido del <li> por un
   <img> y neutralizar estas reglas de color. */
.merchants-strip__item {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.85rem 1.5rem;
  border-radius: var(--ui-radius-pill);
  background: #fff;
  border: 1px solid var(--theme-border);
  box-shadow: var(--ui-shadow-md, 0 6px 22px rgba(31, 27, 46, 0.08));
  font-family: var(--theme-font-heading), system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(1.05rem, 1.8vw, 1.25rem);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--theme-ink);
  white-space: nowrap;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.merchants-strip__item:hover {
  transform: translateY(-3px);
  box-shadow: var(--ui-shadow-lg, 0 22px 50px rgba(31, 27, 46, 0.14));
  border-color: color-mix(in srgb, var(--theme-accent) 35%, var(--theme-border));
}
/* Logo real de la marca (favicon de alta resolución). El nombre acompaña al
   icono; el texto se tinta con el color de marca para reforzar el reconocimiento. */
.merchants-strip__logo {
  width: 1.85em;
  height: 1.85em;
  object-fit: contain;
  border-radius: var(--ui-radius-sm);
  flex: none;
}
.merchants-strip__item[data-merchant="amazon"] { color: #131a22; }
.merchants-strip__item[data-merchant="cdl"] { color: #00843d; }
.merchants-strip__item[data-merchant="fnac"] { color: #111; }
.merchants-strip__item[data-merchant="eci"] { color: #1f8a3b; }
.merchants-strip__item[data-merchant="agapea"] { color: #c0228a; }
.merchants-strip__item[data-merchant="imosver"] { color: #0f5ca8; }
.merchants-strip__item[data-merchant="abacus"] { color: #e30613; }

/* ── Páginas legales / informativas (aviso legal, privacidad, contacto, about).
   Tarjeta de lectura con ancho de medida cómodo; el cuerpo se inyecta como HTML
   desde el CMS de textos, así que estilamos los hijos genéricos (p/h2/ul/a). ── */
.legal-page {
  max-width: none;
  margin: 2.5rem 0 3.5rem;
  padding: clamp(1.5rem, 4vw, 2.75rem);
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-sm, 0 1px 2px rgba(31, 27, 46, 0.06));
}
.legal-page__header {
  margin-bottom: 1.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--theme-border);
}
.legal-page__title {
  margin: 0;
  font-size: clamp(1.6rem, 3.5vw, 2.1rem);
  font-weight: 600;
}
.legal-page__body {
  color: var(--theme-ink);
  line-height: 1.7;
}
.legal-page__body > :first-child { margin-top: 0; }
.legal-page__body > :last-child { margin-bottom: 0; }
.legal-page__body h2 {
  margin: 1.85rem 0 0.6rem;
  font-size: 1.18rem;
  font-weight: 700;
}
.legal-page__body p {
  margin: 0 0 1rem;
  color: var(--theme-ink-muted);
}
.legal-page__body strong { color: var(--theme-ink); }
.legal-page__body ul,
.legal-page__body ol {
  margin: 0 0 1rem;
  padding-left: 1.3rem;
  color: var(--theme-ink-muted);
}
.legal-page__body li { margin: 0 0 0.4rem; }
.legal-page__body a {
  color: var(--theme-accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.legal-page__body a:hover,
.legal-page__body a:focus { color: var(--ui-accent-strong, var(--theme-accent)); }

/* ---- Formulario de contacto (/contacto) ---- */
/* El formulario va ARRIBA, antes de los datos de contacto: quien entra aquí
   viene a escribir, no a leer quiénes somos. El separador tuvo que darse la
   vuelta —era `border-top`, pensado para ir detrás del texto— o quedaba una
   línea suelta justo debajo del H1. */
.contact-form-wrap {
  margin-bottom: 2.25rem;
  padding-bottom: 1.9rem;
  border-bottom: 1px solid var(--theme-border);
}
.contact-form__heading { margin: 0 0 0.35rem; font-size: 1.25rem; }
/* Los <button> NO heredan la fuente: sin esto el navegador les pone su
   familia por defecto (Arial) y el boton desentonaba con toda la web. */
.contact-form__submit,
.contact-form__input,
.contact-form__textarea {
  font-family: inherit;
}

/* Casilla de privacidad: el texto al lado, no debajo, y el cuadro alineado con
   la primera linea. */
.contact-form__consent {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  margin: 0.4rem 0 0.2rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--theme-ink-soft);
  cursor: pointer;
}
.contact-form__consent input {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.15rem;
  accent-color: var(--theme-accent);
}
.contact-form__consent a { color: var(--theme-accent); text-decoration: underline; }

/* Caja de busqueda en /envianos-tu-lista. La tarjeta viene de la home, donde
   vive dentro de un hero de fondo oscuro; aqui va sobre el fondo normal de la
   pagina, asi que se le pone su propio respiro y un separador que deja claro
   donde acaba «buscalo tu» y empieza «te lo hacemos nosotros». */
.send-list__buscar {
  margin: 0 0 2.25rem;
}
.send-list__buscar .hero-compare-card {
  margin-top: 0.9rem;
  /* En la home la tarjeta va centrada y estrecha (`max-width: 44rem`) porque
     vive en un hero a pantalla completa. Aqui el resto de la pagina va a ancho
     completo, asi que centrada dejaba dos calles vacias a los lados y parecia
     un trozo pegado de otra pagina. Especificidad 0,2,0: gana a la regla base
     este donde este en el fichero. */
  max-width: none;
  /* Mas compacta que en la home (decision de Rafael, 11-ago-2026): esta pagina
     es la de ENVIAR el listado, no la de buscar. La caja seguia siendo la del
     hero, tan alta que empujaba el formulario de envio fuera de pantalla. Aqui
     el buscar es la alternativa, no el protagonista. */
  padding: 0.85rem 0.9rem;
}
.send-list__buscar .hero-compare-card__pretitle { margin-bottom: 0.45rem; }
.send-list__buscar .compare-form__textarea { min-height: 2.6rem; }
.send-list__buscar-nota {
  margin: 1.1rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--theme-border);
  font-size: 0.95rem;
  color: var(--theme-ink-soft);
  text-wrap: balance;
}

/* Turnstile. El iframe mide 300x65 fijos y no encoge, asi que en movil se deja
   desbordar en su propio contenedor en vez de estrujar la caja del formulario
   (que arrastraria a los inputs). `min-height` reserva el hueco desde el primer
   pintado: sin ella el boton de enviar da un salto cuando el widget monta. */
.form-turnstile {
  margin: 0.2rem 0 0.1rem;
  min-height: 65px;
  max-width: 100%;
  overflow-x: auto;
}

/* /contacto con la misma piel que /envianos-tu-lista: eran dos formularios que
   hacen lo mismo y se veian distintos. */
.contact-form-wrap {
  padding: 1.9rem 1.9rem 2rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-top: 4px solid var(--theme-accent);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--theme-shadow, 0 12px 32px rgba(16, 42, 67, 0.08));
}
.contact-form-wrap .contact-form { max-width: none; }
.contact-form-wrap .contact-form__submit { width: 100%; padding: 0.95rem 1.5rem; font-size: 1.05rem; }

.contact-form__hint {
  font-size: 0.85rem;
  color: var(--theme-ink-soft);
  line-height: 1.4;
}

/* ---------------------------------------------------------------------------
   /envianos-tu-lista — el visitante nos manda la lista y se la comparamos a
   mano. Es la salida para quien no se apaña con la subida automática: antes de
   esto, esa persona simplemente se iba.
   --------------------------------------------------------------------------- */
/* El enlace de rescate bajo la subida de /comparar. Discreto pero visible: no
   compite con el botón, pero está justo donde alguien abandona. */
.compare-upload__fallback {
  margin: 1rem 0 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--theme-ink-muted);
  text-align: center;
}
.compare-upload__fallback a {
  color: var(--theme-accent);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* Tachar los libros según se compran, cuando la librería no tiene cesta y hay
   que ir de uno en uno. Ver `js/buy-progress.js`. */
.buy-progress__summary {
  margin: 0 0 0.6rem;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--theme-accent);
}

.buy-progress__toggle {
  flex: 0 0 auto;
  width: 1.35rem;
  height: 1.35rem;
  margin-right: 0.7rem;
  padding: 0;
  border: 2px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.buy-progress__toggle:hover { border-color: var(--theme-accent); }

.list-buy-card__item.is-comprado .buy-progress__toggle {
  border-color: var(--theme-success, var(--theme-accent));
  background: var(--theme-success, var(--theme-accent));
  /* La marca va en el fondo: un SVG inline en el JS chocaría con la CSP. */
  background-image: linear-gradient(45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%),
    linear-gradient(-45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%);
  background-size: 62% 62%;
  background-position: center;
  background-repeat: no-repeat;
}

/* El tachado va sobre el título y el precio, no sobre el botón: seguir pudiendo
   comprar es justo lo que se necesita si te has marcado uno por error. */
.list-buy-card__item.is-comprado .list-buy-card__item-title,
.list-buy-card__item.is-comprado .list-buy-card__item-price {
  text-decoration: line-through;
  opacity: 0.55;
}

.send-list__lead {
  margin: 0.6rem 0 0;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--theme-ink-muted);
  /* Sin tope: la caja ya es ancha y 46rem partía la entradilla en tres líneas
     cortas dejando media cabecera vacía. */
  max-width: none;
}

.send-list__section-title {
  margin: 0 0 1rem;
  font-size: 1.22rem;
  font-weight: 700;
}

/* Formulario a la izquierda y pasos a la derecha, en paralelo. Apilados
   dejaban media pantalla en blanco y obligaban a leer la explicación antes de
   poder actuar; en dos columnas el visitante ve qué va a pasar MIENTRAS
   rellena, que es cuando le sirve.

   El formulario va PRIMERO en el DOM: en móvil es lo que tiene que verse
   antes, y para un lector de pantalla la acción manda sobre la explicación. */
.send-list__cols {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
  margin: 2rem 0;
}

@media (max-width: 900px) {
  .send-list__cols { grid-template-columns: 1fr; gap: 1.5rem; }
}

.send-list__cols > .send-list__form-wrap { margin: 0; }
.send-list__cols > .send-list__steps { margin: 0; }

/* En la columna estrecha los pasos van uno bajo otro, no en rejilla. */
.send-list__cols .send-list__steps-list { grid-template-columns: 1fr; }

.send-list__steps { margin: 2.25rem 0; }

.send-list__steps-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: paso;
}

.send-list__steps-list li {
  counter-increment: paso;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1.15rem 1.25rem 1.3rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
}

/* El número va en `::before` y no en el marcador de la lista para poder darle
   forma de ficha; la semántica de <ol> se conserva. */
.send-list__steps-list li::before {
  content: counter(paso);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.85rem;
  height: 1.85rem;
  margin-bottom: 0.15rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: #fff;
  font-weight: 700;
  font-size: 0.95rem;
}

/* La ilustración encabeza cada ficha de paso. `order: -1` porque el número lo
   pinta un `::before`, que en un flex es un hijo más y va delante por defecto:
   sin esto la ilustración quedaba DEBAJO del número. */
.send-list__steps-list .step-art {
  order: -1;
  width: 104px;
  height: 78px;
  margin-bottom: 0.3rem;
}
.send-list__steps-list strong { color: var(--theme-ink); }
.send-list__steps-list span { color: var(--theme-ink-muted); line-height: 1.55; }

/* El formulario ES la página: antes era una sección más, separada por un filete
   y con los campos al mismo nivel visual que el texto de alrededor, así que se
   leía como «más contenido» en vez de como la acción. Ahora es una tarjeta con
   fondo propio y borde de acento — el mismo recurso que usa la caja de búsqueda
   de la home, que es la otra acción principal del sitio. */
/* Fondo azul claro (14-ago-2026): en blanco sobre blanco la tarjeta sólo se
   distinguía por el filete, o sea que la ACCIÓN de la página pesaba lo mismo que
   el texto de al lado. Con el tinte se ve el bloque antes de leerlo y, de
   regalo, los campos —que son blancos— ganan contraste dentro de él. El hex de
   reserva va primero por si el navegador no soporta `color-mix`. */
.send-list__form-wrap {
  margin: 2.25rem 0;
  padding: 1.9rem 1.9rem 2rem;
  background: var(--theme-accent-soft);
  background: color-mix(in srgb, var(--theme-accent) 8%, #fff);
  border: 1px solid var(--theme-border);
  border-top: 4px solid var(--theme-accent);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--theme-shadow, 0 12px 32px rgba(16, 42, 67, 0.08));
}

/* SIN `max-width`: la página ya es una tarjeta a ancho completo, así que capar
   el formulario a 44rem dejaba media pantalla en blanco a la derecha. Aquí
   llega gente que no se apaña con la herramienta: el formulario tiene que ser
   lo único que se ve y llenar el espacio. */
/* `form.` para ganar por especificidad: `.contact-form { max-width: 40rem }`
   está MÁS ABAJO en este fichero y con la misma especificidad ganaba la última,
   así que el formulario seguía ocupando media tarjeta. */
form.send-list__form {
  max-width: none;
  width: 100%;
}

/* Dos columnas de verdad, no `auto-fit`: con `minmax(13rem, 1fr)` sobre un
   contenedor ancho salían tres o cuatro columnas y los campos quedaban
   ridículamente estrechos. */
.send-list .send-list__grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem 1.5rem;
}
.send-list .send-list__grid--tres {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 700px) {
  .send-list .send-list__grid,
  .send-list .send-list__grid--tres {
    grid-template-columns: 1fr;
  }
}

/* El mensaje y el adjunto, a lo ancho: son los dos campos donde de verdad se
   escribe y se pega la lista. */
.send-list__form > .contact-form__row { width: 100%; }

/* Los pasos numerados dentro del propio formulario. Tres bloques cortos se
   leen mejor que once campos seguidos, y dejan claro que sólo el 1 y el 2 son
   obligatorios. */
.send-list__paso {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 1.6rem 0 0.9rem;
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--theme-ink);
}
.send-list__paso:first-child { margin-top: 0; }
.send-list__paso span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: #fff;
  font-size: 0.92rem;
  flex: none;
}
.send-list__paso--opcional {
  font-weight: 600;
  color: var(--theme-ink-soft);
}
.send-list__paso--opcional span {
  background: var(--theme-border);
  color: var(--theme-ink-soft);
}

.send-list__grid--tres {
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}

/* Los campos obligatorios, con más peso que los opcionales: el visitante ve de
   un vistazo que sólo hay tres cosas que rellenar de verdad. */
.send-list__form .contact-form__label {
  font-size: 0.95rem;
  color: var(--theme-ink);
}

.send-list__form .contact-form__input,
.send-list__form .contact-form__textarea {
  background: var(--theme-bg);
  border-width: 1.5px;
}

.send-list__form .contact-form__input:focus,
.send-list__form .contact-form__textarea:focus,
.send-list__form .dropzone--compact:focus-within {
  border-color: var(--theme-accent);
  box-shadow: 0 0 0 3px var(--theme-accent-soft);
  outline: none;
}

/* Etiqueta en línea con su pista («Adjunta tu lista: foto…»), como el
   formulario de referencia: la parte fuerte en tinta y el resto suave. */
.send-list__inline-label {
  display: block;
  margin-bottom: 0.45rem;
  color: var(--theme-ink-soft);
  line-height: 1.45;
}
.send-list__inline-label strong { color: var(--theme-ink); }

.send-list__form .contact-form__submit {
  width: 100%;
  padding: 0.95rem 1.5rem;
  font-size: 1.05rem;
}

.send-list__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1rem;
}

.send-list__faq { margin-top: 2.5rem; }

/* Pantalla de «recibida»: sin formulario, sólo la confirmación y qué pasa ahora. */
.send-list__done {
  margin: 2rem 0;
  padding: 1.75rem 1.75rem 1.9rem;
  background: var(--theme-accent-soft);
  border: 1px solid var(--theme-accent);
  border-radius: var(--ui-radius-lg);
}
.send-list__done-title { margin: 0 0 0.6rem; font-size: 1.3rem; }
.send-list__done p { margin: 0 0 0.75rem; color: var(--theme-ink); line-height: 1.6; }
.send-list__done-cta { margin: 0; }
.send-list__link { color: var(--theme-accent); font-weight: 600; text-decoration: underline; }
.contact-form__lead {
  margin: 0 0 1.25rem;
  color: var(--theme-ink-muted);
  font-size: 0.97rem;
}
.contact-form { display: flex; flex-direction: column; gap: 1rem; max-width: 40rem; }
.contact-form__row { display: flex; flex-direction: column; gap: 0.35rem; }
.contact-form__label { font-weight: 600; font-size: 0.92rem; color: var(--theme-ink); }
.contact-form__input,
.contact-form__textarea {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font: inherit;
}
.contact-form__input:focus,
.contact-form__textarea:focus {
  outline: none;
  border-color: var(--theme-accent);
  box-shadow: 0 0 0 3px var(--theme-accent-soft);
}
.contact-form__textarea { resize: vertical; min-height: 7rem; }
.contact-form__submit {
  align-self: flex-start;
  padding: 0.78rem 1.6rem;
  background: var(--theme-accent);
  color: #fff;
  border: 0;
  border-radius: var(--ui-radius-pill);
  font-weight: 700;
  cursor: pointer;
}
.contact-form__submit:hover { filter: brightness(0.93); }
.contact-form__note { margin: 0.85rem 0 0; font-size: 0.82rem; color: var(--theme-ink-muted); }
/* Honeypot anti-spam: fuera de pantalla, no debe verse ni recibir foco. */
.contact-form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.contact-form__success {
  margin: 0 0 1.1rem;
  padding: 0.85rem 1rem;
  background: color-mix(in srgb, var(--theme-success) 12%, #fff);
  border: 1px solid color-mix(in srgb, var(--theme-success) 30%, transparent);
  border-radius: var(--ui-radius-sm);
  color: color-mix(in srgb, var(--theme-success) 78%, #000 22%);
  font-weight: 500;
}
.contact-form__error {
  margin: 0 0 1.1rem;
  padding: 0.85rem 1rem;
  background: color-mix(in srgb, var(--theme-danger) 10%, #fff);
  border: 1px solid color-mix(in srgb, var(--theme-danger) 30%, transparent);
  border-radius: var(--ui-radius-sm);
  color: #b91c1c;
  font-weight: 500;
}

/* ---- Listado del blog: rejilla de 3 columnas con tarjetas ---- */
.blog-index__header {
  margin-bottom: 1.75rem;
}
.blog-index__lead {
  color: var(--theme-ink-soft);
  font-size: 1.02rem;
  margin: 0.35rem 0 0;
  /* Sin `max-width: 60ch`. Esa medida es buena tipografia para un parrafo
     suelto, pero aqui el lead convive con un H1 y una rejilla de tarjetas que
     ocupan el contenedor entero, y cortarlo a 60ch lo dejaba a media anchura,
     descolgado del resto. El ancho ya lo limita el contenedor de la pagina. */
}
/* El cuerpo SEO va DESPUES de la rejilla de tarjetas: sin separacion propia
   quedaba pegado a la ultima tarjeta, como si fuera parte de ella. */
.blog-index__seo {
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--theme-border);
}
.blog-index__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
.blog-card {
  display: flex;
  flex-direction: column;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  overflow: hidden;
  box-shadow: var(--ui-shadow-sm);
  transition: transform 0.14s ease, box-shadow 0.14s ease;
}
.blog-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--ui-shadow-md);
}
.blog-card__cover {
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--theme-surface-alt);
}
.blog-card__cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.blog-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 1rem 1.15rem 1.2rem;
  flex: 1;
}
.blog-card__title {
  margin: 0;
  font-size: 1.1rem;
  line-height: 1.32;
}
.blog-card__title a {
  color: var(--theme-ink);
  text-decoration: none;
}
.blog-card__title a:hover {
  color: var(--theme-accent);
}
.blog-card__excerpt {
  margin: 0;
  color: var(--theme-ink-soft);
  font-size: 0.92rem;
  line-height: 1.55;
}
.blog-card__meta {
  margin: auto 0 0;
  padding-top: 0.4rem;
  color: var(--theme-ink-muted);
  font-size: 0.82rem;
}
.blog-index__pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  margin-top: 2rem;
  font-size: 0.95rem;
}
.blog-index__pagination a {
  color: var(--theme-accent);
  text-decoration: none;
  font-weight: 600;
}
.blog-index__pagination-status {
  color: var(--theme-ink-muted);
}
.blog-index__empty {
  color: var(--theme-ink-soft);
}
@media (max-width: 880px) {
  .blog-index__list {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 560px) {
  .blog-index__list {
    grid-template-columns: 1fr;
  }
}

/* ---- Imagen de cabecera del post de blog ----
   `aspect-ratio` reserva el hueco antes de que cargue la imagen: sin él, la
   cabecera del post (una página indexable, y esta imagen es su LCP) daba un
   salto de layout de hasta 420px al cargar. `.blog-card__cover` ya lo declara;
   esto sólo alinea el post con la tarjeta. Manda sobre la proporción intrínseca,
   así que no hay salto, y el `max-height` sigue recortando con object-fit. */
.blog-post__cover {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 420px;
  object-fit: cover;
  border-radius: var(--ui-radius-lg);
  margin: 0 0 1.75rem;
  background: var(--theme-surface-alt);
}

/* Enlaces dentro del cuerpo del post: subrayados y en color de acento para que
   se distingan claramente del texto (los CTAs internos a /comparar, /cursos…). */
.blog-post__body a {
  color: var(--theme-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.blog-post__body a:hover {
  text-decoration-thickness: 2px;
}

/* =========================================================================
   HOME — secciones markenianas del rediseño (propuestas de valor, teaser de
   "cómo funciona", intros de categorías, FAQ y banda CTA final). Estilos base
   transversales a todos los presets; el bloque `body.theme-confeti` de más
   abajo los afina al azul editorial.
   ========================================================================= */

/* ---- Propuestas de valor: rejilla de señales con icono + título + frase. --- */
/* ---- Banda de cifras de la home (sustituye a las seis tarjetas de ventajas).
   Sin marcos: lo que sostiene el bloque es el contraste de tamaño entre la
   cifra y su rótulo, no un borde alrededor de cada frase. Los separadores son
   filetes entre columnas, que es lo que hace que se lea como una banda y no
   como cuatro cajas sueltas. */
/* Tarjeta, no franja desnuda (feedback de Rafael con captura, 11-ago-2026):
   entre secciones que son todas cards, los cuatro números con filetes sueltos
   y la nota flotando debajo rompían el sistema. Misma caja que el resto y la
   nota integrada con su separador. */
/* Sin tarjeta, por lo mismo que `.how-it-works`: blanco sobre blanco con un
   filete alrededor. Las líneas verticales entre cifras ya dan la estructura. */
.home-proof {
  padding: 0;
  margin: 2.75rem 0 2rem;
}
.home-proof__figures {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
.home-proof__item {
  display: flex;
  flex-direction: column;
  /* Pegadas arriba: con cifras de ancho tan dispar («4» contra «849.237») cada
     columna centraba su propio alto y la banda se veía descuadrada. */
  justify-content: flex-start;
  gap: 0.45rem;
  align-items: center;
  text-align: center;
  padding: 0.5rem 1rem;
  border-left: 1px solid var(--theme-border);
}
.home-proof__item:first-child { border-left: 0; }
.home-proof__num {
  font-family: var(--theme-font-heading);
  font-weight: 800;
  font-size: clamp(1.9rem, 4vw, 2.7rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--theme-accent);
  font-variant-numeric: tabular-nums;
}
.home-proof__label {
  font-size: 0.86rem;
  line-height: 1.35;
  color: var(--theme-ink-soft);
  /* 11rem y no 15: con 15 cada etiqueta partía por un sitio distinto y la
     primera dejaba «vez» sola en su línea. */
  max-width: 11rem;
  /* Reparte las líneas en vez de llenar la primera: mata las palabras
     huérfanas sin tener que ajustar el ancho al carácter. */
  text-wrap: balance;
}
.home-proof__note {
  /* Solo texto, centrado (el icono del camión se retiró: decoraba sin
     aportar — feedback de Rafael, 13-ago-2026). */
  text-align: center;
  margin: 1.5rem 0 0;
  padding-top: 1.2rem;
  border-top: 1px solid var(--theme-border, var(--theme-border));
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--theme-ink-soft);
  text-align: center;
}
.home-proof__note span { display: inline-block; max-width: 40rem; text-wrap: balance; }
/* Móvil: dos columnas. Con cuatro, la cifra baja tanto que deja de ser cifra;
   y los filetes verticales se sustituyen por una rejilla con separación. */
@media (max-width: 720px) {
  .home-proof__figures { grid-template-columns: repeat(2, 1fr); gap: 1.5rem 0; }
  .home-proof__item { border-left: 0; padding: 0 0.6rem; }
  .home-proof__item:nth-child(even) { border-left: 1px solid var(--theme-border); }
}

.home-vprops {
  padding: 2.5rem 0 0.75rem;
}
.home-vprops__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.9rem;
  /* 6 ventajas → 3 columnas (3+3) en escritorio, 2 en tablet, 1 en móvil:
     una rejilla equilibrada en vez del 4+2 que dejaba un hueco. */
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 920px) {
  .home-vprops__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .home-vprops__grid { grid-template-columns: 1fr; }
}
/* Tarjeta PLANA: el borde sostiene la tarjeta en vez de la sombra, que es lo
   que envejecía el bloque. Rejilla de 2 columnas (icono | texto) con el título
   a la altura del icono: la tarjeta queda más baja y las dos filas dejan de
   arrastrar el hueco muerto que quedaba debajo del cuerpo más corto. */
.home-vprops__item {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.95rem;
  row-gap: 0.4rem;
  align-content: start;
  padding: 1.45rem 1.45rem 1.55rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  transition: border-color 0.18s ease, background-color 0.18s ease;
}
/* Sin translate al pasar: seis tarjetas saltando es ruido. Basta con que el
   borde tome el color de marca y el fondo se tiña un punto. */
.home-vprops__item:hover {
  border-color: color-mix(in srgb, var(--theme-accent) 45%, var(--theme-border));
  background: color-mix(in srgb, var(--theme-accent-soft) 40%, var(--theme-surface));
}
/* Icono al 10% de acento con el glifo en color de marca. Antes eran seis
   pastillas azules macizas que competían con los titulares y, al repetirse,
   dominaban el bloque entero. */
.home-vprops__icon {
  grid-column: 1;
  grid-row: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: var(--ui-radius-md);
  background: color-mix(in srgb, var(--theme-accent) 10%, transparent);
  color: var(--theme-accent);
}
.home-vprops__icon svg { width: 1.25rem; height: 1.25rem; }
.home-vprops__title {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.home-vprops__body {
  grid-column: 2;
  grid-row: 2;
  margin: 0;
  color: var(--theme-ink-muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

/* ---- Enlazado cruzado curso <-> asignatura al pie de las colecciones.
   Chips en vez de lista vertical: son hasta 24 enlaces y en columna
   empujarian el pie a dos pantallas de distancia. ---- */
.collection-crosslinks {
  margin-top: 2rem;
  display: grid;
  gap: 1.5rem;
}
.collection-crosslinks__title {
  margin: 0 0 0.7rem;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.collection-crosslinks__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}
.collection-crosslinks__list a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  font-size: 0.88rem;
  text-decoration: none;
  color: var(--theme-ink-soft);
  transition: border-color 0.18s ease, background-color 0.18s ease;
}
.collection-crosslinks__list a:hover {
  border-color: color-mix(in srgb, var(--theme-accent) 45%, var(--theme-border));
  background: color-mix(in srgb, var(--theme-accent-soft) 45%, var(--theme-surface));
}
.collection-crosslinks__count {
  font-size: 0.78rem;
  color: var(--theme-ink-muted);
}

/* ---- Teaser "cómo funciona": CTA centrada bajo los 3 pasos. ---- */
.how-it-works__cta {
  display: flex;
  justify-content: center;
  margin-top: 1.75rem;
}

/* ---- Intro de la sección de categorías (eyebrow + título + entradilla). ---- */
.home-categories__intro {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-width: 46rem;
}
.home-categories__section-title {
  margin: 0.15rem 0 0;
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.home-categories__section-lead {
  margin: 0.35rem 0 0;
  color: var(--theme-ink-soft);
  font-size: 1rem;
  line-height: 1.6;
}

/* ---- Últimos libros añadidos (rejilla de novedades, 4 columnas). ---- */
.home-latest {
  padding: 1.5rem 0 2.5rem;
}
.home-latest__intro {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-width: 46rem;
  margin: 0 0 1.6rem;
}
.home-latest__title {
  margin: 0.15rem 0 0;
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.home-latest__lead {
  margin: 0.35rem 0 0;
  color: var(--theme-ink-soft);
  font-size: 1rem;
  line-height: 1.6;
}
.home-latest__cta {
  display: flex;
  justify-content: center;
  margin: 1.8rem 0 0;
}
body.theme-confeti .home-latest__title { font-weight: 800; }

/* ---- FAQ honesta (CSS-only con <details>). ---- */
.home-faq {
  padding: 1.5rem 0 2.5rem;
}
.home-faq__intro {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0 0 1.5rem;
}
.home-faq__section-title {
  margin: 0.15rem 0 0;
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.home-faq__list {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.home-faq__item {
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-md);
  box-shadow: var(--ui-shadow-sm);
  overflow: hidden;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.home-faq__item[open] {
  border-color: var(--ui-accent-tint);
  box-shadow: var(--ui-shadow-md);
}
.home-faq__item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.05rem 1.25rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--theme-font-heading);
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--theme-ink);
}
.home-faq__item > summary::-webkit-details-marker { display: none; }
.home-faq__item > summary::after {
  content: "";
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  background: currentColor;
  color: var(--theme-accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.18s ease;
}
.home-faq__item[open] > summary::after { transform: rotate(180deg); }
.home-faq__item > summary:hover { color: var(--theme-accent); }
.home-faq__item > summary:focus-visible {
  outline: 2px solid var(--ui-accent-ring);
  outline-offset: -2px;
}
.home-faq__item p {
  margin: 0;
  padding: 0 1.25rem 1.15rem;
  color: var(--theme-ink-soft);
  font-size: 0.96rem;
  line-height: 1.65;
}

/* ---- Banda CTA final: cierre sobre fondo de marca. ---- */
.home-cta {
  margin: 2.5rem 0;
  padding: clamp(2rem, 5vw, 3rem) clamp(1.25rem, 4vw, 2.5rem);
  text-align: center;
  border-radius: var(--ui-radius-xl);
  background: linear-gradient(135deg, color-mix(in srgb, var(--theme-accent) 82%, #fff) 0%, var(--theme-accent) 55%, var(--ui-accent-strong) 100%);
  color: #fff;
}
.home-cta__title {
  margin: 0;
  font-size: clamp(1.5rem, 3.2vw, 2.2rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #fff;
  max-width: 28ch;
  margin-inline: auto;
}
.home-cta__lead {
  margin: 0.75rem auto 0;
  max-width: 40rem;
  color: rgba(255, 255, 255, 0.92);
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  line-height: 1.6;
}
.home-cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  justify-content: center;
  margin-top: 1.6rem;
}

/* =========================================================================
   PLANETA · refinamiento de las nuevas secciones de la home (azul editorial).
   ========================================================================= */
body.theme-confeti .home-vprops { padding-top: 2.75rem; }
/* El tema `planeta` es el que corre en producción, así que sus overrides ganan:
   si no se rebajan aquí también, el rediseño plano no se ve. Se deja sólo un
   matiz de borde; la sombra grande y la pastilla azul maciza se retiran. */
body.theme-confeti .home-vprops__item {
  border-color: color-mix(in srgb, var(--theme-accent) 14%, var(--theme-border));
}

body.theme-confeti .home-categories__section-title,
body.theme-confeti .home-faq__section-title { font-weight: 800; }

body.theme-confeti .how-it-works__steps { text-align: left; }

body.theme-confeti .home-faq__item { border-radius: var(--ui-radius-md); }
body.theme-confeti .home-faq__item[open] { border-color: var(--theme-accent); }

/* CTA final: degradado navy editorial, coherente con el bloque "función
   estrella" y el footer. */
body.theme-confeti .home-cta {
  background: linear-gradient(135deg, var(--pl-navy) 0%, var(--pl-navy-2) 100%);
}
body.theme-confeti .home-cta .btn-pill--light { color: var(--pl-navy); }
body.theme-confeti .home-cta .btn-pill--light:hover,
body.theme-confeti .home-cta .btn-pill--light:focus { color: var(--pl-navy); background: var(--theme-accent-soft); }

/* =========================================================================
   Banner de consentimiento de cookies (RGPD / Guía AEPD). CSP-safe: la lógica
   vive en public/js/cookie-consent.js; el markup en partials/cookie-banner.ejs.
   "Rechazar" y "Aceptar" comparten EXACTAMENTE el estilo .cookie-btn--solid
   (mismo peso visual) para no incurrir en patrones engañosos.
   ========================================================================= */
/* MODAL centrado con overlay, no barra inferior (11-ago-2026): la barra se
   ignoraba, y en esta web ignorar = no medir NADA (sin decisión no se carga
   ningún tag con cookies). El modal fuerza una DECISIÓN, no una aceptación:
   Rechazar sigue al mismo nivel y peso que Aceptar (guía AEPD) y no hay X que
   lo esquive — se sale decidiendo. */
.cookie-banner {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(15, 23, 42, 0.55);
}
.cookie-banner.is-hidden { display: none; }
/* Mientras el modal está abierto, el fondo no scrollea. `:has()` degrada con
   elegancia: sin soporte, solo se pierde el bloqueo de scroll. */
body:has(.cookie-banner:not(.is-hidden)) { overflow: hidden; }
.cookie-banner__inner {
  background: var(--theme-surface, #fff);
  border: 1px solid var(--theme-border, var(--theme-border));
  border-radius: var(--ui-radius-lg);
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.35);
  max-width: 560px;
  width: 100%;
  max-height: min(88vh, 40rem);
  overflow-y: auto;
  padding: 1.35rem 1.35rem 1.15rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem 1.5rem;
}
.cookie-banner__body { flex: 1 1 320px; min-width: 0; }
.cookie-banner__title { margin: 0 0 0.25rem; font-size: 1.05rem; font-weight: 700; }
.cookie-banner__text {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--theme-ink-soft, var(--theme-ink-soft));
}
.cookie-banner__text a { color: var(--theme-accent, var(--theme-accent)); }
.cookie-banner__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  /* A ancho completo bajo el texto: en el modal los botones cierran la caja. */
  flex: 1 1 100%;
  justify-content: flex-end;
}
.cookie-btn {
  appearance: none;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  padding: 0.6rem 1.1rem;
  border-radius: var(--ui-radius-cta);
  border: 1px solid transparent;
  line-height: 1.1;
}
.cookie-btn:focus-visible { outline: 2px solid var(--ui-accent-ring, var(--theme-accent)); outline-offset: 2px; }
.cookie-btn--solid {
  background: var(--theme-accent, var(--theme-accent));
  color: #fff;
  border-color: var(--theme-accent, var(--theme-accent));
}
.cookie-btn--solid:hover { filter: brightness(0.94); }
.cookie-btn--ghost {
  background: transparent;
  color: var(--theme-ink, var(--theme-ink));
  border-color: var(--theme-border, color-mix(in srgb, var(--theme-border) 60%, var(--theme-ink-muted)));
}
.cookie-btn--ghost:hover { border-color: var(--theme-accent, var(--theme-accent)); }
.cookie-prefs {
  flex: 1 1 100%;
  margin-top: 0.5rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--theme-border, var(--theme-border));
  max-width: 1100px;
}
.cookie-prefs[hidden] { display: none; }
.cookie-prefs__intro { margin: 0 0 0.6rem; font-size: 0.85rem; color: var(--theme-ink-soft, var(--theme-ink-soft)); }
.cookie-prefs__row {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  padding: 0.4rem 0;
  font-size: 0.88rem;
  line-height: 1.45;
}
.cookie-prefs__row input { margin-top: 0.2rem; flex: 0 0 auto; }
.cookie-prefs__row--locked { color: var(--theme-ink-soft, var(--theme-ink-soft)); }
.cookie-prefs__actions { margin-top: 0.6rem; }

@media (max-width: 640px) {
  .cookie-banner__actions { width: 100%; }
  .cookie-btn { flex: 1 1 auto; text-align: center; }
}

/* =========================================================================
   Colegios por ciudad — índice /ciudades y ficha de ciudad /ciudad/:slug
   ========================================================================= */

/* Ficha técnica: ocupa el sitio del «Sobre este libro» cuando no hay sinopsis
   de verdad (antes salía el título repetido como descripción). */
.book-specs {
  background: var(--theme-surface, #fff);
  border: 1px solid var(--theme-border, var(--theme-border));
  border-radius: var(--ui-radius-lg);
  padding: 1.1rem 1.25rem;
  margin: 1.25rem 0;
}
.book-specs h2 { margin: 0 0 0.75rem; font-size: 1.15rem; }
.book-specs__list {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.55rem 1.5rem;
}
.book-specs__list > div { display: flex; gap: 0.5rem; align-items: baseline; }
.book-specs__list dt {
  font-size: 0.85rem;
  color: var(--theme-ink-soft, var(--theme-ink-soft));
  flex: 0 0 auto;
}
.book-specs__list dt::after { content: ':'; }
.book-specs__list dd { margin: 0; font-weight: 600; font-size: 0.92rem; min-width: 0; }
.book-specs__list dd a { color: var(--theme-accent, var(--theme-accent)); }

.cities-header,
.city-header { padding: 0.5rem 0 1.6rem; }
.cities-header__title,
.city-header__title {
  margin: 0 0 0.35rem;
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.02em;
}
.cities-header__meta,
.city-header__meta { margin: 0; color: var(--theme-ink-soft); }

/* /ciudades — rejilla de ciudades */
.city-grid {
  list-style: none;
  margin: 0 0 2.5rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 0.75rem;
}
.city-grid__item { margin: 0; }
.city-grid__link {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  height: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  background: var(--theme-surface);
  color: var(--theme-ink);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.city-grid__link:hover,
.city-grid__link:focus-visible {
  border-color: var(--theme-accent);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--theme-accent) 16%, transparent);
  transform: translateY(-2px);
}
.city-grid__pin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  flex: none;
  border-radius: var(--ui-radius-md);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
}
.city-grid__pin svg { width: 1.15rem; height: 1.15rem; }
.city-grid__text { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.city-grid__name { font-weight: 700; line-height: 1.2; }
.city-grid__count { font-size: 0.82rem; color: var(--theme-ink-soft); }

/* /ciudad/:slug — rejilla de colegios */
.school-cards {
  list-style: none;
  margin: 0 0 2rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 0.9rem;
}
.school-card { margin: 0; }
.school-card__link {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  height: 100%;
  padding: 1.1rem 1.2rem 1.2rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  background: var(--theme-surface);
  color: var(--theme-ink);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.school-card__link:hover,
.school-card__link:focus-visible {
  border-color: var(--theme-accent);
  box-shadow: 0 8px 22px color-mix(in srgb, var(--theme-accent) 15%, transparent);
  transform: translateY(-2px);
}
.school-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.school-card__badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  border-radius: var(--ui-radius-pill);
  font-size: 0.74rem;
  font-weight: 700;
  background: var(--theme-surface-alt);
  color: var(--theme-ink-soft);
}
.school-card__badge[data-type="publico"] { background: var(--theme-accent-soft); color: #1c54c4; }
.school-card__badge[data-type="concertado"] { background: #e7f6ec; color: #1f8a4c; }
.school-card__badge[data-type="privado"] { background: #f3ecfc; color: #6b39c9; }
.school-card__arrow {
  display: inline-flex;
  color: var(--theme-ink-muted);
  transition: transform 0.15s ease, color 0.15s ease;
}
.school-card__arrow svg { width: 1.1rem; height: 1.1rem; }
.school-card__link:hover .school-card__arrow {
  color: var(--theme-accent);
  transform: translateX(3px);
}
.school-card__name {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
}
.school-card__addr {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  color: var(--theme-ink-soft);
  font-size: 0.85rem;
  line-height: 1.35;
}
.school-card__addr svg {
  width: 0.95rem;
  height: 0.95rem;
  flex: none;
  margin-top: 0.12rem;
  color: var(--theme-ink-muted);
}
.school-card__stages {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: auto;
  padding-top: 0.25rem;
}
.stage-tag {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.5rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface-alt);
  color: var(--theme-ink-soft);
  font-size: 0.72rem;
  font-weight: 600;
}

/* =========================================================================
   Ficha de colegio — /colegio/:slug
   ========================================================================= */

.school__header {
  display: flex;
  gap: 1.1rem;
  padding: 1.5rem 1.6rem;
  margin: 0 0 1.5rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
}
.school__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  flex: none;
  border-radius: var(--ui-radius-md);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
}
.school__icon svg { width: 1.6rem; height: 1.6rem; }
.school__head-body { display: flex; flex-direction: column; gap: 0.55rem; min-width: 0; }
.school__name {
  margin: 0;
  font-size: clamp(1.35rem, 2.6vw, 1.85rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.02em;
}
.school__facts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  color: var(--theme-ink-soft);
  font-size: 0.9rem;
}
.school__addr { display: inline-flex; align-items: center; gap: 0.35rem; }
.school__addr svg { width: 0.95rem; height: 0.95rem; flex: none; color: var(--theme-ink-muted); }
.school__stages { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.school__stats { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 0.15rem; }
.school__stat {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  padding: 0.35rem 0.75rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  font-size: 0.84rem;
  color: var(--theme-ink-soft);
}
.school__stat strong { font-size: 1.05rem; font-weight: 800; color: var(--theme-ink); }

/* Badge de tipo (compartido con las tarjetas de /ciudad) */
.school__badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  border-radius: var(--ui-radius-pill);
  font-size: 0.74rem;
  font-weight: 700;
  background: var(--theme-surface-alt);
  color: var(--theme-ink-soft);
}
.school__badge[data-type="publico"] { background: var(--theme-accent-soft); color: #1c54c4; }
.school__badge[data-type="concertado"] { background: #e7f6ec; color: #1f8a4c; }
.school__badge[data-type="privado"] { background: #f3ecfc; color: #6b39c9; }

/* Índice de cursos (chips de navegación) */
.school__toc {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 1.75rem;
}
.school__toc-label { font-weight: 600; color: var(--theme-ink-soft); font-size: 0.9rem; }
.school__toc-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.4rem 0.85rem;
  border-radius: var(--ui-radius-pill);
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  color: var(--theme-ink);
  font-size: 0.88rem;
  font-weight: 600;
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}
.school__toc-chip:hover,
.school__toc-chip:focus-visible {
  border-color: var(--theme-accent);
  color: var(--theme-accent);
  background: var(--theme-accent-soft);
}

/* Cabecera de cada curso */
.school-course { scroll-margin-top: 84px; margin-bottom: 2.25rem; }
.school-course__title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 1rem;
  padding-bottom: 0.6rem;
  font-size: clamp(1.2rem, 2.2vw, 1.5rem);
  font-weight: 800;
  border-bottom: 2px solid var(--theme-border);
}
.school-course__count {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.6rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent-soft);
  color: var(--theme-accent);
  font-size: 0.8rem;
  font-weight: 700;
}

.school__description {
  margin: 0 0 1.5rem;
  color: var(--theme-ink-soft);
  line-height: 1.6;
}
.school__links { margin-top: 2.25rem; }
.school__booklist-source { margin-top: 1.5rem; color: var(--theme-ink-soft); font-size: 0.9rem; }

/* Botón "añadir todo el curso a la comparativa" (tras el detalle por libro) */
.school-course__add { margin-top: 1.25rem; }
.school-course__add-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.7rem 1.35rem;
  border-radius: var(--ui-radius-pill);
  border: 1px solid var(--theme-accent);
  background: var(--theme-accent);
  color: #fff;
  font: inherit;
  font-weight: 700;
  font-size: 0.92rem;
  cursor: pointer;
  transition: filter 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.school-course__add-btn:hover {
  filter: brightness(1.06);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--theme-accent) 28%, transparent);
  transform: translateY(-1px);
}

/* ===== Ofertas sin precio mostrable (Amazon: catálogo base sin refresco) ===== */
.offer__pricing--unknown .offer__price-unknown {
  display: block;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--theme-ink-soft, #445);
}

.book-card__price--consult {
  color: var(--theme-ink-soft, #556);
  font-weight: 600;
}

/* ===== Mix óptimo destacado (la combinación más barata, abierta) ===== */
.list-mix--featured {
  border: 2px solid var(--theme-accent, var(--theme-accent));
  border-radius: var(--ui-radius-md);
  background: var(--theme-accent-soft, var(--theme-accent-soft));
  margin-bottom: 1.4rem;
}

.list-mix--featured > .list-mix__summary {
  font-size: 1.05rem;
}

.list-mix--featured .list-mix__summary-label {
  font-weight: 800;
  color: var(--theme-ink, #123);
}

.list-mix__saving {
  color: var(--theme-success, var(--theme-success));
  font-weight: 800;
}

/* ===== Cesta de Amazon como acción secundaria de la lista ===== */
.list-buys__amazon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem 1.2rem;
  margin-top: 1rem;
  padding: 0.9rem 1.1rem;
  border: 1px dashed var(--theme-border, #d5dde5);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface-alt, #f7fafc);
}

.list-buys__amazon-text {
  flex: 1 1 18rem;
  font-size: 0.92rem;
  color: var(--theme-ink-soft, #445);
}

.list-buys__amazon-cta {
  display: inline-block;
  padding: 0.55rem 1.1rem;
  border-radius: var(--ui-radius-pill);
  background: #ff9900;
  color: #111;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.list-buys__amazon-cta:hover { filter: brightness(0.95); }

/* ===== Feedback de subida de lista (foto/PDF) ===== */
.compare-upload__file {
  margin: 0.5rem 0 0;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--theme-success, var(--theme-success));
  word-break: break-all;
}

.compare-form__submit[disabled] {
  opacity: 0.7;
  cursor: progress;
}

/* Archivo elegido: el recuadro tiene que cambiar lo bastante como para que se
   vea de un vistazo que el fichero entró. Antes no cambiaba nada y el usuario
   no sabía si había pasado algo ni que faltaba pulsar el botón. */
.dropzone.is-loaded {
  border-style: solid;
  border-color: var(--theme-success, var(--theme-success));
  background: color-mix(in srgb, var(--theme-success, var(--theme-success)) 8%, var(--theme-surface));
}
.dropzone.is-loaded .dropzone__icon { color: var(--theme-success, var(--theme-success)); }
.dropzone.is-loaded .dropzone__title { word-break: break-all; }

/* Arrastrando un fichero por encima: confirma que el recuadro acepta el drop. */
.dropzone.is-dragover {
  border-style: solid;
  border-color: var(--theme-accent);
  background: color-mix(in srgb, var(--theme-accent) 16%, var(--theme-surface));
  box-shadow: var(--ui-shadow-sm);
}

/* El botón pasa a primer plano en cuanto hay archivo: es el paso que se perdía. */
.compare-form__submit.is-ready {
  animation: upload-ready-pulse 1.6s ease-out 2;
}
@keyframes upload-ready-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--theme-accent) 55%, transparent); }
  70%  { box-shadow: 0 0 0 0.65rem color-mix(in srgb, var(--theme-accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--theme-accent) 0%, transparent); }
}

/* Barra indeterminada durante la subida. El <form> nativo no expone progreso,
   así que no fingimos un porcentaje: sólo decimos "esto sigue vivo". Subir 3 MB
   por el enlace de subida de una conexión doméstica tarda, y sin esto parecía
   que la web se había colgado. */
.upload-progress {
  margin: 0;
  height: 0.3rem;
  border-radius: var(--ui-radius-pill);
  background: color-mix(in srgb, var(--theme-accent) 18%, var(--theme-surface));
  overflow: hidden;
}
.upload-progress__bar {
  display: block;
  height: 100%;
  width: 40%;
  border-radius: inherit;
  background: var(--theme-accent);
  animation: upload-progress-slide 1.1s ease-in-out infinite;
}
@keyframes upload-progress-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}
.compare-upload.is-uploading .dropzone { cursor: progress; }

@media (prefers-reduced-motion: reduce) {
  .compare-form__submit.is-ready { animation: none; }
  .upload-progress__bar { animation: none; width: 100%; opacity: 0.65; }
}

/* ===== Precio más bajo en 30 días (price_history) ===== */
.offers__lowest30 {
  margin: 0.2rem 0 0.8rem;
  font-size: 0.92rem;
  color: var(--theme-ink-soft, #445);
}

.offers__lowest30 strong {
  color: var(--theme-success, var(--theme-success));
}

/* ===== Navegación de dos verticales (texto / todos los libros) ===== */
.nav-group {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.nav-group__label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  white-space: nowrap;
  font-weight: 600;
}

.nav-group__caret {
  font-size: 0.62em;
  line-height: 1;
  opacity: 0.65;
  transform: translateY(1px);
}

.nav-group:hover .nav-group__caret,
.nav-group:focus-within .nav-group__caret {
  opacity: 1;
}

/* Desktop: menú desplegable en hover/focus. */
@media (min-width: 721px) {
  .nav-group__menu {
    position: absolute;
    top: calc(100% + 0.55rem);
    left: 50%;
    transform: translateX(-50%);
    min-width: 15rem;
  }

  /* Puente invisible label→menú para que el hover no se corte en el hueco. */
  .nav-group::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: 0.6rem;
  }

  .nav-group__menu {
    display: none;
    flex-direction: column;
    padding: 0.5rem 0;
    background: var(--theme-surface, #fff);
    border: 1px solid var(--theme-border, var(--theme-border));
    border-radius: var(--ui-radius-sm);
    box-shadow: var(--ui-shadow-md, 0 10px 26px rgba(16, 42, 67, 0.14));
    z-index: 60;
  }

  .nav-group:hover .nav-group__menu,
  .nav-group:focus-within .nav-group__menu {
    display: flex;
  }

  .nav-group__menu a {
    padding: 0.5rem 1.1rem;
    white-space: nowrap;
  }

  .nav-group__menu a:hover {
    background: var(--theme-accent-soft, var(--theme-accent-soft));
  }
}

/* Móvil (nav off-canvas): los grupos se muestran expandidos como secciones. */
@media (max-width: 720px) {
  .nav-group {
    display: block;
    width: 100%;
  }

  .nav-group__label {
    display: block;
    font-weight: 800;
    pointer-events: auto;
  }

  .nav-group__caret { display: none; }

  .nav-group__menu {
    display: flex;
    flex-direction: column;
    padding-left: 0.9rem;
  }
}

/* =========================================================================
   Chat widget (asistente de libros). Lógica en public/js/chat-widget.js
   (CSP-safe, solo se monta si /api/chat/status responde enabled). Colores,
   radios y sombras SIEMPRE vía tokens del tema para heredar el preset activo
   (Planeta por defecto): nada hardcodeado salvo los fallbacks.
   ========================================================================= */

.clchat-launcher {
  position: fixed;
  right: 1.2rem;
  bottom: 1.2rem;
  /* Bajo el banner de cookies (z 1000): el consentimiento siempre gana. */
  z-index: 90;
  width: 3.5rem;
  height: 3.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--theme-accent, var(--theme-accent));
  color: #fff;
  cursor: pointer;
  box-shadow: var(--ui-shadow-accent, 0 12px 30px rgba(20, 136, 200, 0.32));
  transition: transform 0.15s ease, background 0.15s ease;
}

.clchat-launcher:hover {
  background: var(--ui-accent-strong, var(--ui-accent-strong));
  transform: translateY(-2px);
}

.clchat-launcher:focus-visible {
  outline: 3px solid var(--ui-accent-ring, rgba(20, 136, 200, 0.3));
  outline-offset: 2px;
}

.clchat-launcher svg { display: block; }

.clchat-panel {
  position: fixed;
  right: 1.2rem;
  /* Deja la burbuja visible debajo: sirve de segundo botón de cierre. */
  bottom: 5.4rem;
  z-index: 91;
  width: min(380px, calc(100vw - 2rem));
  height: min(560px, calc(100dvh - 6rem));
  display: flex;
  flex-direction: column;
  background: var(--theme-surface, #fff);
  border: 1px solid var(--theme-border, var(--theme-border));
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-lg, 0 22px 50px rgba(31, 27, 46, 0.14));
  overflow: hidden;
}

.clchat-panel[hidden] { display: none; }

.clchat-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.8rem 1rem;
  background: var(--theme-accent, var(--theme-accent));
  color: #fff;
}

.clchat-head__title {
  flex: 1;
  min-width: 0;
  font-family: var(--theme-font-heading, inherit);
  font-weight: 700;
  font-size: 1rem;
}

.clchat-head__close {
  display: flex;
  border: none;
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 0.3rem;
  border-radius: var(--ui-radius-sm);
}

.clchat-head__close:hover { background: rgba(255, 255, 255, 0.18); }

.clchat-head__close:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.clchat-msgs {
  flex: 1;
  overflow-y: auto;
  /* Evita que el scroll del hilo arrastre el scroll de la página. */
  overscroll-behavior: contain;
  padding: 1rem 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  background: var(--theme-bg, #fff);
}

.clchat-msg {
  max-width: 85%;
  padding: 0.55rem 0.8rem;
  border-radius: var(--ui-radius-md);
  font-size: 0.92rem;
  line-height: 1.45;
  overflow-wrap: break-word;
}

.clchat-msg--user {
  align-self: flex-end;
  background: var(--theme-accent, var(--theme-accent));
  color: #fff;
  border-bottom-right-radius: var(--theme-radius, 4px);
  /* El usuario puede meter saltos con Shift+Enter (textContent, sin <br>). */
  white-space: pre-wrap;
}

.clchat-msg--bot {
  align-self: flex-start;
  background: var(--theme-surface-alt, var(--theme-surface-alt));
  color: var(--theme-ink, var(--theme-ink));
  border-bottom-left-radius: var(--theme-radius, 4px);
}

.clchat-msg--error {
  background: color-mix(in srgb, var(--theme-danger, var(--theme-danger)) 8%, var(--theme-surface, #fff));
  border: 1px solid color-mix(in srgb, var(--theme-danger, var(--theme-danger)) 30%, transparent);
  color: var(--theme-danger, var(--theme-danger));
}

.clchat-msg__text a {
  color: var(--theme-accent, var(--theme-accent));
  text-decoration: underline;
}

.clchat-msg__text code {
  font-family: var(--theme-font-mono, monospace);
  font-size: 0.85em;
  background: rgba(0, 0, 0, 0.06);
  padding: 0.05rem 0.3rem;
  border-radius: var(--ui-radius-sm);
}

.clchat-msg__text ul {
  margin: 0.25rem 0 0.25rem 1.1rem;
  padding: 0;
}

/* Tarjetas de libro dentro de la respuesta del asistente */
.clchat-card {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--theme-surface, #fff);
  border: 1px solid var(--theme-border, var(--theme-border));
  border-radius: var(--ui-radius-lg);
  padding: 0.5rem 0.6rem;
  margin: 0.45rem 0;
}

.clchat-card__img {
  width: 48px;
  height: auto;
  max-height: 72px;
  object-fit: contain;
  border-radius: var(--ui-radius-sm);
  flex-shrink: 0;
}

.clchat-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.clchat-card__title {
  font-weight: 700;
  font-size: 0.88rem;
  color: var(--theme-ink, var(--theme-ink));
  text-decoration: none;
}

a.clchat-card__title:hover {
  color: var(--theme-accent, var(--theme-accent));
  text-decoration: underline;
}

.clchat-card__author {
  font-size: 0.78rem;
  color: var(--theme-ink-muted, var(--theme-ink-muted));
}

.clchat-card__price {
  font-size: 0.92rem;
  font-weight: 800;
  color: var(--theme-ink, var(--theme-ink));
}

.clchat-card__btn {
  align-self: flex-start;
  margin-top: 0.2rem;
  padding: 0.3rem 0.7rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent, var(--theme-accent));
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  text-decoration: none;
}

.clchat-card__btn:hover { background: var(--ui-accent-strong, var(--ui-accent-strong)); }

/* Chips de sugerencia inicial */
.clchat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.clchat-chip {
  border: 1px solid var(--theme-accent, var(--theme-accent));
  color: var(--theme-accent, var(--theme-accent));
  background: var(--theme-surface, #fff);
  border-radius: var(--ui-radius-pill);
  padding: 0.35rem 0.75rem;
  font-size: 0.82rem;
  text-align: left;
  cursor: pointer;
}

.clchat-chip:hover { background: var(--theme-accent-soft, var(--theme-accent-soft)); }

.clchat-chip:focus-visible {
  outline: 2px solid var(--ui-accent-ring, rgba(20, 136, 200, 0.3));
  outline-offset: 2px;
}

/* Indicador de escritura (tres puntos) */
.clchat-typing {
  display: flex;
  gap: 0.3rem;
  padding: 0.7rem 0.9rem;
}

.clchat-typing span {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--theme-ink-muted, var(--theme-ink-muted));
  animation: clchat-blink 1.1s infinite both;
}

.clchat-typing span:nth-child(2) { animation-delay: 0.18s; }
.clchat-typing span:nth-child(3) { animation-delay: 0.36s; }

@keyframes clchat-blink {
  0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-2px); }
}

/* Formulario de envío */
.clchat-form {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  padding: 0.6rem 0.7rem;
  border-top: 1px solid var(--theme-border, var(--theme-border));
  background: var(--theme-surface, #fff);
}

.clchat-input {
  flex: 1;
  resize: none;
  min-height: 2.4rem;
  max-height: 120px;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--theme-border, var(--theme-border));
  border-radius: var(--ui-radius-md);
  font: inherit;
  font-size: 0.92rem;
  line-height: 1.35;
  color: var(--theme-ink, var(--theme-ink));
  background: var(--theme-bg, #fff);
}

.clchat-input:focus-visible {
  outline: 2px solid var(--ui-accent-ring, rgba(20, 136, 200, 0.3));
  border-color: var(--theme-accent, var(--theme-accent));
}

.clchat-send {
  flex-shrink: 0;
  width: 2.6rem;
  height: 2.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--theme-accent, var(--theme-accent));
  color: #fff;
  cursor: pointer;
}

.clchat-send:hover { background: var(--ui-accent-strong, var(--ui-accent-strong)); }

.clchat-send:focus-visible {
  outline: 3px solid var(--ui-accent-ring, rgba(20, 136, 200, 0.3));
  outline-offset: 2px;
}

.clchat-send:disabled,
.clchat-input:disabled {
  opacity: 0.55;
  cursor: default;
}

/* Móvil: el panel ocupa casi toda la pantalla (tapa también la burbuja). */
@media (max-width: 480px) {
  .clchat-panel {
    left: 0.5rem;
    right: 0.5rem;
    bottom: 0.5rem;
    width: auto;
    height: calc(100dvh - 1.5rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .clchat-launcher { transition: none; }
  .clchat-launcher:hover { transform: none; }
  .clchat-typing span { animation: none; opacity: 0.6; }
}

/* ------------------------- Rail de compra (ficha) ------------------------ */
/* El clic a /out es la conversion del sitio y quedaba por debajo del pliegue.
   Este rail lo sube y lo mantiene a la vista mientras se lee la ficha. Reusa el
   MISMO enlace `/out/{merchant}/{isbn}` con sus atributos, asi que la medicion
   no cambia. La comparativa completa sigue abajo: esto no la sustituye. */
.buy-rail__inner {
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  background: var(--theme-surface);
  padding: 1rem;
  box-shadow: var(--theme-shadow-sm);
}
.buy-rail__title { margin: 0 0 0.75rem; font-weight: 700; font-size: 1rem; }
.buy-rail__list { list-style: none; margin: 0; padding: 0; }

/* Bloque de comparativa, encima de las tiendas. Va con fondo propio para que se
   lea como una accion DISTINTA de "comprar aqui" —es lo contrario: no te vayas
   todavia—, y separado por un borde inferior del listado de tiendas. */
/* Señal de la comparativa multi-libro en el hueco del hero: nota con enlace,
   no caja con botón — rellena el espacio que dejó la caja al mudarse tras los
   precios sin competir con el flujo de compra de un solo libro. */
.compare-hint {
  margin: 1.1rem 0 0;
  padding: 0.7rem 0.9rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--theme-ink-soft, var(--theme-ink-soft));
  background: color-mix(in srgb, var(--theme-accent, var(--theme-accent)) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--theme-accent, var(--theme-accent)) 18%, transparent);
  border-radius: var(--ui-radius-md);
}
.compare-hint strong { color: var(--theme-ink, var(--theme-ink)); }
.compare-hint a {
  color: var(--theme-accent, var(--theme-accent));
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* El botón que añade, con pinta de enlace: va en medio de la frase. */
.compare-hint__form { display: inline; }
.compare-hint__link {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
  color: var(--theme-accent, var(--theme-accent));
  text-decoration: underline;
  text-underline-offset: 3px;
}
.compare-hint__link:focus-visible { outline: 2px solid var(--ui-accent-ring, var(--theme-accent)); outline-offset: 2px; }

/* ------------------------- Buscador de cabecera -------------------------
   En posición PRIME tras el logo y con presencia (borde de acento, lupa
   dentro, crece hasta ~430px): es la herramienta nº 1 del sitio. */
.site-header__inner { position: relative; }
.site-header__search-toggle { display: none; }
.site-header__search-btn { display: none; }
.site-header__search {
  position: relative;
  flex: 1 1 auto;
  max-width: 520px;
  margin: 0 0.5rem 0 1.1rem;
}
.site-header__search-icon {
  position: absolute;
  left: 0.8rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.05rem;
  height: 1.05rem;
  color: var(--theme-accent, var(--theme-accent));
  pointer-events: none;
}
.site-header__search input[type='search'] {
  width: 100%;
  padding: 0.55rem 0.9rem 0.55rem 2.35rem;
  border: 1.5px solid color-mix(in srgb, var(--theme-accent, var(--theme-accent)) 45%, var(--theme-border, color-mix(in srgb, var(--theme-border) 60%, var(--theme-ink-muted))));
  border-radius: 999px;
  font: inherit;
  font-size: 0.9rem;
  background: var(--theme-surface, #fff);
  color: var(--theme-ink, var(--theme-ink));
}
.site-header__search input[type='search']:focus-visible {
  outline: 2px solid var(--ui-accent-ring, var(--theme-accent));
  outline-offset: 1px;
  border-color: var(--theme-accent, var(--theme-accent));
}
/* El panel de resultados hereda `left:0; right:0` del form y salía con el
   ancho del input: títulos truncados (feedback de Rafael con captura). Aquí se
   ensancha por encima del input, sin desbordar la pantalla. */
.site-header__search .live-search__panel {
  width: min(30rem, calc(100vw - 2rem));
  right: auto;
  z-index: 60;
}
@media (max-width: 719px) {
  /* La lupa junto a la hamburguesa; el formulario se despliega a ancho
     completo bajo la cabecera (mismo patrón checkbox CSS-only). */
  .site-header__search-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.4rem;
    height: 2.4rem;
    border: 1px solid var(--theme-border, color-mix(in srgb, var(--theme-border) 60%, var(--theme-ink-muted)));
    border-radius: var(--ui-radius-sm);
    color: var(--theme-ink, var(--theme-ink));
    cursor: pointer;
  }
  .site-header__search-btn svg { width: 1.25rem; height: 1.25rem; }
  .site-header__search {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    margin: 0;
    padding: 0.65rem 1rem;
    background: var(--theme-surface, #fff);
    border-bottom: 1px solid var(--theme-border, var(--theme-border));
    box-shadow: 0 10px 24px rgba(15, 23, 42, 0.1);
    z-index: 30;
  }
  .site-header__search-toggle:checked ~ .site-header__search { display: block; }
  .site-header__search input[type='search'] { width: 100%; }
  .site-header__search .live-search__panel { width: 100%; right: 0; }
  .site-header__search-icon { left: 1.8rem; top: calc(50% + 1px); }
}

.buy-rail__trust {
  margin: 0.7rem 0 0;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--theme-ink-muted, var(--theme-ink-muted));
  text-align: center;
}

.buy-rail__compare {
  /* Separacion mayor por debajo: va antes del titular «Comprar este libro» y
     tiene que leerse como un bloque APARTE, no como su entradilla. */
  margin: 0 0 1.1rem;
  padding: 0.75rem 0.8rem;
  /* `md`, no `sm`: esta caja queda pegada a la tarjeta del hero (radio lg) y
     el salto lg→sm entre vecinas era la esquina «rara» de la captura de
     Rafael (13-ago-2026). El paso intermedio suaviza la transición. */
  border-radius: var(--ui-radius-md);
  background: var(--theme-surface-alt, #f5f7fa);
  border: 1px solid var(--theme-border);
}
.buy-rail__compare--ok { border-color: color-mix(in srgb, var(--theme-success) 45%, transparent); }
.buy-rail__compare-text {
  margin: 0 0 0.6rem;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--theme-muted, var(--theme-ink-soft));
}
.buy-rail__compare-text strong {
  display: block;
  color: inherit;
  font-size: 0.9rem;
  margin-bottom: 0.2rem;
  /* Entra en UNA linea por el copy, no por `nowrap`: con 23 caracteres sobra
     en los ~270px utiles de la columna. Forzarlo con `white-space: nowrap`
     habria bastado hoy, pero el texto es editable desde /admin/content y un
     override mas largo se saldria de la tarjeta en vez de partirse. */
}
/* Mismo boton azul que el CTA del medio (`.add-compare__btn`): el de contorno
   se leia como accion opcional cuando es la principal del sitio.

   `--buy-rail-btn-h` la comparten con los botones de tienda: aquel lleva el
   logo de 20px dentro y este no, asi que dejandolos al padding cada uno salia
   de una altura y en una columna estrecha, uno debajo de otro, el desajuste
   cantaba. Con `min-height` mandan los dos lo mismo lleve lo que lleve dentro. */
.buy-rail__inner { --buy-rail-btn-h: 2.75rem; }
.buy-rail__compare-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--buy-rail-btn-h);
  padding: 0.4rem 0.7rem;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  border: 0;
  border-radius: var(--ui-radius-cta);
  background: var(--theme-accent);
  color: var(--theme-surface);
}
a.buy-rail__compare-btn:hover,
.buy-rail__compare-btn:hover { filter: brightness(0.93); text-decoration: none; color: var(--theme-surface); }

.buy-rail__item { padding: 0.6rem 0; border-top: 1px solid var(--theme-border); }
.buy-rail__item:first-child { border-top: 0; padding-top: 0; }
.buy-rail__row { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.buy-rail__merchant { font-weight: 600; font-size: 0.95rem; }
.buy-rail__total { font-weight: 800; font-size: 1.05rem; color: var(--theme-accent); }
.buy-rail__shipping {
  display: block;
  font-size: 0.8rem;
  color: var(--theme-ink-muted);
  margin: 0.1rem 0 0.5rem;
}
.buy-rail__btn {
  /* Flex, no block: el botón lleva el logo de la tienda junto al texto, igual
     que los de la comparativa completa (.offer__button-logo). El color de fondo
     lo pone la marca en línea, así que el logo es lo que hace reconocible el
     botón de un vistazo sin leerlo. */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  text-align: center;
  min-height: var(--buy-rail-btn-h);
  padding: 0.4rem 0.8rem;
  border-radius: var(--ui-radius-cta);
  background: var(--theme-accent);
  color: #fff;
  font-weight: 700;
  font-size: 0.92rem;
  text-decoration: none;
}
.buy-rail__btn-logo {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border-radius: 50%;
  background: #fff;
  padding: 2px;
  object-fit: contain;
}
.buy-rail__btn:hover { filter: brightness(0.93); text-decoration: none; color: #fff; }

/* Insignia «Más barato» junto al nombre de la mejor tienda: el mismo pill que
   la comparativa grande, para que el botón único del rail se lea como LO QUE
   ES — la ganadora — y no como la única opción. */
.buy-rail__flag {
  display: inline-block;
  margin-left: 0.3rem;
  padding: 0.12rem 0.5rem;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  vertical-align: 0.1em;
  white-space: nowrap;
}

/* Separador «También disponible en» entre la ganadora y las alternativas. */
.buy-rail__also {
  margin: 0.9rem 0 0.3rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--theme-border);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--theme-ink-muted);
  list-style: none;
}
.buy-rail__also + .buy-rail__item { border-top: 0; }

/* Tiendas alternativas del rail: filas compactas donde TODA la fila es el
   enlace de compra. Con 5 tiendas, cinco botones grandes con su desglose
   medían más que el viewport y el rail sticky dejaba las últimas fuera de
   alcance (13-ago-2026, al entrar Abacus). Solo la mejor conserva el botón. */
/* Cada tienda alternativa es una FILA PULSABLE, y en reposo no lo parecia: era
   texto sobre el fondo de la tarjeta, separado por filetes, con el galon en
   gris. Habia hover, pero en el movil no hay hover. Ahora cada una es una
   pastilla con su borde —y el filete separador sobra, que si no son dos lineas
   juntas— y el galon va en color de marca, que es la senal de «esto lleva a
   algun sitio» (14-ago-2026). */
.buy-rail__item--alt { padding: 0.15rem 0; border-top: 0; }
.buy-rail__alt-link {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-md);
  background: var(--theme-surface);
  color: var(--theme-ink);
  transition: background 0.15s ease, border-color 0.15s ease;
}
.buy-rail__alt-link:hover {
  background: var(--theme-accent-soft);
  border-color: var(--theme-accent);
  text-decoration: none;
}
.buy-rail__alt-logo { flex: none; border-radius: 4px; object-fit: contain; }
.buy-rail__alt-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.05rem; }
.buy-rail__alt-name { font-weight: 600; font-size: 0.9rem; line-height: 1.2; }
.buy-rail__alt-ship { font-size: 0.75rem; color: var(--theme-ink-muted); line-height: 1.2; }
/* «Envío gratis» en verde (señal positiva visible de un vistazo); el envío con
   coste queda en gris. Mismo tamaño: la visibilidad viene del color, no de
   crecer. */
.buy-rail__shipping.is-free,
.buy-rail__alt-ship.is-free { color: var(--theme-success, #16a34a); font-weight: 600; }
.buy-rail__alt-total { flex: none; font-weight: 800; font-size: 0.95rem; }
.buy-rail__alt-go { flex: none; color: var(--theme-accent); font-size: 1.15rem; line-height: 1; }
.buy-rail__alt-link:hover .buy-rail__alt-go { color: var(--theme-accent); }

.buy-rail__all {
  display: block;
  margin-top: 0.85rem;
  text-align: center;
  font-size: 0.88rem;
}

/* ESCRITORIO: columna pegajosa a la derecha. El rail necesita un AREA tan alta
   como el contenido de la izquierda; sin eso `sticky` no tiene recorrido y se
   queda quieto en su fila.

   Ojo con `grid-row: 1 / -1`, que es lo que habia aqui y NO hace lo que parece:
   `-1` apunta a la ultima linea de la rejilla EXPLICITA, y como aqui no hay
   `grid-template-rows`, esa linea es la 1. O sea que el rail se quedaba en la
   fila 1 —la cabecera del libro— y, al ser mas alto que ella, la estiraba: de
   ahi el hueco en mitad de la pagina, entre la cabecera y la comparativa.

   `span 99` si abarca todas las filas reales (las implicitas de mas se crean
   vacias y no ocupan). Al abarcarlas todas, el contenido de la izquierda ya
   suma mas alto que el rail y no hay sobrante que repartir. */
@media (min-width: 1100px) {
  .book-detail {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 0 2rem;
    align-items: start;
  }
  .book-detail > *:not(.buy-rail) { grid-column: 1; }

  .buy-rail {
    grid-column: 2;
    grid-row: 1 / span 99;
    align-self: start;
    position: sticky;
    /* La cabecera tambien es `sticky` con `top: 0` y mide ~68px: con 1rem el
       rail se le pegaba por debajo sin aire. Se despeja su alto mas un margen. */
    top: 5.5rem;
    /* Red de seguridad: un sticky MAS ALTO que el viewport deja su final
       inaccesible mientras esta pegado (pasó con 5 tiendas y botón por tienda,
       13-ago-2026). Si el rail no cabe, scrollea por dentro en vez de cortarse.
       El padding/margin compensados evitan que el overflow recorte la sombra. */
    max-height: calc(100vh - 6rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 4px;
    margin: -4px;
  }
}

/* POR DEBAJO DE 720 px NO HAY RAIL: manda `.buybar`.
   Las dos son barras `fixed; bottom: 0`, y en un movil se pintaban LAS DOS,
   apiladas una sobre otra, enseñando la misma oferta dos veces y tapandose entre
   ellas — el hueco reservado (`padding-bottom`) solo daba para una, asi que el
   final del contenido quedaba debajo. `.buybar` es la compacta (una fila: precio
   + boton) y la que se diseño para el movil; el rail-convertido-en-barra se
   queda para el tramo tablet, donde si es el unico. */
@media (max-width: 719px) {
  .buy-rail { display: none; }
}

/* TABLET: un rail lateral no cabe, asi que se convierte en barra inferior fija
   con SOLO la mejor oferta — mas de una en esa franja tapa la pagina. */
@media (min-width: 720px) and (max-width: 1099px) {
  .buy-rail {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    padding: 0.5rem 0.75rem calc(0.5rem + env(safe-area-inset-bottom));
    background: var(--theme-surface);
    border-top: 1px solid var(--theme-border);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
  }
  .buy-rail__inner { border: 0; padding: 0; box-shadow: none; background: none; }
  .buy-rail__title,
  .buy-rail__all,
  .buy-rail__compare,
  .buy-rail__also,
  .buy-rail__item:not(:first-child) { display: none; }
  .buy-rail__item:first-child { padding: 0; border: 0; }
  .buy-rail__row { display: inline-flex; }
  .buy-rail__shipping { display: inline; margin: 0 0 0 0.5rem; }
  .buy-rail__btn { margin-top: 0.4rem; }
  /* Hueco para que la barra no tape el final del contenido. */
  .book-detail { padding-bottom: 7.5rem; }
}

/* (La regla que apilaba las barras de compra sobre el banner de cookies se
   retiró el 11-ago-2026: el banner pasó de barra inferior a MODAL con overlay a
   pantalla completa, así que ya no hay solape que resolver — mientras el modal
   está abierto, decidir es lo único que se puede hacer, que es la intención.) */

/* ============ Buscador pegajoso + filtros en barra (08-ago-2026) ============
   La columna lateral de 240 px partia «Comercial Grupo Anaya S.a.» en dos
   lineas, apilaba veinte editoriales con sus recuentos y se quedaba con un
   quinto del ancho de forma permanente para una herramienta que se usa una vez
   y se cierra. Pasa a una barra de desplegables sobre los resultados. */

.search-sticky {
  position: sticky;
  /* Despeja la cabecera del sitio, que tambien es `sticky` con top: 0. */
  top: 3.6rem;
  z-index: 12;
  margin: 0 0 1.25rem;
  padding: 0.5rem 0;
  /* Ni blanco sólido ni transparente: las dos fallan en un extremo distinto.
     Con `--theme-bg` opaco se recortaba un rectángulo blanco contra la capa
     decorativa azulada del tema; sin fondo, las portadas pasan nítidas por
     detrás al desplazarse. Un velo tenue + desenfoque del fondo funciona en los
     dos estados: arriba apenas se distingue de la capa decorativa (que es casi
     lisa) y en scroll disuelve lo que pasa por debajo. */
  background: color-mix(in srgb, var(--theme-bg) 72%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
}
/* Sin soporte de `backdrop-filter` no hay desenfoque que valga: ahí sí compensa
   el fondo opaco, porque tapar mal es peor que recortar un rectángulo. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .search-sticky { background: var(--theme-bg); }
}
@media (min-width: 720px) { .search-sticky { top: 4.2rem; } }

.search-layout { display: block; }

.facet-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
}
.facet-bar__label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--theme-ink-muted);
  margin-right: 0.15rem;
}
.facet-bar__label svg { width: 1rem; height: 1rem; }
.facet-bar__reset {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--theme-ink-muted);
  text-decoration: underline;
}
.facet-bar__reset:hover { color: var(--theme-accent); }

.facet-drop { position: relative; }
.facet-drop__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background: var(--theme-surface);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--theme-ink);
  cursor: pointer;
  list-style: none;
  white-space: nowrap;
}
.facet-drop__btn::-webkit-details-marker { display: none; }
.facet-drop__btn:hover { border-color: var(--theme-accent); color: var(--theme-accent); }
.facet-drop.is-active > .facet-drop__btn {
  background: var(--theme-accent-soft);
  border-color: color-mix(in srgb, var(--theme-accent) 45%, var(--theme-border));
  color: var(--theme-accent);
}
.facet-drop__value {
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 700;
}
.facet-drop__value::before { content: "· "; }
.facet-drop__caret { width: 0.85rem; height: 0.85rem; flex: none; transition: transform 0.15s ease; }
.facet-drop[open] > .facet-drop__btn > .facet-drop__caret { transform: rotate(180deg); }

.facet-drop__panel {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  z-index: 20;
  min-width: 15rem;
  max-width: min(24rem, 88vw);
  /* El tope de alto es lo que hace usable «Editorial», que trae veinte entradas
     con nombres largos: se desplaza dentro del panel en vez de estirar la barra. */
  max-height: min(60vh, 26rem);
  overflow-y: auto;
  padding: 0.4rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-lg, 0 16px 40px rgba(8, 30, 60, 0.16));
}
.facet-drop__list { list-style: none; margin: 0; padding: 0; }
.facet-drop__list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.45rem 0.55rem;
  border-radius: var(--ui-radius-sm);
  color: var(--theme-ink-soft);
  font-size: 0.9rem;
}
.facet-drop__list a:hover { background: var(--theme-accent-soft); color: var(--theme-accent); text-decoration: none; }
.facet-drop__item-name { min-width: 0; }
.facet-drop__list .facet-count { flex: none; font-size: 0.8rem; color: var(--theme-ink-muted); font-variant-numeric: tabular-nums; }
.facet-drop__clear {
  display: block;
  padding: 0.45rem 0.55rem;
  margin-bottom: 0.25rem;
  border-bottom: 1px solid var(--theme-border);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--theme-danger, var(--theme-danger));
}

/* MOVIL: el panel deja de flotar y se abre a lo ancho, que a 360 px un
   desplegable posicionado se sale de la pantalla por un lado o por el otro.
   OJO: `.facet-drop` pasa a static, así que la barra TIENE que ser el ancla
   (`position: relative`) — sin ella, el panel absoluto buscaba el primer
   ancestro posicionado (ninguno en /editorial) y se pintaba al fondo del
   documento: los filtros «no funcionaban» en móvil (bug del 14-ago-2026). */
@media (max-width: 620px) {
  .facet-bar { position: relative; gap: 0.4rem; }
  .facet-bar__label { width: 100%; margin-bottom: 0.1rem; }
  .facet-drop { position: static; }
  .facet-drop__panel { left: 0; right: 0; max-width: none; }
  .facet-drop__value { max-width: 7rem; }
}

/* 404 con salida: buscador y accesos, en vez de solo «Volver al inicio». */
.status-page__search {
  display: flex;
  gap: 0.5rem;
  max-width: 30rem;
  margin: 1.5rem auto 0;
}
.status-page__search-input {
  flex: 1;
  min-width: 0;
  padding: 0.7rem 1rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  font: inherit;
  background: var(--theme-surface);
  color: var(--theme-ink);
}
.status-page__search-btn {
  flex: none;
  padding: 0.7rem 1.3rem;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--theme-accent);
  color: var(--theme-surface);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.status-page__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.25rem;
  margin-top: 1.5rem;
  font-size: 0.92rem;
}
.status-page__links a { color: var(--theme-ink-soft); }
.status-page__links a:hover { color: var(--theme-accent); }

/* ===== Rejilla ancha de listados (08-ago-2026) =====================
   Con los filtros arriba en vez de en una columna de 240 px, el listado se
   queda con el ancho entero y caben cinco por fila. La home la usa también
   desde que pinta 20 libros, que cuadran exactos a cinco, cuatro y dos
   columnas; con los 16 de antes quedaba un huérfano en la cuarta fila. Los
   relacionados siguen fuera: son seis. */
@media (min-width: 1180px) {
  .book-grid--wide { grid-template-columns: repeat(5, 1fr); }
}

/* ===== Filtros con más presencia ===================================
   En barra y en gris pasaban por decoración. Se les da cuerpo: la barra tiene
   fondo y borde propios, y cada filtro es una píldora con sombra, del tamaño de
   algo pulsable. El que está aplicado va en color de marca y macizo, para que
   se vea de un vistazo por dónde está acotado el listado. */
.facet-bar {
  padding: 0.7rem 0.85rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-sm, 0 1px 2px rgba(31, 27, 46, 0.06));
  gap: 0.55rem;
}
.facet-bar__label {
  font-size: 0.82rem;
  color: var(--theme-ink);
}
.facet-bar__label svg { width: 1.05rem; height: 1.05rem; color: var(--theme-accent); }

.facet-drop__btn {
  padding: 0.6rem 1.05rem;
  font-size: 0.95rem;
  border-width: 1.5px;
  box-shadow: 0 1px 2px rgba(31, 27, 46, 0.06);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.facet-drop__btn:hover {
  border-color: var(--theme-accent);
  background: var(--theme-accent-soft);
  box-shadow: 0 3px 10px color-mix(in srgb, var(--theme-accent) 18%, transparent);
}
.facet-drop[open] > .facet-drop__btn {
  border-color: var(--theme-accent);
  box-shadow: 0 3px 12px color-mix(in srgb, var(--theme-accent) 22%, transparent);
}
/* Aplicado: macizo. Un borde de color no basta para distinguirlo de un simple
   hover cuando hay tres filtros seguidos. */
.facet-drop.is-active > .facet-drop__btn {
  background: var(--theme-accent);
  border-color: var(--theme-accent);
  color: var(--theme-surface);
  box-shadow: 0 3px 12px color-mix(in srgb, var(--theme-accent) 30%, transparent);
}
.facet-drop.is-active > .facet-drop__btn:hover {
  background: var(--theme-accent);
  color: var(--theme-surface);
  filter: brightness(0.94);
}
.facet-bar__reset {
  padding: 0.5rem 0.85rem;
  border-radius: var(--ui-radius-pill);
  text-decoration: none;
  border: 1px dashed var(--theme-border);
}
.facet-bar__reset:hover { border-color: var(--theme-danger, var(--theme-danger)); color: var(--theme-danger, var(--theme-danger)); }


/* ================= /cursos: mapa del sistema educativo =================
   Antes era una nube de píldoras: 15 enlaces en 1.500 px de scroll, con
   «Infantil» gastando 130 px para uno solo. Quien entra no viene a leer una
   taxonomía, viene a localizar el curso de su hijo — y a menudo no recuerda si
   2º de la ESO son 13 o 14 años. Cada etapa es un panel con su franja de edad y
   sus cursos dentro, y el conjunto cabe en una pantalla.

   El color es POR ETAPA y sólo tiñe el icono y el filete superior: seis colores
   sobre el texto convertirían la página en un circo. */
.stage-map {
  display: grid;
  /* TRES columnas fijas en escritorio, no `auto-fit`: las etapas son seis y con
     cuatro columnas quedaban 4+2, con un hueco de dos huecos en la segunda
     fila. 3+3 cuadra siempre. */
  grid-template-columns: 1fr;
  align-items: start;
  gap: 1rem;
  margin: 1.75rem 0 2.5rem;
}
@media (min-width: 640px) { .stage-map { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .stage-map { grid-template-columns: repeat(3, 1fr); } }
.stage-card {
  --stage: var(--theme-accent);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: 1.15rem 1.15rem 1.25rem;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--ui-shadow-sm, 0 1px 2px rgba(31, 27, 46, 0.06));
  overflow: hidden;
}
/* Filete superior en el color de la etapa: identifica el bloque sin gritar. */
.stage-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: var(--stage);
}
/* El mapa de edades es una ESCALA, así que el color también: del más cálido al
   más frío según sube el tramo. Ocho colores distintos elegidos al azar harían
   parecer que cada tramo es una cosa aparte; una progresión se lee de un
   vistazo como lo que es, una línea temporal.

   El `nth-child` va contra el orden de `age_ranges.position`, que es el que
   emite el hub. Si algún día se añade un tramo intermedio, la escala se
   recoloca sola en vez de quedarse un color huérfano. */
.stage-map .stage-card:nth-child(1) { --stage: #E8A33C; }
.stage-map .stage-card:nth-child(2) { --stage: #E0763F; }
.stage-map .stage-card:nth-child(3) { --stage: var(--theme-accent); }
.stage-map .stage-card:nth-child(4) { --stage: #D2417A; }
.stage-map .stage-card:nth-child(5) { --stage: #9B4BC4; }
.stage-map .stage-card:nth-child(6) { --stage: #5C5BD6; }
.stage-map .stage-card:nth-child(7) { --stage: #2F7FD6; }
.stage-map .stage-card:nth-child(8) { --stage: var(--theme-success); }

/* La tarjeta entera es el enlace: en un mapa de edades no hay nada dentro que
   se pueda pulsar por separado, así que obligar a acertar en un enlace de texto
   sería reducir a propósito el área de clic. */
.stage-card--link { text-decoration: none; color: inherit; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.stage-card--link:hover,
.stage-card--link:focus-visible {
  text-decoration: none;
  color: inherit;
  transform: translateY(-2px);
  box-shadow: var(--ui-shadow-md);
  border-color: color-mix(in srgb, var(--stage) 45%, var(--theme-border));
}
/* Un tramo sin catálogo NO se oculta: la escala se lee mal con un hueco. Se
   apaga, que dice «aquí todavía no hay nada» sin romper la secuencia. */
.stage-card--link.is-empty { opacity: .55; }
.stage-card__name { display: block; font-family: var(--theme-font-heading); font-weight: 700; }
.stage-card__age { display: block; }

.stage-card__head { display: flex; align-items: center; gap: 0.7rem; }
.stage-card__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--ui-radius-md);
  background: color-mix(in srgb, var(--stage) 13%, transparent);
  color: var(--stage);
}
.stage-card__icon svg { width: 1.3rem; height: 1.3rem; }
.stage-card__titles { min-width: 0; }
.stage-card__name {
  margin: 0;
  font-size: 1.08rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.stage-card__age { margin: 0.15rem 0 0; font-size: 0.82rem; color: var(--theme-ink-muted); }

.stage-card__courses {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.4rem;
}
/* Una etapa de un solo curso (Infantil, FP, Universidad) no necesita rejilla:
   su tarjeta ocupa el ancho y se lee como un botón. */
.stage-card__courses:has(> li:only-child) { grid-template-columns: 1fr; }

.stage-course {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.2rem;
  padding: 0.6rem 0.4rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface-alt);
  color: var(--theme-ink);
  text-align: center;
  line-height: 1.1;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.stage-course:hover, .stage-course:focus-visible {
  text-decoration: none;
  background: color-mix(in srgb, var(--stage) 12%, var(--theme-surface));
  border-color: var(--stage);
  color: var(--theme-ink);
}
/* La cifra es lo que distingue «3º de Primaria» de sus cinco hermanas, así que
   es lo que se ve; el resto del nombre queda de apoyo. */
.stage-course__num {
  font-family: var(--theme-font-heading);
  font-weight: 800;
  font-size: 1.25rem;
  color: var(--stage);
  font-variant-numeric: tabular-nums;
}
.stage-course__ord { font-size: 0.7em; vertical-align: super; }
.stage-course__rest { display: none; }
/* Sin cifra (Infantil, FP, Universidad) el nombre ES el enlace. */
.stage-course__rest--solo {
  display: inline;
  font-weight: 600;
  font-size: 0.95rem;
}
@media (max-width: 380px) {
  .stage-card__courses { grid-template-columns: repeat(3, 1fr); }
  .stage-course { padding: 0.5rem 0.2rem; }
}

/* ===== Compartir la lista de un colegio ==============================
   Aquí tiene más sentido que en ninguna otra página: la lista del cole circula
   de padre a padre por el WhatsApp del grupo de clase, y esta URL es estable
   —no caduca como `/lista/:uuid`—, así que se puede reenviar el septiembre que
   viene y seguirá ahí. Sólo copiar enlace y WhatsApp: nadie tuitea la lista del
   colegio de su hijo. */
.school-share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.25rem;
  margin: 0 0 1.5rem;
  padding: 0.9rem 1.1rem;
  background: var(--theme-surface-alt);
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-lg);
}
.school-share__text { margin: 0; font-size: 0.95rem; color: var(--theme-ink-soft); }
.school-share__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.school-share__copy,
.school-share__wa {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.55rem 1rem;
  border-radius: var(--ui-radius-pill);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.school-share__copy {
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  color: var(--theme-ink);
}
.school-share__copy:hover { border-color: var(--theme-accent); color: var(--theme-accent); }
.school-share__copy.is-copied { border-color: var(--theme-success, var(--theme-success)); color: var(--theme-success, var(--theme-success)); }
.school-share__wa {
  border: 1px solid #25D366;
  background: #25D366;
  color: #fff;
}
.school-share__wa:hover, .school-share__wa:focus { color: #fff; text-decoration: none; filter: brightness(0.95); }
.school-share__copy svg, .school-share__wa svg { width: 1.05rem; height: 1.05rem; flex: none; }
@media (max-width: 560px) {
  .school-share { flex-direction: column; align-items: stretch; }
  .school-share__actions { justify-content: stretch; }
  .school-share__copy, .school-share__wa { flex: 1; justify-content: center; }
}

/* Correo y «más opciones» en el bloque de compartir de la lista. */
.list-share-btn--mail { background: var(--theme-surface); border: 1px solid var(--theme-border); color: var(--theme-ink); }
.list-share-btn--mail:hover { border-color: var(--theme-accent); color: var(--theme-accent); }
.list-share-btn--native {
  background: var(--theme-accent-soft);
  border: 1px solid color-mix(in srgb, var(--theme-accent) 35%, var(--theme-border));
  color: var(--theme-accent);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.list-share-btn--native:hover { background: color-mix(in srgb, var(--theme-accent) 18%, var(--theme-surface)); }

.list-buys__note {
  margin: -0.6rem 0 1.1rem;
  font-size: 0.86rem;
  color: var(--theme-ink-muted);
}


/* ===== Ajustes de la barra de filtros y del desplegable ===== */

/* En móvil los filtros se apilaban en dos y tres líneas, empujando la rejilla
   hacia abajo. Una sola fila que se desplaza a lo ancho ocupa lo mismo que un
   filtro y deja ver que hay más a la derecha. */
@media (max-width: 720px) {
  .facet-bar {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: visible;
    padding-bottom: 0.15rem;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .facet-bar::-webkit-scrollbar { display: none; }
  .facet-bar > * { flex: none; }
  .facet-bar__label { display: none; }
}

/* El texto SEO arrancaba pegado a la paginación y parecía continuación suya. */
.collection-seo-body { margin-top: 2.75rem; }

/* El botón "+" quedaba medio tapado por la barra de scroll del desplegable. */
.live-search__panel { padding-right: 0.6rem; }
.live-search__row { padding-right: 0.1rem; }

/* ------------------------ Buscador de colegios --------------------------- */
/* Formulario GET puro (la CSP prohíbe JS inline). El buscador de CENTROS es
   distinto del de libros a propósito: quien escribe «28034» busca su colegio,
   no un título. */

.school-search__title { margin: 0 0 0.4rem; font-size: 1.6rem; }
.school-search__lead {
  margin: 0 0 1.2rem;
  color: var(--theme-muted, var(--theme-ink-soft));
  max-width: 46rem;
}

.school-search__form {
  display: flex;
  gap: 0.5rem;
  margin: 0 0 1.5rem;
  max-width: 46rem;
}
.school-search__form--inline { margin: 0 0 1.75rem; }

.school-search__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.7rem 0.9rem;
  font-size: 1rem;
  font-family: inherit;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface, #fff);
  color: inherit;
}
.school-search__input:focus-visible {
  outline: 2px solid var(--theme-accent);
  outline-offset: 1px;
  border-color: var(--theme-accent);
}

.school-search__btn {
  flex: 0 0 auto;
  padding: 0.7rem 1.4rem;
  font-size: 1rem;
  font-family: inherit;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  border-radius: var(--ui-radius-cta);
  background: var(--theme-accent);
  color: var(--theme-accent-contrast, #fff);
}
.school-search__btn:hover { filter: brightness(0.94); }

.school-search__count {
  margin: 0 0 0.6rem;
  color: var(--theme-muted, var(--theme-ink-soft));
  font-size: 0.9rem;
}

.school-search__results {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--theme-border);
}
.school-hit {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 0.25rem;
  border-bottom: 1px solid var(--theme-border);
}
.school-hit__link {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  text-decoration: none;
  color: inherit;
}
.school-hit__link:hover .school-hit__name { text-decoration: underline; }
.school-hit__name { font-weight: 600; }
.school-hit__where {
  font-size: 0.85rem;
  color: var(--theme-muted, var(--theme-ink-soft));
}
.school-hit__books {
  flex: 0 0 auto;
  font-size: 0.8rem;
  white-space: nowrap;
  color: var(--theme-muted, var(--theme-ink-soft));
}

.school-search__empty {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-sm);
  background: var(--theme-surface-alt, #fafafa);
  max-width: 46rem;
}
.school-search__empty p { margin: 0 0 0.5rem; }
.school-search__empty p:last-child { margin-bottom: 0; }

@media (max-width: 560px) {
  .school-search__form { flex-wrap: wrap; }
  .school-search__input { flex-basis: 100%; }
  .school-search__btn { flex: 1 1 auto; }
  .school-hit { flex-wrap: wrap; gap: 0.3rem 1rem; }
}

/* Confirmacion del rail cuando solo hay un libro en la comparativa. */
.buy-rail__compare-done {
  margin: 0 0 0.55rem;
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--theme-muted, var(--theme-ink-soft));
}


/* ------------------------- Accesibilidad (jamelguetes) ------------------- */

/* Alias de `.visually-hidden`: las vistas de este proyecto usan `.sr-only`.
   Se mantienen las dos para que un partial portado tal cual siga funcionando. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Salto al contenido: primer tabulador de la página. Fuera de pantalla hasta
   que recibe el foco — si se ocultara con `display:none` el teclado no podría
   alcanzarlo, que es justo para lo que existe. */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  z-index: 100;
  background: var(--theme-surface);
  color: var(--theme-ink);
  padding: 0.75rem 1rem;
  border-radius: var(--ui-radius-sm);
  box-shadow: var(--ui-shadow-md);
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

/* =========================================================================
   Piezas propias de jamelguetes.

   Todo lo de aquí es marcado que este proyecto tiene y comparalibros no —o al
   revés—: la tarjeta de juguete con su CTA a la ficha, el encabezado de las
   colecciones, la barra de orden del buscador, el pie del blog y los estados
   de las ofertas agotadas. Va al FINAL para que se vea de un vistazo qué se ha
   añadido sobre el sistema portado, y todo sale de los mismos tokens.
   ========================================================================= */

/* ---- Tarjeta de juguete ------------------------------------------------- */

/* Botón «Comparar N tiendas»: es el que lleva a la ficha. Es un <a> HERMANO
   del enlace de la tarjeta, no un <span> dentro de él —dos destinos no caben
   en un solo enlace, y anidar <a> es HTML inválido que el navegador desanida
   por su cuenta rompiendo la tarjeta—. Al salir del flujo del cuerpo necesita
   su propio margen. */
.book-card__cta {
  display: block;
  margin: 0 0.9rem 0.95rem;
  padding: 0.55rem 0.75rem;
  background: var(--theme-accent);
  color: #fff;
  border-radius: var(--ui-radius-sm);
  font-weight: 700;
  font-size: 0.92rem;
  text-align: center;
}
.book-card__cta:hover { color: #fff; text-decoration: none; filter: brightness(0.93); }
.book-card__cta:focus-visible { outline: 2px solid var(--ui-accent-ring); outline-offset: 2px; }

/* ---- Ficha: chips y estado de las ofertas ------------------------------- */

.book-chip--category a { color: inherit; }
.book-chip--category a:hover { color: var(--theme-accent); text-decoration: none; }

/* Descuento sobre el PVP. Verde y no rojo: en una comparativa el rojo ya
   significa «cuidado» en el resto de la interfaz, y aquí es una buena noticia. */
.offer__badge--sale {
  background: color-mix(in srgb, var(--theme-success) 14%, transparent);
  color: var(--theme-success);
}

/* Fecha del precio. Sólo se pinta cuando el precio YA NO es reciente, así que
   va discreta: si saliera en todas las ofertas sería ruido, y sembraría la duda
   de que ningún precio es de hoy. */
.offer__checked {
  display: block;
  color: var(--theme-ink-muted);
  font-size: 0.72rem;
}

/* Tiendas sin stock, plegadas. No se ocultan del todo: saber que una tienda lo
   tenía y se ha agotado es información, y esconderla haría parecer que el
   juguete nunca estuvo ahí. */
.offers__gone {
  margin: 1rem 0 0;
  padding: 0.75rem 0.95rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-md);
  background: var(--theme-surface-alt);
  color: var(--theme-ink-soft);
  font-size: 0.9rem;
}
.offers__gone summary { cursor: pointer; font-weight: 600; }
.offers__gone ul { margin: 0.6rem 0 0; padding-left: 1.1rem; }

/* ---- Encabezado y resultados de colección ------------------------------- */

.collection-header { margin: 0 0 0.9rem; }
.collection-header__title { margin: 0; font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.1rem); }
.collection-intro { margin: 0 0 1.4rem; }
.collection-intro__text {
  margin: 0;
  max-width: 68ch;
  color: var(--theme-ink-soft);
  font-size: 1.02rem;
}
.collection-results { margin: 0; }
.collection-results__empty {
  margin: 2rem 0;
  padding: 1.6rem;
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-lg);
  color: var(--theme-ink-muted);
  text-align: center;
}

/* ---- Hub --------------------------------------------------------------- */

.hub__empty {
  margin: 1.6rem 0;
  padding: 1.6rem;
  border: 1px dashed var(--theme-border);
  border-radius: var(--ui-radius-lg);
  color: var(--theme-ink-muted);
  text-align: center;
}
.category-group__title a { color: inherit; }
.category-group__title a:hover { color: var(--theme-accent); text-decoration: none; }

/* ---- Buscador: título y orden ------------------------------------------ */

.search-header__title { margin: 0 0 0.35rem; font-size: clamp(1.4rem, 1.1rem + 1.4vw, 1.95rem); }

/* El orden vive DENTRO de la barra de facetas y no encima de la rejilla:
   filtrar y ordenar son la misma tarea y separarlos deja dos controles en dos
   sitios para lo mismo. `margin-left: auto` lo empuja al extremo. */
.facet-bar__sort { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
.facet-bar__sort select {
  appearance: none;
  padding: 0.45rem 2rem 0.45rem 0.85rem;
  border: 1px solid var(--theme-border);
  border-radius: var(--ui-radius-pill);
  background-color: var(--theme-surface);
  background-image:
    linear-gradient(45deg, transparent 50%, var(--theme-ink-muted) 50%),
    linear-gradient(135deg, var(--theme-ink-muted) 50%, transparent 50%);
  background-position: calc(100% - 1rem) 55%, calc(100% - 0.72rem) 55%;
  background-size: 0.3rem 0.3rem, 0.3rem 0.3rem;
  background-repeat: no-repeat;
  color: var(--theme-ink);
  font-size: 0.88rem;
  cursor: pointer;
}
.facet-drop__name { font-weight: 600; }
.facet-drop__item-n {
  margin-left: 0.4rem;
  color: var(--theme-ink-muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

/* ---- Portada: cabecera de las rejillas ---------------------------------- */

.home-latest__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem 1rem;
  margin: 0 0 1rem;
}
.home-latest__all { font-weight: 600; font-size: 0.92rem; white-space: nowrap; }

/* ---- Blog: entrada ------------------------------------------------------ */

.blog-post { max-width: 76ch; margin: 0 auto; }
.blog-post__header { margin: 0 0 1.2rem; }
.blog-post__title { margin: 0 0 0.4rem; font-size: clamp(1.7rem, 1.2rem + 2vw, 2.5rem); }
.blog-post__meta { margin: 0; color: var(--theme-ink-muted); font-size: 0.9rem; }
.blog-post__excerpt {
  margin: 0 0 1.4rem;
  font-size: 1.12rem;
  line-height: 1.6;
  color: var(--theme-ink-soft);
}
.blog-post__tags { margin: 1.8rem 0 0; }
.blog-post__footer {
  margin: 2rem 0 0;
  padding-top: 1.2rem;
  border-top: 1px solid var(--theme-border);
}
