/* QuestKeep · tarjetas, hero, tablero, insignias y modal */

/* ==========================================================================
   Insignias de plataforma
   Cada familia lleva su color de marca para que el ojo la reconozca al vuelo.
   ========================================================================== */

.plats { display: flex; flex-wrap: wrap; gap: 5px; }

.plat {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding: 3px 7px;
  border-radius: 5px;
  border: 1px solid currentColor;
  background: rgba(0, 0, 0, 0.34);
  white-space: nowrap;
  line-height: 1.35;
}
.plat[data-fam="playstation"] { color: #8fb6d9; }
.plat[data-fam="xbox"]        { color: #8fd98f; }
.plat[data-fam="nintendo"]    { color: #e08a8a; }
.plat[data-fam="pc"]          { color: #a9bba4; }
.plat[data-fam="mobile"]      { color: #d9c07a; }
.plat[data-fam="vr"]          { color: #b9a6d9; }

/* ==========================================================================
   Hero destacado — el proximo lanzamiento
   ========================================================================== */

/* Las diapositivas se apilan en la misma celda de una rejilla de 1x1, de modo
   que el carrusel adopta la altura de la mas alta y el cruce entre ellas es un
   fundido limpio sin saltos de maquetacion. */
.hero-rail {
  position: relative;
  display: grid;
  grid-template-areas: "slide";
  isolation: isolate;
}
.hero-rail > .hero-slide { grid-area: slide; }

.hero-slide {
  opacity: 0;
  visibility: hidden;
  transform: scale(0.995);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out),
              visibility 0s linear var(--dur-slow);
}
.hero-slide[data-active="true"] {
  opacity: 1;
  visibility: visible;
  transform: scale(1);
  transition-delay: 0s;
  z-index: 1;
}

.hero-dots {
  position: absolute;
  z-index: 3;
  right: clamp(16px, 3vw, 30px);
  bottom: clamp(16px, 3vw, 26px);
  display: flex;
  gap: 7px;
}
.hero-dots button {
  appearance: none;
  width: 26px; height: 4px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.28);
  cursor: pointer;
  transition: background var(--dur) var(--ease-out), width var(--dur) var(--ease-spring);
}
.hero-dots button:hover { background: rgba(255, 255, 255, 0.5); }
.hero-dots button[aria-current="true"] {
  width: 40px;
  background: var(--accent);
  box-shadow: var(--glow);
}

.hero {
  position: relative;
  min-height: clamp(340px, 52vh, 520px);
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-float);
  isolation: isolate;
  display: flex;
  align-items: flex-end;
}

/* La capa de arte se escala un poco de mas para que el paralaje del raton
   nunca deje ver el borde del fondo. */
.hero-art {
  position: absolute;
  inset: -4%;
  z-index: -2;
  background-size: cover;
  background-position: center 32%;
  transform: scale(1.04);
  transition: transform 1.1s var(--ease-out);
  will-change: transform;
}
.hero:hover .hero-art { transform: scale(1.08); }

.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(90deg, rgba(3, 6, 3, 0.94) 0%, rgba(3, 6, 3, 0.72) 38%, transparent 72%),
    linear-gradient(0deg, rgba(3, 6, 3, 0.96) 2%, transparent 58%);
}

.hero-body {
  position: relative;
  padding: clamp(22px, 4vw, 48px);
  max-width: min(680px, 92%);
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(123, 232, 39, 0.34);
  background: rgba(123, 232, 39, 0.09);
}
.hero-eyebrow::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: var(--glow);
  animation: pulse 2.1s var(--ease-in-out) infinite;
}

/* El logo oficial del juego cuando existe; si no, el titulo en grande. */
.hero-logo {
  max-width: min(430px, 78%);
  max-height: 132px;
  object-fit: contain;
  object-position: left bottom;
  filter: drop-shadow(0 4px 22px rgba(0, 0, 0, 0.85));
}
.hero-title {
  margin: 0;
  font-size: clamp(30px, 4.6vw, 56px);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.025em;
  color: var(--text-bright);
  text-shadow: 0 3px 26px rgba(0, 0, 0, 0.85);
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap);
  color: var(--text);
  font-size: 14px;
}
.hero-date { font-weight: 600; color: var(--text-bright); }
.hero-studio { color: var(--text-muted); font-size: 13px; }

.hero-actions { display: flex; flex-wrap: wrap; gap: var(--gap-sm); }

/* Cuenta atras: cifras monoespaciadas para que no bailen al cambiar. */
.countdown {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
}
.countdown .n {
  font-family: var(--font-mono);
  font-size: 21px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  text-shadow: var(--glow);
  line-height: 1;
}
.countdown .u {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.countdown[data-soon="true"] .n { color: var(--accent-hot); text-shadow: var(--glow-hot); }
.countdown[data-out="true"] .n { color: var(--accent-bright); text-shadow: var(--glow-bright); }

/* ==========================================================================
   Botones
   ========================================================================== */

.btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 11px 20px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: var(--bg-glass-strong);
  color: var(--text-bright);
  cursor: pointer;
  white-space: nowrap;
  transition: transform var(--dur) var(--ease-spring),
              box-shadow var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.btn:hover { transform: translateY(-2px); background: rgba(255, 255, 255, 0.12); }
.btn:active { transform: translateY(0) scale(0.97); }
.btn svg { width: 16px; height: 16px; }

.btn-primary {
  border-color: transparent;
  background: linear-gradient(100deg, var(--accent), #a6f24e);
  color: #05120a;
  box-shadow: var(--glow);
}
.btn-primary:hover { background: linear-gradient(100deg, #96f03a, #bff77a); }

.btn-ghost { background: rgba(0, 0, 0, 0.4); }

/* Estado "ya esta en el backlog": el boton se apaga y confirma. */
.btn[data-added="true"] {
  background: var(--accent-bright-dim);
  border-color: rgba(217, 255, 74, 0.45);
  color: var(--accent-bright);
  box-shadow: none;
}

/* ==========================================================================
   Tarjeta de juego (rejilla de Proximos y de Buscar)
   ========================================================================== */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: var(--gap);
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  cursor: pointer;
  transition: transform var(--dur) var(--ease-spring),
              box-shadow var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
  /* Se salta el pintado de las tarjetas fuera de pantalla. El alto va con
     `auto`, asi que tras la primera vuelta usa el real y no da saltos. */
  content-visibility: auto;
  contain-intrinsic-size: auto 340px;
}
.card:hover {
  transform: translateY(-6px);
  border-color: rgba(123, 232, 39, 0.4);
  box-shadow: var(--shadow-card), 0 0 0 1px rgba(123, 232, 39, 0.18),
              0 12px 40px rgba(123, 232, 39, 0.16);
}

.card-art {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--bg-deep);
}
.card-art img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.card-art img.loaded { opacity: 1; }
.card:hover .card-art img { transform: scale(1.06); }

/* Barrido de luz que cruza la caratula al pasar el raton. */
.card-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 38%,
              rgba(255, 255, 255, 0.16) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: transform 620ms var(--ease-out);
  pointer-events: none;
}
.card:hover .card-art::after { transform: translateX(120%); }

.card-body {
  padding: 10px 11px 12px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  flex: 1;
}
.card-title {
  margin: 0;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.28;
  color: var(--text-bright);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-date {
  font-size: 11.5px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  margin-top: auto;
}

/* Pastilla de dias restantes, arriba a la izquierda del arte. */
.card-days {
  position: absolute;
  top: 8px; left: 8px;
  z-index: 2;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  background: rgba(3, 6, 3, 0.92);
  border: 1px solid rgba(123, 232, 39, 0.36);
  color: var(--accent);
}
.card-days[data-soon="true"] {
  border-color: rgba(255, 61, 61, 0.5);
  color: var(--accent-hot);
}
.card-days[data-out="true"] {
  border-color: rgba(255, 255, 255, 0.16);
  color: var(--text-faint);
}

/* Marca de estado cuando el juego ya esta en el backlog. */
/* La nota y la medalla van juntas arriba a la derecha. Antes cada una se
   posicionaba en `top: 8px; right: 8px` por su cuenta y la medalla tapaba la
   nota; ahora las coloca este contenedor y basta con ocultar una para que la
   otra recupere la esquina. */
.card-marcas {
  position: absolute;
  top: 8px; right: 8px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 6px;
}

.card-flag {
  width: 22px; height: 22px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(3, 6, 3, 0.93);
  border: 1px solid currentColor;
}
.card-flag svg { width: 12px; height: 12px; }
.card-flag[data-status="backlog"]   { color: var(--status-backlog); }
.card-flag[data-status="playing"]   { color: var(--status-playing); }
.card-flag[data-status="completed"] { color: var(--status-completed); }

/* El boton de añadir asoma desde abajo al pasar el raton. */
.card-add {
  position: absolute;
  left: 8px; right: 8px; bottom: 8px;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px;
  border: 0;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  background: rgba(123, 232, 39, 0.93);
  color: #05120a;
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-spring);
}
.card:hover .card-add,
.card:focus-within .card-add { opacity: 1; transform: translateY(0); }
.card-add:hover { background: var(--accent); }
.card-add svg { width: 13px; height: 13px; }

/* Arte generado cuando no hay imagen: degradado determinista mas el titulo. */
.card-art[data-generated="true"],
.hero-art[data-generated="true"] { background-size: cover; }
.art-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 14px;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.3;
  color: rgba(255, 255, 255, 0.9);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6);
}

/* ==========================================================================
   Tablero del backlog
   ========================================================================== */

.board {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
  align-items: start;
}

.column {
  display: flex;
  flex-direction: column;
  min-height: 260px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.022);
  transition: border-color var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}

/* Al arrastrar por encima, la columna se ilumina con su propio color. */
.column[data-over="true"] {
  border-color: var(--col-accent);
  background: color-mix(in srgb, var(--col-accent) 9%, transparent);
  box-shadow: 0 0 0 1px var(--col-accent), 0 0 34px -6px var(--col-accent);
}
.column[data-status="backlog"]   { --col-accent: var(--status-backlog); }
.column[data-status="playing"]   { --col-accent: var(--status-playing); }
.column[data-status="completed"] { --col-accent: var(--status-completed); }

.column-head {
  display: flex;
  align-items: center;
  gap: var(--gap-sm);
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.column-head .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--col-accent);
  box-shadow: 0 0 12px var(--col-accent);
  flex-shrink: 0;
}
.column-head h3 {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  /* El titulo toma el color de su columna: el punto solo es una pista muy
     pequeña para diferenciar tres estados de un vistazo. */
  color: var(--col-accent);
}
.column-head .n {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--bg-glass);
}

.column-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  min-height: 120px;
}

.column-empty {
  display: grid;
  place-items: center;
  gap: 4px;
  padding: 26px 14px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--text-faint);
  font-size: 12.5px;
  text-align: center;
  line-height: 1.5;
}

/* --- Ficha compacta dentro de una columna --- */

.chip {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-raised);
  cursor: grab;
  touch-action: none;
  user-select: none;
  transition: transform var(--dur) var(--ease-spring),
              border-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.chip:hover {
  border-color: var(--col-accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--col-accent) 40%, transparent);
  transform: translateX(3px);
}
.chip:active { cursor: grabbing; }

/* Mientras se arrastra, el original se queda como hueco tenue y el clon
   flotante (.chip-ghost) es el que sigue al puntero. */
.chip[data-dragging="true"] { opacity: 0.26; filter: grayscale(0.6); }

.chip-ghost {
  position: fixed;
  z-index: 900;
  pointer-events: none;
  margin: 0;
  box-shadow: var(--shadow-float), 0 0 30px -4px var(--col-accent);
  border-color: var(--col-accent);
  cursor: grabbing;
  will-change: transform;
}

.chip-art {
  width: 40px; height: 54px;
  flex-shrink: 0;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-deep);
  position: relative;
}
.chip-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

.chip-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.chip-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-bright);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chip-meta {
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.chip-move {
  display: flex;
  gap: 3px;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}
.chip:hover .chip-move, .chip:focus-within .chip-move { opacity: 1; }
.chip-move button {
  appearance: none;
  width: 26px; height: 26px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--bg-glass);
  color: var(--text-muted);
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease-out);
}
.chip-move button:hover { color: var(--text-bright); border-color: var(--line-strong); }
.chip-move button svg { width: 13px; height: 13px; }

/* --- Barra de finalizacion y medalla --------------------------------- */

.fill-bar {
  position: fixed;
  z-index: 930;
  height: 5px;
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, 0.66);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12), 0 4px 14px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  pointer-events: none;
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
}
.fill-bar span {
  display: block;
  height: 100%;
  width: 100%;
  /* Se escala en X en vez de animar `width`: el escalado va en la GPU y no
     obliga al navegador a recalcular la maquetacion en cada fotograma. */
  transform: scaleX(0);
  transform-origin: left center;
  border-radius: inherit;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--fill-color) 55%, transparent), var(--fill-color));
  box-shadow: 0 0 14px var(--fill-color);
}
/* Al tocar el tope: un fogonazo y la barra se va. */
.fill-bar.done {
  opacity: 0;
  transform: scaleY(2.4);
  box-shadow: 0 0 0 1px var(--fill-color), 0 0 30px 2px var(--fill-color);
}

/* La marca que queda en el juego terminado. Va montada sobre la esquina
   inferior derecha de la caratula, medio dentro y medio fuera, para que se lea
   como algo aplicado encima y no como parte de la imagen.

   Cuelga de la ficha y no de `.chip-art` porque esa recorta su contenido
   (`overflow: hidden`) para redondear la imagen, y se comeria media medalla.
   De ahi que la posicion se derive del hueco del arte: 8px de relleno mas sus
   40x54, menos medio disco. */
.chip-medal {
  position: absolute;
  left: calc(8px + 40px - 15px);
  top: calc(8px + 54px - 16px);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #fbffd6, var(--status-completed) 62%, #9aa81f);
  color: #1d2405;
  box-shadow: 0 0 0 2px var(--bg-raised), 0 0 12px -1px var(--status-completed);
}
.chip-medal svg { width: 12px; height: 12px; }

/* Estampado: entra grande y torcida, y se asienta. */
.chip-medal.stamping { animation: stamp 460ms var(--ease-pop) backwards; }

/* Los completados llevan un barrido platino permanente. */
.chip[data-status="completed"] .chip-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 40%,
              rgba(255, 255, 255, 0.5) 50%, transparent 60%);
  transform: translateX(-100%);
  animation: sweep 3.6s var(--ease-in-out) infinite;
}

/* Mientras hay un arrastre en curso no se selecciona nada en toda la pagina:
   al mover la ficha hacia abajo, el navegador iba seleccionando el texto de
   todo lo que quedaba por el camino y dejaba un sombreado siguiendo al puntero.
   La clase la pone y la quita `js/ui/dnd.js`. */
body.arrastrando,
body.arrastrando * {
  user-select: none;
  -webkit-user-select: none;
}
/* El cursor de agarre manda sobre cualquier otro mientras dura el gesto. */
body.arrastrando { cursor: grabbing; }

/* Marcador de posicion donde caeria la ficha al soltar. */
.drop-slot {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--col-accent);
  box-shadow: 0 0 14px var(--col-accent);
  animation: slot-in 180ms var(--ease-out);
}

/* ==========================================================================
   Modal de detalle
   ========================================================================== */

.modal-back {
  position: fixed;
  inset: 0;
  z-index: 800;
  display: grid;
  place-items: center;
  padding: var(--gap);
  background: rgba(2, 5, 2, 0.76);
  backdrop-filter: blur(10px);
  animation: fade-in var(--dur) var(--ease-out);
}
/* El modal es una columna: arte, cuerpo que hace scroll y pie fijo. Antes hacia
   scroll el modal entero, y por eso los botones se iban con el contenido. */
.modal {
  position: relative;
  width: min(780px, 100%);
  max-height: min(88vh, 760px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line-strong);
  background: var(--bg-base);
  box-shadow: var(--shadow-float);
  animation: modal-in var(--dur-slow) var(--ease-pop);
}
.modal-art {
  position: relative;
  flex: 0 0 auto;
  height: 230px;
  background-size: cover;
  background-position: center 30%;
}
.modal-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, var(--bg-base) 3%, transparent 78%);
}
.modal-logo {
  position: absolute;
  left: 26px; bottom: 18px;
  z-index: 2;
  max-width: 300px;
  max-height: 88px;
  object-fit: contain;
  object-position: left bottom;
  filter: drop-shadow(0 3px 16px rgba(0, 0, 0, 0.85));
}
/* --- Trailer ---------------------------------------------------------- */

/* El boton vive en la esquina inferior derecha del arte, justo donde el
   degradado ya oscurece la imagen, asi que se lee sin necesitar un fondo
   opaco que tape la ilustracion. */
.trailer-btn {
  position: absolute;
  right: 16px;
  bottom: 16px;
  /* Por encima del reproductor (z-index 4), o al abrirse el video taparia el
     propio boton que sirve para cerrarlo. */
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px 9px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(6, 13, 6, 0.62);
  backdrop-filter: blur(10px) saturate(140%);
  color: var(--text-bright);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--dur) var(--ease-spring),
              border-color var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.trailer-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: rgba(255, 61, 61, 0.65);
  background: rgba(255, 61, 61, 0.16);
  box-shadow: var(--glow-hot);
}
.trailer-btn:disabled { opacity: 0.5; cursor: default; }

/* Con el video abierto, la esquina inferior derecha la ocupan los controles de
   YouTube, asi que el boton se aparta arriba a la izquierda: lejos de ellos y
   lejos tambien de la X de cerrar el modal, que esta arriba a la derecha. */
.modal-art[data-playing="true"] .trailer-btn {
  top: 14px;
  left: 14px;
  right: auto;
  bottom: auto;
}

/* Disco de play, con un halo que late para invitar a pulsarlo. */
.trailer-btn .disc {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent-hot);
  color: #fff;
  box-shadow: 0 0 14px rgba(255, 61, 61, 0.7);
  flex-shrink: 0;
}
.trailer-btn .disc svg { width: 11px; height: 11px; margin-left: 1px; }

.trailer-btn[data-loading="true"] .disc {
  background: transparent;
  border: 2px solid rgba(255, 255, 255, 0.25);
  border-top-color: var(--accent-hot);
  box-shadow: none;
  animation: spin 720ms linear infinite;
}
.trailer-btn[data-loading="true"] .disc svg { display: none; }

/* El reproductor sustituye al arte en su sitio: el marco crece hasta 16:9 y
   el video aparece dentro, en vez de abrirse una ventana nueva encima. */
.modal-art { transition: height var(--dur-slow) var(--ease-out); }

.trailer-frame {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  border: 0;
  opacity: 0;
  background: #000;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.trailer-frame.ready { opacity: 1; }

.modal-art[data-playing="true"]::after { opacity: 0; }
.modal-art[data-playing="true"] .modal-logo { opacity: 0; }
.modal-logo { transition: opacity var(--dur) var(--ease-out); }

/* Lo unico que hace scroll. `min-height: 0` es imprescindible: sin el, un hijo
   flexible no encoge por debajo de su contenido y el pie se sale del modal. */
.modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--gap-md);
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}
.modal-body h2 {
  margin: 0;
  font-size: 25px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-bright);
  line-height: 1.15;
}
.modal-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--gap);
  padding: var(--gap) 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.fact .k {
  font-size: 10.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 5px;
}
.fact .v { font-size: 14px; color: var(--text-bright); font-weight: 500; line-height: 1.4; }
/* El pie con las acciones, siempre a la vista. Lleva su propio fondo y un
   borde superior para que se lea como una capa distinta del contenido que pasa
   por debajo al hacer scroll. */
.modal-pie {
  flex: 0 0 auto;
  padding: var(--gap-sm) var(--gap-md);
  background: var(--bg-raised);
  border-top: 1px solid var(--line);
}
.modal-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-sm); }

/* "Me gusta" y "Recomendar" van sin etiqueta: con ella los cinco botones no
   caben en una fila y el pie ocuparia el doble. */
.btn-icono {
  padding: 9px 12px;
  flex: 0 0 auto;
}
.btn-icono svg { display: block; }
/* Los secundarios, en bloque y al extremo opuesto de los botones de estado. */
.modal-secundarios {
  display: flex;
  align-items: center;
  gap: var(--gap-sm);
  margin-left: auto;
}

/* En un movil los tres botones de estado se reparten la fila a partes iguales
   y los secundarios caen debajo: dos filas en vez de tres, y las etiquetas se
   siguen leyendo enteras. */
@media (max-width: 560px) {
  .modal-actions { gap: 7px; }
  .modal-pie { padding-inline: var(--gap); }

  /* Los tres estados se reparten la fila, pero con un ancho minimo que no deja
     que se aplasten: es lo que empuja a los iconos a la fila de abajo. Sin ese
     minimo caben los seis en una linea y las etiquetas se pisan. */
  /* 86 px y no mas: con 94 los tres sumaban 296 y el ancho util del pie en un
     movil de 375 son 293. Se quedaba a tres pixeles de caber y el tercero se
     iba a otra fila. */
  .modal-actions .btn:not(.btn-icono) {
    flex: 1 1 0;
    min-width: 86px;
    padding: 9px 6px;
    font-size: 12.5px;
    justify-content: center;
  }
  /* Sin icono dentro: a este ancho, el simbolo le roba sitio a la palabra. */
  .modal-actions .btn:not(.btn-icono) svg { display: none; }

  /* El grupo ocupa su propia fila: los tres estados arriba, los iconos debajo.
     Es un reparto fijo y no lo que decida el algoritmo de envoltura. */
  .modal-secundarios { margin-left: 0; flex: 1 0 100%; justify-content: flex-end; }
  .btn-icono { flex: 0 0 auto; padding: 9px 18px; }
}
.modal-close {
  position: absolute;
  top: 12px; right: 12px;
  z-index: 3;
  width: 32px; height: 32px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(3, 6, 3, 0.7);
  backdrop-filter: blur(6px);
  color: var(--text);
  cursor: pointer;
  transition: all var(--dur) var(--ease-out);
}
.modal-close:hover { background: var(--accent-hot); color: #fff; border-color: transparent; }

/* ==========================================================================
   Avisos y notificaciones
   ========================================================================== */

.notice {
  display: flex;
  align-items: center;
  gap: var(--gap-sm);
  padding: 11px 16px;
  margin-bottom: var(--gap);
  border-radius: var(--radius);
  border: 1px solid rgba(232, 179, 58, 0.34);
  background: rgba(232, 179, 58, 0.08);
  color: #e8dcaa;
  font-size: 13px;
}
.notice code {
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.4);
}
.notice button {
  margin-left: auto;
  appearance: none;
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  cursor: pointer;
  font-size: 17px;
  line-height: 1;
  padding: 2px 4px;
}
.notice button:hover { opacity: 1; }

/* --- Volver arriba ---------------------------------------------------- */

.to-top {
  position: fixed;
  right: max(var(--gap-md), env(safe-area-inset-right));
  bottom: max(var(--gap-md), env(safe-area-inset-bottom));
  z-index: 700;                 /* sobre el contenido, bajo el modal (800) */
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(9, 16, 9, 0.82);
  backdrop-filter: blur(12px) saturate(140%);
  color: var(--text);
  cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: opacity var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-spring),
              color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.to-top svg { width: 19px; height: 19px; }

.to-top:hover {
  color: var(--accent);
  border-color: rgba(123, 232, 39, 0.55);
  box-shadow: var(--shadow-card), var(--glow);
  transform: translateY(-3px);
}
.to-top:active { transform: translateY(0) scale(0.94); }

/* Entra y sale desplazandose: el JS solo alterna `data-visible`, y quita el
   atributo `hidden` para que la transicion tenga algo que animar. */
.to-top {
  opacity: 0;
  transform: translateY(14px) scale(0.85);
  pointer-events: none;
}
.to-top[data-visible="true"] {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.toast-stack {
  position: fixed;
  bottom: var(--gap-md);
  left: 50%;
  z-index: 950;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 18px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: rgba(9, 19, 9, 0.95);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-float);
  color: var(--text-bright);
  font-size: 13.5px;
  font-weight: 500;
  pointer-events: auto;
  animation: toast-in var(--dur-slow) var(--ease-pop);
}
.toast .swatch {
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
.toast button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 0 0 0 6px;
}
.toast button:hover { text-decoration: underline; }
.toast[data-leaving="true"] { animation: toast-out var(--dur) var(--ease-in-out) forwards; }

/* Lienzo de particulas: cubre la pagina y nunca intercepta el raton. */
#fx-canvas {
  position: fixed;
  inset: 0;
  z-index: 940;
  pointer-events: none;
}

@media (max-width: 900px) {
  .board { grid-template-columns: 1fr; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .hero { min-height: 380px; }
}

/* En pantallas tactiles no existe :hover, asi que los controles que solo
   aparecian al pasar el raton quedarian inalcanzables: sin esto no se puede
   ni añadir un juego ni moverlo de columna desde el movil.

   Va en este archivo, y no en base.css, porque tiene que ganar a las reglas de
   los componentes de mas arriba: misma especificidad, decide el orden. */
@media (hover: none) {
  .card-add {
    opacity: 1;
    transform: none;
    padding: 10px;            /* area de toque comoda */
  }
  .chip-move { opacity: 1; }
  .chip-move button { width: 34px; height: 34px; }

  /* El tablero apila las columnas en vertical, asi que arrastrar una ficha
     chocaria con el gesto de desplazar la pagina. Se cede el eje vertical al
     scroll y los movimientos se hacen con las flechas. */
  /* En tactil la ficha no se arrastra en vertical, se toca para abrirla: el
     cursor de agarre sobra y conviene que se lea como algo pulsable. */
  .chip { touch-action: pan-y; cursor: pointer; }
}

/* ==========================================================================
   Mi inventario (perfil)
   ========================================================================== */

.perfil {
  display: flex;
  align-items: center;
  gap: clamp(var(--gap), 4vw, var(--gap-lg));
  padding: clamp(var(--gap), 3vw, var(--gap-md));
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background:
    radial-gradient(120% 140% at 12% 20%, rgba(123, 232, 39, 0.10), transparent 62%),
    var(--bg-glass);
  box-shadow: var(--shadow-card);
}

.perfil-figura {
  flex: 0 0 auto;
  width: clamp(110px, 18vw, 168px);
  filter: drop-shadow(0 6px 22px rgba(123, 232, 39, 0.22));
}
.mochila { display: block; width: 100%; height: auto; }

/* La mochila entra creciendo desde su base, que es donde se apoya. El escalado
   por tamaño lo pone el JS en el propio `transform`, asi que la animacion solo
   puede tocar la opacidad y dejar que el transform lo mande el estilo en linea. */
.mochila-cuerpo { animation: carga-in 620ms var(--ease-out) backwards; }

.perfil-datos { flex: 1; min-width: 0; }

.perfil-rango {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 4px 11px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(123, 232, 39, 0.34);
  background: rgba(123, 232, 39, 0.09);
}

.perfil-nivel {
  margin: 10px 0 2px;
  font-size: clamp(22px, 3.4vw, 32px);
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: -0.01em;
}
.perfil-nivel strong {
  color: var(--text-bright);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.perfil-lema { margin: 0 0 var(--gap); font-size: 13.5px; color: var(--text-muted); }

.perfil-barra {
  height: 8px;
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, 0.45);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
}
.perfil-barra span {
  display: block;
  height: 100%;
  transform-origin: left center;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent));
  box-shadow: 0 0 14px rgba(123, 232, 39, 0.5);
  /* Se anima el llenado al entrar en la vista, no un salto seco. */
  animation: barra-nivel 900ms var(--ease-out) backwards;
}

.perfil-pie {
  margin: 9px 0 0;
  font-size: 12px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

/* --- Números --- */

.datos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: var(--gap-sm);
}
.dato {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-glass);
  font: inherit;
  text-align: left;
  color: inherit;
  transition: border-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-spring);
}
.dato:hover { border-color: rgba(123, 232, 39, 0.34); transform: translateY(-2px); }

/* Las que se pueden abrir lo anuncian con un cheurón que gira al desplegarse.
   Sin esa pista no habria forma de saber cuales esconden algo. */
.dato[data-abrible] { cursor: pointer; position: relative; }
.dato[data-abrible]::after {
  content: "";
  position: absolute;
  top: 17px; right: 15px;
  width: 7px; height: 7px;
  border-right: 2px solid var(--text-faint);
  border-bottom: 2px solid var(--text-faint);
  transform: rotate(45deg);
  transition: transform var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
.dato[data-abrible]:hover::after { border-color: var(--accent); }
.dato[aria-expanded="true"]::after { transform: rotate(-135deg); border-color: var(--accent); }

/* Al abrirse, la tarjeta ocupa toda la fila: una lista de juegos no cabe en
   una columna estrecha y quedaria en un churro de dos palabras por linea. */
.dato[aria-expanded="true"] {
  grid-column: 1 / -1;
  border-color: rgba(123, 232, 39, 0.4);
  transform: none;
}

.dato-lista {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 2px var(--gap);
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--line);
  max-height: 320px;
  overflow-y: auto;
  animation: fade-in var(--dur) var(--ease-out);
}
.dato-fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap-sm);
  padding: 4px 0;
  font-size: 12.5px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.dato-fila em {
  font-style: normal;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dato-fila b {
  font-weight: 500;
  font-size: 11.5px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.dato-nada {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--text-faint);
  padding: 4px 0;
}
.dato-v {
  font-size: 26px;
  font-weight: 700;
  line-height: 1.05;
  color: var(--text-bright);
  font-variant-numeric: tabular-nums;
}
.dato-k { font-size: 12px; color: var(--text-muted); line-height: 1.35; }
.dato-d { font-size: 11px; color: var(--text-faint); margin-top: 2px; }

/* --- Medallas --- */

.medallas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
  gap: var(--gap-sm);
}

.medalla {
  position: relative;
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px 15px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-glass);
  overflow: hidden;
}

/* Las pendientes enseñan su avance como una franja de fondo: se ve cuanto
   falta sin necesidad de una barra aparte. */
.medalla[data-lograda="false"]::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: calc(var(--avance, 0) * 100%);
  background: rgba(123, 232, 39, 0.07);
  pointer-events: none;
}

.medalla-disco {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(0, 0, 0, 0.35);
  color: var(--text-faint);
}
.medalla[data-lograda="true"] {
  border-color: rgba(232, 255, 58, 0.4);
  background: rgba(232, 255, 58, 0.06);
}
.medalla[data-lograda="true"] .medalla-disco {
  border-color: transparent;
  color: #1d2405;
  background: radial-gradient(circle at 34% 30%, #fbffd6,
              var(--status-completed) 62%, #9aa81f);
  box-shadow: 0 0 14px -1px var(--status-completed);
}

.medalla-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.medalla-n { font-size: 13.5px; font-weight: 600; color: var(--text-bright); }
.medalla-d { font-size: 11.5px; color: var(--text-muted); line-height: 1.35; }
.medalla-p {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.medalla[data-lograda="true"] .medalla-p { color: var(--status-completed); font-size: 15px; }

/* --- Últimos terminados --- */

.hitos { display: flex; flex-direction: column; gap: 2px; }

.hito {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  transition: background var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.hito.clicable { cursor: pointer; }
.hito.clicable:hover {
  background: var(--bg-glass);
  border-color: var(--line);
}
.hito-punto {
  width: 9px; height: 9px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--status-completed);
  box-shadow: 0 0 10px var(--status-completed);
}
.hito-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hito-n {
  font-size: 13.5px; font-weight: 600; color: var(--text-bright);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hito-d { font-size: 11.5px; color: var(--text-faint); }

@media (max-width: 620px) {
  .perfil { flex-direction: column; align-items: flex-start; text-align: left; }
  .perfil-figura { width: 128px; align-self: center; }
}

/* ==========================================================================
   Selector de plataforma
   ========================================================================== */

.picker {
  width: min(420px, 100%);
  padding: var(--gap-md);
  border-radius: var(--radius-lg);
  border: 1px solid var(--line-strong);
  background: var(--bg-base);
  box-shadow: var(--shadow-float);
  animation: modal-in var(--dur-slow) var(--ease-pop);
}

.picker-titulo {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-bright);
}
.picker-sub {
  margin: 4px 0 var(--gap-md);
  font-size: 13.5px;
  color: var(--text-muted);
}

.picker-ops {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: var(--gap-sm);
}

/* Cada opcion lleva el color de su familia, el mismo que las insignias del
   resto de la app, para que se reconozca sin leer. */
.picker-op {
  appearance: none;
  padding: 14px 10px;
  border-radius: var(--radius);
  border: 1px solid currentColor;
  background: rgba(0, 0, 0, 0.34);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--dur) var(--ease-spring),
              background var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.picker-op[data-fam="playstation"] { color: #8fb6d9; }
.picker-op[data-fam="xbox"]        { color: #8fd98f; }
.picker-op[data-fam="nintendo"]    { color: #e08a8a; }
.picker-op[data-fam="pc"]          { color: #a9bba4; }
.picker-op[data-fam="mobile"]      { color: #d9c07a; }
.picker-op[data-fam="vr"]          { color: #b9a6d9; }

.picker-op:hover {
  transform: translateY(-2px);
  background: color-mix(in srgb, currentColor 14%, transparent);
  box-shadow: 0 0 22px -6px currentColor;
}
.picker-op:active { transform: translateY(0) scale(0.96); }

.picker-saltar {
  appearance: none;
  display: block;
  width: 100%;
  margin-top: var(--gap);
  padding: 9px;
  border: 0;
  background: transparent;
  color: var(--text-faint);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: color var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
.picker-saltar:hover { color: var(--text); background: var(--bg-glass); }

/* La plataforma elegida se destaca dentro de la ficha del tablero. */
.chip-meta.chip-plat { color: var(--text-muted); }

/* Enlace para corregir la plataforma desde la ficha de detalle. */
.fact-cambiar {
  appearance: none;
  margin-left: 8px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 11.5px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.fact-cambiar:hover { color: var(--accent-bright); }

/* ==========================================================================
   Insignias que llevan a la tienda
   ========================================================================== */

/* Solo las pulsables cambian de aspecto: en las rejillas siguen siendo
   etiquetas mudas y no deben invitar a hacer clic. */
.plat[data-tienda] {
  appearance: none;
  font-family: inherit;
  cursor: pointer;
  padding-right: 19px;
  position: relative;
  transition: background var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-spring);
}
/* Flechita de "sale de la app", el convenio habitual para un enlace externo. */
.plat[data-tienda]::after {
  content: "";
  position: absolute;
  right: 6px;
  top: 50%;
  width: 7px; height: 7px;
  margin-top: -4px;
  border-top: 1.4px solid currentColor;
  border-right: 1.4px solid currentColor;
  opacity: 0.65;
  transform: rotate(45deg) translate(-1px, 1px);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.plat[data-tienda]:hover {
  background: color-mix(in srgb, currentColor 16%, rgba(0, 0, 0, 0.34));
  box-shadow: 0 0 16px -5px currentColor;
  transform: translateY(-1px);
}
.plat[data-tienda]:hover::after { opacity: 1; transform: rotate(45deg) translate(0, 0); }
.plat[data-tienda]:active { transform: translateY(0) scale(0.95); }

/* --- Menú para elegir tienda (PC sin ficha conocida en Steam) --- */

.store-menu {
  position: fixed;
  z-index: 860;                 /* sobre el modal de detalle (800) */
  min-width: 168px;
  padding: 6px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: rgba(9, 16, 9, 0.97);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-float);
  /* Igual que el panel de filtros: se oculta con `visibility` mientras se mide,
     y la entrada no anima la opacidad para que una animacion congelada no lo
     deje invisible. */
  visibility: hidden;
  opacity: 0;
}
.store-menu[data-listo="true"] {
  visibility: visible;
  opacity: 1;
  animation: panel-in 220ms var(--ease-pop);
}

.store-op {
  appearance: none;
  display: block;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.store-op:hover { background: var(--bg-glass-strong); color: var(--text-bright); }

.store-pie {
  display: block;
  padding: 7px 12px 4px;
  margin-top: 4px;
  border-top: 1px solid var(--line);
  font-size: 10.5px;
  color: var(--text-faint);
}

/* ==========================================================================
   Barra de filtros
   ========================================================================== */

.filtros {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-sm);
  margin-bottom: var(--gap);
}

.filtro {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 30px 8px 14px;
  position: relative;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--bg-glass);
  color: var(--text-muted);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out);
}
/* Cheurón, la pista de que se despliega. */
.filtro::after {
  content: "";
  position: absolute;
  right: 13px; top: 50%;
  width: 6px; height: 6px;
  margin-top: -4px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.6;
}
.filtro:hover { color: var(--text-bright); border-color: var(--line-strong); }

/* Un filtro puesto se enciende: de un vistazo se ve que la lista está recortada
   y no que simplemente hay pocos juegos. */
.filtro[data-activo="true"] {
  color: var(--bg-void);
  background: var(--accent);
  border-color: transparent;
  font-weight: 600;
  box-shadow: var(--glow);
}

.filtros-n {
  font-size: 12.5px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  margin-left: 2px;
}

.filtros-limpiar {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  padding: 4px 2px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.filtros-limpiar:hover { color: var(--accent-bright); }

/* --- Panel desplegable --- */

.filtro-panel {
  position: fixed;
  z-index: 640;
  min-width: 216px;
  max-height: min(380px, 60vh);
  overflow-y: auto;
  padding: 6px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: rgba(9, 16, 9, 0.97);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-float);
  /* Nace invisible porque se mide antes de colocarse. Se usa `visibility` y no
     una animacion de opacidad: con la pestaña en segundo plano las animaciones
     se congelan en su primer fotograma, y una que empezara en opacidad 0
     dejaria el panel invisible para siempre. La entrada solo mueve el
     transform, asi que si se congela el panel se ve igual. */
  visibility: hidden;
  opacity: 0;
}
.filtro-panel[data-listo="true"] {
  visibility: visible;
  opacity: 1;
  animation: panel-in 220ms var(--ease-pop);
}

.filtro-op {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.filtro-op:hover { background: var(--bg-glass-strong); }
.filtro-op em {
  font-style: normal;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.filtro-op b {
  font-weight: 500;
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.filtro-marca {
  width: 15px; height: 15px;
  flex-shrink: 0;
  border-radius: 4px;
  border: 1.5px solid var(--line-strong);
  position: relative;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
/* La misma marca sirve para los desplegables de filtro y para los dialogos de
   elegir (recomendar, favoritos, fondo). Cuando la regla solo nombraba
   `.filtro-op`, en los dialogos la casilla **nunca se pintaba marcada**: la
   eleccion se registraba por dentro pero no se veia, y parecia que el boton
   funcionaba sin haber elegido nada. */
:is(.filtro-op, .elegir-op)[data-marcado="true"] .filtro-marca {
  background: var(--accent);
  border-color: var(--accent);
}
:is(.filtro-op, .elegir-op)[data-marcado="true"] .filtro-marca::after {
  content: "";
  position: absolute;
  left: 4px; top: 1px;
  width: 4px; height: 8px;
  border-right: 2px solid var(--bg-void);
  border-bottom: 2px solid var(--bg-void);
  transform: rotate(43deg);
}
.filtro-op[data-marcado="true"] em { color: var(--text-bright); font-weight: 600; }

/* Las opciones de plataforma llevan su color de familia, como las insignias. */
.filtro-op[data-fam="playstation"] em { color: #8fb6d9; }
.filtro-op[data-fam="xbox"] em        { color: #8fd98f; }
.filtro-op[data-fam="nintendo"] em    { color: #e08a8a; }
.filtro-op[data-fam="mobile"] em      { color: #d9c07a; }
.filtro-op[data-fam="vr"] em          { color: #b9a6d9; }

.ver-mas { display: grid; place-items: center; margin-top: 32px; }

/* ==========================================================================
   Sublistas del backlog
   ========================================================================== */

.grupo {
  margin-top: 8px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.018);
  overflow: hidden;
}

.grupo-cab {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 9px 11px;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.grupo-cab:hover { background: var(--bg-glass); color: var(--text-bright); }

.grupo-cab em {
  font-style: normal;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Flecha que gira al plegar: la pista de que la cabecera se puede pulsar. */
.grupo-flecha {
  width: 6px; height: 6px;
  flex-shrink: 0;
  margin-left: 2px;
  border-right: 1.8px solid var(--col-accent);
  border-bottom: 1.8px solid var(--col-accent);
  transform: rotate(-45deg);
  transition: transform var(--dur) var(--ease-out);
}
.grupo-cab[aria-expanded="true"] .grupo-flecha { transform: rotate(45deg); }

.grupo-n {
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  background: var(--bg-glass);
}

.grupo-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 8px 8px;
}

/* --- Menú para elegir sublista --- */

.lista-menu {
  position: fixed;
  z-index: 860;                 /* sobre el modal de detalle */
  min-width: 200px;
  max-height: min(340px, 56vh);
  overflow-y: auto;
  padding: 6px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: rgba(9, 16, 9, 0.97);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-float);
  /* Igual que los demas paneles: se oculta con `visibility` mientras se mide y
     la entrada no anima la opacidad, para que una animacion congelada no lo
     deje invisible. */
  visibility: hidden;
  opacity: 0;
}
.lista-menu[data-listo="true"] {
  visibility: visible;
  opacity: 1;
  animation: panel-in 220ms var(--ease-pop);
}

.lista-op {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 11px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.lista-op:hover { background: var(--bg-glass-strong); }
.lista-op[data-marcada="true"] { color: var(--accent); font-weight: 600; }
.lista-op[data-marcada="true"]::before { content: "✓"; font-size: 11px; }

.lista-nueva {
  appearance: none;
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 8px 11px;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.lista-nueva:hover { background: var(--accent-dim); }

.lista-campo {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}
.lista-campo input {
  flex: 1;
  min-width: 0;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong);
  background: rgba(0, 0, 0, 0.4);
  color: var(--text-bright);
  font: inherit;
  font-size: 12.5px;
  outline: none;
}
.lista-campo input:focus { border-color: var(--accent); }
.lista-campo button {
  appearance: none;
  padding: 7px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--bg-void);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

/* ==========================================================================
   Valoración, reseña y horas
   ========================================================================== */

.estrellas { display: inline-flex; gap: 3px; vertical-align: middle; }

.estrella {
  appearance: none;
  padding: 0;
  border: 0;
  background: none;
  line-height: 0;
  cursor: pointer;
  color: var(--line-strong);
  transition: color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-spring);
}
.estrella svg { width: 22px; height: 22px; fill: currentColor; }
.estrellas[data-fijas="true"] .estrella { cursor: default; }
.estrella:not(:disabled):hover { transform: scale(1.18); }

/* Se encienden todas las que quedan a la izquierda de la elegida, que es como
   se lee una valoracion de estrellas. */
.estrellas[data-valor="1"] .estrella[data-n="1"],
.estrellas[data-valor="2"] .estrella[data-n="1"],
.estrellas[data-valor="2"] .estrella[data-n="2"],
.estrellas[data-valor="3"] .estrella[data-n="1"],
.estrellas[data-valor="3"] .estrella[data-n="2"],
.estrellas[data-valor="3"] .estrella[data-n="3"],
.estrellas[data-valor="4"] .estrella[data-n="1"],
.estrellas[data-valor="4"] .estrella[data-n="2"],
.estrellas[data-valor="4"] .estrella[data-n="3"],
.estrellas[data-valor="4"] .estrella[data-n="4"],
.estrellas[data-valor="5"] .estrella {
  color: var(--status-completed);
  filter: drop-shadow(0 0 6px rgba(232, 255, 58, 0.45));
}

/* Al pasar el raton se previsualiza la nota completa hasta esa estrella. */
.estrellas:not([data-fijas]) .estrella:hover,
.estrellas:not([data-fijas]) .estrella:hover ~ .estrella { color: var(--line-strong); }
.estrellas:not([data-fijas]):has(.estrella:hover) .estrella { color: var(--status-completed); }
.estrellas:not([data-fijas]) .estrella:hover ~ .estrella { color: var(--line-strong); }

/* --- Diálogo --- */

.valorar {
  width: min(460px, 100%);
  padding: var(--gap-md);
  border-radius: var(--radius-lg);
  border: 1px solid var(--line-strong);
  background: var(--bg-base);
  box-shadow: var(--shadow-float);
  animation: modal-in var(--dur-slow) var(--ease-pop);
}
.valorar-titulo {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-bright);
}
.valorar-sub { margin: 4px 0 var(--gap); font-size: 13.5px; color: var(--text-muted); }

.valorar .estrellas { margin-top: 4px; }
.valorar .estrella svg { width: 30px; height: 30px; }

.valorar-nota {
  display: block;
  margin: 7px 0 var(--gap-md);
  font-size: 12.5px;
  color: var(--text-muted);
  min-height: 1.2em;
}

.valorar-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  margin-bottom: var(--gap-sm);
  font-size: 13.5px;
  color: var(--text);
}
.valorar-horas {
  width: 92px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong);
  background: rgba(0, 0, 0, 0.4);
  color: var(--text-bright);
  font: inherit;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  outline: none;
}
.valorar-horas:focus { border-color: var(--accent); }

.valorar-texto {
  width: 100%;
  padding: 11px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: rgba(0, 0, 0, 0.4);
  color: var(--text-bright);
  font: inherit;
  font-size: 13.5px;
  line-height: 1.5;
  resize: vertical;
  outline: none;
}
.valorar-texto:focus { border-color: var(--accent); }
.valorar-texto::placeholder { color: var(--text-faint); }

.valorar-acciones { display: flex; gap: var(--gap-sm); margin-top: var(--gap); }

/* --- En la ficha del juego --- */

.fact-horas {
  margin-left: 9px;
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.modal-publica {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--gap);
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}
.publica-caja { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.publica-k {
  font-size: 10.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.publica-v {
  font-size: 14px;
  color: var(--text);
  text-decoration: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
}
.publica-v strong {
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  /* El color lo pone el tramo; este es el de reserva por si faltara el dato. */
  color: var(--text-bright);
}
.publica-v strong[data-nota="alta"]  { color: var(--nota-alta); }
.publica-v strong[data-nota="media"] { color: var(--nota-media); }
.publica-v strong[data-nota="baja"]  { color: var(--nota-baja); }

/* De 90 para arriba el numero deja de ser plano y se vuelve una gema: el color
   recorre el texto en bucle, como la luz al girar una piedra tallada.

   El degradado se recorta contra el texto y lo que se anima es su posicion, no
   la opacidad: si la animacion se congela -- pestaña en segundo plano, o
   movimiento reducido -- el numero se queda quieto pero perfectamente visible. */
.publica-v strong[data-nota="joya"] {
  background: linear-gradient(100deg,
    #8affb4 0%, #ffffff 14%, #a6f7ff 28%, #e8ff4a 42%,
    #ffffff 56%, #7be827 70%, #ffffff 84%, #8affb4 100%);
  background-size: 320% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: brillo-joya 3.6s linear infinite;
  filter: drop-shadow(0 0 9px rgba(123, 232, 39, 0.42));
}
/* Las facetas: dos destellos finos que cruzan el numero de vez en cuando. */
.publica-v strong[data-nota="joya"]::after {
  content: "";
  position: absolute;
  inset: -2px -4px;
  pointer-events: none;
  background: linear-gradient(108deg, transparent 44%,
              rgba(255, 255, 255, 0.75) 49%, transparent 54%);
  background-size: 260% 100%;
  animation: faceta-joya 3.6s ease-in-out infinite;
  mix-blend-mode: screen;
}
.publica-v strong[data-nota="joya"] { position: relative; }
.publica-sobre { font-size: 12px; color: var(--text-faint); margin-left: -4px; }
.publica-v em {
  font-style: normal;
  font-size: 11.5px;
  color: var(--text-faint);
  flex: 1 0 100%;
}
/* La nota de prensa enlaza a su ficha; la de Steam no, porque la insignia de
   plataforma ya lleva alli. */
a.publica-v:hover strong { filter: brightness(1.2); }
a.publica-v:hover em { color: var(--text-muted); text-decoration: underline; }

.modal-resenya {
  padding: 13px 15px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-glass);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text);
  white-space: pre-wrap;
}

/* --- Muro de reseñas del perfil --- */

.resenyas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--gap-sm);
}

.resenya {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-glass);
  transition: border-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-spring);
}
.resenya.clicable { cursor: pointer; }
.resenya.clicable:hover {
  border-color: rgba(232, 255, 58, 0.34);
  transform: translateY(-2px);
}

.resenya-cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-sm);
}
.resenya-n {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-bright);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Aquí las estrellas son un dato más, no el protagonista. */
.resenya .estrella svg { width: 13px; height: 13px; }
.resenya .estrellas { gap: 1px; flex-shrink: 0; }

.resenya-meta {
  font-size: 11.5px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.resenya-txt {
  margin: 4px 0 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-muted);
  /* Se recorta a cuatro lineas: el muro es un vistazo, y la reseña entera se
     lee al abrirla. */
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.resenyas-vacio {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 60ch;
}

/* ==========================================================================
   Selector de idioma
   ========================================================================== */

/* La bandera ya es el icono, así que este botón no lleva SVG. */
.lang-btn { font-size: 17px; line-height: 1; padding: 0; }
.lang-bandera { display: block; }

.lang-menu {
  position: fixed;
  z-index: 860;
  min-width: 156px;
  padding: 6px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: rgba(9, 16, 9, 0.97);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-float);
  /* Como el resto de paneles: se oculta con `visibility` mientras se mide y la
     entrada no anima la opacidad, para que una animación congelada no lo deje
     invisible. */
  visibility: hidden;
  opacity: 0;
}
.lang-menu[data-listo="true"] {
  visibility: visible;
  opacity: 1;
  animation: panel-in 220ms var(--ease-pop);
}

.lang-op {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.lang-op:hover { background: var(--bg-glass-strong); }
.lang-op span { font-size: 16px; line-height: 1; }
.lang-op[data-activo="true"] { color: var(--accent); font-weight: 600; }

/* El desglose de la duracion: los extremos y cuantas partidas se han medido.
   Va en su propia linea y en gris, porque es la letra pequeña del dato -- la
   cifra que importa es la de arriba. */
.fact-detalle {
  display: block;
  margin-top: 3px;
  font-size: 11.5px;
  font-weight: 400;
  color: var(--text-faint);
  line-height: 1.45;
}

/* El interruptor de relevancia va en la barra de filtros pero no es un filtro
   mas: es el corte que la lista trae puesto de fabrica. Se distingue con el
   color de acento cuando esta activo, para que se vea de un vistazo que lo que
   hay debajo es una seleccion y no el catalogo entero. */
/* El selector de alcance. No es un filtro mas sino el corte que la lista trae
   puesto de fabrica, asi que se dibuja como un control de dos posiciones y no
   como los desplegables: las dos opciones se ven siempre y se resalta la que
   esta activa. Con un solo boton habia que deducir el estado a partir de una
   etiqueta que decia la accion contraria. */
.filtro-modo {
  display: inline-flex;
  align-items: center;
  padding: 3px;
  gap: 2px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--bg-glass);
}
.filtro-modo button {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out);
}
.filtro-modo button:hover { color: var(--text-bright); }
.filtro-modo button[data-activo="true"] {
  background: linear-gradient(100deg, var(--accent), #b4f55a);
  color: var(--bg-void);
  font-weight: 600;
  box-shadow: var(--glow);
}
.filtro-modo button[data-activo="true"]:hover { color: var(--bg-void); }

@media (max-width: 620px) {
  .filtro-modo button { padding: 5px 10px; font-size: 12px; }
}

/* La nota sobre la caratula, arriba a la derecha -- la cuenta atras ocupa la
   izquierda. Usa los mismos tramos de color que la ficha, pero sin el degradado
   animado de "joya": a este tamaño no se leeria, y aqui el numero tiene que
   distinguirse de un vistazo mientras recorres la rejilla. */
.card-nota {
  min-width: 26px;
  padding: 3px 6px;
  border-radius: 7px;
  background: rgba(4, 9, 4, 0.92);
  border: 1px solid var(--line);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
  line-height: 1.2;
}
.card-nota[data-nota="joya"]  { color: var(--nota-alta); border-color: rgba(123, 232, 39, 0.5); }
.card-nota[data-nota="alta"]  { color: var(--nota-alta); }
.card-nota[data-nota="media"] { color: var(--nota-media); }
.card-nota[data-nota="baja"]  { color: var(--nota-baja); }

/* ==========================================================================
   Me ha gustado
   ========================================================================== */

/* El corazon en la tarjeta. Va relleno, no perfilado: a 12 px un contorno se
   pierde sobre la caratula y hay que poder verlo de un vistazo al recorrer la
   rejilla. */
.card-gusta {
  width: 22px; height: 22px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(3, 6, 3, 0.93);
  border: 1px solid var(--accent-hot);
  color: var(--accent-hot);
}
.card-gusta svg { width: 12px; height: 12px; fill: currentColor; }

/* El boton de la ficha. Sin marcar es un boton normal con el corazon hueco;
   marcado se rellena y toma el color calido, que lo separa de los tres botones
   de estado -- que son verdes y hablan del backlog, no de si te gusto. */
.btn-gusta svg { fill: none; }
.btn-gusta[data-activo="true"] {
  border-color: var(--accent-hot);
  color: var(--accent-hot);
}
.btn-gusta[data-activo="true"] svg { fill: currentColor; }

/* La rejilla del perfil. Tarjetas pequeñas: aqui el juego ya lo conoces, solo
   hacen falta la caratula y el nombre. */
.gustos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: var(--gap);
}
.gusto {
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.gusto-art {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  transition: transform var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
/* `paintArt` inserta un <img>, no un fondo: sin esto la imagen sale a su tamaño
   natural y se ve un recorte de la esquina superior izquierda. */
.gusto-art img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.gusto-art img.loaded { opacity: 1; }
.gusto-art .art-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 8px;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-bright);
}
.gusto:hover .gusto-art {
  transform: translateY(-3px);
  border-color: rgba(255, 61, 61, 0.5);
}
.gusto-nombre {
  display: block;
  margin-top: 7px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--text);
}

/* Dialogo para elegir cuales se enseñan. */
.elegir-caja {
  width: min(440px, calc(100vw - 32px));
  max-height: min(70vh, 560px);
  display: flex;
  flex-direction: column;
  gap: var(--gap-sm);
  padding: var(--gap);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-lg);
}
.elegir-caja h3 { margin: 0; font-size: 17px; color: var(--text-bright); }
.elegir-pie { margin: 0; font-size: 13px; color: var(--text-muted); line-height: 1.5; }
.elegir-lista { overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.elegir-op {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 9px;
  background: none;
  font: inherit;
  font-size: 13.5px;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.elegir-op:hover:not(:disabled) { background: var(--bg-glass); }
.elegir-op:disabled { opacity: 0.4; cursor: default; }

/* Un boton apagado tiene que **verse** apagado. Sin esto, deshabilitar el de
   recomendar no cambiaba nada en pantalla y seguia pareciendo pulsable. */
.btn:disabled { opacity: 0.42; cursor: default; }
.btn:disabled:hover { transform: none; filter: none; }
.elegir-op em { font-style: normal; }
.elegir-acciones { display: flex; justify-content: flex-end; gap: var(--gap-sm); }

/* ==========================================================================
   El fondo del perfil
   ========================================================================== */

.perfil { position: relative; overflow: hidden; }

/* El arte va en su propia capa y no como `background` de `.perfil`: asi el
   degradado que protege el texto puede vivir encima de la imagen sin tener que
   apilar cuatro fondos en la misma propiedad. */
.perfil-fondo {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center 30%;
  opacity: 0.9;
}

/* Lo que hace legible el texto. Sin esto el arte gana casi siempre: los fondos
   de IGDB son ilustraciones a sangre con zonas claras en cualquier sitio, y el
   nivel se pierde justo encima de una. El degradado carga a la izquierda, que
   es donde vive el texto, y deja respirar la derecha de la imagen. */
.perfil[data-con-fondo="true"]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(100deg, rgba(4, 9, 4, 0.94) 20%, rgba(4, 9, 4, 0.80) 55%,
                    rgba(4, 9, 4, 0.28) 88%, rgba(4, 9, 4, 0.14) 100%),
    radial-gradient(120% 140% at 12% 20%, rgba(123, 232, 39, 0.16), transparent 62%);
}

/* Todo lo que se lee va por encima de las dos capas. El texto lleva ademas su
   propia sombra: el degradado protege la zona, pero un arte con una mancha
   clara justo debajo de una linea la dejaria ilegible, y la sombra cubre ese
   caso sin tener que oscurecer la imagen entera. */
.perfil-figura, .perfil-datos { position: relative; z-index: 2; }
.perfil[data-con-fondo="true"] .perfil-datos {
  text-shadow: 0 1px 10px rgba(4, 9, 4, 0.95), 0 1px 3px rgba(4, 9, 4, 0.9);
}
/* La barra de progreso no se estira hasta el borde cuando hay arte: su extremo
   derecho caeria sobre la parte mas iluminada, que es justo la que se deja ver
   a proposito. */
.perfil[data-con-fondo="true"] .perfil-barra { max-width: 74%; }

.perfil-fondo-btn {
  position: absolute;
  top: 10px; right: 10px;
  z-index: 3;
  appearance: none;
  padding: 5px 11px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: rgba(4, 9, 4, 0.7);
  backdrop-filter: blur(8px);
  color: var(--text-muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out), color var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.perfil:hover .perfil-fondo-btn,
.perfil-fondo-btn:focus-visible { opacity: 1; }
.perfil-fondo-btn:hover { color: var(--accent); border-color: rgba(123, 232, 39, 0.45); }

/* En tactil no hay raton que pase por encima: el boton se queda visible. */
@media (hover: none) {
  .perfil-fondo-btn { opacity: 1; }
}

/* El panel del fondo del perfil. Hereda de `.filtro-panel` -- posicion, sombra
   y la entrada por `transform`, que no se congela con la pestaña oculta -- y
   solo añade la rejilla de miniaturas. */
.panel-fondo { width: min(340px, calc(100vw - 24px)); }

.panel-fondo-titulo {
  margin: 2px 4px 8px;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.panel-fondo-arte {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

/* Se elige una imagen, asi que se enseña la imagen: una lista de titulos
   obliga a recordar como es el arte de cada juego. */
.fondo-op {
  position: relative;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: flex-end;
  padding: 6px 7px;
  border-radius: 9px;
  border: 1px solid var(--line);
  background-size: cover;
  background-position: center 30%;
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}
.fondo-op::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(4, 9, 4, 0.92) 8%, rgba(4, 9, 4, 0.1) 70%);
}
.fondo-op span {
  position: relative;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text-bright);
  text-shadow: 0 1px 4px rgba(4, 9, 4, 0.9);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.fondo-op:hover { transform: translateY(-2px); border-color: var(--line-strong); }
.fondo-op[data-activo="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), var(--glow);
}

/* ==========================================================================
   Sesion
   ========================================================================== */

.btn-sesion {
  appearance: none;
  flex-shrink: 0;
  max-width: 160px;
  padding: 8px 15px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--bg-glass);
  color: var(--text-bright);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: all var(--dur) var(--ease-out);
}
.btn-sesion:hover { border-color: rgba(123, 232, 39, 0.45); color: var(--accent); }

/* Sin cuenta el boton llama la atencion, porque es lo que hay que hacer para
   usar la app. Con la sesion abierta se apaga: ya no es una accion pendiente,
   solo dice quien eres. */
.btn-sesion[data-dentro="false"] {
  background: linear-gradient(100deg, var(--accent), #b4f55a);
  border-color: transparent;
  color: var(--bg-void);
  box-shadow: var(--glow);
}
.btn-sesion[data-dentro="false"]:hover { color: var(--bg-void); filter: brightness(1.06); }
.btn-sesion[data-dentro="true"] { font-weight: 500; color: var(--text); }

.menu-sesion { min-width: 170px; }

/* --- la caja de entrar y registrarse --- */

.auth {
  position: relative;
  width: min(380px, calc(100vw - 32px));
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: var(--gap-md);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-lg);
}
.auth-titulo { margin: 0 34px 0 0; font-size: 19px; color: var(--text-bright); }
.auth-motivo { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--text-muted); }

.auth-campo { display: flex; flex-direction: column; gap: 5px; }
.auth-campo span {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.auth-campo input {
  font: inherit;
  font-size: 14px;
  color: var(--text-bright);
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--bg-glass);
  outline: none;
  transition: border-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.auth-campo input:focus {
  border-color: rgba(123, 232, 39, 0.55);
  box-shadow: 0 0 0 3px rgba(123, 232, 39, 0.12);
}

.auth-error {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--nota-baja);
}
.auth-enviar { justify-content: center; margin-top: 2px; }
.auth-cambiar {
  appearance: none;
  border: 0;
  background: none;
  padding: 2px;
  font: inherit;
  font-size: 13px;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.auth-nota {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
  border-top: 1px solid var(--line);
  padding-top: 10px;
}

.inv-cerrado .btn { margin-top: var(--gap-sm); }

/* La barra que avisa de que estas mirando el perfil de otra persona. Se queda
   pegada arriba porque el inventario es largo: sin eso, a media pagina ya no
   se sabe de quien es lo que se esta leyendo. */
.visitando {
  position: sticky;
  top: calc(var(--nav-h) + 6px);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--gap-sm);
  margin-bottom: var(--gap);
  padding: 9px 12px;
  border-radius: var(--radius);
  background: rgba(9, 16, 9, 0.94);
  backdrop-filter: blur(12px);
  border: 1px solid var(--line-strong);
}
.visitando .btn { padding: 6px 12px; font-size: 13px; }
.visitando-quien { font-size: 14px; color: var(--text-muted); }
.visitando-quien strong { color: var(--accent); font-weight: 600; }

/* ==========================================================================
   Amigos
   ========================================================================== */

.amigos-cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap);
  margin: var(--gap-sm) 0 var(--gap-lg);
  padding: var(--gap);
  border-radius: var(--radius-lg);
  background: var(--bg-glass);
  border: 1px solid var(--line);
}
.amigos-alias { display: flex; flex-direction: column; gap: 3px; flex: 0 0 auto; }
.amigos-alias-et {
  font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--text-faint);
}
.amigos-alias strong { font-size: 17px; color: var(--accent); }

.amigos-buscar { position: relative; flex: 1 1 260px; min-width: 220px; }
.amigos-buscar input {
  width: 100%; font: inherit; font-size: 14px; color: var(--text-bright);
  padding: 10px 14px; border-radius: var(--radius-pill);
  border: 1px solid var(--line); background: var(--bg-base); outline: none;
}
.amigos-buscar input:focus { border-color: rgba(123, 232, 39, .5); }

/* Los resultados flotan sobre lo que haya debajo: la lista de amigos no debe
   saltar hacia abajo cada vez que se teclea una letra. */
.amigos-resultados {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 40;
  padding: 6px; border-radius: var(--radius);
  background: rgba(9, 16, 9, .98); backdrop-filter: blur(14px);
  border: 1px solid var(--line-strong); box-shadow: var(--shadow-float);
}
.amigos-nada { margin: 6px 10px; font-size: 13px; color: var(--text-muted); }

.amigos-lista { display: flex; flex-direction: column; gap: 8px; }
.amigo-fila {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px; border-radius: var(--radius);
  background: var(--bg-raised); border: 1px solid var(--line);
}
.amigo-fila .btn { padding: 7px 13px; font-size: 13px; }
.amigo-avatar {
  width: 34px; height: 34px; flex: 0 0 auto;
  display: grid; place-items: center; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-deep));
  color: var(--bg-void); font-size: 12.5px; font-weight: 700;
}
.amigo-nombre { flex: 1; font-size: 14.5px; color: var(--text-bright); }

/* --- recomendaciones --- */

.recos { display: grid; gap: var(--gap-sm); }
.reco {
  display: flex; align-items: center; gap: var(--gap-sm);
  padding: 10px; border-radius: var(--radius);
  background: var(--bg-raised); border: 1px solid var(--line);
}
/* Las que no has visto llevan el acento en el borde. Es lo unico que las
   distingue: no se apartan a otra lista para que no cambien de sitio al
   marcarse como vistas mientras las estas leyendo. */
.reco[data-nueva="true"] { border-color: rgba(123, 232, 39, .45); }
.reco-art {
  position: relative; width: 46px; aspect-ratio: 3/4; flex: 0 0 auto;
  border-radius: 7px; overflow: hidden; background: var(--bg-base);
}
.reco-art img { width: 100%; height: 100%; object-fit: cover; display: block;
                opacity: 0; transition: opacity var(--dur-slow) var(--ease-out); }
.reco-art img.loaded { opacity: 1; }
.reco-art .art-fallback { display: none; }
.reco-cuerpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.reco-cuerpo strong { font-size: 14.5px; color: var(--text-bright); }
.reco-de { font-size: 12px; color: var(--accent); }
.reco-msg { margin: 3px 0 0; font-size: 13px; color: var(--text-muted); line-height: 1.45; }
.reco-acciones { display: flex; gap: 6px; flex: 0 0 auto; }
.reco-acciones .btn { padding: 7px 12px; font-size: 12.5px; }

.alias-pedir { gap: var(--gap-sm); }
.alias-campo {
  font: inherit; font-size: 15px; color: var(--text-bright); text-align: center;
  padding: 11px 16px; border-radius: var(--radius-pill);
  border: 1px solid var(--line); background: var(--bg-glass); outline: none;
  min-width: 220px;
}
.alias-campo:focus { border-color: rgba(123, 232, 39, .55); }
.reco-campo {
  font: inherit; font-size: 14px; color: var(--text-bright);
  padding: 9px 12px; border-radius: 10px; resize: vertical;
  border: 1px solid var(--line); background: var(--bg-glass); outline: none;
}
.reco-campo:focus { border-color: rgba(123, 232, 39, .55); }

@media (max-width: 620px) {
  .reco { flex-wrap: wrap; }
  .reco-acciones { width: 100%; }
}

/* El enlace de recuperar contraseña va apagado: es una salida de emergencia,
   no una accion que haya que ofrecer al mismo nivel que entrar. */
.auth-olvide {
  color: var(--text-muted);
  font-size: 12.5px;
  align-self: center;
  margin-top: -4px;
}
.auth-olvide:hover { color: var(--accent); }

/* Las plataformas retiradas no llevan color de familia: no tienen tienda a la
   que ir, y el gris lo dice sin necesidad de explicarlo. Son las que no
   aparecen en PLATFORM_FAMILY, asi que les falta el atributo `data-fam`. */
.plat:not([data-fam]) {
  color: var(--text-muted);
  border-color: var(--line);
}
