/* Tienda en línea. Aquí SÍ manda el rojo de marca con su degradado
   (CLAUDE.md sección 11): es el color heredado de la tarjeta y la identidad
   de la tienda. En POS y Admin el color de acción es el azul y el rojo
   queda reservado a cancelar y borrar — por eso este archivo solo lo carga
   el shell de la tienda. */

/* ATENCIÓN: amarillo y naranja NO están en la lista de tokens de CLAUDE.md
   sección 11, que es cerrada. Se agregan a pedido explícito del dueño para
   los iconos y el logo de la tienda. Van en :root y no en .tm-store-shell
   porque el menú lateral vive fuera del cascarón —tiene que quedar encima
   de todo— y ahí no heredaría nada. Este archivo solo lo carga la tienda,
   así que POS y Admin nunca ven estos dos colores. */
:root {
  --amarillo: #F5C518;
  --naranja: #E1730B;
  /* Los dos extremos del mismo naranja, siguiendo el patrón que el sistema
     ya tenía con --marca y --marca-hondo.
     El claro es para las pastillas de estante con letra negra: el negro
     necesita un fondo CLARO contra el cual destacar —por eso luce sobre el
     amarillo y se enloda sobre un naranja de tono medio— y sobre este da 6.6
     de contraste. El hondo quedó de cuando se probó con letra blanca. */
  --naranja-claro: #F09030;
  --naranja-hondo: #B85C08;

  /* El esqueleto de carga: el gris de lo que viene y el brillo que lo
     recorre. En oscuro se redefinen con los demás. */
  --hueso: #e9e7ec;
  --hueso-brillo: rgba(255, 255, 255, 0.75);
}

.tm-store-shell {
  grid-template-columns: 1fr;
  grid-template-rows: auto auto 1fr;
  grid-template-areas:
    "topbar"
    "aviso"
    "contenido";
}

/* El banner de la tienda no usa el tema configurable: usa la marca.

   Termina con un filo amarillo, del color del logo, y las puntas de abajo
   redondas. Lo escogió el dueño en la maqueta del 2026-10-16 («la C»,
   con «toque redondo al acabar el color rojo para que no se vean las
   puntas»). El filo va como sombra por dentro para que siga la curva. */
.tm-topbar--store {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  height: auto;
  padding: 6px 14px 14px;
  border-radius: 0 0 22px 22px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  box-shadow: inset 0 -4px 0 var(--amarillo);
}

/* Con la cinta de Abierto, menos rojo abajo: el dueño la sentía «muy
   alta». Se aprieta el aire, no la letra. */
.tm-topbar--store:has(> .tm-estado-tienda:not([hidden])) {
  padding-bottom: 12px;
}

/* ---------- Lo de arriba, en una sola pieza ----------
 *
 * La franja roja, el aviso de cerrado y el «Regresar» viajan juntos. En el
 * teléfono van ENCIMA de la lista, no arriba de ella: así, cuando se
 * esconden al bajar (core/esconder_al_bajar.js), la lista ya ocupa ese
 * lugar y nada cambia de alto ni brinca. Lo escogió el dueño en la maqueta
 * el 2026-10-15: se va todo lo rojo, y el pedido sigue a la mano en la
 * barra «Ver mi pedido» de abajo.
 *
 * La lista deja arriba un hueco del alto de la cabecera. Ese alto lo mide el
 * JavaScript (`--alto-cabeza`) porque cambia: con el aviso de cerrado, con
 * el «Regresar», sin buscador mientras se entra a la cuenta.
 *
 * En pantalla ancha todo se queda donde estaba: ahí sobra alto.
 */
.tm-store-cabeza {
  grid-area: topbar;
  position: relative;
  z-index: 30;
}

/* Debajo de la franja, esté donde esté. */
.tm-store-cabeza .tm-indicador-carga {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
}

@media (max-width: 767px) {
  .tm-store-shell {
    position: relative;
  }

  .tm-store-cabeza {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
  }

  .tm-store-shell > .tm-contenido {
    padding-top: calc(var(--alto-cabeza, 122px) + 12px);
    /* Lo que se enfoca o se lleva a la vista no se queda debajo de ella. */
    scroll-padding-top: var(--alto-cabeza, 122px);
  }

  /* El «Regresar» no traía fondo porque abajo no pasaba nada; ahora la
     lista pasa por debajo. */
  .tm-store-cabeza .tm-volver-zona {
    background: var(--papel);
  }
}

/* La barra y el buscador se alinean con el contenido de abajo en vez de
   irse a las orillas de la pantalla. */
.tm-store-barra,
.tm-store-buscador {
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
}

.tm-store-barra {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Iconos rellenos de amarillo con borde naranja: la caja sigue midiendo 44
   para el pulgar aunque el dibujo sea más chico. */
.tm-store-icono {
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
}

.tm-store-icono svg {
  /* Grandes a propósito: son las dos únicas manijas del cascarón y se
     tocan con el pulgar en movimiento. La caja sigue en 44. */
  width: 31px;
  height: 31px;
  fill: var(--amarillo);
  stroke: var(--naranja);
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.tm-store-icono:hover,
.tm-store-icono:focus-visible {
  background: rgba(255, 255, 255, 0.18);
}

.tm-store-icono--carrito {
  margin-left: auto;
}

/* La orilla de la tarjeta, un poco más marcada y con una sombrita corta:
   con la línea de 6 % se perdía en el crema de «Lo nuevo». Lo escogió el
   dueño en la maqueta del 2026-10-16 («Las dos»). No cambia la forma ni el
   tamaño de la tarjeta heredada, y es solo de la tienda: el POS la deja
   como estaba. En oscuro manda la regla de abajo (borde, sin sombra). */
.store-product-card--store {
  border-color: rgba(0, 0, 0, 0.12);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 3px 8px rgba(0, 0, 0, 0.05);
}

/* El aviso de versión nueva toma el rojo de la tienda, no el azul de
   acción del POS (componentes.css, .tm-aviso-version). */
.tm-aviso-version {
  --aviso-version-color: var(--marca);
}

/* La puerta de la casita, rellena de naranja como en la maqueta. */
.tm-store-casa-puerta {
  fill: var(--naranja);
  stroke: none;
}

/* Ancla del logo centrado. Sin esto se centraría contra la página entera. */
.tm-store-barra {
  position: relative;
}

/* El logo, al centro y grande.
   Se centra con posición absoluta y no con `margin: auto` porque el menú y el
   carrito no pesan lo mismo: centrarlo entre ellos lo dejaría corrido a la
   derecha. Así queda en el centro de la BARRA, que es donde el ojo lo busca. */
.tm-store-marca {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  text-decoration: none;
  color: #ffffff;
  /* Que un toque descuidado en el centro no navegue si lo que se quería era
     el buscador: el enlace mide lo que mide el logo y ni un pixel más. */
  pointer-events: auto;
}

/* El logo se pinta por máscara: el PNG solo aporta la silueta y el color
   sale de aquí. Así el mismo archivo sirve para cualquier color y no hay
   una copia por cada uno. */
.tm-store-logo {
  display: block;
  /* La caja va con la proporción REAL de la tinta del logo —277x168, o sea
     1.65 a 1— ahora que la silueta se recorta bien. Antes la caja era
     cuadrada como el archivo, y como el archivo traía noventa y cuatro
     píxeles de vacío abajo, `contain` escalaba ese vacío junto con el logo:
     salía chico y parecía corto de los lados.
     El alto no sube —«más alto ya no, porque se roba espacio»— así que todo
     el crecimiento va a lo ancho, que es lo que se pidió.

     **Bajado un 10% el 2026-09-14.** El dueño lo vio en su teléfono: «mi
     logo excede un poquito el tamaño, puedes reducirle de altura un
     milímetro para que encaje bien». Y era medible: la tinta terminaba en el
     píxel 69 y el buscador empezaba en el 66, o sea tres de encimado. Antes
     eso se tapó con un `z-index` para que el toque llegara a la caja de
     búsqueda; esto es el arreglo de verdad, y el z-index se queda como red.

     Las dos medidas bajan juntas para no romper la proporción 1.65 a 1 de la
     tinta: con `mask-size: contain`, encoger solo el alto dejaría aire a los
     lados y el logo se vería más chico de lo pedido.

     **Un solo renglón desde el 2026-10-17.** El dueño cambió su logo por la
     «bomba de graffiti» (la B de la maqueta), de unos 4 a 1, y pidió
     recortar el rojo «ya que se ahorra espacio al ser 1 fila, y ya no
     encimado como está hoy». La caja ahora es ancha y bajita: cabe en el
     renglón de los iconos y usa todo el ancho entre la casita y el carrito
     (los 244px son el menú, la casita, el carrito, sus huecos y la orilla
     de la franja, de los dos lados porque va centrado). */
  width: clamp(100px, calc(100vw - 248px), 240px);
  height: 40px;
  flex-shrink: 0;
  background-color: var(--amarillo);
  -webkit-mask-image: var(--logo);
  mask-image: var(--logo);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}



.tm-store-carrito-cuenta {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 18px;
  padding: 0 4px;
  border-radius: 999px;
  background: #ffffff;
  color: var(--marca);
  font-size: 11px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tm-store-carrito-cuenta[hidden] {
  display: none;
}

/* Al agregar algo, el carrito da un brinquito ladeado —como una canasta
   que recibe algo— y el número salta. Medio segundo: se nota con el rabillo
   del ojo y no detiene a nadie. La clase la pone carrito.js solo cuando el
   número SUBE. */
.tm-store-icono--brinca svg {
  transform-origin: 50% 85%;
  animation: tm-carrito-brinca 520ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.tm-store-icono--brinca .tm-store-carrito-cuenta {
  animation: tm-carrito-numero 420ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes tm-carrito-brinca {
  0%   { translate: 0 0; rotate: 0deg; scale: 1; }
  30%  { translate: 0 -6px; rotate: -10deg; scale: 1.14; }
  55%  { translate: 0 0; rotate: 6deg; scale: 0.96; }
  78%  { rotate: -3deg; scale: 1.02; }
  100% { translate: 0 0; rotate: 0deg; scale: 1; }
}

@keyframes tm-carrito-numero {
  0%   { scale: 0.4; }
  60%  { scale: 1.35; }
  100% { scale: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-store-icono--brinca svg,
  .tm-store-icono--brinca .tm-store-carrito-cuenta {
    animation: none;
  }
}

/* Sin internet con la tienda abierta: una pastilla abajo, con las ondas del
   wifi encendiéndose una tras otra, buscando. Abajo y no arriba: arriba
   tapaba el buscador, y abajo es donde está el pulgar esperando que algo
   responda. No atrapa toques: lo que se pueda seguir haciendo, se hace. */
.tm-sin-red {
  position: fixed;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 55;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 10px;
  width: max-content;
  max-width: calc(100vw - 32px);
  margin: 0;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--tinta);
  color: var(--papel);
  font-size: 13.5px;
  font-weight: 600;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
  pointer-events: none;
  animation: tm-sin-red-entra 250ms ease-out;
}

.tm-sin-red[hidden] {
  display: none;
}

.tm-sin-red-ondas {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  fill: currentColor;
}

.tm-sin-red-onda {
  fill: none;
  stroke: currentColor;
  stroke-width: 18;
  stroke-linecap: round;
  opacity: 0.25;
  animation: tm-sin-red-busca 1.8s ease-in-out infinite;
}

.tm-sin-red-onda--2 { animation-delay: 0.2s; }
.tm-sin-red-onda--3 { animation-delay: 0.4s; }

@keyframes tm-sin-red-busca {
  0%, 60%, 100% { opacity: 0.25; }
  25%           { opacity: 1; }
}

@keyframes tm-sin-red-entra {
  from { opacity: 0; translate: -50% 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-sin-red,
  .tm-sin-red-onda {
    animation: none;
  }
  .tm-sin-red-onda { opacity: 1; }
}

/* La foto que vuela al carrito. Encima de todo y sin atrapar toques: si el
   cliente toca otra cosa mientras vuela, el toque tiene que llegar. El
   movimiento lo pone carrito.js (volarAlCarrito). */
.tm-vuelo {
  position: fixed;
  z-index: 60;
  pointer-events: none;
}

.tm-vuelo-altura {
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 14px;
  background: #ffffff;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}

.tm-vuelo-altura img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.tm-vuelo-altura--sin-foto {
  border-radius: 50%;
  background: var(--marca);
}

/* El buscador vive dentro del banner: es lo primero que hace un cliente y
   no tiene por qué gastar una franja aparte debajo. */
.tm-store-buscador {
  position: relative;
  display: flex;
  align-items: center;
  /* Por ENCIMA del logo, y no es un detalle: el logo va en posición
     absoluta y mide hasta 72px dentro de una barra de 44, así que se
     desborda unos doce por abajo y el hueco hasta aquí es de diez. Sin este
     z-index, la orilla de arriba del buscador queda tapada por el enlace del
     logo y el toque que iba a la caja acaba navegando a la portada.

     Lo sospechó el dueño antes de que se midiera: «no busca la barra de
     búsqueda, sospecho que sí sirve pero lo tapa lo de la foto». */
  z-index: 1;

  /* La caja es blanca en los dos temas, así que su tinta es siempre la del
     tema claro. Con la del tema oscuro, lo que se escribía salía blanco
     sobre blanco y no se veía — lo encontró el dueño buscando de noche. */
  --tinta: #1f1f1f;
  --tinta-tenue: #9a9a9a;
}

/* Con una orilla finita y una sombrita que lo levanta del rojo, y un
   anillo amarillo mientras se escribe: antes no se marcaba con nada al
   tocarlo (maqueta del 2026-10-16, «la C»). */
.tm-store-buscador input {
  width: 100%;
  min-height: 44px;
  padding: 0 14px 0 42px;
  border: none;
  border-radius: 12px;
  background: #ffffff;
  font: inherit;
  font-size: 14px;
  color: var(--tinta);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(90, 0, 0, 0.28);
  transition: box-shadow 0.15s ease;
}

.tm-store-buscador input:focus {
  outline: none;
  box-shadow: 0 0 0 3px var(--amarillo), 0 2px 8px rgba(90, 0, 0, 0.28);
}

.tm-store-buscador input::placeholder {
  color: var(--tinta-tenue);
}

.tm-store-buscador-lupa {
  position: absolute;
  left: 12px;
  width: 20px;
  height: 20px;
  pointer-events: none;
  stroke: var(--tinta-tenue);
  stroke-width: 2;
  stroke-linecap: round;
}

/* ---------- Menú lateral ---------- */

.tm-menu-fondo {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, 0.45);
}

.tm-menu-fondo[hidden] {
  display: none;
}

.tm-menu-lateral {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 201;
  /* Del ancho de lo que trae y no fijo: el dueño lo veía muy ancho, con
     aire a la derecha de cada renglón. Con un tope para los nombres largos. */
  width: max-content;
  min-width: 248px;
  max-width: min(320px, 86vw);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px;
  background: var(--papel-alto);
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.25);
  overflow-y: auto;
  animation: tm-menu-entra 0.18s ease-out;
}

/* Va después de la regla de display para que ganar/perder el atributo
   hidden no dependa del orden: es el error clásico de este proyecto. */
.tm-menu-lateral[hidden] {
  display: none;
}

@keyframes tm-menu-entra {
  from { transform: translateX(-100%); }
  to { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .tm-menu-lateral {
    animation: none;
  }
}

.tm-menu-encabezado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 0 4px;
}

.tm-menu-titulo {
  font-size: 17px;
  font-weight: 800;
}

/* El nombre de la tienda, cuando nadie ha entrado: a la altura de los
   renglones, no pegado a la orilla. */
.tm-menu-encabezado > .tm-menu-titulo { padding-left: 10px; }

.tm-menu-cerrar {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--tinta-suave);
  cursor: pointer;
}

.tm-menu-cerrar svg {
  width: 22px;
  height: 22px;
}

.tm-menu-cerrar:hover,
.tm-menu-cerrar:focus-visible {
  background: var(--papel-hondo);
}

.tm-menu-fila {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 8px 12px;
  border-radius: 12px;
  color: var(--tinta);
  text-decoration: none;
  font-size: 15px;
  font-weight: 600;
}

.tm-menu-fila:hover,
.tm-menu-fila:focus-visible {
  background: var(--papel-hondo);
}

/* Cada renglón con su dibujo de línea en un cuadrito amarillo claro: el
   estilo de la maqueta del 2026-10-06, que el dueño prefirió a los iconos
   rellenos de antes. El amarillo y el naranja siguen siendo los suyos. */
.tm-menu-dibujo {
  display: grid;
  place-items: center;
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--amarillo) 24%, transparent);
  color: var(--naranja);
}

.tm-menu-dibujo svg {
  width: 20px;
  height: 20px;
}

/* Cerrar sesión: el mismo cuadrito, en rojo de peligro. */
.tm-menu-fila--salir .tm-menu-dibujo {
  background: color-mix(in srgb, var(--peligro) 14%, transparent);
  color: var(--peligro);
}

/* En oscuro el amarillo diluido sale café, y el dueño lo vio feo. Ahí el
   cuadrito va del gris del menú y el dibujo en amarillo, que es el que
   brilla sobre lo oscuro. */
:root[data-tema-tienda="oscuro"] .tm-menu-dibujo {
  background: var(--papel-hondo);
  color: var(--amarillo);
}

:root[data-tema-tienda="oscuro"] .tm-menu-fila--salir .tm-menu-dibujo {
  background: color-mix(in srgb, var(--peligro) 18%, var(--papel-hondo));
  color: var(--peligro);
}

.tm-contenido {
  padding: 12px 14px;
  padding-bottom: max(16px, env(safe-area-inset-bottom));
  /* **La tienda no se desliza de lado.** Nunca.
   *
   * `overflow-y: auto` de arriba no viene solo: cuando un eje deja de ser
   * `visible`, el CSS convierte el otro en `auto` también. Así que este
   * panel siempre fue un contenedor con scroll horizontal esperando a que
   * algo se pasara un píxel del ancho —y entonces la pantalla entera se
   * arrastra de lado, con los títulos cortados a la izquierda.
   *
   * El dueño lo cachó así: «aún se puede hacer para un lado y para el otro,
   * yo quiero que quepa perfecto».
   *
   * Cerrarlo aquí no estorba a nada: lo que SÍ se arrastra a propósito —las
   * filas de productos, los chips de departamento— trae su propio
   * `overflow-x: auto`, y un padre cerrado no le quita el suyo a un hijo. */
  overflow-x: hidden;
}

.tm-store {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 1100px;
  margin: 0 auto;
}

/* Chips de departamento: redondos, y el activo con el degradado de marca,
   tal como el diseño heredado. */
/* Se arrastran de lado, no se acomodan en varias filas. Se probó
   envolviéndolos y el dueño lo rechazó: en una fila el filtro ocupa un
   renglón fijo y el catálogo empieza más arriba, que es lo que importa en
   un celular. */
.tm-store-chips {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}

.tm-store-chips::-webkit-scrollbar {
  display: none;
}

.tm-chip {
  flex-shrink: 0;
  /* 40px en vez de los 48 que pide CLAUDE.md sección 11 para áreas
     táctiles: el dueño pidió filtros más compactos, y errarle a un chip de
     filtro solo cuesta un toque de más. Los botones que mueven dinero
     siguen intactos. */
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}

.tm-chip--activo {
  border-color: transparent;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
}

/* Secciones como paneles blancos de esquinas grandes sobre el fondo gris,
   como en el diseño heredado. */
.tm-store-seccion {
  background: var(--papel-alto);
  border-radius: 22px;
  padding: 14px;
  box-shadow: var(--sombra-suave);
}

.tm-store-seccion + .tm-store-seccion {
  margin-top: 10px;
}

/* Los títulos de estante, como pastilla naranja.
   Se probó primero con una marca de resaltador por la base de la letra, y el
   dueño la vio y decidió: «rellénalos bien tipo pill button y que sean de
   color naranja». Dicho y hecho.

   Y queda mejor de lo que yo había supuesto: naranja aquí y amarillo en
   «Departamentos» conserva la diferencia que me preocupaba perder. Amarillo
   es la fila de navegación —donde uno se mueve—, naranja son los estantes.
   Dos colores, dos oficios.

   El MISMO amarillo con la misma tinta que «Departamentos». Se recorrieron
   antes tres naranjas —negro sobre el normal, blanco sobre el hondo, negro
   sobre el claro— y al verlos el dueño pidió el amarillo tal cual.

   Yo había defendido dos colores para separar la fila de navegación de los
   estantes. Se pierde esa señal, y a cambio se gana otra que en una pantalla
   chica pesa más: todo lo que es un rótulo se ve igual, y lo que no lo es
   —los botones rojos de agregar— se distingue de un golpe de vista. En un
   teléfono, donde nunca se ve la pantalla completa, esa segunda lectura vale
   más que la primera. */
.tm-store-seccion-titulo {
  display: inline-block;
  margin: 0 0 12px;
  padding: 7px 15px;
  border-radius: 999px;
  background: var(--amarillo);
  color: var(--tinta);
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* ---------- Filtros de dos niveles ----------
   Departamentos arriba, categorías del elegido debajo. Cada fila lleva su
   rótulo porque sin él las dos filas de pastillas se leen como una sola
   lista larga y el cliente no entiende que una manda sobre la otra. */

.tm-filtros {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* Las categorías van en gris: son subordinadas del departamento, y si
   fueran blancas como él las dos filas competirían por la misma atención.
   El :not() no es adorno — dice lo que de verdad se quiere ("la categoría
   APAGADA es gris") y de paso evita que esta regla, con dos clases, le
   gane por especificidad al degradado de .tm-chip--activo, que solo tiene
   una. */
.tm-store-chips--categorias .tm-chip:not(.tm-chip--activo) {
  background: var(--papel-hondo);
  border-color: transparent;
}

.tm-chip--activo {
  border-color: transparent;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  box-shadow: 0 6px 14px rgba(214, 32, 32, 0.28);
}

.tm-store .store-grid {
  margin-top: 4px;
}

/* ---------- Páginas del menú (contacto, cuenta) ---------- */

.tm-store-pagina {
  gap: 10px;
}

.tm-contacto-estado {
  margin: 0 0 12px;
  font-size: 14px;
  font-weight: 800;
}

.tm-contacto-estado--abierto {
  color: var(--ok);
}

.tm-contacto-estado--cerrado {
  color: var(--peligro);
}

.tm-contacto-dato {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 0 10px;
  font-size: 15px;
}

.tm-contacto-dato span {
  font-size: 12px;
  font-weight: 700;
  color: var(--tinta-tenue);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tm-contacto-enlace {
  color: var(--marca);
  font-weight: 700;
  text-decoration: none;
}

/* Escribir, llamar, reportar: renglones grandes para el pulgar, como los del
   perfil, y no tres botones de colores compitiendo. */
.tm-contacto-acciones {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 6px;
}

.tm-contacto-boton {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 0 16px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-hondo);
  color: var(--tinta);
  font-weight: 700;
  text-decoration: none;
}

.tm-contacto-boton:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

.tm-contacto-boton:active {
  scale: 0.98;
}

.tm-contacto-icono {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--marca);
}

.tm-horario {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tm-horario-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--linea);
  font-size: 14px;
}

.tm-horario-fila:last-child {
  border-bottom: none;
}

.tm-horario-fila--hoy {
  font-weight: 800;
}

.tm-horario-horas {
  font-variant-numeric: tabular-nums;
  color: var(--tinta-suave);
}

.tm-horario-fila--hoy .tm-horario-horas {
  color: var(--tinta);
}

.tm-cuenta-resumen {
  margin: 0 0 14px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

/* Decir la verdad cuesta un recuadro: esto todavía no existe y el cliente
   merece saberlo antes de intentarlo. */
.tm-cuenta-aviso {
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--papel-hondo);
  font-size: 13.5px;
  line-height: 1.55;
}

.tm-cuenta-lista-titulo {
  margin: 16px 0 6px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-cuenta-lista {
  margin: 0;
  padding-left: 20px;
  font-size: 14px;
  line-height: 1.8;
}

.tm-cuenta-boton {
  margin-top: 18px;
  justify-content: center;
}

/* Dentro de la tienda la acción primaria es el rojo de marca, no el azul de
   POS y Admin (CLAUDE.md sección 11): aquí el rojo es identidad, y el
   cliente nunca ve un botón de cancelar venta con el que confundirlo. */
.tm-store .tm-boton--primario,
.tm-carrito .tm-boton--primario,
.tm-granel .tm-boton--primario,
.tm-entrar .tm-boton--primario,
/* El aviso de «esa pantalla no existe» lo pinta el router, que es común a
   los tres cascarones y no lleva ninguna de esas clases. Esta hoja solo se
   sirve en la tienda, así que aquí no hace falta ancestro. */
.tm-sin-pantalla .tm-boton--primario,
.tm-ficha .tm-boton--primario,
.tm-ficha-vacia .tm-boton--primario,
/* La presentación y el recorrido viven fuera de `.tm-store` (encima de
   todo), y sin esta línea «Tengo mi clave» salía azul, el color del POS. */
.tm-presentacion .tm-boton--primario,
.tm-recorrido .tm-boton--primario {
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
}

/* ---------- Resultados como renglones ----------
   La otra forma de ver los resultados: un producto por renglón, más denso.
   Se elige en Ajustes > Tienda en línea. */

.tm-lista-productos {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-fila-producto {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: 16px;
}

.tm-fila-producto-imagen {
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--papel-hondo);
  display: grid;
  place-items: center;
}

/* Con foto, blanco. El gris es del cartel de "Sin foto", donde sí dice algo;
   debajo de una foto que ya viene sobre blanco solo deja un marco de otro
   color alrededor del producto. */
.tm-fila-producto-imagen:has(img) {
  background: #ffffff;
}

.tm-fila-producto-imagen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tm-fila-producto-imagen--vacia {
  font-size: 10px;
  font-weight: 700;
  color: var(--tinta-tenue);
  text-align: center;
}

.tm-fila-producto-datos {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.tm-fila-producto-nombre {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
  /* Dos líneas máximo: con nombres largos, un renglón que crece el doble
     que sus vecinos rompe el ritmo de la lista. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.tm-fila-producto-descripcion {
  font-size: 12.5px;
  color: var(--tinta-suave);
  /* Dos líneas y corta: en una lista larga, un renglón que crece rompe el
     ritmo de la exploración. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.tm-fila-producto-agotado {
  align-self: flex-start;
  margin-top: 2px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--peligro-fondo);
  color: var(--peligro);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tm-fila-producto-accion {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  width: 96px;
}

.tm-fila-producto-precio {
  font-size: 16px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tm-fila-producto-accion .store-add-button {
  margin-top: 2px;
}

/* Un vacío que invita a actuar, no un mensaje triste (CLAUDE.md §11). */
.tm-vacio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 28px 16px;
  text-align: center;
}

.tm-vacio p {
  margin: 0;
}

/* La lupa de «no encontramos»: mira a un lado y al otro dos veces y se
   queda quieta. Dos y no para siempre: una lupa que no para distrae de lo
   que sí importa, que es el botón de buscar en toda la tienda. */
.tm-lupa {
  width: 56px;
  height: 56px;
  color: var(--tinta-tenue);
  animation: tm-lupa-busca 1.5s ease-in-out 2;
}

@keyframes tm-lupa-busca {
  0%, 100% { translate: 0 0; rotate: 0deg; }
  25%      { translate: -9px -2px; rotate: -10deg; }
  50%      { translate: 0 2px; rotate: 0deg; }
  75%      { translate: 9px -2px; rotate: 10deg; }
}

/* El corazón late al guardar un favorito. Vive aquí y no en
   tarjeta_producto.css: la tarjeta se heredó tal cual y el corazón solo
   existe en la tienda. */
.store-product-corazon--late svg {
  animation: tm-corazon-late 520ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes tm-corazon-late {
  0%   { scale: 1; }
  30%  { scale: 1.35; }
  55%  { scale: 0.9; }
  75%  { scale: 1.1; }
  100% { scale: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-lupa,
  .store-product-corazon--late svg {
    animation: none;
  }
}

.tm-store-seccion--invitacion {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.tm-store-invitacion-texto {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--tinta-suave);
  max-width: 46ch;
}

/* ---------- Quién entró, en el menú ---------- */

/* Su tarjeta, con el color de la tienda: la misma portada de Mi cuenta en
   chico. Toda la tarjeta lleva a Mi cuenta. */
.tm-menu-quien {
  position: relative;
  overflow: hidden;
  flex: 1;
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  min-height: 76px;
  padding: 12px 14px;
  border-radius: 18px;
  background: linear-gradient(150deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  text-decoration: none;
}

.tm-menu-quien[hidden] { display: none; }

.tm-menu-quien::after {
  content: "";
  position: absolute;
  right: -40px;
  top: -50px;
  width: 130px;
  height: 130px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  pointer-events: none;
}

.tm-menu-quien:focus-visible { outline: 3px solid var(--amarillo); outline-offset: 2px; }

.tm-avatar--menu {
  flex: none;
  width: 48px;
  height: 48px;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.85);
}

.tm-menu-quien-texto {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.tm-menu-quien .tm-menu-titulo {
  color: #ffffff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-menu-quien-detalle {
  font-size: 12.5px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.88);
}

/* Los rótulos de los tres grupos: Comprar, Mi cuenta, Ayuda. */
.tm-menu-rotulo {
  margin: 12px 12px 2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

/* «En camino» al lado de Mis pedidos: lo único que vale la pena avisar desde
   el menú. */
.tm-menu-extra {
  margin-left: auto;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--ok-fondo);
  color: var(--ok);
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}

.tm-menu-extra[hidden] { display: none; }

.tm-menu-fila[hidden] { display: none; }

/* Cerrar sesión y la puerta del personal, hasta abajo. */
.tm-menu-pie {
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--linea);
  display: flex;
  flex-direction: column;
}

/* «Instalar la app», hasta abajo del menú y solo para quien no la tiene.
   Un botón, como Cerrar sesión, con su cuadrito en el color de la tienda
   para que se distinga de los demás renglones. */
.tm-menu-fila--instalar {
  width: 100%;
  margin-top: 4px;
  border: none;
  background: transparent;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.tm-menu-fila--instalar .tm-menu-dibujo,
:root[data-tema-tienda="oscuro"] .tm-menu-fila--instalar .tm-menu-dibujo {
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
}

.tm-menu-instalar-texto {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}

.tm-menu-instalar-texto small {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--tinta-suave);
}

/* Cerrar sesión es un botón, no un enlace: no lleva a ningún lado, hace
   algo. Se ve igual que las demás filas del menú. */
.tm-menu-fila--salir {
  width: 100%;
  border: none;
  background: transparent;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  color: var(--peligro);
  cursor: pointer;
}

/* ---------- Entrar y perfil ---------- */

.tm-cuenta-pestanas {
  display: flex;
  gap: 6px;
  margin-bottom: 16px;
  padding: 4px;
  border-radius: 999px;
  background: var(--papel-hondo);
}

.tm-cuenta-pestana {
  flex: 1;
  min-height: 44px;
  padding: 0 8px;
  border: none;
  /* Redondas como todo lo demás de esta tarjeta desde el rediseño. */
  border-radius: 999px;
  background: transparent;
  font: inherit;
  /* Se encoge antes que partirse: «Con mi contraseña» en dos renglones
     estiraba la fila y dejaba las dos pestañas de distinta altura. */
  font-size: clamp(11.5px, 3.3vw, 13px);
  font-weight: 700;
  white-space: nowrap;
  color: var(--tinta-suave);
  cursor: pointer;
}

.tm-cuenta-pestana--activa {
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: var(--sombra-suave);
}

.tm-cuenta-forma {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tm-cuenta-ayuda {
  font-size: 12px;
  line-height: 1.5;
  color: var(--tinta-tenue);
}

.tm-cuenta-ayuda--centro {
  display: block;
  margin-top: 14px;
  text-align: center;
}

.tm-cuenta-boton {
  min-height: 48px;
  justify-content: center;
}

/* La foto, con sus acciones al lado. En pantalla chica se acomodan debajo
   solas, porque el contenedor envuelve. */
.tm-perfil-foto {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 18px;
}

.tm-avatar--grande {
  width: 88px;
  height: 88px;
  font-size: 30px;
}

.tm-perfil-foto-acciones {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

/* El <label> hace de botón para abrir el selector de archivos: así no hace
   falta un input feo a la vista. */
.tm-perfil-foto-acciones label.tm-boton {
  cursor: pointer;
}

.tm-campo input:disabled {
  background: var(--papel-hondo);
  color: var(--tinta-suave);
}

/* En servicio va en verde sobre blanco; cerrado, en letra blanca sobre el
   rojo, para que no compita con el logo. */
.tm-store-estado--abierto {
  background: rgba(255, 255, 255, 0.94);
  color: var(--ok);
}

.tm-store-estado--cerrado {
  background: rgba(0, 0, 0, 0.26);
  color: #ffffff;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 700;
}

/* Que esté cerrado no es un "vuelve luego": el pedido se prepara al abrir.
   Decirlo aquí evita que el cliente se vaya creyendo que no hay servicio. */
.tm-aviso-cerrado {
  grid-area: aviso;
  margin: 0;
  padding: 9px 16px;
  background: var(--papel-hondo);
  border-bottom: 1px solid var(--linea);
  color: var(--tinta-suave);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
}

.tm-aviso-cerrado[hidden] {
  display: none;
}

/* ---------- Entrar: pantalla de app, no formulario suelto ---------- */

/* `min(...)` y no `460px` a secas, y esto no es manía: es el bug que tenía
   ancha la tienda en el teléfono.

   Esta tarjeta es hijo de `.tm-store`, que es un contenedor flex en columna.
   Un hijo de esos se estira al ancho del padre por sí solo... **hasta que se
   le pone `margin: 0 auto`**. El margen automático apaga el estirado, y
   entonces el navegador la mide por su contenido: aquí salían 393 px dentro
   de un hueco de 332, y la pantalla se arrastraba de lado.

   Medido: 393.2 sin esto, 332.0 con esto. El `100%` la vuelve a atar al
   hueco disponible, y el tope de píxeles sigue mandando en pantalla grande,
   que es para lo que estaba puesto. */
.tm-entrar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  max-width: min(420px, 100%);
  margin: 0 auto;
  padding: 18px 0 32px;
}

.tm-entrar-cabecera {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}

/* El disco con la silueta hace las veces de "aquí empieza tu cuenta": da un
   punto de entrada visual en vez de arrancar de golpe con un campo. */
.tm-entrar-icono {
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  box-shadow: 0 12px 28px rgba(214, 32, 32, 0.28);
}

.tm-entrar-icono svg {
  width: 40px;
  height: 40px;
}

.tm-entrar-titulo {
  margin: 6px 0 0;
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.tm-entrar-lema {
  margin: 0;
  max-width: 34ch;
  font-size: 14px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

.tm-entrar-tarjeta {
  width: 100%;
  padding: 22px 20px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: 18px;
  /* La misma sombra marcada que la puerta del personal: las dos puertas se
     ven hermanas aunque cada una pida lo suyo. */
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.12);
}

/* Campos de pastilla, igual que en la puerta del personal. El color de
   acción sí cambia: aquí manda el rojo de la tienda y allá el azul del POS
   (CLAUDE.md §11). */
.tm-entrar-tarjeta input {
  width: 100%;
  min-height: 52px;
  padding: 12px 18px;
  border: 1px solid var(--tinta-tenue);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
}

.tm-entrar-tarjeta input::placeholder {
  color: var(--tinta-tenue);
}

.tm-entrar-tarjeta input:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 1px;
  border-color: var(--marca);
}

.tm-entrar-tarjeta .tm-cuenta-boton {
  min-height: 52px;
  border-radius: 999px;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.24);
}

.tm-entrar-tarjeta .tm-cuenta-boton:active {
  box-shadow: none;
}

.tm-entrar-pie {
  margin: 0;
  max-width: 36ch;
  text-align: center;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--tinta-tenue);
}

/* Los 4 dígitos, separados y grandes: se teclean mirando un papel. */
/* Los cuatro dígitos, separados para que se lean de un vistazo.
   El ancho tiene que venir de fuera: un `input` sin ancho declarado mide
   veinte caracteres, y veinte caracteres a 26px con medio em de separación
   son bastante más anchos que un teléfono. Así se salía la tarjeta de la
   pantalla al cambiar a esta pestaña. */
.tm-campo-clave {
  width: 100%;
  font-family: var(--fuente-mono, monospace);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.5em;
  /* Compensa la separación del último dígito, que si no descentra el grupo. */
  text-indent: 0.5em;
  text-align: center;
}

/* ---------- Perfil: la foto se toca, como en cualquier app ---------- */

.tm-perfil-foto {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
}

.tm-perfil-avatar {
  position: relative;
  flex-shrink: 0;
  cursor: pointer;
  border-radius: 999px;
}

.tm-perfil-avatar:focus-within {
  outline: 2px solid var(--accion);
  outline-offset: 3px;
}

/* La cámara encima de la esquina, como en Instagram o WhatsApp: no hace
   falta un botón aparte que diga "cambiar foto". */
.tm-perfil-camara {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 3px solid var(--papel-alto);
  background: var(--marca);
  color: #ffffff;
}

.tm-perfil-camara svg {
  width: 16px;
  height: 16px;
}

/* En Mi perfil la foto mide 64 y no 84, así que la cámara encoge con ella:
   a 30 se comía media foto. */
.tm-cuenta-avatar .tm-perfil-camara {
  width: 24px;
  height: 24px;
  border-width: 2.5px;
}

.tm-cuenta-avatar .tm-perfil-camara svg {
  width: 13px;
  height: 13px;
}

/* Quitar la foto es secundario: se ofrece como texto, no como otro botón
   compitiendo con el principal. */
.tm-enlace-suave {
  align-self: flex-start;
  margin-top: 4px;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--marca);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------- El carrito, como cajón ---------- */

.tm-carrito {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 201;
  width: min(420px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--papel);
  box-shadow: -8px 0 40px rgba(0, 0, 0, 0.22);
  animation: tm-carrito-entra 0.2s cubic-bezier(0.2, 0.9, 0.3, 1);
}

/* Después de la regla de display, para que el atributo hidden gane sin
   depender del orden: el error clásico de este proyecto. */
.tm-carrito[hidden] {
  display: none;
}

@keyframes tm-carrito-entra {
  from { transform: translateX(100%); }
  to { transform: translateX(0); }
}

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

/* Cabecera blanca y callada (maqueta aprobada 2026-09-30): el color se
   queda para lo que se toca, no para el título. */
.tm-carrito-cabecera {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: var(--papel-alto);
  border-bottom: 1px solid var(--linea);
}

.tm-carrito-quien {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.tm-carrito-titulo {
  font-size: 19px;
  font-weight: 800;
}

/* Cuántas piezas van. Repite lo que dice la insignia del carrito de arriba,
   y aquí sirve para otra cosa: con el cajón abierto ya no se ve aquella. */
.tm-carrito-cuantas {
  flex: none;
  min-width: 26px;
  height: 26px;
  padding: 0 8px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--marca);
  color: #ffffff;
  font-size: 13px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tm-carrito-cerrar {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta);
  cursor: pointer;
}

.tm-carrito-cerrar svg {
  width: 20px;
  height: 20px;
}

.tm-carrito-cerrar:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

/* Lo de en medio se desplaza; el pie con el total se queda quieto abajo,
   que es donde el ojo lo busca. */
.tm-carrito-cuerpo {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tm-carrito-cuerpo > * {
  flex-shrink: 0;
}

/* La barrita del envío gratis: cuánto falta, con el degradado de marca. */
.tm-carrito-gratis {
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border-radius: 16px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
}

.tm-carrito-gratis p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.4;
}

.tm-carrito-gratis b {
  color: var(--marca);
  font-variant-numeric: tabular-nums;
}

.tm-carrito-gratis--listo b {
  color: var(--ok);
}

.tm-carrito-gratis-barra {
  height: 8px;
  border-radius: 999px;
  background: var(--papel-hondo);
  overflow: hidden;
}

.tm-carrito-gratis-barra i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--marca), var(--amarillo));
  transition: width 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.tm-carrito-gratis--listo .tm-carrito-gratis-barra i {
  background: var(--ok);
}

.tm-carrito-lineas {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Cada renglón va sobre un fondo rojo con el bote: es lo que se descubre
   al deslizarlo a la izquierda. */
.tm-carrito-renglon {
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  background: var(--peligro);
}

.tm-carrito-renglon-fondo {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding-right: 22px;
  color: #ffffff;
  font-size: 14px;
  font-weight: 800;
}

.tm-carrito-renglon-fondo svg {
  width: 22px;
  height: 22px;
}

.tm-carrito-renglon--sale {
  height: 0 !important;
  opacity: 0;
  margin-top: -8px;
  transition: height 0.24s ease 0.14s, opacity 0.2s ease 0.14s, margin 0.24s ease 0.14s;
}

.tm-carrito-linea {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: 18px;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  transition: translate 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

.tm-carrito-linea--arrastra {
  transition: none;
}

.tm-carrito-linea--agotada .tm-carrito-imagen,
.tm-carrito-linea--agotada .tm-carrito-datos {
  opacity: 0.62;
}

.tm-carrito-imagen {
  width: 64px;
  height: 64px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--papel-hondo);
  border: 1px solid var(--linea);
  display: grid;
  place-items: center;
}

/* Igual que en la tarjeta y en la fila: con foto, blanco. */
.tm-carrito-imagen:has(img) {
  background: #ffffff;
}

.tm-carrito-imagen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.tm-carrito-sin-imagen {
  font-size: 11px;
  font-weight: 700;
  color: var(--tinta-tenue);
}

.tm-carrito-datos {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tm-carrito-nombre {
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.25;
}

.tm-carrito-unitario {
  font-size: 12.5px;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

.tm-carrito-importe {
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

.tm-carrito-agotado {
  align-self: flex-start;
  margin-top: 2px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--peligro-fondo);
  color: var(--peligro);
  font-size: 11px;
  font-weight: 800;
}

/* El control de cantidad como una sola pieza: se lee como un mando, no como
   tres botones sueltos. */
.tm-carrito-cantidad {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--papel-hondo);
}

.tm-carrito-cantidad button {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 999px;
  background: var(--papel-alto);
  font-size: 18px;
  font-weight: 800;
  color: var(--tinta);
  cursor: pointer;
  line-height: 1;
}

.tm-carrito-cantidad button:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 1px;
}

.tm-carrito-cantidad > span {
  min-width: 24px;
  padding: 0 2px;
  text-align: center;
  font-size: 14px;
  font-weight: 800;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.tm-carrito-basura {
  color: var(--peligro) !important;
}

.tm-carrito-basura svg {
  width: 17px;
  height: 17px;
}

.tm-carrito-pista {
  margin: 0;
  text-align: center;
  font-size: 12.5px;
  color: var(--tinta-tenue);
}

/* El «Deshacer» se pega al fondo de lo que se ve, justo encima del pie. */
.tm-carrito-deshacer {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 8px 8px 14px;
  border-radius: 14px;
  background: #1f1f24;
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: #ffffff;
  font-size: 14px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25);
  animation: tm-deshacer-sube 0.3s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.tm-carrito-vacio .tm-carrito-deshacer {
  align-self: stretch;
  margin-top: 16px;
}

.tm-carrito-deshacer span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-carrito-deshacer button {
  flex: none;
  min-height: 44px;
  padding: 0 12px;
  border: none;
  border-radius: 10px;
  background: none;
  color: #ffd23f;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

.tm-carrito-deshacer button:focus-visible {
  outline: 2px solid #ffd23f;
}

@keyframes tm-deshacer-sube {
  from { translate: 0 16px; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-carrito-linea,
  .tm-carrito-renglon--sale,
  .tm-carrito-gratis-barra i {
    transition: none;
  }
  .tm-carrito-deshacer {
    animation: none;
  }
}

.tm-carrito-aviso {
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--peligro-fondo);
  color: var(--peligro);
  font-size: 12.5px;
  font-weight: 600;
}

.tm-carrito-pie {
  flex-shrink: 0;
  padding: 12px 16px max(16px, env(safe-area-inset-bottom));
  background: var(--papel-alto);
  border-top: 1px solid var(--linea);
  box-shadow: 0 -8px 20px rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-carrito-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 14px;
  color: var(--tinta-suave);
}

.tm-carrito-total strong {
  font-family: var(--fuente-mono, monospace);
  font-size: 26px;
  font-weight: 600;
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
}

/* El ahorro va en verde, el mismo color con el que la tarjeta marca el
   precio de beneficio: es la misma idea en los dos lugares. */
.tm-carrito-ahorro {
  margin: -4px 0 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--ok);
}

.tm-carrito-nota {
  margin: 0 0 6px;
  font-size: 12px;
  color: var(--tinta-tenue);
}

.tm-carrito-continuar {
  min-height: 54px;
  justify-content: center;
  border-radius: 16px;
  font-size: 16px;
}

.tm-carrito-vacio {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 32px 24px;
  text-align: center;
}

.tm-carrito-vacio-icono {
  width: 76px;
  height: 76px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-tenue);
}

.tm-carrito-vacio-icono svg {
  width: 40px;
  height: 40px;
  /* Animación 5 de la lista del dueño: el carrito llega rodando desde la
     izquierda mientras se dibuja, le salen las ruedas y al final se
     rellena. Menos de un segundo, una sola vez cada que se abre vacío. */
  animation: tm-vacio-llega 700ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.tm-carrito-vacio-icono svg * {
  transform-box: fill-box;
  transform-origin: center;
}

.tm-vacio-trazo {
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
  animation: tm-vacio-traza 650ms ease-out 100ms both;
}

.tm-vacio-rueda {
  animation: tm-vacio-rueda 320ms cubic-bezier(0.34, 1.56, 0.64, 1) 550ms both;
}

.tm-vacio-relleno {
  animation: tm-vacio-rellena 300ms ease-out 750ms both;
}

@keyframes tm-vacio-llega {
  from { translate: -16px 0; rotate: -6deg; opacity: 0; }
  40%  { opacity: 1; }
}

@keyframes tm-vacio-traza {
  from { stroke-dashoffset: 1; }
}

@keyframes tm-vacio-rueda {
  from { scale: 0; }
}

@keyframes tm-vacio-rellena {
  from { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-carrito-vacio-icono svg,
  .tm-carrito-vacio-icono svg * {
    animation: none;
  }
}

.tm-carrito-vacio-titulo {
  margin: 6px 0 0;
  font-size: 17px;
  font-weight: 800;
}

.tm-carrito-vacio-texto {
  margin: 0 0 8px;
  max-width: 28ch;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

/* ---------- Confirmar pedido ----------
   Rediseño aprobado en maqueta (2026-09-30): pasos numerados, opciones
   como tarjetas con dibujo, la cuenta como recibo y el botón con el total
   pegado abajo. Los números de los pasos los pone CSS: cuántos hay depende
   del pedido (envases, bolsa negra, bebidas) y así nunca se saltan. */

.tm-checkout {
  counter-reset: paso;
}

.tm-checkout-paso > .tm-store-seccion-titulo {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  padding: 0;
  background: none;
  color: var(--tinta);
  font-size: 17px;
}

.tm-checkout-paso > .tm-store-seccion-titulo::before {
  counter-increment: paso;
  content: counter(paso);
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--marca);
  color: #ffffff;
  font-size: 14px;
  font-weight: 800;
}

/* Dos por renglón en el teléfono; si son tres, la última ocupa el renglón
   entero en vez de quedarse sola a la mitad. */
.tm-checkout-opciones {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.tm-checkout-opcion:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

@media (min-width: 560px) {
  .tm-checkout-opciones {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }

  .tm-checkout-opcion:last-child:nth-child(odd) {
    grid-column: auto;
  }
}

.tm-checkout-opcion {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-height: 96px;
  padding: 12px 34px 12px 12px;
  border: 2px solid var(--linea);
  border-radius: 16px;
  background: var(--papel);
  color: var(--tinta);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-checkout-opcion svg {
  width: 26px;
  height: 26px;
  margin-bottom: 2px;
  color: var(--marca);
}

.tm-checkout-opcion-titulo {
  font-size: 14.5px;
  font-weight: 800;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.tm-checkout-opcion-detalle {
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--tinta-suave);
}

.tm-checkout-opcion[aria-pressed="true"] {
  border-color: var(--marca);
  background: color-mix(in srgb, var(--marca) 7%, var(--papel-alto));
}

/* La palomita de la elegida, arriba a la derecha. */
.tm-checkout-opcion[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  top: 10px;
  right: 10px;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--marca) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 12.5 4 4 8-9' stroke='white' stroke-width='3' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 14px no-repeat;
}

.tm-checkout-opcion:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

.tm-checkout-donde {
  margin-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-checkout-subtitulo {
  margin: 0;
  font-size: 14px;
  font-weight: 800;
}

.tm-checkout-direccion {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0;
  padding: 12px;
  border-radius: 14px;
  background: var(--papel);
  font-size: 14px;
}

.tm-checkout-direccion > svg {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--marca);
}

.tm-checkout-direccion > span {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.tm-checkout-direccion > span > span {
  color: var(--tinta-suave);
  font-size: 13px;
}

/* La cuenta como recibo: papel con orilla de sierra, igual que el ticket
   de «Mis pedidos». */
.tm-checkout-recibo {
  position: relative;
  margin-bottom: 10px;
  padding: 12px 14px 6px;
  border-radius: 14px 14px 0 0;
  background: var(--papel);
}

.tm-checkout-recibo::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -10px;
  height: 10px;
  background:
    linear-gradient(-45deg, transparent 7px, var(--papel) 0) 0 0 / 14px 10px repeat-x,
    linear-gradient(45deg, transparent 7px, var(--papel) 0) 0 0 / 14px 10px repeat-x;
}

.tm-checkout-productos {
  margin: 0 0 6px;
  padding: 0 0 8px;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-bottom: 1.5px dashed var(--linea);
}

.tm-checkout-productos li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13.5px;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}

.tm-checkout-productos li > span:last-child {
  flex: none;
}

.tm-checkout-por {
  color: var(--tinta-suave);
  white-space: nowrap;
}

.tm-checkout-renglon {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.tm-checkout-renglon--descuento {
  color: var(--ok);
  font-weight: 700;
}

.tm-checkout-nota {
  margin: 2px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--tinta-tenue);
}

.tm-checkout-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 8px;
  padding: 10px 0 6px;
  border-top: 1.5px dashed var(--linea);
  font-size: 15px;
  font-weight: 800;
}

.tm-checkout-total strong {
  font-family: var(--fuente-mono, monospace);
  font-size: 24px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Más aire antes de la nota: pegada al total parecía parte de la cuenta. */
.tm-checkout-cuenta form {
  margin-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* El total siempre a la vista (CLAUDE.md sección 11): el botón se queda
   pegado abajo mientras se baja por los pasos. */
.tm-checkout-pie {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px max(12px, env(safe-area-inset-bottom));
  border-radius: 20px 20px 0 0;
  background: var(--papel-alto);
  border-top: 1px solid var(--linea);
  box-shadow: 0 -8px 20px rgba(0, 0, 0, 0.06);
}

.tm-checkout-pie .tm-checkout-nota {
  margin: 0;
  text-align: center;
}

.tm-checkout-confirmar {
  min-height: 54px;
  justify-content: center;
  gap: 10px;
  border-radius: 16px;
  font-size: 16px;
}

.tm-checkout-confirmar > span {
  font-family: var(--fuente-mono, monospace);
  font-weight: 600;
  opacity: 0.92;
}

/* ---------- Reportar un problema ---------- */

.tm-reporte-pregunta {
  margin: 14px 0 8px;
  font-size: 14px;
  font-weight: 700;
}

.tm-reporte-texto {
  width: 100%;
  min-height: 112px;
  padding: 12px 14px;
  font: inherit;
  font-size: 15px;
  line-height: 1.45;
  color: var(--tinta);
  resize: vertical;
}

.tm-reporte-mandar {
  width: 100%;
  margin-top: 12px;
}

.tm-reporte-listo {
  background: var(--ok-fondo);
}

.tm-reporte-listo-titulo {
  margin: 0 0 2px;
  font-size: 15.5px;
  font-weight: 800;
  color: var(--ok);
}

.tm-reportes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.tm-reporte {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 0;
  border-top: 1px solid var(--linea);
}

.tm-reporte:first-child {
  border-top: 0;
  padding-top: 4px;
}

.tm-reporte-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.tm-reporte-tipo {
  font-size: 13.5px;
  font-weight: 700;
}

/* «Recibido» en el tono de espera; «Atendido» en verde. */
.tm-reporte-estado {
  flex-shrink: 0;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--alerta-fondo);
  color: var(--alerta);
  font-size: 11.5px;
  font-weight: 700;
}

.tm-reporte-estado--atendido {
  background: var(--ok-fondo);
  color: var(--ok);
}

.tm-reporte-texto-leido {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
  overflow-wrap: anywhere;
}

.tm-reporte-fecha {
  font-size: 12px;
  color: var(--tinta-tenue);
}

/* El indicador de carga usa los colores de la tienda; en POS y Trastienda
   caen a los suyos por el valor de respaldo de la variable. */

/* ---------- Buscador: la sugerencia se desvanece al cambiar ---------- */

.tm-store-buscador input::placeholder {
  transition: opacity 0.3s ease;
}

.tm-store-buscador input.tm-buscador-cambia::placeholder {
  opacity: 0.25;
}

/* ---------- Aviso de cerrado: se dice una vez y se va ---------- */

.tm-aviso-cerrado--latiendo {
  animation: tm-latido 3.2s ease-in-out infinite;
}

.tm-aviso-cerrado--saliendo {
  opacity: 0;
  transition: opacity 0.6s ease;
}

@keyframes tm-latido {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-aviso-cerrado--latiendo {
    animation: none;
  }
}

/* ---------- Desglose del descuento por producto ---------- */

.tm-checkout-desglose {
  margin: 8px 0 4px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--papel-hondo);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-checkout-desglose-linea {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.tm-checkout-desglose-nombre {
  display: flex;
  flex-direction: column;
  font-size: 13.5px;
  font-weight: 600;
  min-width: 0;
}

.tm-checkout-desglose-nombre small {
  font-size: 12px;
  font-weight: 500;
  color: var(--tinta-suave);
}

.tm-checkout-desglose-importe {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-variant-numeric: tabular-nums;
}

.tm-checkout-desglose-importe s {
  font-size: 12px;
  color: var(--tinta-tenue);
}

.tm-checkout-desglose-importe strong {
  font-size: 14px;
  color: var(--ok);
}

/* El renglón que SÍ trae descuento se distingue del que no. Sin esto los
   tres se ven igual de importantes y vuelve la confusión que teníamos:
   parecía que todo estaba rebajado. */
.tm-checkout-desglose-linea--ahorra .tm-checkout-desglose-nombre {
  color: var(--ok);
}

.tm-checkout-desglose-igual {
  font-size: 14px;
  font-weight: 600;
  color: var(--tinta-suave);
}

.tm-checkout-desglose-pie {
  margin: 2px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--linea);
  font-size: 12px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-checkout-desglose-pie strong {
  color: var(--tinta);
}

/* El rojo de marca es de la TIENDA. Las mismas opciones se pintan en el POS
   y en la Trastienda, y ahí el color de acción es el azul (CLAUDE.md §11):
   en una caja, elegir y cancelar no pueden verse igual. Por eso el acento
   es una variable y aquí se le pone el rojo, en vez de llevárselo puesto a
   los otros dos cascarones. */
.tm-store-shell {
  --opcion-activa: var(--marca);
  --opcion-activa-fondo: #FDF3F3;
}

/* ---------- Pagar por transferencia ---------- */

/* ---------- Los datos para transferir ----------

   Iba sobre fondo crema con el texto naranja: los tokens de «ojo, algo está
   cerca del mínimo». Pero esto no avisa de nada, explica cómo pagar, y ese
   color le ponía tono de regaño a unas instrucciones. El dueño lo dijo
   directo: «no me gusta ese color cremita».

   Queda una tarjeta de papel con línea de un pixel, y el único color es el
   azul del sistema en lo que se toca. El rojo se queda fuera a propósito
   —«ya estoy harto del rojo»— y además aquí no vende nada: esta pantalla
   sale cuando la compra ya se hizo.

   **Nota sobre la regla:** el azul es el color de acción del POS y de la
   Trastienda; en la tienda manda el rojo de marca. Se usa aquí porque es la
   única pantalla de la tienda donde no se está vendiendo sino cobrando, y
   porque el rojo quedó descartado por el dueño. Si alguna vez estorba, la
   salida sin color es dejar los botones en tinta. */

.tm-pago-titulo {
  margin: 0;
  padding: 14px 14px 10px;
  font-size: 15px;
  font-weight: 700;
  color: var(--tinta);
}

.tm-pago-titulo b {
  font-family: var(--fuente-mono, monospace);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.tm-pago-nota {
  margin: 0;
  padding: 0 14px 12px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* Los datos como renglones de una misma lista. Antes eran tarjetas blancas
   sueltas, y solo lo eran porque tenían que despegarse del crema; sin el
   crema, el marco sobra. */
.tm-pago-dato {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 11px 14px;
  border-top: 1px solid var(--linea);
  border-radius: 0;
  background: none;
}

.tm-pago-dato > span {
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-pago-dato strong { font-size: 14.5px; }

.tm-pago-copiable {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* La CLABE se lee dígito por dígito para compararla con la del banco, así
   que va en la mono y con cifras tabulares.

   `nowrap` y no `break-all`: dieciocho dígitos partidos en dos renglones se
   vuelven imposibles de comparar contra la pantalla del banco. Con el botón
   más chico caben de corrido, que es justo lo que pidió el dueño: «en mi
   celular le sobran dos números y se ponen abajo». */
.tm-pago-copiable code {
  flex: 1;
  min-width: 0;
  font-family: var(--fuente-mono, monospace);
  font-size: 14.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Chico a propósito. Los 44 px son para lo que se toca con prisa y con las
   manos ocupadas; copiar una CLABE se hace una vez, sentado y mirando. Lo
   que sí importa aquí es que los dieciocho dígitos quepan de un jalón, y
   esos 44 se los estaban comiendo. */
.tm-pago-copiar {
  position: relative;
  flex-shrink: 0;
  min-height: 32px;
  padding: 0 9px;
  border: 1px solid var(--accion);
  border-radius: 9px;
  background: var(--papel-alto);
  color: var(--accion);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

/* **Se ve de 32 pero se toca de 44.**
 *
 * El botón tenía que encoger para que la CLABE quepa de corrido —dieciocho
 * dígitos partidos en dos renglones no se pueden comparar contra la pantalla
 * del banco— pero la regla de la casa pide 44 px de área táctil y esa no se
 * negocia: se usa con prisa y a veces con una sola mano.
 *
 * Así que encoge el dibujo y no el blanco: este rectángulo invisible
 * desborda el botón por arriba y por abajo hasta completar los 44, y el dedo
 * lo encuentra aunque el ojo vea una pastilla chica. */
.tm-pago-copiar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}

.tm-pago-copiar--listo {
  border-color: var(--ok);
  color: var(--ok);
}

.tm-pago-copiar:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* El comprobante sí es una acción de dedo, así que este sí conserva su
   altura. Verde de WhatsApp porque abre WhatsApp: el color dice a dónde
   lleva antes de que se lea la etiqueta. */
.tm-pago-whatsapp {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 12px 14px 0;
  min-height: 48px;
  padding: 12px 16px;
  border-radius: 12px;
  background: #128C7E;
  color: #ffffff;
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
}

.tm-pago-whatsapp + .tm-pago-nota {
  padding-top: 8px;
  padding-bottom: 14px;
}

.tm-pago-espera,
.tm-pago-hecho {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-radius: 11px;
  font-size: 13.5px;
  font-weight: 700;
}

/* Esperando no es una falla: queda en tinta sobre papel hondo, sin color de
   alarma. Recibido sí merece el verde, que ahí sí pasó algo bueno. */
.tm-pago-espera { background: var(--papel-hondo); color: var(--tinta-suave); }
.tm-pago-hecho { background: var(--ok-fondo); color: var(--ok); }

/* ---------- Falta pagar ----------

   Un solo bloque, y un solo botón: «Toca aquí para pagar». Antes había dos
   que hacían lo mismo —el grande del «Gracias» y la caja clarita de la
   tarjeta— y los clientes no sabían cuál tocar.

   En el cian de la hoja de pago, que es el color que el dueño escogió para
   todo lo del banco (ver la hoja, abajo): el bloque y la hoja que abre se
   ven como una misma cosa. Es cian sólido y no clarito a propósito: el
   clarito, en el tema oscuro, era un rectángulo que deslumbraba. */

.tm-pago-falta {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin: 14px 0 12px;
  padding: 16px 16px 14px;
  border-radius: 16px;
  background: var(--cian);
  color: #ffffff;
  text-align: center;
}

.tm-pago-falta-titulo {
  margin: 0;
  font-size: 13.5px;
  font-weight: 700;
  opacity: 0.9;
}

.tm-pago-falta-monto {
  font-family: var(--fuente-mono, monospace);
  font-size: 30px;
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

/* Blanco sobre el cian: es lo único que se toca aquí, y así no compite con
   ningún otro color de la pantalla. */
.tm-pago-falta-boton {
  width: 100%;
  min-height: 52px;
  margin-top: 10px;
  padding: 0 16px;
  border: 0;
  border-radius: 12px;
  background: #ffffff;
  color: var(--cian-hondo);
  font: inherit;
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
}

.tm-pago-falta-boton:focus-visible {
  outline: 3px solid #ffffff;
  outline-offset: 3px;
}

/* ---------- La hoja con los datos del banco ----------

   Cian, con los campos en blanco encima. Lo pidió así el dueño: «haz la
   tarjeta de los datos bancarios con un tema azul cian y con los campos
   donde están los datos blancos».

   **Nota sobre la regla:** el cian no está en la lista de colores del
   proyecto, que dice que no se use ninguno fuera de ella. Entra por dos
   razones. Una, que el dueño lo pidió por su nombre después de descartar el
   rojo («ya estoy harto») y el crema. Y dos, que aquí el color hace un
   trabajo: esta hoja es el único sitio de la tienda donde se manejan datos
   de un banco, y que se vea distinta de todo lo demás ayuda a no confundirla
   con una pantalla de compra. Queda declarado como token para que no se
   repita a mano en veinte sitios. */

:root {
  --cian: #0E7490;
  --cian-hondo: #0B5B72;
  --cian-papel: #ECFAFE;
}

.tm-pagohoja-fondo {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
}

@media (min-width: 560px) {
  .tm-pagohoja-fondo { align-items: center; padding: 20px; }
}

/* Sube desde abajo, como cualquier hoja del teléfono: el gesto dice que se
   puede bajar otra vez, y eso quita el miedo de tocarla. */
.tm-pagohoja {
  position: relative;
  width: 100%;
  max-width: min(460px, 100%);
  max-height: 92vh;
  overflow-y: auto;
  padding: 20px 16px 18px;
  border-radius: 22px 22px 0 0;
  background: var(--cian);
  color: #ffffff;
  animation: tm-pagohoja-sube 0.22s cubic-bezier(0.2, 0.9, 0.3, 1);
}

@media (min-width: 560px) {
  .tm-pagohoja { border-radius: 22px; }
}

@keyframes tm-pagohoja-sube {
  from { transform: translateY(24px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

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

/* **El `z-index` no es de más: sin él el botón no responde.**
 *
 * Medido con `elementFromPoint` en el centro exacto del botón: quien
 * contestaba era el párrafo de «TRANSFIERE» que tiene detrás. El dibujo
 * estaba bien puesto y el área táctil no, que es el peor de los errores
 * porque no se ve —el dueño lo describió como «tengo que tocar afuera del
 * icono y arriba para que cierre», y lo que cerraba era el fondo, no la ✕—.
 *
 * Pasa porque el botón vive dentro de un contenedor con `overflow-y: auto`:
 * ahí el orden de pintado deja de ser el de siempre y los hermanos de más
 * abajo del HTML acaban encima. Con `z-index` se sube a su capa y vuelve a
 * ser él quien recibe el toque. */
.tm-pagohoja-cerrar {
  position: absolute;
  z-index: 3;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
  cursor: pointer;
}

.tm-pagohoja-cerrar svg { width: 20px; height: 20px; }

/* Se ve de 36 y se toca de 44, como el botón de copiar. Cerrar es lo que se
   toca con prisa y con una mano, y era justo lo que no respondía. */
.tm-pagohoja-cerrar::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

.tm-pagohoja-cerrar:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

.tm-pagohoja-rotulo {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.75;
}

/* El importe es lo que se teclea en la app del banco, así que es lo más
   grande de la hoja y va en la mono con cifras tabulares: se lee dígito por
   dígito y un número de más es un pedido que no cuadra. */
.tm-pagohoja-monto {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 2px 0 6px;
}

.tm-pagohoja-monto b {
  font-family: var(--fuente-mono, monospace);
  font-size: 34px;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.tm-pagohoja-copiar-monto {
  border-color: rgba(255, 255, 255, 0.55);
  background: transparent;
  color: #ffffff;
}

.tm-pagohoja-nota {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.45;
  opacity: 0.88;
}

/* Los tres pasos: un número en círculo y lo que hay que hacer. */
.tm-pagohoja-pasos {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
}

.tm-pagohoja-paso {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 10px;
}

.tm-pagohoja-num {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: #ffffff;
  color: var(--cian-hondo);
  font-size: 14px;
  font-weight: 800;
}

.tm-pagohoja-paso-cuerpo { min-width: 0; }

.tm-pagohoja-paso-titulo {
  margin: 3px 0 8px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.35;
}

.tm-pagohoja-paso .tm-pago-dato {
  padding: 11px 12px;
  border: 0;
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
}

.tm-pagohoja-paso .tm-pago-dato > span { color: var(--tinta-tenue); }

.tm-pagohoja-paso .tm-pago-copiar {
  border-color: var(--cian);
  color: var(--cian);
}

.tm-pagohoja-paso .tm-pago-copiar--listo {
  border-color: var(--ok);
  color: var(--ok);
}

/* A nombre de quién: se compara con lo que enseña la app del banco antes
   de mandar el dinero. */
.tm-pago-dato > .tm-pagohoja-titular {
  font-size: 12.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tinta-suave);
}

.tm-pagohoja-paso .tm-pagohoja-nota { margin: -4px 0 10px; }
/* Debajo del concepto, no del título: con aire, sin encimarse a la caja. */
.tm-pagohoja-paso .tm-pago-dato + .tm-pagohoja-nota { margin: 8px 0 0; }

.tm-pagohoja-comprobante {
  margin: 14px 0 0;
  font-size: 12.5px;
  opacity: 0.88;
}

/* WhatsApp y Telegram lado a lado y más chicos que «Ya pagué»: el
   comprobante ayuda, pero avisar es lo que hace falta. */
.tm-pagohoja-apps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
}

.tm-pagohoja-apps .tm-pago-whatsapp,
.tm-pagohoja-apps .tm-pago-telegram {
  margin: 6px 0 0;
  min-height: 44px;
  padding: 8px 12px;
  font-size: 14px;
}

.tm-pagohoja-pie {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.45;
  text-align: center;
  opacity: 0.78;
}

/* ---------- Mandar el comprobante, y avisar ---------- */

.tm-pago-telegram,
.tm-pago-whatsapp {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 10px 0 0;
  min-height: 48px;
  padding: 12px 16px;
  border-radius: 12px;
  color: #ffffff;
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
}

/* Cada uno con el color de su aplicación: el color dice a dónde lleva antes
   de que se lea la etiqueta, y equivocarse de app a medio pago es de las
   cosas que hacen abandonar. */
.tm-pago-telegram { background: #229ED9; }
.tm-pago-whatsapp { background: #128C7E; }

.tm-pago-icono { width: 20px; height: 20px; flex: none; }

/* «Listo, ya pagué». Va en blanco sobre el cian y no relleno: mandar el
   comprobante es el camino bueno y son los que llevan color. Este es la
   salida para quien ya transfirió y no quiere mandar foto, que también vale.

   Y 52 de alto: se toca con el pulgar igual que los de arriba. */
/* «Ya pagué» es lo que hay que tocar al final, así que es el botón fuerte
   de la hoja: blanco sólido sobre el cian, igual que «Toca aquí para
   pagar». Antes iba de contorno, debajo de dos botones de colores, y
   parecía la opción menos importante. */
.tm-pago-yapague {
  display: block;
  width: 100%;
  min-height: 52px;
  margin: 0;
  padding: 14px 16px;
  border: 0;
  border-radius: 12px;
  background: #ffffff;
  color: var(--cian-hondo);
  font: inherit;
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
}

.tm-pago-yapague:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

/* ---------- Mientras alguien revisa ----------

   El escalón entre «mandé el dinero» y «ya lo vimos». Va en papel hondo y
   tinta, SIN color de alarma: no hay nada mal, solo hay que esperar. */

.tm-pago-revisando {
  margin-bottom: 12px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-hondo);
}

.tm-pago-revisando-titulo {
  margin: 0 0 3px;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--tinta);
}

.tm-pago-revisando-nota {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-pago-revisando .tm-enlace-suave { margin-top: 6px; }

/* Animación 4 de la lista del dueño: tres puntitos que esperan, como
   cuando alguien está escribiendo en WhatsApp. Sin ellos, «un momento» era
   un letrero quieto que se podía leer como pantalla trabada. */
.tm-espera {
  display: inline-flex;
  gap: 4px;
  margin-left: 6px;
  vertical-align: middle;
}

.tm-espera i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--marca);
  opacity: 0.35;
  animation: tm-espera 1.2s ease-in-out infinite;
}

.tm-espera i:nth-child(2) { animation-delay: 150ms; }
.tm-espera i:nth-child(3) { animation-delay: 300ms; }

@keyframes tm-espera {
  0%, 60%, 100% { translate: 0 0; opacity: 0.35; }
  30%           { translate: 0 -4px; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-espera i {
    animation: none;
    opacity: 0.7;
  }
}

/* ---------- Pago confirmado ----------

   La única de las tres que da una noticia buena, y la única que cierra el
   asunto: de aquí ya no hay nada que hacer, así que la salida al catálogo va
   aquí mismo en vez de mandar a buscar el menú. */

.tm-pago-listo {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 12px;
  margin-bottom: 12px;
  padding: 14px;
  border-radius: 14px;
  background: var(--ok-fondo);
}

/* La palomita verde, la misma del «Gracias» en chico. */
.tm-pago-listo-sello {
  width: 40px;
  height: 40px;
}

.tm-pago-listo-sello circle { fill: var(--ok); }

.tm-pago-listo-sello path {
  fill: none;
  stroke: #ffffff;
  stroke-width: 4.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Animación 3 de la lista del dueño: la primera vez que el cliente ve su
   pago confirmado, el círculo brota y la palomita se traza —la misma
   celebración del «Gracias», en chico—. Las veces siguientes ya está
   puesta. */
.tm-pago-listo--recien .tm-pago-listo-sello * {
  transform-box: fill-box;
  transform-origin: center;
}

.tm-pago-listo--recien .tm-pago-listo-sello circle {
  animation: tm-fiesta-circulo 600ms both;
}

.tm-pago-listo--recien .tm-pago-listo-sello path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: tm-fiesta-trazo 533ms cubic-bezier(0.42, 0, 0.58, 1) 467ms forwards;
}

@media (prefers-reduced-motion: reduce) {
  .tm-pago-listo--recien .tm-pago-listo-sello circle,
  .tm-pago-listo--recien .tm-pago-listo-sello path {
    animation: none;
    stroke-dashoffset: 0;
  }
}

.tm-pago-listo-titulo {
  margin: 0 0 2px;
  font-size: 15.5px;
  font-weight: 800;
  color: var(--ok);
}

.tm-pago-listo-nota {
  margin: 0;
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-pago-listo-ir {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 4px;
  color: var(--ok);
  font-size: 14px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------- Mis direcciones ---------- */

.tm-dirs {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Cerrada: un renglón que se elige de un toque. Abiertas con sus campos,
   tres direcciones llenan la pantalla de formularios que casi nunca se
   tocan. */
.tm-dir {
  display: flex;
  align-items: stretch;
  gap: 0;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  overflow: hidden;
}

.tm-dir--elegida {
  border-color: var(--marca);
  box-shadow: 0 0 0 1px var(--marca);
}

.tm-dir-elegir {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 13px 12px;
  border: none;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-dir-marca {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  margin-top: 2px;
  border: 2px solid var(--tinta-tenue);
  border-radius: 999px;
  color: #ffffff;
}

.tm-dir--elegida .tm-dir-marca {
  border-color: var(--marca);
  background: var(--marca);
}

.tm-dir-marca svg { width: 15px; height: 15px; }

.tm-dir-texto {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.tm-dir-etiqueta {
  font-size: 15px;
  font-weight: 700;
}

.tm-dir-calle {
  font-size: 14px;
  color: var(--tinta-suave);
  line-height: 1.35;
}

.tm-dir-refs {
  font-size: 12.5px;
  color: var(--tinta-tenue);
}

.tm-dir-editar {
  flex-shrink: 0;
  min-width: 68px;
  border: none;
  border-left: 1px solid var(--linea);
  background: transparent;
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--marca);
  cursor: pointer;
}

.tm-dir-editar:hover { background: var(--papel-hondo); }

.tm-dir--editando {
  display: block;
  border-color: var(--marca);
  padding: 14px;
}

.tm-dir-forma-titulo {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 700;
}

.tm-dir-forma-acciones {
  display: flex;
  gap: 8px;
}

.tm-dir-forma-acciones .tm-boton { flex: 1; }

.tm-dir-borrar {
  display: block;
  width: 100%;
  min-height: 44px;
  margin-top: 10px;
  border: none;
  background: transparent;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--peligro);
  cursor: pointer;
}

.tm-dirs-agregar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 48px;
  border: 1px dashed var(--tinta-tenue);
  border-radius: 14px;
  background: transparent;
  font: inherit;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--marca);
  cursor: pointer;
}

.tm-dirs-agregar:hover { border-color: var(--marca); background: var(--papel-hondo); }

.tm-dirs-agregar span { font-size: 20px; line-height: 1; }


/* ---------- Secciones plegadas ---------- */

.tm-store-seccion--plegable { padding: 0; }

.tm-plegable-titulo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 56px;
  padding: 0 18px;
  cursor: pointer;
  list-style: none;
  font-size: 16px;
  font-weight: 700;
}

.tm-plegable-titulo::-webkit-details-marker { display: none; }

.tm-plegable-flecha {
  font-size: 22px;
  color: var(--tinta-tenue);
  transition: transform 0.15s ease;
}

.tm-plegable[open] .tm-plegable-flecha { transform: rotate(90deg); }

.tm-plegable .tm-cuenta-forma { padding: 0 18px 18px; }

@media (prefers-reduced-motion: reduce) {
  .tm-plegable-flecha { transition: none; }
}

/* El control de cantidad dentro de una fila de búsqueda. Ocupa el mismo
   hueco que el botón «Agregar» al que reemplaza, para que la fila no dé un
   brinco al agregar algo. */
.tm-fila-producto-accion .store-qty-control {
  margin-top: 2px;
  width: 100%;
}

/* ---------- El carrusel de departamentos ----------
   La forma sale de una referencia que pasó el dueño: círculo con un bodegón
   de productos y el nombre debajo. Lo que NO se copió son las flechas de
   los lados — le caen encima a los círculos, y en un teléfono nadie las
   usa: se desliza. El sitio que ocupaban se lo queda un círculo más. */

.tm-deptos {
    display: flex;
    gap: 14px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    padding-bottom: 6px;
    margin-bottom: 6px;
    scrollbar-width: none;
}

.tm-deptos::-webkit-scrollbar {
    display: none;
}

.tm-depto {
    flex: 0 0 auto;
    width: 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    scroll-snap-align: start;
    font: inherit;
}

.tm-depto-foto {
    width: 72px;
    height: 72px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--papel-hondo);
    display: grid;
    place-items: center;
    border: 2px solid transparent;
    transition: border-color 0.15s ease;
}

.tm-depto-foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Sin foto no se deja un hueco gris: se pone la inicial sobre un color de la
   casa. Un círculo gris se lee como una imagen que no cargó, y hoy treinta de
   los treinta y seis departamentos siguen sin foto: era casi toda la fila
   pareciendo rota.

   Los tres tintes son los que la tienda ya usa —amarillo, naranja y rojo de
   marca—, no colores nuevos. Y cada departamento se queda siempre con el
   suyo, porque el color sale de su nombre. */
.tm-depto-inicial {
    font-size: 28px;
    font-weight: 800;
    color: var(--tinta-tenue);
}

.tm-depto-foto--t0,
.tm-depto-foto--t1,
.tm-depto-foto--t2 {
    /* El borde de «activo» se pinta encima, así que el fondo va en la caja
       interior para no comérselo. */
    background-clip: padding-box;
}

.tm-depto-foto--t0 {
    background-color: var(--amarillo);
}

.tm-depto-foto--t0 .tm-depto-inicial {
    color: var(--tinta);
}

.tm-depto-foto--t1 {
    background-color: var(--naranja);
}

.tm-depto-foto--t2 {
    background-color: var(--marca);
}

.tm-depto-foto--t1 .tm-depto-inicial,
.tm-depto-foto--t2 .tm-depto-inicial {
    color: #ffffff;
}

/* El nombre en tinta y no en gris: en la referencia va gris sobre blanco y
   ahí se pierde. Dos líneas, con alto fijo para que los círculos no queden
   a distinta altura cuando un nombre es largo y el de al lado corto. */
.tm-depto-nombre {
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1.25;
    color: var(--tinta);
    text-align: center;
    min-height: 32px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.tm-depto--activo .tm-depto-foto {
    border-color: var(--marca);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--marca) 22%, transparent);
}

.tm-depto--activo .tm-depto-nombre {
    color: var(--marca);
}

.tm-depto:focus-visible .tm-depto-foto {
    outline: 2px solid var(--marca);
    outline-offset: 2px;
}

@media (min-width: 768px) {
    .tm-depto { width: 96px; }
    .tm-depto-foto { width: 84px; height: 84px; }
    .tm-depto-nombre { font-size: 13.5px; }
}

/* Mientras la foto va camino al servidor. Se enseña ya —del archivo que el
   navegador tiene en la mano— y este pulso dice que todavía no está
   guardada: sin él, una foto que aparece al instante se lee como "ya quedó"
   aunque la subida falle después. */
.tm-perfil-avatar--subiendo .tm-avatar {
    opacity: 0.55;
    animation: tm-latido 1s ease-in-out infinite;
}

@keyframes tm-latido {
    50% { opacity: 0.85; }
}

@media (prefers-reduced-motion: reduce) {
    .tm-perfil-avatar--subiendo .tm-avatar {
        animation: none;
    }
}

/* ---------- El anuncio de banda, tipo letrero de LED ----------
   Lo pidió el dueño para quien llega sin registrarse. La cinta lleva el
   texto DOS veces y la animación corre exactamente la mitad: cuando la
   primera copia sale por la izquierda, la segunda está justo donde empezó
   la primera y el ciclo se reinicia sin que se vea el corte. */

.tm-marquesina {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
    padding: 0 12px 0 0;
    border-radius: 14px;
    background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
    color: #ffffff;
    overflow: hidden;
}

.tm-marquesina[hidden] {
    display: none;
}

.tm-marquesina-cinta {
    flex: 1;
    min-width: 0;
    display: flex;
    overflow: hidden;
    padding: 11px 0;
    /* Se difumina en las orillas: el texto entra y sale en vez de cortarse
       de golpe contra el borde, que es lo que hace que parezca un letrero
       y no un texto recortado. */
    mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent);
}

.tm-marquesina-cinta span {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
    animation: tm-banda 38s linear infinite;
}

@keyframes tm-banda {
    to { transform: translateX(-100%); }
}

.tm-marquesina-boton {
    flex-shrink: 0;
    min-height: 36px;
    display: inline-flex;
    align-items: center;
    padding: 0 14px;
    border-radius: 999px;
    background: #ffffff;
    color: var(--marca-hondo);
    font-size: 13px;
    font-weight: 800;
    text-decoration: none;
}

.tm-marquesina-boton:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}

/* Quien pidió que no se le mueva nada, no ve una banda corriendo. El aviso
   sigue ahí, quieto: el mensaje importa más que el efecto. */
@media (prefers-reduced-motion: reduce) {
    .tm-marquesina-cinta span {
        animation: none;
    }
}

/* El precio tapado. En gris y en cursiva para que se lea como un aviso y no
   como una cantidad: un renglón vacío donde va el precio parece un error. */
.store-product-price--oculto {
    font-size: 11.5px;
    font-weight: 700;
    color: var(--tinta-tenue);
    font-style: italic;
}

.store-add-button--registro {
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    background: var(--papel-hondo);
    color: var(--marca-hondo);
}

/* El mapa de la bienvenida: visto desde arriba, como Google Maps. Diseñado
   con el dueño en LottieFiles Creator y copiado aquí con sus medidas y sus
   tiempos (ver _mapa() en bienvenida.js).

   Cada figura trae su estado final como estilo normal y la animación solo
   la lleva hasta ahí (`both`): así, quien pidió menos movimiento ve el
   mapa completo y quieto, sin tener que repetir las figuras aquí. */
.tm-mapa {
  --mapa-fondo: #f0f2ed;
  --mapa-cuadra: #e0e3de;
  --mapa-parque: #c5e4c4;
  --mapa-arbol: #7ebe80;
  --mapa-sombra: #aaaca6;

  /* La versión de noche va con los demás retoques del tema oscuro. */
  width: min(280px, 78vw);
  height: auto;
  margin-bottom: 4px;
}

.tm-mapa * {
  transform-box: fill-box;
  transform-origin: center;
}

.tm-mapa-fondo {
  fill: var(--mapa-fondo);
  animation: tm-mapa-aparece 267ms ease-out both;
}

.tm-mapa-cuadra { fill: var(--mapa-cuadra); }
.tm-mapa-parque { fill: var(--mapa-parque); }
.tm-mapa-arbol { fill: var(--mapa-arbol); }

.tm-mapa-brota {
  animation: tm-mapa-brota 400ms cubic-bezier(0.22, 1, 0.36, 1) var(--tarde) both;
}

.tm-mapa-arbol.tm-mapa-brota,
.tm-mapa-salta {
  animation: tm-mapa-brota 400ms cubic-bezier(0.34, 1.56, 0.64, 1) var(--tarde) both;
}

@keyframes tm-mapa-aparece {
  from { opacity: 0; }
}

@keyframes tm-mapa-brota {
  from { opacity: 0; scale: 0; }
}

/* La ruta se traza de la tienda al pin, por las calles. */
.tm-mapa-ruta {
  stroke: var(--marca);
  stroke-width: 9;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
  animation: tm-mapa-traza 1133ms cubic-bezier(0.42, 0, 0.58, 1) 1333ms both;
}

@keyframes tm-mapa-traza {
  from { stroke-dashoffset: 1; }
}

/* El pin cae cuando llega la ruta y rebota tres veces, cada vez menos. */
.tm-mapa-pin {
  animation: tm-mapa-cae 467ms 2333ms both;
}

@keyframes tm-mapa-cae {
  0%   { opacity: 0; translate: 0 -62px; animation-timing-function: ease-in; }
  6%   { opacity: 1; }
  43%  { translate: 0 0; animation-timing-function: ease-out; }
  61%  { translate: 0 -12px; animation-timing-function: ease-in; }
  79%  { translate: 0 0; animation-timing-function: ease-out; }
  88%  { translate: 0 -2.5px; animation-timing-function: ease-in; }
  100% { opacity: 1; translate: 0 0; }
}

.tm-mapa-sombra {
  fill: var(--mapa-sombra);
  animation: tm-mapa-sombra 467ms 2333ms both;
}

@keyframes tm-mapa-sombra {
  0%   { scale: 0; }
  1%   { scale: 0.3; animation-timing-function: ease-in; }
  43%  { scale: 1.1; animation-timing-function: ease-out; }
  100% { scale: 1; }
}

/* Sin domicilio no hay a dónde llevarlo: solo la tienda en su cuadra. */
.tm-mapa--solo-tienda .tm-mapa-ruta,
.tm-mapa--solo-tienda .tm-mapa-pin,
.tm-mapa--solo-tienda .tm-mapa-sombra {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .tm-mapa,
  .tm-mapa * {
    animation: none !important;
  }
}

/* ---------- El alta, en pasos: clave, cómo funciona, tus datos ----------

   Como en la maqueta que aprobó el dueño (2026-09-29): una barra de avance
   arriba, un paso por pantalla, y el botón principal abajo, al alcance del
   pulgar. Reemplazó al carrusel de la bienvenida: las tres animaciones son
   ahora el paso 2, entre la clave y los datos. */

.tm-alta {
  width: min(440px, 100%);
  margin: 0 auto;
  min-height: 70vh;
  display: flex;
  flex-direction: column;
}

.tm-alta-barra {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0 8px;
}

.tm-alta-atras {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  cursor: pointer;
}

.tm-alta-atras svg {
  width: 20px;
  height: 20px;
}

.tm-alta-avance {
  flex: 1;
  display: flex;
  gap: 6px;
}

.tm-alta-seg {
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: var(--linea);
  transition: background 0.3s;
}

.tm-alta-seg--hecho { background: color-mix(in srgb, var(--marca) 45%, transparent); }
.tm-alta-seg--ahora { background: var(--marca); }

.tm-alta-cuenta {
  min-width: 44px;
  text-align: right;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tinta-tenue);
}

.tm-alta-saltar,
.tm-alta-enlace {
  min-height: 44px;
  border: 0;
  background: none;
  color: var(--marca-hondo);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.tm-alta-saltar {
  padding: 0 6px;
  font-size: 14px;
}

.tm-alta-enlace {
  display: grid;
  place-items: center;
  font-size: 14.5px;
  text-align: center;
  text-decoration: none;
}

.tm-alta-cuerpo {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 22px 2px 8px;
  animation: tm-alta-entra 0.35s ease-out both;
}

@keyframes tm-alta-entra {
  from { opacity: 0; translate: 18px 0; }
}

.tm-alta-cuerpo--como {
  align-items: center;
  gap: 10px;
  padding-top: 10px;
  text-align: center;
}

.tm-alta-icono {
  width: 84px;
  height: 84px;
  border-radius: 26px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--marca) 12%, transparent);
  color: var(--marca-hondo);
}

.tm-alta-icono svg {
  width: 40px;
  height: 40px;
}

.tm-alta-titulo {
  margin: 0;
  font-size: 27px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-wrap: balance;
}

.tm-alta-texto {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

/* Cuatro números grandes, en letra de máquina: se dictan por teléfono, y en
   mono una S no se confunde con un 5. */
.tm-alta-clave {
  width: 100%;
  height: 76px;
  padding-left: 0.5em;
  border: 2px solid var(--linea);
  border-radius: 18px;
  background: var(--papel-alto);
  color: var(--tinta);
  text-align: center;
  font: 600 36px "IBM Plex Mono", ui-monospace, monospace;
  letter-spacing: 0.5em;
}

.tm-alta-clave:focus {
  outline: none;
  border-color: var(--marca);
}

.tm-alta-clave::placeholder {
  color: var(--tinta-tenue);
  opacity: 0.5;
}

.tm-alta-chip {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 999px;
  background: var(--ok-fondo);
  color: var(--ok);
  font-size: 13.5px;
  font-weight: 700;
}

.tm-alta-chip svg {
  width: 16px;
  height: 16px;
}

.tm-alta-oculta {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.tm-alta-dibujo .tm-mapa {
  width: min(290px, 76vw);
}

.tm-alta-puntos {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 4px;
}

.tm-alta-punto {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--tinta-tenue);
  opacity: 0.45;
}

.tm-alta-punto--ahora {
  width: 22px;
  background: var(--marca);
  opacity: 1;
}

.tm-alta-pie {
  width: 100%;
  margin-top: auto;
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tm-alta-seguir {
  width: 100%;
  min-height: 56px;
  font-size: 16px;
}

.tm-alta-nota {
  margin: 0;
  text-align: center;
  font-size: 14px;
  color: var(--tinta-suave);
}

.tm-alta-atras:focus-visible,
.tm-alta-saltar:focus-visible,
.tm-alta-enlace:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
  border-radius: 12px;
}

@media (prefers-reduced-motion: reduce) {
  .tm-alta-cuerpo { animation: none; }
}

/* ---------- Mientras carga: el esqueleto ----------

   Tarjetas grises con un brillo que las recorre, con la forma de lo que
   viene (catalogo.js y producto.js). Aprobado por el dueño en maqueta el
   2026-09-30: la pantalla vacía se sentía más lenta de lo que era. */

.tm-hueso {
  background-color: var(--hueso);
  background-image: linear-gradient(100deg, transparent 20%, var(--hueso-brillo) 50%, transparent 80%);
  background-size: 220% 100%;
  background-repeat: no-repeat;
  animation: tm-hueso-brillo 1.3s linear infinite;
}

@keyframes tm-hueso-brillo {
  from { background-position: 160% 0; }
  to { background-position: -60% 0; }
}

.tm-hueso-renglon {
  display: block;
  height: 10px;
  border-radius: 6px;
}

.tm-hueso-titulo {
  display: block;
  height: 24px;
  border-radius: 8px;
}

.tm-hueso-precio {
  display: block;
  width: 36%;
  height: 28px;
  border-radius: 8px;
}

.tm-hueso-boton {
  display: block;
  height: 36px;
  margin-top: auto;
  border-radius: 12px;
}

.tm-ficha .tm-hueso-boton {
  height: 52px;
  margin-top: 6px;
  border-radius: 14px;
}

/* El título de sección de verdad: pastilla de 17px con su relleno y su
   margen de abajo. */
.tm-hueso-pastilla {
  display: block;
  width: 110px;
  height: 35px;
  margin: 0 0 12px;
  border-radius: 999px;
}

/* El hueco que ocupa lo que viene, con sus renglones grises centrados. */
.tm-hueso-hueco {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  min-height: var(--alto);
}

.tm-esqueleto {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* El esqueleto no se toca: no es nada todavía. */
.tm-esqueleto,
.tm-depto--hueso {
  pointer-events: none;
}

.tm-depto--hueso .tm-hueso-hueco {
  width: 100%;
  align-items: center;
}

/* Lo que llega entra una cosa tras otra, de arriba abajo. */
.tm-entra {
  animation: tm-entra 0.38s cubic-bezier(0.22, 1, 0.36, 1) var(--tm-entra-t, 0ms) both;
}

@keyframes tm-entra {
  from { opacity: 0; translate: 0 10px; }
}

/* Los datos de la ficha, cuando llegan: sube poquito y aparece. */
.tm-ficha-datos--entra {
  animation: tm-entra 0.34s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* La foto que viaja entre la tarjeta y la ficha (transicion.js). Encima del
   contenido y debajo del menú y el carrito; sin atrapar toques. */
.tm-foto-viajera {
  position: fixed;
  z-index: 150;
  margin: 0;
  object-fit: contain;
  background: #ffffff;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.16);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .tm-hueso,
  .tm-entra,
  .tm-ficha-datos--entra {
    animation: none;
  }
}

/* ---------- El recorrido guiado ----------

   La primera vez que el cliente llega a comprar (recorrido.js): un foco con
   aro amarillo que late sobre cada parte de la tienda, y una burbuja con lo
   que es. Como en la maqueta: el velo lo pone la sombra enorme del foco, así
   que lo iluminado queda limpio y todo lo demás oscuro. La capa entera
   atrapa los toques: durante el recorrido no se compra por accidente. */

.tm-recorrido {
  position: fixed;
  inset: 0;
  z-index: 300;
}

.tm-recorrido-foco {
  position: fixed;
  border-radius: 14px;
  box-shadow: 0 0 0 200vmax rgba(12, 10, 22, 0.62);
  pointer-events: none;
  transition:
    left 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    top 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    width 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    height 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    border-radius 0.4s;
}

.tm-recorrido-foco::after {
  content: "";
  position: absolute;
  inset: -5px;
  border: 3px solid var(--amarillo);
  border-radius: inherit;
  animation: tm-recorrido-late 1.6s ease-out infinite;
}

@keyframes tm-recorrido-late {
  0%   { opacity: 0.9; scale: 0.97; }
  100% { opacity: 0; scale: 1.1; }
}

.tm-recorrido-burbuja {
  position: fixed;
  width: min(320px, calc(100vw - 24px));
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  border-radius: 20px;
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.28);
  transition:
    top 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    left 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.tm-recorrido-contador {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--marca-hondo);
}

.tm-recorrido-texto {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.45;
  text-wrap: pretty;
}

.tm-recorrido-botones {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.tm-recorrido-saltar {
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  background: none;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.tm-recorrido-seguir {
  min-height: 46px;
  padding: 0 22px;
}

.tm-recorrido-saltar:focus-visible,
.tm-recorrido-seguir:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .tm-recorrido-foco,
  .tm-recorrido-burbuja {
    transition: none;
  }

  .tm-recorrido-foco::after {
    animation: none;
    opacity: 0.9;
  }
}

/* ---------- «Tu tarjeta de cliente» y «Mi tarjeta» ----------

   Rehecha el 2026-10-17 con la maqueta que aprobó el dueño («la A»; la de
   antes «no se ve profesional»): una tarjeta de verdad —1.586 a 1, textura
   fina, chip dorado, filo amarillo y su logo— que se voltea para enseñar su
   código, el que cambia cada 5 minutos (store/tarjeta_cliente.js). Al
   frente no va código: «que se voltee la tarjeta para ver el código de
   barra de atrás, más no que esté por enfrente». */

.tm-cara-hueco {
  width: 44px;
  flex-shrink: 0;
}

.tm-cara-cuerpo {
  gap: 16px;
  padding-top: 14px;
}

.tm-cara-cabeza {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.tm-credencial {
  display: block;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 1.586;
  padding: 0;
  border: 0;
  border-radius: 18px;
  background: none;
  color: #ffffff;
  font: inherit;
  text-align: left;
  perspective: 1200px;
  cursor: pointer;
  animation: tm-credencial-entra 500ms cubic-bezier(0.22, 1, 0.36, 1) 100ms both;
}

.tm-credencial:focus-visible {
  outline: 3px solid var(--amarillo);
  outline-offset: 4px;
}

@keyframes tm-credencial-entra {
  from { opacity: 0; transform: translateY(12px) scale(0.97); }
}

.tm-credencial-giro {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.6s cubic-bezier(0.3, 1.2, 0.4, 1);
}

.tm-credencial[aria-pressed="true"] .tm-credencial-giro {
  transform: rotateY(180deg);
}

.tm-credencial-frente,
.tm-credencial-atras {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 18px;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  box-shadow: inset 0 -5px 0 var(--amarillo), 0 14px 30px rgba(120, 10, 10, 0.28);
}

.tm-credencial-frente {
  display: grid;
  grid-template-rows: auto 1fr auto;
  padding: 16px 18px 18px;
  background:
    radial-gradient(circle at 108% -12%, rgba(255, 255, 255, 0.16) 0 36%, transparent 36.5%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.045) 0 2px, transparent 2px 9px),
    linear-gradient(135deg, var(--marca), var(--marca-hondo));
}

.tm-credencial-arriba,
.tm-credencial-abajo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

/* El logo, pintado como en la franja: su silueta, de amarillo. */
.tm-credencial-logo {
  display: block;
  width: 104px;
  height: 24px;
  background-color: var(--amarillo);
  -webkit-mask: var(--logo) left center / contain no-repeat;
  mask: var(--logo) left center / contain no-repeat;
}

.tm-credencial-tienda {
  font-size: 15px;
  font-weight: 800;
  color: var(--amarillo);
}

.tm-credencial-tipo {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
}

.tm-credencial-chip {
  position: absolute;
  right: 22px;
  top: 52px;
  width: 34px;
  height: 26px;
  border-radius: 6px;
  background: linear-gradient(135deg, #f7d774, #d9a400);
  box-shadow: inset 0 0 0 1px rgba(120, 80, 0, 0.35);
}

.tm-credencial-chip::before,
.tm-credencial-chip::after {
  content: "";
  position: absolute;
  background: rgba(120, 80, 0, 0.35);
}

.tm-credencial-chip::before {
  left: 33%;
  top: 0;
  bottom: 0;
  width: 1px;
  box-shadow: 10px 0 0 rgba(120, 80, 0, 0.35);
}

.tm-credencial-chip::after {
  top: 50%;
  left: 0;
  right: 0;
  height: 1px;
}

.tm-credencial-quien {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.tm-credencial-cara {
  flex: none;
  width: 62px;
  height: 62px;
  border-radius: 999px;
  overflow: hidden;
  background: #ffffff;
  box-shadow: 0 0 0 3px #ffffff, 0 0 0 6px rgba(245, 197, 24, 0.9);
}

.tm-credencial-cara .tm-avatar--credencial {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  border-radius: 999px;
  object-fit: cover;
  color: #ffffff;
  font-size: 22px;
  font-weight: 800;
}

.tm-credencial-cara--brota {
  animation: tm-credencial-brota 420ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes tm-credencial-brota {
  from { transform: scale(0.6); opacity: 0.4; }
}

.tm-credencial-cara--subiendo {
  animation: tm-credencial-sube 1s ease-in-out infinite;
}

@keyframes tm-credencial-sube {
  50% { opacity: 0.55; }
}

.tm-credencial-datos {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.tm-credencial-nombre {
  overflow: hidden;
  font-size: 19px;
  font-weight: 800;
  line-height: 1.2;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tm-credencial-desde {
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.82);
}

.tm-credencial-voltear {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  font-size: 12.5px;
  font-weight: 700;
}

.tm-credencial-voltear svg {
  width: 15px;
  height: 15px;
}

.tm-credencial-numero {
  font-family: var(--fuente-mono, monospace);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}

/* Atrás: la banda negra de las tarjetas de banco, y el código en blanco.
   Blanco y negro de verdad, también de noche: la pistola necesita
   contraste, no el color de la tienda. */
.tm-credencial-atras {
  display: flex;
  flex-direction: column;
  transform: rotateY(180deg);
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
}

.tm-credencial-banda {
  flex: none;
  height: 28px;
  margin-top: 14px;
  background: #1e1a1a;
}

.tm-credencial-atras-cuerpo {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 0;
  padding: 10px 16px 16px;
}

.tm-credencial-codigo {
  display: grid;
  place-items: center;
  min-height: 82px;
  padding: 8px 6px 6px;
  border-radius: 10px;
  background: #ffffff;
  color: #1f1f1f;
}

.tm-credencial-codigo svg {
  display: block;
  width: 100%;
  height: 54px;
}

.tm-credencial-codigo-texto {
  margin-top: 2px;
  font-family: var(--fuente-mono, monospace);
  font-size: 12px;
  letter-spacing: 0.12em;
  color: #3a3a3a;
}

.tm-credencial-codigo--nuevo {
  animation: tm-credencial-destello 0.6s ease-out;
}

@keyframes tm-credencial-destello {
  from { box-shadow: 0 0 0 0 rgba(245, 197, 24, 0.9); }
  to { box-shadow: 0 0 0 10px rgba(245, 197, 24, 0); }
}

.tm-credencial-aviso {
  padding: 0 8px;
  font-size: 13px;
  line-height: 1.4;
  text-align: center;
  color: #5f5e66;
}

.tm-credencial-renueva {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
}

.tm-credencial-renueva[hidden] {
  display: none;
}

.tm-credencial-renueva b {
  font-family: var(--fuente-mono, monospace);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.tm-credencial-reloj {
  position: relative;
  flex: 1;
  height: 5px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.25);
}

.tm-credencial-reloj i {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: inherit;
  background: var(--amarillo);
}

.tm-credencial-atras-pie {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-top: auto;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.85);
}

.tm-credencial-atras-pie b {
  font-family: var(--fuente-mono, monospace);
  font-weight: 600;
  letter-spacing: 0.06em;
}

/* Su cara: «Tu foto», sus iniciales y los personajes, en una sola fila. */
.tm-cara-rotulo {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
}

.tm-cara-pestanas {
  display: inline-flex;
  align-self: flex-start;
  padding: 3px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-cara-pestana {
  min-height: 38px;
  padding: 0 16px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.tm-cara-pestana[aria-pressed="true"] {
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.tm-cara-fichas {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px 10px;
}

.tm-cara-ficha {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
}

.tm-cara-ficha-cara {
  display: grid;
  place-items: center;
  width: 62px;
  height: 62px;
  overflow: hidden;
  border-radius: 999px;
  box-shadow: 0 0 0 1px var(--linea);
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.tm-cara-ficha-cara img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tm-cara-ficha:active .tm-cara-ficha-cara {
  transform: scale(0.94);
}

.tm-cara-ficha--si {
  color: var(--tinta);
}

.tm-cara-ficha--si .tm-cara-ficha-cara {
  box-shadow: 0 0 0 3px var(--papel), 0 0 0 5.5px var(--marca);
  transform: scale(1.04);
}

/* La palomita de la escogida. */
.tm-cara-ficha--si::after {
  content: "";
  position: absolute;
  top: 42px;
  left: calc(50% + 14px);
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--marca) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 12.5 4 4L18 8' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 14px no-repeat;
  box-shadow: 0 0 0 2px var(--papel);
}

.tm-cara-ficha-cara--foto {
  border: 2px dashed color-mix(in srgb, var(--marca) 45%, transparent);
  background: var(--papel-alto);
  color: var(--marca);
  box-shadow: none;
}

.tm-cara-ficha-cara--foto svg {
  width: 26px;
  height: 26px;
}

.tm-cara-ficha--si .tm-cara-ficha-cara--foto {
  border: 0;
}

.tm-cara-ficha-cara--iniciales {
  color: #ffffff;
  font-size: 20px;
  font-weight: 800;
}

/* Cómo ver la tienda, en un selector de una fila. */
.tm-cara-temas {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  padding: 3px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-cara-tema {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.tm-cara-tema svg {
  width: 16px;
  height: 16px;
}

.tm-cara-tema--si {
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.tm-cara-ficha:focus-visible,
.tm-cara-ficha:focus-within,
.tm-cara-pestana:focus-visible,
.tm-cara-tema:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 3px;
  border-radius: 12px;
}

.tm-cara .tm-alta-seguir {
  display: grid;
  place-items: center;
  text-decoration: none;
}

/* «Mi tarjeta»: la tarjeta, un botón grande para voltearla y dos pistas. */
.tm-mi-tarjeta {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 520px;
  margin: 0 auto;
  padding: 16px 16px 24px;
}

.tm-mi-tarjeta .tm-credencial {
  max-width: none;
}

.tm-mi-tarjeta-voltear {
  min-height: 50px;
  justify-content: center;
  gap: 8px;
  font-size: 15px;
}

.tm-mi-tarjeta-voltear svg {
  width: 18px;
  height: 18px;
}

.tm-mi-tarjeta-pistas {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--papel-alto);
  box-shadow: 0 0 0 1px var(--linea);
  list-style: none;
  font-size: 13px;
  line-height: 1.4;
  color: var(--tinta-suave);
}

.tm-mi-tarjeta-pistas li {
  display: flex;
  gap: 8px;
}

.tm-mi-tarjeta-pistas svg {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--marca);
}

/* El «Nuevo» del menú, amarillo para que se note. */
.tm-menu-extra--nuevo {
  background: var(--amarillo);
  color: #1f1f1f;
}

@media (prefers-reduced-motion: reduce) {
  .tm-credencial,
  .tm-credencial-cara--brota,
  .tm-credencial-cara--subiendo,
  .tm-credencial-codigo--nuevo {
    animation: none;
  }

  .tm-credencial-giro {
    transition: none;
  }
}

/* Pantalla 1: los productos caen en el carrito, uno tras otro. */
.tm-escoge-piso {
  fill: var(--mapa-sombra);
  opacity: 0.35;
}

.tm-escoge-cae {
  animation: tm-escoge-cae 600ms var(--tarde) both;
}

@keyframes tm-escoge-cae {
  0%   { opacity: 0; translate: 0 -240px; animation-timing-function: ease-in; }
  8%   { opacity: 1; }
  55%  { translate: 0 0; animation-timing-function: ease-out; }
  72%  { translate: 0 -16px; animation-timing-function: ease-in; }
  88%  { translate: 0 0; }
  100% { opacity: 1; translate: 0 0; }
}

/* El carrito se sume un poquito con cada producto que le cae. */
.tm-escoge-carrito {
  transform-origin: 50% 100%;
  animation: tm-escoge-recibe 1700ms linear both;
}

@keyframes tm-escoge-recibe {
  0%, 36%, 45%, 59%, 68%, 82%, 92%, 100% { translate: 0 0; scale: 1; }
  39% { translate: 0 5px; scale: 1.03 0.96; }
  62% { translate: 0 5px; scale: 1.03 0.96; }
  86% { translate: 0 6px; scale: 1.04 0.95; }
}

/* Pantalla 3: un renglón por forma de pago encendida, cada uno con su
   movimiento. El dueño pidió «más detallista»: billetes y monedas que caen;
   dos celulares con las flechas girando; la tarjeta que entra a la
   terminal y la pantalla que dice aprobado. */
.tm-pg-fila { animation: tm-pg-sube 450ms ease-out var(--t) both; }
.tm-pg-telefono { animation: tm-pg-sube 400ms ease-out var(--t) both; }

@keyframes tm-pg-sube {
  from { opacity: 0; translate: 0 18px; }
}

.tm-pg-billete { animation: tm-pg-billete 500ms cubic-bezier(0.22, 1, 0.36, 1) var(--t) both; }

@keyframes tm-pg-billete {
  from { opacity: 0; translate: -40px 0; }
}

.tm-pg-moneda { animation: tm-pg-moneda 500ms var(--t) both; }

@keyframes tm-pg-moneda {
  0%   { opacity: 0; translate: 0 -60px; animation-timing-function: ease-in; }
  10%  { opacity: 1; }
  60%  { translate: 0 0; animation-timing-function: ease-out; }
  78%  { translate: 0 -8px; animation-timing-function: ease-in; }
  100% { opacity: 1; translate: 0 0; }
}

.tm-pg-giro {
  transform-origin: center;
  animation: tm-mapa-aparece 300ms ease-out 800ms both, tm-pg-gira 1.6s linear 1s infinite;
}

@keyframes tm-pg-gira {
  to { rotate: 360deg; }
}

.tm-pg-ok { animation: tm-mapa-brota 400ms cubic-bezier(0.34, 1.56, 0.64, 1) 1.9s both; }
.tm-pg-aprobado { animation: tm-mapa-brota 400ms cubic-bezier(0.34, 1.56, 0.64, 1) 2.7s both; }

.tm-pg-palomita,
.tm-pg-apr-palomita {
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
}

.tm-pg-palomita { animation: tm-pg-traza 350ms ease-out 2.1s both; }
.tm-pg-apr-palomita { animation: tm-pg-traza 300ms ease-out 2.9s both; }

@keyframes tm-pg-traza {
  from { stroke-dashoffset: 1; }
}

/* La tarjeta llega volando, se acomoda sobre la ranura y entra. Quieta
   (menos movimiento) ya está metida: su lugar de siempre es el final. */
.tm-pg-tarjeta { animation: tm-pg-tarjeta 1.4s cubic-bezier(0.45, 0, 0.3, 1) 1.2s both; }

@keyframes tm-pg-tarjeta {
  0%   { opacity: 0; translate: -90px 12px; rotate: -24deg; }
  20%  { opacity: 1; }
  60%  { translate: 0 -26px; rotate: 0deg; }
  75%  { translate: 0 -26px; rotate: 0deg; }
  100% { opacity: 1; translate: 0 0; rotate: 0deg; }
}

/* ---------- Mi cuenta: tablero, no formulario ---------- */

.tm-cuenta-hub {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: min(460px, 100%);
  margin: 0 auto;
  padding: 2px 0 28px;
}

/* ---------- La portada ----------

   Estilo «Portada», el que escogió el dueño entre cuatro el 2026-10-05: su
   cara al centro sobre el color de la tienda, como las apps de hoy. Antes
   iba de lado y en chico —se veía como ajustes de WhatsApp— y él lo quería
   «más como las apps modernas».

   Es una tarjeta con esquinas y no una franja de lado a lado: la página de
   la tienda tiene su margen, y romperlo solo aquí haría saltar la pantalla
   al entrar. */

.tm-cuenta-portada {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
  padding: 24px 16px 58px;
  border-radius: 24px;
  background: linear-gradient(150deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  text-align: center;
}

/* Dos círculos de luz, apenas: le quitan lo plano sin ser un dibujo. */
.tm-cuenta-portada::before,
.tm-cuenta-portada::after {
  content: "";
  position: absolute;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  pointer-events: none;
}

.tm-cuenta-portada::before {
  width: 220px;
  height: 220px;
  right: -70px;
  top: -90px;
}

.tm-cuenta-portada::after {
  width: 140px;
  height: 140px;
  left: -50px;
  bottom: -60px;
}

.tm-cuenta-portada > * {
  position: relative;
  z-index: 1;
}

.tm-cuenta-avatar .tm-avatar--grande {
  width: 88px;
  height: 88px;
  font-size: 30px;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.85);
}

.tm-cuenta-portada .tm-perfil-camara {
  width: 30px;
  height: 30px;
  border-width: 3px;
  border-color: var(--marca-hondo);
  background: #ffffff;
  color: var(--marca);
}

.tm-cuenta-portada .tm-perfil-camara svg {
  width: 15px;
  height: 15px;
}

.tm-cuenta-nombre {
  margin: 12px 0 0;
  max-width: 100%;
  font-size: 22px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.02em;
  /* Un apellido compuesto no tiene dónde cortar y empujaría la tarjeta. */
  overflow-wrap: anywhere;
}

.tm-cuenta-telefono {
  font-family: var(--fuente-mono, "IBM Plex Mono", monospace);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  opacity: 0.9;
}

.tm-cuenta-portada-acciones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}

.tm-cuenta-portada-boton {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  color: #ffffff;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
}

.tm-cuenta-portada-boton:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

/* ---------- Los tres números, flotando sobre el borde ---------- */

.tm-cuenta-cifras {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: -46px 14px 0;
  padding: 12px 4px;
  border-radius: 20px;
  background: var(--papel-alto);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.1);
}

.tm-cuenta-cifra {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-height: 52px;
  justify-content: center;
  color: inherit;
  text-decoration: none;
}

.tm-cuenta-cifra + .tm-cuenta-cifra {
  border-left: 1px solid var(--linea);
}

.tm-cuenta-cifra strong {
  font-family: var(--fuente-mono, "IBM Plex Mono", monospace);
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.tm-cuenta-cifra span {
  font-size: 11.5px;
  color: var(--tinta-suave);
}

.tm-cuenta-cifra:focus-visible {
  outline: 3px solid var(--marca);
  outline-offset: -3px;
  border-radius: 14px;
}

/* ---------- El pedido en curso ---------- */

.tm-cuenta-curso {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 4px;
  padding: 14px;
  border-radius: 18px;
  background: var(--ok-fondo);
  color: var(--tinta);
  text-decoration: none;
}

/* Un pin chiquito —a dónde va— y no un camión: lo pidió el dueño. */
.tm-cuenta-curso-icono {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--ok);
}

.tm-cuenta-curso-icono svg {
  width: 17px;
  height: 17px;
}

.tm-cuenta-curso-texto {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.tm-cuenta-curso-texto b {
  font-size: 15px;
}

.tm-cuenta-curso-texto small {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ok);
}

.tm-cuenta-curso-pasos {
  display: flex;
  gap: 4px;
  margin-top: 8px;
}

.tm-cuenta-curso-pasos i {
  flex: 1;
  height: 4px;
  border-radius: 4px;
  background: var(--ok);
  opacity: 0.22;
}

.tm-cuenta-curso-pasos i.si {
  opacity: 1;
}

.tm-cuenta-curso:focus-visible {
  outline: 3px solid var(--ok);
  outline-offset: 2px;
}

/* ---------- Los atajos redondos ---------- */

.tm-cuenta-atajos {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
}

.tm-cuenta-atajo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  color: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
}

.tm-cuenta-atajo-burbuja {
  position: relative;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 18px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
  color: var(--marca);
}

.tm-cuenta-atajo-burbuja svg {
  width: 23px;
  height: 23px;
}

.tm-cuenta-atajo-burbuja--falta {
  background: var(--alerta-fondo);
  color: var(--alerta);
}

.tm-cuenta-atajo-burbuja em {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 2px solid var(--papel);
  background: var(--marca);
  color: #ffffff;
  font-size: 11px;
  font-style: normal;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tm-cuenta-atajo:active .tm-cuenta-atajo-burbuja {
  transform: scale(0.94);
}

.tm-cuenta-atajo:focus-visible {
  outline: none;
}

.tm-cuenta-atajo:focus-visible .tm-cuenta-atajo-burbuja {
  outline: 3px solid var(--marca);
  outline-offset: 2px;
}

/* Los encabezados de grupo no decoran: separan lo que ya compraste de quién
   eres. */
.tm-cuenta-grupo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
  padding: 10px 6px 2px;
}

.tm-cuenta-grupo-falta {
  font-style: normal;
  letter-spacing: 0;
  text-transform: none;
  font-size: 12px;
  color: var(--alerta);
}

.tm-cuenta-lista {
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
}

.tm-cuenta-fila {
  display: flex;
  align-items: center;
  /* Los 10 del hueco entre el icono y el texto se quedan: el dueño los dio
     por buenos. Lo que se mueve es la sangría de la izquierda, a 6.

     Y el 6 no es un número al tanteo. El rótulo del grupo —MIS COMPRAS—
     también lleva 6 de sangría, así que con esto el icono y el rótulo caen
     los dos a 20 del borde de la pantalla: **la misma línea vertical**. Con
     14 el icono iba a 28 y el escalón contra el título se veía.

     A la derecha se quedan los 14, y es a propósito: ahí va la flecha, que
     no es para tocarse sino para mirarse, y pegada al borde se ve apretada. */
  gap: 10px;
  width: 100%;
  min-height: 62px;
  padding: 11px 14px 11px 6px;
  border: 0;
  border-bottom: 1px solid var(--linea);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
}

.tm-cuenta-lista .tm-cuenta-fila:last-child {
  border-bottom: 0;
}

.tm-cuenta-fila:active {
  background: var(--papel-hondo);
}

.tm-cuenta-fila:focus-visible {
  outline: 3px solid var(--marca);
  outline-offset: -3px;
}

.tm-cuenta-fila-icono {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 11px;
  background: var(--papel-hondo);
  color: var(--marca);
}

/* Lo que falta se marca con color, no con un regaño. */
.tm-cuenta-fila-icono--falta {
  background: var(--alerta-fondo);
  color: var(--alerta);
}

.tm-cuenta-fila-icono--salir {
  background: var(--peligro-fondo);
  color: var(--peligro);
}

.tm-cuenta-fila-icono svg {
  width: 20px;
  height: 20px;
}

.tm-cuenta-fila-texto {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.tm-cuenta-fila-titulo {
  font-size: 15px;
  font-weight: 600;
}

.tm-cuenta-fila-detalle {
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--tinta-suave);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-cuenta-pastilla {
  flex: none;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--alerta-fondo);
  color: var(--alerta);
}

.tm-cuenta-pastilla--listo {
  background: var(--ok-fondo);
  color: var(--ok);
}

.tm-cuenta-fila-flecha {
  flex: none;
  font-size: 20px;
  color: var(--tinta-tenue);
}

.tm-cuenta-fila--salir .tm-cuenta-fila-titulo {
  color: var(--peligro);
}

/* ---------- Las pantallas de la cuenta: una sola forma ----------

   Tu nombre, tu correo, la contraseña, Telegram, los aparatos, los
   depósitos y las direcciones. Antes cada una ponía su título a su manera y
   su propio «← Mi perfil» debajo del «Seguir comprando»: dos botones de
   regresar encimados. Ahora el «‹ Mi cuenta» lo pone el cascarón y todas
   empiezan igual: su icono —el mismo de su renglón en Mi cuenta—, el título
   grande y una línea de para qué es. El botón va abajo y a todo lo ancho,
   donde lo alcanza el pulgar. Maqueta aprobada por el dueño el 2026-10-06. */

.tm-sub {
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* A todo lo ancho siempre: dentro de la página la caja se encogía al
     tamaño de su texto, y «Tu nombre» salía más angosta que «Tu correo». */
  width: 100%;
  max-width: min(460px, 100%);
  margin: 0 auto;
  padding: 4px 0 28px;
}

.tm-sub-cabeza {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.tm-sub-icono {
  display: grid;
  place-items: center;
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--marca) 12%, var(--papel-alto));
  color: var(--marca);
}

.tm-sub-icono svg { width: 26px; height: 26px; }

.tm-sub-cabeza-texto { min-width: 0; }

.tm-sub-titulo {
  margin: 0;
  font-size: 23px;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.tm-sub-texto {
  margin: 3px 0 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-sub-tarjeta {
  margin: 0;
  padding: 16px;
  border: 1px solid var(--linea);
  border-radius: 20px;
  background: var(--papel-alto);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
}

.tm-sub-forma {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tm-sub-boton {
  width: 100%;
  min-height: 52px;
  margin: 0;
  border-radius: 16px;
  font-size: 16px;
  justify-content: center;
}

/* Lo que ya trae su margen de cuando cada pantalla se acomodaba sola: aquí
   el espacio lo pone el hueco de .tm-sub. */
.tm-sub > .tm-tg-caja,
.tm-sub > .tm-sesiones,
.tm-sub > .tm-dirs,
.tm-sub .tm-cuenta-nota { margin: 0; }

.tm-sub-chip {
  flex: none;
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
}

.tm-sub-chip--ok { background: var(--ok-fondo); color: var(--ok); }

.tm-sub-rotulo {
  margin: 4px 2px -6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-tg-avisos {
  display: flex;
  flex-direction: column;
  gap: 10px;
  list-style: none;
}

.tm-tg-avisos li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
}

.tm-tg-avisos li span {
  display: grid;
  place-items: center;
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 10px;
  background: var(--papel-hondo);
}

/* El vale de muestra: se ve como uno de verdad, pero no se toca ni se
   confunde con uno vivo. */
.tm-deposito--ejemplo {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--marca) 40%, transparent);
  box-shadow: none;
  cursor: default;
}

/* ---------- Una cosa de la cuenta, en su pantalla ---------- */

.tm-cuenta-campo {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: min(460px, 100%);
  margin: 0 auto;
  padding: 10px 0 32px;
}

.tm-tg-caja {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0;
  padding: 14px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
}

.tm-tg-icono {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 13px;
  display: grid;
  place-items: center;
  background: #229ED9;
  color: #fff;
}

.tm-tg-icono svg { width: 24px; height: 24px; }

.tm-tg-texto { display: flex; flex-direction: column; min-width: 0; }
.tm-tg-texto b { font-weight: 600; }
.tm-tg-texto span { font-size: 13px; color: var(--tinta-suave); }

/* La clave se copia a mano en otra aplicación: grande, monoespaciada y muy
   separada, para no confundir un carácter con otro. */
.tm-tg-clave {
  margin-bottom: 16px;
  padding: 18px;
  border: 1px dashed var(--marca);
  border-radius: 16px;
  background: var(--papel-hondo);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}

.tm-tg-clave b {
  font-family: var(--fuente-mono);
  font-size: 34px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  color: var(--marca);
  line-height: 1.15;
}

.tm-tg-clave-rotulo { font-size: 13.5px; color: var(--tinta-suave); line-height: 1.4; }
.tm-tg-clave-pie { font-size: 12px; color: var(--tinta-tenue); }

/* ---------- El pedido, como lo pidió el dueño ----------

   Es la pantalla que ve el cliente al terminar de pedir y cada vez que quiere
   saber cómo va. Va en claro aunque la referencia que él enseñó estuviera en
   oscuro: la tienda es clara, y el sistema decide el tema por el aparato de
   quien mira. */

.tm-listo {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
}

/* ---------- La celebración del «Gracias» ----------

   Diseñada en LottieFiles Creator con el dueño y copiada aquí en SVG + CSS
   con los mismos tiempos (ver _celebracion() en pedidos.js). El lienzo es
   de 512 y el círculo de 220: a 200 pixeles el círculo mide unos 86, como
   la palomita de antes, y el confeti vuela alrededor. Los márgenes
   negativos quitan el aire del lienzo que solo usa el confeti. */
.tm-fiesta {
  width: 200px;
  height: 200px;
  margin: -34px 0 -38px;
  overflow: visible;
}

.tm-fiesta * {
  transform-box: fill-box;
  transform-origin: center;
}

.tm-fiesta-circulo {
  fill: var(--ok);
  animation: tm-fiesta-circulo 600ms both;
}

@keyframes tm-fiesta-circulo {
  0%   { scale: 0; animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
  67%  { scale: 1.1; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
  100% { scale: 1; }
}

/* La palomita se traza: con pathLength="1", el trazo completo mide 1. */
.tm-fiesta-palomita {
  stroke: #ffffff;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: tm-fiesta-trazo 533ms cubic-bezier(0.42, 0, 0.58, 1) 467ms forwards;
}

@keyframes tm-fiesta-trazo {
  to { stroke-dashoffset: 0; }
}

.tm-fiesta-onda {
  stroke: var(--ok);
  opacity: 0;
  /* `forwards` y no `both`: con `both` se veía la onda desde el primer
     instante, antes de que existiera el círculo del que sale. */
  animation: tm-fiesta-onda 867ms cubic-bezier(0.22, 1, 0.36, 1) 400ms forwards;
}

@keyframes tm-fiesta-onda {
  from { opacity: 0.7; scale: 1; }
  to   { opacity: 0; scale: 1.65; }
}

/* El confeti sale disparado y se encoge hasta desaparecer. Dos
   animaciones separadas —el viaje y el tamaño— porque cada una lleva su
   propia curva, como en Creator. */
.tm-fiesta-confeti {
  translate: var(--desde);
  scale: 0;
  animation:
    tm-fiesta-viaje 867ms cubic-bezier(0.22, 1, 0.36, 1) calc(467ms + var(--tarde)) forwards,
    tm-fiesta-chispa 1000ms calc(467ms + var(--tarde)) forwards;
}

.tm-fiesta-confeti--a { fill: var(--marca); }
.tm-fiesta-confeti--b { fill: var(--amarillo); }

@keyframes tm-fiesta-viaje {
  from { translate: var(--desde); }
  to   { translate: var(--hasta); }
}

@keyframes tm-fiesta-chispa {
  0%   { scale: 0; animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
  17%  { scale: 1.1; animation-timing-function: cubic-bezier(0.42, 0, 1, 1); }
  100% { scale: 0; }
}

/* Sin movimiento: el círculo y la palomita ya puestos, sin fiesta. */
@media (prefers-reduced-motion: reduce) {
  .tm-fiesta-circulo,
  .tm-fiesta-palomita,
  .tm-fiesta-onda,
  .tm-fiesta-confeti {
    animation: none;
  }

  .tm-fiesta-palomita { stroke-dashoffset: 0; }
}

.tm-listo-titulo {
  margin: 0;
  font-size: 23px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.tm-listo-folio {
  margin: 0;
  font-size: 16px;
  color: var(--tinta-suave);
}

.tm-listo-folio b {
  color: var(--tinta);
  font-family: var(--fuente-mono);
  font-variant-numeric: tabular-nums;
}

/* La cuenta regresiva. El enlace de irse va al lado a propósito: esperar los
   segundos por no tener salida es lo que se quiso quitar, no obligar a
   esperarlos. */
.tm-listo-cuenta {
  margin: 14px 0 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--papel-hondo);
  font-size: 14px;
  color: var(--tinta-suave);
}

.tm-listo-cuenta b {
  display: inline-grid;
  place-items: center;
  min-width: 30px;
  height: 30px;
  padding: 0 7px;
  margin-left: 6px;
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.tm-listo-cuenta a {
  color: var(--marca);
  font-weight: 600;
  text-decoration: none;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.tm-listo-cuenta a:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 3px;
  border-radius: 8px;
}

/* ---------- Mis pedidos, rediseñado (2026-09-30) ----------

   Lo aprobó el dueño en maqueta: «no me gusta como tal el acabado, se ve
   sencillo». Lo que va en curso va en grande, con un dibujo animado por
   etapa (escenas_pedido.js); su detalle es un ticket de papel con el borde
   en zigzag; lo que ya terminó, en renglones que se abren al tocarlos. */

.tm-pedidos-rotulo {
  margin: 6px 2px 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-curso {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
  overflow: hidden;
}

.tm-curso > .tm-pago-falta,
.tm-curso > .tm-pago-revisando,
.tm-curso > .tm-pago-listo,
.tm-curso > .tm-pago-espera {
  margin: 12px 12px 0;
}

.tm-curso-cabeza {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 16px 4px;
}

.tm-curso-folio {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-curso-titulo {
  margin: 0;
  font-size: 23px;
  line-height: 1.2;
  text-wrap: balance;
}

.tm-curso-nota {
  margin: 0;
  font-size: 14.5px;
  color: var(--tinta-suave);
}

.tm-escena {
  --tm-esc-cuadra: color-mix(in srgb, var(--tinta) 7%, var(--papel-alto));
  height: 150px;
  margin: 10px 12px 0;
  border-radius: 18px;
  overflow: hidden;
  background: color-mix(in srgb, var(--marca) 7%, var(--papel-alto));
}

.tm-escena svg {
  display: block;
  width: 100%;
  height: 100%;
}

.tm-escena * {
  transform-box: fill-box;
}

.tm-curso .tm-pasos {
  margin: 0;
  padding: 16px 14px 14px;
}

.tm-recibo {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 12px 20px;
  padding: 14px 14px 10px;
  border-radius: 14px 14px 0 0;
  background: var(--papel);
  font-size: 14px;
}

/* El corte de la impresora: un zigzag del mismo papel, colgando. */
.tm-recibo::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -10px;
  height: 10px;
  background:
    linear-gradient(-45deg, transparent 7px, var(--papel) 0) 0 0 / 14px 10px repeat-x,
    linear-gradient(45deg, transparent 7px, var(--papel) 0) 0 0 / 14px 10px repeat-x;
}

.tm-recibo-renglon {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.tm-recibo-renglon > span:last-child {
  flex: none;
  font-variant-numeric: tabular-nums;
}

.tm-recibo-suave { color: var(--tinta-suave); }
.tm-recibo-ahorro > span:last-child { color: var(--ok); }

.tm-recibo-raya {
  margin: 2px 0;
  border: 0;
  border-top: 1.5px dashed var(--linea);
}

.tm-recibo-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.tm-recibo-total span { font-weight: 700; }

/* Letra de máquina para el total: es lo que se lee en un ticket. */
.tm-recibo-total strong {
  font: 600 22px "IBM Plex Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}

.tm-recibo-dato {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13.5px;
  color: var(--tinta-suave);
}

.tm-recibo-dato svg {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--marca);
}

.tm-recibo-dato b {
  color: var(--tinta);
  font-weight: 600;
}

.tm-curso-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 12px 14px;
}

.tm-curso-boton {
  flex: 1 1 140px;
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 12px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel);
  color: var(--tinta);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.tm-curso-boton svg {
  width: 18px;
  height: 18px;
}

.tm-curso-boton--peligro { color: var(--peligro); }

.tm-curso-boton:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

/* Los que ya terminaron. */
.tm-anteriores {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-viejo {
  border: 1px solid var(--linea);
  border-radius: 18px;
  background: var(--papel-alto);
  overflow: hidden;
}

.tm-viejo summary {
  min-height: 64px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  list-style: none;
  cursor: pointer;
}

.tm-viejo summary::-webkit-details-marker { display: none; }

.tm-viejo summary:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: -2px;
  border-radius: 18px;
}

.tm-viejo[open] summary {
  border-bottom: 1px dashed var(--linea);
  margin-bottom: 12px;
}

.tm-viejo-icono {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 12px;
}

.tm-viejo-icono svg {
  width: 20px;
  height: 20px;
}

.tm-viejo--entregado .tm-viejo-icono { background: var(--ok-fondo); color: var(--ok); }
.tm-viejo--cancelado .tm-viejo-icono { background: var(--peligro-fondo); color: var(--peligro); }

.tm-viejo-que {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.tm-viejo-que b { font-size: 15px; }

.tm-viejo-que span {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 12.5px;
  color: var(--tinta-suave);
}

.tm-viejo-cuanto {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}

.tm-viejo-cuanto strong {
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

.tm-viejo-cuanto small {
  font-size: 12px;
  font-weight: 700;
}

.tm-viejo--entregado .tm-viejo-cuanto small { color: var(--ok); }
.tm-viejo--cancelado .tm-viejo-cuanto small { color: var(--peligro); }

.tm-viejo > .tm-pago-falta,
.tm-viejo > .tm-pago-revisando,
.tm-viejo > .tm-pago-espera {
  margin: 0 12px 12px;
}

.tm-viejo-motivo {
  margin: 0 12px 12px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--peligro-fondo);
  color: var(--peligro);
  font-size: 13.5px;
  font-weight: 600;
}

.tm-viejo-reportar {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 0 14px 6px;
  color: var(--tinta-suave);
}

/* Las escenas (escenas_pedido.js). */
.tm-esc-borde { stroke: color-mix(in srgb, var(--tinta) 18%, transparent); }

.tm-esc-ticket { animation: tm-esc-ticket 4s cubic-bezier(0.22, 1, 0.36, 1) infinite; }
@keyframes tm-esc-ticket {
  0% { translate: 0 64px; }
  35%, 100% { translate: 0 0; }
}

.tm-esc-sello {
  transform-origin: center;
  animation: tm-esc-sello 4s ease-out infinite;
}
@keyframes tm-esc-sello {
  0%, 38% { opacity: 0; scale: 1.8; }
  46% { opacity: 1; scale: 0.9; }
  52%, 92% { opacity: 1; scale: 1; }
  100% { opacity: 0; scale: 1; }
}

.tm-esc-cae { animation: tm-esc-cae 3.6s ease-in var(--t) infinite; }
@keyframes tm-esc-cae {
  0% { translate: 0 -90px; opacity: 0; }
  8% { opacity: 1; }
  22% { translate: 0 0; opacity: 1; }
  26%, 100% { translate: 0 0; opacity: 0; }
}

.tm-esc-bolsa {
  transform-origin: 50% 100%;
  animation: tm-esc-bolsa 3.6s linear infinite;
}
@keyframes tm-esc-bolsa {
  0%, 21%, 29%, 45%, 53%, 69%, 77%, 100% { scale: 1 1; }
  24%, 48%, 72% { scale: 1.05 0.95; }
}

.tm-esc-aro {
  transform-origin: center;
  animation: tm-esc-aro 1.8s ease-out infinite;
}
@keyframes tm-esc-aro {
  0% { opacity: 0.7; scale: 0.6; }
  100% { opacity: 0; scale: 1.6; }
}

.tm-esc-brinca {
  transform-origin: 50% 100%;
  animation: tm-esc-brinca 1.6s ease-in-out infinite;
}
@keyframes tm-esc-brinca {
  0%, 60%, 100% { translate: 0 0; }
  30% { translate: 0 -8px; }
}

.tm-esc-etiqueta {
  transform-box: view-box;
  transform-origin: 206px 52px;
  animation: tm-esc-mece 2.4s ease-in-out infinite alternate;
}
@keyframes tm-esc-mece {
  from { rotate: -10deg; }
  to { rotate: 10deg; }
}

.tm-esc-palomita {
  transform-origin: center;
  animation: tm-esc-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.4s both;
}
@keyframes tm-esc-pop {
  from { scale: 0; }
}

.tm-esc-confeti { animation: tm-esc-confeti 1.1s ease-out 0.6s both; }
@keyframes tm-esc-confeti {
  from { opacity: 1; translate: 0 0; }
  to { opacity: 0; translate: var(--x) var(--y); }
}

/* Quien pidió menos movimiento ve cada escena ya acomodada y quieta. */
@media (prefers-reduced-motion: reduce) {
  .tm-escena *,
  .tm-escena *::before {
    animation: none !important;
  }

  .tm-esc-cae,
  .tm-esc-confeti { opacity: 0; }
  .tm-esc-cae:first-of-type { opacity: 1; }
}

/* ---------- Los pasos ---------- */

.tm-pasos {
  list-style: none;
  margin: 16px 0 4px;
  padding: 0;
  width: 100%;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}

.tm-paso {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  position: relative;
  font-size: 12px;
  color: var(--tinta-tenue);
  text-align: center;
}

/* La línea que une un paso con el siguiente. Se dibuja hacia atrás desde cada
   punto para que el primero no arrastre una línea que sale de la nada. */
.tm-paso + .tm-paso::before {
  content: "";
  position: absolute;
  top: 18px;
  right: 50%;
  left: -50%;
  height: 4px;
  border-radius: 2px;
  background: var(--papel-hondo);
}

/* La raya verde va ENCIMA de la gris y se llena de izquierda a derecha, un
   paso tras otro: el pedido «avanza» cada vez que se abre la pantalla o cambia
   de estado. Es la animación 2 de la lista del dueño. */
.tm-paso + .tm-paso::after {
  content: "";
  position: absolute;
  top: 18px;
  right: 50%;
  left: -50%;
  height: 4px;
  border-radius: 2px;
  background: var(--marca);
  transform-origin: left center;
  scale: 0 1;
}

/* Con el mismo `.tm-paso + ` de arriba: con menos peso, el `scale: 0 1` de
   la raya vacía le ganaba y la verde nunca se llenaba. */
.tm-paso + .tm-paso--hecho::after,
.tm-paso + .tm-paso--ahora::after {
  scale: 1 1;
  animation: tm-paso-llena 320ms ease-out calc((var(--i) - 1) * 260ms) both;
}

@keyframes tm-paso-llena {
  from { scale: 0 1; }
}

/* Con su dibujito adentro desde el rediseño del 2026-09-30: ticket,
   bolsa, ruta o tienda, y la casa. */
.tm-paso-punto {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--tinta-tenue);
  background: var(--papel-hondo);
  box-shadow: 0 0 0 3px var(--papel-alto);
  position: relative;
  z-index: 1;
}

.tm-paso-punto svg {
  width: 20px;
  height: 20px;
}

.tm-paso--hecho .tm-paso-punto { background: var(--marca); color: #ffffff; }

/* El paso de ahora se ve distinto de los ya pasados: verde es «ya fue», y lo
   que está ocurriendo necesita su propio color o el cliente no sabe dónde
   está parado. */
.tm-paso--ahora .tm-paso-punto {
  background: var(--marca);
  color: #ffffff;
}

.tm-paso--ahora .tm-paso-nombre {
  color: var(--tinta);
  font-weight: 600;
}

/* Cada punto se enciende cuando la raya llega a él. */
.tm-paso--hecho .tm-paso-punto,
.tm-paso--ahora .tm-paso-punto {
  animation: tm-paso-enciende 300ms cubic-bezier(0.34, 1.56, 0.64, 1) calc(var(--i) * 260ms) both;
}

@keyframes tm-paso-enciende {
  from { background: var(--papel-hondo); scale: 0.6; }
}

/* Y el de ahora late con un anillo suave: «aquí vamos». */
.tm-paso--ahora .tm-paso-punto::after {
  content: "";
  position: absolute;
  inset: -4px;
  border: 2px solid var(--marca);
  border-radius: 50%;
  opacity: 0;
  animation: tm-paso-late 1.8s ease-out calc(var(--i) * 260ms + 300ms) infinite;
}

@keyframes tm-paso-late {
  0%   { opacity: 0.7; scale: 0.7; }
  100% { opacity: 0; scale: 1.9; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-paso::after,
  .tm-paso-punto,
  .tm-paso-punto::after {
    animation: none !important;
  }
}

.tm-paso--hecho .tm-paso-nombre { color: var(--tinta-suave); }

/* ============================================================
   La puerta del cliente
   ============================================================

   Calcada de la referencia que pasó el dueño: tarjeta blanca sola,
   título grande y centrado, campos de pastilla, enlace chico a la
   derecha, botón de ancho completo, y debajo un renglón de texto más
   dos botones secundarios.

   Lo que cambia respecto del original, y por qué:

   - «Regístrate» no existe: en este sistema nadie se da de alta solo,
     el dueño da de alta al cliente y le entrega una clave. Ese renglón
     lo ocupa la verdad —«¿Primera vez? Pide tu clave en la tienda»—.

   - Los dos botones de Apple y Google tampoco: no hay OAuth y cargarlos
     pediría recursos de internet, que están prohibidos porque la tienda
     debe servir sin él. Sus lugares se los quedan las DOS maneras reales
     de entrar aquí: con la clave de cuatro dígitos, y ver el catálogo sin
     cuenta. Se respeta el ritmo del diseño —uno de color, uno oscuro, uno
     de contorno— con acciones que sí llevan a algún lado.

   - El color no es el verde azulado del original sino el rojo de la
     tienda, que es el de acción aquí (CLAUDE.md §11).
*/

/* Sin esto, esconder el buscador no lo escondía: `.tm-store-buscador` trae
   `display: flex`, y una regla de hoja de estilos le gana al `hidden` que el
   navegador trae de fábrica. Es el error clásico de esconder con `hidden` un
   elemento al que ya se le declaró un `display`. */
.tm-store-buscador[hidden] { display: none; }

.tm-puerta {
  display: flex;
  justify-content: center;
  padding: 22px 16px 28px;
}

.tm-puerta-tarjeta {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  padding: 26px 24px 24px;
  border-radius: 18px;
  background: var(--papel-alto);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.14);
}

/* El sello de la tienda: la bolsa de mandado con su candado. Es lo primero
   que se ve y dice de qué va esto sin una palabra. */
.tm-puerta-sello {
  width: 54px;
  height: 54px;
  margin: 2px auto 14px;
  display: grid;
  place-items: center;
  border-radius: 18px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  box-shadow: 0 6px 16px rgba(214, 32, 32, 0.28);
}

.tm-puerta-sello svg { width: 28px; height: 28px; }

.tm-puerta-titulo {
  margin: 0 0 2px;
  font-family: var(--fuente-titulo);
  text-align: center;
  /* Se encoge en pantalla angosta antes que partirse en dos renglones,
     que movería todo lo de abajo al cambiar de manera de entrar. */
  font-size: clamp(23px, 6.4vw, 28px);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
  white-space: nowrap;
}

/* El renglón que dice para qué sirve esta pantalla. Va en Sans, no en la
   serif: la serif es para el saludo, no para las instrucciones. */
.tm-puerta-lema {
  margin: 0 0 20px;
  text-align: center;
  font-size: 13px;
  color: var(--tinta-suave);
}

/* Soy nuevo / Ya tengo cuenta.
   Es lo primero que se decide, así que va arriba de todo y no escondido en un
   renglón al pie. «Soy nuevo» viene elegido de fábrica: al abrir la tienda al
   público, la mayoría de quien llegue no está en la base todavía. */
.tm-puerta-cambio {
  display: flex;
  gap: 4px;
  margin-bottom: 18px;
  padding: 4px;
  border-radius: 999px;
  background: var(--papel-hondo);
}

.tm-puerta-cambio button {
  flex: 1;
  min-height: 42px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--tinta-suave);
  cursor: pointer;
}

/* La activa va en el color de la marca rebajado, no en blanco.
   En blanco sobre gris claro la diferencia era tan poca que había que fijarse
   para saber en cuál se está —lo reportó el dueño—. Sale de `--marca` y no
   de un rojo escrito a mano: con el rojo fijo, en el tema oscuro quedaba un
   borde rojo alrededor de letra morada. */
.tm-puerta-cambio button[aria-selected="true"] {
  background: color-mix(in srgb, var(--marca) 12%, transparent);
  color: var(--marca-hondo);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--marca) 35%, transparent);
}

.tm-puerta-cambio button:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 1px;
}

/* La clave de invitación son seis caracteres y se dictan por teléfono, así
   que se enseñan separados y en mono: sin eso, distinguir una S de un 5 al
   copiarla es adivinar. */
.tm-puerta-invitacion {
  font-family: var(--fuente-mono, monospace);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-align: center;
  text-transform: uppercase;
}

.tm-puerta-forma {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tm-puerta-campo {
  width: 100%;
  /* Alto EXACTO, no mínimo: la letra mono de los cuatro dígitos es más alta
     que la de la contraseña y estiraba el campo cuatro píxeles. Poca cosa,
     salvo que es justo el defecto que se venía a corregir. */
  height: 52px;
  /* 52 y no los 40 del original: se usa con prisa y desde el celular. */
  min-height: 52px;
  padding: 12px 20px;
  border: 1px solid var(--tinta-tenue);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
}

.tm-puerta-campo::placeholder { color: var(--tinta-tenue); }

.tm-puerta-campo:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 1px;
  border-color: var(--marca);
}

/* El renglón de «¿Olvidaste tu contraseña?». Ocupa su sitio en las dos
   maneras de entrar —cambia el texto, nunca la altura— para que el botón
   no se mueva de donde el dedo ya lo esperaba. */
.tm-puerta-olvido {
  margin: -4px 0 0;
  text-align: right;
  min-height: 20px;
}

.tm-puerta-olvido button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--tinta-suave);
  text-decoration: underline;
  cursor: pointer;
}

.tm-puerta-olvido button:hover,
.tm-puerta-olvido button:focus-visible { color: var(--tinta); }

.tm-puerta-entrar {
  width: 100%;
  min-height: 52px;
  margin-top: 2px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.24);
}

.tm-puerta-entrar:active { box-shadow: none; }

.tm-puerta-alta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 14px 0 0;
  text-align: center;
  font-size: 12px;
  line-height: 1.4;
  color: var(--tinta-suave);
}

.tm-puerta-alta svg {
  flex: none;
  width: 15px;
  height: 15px;
  color: var(--marca);
}

.tm-puerta-otras {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
}

.tm-puerta-otra {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 50px;
  padding: 0 16px;
  border-radius: 999px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.tm-puerta-otra svg {
  flex: none;
  width: 19px;
  height: 19px;
}

/* El oscuro, donde el original ponía el de Apple. */
.tm-puerta-otra--llave {
  border: 2px solid var(--tinta);
  background: var(--tinta);
  color: var(--papel-alto);
}

/* El de contorno, donde iba el de Google. */
.tm-puerta-otra--tienda {
  border: 2px solid var(--tinta-suave);
  background: var(--papel-alto);
  color: var(--tinta);
}

.tm-puerta-otra:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

/* Los cuatro dígitos, en el mismo hueco que la contraseña. */
.tm-puerta-campo.tm-campo-clave {
  /* La del alta y la del cliente ya capturado se ven igual: las dos son
     cuatro dígitos que alguien dicta por teléfono. */
  font-family: var(--fuente-mono, monospace);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.55em;
  text-indent: 0.55em;
  text-align: center;
  padding: 12px 14px;
}


/* ---------- La salida de las pantallas interiores ---------- */

.tm-volver-zona {
  padding: 10px 14px 0;
}

.tm-volver-zona[hidden] { display: none; }

.tm-volver {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  /* 44px de alto real aunque el texto sea chico: se toca con el pulgar y
     con prisa, como todo lo demás (CLAUDE.md §11). */
  min-height: 44px;
  padding: 0 14px 0 6px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
  color: var(--tinta-suave);
  text-decoration: none;
}

.tm-volver svg {
  width: 22px;
  height: 22px;
}

.tm-volver:hover,
.tm-volver:focus-visible {
  background: var(--papel-hondo);
  color: var(--tinta);
}




/* ---------- El hueco de un producto sin foto ----------

   Cálido pero callado, al revés que los círculos de departamento. Son
   setecientos cuarenta y nueve productos sin foto: si cada uno gritara color
   le ganarían la pantalla a los quinientos que sí tienen la suya, que son los
   que de verdad venden. Basta con que no parezca una imagen rota. */
/* La forma y el tamaño de este hueco viven en core/tarjeta_producto.css, que
   cargan los cuatro clientes. Aquí queda solo lo que de verdad es de la
   tienda: el degradado tibio, que en el POS sería ruido. */
.store-product-image--vacia {
  background: linear-gradient(160deg, #FBF3E4, var(--papel-hondo));
}


/* La nota del carrito de quien todavía no ha entrado. Va en el lugar del
   total, porque es la respuesta a la pregunta que uno trae al abrirlo. */
.tm-carrito-nota--registro {
  margin-bottom: 12px;
  line-height: 1.5;
  color: var(--tinta-suave);
}


/* El precio de lista del envío, tachado junto al que se paga.
   Gris y más chico: es la referencia, no la cifra que importa. La que se
   cobra tiene que seguir siendo la que salta a la vista. */
.tm-envio-antes {
  color: var(--tinta-tenue);
  font-size: 0.85em;
  text-decoration-thickness: 1.5px;
  margin-right: 4px;
}

.tm-checkout-nota--ahorro {
  color: var(--ok);
  font-weight: 600;
}


/* ---------- Tocar el producto para verlo con calma ----------
 *
 * El enlace envuelve la foto y el nombre, no la tarjeta entera: el botón de
 * agregar vive dentro y un enlace alrededor de todo se lo tragaría. Hereda
 * el color para que nada cambie de aspecto por volverse enlace.
 */
.store-product-vinculo,
.tm-fila-producto-vinculo {
  display: block;
  color: inherit;
  text-decoration: none;
  border-radius: 12px;
}

.tm-fila-producto-vinculo {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1 1 auto;
  min-width: 0;
}

.store-product-vinculo:focus-visible,
.tm-fila-producto-vinculo:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

/* ---------- La ficha del producto ---------- */

/* El pasillo es un atajo, no un segundo botón de atrás: el cascarón ya trae
   «Seguir comprando» arriba, y dos flechas seguidas confunden cuál regresa. */
.tm-ficha-etiqueta--pasillo {
  background: #F4E4E4;
  color: var(--marca-hondo);
  text-decoration: none;
}

.tm-ficha {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: 22px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
}

/* La foto grande es el motivo de esta pantalla: quien la abre lo hace para
   verla bien. Cuadrada y con la imagen entera dentro —`contain` y no
   `cover`— porque aquí sí importa que no se le corte la etiqueta. */
.tm-ficha-foto {
  position: relative;
  aspect-ratio: 1;
  /* En el teléfono la foto cuadrada se comería la pantalla entera y habría
     que bajar para ver el precio. Se le pone tope para que el nombre, el
     precio y el botón queden a la vista sin desplazar. */
  max-height: 46vh;
  border-radius: 18px;
  background: var(--papel-hondo);
  /* Cuando se llega tocando la tarjeta, su foto chica queda de fondo
     mientras baja la grande (producto.js): mismo encuadre que la imagen. */
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.tm-ficha-foto img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.tm-ficha-foto--vacia span {
  color: var(--tinta-tenue);
  font-size: 13px;
}

.tm-ficha-promo {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}

.tm-ficha-datos {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.tm-ficha-marca {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

/* Sin recorte de líneas, que es justo el motivo de esta pantalla. */
.tm-ficha-nombre {
  margin: 0;
  font-size: 22px;
  line-height: 1.25;
  font-weight: 700;
  text-wrap: balance;
}

.tm-ficha-precio {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.tm-ficha-precio strong {
  font-size: 28px;
  font-weight: 700;
  color: var(--marca);
  font-variant-numeric: tabular-nums;
}

.tm-ficha-unidad {
  font-size: 14px;
  color: var(--tinta-suave);
}

.tm-ficha-sin-precio {
  color: var(--marca);
  font-size: 15px;
  font-weight: 700;
}

.tm-ficha-descripcion {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--tinta-suave);
  max-width: 62ch;
}

.tm-ficha-descripcion--falta {
  color: var(--tinta-tenue);
  font-style: italic;
}

.tm-ficha-etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tm-ficha-etiqueta {
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 12px;
  font-weight: 600;
}

.tm-ficha-etiqueta--adultos {
  background: #F4E4E4;
  color: var(--peligro);
}

.tm-ficha-etiqueta--agotado {
  background: #F4E4E4;
  color: var(--peligro);
}

.tm-ficha-accion {
  margin-top: 4px;
}

.tm-ficha-agregar {
  width: 100%;
  min-height: 52px;
  justify-content: center;
  font-size: 16px;
}

.tm-ficha-cantidad {
  width: 100%;
  min-height: 56px;
}

/* El − y el + de la ficha, grandes: se tocan con prisa y con el pulgar. */
.tm-ficha-cantidad .store-qty-btn {
  min-width: 56px;
  min-height: 56px;
  font-size: 24px;
}

.tm-ficha-cantidad .store-qty-value {
  font-family: var(--fuente-mono, monospace);
  font-size: 20px;
  font-weight: 600;
}

/* «Ya está en tu carrito», en verde, encima del − y el +. */
.tm-ficha-ya {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 14px;
  background: var(--ok-fondo, #e4f5e8);
  color: var(--ok);
  font-size: 14px;
  font-weight: 700;
  animation: tm-ficha-ya-entra 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.tm-ficha-ya svg {
  width: 22px;
  height: 22px;
  flex: none;
}

@keyframes tm-ficha-ya-entra {
  from { translate: 0 8px; opacity: 0; }
}

/* A granel la cantidad es un botón: tocarla abre «¿Cuánto quieres?». */
.tm-ficha-granel,
.tm-carrito-granel {
  border: none;
  background: none;
  color: inherit;
  cursor: pointer;
  text-decoration: underline dotted var(--tinta-tenue);
  text-underline-offset: 4px;
  white-space: nowrap;
}

.tm-carrito-cantidad .tm-carrito-granel {
  width: auto;
  min-width: 52px;
  padding: 0 4px;
  background: none;
  font-size: 13.5px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* La ventanita de granel vive en core/componentes.css; en la tienda su
   acento es el de marca. */
.tm-granel {
  --granel-acento: var(--marca);
}

@media (prefers-reduced-motion: reduce) {
  .tm-ficha-ya {
    animation: none;
  }
}

.tm-ficha-agotado {
  margin: 0;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 14px;
}

.tm-ficha-vacia {
  align-items: flex-start;
  gap: 10px;
}

@media (min-width: 768px) {
  /* En pantalla ancha la foto y los datos se ponen lado a lado: apilados
     obligarían a bajar para leer la descripción, que es a lo que se vino. */
  .tm-ficha {
    display: grid;
    grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
    align-items: start;
    gap: 28px;
    padding: 24px;
  }

  /* Con la foto al lado ya no compite con el texto por el alto. */
  .tm-ficha-foto {
    max-height: none;
  }

  .tm-ficha-agregar,
  .tm-ficha-cantidad {
    width: auto;
    min-width: 220px;
  }
}


/* ---------- La bienvenida ----------
 *
 * Un cuadro al centro, con letra de libro y casi sin color. La primera
 * versión era una banda roja arriba y el dueño la devolvió: «con letra
 * elegante y sin tantos colores». Tiene razón — una bienvenida que grita no
 * da la bienvenida.
 *
 * Ocupa el hueco de la primera carga, que existe y no se puede fingir que
 * no: cientos de productos por un túnel y con datos móviles. Lo que se puede
 * es que ese hueco diga algo.
 */
.tm-bienvenida {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* Un velo del color del papel, no un negro de modal: no está
     interrumpiendo nada, está esperando con uno. Sale del tema: blanco fijo
     se veía como un foco prendido en la tienda oscura. */
  background: color-mix(in srgb, var(--papel) 94%, transparent);
  backdrop-filter: blur(2px);
  animation: tm-bienvenida-entra 200ms ease-out;
}

.tm-bienvenida-cuadro {
  max-width: 360px;
  width: 100%;
  padding: 30px 24px 26px;
  border-radius: 28px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.07);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: tm-bienvenida-brota 450ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* Su cara: la foto o el dibujo que escogió, o sus iniciales. El aro es del
   color de la tienda, para que se lea como «tu tarjeta de aquí». */
.tm-bienvenida-cara {
  width: 88px;
  height: 88px;
  font-size: 30px;
  border: 3px solid var(--marca);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--marca) 16%, transparent);
  animation: tm-bienvenida-brota 450ms cubic-bezier(0.34, 1.56, 0.64, 1) 120ms both;
}

/* El único otro color del cuadro, y pequeño: el corazón de la casa. Late
   dos veces cuando la frase terminó de escribirse. */
.tm-bienvenida-marca {
  display: inline-flex;
  margin-top: 12px;
  color: var(--marca);
}

.tm-bienvenida-marca svg {
  width: 26px;
  height: 26px;
}

.tm-bienvenida-marca--late {
  animation: tm-bienvenida-late 1s ease-in-out 2;
}

/* La letra de libro que el dueño pidió. Es la misma familia con serifas que
   ya usa el sistema para los títulos, así que no entra una fuente nueva que
   la Raspberry tenga que servir. */
.tm-bienvenida-hola {
  margin: 14px 0 6px;
  font-family: var(--fuente-titulo, Georgia, serif);
  font-size: 28px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--tinta);
  /* Reserva su renglón desde el principio: sin esto, el cuadro crece de
     golpe cuando la frase salta de línea a media escritura. */
  min-height: 1.2em;
}

.tm-bienvenida-nota {
  margin: 0;
  font-family: var(--fuente-titulo, Georgia, serif);
  font-size: 15px;
  font-style: italic;
  line-height: 1.4;
  color: var(--tinta-suave);
  min-height: 1.4em;
}

/* El cursor de la escritura: una raya que parpadea al final de lo escrito.
   Es lo que hace que se lea como alguien escribiendo y no como texto que
   aparece a pedazos. */
.tm-bienvenida-hola::after,
.tm-bienvenida-nota::after {
  content: "";
  display: inline-block;
  width: 1px;
  height: 1em;
  margin-left: 2px;
  vertical-align: -0.14em;
  background: currentColor;
  opacity: 0.55;
  animation: tm-bienvenida-cursor 900ms steps(2, start) infinite;
}

/* Un solo cursor: en cuanto empieza el segundo renglón, el primero ya
   terminó y su raya estorba. */
.tm-bienvenida-cuadro:has(.tm-bienvenida-nota:not(:empty)) .tm-bienvenida-hola::after {
  display: none;
}

.tm-bienvenida--yendose {
  transition: opacity 320ms ease;
  opacity: 0;
  pointer-events: none;
}

@keyframes tm-bienvenida-entra {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes tm-bienvenida-cursor {
  50% { opacity: 0; }
}

@keyframes tm-bienvenida-brota {
  from { opacity: 0; scale: 0.85; }
}

@keyframes tm-bienvenida-late {
  0%, 100% { scale: 1; }
  40% { scale: 1.3; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-bienvenida,
  .tm-bienvenida--yendose,
  .tm-bienvenida-cuadro,
  .tm-bienvenida-cara,
  .tm-bienvenida-marca--late {
    animation: none;
    transition: none;
  }

  .tm-bienvenida-hola::after,
  .tm-bienvenida-nota::after {
    animation: none;
  }
}


/* ---------- El pasillo de favoritos ----------
 *
 * Va primero en la fila de círculos, con el mismo corazón que el cliente ya
 * toca en cada producto: es la misma forma, así que no hay nada nuevo que
 * aprender. Y va donde cae el pulgar sin deslizar, que es lo que uno espera
 * de «lo mío».
 */
.tm-depto-foto--corazon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #F4E4E4;
  color: var(--marca);
}

.tm-depto-foto--corazon svg {
  width: 42%;
  height: 42%;
}

.tm-depto--favoritos.tm-depto--activo .tm-depto-nombre {
  color: var(--marca);
}

/* ---------- Dónde tengo abierta mi cuenta ----------

   La lista de aparatos del cliente. Nace de una pregunta del dueño antes de
   abrir la tienda: qué pasa si alguien le presta su cuenta a media colonia.
   Hoy son tres aparatos como tope, y aquí se ven y se cierran. */

.tm-sesiones {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 18px 0;
}

.tm-sesion {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
}

/* El aparato en el que estás, marcado. Sin esto uno duda antes de cerrar los
   otros, por miedo a cerrarse a sí mismo. */
.tm-sesion--este {
  border-color: var(--ok);
  background: #e4f5e8;
}

.tm-sesion-icono {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 13px;
  display: grid;
  place-items: center;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
}

.tm-sesion--este .tm-sesion-icono {
  background: var(--ok);
  color: #fff;
}

.tm-sesion-icono svg { width: 24px; height: 24px; }

.tm-sesion-texto { display: flex; flex-direction: column; min-width: 0; }
.tm-sesion-texto b { font-weight: 600; }
.tm-sesion-texto span { font-size: 13px; color: var(--tinta-suave); }

.tm-cuenta-nota {
  margin: 12px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

/* ---------- ¿Traes los envases? ----------

   La pregunta del envase retornable en el checkout. Va SIN respuesta puesta
   de fábrica y por eso la tarjeta sin contestar se marca: es lo único que
   detiene el pedido, y tiene que verse de un vistazo entre todo lo demás.

   El dueño lo pidió justo por esto: «mucha gente no lo va a leer hasta que
   ya lo pagó». */

.tm-envase-pregunta {
  padding: 6px;
  margin-bottom: 12px;
  border: 1px solid var(--linea);
  border-radius: 18px;
  background: var(--papel-alto);
}

.tm-envase-pregunta--sin-responder {
  border-color: var(--alerta);
  background: #fdf6ec;
}

/* ---------- La cabecera: foto, nombre y de cuánto es el depósito ----------

   La foto no es adorno. La pregunta llega después de armar el carrito, con
   el producto ya fuera de la vista, y un nombre largo de refresco a secas
   —«Coca Cola 1¼ Vidrio Retornable 1.25 L»— no dice de un vistazo cuál de
   los que lleva es. La miniatura ya viaja en el carrito; no cuesta nada. */

.tm-envase-encabezado {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 8px 12px;
}

.tm-envase-foto {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  background: var(--papel-hondo);
  overflow: hidden;
}

.tm-envase-foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.tm-envase-nombre {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.tm-envase-nombre b { font-weight: 600; line-height: 1.3; }

.tm-envase-nombre span {
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--tinta-suave);
}

/* ---------- Las opciones: una lista, no tres botones sueltos ----------

   Antes eran pastillas que se acomodaban solas y con tres opciones se
   partían en dos renglón y medio, con un hueco al lado del último. Eso se
   lee como algo que no cupo, no como algo que se diseñó.

   Puestas en columna se resuelven las dos cosas de un golpe: el ancho deja
   de pelearse con el texto —y «No traigo ninguno» cabe igual que «Traigo
   1»— y a la derecha queda un carril fijo para lo que cuesta cada opción.
   Es una elección de verdad, con su punto y su precio, no tres chips. */

.tm-envase-opciones {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  overflow: hidden;
}

/* 48 de alto para el pulgar, como todo lo que se toca (CLAUDE.md §11). */
.tm-envase-opcion {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 8px 14px;
  border: 0;
  border-bottom: 1px solid var(--linea);
  background: none;
  color: var(--tinta);
  font-size: 14.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.tm-envase-opcion:last-child { border-bottom: 0; }

.tm-envase-marca {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--tinta-tenue);
  background: var(--papel-alto);
  /* Sombra interior del color del papel: tapa el centro y deja solo el aro.
     Al elegirse se encoge y aparece el punto. */
  box-shadow: inset 0 0 0 9px var(--papel-alto);
}

.tm-envase-opcion-texto {
  flex: 1 1 auto;
  min-width: 0;
}

.tm-envase-opcion-cobro {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

/* ---------- Elegida: se enciende el punto, no el renglón ----------

   Antes la fila entera se pintaba de rojo. Una barra roja de ancho completo
   es del tamaño de una advertencia, y esto no advierte nada: nada más dice
   cuál de las dos contestó. El rojo de marca es caro y ya lo gasta el botón
   de confirmar, que sí es la acción de la pantalla.

   Así que la señal se va toda al punto —que es donde el ojo busca en
   cualquier formulario— y el renglón se distingue del resto por el peso de
   la letra: la elegida en tinta llena, las otras en gris. */

.tm-envase-opcion--puesta .tm-envase-marca {
  border-color: var(--marca);
  background: var(--marca);
  box-shadow: inset 0 0 0 3px var(--papel-alto);
}

.tm-envase-opcion--puesta .tm-envase-opcion-texto {
  color: var(--tinta);
  font-weight: 700;
}

.tm-envase-opcion:not(.tm-envase-opcion--puesta) .tm-envase-opcion-texto {
  color: var(--tinta-suave);
}

/* Un enlace DENTRO de un párrafo. `.tm-enlace-suave` no sirve aquí: está
   hecho para ir suelto en una columna —trae `align-self` y su propio tamaño
   de letra— y metido en un renglón de texto sale más chico que lo que lo
   rodea. Este hereda el tamaño de su párrafo, que es lo único que cambia. */
.tm-enlace-dentro {
  color: var(--marca);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* El parpadeo de «es esto lo que falta».
 *
 * Un globo que dice «contesta lo de los envases» y nada más deja a alguien
 * buscando cuál de tres tarjetas es. Sube a ella y se la prende un segundo
 * y medio: el tiempo justo para que el ojo la encuentre sin que se sienta
 * que la pantalla se descompuso. */
.tm-resaltado {
  animation: tm-resaltar 1.6s ease;
}

@keyframes tm-resaltar {
  0%, 100% { box-shadow: 0 0 0 0 rgba(214, 32, 32, 0); }
  15%, 65% { box-shadow: 0 0 0 4px rgba(214, 32, 32, 0.22); }
}

@media (prefers-reduced-motion: reduce) {
  .tm-resaltado { animation: none; box-shadow: 0 0 0 3px rgba(214, 32, 32, 0.28); }
}

.tm-envase-cobro {
  margin: 10px 8px 6px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-checkout-nota--falta {
  color: var(--alerta);
  font-weight: 600;
}



/* ---------- ¿Con cuánto vas a pagar? ----------

   Los montos se ven como el resto de la tienda —píldoras redondas, el elegido
   en rojo de marca— y no como cajas grises de formulario. El dueño lo cazó de
   una mirada: «no se ve que combine».

   Y lleva campo manual porque nadie paga solo con billetes redondos: él lo
   dijo con un ejemplo real, «si trae cantidades como 80». */

.tm-pagacon {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--linea);
}

.tm-pagacon-pregunta {
  margin: 0;
  font-size: 15.5px;
  font-weight: 700;
}

.tm-pagacon-ayuda {
  margin: 2px 0 12px;
  font-size: 13.5px;
  color: var(--tinta-suave);
}

.tm-pagacon-montos {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Píldoras, como los chips de categoría del catálogo. 44 de alto para el
   pulgar, igual que todo lo que se toca (CLAUDE.md §11). */
.tm-pagacon-monto {
  min-height: 44px;
  padding: 0 18px;
  border-radius: 999px;
  border: 2px solid var(--linea);
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.tm-pagacon-monto--puesta {
  border-color: var(--marca);
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
}

.tm-pagacon-monto:focus-visible,
.tm-pagacon-otro:focus-within {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* El campo manual va en la misma fila y con la misma forma que los botones:
   es una opción más, no un formulario aparte. */
.tm-pagacon-otro {
  display: flex;
  align-items: center;
  gap: 2px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 999px;
  border: 2px dashed var(--tinta-tenue);
  background: var(--papel-alto);
  cursor: text;
}

.tm-pagacon-otro--puesta {
  border-style: solid;
  border-color: var(--marca);
  background: #fdf3f3;
}

.tm-pagacon-otro span {
  font-size: 15px;
  font-weight: 700;
  color: var(--tinta-suave);
}

.tm-pagacon-otro--puesta span { color: var(--marca); }

.tm-pagacon-otro input {
  width: 112px;
  border: 0;
  background: none;
  padding: 0 2px;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--tinta);
}

.tm-pagacon-otro input:focus { outline: none; }

/* Se le quitan las flechitas de número: aquí estorban y se tocan sin querer. */
.tm-pagacon-otro input::-webkit-outer-spin-button,
.tm-pagacon-otro input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.tm-pagacon-otro input[type="number"] { -moz-appearance: textfield; }

.tm-pagacon-cambio {
  margin: 12px 0 0;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ok);
  min-height: 1.2em;
}


/* ---------- Te puede interesar ----------

   Los vecinos de pasillo de lo que se buscó. La separación es de verdad —una
   raya de lado a lado con la pastilla encima— y eso no es adorno: esto NO es
   lo que la persona pidió. Mezclarlo con los resultados convertiría una
   búsqueda en una sugerencia disfrazada, y a la segunda vez ya no se le cree
   a la búsqueda. */

.tm-sugerencias {
  margin-top: 26px;
}

/* La raya pasa por detrás y la pastilla la interrumpe: es el gesto que dice
   «hasta aquí lo tuyo» sin escribirlo. */
.tm-sugerencias-raya {
  position: relative;
  display: flex;
  justify-content: center;
  margin-bottom: 16px;
}

.tm-sugerencias-raya::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  border-top: 1px solid var(--linea);
}

.tm-sugerencias-chip {
  position: relative;
  padding: 8px 18px;
  border-radius: 999px;
  background: var(--amarillo);
  color: var(--tinta);
  font-size: 13.5px;
  font-weight: 800;
}

/* ==========================================================================
   TEMA OSCURO DE LA TIENDA
   ==========================================================================

   Solo la tienda. El POS y la Trastienda siguen con un único tema claro
   (CLAUDE.md §11); el dueño abrió la excepción para la tienda el 2026-09-17,
   con un motivo que no es de gusto:

   Sus clientes entran con Samsung Internet, que trae el oscurecido forzado
   prendido de fábrica y **no respeta** la petición de quedarse claro. Una
   captura de un cliente lo enseñó: el logo quedó café sobre café, el aviso
   de registro rojo sobre rojo y los verdes ilegibles. Lo que Samsung sí
   respeta —y Chrome también— es un sitio que trae SU PROPIO tema oscuro:
   entonces lo usa en vez de inventar uno invirtiendo colores.

   Así que esto no es un adorno: es la única manera de que el cliente que
   trae el teléfono en oscuro vea algo hecho a propósito.

   **Morado y no rojo**, elegido por el dueño viendo las dos maquetas. El
   rojo de marca sobre negro se vuelve pesado y en un teléfono en penumbra
   cansa; el morado deja respirar al amarillo del logo, que es lo que se
   reconoce. El rojo sigue mandando en el tema claro, que es el de siempre.

   **Las fotos se quedan sobre blanco.** Vienen con fondo blanco de fábrica:
   sobre oscuro, una placa blanca redonda se lee como algo hecho a
   propósito, y sin ella quedarían recortes flotando con un halo gris. */

/* El tema oscuro cuelga de un atributo y NO del «prefers-color-scheme»
   directo. Así el cliente puede elegir claro u oscuro desde el menú y su
   decisión manda sobre la del teléfono; quien no elige nada se queda en
   «automático», que es el script del cascarón leyendo esa misma preferencia
   del sistema antes de pintar. Un solo bloque de colores, no dos copias que
   se despeguen con el tiempo. */
:root[data-tema-tienda="oscuro"] {
  /* **«dark», no «light dark».** Ahí estaba el bug que el dueño siguió
     viendo: «en Samsung browser sigue invirtiendo colores sin importar que
     tengamos tema oscuro».

     «light dark» significa «sé pintarme de los dos modos» y deja que el
     navegador elija según el teléfono. Pero aquí el tema NO lo elige el
     teléfono: lo elige el cliente desde el menú. Así que con el teléfono en
     claro y la tienda puesta en oscuro a mano, el navegador creía estar
     mirando una página clara —y Samsung, que oscurece por su cuenta lo que
     cree claro, le pasaba su propio filtro encima a unos colores que ya
     eran oscuros. De ahí los colores invertidos.

     Diciendo que esta página YA es oscura, el navegador deja de creer que
     tiene que oscurecerla él. Y va con «only» —la misma palabra que usa el
     tema claro— porque es la que el navegador entiende como «no me apliques
     tu esquema, ya tengo el mío»: a Samsung las señales suaves ya se le
     vieron ignorar una vez.

     Va aquí y no en tokens.css porque tokens lo cargan también el POS y la
     Trastienda, que se quedan en «only light». */
  color-scheme: only dark;

  --papel: #131320;
  --papel-alto: #1d1c2e;
  --papel-hondo: #252437;
  --tinta: #f2f2f7;
  --tinta-suave: #a9a7bd;
  --tinta-tenue: #7d7b92;
  --linea: rgba(255, 255, 255, 0.09);
  --hueso: #262538;
  --hueso-brillo: rgba(255, 255, 255, 0.07);

  /* La identidad de la tienda en oscuro. El degradado se conserva: es el
     mismo gesto del diseño heredado, solo que en morado. */
  --marca: #8b5cf6;
  --marca-hondo: #6d35e0;

  /* Los de estado se aclaran: los del tema claro están hechos para leerse
     sobre papel y sobre negro se apagan. El fondo, al revés: tiene que ser
     oscuro y del mismo tono, no el pastel de siempre. */
  --ok: #5fd28e;
  --ok-fondo: #14311f;
  --alerta: #e8a95a;
  --peligro: #f08a8a;
  --peligro-fondo: #351c1c;
  --alerta-fondo: #33260f;

  /* El azul de acción del sistema, en oscuro, era azul marino sobre casi
     negro: la pastilla de «Nuevo» de un pedido no se leía. En la tienda
     oscura lo que actúa es morado, igual que la marca. */
  --accion: #a78bfa;
  --accion-tenue: rgba(139, 92, 246, 0.18);

  /* El amarillo del logo sube un punto: sobre morado oscuro el original
     se veía mostaza. El naranja de las pastillas de estante también. */
  --amarillo: #ffd23f;
  --naranja-claro: #f5a33f;
}

:root[data-tema-tienda="oscuro"] .tm-store-shell,
:root[data-tema-tienda="oscuro"] body {
  background: var(--papel);
  color: var(--tinta);
}

/* Los blancos escritos a mano que SÍ son superficie, no tinta sobre color.
   Los demás `#ffffff` de este archivo son letra sobre morado o sobre rojo
   y ahí siguen estando bien. */
:root[data-tema-tienda="oscuro"] .tm-opcion-lista--activa {
  background: rgba(139, 92, 246, 0.16);
}

:root[data-tema-tienda="oscuro"] .store-product-card {
  --tarjeta-fondo: #1d1c2e;
  --tarjeta-imagen-vacia: #2b2a3f;
}

/* La cuenta del carrito: círculo claro con número morado, para que el
   número se lea. Sobre el degradado oscuro un círculo blanco puro brilla
   demasiado. */
:root[data-tema-tienda="oscuro"] .tm-store-carrito-cuenta {
  background: #f2f2f7;
  color: var(--marca-hondo);
}

/* Las sombras del tema claro no existen sobre oscuro: lo que separa una
   superficie de otra es el borde, no la sombra. */
:root[data-tema-tienda="oscuro"] .tm-store-seccion,
:root[data-tema-tienda="oscuro"] .store-product-card {
  box-shadow: none;
  border: 1px solid var(--linea);
}

/* «Soy nuevo / Ya tengo cuenta» y el «Siguiente» de la introducción: el
   morado hondo de la marca casi no se lee sobre el fondo de noche. Van en el
   morado claro. */
:root[data-tema-tienda="oscuro"] .tm-puerta-cambio button[aria-selected="true"],
:root[data-tema-tienda="oscuro"] .tm-alta-saltar,
:root[data-tema-tienda="oscuro"] .tm-alta-enlace,
:root[data-tema-tienda="oscuro"] .tm-alta-icono,
:root[data-tema-tienda="oscuro"] .tm-presentacion-enlace,
:root[data-tema-tienda="oscuro"] .tm-presentacion-hoja-icono,
:root[data-tema-tienda="oscuro"] .tm-recorrido-contador {
  color: var(--accion);
}

/* En oscuro, un mapa de noche: los mismos tonos pero apagados. El verde
   clarito del día era un cuadro que deslumbraba. */
:root[data-tema-tienda="oscuro"] .tm-mapa {
  --mapa-fondo: #22212f;
  --mapa-cuadra: #2d2c3f;
  --mapa-parque: #1f3528;
  --mapa-arbol: #3f7a52;
  --mapa-sombra: #0e0d17;
}

/* El cartel de novedades usa el azul de acción, que en la tienda no existe:
   aquí manda el rojo de marca (y el morado en oscuro). Este archivo solo lo
   carga la tienda, así que la regla no toca al POS ni a la Trastienda. */
.tm-novedades-version {
  background: color-mix(in srgb, var(--marca) 14%, transparent);
  color: var(--marca);
}

.tm-novedades-lista li::marker {
  color: var(--marca);
}

/* ---------- Mis depósitos de envases ----------
   La tarjeta que el checkout promete. Dos caras: el QR para la pistola de
   cámara, y el código escrito para dictarlo o teclearlo cuando la pistola
   no lee pantallas —que pasa seguido—. Se cambia de cara tocándola.

   El volteo se hace con una transición simple y no con un giro 3D: en un
   teléfono modesto el giro se ve a tirones, y una animación que tartamudea
   se siente peor que no tenerla. */

.tm-deposito-total {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-bottom: 14px;
  padding: 18px 16px;
  border-radius: 20px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  text-align: center;
}

.tm-deposito-total strong {
  font-size: 34px;
  font-weight: 800;
  line-height: 1.1;
}

.tm-deposito-total span {
  font-size: 13px;
  opacity: 0.92;
}

.tm-deposito {
  margin-bottom: 12px;
  padding: 16px;
  border: 1px solid var(--linea);
  border-radius: 18px;
  background: var(--papel-alto);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
  cursor: pointer;
}

.tm-deposito[data-voltear]:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

.tm-deposito-cabeza {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.tm-deposito-envase {
  font-size: 15px;
  font-weight: 700;
}

.tm-deposito-monto {
  font-size: 20px;
  font-weight: 800;
  color: var(--marca);
}

/* El QR manda mientras la tarjeta está de frente. */
.tm-deposito-qr {
  display: flex;
  justify-content: center;
  margin: 10px auto 4px;
  padding: 10px;
  width: fit-content;
  /* Blanco SIEMPRE, también en tema oscuro: una cámara lee un QR por el
     contraste, y sobre fondo oscuro los cuadros negros desaparecen. */
  background: #ffffff;
  border-radius: 12px;
}

.tm-deposito-qr svg {
  width: min(210px, 62vw);
  height: auto;
}

.tm-deposito-codigo {
  padding: 6px 0;
  text-align: center;
  font-size: 40px;
  font-weight: 800;
  letter-spacing: 0.12em;
  line-height: 1.1;
}

/* De frente: QR grande y el código chico debajo, como referencia.
   Volteada: el código enorme y el QR guardado. */
.tm-deposito:not(.tm-deposito--volteada) .tm-deposito-codigo {
  font-size: 22px;
  letter-spacing: 0.18em;
  color: var(--tinta-suave);
}

.tm-deposito--volteada .tm-deposito-qr {
  display: none;
}

.tm-deposito-voltear,
.tm-deposito-nota {
  margin: 4px 0 0;
  text-align: center;
  font-size: 12.5px;
  color: var(--tinta-suave);
}

.tm-deposito--cobrado {
  opacity: 0.62;
  box-shadow: none;
  cursor: default;
}

.tm-deposito--cobrado .tm-deposito-codigo {
  font-size: 20px;
  color: var(--tinta-suave);
  text-decoration: line-through;
}

/* ---------- El interruptor de apariencia: sol y luna ----------

   Tomado de Uiverse.io (componente de JkHuger, licencia MIT) y vestido con
   los colores de la tienda. Del original se conserva lo que vale: el sol que
   se encoge hasta volverse luna y los nueve rayos que giran y se apagan. Se
   le quitó la capa que invertía la pantalla entera —aquí el tema lo pone el
   atributo del documento, no un truco visual— y sus colores fijos.

   El alto sale en 45px reales (3em sobre 15px): un interruptor que se toca
   con el pulgar no puede medir menos de 44 (CLAUDE.md sección 11). */

.tm-menu-tema {
  display: flex;
  flex-direction: column;
}

.tm-menu-fila--tema {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.tm-menu-fila--tema .tm-tema-envoltura { margin-left: 2px; }

.tm-tema-texto {
  font-size: 15px;
  font-weight: 600;
  color: var(--tinta);
}

.tm-tema-envoltura {
  position: relative;
  font-size: 15px;
}

.tm-tema-icono,
.tm-tema-casilla {
  z-index: 1;
}

.tm-tema-icono,
.tm-tema-parte {
  position: absolute;
}

.tm-tema-icono {
  display: block;
  top: 0.5em;
  left: 0.5em;
  width: 1.5em;
  height: 1.5em;
  pointer-events: none;
}

.tm-tema-parte {
  border-radius: 50%;
  box-shadow: 0.4em -0.4em 0 0.5em #ffffff inset;
  top: calc(50% - 0.5em);
  left: calc(50% - 0.5em);
  width: 1em;
  height: 1em;
  transform: scale(0.5);
  transition: box-shadow 0.4s ease-in-out, opacity 0.4s ease-in-out,
    transform 0.4s ease-in-out;
}

.tm-tema-parte ~ .tm-tema-parte {
  background-color: #ffffff;
  border-radius: 0.05em;
  top: 50%;
  left: calc(50% - 0.05em);
  width: 0.1em;
  height: 0.2em;
  transform: rotate(0deg) translateY(0.5em);
  transform-origin: 50% 0;
}

.tm-tema-parte:nth-child(3) { transform: rotate(45deg) translateY(0.45em); }
.tm-tema-parte:nth-child(4) { transform: rotate(90deg) translateY(0.45em); }
.tm-tema-parte:nth-child(5) { transform: rotate(135deg) translateY(0.45em); }
.tm-tema-parte:nth-child(6) { transform: rotate(180deg) translateY(0.45em); }
.tm-tema-parte:nth-child(7) { transform: rotate(225deg) translateY(0.45em); }
.tm-tema-parte:nth-child(8) { transform: rotate(270deg) translateY(0.5em); }
.tm-tema-parte:nth-child(9) { transform: rotate(315deg) translateY(0.5em); }

.tm-tema-casilla,
.tm-tema-casilla:before {
  display: block;
}

.tm-tema-casilla {
  position: relative;
  width: 6em;
  height: 3em;
  padding: 0.25em;
  border: 0;
  border-radius: 25% / 50%;
  /* El amarillo del logo para el día: es el color que esta tienda ya usa
     para el sol de su marca. */
  background-color: var(--amarillo);
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  transition: background-color 0.4s ease-in-out;
}

.tm-tema-casilla:before {
  content: "";
  width: 2.5em;
  height: 2.5em;
  border-radius: 50%;
  background-color: var(--naranja);
  transition: 0.3s;
}

.tm-tema-casilla:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 3px;
}

/* De noche: el fondo se hace azul profundo, el sol se corre a la derecha,
   se encoge y le sale la mordida de luna; los rayos se apagan. */
.tm-tema-casilla:checked {
  background-color: #10203a;
}

.tm-tema-casilla:checked:before {
  background-color: #7aa7ff;
  transform: translateX(3em);
}

.tm-tema-casilla:checked ~ .tm-tema-icono {
  transform: translateX(3em);
}

.tm-tema-casilla:checked ~ .tm-tema-icono .tm-tema-parte:nth-child(1) {
  box-shadow: 0.2em -0.2em 0 0.2em #ffffff inset;
  transform: scale(1);
  top: 0.2em;
  left: -0.2em;
}

.tm-tema-casilla:checked ~ .tm-tema-icono .tm-tema-parte ~ .tm-tema-parte {
  opacity: 0;
}

.tm-tema-auto {
  align-self: flex-start;
  margin: 0 12px 4px 60px;
  padding: 4px 2px;
  font-size: 12.5px;
  border: 0;
  background: transparent;
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
  opacity: 0.8;
  cursor: pointer;
}

/* Quien pidió menos movimiento no quiere ver girar nueve rayos: el
   interruptor sigue funcionando, solo que sin espectáculo. */
@media (prefers-reduced-motion: reduce) {
  .tm-tema-casilla,
  .tm-tema-casilla:before,
  .tm-tema-icono,
  .tm-tema-parte {
    transition: none;
  }
}

/* ---------- La bienvenida ---------- */
/*
   Una franja, no una pantalla. El dueño abrió su dominio y le faltó algo:
   «se siente seco». Entrar de golpe al catálogo no dice de quién es la
   tienda; una pantalla que hay que cerrar antes de comprar es peor. Esto se
   lee en dos segundos y se va al bajar.

   Queda BAJITA a propósito: el catálogo tiene que seguir asomándose en el
   primer vistazo. Si esto empujara los productos fuera de la pantalla,
   habría cambiado un problema por uno más caro. */

/* ---------- Frías o al tiempo ---------- */
/*
   Plegado de entrada. Va cerrado a propósito: se da por hecho que las
   bebidas van frías —que es lo que quiere casi todo el mundo— y solo se
   ofrece cambiarlo. Desplegarle la pregunta a todos por algo que pide uno
   de cada veinte le cobraría a los diecinueve el trabajo del que falta. */

.tm-al-tiempo {
  margin-top: 10px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  overflow: hidden;
}

.tm-al-tiempo-abrir {
  padding: 13px 14px;
  min-height: 48px;
  display: flex;
  align-items: center;
  font-size: 14.5px;
  font-weight: 650;
  color: var(--marca);
  cursor: pointer;
  list-style: none;
}

.tm-al-tiempo-abrir::-webkit-details-marker { display: none; }

.tm-al-tiempo-linea {
  padding: 12px 14px;
  border-top: 1px solid var(--linea);
}

.tm-al-tiempo-nombre {
  display: block;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 8px;
}

.tm-al-tiempo-nombre small {
  font-weight: 400;
  color: var(--tinta-tenue);
}

.tm-al-tiempo-opciones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tm-al-tiempo-opcion {
  /* 44px: se toca con el pulgar, y de pie en la calle. */
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: var(--papel);
  color: var(--tinta);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}

.tm-al-tiempo-opcion--puesta {
  background: var(--marca);
  border-color: var(--marca);
  color: #fff;
}

/* ---------- Al trabajo: cuándo llega (parte 3 de Empresas y vecinos) ----------

   Como texto, no en una caja gris: en caja parecía un botón que no hacía
   nada (maqueta de la pantalla de pago, 2026-10-16). */

.tm-checkout-reparto {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 2px 2px 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-checkout-reparto b {
  color: var(--tinta);
}

.tm-checkout-reparto svg {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--marca);
}

/* Cuánto falta para el envío gratis: la barrita del carrito, en chico y
   dentro de la cuenta. */
.tm-checkout-meta {
  display: grid;
  gap: 6px;
  margin: 4px 0 6px;
}

.tm-checkout-meta p {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--tinta-suave);
}

.tm-checkout-meta b {
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
}

.tm-checkout-meta-barra {
  display: block;
  height: 6px;
  overflow: hidden;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tinta) 9%, transparent);
}

.tm-checkout-meta-barra i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--ok);
}

.tm-pedido-reparto {
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--marca) 8%, var(--papel-alto));
  color: var(--tinta);
  font-size: 14px;
  font-weight: 700;
  text-align: center;
}


/* ---------- Mis direcciones: el punto en el mapa ---------- */

.tm-dir-mapa {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-dir-mapa-nota {
  margin: 0;
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-dir-aqui {
  min-height: 50px;
  justify-content: center;
  gap: 8px;
}

.tm-dir-aqui svg { width: 18px; height: 18px; flex: none; }

/* La forma de dirección compartida (forma_direccion.js, 2026-10-08): en el
   orden en que se piensa, y «¿Cómo le dices?» al final, como opciones. */
.tm-dir-opcional { font-weight: 400; color: var(--tinta-tenue); }

.tm-dir-etiqueta-titulo {
  display: block;
  margin-bottom: 6px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--tinta-suave);
}

.tm-dir-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.tm-dir-chip {
  min-height: 44px;
  padding: 0 16px;
  border: 1.5px solid var(--linea);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
}

.tm-dir-chip[aria-checked="true"] {
  border-color: var(--marca);
  background: color-mix(in srgb, var(--marca) 9%, var(--papel-alto));
  color: var(--marca);
}

.tm-dir-chip:focus-visible { outline: 2px solid var(--marca); outline-offset: 2px; }

.tm-dir-otra {
  width: 100%;
  min-height: 46px;
  margin-top: 8px;
  padding: 0 14px;
  border: 1.5px solid var(--marca);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
}

.tm-dir-otra[hidden] { display: none; }


/* ---------- ¿Dónde recibes tus pedidos? (grupo.js) ----------
   En tu trabajo (tu empresa) o soy vecino: uno u otro. Paso 4 del alta y
   fila de Mi cuenta (2026-10-05). */

.tm-grupo-pagina .tm-alta-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tm-grupo-ayuda {
  margin: -4px 0 4px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

.tm-grupo-opcion {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 24px;
  align-items: center;
  gap: 12px;
  min-height: 68px;
  padding: 12px;
  border: 2px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-grupo-opcion[aria-pressed="true"] {
  border-color: var(--marca);
  background: color-mix(in srgb, var(--marca) 6%, var(--papel-alto));
}

.tm-grupo-opcion:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

.tm-grupo-opcion b {
  display: block;
  font-size: 15.5px;
}

.tm-grupo-opcion small {
  display: block;
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-grupo-icono {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--papel-hondo);
  color: var(--marca);
}

.tm-grupo-icono svg {
  width: 24px;
  height: 24px;
}

.tm-grupo-radio {
  width: 22px;
  height: 22px;
  border-radius: 999px;
  border: 2px solid var(--tinta-tenue);
}

.tm-grupo-opcion[aria-pressed="true"] .tm-grupo-radio {
  border: 7px solid var(--marca);
}

/* «Selecciona tu empresa»: un botón que se abre como acordeón (maqueta
   aprobada 2026-10-08). Sin circulitos en la lista: la escogida se marca con
   su fondo y una palomita. */
.tm-grupo-selector,
.tm-grupo-vecino {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: -4px;
}

.tm-grupo-selector[hidden],
.tm-grupo-vecino[hidden] { display: none; }

.tm-grupo-selecciona {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 16px;
  border: 1.5px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 15.5px;
  text-align: left;
  cursor: pointer;
}

.tm-grupo-selecciona[aria-expanded="true"] {
  border-color: var(--marca);
  border-radius: 16px 16px 0 0;
}

.tm-grupo-selecciona:focus-visible { outline: 2px solid var(--marca); outline-offset: 2px; }
.tm-grupo-valor { flex: 1; min-width: 0; font-weight: 600; }
.tm-grupo-valor--vacio { color: var(--tinta-tenue); font-weight: 400; }
.tm-grupo-palomita { width: 20px; height: 20px; flex: none; color: var(--ok); }
.tm-grupo-flecha { width: 20px; height: 20px; flex: none; color: var(--tinta-suave); transition: transform 0.2s ease; }
.tm-grupo-selecciona[aria-expanded="true"] .tm-grupo-flecha { transform: rotate(180deg); }

.tm-grupo-opciones {
  display: flex;
  flex-direction: column;
  margin-top: -8px;
  border: 1.5px solid var(--marca);
  border-top: 0;
  border-radius: 0 0 16px 16px;
  background: var(--papel-alto);
  overflow: hidden;
  animation: tm-grupo-abre 0.18s ease;
}

.tm-grupo-opciones[hidden] { display: none; }

@keyframes tm-grupo-abre { from { opacity: 0; transform: translateY(-4px); } }

.tm-grupo-buscar {
  margin: 10px;
  min-height: 46px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid var(--linea);
  background: var(--papel);
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
}

.tm-grupo-opciones [role="listbox"] { display: flex; flex-direction: column; }

.tm-grupo-empresa {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 16px;
  border: 0;
  border-top: 1px solid var(--linea);
  background: none;
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
  text-align: left;
  cursor: pointer;
}

.tm-grupo-empresa[aria-selected="true"] {
  background: color-mix(in srgb, var(--marca) 9%, var(--papel-alto));
  font-weight: 700;
}

.tm-grupo-empresa[aria-selected="true"]::after {
  content: "";
  width: 12px;
  height: 7px;
  margin-left: auto;
  border: solid var(--marca);
  border-width: 0 0 2.5px 2.5px;
  transform: translateY(-2px) rotate(-45deg);
}

.tm-grupo-empresa:focus-visible { outline: 2px solid var(--marca); outline-offset: -2px; }

.tm-grupo-otra-campo {
  min-height: 50px;
  padding: 0 14px;
  border: 1.5px solid var(--marca);
  border-radius: 14px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
}

.tm-grupo-otra {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-grupo-opciones .tm-grupo-otra { padding: 12px 16px 0; }

.tm-grupo-parecidas { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

.tm-grupo-parecida {
  min-height: 40px;
  padding: 0 14px;
  border: 1.5px solid var(--marca);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--marca);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

/* El vecino: su dirección aquí mismo, o la que ya tenía. */
.tm-grupo-dir,
.tm-grupo-dir-forma {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
}

.tm-grupo-dir-forma { gap: 12px; }
.tm-grupo-dir-forma .tm-campo { margin: 0; }
.tm-grupo-dir-titulo { margin: 0; font-size: 16px; }
.tm-grupo-dir-rotulo { font-size: 12.5px; font-weight: 600; color: var(--tinta-suave); }
.tm-grupo-dir b { font-size: 15px; }
.tm-grupo-dir span:not(.tm-grupo-dir-rotulo) { font-size: 13.5px; color: var(--tinta-suave); }

.tm-grupo-dir-otra {
  align-self: flex-start;
  min-height: 44px;
  margin-top: 6px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--marca);
  font: inherit;
  font-size: 14.5px;
  font-weight: 700;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .tm-grupo-opciones { animation: none; }
  .tm-grupo-flecha { transition: none; }
}

.tm-grupo-guardar {
  min-height: 54px;
  margin-top: 8px;
  justify-content: center;
  font-size: 16px;
}


/* ---------- La portada con acabado profesional ----------
   Aprobada en maqueta el 2026-10-05: «Ver todo ›» y una línea de qué hay en
   cada estante, y la barra del pedido abajo. La tarjeta de producto heredada
   no se toca. */

/* El letrero de abierto: un solo renglón en la franja, bajo el buscador,
   que corre como cinta. Lo escogió el dueño en maqueta el 2026-10-15 («C»):
   la tarjeta blanca de antes «no combina», y en dos renglones «roba mucho
   espacio el rojo, que es vital a la vista de la tienda». Letra blanca
   sobre rojo de día y sobre morado de noche; las orillas se desvanecen
   para que el texto entre y salga sin cortarse en seco. */
.tm-estado-tienda {
  width: 100%;
  max-width: 1100px;
  margin: -6px auto 0;
  overflow: hidden;
  color: rgba(255, 255, 255, 0.86);
  font-size: 13px;
  line-height: 16px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18px, #000 calc(100% - 18px), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 18px, #000 calc(100% - 18px), transparent);
}

.tm-estado-tienda[hidden] {
  display: none;
}

/* El punto dice el estado: verde se puede todo, amarillo se puede menos,
   blanco está cerrado. Claros en los dos temas, porque van sobre la franja
   (mezclado con --ok-fondo, de noche salía verde oscuro). */
.tm-estado-tienda[data-tono="servicio"] {
  --estado-punto: color-mix(in srgb, var(--whatsapp) 60%, #ffffff);
}

.tm-estado-tienda[data-tono="recoger"] {
  --estado-punto: var(--amarillo);
}

.tm-estado-tienda[data-tono="cerrado"] {
  --estado-punto: #ffffff;
}

/* La cinta lleva el letrero repetido (main.js `_llenarCinta`) y corre el
   largo de una vuelta, ni un pixel más. Arranca 18px adentro, pasada la
   orilla que se desvanece, para que lo primero que se lea —«Abierto» o
   «Cerrado»— no nazca borroso; como todas las vueltas se recorren igual,
   el empalme sigue sin notarse. */
.tm-estado-tienda-cinta {
  display: flex;
  width: max-content;
  padding-left: 18px;
  animation: tm-cinta-corre 12s linear infinite;
}

@keyframes tm-cinta-corre {
  to { transform: translateX(calc(-1 * var(--cinta-vuelta, 50%))); }
}

.tm-estado-tienda-vuelta {
  display: flex;
  align-items: center;
  padding-right: 32px;
  white-space: nowrap;
}

.tm-estado-tienda-parte {
  display: inline-flex;
  align-items: center;
}

.tm-estado-tienda-parte b {
  color: #ffffff;
}

.tm-estado-tienda-parte svg {
  flex: none;
  width: 14px;
  height: 14px;
  margin-right: 5px;
}

.tm-estado-tienda-separa {
  padding: 0 9px;
}

.tm-estado-tienda-punto {
  flex: none;
  width: 8px;
  height: 8px;
  margin: 0 7px 0 3px;
  border-radius: 999px;
  background: var(--estado-punto);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.18);
}

/* Quien pidió menos movimiento lo lee quieto, completo y centrado, aunque
   ocupe dos renglones. */
@media (prefers-reduced-motion: reduce) {
  .tm-estado-tienda {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .tm-estado-tienda-cinta {
    width: auto;
    padding-left: 0;
    animation: none;
  }

  .tm-estado-tienda-vuelta {
    flex: 1;
    flex-wrap: wrap;
    justify-content: center;
    column-gap: 14px;
    padding-right: 0;
  }

  .tm-estado-tienda-vuelta[aria-hidden],
  .tm-estado-tienda-separa {
    display: none;
  }
}

/* El rótulo amarillo con su «Ver todo ›» a la derecha. */
.tm-seccion-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.tm-seccion-cabeza .tm-store-seccion-titulo {
  margin: 0;
}

.tm-ver-todo {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-height: 44px;
  padding: 0 4px;
  border: none;
  background: none;
  color: var(--marca);
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
}

.tm-ver-todo svg {
  width: 16px;
  height: 16px;
}

.tm-ver-todo:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
  border-radius: 8px;
}

.tm-seccion-que-hay {
  margin: -6px 0 12px;
  font-size: 13px;
  color: var(--tinta-suave);
}

/* En claro la portada se veía «triste» —lo dijo el dueño—: todo blanco y
   gris. Cada estante lleva arriba un tinte del amarillo de sus rótulos. En
   oscuro el morado ya da vida y no hace falta.
   Hasta el 2026-10-15 el rojo de la cabecera también bajaba, rosado, detrás
   de los departamentos; se fue con la tarjeta del estado: entre la franja y
   el gris se veía como mancha. */
:root:not([data-tema-tienda="oscuro"]) .tm-catalogo .tm-store-seccion {
  background-image: linear-gradient(
    180deg,
    color-mix(in srgb, var(--amarillo) 12%, var(--papel-alto)) 0,
    var(--papel-alto) 110px
  );
}

/* La barra del pedido, pegada abajo mientras se compra. */
.tm-barra-pedido {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: max(14px, env(safe-area-inset-bottom));
  z-index: 150;
  max-width: 520px;
  margin: 0 auto;
  min-height: 58px;
  padding: 0 8px 0 14px;
  border: none;
  border-radius: 18px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  display: flex;
  align-items: center;
  gap: 12px;
  box-shadow: 0 12px 26px rgba(0, 0, 0, 0.25);
  font: inherit;
  cursor: pointer;
  animation: tm-barra-sube 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.tm-barra-pedido[hidden] {
  display: none;
}

.tm-barra-pedido-cuantos {
  min-width: 30px;
  height: 30px;
  padding: 0 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
  display: grid;
  place-items: center;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tm-barra-pedido b {
  flex: 1;
  text-align: left;
  font-size: 15.5px;
}

.tm-barra-pedido-total {
  padding: 9px 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.16);
  font-family: var(--fuente-mono, monospace);
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.tm-barra-pedido-total[hidden] {
  display: none;
}

.tm-barra-pedido:focus-visible {
  outline: 3px solid var(--amarillo);
  outline-offset: 2px;
}

/* El final de la página sube lo que mide la barra. */
body.tm-con-barra-pedido {
  padding-bottom: 88px;
}

@keyframes tm-barra-sube {
  from { translate: 0 30px; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-barra-pedido {
    animation: none;
  }
}


/* ---------- La presentación ----------

   Lo primero que ve un cliente nuevo o un extraño, una vez en su teléfono.
   Reemplazó a la cortina metálica el 2026-09-29: la información se quedó
   (la frase del dueño, cómo se entrega, su firma) y el diseño cambió al de
   la maqueta que aprobó. Toma los colores del tema: rojo de día, morado de
   noche. */

html.tm-con-presentacion,
html.tm-con-presentacion body {
  overflow: hidden;
}

.tm-presentacion {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--papel);
  color: var(--tinta);
}

.tm-presentacion[hidden] {
  display: none;
}

.tm-presentacion--sale {
  pointer-events: none;
  animation: tm-presentacion-sale 0.3s ease-in forwards;
}

@keyframes tm-presentacion-sale {
  to { opacity: 0; translate: 0 -14px; }
}

/* Pantalla 1: toda la pantalla es la tienda, con «Comenzar» abajo. */
.tm-presentacion-cielo {
  position: relative;
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: calc(20px + env(safe-area-inset-top, 0px)) 20px calc(14px + env(safe-area-inset-bottom, 0px));
  overflow: hidden;
  text-align: center;
  background: linear-gradient(160deg, var(--marca), var(--marca-hondo));
}

/* Todo cabe en la pantalla sin moverla, como lo pidió el dueño: el logo y
   la tiendita se encogen con el alto del teléfono, y los márgenes
   automáticos reparten lo que sobre arriba y abajo. */

.tm-presentacion-cielo[hidden],
.tm-presentacion-caminos[hidden] {
  display: none;
}

.tm-presentacion-pie {
  position: relative;
  width: min(400px, 100%);
  margin-top: auto;
  padding-top: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tm-presentacion-comenzar {
  min-height: 56px;
  border: 0;
  border-radius: 16px;
  background: #ffffff;
  color: var(--marca-hondo);
  font: inherit;
  font-size: 17px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
}

.tm-presentacion-comenzar:active { scale: 0.98; }

/* «Instalar la app», debajo de «Comenzar»: delineado en blanco para no
   competir con él, y con un brinquito al aparecer, que es lo que insiste
   sin estorbar. Solo sale en un teléfono que no la tiene. */
.tm-presentacion-instalar {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1.5px solid rgba(255, 255, 255, 0.75);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.08);
  color: #ffffff;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  animation: tm-presentacion-insiste 0.9s cubic-bezier(0.34, 1.56, 0.64, 1) 1.6s both;
}

.tm-presentacion-instalar[hidden] {
  display: none;
}

.tm-presentacion-instalar svg {
  flex: none;
  width: 20px;
  height: 20px;
}

.tm-presentacion-instalar:active { scale: 0.98; }

@keyframes tm-presentacion-insiste {
  0%   { opacity: 0; scale: 0.7; }
  40%  { opacity: 1; scale: 1.06; }
  60%  { scale: 0.97; }
  100% { scale: 1; }
}

/* Con el botón, la tiendita se encoge un poco para que todo siga cabiendo
   sin mover la pantalla en un teléfono chico (360 × 620). */
.tm-presentacion-cielo:has(.tm-presentacion-instalar:not([hidden])) .tm-tiendita {
  max-height: 27dvh;
}

/* Pantalla 2: los caminos, en el papel de la tienda. */
.tm-presentacion-caminos {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  padding-top: env(safe-area-inset-top, 0px);
  animation: tm-alta-entra 0.35s ease-out both;
}

.tm-presentacion-atras {
  width: 44px;
  height: 44px;
  margin: 12px 0 0 16px;
  display: grid;
  place-items: center;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  cursor: pointer;
}

.tm-presentacion-atras svg {
  width: 20px;
  height: 20px;
}

/* La pregunta arriba y los botones abajo, donde llega el pulgar. */
.tm-presentacion-caminos .tm-presentacion-acciones {
  flex: 1;
  padding-top: 18px;
}

.tm-presentacion-pregunta {
  margin: 0;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  text-wrap: balance;
}

.tm-presentacion-explica {
  margin: 0 0 auto;
  padding-bottom: 28px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

.tm-presentacion-cielo::before,
.tm-presentacion-cielo::after {
  content: "";
  position: absolute;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
}

.tm-presentacion-cielo::before { left: -70px; bottom: -90px; width: 260px; height: 260px; }
.tm-presentacion-cielo::after { right: -50px; top: 70px; width: 170px; height: 170px; }

.tm-presentacion-tema {
  position: absolute;
  z-index: 1;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: 12px;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
  cursor: pointer;
}

.tm-presentacion-tema svg {
  width: 22px;
  height: 22px;
}

/* De día se ofrece la luna; de noche, el sol. */
.tm-presentacion-sol { display: none; }

/* «Bienvenidos a» en un letrero blanco colgado de un clavo con su hilo,
   como el de ABIERTO de la puerta de la tiendita, que se columpia al
   aparecer. El dueño lo escogió el 2026-10-14 entre siete maquetas: en un
   renglón chico se veía «incompleto». Se mece desde el clavo. */
.tm-presentacion-bienvenido {
  position: relative;
  margin: auto 0 8px;
  padding-top: 19px;
  transform-origin: 50% 4px;
  animation: tm-presentacion-columpio 1.9s cubic-bezier(0.3, 0.7, 0.4, 1) 0.15s both;
}

@keyframes tm-presentacion-columpio {
  0%   { opacity: 0; rotate: -16deg; }
  15%  { opacity: 1; rotate: 11deg; }
  35%  { rotate: -7deg; }
  55%  { rotate: 4deg; }
  75%  { rotate: -2deg; }
  100% { rotate: 0deg; }
}

/* Los dos hilos, del clavo a las esquinas del letrero: se estiran con lo
   que mida el letrero, y el trazo no engorda al estirarse. */
.tm-presentacion-hilos {
  position: absolute;
  top: 4px;
  left: 18px;
  width: calc(100% - 36px);
  height: 17px;
  overflow: visible;
}

.tm-presentacion-hilos path {
  fill: none;
  stroke: rgba(255, 255, 255, 0.85);
  stroke-width: 1.6;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.tm-presentacion-clavo {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 50%;
  width: 9px;
  height: 9px;
  margin-left: -4.5px;
  border-radius: 50%;
  background: var(--amarillo);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/* Con su doble orilla, como los letreros de las tiendas. */
.tm-presentacion-tabla {
  position: relative;
  display: block;
  padding: 9px 20px;
  border-radius: 9px;
  background: #ffffff;
  color: var(--marca-hondo);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.2;
  box-shadow:
    0 5px 12px rgba(0, 0, 0, 0.16),
    inset 0 0 0 3px #ffffff,
    inset 0 0 0 4.5px currentColor;
}

.tm-presentacion-titulo {
  position: relative;
  margin: 0;
  color: var(--amarillo);
  font-size: 44px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}

/* Su logo, más grande que en la barra: es el momento de enseñarlo. Un poco
   más chico desde que va arriba de la tiendita (2026-09-30), y con tope
   por el alto de la pantalla. Guarda la proporción de la tinta del logo,
   1.65 a 1. */
/* Ancho y bajito para el logo de un renglón (2026-10-17). */
.tm-presentacion-logo {
  display: block;
  width: min(300px, 78vw);
  height: min(80px, 19vw, 11vh);
  height: min(80px, 19vw, 11dvh);
}

/* Cómo se entrega, en botoncitos blancos con la casita y la bolsa del
   menú. No se aprietan: dicen lo que hay. */
.tm-presentacion-servicio {
  position: relative;
  margin: 12px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.tm-presentacion-pastilla {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 15px 9px 12px;
  border-radius: 999px;
  background: #ffffff;
  color: var(--marca-hondo);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.14);
  animation: tm-presentacion-brota 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) var(--t) both;
}

.tm-presentacion-pastilla svg {
  flex: none;
  width: 18px;
  height: 18px;
}

.tm-presentacion-o {
  color: rgba(255, 255, 255, 0.85);
  font-size: 14px;
  animation: tm-presentacion-sube 0.4s ease-out 1.5s both;
}

@keyframes tm-presentacion-brota {
  from { opacity: 0; scale: 0.6; }
}

.tm-presentacion-acciones {
  width: min(440px, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px 20px calc(18px + env(safe-area-inset-bottom, 0px));
}

.tm-presentacion-boton {
  width: 100%;
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  border-radius: 16px;
  font-size: 16px;
  font-weight: 700;
  text-decoration: none;
}

.tm-presentacion-boton[hidden] {
  display: none;
}

.tm-presentacion-boton--suave {
  border: 1px solid var(--linea);
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.tm-presentacion-boton small {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--tinta-suave);
}

.tm-presentacion-enlace {
  min-height: 44px;
  border: 0;
  background: none;
  color: var(--marca-hondo);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}

.tm-presentacion-entrar {
  margin: -4px 0 0;
  text-align: center;
  font-size: 14px;
  color: var(--tinta-suave);
}

.tm-presentacion-entrar .tm-presentacion-enlace {
  min-height: 36px;
  font-size: 14px;
}

.tm-presentacion-firma {
  margin: 2px 0 0;
  text-align: center;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.72);
}

.tm-presentacion-aparece {
  animation: tm-presentacion-sube 0.5s ease-out var(--t) both;
}

@keyframes tm-presentacion-sube {
  from { opacity: 0; translate: 0 18px; }
}

.tm-presentacion-tema:focus-visible,
.tm-presentacion-instalar:focus-visible,
.tm-presentacion-enlace:focus-visible,
.tm-presentacion-boton:focus-visible,
.tm-presentacion-comenzar:focus-visible,
.tm-presentacion-atras:focus-visible {
  outline: 3px solid var(--amarillo);
  outline-offset: 2px;
}

/* «Quiero mi cuenta»: una hoja que sube desde abajo. */
.tm-presentacion-hoja {
  position: fixed;
  inset: 0;
  z-index: 91;
  display: flex;
  align-items: flex-end;
  background: rgba(12, 10, 22, 0.55);
  animation: tm-mapa-aparece 0.2s ease-out both;
}

.tm-presentacion-hoja[hidden] {
  display: none;
}

.tm-presentacion-hoja-caja {
  width: min(480px, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px 22px calc(26px + env(safe-area-inset-bottom, 0px));
  border-radius: 28px 28px 0 0;
  background: var(--papel-alto);
  animation: tm-presentacion-hoja 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes tm-presentacion-hoja {
  from { translate: 0 100%; }
}

.tm-presentacion-hoja-icono {
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: 20px;
  background: color-mix(in srgb, var(--marca) 12%, transparent);
  color: var(--marca-hondo);
}

.tm-presentacion-hoja-icono svg {
  width: 30px;
  height: 30px;
}

.tm-presentacion-hoja-titulo {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
}

.tm-presentacion-hoja-texto {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

/* «Instálala en tu iPhone» y «Ábrela en tu navegador»: la hojita que sube
   cuando instalar no es un solo botón (js/store/instalar.js). Va encima de
   la presentación, y sirve igual desde el menú. */
.tm-instalar-hoja {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  align-items: flex-end;
  background: rgba(12, 10, 22, 0.55);
  animation: tm-mapa-aparece 0.2s ease-out both;
}

.tm-instalar-hoja[hidden],
.tm-instalar-modo[hidden] {
  display: none;
}

.tm-instalar-caja {
  width: min(480px, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px 22px calc(18px + env(safe-area-inset-bottom, 0px));
  border-radius: 28px 28px 0 0;
  background: var(--papel-alto);
  color: var(--tinta);
  animation: tm-presentacion-hoja 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.tm-instalar-modo {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tm-instalar-titulo {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
}

.tm-instalar-texto {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* Los pasos sí van numerados: es el orden en que se tocan. */
.tm-instalar-pasos {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tm-instalar-pasos li {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  align-items: center;
  gap: 10px;
  font-size: 15px;
}

.tm-instalar-n {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--marca) 12%, transparent);
  color: var(--marca-hondo);
  font-size: 14px;
  font-weight: 700;
}

/* El dibujo tal como lo va a ver en su teléfono, en el azul de los
   botones de Apple. */
.tm-instalar-dibujo {
  min-width: 34px;
  height: 34px;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  border-radius: 9px;
  background: var(--papel-hondo);
  color: var(--accion);
}

.tm-instalar-dibujo svg {
  width: 20px;
  height: 20px;
}

.tm-instalar-dibujo--texto {
  padding: 0 10px;
  font-size: 14px;
  font-weight: 600;
}

.tm-instalar-entendido {
  min-height: 52px;
  margin-top: 4px;
  border: 0;
  border-radius: 14px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}

.tm-instalar-ya {
  min-height: 44px;
  border: 0;
  background: none;
  color: var(--marca-hondo);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}

.tm-instalar-entendido:focus-visible,
.tm-instalar-ya:focus-visible {
  outline: 3px solid var(--amarillo);
  outline-offset: 2px;
}

/* ---------- La tiendita que abre ----------

   Una tienda de barrio de frente: letrero de ABARROTES, toldo de rayas,
   el aparador que se llena, la lámpara de la puerta, el cartel que pasa
   de CERRADO a ABIERTO y el refri que se prende parpadeando. De noche,
   luna y estrellas.

   En pocos colores a propósito: blanco en transparencias, amarillo y el
   color del tema, que se ve detrás. La primera versión traía papel picado,
   cajas de refresco, pizarrón y productos de todos los colores, y el
   dueño pidió «bajarle a tanto detalle o color» (2026-09-30). Como todo es
   blanco transparente, sirve igual sobre el rojo del día que sobre el
   morado de la noche. */
.tm-tiendita {
  --tt-pared: rgba(255, 255, 255, 0.12);
  --tt-cornisa: rgba(255, 255, 255, 0.22);
  --tt-marco: rgba(255, 255, 255, 0.22);
  --tt-vidrio: rgba(0, 0, 0, 0.14);
  --tt-luz: var(--amarillo);
  --tt-banqueta: rgba(255, 255, 255, 0.14);
  --tt-astro: #fff3b0;

  position: relative;
  width: min(310px, 82vw);
  /* En un teléfono chaparro se encoge por el alto, no se sale de la
     pantalla. */
  max-height: 34vh;
  max-height: 34dvh;
  margin-top: 14px;
  height: auto;
  overflow: visible;
}

.tm-tiendita * {
  transform-box: fill-box;
}

.tm-tt-edificio { animation: tm-presentacion-sube 0.5s cubic-bezier(0.22, 1, 0.36, 1) both; }
.tm-tt-astro { animation: tm-mapa-aparece 0.8s ease-out both; }

.tm-tt-estrella {
  display: none;
  transform-origin: center;
  animation: tm-tt-brillo 2.4s ease-in-out var(--t) infinite both;
}

@keyframes tm-tt-brillo {
  0%, 100% { opacity: 0; scale: 0.3; }
  50%      { opacity: 1; scale: 1; }
}

.tm-tt-letrero-pinta {
  transform-origin: center;
  animation: tm-mapa-brota 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) 0.45s both;
}

.tm-tt-toldo {
  transform-origin: 50% 0;
  animation: tm-tt-toldo 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) 0.6s both;
}

@keyframes tm-tt-toldo {
  from { scale: 1 0; }
}

.tm-tt-ventana {
  opacity: 0.22;
  animation: tm-mapa-aparece 0.6s ease-out 0.9s both;
}

.tm-tt-p {
  transform-origin: 50% 100%;
  animation: tm-mapa-brota 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) var(--t) both;
}

.tm-tt-refri-luz {
  opacity: 0.2;
  animation: tm-tt-parpadea 1s linear 1.1s both;
}

@keyframes tm-tt-parpadea {
  0%   { opacity: 0; }
  20%  { opacity: 0.26; }
  30%  { opacity: 0.04; }
  45%  { opacity: 0.26; }
  55%  { opacity: 0.08; }
  100% { opacity: 0.2; }
}

.tm-tt-cono {
  opacity: 0.2;
  animation: tm-mapa-aparece 0.5s ease-out 1.3s both;
}

.tm-tt-foco { animation: tm-mapa-aparece 0.3s 1.3s both; }

/* El cartel de la puerta se voltea: a la mitad del giro cambia de letrero. */
.tm-tt-cartel {
  transform-origin: 50% 0;
  animation: tm-tt-voltea 0.7s ease-in-out 1.9s both;
}

@keyframes tm-tt-voltea {
  0%, 100% { scale: 1 1; }
  50%      { scale: 0 1; }
}

.tm-tt-cerrado { animation: tm-tt-ocultar 0.01s linear 2.25s both; }
.tm-tt-abierto { animation: tm-tt-mostrar 0.01s linear 2.25s both; }

@keyframes tm-tt-ocultar {
  to { opacity: 0; }
}

@keyframes tm-tt-mostrar {
  from { opacity: 0; }
}

/* «Van y vienen»: el cliente es un monito liso, del mismo blanco y amarillo
   de la tienda, para que no se vea ni infantil ni realista. Nace
   escondido; lo mueve presentacion.js. Se mueve sobre el dibujo entero,
   no sobre su propia caja. */
.tm-tt-cliente {
  --tt-ropa: #ffffff;
  --tt-bolsa: var(--amarillo);
  opacity: 0;
  transform-box: view-box;
  transform-origin: 0 0;
}

.tm-tt-cliente--amarillo {
  --tt-ropa: var(--amarillo);
  --tt-bolsa: #ffffff;
}

.tm-tt-ropa { fill: var(--tt-ropa); }
.tm-tt-atras { fill: var(--tt-ropa); opacity: 0.7; }
.tm-tt-cabeza { fill: #ffffff; }
.tm-tt-bolsa { fill: var(--tt-bolsa); }
.tm-tt-asa { fill: none; stroke: var(--tt-bolsa); stroke-width: 1.6; }
.tm-tt-pierna,
.tm-tt-brazo { transform-origin: 50% 0; }

.tm-tt-cliente--camina .tm-tt-pierna-a,
.tm-tt-cliente--camina .tm-tt-brazo-b {
  animation: tm-tt-zancada 0.42s ease-in-out infinite alternate;
}

.tm-tt-cliente--camina .tm-tt-pierna-b,
.tm-tt-cliente--camina .tm-tt-brazo-a {
  animation: tm-tt-zancada 0.42s ease-in-out infinite alternate-reverse;
}

.tm-tt-cliente--camina .tm-tt-cuerpo {
  animation: tm-tt-rebote 0.21s ease-in-out infinite alternate;
}

@keyframes tm-tt-zancada {
  from { rotate: -24deg; }
  to   { rotate: 24deg; }
}

@keyframes tm-tt-rebote {
  to { translate: 0 -1.6px; }
}

/* La campanita de la puerta: tres rayitas, sin sonido. */
.tm-tt-ding {
  opacity: 0;
  transform-origin: 50% 100%;
}

/* De noche: la luna en vez del sol, la luz de adentro pesa más y salen
   las estrellas. */
:root[data-tema-tienda="oscuro"] .tm-tiendita {
  --tt-astro: #f2f2f7;
}

:root[data-tema-tienda="oscuro"] .tm-tt-estrella { display: block; }
:root[data-tema-tienda="oscuro"] .tm-tt-ventana { opacity: 0.32; }
:root[data-tema-tienda="oscuro"] .tm-tt-cono { opacity: 0.34; }
:root[data-tema-tienda="oscuro"] .tm-presentacion-luna { display: none; }
:root[data-tema-tienda="oscuro"] .tm-presentacion-sol { display: block; }

/* Quien pidió menos movimiento ve la tienda ya abierta y quieta. */
@media (prefers-reduced-motion: reduce) {
  .tm-presentacion,
  .tm-presentacion *,
  .tm-instalar-hoja,
  .tm-instalar-hoja * {
    animation: none !important;
  }

  .tm-tt-cerrado { opacity: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   El arranque de la app (plantillas/shells/_arranque_tienda.html y
   js/store/arranque.js). «TeLemarket» se borra hasta «TL», la manita
   aprieta «Ordenar ahora», sale la palomita y se abre un hueco desde ella.

   Los colores van escritos aquí y no con los tokens: el tema oscuro cambia
   --marca y el papel, y esto tiene que verse igual que la pantalla fija de
   Android que va justo antes, que siempre es roja.
   ═══════════════════════════════════════════════════════════════════════ */

/* El hueco que se abre al final. Registrado para que se pueda animar; en un
   navegador que no lo entienda, la capa simplemente se desvanece. */
@property --tm-hueco {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

.tm-con-arranque body { overflow: hidden; }

.tm-arranque {
  --tm-hueco: 0px;
  position: fixed;
  inset: 0;
  z-index: 1000;
  overflow: hidden;
  /* El fondo de la pantalla de Android (background_color del manifiesto). */
  background: #7e0d0d;
  -webkit-tap-highlight-color: transparent;
}

.tm-arranque[hidden] { display: none; }

/* La máscara solo existe al abrir: aun en cero, el borde suavizado del
   círculo deja pasar un punto de la tienda en medio de la pantalla. */
.tm-arranque.abre {
  -webkit-mask: radial-gradient(circle at var(--x, 50%) var(--y, 60%), transparent var(--tm-hueco), #000 calc(var(--tm-hueco) + 1px));
  mask: radial-gradient(circle at var(--x, 50%) var(--y, 60%), transparent var(--tm-hueco), #000 calc(var(--tm-hueco) + 1px));
  --tm-hueco: 160vmax;
  opacity: 0;
  transition: --tm-hueco 700ms cubic-bezier(0.65, 0, 0.35, 1), opacity 250ms ease 500ms;
}

/* El primer cuadro copia la pantalla de Android: el círculo rojo del icono
   (62 % del ancho, medido en el teléfono del dueño) con su TL. El círculo
   crece hasta llenar la pantalla y la TL se va: de ahí sale la escena. */
.tm-arranque-rojo {
  position: absolute;
  inset: 0;
  background: #d62020;
  clip-path: circle(31vw at 50% 50%);
}

.tm-arranque.crece .tm-arranque-rojo {
  clip-path: circle(150vmax at 50% 50%);
  transition: clip-path 550ms cubic-bezier(0.65, 0, 0.35, 1);
}

.tm-arranque-sello {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 42vw;
  translate: -50% -50%;
  overflow: visible;
}

.tm-arranque.crece .tm-arranque-sello {
  opacity: 0;
  transform: scale(0.85);
  transition: opacity 200ms ease 120ms, transform 300ms ease 120ms;
}

/* La escena mide lo de un teléfono de 324 x 704 y se escala al de verdad. */
.tm-arranque-escena {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 324px;
  height: 704px;
  margin: -352px 0 0 -162px;
  transform: scale(var(--k, 1));
}

/* «TeLemarket» → «TL». Cada letra sabe de dónde sale y a dónde va. */
.tm-arranque-letrero {
  position: absolute;
  left: 12px;
  top: 36px;
  width: 300px;
  overflow: visible;
}

.tm-arranque-palabra { opacity: 0; }
.tm-arranque.corre .tm-arranque-palabra { animation: tm-arranque-aparece 450ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }

.tm-arranque-letra {
  transform-box: view-box;
  transform-origin: 0 0;
  transform: var(--ini);
  transition: transform 450ms cubic-bezier(0.65, 0, 0.35, 1), opacity 180ms ease;
}

.tm-arranque.borra .tm-arranque-letra:not(.tm-arranque-letra--queda) {
  opacity: 0;
  transform: var(--fin);
  transition: transform 250ms ease, opacity 180ms ease;
  transition-delay: var(--espera);
}

.tm-arranque.junta .tm-arranque-letra--queda { transform: var(--fin); }

/* Letra blanca con su filo y su sombra rojo oscuro: el «TL» del icono. */
.tm-arranque-sombra { fill: #7e0d0d; stroke: #7e0d0d; stroke-width: 90; stroke-linejoin: round; }
.tm-arranque-frente { fill: #fff; stroke: #7e0d0d; stroke-width: 55; stroke-linejoin: round; paint-order: stroke; }

/* La tiendita amarilla, con su toldo que se desenrolla. */
.tm-arranque-tiendita {
  position: absolute;
  left: 74px;
  top: 230px;
  width: 176px;
  overflow: visible;
  opacity: 0;
}

.tm-arranque.corre .tm-arranque-tiendita { animation: tm-arranque-aparece 500ms cubic-bezier(0.2, 0.8, 0.2, 1) 100ms both; }
.tm-arranque-toldo { transform-box: fill-box; transform-origin: 50% 0; transform: scaleY(0); }
.tm-arranque.corre .tm-arranque-toldo { transform: none; transition: transform 350ms cubic-bezier(0.2, 0.8, 0.2, 1) 300ms; }
.tm-arranque-tiendita text { font-family: var(--fuente-interfaz); }

/* El teléfono con un solo botón. */
.tm-arranque-cel {
  position: absolute;
  left: 78px;
  top: 335px;
  width: 168px;
  height: 320px;
  padding: 8px;
  border-radius: 30px;
  background: #18181d;
  box-shadow: 0 16px 34px rgba(70, 0, 0, 0.35);
  transform: translateY(560px);
}

.tm-arranque.corre .tm-arranque-cel { transform: none; transition: transform 750ms cubic-bezier(0.2, 0.8, 0.2, 1) 300ms; }

.tm-arranque-isla {
  position: absolute;
  top: 15px;
  left: 50%;
  width: 48px;
  height: 14px;
  margin-left: -24px;
  border-radius: 7px;
  background: #18181d;
}

.tm-arranque-pantalla {
  position: relative;
  height: 100%;
  border-radius: 23px;
  background: #fff;
  display: grid;
  place-items: center;
}

.tm-arranque-boton {
  position: relative;
  display: grid;
  place-items: center;
  width: 140px;
  height: 46px;
  border-radius: 13px;
  background: #d62020;
  transition: width 380ms cubic-bezier(0.65, 0, 0.35, 1), border-radius 380ms cubic-bezier(0.65, 0, 0.35, 1),
              background-color 300ms ease, transform 120ms ease;
}

.tm-arranque-boton span {
  color: #fff;
  font-family: var(--fuente-interfaz);
  font-size: 15px;
  font-weight: 700;
  white-space: nowrap;
  transition: opacity 120ms ease;
}

.tm-arranque.aprieta .tm-arranque-boton { transform: scale(0.94); }
.tm-arranque.cambia .tm-arranque-boton { width: 48px; border-radius: 24px; background: #1f7a43; }
.tm-arranque.cambia .tm-arranque-boton span { opacity: 0; }

.tm-arranque-palomita { position: absolute; width: 25px; height: 25px; }

.tm-arranque-palomita path {
  fill: none;
  stroke: #fff;
  stroke-width: 3.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.tm-arranque.exito .tm-arranque-palomita path { stroke-dashoffset: 0; transition: stroke-dashoffset 300ms ease-out; }

.tm-arranque.exito .tm-arranque-boton::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 3px solid #1f7a43;
  animation: tm-arranque-onda 650ms ease-out forwards;
}

.tm-arranque-listo {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + 34px);
  margin: 0;
  text-align: center;
  color: #1f7a43;
  font-family: var(--fuente-interfaz);
  font-size: 16px;
  font-weight: 700;
  opacity: 0;
  transform: translateY(6px);
}

.tm-arranque.exito .tm-arranque-listo { opacity: 1; transform: none; transition: opacity 300ms ease 120ms, transform 300ms ease 120ms; }

/* La manita: entra, aprieta (se encoge al 85 %, como la de LottieFiles) y
   se va antes de que salga la palomita, para no taparla. */
.tm-arranque-mano {
  position: absolute;
  overflow: visible;
  pointer-events: none;
  transform: translate(130px, 340px);
}

.tm-arranque.entra .tm-arranque-mano { transform: none; transition: transform 450ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.tm-arranque.cambia .tm-arranque-mano { transform: translate(130px, 340px); transition: transform 400ms cubic-bezier(0.5, 0, 0.75, 0); }
.tm-arranque-dedo { transform-box: view-box; transform-origin: 452px 396px; }
.tm-arranque.dedo .tm-arranque-dedo { animation: tm-arranque-apreton 330ms ease-in-out; }

@keyframes tm-arranque-aparece {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}

@keyframes tm-arranque-apreton {
  50% { transform: scale(0.85); }
}

@keyframes tm-arranque-onda {
  from { transform: scale(1); opacity: 0.7; }
  to { transform: scale(2); opacity: 0; }
}

/* Los botones de la tienda se quedan como estaban: el estilo Stripe
   (core/tokens.css, 2026-10-09) es del POS. Aquí manda el rojo de marca. */
:root {
  --boton-radio: 12px;
  --boton-borde: var(--linea);
  --boton-sombra: none;
  --boton-sombra-accion: var(--sombra-suave);
  --boton-sombra-color: var(--sombra-suave);
  --boton-hundir: 0px;
}

/* ---------- Billetin: cómo vas a pagar (store/billetin.js) ----------
 *
 * Maqueta aprobada por el dueño el 2026-10-15. Una hoja que sube desde
 * abajo, con Billetin a la izquierda hablando en globos y los tres botones
 * al alcance del pulgar (CLAUDE.md §11).
 *
 * Los colores del dibujo van en el propio SVG y no son de la paleta: es una
 * ilustración, como la tiendita de la presentación. Lo de alrededor —hoja,
 * globos, botones— sí sale de los tokens, para que el tema oscuro funcione. */

.tm-billetin-capa {
  position: fixed;
  inset: 0;
  z-index: 250;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.tm-billetin-velo {
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 30, 0.45);
  animation: tm-billetin-aparece 0.3s ease-out;
}

.tm-billetin-hoja {
  position: relative;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 12px 18px calc(22px + env(safe-area-inset-bottom, 0px));
  border-radius: 24px 24px 0 0;
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.08);
  animation: tm-billetin-sube 0.38s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.tm-billetin-capa--sale .tm-billetin-hoja {
  animation: tm-billetin-baja 0.28s ease-in forwards;
}

.tm-billetin-capa--sale .tm-billetin-velo {
  animation: tm-billetin-desaparece 0.28s ease-in forwards;
}

.tm-billetin-asa {
  align-self: center;
  width: 40px;
  height: 4px;
  border-radius: 999px;
  background: var(--papel-hondo);
}

.tm-billetin-charla {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}

.tm-billetin-figura {
  flex-shrink: 0;
  margin-left: -8px;
  line-height: 0;
}

.tm-billetin-globos {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 8px;
}

.tm-billetin-globo {
  margin: 0;
  padding: 10px 12px;
  border-radius: 4px 16px 16px 16px;
  background: var(--papel);
  font-size: 15px;
  line-height: 1.35;
  text-wrap: pretty;
  animation: tm-billetin-globo 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* El secreto, en el amarillo del logo muy rebajado: se distingue del saludo
   sin gritar, y en oscuro se mezcla con el papel en vez de ser un foco. */
.tm-billetin-globo--secreto {
  background: color-mix(in srgb, var(--amarillo, #f5c518) 24%, var(--papel-alto));
  font-size: 14px;
  line-height: 1.38;
}

.tm-billetin-globo[hidden] {
  display: none;
}

.tm-billetin-botones {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tm-billetin-boton {
  min-height: 50px;
  padding: 8px 12px;
  border: 1px solid rgba(0, 0, 0, 0.16);
  border-radius: 14px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.12s ease;
}

:root[data-tema-tienda="oscuro"] .tm-billetin-boton {
  border-color: rgba(255, 255, 255, 0.18);
}

/* El rojo de la tienda (CLAUDE.md §11: la tienda conserva su degradado). */
.tm-billetin-boton--principal {
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  border: none;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
}

.tm-billetin-boton--principal small {
  font-size: 12.5px;
  font-weight: 600;
  opacity: 0.92;
}

.tm-billetin-boton--suave {
  min-height: 44px;
  border: none;
  background: transparent;
  color: var(--tinta-suave);
  font-size: 14px;
  font-weight: 600;
}

.tm-billetin-boton:active,
.tm-billetin-boton--escogido {
  transform: scale(0.98);
}

.tm-billetin-boton:focus-visible,
.tm-billetin-pastilla-boton:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* La pastilla de la portada, entre la primera sección y la segunda: lo
   que escogió y «Cambiar». Lleva el mismo aire que hay entre sección y
   sección. */
.tm-billetin-zona {
  margin: 10px 0 0;
}

.tm-billetin-zona + .tm-store-seccion {
  margin-top: 10px;
}

.tm-billetin-zona[hidden] {
  display: none;
}

.tm-billetin-pastilla {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px 6px 6px;
  border-radius: 18px;
  background: var(--papel-alto);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
  animation: tm-billetin-globo 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.tm-billetin-pastilla-figura {
  flex-shrink: 0;
  width: 44px;
  line-height: 0;
}

.tm-billetin-pastilla-texto {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 12.5px;
  line-height: 1.3;
  color: var(--tinta-suave);
}

.tm-billetin-pastilla-texto b {
  font-size: 14px;
  line-height: 1.25;
  color: var(--tinta);
}

.tm-billetin-pastilla-boton {
  flex-shrink: 0;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid rgba(0, 0, 0, 0.16);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--marca-hondo);
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
}

:root[data-tema-tienda="oscuro"] .tm-billetin-pastilla-boton {
  border-color: rgba(255, 255, 255, 0.18);
  color: var(--accion);
}

/* El dibujo y sus gestos. Todas las partes están dibujadas; el gesto decide
   cuáles se ven. */
.tm-billetin {
  overflow: visible;
}

.tm-billetin [data-solo] {
  display: none;
}

.tm-billetin[data-gesto="saluda"] [data-solo~="saluda"],
.tm-billetin[data-gesto="pregunta"] [data-solo~="pregunta"],
.tm-billetin[data-gesto="shh"] [data-solo~="shh"],
.tm-billetin[data-gesto="feliz"] [data-solo~="feliz"] {
  display: inline;
}

.tm-billetin-letra {
  font-weight: 700;
  text-anchor: middle;
}

.tm-billetin-respira {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: tm-billetin-respira 2.4s ease-in-out infinite;
}

.tm-billetin-capa1,
.tm-billetin-capa2 {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}

.tm-billetin-capa1 {
  animation: tm-billetin-capa1 2.4s ease-in-out infinite;
}

.tm-billetin-capa2 {
  animation: tm-billetin-capa2 2.4s ease-in-out 0.15s infinite;
}

.tm-billetin-ojo {
  transform-box: fill-box;
  transform-origin: center;
  animation: tm-billetin-parpadeo 4.8s infinite;
}

.tm-billetin-mira {
  animation: tm-billetin-mira 6s ease-in-out infinite;
}

.tm-billetin-gorra {
  transform-box: fill-box;
  transform-origin: 60% 100%;
  animation: tm-billetin-gorra 2.4s ease-in-out 0.1s infinite;
}

.tm-billetin-saluda {
  transform-box: fill-box;
  transform-origin: 0% 100%;
  animation: tm-billetin-mano 1.3s ease-in-out infinite;
}

.tm-billetin-duda {
  animation: tm-billetin-duda 1.6s ease-in-out infinite;
}

.tm-billetin-shhh {
  animation: tm-billetin-shhh 1.8s ease-in-out infinite;
}

.tm-billetin-brillo {
  transform-box: fill-box;
  transform-origin: center;
  animation: tm-billetin-brillo 1.1s ease-in-out infinite;
}

.tm-billetin-brillo--tarde {
  animation-delay: 0.4s;
}

.tm-billetin[data-gesto="feliz"] .tm-billetin-todo {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: tm-billetin-brinca 1.1s cubic-bezier(0.3, 0.7, 0.4, 1) infinite;
}

.tm-billetin[data-gesto="feliz"] .tm-billetin-sombra {
  transform-box: fill-box;
  transform-origin: center;
  animation: tm-billetin-sombra 1.1s cubic-bezier(0.3, 0.7, 0.4, 1) infinite;
}

/* En la pastilla brinca tres veces al aparecer y luego se queda respirando:
   brincando sin parar encima de los productos distraería de lo que se vino
   a comprar. */
.tm-billetin-pastilla .tm-billetin[data-gesto="feliz"] .tm-billetin-todo,
.tm-billetin-pastilla .tm-billetin[data-gesto="feliz"] .tm-billetin-sombra,
.tm-billetin-pastilla .tm-billetin-brillo {
  animation-iteration-count: 3;
}

@keyframes tm-billetin-respira {
  0%, 100% { transform: scale(1, 1); }
  50% { transform: scale(1.015, 0.985); }
}

@keyframes tm-billetin-brinca {
  0%, 85%, 100% { transform: translateY(0) scale(1, 1); }
  10% { transform: translateY(0) scale(1.05, 0.94); }
  40% { transform: translateY(-16px) scale(0.97, 1.04); }
  70% { transform: translateY(0) scale(1.04, 0.96); }
}

@keyframes tm-billetin-sombra {
  0%, 70%, 100% { transform: scale(1); }
  40% { transform: scale(0.72); }
}

@keyframes tm-billetin-capa1 {
  0%, 100% { transform: rotate(0.6deg); }
  50% { transform: rotate(1.8deg); }
}

@keyframes tm-billetin-capa2 {
  0%, 100% { transform: rotate(1.4deg); }
  50% { transform: rotate(3.4deg); }
}

@keyframes tm-billetin-parpadeo {
  0%, 91%, 97%, 100% { transform: scaleY(1); }
  94% { transform: scaleY(0.1); }
}

@keyframes tm-billetin-mira {
  0%, 35%, 100% { transform: translate(0, 0); }
  45%, 60% { transform: translate(2.6px, -0.6px); }
  70%, 85% { transform: translate(-2.4px, 0.4px); }
}

@keyframes tm-billetin-gorra {
  0%, 100% { transform: rotate(-1.5deg); }
  50% { transform: rotate(1.5deg) translateY(-1px); }
}

@keyframes tm-billetin-mano {
  0%, 100% { transform: rotate(-10deg); }
  50% { transform: rotate(16deg); }
}

@keyframes tm-billetin-duda {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}

@keyframes tm-billetin-shhh {
  0%, 100% { opacity: 0.25; transform: translateX(0); }
  50% { opacity: 1; transform: translateX(4px); }
}

@keyframes tm-billetin-brillo {
  0%, 100% { transform: scale(0.6); opacity: 0.5; }
  50% { transform: scale(1.15); opacity: 1; }
}

@keyframes tm-billetin-sube {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

@keyframes tm-billetin-baja {
  from { transform: translateY(0); }
  to { transform: translateY(100%); }
}

@keyframes tm-billetin-aparece {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes tm-billetin-desaparece {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes tm-billetin-globo {
  from { opacity: 0; transform: translateY(6px) scale(0.96); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-billetin *,
  .tm-billetin-hoja,
  .tm-billetin-velo,
  .tm-billetin-globo,
  .tm-billetin-pastilla {
    animation: none !important;
  }
}

/* El precio con descuento en la lista del buscador y en la ficha: la misma
   lectura que en la tarjeta (core/tarjeta_producto.css). */
.tm-fila-producto-descuento {
  display: none;
}

.tm-paga-inmediato .tm-fila-producto-accion--descuento .tm-fila-producto-descuento {
  display: block;
  font-size: 16px;
  font-weight: 800;
  color: var(--ok);
  font-variant-numeric: tabular-nums;
}

.tm-paga-inmediato .tm-fila-producto-accion--descuento .tm-fila-producto-precio {
  font-size: 12px;
  font-weight: 600;
  color: var(--tinta-suave);
  text-decoration: line-through;
}

.tm-paga-inmediato .tm-fila-producto-accion--descuento .store-product-price-beneficio,
.tm-paga-inmediato .tm-fila-producto-accion--descuento .tm-fila-producto-precio .store-product-price-unidad {
  display: none;
}

.tm-ficha-precio .tm-ficha-descuento {
  display: none;
}

.tm-paga-inmediato .tm-ficha-precio--descuento .tm-ficha-descuento {
  display: inline;
  color: var(--ok);
}

.tm-paga-inmediato .tm-ficha-precio--descuento .tm-ficha-lista {
  font-size: 18px;
  font-weight: 600;
  color: var(--tinta-suave);
  text-decoration: line-through;
}

/* El carrito, con efectivo escogido: el que paga en verde y el de etiqueta
   tachado. */
.tm-carrito-total-cifras {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.tm-carrito-total-cifras s {
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.tm-carrito-total--descuento strong {
  color: var(--ok);
}

.tm-carrito-importe-descuento {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}

.tm-carrito-importe-descuento .tm-carrito-importe {
  color: var(--ok);
}

.tm-carrito-importe-descuento s {
  font-size: 12px;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

/* ---------- La burbuja del pedido en curso (store/burbuja_pedido.js) ----------

   Escogida en la maqueta del 2026-10-16: el aro de colores que gira como
   las historias sin ver (G) y el meneo de campanita con su «1» (E), con el
   letrero del paso debajo (C). Todo se mueve SOLO mientras hay algo sin ver;
   al verla, el aro se pone gris y se queda quieta.

   Va debajo de la bienvenida, la presentación, la barra de «Ver mi pedido»,
   el menú y el carrito: es un recordatorio, no se pone encima de nada. */
.tm-burbuja {
  position: fixed;
  z-index: 75;
  width: 60px;
  height: 60px;
  touch-action: none;
}

.tm-burbuja[hidden] {
  display: none;
}

.tm-burbuja--suelta {
  transition: left 0.28s cubic-bezier(0.22, 1, 0.36, 1), top 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}

.tm-burbuja-boton {
  position: relative;
  width: 60px;
  height: 60px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--papel-alto);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
  cursor: grab;
  touch-action: none;
  transition: transform 0.15s ease;
}

.tm-burbuja-boton:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 9px;
}

.tm-burbuja--arrastrando .tm-burbuja-boton {
  transform: scale(1.1);
  cursor: grabbing;
}

/* La bolsita de regalo, con los colores de la marca: en el tema oscuro
   también se vuelve morada. */
.tm-burbuja-bolsa {
  width: 40px;
  height: 40px;
}

.tm-burbuja-bolsa .asa {
  fill: none;
  stroke: color-mix(in srgb, var(--marca-hondo) 75%, #000000);
  stroke-width: 2.6;
  stroke-linecap: round;
}

.tm-burbuja-bolsa .cuerpo {
  fill: var(--marca);
}

.tm-burbuja-bolsa .sombra {
  fill: var(--marca-hondo);
}

.tm-burbuja-bolsa .brillo {
  fill: #ffffff;
  opacity: 0.22;
}

.tm-burbuja-bolsa .liston,
.tm-burbuja-bolsa .mono,
.tm-burbuja-bolsa .chispa {
  fill: var(--amarillo);
}

.tm-burbuja-bolsa .mono {
  stroke: var(--naranja);
  stroke-width: 1.1;
  stroke-linejoin: round;
}

.tm-burbuja-bolsa .nudo {
  fill: var(--naranja);
}

.tm-burbuja-bolsa .chispa {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0.5;
}

.tm-burbuja--sin-ver .tm-burbuja-bolsa .chispa {
  animation: tm-burbuja-chispa 1.8s ease-in-out infinite;
}

.tm-burbuja--sin-ver .tm-burbuja-bolsa .chispa--2 {
  animation-delay: 0.9s;
}

/* El aro: gris en reposo, de colores y girando si hay algo sin ver. */
.tm-burbuja-aro {
  position: absolute;
  inset: -6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tinta) 22%, transparent);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000000 calc(100% - 3.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000000 calc(100% - 3.5px));
  pointer-events: none;
}

.tm-burbuja--sin-ver .tm-burbuja-aro {
  background: conic-gradient(var(--marca), var(--naranja), var(--amarillo), var(--naranja), var(--marca));
  animation: tm-burbuja-girar 1.8s linear infinite;
}

.tm-burbuja--llego .tm-burbuja-aro {
  background: var(--ok);
  animation: none;
}

/* La campanita: se menea cada ratito, con su «1». */
.tm-burbuja--sin-ver:not(.tm-burbuja--llego) .tm-burbuja-boton {
  transform-origin: 50% 8%;
  animation: tm-burbuja-campana 3.4s ease-in-out infinite;
}

.tm-burbuja-uno {
  display: none;
  position: absolute;
  z-index: 1;
  top: -4px;
  right: -4px;
  min-width: 21px;
  height: 21px;
  padding: 0 5px;
  border-radius: 999px;
  place-items: center;
  background: var(--marca);
  color: #ffffff;
  font-size: 12px;
  font-weight: 800;
  box-shadow: 0 0 0 2px var(--papel-alto);
}

.tm-burbuja--sin-ver:not(.tm-burbuja--llego) .tm-burbuja-uno {
  display: grid;
}

.tm-burbuja-palomita {
  display: none;
  position: absolute;
  z-index: 1;
  right: -3px;
  bottom: -3px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  place-items: center;
  background: var(--ok);
  box-shadow: 0 0 0 2px var(--papel-alto);
}

.tm-burbuja--llego .tm-burbuja-palomita {
  display: grid;
}

/* El letrero del paso, debajo. */
.tm-burbuja-letrero {
  position: absolute;
  left: 50%;
  top: 68px;
  translate: -50% 0;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--marca);
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.16);
  pointer-events: none;
}

.tm-burbuja--llego .tm-burbuja-letrero {
  color: var(--ok);
}

.tm-burbuja--nace {
  animation: tm-burbuja-nace 0.7s cubic-bezier(0.2, 1.5, 0.4, 1) both;
}

.tm-burbuja--se-va {
  animation: tm-burbuja-se-va 0.45s ease-in forwards;
}

/* La ✕ de abajo para esconderla. Sale solo mientras se arrastra, arriba
   de la barra de «Ver mi pedido». */
.tm-burbuja-x {
  position: fixed;
  z-index: 74;
  left: 50%;
  bottom: calc(100px + env(safe-area-inset-bottom));
  translate: -50% 0;
  width: 56px;
  height: 56px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: rgba(31, 31, 31, 0.78);
  color: #ffffff;
  opacity: 0;
  scale: 0.6;
  transition: opacity 0.2s ease, scale 0.2s ease, background 0.15s ease;
  pointer-events: none;
}

.tm-burbuja-x[hidden] {
  display: none;
}

.tm-burbuja-x--a-la-vista {
  opacity: 1;
  scale: 1;
}

.tm-burbuja-x--encima {
  background: var(--peligro);
  scale: 1.18;
}

/* Al tocarla: cómo va, en corto. */
.tm-burbuja-globito {
  position: fixed;
  z-index: 76;
  width: min(290px, calc(100vw - 24px));
  padding: 10px 14px 14px;
  border-radius: 18px;
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2), 0 0 0 1px var(--linea);
  animation: tm-burbuja-abre 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}

.tm-burbuja-globito[hidden] {
  display: none;
}

.tm-burbuja-globito-cabeza {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tm-burbuja-globito-cabeza .tm-burbuja-bolsa {
  width: 26px;
  height: 26px;
}

.tm-burbuja-globito-cabeza .chispa {
  display: none;
}

.tm-burbuja-folio {
  font-size: 13px;
  font-weight: 600;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

.tm-burbuja-cerrar {
  margin-left: auto;
  width: 44px;
  height: 44px;
  margin-right: -8px;
  border: 0;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: transparent;
  color: var(--tinta-suave);
  cursor: pointer;
}

.tm-burbuja-cerrar svg {
  width: 18px;
  height: 18px;
}

.tm-burbuja-estado {
  margin: 0 0 12px;
  font-size: 20px;
  font-weight: 800;
  line-height: 1.2;
}

.tm-burbuja-pasos {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.tm-burbuja-pasos li {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  line-height: 1.2;
  color: var(--tinta-tenue);
  text-align: center;
}

.tm-burbuja-pasos li::before {
  content: "";
  position: relative;
  z-index: 1;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--papel-hondo);
}

.tm-burbuja-pasos li::after {
  content: "";
  position: absolute;
  top: 5px;
  left: -50%;
  width: 100%;
  height: 2px;
  background: var(--papel-hondo);
}

.tm-burbuja-pasos li:first-child::after {
  display: none;
}

.tm-burbuja-pasos .tm-burbuja-paso--hecho::before,
.tm-burbuja-pasos .tm-burbuja-paso--hecho::after,
.tm-burbuja-pasos .tm-burbuja-paso--ahora::before,
.tm-burbuja-pasos .tm-burbuja-paso--ahora::after {
  background: var(--ok);
}

.tm-burbuja-pasos .tm-burbuja-paso--ahora {
  color: var(--tinta);
  font-weight: 700;
}

.tm-burbuja-pasos .tm-burbuja-paso--ahora::before {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 20%, transparent);
}

.tm-burbuja-frase {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 6px;
  font-size: 13.5px;
  line-height: 1.4;
}

.tm-burbuja-frase svg {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--marca);
}

.tm-burbuja-cuenta {
  margin: 0 0 12px 26px;
  font-size: 13px;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

.tm-burbuja-cuenta b {
  color: var(--tinta);
}

.tm-burbuja-detalle {
  width: 100%;
  min-height: 48px;
  border: 0;
  border-radius: 14px;
  background: linear-gradient(135deg, var(--marca), var(--marca-hondo));
  color: #ffffff;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}

.tm-burbuja-detalle:focus-visible,
.tm-burbuja-cerrar:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

@keyframes tm-burbuja-girar {
  to { rotate: 360deg; }
}

@keyframes tm-burbuja-campana {
  0%, 24%, 100% { rotate: 0deg; }
  3% { rotate: -16deg; }
  6% { rotate: 13deg; }
  9% { rotate: -10deg; }
  12% { rotate: 7deg; }
  15% { rotate: -4deg; }
  18% { rotate: 2deg; }
}

@keyframes tm-burbuja-chispa {
  0%, 100% { opacity: 0.35; scale: 0.6; }
  50% { opacity: 1; scale: 1.15; }
}

@keyframes tm-burbuja-nace {
  from { scale: 0; opacity: 0; }
  to { scale: 1; opacity: 1; }
}

@keyframes tm-burbuja-se-va {
  to { scale: 0; opacity: 0; }
}

@keyframes tm-burbuja-abre {
  from { opacity: 0; scale: 0.94; }
}

/* Sin movimiento: el aro de colores y el «1» bastan para decir que hay algo. */
@media (prefers-reduced-motion: reduce) {
  .tm-burbuja--sin-ver .tm-burbuja-aro,
  .tm-burbuja--sin-ver .tm-burbuja-boton,
  .tm-burbuja--sin-ver .tm-burbuja-bolsa .chispa,
  .tm-burbuja--nace,
  .tm-burbuja-globito {
    animation: none;
  }

  .tm-burbuja--suelta {
    transition: none;
  }

  .tm-burbuja--se-va {
    animation-duration: 0.01s;
  }
}
