/* Delistado — hoja de estilos única, sin compilación.
   Diseñada asumiendo que MUCHAS obras no tendrán carátula: el marcador de
   posición es tipográfico y deliberado, no una imagen rota. */

:root {
  /* Paleta de la identidad corporativa (manifest.json del kit de marca).
     Los verdes son dos porque el contraste manda: #2BD9AB da 10,29:1 sobre
     fondo oscuro y #087F67 da 4,95:1 sobre claro. Usar el mismo en los dos
     bajaría de AA en uno de ellos. */
  --bg:        #111317;   /* ink */
  --surface:   #191C21;
  --surface-2: #23272E;
  --line:      #2E333B;
  --ink:       #F7F5F0;   /* white */
  --ink-2:     #B6BDC8;   /* dark_text  · 9,83:1 */
  /*
   * Subido de #6B7280 el 21/08/2026.
   *
   * Ese gris daba 3,85:1 sobre el fondo oscuro, y la norma —WCAG AA— pide 4,5
   * para texto normal. Y no era un detalle de una pantalla suelta: es el color
   * de «.dim», que es el texto explicativo de TODA la aplicación, a 14 píxeles.
   *
   * Se subió lo justo para pasar con margen y no más, para que siga siendo el
   * color secundario y no compita con el principal.
   */
  /* Subido otra vez el 22/08/2026, por el mismo motivo de antes pero en otro
     sitio: 5,21 sobre el fondo estaba bien, pero sobre la superficie elevada
     —los botones, las etiquetas, los ejemplares— se quedaba en 4,20. Ahora
     5,70 sobre el fondo y 4,60 sobre la elevada. */
  --ink-3:     #878F9C;   /* gray · 5,70:1 */
  --accent:    #2BD9AB;   /* dark_green · 10,29:1 */
  --accent-dk: #16C79A;   /* green, el de la marca */

  /* ── El texto que va ENCIMA del verde ─────────────────────────────────
     Estaba escrito «#fff» a pelo en los cuatro sitios que pintan un fondo
     verde sólido: el botón de estado marcado, el botón principal, la etiqueta
     «mía» y la página activa del paginador.

     Medido el 22/08/2026: blanco sobre #16C79A da 2,17:1. La norma pide 4,5.
     Y no es una pantalla suelta — es el botón «Vista / Leído / Jugado», que es
     el control que más se pulsa de todo el producto.

     En modo oscuro la solución es al revés de lo que parece: el verde de la
     marca es CLARO, así que encima va tinta, no blanco. 8,56:1. En modo claro
     el verde sí es oscuro y encima va blanco, 5,41:1. Por eso es una variable
     y no un color fijo. */
  --sobre-acento: #111317;
  --gold:      #FF9D2E;   /* orange */
  --danger:    #FF5A5F;   /* red */
  --ok:        #2BD9AB;

  /* ── Los colores de las categorías ─────────────────────────────────────

     Hasta el 20/08/2026 eran las cinco barras del isotipo, literalmente. Era
     una idea buena y se ha cambiado con tres medidas encima de la mesa:

       · Tres de los cinco eran EL MISMO color que algo con significado en la
         interfaz: película = el rojo de error, libros = el verde de la marca,
         música = el naranja de aviso. Una ficha de película llevaba el color
         de un mensaje de error.
       · Simulando deuteranopía —la más común, ~5 % de los hombres— series y
         cómics quedaban a una distancia de 6,4: prácticamente el mismo color.
         Esta paleta, con DOS colores más, tiene una separación mínima de 13,7.
       · Solo había cinco. Faltaban videojuegos y «en directo».

     El logotipo no se toca. Lo que se pierde es la correspondencia «primera
     barra = cine», que solo existía en este comentario y que nadie ve.

     ── Las tres reglas que salen de la validación ───────────────────────────

     1. EL ORDEN ES FIJO en toda la aplicación. Siete colores no pueden ser
        distinguibles entre sí dos a dos —está medido, el máximo son tres—.
        Con orden fijo solo se tocan vecinos, y así la paleta aguanta. Un orden
        que cambia según la pantalla rompe la garantía.
     2. EL COLOR NUNCA VA SOLO: siempre color + icono + texto. En modo claro,
        cuatro de los siete no llegan a 3:1 sobre el crema —medido—, así que
        un punto de color a secas es ilegible para mucha gente.
     3. EL VERDE ES DE LA MARCA. Ninguna categoría lo usa.

     Se nombran por el código del tipo y no por su nombre en español, para que
     el CSS, el componente de icono y la base de datos digan la misma palabra. */
  --cat-movie:   #e66767;
  --cat-tv_show: #3987e5;
  --cat-book:    #c98500;
  --cat-comic:   #d55181;
  --cat-album:   #9085e9;
  --cat-game:    #199e70;
  --cat-board_game: #35c0dc;
  --cat-live:    #d95926;
  --cat-tcg:     #d89ad0;
  --cat-stickers: #b8cc4a;

  /* ── Espaciado ─────────────────────────────────────────────────────────
     Una escala corta y siempre la misma. El motivo no es la pureza: son las
     medidas que se repiten, y tenerlas con nombre evita que cada pantalla
     invente su propio 14 o su propio 18 y el conjunto quede desalineado sin
     que se sepa por qué. */
  --e1: 4px;
  --e2: 8px;
  --e3: 12px;
  --e4: 16px;
  --e5: 24px;
  --e6: 32px;

  --radius: 10px;
  --radius-sm: 6px;
  --sans: 'Poppins', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: 'Poppins', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

/* Poppins servida desde aquí: sin depender de Google Fonts, que además
   añadiría una petición a otro dominio en cada carga. */
@font-face {
  font-family: 'Poppins';
  /* WOFF2 primero: 7 KB frente a los 156 del TTF, recortado a los caracteres
     que la aplicación puede necesitar. El TTF queda de respaldo. */
  src: url('/fonts/Poppins-Regular.woff2') format('woff2'),
       url('/fonts/Poppins-Regular.ttf') format('truetype');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Poppins';
  src: url('/fonts/Poppins-Bold.woff2') format('woff2'),
       url('/fonts/Poppins-Bold.ttf') format('truetype');
  font-weight: 700; font-style: normal; font-display: swap;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #F7F5F0;        /* white del kit */
    --surface: #FFFFFF;
    /* ── Un crema, no un gris frío ────────────────────────────────────
       #E5E7EB era gris azulado sobre un fondo crema: la superficie elevada
       se veía de otra temperatura que la página, y encima dejaba el acento en
       4,00:1. Este es el mismo tono que la banda alterna de delistado.com, así
       que las dos mitades del producto usan el mismo papel. */
    --surface-2: #EFEBE2; /* paper */
    --line: #DCDFE4;
    --ink: #111317;
    --ink-2: #4B5563;     /* light_text · 7,56:1 */
    /* En claro pasaba lo mismo, y por poco: 4,44:1. Bajado a 5,17:1. */
    --ink-3: #616872;
    /* Oscurecido de #087F67 el 22/08/2026, a la vez que en la portada y por
       lo mismo: sobre la superficie elevada se quedaba en 4,16:1. Ahora
       4,54 sobre ella, 4,96 sobre el fondo y 5,41 sobre blanco. */
    --accent: #077865;    /* light_green · 4,96:1 */
    --accent-dk: #077865;
    /* 4,41 sobre el crema y 4,04 sobre la elevada: por debajo los dos, y es
       el color de los mensajes de error. Ahora 5,11 y 4,68. */
    --danger: #C62A2F;
    --ok: #077865;

    /* ── El dorado de las estrellas ───────────────────────────────────
       #FF9D2E daba 1,91:1 sobre el crema. Una estrella de valoración no es
       decoración: es lo que dice cuánto te gustó algo, y a 1,91 no se ve.
       Este ocre da 5,35 sobre el crema, 5,83 sobre blanco y 4,90 sobre la
       superficie elevada. Se bajó hasta pasar de 4,5 en LOS TRES y no solo el
       3:1 que pide una estrella como dibujo: así también vale de color de
       texto y no hay que acordarse de la excepción.

       En oscuro se queda el naranja de siempre, que ahí da 8,96. */
    --gold: #96550A;

    /* Encima del verde oscuro del modo claro sí va blanco: 5,41:1. */
    --sobre-acento: #FFFFFF;

    /* Las categorías tienen su propia versión clara. El mismo color no puede
       servir para los dos fondos: sobre crema, los que van bien sobre tinta se
       quedan lavados, y al revés. */
    --cat-movie:   #e34948;
    --cat-tv_show: #2a78d6;
    --cat-book:    #eda100;
    --cat-comic:   #e87ba4;
    --cat-album:   #4a3aa7;
    --cat-game:    #1baf7a;
    --cat-board_game: #127f9e;
    --cat-live:    #eb6834;
    --cat-tcg:     #94378c;
    --cat-stickers: #5f7d12;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-underline-offset: 2px; }
a:hover { color: var(--ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
img { max-width: 100%; display: block; }

/* ---------- Estructura ---------- */
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 20px 80px; }

.topbar {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--line);
  margin-bottom: 28px;
}
.topbar-inner {
  max-width: 1080px; margin: 0 auto; padding: 12px 20px;
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
}
.brand {
  font-family: var(--serif); font-size: 22px; letter-spacing: -.01em;
  color: var(--ink); text-decoration: none; flex: none;
}
.brand span { color: var(--accent); }
.nav { display: flex; gap: 16px; margin-left: auto; align-items: center; font-size: 14.5px; }
.nav a { color: var(--ink-2); text-decoration: none; }
.nav a:hover, .nav a.on { color: var(--ink); }

/* En un móvil los ocho enlaces no caben en una línea, y sin permitirles bajar
   el último se quedaba cortado a media palabra —«Pa» en vez de «Panel»— sin
   ninguna forma de llegar a él. Bajan de línea en vez de esconderse: un enlace
   que hay que adivinar es un enlace que no existe. */
@media (max-width: 760px) {
  .nav { flex-wrap: wrap; margin-left: 0; width: 100%; gap: 12px 15px; }
}

/* ---------- Buscador ---------- */
.searchbar { flex: 1 1 260px; min-width: 200px; }
.searchbar form { display: flex; gap: 8px; }
.searchbar input {
  flex: 1; background: var(--surface); border: 1px solid var(--line);
  color: var(--ink); padding: 9px 14px; border-radius: 999px;
  font-size: 15px; font-family: inherit;
}
.searchbar input::placeholder { color: var(--ink-3); }
.searchbar input:focus { border-color: var(--accent); outline: none; }

/* ---------- Botones ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 7px; justify-content: center;
  background: var(--surface-2); color: var(--ink); border: 1px solid var(--line);
  padding: 8px 14px; border-radius: 8px; font-size: 14.5px; font-family: inherit;
  cursor: pointer; text-decoration: none; line-height: 1.2;
}
.btn:hover { border-color: var(--accent); color: var(--ink); }
.btn.on { background: var(--accent-dk); border-color: var(--accent); color: var(--sobre-acento); }
.btn.primary { background: var(--accent-dk); border-color: var(--accent-dk); color: var(--sobre-acento); }
.btn.primary:hover { background: var(--accent); }
.btn.ghost { background: transparent; }
.btn.small { padding: 5px 10px; font-size: 13px; }
.btn.gold.on { background: #7a5a12; border-color: var(--gold); color: #fff; }
.btn.danger:hover { border-color: var(--danger); color: var(--danger); }

/* El botón del que no se vuelve.

   «.danger» a secas solo se pintaba al pasar por encima, que está bien para
   «quitar esta contraseña» pero no para cerrar la cuenta: ahí el aspecto tiene
   que avisar ANTES de acercar el ratón, y en un móvil no hay «encima» que valga.

   Borde y letra en rojo, no fondo rojo: el rojo de la marca da 3,1:1 contra el
   blanco en modo claro, o sea que un botón rojo con letra blanca no llegaría al
   mínimo legible. Así el rojo va donde sí contrasta —sobre el fondo de la
   página— y el aviso se ve igual. */
.btn.danger {
    border-color: var(--danger);
    color: var(--danger);
    font-weight: 500;
}
.btn.danger:hover, .btn.danger:focus-visible {
    background: color-mix(in srgb, var(--danger) 12%, var(--surface));
}

/* ---------- Tipografía ---------- */
h1 { font-family: var(--serif); font-size: clamp(28px, 5vw, 40px); font-weight: 400;
     letter-spacing: -.02em; line-height: 1.1; margin: 0 0 6px; text-wrap: balance; }
h2 { font-family: var(--serif); font-size: 22px; font-weight: 400; margin: 34px 0 14px; }
.eyebrow { font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em;
           text-transform: uppercase; color: var(--ink-3); margin: 0 0 10px; }
.muted { color: var(--ink-2); }
.dim   { color: var(--ink-3); font-size: 14px; }

/* ---------- Carátulas y su ausencia ---------- */
.cover { aspect-ratio: 2/3; border-radius: var(--radius); overflow: hidden;
         background: var(--surface-2); position: relative; }
/* La imagen va superpuesta al marcador tipográfico: si no carga, se retira
   sola (onerror) y debajo ya está el sustituto. Nunca hay hueco roto. */
.cover .cover-img { position: absolute; inset: 0; width: 100%; height: 100%;
                    object-fit: cover; background: var(--surface-2); }
.cover-none {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px; padding: 10px;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line); border-radius: var(--radius);
}
.cover-none .ini { font-family: var(--serif); font-size: 2.2rem; color: var(--ink-2); line-height: 1; }
.cover-none .ico { font-size: 1.1rem; opacity: .75; }

/* ---------- Resultados y rejillas ---------- */
.grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
.card { text-decoration: none; color: inherit; display: flex; flex-direction: column; gap: 8px; }
.card .t { font-size: 14.5px; font-weight: 600; line-height: 1.3; }
.card .s { font-size: 12.5px; color: var(--ink-3); }
.card:hover .cover { outline: 2px solid var(--accent); outline-offset: 2px; }

/* El motivo por el que una obra sale como parecida. Más pequeño y más apagado
   que el medio: es la explicación, no el dato. */
.parecida-porque { font-size: 11.5px; margin-top: 2px; opacity: .85; }

/* ── La biblioteca partida por años ─────────────────────────────────────────

   Es la línea temporal de delistado.com, pero aquí con datos de verdad. En la
   portada el hilo es una promesa dibujada; en el perfil público es la
   biblioteca de alguien ordenada por cuándo pasó cada cosa. Mismo lenguaje: un
   hilo vertical, un nodo por parada y la fecha delante del título.

   El hilo va de acento a línea de arriba abajo. No lleva los nueve colores
   como en la portada a propósito: allí cada nodo ES un medio y el color dice
   algo; aquí cada nodo es un AÑO, que no tiene medio, y pintarlo de colores
   sería decorar con un código que no significa nada. El color de medio ya está
   donde toca — en cada carátula. */
.anyos { list-style: none; margin: 0; padding: 0 0 0 30px; position: relative; }
.anyos::before {
  content: ""; position: absolute; left: 6px; top: 12px; bottom: 12px; width: 3px;
  border-radius: 3px;
  /* No baja hasta «--line»: con quince años el hilo mide tres mil píxeles y
     al final se quedaba invisible, justo en los años más antiguos, que son
     los que más sorprenden. Se apaga hasta un cuarto del acento y ahí para. */
  background: linear-gradient(var(--accent),
              color-mix(in srgb, var(--accent) 28%, var(--line)));
}
.anyo { position: relative; margin: 0 0 34px; }
.anyo:last-child { margin-bottom: 0; }

.anyo-cabecera { display: flex; align-items: baseline; gap: 12px; margin: 0 0 14px; }
.anyo-nodo {
  position: absolute; left: -30px; top: 6px; width: 15px; height: 15px;
  border-radius: 50%; background: var(--accent);
  /* El halo es lo que hace que el nodo se lea como una parada y no como una
     viñeta de lista. Es el mismo recurso que en la portada. */
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 24%, transparent);
}
.anyo-numero {
  font-family: var(--serif); font-size: 21px; font-weight: 400; margin: 0;
  letter-spacing: -.01em; font-variant-numeric: tabular-nums; color: var(--ink);
}

@media (max-width: 520px) {
  /* En 320 px, 30 px de sangrado son casi una columna de carátula. */
  .anyos { padding-left: 22px; }
  .anyos::before { left: 4px; }
  .anyo-nodo { left: -22px; width: 13px; height: 13px; }
  .anyo-numero { font-size: 19px; }
}

.hits { display: flex; flex-direction: column; gap: 2px; }
.hit {
  display: grid; grid-template-columns: 54px 1fr auto; gap: 14px; align-items: center;
  padding: 12px 10px; border-radius: var(--radius); text-decoration: none; color: inherit;
  border: 1px solid transparent;
}
.hit:hover { background: var(--surface); border-color: var(--line); }
.hit .cover { aspect-ratio: 2/3; width: 54px; }
.hit .t { font-weight: 600; font-size: 15.5px; line-height: 1.3; }
.hit .s { font-size: 13px; color: var(--ink-3); margin-top: 2px; }
.hit .meta { text-align: right; font-size: 12.5px; color: var(--ink-3); white-space: nowrap; }

/* ── Mientras se trae una ficha de fuera ──────────────────────────────────

   Abrir un resultado ajeno tarda un par de segundos —hay que pedirle la ficha
   a otro catálogo y guardarla— y hasta hoy la página no se movía ni un pelo.
   Parecía que el clic no había hecho nada, y lo que hace la gente entonces es
   volver a pulsar.

   La fila elegida se queda encendida con su «Trayendo…» y las demás se apagan:
   sin eso, quien se cansa pulsa OTRA obra y acaban dos importaciones a la vez,
   enseñándose la que termine antes y no la que pidió. */
.hit[aria-busy] { cursor: progress; }
.hit[aria-busy] .tag {
    background: var(--accent, var(--verde)); color: #fff; border-color: transparent;
}

/* Un latido lento y discreto: dice «esto sigue vivo» sin llamar la atención,
   que es justo lo que hace falta durante una espera corta. */
@keyframes trayendo { 0%, 100% { opacity: 1 } 50% { opacity: .55 } }
.hit[aria-busy] .tag { animation: trayendo 1.1s ease-in-out infinite; }

.hit.apagada { opacity: .4; pointer-events: none; }

/* Quien prefiera no ver animaciones tampoco las ve aquí. El color del
   «Trayendo…» sigue diciendo lo mismo sin moverse. */
@media (prefers-reduced-motion: reduce) {
    .hit[aria-busy] .tag { animation: none; }
}

/* ---------- La espera de la búsqueda externa ----------
   Consultar TheTVDB, Wikidata y Open Library puede tardar varios segundos. Sin
   nada en ese hueco, la página da un salto cuando llegan los resultados y
   quien está mirando no sabe si se ha colgado.

   Estas filas fantasma ocupan exactamente lo que ocuparán las de verdad, así
   que nada se mueve. Y NO son una promesa: si no aparece nada, se retiran y se
   dice que no hay resultados. Un esqueleto que se queda para siempre es peor
   que no haberlo puesto. */
.fantasma { pointer-events: none; }
.fantasma .cover, .fantasma .linea {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--line) 50%, var(--surface-2) 75%);
  background-size: 300% 100%;
  animation: fantasmear 1.4s ease-in-out infinite;
  border-radius: var(--radius-sm);
}
.fantasma .linea { height: 13px; }
.fantasma .linea.corta { width: 45%; margin-top: 7px; height: 11px; }

@keyframes fantasmear {
  0%   { background-position: 100% 0; }
  100% { background-position: 0 0; }
}

/* Quien ha pedido menos movimiento ve el hueco quieto, no parpadeando. */
@media (prefers-reduced-motion: reduce) {
  .fantasma .cover, .fantasma .linea { animation: none; }
}

/* El mismo hueco vivo, en el panel de la tienda.

   Consultar la biblioteca y luego un catálogo de fuera son varios segundos, y
   hasta ahora el único aviso era el botón de arriba, que a esas alturas ya está
   fuera de la vista: quien mira está abajo, en el sitio donde deberían aparecer
   las fichas. Un aviso fuera de la vista no avisa.

   Cada hueco mide lo que mide un botón de propuesta, así que cuando llegan las
   de verdad no se mueve nada. */
.sugerencia-fantasma { padding: 9px 0; }

/* Al llegar por un enlace, que no quede debajo de la cabecera fija.

   La cabecera va «sticky» arriba del todo, así que un salto a un ancla deja lo
   enlazado tapado por ella: llegas a un formulario sin ver de qué es. Esto
   reserva el hueco. */
details[id^="articulo-"] { scroll-margin-top: 96px; }
.sugerencia-fantasma .linea { height: 15px; border-radius: var(--radius-sm); }

.tag {
  display: inline-flex; align-items: center; gap: 4px; font-family: var(--mono);
  font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase;
  background: var(--surface-2); color: var(--ink-2);
  padding: 3px 7px; border-radius: 4px; border: 1px solid var(--line);
}
.tag.mine { background: var(--accent-dk); color: var(--sobre-acento); border-color: var(--accent-dk); }
.tag.new  { background: transparent; color: var(--ink-3); }

/* ---------- Ficha de obra ---------- */
.work { display: grid; grid-template-columns: 200px 1fr; gap: 30px; align-items: start; }
/* En el móvil la ficha va en UNA columna.
   Antes era 120px + resto, y como los paneles ocupaban solo la segunda
   columna quedaba un hueco vertical enorme bajo la carátula: en una pantalla
   estrecha eso es la mitad del ancho desperdiciado. */
@media (max-width: 640px) {
  .work { grid-template-columns: 1fr; gap: 16px; }
  /* La carátula va dentro de un div envoltorio, así que el tamaño hay que
     ponerlo AHÍ: apuntar a .cover directamente no coincide con nada. */
  .work > div:first-child { width: 140px; }
  .work > div:last-child  { min-width: 0; }   /* evita desbordes por texto largo */
}
.work .synopsis { color: var(--ink-2); max-width: 62ch; }
.work .source { font-size: 12px; color: var(--ink-3); margin-top: 8px; }

.panel { background: var(--surface); border: 1px solid var(--line);
         border-radius: var(--radius); padding: 18px 20px; margin: 22px 0; }
/*
 * El título de un panel se pinta igual sea h2 o h3.
 *
 * El NIVEL lo decide la estructura de la página, no el aspecto: en una pantalla
 * donde el panel cuelga directo del título, es un h2; dentro de una sección con
 * su propio h2, es un h3. Saltar del h1 al h3 obliga a quien navega por
 * encabezados con un lector de pantalla a adivinar si se ha perdido algo.
 */
.panel h2,
.panel h3 { margin: 0 0 12px; font-size: 12px; text-transform: uppercase;
            letter-spacing: .1em; color: var(--ink-3); font-weight: 600; }
.row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* ── «hidden» tiene que ganar SIEMPRE ─────────────────────────────────────

   El atributo `hidden` esconde algo porque el navegador le pone `display:none`
   por su cuenta. Pero esa regla suya es de las más débiles que existen, así
   que cualquier `display` nuestro la pisa — y `.row` pone `display:flex`.

   Ya ha mordido dos veces, las dos igual de tontas y las dos invisibles desde
   el código: la fila de compartir salía desplegada sin pulsar nada, y en el
   panel de la tienda aparecía «Crear la ficha, trayéndola de Open Library»
   sobre un vinilo, que es un catálogo de LIBROS.

   Con `!important` no hay tercera. Es de los pocos sitios donde está
   justificado: `hidden` no es un estilo, es «esto no está». */
[hidden] { display: none !important; }

/* Estrellas: 0,5 a 5 en pasos de media */
.stars { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 0; }
.stars input { position: absolute; opacity: 0; pointer-events: none; }
.stars label {
  cursor: pointer; font-size: 26px; line-height: 1; color: var(--ink-3);
  width: .5em; overflow: hidden; transition: color .1s;
}

/* El foco tiene que verse. Los botones de radio están escondidos —la estrella
   es una etiqueta— así que sin esto se puede llegar con el teclado a un
   control que no da ninguna señal de estar seleccionado. */
.stars input:focus-visible + label {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px;
}

/* Con el dedo, media estrella de 13 píxeles es imposible de acertar. Se
   agranda solo donde se toca.

   Honestamente: ni así llega a los 44 píxeles de ANCHO, porque media estrella
   es la mitad de un carácter y ensancharla más deformaría el dibujo. Pasa de
   13 a 22, que es la diferencia entre fallar siempre y acertar casi siempre. */
@media (pointer: coarse) {
  .stars label { font-size: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .stars label { transition: none; }
}
.stars label:nth-of-type(odd) { direction: rtl; }
.stars label::before { content: '★'; }
.stars:hover label:hover, .stars:hover label:hover ~ label,
.stars input:checked ~ label { color: var(--gold); }
.stars-value { font-family: var(--mono); font-size: 13px; color: var(--ink-2); margin-left: 10px; }

/* ---------- Diario ---------- */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { display: grid; grid-template-columns: 92px 1fr; gap: 14px;
               padding: 10px 0; border-top: 1px solid var(--line); font-size: 14.5px; }
.timeline li:first-child { border-top: none; }
.timeline time { font-family: var(--mono); font-size: 12px; color: var(--ink-3); padding-top: 2px; }

/* ---------- Avisos ---------- */
.flash { background: color-mix(in srgb, var(--ok) 14%, var(--surface));
         border: 1px solid var(--ok); color: var(--ink);
         padding: 10px 14px; border-radius: 8px; margin-bottom: 18px; font-size: 14.5px; }
.error { background: color-mix(in srgb, var(--danger) 14%, var(--surface));
         border: 1px solid var(--danger); color: var(--ink);
         padding: 10px 14px; border-radius: 8px; margin-bottom: 18px; font-size: 14.5px; }

/* ---------- Estados vacíos ---------- */

/* Un hueco en blanco no dice nada y parece una avería. Con el isotipo de fondo
   —muy tenue, que acompaña sin gritar— y una frase que explique qué hacer, un
   vacío deja de parecer un error y pasa a ser una invitación. */
/* El relleno de arriba deja sitio al isotipo: sin él, el dibujo queda debajo
   del texto y las dos cosas se estorban. */
.empty { text-align: center; padding: 132px 20px 64px; color: var(--ink-3);
         position: relative; }
.empty::before {
  content: ''; position: absolute; top: 14px; left: 50%;
  width: 96px; height: 96px; transform: translateX(-50%);
  background: url('/marca/isotipo-oscuro.svg') center/contain no-repeat;
  opacity: .09; pointer-events: none;
}
.empty > * { position: relative; }
.empty p { margin: 0 0 6px; }
.empty .big { display: none; }   /* lo sustituye el isotipo de arriba */

@media (prefers-color-scheme: light) {
  .empty::before { background-image: url('/marca/isotipo-claro.svg'); opacity: .12; }
}

/* ---------- Color por categoría ---------- */

/* Cada tipo de obra lleva el color de su barra en el logotipo. No es adorno:
   en una parrilla de cien carátulas es lo que permite distinguir un disco de
   un cómic sin leer nada. */
.cover-movie   { --cat: var(--cat-movie); }
.cover-tv_show { --cat: var(--cat-tv_show); }
.cover-book    { --cat: var(--cat-book); }
.cover-album   { --cat: var(--cat-album); }
.cover-comic   { --cat: var(--cat-comic); }
.cover-game    { --cat: var(--cat-game); }
.cover-board_game { --cat: var(--cat-board_game); }
.cover-live    { --cat: var(--cat-live); }
.cover-tcg     { --cat: var(--cat-tcg); }
.cover-stickers { --cat: var(--cat-stickers); }

/* El tinte va SOLO en el sustituto, nunca sobre la carátula real: teñir una
   portada de verdad sería estropearla. */
.cover[class*="cover-"] .cover-none {
  background: linear-gradient(160deg,
              color-mix(in srgb, var(--cat) 13%, var(--surface-2)),
              var(--surface));
  border-color: color-mix(in srgb, var(--cat) 26%, var(--line));
}
.cover[class*="cover-"] .cover-none .ini { color: color-mix(in srgb, var(--cat) 55%, var(--ink-2)); }

/* ---------- Iconos ---------- */

/* Alineados con el texto que acompañan: sin esto se apoyan en la línea base y
   quedan flotando por encima de la palabra. */
.icono { vertical-align: -0.18em; flex: none; }

/* Dentro de un botón, el icono y la palabra van juntos y no se parten. */
.btn .icono { margin-right: 2px; }

/* Cuando el filtro está activo, el icono pasa a blanco para leerse sobre el
   fondo del botón; si no, se pierde. */
.btn.on .icono { stroke: currentColor; }

/* ---------- Estadísticas ---------- */
.stats { display: flex; gap: 12px; flex-wrap: wrap; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
        padding: 14px 18px; min-width: 116px; }
.stat .n { font-family: var(--serif); font-size: 30px; line-height: 1; display: block; }
.stat .l { font-size: 12.5px; color: var(--ink-3); margin-top: 5px; display: block; }

/* La cifra entera es el enlace, no una palabra dentro: el objetivo a pulsar
   pasa de una línea de 12 px a la tarjeta completa, que es lo que se acierta
   con el pulgar. */
.stat-enlace { display: block; color: inherit; text-decoration: none; }
.stat-enlace:hover .n { color: var(--accent); }
.stat-enlace:hover { color: inherit; }

/* La tarjeta que se está mirando, marcada.

   Sin esto, al filtrar por un tipo la pantalla cambiaba abajo y arriba seguía
   igual: no había forma de ver cuál de los diez recuadros habías pulsado, ni
   por dónde cerrarlo. */
.stat-puesta { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.stat-puesta .n { color: var(--accent); }

/* «Qué cuenta», plegado. Igual que en el resumen: una cifra sin definición no
   se puede interpretar, pero desplegada por defecto taparía las demás. */
.stat-que { margin-top: 8px; }
.stat-que summary { font-size: 11.5px; color: var(--ink-3); cursor: pointer; }
.stat-que summary:hover { color: var(--ink-2); }
.stat-que div { margin-top: 8px; max-width: 34ch; }
.stat-que p { font-size: 12.5px; color: var(--ink-2); margin: 0 0 6px; line-height: 1.5; }
.stat-que p:last-child { margin-bottom: 0; }
.stat-que strong { color: var(--ink); }

/* ---------- Formularios ---------- */
.form { max-width: 380px; margin: 60px auto; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 13px; color: var(--ink-2); margin-bottom: 5px; }

/* ── La etiqueta de una casilla ───────────────────────────────────────────

   Un `<label>` dentro de un `.field` es el TÍTULO del campo: bloque, gris,
   pequeño y con su hueco debajo. Eso está bien para «Cómo lo llamas» y está
   mal para una casilla, donde el texto va al lado del cuadradito y es la
   opción, no su nombre.

   Sin esto, la etiqueta de una casilla medía 284 píxeles de alto y el
   cuadradito se le iba encima. Se venía apañando poniéndole la clase `.row`,
   que arreglaba el aspecto y de paso rompía el atributo `hidden` — que es
   como acabó saliendo «Crear la ficha de Open Library» sobre un vinilo.

   Con `[hidden]` ganando siempre en el CSS, esta clase ya es segura. */
/* `label.casilla` y no `.casilla` a secas: hay que pesar lo mismo que
   `.field label`, que es quien pone el `display:block` que estorba. Con el
   mismo peso gana la que va después, y esta va después. */
label.casilla {
    /* `flex` y no `inline-flex`.

       Con `inline-flex` la etiqueta se encoge a su contenido mínimo, y dentro
       de una columna estrecha eso dejaba el texto en 76 píxeles de ancho y 157
       de alto: una tira de palabras sueltas al lado del cuadradito. Estas
       etiquetas van solas en su línea, así que deben ocuparla entera. */
    display: flex; align-items: flex-start; gap: 7px;
    font-size: 14px; color: var(--ink); margin: 0;
    cursor: pointer; line-height: 1.4;
}
/* El texto se queda con todo el ancho que sobre después del cuadradito. */
label.casilla > span { flex: 1; min-width: 0; }
/* El cuadradito no se estira ni se encoge aunque el texto ocupe dos líneas. */
/* El cuadradito no se estira ni se encoge, y se alinea con la PRIMERA línea
   del texto: con `align-items:center` y un texto de dos líneas, se quedaba
   flotando en medio, lejos de la palabra a la que corresponde. */
label.casilla input[type="checkbox"] { margin: 2px 0 0; }
.field input {
  width: 100%; background: var(--surface); border: 1px solid var(--line);
  color: var(--ink); padding: 10px 13px; border-radius: 8px;
  font-size: 15px; font-family: inherit;
}
.field input:focus { border-color: var(--accent); outline: none; }

/* ── Una casilla NO es un campo de texto ──────────────────────────────────

   La regla de arriba estira cualquier `input` de un `.field` al 100 % del
   ancho y le pone relleno y borde, que es lo correcto para escribir un título
   y absurdo para un cuadradito de marcar.

   Sin esto, la casilla medía 354 píxeles de ancho y empujaba su texto a cero:
   el resultado era una tira de palabras sueltas al lado de un cuadrado
   gigante, que es justo lo que se veía en el panel de la tienda.

   Va aquí y no dentro de `.casilla` porque el fallo es de cualquier casilla
   que caiga dentro de un `.field`, no solo de las mías. */
.field input[type="checkbox"],
.field input[type="radio"] {
    width: auto; padding: 0; border: 0; border-radius: 0;
    background: none; flex: 0 0 auto;
}

/*
 * Y el área de texto igual que el resto de campos.
 *
 * Se quedó sin estilo y se notaba: la caja para escribir una reseña salía tal
 * como la pinta el navegador —fondo blanco, letra de máquina de escribir y del
 * tamaño mínimo—, en medio de una pantalla oscura y justo en el sitio donde se
 * le pide a alguien que escriba un par de párrafos. Cuesta escribir en una
 * caja que parece rota.
 *
 * El alto lo sigue mandando el atributo «rows» de cada sitio: una descripción
 * de lista pide tres líneas y una reseña seis, y forzar aquí un mínimo para
 * todos convertiría el campo pequeño en uno enorme.
 */
.field textarea {
  width: 100%; background: var(--surface); border: 1px solid var(--line);
  color: var(--ink); padding: 11px 13px; border-radius: 8px;
  font-size: 15px; font-family: inherit; line-height: 1.55;
  resize: vertical; display: block;
}
.field textarea:focus { border-color: var(--accent); outline: none; }
.field textarea::placeholder { color: var(--ink-3); }

/*
 * Los campos sueltos, fuera de un «.field».
 *
 * Hay sitios donde un campo va solo dentro de un desplegable —«dónde fue»,
 * «con quién fue»— y envolverlos en la estructura entera de un formulario sería
 * más ruido que ayuda. Sin esto salían con el fondo blanco del navegador, que
 * en una pantalla oscura canta muchísimo.
 */
input.suelto {
    width: 100%; background: var(--surface); border: 1px solid var(--line);
    color: var(--ink); padding: 10px 13px; border-radius: 8px;
    font-size: 15px; font-family: inherit;
}
input.suelto:focus { border-color: var(--accent); outline: none; }
.field .hint { font-size: 12.5px; color: var(--ink-3); margin-top: 5px; }

/* Avisar tiene que costar menos que abandonar, pero tampoco competir con el
   contenido: discreto y siempre en el mismo sitio. */
.pie-avisar { max-width: 1080px; margin: 40px auto 0; padding: 0 20px;
              font-size: 13.5px; color: var(--ink-3); text-align: center; }

/* Una categoría siempre es color + icono + texto, nunca menos. */
.categoria { display: inline-flex; align-items: center; gap: var(--e2); }

/* ---------- Solo para quien no ve la pantalla ----------
   Un texto que existe para el lector de pantalla pero no ocupa sitio. No se
   usa «display:none» ni «visibility:hidden»: las dos lo esconden TAMBIÉN del
   lector, que es justo lo contrario de lo que hace falta.

   Esta clase se usaba ya en una vista y no existía: el texto se veía. */
.oculto {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---------- Zonas que se tocan con el dedo ----------
   Solo donde se toca de verdad. En un ordenador con ratón se apunta con
   precisión de un píxel y agrandarlo todo dejaría la interfaz con aspecto de
   juguete; en un móvil, un botón de 28 píxeles se falla.

   Se usa el alto mínimo y no el relleno para no descolocar los textos. */
@media (pointer: coarse) {
  /*
   * 44 píxeles es lo mínimo que se acierta con el dedo sin mirar.
   *
   * Los campos sueltos entran aquí también: con su relleno se quedaban en 41,
   * y esos cuatro píxeles son la diferencia entre escribir dónde viste algo y
   * pulsar dos veces al lado.
   */
  .btn.small, .filters .btn, .subnav .btn, input.suelto { min-height: 44px; }
}

/* ---------- Bloques que se pliegan ----------
   Se pliegan los que la mayoría no usa en la mayoría de obras, y se abren solos
   cuando ya tienen algo dentro. La zona pulsable es la cabecera entera y no
   solo el triangulito: 44 píxeles de alto es lo mínimo que se acierta con el
   dedo sin mirar. */
.plegable > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 8px;
  min-height: 44px; margin: -4px 0;
}
.plegable > summary::-webkit-details-marker { display: none; }
.plegable > summary::before {
  content: '›'; font-size: 20px; line-height: 1; color: var(--ink-3);
  transition: transform .15s ease; flex: none;
}
.plegable[open] > summary::before { transform: rotate(90deg); }
.plegable > summary h3 { margin: 0; }
.plegable > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }

/* Quien ha pedido menos movimiento no quiere que nada gire. */
@media (prefers-reduced-motion: reduce) {
  .plegable > summary::before { transition: none; }
}

/* ---------- Errores de formulario ----------
   El mensaje va pegado al campo que falla, no en un bloque al principio de la
   página: en un móvil, un aviso arriba y el campo culpable abajo no caben en
   la misma pantalla, y quien lo lee tiene que adivinar cuál de los cuatro era. */
.error-campo { font-size: 12.5px; color: var(--danger); margin-top: 5px;
               display: flex; gap: 6px; align-items: flex-start; line-height: 1.45; }
/* El aspa no es decoración: sin ella el único aviso sería el color, y quien no
   distingue el rojo se queda sin saber que hay un error. */
.error-campo::before { content: '\00d7'; font-weight: 700; line-height: 1.2; }

.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] { border-color: var(--danger); }
.field input[aria-invalid="true"]:focus { border-color: var(--danger); }

.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 22px; }
.pagination { display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
              margin-top: 28px; font-size: 14px; }
.pagination a, .pagination span { padding: 7px 12px; border: 1px solid var(--line);
                                  border-radius: 6px; text-decoration: none; color: var(--ink-2);
                                  line-height: 1.2; }
.pagination a:hover { border-color: var(--ink-3); color: var(--ink); }

/* La página en la que estás. */
.pagination .activa { background: var(--accent-dk); border-color: var(--accent-dk); color: var(--sobre-acento); }

/* «Anterior» cuando ya estás en la primera, y los puntos suspensivos: se ven,
   pero no invitan a pulsarlos. */
.pagination .apagado { color: var(--ink-3); border-color: transparent; }

/* El recuento va debajo y en pequeño: orienta sin competir con los enlaces. */
.pagination-cuenta { margin: 10px 0 0; font-size: 13px; color: var(--ink-3); }

/* En el móvil los números se estrechan para que quepan sin partir la fila. */
@media (max-width: 480px) {
    .pagination { gap: 5px; font-size: 13px; }
    .pagination a, .pagination span { padding: 6px 9px; }
}

/* ── Panel de administración ─────────────────────────────────────────────
   No hay tablas en el resto de la aplicación porque no hacían falta: aquí sí,
   porque se comparan filas entre sí. */

.subnav { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 22px; }

/* ── Tablas que no caben en un móvil ────────────────────────────────────
   Se desplazan de lado, pero desplazarse tenía dos problemas y los dos se ven
   en cuanto lo pruebas en un teléfono de verdad:

   1. NADA decía que se pudiera arrastrar. Una tabla cortada por la derecha
      parece rota, no parece que siga. La sombra del borde derecho es la única
      señal de que hay más, y desaparece sola al llegar al final.

   2. Al arrastrar se iba la primera columna, que es la que dice DE QUIÉN es
      cada fila. Se quedaba uno leyendo «hace 14 horas» sin saber de quién.
      Por eso la primera columna se queda fija: es la que da sentido al resto.

   Es la decisión para TODAS las tablas del panel, no un parche por pantalla. */
.tabla-envoltura {
  overflow-x: auto;
  /* La sombra viaja con el fondo y solo se ve mientras quede algo a la
     derecha: es un degradado anclado al borde que el propio desplazamiento
     tapa al llegar al final. El color sale de la tinta del tema: en modo
     oscuro es un halo claro y en modo claro una sombra, porque una sombra
     negra sobre un fondo #191C21 no la vería nadie. */
  background:
    linear-gradient(to right, var(--surface) 30%, transparent),
    linear-gradient(to left,  var(--surface) 30%, transparent) 100% 0,
    radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--ink) 22%, transparent), transparent),
    radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--ink) 22%, transparent), transparent) 100% 0;
  background-repeat: no-repeat;
  background-size: 32px 100%, 32px 100%, 14px 100%, 14px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* La primera columna se queda quieta mientras el resto se desliza por debajo.
   Solo en pantallas donde la tabla no cabe: en un ordenador cabe entera y
   fijar una columna que nunca se mueve solo añade formas de romperse.
   Necesita fondo propio, o el texto que pasa por debajo se le ve a través. */
@media (max-width: 760px) {
  .tabla-envoltura .tabla th:first-child,
  .tabla-envoltura .tabla td:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--surface);
    padding-right: 14px;
    /* Con un correo largo, la columna fija se comía la pantalla entera y no
       quedaba sitio para desplazar lo demás. */
    max-width: 46vw;
  }
}
.tabla { width: 100%; border-collapse: collapse; font-size: 14px; }
.tabla th {
  text-align: left; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3); font-family: var(--mono); font-weight: 400;
  padding: 0 12px 8px 0; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.tabla td { padding: 9px 12px 9px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.tabla tr:last-child td { border-bottom: none; }
.tabla td.num, .tabla th.num { text-align: right; font-family: var(--mono); font-size: 13px; }

/* Gráfico de barras sin librerías: son doce números, no hace falta más. */
.barras { display: flex; align-items: flex-end; gap: 5px; height: 90px; margin-top: 6px; }
/* El tope de anchura es para las primeras semanas: con una sola barra, sin él,
   ocupaba el ancho entero de la pantalla y parecía un error. */
.barras .b { flex: 1; max-width: 54px; display: flex; flex-direction: column;
             justify-content: flex-end; height: 100%; }
.barras .b i { display: block; background: var(--accent-dk); border-radius: 3px 3px 0 0; min-height: 2px; }
.barras .b b { font-family: var(--mono); font-size: 10px; font-weight: 400; color: var(--ink-3);
               text-align: center; padding-top: 4px; }
.barras-pie { display: flex; gap: 5px; margin-top: 2px; }
.barras-pie span { flex: 1; max-width: 54px; text-align: center; font-family: var(--mono); font-size: 9.5px; color: var(--ink-3); }

.medidor { height: 6px; background: var(--surface-2); border-radius: 3px; overflow: hidden; margin-top: 6px; }
.medidor i { display: block; height: 100%; background: var(--danger); }
.medidor.ok i { background: var(--ok); }

.avatar {
  width: 30px; height: 30px; border-radius: 50%; object-fit: cover; flex: none;
  background: var(--surface-2); border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--ink-3); font-family: var(--mono);
}

/* ── Entrar con Google ───────────────────────────────────────────────────── */
.btn.google { width: 100%; background: var(--surface-2); font-weight: 500; padding: 11px 16px; }
.btn.google:hover { border-color: var(--accent); }

.separador { display: flex; align-items: center; gap: 12px; margin: 18px 0; }
.separador::before, .separador::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.separador span { font-size: 12px; color: var(--ink-3); }

/* Aviso de consumo en el panel. Tiene que verse, ese es su único trabajo. */
.aviso {
  background: color-mix(in srgb, var(--gold) 16%, var(--surface));
  border: 1px solid var(--gold);
  border-radius: var(--radius); padding: 13px 16px; margin: 0 0 20px; font-size: 14px; line-height: 1.55;
}
.aviso.grave { background: color-mix(in srgb, var(--danger) 16%, var(--surface)); border-color: var(--danger); }

/* Los resultados de la corrección son botones de formulario, no enlaces. */
.hit-form { display: contents; }
button.hit { font: inherit; color: inherit; border: 1px solid var(--line); background: var(--surface); }
button.hit:hover { border-color: var(--accent); }

/* ── Logotipo ─────────────────────────────────────────────────────────────
   Lo elige <picture> en el componente «x-marca», así que aquí no hay reglas de
   tema que aplicar. Antes se pintaban dos <img> y el CSS escondía una: eso
   enseñaba la correcta pero descargaba las dos, porque «display:none» no
   cancela una petición. En la portada eran 48 KB de logotipo para usar 24. */
.brand img { height: 30px; width: auto; }
.marca-grande img { width: 100%; max-width: 330px; height: auto; margin-bottom: 26px; }

/* La cabecera ya no lleva texto, así que el estilo tipográfico sobra. */
.brand { display: inline-flex; align-items: center; text-decoration: none; }

/* ── Portada pública ───────────────────────────────────────────────────── */
.portada { max-width: 520px; margin: 40px auto; }
.portada .entradilla { color: var(--ink-2); font-size: 16px; line-height: 1.65; margin-bottom: 22px; }
.portada .rasgos { list-style: none; margin: 0 0 26px; padding: 0; }
/* «center» y no «baseline»: los iconos son dibujos, no letras, y alineados
   por la línea base quedan colgando medio píxel por debajo del texto. */
.portada .rasgos li { padding: var(--e1) 0; color: var(--ink-2);
                      display: flex; gap: var(--e2); align-items: center; }

/* Las diez categorías, en dos columnas.

   En una sola son diez líneas y empujan el botón de crear cuenta fuera de la
   primera pantalla, que es peor que no enseñarlas. En dos son cinco líneas y
   se leen de un vistazo, que es de lo que se trata: que quien llega vea que
   aquí caben los cromos y los conciertos, no solo las películas.

   `auto-fit` con mínimo: en un móvil estrecho vuelve a una columna sola en vez
   de partir «Colecciones de cartas» por la mitad. */
.portada .rasgos-categorias { display: grid; gap: 0 var(--e3); margin-bottom: 18px;
                              grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.portada .rasgos-categorias li { padding: 3px 0; font-size: 15px; }

.portada .acciones { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }

/* ── Ejemplares físicos ──────────────────────────────────────────────────── */
.ejemplar { border: 1px solid var(--line); border-radius: var(--radius);
            padding: 12px 14px; margin-bottom: 10px; background: var(--surface-2); }
.tag.gold { background: color-mix(in srgb, var(--gold) 22%, var(--surface));
            border-color: var(--gold); color: var(--ink); }
select { font: inherit; color: var(--ink); background: var(--surface-2);
         border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px; width: 100%; }

/* ── Aviso de cookies ──────────────────────────────────────────────────────
   Solo se ve en las páginas públicas: dentro de la cuenta no hay analítica y
   por tanto no hay nada que consentir.

   Los dos botones son deliberadamente IGUALES —mismo tamaño, mismo peso, mismo
   color—. Hacer «Aceptar» más llamativo que «Rechazar» es una de las cosas por
   las que sanciona la AEPD. */
#aviso-cookies { position:fixed; inset:auto 0 0 0; z-index:9999;
                 background:var(--surface); border-top:1px solid var(--line);
                 box-shadow:0 -8px 32px rgba(0,0,0,.28); }
.aviso-cookies-caja { max-width:900px; margin:0 auto; padding:18px 22px;
                      display:flex; gap:22px; align-items:center; flex-wrap:wrap; }
.aviso-cookies-texto { flex:1 1 340px; }
.aviso-cookies-texto strong { display:block; font-size:15px; margin-bottom:4px; color:var(--ink); }
.aviso-cookies-texto p { margin:0; font-size:13.5px; line-height:1.55; color:var(--ink-2); }
.aviso-cookies-botones { display:flex; gap:10px; flex:0 0 auto; }
.aviso-cookies-botones button {
  font-family:inherit; font-size:14.5px; font-weight:400;
  padding:11px 24px; min-width:118px; border-radius:9px; cursor:pointer;
  background:transparent; color:var(--ink); border:1px solid var(--line); }
.aviso-cookies-botones button:hover { background:var(--bg); border-color:var(--ink-3); }
.aviso-cookies-botones button:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
@media (max-width:560px) {
  .aviso-cookies-caja { padding:16px 18px; gap:14px; }
  .aviso-cookies-botones { width:100%; }
  .aviso-cookies-botones button { flex:1; min-width:0; }
}
.enlace-desnudo { background:none; border:0; padding:0; font:inherit;
                  color:var(--ink-3); text-decoration:underline; cursor:pointer; }
.enlace-desnudo:hover { color:var(--ink); }

/* Pie con los enlaces legales. Discreto pero presente en todas las pantallas:
   una aplicación que guarda datos personales tiene que poder enseñar su
   política de privacidad desde cualquier sitio, no solo desde la portada. */
.pie-legal { max-width:960px; margin:48px auto 0; padding:20px 22px 30px;
             border-top:1px solid var(--line); display:flex; flex-wrap:wrap;
             gap:8px 18px; font-size:13px; }
.pie-legal a, .pie-legal button { color:var(--ink-3); text-decoration:none; }
.pie-legal a:hover, .pie-legal button:hover { color:var(--ink); text-decoration:underline; }

/* ── Fuentes de importación ────────────────────────────────────────────────
   La rejilla se adapta sola: con pocas fuentes no quedan huecos raros y con
   muchas no se estrechan hasta ser ilegibles. */
.fuentes { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.fuente { display: block; padding: 15px 17px; border: 1px solid var(--line);
          border-radius: 10px; text-decoration: none; background: var(--surface); }
.fuente:hover { border-color: var(--accent-dk); }
.fuente strong { display: block; color: var(--ink); margin-bottom: 4px; }
.fuente span { font-size: 13px; line-height: 1.5; display: block; }

/* ── El asistente de puesta a punto ─────────────────────────────────────────
   Una lista de pasos con estado. La marca de la izquierda no es un adorno: es
   lo que deja ver de un vistazo cuánto queda, que es lo que hace que alguien
   termine una lista en vez de abandonarla a la mitad.

   Los estados NO se distinguen solo por el color. Hecho lleva su ✓, saltado su
   raya y el texto se apaga: con un punto verde y otro gris a secas, quien no
   distinga bien los colores ve dos pasos iguales. */
.pasos-bienvenida { list-style: none; margin: 0; padding: 0; }
.paso-bienvenida {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 18px 0; border-top: 1px solid var(--line);
}
.paso-bienvenida:last-child { border-bottom: 1px solid var(--line); }

.paso-marca {
  flex: none; width: 26px; height: 26px; border-radius: 50%; margin-top: 2px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid var(--line); color: var(--ink-3);
  font-size: 14px; line-height: 1;
}
.paso-hecho .paso-marca {
  background: var(--accent-dk); border-color: var(--accent-dk); color: var(--sobre-acento);
}
.paso-pedido .paso-marca { border-color: var(--gold); color: var(--gold); }
.paso-pedido .paso-marca::before { content: "⏳"; font-size: 12px; }

.paso-cuerpo { flex: 1 1 auto; min-width: 0; }
.paso-cuerpo h3 { margin: 0 0 4px; font-size: 16px; display: flex; align-items: center;
                  gap: 9px; flex-wrap: wrap; }

/* Lo resuelto se apaga: sigue estando, deja de pedir atención. */
.paso-hecho .paso-cuerpo h3, .paso-saltado .paso-cuerpo h3 { color: var(--ink-2); }
/* Se tacha el NOMBRE, no el título entero.
   Tachar «IMPORTAR» no dice que esté hecho: dice que ya no es una importación,
   que es otra cosa y además falsa. Antes se intentaba quitándole la decoración
   a la etiqueta, y no funcionaba: una línea heredada se dibuja A TRAVÉS de los
   hijos, y «text-decoration: none» no la borra — depende de detalles del
   navegador, y en algunos salía tachada igual. Tachando solo el nombre no hay
   nada que deshacer. */
.paso-hecho .paso-cuerpo h3 .paso-nombre {
  text-decoration: line-through; text-decoration-thickness: 1px;
}
.paso-saltado { opacity: .72; }

/* Los avisos previos —«tiene que ser diary.csv, no watched.csv»— se marcan con
   una banda lateral: hay que leerlos ANTES de subir el fichero, no después. */
.panel.aviso { border-left: 3px solid var(--gold); }   /* el mismo dorado que las estrellas */
.panel.aviso p { font-size: 14px; line-height: 1.6; color: var(--ink-2); }

/* Elegir cuál de las cuentas de un servidor Plex es la tuya. La fila entera es
   pulsable: acertar en un punto de diez píxeles con el dedo no es razonable. */
.cuenta-plex { display: flex; gap: 12px; align-items: flex-start; cursor: pointer;
               padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px;
               margin-bottom: 10px; background: var(--surface); }
.cuenta-plex:hover { border-color: var(--ink-3); }
.cuenta-plex:has(input:checked) { border-color: var(--accent-dk); }
.cuenta-plex input { margin-top: 3px; flex: none; }
.cuenta-plex > span { display: block; }
.cuenta-plex .titulos { display: block; margin-top: 5px; font-size: 13px; line-height: 1.5; }

/* Una casilla con su texto al lado, pulsable entera. Acertar en un cuadradito
   de trece píxeles con el dedo no es razonable. */
.fila-casilla { display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
                padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px;
                margin-top: 14px; background: var(--surface); font-size: 14.5px; }
.fila-casilla input { margin-top: 2px; flex: none; }
.fila-casilla:has(input:checked) { border-color: var(--accent-dk); }

/* ---------- Fecha pasada ---------- */

/* Cerrado por defecto a propósito: marcar algo que acabas de terminar tiene que
   seguir costando un solo clic. Esto solo se abre cuando alguien está
   rescatando su pasado, que es lo raro. */
.fecha-pasada { margin-top: 14px; }
.fecha-pasada > summary { cursor: pointer; font-size: 14px; color: var(--ink-2);
                          padding: 6px 0; }
.fecha-pasada > summary:hover { color: var(--ink); }
.fecha-pasada[open] > summary { color: var(--ink); margin-bottom: 4px; }

.campo-corto { display: flex; flex-direction: column; gap: 5px; }
.campo-corto > span { font-size: 12px; color: var(--ink-3); }
.campo-corto select, .campo-corto input {
  font-family: inherit; font-size: 16px;   /* 16px evita que el iPhone amplíe */
  padding: 9px 11px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink); }
.campo-corto input[type=number] { width: 96px; }
.campo-corto select:focus-visible, .campo-corto input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; }

/* Una fecha aproximada se marca con un subrayado punteado. Sin esto, «2019» y
   «07/04/2019» parecen el mismo tipo de dato con distinto formato, y no lo
   son: uno es un hecho y el otro un recuerdo. No depende solo del color, que
   dejaría fuera a quien no lo distingue. */
time.aproximada { border-bottom: 1px dotted var(--ink-3); cursor: help; }

/* La sugerencia de discografía, arriba del todo de los resultados: cuando
   alguien escribe el nombre de un grupo, es casi seguro lo que buscaba. */
.sugerencia-artista { display: flex; gap: 12px; align-items: center; padding: 14px 16px;
                      border: 1px solid var(--accent-dk); border-radius: 10px;
                      background: var(--surface); text-decoration: none; color: inherit;
                      margin-bottom: 16px; }
.sugerencia-artista:hover { background: var(--surface-2); }
.sugerencia-artista strong { display: block; }
.sugerencia-artista .dim { font-size: 13px; }

/* ═══════════ Estadísticas ═══════════ */

.filtros-stats { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;
                 margin: 20px 0 26px; }

/* ---------- Cifras ---------- */

.rejilla-cifras { display: grid; gap: 12px;
                  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }
.cifra { background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
         padding: 16px 18px; display: flex; flex-direction: column; gap: 2px; }
.cifra-n { font-size: 30px; line-height: 1.1; color: var(--ink); }
.cifra-et { font-size: 13px; color: var(--ink-3); }

/* La explicación va plegada: quien mira las cifras no quiere leer definiciones,
   pero quien duda de una necesita poder comprobarla sin salir de aquí. */
.cifra-que { margin-top: 4px; }
.cifra-que > summary { cursor: pointer; font-size: 11.5px; color: var(--ink-3);
                       text-decoration: underline dotted; }
.cifra-que > summary:hover { color: var(--ink-2); }
.cifra-que > div { margin-top: 8px; font-size: 12.5px; line-height: 1.55; color: var(--ink-2); }
.cifra-que p { margin: 0 0 6px; }
.cifra-ver { margin-top: 8px; font-size: 12.5px; text-decoration: none; }
.cifra-ver:hover { text-decoration: underline; }

/* ---------- Gráficos ---------- */

.grafico { margin: 0; }

/* Con muchos años la gráfica se desplaza en vez de encogerse hasta ser
   ilegible. En el móvil es la diferencia entre poder leerla o no. */
.grafico-lienzo { overflow-x: auto; overflow-y: hidden; padding-bottom: 4px; }

.grafico-cifra { fill: var(--ink-2); font-size: 11px; font-family: var(--sans); }
.grafico-etiqueta { fill: var(--ink-3); font-size: 10.5px; font-family: var(--sans); }
.grafico-anillo-cifra { fill: var(--ink); font-size: 26px; font-family: var(--sans); }

.leyenda { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 12px;
           font-size: 13px; color: var(--ink-2); }
.leyenda i { display: inline-block; width: 10px; height: 10px; border-radius: 3px;
             margin-right: 6px; vertical-align: -1px; }
.leyenda b { color: var(--ink); font-weight: 600; }
.leyenda-vertical { flex-direction: column; gap: 7px; }

.grafico-anillo { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; }

.grafico-tabla { margin-top: 14px; }
.grafico-tabla > summary { cursor: pointer; font-size: 13px; color: var(--ink-3); }
.grafico-tabla > summary:hover { color: var(--ink); }

/* ---------- Meses ---------- */

.meses { display: flex; gap: 5px; align-items: flex-end; height: 130px; }
.mes { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px;
       height: 100%; justify-content: flex-end; }
.mes-barra { width: 100%; height: 100%; display: flex; align-items: flex-end; }
.mes-barra i { width: 100%; background: var(--accent-dk); border-radius: 3px 3px 0 0;
               display: block; }
.mes-cifra { font-size: 11px; color: var(--ink-2); min-height: 14px; }

/* ---------- Barras horizontales ---------- */

.barras-h { display: flex; flex-direction: column; gap: 8px; }
.barra-h { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.barra-h-et { width: 54px; color: var(--ink-3); flex: none; }
.barra-h-pista { flex: 1; height: 12px; background: var(--surface-2); border-radius: 6px;
                 overflow: hidden; }
.barra-h-pista i { display: block; height: 100%; background: var(--accent-dk);
                   border-radius: 6px; }
.barra-h-cifra { width: 34px; text-align: right; color: var(--ink-2); flex: none; }

/* ---------- Exacto frente a aproximado ---------- */

/* La parte aproximada va rayada, no solo de otro color: quien no distingue
   colores tiene que poder ver la diferencia igual. */
.barra-precision { height: 16px; border-radius: 8px; overflow: hidden;
  background: repeating-linear-gradient(45deg, var(--surface-2), var(--surface-2) 5px,
              var(--line) 5px, var(--line) 10px); }
.barra-precision .exacta { display: block; height: 100%; background: var(--accent-dk); }

/* ---------- Dos columnas ---------- */

.dos-columnas { display: grid; gap: 14px; grid-template-columns: 1fr; }
@media (min-width: 760px) { .dos-columnas { grid-template-columns: 1fr 1fr; } }

/* El recuerdo: la nota privada de una obra. Plegado si está vacío para no
   pedir nada a quien solo quiere marcar, y abierto si ya hay algo escrito
   porque entonces es lo que esa persona viene a releer. */
.recuerdo { margin-top: 14px; }
.recuerdo > summary { cursor: pointer; font-size: 14px; color: var(--ink-2); padding: 6px 0; }
.recuerdo > summary:hover { color: var(--ink); }
.recuerdo textarea { width: 100%; font-family: inherit; font-size: 15px; line-height: 1.55;
                     padding: 11px 13px; border-radius: 9px; margin-top: 8px;
                     border: 1px solid var(--line); background: var(--bg); color: var(--ink);
                     resize: vertical; }
.recuerdo textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ═══════════ Puntos ═══════════ */

.nivel { background: linear-gradient(150deg,
         color-mix(in srgb, var(--accent-dk) 12%, var(--surface)), var(--surface)); }
/* Se envuelve en pantallas estrechas: sin esto, la cifra de puntos se sale
   por la derecha justo en el móvil, que es donde más se mira. */
.nivel-cabecera { display: flex; justify-content: space-between; align-items: flex-start;
                  gap: 10px 16px; margin-bottom: 14px; flex-wrap: wrap; }
.nivel-cabecera > div:last-child { text-align: right; margin-left: auto; }
.nivel-nombre { font-size: 25px; margin: 2px 0 0; line-height: 1.2; }
.nivel-puntos { font-size: 32px; margin: 0; line-height: 1; color: var(--accent); }

.nivel-pista { height: 10px; background: var(--surface-2); border-radius: 5px; overflow: hidden; }
.nivel-pista i { display: block; height: 100%; border-radius: 5px;
                 background: linear-gradient(90deg, var(--accent-dk), var(--accent)); }

/* Cada acción con su explicación al lado. Una puntuación sin motivo se
   discute; con motivo, se entiende aunque no guste. */
.barra-h.accion { gap: 8px; }
.accion-nombre { width: 128px; color: var(--ink-2); }
.barra-h.accion .cifra-que { margin: 0; flex: none; }
.barra-h.accion .cifra-que > summary { width: 18px; height: 18px; border-radius: 50%;
  border: 1px solid var(--line); text-align: center; line-height: 16px; font-size: 11px;
  text-decoration: none; color: var(--ink-3); }
/* Fuera el triángulo que pone el navegador: aquí el propio círculo con la
   interrogación ya dice que se puede abrir. */
.barra-h.accion .cifra-que > summary::-webkit-details-marker { display: none; }
.barra-h.accion .cifra-que > summary { list-style: none; }

/* En pantalla estrecha el nombre se lleva todo el ancho y la barra se queda en
   nada. Se apila: nombre arriba, barra debajo. Una barra de cero píxeles no
   informa de nada, y este bloque existe justamente para comparar de un vistazo. */
@media (max-width: 620px) {
  .barra-h.accion { display: grid; grid-template-columns: 1fr auto auto;
                    grid-template-areas: "nombre cifra ayuda" "pista pista pista";
                    gap: 5px 8px; margin-bottom: 6px; }
  .barra-h.accion .accion-nombre { grid-area: nombre; width: auto; }
  .barra-h.accion .barra-h-cifra { grid-area: cifra; }
  .barra-h.accion .cifra-que { grid-area: ayuda; }
  .barra-h.accion .barra-h-pista { grid-area: pista; }
}
.barra-h.accion .cifra-que > summary:hover { border-color: var(--ink-3); color: var(--ink); }
.barra-h.accion .cifra-que > div { position: relative; z-index: 2; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 9px; padding: 12px 14px; margin-top: 8px; }

.clasificacion td { padding: 10px 12px 10px 0; }
.clasificacion .puesto { width: 34px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
/* Tu propia fila se marca con el color de marca y con un borde: no depende
   solo del color. */
.clasificacion tr.yo { background: color-mix(in srgb, var(--accent-dk) 10%, transparent); }
.clasificacion tr.yo td:first-child { border-left: 3px solid var(--accent-dk); padding-left: 9px; }

/* ── Álbumes de cromos ─────────────────────────────────────────────────────
   El mapa del álbum manda y la cifra le hace de pie: en la ficha van uno al
   lado del otro mientras haya sitio, y apilados en cuanto no lo hay. La cifra
   va primero al apilarse porque es lo que se lee de un vistazo desde lejos. */
.cromos-cabecera { display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: 18px 22px; }
.cromos-cabecera > svg { flex: 1 1 260px; min-width: 0; }
.cromos-cifra { display: flex; flex-direction: column; gap: 2px; flex: 0 0 auto; }
.cromos-cifra strong { font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; }
.cromos-cifra .dim { font-size: 13px; }

/* El color del equipo entra por el borde y por un punto, nunca solo por el
   fondo: es la misma regla que la paleta de categorías —color + texto—, y aquí
   además hay veinte tintes que en su versión real no se distinguirían. */
.cromos-chip { border-left: 3px solid var(--tinte, var(--cat-stickers)); }
.cromos-chip strong { font-variant-numeric: tabular-nums; color: var(--ink-3); }

/* Una sección de la rejilla. El tinte pinta la barra y el filo de arriba; el
   nombre sigue diciendo de quién es, que es lo que de verdad lo identifica. */
.cromos-seccion { border: 1px solid var(--line); border-top: 3px solid var(--tinte, var(--cat-stickers));
  border-radius: 8px; padding: 11px 13px; display: flex; flex-direction: column; gap: 7px;
  text-decoration: none; color: inherit; }
.cromos-seccion:hover { border-color: var(--tinte, var(--accent)); }
.cromos-seccion .t { font-size: 14.5px; font-weight: 600; line-height: 1.25; }
.cromos-seccion .s { font-size: 12.5px; color: var(--ink-3); }
.cromos-barra { display: block; height: 6px; border-radius: 3px; background: var(--line);
  overflow: hidden; }
.cromos-barra i { display: block; height: 100%; background: var(--tinte, var(--cat-stickers)); }

/* Un hueco de la rejilla. Ya pegado, se tiñe: la casilla marcada y el color
   dicen lo mismo dos veces a propósito, porque marcar cromos se hace deprisa
   y de pie. */
.cromo { border: 1px solid var(--line); border-radius: 8px; padding: 9px 11px; }
.cromo.puesto { border-color: var(--tinte, var(--cat-stickers));
  background: color-mix(in srgb, var(--tinte, var(--cat-stickers)) 9%, transparent); }
.cromo .numero { font-family: var(--mono); font-weight: 600; font-size: 15px; }

/* La portada de un álbum de cromos es su mapa. Comparte marco con las demás
   —mismo tamaño, mismo redondeo— para que en una parrilla no desentone, pero
   dentro lleva el dibujo en vez de una imagen que no puede existir. */
.cover-mapa { display: flex; align-items: center; justify-content: center;
  padding: 12px; background: var(--surface-2); overflow: hidden; }
/* El mapa manda en ancho salvo que no quepa de alto, que es lo que pasa con
   veintiocho secciones en una portada apaisada: entonces manda el alto y el
   ancho se ajusta solo. Sin esto el dibujo se sale del marco por arriba. */
.cover-mapa svg { max-width: 100% !important; max-height: 100%; width: auto; }

/* En la ficha las cifras van en fila, porque ahí el mapa ya está de portada y
   este bloque es solo el texto. */
.cromos-cifra-fila { flex-direction: row; align-items: baseline;
  flex-wrap: wrap; gap: 4px 14px; margin-bottom: 4px; }

/* ── «Aquí también cabe» ───────────────────────────────────────────────────
   El bloque que enseña las categorías que esa persona no ha usado todavía.
   Cada una lleva su icono y su color, que es lo que las hace reconocibles
   después en el resto de la aplicación; y su ejemplo debajo, que es lo que de
   verdad explica qué se puede poner dentro. */
.descubrir { margin: 22px 0; }
.descubrir-lista { display: grid; gap: 10px; margin-top: 12px;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr)); }
.descubrir-uno { display: flex; flex-direction: column; gap: 4px;
  border: 1px solid var(--line); border-radius: 9px; padding: 11px 13px;
  text-decoration: none; color: inherit; }
.descubrir-uno:hover { border-color: var(--accent); }
.descubrir-uno .s { font-size: 12.5px; color: var(--ink-3); line-height: 1.45; }

/* ── Un botón que está trabajando ──────────────────────────────────────────
   Sale al enviar un formulario que tarda —subir un historial, por ejemplo—.
   Lleva un aro girando ADEMÁS del texto, no en su lugar: quien no distingue
   bien el movimiento tiene que poder leer qué está pasando. Y el cursor de
   «no se puede» remata el mensaje de que no hay que volver a pulsar. */
.btn.ocupado { cursor: progress; opacity: .85; }
.btn.ocupado::before {
  content: ''; display: inline-block; width: 13px; height: 13px;
  margin-right: 8px; vertical-align: -2px;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: girando .7s linear infinite;
}
@keyframes girando { to { transform: rotate(360deg); } }

/* Quien ha pedido menos movimiento no quiere un aro girando: se le deja el
   aro quieto, que sigue marcando que algo está en marcha. */
@media (prefers-reduced-motion: reduce) {
  .btn.ocupado::before { animation: none; }
}

/* ── Elegir cuántos discos emparejar ───────────────────────────────────────
   Cada opción es un botón grande con su cifra y lo que tarda. Botones y no
   una lista con casillas: así elegir y empezar son el mismo gesto, en vez de
   marcar algo y buscar después dónde estaba el botón de continuar. */
.opciones-cuantos { display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.opcion-cuantos {
  display: flex; flex-direction: column; gap: 3px; text-align: left;
  padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--ink); cursor: pointer;
  font-family: inherit; font-size: 15px;
}
.opcion-cuantos:hover { border-color: var(--accent); }
.opcion-cuantos:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.opcion-cuantos strong { font-size: 16px; }
.opcion-cuantos .dim { font-size: 13px; }
/* La de «todos» va marcada porque es la que más tarda: quien la elija tiene
   que verla distinta antes de pulsarla, no después. */
.opcion-cuantos.todos { border-style: dashed; }

/* ── Repaso de lo importado: los botones a mano ──────────────────────────── */

.revisar-acciones { display: flex; align-items: center; gap: 10px; }
.revisar-acciones.arriba { margin-top: 0; }
.revisar-acciones .botones { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* Cuántas van marcadas. Fuera de la parte que se desplaza: si se fuera con los
   botones, el dato que hace falta para pulsarlos con criterio desaparecería
   justo al ir a pulsarlos. */
.revisar-acciones .marcadas { font-size: 13px; white-space: nowrap; flex: 0 0 auto; }

/* La barra de abajo se pega al pie de la ventana.

   Con cuatrocientas filas, quien va marcando por la mitad de la lista tiene
   los dos juegos de botones fuera de pantalla —uno muy arriba y otro muy
   abajo— y le toca buscar a ciegas. Pegada al pie, están siempre a mano.

   `sticky` y no `fixed`: así deja de flotar cuando termina la lista, en vez de
   quedarse tapando el pie de la página para siempre.

   El fondo es opaco a propósito. Con transparencia se leen las filas por
   debajo de los botones y no se distingue dónde acaba una cosa y empieza la
   otra — y aquí uno de los botones borra cosas. */
.revisar-acciones.abajo {
    position: sticky;
    bottom: 0;
    z-index: 5;
    background: var(--surface);
    border-top: 1px solid var(--line);
    /* El margen negativo lo estira hasta los bordes del contenedor: una barra
       con aire a los lados deja ver las filas colándose por las esquinas. */
    margin: 16px calc(var(--e3) * -1) 0;
    padding: 12px var(--e3);
    /* Sombra hacia arriba: dice que hay contenido por debajo pasando. Sin
       ella, la barra parece el final de la página y se deja de bajar. */
    box-shadow: 0 -6px 16px -8px rgb(0 0 0 / 22%);
}

/* En un móvil los botones no caben en una fila y, apilados, la barra se come
   media pantalla. Con desplazamiento lateral se quedan en una línea y la lista
   sigue viéndose, que es de lo que se trata.

   `min-width: 0` en el contenedor que se desplaza: sin eso, un hijo flex se
   niega a encoger por debajo de su contenido y no hay desplazamiento ninguno,
   se sale de la pantalla y ya está. */
@media (max-width: 620px) {
    .revisar-acciones.abajo .botones {
        flex-wrap: nowrap;
        overflow-x: auto;
        min-width: 0;
        flex: 1 1 auto;
        /* Espacio abajo para la barra de desplazamiento, que en algunos
           navegadores se dibuja encima de los botones. */
        padding-bottom: 2px;
    }
    .revisar-acciones.abajo .botones .btn { flex: 0 0 auto; }
}

/* ── Filtros plegables ───────────────────────────────────────────────────── */

/* En pantalla ancha no se pliega nada.

   Los filtros son dieciocho botones. En un portátil caben en dos líneas y
   tenerlos delante es mejor que tener que abrirlos; el plegado es una
   respuesta a la falta de sitio del móvil, y donde hay sitio estorba.

   El «display: flex» saca los filtros de dentro del plegado aunque el
   «details» esté cerrado: el navegador los esconde por su cuenta, y esto lo
   deshace. Sin JavaScript. */
.filtros-plegables > summary { display: none; }
.filtros-plegables > .filters { display: flex; }

@media (max-width: 700px) {
    .filtros-plegables > summary {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 10px;
        margin-top: 16px;
        padding: 10px 12px;
        border: 1px solid var(--line);
        border-radius: var(--radius);
        background: var(--surface-2);
        cursor: pointer;
        /* Quita el triangulito del navegador: se sustituye por el texto
           «Filtrar», que dice qué pasa al pulsar. Un triángulo no lo dice. */
        list-style: none;
    }
    .filtros-plegables > summary::-webkit-details-marker { display: none; }

    /* Lo que está filtrado, que es lo que se lee cuando está cerrado. */
    .filtros-plegables > summary .que { font-weight: 600; font-size: 15px;
                                        overflow: hidden; text-overflow: ellipsis;
                                        white-space: nowrap; }
    .filtros-plegables > summary .abrir { font-size: 13px; white-space: nowrap; }
    .filtros-plegables[open] > summary .abrir::after { content: ' ▴'; }
    .filtros-plegables:not([open]) > summary .abrir::after { content: ' ▾'; }

    /* Cerrado, se esconden de verdad. */
    .filtros-plegables:not([open]) > .filters { display: none; }
    .filtros-plegables[open] > .filters { display: flex; }

    /* Y el primer bloque no necesita su margen de arriba: ya lo pone el
       resumen que tiene justo encima. */
    .filtros-plegables[open] > .filters:first-of-type { margin-top: 12px !important; }
}

/* ── Cambios de cromos ───────────────────────────────────────────────────── */

/* Las dos manos del cambio, una al lado de la otra.

   Un cambio se cierra mirando las dos a la vez: lo que das y lo que te dan.
   Una debajo de otra habría que subir y bajar para cuadrarlo, que es
   exactamente lo que esta pantalla viene a evitar.

   En móvil se apilan solas, porque ahí no caben dos columnas legibles y es
   preferible desplazarse a leer números apretados. */
.cambios { display: grid; gap: var(--e3); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.cambios .panel { margin: 0; }

/* ── El escaparate de recomendaciones ────────────────────────────────────── */

/* Rejilla que se adapta sola.

   `auto-fill` con mínimo de 190 px: en un portátil salen cinco o seis por
   fila, en una tablet tres, y en el móvil dos. Sin puntos de ruptura escritos
   a mano, que siempre se quedan cortos con la pantalla siguiente. */
/* `align-items: stretch` es lo que hace que todas las tarjetas de una fila
   midan lo mismo aunque sus textos midan distinto. Sin eso, la fila queda como
   una dentadura. */
.escaparate { display: grid; gap: var(--e3); align-items: stretch;
              grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }

/* Cada cosa: foto arriba, texto debajo, y todo pulsable. */
.escaparate-cosa {
    display: flex; flex-direction: column;
    /* Llena su celda de la rejilla.

       Con `align-items: stretch` la celda ya mide lo mismo que sus vecinas,
       pero la tarjeta de dentro se quedaba de su tamaño natural: un título de
       una línea al lado de uno de dos dejaba la fila como una dentadura.

       Con `height: 100%` la tarjeta se estira, y como el texto lleva
       `margin-top: auto` en su pie, lo que crece es el hueco de en medio y los
       pies quedan a la misma altura. */
    height: 100%;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface); overflow: hidden;
    text-decoration: none; color: inherit;
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.escaparate-cosa:hover {
    transform: translateY(-2px);
    border-color: var(--accent);
    box-shadow: 0 6px 20px -10px rgb(0 0 0 / 30%);
}

/* La tapa: la parte que lleva a la tienda, que es casi toda la tarjeta.

   Antes la tarjeta ENTERA era un enlace. Dejó de poder serlo al añadirle un
   segundo destino —la ficha de la biblioteca—, porque un enlace dentro de otro
   enlace no existe: el navegador cierra el de fuera al encontrarse el de
   dentro, y lo que queda son dos enlaces rotos uno detrás de otro.

   `flex: 1` para que la tapa se coma todo el alto que sobre, y así la línea de
   la ficha quede pegada abajo y a la misma altura en todas las tarjetas de la
   fila. `min-height: 0` porque sin él un hijo de flex no baja de su tamaño
   natural, que es justo lo que impedía a las fotos hacerse cuadradas. */
.escaparate-cosa .tapa {
    display: flex; flex-direction: column; flex: 1; min-height: 0;
    text-decoration: none; color: inherit;
}

/* La línea de la ficha: pequeña, abajo, y claramente otra cosa.

   Separada por una línea y con el fondo un punto más apagado porque va a otro
   sitio —a una página nuestra, no a la tienda— y confundir las dos es mandar a
   comprar a quien quería leer. */
.escaparate-cosa .ficha-de {
    display: block; padding: 8px 12px;
    border-top: 1px solid var(--line);
    font-size: 12px; font-weight: 600;
    color: var(--ink-2); text-decoration: none;
}
.escaparate-cosa .ficha-de:hover { color: var(--accent); text-decoration: underline; }

/* Un destacado ocupa dos columnas y su foto es más alta.

   Un escaparate donde todo pesa igual no es un escaparate, es un listado.
   `span 2` solo si hay sitio: en un móvil de dos columnas ocuparía la fila
   entera, que es justo lo que se quiere. */
.escaparate-cosa.grande { grid-column: span 2; }
.escaparate-cosa.grande .foto { aspect-ratio: 16 / 10; }
.escaparate-cosa.grande .t { font-size: 16px; }

/* La foto.

   `contain` y no `cover`: son fotos de producto sobre fondo blanco y
   recortarlas les corta el objeto. El fondo claro es el de la mayoría de fotos
   de tienda, así que el relleno no se nota. */
.escaparate-cosa .foto {
    position: relative;
    aspect-ratio: 1 / 1;
    background: #fff;
    display: flex; align-items: center; justify-content: center;
    padding: 10px;
    /* Sin encogerse ni estirarse.

       La tarjeta es un flex vertical, así que sin esto el hueco de la foto se
       ajusta a lo que ocupe la imagen: una portada de libro alta lo estiraba a
       313 píxeles y una consola apaisada lo dejaba en 196. Las tarjetas medían
       lo mismo por fuera y por dentro empezaban el texto a alturas distintas,
       que es lo que se veía torcido.

       El `min-height: 0` es lo que hace que funcione. Un elemento dentro de un
       flex arranca con `min-height: auto`, que significa «no encojas por debajo
       de tu contenido» — y con eso, una portada alta estira el hueco y el
       `aspect-ratio` no llega a cumplirse nunca. Es la línea que parece que
       sobra y es la única imprescindible. */
    flex: 0 0 auto;
    min-height: 0;
    overflow: hidden;
}
.escaparate-cosa .foto img {
    position: relative; z-index: 1;
    max-width: 100%; max-height: 100%;
    object-fit: contain;
}

/* Cuando no hay foto —o se cae la de fuera— queda el título en grande.

   ── Por qué está SIEMPRE en el DOM y se esconde con CSS ────────────────

   Porque una foto de otro servidor puede desaparecer cualquier día, y el
   `data-quitar-si-falla` de la imagen la borra del documento cuando eso pasa.
   En ese momento el `:has(img)` deja de cumplirse y el respaldo aparece solo,
   sin que nadie tenga que detectar nada.

   ── Y el fallo que corrige el `:has` ───────────────────────────────────

   Estaba puesto detrás de la imagen con z-index, contando con que la taparía.
   Pero las fotos de producto no son cuadradas: con `contain`, una foto de
   500×333 ocupa una banda en mitad del cuadro y el respaldo se veía alrededor
   —con su texto y todo— como si la imagen no hubiera cargado. Se veía en la
   pantalla y no en ninguna prueba. */
.escaparate-cosa .foto:has(img) .sin-foto { display: none; }

.escaparate-cosa .sin-foto {
    position: absolute; inset: 0; z-index: 0;
    display: flex; align-items: center; justify-content: center;
    padding: 14px; text-align: center;
    font-weight: 600; font-size: 14px; line-height: 1.35;
    color: var(--ink-2);
    background: var(--surface-2);
}

.escaparate-cosa .texto { padding: 11px 12px 12px; display: flex;
                          flex-direction: column; gap: 5px; flex: 1; }

/* El nombre oficial del producto, debajo del nuestro.

   Pequeño y en gris a propósito: dice qué edición es exactamente —lo que alguien
   reconoce si lo ha visto en la tienda— pero no compite con el nombre que le
   hemos puesto nosotros, que es lo que convierte esto en una recomendación.

   A dos líneas: algunos son kilométricos —«Coldplay Ghost Stories Clear
   EcoRecord VINYL»— y sin tope se comen la tarjeta entera. */
.escaparate-cosa .oficial {
    font-size: 11.5px; line-height: 1.35; color: var(--ink-3);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
/* El título, a tres líneas como mucho.

   «Hermanos, un cuento que nos llenará el corazón» ocupaba tres líneas al lado
   de «La luz de Lucía», que ocupa una, y la fila entera quedaba descuadrada.
   Cortando por arriba todas las tarjetas miden lo mismo. */
.escaparate-cosa .t { font-weight: 600; font-size: 14px; line-height: 1.3;
                      display: -webkit-box; -webkit-line-clamp: 3;
                      -webkit-box-orient: vertical; overflow: hidden; }
.escaparate-cosa .d { margin: 0; font-size: 13px; line-height: 1.45;
                      color: var(--ink-2);
                      /* Tres líneas y corta: descripciones de largos distintos
                         descuadran la rejilla entera. */
                      display: -webkit-box; -webkit-line-clamp: 3;
                      -webkit-box-orient: vertical; overflow: hidden; }
/* El pie: la nota a la izquierda y «ver precio» a la derecha.

   Se envuelve porque «Ver precio en El Corte Inglés» no cabe al lado de una
   nota en una tarjeta de 190 px, y partido por la mitad no se lee. */
.escaparate-cosa .pie { margin-top: auto; padding-top: 6px;
                        display: flex; justify-content: space-between;
                        align-items: baseline; gap: 4px 8px; flex-wrap: wrap; }
.escaparate-cosa .precio { font-weight: 600; font-size: 14px; }
.escaparate-cosa .donde { font-size: 12px; color: var(--ink-3, var(--ink-2)); opacity: .8; }

/* La marca de «afiliado», en cada tarjeta.

   Discreta pero legible, y no un gris fantasma: el asesor legal pidió que la
   identificación esté donde está el enlace (H-26), y una advertencia que hay que
   buscar no advierte. Va con la línea del precio, que es lo último que se lee
   antes de pulsar.

   Se ocupa la fila entera cuando no cabe al lado, en vez de partirse. */
.escaparate-cosa .afiliado { font-size: 11px; letter-spacing: .04em;
                             text-transform: uppercase; opacity: .62;
                             border: 1px solid currentColor; border-radius: 3px;
                             padding: 0 4px; line-height: 1.5; white-space: nowrap; }

/* En el móvil, un destacado no puede ocupar dos de dos columnas y quedarse
   solo: ahí ya ocupa la fila y no hace falta marcarlo más. */
@media (max-width: 460px) {
    .escaparate { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
    .escaparate-cosa.grande { grid-column: span 2; }
}

/* ── El cartel del pie ───────────────────────────────────────────────────── */

/* Discreto a propósito.

   Va después del contenido, así que lo ve quien ha terminado. Si además
   gritara, sería un anuncio que interrumpe al final en vez de al principio —y
   enseñaría igual a no mirar esta zona nunca más—. Con un borde y un fondo
   suave se ve que es otra cosa sin competir con lo que hay arriba. */
.cartel { max-width: var(--ancho, 1100px); margin: 34px auto 10px; padding: 0 var(--e3); }

.cartel > a {
    display: flex; align-items: center; gap: var(--e3);
    padding: 14px 16px;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface-2);
    text-decoration: none; color: inherit;
    transition: border-color .12s ease, background .12s ease;
}
.cartel > a:hover { border-color: var(--accent); background: var(--surface); }

/* La imagen, pequeña y a la izquierda: es acompañamiento, no el asunto.
   Un cartel de solo texto tiene que verse igual de bien, y por eso el texto
   manda el alto. */
.cartel img { flex: 0 0 auto; width: 64px; height: 64px;
              object-fit: cover; border-radius: 8px; }

.cartel .texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cartel .texto strong { font-size: 15px; line-height: 1.3; }
.cartel .texto .d { font-size: 13.5px; line-height: 1.45; color: var(--ink-2); }

/* El botón no es un botón de verdad —todo el cartel es el enlace— pero lo
   parece, porque es lo que dice que aquí se puede pulsar. */
.cartel .btn { flex: 0 0 auto; pointer-events: none; }

/* En el móvil se apila y el botón ocupa el ancho: un botón pequeño al lado de
   dos líneas de texto en una pantalla estrecha no se acierta con el dedo. */
@media (max-width: 560px) {
    .cartel > a { flex-wrap: wrap; }
    .cartel .texto { flex-basis: 100%; order: 2; }
    .cartel img { order: 1; }
    .cartel .btn { order: 3; width: 100%; text-align: center; }
}

/* ── El «Más» del menú ───────────────────────────────────────────────────── */

/* ── Por qué esto NO es un «details» ──────────────────────────────────────
 *
 * Lo fue, y rompió media aplicación en Chrome. En escritorio hacía falta que
 * los enlaces de dentro salieran en línea con los de fuera, y eso se hacía con
 * `display: contents` sobre el propio `<details>`.
 *
 * Chrome oculta el contenido de un `<details>` cerrado por su cuenta, con un
 * mecanismo interno que `display: contents` no deshace. Así que el botón «Más»
 * quedaba oculto por el CSS, el contenido oculto por el navegador, y ocho
 * secciones inalcanzables — sin ningún error, en ninguna parte, y funcionando
 * bien en otros navegadores.
 *
 * Una casilla con su etiqueta hace lo mismo con CSS de hace quince años. El
 * `display: contents` se queda, pero sobre un `<div>` normal, donde sí es
 * predecible. */

/* La casilla no se ve nunca: quien la maneja es la etiqueta. No se oculta con
   «display: none» porque eso la saca del recorrido del teclado y entonces el
   menú deja de poder abrirse sin ratón. */
.nav-mas-check {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap; border: 0;
}

/* En pantalla ancha caben los once y el «Más» sobra.

   El «display: contents» hace que los enlaces del div salgan en línea con los
   de fuera, como si el div no existiera. Sobre un div normal esto es estable y
   está soportado desde hace años. */
.nav-mas-boton { display: none; }
.nav-mas-caja { display: contents; }

@media (max-width: 900px) {
    .nav-mas-boton {
        display: inline-block;
        cursor: pointer;
        color: var(--ink-2);
        user-select: none;
    }
    .nav-mas-boton::after { content: ' ▾'; font-size: 11px; }
    .nav-mas-check:checked ~ .nav-mas-boton { color: var(--ink); }
    .nav-mas-check:checked ~ .nav-mas-boton::after { content: ' ▴'; }

    /* Que se vea al llegar con el teclado: sin esto, quien navega tabulando no
       sabe dónde está. */
    .nav-mas-check:focus-visible ~ .nav-mas-boton { outline: 2px solid var(--accent); outline-offset: 3px; }

    /* Cerrado, el contenido no está. Abierto, cae como un panel flotante y no
       empuja la página: empujando, el contenido se movería hacia abajo y quien
       mira perdería el sitio donde estaba. */
    .nav-mas-caja { display: none; }

    .nav-mas-check:checked ~ .nav-mas-caja {
        display: flex;
        flex-direction: column;
        gap: 12px;
        position: absolute;
        top: 100%;
        right: 0;
        z-index: 20;
        min-width: 180px;
        margin-top: 10px;
        padding: 14px 16px;
        background: var(--surface);
        border: 1px solid var(--line);
        border-radius: var(--radius);
        box-shadow: 0 10px 30px -12px rgb(0 0 0 / 35%);
    }
    .nav-mas-check:checked ~ .nav-mas-caja form { margin-top: 4px; }

    /* El panel se coloca respecto al menú, que es quien tiene la posición. */
    .nav { position: relative; }
}

/* ── El cartel del pie ───────────────────────────────────────────────────── */

/* Discreto a propósito.

   Va después del contenido, así que lo ve quien ha terminado. Si además
   gritara, sería un anuncio que interrumpe al final en vez de al principio —y
   enseñaría igual a no mirar esta zona nunca más—. Con un borde y un fondo
   suave se ve que es otra cosa sin competir con lo que hay arriba. */
.cartel { max-width: var(--ancho, 1100px); margin: 34px auto 10px; padding: 0 var(--e3); }

.cartel > a {
    display: flex; align-items: center; gap: var(--e3);
    padding: 14px 16px;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface-2);
    text-decoration: none; color: inherit;
    transition: border-color .12s ease, background .12s ease;
}
.cartel > a:hover { border-color: var(--accent); background: var(--surface); }

/* La imagen, pequeña y a la izquierda: es acompañamiento, no el asunto.
   Un cartel de solo texto tiene que verse igual de bien, y por eso el texto
   manda el alto. */
.cartel img { flex: 0 0 auto; width: 64px; height: 64px;
              object-fit: cover; border-radius: 8px; }

.cartel .texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cartel .texto strong { font-size: 15px; line-height: 1.3; }
.cartel .texto .d { font-size: 13.5px; line-height: 1.45; color: var(--ink-2); }

/* El botón no es un botón de verdad —todo el cartel es el enlace— pero lo
   parece, porque es lo que dice que aquí se puede pulsar. */
.cartel .btn { flex: 0 0 auto; pointer-events: none; }

/* En el móvil se apila y el botón ocupa el ancho: un botón pequeño al lado de
   dos líneas de texto en una pantalla estrecha no se acierta con el dedo. */
@media (max-width: 560px) {
    .cartel > a { flex-wrap: wrap; }
    .cartel .texto { flex-basis: 100%; order: 2; }
    .cartel img { order: 1; }
    .cartel .btn { order: 3; width: 100%; text-align: center; }
}


/* ── La foto de tu ejemplar ──────────────────────────────────────────────── */

/* Pequeña a propósito.

   Es un recordatorio de qué edición tienes, no una galería. Ocupando media
   pantalla taparía los datos del ejemplar —dónde lo guardas, a quién se lo
   prestaste— que es lo que de verdad se viene a mirar aquí. */
.ejemplar-foto { display: flex; gap: 12px; align-items: flex-start; margin: 10px 0 0; }
.ejemplar-foto img {
    width: 92px; height: 122px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--line);
    background: var(--surface-2);
}

/* ── Compartir ───────────────────────────────────────────────────────────── */

/* El botón y, en ordenador, la fila de enlaces que despliega.

   En el móvil la fila no llega a verse nunca: ahí el navegador abre la bandeja
   del sistema, con las aplicaciones que esa persona tiene de verdad. */
.compartir { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }

.compartir-boton { display: inline-flex; align-items: center; gap: 6px; }
/* El icono acompaña al texto y no manda: alineado a la mitad de la línea y sin
   que su alto estire el botón. */
.compartir-boton svg { flex: 0 0 auto; }

/* La fila se envuelve porque seis botones no caben en un móvil ancho, y
   partidos por la mitad no se leen. */
.compartir-caja { display: flex; flex-wrap: wrap; gap: 6px; }


.compartir-dicho { font-size: 13px; color: var(--ink-2); }
.compartir-dicho:empty { display: none; }
