/* Escanea y Juega · sistema visual (DEC-0015, principios de Máximo: 06 Guías/Principios de diseño).
   Regla: las pantallas usan SOLO estas variables y componentes. Si falta algo, se añade aquí (y antes en el
   Design System, DEC-0032). Dos modos (claro y oscuro) y cuatro tamaños de letra: los elige el servidor en
   <html data-tema data-letra> (DEC-0039). El contraste AA de los dos modos lo comprueba test/test_estilo.py.
*/

/* Letras (DEC-0039), desde nuestro servidor (licencia OFL en estaticos/letras/): variables y solo el juego «latin»,
   que trae todo el español, el € y las comillas « ». Mientras llegan se ve la del sistema (font-display: swap). */
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("letras/atkinson-hyperlegible-next.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("letras/bricolage-grotesque.woff2") format("woff2");
  font-weight: 600 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Caveat";
  src: url("letras/caveat.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light;
  /* Neutros: fondos, superficies y texto */
  --color-fondo: #faf8f5;          /* blanco cálido, descansa la vista */
  --color-superficie: #ffffff;
  --color-texto: #1f2328;
  --color-texto-secundario: #5b616b;
  --color-linea: #e7e3dc;          /* separadores suaves */
  --color-borde-control: #858a93;  /* bordes de campos y huecos vacíos: ≥ 3:1 también sobre acento-suave (DS v6) */

  /* Acción principal: un solo color, solo para lo importante */
  --color-principal: #c2410c;
  --color-principal-hover: #9a3412;
  --color-principal-suave: #fff1e8;

  /* Tinta del sello de la base común (Design System J&G, DEC-0032): caramelo */
  --color-acento: #8a4b0f;          /* 6,4:1 sobre el fondo */
  --color-acento-oscuro: #6e3b0b;   /* 8,2:1 sobre acento-suave */
  --color-acento-suave: #fdf1de;

  /* Fondo del círculo de cada figura 3D según el tipo de local (decorativo, sin texto encima) */
  --color-avatar-cafeteria: #fdf1de;
  --color-avatar-pasteleria: #fff7e0;
  --color-avatar-churreria: #fff1e8;
  --color-avatar-heladeria: #fdeaea;
  --color-avatar-otro: #efe9df;      /* cualquier otro negocio (DEC-0049): piedra cálida, como su acera */

  /* Estados: solo para comunicar estados (texto oscuro sobre fondo claro) */
  --color-exito: #166534;       --color-exito-fondo: #ecfdf3;
  --color-advertencia: #92400e; --color-advertencia-fondo: #fffbeb;
  --color-info: #1e40af;        --color-info-fondo: #eff6ff;
  --color-error: #991b1b;       --color-error-fondo: #fef2f2;

  /* Letras del Design System: el texto, muy legible (pensada para baja visión); los títulos, con carácter; y un
     guiño a mano. Si aún no han llegado, la del sistema. */
  --letra: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --letra-titulos: "Bricolage Grotesque", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --letra-mano: Caveat, "Segoe Print", "Bradley Hand", cursive;
  --texto-base: 1.0625rem;   /* 17 px: cómodo en móvil */
  --texto-pequeno: 0.9375rem;
  --titulo-1: clamp(2rem, 6vw, 2.75rem);
  --titulo-2: 1.375rem;

  /* Espacios (múltiplos de 4 px) */
  --espacio-1: 0.25rem;
  --espacio-2: 0.5rem;
  --espacio-3: 0.75rem;
  --espacio-4: 1rem;
  --espacio-5: 1.5rem;
  --espacio-6: 2rem;
  --espacio-7: 3rem;

  /* Formas: sutiles y coherentes */
  --radio: 12px;
  --radio-control: 10px;
  --sombra: 0 1px 2px rgb(31 35 40 / 0.06), 0 1px 1px rgb(31 35 40 / 0.04);
  --transicion: 150ms ease;
  --objetivo-tactil: 48px;
  --radio-grande: 20px;
  --sombra-barra: 0 -1px 0 rgb(31 35 40 / 0.06), 0 -8px 20px rgb(31 35 40 / 0.07);
  --sombra-destacada: 0 1px 2px rgb(31 35 40 / 0.06), 0 6px 18px rgb(154 52 18 / 0.08); /* «Añade un local» */
  --sombra-logo: 0 4px 6px rgb(154 52 18 / 0.25);  /* el sello 3D del centro de la barra (drop-shadow) */
  --color-sobre-principal: #ffffff;   /* texto del botón principal (5,2:1) */
  --color-marca-mostaza: #f2a900;     /* anillo del logo J&G: solo decoración, nunca texto (DS) */
  --color-marca-crema: #fff6e5;       /* fondo del icono de la app (DS, «AppMovil»): solo decoración */
  --color-qr-fondo: #ffffff;          /* el QR del mostrador, siempre oscuro sobre blanco: lo que leen las cámaras */
  /* El cartel del local (DS, «Cartel»; DEC-0047): es papel, igual de día y de noche, y se lee en blanco y negro */
  --color-papel: #ffffff;
  --color-papel-texto: #1f2328;       /* 15,8:1 */
  --color-papel-secundario: #5b616b;  /* la dirección bajo el QR y la línea de cortar (6,2:1) */
  --color-papel-linea: #e7e3dc;       /* marco del QR y raya del pie: solo decoración */
  --color-papel-tinta: #8a4b0f;       /* «¡Apunta aquí!» a mano y su flecha (6,8:1) */
  --color-papel-numero: #9a3412;      /* el número de cada paso, sobre papel-suave (6,6:1) */
  --color-papel-suave: #fff1e8;       /* los círculos de la figura y de los pasos */
}

/* ---------- Modo oscuro (Design System J&G, DEC-0032 y DEC-0039) ----------
   Lo pone el servidor con <html data-tema="oscuro"> (elegido en Ajustes, o «automático» de noche en Alcalá).
   El escáner (.tema-oscuro) es siempre oscuro: la imagen de la cámara se ve mejor y no deslumbra.
   Los mismos nombres que en claro: las pantallas no cambian, solo los valores (lo vigila test/test_estilo.py). */
:root[data-tema="oscuro"],
:root:has(.tema-oscuro) {
  color-scheme: dark;
  --color-fondo: #171412;
  --color-superficie: #221e1a;
  --color-linea: #3b352f;
  --color-texto: #f3ede6;
  --color-texto-secundario: #b8afa4;
  --color-borde-control: #857c72;
  --color-principal: #f07a3e;
  --color-principal-hover: #f59a6a;
  --color-principal-suave: #3a2219;
  --color-sobre-principal: #1a120c;
  --color-acento: #e0a458;
  --color-acento-oscuro: #f2c58a;
  --color-acento-suave: #3a2a17;
  --color-avatar-cafeteria: #3a2a17;
  --color-avatar-pasteleria: #383017;
  --color-avatar-churreria: #3a2219;
  --color-avatar-heladeria: #3a1d22;
  --color-avatar-otro: #302a24;
  --color-exito: #6cc08b;       --color-exito-fondo: #14281c;
  --color-advertencia: #f0b45a; --color-advertencia-fondo: #2e2210;
  --color-info: #8fb2ff;        --color-info-fondo: #162036;
  --color-error: #f08a8a;       --color-error-fondo: #331616;
  --color-marca-mostaza: #f2a900;
  --color-marca-crema: #fff6e5;       /* el icono de la app es el mismo de día y de noche */
  --color-qr-fondo: #ffffff;          /* también de noche: un QR claro sobre oscuro no lo leen todas las cámaras */
  --color-papel: #ffffff;             /* el cartel es papel: los mismos colores que de día */
  --color-papel-texto: #1f2328;
  --color-papel-secundario: #5b616b;
  --color-papel-linea: #e7e3dc;
  --color-papel-tinta: #8a4b0f;
  --color-papel-numero: #9a3412;
  --color-papel-suave: #fff1e8;
  --sombra: 0 1px 2px rgb(0 0 0 / 0.4);
  --sombra-barra: 0 -1px 0 rgb(0 0 0 / 0.5);
  --sombra-destacada: 0 1px 2px rgb(0 0 0 / 0.4), 0 6px 18px rgb(0 0 0 / 0.35);
  --sombra-logo: 0 4px 6px rgb(0 0 0 / 0.45);
  --color-visor: #2a2521;
}

/* Tamaño de letra de la persona (Ajustes). Todo va en rem, así que crece la app entera. En porcentaje y no en px:
   el 100 % respeta el tamaño que ya tenga puesto el móvil. */
:root[data-letra="grande"] { font-size: 112.5%; }
:root[data-letra="muy_grande"] { font-size: 125%; }
:root[data-letra="enorme"] { font-size: 150%; }

/* ---------- Base ---------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-fondo);
  color: var(--color-texto);
  font-family: var(--letra);
  font-size: var(--texto-base);
  line-height: 1.6;
}

h1, h2, h3 { font-family: var(--letra-titulos); line-height: 1.2; margin: 0; }
h1 { font-size: var(--titulo-1); font-weight: 700; letter-spacing: -0.01em; }
h2 { font-size: var(--titulo-2); font-weight: 650; }
p { margin: 0; }

/* Nota a mano (Design System, «nota»): un único guiño por pantalla, nunca instrucciones, errores ni datos clave */
.nota { font-family: var(--letra-mano); font-size: 1.5rem; font-weight: 600; line-height: 1.15; color: var(--color-acento); }
.nota--inclinada { transform: rotate(-2deg); }

a { color: var(--color-principal); text-underline-offset: 0.2em; }

/* Foco visible y claro para quien navega con teclado */
:focus-visible {
  outline: 3px solid var(--color-principal);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Columna de lectura: estrecha en móvil y con aire en escritorio */
.pagina {
  max-width: 40rem;
  margin: 0 auto;
  padding: var(--espacio-6) var(--espacio-5) var(--espacio-7);
}

.seccion + .seccion { margin-top: var(--espacio-7); }

.texto-secundario { color: var(--color-texto-secundario); }
.texto-pequeno { font-size: var(--texto-pequeno); }

/* ---------- Componentes ---------- */

/* Botón: mínimo 48 px de alto para el dedo; responde un poco al pulsarlo */
.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--espacio-2);
  min-height: var(--objetivo-tactil);
  padding: 0 min(var(--espacio-5), 24px);  /* con letra grande, el sitio va al texto: «Escanear código» en una línea */
  border: 1px solid transparent;
  border-radius: var(--radio-control);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;  /* sin el recuadro gris del móvil: ya responde el botón (DEC-0054) */
  transition: background-color var(--transicion), transform var(--transicion);
}
.boton:active { transform: scale(0.98); }

.boton--principal { background: var(--color-principal); color: var(--color-sobre-principal); }
.boton--principal:hover { background: var(--color-principal-hover); }

.boton--secundario {
  background: var(--color-superficie);
  color: var(--color-texto);
  border-color: var(--color-borde-control);
}
.boton--secundario:hover { background: var(--color-fondo); }

/* Peligro (Design System, Boton): SOLO el último paso de lo que no se deshace, al lado de «Cancelar» (DEC-0040).
   Texto error-fondo sobre error: 7,6:1 en claro y 6,9:1 en oscuro. */
.boton--peligro { background: var(--color-error); color: var(--color-error-fondo); }

/* Panel: solo cuando agrupa información de verdad */
.panel {
  background: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: var(--espacio-5);
}

/* Aviso: estado con color + texto (nunca solo color) */
.aviso {
  display: flex;
  gap: var(--espacio-3);
  padding: var(--espacio-4);
  border-radius: var(--radio-control);
  /* Sin raya de color a un lado (02-11, /diseno-sin-ia: es la señal más reconocible de una interfaz hecha con IA, y el
     Design System la tenía en «Lo que no hacemos»). El estado se dice con su fondo, su título y su texto */
}
.aviso__titulo { font-weight: 650; }
.aviso--antes-del-titulo { margin-bottom: var(--espacio-5); }  /* lo que acaba de pasar, encima del título de la pantalla */
.aviso p { color: var(--color-texto); }
.aviso--exito { color: var(--color-exito); background: var(--color-exito-fondo); }
.aviso--advertencia { color: var(--color-advertencia); background: var(--color-advertencia-fondo); }
.aviso--info { color: var(--color-info); background: var(--color-info-fondo); }
.aviso--error { color: var(--color-error); background: var(--color-error-fondo); }

/* Pasos numerados: lista sencilla, sin tarjetas */
.pasos {
  list-style: none;
  margin: var(--espacio-5) 0 0;
  padding: 0;
  display: grid;
  gap: var(--espacio-5);
}
.paso { display: grid; grid-template-columns: 2.5rem 1fr; gap: var(--espacio-4); align-items: start; }
.paso__numero {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--color-principal-suave);
  color: var(--color-principal-hover);
  font-weight: 700;
}
.paso__titulo { font-weight: 650; }

/* Indicador de carga sencillo */
.cargando {
  width: 1.25rem;
  height: 1.25rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: girar 700ms linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }

/* Quien pide menos movimiento, no lo tiene */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

.boton:disabled { opacity: 0.7; cursor: progress; transform: none; }

/* Varios botones: en fila si caben, uno debajo de otro en móvil */
.acciones { display: flex; flex-wrap: wrap; gap: var(--espacio-3); margin-top: var(--espacio-5); }

/* Enlace discreto para acciones secundarias de navegación */
.enlace { color: var(--color-principal-hover); font-weight: 600; }

/* Cabecera común: siempre se sabe dónde se está y cómo volver al inicio. Al cambiar de página no se mueve (su propio
   nombre en la transición, DEC-0054) */
.cabecera-app {
  max-width: 40rem;
  margin: 0 auto;
  padding: var(--espacio-4) var(--espacio-5) 0;
  view-transition-name: cabecera;
}

/* ---------- Formularios ---------- */

.formulario { display: grid; gap: var(--espacio-5); margin-top: var(--espacio-6); }

.campo { display: grid; gap: var(--espacio-2); }
.campo__etiqueta { font-weight: 600; }
.campo__ayuda { font-size: var(--texto-pequeno); color: var(--color-texto-secundario); }
.campo__fila { display: flex; flex-wrap: wrap; gap: var(--espacio-3); }
.campo__fila .entrada { flex: 1 1 10rem; min-width: 0; }

.entrada {
  min-height: var(--objetivo-tactil);
  padding: 0 var(--espacio-4);
  border: 1px solid var(--color-borde-control);
  border-radius: var(--radio-control);
  background: var(--color-superficie);
  color: var(--color-texto);
  font: inherit;
}

/* Casilla: toda la línea se puede pulsar (objetivo táctil grande) */
.verificacion {
  display: flex;
  gap: var(--espacio-3);
  align-items: flex-start;
  min-height: var(--objetivo-tactil);
  cursor: pointer;
}
.verificacion input {
  width: 1.375rem;
  height: 1.375rem;
  margin: 0.15rem 0 0;
  accent-color: var(--color-principal);
  flex: none;
}

/* Quien aún no ha llegado a un paso, no lo ve (presentación progresiva) */
.oculto { display: none !important; }

/* ---------- Códigos de recuperación ---------- */

.codigos {
  list-style: none;
  margin: var(--espacio-5) 0 0;
  padding: var(--espacio-5);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7em, 1fr));  /* dos por fila; con letra grande, uno, entero */
  gap: var(--espacio-3) var(--espacio-5);
  background: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 1.0625rem;
  letter-spacing: 0.04em;
}

/* ---------- Escanear (resultado del QR) ---------- */

.escanear__espera { display: flex; align-items: center; gap: var(--espacio-3); margin-top: var(--espacio-4); }
.escanear__resumen { margin-top: var(--espacio-4); font-size: 1.1875rem; }
.escanear__detalle { margin-top: var(--espacio-3); }
.escanear__aviso { margin-top: var(--espacio-5); }
/* El título recibe el foco por JS para el lector de pantalla: sin marco, porque no se pulsa */
.seccion h1:focus { outline: none; }

/* La tarjeta NFC del mostrador (paso 3, DEC-0051; boceto aprobado, mesas 2 a 7): en «Primero, pide tu sello» se ve la
   tarjeta de verdad (para reconocerla en el mostrador) y en «Escanea el código de la pantalla», el móvil con el código.
   Debajo, la acción principal grande y «Ir al inicio» como enlace. */
.escanear__objeto { display: block; width: min(12rem, 60%); height: auto; margin: var(--espacio-5) auto 0; }
.escanear__objeto--pequeno { width: min(6rem, 30%); }
.escanear__enlace { justify-self: center; display: inline-flex; align-items: center; min-height: var(--objetivo-tactil); }
/* El símbolo redondo del aviso (Design System: los avisos llevan su símbolo, nunca una raya a un lado): el círculo del
   color del estado y la marca (✕, i, !) del color de su fondo. Contrastes de la pareja, los del botón de peligro
   (7,6:1) y los de cada estado sobre su fondo */
.aviso__icono { flex: none; margin-top: 0.125rem; }
.aviso__icono path { fill: none; stroke-width: 2.4; stroke-linecap: round; }
.aviso--error .aviso__icono circle { fill: var(--color-error); }
.aviso--error .aviso__icono path { stroke: var(--color-error-fondo); }
.aviso--info .aviso__icono circle { fill: var(--color-info); }
.aviso--info .aviso__icono path { stroke: var(--color-info-fondo); }
.aviso--advertencia .aviso__icono circle { fill: var(--color-advertencia); }
.aviso--advertencia .aviso__icono path { stroke: var(--color-advertencia-fondo); }

/* ---------- El sello lo estampas tú, el premio y el canje (punto 7 · DEC-0037, boceto aprobado en Claude Design) ---------- */

/* El sello J&G en 3D, encima de la tarjeta, esperando tu toque. Al pulsar baja hasta el hueco (escanear.js, con la API de
   animaciones: el destino depende de la pantalla) y desaparece. */
.sello3d { display: block; width: min(8rem, 160px); height: auto; margin: var(--espacio-4) auto 0; transform: rotate(-8deg); filter: drop-shadow(var(--sombra-logo)); }
.tarjeta--sello { margin-top: var(--espacio-4); }
.tarjeta__cabeza { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: var(--espacio-1) var(--espacio-3); }
.tarjeta__cabeza .nota { margin-left: auto; }  /* «¡Uno más!»: a la derecha, también si un nombre largo la baja de línea */
.estampar { display: grid; gap: var(--espacio-2); margin-top: var(--espacio-5); }
.estampar__ayuda { text-align: center; }
/* Mientras la tarjeta espera tu toque, la vista algo más compacta: el sello J&G, más pequeño (paso 6, DEC-0056) */
.sello3d--compacto { width: min(6rem, 120px); margin-top: var(--espacio-2); }
/* «Estampar mi sello» fijo abajo (paso 6, DEC-0056; Design System «AccionFija»): se ve en cualquier móvil y con cualquier
   letra, al alcance del pulgar. Sale del margen de la página para ocupar todo el ancho, con el fondo de papel y una línea
   encima (separa, no flota); respeta la barra de inicio del iPhone. Al estampar se va con el resto del ritual. En el
   ordenador, el botón a una medida cómoda. Solo en páginas sin la barra de navegación (/escanear) */
.accion-fija {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin: var(--espacio-5) calc(-1 * var(--espacio-5)) 0;
  padding: var(--espacio-3) var(--espacio-5) calc(var(--espacio-3) + env(safe-area-inset-bottom, 0px));
  background: var(--color-fondo);
  border-top: 1px solid var(--color-linea);
}
.accion-fija .boton { width: 100%; max-width: 22rem; justify-self: center; }
/* Al moverse con el teclado, el foco nunca queda tapado por la franja */
html:has(.accion-fija:not(.oculto)) { scroll-padding-bottom: 9rem; }
.escanear__fuerte { margin-top: var(--espacio-5); font-size: 1.1875rem; font-weight: 700; }
.escanear__mano { margin-top: var(--espacio-1); }

/* El vale (Design System, Vale): el premio en la mano. Papel con el sello J&G en 3D asomando, muescas de ticket y la fila
   de sellos que lo han pagado. Canjeado: sin el sello y con el tampón. */
.vale {
  position: relative;
  display: grid;
  gap: var(--espacio-1);
  margin-top: 3.75rem;
  padding: 5.25rem var(--espacio-5) var(--espacio-5);
  background: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio);
  box-shadow: var(--sombra-destacada);
}
.vale--canjeado { margin-top: var(--espacio-4); padding-top: var(--espacio-5); box-shadow: var(--sombra); }
.vale__sello { --giro: -8deg; position: absolute; top: -3.125rem; left: 0.625rem; width: min(7.75rem, 155px); height: auto; transform: rotate(var(--giro)); filter: drop-shadow(var(--sombra-logo)); animation: estampar-tinta 250ms cubic-bezier(0.3, 1.4, 0.6, 1) both; }
.vale__nota { position: absolute; top: 1.375rem; right: var(--espacio-4); max-width: 55%; text-align: right; transform: rotate(-4deg); }
.vale__etiqueta { font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-acento-oscuro); }
.vale__premio { font-size: 1.875rem; line-height: 1.15; overflow-wrap: anywhere; }
.vale__corte { position: relative; margin: var(--espacio-4) 0 var(--espacio-3); border-top: 2px dashed var(--color-linea); }
.vale__corte::before,
.vale__corte::after {
  content: "";
  position: absolute;
  top: -0.6875rem;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: var(--color-fondo);
  border: 1px solid var(--color-linea);
}
.vale__corte::before { left: calc(-1 * var(--espacio-5) - 0.6875rem); }
.vale__corte::after { right: calc(-1 * var(--espacio-5) - 0.6875rem); }
.vale__sellos { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.vale__sellos .hueco { width: 1.75rem; }
.vale__hora { font-weight: 700; }
.vale__tambien { margin-top: var(--espacio-3); }

/* El tampón «Canjeado»: tinta a mano que se estampa al llegar (sin sonido: estás en el mostrador). Pisa el borde de
   arriba del vale, no el nombre del premio: en el mostrador tienen que poder leerlo entero. Crece desde su lado
   derecho al estamparse: así ni siquiera entonces se sale de la pantalla del móvil. */
.tampon {
  --giro: -10deg;
  position: absolute;
  top: -0.875rem;
  right: var(--espacio-3);
  transform-origin: 85% 50%;
  padding: var(--espacio-1) var(--espacio-3);
  border: 3px solid var(--color-acento);
  border-radius: var(--radio-control);
  color: var(--color-acento);
  font-family: var(--letra-titulos);
  font-size: 1.375rem;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--color-superficie);
  transform: rotate(var(--giro));
  filter: url(#tembleque);
  animation: estampar-tinta 250ms cubic-bezier(0.3, 1.4, 0.6, 1) 150ms both;
}

/* ---------- Mis tarjetas ---------- */

/* La columna nunca es más ancha que la pantalla: lo que no quepa se parte dentro de la tarjeta (ERR-0018) */
.tarjetas { list-style: none; margin: var(--espacio-6) 0 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--espacio-5); }
.tarjeta__bar { font-family: var(--letra-titulos); font-size: var(--titulo-2); overflow-wrap: anywhere; }
.tarjeta__sellos { margin-top: var(--espacio-1); font-size: 1.1875rem; font-weight: 650; }
.tarjeta__meta { margin-top: var(--espacio-3); }
.tarjeta__aviso { margin-top: var(--espacio-4); }
.tarjeta__titulo-premios {
  margin-top: var(--espacio-5);
  font-size: var(--texto-pequeno);
  font-weight: 650;
  color: var(--color-texto-secundario);
}
.tarjetas__vacio { margin-top: var(--espacio-4); font-size: 1.1875rem; }

/* Huecos de la tarjeta de sellos (Design System, TarjetaSellos · DEC-0037): hasta 15 sellos son la barra de progreso.
   Vacío = círculo discontinuo; sellado = tinta con el borde a mano (filtro #tembleque) y una ✓; el que espera tu toque =
   discontinuo naranja. Se distinguen por forma, no solo por color, y lo leen en voz alta con el aria-label del grupo.
   Filas equilibradas (3, 4 o 5 por fila, plantillas/_huecos.html) y huecos que encogen si la letra es enorme. */
.huecos { display: grid; grid-template-columns: repeat(5, minmax(0, 3rem)); gap: min(var(--espacio-3), 12px); margin-top: var(--espacio-4); }
.huecos--c3 { grid-template-columns: repeat(3, minmax(0, 3rem)); }
.huecos--c4 { grid-template-columns: repeat(4, minmax(0, 3rem)); }
.huecos--c5 { grid-template-columns: repeat(5, minmax(0, 3rem)); }
.hueco { display: block; width: 100%; height: auto; aspect-ratio: 1; overflow: visible; }
.hueco circle { fill: none; stroke: var(--color-borde-control); stroke-width: 2; stroke-dasharray: 4 4; }
.hueco--espera circle { fill: var(--color-principal-suave); stroke: var(--color-principal-hover); stroke-width: 2.4; stroke-dasharray: 5 4; }
.hueco--lleno .hueco__tinta { fill: var(--color-acento-suave); stroke: var(--color-acento); stroke-width: 2.6; stroke-dasharray: none; }
.hueco__marca { fill: none; stroke: var(--color-acento-oscuro); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
/* El sello que se estampa: baja, aprieta y rebota en 250 ms. Es el mismo gesto en toda la app (DEC-0054): los huecos,
   el vale, el tampón «Canjeado», el ✓ de los avisos y el de cada pareja del Memoria. --giro: el ángulo en el que se
   queda (el tampón, −10°). Quien pide menos movimiento lo ve ya puesto (la regla general de «Quien pide menos
   movimiento»). */
.hueco--nuevo { transform-origin: center; animation: estampar-tinta 250ms cubic-bezier(0.3, 1.4, 0.6, 1) both; }
@keyframes estampar-tinta {
  0% { transform: scale(1.5) rotate(calc(var(--giro, 0deg) - 12deg)); opacity: 0; }
  60% { transform: scale(0.92) rotate(calc(var(--giro, 0deg) + 2deg)); opacity: 1; }
  100% { transform: scale(1) rotate(var(--giro, 0deg)); opacity: 1; }
}
/* El filtro de la tinta: un <svg> de 0 × 0 que no ocupa sitio */
.filtro-tinta { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Más de 15 sellos: una barra de verdad (<progress>, sin estilos en línea por la CSP): pista suave y relleno de tinta */
.progreso {
  appearance: none;
  display: block;
  width: 100%;
  height: 0.875rem;
  margin-top: var(--espacio-4);
  border: 1px solid var(--color-borde-control);
  border-radius: 999px;
  background: var(--color-acento-suave);
  overflow: hidden;
}
.progreso::-webkit-progress-bar { background: var(--color-acento-suave); }
.progreso::-webkit-progress-value { background: var(--color-acento); border-radius: 999px; }
.progreso::-moz-progress-bar { background: var(--color-acento); border-radius: 999px; }

.premios { list-style: none; margin: var(--espacio-2) 0 0; padding: 0; }
/* Nombre y coste en una línea; si no caben (letra enorme, móvil estrecho), el coste baja debajo del nombre (ERR-0018).
   El nombre ocupa lo que sobra y su palabra más larga decide si el coste cabe al lado. El número y su palabra van juntos
   con &nbsp; en la plantilla: el coste se puede partir por «·», nunca entre «5» y «sellos». */
.premio {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--espacio-1) var(--espacio-4);
  padding: var(--espacio-2) 0;
  border-top: 1px solid var(--color-linea);
}
.premio__nombre { flex: 1 1 0; overflow-wrap: break-word; }
.premio__coste { color: var(--color-texto-secundario); }
.premio__coste--listo { color: var(--color-exito); font-weight: 650; }

/* ---------- Locales (/explorar) · boceto aprobado (Claude Design, v7) ---------- */

/* Filtros (02-11, Máximo: «no me termina de gustar»; boceto de la portada común): un círculo con la figura 3D de cada
   tipo y su nombre corto debajo. Columnas de 3,25rem como mínimo (los 6 caben en una fila a 375 px): crecen con la
   letra y, si no caben, bajan a otra fila (nunca una barra de desplazamiento que esconda filtros). */
.filtros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(3.25rem, 1fr));
  gap: var(--espacio-3) var(--espacio-1);
  margin: var(--espacio-4) calc(-1 * var(--espacio-2)) 0;
}
.filtro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--espacio-1);
  min-height: var(--objetivo-tactil);
  padding-block: var(--espacio-1);
  border-radius: var(--radio-control);
  color: var(--color-texto);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
}
.filtro__figura {
  position: relative;
  display: grid;
  place-items: center;
  width: 3.125rem;
  height: 3.125rem;
  border-radius: 50%;
  background: var(--color-avatar-cafeteria);
  box-shadow: 0 0 0 1px var(--color-linea);
}
.filtro__figura img { width: 85%; height: 85%; }
.filtro__figura--todos { background: var(--color-principal-suave); }
/* El elegido: aro teja y texto en negrita y teja (nunca solo el color). El aro es su propia pieza, dentro de la figura
   del elegido, para que al filtrar viaje del filtro de antes al nuevo (paso 2, DEC-0054; un solo aro por página) */
.filtro[aria-current="page"] { color: var(--color-principal-hover); font-weight: 800; }
.filtro__aro {
  position: absolute;
  inset: -3px;
  border: 3px solid var(--color-principal);
  border-radius: 50%;
  pointer-events: none;
  view-transition-name: filtro-aro;
}

.avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: var(--color-avatar-cafeteria);
}
.avatar img { width: 90%; height: 90%; }
.avatar--grande { width: 4.75rem; height: 4.75rem; background: var(--color-superficie); }
.avatar--pasteleria { background: var(--color-avatar-pasteleria); }
.avatar--churreria { background: var(--color-avatar-churreria); }
.avatar--heladeria { background: var(--color-avatar-heladeria); }
.avatar--otro { background: var(--color-avatar-otro); }
.avatar--vacio { width: 10rem; height: 10rem; }

.destacado {
  display: grid;
  gap: var(--espacio-3);
  margin-top: var(--espacio-5);
  padding: var(--espacio-4);
  border-radius: var(--radio-grande);
  background: var(--color-acento-suave);
  color: var(--color-texto);
  text-decoration: none;
}
/* Con letra grande, la cifra que falta baja a su propia línea en vez de apretar el nombre */
.destacado__cabeza { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espacio-3); }
.destacado__texto { flex: 999 1 6rem; display: grid; min-width: 0; }
/* «Más cerca del premio»: en texto normal y discreto (paso 2, DEC-0054: la etiqueta en mayúsculas encima de un título
   es otra señal de IA, DEC-0053) */
.destacado__etiqueta { font-size: var(--texto-pequeno); font-weight: 600; color: var(--color-texto-secundario); }
.destacado__nombre { font-family: var(--letra-titulos); font-size: var(--titulo-2); line-height: 1.15; }
.destacado__falta { font-weight: 700; color: var(--color-acento-oscuro); }
/* El premio listo, primero (paso 6, DEC-0056): «¡Premio listo!» con su ✓ (con texto, nunca solo color) y «Ya puedes pedir
   tu «Café gratis».» en el color del texto; lo que falta para el siguiente, detrás y más suave */
.destacado__etiqueta--listo { display: inline-flex; align-items: center; gap: var(--espacio-1); font-weight: 700; color: var(--color-exito); }
.destacado__etiqueta--listo svg { flex: none; }
.destacado__falta--listo { color: var(--color-texto); }
.destacado__siguiente { font-weight: 400; color: var(--color-texto-secundario); }
.huecos--compactos { display: flex; flex-wrap: wrap; margin-top: 0; gap: 0.375rem; }
.huecos--compactos .hueco { width: 1.5rem; }
.progreso--compacto { margin-top: 0; height: 0.625rem; }

.explorar__titulo { margin-top: var(--espacio-6); font-size: 1.125rem; }
.locales-lista { list-style: none; margin: var(--espacio-3) 0 0; padding: 0; display: grid; gap: var(--espacio-3); }
.local-fila {
  display: flex;
  flex-wrap: wrap;  /* con letra grande, lo de la derecha (regalo, botón) baja de línea en vez de apretar el texto */
  align-items: center;
  gap: var(--espacio-3);
  min-height: var(--objetivo-tactil);
  padding: var(--espacio-3);
  border-radius: var(--radio);
  background: var(--color-superficie);
  box-shadow: var(--sombra);
  color: var(--color-texto);
  text-decoration: none;
}
.local-fila__texto { flex: 999 1 6rem; min-width: 0; display: grid; }  /* se queda casi todo el sitio libre */
.etiqueta-regalo {
  flex: none;
  padding: 0.25rem 0.625rem;
  border-radius: 999px;
  background: var(--color-acento-suave);
  color: var(--color-acento-oscuro);
  font-size: 0.8125rem;
  font-weight: 700;
}
.vacio { display: grid; justify-items: center; gap: var(--espacio-4); margin-top: var(--espacio-6); text-align: center; }
.vacio__titulo { font-size: 1.25rem; font-weight: 700; }

/* ---------- Barra fija (Inicio · Tarjetas · [J&G → Escanear] · Locales · Jugar; paso 4, DEC-0050) ---------- */

.barra {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  max-width: 40rem;
  margin: 0 auto;
  padding: var(--espacio-1) var(--espacio-2) calc(var(--espacio-2) + env(safe-area-inset-bottom, 0px));
  background: var(--color-superficie);
  border-radius: var(--radio-grande) var(--radio-grande) 0 0;
  box-shadow: var(--sombra-barra);
  view-transition-name: barra;  /* al cambiar de página no se mueve: solo pasa el destino activo (DEC-0054) */
}
.barra__lista { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); align-items: end; }
/* La barra crece con la letra hasta el 125 % como mucho (Design System, BarraNavegacion): con más, «Tarjetas» ya no
   cabe en su hueco de un móvil de 375 px, y las etiquetas nunca se cortan ni se esconden. min() pone ese tope. */
.barra__destino {
  display: grid;
  grid-template-columns: minmax(0, 1fr);  /* su columna mide lo que su hueco: lo que es más ancho (el sello con letra
                                             grande) sobresale igual por los dos lados, sin empujar a la derecha */
  justify-items: center;
  min-height: var(--objetivo-tactil);
  padding: var(--espacio-1) 0;
  border-radius: var(--radio-control);
  color: var(--color-texto-secundario);
  /* 14 px con la letra normal (paso 8, DEC-0058: con 13 se leía mal), que crecen hasta 16,25 px como mucho, el tope de
     antes: con el 125 % de 14 (17,5 px), a 360 px y con la letra muy grande, las etiquetas se pisaban (medido, R-43) */
  font-size: min(0.875rem, 16.25px);
  font-weight: 700;
  text-decoration: none;
}
.barra__destino img { width: min(2.125rem, 42.5px); height: min(2.125rem, 42.5px); }
.barra__destino[aria-current="page"] { color: var(--color-principal-hover); background: var(--color-principal-suave); }
.barra__centro { margin-top: max(-2.25rem, -45px); }
.barra__centro img { width: min(4.25rem, 85px); height: min(4.25rem, 85px); filter: drop-shadow(var(--sombra-logo)); transition: transform 120ms ease; }
.barra__centro[aria-current="page"] { background: none; }
/* En las pantallas más estrechas (menos de 360 px, como el primer iPhone SE) la barra no crece con la letra: con
   «Escanear» en el centro (paso 4), a 320 px y con la letra grande, el sello y las etiquetas de al lado se tocaban */
@media (max-width: 359px) {
  .barra__destino { font-size: min(0.875rem, 14.5px); }
  .barra__centro { margin-top: -36px; }
  .barra__centro img { width: 68px; height: 68px; }
}
/* Que la barra no tape el final de la página, ni lo que se lleva a la vista con el foco (WCAG 2.4.11): el navegador
   deja ese mismo hueco abajo al enfocar o al hacer scrollIntoView (lo que aparece al pulsar, como «Enlace listo») */
body:has(.barra) .pagina { padding-bottom: 8rem; }
html:has(.barra) { scroll-padding-bottom: 8rem; }

@media (min-width: 48rem) {
  .locales-lista { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- Piezas comunes nuevas (panel inicial, 30-10) ---------- */

/* Texto solo para el lector de pantalla (p. ej. «6 de 8» → «6 de 8 sellos») */
.solo-lector {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.boton--ancho { width: 100%; padding-inline: var(--espacio-4); }  /* a lo ancho, el sitio es para el texto */
.boton__icono { flex: none; width: 2.125rem; height: 2.125rem; }
/* Columna algo más ancha: el panel pone dos tarjetas en fila en escritorio (boceto «Escritorio») */
.pagina--ancha { max-width: 47.5rem; }

/* Marca J&G con su sello: la cabecera de las páginas sin barra (Design System, «Logo»; punto 8, DEC-0045). Desde el
   02-11, el sello solo, algo más grande (sin el texto «J&G» al lado: el sello ya lo dice) */
.marca-jg {
  display: inline-flex;
  align-items: center;
  min-width: var(--objetivo-tactil);
  min-height: var(--objetivo-tactil);
  border-radius: 50%;
}
.marca-jg img { width: 2.75rem; height: 2.75rem; filter: drop-shadow(0 2px 3px rgb(154 52 18 / 0.18)); }

/* Aviso con marca redonda (premio listo, local añadido): el símbolo acompaña al texto, nunca lo sustituye */
.aviso--marca { align-items: center; border-radius: var(--radio); }
.aviso__marca {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--color-exito);
  color: var(--color-exito-fondo);   /* el ✓ (6,8:1) */
}

/* ---------- Panel inicial de J&G (/ con sesión) · boceto aprobado en Claude Design ---------- */

.panel-inicio { display: grid; gap: var(--espacio-5); }
.saludo { display: flex; align-items: center; gap: var(--espacio-3); }
.saludo img { flex: none; width: 2.75rem; height: 2.75rem; }
.saludo__texto { display: grid; min-width: 0; }
.saludo__nota { font-size: 1.375rem; line-height: 1; }
/* El saludo y «Tu cuenta» en una fila (paso 4, DEC-0050): si no caben (letra grande), «Tu cuenta» baja debajo, entera.
   En la primera vez (sin saludo), arriba a la derecha */
.panel-inicio__saludo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--espacio-3); }
.panel-inicio__cuenta { display: flex; justify-content: flex-end; margin-bottom: var(--espacio-3); }
/* «Tu cuenta»: un botón secundario pequeño con tu llavero (el mismo objeto que en la página de tu cuenta) */
.tu-cuenta { padding: 0 var(--espacio-4) 0 var(--espacio-2); font-size: var(--texto-pequeno); font-weight: 700; }
.tu-cuenta img { flex: none; width: 2rem; height: 2rem; }
.panel-inicio__arriba { display: grid; gap: var(--espacio-5); }
.panel-inicio__titulo { font-size: 1.1875rem; font-weight: 700; }
.panel-inicio__cabeza { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--espacio-3); }
.panel-inicio__cabeza .enlace {
  display: inline-flex;
  align-items: center;
  min-height: var(--objetivo-tactil);
  font-size: var(--texto-pequeno);
}
.panel-inicio .locales-lista { margin-top: var(--espacio-1); }

/* «Añade un local»: toda la tarjeta se pulsa; el botón de dentro es la acción principal de la pantalla */
.accion-local {
  display: flex;
  flex-wrap: wrap;  /* con letra grande, el dibujo arriba y el texto debajo, a todo lo ancho */
  align-items: center;
  gap: var(--espacio-4);
  padding: var(--espacio-4);
  border-radius: var(--radio-grande);
  background: var(--color-superficie);
  box-shadow: var(--sombra-destacada);
  color: var(--color-texto);
  text-decoration: none;
}
.accion-local > img { flex: none; width: 4.75rem; height: 4.75rem; }
.accion-local__texto { flex: 1 1 10rem; display: grid; justify-items: start; gap: var(--espacio-2); }
.accion-local__titulo { font-size: 1.125rem; line-height: 1.2; }
.accion-local:hover .boton--principal { background: var(--color-principal-hover); }

/* Tu próximo premio: la tarjeta de Locales (.destacado) con la cifra que falta, grande */
.proximo { display: grid; gap: var(--espacio-3); }
.proximo .destacado { margin-top: 0; }
.proximo__local { font-size: 1.125rem; line-height: 1.2; }
.cifra { margin-left: auto; display: flex; align-items: baseline; gap: var(--espacio-1); color: var(--color-acento-oscuro); }
.cifra__numero { font-family: var(--letra-titulos); font-size: 2.5rem; font-weight: 750; line-height: 1; }
.cifra__texto { font-size: var(--texto-pequeno); font-weight: 700; }

/* «Jugar» a su tamaño al lado del texto; si con letra grande baja de línea, ocupa toda la fila (crece 1 frente a 999) */
.partidas .boton { flex: 1 0 auto; }

/* Mis locales: tres por fila; en el móvil, la figura encima del nombre. Con letra grande, dos por fila (cada columna
   mide al menos 5,5rem), para que los nombres no se partan a mitad de palabra; nunca más de tres (30 %). */
.mis-locales {
  list-style: none;
  margin: var(--espacio-1) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(max(5.5rem, 30%), 1fr));
  gap: var(--espacio-3);
}
.mini-local {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--espacio-2);
  height: 100%;
  padding: var(--espacio-3) var(--espacio-2);
  border-radius: var(--radio);
  background: var(--color-superficie);
  box-shadow: var(--sombra);
  color: var(--color-texto);
  text-align: center;
  text-decoration: none;
}
.mini-local__texto { display: grid; gap: var(--espacio-1); min-width: 0; }
.mini-local__nombre { font-size: var(--texto-pequeno); line-height: 1.25; overflow-wrap: anywhere; }
.mini-local__estado { font-size: 0.8125rem; font-weight: 700; color: var(--color-acento-oscuro); }
.mini-local__estado--listo { color: var(--color-exito); }

/* Primera vez (sin locales): bienvenida con el sello J&G en perspectiva */
.bienvenida { display: grid; justify-items: center; gap: var(--espacio-2); max-width: 26rem; margin: 0 auto; text-align: center; }
.bienvenida__logo { width: min(14.375rem, 100%); height: auto; aspect-ratio: 1; }  /* con letra enorme no se sale */
.bienvenida__saludo { font-size: 1.75rem; }  /* nota a mano */
.bienvenida__texto { margin-top: var(--espacio-2); }
.bienvenida__acciones { display: grid; gap: var(--espacio-3); width: 100%; margin-top: var(--espacio-5); }

@media (min-width: 48rem) {
  /* Escritorio: próximo premio a la izquierda y «Añade un local» a la derecha, a la misma altura */
  .panel-inicio__arriba:has(.proximo) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas: "titulo ." "proximo anade";
    gap: var(--espacio-3) var(--espacio-4);
  }
  .panel-inicio__arriba:has(.proximo) .proximo { display: contents; }
  .proximo .panel-inicio__titulo { grid-area: titulo; }
  .proximo__tarjeta { grid-area: proximo; }
  .panel-inicio__arriba:has(.proximo) .accion-local { grid-area: anade; }
  /* El premio listo (paso 6, DEC-0056): en su propia fila, encima de los dos */
  .panel-inicio__arriba:has(.proximo):has(.panel-inicio__listo) { grid-template-areas: "listo listo" "titulo ." "proximo anade"; }
  .panel-inicio__arriba:has(.proximo) .panel-inicio__listo { grid-area: listo; }
  .mini-local { flex-direction: row; text-align: left; padding: var(--espacio-3); }
}

/* ---------- Página fija de un local (/l/<slug>, la abren su QR y su NFC) ---------- */

/* En el móvil, los botones quedan abajo, al alcance del pulgar (boceto «Añadir un local») */
.ficha-local { display: flex; flex-direction: column; gap: var(--espacio-5); min-height: calc(100vh - 9rem); min-height: calc(100dvh - 9rem); }
.ficha-local__cabeza { display: grid; justify-items: center; gap: var(--espacio-2); text-align: center; }
.ficha-local__cabeza h1 { margin-top: var(--espacio-2); }
.avatar--enorme { width: 9.75rem; height: 9.75rem; }
.regalo { display: grid; gap: var(--espacio-2); padding: var(--espacio-4); border-radius: var(--radio); background: var(--color-acento-suave); }
.regalo__titulo { font-size: 1.625rem; justify-self: start; }  /* nota a mano; acento sobre acento-suave: 6,1:1 y 6,3:1 */
.ficha-local__acciones { display: grid; gap: var(--espacio-3); margin-top: auto; }
/* Dónde está y cuándo abre (paso 8, DEC-0058; boceto «La ficha del local»): como el papel de la puerta, dos líneas que
   se leen de un vistazo, alineadas a la izquierda. En el ordenador, una al lado de la otra */
.ficha-local__datos { margin: 0; display: grid; gap: var(--espacio-4); }
.ficha-local__dato { display: grid; gap: 0.125rem; align-content: start; }
.ficha-local__dato dt { font-size: var(--texto-pequeno); color: var(--color-texto-secundario); }
.ficha-local__dato dd { margin: 0; overflow-wrap: anywhere; }
.ficha-local__llegar { display: inline-flex; align-items: center; gap: var(--espacio-1); min-height: var(--objetivo-tactil); }
/* Sus premios: como la pizarra de la tienda, el premio y lo que cuesta, del más barato al más caro. Con la letra grande,
   lo que cuesta baja de línea antes que salirse (R-34) */
.ficha-local__premios { display: grid; gap: var(--espacio-2); margin-top: var(--espacio-2); }
.ficha-local__lista { list-style: none; margin: 0; padding: 0; }
.ficha-local__lista li { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 var(--espacio-4); padding-block: var(--espacio-3); border-bottom: 1px solid var(--color-linea); }
.ficha-local__lista li:last-child { border-bottom: 0; }
.ficha-local__coste { margin-left: auto; color: var(--color-texto-secundario); font-variant-numeric: tabular-nums; }  /* también si baja: a la derecha, en su columna */
@media (min-width: 48rem) {
  .ficha-local__datos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--espacio-5); }
}

@media (min-width: 48rem) {
  .ficha-local { min-height: 0; }
  .ficha-local__acciones { margin-top: var(--espacio-2); }
}

/* ---------- Escáner de la app (/camara) · boceto aprobado, mesa «Escanear» (paso 4: mesas 6 a 11) ---------- */

/* En columna y con el alto de la pantalla: «¿Hay una tarjeta…?» queda abajo, a mano del pulgar. La página ocupa la
   pantalla (con su aire, sea cual sea) y el escáner llena lo que queda: así nunca hace falta desplazarse */
body:has(.camara) .pagina { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.camara { flex: 1; display: flex; flex-direction: column; gap: var(--espacio-5); }
.camara__cabeza { display: flex; align-items: center; justify-content: space-between; gap: var(--espacio-3); }
.camara__cabeza h1 { font-size: 1.5rem; }
.camara__visor {
  position: relative;
  align-self: center;
  display: grid;
  place-items: center;
  width: min(100%, 17.5rem);
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--radio-grande);
  background: var(--color-visor);
}
.camara__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.camara__pista { padding: 0 var(--espacio-6); text-align: center; font-size: var(--texto-pequeno); color: var(--color-texto-secundario); }
/* Marco del visor con el mostaza del logo (decorativo) */
.camara__esquina {
  position: absolute;
  width: 2.75rem;
  height: 2.75rem;
  border: 0 solid var(--color-marca-mostaza);
  transition: top 150ms cubic-bezier(0.2, 0, 0, 1), right 150ms cubic-bezier(0.2, 0, 0, 1),
    bottom 150ms cubic-bezier(0.2, 0, 0, 1), left 150ms cubic-bezier(0.2, 0, 0, 1), width 150ms ease, height 150ms ease,
    border-color 150ms ease;
}
.camara__esquina--arriba-izquierda { top: 1rem; left: 1rem; border-width: 5px 0 0 5px; border-top-left-radius: 14px; }
.camara__esquina--arriba-derecha { top: 1rem; right: 1rem; border-width: 5px 5px 0 0; border-top-right-radius: 14px; }
.camara__esquina--abajo-izquierda { bottom: 1rem; left: 1rem; border-width: 0 0 5px 5px; border-bottom-left-radius: 14px; }
.camara__esquina--abajo-derecha { bottom: 1rem; right: 1rem; border-width: 0 5px 5px 0; border-bottom-right-radius: 14px; }
/* Encontrado (paso 2, DEC-0054): al leer un código de J&G, la línea se para y las esquinas se cierran sobre él, en verde,
   como la luz del lector de la caja del súper. camara.js pone dónde está (--marco-*, en px desde cada borde del visor);
   sin eso, al centro. Un código que no es de J&G no cierra nada. Sin movimiento, las esquinas saltan a su sitio. */
.camara__visor--encontrado .camara__esquina { width: 1.875rem; height: 1.875rem; border-color: var(--color-exito); }
.camara__visor--encontrado .camara__esquina--arriba-izquierda { top: var(--marco-arriba, 25%); left: var(--marco-izquierda, 25%); }
.camara__visor--encontrado .camara__esquina--arriba-derecha { top: var(--marco-arriba, 25%); right: var(--marco-derecha, 25%); }
.camara__visor--encontrado .camara__esquina--abajo-izquierda { bottom: var(--marco-abajo, 25%); left: var(--marco-izquierda, 25%); }
.camara__visor--encontrado .camara__esquina--abajo-derecha { bottom: var(--marco-abajo, 25%); right: var(--marco-derecha, 25%); }
/* La línea solo sale mientras la cámara lee; entonces barre el visor (quieta si se pide menos movimiento) */
.camara__linea {
  position: absolute;
  left: 2.25rem;
  right: 2.25rem;
  top: 50%;
  display: none;
  height: 3px;
  border-radius: 2px;
  background: var(--color-marca-mostaza);
  opacity: 0.85;
}
.camara__visor--leyendo .camara__linea { display: block; animation: barrer 2.4s ease-in-out infinite alternate; }
@keyframes barrer { from { top: 18%; } to { top: 82%; } }
/* Lo que pasa (grande) y, debajo, el detalle si hace falta («La cámara está apagada»); vacío no ocupa sitio */
.camara__estado { display: grid; gap: var(--espacio-2); text-align: center; font-size: 1.1875rem; font-weight: 700; }
.camara__detalle { font-size: 1rem; font-weight: 400; color: var(--color-texto-secundario); }
.camara__detalle:empty { display: none; }
.camara__boton { align-self: center; }  /* «Volver a probar» y «Volver a la cámara», a su tamaño y al centro */
/* «Acercar el móvil» (paso 4, DEC-0050): la cámara se apaga y el visor enseña la tarjeta del mostrador en su taco */
.camara__tarjeta-3d { display: none; width: 74%; height: auto; }
.camara__visor--tarjeta { background: var(--color-superficie); }
.camara__visor--tarjeta .camara__tarjeta-3d { display: block; }
.camara__visor--tarjeta .camara__esquina { display: none; }
/* «¿Hay una tarjeta o una pegatina de J&G?»: solo en pantallas táctiles (un ordenador no lee tarjetas), abajo del todo */
.camara__tarjeta {
  display: none;
  grid-template-columns: 4rem minmax(0, 1fr);
  align-items: center;
  gap: var(--espacio-3) var(--espacio-4);
  margin-top: auto;
  padding: var(--espacio-4);
  border-radius: var(--radio);
  background: var(--color-superficie);
}
.camara__tarjeta img { width: 4rem; height: 4rem; object-fit: contain; }
.camara__tarjeta .boton { grid-column: 1 / -1; }
@media (pointer: coarse) {
  .camara__tarjeta { display: grid; }
}

/* ---------- Tu cuenta y sus páginas (/cuenta, /ajustes, /cuenta/…) · boceto aprobado (DEC-0040) ---------- */

.cuenta { display: grid; gap: var(--espacio-6); }
.cuenta__cabeza { display: grid; gap: var(--espacio-2); }
/* «‹ Tu cuenta»: volver al resumen, con objetivo táctil de 48 px */
.volver {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: var(--espacio-1);
  min-height: var(--objetivo-tactil);
  color: var(--color-principal-hover);
  font-weight: 700;
  text-decoration: none;
}
.volver svg { flex: none; }
.bloque { display: grid; gap: var(--espacio-3); }
.bloque__accion { display: flex; flex-wrap: wrap; gap: var(--espacio-3); }  /* el botón a su tamaño, no a lo ancho */
.acciones--juntas { margin-top: 0; }
.formulario--junto { margin-top: 0; }

/* Quién eres: el icono de Cuenta, tu alias, tu nombre y desde cuándo */
.identidad {
  display: flex;
  align-items: center;
  gap: var(--espacio-4);
  padding: var(--espacio-4);
  border-radius: var(--radio);
  background: var(--color-superficie);
  box-shadow: var(--sombra);
}
.identidad .avatar img { width: 75%; height: 75%; }
.identidad__texto { display: grid; min-width: 0; }
.identidad__alias { font-family: var(--letra-titulos); font-size: var(--titulo-2); font-weight: 650; line-height: 1.25; overflow-wrap: anywhere; }

/* Filas del resumen: toda la fila se pulsa; dicen lo que hay dentro y la flecha, que llevan a otra página */
.filas { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espacio-3); }
.fila {
  display: flex;
  align-items: center;
  gap: var(--espacio-3);
  min-height: var(--objetivo-tactil);
  padding: var(--espacio-3) var(--espacio-4);
  border-radius: var(--radio);
  background: var(--color-superficie);
  box-shadow: var(--sombra);
  color: var(--color-texto);
  text-decoration: none;
}
.fila__texto { flex: 1; display: grid; min-width: 0; }
.fila__resumen { font-size: var(--texto-pequeno); color: var(--color-texto-secundario); }
.fila__flecha { flex: none; color: var(--color-texto-secundario); }
.fila--boton { width: 100%; border: 0; font: inherit; text-align: left; cursor: pointer; }  /* una fila que hace algo aquí */
.salir { display: grid; gap: var(--espacio-2); }

/* Instalar J&G en tu móvil (punto 9, DEC-0046; DS «AppMovil»): todo oculto hasta que instalar.js sepa que se puede.
   Si no se enseña nada, el bloque tampoco ocupa sitio (sin un hueco de más entre las filas y «Salir»). */
.instalar { display: grid; gap: var(--espacio-3); }
.instalar:not(:has(> :not(.oculto))) { display: none; }
.instalar__icono { flex: none; display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: 0.75rem; background: var(--color-marca-crema); }
.instalar__icono img { width: 2.375rem; height: 2.375rem; }
.instalar__pasos { margin: 0; padding: var(--espacio-5); border-radius: var(--radio); background: var(--color-superficie); box-shadow: var(--sombra); }
.instalar__compartir { vertical-align: -0.25em; }

/* Ajustes: cada grupo con su título y su «✓ Guardado» debajo */
.ajustes { display: grid; gap: var(--espacio-6); }
.grupo { min-width: 0; margin: 0; padding: 0; border: 0; display: grid; gap: var(--espacio-3); }
.grupo__titulo { padding: 0; margin-bottom: var(--espacio-3); font-family: var(--letra-titulos); font-size: var(--titulo-2); font-weight: 650; line-height: 1.25; }
.grupo__subtitulo { padding: 0; margin-bottom: var(--espacio-2); font-weight: 700; }
.grupo > .boton { justify-self: start; }  /* «Probar…» a su tamaño */
.guardado { min-height: 1.5rem; display: flex; align-items: center; gap: var(--espacio-1); font-size: var(--texto-pequeno); font-weight: 700; color: var(--color-exito); }
.guardado--error { color: var(--color-error); }

/* Opciones (letra, modo, tono): una radio de verdad, invisible, cubre cada opción; la elegida lleva borde grueso,
   fondo suave y una ✓ (forma además de color). Con letra grande caben menos por fila: bajan solas. */
.opciones { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 6rem), 1fr)); gap: var(--espacio-2); }
.opciones--letra { grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr)); }  /* 2 × 2 en el móvil; 4 en fila en escritorio */
.opcion {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.125rem;
  min-height: 3.5rem;
  padding: var(--espacio-2);
  border: 1px solid var(--color-borde-control);
  border-radius: var(--radio-control);
  background: var(--color-superficie);
  color: var(--color-texto);
  font-size: var(--texto-pequeno);
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  cursor: pointer;
}
.opcion input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.opcion:has(input:checked) { border: 2px solid var(--color-principal-hover); background: var(--color-principal-suave); color: var(--color-principal-hover); }
.opcion:has(input:focus-visible) { outline: 3px solid var(--color-principal); outline-offset: 3px; }
/* La ✓, en la esquina y medio fuera (con un aro del color del fondo): nunca pisa el texto, aunque la opción sea estrecha */
.opcion__marca { display: none; position: absolute; top: -0.5rem; right: -0.5rem; width: 1.375rem; height: 1.375rem; }
.opcion:has(input:checked) .opcion__marca { display: block; }
.opcion__marca circle { fill: var(--color-principal-hover); stroke: var(--color-fondo); stroke-width: 2.5; }
.opcion__marca path { fill: none; stroke: var(--color-sobre-principal); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }  /* 7,3:1 · 8,6:1 */
.aa { font-family: var(--letra-titulos); font-weight: 700; line-height: 1; }
.aa--normal { font-size: 1.25rem; }
.aa--grande { font-size: 1.4375rem; }
.aa--muy_grande { font-size: 1.625rem; }
.aa--enorme { font-size: 1.875rem; }

/* Interruptor (sonido, vibración): la casilla de verdad, invisible encima; se dibuja la pista con su bolita.
   Toda la fila responde al dedo (paso 8, 48 px): el texto llena su alto y la casilla invisible mide al menos 48 px,
   aunque la pista que se ve mida 32 (antes, tocar 6 px por encima o por debajo no hacía nada). */
.linea { display: flex; align-items: center; justify-content: space-between; gap: var(--espacio-3); min-height: var(--objetivo-tactil); }
.linea label { flex: 1; align-self: stretch; display: flex; align-items: center; font-weight: 700; cursor: pointer; }
.interruptor { position: relative; flex: none; width: 3.25rem; height: 2rem; }
.interruptor input { position: absolute; top: 50%; left: 0; z-index: 1; width: 100%; height: max(100%, var(--objetivo-tactil)); margin: 0; opacity: 0; cursor: pointer; transform: translateY(-50%); }
.interruptor__pista {
  position: absolute;
  inset: 0;
  border: 2px solid var(--color-borde-control);
  border-radius: 1rem;
  background: var(--color-superficie);
  transition: background-color var(--transicion), border-color var(--transicion);
}
.interruptor__pista::after {
  content: "";
  position: absolute;
  top: 0.25rem;
  left: 0.25rem;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: var(--color-borde-control);
  transition: transform var(--transicion);
}
.interruptor input:checked + .interruptor__pista { border-color: var(--color-principal-hover); background: var(--color-principal-suave); }
.interruptor input:checked + .interruptor__pista::after { transform: translateX(1.25rem); background: var(--color-principal-hover); }
.interruptor input:focus-visible + .interruptor__pista { outline: 3px solid var(--color-principal); outline-offset: 3px; }

/* Campos con error: borde grueso de error y el porqué debajo, con ✕ (no solo color) */
.campo__opcional { font-weight: 400; color: var(--color-texto-secundario); }
/* Un texto de varias líneas (la descripción y el horario del local, paso 8): lo largo se ve entero, sin barra lateral */
.entrada--texto { min-height: 4.5rem; padding-block: var(--espacio-2); line-height: 1.5; resize: vertical; }
.entrada[aria-invalid="true"] { border: 2px solid var(--color-error); }
.campo__error { display: flex; gap: var(--espacio-2); align-items: flex-start; font-size: var(--texto-pequeno); font-weight: 700; color: var(--color-error); }
.campo__error svg { flex: none; margin-top: 0.0625rem; }
.campo__error circle { fill: var(--color-error); }
.campo__error path { fill: none; stroke: var(--color-error-fondo); stroke-width: 2.4; stroke-linecap: round; }
.verificacion__texto { display: grid; }

/* Seguridad: cada dispositivo con sus botones; cambiar el nombre y quitar se abren dentro de su tarjeta */
.dispositivos { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espacio-3); }
.dispositivo { display: grid; gap: var(--espacio-3); padding: var(--espacio-4); border-radius: var(--radio); background: var(--color-superficie); box-shadow: var(--sombra); }
.dispositivo__texto { display: grid; min-width: 0; }
.dispositivo__nombre { overflow-wrap: anywhere; }
.dispositivo__renombrar, .confirmar { display: grid; gap: var(--espacio-3); }
.aviso:focus { outline: none; }  /* recibe el foco por JS para que el lector lo lea: no se pulsa */

/* Tus datos: borrar la cuenta (dos pasos; lo que se pierde, en rojo y con «!», no solo color) */
.borrar { display: grid; gap: var(--espacio-3); padding: var(--espacio-4); border-radius: var(--radio); background: var(--color-error-fondo); }
.borrar__aviso { display: flex; gap: var(--espacio-3); align-items: flex-start; }
.borrar__aviso:focus { outline: none; }
.borrar__aviso strong { color: var(--color-error); }
.borrar__marca {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--color-error);
  color: var(--color-error-fondo);
  font-weight: 700;
  line-height: 1;
}
.verificacion--peligro input { accent-color: var(--color-error); }
.borrada { display: grid; justify-items: start; gap: var(--espacio-4); padding-top: var(--espacio-6); }
.borrada img { width: 4.5rem; height: 4.5rem; }
.borrada h1:focus { outline: none; }

/* ---------- Panel del local: el mostrador (/local/<slug>) · boceto aprobado (DEC-0041) ---------- */

/* Etiqueta pequeña encima de un título («Mostrador», «Tu trabajo»): en texto normal y discreto, sin mayúsculas
   (paso 2, DEC-0054: la etiqueta en mayúsculas encima de un título es otra señal de IA, DEC-0053) */
.antetitulo { font-size: var(--texto-pequeno); font-weight: 600; color: var(--color-texto-secundario); }
.avatar--pequeno { width: 2.75rem; height: 2.75rem; }

.mostrador__vista { display: grid; gap: var(--espacio-6); }
.mostrador__local { display: flex; align-items: center; gap: var(--espacio-4); }
.mostrador__titulo { display: grid; min-width: 0; }
.mostrador__titulo h1 { font-size: 1.875rem; overflow-wrap: anywhere; }

/* Dar sellos: la tarjeta que invita a actuar, con el contador (− n +) si el local da más de uno por compra */
.dar { display: grid; gap: var(--espacio-3); padding: var(--espacio-4); border-radius: var(--radio-grande); background: var(--color-superficie); box-shadow: var(--sombra-destacada); }
.contador { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--espacio-3); font-weight: 700; }
.contador__mandos { display: flex; align-items: center; gap: var(--espacio-3); }
/* Los botones − y +. Antes se llamaban «.paso» y pisaban los pasos numerados de la portada y de Memoria (ERR-0016) */
.contador__paso {
  display: grid;
  place-items: center;
  width: var(--objetivo-tactil);
  height: var(--objetivo-tactil);
  border: 1px solid var(--color-borde-control);
  border-radius: 50%;
  background: var(--color-superficie);
  color: var(--color-texto);
  font: inherit;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.contador__paso:disabled { opacity: 0.45; cursor: not-allowed; }
.contador__numero { min-width: 2ch; text-align: center; font-family: var(--letra-titulos); font-size: 1.75rem; font-weight: 750; }
/* El contador con el número escribible («Tus premios»: de 1 a 50 sellos, con − y + o tecleando) */
.contador__entrada { width: 5rem; text-align: center; font-family: var(--letra-titulos); font-size: 1.5rem; font-weight: 750; font-variant-numeric: tabular-nums; }

/* «Tus premios» (DEC-0059): la carta de premios del local, como la de un bar. Cada premio es una fila que se abre en el
   sitio para cambiarlo (un <details> con name="premio": uno abierto cada vez); abierto, lleva el borde de lo que se está
   tocando. «Añadir un premio» es otro igual. Sus clases no son las de la lista de premios de Tus tarjetas (.premio) */
.carta-premios { display: grid; gap: var(--espacio-3); }
.carta-premio__fila { list-style: none; cursor: pointer; }
.carta-premio__fila::-webkit-details-marker { display: none; }
.carta-premio__coste { font-variant-numeric: tabular-nums; }
.carta-premio__accion { flex: none; color: var(--color-principal-hover); font-weight: 700; }
.carta-premio__cerrar, .carta-premio[open] .carta-premio__abrir { display: none; }
.carta-premio[open] .carta-premio__cerrar { display: inline; }
.carta-premio[open] { border: 2px solid var(--color-principal-hover); border-radius: var(--radio); background: var(--color-superficie); }
.carta-premio[open] > .carta-premio__fila { box-shadow: none; }
.carta-premio__formulario { display: grid; gap: var(--espacio-4); padding: 0 var(--espacio-4) var(--espacio-4); }
.carta-premio__botones { display: flex; flex-wrap: wrap; gap: var(--espacio-3); }
.carta-premio__retirar { display: grid; justify-items: start; gap: var(--espacio-2); padding-top: var(--espacio-4); border-top: 1px solid var(--color-linea); }
.carta-premio--nuevo > summary { list-style: none; }
.carta-premio--nuevo > summary::-webkit-details-marker { display: none; }
.carta-premio--nuevo[open] > summary { display: none; }  /* abierto, se cierra con «Cancelar» */
.carta-premio--nuevo[open] > .carta-premio__formulario { padding-top: var(--espacio-4); }
.carta-premios__hecho { display: grid; justify-items: start; gap: var(--espacio-3); }
.carta-retirados { border-top: 1px solid var(--color-linea); padding-top: var(--espacio-2); }
.carta-retirados > summary { display: flex; align-items: center; min-height: var(--objetivo-tactil); font-weight: 700; cursor: pointer; }
.carta-retirados__lista { display: grid; gap: var(--espacio-3); }
.carta-retirado { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espacio-3); padding: var(--espacio-3) var(--espacio-4); border: 1px dashed var(--color-borde-control); border-radius: var(--radio); }
.carta-retirado .fila__texto { flex: 1 1 10rem; color: var(--color-texto-secundario); }
.boton--grande { min-height: 3.5rem; font-size: 1.1875rem; }

/* Canjear un premio: cada premio es un botón con su coste */
.premios-mostrador { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espacio-2); }
.premio-boton {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-1) var(--espacio-3);
  width: 100%;
  min-height: 3.5rem;
  padding: var(--espacio-2) var(--espacio-4);
  border: 1px solid var(--color-borde-control);
  border-radius: var(--radio);
  background: var(--color-superficie);
  color: var(--color-texto);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.premio-boton__nombre { flex: 999 1 8rem; font-weight: 700; overflow-wrap: anywhere; }
.premio-boton__coste { color: var(--color-texto-secundario); white-space: nowrap; }

/* Hoy: dos cifras y lo último primero (horas y cantidades, nunca quién) */
.hoy-cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr)); gap: var(--espacio-2); }
.hoy-cifra { display: grid; padding: var(--espacio-3) var(--espacio-4); border-radius: var(--radio); background: var(--color-acento-suave); color: var(--color-acento-oscuro); }
.hoy-cifra__numero { font-family: var(--letra-titulos); font-size: 2rem; font-weight: 750; line-height: 1.05; }
.hoy-cifra__texto { font-size: var(--texto-pequeno); font-weight: 700; }
.eventos { list-style: none; margin: 0; padding: 0; }
.evento { display: flex; gap: var(--espacio-3); padding: var(--espacio-2) 0; border-top: 1px solid var(--color-linea); }
.evento__hora { flex: none; min-width: 3.25rem; font-weight: 700; color: var(--color-texto-secundario); font-variant-numeric: tabular-nums; }
.eventos-mas summary { display: flex; align-items: center; min-height: var(--objetivo-tactil); font-weight: 700; color: var(--color-principal-hover); cursor: pointer; }

/* El QR: grande, siempre oscuro sobre blanco (también de noche) y con su cuenta atrás */
.qr-vista { display: grid; gap: var(--espacio-4); text-align: center; }
.qr-vista h1:focus, .qr-hecho h1:focus { outline: none; }
.qr-tarjeta { position: relative; justify-self: center; padding: var(--espacio-4); border: 1px solid var(--color-linea); border-radius: var(--radio-grande); background: var(--color-qr-fondo); }
.qr-tarjeta img { display: block; width: min(15rem, 70vw); height: auto; aspect-ratio: 1; }
.qr-tarjeta--caducado img { opacity: 0.15; }
.qr-tarjeta__caducado {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: var(--espacio-2) var(--espacio-4);
  border-radius: 999px;
  background: var(--color-texto);
  color: var(--color-superficie);
  font-weight: 700;
  white-space: nowrap;
}
.qr-tiempo { display: grid; gap: var(--espacio-1); }
.qr-tiempo__barra { width: 100%; height: 0.5rem; border: 0; border-radius: 0.25rem; background: var(--color-linea); overflow: hidden; appearance: none; -webkit-appearance: none; }
.qr-tiempo__barra::-webkit-progress-bar { background: var(--color-linea); }
.qr-tiempo__barra::-webkit-progress-value { background: var(--color-principal-hover); border-radius: 0.25rem; }
.qr-tiempo__barra::-moz-progress-bar { background: var(--color-principal-hover); border-radius: 0.25rem; }
.qr-tiempo__texto { font-weight: 700; font-variant-numeric: tabular-nums; }
/* El tiempo y «+1 minuto» (paso 5, DEC-0055) en una fila; con letra grande, el botón baja debajo, entero */
.qr-tiempo__fila { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--espacio-2) var(--espacio-4); }
.qr-estado { display: flex; align-items: center; justify-content: center; gap: var(--espacio-3); padding: var(--espacio-3) var(--espacio-4); border-radius: var(--radio); background: var(--color-principal-suave); color: var(--color-principal-hover); font-weight: 700; }
.qr-estado--caducado { background: var(--color-advertencia-fondo); color: var(--color-advertencia); }
.qr-vista .boton--secundario { justify-self: center; }

/* Hecho: el sello (o el premio) ya está en el móvil del cliente */
.qr-hecho { display: grid; justify-items: center; gap: var(--espacio-4); padding-top: var(--espacio-6); text-align: center; }
.qr-hecho__marca { display: grid; place-items: center; width: 6rem; height: 6rem; border-radius: 50%; background: var(--color-exito-fondo); }
.qr-hecho__marca > span { display: grid; place-items: center; width: 4rem; height: 4rem; border-radius: 50%; background: var(--color-exito); color: var(--color-exito-fondo); }

/* Tu trabajo: el acceso del equipo a su mostrador (arriba en el Inicio) */
.trabajos { display: grid; gap: var(--espacio-3); }
.trabajos--arriba { margin-bottom: var(--espacio-5); }
.trabajo { display: flex; align-items: center; gap: var(--espacio-3); padding: var(--espacio-3) var(--espacio-4); border-radius: var(--radio-grande); background: var(--color-acento-suave); color: var(--color-texto); text-decoration: none; }
.trabajo .avatar { width: 3.25rem; height: 3.25rem; background: var(--color-superficie); }
.trabajo__texto { flex: 1; display: grid; min-width: 0; }
.trabajo__nombre { font-size: 1.125rem; line-height: 1.25; overflow-wrap: anywhere; }
.trabajo__accion { font-size: var(--texto-pequeno); font-weight: 700; color: var(--color-acento-oscuro); }
.trabajo svg { flex: none; color: var(--color-acento-oscuro); }

/* ---------- Panel del local: «Cómo va tu local» (/local/<slug>/cifras) · boceto aprobado (DEC-0041), DS «Cifras» ---------- */

/* En escritorio, más aire y más columnas (boceto 8): no más cosas */
.pagina--amplia { max-width: 60rem; }
.cifras { display: grid; gap: var(--espacio-6); }
.cifras__cabeza { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--espacio-3) var(--espacio-5); }
.cifras__cabeza .filtros { margin-top: 0; }

/* Cada cifra: etiqueta, número grande y una línea que la explica; 2 en fila en el móvil (1 con letra muy grande o
   enorme, como «Hoy» del mostrador) y 4 en escritorio */
.cifras__tarjetas { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr)); gap: var(--espacio-3); }
.cifra-tarjeta {
  display: grid;
  align-content: start;
  gap: var(--espacio-1);
  margin: 0;
  padding: var(--espacio-4);
  border-radius: var(--radio);
  background: var(--color-superficie);
  box-shadow: var(--sombra);
}
.cifra-tarjeta__etiqueta { font-size: var(--texto-pequeno); font-weight: 700; line-height: 1.3; }
.cifra-tarjeta__numero { font-family: var(--letra-titulos); font-size: 2.25rem; font-weight: 750; line-height: 1.05; overflow-wrap: anywhere; }
.cifra-tarjeta__detalle { font-size: var(--texto-pequeno); line-height: 1.4; color: var(--color-texto-secundario); }
.cifra-tarjeta__detalle--sube { font-weight: 700; color: var(--color-exito); }  /* sube: flecha, palabras y verde */
.cifra-tarjeta__nota { font-size: var(--texto-pequeno); font-weight: 700; }  /* en vez del número, si aún no hay datos */
.cifra-tarjeta--suave { background: var(--color-acento-suave); box-shadow: none; color: var(--color-acento-oscuro); }

/* Visitas por día: barras en acento (≥ 3:1 sobre la superficie en los dos modos), sin ejes ni rejilla */
.grafica { padding: var(--espacio-4) var(--espacio-4) var(--espacio-2); border-radius: var(--radio); background: var(--color-superficie); box-shadow: var(--sombra); }
.grafica svg { display: block; width: 100%; height: auto; }
.grafica rect { fill: var(--color-acento); }
.grafica line { stroke: var(--color-linea); stroke-width: 1; }
.grafica__ejes { display: flex; justify-content: space-between; gap: var(--espacio-3); margin-top: var(--espacio-1); font-size: 0.8125rem; font-weight: 700; color: var(--color-texto-secundario); }

/* ¿Vuelven?: dos cifras sobre caramelo suave; en escritorio, al lado de las visitas */
.vuelven { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr)); gap: var(--espacio-3); }
.cifras__fila { display: flex; flex-wrap: wrap; gap: var(--espacio-6) var(--espacio-5); }
.cifras__visitas { flex: 999 1 26rem; min-width: 0; }
.cifras__vuelven { flex: 1 1 15rem; min-width: 0; }

/* Oportunidades: número grande en caramelo oscuro, qué es y qué puedes hacer */
.oportunidades { list-style: none; margin: 0; padding: 0; display: grid; }
.oportunidad { display: flex; align-items: flex-start; gap: var(--espacio-4); padding: var(--espacio-3) 0; border-top: 1px solid var(--color-linea); }
.oportunidad__numero { flex: none; min-width: 2.75rem; font-family: var(--letra-titulos); font-size: 1.875rem; font-weight: 750; line-height: 1; color: var(--color-acento-oscuro); }
.oportunidad__texto { display: grid; min-width: 0; }
.oportunidad__ayuda { font-size: var(--texto-pequeno); color: var(--color-texto-secundario); }

/* «Solo cifras»: el aviso de información, con su candado */
.cifras__privado svg { flex: none; margin-top: 0.125rem; }
.cifras__privado strong { color: var(--color-info); }

@media (min-width: 48rem) {
  .cifras__tarjetas { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .cifra-tarjeta__numero { font-size: 2.5rem; }
  .oportunidades { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: var(--espacio-3); }
  .oportunidad { padding: var(--espacio-4); border-top: 0; border-radius: var(--radio); background: var(--color-superficie); box-shadow: var(--sombra); }
}

/* ---------- Panel del local: «Tu equipo» (/local/<slug>/equipo) y aceptar una invitación (/invitacion) ----------
   Boceto aprobado (DEC-0041, mesas 7 y 9), componente «Equipo» del Design System */

.equipo { display: grid; gap: var(--espacio-6); }

/* Cada persona: su alias y su papel; el botón, al lado si cabe y, si no, debajo. Quitar se abre dentro de su tarjeta. */
.miembros { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espacio-3); }
.miembro {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-3);
  padding: var(--espacio-3) var(--espacio-4);
  border-radius: var(--radio);
  background: var(--color-superficie);
  box-shadow: var(--sombra);
}
.miembro__texto { flex: 999 1 10rem; display: grid; min-width: 0; }
.miembro__alias { overflow-wrap: anywhere; }
.miembro .confirmar, .miembro__aviso { flex-basis: 100%; }

/* «¿Qué podrá hacer?»: las opciones de Ajustes, a lo ancho y con su explicación debajo (también en gris en la elegida:
   texto-secundario sobre principal-suave, 5,6:1 y 6,8:1) */
.invitar { display: grid; gap: var(--espacio-4); }
.opciones--papel { grid-template-columns: minmax(0, 1fr); }
.opcion--papel { align-items: flex-start; padding: var(--espacio-3) var(--espacio-4); font-size: inherit; text-align: left; }
.opcion__ayuda { font-size: var(--texto-pequeno); font-weight: 400; color: var(--color-texto-secundario); }

/* Enlace listo: caja de éxito con su ✓, el enlace (solo lectura) y «Compartir» / «Copiar enlace».
   Los bordes de los controles sobre exito-fondo: 3,3:1 y 3,8:1 */
.enlace-listo { display: grid; gap: var(--espacio-3); padding: var(--espacio-4); border-radius: var(--radio); background: var(--color-exito-fondo); }
.enlace-listo__texto { display: flex; gap: var(--espacio-3); align-items: flex-start; }
.enlace-listo__texto:focus { outline: none; }
.enlace-listo__texto strong { color: var(--color-exito); }
.enlace-listo .entrada { width: 100%; min-width: 0; }

/* ---------- Tarjetas del mostrador (/local/<slug>/tarjetas) · paso 3, DEC-0051, boceto aprobado (mesas 11 a 16) ----------
   En el móvil, una columna en el orden de la página: sin tarjetas, «Cómo funciona» (con la tarjeta en 3D) va antes de
   crearla; con tarjetas, la lista primero y «Cómo funciona» al final. En el ordenador, dos columnas: lo que haces a la
   izquierda y lo que lo explica, a la derecha. La lista usa la fila de «Tu equipo» (.miembro): el mismo dibujo y los
   mismos dos pasos para quitar. */
.tarjetas-mostrador { display: grid; gap: var(--espacio-6); }
.tarjetas-mostrador__ayuda,
.tarjetas-mostrador__lista,
.tarjetas-mostrador__crear { display: grid; gap: var(--espacio-3); align-content: start; }
.tarjetas-mostrador__ayuda .pasos { margin-top: var(--espacio-2); }
.tarjetas-mostrador__objeto { display: block; justify-self: center; width: min(12rem, 60%); height: auto; }

/* La tarjeta recién creada: la caja de éxito con su ✓ (y, en iPhone, la dirección para copiarla) y debajo lo que toca:
   grabarla con el móvil, bloquearla o los pasos para otra app. Los bordes de los controles sobre exito-fondo, como en
   «Enlace listo» (3,3:1 y 3,8:1) */
.tarjeta-nueva { display: grid; gap: var(--espacio-5); }
.tarjeta-nueva__caja { display: grid; gap: var(--espacio-3); padding: var(--espacio-4); border-radius: var(--radio); background: var(--color-exito-fondo); }
.tarjeta-nueva__titulo { display: flex; gap: var(--espacio-3); align-items: flex-start; }
.tarjeta-nueva__titulo:focus { outline: none; }
.tarjeta-nueva__titulo strong { color: var(--color-exito); }
.tarjeta-nueva__direccion { display: grid; gap: var(--espacio-3); }
.tarjeta-nueva__direccion .entrada { width: 100%; min-width: 0; }
.tarjeta-nueva__parte { display: grid; gap: var(--espacio-4); }
.tarjeta-nueva__parte .pasos { margin-top: 0; }
.tarjeta-nueva__cancelar { justify-self: center; }
/* «¿Este móvil no tiene NFC? Copia la dirección»: hace algo aquí (no lleva a otra página), así que es un botón, pero se
   ve como un enlace: es la salida de al lado, no la acción principal */
.tarjeta-nueva__otra-app {
  justify-self: center;
  min-height: var(--objetivo-tactil);
  padding: 0 var(--espacio-2);
  border: 0;
  background: none;
  color: var(--color-principal-hover);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  cursor: pointer;
}
.tarjeta-nueva__volver { justify-self: center; display: inline-flex; align-items: center; min-height: var(--objetivo-tactil); }

/* En el ordenador: lo que lo explica, a la derecha, a lo alto de toda la página. Su altura cae en la última fila (1fr),
   así que no separa los bloques de la izquierda, que se ponen uno detrás de otro con su margen. */
@media (min-width: 60rem) {
  .tarjetas-mostrador {
    grid-template-columns: minmax(0, 1fr) minmax(16rem, 20rem);
    grid-template-rows: repeat(4, auto) 1fr;
    column-gap: var(--espacio-7);
    row-gap: 0;
    align-items: start;
  }
  .tarjetas-mostrador > * { grid-column: 1; margin-bottom: var(--espacio-6); }
  .tarjetas-mostrador > .tarjetas-mostrador__ayuda { grid-column: 2; grid-row: 1 / -1; margin-bottom: 0; }
}

/* La invitación: el logo, a qué local y con qué cuenta, y los botones a lo ancho */
.invitacion { display: grid; gap: var(--espacio-5); padding-top: var(--espacio-4); }
.invitacion__logo { width: 4.5rem; height: 4.5rem; }
.invitacion__estado { display: grid; gap: var(--espacio-4); }
.invitacion__estado h1:focus { outline: none; }
.invitacion__lema { font-size: 1.1875rem; }
.invitacion__cuenta { display: grid; padding: var(--espacio-3) var(--espacio-4); border-radius: var(--radio); background: var(--color-superficie); box-shadow: var(--sombra); }
.invitacion__alias { overflow-wrap: anywhere; }
.invitacion__acciones { display: grid; gap: var(--espacio-3); margin-top: var(--espacio-2); }

/* ---------- Memoria (punto 6 · DEC-0043; más humano y en 3D, DEC-0042; DS «Memoria» y «CartaMemoria») ----------
   Presupuesto de atención: un protagonista por pantalla (el abanico, el tablero o los puntos), una acción principal y
   un detalle humano. Las caras son objetos 3D de estudio (estaticos/iconos/); el dorso, el sello J&G. */

.memoria { display: grid; gap: var(--espacio-5); }
.memoria h1:focus { outline: none; }
.memoria .pasos { margin-top: 0; }
.memoria__resumen { font-size: 1.1875rem; }
.memoria__local { display: flex; align-items: center; gap: var(--espacio-3); }
.memoria__local-texto { display: grid; min-width: 0; }
.memoria__local-nombre { font-family: var(--letra-titulos); font-size: var(--titulo-2); line-height: 1.2; overflow-wrap: anywhere; }
.memoria__otras { display: grid; gap: var(--espacio-3); }
.memoria__otras-titulo { font-size: 1.1875rem; }
.memoria__otras .locales-lista { margin-top: 0; }
.memoria__otras .fila__flecha { flex: none; margin-left: auto; color: var(--color-texto-secundario); }

/* El abanico de «Antes de empezar»: dos cartas de dorso y una cara en 3D. Decorativo, con tope en px para que la letra
   «enorme» no lo desborde */
.abanico { position: relative; width: min(16rem, 260px); height: min(7.25rem, 118px); margin: 0 auto; }
.naipe {
  position: absolute;
  top: min(0.875rem, 14px);
  width: min(5.5rem, 88px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: var(--radio-control);
  background: var(--color-principal-suave);
  border: 1px solid var(--color-borde-control);
  box-shadow: var(--sombra-destacada);
}
.naipe img { width: 46%; height: auto; }
.naipe--izquierda { left: min(0.625rem, 10px); transform: rotate(-12deg); }
.naipe--derecha { right: min(0.625rem, 10px); transform: rotate(12deg); }
.naipe--cara { top: 0; left: calc(50% - min(2.75rem, 44px)); background: var(--color-superficie); border: 2px solid var(--color-texto); }
.naipe--cara img { width: 82%; }
.abanico--quieto { width: min(11rem, 180px); margin: 0; }
.abanico--quieto .naipe--izquierda { left: 0; transform: rotate(-6deg); }
.abanico--quieto .naipe--cara { left: auto; right: 0; transform: rotate(5deg); }

/* Jugando: el marcador (parejas, fallos, tiempo) con la barra que se vacía y, en los últimos 30 s, en advertencia */
.memoria--jugando { gap: var(--espacio-4); }
.memoria__cabeza { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 var(--espacio-3); }
.memoria__titulo { font-size: 1.875rem; }
.marcador { display: grid; gap: var(--espacio-2); padding: var(--espacio-3) var(--espacio-4); border-radius: var(--radio); background: var(--color-superficie); box-shadow: var(--sombra); }
/* Cada dato, a su ancho y sin partirse («0 de 8» entero): con letra enorme, si no caben, baja el dato entero */
.marcador__datos { margin: 0; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--espacio-2) var(--espacio-4); }
.marcador__dato { display: grid; align-content: start; }
.marcador__dato dt { font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.02em; color: var(--color-texto-secundario); }
.marcador__dato dd { margin: 0; font-family: var(--letra-titulos); font-size: 1.375rem; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; white-space: nowrap; }
.marcador__dato--tiempo { justify-items: end; margin-left: auto; }
.marcador__barra { height: 0.375rem; border-radius: 999px; background: var(--color-linea); overflow: hidden; }
.marcador__relleno { display: block; height: 100%; border-radius: 999px; background: var(--color-acento); transform-origin: left; transition: transform 250ms linear; }
.memoria--poco-tiempo .marcador__dato--tiempo dd { color: var(--color-advertencia); }
.memoria--poco-tiempo .marcador__relleno { background: var(--color-advertencia); }
.memoria__estado { min-height: 3.2em; text-align: center; }

/* El tablero: 4 × 4 cartas que giran en 3D (concepto «Giro 3D con CSS»). Boca abajo, la cara está vacía: la pone
   memoria.js cuando el servidor dice qué hay. Con menos movimiento, sin giro (regla general de arriba). */
.tablero { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--espacio-2); }
.carta {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: var(--radio-control);
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  perspective: 600px;
}
.carta:focus-visible { border-radius: var(--radio-control); }
.carta[aria-disabled="true"] { cursor: default; }
.carta__interior { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform 250ms ease; }
.carta--arriba .carta__interior,
.carta--pareja .carta__interior { transform: rotateY(180deg); }
.carta--pensando .carta__interior { transform: scale(0.96); }
.carta__dorso,
.carta__cara {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: var(--radio-control);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.carta__dorso { background: var(--color-principal-suave); border: 1px solid var(--color-borde-control); }  /* 3:1: se ve dónde pulsar */
.carta__dorso img { width: 46%; height: auto; }
.carta__cara { transform: rotateY(180deg); background: var(--color-superficie); border: 2px solid var(--color-texto); }
.carta__cara img { width: 84%; height: auto; }
/* Pareja: fondo, borde y un sello ✓ que se estampa con el gesto de sello de toda la app (no solo color) */
.carta--pareja .carta__cara { background: var(--color-acento-suave); border-color: var(--color-acento); }
.carta--pareja .carta__cara::after {
  content: "✓";
  position: absolute;
  top: 0.2rem;
  right: 0.2rem;
  width: 1.25rem;
  height: 1.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--color-acento);
  color: var(--color-acento-suave);
  font-size: 0.75rem;
  font-weight: 700;
  --giro: -12deg;
  transform: rotate(var(--giro));
  animation: estampar-tinta 250ms cubic-bezier(0.3, 1.4, 0.6, 1) both;
}

/* El resultado: los puntos en grande, «Tus parejas» y el ranking del mes con tu fila marcada */
.memoria--resultado { gap: var(--espacio-4); }
.resultado__puntos { display: flex; align-items: baseline; gap: var(--espacio-2); margin-top: var(--espacio-2); }
.resultado__cifra { font-family: var(--letra-titulos); font-size: 3.25rem; font-weight: 750; line-height: 1; font-variant-numeric: tabular-nums; }
.resultado__quedan { text-align: center; }
.coleccion { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 0.375rem; max-width: 28rem; }
.coleccion__hueco { aspect-ratio: 1; display: grid; place-items: center; border-radius: 8px; background: var(--color-acento-suave); border: 1px solid var(--color-acento); }
.coleccion__hueco img { width: 88%; height: auto; }
.coleccion__hueco--vacio { background: none; border: 1.5px dashed var(--color-borde-control); }
.ranking { display: grid; gap: var(--espacio-1); }
.ranking__lista { list-style: none; margin: var(--espacio-3) 0 0; padding: 0; }
.ranking__puesto { display: flex; align-items: center; gap: var(--espacio-3); padding: var(--espacio-3) 0; border-top: 1px solid var(--color-linea); }
.ranking__n { flex: none; width: 1.5rem; font-weight: 700; color: var(--color-texto-secundario); }
.ranking__nombre { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.ranking__puntos { font-weight: 700; font-variant-numeric: tabular-nums; }
.ranking__puesto--tu {
  margin: 0 calc(-1 * var(--espacio-3));
  padding-inline: var(--espacio-3);
  border-top-color: transparent;
  border-radius: var(--radio-control);
  background: var(--color-principal-suave);
}
.ranking__puesto--tu .ranking__n { color: var(--color-principal-hover); }
.ranking__tuyo { margin-top: var(--espacio-3); font-weight: 600; }

/* Tras el sello (escanear.html): la partida que trae y «Jugar tu partida» como acción principal */
.partida-nueva { display: flex; align-items: center; gap: var(--espacio-3); margin-top: var(--espacio-5); padding: var(--espacio-3) var(--espacio-4); border-radius: var(--radio); background: var(--color-superficie); box-shadow: var(--sombra); }
.partida-nueva img { flex: none; width: min(3.25rem, 65px); height: auto; }
.partida-nueva__texto { display: grid; min-width: 0; }
.acciones--columna { display: grid; }

@media (min-width: 48rem) {
  .tablero { width: 100%; max-width: 30rem; margin: 0 auto; gap: var(--espacio-3); }
}

/* ---------- Portada (punto 8, DEC-0045; Design System, «Portada») ---------- */

/* El protagonista (02-11, DEC-0049 y /diseno-sin-ia): tres tarjetas de sellos de cartulina de tiendas distintas, en 3D
   (diseno/blender/portada_3d.py). Al abrir la portada, el sello J&G baja una vez al hueco que espera de la de delante,
   se aprieta y vuelve, y aparece su tinta (una capa hecha con la misma cámara). Es un dibujo (aria-hidden). Con
   «reducir movimiento» no se mueve nada y ya sale sellada. Todo en % de la imagen: el hueco cae al 27,47 % del ancho y
   al 68,24 % del alto (lo dice portada_3d.py al renderizar), y así se alinea a cualquier tamaño. */
.portada__ejemplo { position: relative; width: min(30rem, 100%); aspect-ratio: 1220 / 720; margin: var(--espacio-4) 0 var(--espacio-5); }
.portada__tarjetas,
.portada__tinta { position: absolute; inset: 0; width: 100%; height: 100%; }
.portada__tinta { animation: tinta-portada 900ms ease-out 300ms both; }
.portada__sello {
  position: absolute;
  left: 14.6%;   /* 27,47 % (el hueco) menos medio sello */
  top: 41.3%;    /* 68,24 % menos algo más de medio sello: el sello apoya por abajo */
  width: 25.7%;
  height: auto;
  filter: drop-shadow(var(--sombra-logo));
  transform: translate(220%, -75%) rotate(-14deg) scale(1.1);  /* en reposo, arriba a la derecha */
  animation: sello-portada 900ms cubic-bezier(0.3, 1.15, 0.6, 1) 300ms both;
}
@keyframes sello-portada {
  0%, 100% { transform: translate(220%, -75%) rotate(-14deg) scale(1.1); }
  40%, 60% { transform: translate(0, 0) rotate(-6deg) scale(1); }
  50% { transform: translate(0, 2%) rotate(-6deg) scale(0.92); }  /* aprieta */
}
@keyframes tinta-portada { 0%, 45% { opacity: 0; } 55%, 100% { opacity: 1; } }
.portada__titulo { text-wrap: balance; }  /* líneas equilibradas: en escritorio, «móvil» no se queda solo */

/* También las usan crear cuenta, entrar, recuperar y la página de error */
.portada__resumen { margin-top: var(--espacio-4); font-size: 1.1875rem; }
.portada__acciones { margin-top: var(--espacio-6); }
.portada__confianza { margin-top: var(--espacio-5); }

.portada__nota { margin: 0.875rem 0 0 0.375rem; }  /* el único detalle a mano de la portada */
.portada__donde { margin-top: var(--espacio-3); }
.portada__enlace { display: inline-flex; align-items: center; min-height: var(--objetivo-tactil); margin-top: var(--espacio-1); }

@media (min-width: 48rem) {
  .pagina { padding-top: var(--espacio-7); }
}

/* En el ordenador (paso 2, DEC-0054; boceto «La portada en el ordenador»): dos columnas en una página más ancha, el texto a
   la izquierda y las tarjetas a la derecha (solo cambia dónde se ven: el dibujo no se lee y no se pulsa). Debajo, «Cómo
   funciona» y «¿Dónde consigo sellos?» en una fila con una raya encima. Más aire, no más cosas: «Ya tengo cuenta» sale
   una sola vez. La cabecera se ensancha con la página, para que el sello quede alineado con el texto. */
@media (min-width: 60rem) {
  .pagina--portada,
  body:has(.pagina--portada) .cabecera-app { max-width: 70rem; padding-inline: var(--espacio-7); }
  .portada { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 30rem); align-items: center; gap: var(--espacio-7); }
  .portada .portada__ejemplo { order: 2; width: 100%; margin: 0; }
  .portada__titulo { font-size: 3.25rem; line-height: 1.05; letter-spacing: -0.015em; }
  .portada__texto .portada__resumen { max-width: 32rem; font-size: 1.3125rem; }
  .pagina--portada .pasos { max-width: 38rem; }
  .portada__lugar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
    column-gap: var(--espacio-6);
    align-items: center;
    padding-top: var(--espacio-5);
    border-top: 1px solid var(--color-linea);
  }
  .portada__lugar > * { grid-column: 1; }
  .portada__lugar .portada__confianza { grid-column: 2; grid-row: 1 / span 3; margin-top: 0; }
}

/* ---------- El cartel del local (punto 9 bis, DEC-0047; Design System, «Cartel») ---------- */

/* La página: el tamaño, la vista previa (la protagonista) y lo demás, en ese orden en el móvil; en escritorio, la
   vista previa a la izquierda y el resto a la derecha */
.cartel-pagina { display: grid; gap: var(--espacio-6); }
.cartel-pagina__cuerpo { display: grid; gap: var(--espacio-6); }
.cartel-pagina__acciones { display: grid; gap: var(--espacio-6); align-content: start; }
.cartel-vista { margin: 0; display: grid; gap: var(--espacio-2); justify-items: center; }
.cartel-vista__papel { width: 100%; max-width: 28rem; }
/* Las dos hojas vienen en la página: se ve (y se imprime) solo la elegida, sin JavaScript */
.cartel-pagina:has(#tamano-grande:checked) .hoja--mediano,
.cartel-pagina:has(#tamano-mediano:checked) .hoja--grande { display: none; }
.cartel-nfc { border-top: 1px solid var(--color-linea); }
.cartel-nfc summary { display: flex; align-items: center; min-height: var(--objetivo-tactil); font-weight: 700; color: var(--color-principal-hover); cursor: pointer; }
.cartel-nfc__cuerpo { display: grid; gap: var(--espacio-4); padding-top: var(--espacio-2); }
.cartel-nfc__cuerpo .pasos { margin-top: var(--espacio-2); }

@media (min-width: 48rem) {
  .cartel-pagina__cuerpo {
    grid-template-columns: minmax(0, 26rem) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    grid-template-areas: "vista tamano" "vista acciones";
    column-gap: var(--espacio-7);
    align-items: start;
  }
  .cartel-tamano { grid-area: tamano; }
  .cartel-vista { grid-area: vista; }
  .cartel-pagina__acciones { grid-area: acciones; }
}

/* La hoja: siempre papel claro (--color-papel-*, también de noche) y todo en proporción a su ancho (cqi), así que la
   vista previa y el papel son el mismo dibujo. Al imprimir salen también sus fondos (print-color-adjust). */
.hoja {
  container-type: inline-size;
  position: relative;
  width: 100%;
  aspect-ratio: 210 / 297;
  overflow: hidden;
  background: var(--color-papel);
  color: var(--color-papel-texto);
  box-shadow: var(--sombra-destacada);
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}
.cartel {
  height: 100%;
  padding: 6cqi 7cqi 5.5cqi;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  line-height: 1.3;
}
.cartel__local { margin: 0; display: flex; align-items: center; gap: 2cqi; font-family: var(--letra-titulos); font-size: 4.3cqi; font-weight: 700; line-height: 1.15; }
.cartel__figura { flex: none; display: grid; place-items: center; width: 11cqi; height: 11cqi; border-radius: 50%; background: var(--color-papel-suave); }
.cartel__figura img { width: 90%; height: 90%; object-fit: contain; }
.cartel__titulo { margin: 3.5cqi 0 0; font-family: var(--letra-titulos); font-size: 9.8cqi; font-weight: 750; line-height: 1.02; letter-spacing: -0.02em; text-wrap: balance; }
.cartel__resumen { margin: 2.3cqi 0 0; font-size: 3.3cqi; line-height: 1.35; }
/* El QR, protagonista, y el único toque a mano: «¡Apunta aquí!» con su flecha */
.cartel__codigo { position: relative; margin-top: 3.8cqi; }
.cartel__marco { padding: 2cqi; border: 0.25cqi solid var(--color-papel-linea); border-radius: 3cqi; background: var(--color-papel); }
.cartel__qr { display: block; width: 45cqi; height: 45cqi; }
.cartel__nota { position: absolute; top: 8.8cqi; left: calc(100% + 2.3cqi); width: 16.6cqi; margin: 0; font-family: var(--letra-mano); font-size: 5cqi; font-weight: 600; line-height: 0.95; color: var(--color-papel-tinta); text-align: left; transform: rotate(-6deg); }
.cartel__flecha { position: absolute; top: 19.9cqi; left: calc(100% - 2.8cqi); width: 15.1cqi; height: 11.3cqi; fill: none; stroke: var(--color-papel-tinta); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.cartel__pasos { list-style: none; margin: 4.3cqi 0 0; padding: 0; width: 100%; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3cqi; }
.cartel__paso { display: grid; justify-items: center; align-content: start; gap: 1.3cqi; font-size: 2.8cqi; font-weight: 650; }
.cartel__numero { display: grid; place-items: center; width: 5.5cqi; height: 5.5cqi; border-radius: 50%; background: var(--color-papel-suave); color: var(--color-papel-numero); font-weight: 700; }
.cartel__pie { margin-top: auto; width: 100%; padding-top: 2.3cqi; border-top: 0.25cqi solid var(--color-papel-linea); display: flex; align-items: center; justify-content: space-between; gap: 2cqi; }
.cartel__marca { display: inline-flex; align-items: center; gap: 1.3cqi; font-family: var(--letra-titulos); font-size: 3.8cqi; font-weight: 700; line-height: 1; }
.cartel__marca img { width: 6.5cqi; height: 6.5cqi; }
.cartel__direccion { font-size: 2.5cqi; color: var(--color-papel-secundario); overflow-wrap: anywhere; }

/* El mediano: dos A5 apaisados en la hoja A4; el QR a la izquierda y el texto a la derecha. Medidas en cqi de la hoja. */
.hoja--mediano { display: flex; flex-direction: column; }
.hoja--mediano::after { content: ""; position: absolute; top: 50%; left: 0; right: 0; border-top: 0.25cqi dashed var(--color-papel-secundario); }
.hoja__corte { position: absolute; z-index: 1; top: 50%; left: 5cqi; margin: 0; padding: 0 1cqi; display: flex; align-items: center; gap: 0.8cqi; background: var(--color-papel); color: var(--color-papel-secundario); font-size: 1.64cqi; line-height: 1; transform: translateY(-50%); }
.hoja__corte svg { width: 2.3cqi; height: 2.3cqi; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cartel--mediano { height: 50%; flex-direction: row; align-items: center; gap: 5cqi; padding: 5.5cqi 6cqi; text-align: left; }
.cartel--mediano .cartel__codigo { flex: none; margin: 0; }
.cartel--mediano .cartel__marco { padding: 1.5cqi; border-radius: 2.5cqi; }
.cartel--mediano .cartel__qr { width: 33.75cqi; height: 33.75cqi; }
.cartel--mediano .cartel__nota { top: -6.5cqi; left: 18.9cqi; width: auto; white-space: nowrap; font-size: 4cqi; transform: rotate(-5deg); }
.cartel--mediano .cartel__flecha { top: -4.5cqi; left: 11.6cqi; width: 7.6cqi; height: 6.3cqi; stroke-width: 3.5; }
.cartel__texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1.8cqi; }
.cartel--mediano .cartel__local { gap: 1.5cqi; font-size: 3cqi; }
.cartel--mediano .cartel__figura { width: 7cqi; height: 7cqi; }
.cartel--mediano .cartel__titulo { margin: 0; font-size: 5.3cqi; }
.cartel--mediano .cartel__resumen { margin: 0; font-size: 2.27cqi; }
.cartel--mediano .cartel__pasos { margin: 0.5cqi 0 0; grid-template-columns: minmax(0, 1fr); gap: 1cqi; }
.cartel--mediano .cartel__paso { display: flex; align-items: center; gap: 1.3cqi; font-size: 2.14cqi; }
.cartel--mediano .cartel__numero { flex: none; width: 3.8cqi; height: 3.8cqi; font-size: 2cqi; }
.cartel--mediano .cartel__pie { margin-top: 0.8cqi; padding-top: 0; border-top: 0; justify-content: flex-start; }
.cartel--mediano .cartel__marca { font-size: 2.5cqi; }
.cartel--mediano .cartel__marca img { width: 4.3cqi; height: 4.3cqi; }
.cartel--mediano .cartel__direccion { font-size: 1.76cqi; }

/* Al imprimir sale solo la hoja elegida, a su tamaño y sin los márgenes del navegador (que así tampoco añade la
   dirección ni la fecha). @page con nombre: imprimir cualquier otra página de J&G sigue igual. */
@page cartel { size: A4 portrait; margin: 0; }
@media print {
  body:has(.cartel-pagina) { page: cartel; background: var(--color-papel); }
  body:has(.cartel-pagina) .pagina { max-width: none; margin: 0; padding: 0; }
  body:has(.cartel-pagina) .barra,
  .cartel-pagina .cuenta__cabeza,
  .cartel-tamano,
  .cartel-vista figcaption,
  .cartel-pagina__acciones { display: none !important; }
  .cartel-pagina, .cartel-pagina__cuerpo, .cartel-vista { display: block; }
  .cartel-vista__papel { max-width: none; }
  .hoja { width: 210mm; height: 296mm; aspect-ratio: auto; box-shadow: none; break-inside: avoid; }
}

/* ---------- Las condiciones y la privacidad (paso 7, DEC-0057; boceto aprobado en Claude Design, «Escanea y Juega ·
   Condiciones y privacidad») ---------- */

/* Dos páginas para leer con calma: una sola columna (también en el ordenador), títulos que dicen lo que hay y la letra
   de siempre, sin letra pequeña. Un correo o un nombre largos se parten antes que salirse de la pantalla (R-34). */
.legal { overflow-wrap: anywhere; }
.legal h1 { text-wrap: balance; }  /* «Las condiciones / de J&G»: que «J&G» no se quede solo en su línea */
.legal__fecha { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--espacio-2) var(--espacio-5); margin-top: var(--espacio-2); }
.legal__nota { transform-origin: left center; }  /* el único guiño a mano: «Sin letra pequeña», «Solo lo justo» */
/* «En corto»: el reverso de una tarjeta de sellos (un panel) con el sello J&G entintado arriba a la derecha, girado y
   con la tinta que no cubre del todo, como un sello de goma de verdad. Cada página lo gira a su manera. Con la letra
   grande, el sitio va al texto (como en el botón): el sello no pasa de 64 px ni el panel de 20 px a los lados, y «En
   corto» cabe en una línea también con la letra enorme. */
.en-corto { margin-top: var(--espacio-5); padding-inline: min(var(--espacio-5), 20px); }
.en-corto__cabeza { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--espacio-3); }
.en-corto__sello { flex: none; width: min(3.625rem, 64px); height: min(3.625rem, 64px); margin: -0.375rem -0.25rem 0 0; color: var(--color-acento); opacity: 0.9; transform: rotate(-11deg); }
.en-corto__sello--derecha { transform: rotate(8deg); }
.en-corto__sello text { font-family: var(--letra-titulos); font-size: 17px; font-weight: 800; }
.en-corto__lista { list-style: none; margin: var(--espacio-2) 0 0; padding: 0; display: grid; gap: var(--espacio-3); }
/* Cada punto, una gota de tinta centrada en la primera línea (con cualquier letra) */
.en-corto__lista li { position: relative; padding-left: calc(0.5625rem + var(--espacio-3)); }
.en-corto__lista li::before { content: ""; position: absolute; left: 0; top: calc(0.8em - 0.28125rem); width: 0.5625rem; height: 0.5625rem; border-radius: 50%; background: var(--color-acento); }
/* Cada apartado: su título y lo que dice, con aire entre uno y otro */
.legal__apartado { margin-top: var(--espacio-6); }
.legal__apartado > * + * { margin-top: var(--espacio-2); }
.legal__lista { margin-bottom: 0; padding-left: 1.375rem; display: grid; gap: var(--espacio-2); }
.legal__lista li::marker { color: var(--color-acento); }
.legal__otra { margin-top: var(--espacio-7); }  /* al final, la otra página */

/* «Condiciones · Privacidad», al pie de la portada (con su raya) y al final de Tu cuenta: enlaces de 48 px de alto */
.pie { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--espacio-2); color: var(--color-texto-secundario); }
.pie a { display: inline-flex; align-items: center; min-height: var(--objetivo-tactil); }
.pie--raya { margin-top: var(--espacio-7); padding-top: var(--espacio-4); border-top: 1px solid var(--color-linea); }

/* ---------- Movimiento con sentido (paso 2 · DEC-0054; boceto aprobado en Claude Design, «Escanea y Juega ·
   Movimiento») ---------- */

/* Solo se mueve lo que cuenta algo, una vez y corto (el gesto, 250 ms como mucho). Nada aparece bloque a bloque al
   bajar, nada se mueve solo y nada rebota de más. Quien pide menos movimiento no tiene nada de esto (al final). */

/* Cambiar de página: la barra y la cabecera se quedan quietas (llevan su nombre: .barra y .cabecera-app) y solo cambia
   lo de dentro, con el «fundido de paso» que Material usa para la barra de abajo: lo de antes se va (90 ms) y después
   llega lo nuevo (160 ms, del 98 % a su tamaño), sin quedar las dos encima. Lo hace el navegador (Chrome y Android;
   iPhone desde iOS 18.2); donde no sabe, la página cambia como siempre. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
::view-transition-old(root) { animation: 90ms cubic-bezier(0.4, 0, 1, 1) both pagina-se-va; }
::view-transition-new(root) { animation: 160ms cubic-bezier(0, 0, 0.2, 1) 90ms both pagina-llega; }
/* Lo que solo está en una de las dos páginas (la barra al entrar en un local, la cabecera, la figura de la ficha): se va
   y llega con el resto, sin encogerse */
::view-transition-old(*):only-child { animation: 90ms cubic-bezier(0.4, 0, 1, 1) both pagina-se-va; }
::view-transition-new(*):only-child { animation: 160ms cubic-bezier(0, 0, 0.2, 1) 90ms both pagina-aparece; }
@keyframes pagina-se-va { to { opacity: 0; } }
@keyframes pagina-llega { from { opacity: 0; transform: scale(0.98); } }
@keyframes pagina-aparece { from { opacity: 0; } }
/* La misma página con otra búsqueda (un filtro de Locales, el periodo de las cifras): fundido cruzado, así lo que no
   cambia ni se mueve y solo cambia la lista; el aro (.filtro__aro) viaja al filtro elegido. Lo marca movimiento.js. */
html[data-transicion="misma-pagina"]::view-transition-old(root) { animation: 200ms ease both pagina-se-va; }
html[data-transicion="misma-pagina"]::view-transition-new(root) { animation: 200ms ease both pagina-aparece; }
/* La tienda va a su página: su figura viaja de la fila a la ficha y crece (y con «atrás», vuelve). En la ficha lleva el
   nombre siempre; en la lista, movimiento.js se lo pone solo a la fila que se ha tocado. El aro viaja igual de suave. */
.ficha-local__cabeza .avatar--enorme { view-transition-name: figura-local; }
::view-transition-group(figura-local),
::view-transition-group(filtro-aro) { animation-duration: 250ms; animation-timing-function: cubic-bezier(0.2, 0, 0, 1); }

/* Al tocar, responde al dedo: lo que se pulsa se hunde un poco, como ya hacían los botones. Solo enlaces y botones (lo
   que no se pulsa no se mueve) y sin el recuadro gris que pone el móvil encima: ya responde la propia fila. En el
   iPhone, Safari solo enseña :active si la página escucha los toques (lo hace movimiento.js). */
a.local-fila, a.fila, button.fila, .mini-local, .destacado, .accion-local, .trabajo, .filtro, .barra__destino {
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms ease;
}
a.local-fila:active, a.fila:active, button.fila:active, .mini-local:active, .destacado:active, .accion-local:active,
.trabajo:active, .filtro:active { transform: scale(0.98); }
.barra__destino:active { transform: scale(0.96); }
.barra__centro:active { transform: none; }  /* el sello del centro se aprieta, como un sello de goma */
.barra__centro:active img { transform: translateY(2px) scale(0.9); }

/* Con ratón, en el ordenador: el nombre de lo que se abre se subraya, como cualquier enlace. Nada crece, ni flota, ni
   echa más sombra. Solo con un puntero que de verdad pasa por encima: en el móvil no se queda nada marcado al tocar. */
@media (hover: hover) and (pointer: fine) {
  a.local-fila:hover strong,
  a.fila:hover strong,
  button.fila:hover strong,
  .mini-local:hover .mini-local__nombre,
  .destacado:hover :is(.destacado__nombre, .proximo__local),
  .trabajo:hover .trabajo__nombre,
  .accion-local:hover .accion-local__titulo,
  .filtro:hover,
  .barra__destino:hover span { text-decoration: underline; text-underline-offset: 0.2em; }
}

/* Cuando pasa algo, se mueve solo lo nuevo: el aviso que lo cuenta (role="status" o "alert") baja 6 px y se asienta, y
   su ✓ se estampa con el gesto de sello. Los que solo informan (sin role) se quedan quietos, y un error no tiembla.
   Tras cambiar de página, el aviso llega con ella (90 ms) y el ✓ cuando ya se lee (250 ms). */
.aviso[role="status"], .aviso[role="alert"] { animation: aviso-llega 200ms ease-out 90ms both; }
.aviso--marca[role="status"] .aviso__marca { animation: estampar-tinta 250ms cubic-bezier(0.3, 1.4, 0.6, 1) 250ms both; }
@keyframes aviso-llega { from { opacity: 0; transform: translateY(-6px); } }

/* Quien pide menos movimiento no tiene nada de esto: sin @view-transition no hay transición entre páginas, y aquí se
   paran también las de dentro de una página (escanear.js) y sus pseudoelementos, que la regla general no alcanza */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-image-pair(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
