/* Kirava · archivador y ficha de carta
   El chrome compartido está en shell.css; el buscador, en search.css. */

@layer components {

/* --- Cabecera de set ---------------------------------------------------
   En pantalla ancha la ficha del set va al lado del álbum y no encima: así el
   hueco vertical se lo queda entero la hoja, que es lo que importa. */

.set-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5);
}
/* minmax(0, 1fr) y no 1fr: por defecto un item de grid tiene min-width auto y
   se niega a encoger por debajo de su contenido, así que una tabla ancha dentro
   estira la columna y desborda toda la página. */
.set-layout > * { min-width: 0; }

@media (min-width: 1000px) {
  .set-layout {
    grid-template-columns: minmax(200px, 250px) minmax(0, 1fr);
    align-items: start;
    gap: var(--sp-6);
  }
  .set-head { position: sticky; top: calc(var(--header-h) + var(--sp-4)); }
  .set-meta { grid-template-columns: repeat(2, 1fr); }
}

.set-head { display: grid; gap: var(--sp-2); align-content: start; }
.back-link { font-size: .8rem; color: var(--ink-3); transition: color var(--dur-fast); }
.back-link:hover { color: var(--primary-ink); }
.serie { font-size: .7rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-3); }
.set-head h1 { font-size: clamp(1.35rem, 3.2vw, 1.9rem); letter-spacing: -.03em; line-height: 1.1; }

.set-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(72px, 1fr));
  gap: var(--sp-3);
  min-width: 0;
  margin-top: var(--sp-2);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line-soft);
}
.set-meta div { display: grid; gap: 1px; }
.set-meta dt { font-size: .64rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.set-meta dd { font-size: .88rem; font-family: var(--font-num); }

/* --- El archivador -----------------------------------------------------
   La hoja entera tiene que caber en pantalla. Si hay que hacer scroll para ver
   las nueve fundas, deja de ser una hoja de álbum y vuelve a ser una lista.

   Por eso el ancho lo manda el ALTO disponible, no el ancho: se calcula cuánto
   mide una hoja 3x3 de cartas 63x88 en el hueco vertical que queda. Es lo mismo
   que hace una carpeta física: la página tiene el tamaño que tiene. */
.binder {
  --chrome: 248px;
  --sheet-ratio: .716;              /* 63/88 */
  position: relative;
  padding: clamp(var(--sp-3), 2.2vw, var(--sp-5));
  width: min(100%, max(430px, calc((100dvh - var(--chrome)) * var(--sheet-ratio) + 74px)));
  margin-inline: auto;
  border-radius: 16px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-2);
}

/* Las anillas del archivador viven ahora en content.css, junto al canto y la
   hoja de plástico: son tres piezas del mismo dibujo y separarlas hacía que
   cualquier ajuste requiriera tocar dos ficheros. */

.sheet {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(var(--sp-2), 1.6vw, var(--sp-4));
  /* Sin content-visibility a propósito.
     ------------------------------------------------------------------------
     Lo tenía puesto de cuando la rejilla podía traer miles de cartas de golpe.
     Ahora se pagina de 24 en 24 y de 9 en 9, así que no ahorra nada — y sí
     rompe algo: un elemento dentro de un subárbol con content-visibility
     puede quedar sin renderizar en el momento en que el navegador toma la
     instantánea de la View Transition, y entonces la carta no crece desde su
     sitio: la ficha aparece de golpe. El zoom es de lo mejor que tiene esto;
     no se sacrifica por una optimización que ya no hace falta. */
}

.slot { position: relative; display: block; border-radius: 8px; }

/* La funda de plástico. */
.sleeve {
  position: relative;
  aspect-ratio: var(--card-ratio);
  border-radius: 7px;
  padding: 3px;
  background: linear-gradient(158deg, rgb(255 255 255 / .9), var(--surface-3));
  box-shadow:
    var(--aura, 0 0 rgb(0 0 0 / 0)),
    inset 0 0 0 1px rgb(47 42 37 / .06),
    inset 0 1px 3px rgb(47 42 37 / .1);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

/* Al pasar por encima la carta se levanta. Sutil. */
.slot:hover .sleeve,
.slot:focus-visible .sleeve {
  transform: translateY(-6px) scale(1.012);
  box-shadow: var(--aura, 0 0 rgb(0 0 0 / 0)), inset 0 0 0 1px rgb(47 42 37 / .08), var(--shadow-3);
}

/* Los huecos vacíos se ven como huecos: ver lo que falta es media gracia del
   coleccionismo, y omitirlos rompe la metáfora de la hoja de nueve fundas. */
.slot-empty .sleeve {
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--line-soft), inset 0 2px 6px rgb(47 42 37 / .05);
  display: grid;
  place-items: center;
}
.sleeve-mark {
  width: 24px; height: 24px;
  border: 1.5px dashed var(--line);
  border-radius: 50%;
}

.slot-num {
  position: absolute;
  right: 6px; bottom: 6px;
  font-family: var(--font-num);
  font-size: .62rem;
  color: var(--ink-2);
  background: color-mix(in oklab, var(--surface) 88%, transparent);
  padding: 1px 5px;
  border-radius: 4px;
  opacity: 0;
  transition: opacity var(--dur-fast);
  pointer-events: none;
}
.slot:hover .slot-num, .slot:focus-visible .slot-num { opacity: 1; }

.sheet-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-5);
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-soft);
}

/* --- Ficha de carta ---------------------------------------------------- */

.detail {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;

  /* Los dos huecos que rodean a la carta, con nombre, porque más abajo hay que
     restarlos para saber cuánto alto queda de verdad. Si se repitieran a mano
     acabarían desincronizándose y la cuenta saldría mal sin que se note. */
  --panel-inset: clamp(var(--sp-3), 3vw, var(--sp-6));
  --panel-pad:   clamp(var(--sp-4), 3vw, var(--sp-6));

  padding: var(--panel-inset);
}

/* Lo que había detrás sigue ahí: se atenúa y desenfoca, pero se ve.
   El usuario nunca pierde de vista dónde estaba. */
.detail-backdrop {
  position: fixed;
  inset: 0;
  background: color-mix(in oklab, var(--ink) 34%, transparent);
  backdrop-filter: blur(7px) saturate(.85);
  animation: fade var(--dur) var(--ease-out);
}
@keyframes fade { from { opacity: 0 } }

/* La ficha, y el problema que hay que resolver bien.
   ------------------------------------------------------------------------
   Una carta trae mucha información: estadísticas, habilidad, ataques,
   debilidades, variantes, otras impresiones y otras cartas de la misma especie.
   En un portátil de pantalla corta o en un móvil, eso no cabe.

   La solución NO puede ser recortar contenido según el tamaño: el dato que se
   corta es justo el que alguien ha venido a buscar. La solución es que todo
   siga estando y se pueda alcanzar.

   Dos modos, según lo que quepa:

   · Ancho y alto suficientes -> dos columnas, la carta fija a la izquierda y la
     información con su propio scroll a la derecha.
   · Estrecho o bajo -> una columna y el panel entero hace scroll, con la carta
     arriba. Nada se recorta; se baja.

   El interruptor es una consulta de ALTO además de ancho, porque el caso que
   falla de verdad no es el móvil: es el portátil de 1366x768. */
.detail-panel {
  position: relative;
  display: grid;
  /* La columna izquierda mide lo que mide la carta, ni un píxel más.
     ---------------------------------------------------------------------
     Con un porcentaje fijo sobraban doscientos píxeles a los lados de la
     carta: la carta está limitada por ALTO, así que darle más ancho no la hace
     crecer — solo se lo quita a la información de la derecha.

     El tope del 48% es para pantallas altas, donde la carta sí podría crecer
     por ancho y se comería el panel entero.

     Ojo: aquí va la fórmula del ancho y no `auto`. Una pista `auto` se mide por
     el contenido, y el contenido pide `width: 100%` de la pista: circular, y el
     ancho resuelve a cero (la carta desaparece). Con la fórmula, la pista sale
     del alto disponible y no hay ciclo. */
  grid-template-columns: minmax(280px, min(48%, var(--card-w))) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  gap: clamp(var(--sp-4), 3vw, var(--sp-6));
  width: min(100%, 1280px);

  /* Las medidas de la ficha, calculadas UNA vez y en cadena, porque todas salen
     del mismo sitio: cuánto alto queda dentro del panel.

       panel-inner -> alto útil (ventana menos márgenes y relleno)
       card-h      -> lo mismo menos la fila de botones: el alto de la carta
       card-w      -> ese alto por la proporción 63/88

     De aquí beben el ancho de la columna izquierda, el tamaño de la carta y el
     tope de scroll de la derecha. Repetir la cuenta en cada sitio es cómo se
     desincronizan y aparecen los recortes. */
  --panel-inner: calc(100dvh - 2 * var(--panel-inset) - 2 * var(--panel-pad));
  --card-chrome: 4.25rem;   /* hueco + fila de botones, con holgura */
  --card-h: calc(var(--panel-inner) - var(--card-chrome));
  --card-w: calc(var(--card-h) * 63 / 88);

  max-height: min(100%, calc(100dvh - 2 * var(--panel-inset)));
  padding: var(--panel-pad);
  border-radius: 20px;
  background: var(--surface);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}

.detail-stage {
  display: grid; align-content: start; gap: var(--sp-3); justify-items: center;
  min-height: 0;
}

/* La carta no crece sin límite: en pantallas altas y estrechas se comía todo el
   panel y empujaba los controles fuera.
   ------------------------------------------------------------------------
   Se limita por ANCHO calculado a partir del alto, no con `width: auto`.
   `width: auto` en un item de grid centrado lo encoge a su contenido — pero su
   hijo `.flip` pide `width: 100%` del padre. Padre que depende del hijo y el
   hijo del padre: circular, el ancho resuelve a cero y la carta desaparece
   entera. Se ve exactamente igual que si faltara la imagen.

   Con el ancho calculado del alto no hay ciclo: el alto disponible por la
   proporción 63/88 da el ancho, y el resto se deduce de ahí.

   `--card-h` NO es un porcentaje del alto de ventana a ojo. Era `70dvh` con
   tramos a 62/56/48 según la pantalla, y esos números dejaban ciento y pico
   píxeles de blanco muertos debajo de la carta: 70dvh mide desde el borde de la
   ventana, pero la carta no empieza ahí — antes hay el margen del panel, su
   relleno, el hueco y la fila de botones. Lo que sobraba era justo eso, restado
   dos veces por lo bajo.

   Ahora se resta lo que hay de verdad. La carta ocupa todo el alto que queda y
   no hace falta ningún tramo: el cálculo ya se adapta a cualquier ventana,
   incluido el portátil de 1366x768 que era el caso problemático. */
.detail-stage {
  min-height: 0;

  /* Sin overflow, y es importante.
     ---------------------------------------------------------------------
     Aquí había `overflow-y: auto` como red de seguridad por si la carta no
     cabía. Pero en CSS no se puede recortar un solo eje: en cuanto uno deja de
     ser `visible`, el otro pasa a `auto` solo. O sea que también recortaba a lo
     ancho — y desde que esta columna mide exactamente lo que la carta, el corte
     cae justo sobre su borde y la sombra sale rebanada en rectángulo.

     La red ya no hace falta: `--card-h` se calcula del hueco real y siempre
     sobran ~20px por debajo de la fila de botones. */
}
.detail-stage .card-big {
  width: min(100%, var(--card-w));
  margin-inline: auto;
}
.stage-tools { display: flex; align-items: center; justify-content: center; gap: var(--sp-2); }
.stage-pos {
  font-family: var(--font-num);
  font-size: .74rem;
  color: var(--ink-3);
  margin-top: calc(var(--sp-2) * -1);
}
.tool {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .82rem;
  color: var(--ink-2);
  transition: border-color var(--dur-fast), color var(--dur-fast);
}
.tool:hover { color: var(--ink); border-color: var(--ink-3); }
.tool[hidden] { display: none; }

/* Inclinar. Cuando está activo se marca de verdad —relleno, no solo un borde
   distinto— porque en el móvil se ve a un palmo y de reojo: el usuario está
   mirando la carta, no el botón. */
.tool-tilt[aria-pressed='true'] {
  color: var(--primary-ink);
  border-color: var(--primary);
  background: var(--primary-wash);
}
.tilt-icon {
  width: 12px; height: 17px;
  border: 1.5px solid currentColor;
  border-radius: 3px;
  display: inline-block;
  transform: rotate(-14deg);
  transition: transform var(--dur-fast) ease;
}
/* El icono se balancea solo mientras está encendido: enseña el gesto sin
   tener que explicarlo con palabras. */
.tool-tilt[aria-pressed='true'] .tilt-icon { animation: tilt-rock 2.4s ease-in-out infinite; }
@keyframes tilt-rock {
  0%, 100% { transform: rotate(-14deg); }
  50%      { transform: rotate(14deg); }
}
@media (prefers-reduced-motion: reduce) {
  .tool-tilt[aria-pressed='true'] .tilt-icon { animation: none; }
}

.detail-info {
  overflow-y: auto;

  /* `overflow-y: auto` por sí solo NO scrollea aquí.
     ---------------------------------------------------------------------
     Un item de grid trae `min-height: auto`, o sea «nunca más bajo que su
     contenido». Así que la fila crecía hasta caber entera, el panel se pasaba
     de su max-height y el `overflow: hidden` del panel cortaba lo de abajo por
     lo seco: las miniaturas de otros idiomas se quedaban a medias y no había
     forma de llegar a ellas.

     Con min-height: 0 la fila sí puede quedarse más baja que su contenido...
     pero tampoco basta: una fila `auto` se dimensiona por su contenido, y el
     `max-height` del panel solo recorta DESPUÉS. Hace falta además un tope
     definido, el mismo alto útil del que sale la carta. */
  min-height: 0;
  max-height: var(--panel-inner);

  padding-inline-end: var(--sp-2);
  /* Hueco para el paginador flotante y el botón +: sin esto tapan la última
     fila justo cuando alguien llega a ella. */
  padding-bottom: var(--sp-8);
  display: grid;
  gap: var(--sp-4);
  align-content: start;
}
.detail-info::-webkit-scrollbar { width: 8px; }
.detail-info::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 4px; }

.di-set { font-size: .7rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-3); }
.di-name { font-size: clamp(1.35rem, 3vw, 1.95rem); letter-spacing: -.03em; line-height: 1.1; margin-top: var(--sp-1); }
.di-sub { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }

.chip {
  padding: 2px var(--sp-3);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .74rem;
  color: var(--ink-2);
  font-family: var(--font-num);
}
.chip-lang { border-color: var(--primary); color: var(--primary-ink); background: var(--primary-wash); font-weight: 600; }

.di-stats { display: flex; flex-wrap: wrap; gap: var(--sp-5); padding: var(--sp-3) 0; border-block: 1px solid var(--line-soft); }
.di-stats div { display: grid; gap: 2px; }
.di-stats dt { font-size: .68rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.di-stats dd { font-size: .95rem; font-weight: 600; display: flex; align-items: center; gap: var(--sp-2); }

.di-move { display: grid; gap: var(--sp-1); }
.di-move h3 { font-size: .98rem; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.di-move p { font-size: .88rem; color: var(--ink-2); line-height: 1.55; }
.di-ability h3 { color: var(--secondary-ink); }
.tag {
  font-size: .6rem; text-transform: uppercase; letter-spacing: .09em; font-weight: 700;
  padding: 2px 6px; border-radius: 5px;
  background: var(--secondary-wash);
  color: var(--secondary-ink);
}
.dmg { margin-inline-start: auto; font-family: var(--font-num); font-size: 1.05rem; font-weight: 700; }
.cost { display: inline-flex; gap: 3px; }

.energy {
  display: inline-flex; align-items: center;
  font-size: .74rem; padding: 1px var(--sp-2);
  border-radius: 999px;
  background: var(--e-bg, var(--surface-3));
  color: var(--e-ink, var(--ink));
  font-weight: 600;
}
.energy-dot { width: 15px; height: 15px; padding: 0; border-radius: 50%; }

.energy[data-type="Fire"]      { --e-bg: #e8523a; --e-ink: #fff; }
.energy[data-type="Water"]     { --e-bg: #3aa0e8; --e-ink: #fff; }
.energy[data-type="Grass"]     { --e-bg: #4caf50; --e-ink: #fff; }
.energy[data-type="Lightning"] { --e-bg: #edc531; --e-ink: #3a2f00; }
.energy[data-type="Psychic"]   { --e-bg: #9b5fc0; --e-ink: #fff; }
.energy[data-type="Fighting"]  { --e-bg: #b8622f; --e-ink: #fff; }
.energy[data-type="Darkness"]  { --e-bg: #3c4358; --e-ink: #fff; }
.energy[data-type="Metal"]     { --e-bg: #8b95a8; --e-ink: #fff; }
.energy[data-type="Fairy"]     { --e-bg: #e26aa8; --e-ink: #fff; }
.energy[data-type="Dragon"]    { --e-bg: #b9962e; --e-ink: #fff; }
.energy[data-type="Colorless"] { --e-bg: #ded9cd; --e-ink: var(--ink); }

.di-block { display: grid; gap: var(--sp-3); }
.di-h { font-size: .74rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-3); display: flex; align-items: center; gap: var(--sp-2); }
.di-h .count {
  font-family: var(--font-num); font-size: .7rem; letter-spacing: 0;
  padding: 0 6px; border-radius: 999px;
  background: var(--surface-3); color: var(--ink-2);
}

.variant-list { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.variant {
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: .8rem;
  color: var(--ink-2);
  transition: border-color var(--dur-fast), color var(--dur-fast), background var(--dur-fast);
}
.variant:hover { color: var(--ink); border-color: var(--ink-3); }
.variant.is-on { border-color: var(--secondary); color: var(--secondary-ink); background: var(--secondary-wash); font-weight: 600; }

.sibling-list { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.sibling-list a { display: grid; gap: var(--sp-1); width: 92px; }
.sibling-list img { border-radius: 5px; box-shadow: var(--shadow-1); transition: transform var(--dur) var(--ease-out); }
.sibling-list a:hover img { transform: translateY(-4px); box-shadow: var(--shadow-2); }
.sib-lang { font-size: .66rem; color: var(--primary-ink); font-family: var(--font-num); font-weight: 700; }
.sib-name { font-size: .76rem; color: var(--ink); line-height: 1.3; font-weight: 500; }
.sib-set  { font-size: .66rem; color: var(--ink-3); line-height: 1.25; }
.sib-doubt { font-size: .64rem; color: var(--ink-3); font-style: italic; }

/* Sin imagen la carta sigue siendo reconocible: número, nombre y set bastan. */
.sib-noimg {
  display: grid; place-items: center;
  aspect-ratio: var(--card-ratio);
  border: 1px dashed var(--line);
  border-radius: 5px;
  background: var(--surface-2);
  font-family: var(--font-num);
  font-size: .7rem;
  color: var(--ink-3);
}

.di-sub-note { font-size: .78rem; color: var(--ink-3); margin-top: calc(var(--sp-2) * -1); }

.note {
  font-size: .86rem; color: var(--ink-2); line-height: 1.6;
  padding: var(--sp-3) var(--sp-4);
  border-inline-start: 3px solid var(--line);
  border-radius: 0 9px 9px 0;
  background: var(--surface-2);
}
.note-star { border-inline-start-color: var(--secondary); background: var(--secondary-wash); }
.note strong { color: var(--ink); }

.di-foot { display: flex; flex-wrap: wrap; gap: var(--sp-5); padding-top: var(--sp-3); border-top: 1px solid var(--line-soft); }
.di-foot div { display: grid; gap: 2px; }
.di-foot dt { font-size: .66rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.di-foot dd { font-size: .85rem; color: var(--ink-2); }

.detail-nav {
  position: absolute;
  left: 50%; bottom: var(--sp-3);
  transform: translateX(-50%);
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  background: color-mix(in oklab, var(--surface) 92%, transparent);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow-2);
  z-index: 3;
}
.nav-pos {
  font-family: var(--font-num);
  font-size: .74rem;
  color: var(--ink-3);
  padding-inline: var(--sp-2);
  white-space: nowrap;
}

.nav-btn {
  display: grid; place-items: center;
  width: 32px; height: 32px;
  border: 1px solid var(--line);
  border-radius: 50%;
  font-size: 1.2rem; line-height: 1;
  color: var(--ink-2);
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}
.nav-btn:hover { background: var(--surface-3); color: var(--ink); border-color: var(--ink-3); }
.nav-btn.is-off { opacity: .3; pointer-events: none; }

.detail-close {
  position: absolute;
  top: var(--sp-3); right: var(--sp-3);
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--ink-2);
  background: var(--surface);
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}
.detail-close:hover { background: var(--surface-3); color: var(--ink); border-color: var(--ink-3); }

/* --- Móvil ------------------------------------------------------------- */

/* Una columna SOLO cuando no cabe a lo ancho.
   ------------------------------------------------------------------------
   Antes esto también saltaba con `(max-height: 760px)`, y era un error: un
   portátil normal tiene el viewport por debajo de esa cifra, así que en la
   mayoría de pantallas la ficha se plegaba a una columna sin necesidad. Con
   sitio a lo ancho siempre son dos columnas — carta a la izquierda, datos con
   su scroll a la derecha— y lo que se ajusta al alto es el tamaño de la carta,
   que para eso está calculado desde el alto. */
@media (max-width: 900px) {
  .detail { padding: clamp(var(--sp-2), 2vw, var(--sp-4)); }

  .detail-panel {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto;
    align-content: start;
    overflow-y: auto;
    overscroll-behavior: contain;       /* el scroll no se escapa a la página */
    -webkit-overflow-scrolling: touch;
    gap: var(--sp-4);
  }

  .detail-info {
    overflow: visible;                  /* ya no scrollea por su cuenta */
    max-height: none;
    padding-inline-end: 0;
  }

  /* Una columna: manda el ancho disponible, no el alto. */
  .detail-stage { overflow: visible; }
  .detail-stage .card-big { width: min(380px, 74vw); }

  /* La X se queda pegada arriba mientras se baja: si se va con el scroll, en
     móvil hay que volver arriba solo para cerrar. */
  .detail-close {
    position: sticky;
    top: 0;
    margin-inline-start: auto;
    z-index: 2;
  }
}

/* Aquí estaban los tramos de `--card-h` a 62/56/48dvh. Ya no hacen falta: el
   cálculo de arriba resta el marco real, así que se ajusta solo a cualquier
   alto de ventana en vez de saltar entre tres tamaños fijos.

   En ventanas muy bajas lo único que se retoca es el texto del paginador. */
@media (min-width: 901px) and (max-height: 640px) {
  .stage-pos { font-size: .72rem; }
}

@media (max-width: 560px) {
  .binder { width: 100%; padding: var(--sp-2); border-radius: 12px; }
  .binder::before { display: none; }
  .sheet-nav { gap: var(--sp-3); margin-top: var(--sp-4); }
  .detail-stage .card-big { width: min(340px, 82vw); }
  .set-layout { gap: var(--sp-3); }
  .set-head h1 { font-size: 1.3rem; }
  .set-meta { grid-template-columns: repeat(4, auto); justify-content: start; gap: var(--sp-4); }
  .set-meta dd { font-size: .8rem; }
}

@media (max-height: 720px) and (min-width: 561px) {
  .binder { --chrome: 200px; }
}

}

@layer components {

/* --- Botón de añadir al vault --------------------------------------------
   Redondo, flotante y con brillo. Es la única acción de la ficha que crea algo:
   merece pesar más que el resto y verse sin tener que buscarla. */

.fab-add {
  position: absolute;
  right: var(--sp-4);
  bottom: var(--sp-4);
  z-index: 4;

  /* Píldora, no círculo: tiene que caber lo que hace. Sigue siendo redonda
     por los extremos, así que conserva el aire de botón flotante. */
  height: 54px;
  padding: 0 var(--sp-5) 0 var(--sp-4);
  display: inline-flex; align-items: center; gap: var(--sp-2);
  border: 0; border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;

  background: linear-gradient(140deg, var(--secondary), #f0b45f 55%, var(--secondary));
  box-shadow:
    0 4px 14px -2px color-mix(in oklab, var(--secondary) 55%, transparent),
    0 0 0 0 color-mix(in oklab, var(--secondary) 45%, transparent);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
  overflow: hidden;
  animation: fab-pulse 3.2s var(--ease-in-out) infinite;
}
.fab-text {
  font-size: .92rem; font-weight: 650; letter-spacing: -.01em;
  color: #fff;
}

/* Muy estrecho: se queda el círculo con el «+». El texto es lo primero que
   sobra cuando no hay sitio, pero solo entonces. */
@media (max-width: 560px) {
  .fab-text { display: none; }
  .fab-add { width: 54px; padding: 0; justify-content: center; }
}

.fab-add:hover {
  transform: scale(1.06);
  box-shadow: 0 8px 22px -4px color-mix(in oklab, var(--secondary) 70%, transparent);
}
.fab-add:active { transform: scale(.96); }

/* El destello que lo cruza. Va en un ::after y solo mueve transform: no toca
   el layout ni obliga a repintar el panel entero. */
.fab-add::after {
  content: "";
  position: absolute;
  inset: -30%;
  background: linear-gradient(75deg,
    rgb(255 255 255 / 0) 42%,
    rgb(255 255 255 / .55) 50%,
    rgb(255 255 255 / 0) 58%);
  transform: translateX(-120%);
  animation: fab-shine 3.2s var(--ease-in-out) infinite;
}

/* El + dibujado con dos barras: no depende de ninguna fuente de iconos. */
.fab-plus {
  position: relative;
  width: 20px; height: 20px;
}
.fab-plus::before, .fab-plus::after {
  content: "";
  position: absolute;
  inset-block: 50%; inset-inline: 0;
  height: 2.5px; margin-block: -1.25px;
  border-radius: 2px;
  background: #fff;
}
.fab-plus::after { transform: rotate(90deg); }

@keyframes fab-shine {
  0%, 55%  { transform: translateX(-120%); }
  75%,100% { transform: translateX(120%); }
}
@keyframes fab-pulse {
  0%, 70%, 100% { box-shadow: 0 4px 14px -2px color-mix(in oklab, var(--secondary) 55%, transparent),
                              0 0 0 0 color-mix(in oklab, var(--secondary) 40%, transparent); }
  85%           { box-shadow: 0 4px 14px -2px color-mix(in oklab, var(--secondary) 55%, transparent),
                              0 0 0 10px color-mix(in oklab, var(--secondary) 0%, transparent); }
}

/* Un brillo que late sin parar cansa y consume batería. Se apaga con el
   interruptor de efectos y con prefers-reduced-motion, como todo lo demás. */
@media (prefers-reduced-motion: reduce) {
  .fab-add, .fab-add::after { animation: none; }
  .fab-add::after { display: none; }
}
:root[data-fx="off"] .fab-add,
:root[data-fx="off"] .fab-add::after { animation: none; }
:root[data-fx="off"] .fab-add::after { display: none; }

/* --- Diálogo de añadir --------------------------------------------------- */

.add-dialog {
  width: min(92vw, 400px);
  padding: var(--sp-5);
  border: 1px solid var(--line-soft);
  border-radius: 18px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-3);
}
.add-dialog::backdrop { background: rgb(47 42 37 / .45); backdrop-filter: blur(3px); }

.ad-head { margin-bottom: var(--sp-4); }
.ad-head h2 { font-size: 1.15rem; letter-spacing: -.02em; }
.ad-card { font-size: .82rem; color: var(--ink-3); margin-top: var(--sp-1); }
.ad-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.ad-row input[type="number"] {
  width: 100%; padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line); border-radius: 9px; background: var(--surface); font-size: .95rem;
}
.ad-foot { display: flex; gap: var(--sp-2); justify-content: flex-end; margin-top: var(--sp-4); }
.add-dialog .vault-add-msg { min-height: 1.2em; font-size: .8rem; color: var(--accent-ink); }
.add-dialog .vault-add-msg[data-error] { color: #b8322e; }

@media (max-width: 560px) {
  .fab-add { width: 48px; height: 48px; right: var(--sp-3); bottom: var(--sp-3); }
}

}
