/* GAMERLY · web pública
   Un solo fichero para todas las páginas. El sistema es el de la app: mismas
   superficies, mismos filetes, misma tinta. Elevación por salto de superficie y
   filete de 1 px, nunca sombra difusa. Radios pequeños, ninguna píldora. */

@font-face {
  font-family: "IBM Plex Mono";
  src: url("/fuentes/ibm-plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
/* LIMA (16-10-2026, docs/DESIGN.md): Big Shoulders Display para el display, siempre en mayúsculas, y Barlow para
   el texto. SIL OFL, licencias en herramientas/fuentes-licencias/. Con `swap` y sus respaldos medidos, como el resto. */
@font-face { font-family: "Big Shoulders Display"; src: url("/fuentes/big-shoulders-display-700.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Big Shoulders Display"; src: url("/fuentes/big-shoulders-display-900.woff2") format("woff2"); font-weight: 900; font-style: normal; font-display: optional; }
@font-face { font-family: "Barlow"; src: url("/fuentes/barlow-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: optional; }
/* BARLOW, EN `optional` Y PRECARGADA (17-10-2026). Con `swap` el texto corrido se pintaba con el respaldo y, al llegar la fuente,
   un párrafo con la última línea casi llena se partía en una línea más o menos: el respaldo iguala la anchura MEDIA,
   no la de cada frase, y fuentes-tarde lo cazó en ocho páginas (/terminos, /soporte, /beta…). Ajustarlo frase a
   frase se rompe con cada cambio de texto. Con `optional` y la precarga que llevan todas las páginas, la fuente llega
   a tiempo casi siempre; si no, esa visita se queda con el respaldo medido, sin saltos, y la siguiente ya la tiene.
   Las DOS caras se precargan en todas las páginas: en `optional` y sin precarga, la 700 se quedaba en Arial en casi
   toda primera visita (lo vio una sonda en /beta). No suma bytes —todas las páginas usan las dos—, solo prioridad.
   Y Big Shoulders 900, la de los titulares, igual y por lo mismo: con la barrita delante, «PRIVACY POLICY» y dos
   titulares legales más se partían distinto con el respaldo (fuentes-tarde, mismo día). También se precarga en
   todas. La 700 sigue en `swap`: no se precarga, y en `optional` se quedaría en el respaldo. */
/* Sin Barlow 600 (16-10-2026, decisión de Rafa, por el peso): el 600 lo pinta la cara 700. */
@font-face { font-family: "Barlow"; src: url("/fuentes/barlow-700.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: optional; }

/* <RESPALDOS> · lo escribe `python herramientas/respaldo-fuentes.py`. No se edita a mano. */
@font-face {
  font-family: "Big Shoulders Display respaldo Arial";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 900;
  font-style: normal;
  size-adjust: 69.43%;
  ascent-override: 141.73%;
  descent-override: 30.68%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2116, U+2190-2193, U+2197, U+2212;
}
@font-face {
  font-family: "Big Shoulders Display respaldo Roboto";
  src: local("Roboto Bold"), local("Roboto-Bold");
  font-weight: 900;
  font-style: normal;
  size-adjust: 74.98%;
  ascent-override: 131.24%;
  descent-override: 28.41%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2116, U+2190-2193, U+2197, U+2212;
}
@font-face {
  font-family: "Barlow respaldo Arial";
  src: local("Arial"), local("ArialMT");
  font-weight: 500;
  font-style: normal;
  size-adjust: 96.82%;
  ascent-override: 103.29%;
  descent-override: 20.66%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2212;
}
@font-face {
  font-family: "Barlow respaldo Roboto";
  src: local("Roboto"), local("Roboto-Regular"), local("Roboto Regular");
  font-weight: 500;
  font-style: normal;
  size-adjust: 97.57%;
  ascent-override: 102.49%;
  descent-override: 20.50%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2212;
}
@font-face {
  font-family: "Barlow respaldo Arial";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 700;
  font-style: normal;
  size-adjust: 91.70%;
  ascent-override: 109.05%;
  descent-override: 21.81%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2212;
}
@font-face {
  font-family: "Barlow respaldo Roboto";
  src: local("Roboto Bold"), local("Roboto-Bold");
  font-weight: 700;
  font-style: normal;
  size-adjust: 97.84%;
  ascent-override: 102.21%;
  descent-override: 20.44%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2212;
}
@font-face {
  font-family: "Alegreya respaldo Georgia";
  src: local("Georgia Bold"), local("Georgia-Bold");
  font-weight: 700;
  font-style: normal;
  size-adjust: 80.35%;
  ascent-override: 126.45%;
  descent-override: 42.94%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2191, U+2193, U+2212;
}
@font-face {
  font-family: "Alegreya respaldo Noto Serif";
  src: local("Noto Serif Bold"), local("NotoSerif-Bold");
  font-weight: 700;
  font-style: normal;
  size-adjust: 81.71%;
  ascent-override: 124.34%;
  descent-override: 42.22%;
  line-gap-override: 0.00%;
  unicode-range: U+20-7E, U+A0-FF, U+131, U+152-153, U+2013-2014, U+2018-201A, U+201C-201E, U+2022, U+2026, U+2032-2033, U+2039-203A, U+20AC, U+2191, U+2193, U+2212;
}
/* </RESPALDOS> */

:root {
  color-scheme: dark;

  /* superficies, de abajo arriba */
  --canvas: #0e0b17;
  --bg: #14101f;
  --surface: #1d1730;
  --surface-raised: #29203f;
  --surface-sunken: #241b3d;
  --selected: #322650;

  /* filetes */
  --hairline: #3b2f5b;
  --hairline-subtle: #2a2140;
  --hairline-accent: #4a3a6b;
  /* el borde de un control: los filetes no llegan a 3:1 */
  --line-control: #735eac;

  /* tinta */
  --ink: #f3effa;
  --ink-bright: #d8cfea;
  --ink-soft: #b3a6cc;
  --ink-muted: #9a8db8;

  /* acción */
  --action: #be7bff;
  --action-ink: #0e0b17;
  --action-hover: #cb95ff;
  --danger: #ff8fa3;

  /* el vidrio del fundador, del grupo `glass` de la app */
  --glass-surface: #191233;
  --glass-plate: rgba(255, 255, 255, 0.9);
  --glass-plate-ink: #191233;
  --glass-plate-label: #4a3f6b;
  --glass-edge: rgba(255, 255, 255, 0.3);

  --radius-s: 3px;
  --radius-m: 6px;
  --radius-l: 10px;

  --mono: "IBM Plex Mono", "IBM Plex Mono respaldo Courier New", "IBM Plex Mono respaldo Droid Sans Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --font: "Barlow", "Barlow respaldo Arial", "Barlow respaldo Roboto", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --t-display: clamp(2.625rem, 1.55rem + 5.2vw, 5.75rem);
  --t-h2: clamp(2rem, 1.35rem + 2.9vw, 3.5rem);
  --t-h3: clamp(1.1875rem, 1.1rem + 0.35vw, 1.375rem);
  --t-lead: clamp(1.125rem, 1.02rem + 0.5vw, 1.4375rem);
  --t-body: 1.0625rem;
  --t-small: 0.9375rem;
  --t-label: 0.75rem;

  --gutter: clamp(1rem, 0.6rem + 2.4vw, 2.5rem);
  --section: clamp(4.5rem, 3rem + 5.5vw, 7.5rem);

  /* EL MOVIMIENTO, en cuatro niveles (auditoría del 29-9-2026, sección G).
     Eran dos sistemas a la vez —`--ease-*` aquí y `--fv-*` en la hoja del
     sistema— con diez curvas distintas. Quedan cuatro duraciones y tres curvas,
     y cada una dice lo que hace. */
  --mov-rapido: 140ms;   /* 1 · micro: pulsar, foco, un chip, el hover */
  --mov-base: 240ms;     /* 2 · transiciones: puertas, preguntas, avisos */
  --mov-lento: 420ms;    /* 2 · el interruptor de idioma y lo que entra despacio */
  --mov-escena: 860ms;   /* 4 · la vuelta al fondo del mazo: 320 + 540 */
  --curva-salida: cubic-bezier(0.23, 1, 0.32, 1);    /* responde al gesto */
  --curva-mesa: cubic-bezier(0.3, 0.2, 0.55, 1);     /* un objeto cruza la mesa */
  --curva-reparto: cubic-bezier(0.2, 0.9, 0.3, 1.1); /* la única que se pasa: repartir */
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--canvas);
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img,
svg {
  display: block;
  max-width: 100%;
}

h1,
h2,
h3,
p,
ul,
ol,
figure,
blockquote,
dl,
dd {
  margin: 0;
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
  padding: 0;
}

a {
  color: inherit;
}

button,
input,
textarea {
  font: inherit;
  color: inherit;
}

::selection {
  background: var(--action);
  color: var(--action-ink);
}

/* ── FOCO ─────────────────────────────────────────────────────────────────
   Un anillo de 2 px en el color de acción, separado del control: se ve sobre
   cualquier superficie de la página y no se confunde con un borde. Sobre un
   relleno de acción el anillo pasa a tinta, que es lo que contrasta allí. */

:focus {
  outline: none;
}

:focus-visible {
  outline: 2px solid var(--action);
  outline-offset: 3px;
  border-radius: var(--radius-s);
  animation: foco-cierra var(--mov-rapido) var(--curva-salida);
}

.boton--accion:focus-visible {
  outline-color: var(--ink);
  box-shadow: 0 0 0 5px var(--canvas), 0 0 0 7px var(--action);
  animation: foco-cierra-accion var(--mov-rapido) var(--curva-salida);
}

/* EL FOCO SE CIERRA SOBRE EL CONTROL: el anillo llega desde más fuera y se asienta
   en su sitio, así que al tabular se ve dónde cae. Solo `from`: termina en el
   desplazamiento propio de cada control. Con menos movimiento, llega ya puesto. */
@keyframes foco-cierra {
  from {
    outline-offset: 9px;
    outline-color: transparent;
  }
}

@keyframes foco-cierra-accion {
  from {
    box-shadow: 0 0 0 11px var(--canvas), 0 0 0 13px transparent;
  }
}

.envoltura {
  width: 100%;
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

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

.saltar {
  position: absolute;
  left: var(--gutter);
  top: 0.75rem;
  z-index: 50;
  padding: 0.75rem 1rem;
  background: var(--action);
  color: var(--action-ink);
  font-weight: 800;
  text-decoration: none;
  border-radius: var(--radius-s);
  transform: translateY(-200%);
}

.saltar:focus-visible {
  transform: none;
}

/* ── TIPOGRAFÍA ───────────────────────────────────────────────────────── */

.rotulo {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.rotulo__serie {
  color: var(--action);
}

.entradilla {
  font-size: var(--t-lead);
  line-height: 1.45;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.entradilla strong {
  color: var(--ink);
  font-weight: 600;
}

/* ── BOTONES Y ENLACES ────────────────────────────────────────────────── */

.boton {
  --alto: 3.25rem;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  min-height: var(--alto);
  padding: 0 1.375rem;
  border: 1px solid transparent;
  border-radius: var(--radius-m);
  font-size: 0.9375rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1.1;
  cursor: pointer;
  transition: background-color var(--mov-rapido) var(--curva-salida), border-color var(--mov-rapido) var(--curva-salida),
    color 160ms var(--curva-salida), transform 160ms var(--curva-salida);
  -webkit-tap-highlight-color: transparent;
}

/* la pulsación: baja un píxel y se comprime un poco, al instante; vuelve en 160 ms */
.boton:active {
  transform: translateY(1px) scale(0.985);
  transition-duration: 60ms;
}

.boton--accion {
  background: var(--action);
  color: var(--action-ink);
}

.boton--accion:hover {
  background: var(--action-hover);
}

.boton--linea {
  background: transparent;
  border-color: var(--line-control);
  color: var(--ink);
}

.boton--linea:hover {
  background: var(--surface);
  border-color: var(--action);
}

.boton--compacto {
  --alto: 2.75rem;
  padding: 0 1rem;
  font-size: 0.8125rem;
}

.enlace {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--action);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: text-decoration-thickness var(--mov-rapido), color var(--mov-rapido);
}

.enlace:hover {
  text-decoration-thickness: 2px;
  color: var(--ink-bright);
}

/* ── CABECERA ─────────────────────────────────────────────────────────── */

.cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.125rem;
}

.marca {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  min-height: 2.75rem;
  text-decoration: none;
}

/* El lockup horizontal de la marca (Fase 24), recortado a su dibujo (318×87). En móvil crece con
   la pantalla hasta donde cabe al lado del botón de la lista en las páginas legales (153 px): a 393
   sale a 50 px de alto, a 360 a 41, y nunca baja de 38 (139 de ancho; el paquete pide 112 como
   mínimo con símbolo). Sin el flex-shrink de .marca, la cabecera lo estrujaba: deformado. Por eso
   el enlace entre páginas legales se oculta en estrecho (sigue en el pie). */
.marca img {
  height: clamp(2.375rem, (100vw - 13rem) / 3.7, 3.25rem);
  width: auto;
}

/* En las portadas, en móvil, el botón de la lista de la cabecera repite la llamada del titular,
   que cae en la primera pantalla: se quita para que quepa el logotipo grande. */

/* En escritorio, junto a un titular de ese cuerpo, a 44 px seguía viéndose pequeño (16-9-2026). */
@media (min-width: 40rem) {
  .marca img {
    height: 3.25rem;
  }
}

/* ── EL INTERRUPTOR DE IDIOMA ─────────────────────────────────────────────
   Es el chip de idiomas de la carta («ES · EN», en mono y con filete) hecho control:
   lo mismo que en la app te dice qué habla alguien, aquí elige qué hablas tú. Dos
   estados y no un menú; cada idioma escrito en su idioma; sin banderas. El activo va
   en tinta plena sobre su placa y no es un enlace (ya estás ahí); el otro, apagado.
   Al llegar desde la otra portada, la placa termina de deslizarse hacia el idioma
   elegido: lo decide `document.referrer`, sin guardar nada (portada.js, pieza 5). */
/* isolation en el grupo y no en cada opción: la placa, al deslizarse, pasa por debajo
   del otro nombre y no por encima */
.idioma {
  isolation: isolate;
  display: inline-flex;
  flex-shrink: 0;
  gap: 2px;
  padding: 3px;
  background: var(--canvas);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-m);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1;
}

.idioma__opcion {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  min-height: 2.25rem;
  padding-inline: 0.625rem;
  border-radius: var(--radius-s);
  color: var(--ink-muted);
  text-decoration: none;
  white-space: nowrap;
}

.idioma__opcion::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  transition: background-color var(--mov-rapido) var(--curva-salida);
}

a.idioma__opcion:hover {
  color: var(--ink);
}

a.idioma__opcion:hover::before {
  background: var(--surface);
}

a.idioma__opcion:focus-visible {
  outline-offset: 2px;
}

.idioma__opcion[aria-current] {
  color: var(--ink);
}

.idioma__opcion[aria-current]::before {
  background: var(--selected);
  box-shadow: inset 0 0 0 1px var(--hairline-accent);
}

/* el código, como el chip de la carta; en la cabecera de un móvil no cabe y sobra */
.idioma__codigo {
  display: none;
  padding: 0.1875rem 0.3125rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-s);
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.06rem;
  line-height: 1;
}

.idioma__opcion[aria-current] .idioma__codigo {
  border-color: var(--hairline-accent);
}

.idioma--pie .idioma__codigo {
  display: inline-block;
}

/* desde 52rem: entre 40 y 52 la cabecera ya lleva Fundadores y el botón, y con los
   códigos se salía 4 px a 640 */
@media (min-width: 52rem) {
  .idioma__codigo {
    display: inline-block;
  }
}

/* a 320 el interruptor medía 145 y empujaba la cabecera contra el borde */

.idioma--pie {
  justify-self: start;
}

.idioma--llega .idioma__opcion[aria-current]::before {
  animation: idioma-llega var(--mov-lento) var(--curva-salida) both;
}

.idioma--llega .idioma__opcion[aria-current]:first-child::before {
  --desde: 100%;
}

.idioma--llega .idioma__opcion[aria-current]:last-child::before {
  --desde: -100%;
}

@keyframes idioma-llega {
  from {
    transform: translateX(var(--desde));
  }
}

@media (prefers-reduced-motion: reduce) {
  .idioma--llega .idioma__opcion[aria-current]::before {
    animation: none;
  }
}

/* el subrayado de la cabecera y del pie crece desde la izquierda al pasar el ratón */
.pie__enlaces a {
  position: relative;
}

@media (hover: hover) {
  .pie__enlaces a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0.5rem;
    height: 1px;
    background: var(--action);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--mov-base) var(--curva-salida);
  }

  

  .pie__enlaces a:hover::after {
    transform: scaleX(1);
  }
}

/* ── RECORTE LATERAL ──────────────────────────────────────────────────────
   La carta que sale a la derecha llega a 1,7 veces su ancho fuera de la mesa.
   Sin esto el documento se ensanchaba hasta 1.087 px en un móvil de 390, y
   Safari en iOS —que no acota el ancho con el overflow del body— reencuadraba
   la página entera durante el gesto: la columna a la mitad y la carta enorme.
   Hacia la izquierda no pasaba porque salir por ese lado no añade ancho.

   `clip` recorta sin crear un contenedor de desplazamiento, así que no rompe
   nada de dentro; `hidden` queda de respaldo para Safari anterior al 16. Va en
   el <main> y no en la mesa para que la carta siga volando hasta el borde de la
   pantalla y no se corte en seco a mitad. */

.recorte {
  overflow-x: hidden;
}

@supports (overflow: clip) {
  .recorte {
    overflow-x: clip;
  }
}

/* ── PORTADA ──────────────────────────────────────────────────────────── */

.portada {
  position: relative;
  display: grid;
  gap: clamp(2.5rem, 1.5rem + 4vw, 4rem);
  padding-block: clamp(1.5rem, 1rem + 3vw, 4.5rem) var(--section);
}

.portada::before {
  /* una retícula de puntos, contenida en la portada: da escala sin decorar */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(circle at 1px 1px, rgba(154, 141, 184, 0.16) 1px, transparent 0);
  background-size: 28px 28px;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.55) 55%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.55) 55%, transparent 100%);
  pointer-events: none;
}

@media (min-width: 60rem) {
  .portada {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    align-items: center;
    min-height: min(52rem, calc(100svh - 5rem));
  }
}

.estado {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: 0.625rem;
  padding: 0.4375rem 0.75rem 0.4375rem 0.625rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-s);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-bright);
  line-height: 1.3;
}

.portada h1 {
  font-size: var(--t-display);
  font-weight: 800;
  line-height: 0.96;
  letter-spacing: -0.042em;
  text-wrap: balance;
}

.portada h1 em {
  font-style: normal;
  color: var(--action);
}

.portada .entradilla {
  max-width: 34rem;
}

/* ── LA CARTA ─────────────────────────────────────────────────────────────
   La carta de persona de la app, con sus medidas y su anatomía: la de
   `src/ui/PersonCard.tsx` y la pantalla 06 del diseño. 330×462, arte de 268 con
   el degradado del avatar, trama diagonal e inicial; presencia arriba; nombre
   sobre el velo; y en el cuerpo, idiomas · franja · región, los juegos con su
   tinte y sus horas, y la línea de qué busca. Los datos son de ejemplo y cada
   carta lo dice. */

.carta {
  position: relative;
  width: min(100%, 20.625rem);
  height: 28.875rem;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
  overflow: hidden;
  isolation: isolate;
}

.carta__arte {
  position: relative;
  flex: none;
  height: 16.75rem;
  overflow: hidden;
}

.carta__arte-capa {
  position: absolute;
  inset: 0;
}

/* la trama del sistema: rayas de 2 px cada 13, a 38°, blancas al 5 % */
.carta__arte-capa::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(128deg, rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 13px);
}

/* ⚠ FUE `.carta__horas` HASTA EL 24-9-2026. La imagen de compartir enseñaba
   «412 H» al lado de cada juego, y la app no guarda horas por juego:
   `PersonCardGame` tiene nombre, tinte, sigla y rango. Ahora lleva el rango, que
   sí existe — y solo en Valorant, que es el único juego del catálogo que los
   declara. La clase la usan las dos fuentes de `herramientas/compartir/`, que no
   son páginas servidas: por eso ningún guardián de la web las miraba. */

.tinte {
  width: 9px;
  height: 9px;
  border-radius: 2px;
}

.tinte--red { background: #ff4655; }
.tinte--teal { background: #0a96aa; }
.tinte--orange { background: #f5a03c; }
.tinte--crimson { background: #a83a5c; }
.tinte--gold { background: #c8a24b; }
.tinte--green { background: #7dbf6a; }
.tinte--steel { background: #7e97ad; }
.tinte--indigo { background: #6a6adf; }
.tinte--magenta { background: #c266a8; }
.tinte--lime { background: #a8c24b; }
.tinte--cyan { background: #4ba8c2; }
.tinte--neutral { background: #8a8aa0; }

/* Los seis artes de avatar de la app (`gradient.avatarArt`), a 150°. */

.arte--blue { background: linear-gradient(150deg, #2e4a6b 0%, #1b2a45 60%, #3a5b7a 100%); }

/* chips sueltos de la página (pasos, fila de sesión) */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  list-style: none;
  padding: 0;
}

.chip {
  display: inline-flex;
  align-items: center;
  min-height: 1.625rem;
  padding: 0 0.5rem;
  background: var(--surface-raised);
  border: 1px solid var(--hairline-accent);
  border-radius: var(--radius-s);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-bright);
  line-height: 1;
}

/* ── LA BARAJA ────────────────────────────────────────────────────────── */

.baraja {
  display: grid;
  justify-items: center;
  gap: 1.25rem;
}

/* El encabezado de la baraja: sin él, en móvil la carta quedaba debajo del enlace
   a los fundadores y se leía como una carta de fundador. */

/* Sin JavaScript no hay baraja: solo la primera carta, quieta. */

/* Las cartas de detrás no enseñan nada de lo que llevan: un dorso, no un avance. */

/* EL REPARTO (portada.js): hasta que la mesa entra en pantalla, las cartas esperan
   escondidas; solo ellas, nunca el titular. Sin movimiento no se esconde nada. */

/* Los sellos que aparecen al arrastrar: dicen qué va a pasar al soltar. */
.sello {
  position: absolute;
  top: 1.125rem;
  z-index: 4;
  padding: 0.375rem 0.625rem;
  border: 2px solid currentColor;
  border-radius: var(--radius-s);
  background: rgba(14, 11, 23, 0.82);
  font-size: 0.875rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0;
  pointer-events: none;
}

.sello--pasar {
  right: 1rem;
  color: var(--ink-soft);
  transform: rotate(8deg);
}

/* El saludo: a la derecha no hay «me gusta», se abre un mensaje. */
.saludo {
  position: absolute;
  left: 0.75rem;
  right: 0.75rem;
  top: 50%;
  z-index: 10;
  margin-top: -4.5rem;
  display: grid;
  gap: 0.5rem;
  padding: 0.875rem;
  background: var(--surface-raised);
  border: 1px solid var(--action);
  border-radius: var(--radius-m);
  opacity: 0;
  transform: translateY(0.75rem);
  transition: opacity var(--mov-base) var(--curva-salida), transform var(--mov-base) var(--curva-salida);
  pointer-events: none;
}

/* mientras el saludo está a la vista, la carta nueva espera en segundo plano:
   el mensaje era para la anterior, no para ésta */

/* la que sale volando no: lleva su contenido hasta que desaparece */

/* ── SECCIONES ────────────────────────────────────────────────────────── */

.seccion {
  padding-block: var(--section);
  border-top: 1px solid var(--hairline-subtle);
}

.seccion__cabeza {
  display: grid;
  gap: 1.25rem;
  margin-bottom: clamp(2.5rem, 1.8rem + 3vw, 4.5rem);
  max-width: 50rem;
}

/* ── CÓMO FUNCIONA ────────────────────────────────────────────────────── */

.pasos {
  display: grid;
  gap: 1rem;
  counter-reset: paso;
  list-style: none;
  padding: 0;
}

@media (min-width: 56rem) {
  .pasos {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.paso {
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: 0.75rem;
  padding: 1.5rem 1.375rem 1.75rem;
  background: var(--bg);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
}

.paso h3 {
  font-size: var(--t-h3);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.015em;
}

.paso p {
  color: var(--ink-soft);
  font-size: var(--t-small);
  line-height: 1.6;
}

/* figura 1: los chips que te describen */

/* figura 2: la carta con sus dos salidas */

/* figura 3: el chat que se abre */

/* «escribiendo», del guion de los pasos (portada.js): encima del sitio de la
   respuesta y fuera del flujo, así que quitarlo no mueve nada */

/* ── JUGAR YA ─────────────────────────────────────────────────────────── */

.jugar {
  display: grid;
  gap: 1.5rem;
  margin-top: 1rem;
  padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
  background:
    linear-gradient(90deg, var(--action) 0 3px, transparent 3px),
    var(--canvas);
}

@media (min-width: 56rem) {
  .jugar {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: 3rem;
  }
}

.jugar h3 {
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.875rem);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.022em;
}

.jugar p {
  color: var(--ink-soft);
}

/* SIN BORDE: esta fila vive DENTRO de `.jugar`, que ya es una caja con el suyo,
   y dos bordes anidados hacen que no se sepa dónde empieza cada cosa. Lo que la
   separa del fondo es su superficie, que es lo que la regla recomienda para
   separar sin meter otra caja. */

/* ── FUNDADORES ───────────────────────────────────────────────────────── */

.fundadores {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 50% at 78% 38%, rgba(190, 123, 255, 0.08), transparent 70%),
    var(--canvas);
}

.hechos {
  display: grid;
  border-top: 1px solid var(--hairline);
  list-style: none;
  padding: 0;
}

.hecho {
  display: grid;
  gap: 0.25rem;
  padding-block: 1.125rem;
  border-bottom: 1px solid var(--hairline);
}

@media (min-width: 36rem) {
  .hecho {
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: 1.5rem;
  }
}

/* Lo que la lista da y lo que no: no es letra pequeña, es un bloque que se lee. */

/* la lente: el mismo arte, un poco más grande, visto solo a través de las bandas */

/* ⚠ EL COSTE DEL CRISTAL ESTÁ AQUÍ, en el modo de fusión (medido el 17-9-2026): al
   arrastrar una carta de cristal el navegador repinta unas 65 veces por gesto frente a
   16 de una carta normal, unas cuatro veces más. No es la refracción: con ella y sin
   ella cuesta lo mismo (pintado 25-39 ms frente a 26-30 ms en 120 movimientos, CPU 4x).
   Si el cristal va a tirones en un móvil, lo primero que se prueba es esto. */

/* LA REFRACCIÓN AL ARRASTRAR (portada.js): lente y facetas se desplazan al revés
   del gesto, hasta 16 px. Para que nunca asome su borde, las dos capas son 24 px
   más anchas por cada lado, y las bandas y el arte se dibujan en el ancho de
   siempre: en reposo la carta es la de antes (medido contra producción: 4 de 255 como
   mucho, redondeo de los degradados). */

/* EL DESTELLO (portada.js): una banda de luz que cruza la lámina una vez al llegar
   arriba. Vive dentro de la carta; en reposo está fuera, a la izquierda. */

/* la lámina sobre la carta entera: tinte, canto y la luz que sigue al puntero */

/* ── POR DENTRO ───────────────────────────────────────────────────────── */

.principio {
  display: grid;
  gap: 0.625rem;
  padding-block: clamp(1.5rem, 1.2rem + 1.2vw, 2.25rem);
  border-bottom: 1px solid var(--hairline);
  counter-increment: principio;
}

@media (min-width: 52rem) {
  .principio {
    grid-template-columns: 4rem minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 2rem;
    align-items: baseline;
  }
}

.principio::before {
  content: counter(principio, decimal-leading-zero);
  font-size: var(--t-label);
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--action);
  font-variant-numeric: tabular-nums;
}

.principio h3 {
  font-size: clamp(1.3125rem, 1.1rem + 0.9vw, 1.875rem);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.principio p {
  color: var(--ink-soft);
}

/* ── LISTA DE ESPERA ──────────────────────────────────────────────────── */

.lista {
  display: grid;
  gap: clamp(2.5rem, 2rem + 3vw, 4.5rem);
}

@media (min-width: 60rem) {
  .lista {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
  }
}

.formulario {
  position: relative;
  display: grid;
  gap: 1.25rem;
  padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
}

.campo {
  display: grid;
  gap: 0.5rem;
}

.campo label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink-bright);
}

.entrada {
  width: 100%;
  min-height: 3.25rem;
  padding: 0 1rem;
  background: var(--bg);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-m);
  font-size: 1.0625rem;
  color: var(--ink);
  transition: border-color var(--mov-rapido) var(--curva-salida), background-color var(--mov-rapido) var(--curva-salida);
}

.entrada::placeholder {
  color: var(--ink-muted);
}

.entrada:hover {
  border-color: var(--ink-muted);
}

.entrada:focus-visible {
  border-color: var(--action);
  outline-offset: 2px;
}

.entrada[aria-invalid="true"] {
  border-color: var(--danger);
}

.entrada:disabled {
  color: var(--ink-soft);
  border-color: var(--hairline);
}

.casilla {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.casilla input {
  -webkit-appearance: none;
  appearance: none;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  background: var(--bg);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-s);
  cursor: pointer;
  transition: background-color var(--mov-rapido) var(--curva-salida), border-color var(--mov-rapido) var(--curva-salida);
}

.casilla input::after {
  content: "";
  width: 0.75rem;
  height: 0.4rem;
  border-left: 2.5px solid var(--action-ink);
  border-bottom: 2.5px solid var(--action-ink);
  transform: translateY(-2px) rotate(-45deg) scale(0);
  transition: transform var(--mov-rapido) var(--curva-salida);
}

.casilla input:checked {
  background: var(--action);
  border-color: var(--action);
}

.casilla input:checked::after {
  transform: translateY(-2px) rotate(-45deg) scale(1);
}

.casilla input[aria-invalid="true"] {
  border-color: var(--danger);
}

.casilla input:disabled {
  opacity: 0.6;
}

.trampa {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.formulario .boton {
  width: 100%;
  overflow: hidden;
}

.boton[aria-busy="true"] {
  cursor: progress;
}

/* enviando: una línea que recorre el borde inferior del botón */
.boton[aria-busy="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 40%;
  background: var(--action-ink);
  animation: enviando 1100ms var(--curva-mesa) infinite;
}

/* el error entra, no tiembla: nada de sacudir el campo */
@keyframes aviso-entra {
  from {
    opacity: 0;
    translate: 0 -4px;
  }
}

@keyframes enviando {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(250%);
  }
}

.boton:disabled:not([aria-busy="true"]) {
  cursor: not-allowed;
}

.aviso {
  display: none;
  gap: 0.625rem;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  padding: 0.75rem 0.875rem;
  border-radius: var(--radius-m);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.aviso[data-estado] {
  display: grid;
}

.aviso::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  margin-top: 0.45rem;
  border-radius: var(--radius-s);
}

.aviso[data-estado="error"] {
  animation: aviso-entra var(--mov-rapido) var(--curva-salida);
  background: rgba(255, 143, 163, 0.08);
  border: 1px solid rgba(255, 143, 163, 0.5);
  color: var(--ink);
}

.aviso[data-estado="error"]::before {
  background: var(--danger);
}

.aviso[data-estado="cargando"] {
  display: none;
}

/* enviado: el formulario deja paso a una confirmación que se lee entera */
.hecho-lista {
  display: grid;
  gap: 0.875rem;
  padding: 0.25rem 0 0.25rem;
}

.hecho-lista[hidden] {
  display: none;
}

.hecho-lista__sello {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  background: var(--action);
  border-radius: var(--radius-m);
  color: var(--action-ink);
}

.hecho-lista__sello svg {
  width: 1.5rem;
  height: 1.5rem;
}

.hecho-lista h3 {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.hecho-lista h3:focus-visible {
  outline-offset: 6px;
}

.hecho-lista p {
  color: var(--ink-soft);
  font-size: var(--t-small);
}

.guardamos {
  font-size: 0.875rem;
  color: var(--ink-muted);
  line-height: 1.55;
}

/* ── PREGUNTAS ────────────────────────────────────────────────────────── */

.preguntas {
  display: grid;
  gap: clamp(2rem, 1.5rem + 3vw, 4rem);
}

@media (min-width: 60rem) {
  .preguntas {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    align-items: start;
  }
}

/* ── PIE ──────────────────────────────────────────────────────────────── */

.pie {
  padding-block: clamp(3rem, 2rem + 4vw, 5rem) 2.5rem;
  border-top: 1px solid var(--hairline);
  background: var(--bg);
  font-size: 0.875rem;
  color: var(--ink-soft);
}

.pie__rejilla {
  display: grid;
  gap: 2.5rem;
}

@media (min-width: 52rem) {
  .pie__rejilla {
    grid-template-columns: minmax(0, 1fr) auto;
  }
}

.pie__marca {
  display: grid;
  gap: 1rem;
  align-content: start;
  max-width: 30rem;
}

.pie__enlaces {
  display: grid;
  gap: 0.25rem;
  list-style: none;
  padding: 0;
  align-content: start;
}

.pie__enlaces a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}

.pie__enlaces a:hover {
  color: var(--action);
}

/* Las guías para buscar grupo (10-10-2026), en la columna de la marca. Los juegos en línea, y cada enlace con su
   alto táctil de 44 px aunque el texto sea pequeño. */
.pie__guias {
  display: grid;
  gap: 0;
}

.pie__guias-titulo {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}

/* EN REJILLA Y NO EN FILA (10-10-2026): en fila, dónde partía la línea dependía del ancho del texto, y con la fuente
   de respaldo partía en otro sitio; al llegar la buena, el pie de /descargar saltaba (fuentes-tarde, CLS 0,009). Con
   columnas de ancho fijo, el corte lo decide la pantalla. 9,5 rem caben «League of Legends» con las dos fuentes. */
.pie__guias ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 0 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pie__guias li a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--ink-muted);
  text-underline-offset: 3px;
}

.pie__guias a:hover {
  color: var(--action);
}

.pie__legal {
  display: grid;
  gap: 0.75rem;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--hairline-subtle);
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--ink-muted);
}

.pie__legal dl {
  display: grid;
  gap: 0 1rem;
}

@media (min-width: 30rem) {
  .pie__legal dl {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.25rem 1rem;
  }
}

.pie__legal dd {
  overflow-wrap: anywhere;
  margin-bottom: 0.375rem;
}

.pie__legal dt {
  color: var(--ink-soft);
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }

  .boton[aria-busy="true"]::after {
    display: none;
  }

  
}

/* ── AJUSTES SIN ATRIBUTO style ───────────────────────────────────────────
   La política de seguridad de contenidos no admite estilos en línea. */

.campos {
  display: grid;
  gap: 1.25rem;
}

.pasos > :nth-child(2) {
  --orden: 1;
}

.pasos > :nth-child(3) {
  --orden: 2;
}

.campos[hidden] {
  display: none;
}

/* ── LA TIRA DE LA GUÍA ────────────────────────────────────────────────────
   Una línea entre dos secciones: rótulo, frase y enlace. No es una sección con su
   fondo porque no compite con ninguna: es un desvío para quien viene por ese juego.
   Va antes de la lista de espera y nunca cerca de la baraja, que es lo que la
   portada tiene que enseñar primero. En móvil se apila y no empuja nada. */
.tira {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding: 1.25rem 0;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

@media (max-width: 39.99rem) {
  .tira {
    gap: 0.5rem;
  }

  
}

/* Los tres tamaños, en puntos: un punto eres tú y los demás son los que faltan. */

/* La carta y la fila de sesión, juntas, cuando la guía habla de la app. */

/* ── LA PRIMERA PANTALLA EN MÓVIL: QUE LA CARTA ASOME ──────────────────────
   Medido el 23-9-2026: la baraja empezaba en el píxel 685 y en NINGÚN móvil llegaba al
   35 % visible, así que ni se repartía ni se veía una carta sin bajar. En el iPhone SE y
   a 320 no asomaba nada. Lo que se ajusta aquí es el aire de la parte de arriba; lo que
   se movió —la instrucción de la baraja, entera— está en el HTML, debajo de las cartas.
   ⚠ El H1 NO se esconde ni pierde contenido: sigue diciendo qué es GAMERLY, que es lo
   único que entiende quien llega de una red social con cinco segundos de paciencia. */
@media (max-width: 40rem) {
  .cabecera {
    padding-block: 0.75rem;
  }

  .portada {
    gap: 1.5rem;
    padding-block: 1rem var(--section);
  }

  

  .portada h1 {
    font-size: 1.875rem;
  }

  .portada .entradilla {
    font-size: 1rem;
  }

  .estado {
    font-size: 0.75rem;
    padding: 0.25rem 0.625rem 0.25rem 0.5rem;
  }

  /* que ni el botón ni el enlace partan palabras: dos líneas limpias ocupan menos que
     dos líneas rotas, y se leen mejor */
  

  

  .baraja {
    gap: 0.875rem;
  }

  

  /* la instrucción, ahora debajo de las cartas: mismo ancho que ellas */
  
}

/* A 320 el titular necesita otro escalón. El rótulo «Pruébala» NO se quita: sin él la
   carta se lee como una de fundador, y eso vale más que los 40 px que ahorraría. */
@media (max-width: 24rem) {
  .portada h1 {
    font-size: 1.625rem;
  }

  .portada .entradilla {
    font-size: 0.9375rem;
  }
}

/* ── El listado de hermandades ───────────────────────────────────────────── */

.hermandades {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 46rem) {
  .hermandades {
    grid-template-columns: 1fr 1fr;
  }
}

.hermandad {
  display: grid;
  gap: 0.625rem;
  align-content: start;
  padding: 1rem 1.125rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-m);
}

/* ── El bloque de líderes ────────────────────────────────────────────────
   Es lo que se ve mientras no hay listado, así que no es un aviso pequeño:
   ocupa lo que ocuparía la lista. */

@media (max-width: 40rem) {
  .forever {
    padding-block-start: 1.5rem;
  }

  

  .hermandad {
    padding: 0.875rem 1rem;
  }
}

/* ── /g/… · la invitación a un grupo ───────────────────────────────────────
   Un solo interruptor, `data-destino` en el <body>, y el CSS esconde lo que
   sobra: sin JavaScript, y sin un estado en el que se vean los dos. */
body[data-destino="lista"] .si-tiendas,
body[data-destino="tiendas"] .si-lista {
  display: none;
}

/* LAS PÁGINAS QUE SIRVEN A LOS DOS IDIOMAS (/g/, /descargar, la 404; 13-10-2026): `js/idioma.js` pone en <html> el del
   navegador antes de pintar, y esto esconde el otro. Sin JavaScript se ven los dos, que es lo que había. El pie bilingüe
   (`pieBilingue()`) es de /i/ también, que marca el idioma en el <body>. */
html[data-idioma="es"] .bilingue [lang="en"],
html[data-idioma="en"] .bilingue [lang="es"],
html[data-idioma="es"] .pie--bilingue [lang="en"],
html[data-idioma="en"] .pie--bilingue [lang="es"],
[data-idioma="es"] .pie--bilingue [lang="en"],
[data-idioma="en"] .pie--bilingue [lang="es"] { display: none !important; }

.invitacion {
  max-width: 40rem;
  padding-block: 3rem 4rem;
}

.invitacion h1 {
  font-size: clamp(1.75rem, 1.25rem + 2.2vw, 2.75rem);
  line-height: 1.12;
  letter-spacing: -0.03em;
  margin: 0.75rem 0 1rem;
}

.invitacion h2 {
  font-size: 1.125rem;
  letter-spacing: -0.01em;
  margin-bottom: 0.5rem;
}

.invitacion p + p {
  margin-top: 1rem;
}

.invitacion__tiendas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.invitacion__pie {
  margin-top: 3rem;
}

.invitacion__botones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* ── El campo del juego en la lista de espera ─────────────────────────────
   El «¿cuál?» solo aparece con «Otro», y lo decide el CSS a partir del atributo
   que pone el script: sin él no habría forma de esconderlo sin estilos en línea,
   que la CSP no admite. */

.opciones {
  display: grid;
  gap: 0.5rem;
}

/* ── /forever, rediseñada el 23-9-2026 ────────────────────────────────────
   Menos texto y dos puertas en vez de tres. Lo que manda el reparto vertical es
   que en el móvil quepan, SIN desplazar: título, línea, las dos puertas y las
   tres fechas. Lo que se añada aquí arriba empuja las puertas fuera. */
.forever {
  /* padding-block, no el atajo: .envoltura pone los márgenes laterales. */
  padding-block: 1.5rem 4rem;
  max-width: 48rem;
}

/* ── Las dos puertas ──────────────────────────────────────────────────────
   Dos columnas también en el móvil: son una elección, y una debajo de otra se
   lee como una lista de enlaces. Son `<a>` a anclas de la misma página. */

.acceso {
  position: relative;
  display: grid;
  gap: 0.25rem;
  align-content: start;
  min-height: 7.5rem;
  padding: 0.875rem 0.875rem 2.5rem;
  color: var(--ink-bright);
  text-decoration: none;
  background: var(--selected);
  border: 1px solid var(--action);
  border-radius: var(--radius-l);
}

@media (prefers-reduced-motion: no-preference) {
  .acceso {
    transition: background-color var(--mov-rapido) var(--curva-salida), border-color var(--mov-rapido) var(--curva-salida);
  }
}

.acceso:hover {
  background: var(--surface-raised);
  border-color: var(--action-hover);
}

/* Pulsado: se hunde y se apaga. Sin `transition` para que no llegue tarde al dedo. */
.acceso:active {
  background: var(--surface-sunken);
  border-color: var(--ink-muted);
  transform: translateY(1px);
  transition: none;
}

.acceso:focus-visible {
  outline: 2px solid var(--action);
  outline-offset: 3px;
}

/* La flecha es de la casa, dos trazos: un icono de stock aquí desentonaría. */

/* ── Las tres fechas, en una fila ─────────────────────────────────────────
   Compactas porque van en la primera pantalla. El «faltan X días» lo escribe
   `forever.js`, y solo en la SIGUIENTE: en las pasadas sobra. */
/* Sitio reservado para el «faltan X días» que escribe forever.js: son 22 px
   medidos, y sin reservarlos la fila crece al cargar y la página da un salto
   —CLS 0,007 en vez de 0—. Lo mismo a 320, donde esa línea ocupa dos. */
.fechas {
  min-height: 4.875rem;
  display: flex;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ── Qué es GAMERLY: tres frases ──────────────────────────────────────── */

/* ── La guía, plegada ─────────────────────────────────────────────────────
   `<details>` de serie: abre sin JavaScript y lo de dentro se sigue pudiendo
   buscar en la página. */
.guia {
  margin-top: 3rem;
  border-top: 1px solid var(--hairline);
}

/* El triángulo, dibujado: el de serie no se puede teñir en todos los navegadores. */

.guia h3 {
  margin: 2rem 0 0.5rem;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.guia p {
  color: var(--ink-soft);
  max-width: 38rem;
}

.guia p + p {
  margin-top: 0.625rem;
}

/* A 320 la primera pantalla mide 568 px y la fila de fechas se salía por 53.
   Medido, no tanteado: se recorta de donde sobra —cabecera, titular, línea y
   tarjetas—, y el `> .rotulo` es a propósito, para no tocar el de «para líderes»
   ni el de las demás páginas. */
@media (max-width: 24rem) {
  

  .forever > .rotulo {
    font-size: 0.6875rem;
  }

  

  

  

  .acceso {
    min-height: 6.5rem;
    padding: 0.75rem 0.75rem 2.125rem;
  }

  

  

  

  

  .fechas {
    min-height: 5.5rem;
  }
}

/* El botón «ya la tengo» solo existe si el id de la URL casa con su forma, así
   que su hueco nace oculto y lo destapa `js/grupo.js`. */
.invitacion__tengo {
  margin-top: 1rem;
}

/* ── El QR de la invitación ───────────────────────────────────────────────
   Solo en pantallas anchas: quien lee el listado en un foro está en el PC y no
   puede instalar nada ahí. En el móvil no aparece —`js/grupo.js` ni siquiera
   descarga la librería— y se quedan los botones. */
.qr {
  display: none;
}

@media (min-width: 48rem) {
  .qr:not([hidden]) {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    width: max-content;
    margin-top: 2.5rem;
    padding: 1.25rem;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-m);
  }
}

/* El dibujo lleva su propio blanco: un QR sobre fondo oscuro lo lee la mitad de
   los móviles y la otra mitad no. El redondeo es del marco, no del código. */
.qr svg {
  display: block;
  border-radius: var(--radius-s);
}

.qr__texto {
  max-width: 15rem;
  font-size: 0.8125rem;
  line-height: 1.35;
  text-align: center;
  color: var(--ink-soft);
}

.qr__texto + .qr__texto {
  margin-top: -0.375rem;
  color: var(--ink-muted);
}

/* El botón del grupo va debajo de la ficha, no entre los chips: es una acción,
   y una acción entre datos se lee como un dato más. */

/* En escritorio el QR es LA respuesta —no puedes instalar nada aquí—, así que va
   al lado de las acciones y no al final: al final hay que buscarlo, y quien no lo
   encuentra se queda sin saber qué hacer con el enlace. */
@media (min-width: 48rem) {
  .invitacion {
    max-width: 62rem;
  }

  /* El sitio del QR se RESERVA con padding y el QR va encima, posicionado. Con
     un flotante el texto se recolocaba al aparecer el dibujo —CLS 0,106, por
     encima del umbral—: la librería tarda en llegar y la reserva tiene que
     existir antes. Si el QR no llega a pintarse, ahí queda un margen y ya. */
  .invitacion {
    position: relative;
    padding-right: 17.5rem;
  }

  .invitacion > .qr:not([hidden]) {
    position: absolute;
    top: 0.5rem;
    right: 0;
    width: 14.5rem;
  }
}

/* ╔══════════════════════════════════════════════════════════════════════════╗
   ║  EL SISTEMA · lo que era `sistema.css` hasta el 29-9-2026                  ║
   ╚══════════════════════════════════════════════════════════════════════════╝

   Era una hoja aparte «para que no la descargara quien lee los términos», pero
   desde que todas las páginas llevan el sistema la cargaban TODAS, siempre
   detrás de esta: dos peticiones para una hoja partida en dos. Va aquí, en el
   mismo orden, así que la cascada es la misma. */

/* ╔══════════════════════════════════════════════════════════════════════════╗
   ║  EL SISTEMA · la carta, la baraja, la barra, los botones y /forever      ║
   ╚══════════════════════════════════════════════════════════════════════════╝

   ═══ EL MOVIMIENTO ═══

   Todo es `transform` u `opacity`. Nada toca `layout` ni `filter`. Las
   duraciones y las curvas son los tokens `--mov-*` y `--curva-*` de `:root`.

   Las animaciones infinitas se paran solas cuando su sección sale de pantalla:
   `forever.js` quita `.fv-vivo` y aquí todo lo infinito cuelga de esa clase. Sin
   JavaScript no hay `.fv-vivo` en ninguna parte, así que la página queda quieta
   y completa, que es exactamente lo que tiene que pasar.

   ═══ LOS TOKENS ═══

   Los de la entrega viven en `.fv`, que desde el 23-9-2026 lleva el `<body>` de
   todas las páginas. */

.fv {
  --fv-bg: #14101F;
  --fv-surface: #1D1730;
  --fv-surface-2: #29203F;
  --fv-line: #2A2140;
  --fv-line-2: #3B2F5B;
  --fv-line-3: #4A3A6B;
  --fv-ink: #F3EFFA;
  --fv-ink-2: #D8CFEA;
  --fv-ink-3: #B3A6CC;
  --fv-ink-4: #8E86A8;
  --fv-ink-5: #9A8DB8;
  --fv-action: #BE7BFF;
  --fv-action-ink: #1A1030;

  /* Tintes de juego, de theme.ts */
  --fv-teal: #0A96AA;
  --fv-teal-luz: #8FD9E4;
  --fv-indigo: #6A6ADF;
  --fv-orange: #F5A03C;
  --fv-orange-luz: #FFC98A;
  --fv-magenta: #C266A8;
  --fv-lime: #A8C24B;
  --fv-crimson: #D64545;
  --fv-online: #8FE388;

  /* web.* — los nuevos de la entrega */
  /* Lo que baja la última carta del mazo, y lo que el mazo reserva por debajo
     para que quepa. Un solo número: ver `.fv-baraja__frente`. */
  --fv-mazo-hondo: 20px;
  --fv-gold-art: linear-gradient(160deg, #F2D27A 0%, #D4A73E 38%, #9C7424 78%, #6E5118 100%);
  --fv-gold-edge: rgba(255, 226, 150, 0.85);
  --fv-gold-panel: linear-gradient(180deg, #3A2F22, #221A2E 60%, #1D1730);
  --fv-gold-tile: rgba(212, 167, 62, 0.22);
  --fv-gold-tile-edge: rgba(255, 226, 150, 0.45);
  --fv-gold: #D4A73E;
  --fv-slot: rgba(190, 123, 255, 0.07);
  --fv-slot-edge: rgba(190, 123, 255, 0.5);
  --fv-slot-ink: #C9B8F0;
  --fv-example: #E88B8B;
  --fv-stamp: #8FE388;

  background: var(--fv-bg);
  color: var(--fv-ink);
}

/* Las anclas caen bajo la barra, que mide 48. */
.fv :target,
.fv [id] {
  scroll-margin-top: 56px;
}

/* ── Tipografía de la página ─────────────────────────────────────────────── */

.fv-h1 {
  margin: 0;
  font-size: 2.375rem;
  line-height: 2.5rem;
  font-weight: 800;
  /* Era −0,045em: las letras se tocaban y los puntos flotaban (auditoría, 29-9-2026). */
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.fv-linea {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.375rem;
  color: var(--fv-ink-2);
  max-width: 46ch;
  text-wrap: pretty;
}

.fv-parrafo {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.375rem;
  color: var(--fv-ink-2);
  text-wrap: pretty;
}

.fv-nota {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.125rem;
  color: var(--fv-ink-3);
  text-wrap: pretty;
}

/* UN AVISO VACÍO NO ES UNA CAJA VACÍA: NO ES NADA. `#estado-lista` nace sin
   texto y lo rellena el envío, así que sin esto el formulario enseña un recuadro
   hueco encima del botón — y un recuadro hueco parece un fallo de carga. */
.fv-aviso:empty { display: none; }

.fv-aviso {
  margin: 0;
  padding: 0.75rem 0.875rem;
  border: 1px solid var(--fv-line-2);
  border-radius: var(--radius-l);
  background: var(--fv-bg);
  font-size: 0.8125rem;
  line-height: 1.25rem;
  color: var(--fv-ink-2);
  text-wrap: pretty;
}

.fv-seccion {
  padding: 2.5rem 1.125rem 2.25rem;
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1.125rem;
}

/* ── La barra ────────────────────────────────────────────────────────────── */

.fv-barra {
  position: sticky;
  top: 0;
  z-index: 5;
  height: 48px;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0 1.125rem;
  border-bottom: 1px solid #221B38;
  background: var(--fv-bg);
}

.fv-barra__marca {
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  color: var(--fv-ink);
  text-decoration: none;
}

.fv-barra__raya {
  width: 1px;
  height: 16px;
  background: var(--fv-line-2);
}

/* EL INTERRUPTOR DE IDIOMA Y LA ACCIÓN, que llevan todas las páginas desde el
   23-9-2026. `margin-left: auto` va en el idioma: empuja los dos a la derecha y
   deja la marca —y el juego, si lo hay— a la izquierda. */
.fv-barra__idioma {
  margin-left: auto;
  min-height: 44px;
  display: flex;
  align-items: center;
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--fv-ink-2);
  text-decoration: none;
}

.fv-barra__idioma:hover { color: var(--fv-ink); }

.fv-barra__accion {
  flex: none;
  white-space: nowrap;
  height: 32px;
  padding: 0 0.6875rem;
  display: flex;
  align-items: center;
  border-radius: var(--radius-m);
  border: 1px solid #7A5FA8;
  font-size: 0.75rem;
  font-weight: 700;
  color: #E8DEFF;
  text-decoration: none;
}

.fv-barra__accion:hover { background: var(--fv-surface-2); color: var(--fv-ink); }

/* EN 320 PX NO CABE TODO, Y LO QUE SE ACORTA ES LA ACCIÓN: es lo único que se
   puede acortar sin perder nada, porque a dónde lleva se ve al tocarla. Las dos
   están en el árbol y el CSS enseña una; una segunda barra para móvil se
   separaría de ésta a la primera corrección. */
.fv-barra__corta { display: none; font-style: normal; }

@media (max-width: 22.5rem) {
  .fv-barra__larga { display: none; }
  .fv-barra__corta { display: inline; }
}

/* El hueco del «faltan X días» existe aunque el texto no: lo escribe el script
   y sin reservarlo la página daría un salto al cargar. */

/* ── «Otro» ─────────────────────────────────────────────────────────────────
   Es el único juego que no sale del catálogo —es lo que el visitante escriba—, así que lleva el violeta de
   marca y no un tinte de juego. Aquí vivía la carta `.ca` de antes; se fue el 9-10-2026 con sus notas, que
   eran de reglas ya borradas. La carta de ahora es la Lima (`carta.css`). */
.tinte--otro { background: #be7bff; }

/* ── El listado ──────────────────────────────────────────────────────────── */

.fv-boton {
  min-height: 52px;
  border: 0;
  border-radius: var(--radius-l);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0 1rem;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 800;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
  transition: transform var(--mov-rapido) var(--curva-salida);
}

/* LOS TRES NIVELES DEL SISTEMA, y ninguno se parece a un botón apagado:
     relleno  — la acción de la pantalla;
     suave    — la de al lado, con filete y fondo transparente;
     solo texto — la que no compite con nada.
   «Añadir otra» iba en relleno gris y se leía como desactivado, que es el peor
   sitio donde puede acabar una acción que sí funciona. */
.fv-boton--claro { background: var(--fv-ink); color: var(--fv-bg); }
.fv-boton--accion { min-height: 56px; background: var(--fv-action); color: var(--fv-action-ink); font-size: 1.0625rem; }

.fv-boton:active { transform: scale(.98); transition: none; }
.fv-boton:focus-visible { outline: 3px solid var(--fv-action); outline-offset: 3px; }

/* LA MESA NO SE QUEDA CON EL SCROLL. `pan-y` deja el desplazamiento vertical al
   navegador y solo se reserva el horizontal, que es el del gesto. Sin esto, un
   dedo que baja por encima de la carta no mueve la página, y eso en un móvil se
   siente como que la web se ha colgado. */
/* ⚠ `[hidden]` NO GANA A UN `display` DE AUTOR, Y ESTO CIERRA LA CLASE ENTERA.
   La regla del navegador es `display: none` con la especificidad de un selector
   de tipo, así que cualquier `.mi-clase { display: flex }` la pisa y el elemento
   se queda a la vista con el atributo puesto. Pasó DOS veces en esta hoja —el
   bloque de «Recibida» y el texto de captación— y la segunda con el arreglo de
   la primera ya escrito: taparlo caso por caso no cierra nada, porque el
   siguiente `display` que alguien escriba vuelve a abrirlo.

   `!important` aquí es lo correcto y no un atajo: `hidden` significa «esto no
   está», y no hay ningún caso en el que un `display` deba poder discutirlo. */
.fv [hidden] { display: none !important; }

/* Los botones de la baraja, igual: con la baraja en la primera pantalla, que
   aparecieran al cargar el script subía la columna entera (CLS 0,004 en escritorio). */
.js #demo-botones[data-js-muestra][hidden] { display: grid !important; }

/* Para quien escucha la página y no la ve: el anuncio de qué carta ha entrado.
   No se puede esconder con `display:none` ni con `hidden` —entonces tampoco lo
   lee el lector de pantalla—, así que se saca del dibujo sin sacarlo del árbol. */
.fv-visualmente-oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── LA PILA ────────────────────────────────────────────────────────────────
   Las cartas se apilan de verdad —todas en la MISMA celda de una rejilla— para
   que la que sale pueda pasar por detrás de las demás y volver al fondo. Antes
   era una sola carta con las otras `hidden`, y así no hay fondo al que volver.

   ⚠ REJILLA Y NO POSICIÓN ABSOLUTA. Con `absolute` la pila no tendría alto
   propio y habría que dárselo fijo — que es exactamente el derrame que la caja
   del abanico costó el 24-9-2026. Con `grid-area: 1/1` todas ocupan la misma
   celda y la pila mide lo que la más alta, sola. */

/* ⚠ HASTA EL REPARTO, LA MESA ESTÁ VACÍA, y solo con JS y con movimiento (el
   reparto está en `baraja.js`). El seguro: si el script no corre, a los cuatro
   segundos la animación de espera acaba y las cartas se ven quietas. */

@keyframes fv-espera-reparto { from { visibility: hidden; } to { visibility: visible; } }

/* LAS DE DETRÁS ENSEÑAN SU MARCO Y SU FONDO, Y NADA DE DENTRO (30-9-2026): como
   en la app, el mazo no adelanta la carta que viene. Asomando se leían trozos de
   la siguiente («MIN», «COMÚN»), y más con el mazo abierto del hero. El contenido
   se enciende al subir a la cima. */

[data-pos="0"] { z-index: 3; transform: none; opacity: 1; }
/* Las dos poses de atrás son variables para que un sitio pueda abrir el mazo (el
   hero de la portada lo abre en abanico). `baraja.js` lee `--fv-pos2` para que la
   carta que vuelve al fondo aterrice justo ahí. */

[data-pos="1"] { z-index: 2; transform: var(--fv-pos1); opacity: .9; }
[data-pos="2"] { z-index: 1; transform: var(--fv-pos2); opacity: .6; }

/* Las que esperan su turno no se ven y no se tocan: quedan donde acaba el mazo,
   así que la que vuelve al fondo aterriza justo ahí y no da un salto. */
[data-pos="oculta"] {
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  transform: var(--fv-pos2);
}

.fv-arrastrando {
  transition: none;
  cursor: grabbing;
}

/* ── Los sellos del gesto ───────────────────────────────────────────────────
   Aparecen con el arrastre, cada uno por su lado y con la inclinación contraria
   a la carta, como un sello puesto a mano. Son lo que dice qué va a pasar antes
   de soltar: con ellos el gesto no necesita instrucciones. */
.fv-sello-gesto {
  position: absolute;
  /* Debajo de la fila de insignias, no a su altura: a 18 px el sello de PASAR se
     montaba encima de la etiqueta EJEMPLO y se leían los dos a la vez. */
  top: 64px;
  z-index: 3;
  padding: 6px 12px;
  border-radius: var(--radius-m);
  border: 2px solid currentColor;
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  opacity: 0;
  pointer-events: none;
}

/* EL SELLO SALE POR EL LADO CONTRARIO AL QUE VA LA CARTA: arrastrando a la
   derecha aparece a la izquierda, que es donde el pulgar no lo tapa. */
.fv-sello-gesto--saludar {
  left: 18px;
  color: var(--fv-online);
  transform: rotate(-10deg);
}

.fv-sello-gesto--pasar {
  right: 18px;
  color: var(--fv-ink-3);
  transform: rotate(10deg);
}

/* ── LA CASILLA, LA TRAMPA Y EL SELLO ──────────────────────────────────────
   Tres piezas de formulario que el sistema no tenía porque /forever no pide
   consentimiento: su formulario es para publicar una hermandad, no para guardar
   un dato personal. La lista de espera sí, y la casilla es lo que hace que ese
   dato se pueda guardar (§13). Viven aquí y no en la portada porque cualquier
   formulario que pida un correo va a necesitarlas. */

.fv-form__campos {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}

.fv-casilla {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--fv-ink-2);
  cursor: pointer;
}

/* El cuadro se dibuja a mano porque el del sistema operativo no se puede teñir,
   y en una superficie oscura sale blanco de fábrica. `appearance: none` deja el
   control vivo —foco, teclado, `:checked`— y solo cambia su pintura. */
.fv-casilla input {
  -webkit-appearance: none;
  appearance: none;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
  background: var(--fv-bg);
  border: 1.5px solid var(--fv-ink-5);
  border-radius: var(--radius-m);
  cursor: pointer;
  transition: background-color var(--mov-rapido) var(--curva-salida), border-color var(--mov-rapido) var(--curva-salida);
}

.fv-casilla input::after {
  content: "";
  width: 0.75rem;
  height: 0.4rem;
  border-left: 2.5px solid var(--fv-action-ink);
  border-bottom: 2.5px solid var(--fv-action-ink);
  transform: translateY(-2px) rotate(-45deg) scale(0);
  transition: transform var(--mov-rapido) var(--curva-salida);
}

.fv-casilla input:checked { background: var(--fv-action); border-color: var(--fv-action); }
.fv-casilla input:checked::after { transform: translateY(-2px) rotate(-45deg) scale(1); }
.fv-casilla input[aria-invalid="true"] { border-color: #FFB3B3; }
.fv-casilla input:focus-visible { outline: 2px solid var(--fv-ink); outline-offset: 2px; }

/* LA TRAMPA. Fuera de pantalla y no `display: none`: un robot que rellena
   formularios lee el árbol, y lo que está oculto del todo lo salta. Esto lo ve
   él y no lo ve nadie más. */
.fv-trampa {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.fv-hecho__sello {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  background: var(--fv-action);
  border-radius: var(--radius-l);
  color: var(--fv-action-ink);
}

.fv-hecho__sello svg { width: 1.5rem; height: 1.5rem; }

/* ── EL FINAL DEL MAZO ─────────────────────────────────────────────────────
   Ocupa el hueco de la carta —misma caja, mismo sitio— para que no salte nada al
   aparecer. Va en violeta de marca y no en un tinte de juego: no es la carta de
   nadie, es el cierre. */
.fv-fin {
  position: relative;
  width: 100%;
  max-width: 318px;
  min-height: 400px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.875rem;
  border-radius: 12px;
  padding: 2px;
  background: linear-gradient(150deg, #B9A6FF, #5E48B8);
  animation: fvEntraFin var(--mov-base) var(--curva-salida) both;
}

/* El relleno va en un pseudoelemento y no en un hijo: el degradado del marco es
   el fondo de la caja, y esto lo tapa por dentro dejando los dos pixeles del
   canto. Un hijo más en el HTML para esto es una caja que no significa nada. */
.fv-fin::before {
  content: "";
  position: absolute;
  inset: 2px;
  border-radius: 10px;
  background: linear-gradient(180deg, #2A2150, #1D1730);
}

.fv-fin > * {
  position: relative;
  z-index: 1;
}

.fv-fin__texto {
  margin: 1.375rem 1.375rem 0;
  font-size: 1.5rem;
  line-height: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.05rem;
  text-wrap: balance;
}

.fv-fin .fv-boton {
  margin: 0 1.375rem;
  text-decoration: none;
}

.fv-fin__otra {
  margin: 0 1.375rem 1.375rem;
  height: 44px;
  border-radius: 8px;
  border: 1px solid #7A5FA8;
  background: transparent;
  color: #E8DEFF;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  cursor: pointer;
}

.fv-fin__otra:focus-visible { outline: 2px solid var(--fv-ink); outline-offset: 2px; }

@keyframes fvEntraFin {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .fv-fin { animation: none; }
}

/* ── Los cien ────────────────────────────────────────────────────────────── */

/* ── LA BARAJA ───────────────────────────────────────────────────────────── */

/* ── El cierre ───────────────────────────────────────────────────────────── */

/* ⚠ AQUÍ IBAN `.fv-hecho { grid-area: hecho }` y `.fv-hecho__titulo { grid-area: titulo }`, del bloque de líderes de la
   /forever vieja (17-10-2026). Sin un `grid-template-areas` que las nombrara, en la rejilla del formulario de la portada
   cada una abría una columna implícita: «Ya estás en la lista» se pintaba partido en columnas estrechas. Fuera. */

/* ── Los campos ───────────────────────────────────────────────────────────── */

.fv-campo {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  min-width: 0;
}

/* El contacto va aparte y más abajo: no se publica, y pedirlo con el mismo peso
   que el nombre hace que el formulario parezca un trámite. */

.fv-campo__nombre {
  padding: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--fv-ink-2);
}

.fv-campo__opcional {
  margin-left: 0.25rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fv-ink-4);
}

.fv-entrada {
  width: 100%;
  min-height: 48px;
  padding: 0 0.875rem;
  border-radius: var(--radius-l);
  border: 1px solid var(--fv-line-2);
  background: var(--fv-bg);
  color: var(--fv-ink);
  font-family: inherit;
  font-size: 1rem;
}

.fv-entrada::placeholder { color: var(--fv-ink-4); }

.fv-entrada:focus-visible {
  outline: 2px solid var(--fv-action);
  outline-offset: 1px;
  border-color: transparent;
}

/* El campo con error se marca en ROJO, no con el lila del foco: el lila dice
   «estás aquí» y el rojo «esto está mal», y con los dos a la vez no se sabe. */
.fv-entrada[aria-invalid="true"] { border-color: var(--fv-crimson); }

.fv-campo__pista {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.125rem;
  color: var(--fv-ink-4);
}

/* ── La casilla y el envío ────────────────────────────────────────────────── */

.fv-enlace {
  color: var(--fv-ink);
  text-underline-offset: 2px;
}

/* ── «Recibida» ───────────────────────────────────────────────────────────── */

.fv-hecho {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  align-items: flex-start;
}

/* El foco aterriza en el TÍTULO, no en el bloque: un contorno alrededor de todo
   el bloque se lee como otra caja, que es justo lo que este estado no puede
   tener. Y tiene que aterrizar en algo, o quien navega con teclado se queda
   donde estaba el botón que ya no existe. */
/* El contorno abraza la PALABRA, no el ancho del bloque: un párrafo ocupa toda
   la línea, así que el foco dibujaba un rectángulo de lado a lado que se leía
   como otra caja — justo lo que este estado no puede tener. */
.fv-hecho__titulo {
  width: fit-content;
}

.fv-hecho__titulo:focus-visible {
  outline: 2px solid var(--fv-action);
  outline-offset: 6px;
  border-radius: var(--radius-s);
}

.fv-hecho__titulo {
  margin: 0;
  font-size: 1.5rem;
  line-height: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

/* El cambio en la ficha se nota, y es lo único que se mueve aquí. */
@keyframes fv-ficha-cambia {
  from { background-color: rgba(190, 123, 255, 0.28); }
  to { background-color: transparent; }
}

.fv-form { display: flex; flex-direction: column; }
.fv-form .campos { display: flex; flex-direction: column; gap: 0.75rem; }

.fv-tiendas { display: flex; flex-direction: column; gap: 0.5rem; }

/* El interruptor: A (lista de espera) o B (tiendas). Sin JavaScript, igual. */
.fv[data-destino="lista"] .si-tiendas,
.fv[data-destino="tiendas"] .si-lista { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   ESCRITORIO
   ══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 60rem) {
  .fv-barra { padding: 0 3rem; }

  

  
  
  

  .fv-h1 { font-size: 4rem; line-height: 4rem; letter-spacing: -0.022em; }
  

  /* El aire de los lados, en las secciones que lo llevan a mano. */
  .fv-seccion { padding-inline: 3rem; }

  
  .fv-tiendas { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   EL MOVIMIENTO
   Todo cuelga de `.fv-vivo`, que pone y quita `forever.js` según la sección
   esté en pantalla. Sin JavaScript no hay `.fv-vivo`: la página queda quieta.
   ══════════════════════════════════════════════════════════════════════════ */

/* Sin JavaScript no hay botones de demo: la carta de ejemplo se queda quieta,
   que es lo que puede enseñar una página estática. */
.js #demo-botones { display: grid; }

@media (prefers-reduced-motion: reduce) {
  .fv *,
  .fv *::before,
  .fv *::after {
    animation: none !important;
    transition: none !important;
  }

  
}

/* ══════════════════════════════════════════════════════════════════════════
   320 px
   ══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 22.5rem) {
  .fv-h1 { font-size: 2rem; line-height: 2.125rem; }
  .fv-linea { font-size: 0.875rem; line-height: 1.25rem; }
  
  
  
  
  
  
}

/* ╔══════════════════════════════════════════════════════════════════════════╗
   ║  LOS ESTANDARTES · la campaña de /forever (30-9-2026)                     ║
   ╚══════════════════════════════════════════════════════════════════════════╝

   Sustituye al tablón de papel del 29-9 (decisión del desarrollador: el papel
   crema no pegaba con una web oscura, y /forever parecía otra web). La página es
   OSCURA como la portada —el mismo lienzo, las mismas superficies, la misma letra
   de texto— y lo medieval lo ponen los OBJETOS, con piezas que no son de nadie:
   cada hermandad es un ESTANDARTE colgado de su vara —su sigla como blasón, su
   facción en el color de la tela, su ritmo como marca, sus modos como insignias—
   y la fecha de comprobación es un SELLO al pie.

   ⚠ NADA DE BLIZZARD, y se descartó con nombre: los emblemas de facción (un león,
   un puño, cualquier cresta: aquí la facción es SOLO el color de la tela), el marco
   de piedra con filigrana dorada de su interfaz, las esquinas ornamentadas, el
   pergamino, las texturas de piedra o metal y cualquier letra que imite su rótulo.
   Alegreya es una serifa de libro, y solo en los titulares. Si una pieza se parece
   a una captura del juego, fuera.

   EL COLOR LO PONE EL JUEGO: el oro es `#C8A24B`, el `gold` que la app le da a WoW
   Forever (`tintFor`, fijado en `TINT_EXCEPTIONS`; lo vigila la fila
   `tintes-lanzamiento`), y es el único acento. Azul y rojo son de las facciones y
   solo están en las telas y en sus pestañas. La mesa no brilla: ni degradados de
   sección ni brillos radiales, y la poca luz que hay vive en la vara y el sello.

   Todo cuelga de `.fv-heraldica`, en el `<body>` de las dos /forever. */

@font-face {
  font-family: "Alegreya";
  font-style: normal;
  font-weight: 700;
  /* Alegreya 700, licencia OFL (herramientas/fuentes-licencias), recortada al
     mismo juego de caracteres que la sans: 18 KB. */
  src: url("/fuentes/alegreya-700.woff2") format("woff2");
  font-display: optional;
}

/* ── «CUELGA TU ESTANDARTE»: al enviar, sube a su vara y queda colgado ───────
   El sello NO es el de oro: dice «pendiente de comprobar», en tinta, porque es
   verdad —se comprueba antes de publicarla— y el oro es de lo comprobado. */

@keyframes fv-iza {
  from { transform: translateY(-1.5rem) rotate(-3deg); }
  55% { transform: rotate(1.2deg); }
  to { transform: none; }
}

@keyframes fv-sella {
  from { transform: rotate(-20deg) scale(1.6); opacity: 0; }
  to { transform: rotate(-8deg) scale(1); opacity: 1; }
}

/* ═══ EL MOMENTO DE LA PÁGINA: EL LISTADO SE CUELGA ═════════════════════════
   Uno solo, y es este: cada estandarte baja desde su vara y se asienta según
   entra en pantalla. Ligado al scroll con CSS (`view()`), sin JavaScript y sin
   nada escondido esperando: donde el navegador no lo sabe hacer, o si alguien
   pidió menos movimiento, los estandartes ya están colgados y quietos. Los que
   están en pantalla al cargar ya han entrado, así que salen en su sitio. */

@keyframes fv-cuelga {
  from { transform: translateY(-1.25rem) rotate(-2.5deg); }
  60% { transform: rotate(0.8deg); }
  to { transform: none; }
}

/* ── LAS PUERTAS DEL LISTADO: los estandartes se recolocan ───────────────────
   Con View Transitions y solo si nadie ha pedido menos movimiento: lo decide
   `forever.js`. Sin ellas, el cambio es seco. */

::view-transition-group(*) {
  animation-duration: var(--mov-base);
  animation-timing-function: var(--curva-mesa);
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

