/* ==========================================================================
   TCG Doczel v2 · Componentes
   Depende de tokens.css. Mobile-first (375 px). Sin hex sueltos: solo var().

   Convenciones
   - Nombres BEM: .bloque, .bloque__parte, .bloque--variante
   - Estado con atributos ARIA cuando existen (aria-pressed, aria-current,
     aria-busy, aria-selected, disabled) en vez de clases inventadas.
   - .is-hover / .is-focus / .is-active fuerzan un estado visual; existen solo
     para mostrar estados en la vista previa y en pruebas. No usar en la app.

   Índice
   1. Base           6. Etiquetas (rareza, alza/baja, "Ejemplo")
   2. Íconos         7. Imagen de carta (.card-img) y tarjeta de carta
   3. Botones        8. Bento
   4. Búsqueda       9. Navegación inferior
   5. Chips         10. Efecto holográfico
                    11. Carga (skeleton y spinner)
   ========================================================================== */


/* 1. Base ------------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-family-base);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-base);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent; /* damos nuestro propio feedback al toque */
  text-size-adjust: 100%;
}

img { max-width: 100%; }

/* Contenedor de la app: los componentes responden a SU ancho (container
   queries), no al de la ventana. Así el mismo bento sirve en celular,
   en un panel lateral o dentro de la maqueta de preview.html. */
.app {
  container-type: inline-size;
  container-name: app;
  min-height: 100dvh;
  padding-inline: max(var(--layout-gutter), env(safe-area-inset-left)) max(var(--layout-gutter), env(safe-area-inset-right));
}
.app--with-bottom-nav {
  padding-bottom: calc(var(--bottom-nav-height) + env(safe-area-inset-bottom) + var(--space-6));
}

/* Foco visible y consistente en todo lo que se toca o tabula */
:focus-visible,
.is-focus {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
}

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

.num { font-variant-numeric: tabular-nums; }


/* 2. Íconos (sprite Lucide: <svg class="icon"><use href="#i-search"/></svg>) */

.icon {
  width: var(--icon-size-md);
  height: var(--icon-size-md);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
}
.icon--sm { width: var(--icon-size-sm); height: var(--icon-size-sm); }
.icon--lg { width: var(--icon-size-lg); height: var(--icon-size-lg); }

/* Cuadro de color para íconos que acompañan a un título o acceso */
.icon-badge {
  display: inline-grid;
  place-items: center;
  width: var(--tap-target-min);
  height: var(--tap-target-min);
  flex: none;
  border-radius: var(--radius-sm);
  background: var(--color-surface-muted);
  color: var(--color-primary);
}
/* Naranja decorativo: solo ícono grande en blanco (3.6:1, cumple 3:1 de ícono),
   y solo dentro de un elemento que se puede tocar (ej. el tile "Lotes") */
.icon-badge--action { background: var(--color-action-decorative); color: var(--color-text-on-action); }


/* 3. Botones ----------------------------------------------------------------
   .btn--primary   verde, acción principal de la pantalla
   .btn--action    naranja, acción de compra/guardar que debe destacar
   .btn--secondary borde, acciones de apoyo
   .btn--icon      solo ícono: SIEMPRE con aria-label                       */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-target-min);
  min-width: var(--tap-target-min);
  padding: 0 var(--space-5);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    transform var(--duration-instant) var(--ease-out);
}
/* Feedback al presionar: transform no mueve el layout de alrededor */
.btn:active:not(:disabled, [aria-disabled="true"], [aria-busy="true"]),
.btn.is-active { transform: scale(0.97); }

.btn--primary { background: var(--color-primary-text); color: var(--color-text-on-primary); }
.btn--primary:hover,
.btn--primary.is-hover { background: var(--color-primary-text-hover); }

.btn--action { background: var(--color-action); color: var(--color-text-on-action); }
.btn--action:hover,
.btn--action.is-hover { background: var(--color-action-hover); }

.btn--secondary {
  background: var(--color-surface);
  border-color: var(--color-border-control);
  color: var(--color-primary-text);
}
.btn--secondary:hover,
.btn--secondary.is-hover { background: var(--color-surface-muted); border-color: var(--color-primary-text); }

/* Sin borde: para barras superiores (volver, compartir) */
.btn--ghost { color: var(--color-text); }
.btn--ghost:hover,
.btn--ghost.is-hover { background: var(--color-surface-muted); }

.btn--icon { padding: 0; width: var(--tap-target-min); }
.btn--lg { min-height: 3.25rem; padding-inline: var(--space-6); font-size: var(--font-size-lg); }
.btn--block { display: flex; width: 100%; }

.btn[aria-pressed="true"] { color: var(--color-action); }
.btn[aria-pressed="true"] .icon { fill: currentColor; }

/* Deshabilitado: atributo disabled (o aria-disabled si debe seguir enfocable) */
.btn:disabled,
.btn[aria-disabled="true"] {
  background: var(--color-disabled-bg);
  border-color: transparent;
  color: var(--color-disabled-text);
  cursor: not-allowed;
}

/* Cargando: <button aria-busy="true" disabled> + ícono .icon--spin */
.btn[aria-busy="true"] { cursor: progress; }
.btn--primary[aria-busy="true"] { background: var(--color-primary-text); color: var(--color-text-on-primary); }
.btn--action[aria-busy="true"] { background: var(--color-action); color: var(--color-text-on-action); }
.btn--secondary[aria-busy="true"] { background: var(--color-surface); border-color: var(--color-border-control); color: var(--color-primary-text); }


/* 4. Búsqueda ---------------------------------------------------------------
   <div class="search-field">
     <svg class="icon search-field__icon">…</svg>
     <input class="search-field__input" type="search" role="combobox" …>
     <button class="btn btn--icon btn--ghost search-field__clear" aria-label="Borrar búsqueda">
   </div>
   Sugerencias: <ul class="search-suggestions" role="listbox"> con
   <li class="search-suggestion" role="option" aria-selected>              */

.search-field { position: relative; display: flex; align-items: center; }

.search-field__icon {
  position: absolute;
  left: var(--space-4);
  color: var(--color-text-muted);
  pointer-events: none;
}

.search-field__input {
  width: 100%;
  min-height: 3.25rem;              /* 52px: más grande que el mínimo, es la acción principal */
  padding: 0 var(--space-12) 0 3rem;
  border: var(--border-width) solid var(--color-border-control);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: var(--font-size-md);   /* 16px o más: iOS no hace zoom al enfocar */
  appearance: none;
  transition: border-color var(--duration-fast) var(--ease-out);
}
.search-field__input::placeholder { color: var(--color-text-muted); opacity: 1; }
.search-field__input::-webkit-search-cancel-button { appearance: none; }
.search-field__input:hover,
.search-field__input.is-hover { border-color: var(--color-text-muted); }
.search-field__input:focus-visible,
.search-field__input.is-focus { border-color: var(--color-primary-text); }
.search-field__input:disabled {
  background: var(--color-disabled-bg);
  border-color: var(--color-disabled-bg);
  color: var(--color-disabled-text);
  cursor: not-allowed;
}

.search-field--lg .search-field__input { min-height: 3.5rem; font-size: var(--font-size-lg); }

.search-field__clear { position: absolute; right: var(--space-1); }
.search-field__input:placeholder-shown ~ .search-field__clear { display: none; }

.search-suggestions {
  position: absolute;
  z-index: var(--z-popover);
  top: calc(100% + var(--space-2));
  left: 0;
  right: 0;
  margin: 0;
  padding: var(--space-2);
  list-style: none;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-popover);
}
.search-suggestions--inline { position: static; margin-top: var(--space-2); }

.search-suggestion {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  min-height: 3.25rem;
  padding: var(--space-1) var(--space-2);
  border-radius: calc(var(--radius-sm) - 4px);
  cursor: pointer;
}
.search-suggestion:hover,
.search-suggestion[aria-selected="true"] { background: var(--color-surface-muted); }
.search-suggestion__thumb { width: 2rem; }   /* es un .card-img (§7) */
.search-suggestion__name { font-weight: var(--font-weight-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-suggestion__name mark { background: none; color: inherit; font-weight: var(--font-weight-extrabold); }
.search-suggestion__meta { display: block; font-size: var(--font-size-xs); color: var(--color-text-muted); white-space: normal; }
.search-suggestion__price { font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; }

/* Sin resultados: nunca un "0 resultados" seco, siempre una salida */
.search-empty { padding: var(--space-3); font-size: var(--font-size-sm); color: var(--color-text-muted); }
.search-empty strong { color: var(--color-text); }


/* 5. Chips de filtro ----------------------------------------------------------
   <button class="chip" aria-pressed="false">Holo</button>
   Seleccionado = fondo verde + check (no solo color).                       */

.chip-group { display: flex; flex-wrap: wrap; gap: var(--space-2); }  /* se envuelven, nunca se cortan */

.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 2.5rem;
  padding: 0 var(--space-4);
  border: var(--border-width) solid var(--color-border-control);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  text-decoration: none;   /* también se usa como enlace: <a class="chip"> (sugerencias) */
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
/* El chip mide 40 px pero su área táctil llega a 44 px */
.chip::after { content: ""; position: absolute; inset: -2px 0; }
.chip:hover,
.chip.is-hover { background: var(--color-surface-muted); }
.chip:active { background: var(--color-border); }

.chip .chip__check { display: none; }
.chip[aria-pressed="true"] {
  background: var(--color-primary-text);
  border-color: var(--color-primary-text);
  color: var(--color-text-on-primary);
  padding-left: var(--space-3);
}
.chip[aria-pressed="true"] .chip__check { display: inline; }
.chip[aria-pressed="true"]:hover,
.chip[aria-pressed="true"].is-hover { background: var(--color-primary-text-hover); }

.chip:disabled {
  background: var(--color-disabled-bg);
  border-color: transparent;
  color: var(--color-disabled-text);
  cursor: not-allowed;
}


/* 6. Etiquetas ------------------------------------------------------------- */

/* Rareza: neutro oscuro con texto blanco (15.3:1).
   Las etiquetas informan, no se tocan: por eso NUNCA naranja (el naranja es solo para lo interactivo). */
.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.125rem var(--space-2);
  border-radius: var(--radius-xs);
  background: var(--color-tag-rarity);
  color: var(--color-text-on-tag-rarity);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  line-height: 1.4;
}
.tag--neutral { background: var(--color-surface-muted); color: var(--color-text); }
.tag--primary { background: var(--color-primary-text); color: var(--color-text-on-primary); }

/* Alza / baja: flecha + signo + color. Nunca solo color.
   <span class="trend trend--up"><svg class="icon icon--sm">…</svg>+18,2%<span class="visually-hidden">de alza</span></span>
   El texto del porcentaje sale siempre de TCGFormat.percent() (static/js/format.js).
   Baja solo sobre --color-surface o --color-bg (sobre el fondo atenuado no llega a 4.5:1). */
.trend {
  display: inline-flex;
  align-items: center;
  gap: 0.125rem;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.trend--up { color: var(--color-price-up); }
.trend--down { color: var(--color-price-down); }

/* "Ejemplo": marca cualquier dato que no es real (maquetas, demos, estados vacíos) */
.sample-badge {
  display: inline-flex;
  align-items: center;
  padding: 0 0.375rem;
  border: var(--border-width) dashed var(--color-border-control);
  border-radius: var(--radius-xs);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--letter-spacing-caps);
  text-transform: uppercase;
  line-height: 1.5;
  white-space: nowrap;
}


/* 7. Imagen de carta + tarjeta de carta ------------------------------------------

   .card-img: TODA imagen de carta va dentro de este recuadro (tarjeta, detalle,
   autocompletado, alzas/bajas). El recuadro de reserva (fondo atenuado +
   ícono de carta, proporción 63:88) está siempre debajo de la imagen, así que:
   - mientras carga se ve el recuadro, sin saltos de layout;
   - si la imagen falla, static/js/card-image.js agrega .is-broken: la imagen
     se vuelve transparente pero NO se elimina (su alt sigue leyéndose) y
     queda el mismo recuadro, nunca un hueco ni el ícono roto del navegador;
   - si la carta no tiene imagen, se omite el <img> y se pone
     role="img" + aria-label en el recuadro.

   <span class="card-img">
     <svg class="icon card-img__icon" aria-hidden="true"><use href="#i-rectangle-vertical"/></svg>
     <img class="card-img__img" src="…" alt="Carta Mew ex 152/128">
   </span>                                                                       */

.card-img {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: var(--card-aspect-ratio);
  overflow: hidden;
  border-radius: var(--radius-card-image);
  background: var(--color-image-fallback);
  box-shadow: inset 0 0 0 var(--border-width) var(--color-border);
}
.card-img__icon {
  width: 32%;
  min-width: 0.875rem;
  max-width: 3rem;
  height: auto;
  aspect-ratio: 1;
  color: var(--color-image-fallback-icon);
}
.card-img__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card-img.is-broken .card-img__img { opacity: 0; }


/* Tarjeta de carta (resultados, listas)
   <a class="tcg-card" href="…"> .card-img + nombre + meta + precio          */

.tcg-card-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}
@container app (min-width: 560px) { .tcg-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@container app (min-width: 820px) { .tcg-card-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-4); } }

.tcg-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  padding: var(--space-2) var(--space-2) var(--space-3);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  color: inherit;
  text-decoration: none;
  transition: box-shadow var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
@media (hover: hover) {
  .tcg-card:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); }
}
.tcg-card.is-hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); }
.tcg-card:active { transform: scale(0.98); }

.tcg-card__media { margin-bottom: var(--space-1); }   /* es un .card-img */
.tcg-card__media .tag { position: absolute; left: var(--space-2); bottom: var(--space-2); }

.tcg-card__name {
  margin: 0 var(--space-1);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-snug);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tcg-card__meta { margin: 0 var(--space-1); font-size: var(--font-size-xs); color: var(--color-text-muted); }
.tcg-card__price-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 var(--space-2);
  margin: auto var(--space-1) 0;
  padding-top: var(--space-1);
}
.tcg-card__price {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-extrabold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--letter-spacing-tight);
}

/* Tarjeta para elegir una entre varias (candidatos de "Agregar con cámara")
   <button class="tcg-card tcg-card--elegible" type="button" aria-pressed="false">
     <span class="tcg-card__check"><svg class="icon">…check</svg></span>  .card-img + nombre + meta
   </button>
   Elegida = aria-pressed="true": borde y anillo verdes + el visto en la esquina
   (no solo color). Sin efecto holo: la carta se ve tal como es.             */
.tcg-card--elegible { width: 100%; font: inherit; text-align: left; cursor: pointer; }
.tcg-card--elegible[aria-pressed="true"] {
  border-color: var(--color-primary-text);
  box-shadow: 0 0 0 2px var(--color-primary-text), var(--shadow-card);
}
.tcg-card__check {
  position: absolute;
  z-index: 1;
  top: var(--space-3);
  right: var(--space-3);
  display: none;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-pill);
  background: var(--color-primary-text);
  color: var(--color-text-on-primary);
  box-shadow: 0 0 0 2px var(--color-surface);
}
.tcg-card--elegible[aria-pressed="true"] .tcg-card__check { display: grid; }

/* Fila compacta (alzas/bajas, fuentes de precio) */
.price-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  min-height: 3.5rem;
  padding: var(--space-2) 0;
  color: inherit;
  text-decoration: none;
}
.price-row + .price-row { border-top: var(--border-width) solid var(--color-border); }
a.price-row { outline-offset: 0; }
a.price-row:hover .price-row__title { text-decoration: underline; text-underline-offset: 3px; }
.price-row__thumb { width: 2.5rem; }   /* es un .card-img */
.price-row__title { display: block; font-size: var(--font-size-sm); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); }
.price-row__meta { display: block; font-size: var(--font-size-xs); color: var(--color-text-muted); }
.price-row__end { display: flex; flex-direction: column; align-items: flex-end; gap: 0.125rem; text-align: right; }
.price-row__price { font-weight: var(--font-weight-extrabold); font-variant-numeric: tabular-nums; }


/* 8. Bento -------------------------------------------------------------------
   2 columnas en celular, 4 desde 640 px de contenedor.
   .tile--wide  ocupa todo el ancho     .tile--tall  ocupa 2 filas            */

.bento {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-flow: row dense;
  gap: var(--bento-gap);
}
@container app (min-width: 640px) {
  .bento { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
  .tile--wide-md { grid-column: span 2; }
  .tile--tall-md { grid-row: span 2; }
}

.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
  padding: var(--space-4);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  color: inherit;
  text-decoration: none;
}
.tile--wide { grid-column: 1 / -1; }
.tile--tall { grid-row: span 2; }
.tile--muted { background: var(--color-surface-muted); box-shadow: none; }

a.tile { transition: box-shadow var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out); }
@media (hover: hover) {
  a.tile:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); }
}
a.tile.is-hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); }
a.tile:active { transform: scale(0.98); }

.tile__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.tile__label {
  margin: 0;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--letter-spacing-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.tile__title { margin: 0; font-size: var(--font-size-lg); font-weight: var(--font-weight-extrabold); line-height: var(--line-height-snug); }
.tile__value {
  margin: 0;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-extrabold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--letter-spacing-tight);
  line-height: var(--line-height-tight);
}
.tile__value--xl { font-size: var(--font-size-3xl); }
.tile__text { margin: 0; font-size: var(--font-size-sm); color: var(--color-text-muted); }
.tile__footer { margin-top: auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); }


/* 9. Navegación inferior -------------------------------------------------------
   Máximo 5 destinos de primer nivel, ícono + texto siempre.
   <nav class="bottom-nav" aria-label="Principal"><ul class="bottom-nav__list">
   <li><a class="bottom-nav__link" aria-current="page">                      */

.bottom-nav {
  position: fixed;
  z-index: var(--z-nav);
  left: 0;
  right: 0;
  bottom: 0;
  padding:
    var(--space-1)
    max(var(--space-2), env(safe-area-inset-right))
    calc(var(--space-1) + env(safe-area-inset-bottom))   /* barra de gestos del iPhone */
    max(var(--space-2), env(safe-area-inset-left));
  background: var(--color-surface);
  border-top: var(--border-width) solid var(--color-border);
  box-shadow: var(--shadow-floating);
}
.bottom-nav__list {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  max-width: 32rem;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}
.bottom-nav__link {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.125rem;
  min-height: 3.5rem;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-out);
}
.bottom-nav__indicator {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 2rem;
  border-radius: var(--radius-pill);
  transition: background-color var(--duration-fast) var(--ease-out), transform var(--duration-instant) var(--ease-out);
}
.bottom-nav__link:hover,
.bottom-nav__link.is-hover { color: var(--color-text); }
.bottom-nav__link:active .bottom-nav__indicator { transform: scale(0.92); background: var(--color-surface-muted); }
/* Activo = color + píldora de fondo (dos señales, no solo color) */
.bottom-nav__link[aria-current="page"] { color: var(--color-primary-text); }
.bottom-nav__link[aria-current="page"] .bottom-nav__indicator { background: var(--color-surface-muted); }


/* 10. Efecto holográfico -----------------------------------------------------
   Solo cartas raras y detalle de carta. Lo mueve static/js/holo.js.
   <div class="holo" data-holo>
     <div class="holo__card card-img">           ← también es un .card-img (§7)
       <svg class="icon card-img__icon" …><use href="#i-rectangle-vertical"/></svg>
       <img class="card-img__img" …>
       <span class="holo__shine" aria-hidden="true"></span>
       <span class="holo__glare" aria-hidden="true"></span>
     </div>
   </div>
   Rendimiento: el JS solo escribe transform y opacity, dentro de
   requestAnimationFrame. Con prefers-reduced-motion queda estático.
   Si la imagen no carga, el brillo se apaga: queda el recuadro de reserva limpio. */

.holo {
  position: relative;
  perspective: var(--holo-perspective);
  touch-action: pan-y;              /* arrastre horizontal inclina, vertical hace scroll */
  -webkit-user-select: none;
  user-select: none;
}

.holo__card {
  /* forma, proporción y recuadro de reserva vienen de .card-img */
  box-shadow: inset 0 0 0 var(--border-width) var(--color-border), 0 18px 30px -18px rgb(15 42 31 / 0.55);
  isolation: isolate;               /* el mix-blend-mode solo afecta a la carta */
  transform: rotateX(0deg) rotateY(0deg);
  transition: transform var(--duration-slow) var(--ease-out);
  will-change: transform;
}
.holo.is-tracking .holo__card { transition: none; } /* mientras sigue al puntero, manda el rAF */

.card-img.is-broken .holo__shine,
.card-img.is-broken .holo__glare { display: none; }

/* Brillo tornasol: aquí sí se permiten azul y morado (solo dentro del holo) */
.holo__shine,
.holo__glare {
  position: absolute;
  inset: -50%;                      /* capa más grande que la carta: se desplaza con transform, sin repintar el gradiente */
  pointer-events: none;
}
/* Dos capas que se componen sin pisarse:
   .holo__shine   la mueve el JS según el puntero/giroscopio (transform inline)
   ::before       deriva lenta en CSS mientras la carta está a la vista      */
.holo__shine {
  mix-blend-mode: color-dodge;
  opacity: var(--holo-shine-opacity);
}
.holo__shine::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    115deg,
    hsl(340 95% 72%) 0%,
    hsl(42 100% 64%) 5%,
    hsl(150 85% 60%) 10%,
    hsl(190 95% 62%) 15%,
    hsl(265 90% 74%) 20%,
    hsl(340 95% 72%) 25%
  );
  transform: translate3d(-4%, -4%, 0);
}
.holo__glare {
  background: radial-gradient(circle at 50% 50%, rgb(255 255 255 / 0.9) 0%, rgb(255 255 255 / 0) 30%);
  mix-blend-mode: soft-light;
  opacity: 0;
}

@keyframes holo-drift {
  from { transform: translate3d(-12%, -8%, 0); }
  to   { transform: translate3d(12%, 8%, 0); }
}
.holo.is-visible .holo__shine::before { animation: holo-drift 6s var(--ease-in-out) infinite alternate; }

/* Botón para pedir permiso del giroscopio (iPhone). holo.js lo muestra solo si hace falta. */
.holo-motion { display: none; }
.holo-motion.is-needed { display: inline-flex; }

@media (prefers-reduced-motion: reduce) {
  .holo__card { transform: none !important; transition: none; }
  .holo__shine { transform: none !important; }
  .holo__shine::before { animation: none !important; }
  .holo__glare { opacity: 0 !important; }
  .holo-motion { display: none !important; }
}


/* 11. Carga ---------------------------------------------------------------------- */

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 50% { opacity: 0.4; } }
@keyframes shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

.icon--spin { animation: spin 0.9s linear infinite; }

/* Bloque de reserva mientras carga: mismo tamaño que el contenido final */
.skeleton {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xs);
  background: var(--color-skeleton);
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--color-skeleton-shine), transparent);
  animation: shimmer 1.4s var(--ease-in-out) infinite;
}
.skeleton--text { height: 0.875rem; }
.skeleton--price { height: 1.25rem; width: 60%; }

@media (prefers-reduced-motion: reduce) {
  .icon--spin { animation: pulse 1.6s ease-in-out infinite; } /* sigue indicando "cargando", sin girar */
  .skeleton::after { animation: none; }
}
