/* Componentes base compartidos por los cuatro clientes. En Admin y POS el
   color de acción es el azul (--accion); el rojo (--marca) queda reservado
   a la tienda. --peligro es solo para cancelar/borrar. */

/* ---------- Shell de aplicación: mecanismo compartido por Admin y POS.
   Cada shell arma su propia rejilla (con o sin columna de navegación) en su
   propio CSS; aquí solo lo que es igual en los dos: el shell ocupa
   exactamente el alto de la pantalla y no se desplaza él mismo — solo
   .tm-contenido tiene scroll propio, así el banner (y la navegación, donde
   exista) quedan fijos siempre sin trucos de position:sticky. ---------- */

html,
body {
  height: 100%;
}

.tm-shell {
  height: 100vh;
  height: 100dvh;
  display: grid;
  overflow: hidden;
}

/* El banner combina con la paleta elegida en Ajustes/Tema (--accion), no un
   color fijo aparte. */
.tm-topbar {
  grid-area: topbar;
  height: 68px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--accion);
  overflow: hidden;
}

.tm-topbar-marca {
  flex-shrink: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 800;
  font-size: 22px;
  color: #ffffff;
  letter-spacing: -0.3px;
}

.tm-topbar-separador {
  flex-shrink: 0;
  color: rgba(255, 255, 255, 0.35);
}

/* El título de cada vista se fusiona aquí (establecerTituloPagina en
   core/ui.js) en vez de repetirse como <h1> dentro del contenido — libera
   una fila completa de alto en cada pantalla. Sigue siendo un <h1> real
   para accesibilidad, solo que se ve como texto de breadcrumb. */
.tm-topbar-seccion {
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.85);
  font-size: 16px;
  font-weight: 700;
}

/* ---------- Reloj y fecha en la barra superior ----------
   Solo de tableta para arriba, donde sobra barra. En el teléfono la barra se
   queda con lo que se toca —menú, pantalla, estrella, asistente, campanita—:
   la hora ya la trae el propio teléfono arriba.

   Aquí vivía también el letrero de abierto/cerrado, en todas las pantallas.
   El dueño lo sacó el 2026-10-13: «no me gustó cómo se ve en todos lados ahí
   en ese banner morado… así tendrá más chance de respirar el contenido y
   palabras que hay ahí». Ahora va en el menú, junto al nombre del negocio
   (ver «El letrero de abierto, en el menú», más abajo). */

.tm-banner-info {
  display: none;
  margin-left: auto;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

@media (min-width: 768px) {
  .tm-banner-info {
    display: flex;
  }
}

/* En el teléfono la barra va más apretada por los lados, y el nombre un par
   de puntos más chico: con el botón del menú, la estrella, el asistente y la
   campanita, cada píxel cuenta. */
@media (max-width: 767px) {
  .tm-topbar {
    padding: 0 12px;
    gap: 8px;
  }

  .tm-topbar-marca {
    font-size: 19px;
  }
}

/* Por debajo de 420px no hay lugar para la marca Y el nombre de la sección:
   se aplastaba a un guion suelto ("TeleMarket / \") y se veía roto. Se
   esconde entero: la barra de navegación de abajo ya marca en qué sección
   estás. (Con el menú en cajón es al revés: se va la marca y se queda la
   sección; ver «En el teléfono angosto», al final de esta hoja.) */
@media (max-width: 419px) {
  .tm-topbar-separador,
  .tm-topbar-seccion {
    display: none;
  }
}

/* La pastilla de «Abierto / Cerrado» de Ajustes → Mi negocio → Horario. El
   nombre le quedó de cuando también era la de la barra; la del menú es
   .tm-nav-estado. Sobre papel toma los colores de gestion.css. */
.tm-banner-estado {
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
}

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

.tm-banner-estado--abierto {
  background: var(--ok);
  color: #ffffff;
}

.tm-banner-estado--cerrado {
  background: var(--peligro);
  color: #ffffff;
}

.tm-banner-reloj {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.15;
  color: #ffffff;
}

.tm-banner-fecha {
  font-size: 11px;
  opacity: 0.75;
  white-space: nowrap;
}

.tm-banner-hora {
  font-size: 13px;
  font-weight: 700;
}

.tm-contenido {
  grid-area: contenido;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ---------- Navegación principal: compartida por Admin y POS. Mobile-first:
   barra inferior con áreas táctiles ≥48px y alcance del pulgar; en
   escritorio se convierte en columna lateral fija. Ninguna función vive
   solo en un ancho — es la misma barra, solo cambia de posición (CLAUDE.md
   sección 11). Con más de 5-6 secciones ya no caben todas a lo ancho sin
   apretarlas por debajo del mínimo táctil, así que la barra se vuelve
   desplazable — mismo patrón que .tm-submenu, nunca se oculta ninguna
   sección. Fondo pastel: el mismo tono del tema, muy diluido, para que la
   columna se sienta parte del sistema sin competir con el contenido. Cada
   shell arma su propia rejilla (grid-template-areas/columns) y sus propios
   colores de icono por sección; aquí solo el comportamiento común a los
   dos. */
.tm-nav {
  grid-area: nav;
  display: flex;
  overflow-x: auto;
  background: var(--accion-pastel);
  border-top: 1px solid var(--linea);
  padding-bottom: env(safe-area-inset-bottom);
  scrollbar-width: none;
}

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

.tm-nav-enlace {
  flex: 0 0 auto;
  width: 74px;
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  margin: 4px 3px;
  border-radius: 12px;
  text-decoration: none;
  color: var(--tinta-suave);
  font-size: 10.5px;
  font-weight: 700;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.tm-nav-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  color: var(--tinta-suave);
}

/* El nombre del negocio, arriba del menú, y junto a él el letrero de
   abierto/cerrado. Ocupa el lugar que tenía la Trastienda, con la misma
   línea que lo separa de las secciones: es el negocio donde trabajas, no una
   sección más. El icono va en gris neutro para no competir con los colores
   de las de abajo.

   Aquí va la forma de la barra de abajo (nombre y letrero en fila, como un
   botón más); la columna de la computadora y el cajón del teléfono ponen la
   suya, cada una en su bloque. */
.tm-nav-negocio {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 2px;
  padding-right: 6px;
}

.tm-nav-icono--negocio {
  color: var(--tinta-suave);
}

/* Para quien no puede cambiar los datos del negocio el nombre es un letrero,
   no un enlace: que el cursor no prometa lo contrario. */
.tm-nav-enlace--letrero {
  cursor: default;
}

/* Un nombre largo se corta con puntos, no empuja el menú. En la barra de
   abajo cada botón mide 74 pixeles, y «Abarrotes y Cremería La Esperanza»
   no cabe ni cabrá. */
.tm-nav-enlace--negocio .tm-nav-texto {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La sección activa se marca con el color sólido, no un tinte — sobre el
   fondo pastel de la columna, un tinte igual de suave se perdía y costaba
   notar en dónde estabas. El SVG hereda el color por currentColor. */
.tm-nav-enlace--activo {
  background: var(--accion);
  color: #ffffff;
}

.tm-nav-enlace--activo .tm-nav-icono {
  color: #ffffff;
}

/* Secciones todavía no construidas: visibles, con su icono y su color, pero
   inertes — nunca un enlace roto. */
.tm-nav-enlace--pendiente {
  cursor: default;
  opacity: 0.55;
}

.tm-nav-pronto {
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

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

/* Tableta y escritorio: la navegación se convierte en barra lateral fija,
   nunca se oculta ninguna función, solo cambia de posición. */
@media (min-width: 768px) {
  .tm-nav {
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 4px;
    padding: 16px 12px;
    border-top: none;
    border-right: 1px solid var(--linea);
    overflow-y: auto;
  }

  .tm-nav-enlace {
    flex: 0 0 auto;
    width: auto;
    flex-direction: row;
    justify-content: flex-start;
    gap: 10px;
    margin: 0;
    padding: 0 12px;
    border-radius: 12px;
    font-size: 13px;
  }

  .tm-nav-pronto {
    margin-left: auto;
  }

  /* En la columna el letrero va DEBAJO del nombre, no al lado: la columna
     mide 240px y, lado a lado, «El Porvenir» se cortaba en «El Porve…» para
     hacerle sitio. Abajo sobra alto. La sangría lo alinea con el nombre:
     12 de relleno del renglón, 22 del icono y 10 de separación. */
  .tm-nav-negocio {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0 0 12px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--linea);
  }

  .tm-nav-negocio .tm-nav-enlace--negocio {
    min-height: 44px;
  }

  .tm-nav-negocio .tm-nav-estado {
    align-self: flex-start;
    margin-left: 44px;
  }
}

.tm-boton {
  min-height: 48px;
  padding: 0 20px;
  border: 1px solid transparent;
  border-radius: var(--boton-radio);
  font-weight: 700;
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  background: var(--accion);
  color: #ffffff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  /* Una etiqueta partida en dos renglones —"Guardar / privilegios"— hace
     que el botón parezca roto. Si no cabe, que se acomode el renglón de
     botones, no la palabra. */
  white-space: nowrap;
  box-shadow: var(--boton-sombra-accion);
  transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease, transform 0.06s ease;
}

/* El foco de teclado tiene que verse (CLAUDE.md sección 11). Va por fuera
   del botón para que no lo tape su propio fondo. */
.tm-boton:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* Solo donde hay cursor de verdad: en pantalla táctil el hover se queda
   pegado después de tocar y el botón se ve "atorado". */
@media (hover: hover) {
  .tm-boton:hover {
    filter: brightness(0.93);
  }

  .tm-boton--secundario:hover {
    filter: none;
    border-color: var(--tinta-tenue);
  }
}

/* display:inline-flex de arriba, si no se acota, gana sobre la regla nativa
   [hidden]{display:none} del navegador. Se restaura explícitamente. */
.tm-boton[hidden] {
  display: none;
}

/* Se hunde un pixel y pierde la sombra: se siente apretado sin parpadear. */
.tm-boton:active {
  transform: translateY(var(--boton-hundir));
  box-shadow: none;
}

.tm-boton:disabled,
.tm-boton--cargando {
  cursor: not-allowed;
  opacity: 0.6;
}

.tm-boton--secundario {
  background: var(--papel-alto);
  color: var(--tinta);
  border-color: var(--boton-borde);
  box-shadow: var(--boton-sombra);
}

/* Delineado en rojo, no relleno (estilo Stripe): junto a «Cobrar» se
   distingue por el color y no compite con él por peso. */
.tm-boton--peligro {
  background: var(--papel-alto);
  color: var(--peligro);
  border-color: color-mix(in srgb, var(--peligro) 45%, transparent);
  box-shadow: var(--boton-sombra);
}

.tm-boton--peligro:focus-visible {
  outline-color: var(--peligro);
}

.tm-boton--primario {
  background: var(--accion);
  color: #ffffff;
}

.tm-campo {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

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

.tm-campo label {
  font-size: 12px;
  font-weight: 700;
  color: var(--tinta-suave);
}

.tm-campo input,
.tm-campo select,
.tm-campo textarea {
  min-height: 48px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
}

.tm-tabla {
  width: 100%;
  border-collapse: collapse;
}

.tm-tabla th,
.tm-tabla td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--linea);
}

.tm-panel {
  background: var(--papel-alto);
  border-radius: var(--radio-panel);
  border: 1px solid var(--linea);
  box-shadow: var(--sombra-suave);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

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

.tm-panel h2 {
  margin: 0;
  font-size: 15px;
}

/* ---------- Formulario de producto: dos columnas en escritorio para
   aprovechar el ancho y no dejar la página tan alta (menos aire, mismo
   contenido). Una sola columna en móvil, mobile-first. ---------- */

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

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

.tm-formulario-col {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

@media (min-width: 768px) {
  .tm-formulario-columnas {
    flex-direction: row;
    align-items: flex-start;
  }

  .tm-formulario-col {
    flex: 1;
    min-width: 0;
  }
}

/* ---------- Toast ---------- */

.tm-toasts {
  position: fixed;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 100;
  width: min(360px, calc(100vw - 32px));
}

.tm-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  position: relative;
  overflow: hidden;
  padding: 13px 16px;
  border-radius: 14px;
  background: var(--tinta);
  color: #ffffff;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
  /* Más profunda que las sombras del resto: el aviso flota por encima de
     todo y tiene que despegarse de lo que hay debajo. */
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
  opacity: 1;
  transition: opacity 0.18s ease, transform 0.18s ease;
  animation: tm-toast-entra 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

/* El icono va en su propio disco translúcido: da peso al aviso y separa el
   símbolo del texto sin una línea. */
.tm-toast-icono {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
}

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

.tm-toast-texto {
  flex: 1;
  min-width: 0;
}

/* Una barra que se vacía: se ve cuánto le queda al aviso en vez de que
   desaparezca de sorpresa. */
.tm-toast-tiempo {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 100%;
  transform-origin: left;
  background: rgba(255, 255, 255, 0.45);
  animation-name: tm-toast-tiempo;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

@keyframes tm-toast-entra {
  from { opacity: 0; transform: translateY(14px) scale(0.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes tm-toast-tiempo {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}

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

.tm-toast--peligro {
  background: var(--peligro);
}

.tm-toast--ok {
  background: var(--ok);
}

/* Deshacer salió bien: va en tinta, no en rojo. El rojo de este sistema
   significa cancelar o error, y quitar algo de una lista no es ninguno
   de los dos. */
.tm-toast--quitado {
  background: var(--tinta);
}

.tm-toast--saliendo {
  opacity: 0;
  transform: translateY(6px);
}

/* ---------- Modal de confirmación ---------- */

.tm-modal-fondo {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 200;
}

.tm-modal {
  background: var(--papel-alto);
  border-radius: var(--radio-panel);
  padding: 20px;
  max-width: 360px;
  width: 100%;
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.12);
}

.tm-modal-texto {
  margin: 0 0 16px;
  font-size: 14px;
}

.tm-modal-acciones {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* ---------- Vistas de prueba ---------- */

.tm-vista {
  padding: 4px;
}

.tm-vista h1 {
  font-size: 20px;
  margin: 0 0 8px;
}

.tm-vista-proximamente {
  color: var(--tinta-tenue);
}

/* ---------- Indicador de carga de navegación ---------- */

/* ---------- Que algo está cargando ----------

   Una línea delgada que barre el borde superior del contenido.

   Antes era la palabra «cargando…» a media pantalla, en amarillo con
   contorno, con las letras brincando. El dueño la retiró y su razón es la
   buena: sus navegaciones tardan décimas de segundo, así que lo más grande
   de la pantalla aparecía y desaparecía de golpe por una espera que casi no
   existe. Un indicador que se nota más que la espera estorba.

   Va en la MISMA celda de la rejilla que el contenido, alineada arriba. Así
   queda pegada exactamente al borde donde termina el banner, sin números
   mágicos que se rompan cuando el banner cambie de alto, y sin empujar nada:
   dos elementos en la misma celda se enciman.

   Y va en el rojo de marca, no en gris. La versión anterior de esto se
   descartó porque «una barrita gris arriba se confunde con la del navegador
   y nadie la ve» — con el color de la tienda y pegada al contenido, no hay
   con qué confundirla. */

.tm-indicador-carga {
  grid-area: contenido;
  align-self: start;
  /* `relative` porque el barrido va dentro con `absolute`: sin esto se
     posicionaría contra la página entera y cruzaría toda la pantalla. */
  position: relative;
  z-index: 20;
  height: 3px;
  width: 100%;
  overflow: hidden;
  pointer-events: none;
  background: transparent;
}

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

/* El barrido es un degradado que cruza de lado a lado. No es una barra de
   progreso: no sabemos cuánto falta, y fingir un porcentaje sería mentir. */
.tm-indicador-carga::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--marca), transparent);
  animation: tm-barrido 1.15s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

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

/* Sin movimiento se queda una línea fija: sigue diciendo «espera» sin
   animarse. Desaparecerla dejaría a esas personas sin ninguna señal. */
@media (prefers-reduced-motion: reduce) {
  .tm-indicador-carga::after {
    animation: none;
    background: var(--marca);
    opacity: 0.55;
  }
}

/* ---------- Menú desplegable de acciones (reemplaza a la fila fija de
   pestañas: "Más acciones" en vez de tabs siempre visibles) ---------- */

/* En pantalla chica el panel NO cuelga del botón: se ancla a la barra de
   acciones completa y ocupa su ancho. Colgándolo del botón se salía por la
   izquierda de la pantalla, porque el botón vive pegado a la derecha y el
   panel crece hacia el otro lado. Anclarlo al contenedor lo mantiene
   siempre dentro, sin calcular posiciones en JavaScript. */
.tm-menu {
  position: static;
}

.tm-menu-panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 6px;
  background: var(--papel-alto);
  border-radius: 14px;
  border: 1px solid var(--linea);
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.12);
}

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

.tm-menu-icono {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--tinta-suave);
}

.tm-menu-opcion:hover {
  background: var(--papel-hondo);
}

.tm-menu-opcion--activa {
  color: var(--accion);
  font-weight: 700;
}

.tm-menu-opcion--activa .tm-menu-icono {
  color: var(--accion);
}

@media (min-width: 768px) {
  /* Con espacio de sobra vuelve a ser un desplegable normal colgado del
     botón: ocupar toda la fila se vería desproporcionado. */
  .tm-menu {
    position: relative;
  }

  .tm-menu-panel {
    left: auto;
    right: 0;
    min-width: 250px;
  }
}

/* ---------- Encabezado de sección: título + acciones ---------- */

/* El título ya no vive aquí — está en la barra superior del shell
   (breadcrumb "TeleMarket / X", ver establecerTituloPagina en core/ui.js).
   Esta fila es solo para los controles de la página: el menú "Más acciones"
   y, si aplica, un botón primario propio de esa vista. */
.tm-barra-acciones {
  position: relative; /* ancla del panel "Más acciones" en pantalla chica */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-bottom: 16px;
}

.tm-barra-acciones-derecha {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* ---------- Búsqueda ---------- */

.tm-busqueda {
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  border-radius: 12px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
  font-size: 14px;
  margin-bottom: 16px;
}

.tm-cargar-mas {
  margin-top: 16px;
}

/* ---------- Filas de lista (departamentos, categorías, importaciones) ---------- */

.tm-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  margin-bottom: 8px;
}

.tm-fila-nombre {
  font-weight: 700;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-fila-acciones {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.tm-fila-boton {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: none;
  background: var(--papel-hondo);
  color: var(--tinta);
  font-size: 16px;
  cursor: pointer;
}

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

.tm-subfilas {
  padding-left: 20px;
  margin-bottom: 12px;
}

/* ---------- Departamentos plegados ----------

   Esta pantalla medía VEINTISIETE pantallas de alto —quince mil píxeles— con
   treinta y seis departamentos abiertos a la vez y todas sus categorías
   colgando. Para llegar al último había que deslizar veintisiete veces.

   Plegados es lo natural: uno viene a tocar UN departamento, no a leer los
   treinta y seis. El que se abre se queda abierto al recargar, para que
   agregar una categoría no cierre lo que se estaba editando. */

.tm-depto {
  margin-bottom: 8px;
  border-radius: 14px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  overflow: hidden;
}

.tm-depto-cabeza {
  display: flex;
  align-items: center;
  gap: 10px;
  /* 52 de alto: sigue siendo cómodo para el pulgar sin ser una tarjeta. */
  min-height: 52px;
  padding: 8px 14px;
  cursor: pointer;
  list-style: none;
}

/* La flecha propia del navegador sobra: ya hay una dibujada. */
.tm-depto-cabeza::-webkit-details-marker { display: none; }

.tm-depto-cabeza:hover {
  background: var(--papel-hondo);
}

.tm-depto-flecha {
  flex: none;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  color: var(--tinta-tenue);
  transition: transform 0.15s ease;
}

.tm-depto-flecha svg { width: 18px; height: 18px; }

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

/* Cuántas categorías tiene, sin abrirlo. Es la pregunta que uno se hace
   antes de decidir si vale la pena desplegarlo. */
.tm-depto-cuantas {
  flex: none;
  min-width: 24px;
  height: 22px;
  padding: 0 7px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 12px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tm-depto .tm-subfilas {
  padding: 0 14px 12px 34px;
  margin-bottom: 0;
}

/* Una categoría es UNA PALABRA. No necesita una tarjeta de cien píxeles de
   alto: con cuarenta y cuatro se toca bien y caben el triple en pantalla. */
.tm-fila--compacta {
  min-height: 44px;
  padding: 6px 12px;
  margin-bottom: 6px;
  border-radius: 10px;
  background: var(--papel);
}

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

/* ---------- Secuencia de paneles (importación) ---------- */

.tm-secciones {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.tm-preview-scroll {
  max-height: 360px;
  overflow-y: auto;
}

.tm-fila-con-error {
  margin-bottom: 8px;
}

.tm-fila-error {
  margin: -4px 0 0 4px;
  font-size: 12px;
  color: var(--peligro);
}

.tm-espacio-superior {
  margin-top: 12px;
}

/* ---------- Botón flotante de volver ---------- */

.tm-boton-volver {
  position: fixed;
  z-index: 70;
  top: 84px;
  left: 12px;
  width: 50px;
  height: 50px;
  border-radius: 999px;
  background: var(--accion);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 20px rgba(27, 77, 228, 0.32);
  text-decoration: none;
}

.tm-boton-volver:focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: 3px;
}

.tm-boton-volver:active {
  transform: scale(0.95);
}

@media (prefers-reduced-motion: reduce) {
  .tm-boton-volver:active {
    transform: none;
  }
}

@media (min-width: 768px) {
  .tm-boton-volver {
    top: 92px;
    left: 264px;
  }
}

/* ---------- Selector de tema (Ajustes) ---------- */

/* Los cuatro en un renglón. Con `flex-wrap` cabían tres y el último se
   quedaba solo abajo, como si sobrara. */
.tm-temas {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.tm-temas .tm-tema-opcion {
  min-width: 0;
  padding: 12px 4px;
  text-align: center;
}

.tm-tema-opcion {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-width: 84px;
  padding: 12px 10px;
  border: 2px solid transparent;
  border-radius: 14px;
  background: var(--papel-hondo);
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
  color: var(--tinta);
}

.tm-tema-opcion--activa {
  border-color: var(--accion);
  background: var(--accion-tenue);
}

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

.tm-tema-muestra {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}

/* ---------- Ajustes: negocio y ticket ---------- */

.tm-ajustes-logo-previa {
  width: 120px;
  height: 120px;
  border-radius: 12px;
  border: 1px dashed var(--tinta-tenue);
  background: var(--papel-hondo);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  cursor: pointer;
  margin-bottom: 8px;
}

.tm-ajustes-logo-imagen {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.tm-ajustes-ticket {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.tm-ajustes-ticket-controles {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  min-width: 0;
}

/* Un hijo de flex se niega a bajar del ancho de su contenido si no se le
   dice; sin esto la columna de controles empujaba el panel a lo ancho.

   Y cada tarjeta llena su renglón: sin `flex` medían lo que su contenido,
   y «Formato de impresión», que solo trae dos listas, quedaba a media
   pantalla junto a las demás a todo lo ancho. Si caben dos de 260, van
   lado a lado y parejas. */
.tm-ajustes-ticket-controles > * {
  min-width: 0;
  flex: 1 1 260px;
}

.tm-ajustes-plantillas,
.tm-ajustes-ancho {
  display: flex;
  gap: 8px;
}

.tm-ajustes-ticket-previa {
  background: var(--papel-hondo);
  border-radius: var(--radio-panel);
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.tm-ajustes-ticket-iframe {
  width: 100%;
  max-width: 320px;
  height: 480px;
  border: 1px solid var(--linea);
  border-radius: 8px;
  background: #ffffff;
}

.tm-ajustes-ticket-previa .tm-ajustes-pista {
  text-align: center;
  max-width: 320px;
}

/* ---------- Editor de botones rápidos del POS ---------- */

.tm-ajustes-interruptor {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.tm-ajustes-interruptor input {
  width: 20px;
  height: 20px;
  accent-color: var(--accion);
  flex-shrink: 0;
}

.tm-ajustes-pista {
  font-weight: 400;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* Un interruptor con su explicación: el texto a la izquierda y la palanca
   a la derecha, en el mismo renglón, como en los ajustes del teléfono.
   `paneles_ajustes.js` las pinta desde que existen, pero la regla nunca se
   escribió: la palanca caía debajo del texto, y en la computadora repetía
   el título a su lado. */
.tm-opcion {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 48px;
}

.tm-opcion .tm-opcion-texto strong {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--tinta);
}

.tm-opcion .tm-opcion-texto span {
  font-size: 13px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-opcion .tm-palanca {
  flex-shrink: 0;
}

.tm-opcion .tm-palanca-texto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.tm-opcion + .tm-opcion {
  padding-top: 14px;
  border-top: 1px solid var(--linea);
}

.tm-botones-elegidos {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-boton-elegido {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--papel-hondo);
  border-radius: 12px;
}

.tm-boton-elegido-icono {
  display: flex;
  color: var(--accion);
  flex-shrink: 0;
}

.tm-boton-elegido-nombre {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 700;
}

.tm-botones-disponibles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
}

.tm-boton-disponible {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 48px;
  padding: 8px 12px;
  border: 1px dashed var(--tinta-tenue);
  border-radius: 12px;
  background: transparent;
  color: var(--tinta);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.tm-boton-disponible:hover,
.tm-boton-disponible:focus-visible {
  border-style: solid;
  border-color: var(--accion);
  background: var(--accion-tenue);
}

.tm-boton-disponible span:first-child {
  display: flex;
  color: var(--tinta-suave);
  flex-shrink: 0;
}

/* ---------- Estado vacío ---------- */

/* Las pantallas cuando no hay nada. El dibujo va apagado a propósito: es
   compañía para el hueco, no algo que compita con lo que sí importa
   cuando la lista se llena. */
.tm-vacio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 36px 20px;
  text-align: center;
  color: var(--tinta-tenue);
}

.tm-vacio-dibujo {
  width: 64px;
  height: 64px;
  color: var(--linea);
  /* La línea sola se ve raquítica sobre el papel: se sube el contraste solo
     lo justo para que se lea como dibujo y no como una mancha. */
  color: rgba(0, 0, 0, 0.13);
}

.tm-vacio-titulo {
  margin: 0;
  color: var(--tinta-suave);
  font-size: 15px;
  font-weight: 600;
}

.tm-vacio-pista {
  margin: 0;
  max-width: 34ch;
  color: var(--tinta-tenue);
  font-size: 13px;
  line-height: 1.5;
}

.tm-vacio .tm-boton {
  margin-top: 4px;
}

/* Cuando no haber nada es la buena noticia: todo al día. */
.tm-vacio--bien .tm-vacio-dibujo { color: var(--ok); opacity: 0.5; }
.tm-vacio--bien .tm-vacio-titulo { color: var(--ok); }

/* ---------- Tabla de productos (Admin, ≥768px) y su respaldo en tarjetas
   apiladas en pantalla angosta — nunca una tabla con scroll horizontal
   (CLAUDE.md sección 11). Mobile-first: la tabla empieza oculta. ---------- */

.tm-tabla-productos {
  display: none;
  width: 100%;
  border-collapse: collapse;
  background: var(--papel-alto);
  border-radius: var(--radio-panel);
  overflow: hidden;
  box-shadow: var(--sombra-suave);
}

.tm-tabla-productos th {
  text-align: left;
  padding: 12px 16px;
  font-size: 11px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tinta-suave);
  border-bottom: 1px solid var(--linea);
}

.tm-tabla-productos td {
  padding: 10px 16px;
  border-bottom: 1px solid var(--linea);
  font-size: 14px;
  vertical-align: middle;
}

.tm-tabla-productos tbody tr:last-child td {
  border-bottom: none;
}

.tm-tabla-producto-celda {
  display: flex;
  align-items: center;
  gap: 10px;
}

.tm-tabla-miniatura,
.tm-tabla-miniatura-vacia {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  flex-shrink: 0;
  background: var(--papel-hondo);
  object-fit: cover;
}

.tm-tabla-nombre-boton {
  background: none;
  border: none;
  padding: 2px 0;
  font: inherit;
  font-weight: 400;
  color: var(--tinta);
  cursor: pointer;
  text-align: left;
}

.tm-tabla-nombre-boton:hover {
  color: var(--accion);
}

.tm-tabla-nombre-boton:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
  border-radius: 4px;
}

.tm-tabla-precio {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tm-tabla-acciones-celda {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}

/* Existencias editables dentro de la tabla. El color habla del stock
   (ámbar en el mínimo, rojo en cero), no del estado web: son cosas
   distintas y este campo es el del inventario. Vive en core porque la
   misma tabla se monta en Admin y en POS. */
.tm-tabla-stock {
  width: 78px;
  min-height: 40px;
  padding: 4px 8px;
  border: 1px solid var(--linea);
  border-radius: 8px;
  font: inherit;
  font-weight: 700;
  text-align: right;
  background: var(--papel-alto);
  color: var(--tinta);
}

.tm-tabla-stock:focus {
  border-color: var(--accion);
}

.tm-tabla-stock:disabled {
  opacity: 0.5;
}

.tm-tabla-stock--ok {
  background: var(--ok-fondo);
  color: var(--ok);
}

.tm-tabla-stock--alerta {
  background: #fdf1e0;
  color: var(--alerta);
}

.tm-tabla-stock--peligro {
  background: var(--peligro-fondo);
  color: var(--peligro);
}

@media (min-width: 768px) {
  .tm-tabla-productos {
    display: table;
  }

  /* Doble clase a propósito: .store-grid (tarjeta_producto.css) también fija
     su propio display:grid sin media query, y por cargarse después en el
     <head> le gana a esta regla en un empate de especificidad. Con las dos
     clases juntas la especificidad es mayor y esta regla gana siempre. */
  .tm-tarjetas-productos-movil.store-grid {
    display: none;
  }
}

/* ---------- Etiquetas de severidad (importación, validación) ---------- */

.tm-etiqueta {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
}

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

.tm-etiqueta--peligro {
  background: var(--peligro-fondo);
  color: var(--peligro);
}

.tm-etiqueta--info {
  background: var(--papel-hondo);
  color: var(--tinta-suave);
}

.tm-etiqueta--alerta {
  background: #fdf1e0;
  color: var(--alerta);
}

/* ---------- Checkbox ---------- */

.tm-checkbox {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 2px 0;
  cursor: pointer;
  font-size: 14px;
}

/* Una casilla que va sola en su renglón, sin pareja al lado. Es para las
   que se confunden con la de junto: «Es alcohol» y «Solo adultos» hacen
   cosas distintas —una bloquea la venta con ley seca y la otra pone el aviso
   de +18— y en la misma fila se marcaba una creyendo que hacía lo de la
   otra. Separarlas cuesta un renglón y evita vender lo que no se debe. */
.tm-checkbox--solo {
  margin-top: 10px;
}

.tm-checkbox input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--accion);
  outline: 1.5px solid var(--tinta-tenue);
  outline-offset: 1px;
  border-radius: 3px;
  cursor: pointer;
}

/* ---------- Formulario en línea (agregar departamento, categoría, lista) ---------- */

.tm-linea-formulario {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}

.tm-linea-formulario input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
}

.tm-linea-formulario input:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

.tm-linea-formulario--compacta {
  margin: 6px 0 16px;
}

.tm-linea-formulario--compacta input {
  min-height: 40px;
  border-radius: 10px;
  font-size: 13px;
}

.tm-linea-formulario--en-fila {
  flex: 1;
  margin: 0;
}

.tm-linea-formulario--en-fila input {
  min-height: 36px;
  border-radius: 8px;
  padding: 0 10px;
  font-size: 13px;
}

/* ---------- Fila de conversión de unidad ---------- */

.tm-conversion-fila {
  display: flex;
  gap: 8px;
  margin-bottom: 6px;
}

.tm-conversion-fila input {
  min-height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
}

.tm-conversion-fila input:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

.tm-conversion-fila input[data-conversion="nombre"] {
  flex: 1;
  min-width: 0;
}

.tm-conversion-fila input[data-conversion="factor"] {
  width: 96px;
  flex-shrink: 0;
}

/* ---------- Imagen de previsualización ---------- */

.tm-imagen-previa {
  width: 108px;
  height: 108px;
  border-radius: 14px;
  object-fit: cover;
  margin-bottom: 10px;
  border: 1px solid var(--linea);
}

/* ---------- Selector propio del sistema (reemplaza <select> nativo) ---------- */

.tm-selector {
  position: relative;
}

.tm-selector-boton {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 14px;
  font-family: inherit;
  color: var(--tinta);
  cursor: pointer;
  text-align: left;
}

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

.tm-selector-texto {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-selector-texto--marcador {
  color: var(--tinta-tenue);
}

.tm-selector-flecha {
  flex-shrink: 0;
  display: inline-flex;
  color: var(--tinta-suave);
  transition: transform 0.15s ease;
}

.tm-selector--abierto .tm-selector-flecha {
  transform: rotate(180deg);
}

.tm-selector-panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--papel-alto);
  border-radius: 14px;
  border: 1px solid var(--linea);
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.12);
}

.tm-selector-opcion {
  padding: 11px 12px;
  border-radius: 10px;
  cursor: pointer;
  font-size: 14px;
}

.tm-selector-opcion:hover,
.tm-selector-opcion--resaltada {
  background: var(--papel-hondo);
}

.tm-selector-opcion--activa {
  color: var(--accion);
  font-weight: 700;
}

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

/* ---------- Personal (quién entra al sistema) ---------- */

.tm-personal {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tm-personal-yo {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.tm-personal-yo-datos {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.tm-personal-yo-nombre {
  font-size: 16px;
  font-weight: 700;
}

.tm-personal-yo .tm-boton {
  flex-shrink: 0;
  white-space: nowrap;
}

.tm-personal-yo-rol {
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-personal-alta {
  align-self: flex-start;
}

/* Una persona por tarjeta, no una tabla: son pocos renglones y así la
   pantalla chica no necesita ningún desplazamiento horizontal
   (CLAUDE.md sección 11). */
.tm-persona {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 14px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: 14px;
}

.tm-persona--inactiva {
  background: var(--papel-hondo);
}

.tm-persona-datos {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 140px;
}

.tm-persona-nombre {
  font-weight: 700;
}

.tm-persona-yo {
  font-size: 11px;
  font-weight: 700;
  color: var(--tinta-tenue);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tm-persona-usuario {
  font-size: 13px;
  color: var(--tinta-suave);
}

/* ---------- La pastilla del puesto ----------
 *
 * Su color y su icono, elegidos por el dueño: admin verde, encargado
 * amarillo, cajero café, repartidor azul. No es adorno — en una lista de
 * gente, el puesto es lo que se busca, y con color se encuentra sin leer.
 *
 * El café y el amarillo son vecinos y podrían confundirse; los separan el
 * fondo y, sobre todo, el icono: la llave, el portapapeles, el billete y la
 * moto no se parecen en nada aunque los tiñas igual.
 */
.tm-persona-rol {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px 5px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  white-space: nowrap;
}

.tm-persona-rol svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

.tm-persona-rol--admin {
  background: var(--rol-admin-fondo);
  color: var(--rol-admin);
}

.tm-persona-rol--encargado {
  background: var(--rol-encargado-fondo);
  color: var(--rol-encargado);
}

.tm-persona-rol--cajero {
  background: var(--rol-cajero-fondo);
  color: var(--rol-cajero);
}

.tm-persona-rol--repartidor {
  background: var(--rol-repartidor-fondo);
  color: var(--rol-repartidor);
}

/* El avatar toma el color del PUESTO y no el del nombre, al revés que el de
   los clientes. Aquí lo que se busca en la lista es quién hace qué, y así el
   renglón entero —círculo y pastilla— dice lo mismo dos veces. */
.tm-persona-avatar {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.02em;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
}

.tm-persona-avatar--admin {
  background: var(--rol-admin-fondo);
  color: var(--rol-admin);
}

.tm-persona-avatar--encargado {
  background: var(--rol-encargado-fondo);
  color: var(--rol-encargado);
}

.tm-persona-avatar--cajero {
  background: var(--rol-cajero-fondo);
  color: var(--rol-cajero);
}

.tm-persona-avatar--repartidor {
  background: var(--rol-repartidor-fondo);
  color: var(--rol-repartidor);
}

.tm-persona-baja {
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  background: #F4E4E4;
  color: var(--peligro);
}

/* En pantalla chica "Editar" ocupa todo el renglón de abajo: cabe el
   pulgar y la tarjeta no se aprieta contra la insignia del puesto. */
.tm-persona-editar {
  flex: 1 0 100%;
  justify-content: center;
}

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

.tm-personal-permisos {
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-personal-permisos-titulo {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: var(--tinta-suave);
  margin-bottom: 6px;
}

.tm-personal-permisos-lista {
  margin: 0;
  padding-left: 18px;
  font-size: 13px;
  line-height: 1.7;
}

.tm-personal-activo {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: 14px;
  font-weight: 600;
}

.tm-personal-activo input {
  width: 20px;
  height: 20px;
}

.tm-personal-forma-acciones {
  display: flex;
  gap: 10px;
}

.tm-personal-forma-acciones .tm-boton {
  flex: 1;
  justify-content: center;
}

@media (min-width: 768px) {
  .tm-persona-editar {
    flex: 0 0 auto;
    margin-left: auto;
  }

  .tm-personal-forma-acciones {
    justify-content: flex-end;
  }

  .tm-personal-forma-acciones .tm-boton {
    flex: 0 0 auto;
  }
}

/* ---------- Ajustes: entrada a una subpágina ---------- */

/* Ajustes crece por áreas, no por scroll: cada área es una página con su
   URL. Esta fila es la puerta. */
.tm-panel-enlace {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: var(--tinta);
  text-decoration: none;
}

.tm-panel-enlace:hover,
.tm-panel-enlace:focus-visible {
  border-color: var(--accion);
}

.tm-panel-enlace-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.tm-panel-enlace-titulo {
  font-size: 16px;
  font-weight: 700;
}

.tm-panel-enlace-resumen {
  font-size: 13px;
  color: var(--tinta-suave);
}

/* ---------- Elegir cómo se ve algo, con muestra ---------- */

.tm-opciones-vista {
  display: grid;
  gap: 12px;
  grid-template-columns: minmax(0, 1fr);
}

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

.tm-opcion-vista {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px;
  border: 2px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
  text-align: left;
  font: inherit;
  color: var(--tinta);
  cursor: pointer;
}

.tm-opcion-vista--activa {
  border-color: var(--accion);
  background: var(--accion-pastel);
}

.tm-opcion-vista-nombre {
  font-size: 15px;
  font-weight: 700;
}

.tm-opcion-vista-resumen {
  font-size: 13px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* La muestra: bloques grises que imitan la forma de cada acomodo. Se
   entiende de un vistazo mejor que cualquier párrafo. */
.tm-muestra {
  display: grid;
  gap: 5px;
  padding: 10px;
  border-radius: 12px;
  background: var(--papel-hondo);
  margin-bottom: 6px;
}

.tm-muestra span {
  background: var(--tinta-tenue);
  border-radius: 4px;
  opacity: 0.5;
}

.tm-muestra--tarjetas {
  grid-template-columns: repeat(3, 1fr);
}

.tm-muestra--tarjetas span {
  height: 26px;
}

.tm-muestra--lista span {
  height: 12px;
}

.tm-opcion-vista--activa .tm-muestra span {
  background: var(--accion);
  opacity: 0.65;
}

/* Regreso en línea para subpáginas de ajustes. El botón flotante
   (.tm-boton-volver) sirve donde el contenido empieza a la derecha; aquí
   el título vive pegado a la izquierda y se lo tapaba. */
.tm-volver-enlace {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  padding: 0 12px 0 6px;
  margin-bottom: 4px;
  border-radius: 10px;
  color: var(--tinta-suave);
  text-decoration: none;
  font-size: 14px;
  font-weight: 700;
}

.tm-volver-enlace:hover,
.tm-volver-enlace:focus-visible {
  background: var(--papel-hondo);
  color: var(--accion);
}

/* ---------- Identidad del cliente en la barra superior ----------
   Debajo de la marca, en chiquito, va de cuál de las tres caras se trata:
   Trastienda, POS o Tienda. Hace falta sobre todo en el celular, donde el
   "/ Sección" se esconde por falta de ancho y la barra se quedaba diciendo
   solo "TeleMarket" en los dos clientes por igual. */
.tm-topbar-identidad {
  /* Cede cuando falta ancho, y es lo ÚNICO que cede: una hora cortada a la
     mitad no se puede leer, y «TeleMarket» sí se adivina. */
  flex-shrink: 1;
  min-width: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  line-height: 1.04;
}

.tm-topbar-cliente {
  align-self: flex-end;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
}

/* ---------- Clientes ---------- */

.tm-clientes {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ---------- Clientes, rediseñado (maqueta aprobada 2026-10-05) ---------- */

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

.tm-clientes-titulo {
  margin: 0;
  font-size: 22px;
}

.tm-clientes .tm-busqueda {
  margin-bottom: 0;
}

/* Los huecos de invitación, zonas y formulario no ocupan lugar mientras
   están vacíos: dejaban un claro grande antes del primer cliente. */
.tm-clientes > div:empty {
  display: none;
}

/* El alta con QR, destacada: solo la ven los administradores. */
.tm-qr-alta {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px;
  border: none;
  border-radius: 20px;
  background: linear-gradient(135deg, var(--accion), #3b2fd0);
  color: #ffffff;
  text-align: left;
  font: inherit;
  cursor: pointer;
  box-shadow: 0 10px 22px rgba(27, 77, 228, 0.25);
}

.tm-qr-alta:focus-visible {
  outline: 3px solid var(--tinta);
  outline-offset: 2px;
}

.tm-qr-alta-icono {
  flex: none;
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.18);
}

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

.tm-qr-alta-texto b {
  display: block;
  font-size: 16px;
}

.tm-qr-alta-texto small {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  line-height: 1.35;
  opacity: 0.92;
}

.tm-qr-alta-solo {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
  font-size: 11px;
  font-weight: 700;
  vertical-align: 2px;
}

.tm-clientes-resumen {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.tm-clientes-cifra {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 16px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
}

.tm-clientes-cifra strong {
  font-family: var(--fuente-mono);
  font-size: 22px;
  font-variant-numeric: tabular-nums;
}

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

.tm-clientes-filtros {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
}

/* Buscar y filtros, juntos en la barra que se pega arriba. */
.tm-clientes-pegada {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tm-clientes-filtros::-webkit-scrollbar {
  display: none;
}

.tm-clientes-filtro {
  flex: none;
  min-height: 40px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid var(--boton-borde);
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}

.tm-clientes-filtro[aria-pressed="true"] {
  background: var(--accion);
  border-color: var(--accion);
  color: #ffffff;
}

/* Opciones: lo que casi no se usa, junto en un menú (pedido del dueño,
   2026-10-05). */
.tm-clientes-botones {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* `.tm-opciones-*` es el mismo botón y el mismo menú de Clientes, para
   las otras pantallas que tienen cosas que casi no se tocan (Tortillas). */
.tm-clientes-opciones,
.tm-opciones-boton {
  position: relative;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border: 1px solid var(--boton-borde);
  box-shadow: var(--boton-sombra);
  border-radius: 14px;
  background: var(--papel-alto);
  color: var(--tinta);
  cursor: pointer;
}

.tm-clientes-opciones svg,
.tm-opciones-boton svg {
  width: 22px;
  height: 22px;
}

.tm-clientes-opciones[aria-expanded="true"],
.tm-opciones-boton[aria-expanded="true"] {
  background: var(--accion-tenue);
  color: var(--accion);
  border-color: var(--accion);
}

.tm-clientes-pendientes {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--peligro);
  color: #ffffff;
  font-size: 11px;
  font-weight: 800;
}

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

.tm-clientes-menu,
.tm-opciones-menu {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  border-radius: 18px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.12);
  animation: tm-menu-cae 0.18s ease both;
}

@keyframes tm-menu-cae {
  from { opacity: 0; translate: 0 -6px; }
}

.tm-clientes-menu-opcion,
.tm-opciones-opcion {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 0 12px;
  border: none;
  border-radius: 12px;
  background: none;
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.tm-clientes-menu-opcion:hover,
.tm-clientes-menu-opcion:focus-visible,
.tm-opciones-opcion:hover,
.tm-opciones-opcion:focus-visible {
  background: var(--papel);
}

.tm-clientes-menu-opcion > svg,
.tm-opciones-opcion > svg {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--accion);
}

.tm-clientes-menu-opcion small,
.tm-opciones-opcion small {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--tinta-suave);
}

.tm-clientes-menu-opcion small b {
  color: var(--peligro);
}

/* El interruptor de «Escoger para borrar»: dice si está prendido. */
.tm-interruptor {
  position: relative;
  flex: none;
  margin-left: auto;
  width: 44px;
  height: 26px;
  border-radius: 999px;
  background: var(--papel-hondo);
}

.tm-interruptor::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  transition: translate 0.2s ease;
}

[aria-checked="true"] > .tm-interruptor {
  background: var(--accion);
}

[aria-checked="true"] > .tm-interruptor::after {
  translate: 18px 0;
}

.tm-cliente-grupo {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accion);
}

/* ---------- Empresas y vecinos ---------- */

.tm-empresas {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border-radius: 20px;
  background: var(--papel);
  border: 1px solid var(--linea);
}

.tm-empresas-cabeza {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tm-empresas-cabeza h3 {
  flex: 1;
  margin: 0;
  font-size: 18px;
}

.tm-empresas-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-empresas-cerrar svg {
  width: 20px;
  height: 20px;
}

.tm-empresas-cargando,
.tm-empresas-vacio {
  margin: 0;
  font-size: 13.5px;
  color: var(--tinta-suave);
}

.tm-empresa {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border-radius: 16px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
}

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

.tm-empresa-cabeza b {
  font-size: 15.5px;
}

.tm-empresa-gente {
  font-size: 12.5px;
  color: var(--tinta-suave);
}

.tm-empresa-reglas {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--papel);
  font-size: 13.5px;
}

.tm-empresa-reglas div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}

.tm-empresa-reglas span {
  color: var(--tinta-suave);
}

.tm-empresa-reglas b {
  text-align: right;
}

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

.tm-empresa-botones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tm-empresa-botones .tm-boton,
.tm-revisar-juntar {
  min-height: 44px;
}

.tm-empresa--vecinos {
  border-style: dashed;
}

.tm-revisar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border-radius: 16px;
  border: 2px dashed var(--alerta);
  background: var(--alerta-fondo);
}

.tm-revisar-titulo {
  color: var(--alerta);
}

.tm-revisar-grupo {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px dashed color-mix(in srgb, var(--alerta) 40%, transparent);
}

.tm-revisar-grupo:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.tm-revisar-grupo p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
}

.tm-revisar-juntar {
  padding: 0 10px;
  border-radius: 12px;
  border: 1px solid var(--linea);
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 14px;
}

.tm-empresa-forma {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tm-empresa-forma fieldset {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tm-empresa-forma legend {
  width: 100%;
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--tinta-suave);
}

/* Los días como botoncitos que se prenden: se tocan con el pulgar. */
.tm-dia input,
.tm-opcion-envio input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.tm-dia span {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  border: 1px solid var(--linea);
  background: var(--papel);
  font-weight: 700;
  cursor: pointer;
}

.tm-dia input:checked + span {
  background: var(--accion);
  border-color: var(--accion);
  color: #ffffff;
}

.tm-dia input:focus-visible + span,
.tm-opcion-envio input:focus-visible + span {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

.tm-empresa-horas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
}

.tm-opcion-envio span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid var(--linea);
  background: var(--papel);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.tm-opcion-envio input:checked + span {
  background: var(--accion);
  border-color: var(--accion);
  color: #ffffff;
}

.tm-empresa-costo {
  width: 100%;
}

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

/* El «⋯» de cada cliente: abre Dar clave, Privilegios y Editar. */
.tm-cliente-mas {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 12px;
  background: var(--papel-hondo);
  color: var(--tinta);
  cursor: pointer;
}

.tm-cliente-mas svg {
  width: 20px;
  height: 20px;
}

.tm-cliente-mas[aria-expanded="true"] {
  background: var(--accion-tenue);
  color: var(--accion);
}

.tm-cliente-marca--en-linea {
  background: var(--ok-fondo);
  color: var(--ok);
}

/* La clave como boleto: cada dígito en su casilla, para dictarla sin error. */
.tm-clave-boleto {
  display: grid;
  grid-template-columns: repeat(4, 56px);
  gap: 8px;
  letter-spacing: 0;
  text-indent: 0;
}

.tm-clave-boleto span {
  aspect-ratio: 3 / 4;
  display: grid;
  place-items: center;
  border-radius: 14px;
  background: var(--papel-alto);
  box-shadow: 0 2px 8px rgba(27, 77, 228, 0.12);
}

/* ---------- La pantalla del QR ----------
   Blanco puro a pantalla completa: lo más claro que se puede pedir desde
   una página, que no puede subir el brillo del teléfono. */

.tm-qr {
  position: fixed;
  inset: 0;
  z-index: 400;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 18px 20px max(20px, env(safe-area-inset-bottom));
  background: #ffffff;
  color: #1f1f1f;
  animation: tm-qr-entra 0.3s ease both;
}

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

.tm-qr-arriba {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: 420px;
  margin: 0 auto;
  width: 100%;
}

.tm-qr-arriba b {
  font-size: 17px;
}

.tm-qr-cerrar {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 999px;
  background: #f2f0ee;
  color: #1f1f1f;
  cursor: pointer;
}

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

.tm-qr-caja {
  width: min(300px, 78vw);
  aspect-ratio: 1;
  padding: 16px;
  border: 3px solid #1f1f1f;
  border-radius: 22px;
  background: #ffffff;
}

.tm-qr-caja svg {
  display: block;
  width: 100%;
  height: 100%;
}

.tm-qr-dice {
  margin: 0;
  text-align: center;
  font-size: 15px;
  line-height: 1.45;
}

.tm-qr-dice b {
  font-size: 18px;
}

.tm-qr-datos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

.tm-qr-datos span {
  padding: 6px 12px;
  border-radius: 999px;
  background: #f2f0ee;
  font-size: 13px;
  font-weight: 600;
}

.tm-qr-datos b {
  font-family: var(--fuente-mono);
  letter-spacing: 0.08em;
}

.tm-qr-luz {
  margin: 0;
  max-width: 420px;
  padding: 8px 12px;
  border-radius: 12px;
  background: #fff7d6;
  color: #6b5300;
  font-size: 12.5px;
  font-weight: 600;
  text-align: center;
}

.tm-qr-listo {
  margin: 0;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--ok-fondo);
  color: var(--ok);
  font-weight: 700;
  text-align: center;
  animation: tm-qr-entra 0.35s ease both;
}

.tm-qr-abajo {
  margin-top: auto;
  width: 100%;
  max-width: 420px;
  display: grid;
  gap: 8px;
}

.tm-qr-abajo .tm-boton {
  min-height: 52px;
  justify-content: center;
}

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

/* La foto, o las iniciales sobre su color. El color sale del nombre, así
   que a cada persona le toca siempre el mismo y se reconoce antes de leer. */
.tm-avatar {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  object-fit: cover;
  display: grid;
  place-items: center;
  color: #ffffff;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.tm-cliente {
  padding: 12px 14px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: 16px;
}

.tm-cliente-fila {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
}

.tm-cliente-datos {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 150px;
}

.tm-cliente-nombre {
  font-size: 15px;
  font-weight: 700;
}

.tm-cliente-telefono {
  font-size: 14px;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

.tm-cliente-direccion {
  font-size: 13px;
  color: var(--tinta-tenue);
}

.tm-cliente-marcas {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}

.tm-cliente-marca {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 11px;
  font-weight: 700;
}

.tm-cliente-marca--envio {
  background: var(--ok-fondo);
  color: var(--ok);
}

.tm-cliente-marca--baja {
  background: var(--peligro-fondo);
  color: var(--peligro);
}

/* Se abre con el «⋯»: tres botones parejos debajo del cliente. */
.tm-cliente-acciones {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-top: 10px;
}

.tm-cliente-acciones .tm-boton {
  min-height: 44px;
  padding: 0 8px;
  justify-content: center;
}

/* La clave solo se puede leer aquí, recién generada: después ya no hay
   manera de recuperarla. Por eso va grande y en mono. */
.tm-clave {
  margin-top: 12px;
  padding: 14px;
  border-radius: 14px;
  background: var(--accion-tenue);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}

.tm-clave-numero {
  font-family: var(--fuente-mono);
  font-size: 40px;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--accion);
  text-indent: 0.22em;
}

.tm-clave-nota {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--tinta-suave);
  max-width: 44ch;
}

.tm-clave-acciones {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

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

.tm-cliente-envio {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.tm-cliente-envio legend {
  padding: 0 6px;
  font-size: 12px;
  font-weight: 800;
  color: var(--tinta-suave);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.tm-cliente-casilla {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: 14px;
  font-weight: 600;
}

.tm-cliente-casilla input {
  width: 20px;
  height: 20px;
}

.tm-cliente-forma-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tm-cliente-forma-acciones .tm-boton {
  flex: 1 1 140px;
  justify-content: center;
}

@media (min-width: 768px) {
  .tm-cliente-forma-acciones {
    justify-content: flex-end;
  }

  .tm-cliente-forma-acciones .tm-boton {
    flex: 0 0 auto;
  }
}

/* ---------- Privilegios del cliente ----------
   Opciones excluyentes, no casillas sueltas: un cliente tiene UN privilegio
   de envío. Con casillas se podía marcar "de por vida" y "una semana" a la
   vez, y nadie sabría cuál gana. */

.tm-privilegios {
  margin-top: 12px;
  padding: 14px;
  border-radius: 14px;
  background: var(--accion-pastel);
  border: 1px solid var(--linea);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tm-privilegios-titulo {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tinta-suave);
}

.tm-privilegios-opciones {
  display: grid;
  gap: 8px;
}

@media (min-width: 700px) {
  .tm-privilegios-opciones {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.tm-privilegio {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 48px;
  padding: 10px 12px;
  border: 2px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  cursor: pointer;
}

.tm-privilegio--activo {
  border-color: var(--accion);
}

.tm-privilegio input {
  margin-top: 2px;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

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

.tm-privilegio-etiqueta {
  font-size: 14px;
  font-weight: 700;
}

.tm-privilegio-detalle {
  font-size: 12px;
  color: var(--tinta-suave);
}

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

/* ---------- Campanita de pedidos ----------
   Vive en la barra de arriba, así que se ve estés donde estés. Sube de tono
   con la espera en vez de repetir siempre la misma alarma: una alarma que
   suena igual se vuelve ruido y se aprende a ignorar. */

.tm-campanita {
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  margin-left: auto;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
}

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

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

.tm-campanita:hover,
.tm-campanita:focus-visible {
  background: rgba(255, 255, 255, 0.26);
}

/* Con pedidos pendientes se enciende en blanco; con la espera pasa a ámbar
   y luego a rojo. El color hace el trabajo antes que el número. */
.tm-campanita--hay { color: #ffffff; }
.tm-campanita--tibia { color: #FBBF24; }

.tm-campanita--urgente {
  color: #ffffff;
  background: var(--peligro);
  animation: tm-campanita-late 1.6s ease-in-out infinite;
}

@keyframes tm-campanita-late {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.09); }
}

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

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

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

.tm-campanita--urgente .tm-campanita-cuenta {
  background: #ffffff;
  color: var(--peligro);
}

/* ---------- Bandeja de pedidos ---------- */

.tm-bandeja {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* La barra de bandejas es un solo bloque segmentado, no seis cajitas
   sueltas. El activo se levanta con fondo claro y una sombra baja: es el
   mismo gesto del control segmentado que cualquiera ya conoce del teléfono,
   así que no hay nada que aprender.

   Va completa aquí y no depende de la .tm-chip de la tienda: el POS y la
   Trastienda no cargan store.css. */

.tm-bandeja-filtros {
  display: flex;
  /* El bloque mide lo que miden las seis bandejas y ahí se queda. En pantalla
     grande eso lo deja compacto a la izquierda en vez de estirado de orilla a
     orilla; en el celular, donde ya no caben, el tope del 100% lo obliga a
     arrastrarse. Una sola regla resuelve los dos casos. */
  width: fit-content;
  max-width: 100%;
  align-self: flex-start;
  gap: 2px;
  padding: 3px;
  border-radius: 12px;
  background: var(--papel-hondo);
  overflow-x: auto;
  scrollbar-width: none;
}

.tm-bandeja-filtros::-webkit-scrollbar { display: none; }

.tm-bandeja-filtros .tm-chip {
  /* En el celular cada bandeja conserva su ancho y la barra se arrastra.
     Apretar las seis para que quepan en 360px las dejaría en tres letras
     cada una. */
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 13px;
  border: none;
  border-radius: 9px;
  background: none;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.tm-bandeja-filtros .tm-chip--activo {
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.tm-bandeja-filtros .tm-chip:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: -2px;
}

.tm-bandeja-filtros .tm-chip-cuantos {
  margin-left: 0;
  min-width: 18px;
  background: rgba(0, 0, 0, 0.07);
  color: var(--tinta-suave);
  font-size: 11px;
}

/* El número de la bandeja abierta en azul, no en rojo: en el POS y en la
   Trastienda el rojo está apartado para cancelar y borrar. */
.tm-bandeja-filtros .tm-chip--activo .tm-chip-cuantos {
  background: var(--accion);
  color: #ffffff;
}

.tm-pedido-estado {
  flex-shrink: 0;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 12px;
  font-weight: 800;
}

.tm-pedido-estado--nuevo,
.tm-pedido-estado--confirmado {
  background: var(--accion-tenue);
  color: var(--accion);
}

.tm-pedido-estado--en_camino,
.tm-pedido-estado--listo {
  background: var(--alerta-fondo);
  color: var(--alerta);
}

.tm-pedido-estado--entregado {
  background: var(--ok-fondo);
  color: var(--ok);
}

.tm-pedido-estado--cancelado {
  background: var(--peligro-fondo);
  color: var(--peligro);
}

/* La tarjeta es un ticket.
   Los dientes de arriba y abajo se dibujan con pseudoelementos y no con una
   máscara sobre la tarjeta: la máscara recorta también la sombra, y la
   tarjeta se queda plana sobre el fondo. */
.tm-bandeja .tm-pedido {
  position: relative;
  padding: 10px 0;
  background: transparent;
}

.tm-bandeja .tm-pedido-papel {
  position: relative;
  padding: 16px 15px;
  background: var(--papel-alto);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.06);
}

.tm-bandeja .tm-pedido-papel::before,
.tm-bandeja .tm-pedido-papel::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 8px;
  pointer-events: none;
}

.tm-bandeja .tm-pedido-papel::before {
  top: 0;
  background: radial-gradient(circle at 7px 0, var(--papel) 6px, transparent 6.5px) repeat-x;
  background-size: 14px 8px;
}

.tm-bandeja .tm-pedido-papel::after {
  bottom: 0;
  background: radial-gradient(circle at 7px 8px, var(--papel) 6px, transparent 6.5px) repeat-x;
  background-size: 14px 8px;
}

/* El que ya se tardó: una franja roja en el canto izquierdo, como el ticket
   que alguien marcó con plumón. Se ve de reojo desde el mostrador. */
.tm-bandeja .tm-pedido--tarde .tm-pedido-papel {
  border-left: 5px solid var(--peligro);
}

.tm-bandeja .tm-pedido--editando .tm-pedido-papel {
  box-shadow: 0 0 0 2px var(--accion);
}

/* --- La cabecera del ticket --- */

.tm-bandeja .tm-pedido-encabezado {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding-top: 4px;
  font-family: var(--fuente-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
  font-variant-numeric: tabular-nums;
}

.tm-bandeja .tm-pedido-quien {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 13px 0 12px;
}

.tm-bandeja .tm-pedido-avatar {
  width: 42px;
  height: 42px;
  font-size: 14px;
}

.tm-bandeja .tm-pedido-nombre {
  display: block;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.2;
}

.tm-bandeja .tm-pedido-veces {
  display: block;
  font-size: 12px;
  color: var(--tinta-tenue);
}

.tm-bandeja .tm-pedido-tel {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--accion);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

/* --- La línea punteada de corte --- */

.tm-bandeja .tm-pedido-corte {
  border: none;
  border-top: 1px dashed var(--tinta-tenue);
  margin: 12px 0;
}

/* --- Los renglones de datos --- */

.tm-bandeja .tm-pedido-datos,
.tm-bandeja .tm-pedido-suma {
  margin: 0;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
}

.tm-bandeja .tm-pedido-datos > div,
.tm-bandeja .tm-pedido-suma > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 3px 0;
}

.tm-bandeja .tm-pedido-datos dt,
.tm-bandeja .tm-pedido-suma dt {
  color: var(--tinta-suave);
  flex-shrink: 0;
}

.tm-bandeja .tm-pedido-datos dd,
.tm-bandeja .tm-pedido-suma dd {
  margin: 0;
  text-align: right;
  font-weight: 600;
}

.tm-bandeja .tm-pedido-tarde {
  color: var(--peligro);
  font-weight: 700;
}

/* --- Lo pedido: la cantidad en su propia columna --- */

.tm-bandeja .tm-pedido-items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tm-bandeja .tm-pedido-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 4px 0;
  font-size: 14px;
}

/* Como imprime un ticket de verdad: primero cuántos, luego qué. Pegada al
   nombre, la cantidad se lee como parte de él y hay que releerla. */
.tm-bandeja .tm-pedido-item-cantidad {
  flex-shrink: 0;
  min-width: 30px;
  font-family: var(--fuente-mono);
  font-size: 13.5px;
  font-weight: 700;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--tinta-suave);
}

.tm-bandeja .tm-pedido-item-nombre {
  flex: 1;
  min-width: 0;
  line-height: 1.35;
}

/* «Pesar», debajo del nombre de lo que va a granel. */
.tm-bandeja .tm-pedido-pesar {
  display: flex;
  margin-top: 6px;
}

.tm-bandeja .tm-pedido-item-importe {
  flex-shrink: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* --- El total: lo más grande del ticket --- */

.tm-bandeja .tm-pedido-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 2px solid var(--tinta);
}

.tm-bandeja .tm-pedido-total span {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tinta-suave);
}

.tm-bandeja .tm-pedido-total strong {
  font-family: var(--fuente-mono);
  font-size: 30px;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

/* --- Avisos y notas --- */

.tm-bandeja .tm-pedido-pago {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 8px 8px 12px;
  border-radius: 10px;
  font-size: 13.5px;
  font-weight: 700;
}

.tm-bandeja .tm-pedido-pago span { flex: 1; min-width: 0; }

.tm-bandeja .tm-pedido-pago--espera {
  background: var(--alerta-fondo);
  color: var(--alerta);
}

.tm-bandeja .tm-pedido-pago--hecho {
  background: var(--ok-fondo);
  color: var(--ok);
  padding: 9px 12px;
}

.tm-bandeja .tm-pedido-deshacer {
  border: none;
  background: transparent;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tinta-suave);
  text-decoration: underline;
  cursor: pointer;
  padding: 4px;
}

.tm-bandeja .tm-pedido-aviso {
  margin: 8px 0 0;
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 12.5px;
  font-weight: 700;
}

/* La entrega discreta se marca en negro: es la instrucción que el repartidor
   no puede pasar por alto. */
.tm-bandeja .tm-pedido-aviso--discreta {
  background: var(--tinta);
  color: #ffffff;
}

/* Los envases que hay que recoger, en verde: no es una alarma, es un recado.
   Si se olvida, el envase se pierde y la tienda se lo paga al proveedor. */
.tm-bandeja .tm-pedido-aviso--envases {
  background: #e4f5e8;
  color: var(--ok);
}

.tm-bandeja .tm-pedido-nota {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--papel-hondo);
  font-size: 13px;
  font-style: italic;
  color: var(--tinta-suave);
}

.tm-bandeja .tm-pedido-pie-nota {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--alerta);
  font-weight: 600;
}

.tm-bandeja .tm-pedido-ajustar {
  display: block;
  width: 100%;
  min-height: 44px;
  margin-top: 12px;
  border: 1px dashed var(--tinta-tenue);
  border-radius: 10px;
  background: transparent;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--tinta-suave);
  cursor: pointer;
}

.tm-bandeja .tm-pedido-ajustar:hover {
  border-color: var(--accion);
  color: var(--accion);
}

/* --- Los botones, fuera del papel --- */

.tm-bandeja .tm-pedido-acciones {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.tm-bandeja .tm-pedido-acciones .tm-boton {
  flex: 1;
  min-width: 128px;
}

/* El número de cada bandeja. Va dentro del chip para que se lea como parte
   del nombre, no como un adorno pegado. */
.tm-chip-cuantos {
  display: inline-block;
  margin-left: 6px;
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.08);
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tm-chip--activo .tm-chip-cuantos {
  background: rgba(255, 255, 255, 0.28);
}

/* ---------- Problemas que reportan los clientes ----------
   Una columna de tarjetas, del ancho de un ticket: se leen de arriba abajo
   y en pantalla grande no tiene caso estirarlas. */

.tm-problemas {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 640px;
}

.tm-problemas-titulo {
  margin: 4px 0 0;
  font-size: 15px;
  font-weight: 700;
}

.tm-problemas-titulo--suave {
  margin-top: 14px;
  color: var(--tinta-suave);
}

.tm-problema {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
}

/* El que ya se atendió baja el volumen: sigue ahí para consultarlo, pero no
   compite con lo que falta. */
.tm-problema--atendido {
  background: var(--papel-hondo);
  box-shadow: none;
}

.tm-problema-cabeza {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.tm-problema-tipo {
  font-weight: 700;
}

.tm-problema-cuando,
.tm-problema-atendio {
  color: var(--tinta-tenue);
  font-size: 13px;
}

.tm-problema-texto {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.tm-problema-quien {
  margin: 0;
  color: var(--tinta-suave);
  font-size: 14px;
}

.tm-problema-quien a {
  color: inherit;
  font-variant-numeric: tabular-nums;
}

.tm-problema-acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.tm-problema-acciones .tm-boton {
  flex: 1 1 150px;
}

.tm-problema-atendio {
  flex-basis: 100%;
}

/* Confirmar que llegó dinero es lo único que se marca en verde: es un hecho
   que ya pasó, no una acción que va a pasar. */
.tm-boton--ok {
  background: var(--ok);
  color: #ffffff;
  box-shadow: var(--boton-sombra-color);
}

.tm-boton--ok:hover { background: #196536; }

/* --- Ajustar el pedido --- */

.tm-ajuste {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px;
  border-radius: 14px;
  background: var(--papel-hondo);
}

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

/* Editando, el renglón crece a dos pisos: arriba qué es y cuánto cuesta,
   abajo los controles. En 360px no caben en una línea sin apretarse por
   debajo de los 44px que necesita un dedo. */
.tm-bandeja .tm-pedido-item--editando {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
}

.tm-bandeja .tm-pedido-item--cambiando {
  border-color: var(--accion);
}

.tm-bandeja .tm-pedido-item-fila {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.tm-bandeja .tm-pedido-item-controles {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.tm-contador {
  display: flex;
  align-items: center;
  border: 1px solid var(--linea);
  border-radius: 10px;
  overflow: hidden;
}

.tm-contador button {
  min-width: 40px;
  min-height: 40px;
  border: none;
  background: var(--papel-alto);
  font: inherit;
  font-size: 20px;
  font-weight: 700;
  color: var(--accion);
  cursor: pointer;
}

.tm-contador button:hover {
  background: var(--papel-hondo);
}

.tm-contador span {
  min-width: 44px;
  text-align: center;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tm-boton--chico {
  min-height: 40px;
  padding: 0 12px;
  font-size: 13px;
}

.tm-boton-icono {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--boton-borde);
  box-shadow: var(--boton-sombra);
  border-radius: 10px;
  background: var(--papel-alto);
  cursor: pointer;
  margin-left: auto;
}

.tm-boton-icono--peligro {
  color: var(--peligro);
}

.tm-boton-icono--peligro:hover {
  background: var(--peligro-fondo);
}

.tm-ajuste-cuenta {
  padding: 12px;
  border-radius: 12px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
}

.tm-ajuste-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.tm-ajuste-total strong {
  font-size: 26px;
  font-variant-numeric: tabular-nums;
}

.tm-ajuste-cambio {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--ok);
  font-variant-numeric: tabular-nums;
}

.tm-ajuste-cambio--sube {
  color: var(--alerta);
}

.tm-ajuste-ojo {
  margin: 6px 0 0;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--alerta);
}

.tm-ajuste-calculando,
.tm-ajuste-error {
  margin: 0;
  font-size: 13px;
  color: var(--tinta-tenue);
}

.tm-ajuste-error {
  color: var(--peligro);
  font-weight: 600;
}

.tm-ajuste-buscador {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tm-ajuste-buscador-etiqueta {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--tinta-suave);
}

.tm-ajuste-buscador input {
  min-height: 44px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
  font: inherit;
}

.tm-ajuste-resultados {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 260px;
  overflow-y: auto;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
}

.tm-ajuste-resultados button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  padding: 8px 10px;
  border: none;
  border-bottom: 1px solid var(--linea);
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-ajuste-resultados li:last-child button {
  border-bottom: none;
}

.tm-ajuste-resultados button:hover {
  background: var(--papel-hondo);
}

.tm-ajuste-resultados img,
.tm-ajuste-resultado-sinfoto {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  object-fit: cover;
  background: var(--papel-hondo);
  flex-shrink: 0;
}

.tm-ajuste-resultado-nombre {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  font-size: 14px;
  line-height: 1.25;
}

.tm-ajuste-resultado-nombre small {
  font-size: 11.5px;
  color: var(--tinta-tenue);
}

.tm-ajuste-resultado-precio {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

.tm-ajuste-agotado {
  font-size: 11px;
  font-weight: 700;
  color: var(--peligro);
}

.tm-ajuste-acciones {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.tm-ajuste-acciones .tm-boton {
  flex: 1;
  min-width: 130px;
}

@media (min-width: 768px) {
  .tm-bandeja .tm-pedido-item--editando {
    flex-direction: row;
    align-items: center;
  }

  .tm-bandeja .tm-pedido-item-fila {
    flex: 1;
    min-width: 0;
  }

  .tm-ajuste-acciones .tm-boton {
    flex: 0 0 auto;
  }
}

/* Campanita y reloj viajan juntos a la derecha: los dos tenían margen
   automático y se repartían el hueco, dejando la campanita a media barra. */
.tm-campanita ~ .tm-banner-info {
  margin-left: 12px;
}

/* ---------- Ley seca ---------- */

.tm-ley-estado {
  padding: 14px 16px;
  border-radius: 14px;
  font-size: 14px;
  line-height: 1.5;
  margin-bottom: 12px;
}

.tm-ley-estado--libre {
  background: var(--ok-fondo);
  color: var(--ok);
  font-weight: 600;
}

.tm-ley-estado--activa {
  background: var(--peligro-fondo);
  color: var(--peligro);
}

/* ---------- Envases retornables (core/vista_envases.js) ----------

   Rehecha el 2026-10-07 con la maqueta que aprobó el dueño: cajitas arriba
   como en Tortillas, tres pestañas, los envases como fichas con su depósito
   y la barra de cobrar abajo, al pulgar. */

.tm-env { display: flex; flex-direction: column; gap: 12px; }
.tm-env-panel { display: flex; flex-direction: column; gap: 14px; }

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

.tm-env-cabeza .tm-titulo { margin: 0; }

.tm-env-cajas {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px;
}

.tm-env-caja {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 14px;
  border-radius: 16px;
  background: var(--papel-hondo);
}

.tm-env-caja span { font-size: 12.5px; font-weight: 600; color: var(--tinta-suave); }

.tm-env-caja strong {
  font-family: var(--fuente-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(22px, 7vw, 28px);
  line-height: 1.15;
}

.tm-env-caja small {
  font-size: 12.5px;
  color: var(--tinta-suave);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-env-caja--alerta strong { color: var(--alerta); }

.tm-env-pestanas {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  padding: 4px;
  border-radius: 14px;
  background: var(--papel-hondo);
}

.tm-env-pestanas button {
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

.tm-env-pestanas button[aria-selected="true"] {
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

.tm-env-num {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--accion-tenue);
  color: var(--accion);
  font-family: var(--fuente-mono);
  font-size: 12px;
}

.tm-env-pista { margin: 0 0 10px; font-size: 13.5px; color: var(--tinta-suave); }

/* Prestar: cada envase es una ficha con su depósito ya puesto. */
.tm-env-fichas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
}

.tm-env-ficha {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-height: 132px;
  padding: 12px;
  border: 1.5px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-env-ficha:focus-visible { outline: 2px solid var(--accion); outline-offset: 2px; }
.tm-env-ficha--elegida { border-color: var(--accion); background: var(--accion-tenue); cursor: default; }
.tm-env-ficha--otro { border-style: dashed; color: var(--tinta-suave); }

.tm-env-dibujo,
.tm-env-ficha--otro svg { width: 38px; height: 38px; margin-bottom: 6px; flex: none; }

.tm-env-ficha-nombre { font-size: 14px; font-weight: 600; line-height: 1.25; }

.tm-env-ficha-precio {
  margin-top: 2px;
  font-family: var(--fuente-mono);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--tinta-suave);
}

.tm-env-ficha-pista { margin-top: auto; font-size: 12.5px; }

/* El − cuántos + ocupa el pie de la ficha, como el «Agregar» de la tarjeta
   de producto: en el mismo lugar y con botones de 44 para el pulgar. */
.tm-env-cuantos {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding: 2px;
  border-radius: 12px;
  background: var(--accion);
  color: #ffffff;
}

.tm-env-cuantos button {
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
  font: inherit;
  font-size: 19px;
  font-weight: 700;
  cursor: pointer;
}

.tm-env-cuantos b {
  flex: 1;
  text-align: center;
  font-family: var(--fuente-mono);
  font-size: 17px;
  font-variant-numeric: tabular-nums;
}

.tm-env-quien { margin-top: 12px; }
.tm-env-opcional { font-weight: 400; }

.tm-env-otro,
.tm-env-tipo,
.tm-env-nuevo {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
}

.tm-env-otro { margin-top: 10px; }
.tm-env-otro-titulo { margin: 0; font-size: 14.5px; font-weight: 700; }

.tm-env-otro-campos,
.tm-env-tipo-campos {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
}

.tm-env-otro-campos .tm-campo:first-child,
.tm-env-tipo-nombre { grid-column: 1 / -1; }

.tm-env-otro-acciones,
.tm-env-tipo-acciones { display: flex; flex-wrap: wrap; gap: 8px; }

.tm-env-otro-acciones .tm-boton,
.tm-env-tipo-acciones .tm-boton { flex: 1; min-width: 140px; }

/* Cobrar, pegado abajo de lo que se ve: el contenido del POS tiene su propio
   desplazamiento, así que queda justo encima de la barra de navegación. Lo
   pegajoso es la envoltura, hija directa de la vista: un sticky no sale de
   su papá, y si el papá mide lo mismo que él, no se pega a nada. */
.tm-env-barra { position: sticky; bottom: 12px; z-index: 5; }
.tm-env-barra:empty { display: none; }

.tm-env-cobrar {
  width: 100%;
  min-height: 58px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 18px;
  border: 0;
  border-radius: 16px;
  background: var(--accion);
  color: #ffffff;
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 8px 22px color-mix(in srgb, var(--accion) 35%, transparent);
}

.tm-env-cobrar:focus-visible { outline: 2px solid var(--tinta); outline-offset: 2px; }
.tm-env-cobrar-monto { font-family: var(--fuente-mono); font-size: 19px; font-variant-numeric: tabular-nums; }

/* Devolver: el código se escribe en grande, como viene en el vale. */
.tm-env-buscar { display: flex; gap: 8px; }

.tm-env-buscar input {
  flex: 1;
  min-width: 0;
  min-height: 52px;
  padding: 0 14px;
  border: 1.5px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  color: var(--tinta);
  font-family: var(--fuente-mono);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.06em;
}

.tm-env-buscar input::placeholder {
  font-family: var(--fuente-interfaz);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
}

.tm-env-buscar .tm-boton { min-height: 52px; }

.tm-env-lista { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }

.tm-env-filtros { display: flex; gap: 6px; }

.tm-env-filtros button {
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--boton-borde);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}

.tm-env-filtros button[aria-pressed="true"] { border-color: var(--accion); background: var(--accion); color: #ffffff; }

.tm-env-vale {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
}

.tm-env-vale-arriba { display: flex; align-items: center; gap: 10px; }

.tm-env-codigo {
  padding: 2px 8px;
  border-radius: 8px;
  background: var(--papel-hondo);
  font-family: var(--fuente-mono);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.tm-env-vale-quien { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.tm-env-vale-quien b {
  font-size: 14.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-env-vale-quien small { font-size: 12.5px; color: var(--tinta-suave); }
.tm-env-vale-total { font-family: var(--fuente-mono); font-size: 18px; font-variant-numeric: tabular-nums; }
.tm-env-vale-envases { margin: 0; font-size: 13.5px; color: var(--tinta-suave); }

.tm-env-marca {
  display: inline-block;
  margin-left: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 11.5px;
  font-weight: 700;
}

.tm-env-marca--vencido { background: var(--alerta-fondo); color: var(--alerta); }

.tm-env-vale-acciones { display: flex; flex-wrap: wrap; gap: 8px; }
.tm-env-vale-acciones .tm-boton { flex: 1; min-width: 130px; }

/* Devolver es dinero que sale: verde de «se cerró bien», no el color de
   acción, para que no se confunda con prestar. */
.tm-env-devolver { border-color: var(--ok); background: var(--ok); color: #ffffff; }

/* La hoja de abajo: el vale listo y Mis envases. En la computadora, una
   ventana al centro. */
.tm-env-velo { position: fixed; inset: 0; z-index: 200; background: rgba(10, 10, 20, 0.45); }

.tm-env-hoja {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 201;
  max-height: 88vh;
  overflow-y: auto;
  padding: 10px 16px calc(18px + env(safe-area-inset-bottom, 0px));
  border-radius: 22px 22px 0 0;
  background: var(--papel-alto);
  box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.18);
  animation: tm-env-sube 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (min-width: 768px) {
  .tm-env-hoja {
    top: 50%;
    bottom: auto;
    left: 50%;
    right: auto;
    width: min(520px, 92vw);
    translate: -50% -50%;
    border-radius: 22px;
  }
}

@keyframes tm-env-sube { from { transform: translateY(40px); opacity: 0; } }

.tm-env-asa { width: 40px; height: 4px; margin: 0 auto 12px; border-radius: 2px; background: var(--linea); }

.tm-env-cobrado {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--ok-fondo);
  color: var(--ok);
  font-size: 15px;
}

.tm-env-cobrado svg { width: 20px; height: 20px; flex: none; }
.tm-env-impreso { margin: 0 0 8px; font-size: 13.5px; color: var(--tinta-suave); }
.tm-env-hoja-titulo { margin: 0 0 4px; font-size: 18px; }
.tm-env-hoja-acciones { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.tm-env-hoja-acciones .tm-boton { flex: 1; min-width: 130px; }
.tm-env-hoja-acciones .tm-env-listo { flex-basis: 100%; }
.tm-env-tipos { display: flex; flex-direction: column; gap: 10px; margin: 12px 0 16px; }

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

/* El vale, con cara de ticket: papel claro, todo centrado y el código
   grande, porque muchas veces se dicta o se teclea en vez de escanearse. */
.tm-vale-papel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 18px;
  border-radius: 12px;
  border: 1px dashed var(--tinta-tenue);
  background: #ffffff;
  text-align: center;
}

.tm-vale-negocio {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-suave);
}

.tm-vale-envase {
  font-size: 15px;
  font-weight: 700;
}

.tm-vale-monto {
  font-family: var(--fuente-mono);
  font-size: 30px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tm-vale-barras {
  width: 100%;
  max-width: 320px;
  margin: 6px 0 2px;
}

.tm-vale-codigo-grande {
  font-family: var(--fuente-mono);
  font-size: 34px;
  font-weight: 700;
  letter-spacing: 0.14em;
}

.tm-vale-cliente,
.tm-vale-vence {
  font-size: 12.5px;
  color: var(--tinta-suave);
}

/* Al imprimir, solo el vale. Lo demás de la pantalla no tiene por qué
   gastar papel térmico. */
@media print {
  body * {
    visibility: hidden;
  }

  .tm-vale-papel,
  .tm-vale-papel * {
    visibility: visible;
  }

  .tm-vale-papel {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    border: none;
  }
}

/* Una CLABE incompleta se ve igual que una completa. El contador de Ajustes
   lo dice, y en rojo cuando va a medias. */
.tm-ajustes-pista--mal { color: var(--peligro); font-weight: 600; }

/* ---------- Impresora ---------- */

.tm-impresora-acciones {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 14px;
}

.tm-impresora-acciones .tm-boton { flex: 1; min-width: 150px; }

/* «Buscar en mi red»: las impresoras que contestaron, una por botón. */
.tm-impresora-buscar {
  display: grid;
  gap: 8px;
  justify-items: start;
  margin-top: 10px;
}

.tm-impresora-buscar .tm-ajustes-pista { margin: 0; }

.tm-impresora-encontradas {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tm-impresora-encontradas .tm-chip {
  min-height: 48px;
  font-family: var(--fuente-mono);
  font-variant-numeric: tabular-nums;
}

.tm-impresora-encontradas .tm-chip[aria-pressed="true"] {
  border-color: var(--accion);
  background: var(--accion);
  color: #ffffff;
}

/* ---------- Tamaño del logo del ticket ---------- */

.tm-logo-medida {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tm-logo-medida input[type="range"] {
  flex: 1;
  min-width: 0;
  accent-color: var(--accion);
  height: 44px;
}

.tm-logo-medida output {
  flex-shrink: 0;
  min-width: 48px;
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* La regla: el rollo a escala, con el logo del tamaño que va a salir. Un
   número de por ciento no le dice nada a nadie hasta que se ve. */
.tm-logo-regla {
  display: grid;
  place-items: center;
  margin-top: 8px;
  padding: 10px 0;
  border: 1px dashed var(--tinta-tenue);
  border-radius: 8px;
  background: #ffffff;
}

.tm-logo-regla img {
  width: var(--ancho, 55%);
  /* En papel térmico no hay grises: se ve así de contrastado. */
  filter: grayscale(1) contrast(3);
}

/* ---------- Compras ---------- */

.tm-compras {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding-bottom: 90px; /* sitio para el pie del pedido */
}

.tm-compras-cabeza h1 {
  margin: 0;
  font-size: 24px;
  letter-spacing: -0.015em;
}

.tm-compras-pendiente {
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--alerta);
  font-weight: 600;
}

.tm-compras-pendiente--limpio {
  color: var(--tinta-tenue);
  font-weight: 400;
}

/* --- Los proveedores --- */

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

.tm-prov {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
  text-decoration: none;
  color: inherit;
}

/* Con algo apuntado, la tarjeta lo dice de lejos: es la razón por la que uno
   entra a esta pantalla. */
.tm-prov--pendiente {
  border-color: var(--alerta);
}

.tm-prov-inicial {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  background: var(--papel-hondo);
  font-size: 20px;
  font-weight: 800;
  color: var(--tinta-suave);
}

.tm-prov-datos { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tm-prov-nombre { font-size: 16.5px; font-weight: 700; }
.tm-prov-señas { font-size: 12.5px; color: var(--tinta-tenue); }

.tm-prov-marcas {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
}

.tm-prov-apuntados,
.tm-prov-abierto {
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}

.tm-prov-apuntados { background: var(--alerta-fondo); color: var(--alerta); }
.tm-prov-abierto { background: var(--accion-tenue); color: var(--accion); }

.tm-prov-tel {
  font-size: 14px;
  font-weight: 600;
  color: var(--accion);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

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

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

/* --- Rutas y filtros --- */

.tm-compras-rutas,
.tm-compras-filtros {
  display: flex;
  gap: 8px;
  align-items: center;
  overflow-x: auto;
  scrollbar-width: none;
}

.tm-compras-rutas::-webkit-scrollbar,
.tm-compras-filtros::-webkit-scrollbar { display: none; }

.tm-compras-filtros input {
  flex: 1;
  min-width: 140px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--tinta-tenue);
  border-radius: 12px;
  background: var(--papel-alto);
  font: inherit;
}

/* --- Los renglones --- */

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

.tm-compra-item {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
}

.tm-compra-item--falta { border-left: 4px solid var(--alerta); }

.tm-compra-item-datos { flex: 1; min-width: 160px; display: flex; flex-direction: column; gap: 3px; }
.tm-compra-item-nombre { font-size: 15px; font-weight: 700; line-height: 1.25; }

.tm-compra-item-señas {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--tinta-tenue);
}

.tm-compra-item-costo {
  align-self: flex-start;
  min-height: 32px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12.5px;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
  text-align: left;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  cursor: pointer;
}

.tm-compra-item-costo em { color: var(--accion); font-style: normal; font-weight: 600; }

/* El semáforo. "Sin conteo" es gris a propósito: donde no se cuentan
   existencias, un verde sería una mentira. */
.tm-semaforo {
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 700;
}

.tm-semaforo--verde { background: var(--ok-fondo); color: var(--ok); }
.tm-semaforo--ambar { background: var(--alerta-fondo); color: var(--alerta); }
.tm-semaforo--rojo { background: var(--peligro-fondo); color: var(--peligro); }
.tm-semaforo--sin_control { background: var(--papel-hondo); color: var(--tinta-tenue); }

.tm-compra-apuntado { color: var(--alerta); font-weight: 700; }

.tm-compra-item-control { display: flex; align-items: center; gap: 8px; margin-left: auto; }

.tm-compra-sugerido {
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--accion);
  border-radius: 10px;
  background: var(--papel-alto);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--accion);
  cursor: pointer;
  white-space: nowrap;
}

/* --- El pedido, siempre a la vista --- */

.tm-compras-pie {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-alto);
  box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.06);
}

.tm-compras-pie-cuenta {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 120px;
}

.tm-compras-pie-cuenta span { font-size: 12.5px; color: var(--tinta-suave); }
.tm-compras-pie-cuenta strong { font-size: 24px; font-variant-numeric: tabular-nums; }

.tm-compras-pie-acciones { display: flex; gap: 8px; }

.tm-compras-pie-vacio {
  margin: 0;
  padding: 14px;
  border: 1px dashed var(--linea);
  border-radius: 14px;
  font-size: 13px;
  color: var(--tinta-tenue);
  text-align: center;
}

/* ---------- Checador de turnos ---------- */

.tm-turnos { display: flex; flex-direction: column; gap: 12px; }

.tm-checador { text-align: center; }

.tm-checador-estado {
  margin: 10px 0 16px;
  font-size: 15px;
  color: var(--tinta-suave);
}

.tm-checador-abierto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 12px 0 18px;
}

.tm-checador-desde { font-size: 13.5px; color: var(--tinta-suave); }

/* El reloj corrido, grande y en mono: es lo que hace que se sienta un
   checador y no un formulario. */
.tm-checador-corrido {
  font-family: var(--fuente-mono);
  font-size: 40px;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}

/* Se toca al llegar y al irse, con prisa y a veces con las manos ocupadas. */
.tm-checador-boton {
  width: 100%;
  min-height: 64px;
  font-size: 19px;
}

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

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

.tm-nomina-quien { flex: 1; min-width: 130px; display: flex; flex-direction: column; gap: 1px; }
.tm-nomina-nombre { font-size: 15px; font-weight: 700; }
.tm-nomina-detalle { font-size: 12.5px; color: var(--tinta-tenue); font-variant-numeric: tabular-nums; }
.tm-nomina-pago { font-size: 19px; font-variant-numeric: tabular-nums; }

.tm-nomina-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--linea);
}

.tm-nomina-total span { font-size: 13.5px; color: var(--tinta-suave); }
.tm-nomina-total strong { font-size: 24px; font-variant-numeric: tabular-nums; }

/* El título que agrupa paneles de ajustes. Va fuera de las tarjetas para
   que se lea como un rótulo de sección y no como el nombre de un panel. */
.tm-ajustes-seccion {
  margin: 18px 4px 2px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-ajustes-seccion:first-of-type { margin-top: 6px; }

/* ---------- Armazón de Ajustes ---------- */

.tm-shell-ajustes {
  display: grid;
  gap: 16px;
}

/* En pantalla chica son DOS PASOS, no dos columnas: una barra lateral de
   200px en un celular de 360 deja al contenido con 160, que no es contenido,
   es una columna de letras (CLAUDE.md sección 11). */
.tm-shell-ajustes[data-paso="lista"] .tm-shell-cuerpo,
.tm-shell-ajustes[data-paso="lista"] [data-rol="ayuda"] { display: none; }
.tm-shell-ajustes[data-paso="detalle"] .tm-shell-lista { display: none; }

/* Un título de verdad. En mayúsculas grises y espaciadas se leía como
   etiqueta de formulario, no como el nombre de la pantalla. */
.tm-shell-titulo {
  margin: 0 0 10px;
  padding: 0 4px;
  font-size: 22px;
  font-weight: 700;
  color: var(--tinta);
}

/* En el celular, ya dentro de una sección, arriba había dos maneras de
   regresar: «← Volver a la venta» y «‹ Ajustes». Se queda la de Ajustes,
   que es a donde uno quiere volver desde ahí; a la venta se llega con el
   menú. En la computadora la lista y el detalle se ven juntos y el enlace
   a la venta se queda. (899 y no 767: el armazón parte en dos pasos por
   debajo de 900, ver ANCHO_ESCRITORIO en shell_ajustes.js.) */
@media (max-width: 899px) {
  .tm-vista:has(> [data-rol="armazon"] .tm-shell-ajustes[data-paso="detalle"]) > .tm-corte-volver {
    display: none;
  }
}

.tm-shell-lista ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.tm-shell-seccion {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 10px 12px;
  border: none;
  border-radius: 12px;
  background: transparent;
  font: inherit;
  text-align: left;
  color: var(--tinta);
  cursor: pointer;
}

.tm-shell-seccion:hover { background: var(--papel-hondo); }

.tm-shell-seccion--activa {
  background: var(--accion-tenue);
  color: var(--accion);
}

.tm-shell-seccion-icono { flex-shrink: 0; display: grid; place-items: center; }

.tm-shell-seccion-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tm-shell-seccion-nombre { font-size: 15px; font-weight: 700; }

.tm-shell-seccion-resumen {
  font-size: 12px;
  color: var(--tinta-tenue);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-shell-seccion--activa .tm-shell-seccion-resumen { color: var(--accion); opacity: 0.75; }

.tm-shell-seccion-flecha { font-size: 20px; color: var(--tinta-tenue); }

.tm-shell-volver {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  margin-bottom: 8px;
  padding: 0 4px;
  border: none;
  background: transparent;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--accion);
  cursor: pointer;
}

.tm-shell-cuerpo { min-width: 0; display: flex; flex-direction: column; gap: 12px; }

/* Las tarjetas de una misma sección iban pegadas, borde con borde: nadie
   les ponía separación. */
.tm-shell-cuerpo [data-rol="paneles"] { display: flex; flex-direction: column; gap: 12px; }

/* Tarjeta dentro de tarjeta. Las secciones grandes (Venta, Ticket, Mi
   negocio, Acceso remoto) son un panel blanco con tarjetas blancas adentro:
   dos bordes, dos márgenes, y en el celular el contenido quedaba 32 pixeles
   más angosto de lo que la pantalla daba. El panel de afuera deja de
   dibujarse; su título queda sobre el fondo, como encabezado de la
   sección, y las tarjetas de adentro son las tarjetas. */
.tm-shell-cuerpo .tm-panel:is(:has(> .tm-tarjeta-cabeza), :has(> .tm-tarjeta)) {
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.tm-shell-cuerpo .tm-panel:is(:has(> .tm-tarjeta-cabeza), :has(> .tm-tarjeta)) .tm-tarjeta {
  border-radius: var(--radio-panel);
  box-shadow: var(--sombra-suave);
}

.tm-shell-cuerpo .tm-panel > .tm-tarjeta-cabeza {
  padding: 4px 4px 0;
}

/* El título y su explicación van juntos. El párrafo traía su margen de
   navegador encima del hueco del panel, y quedaba flotando a 30 pixeles de
   lo que explicaba. En Ajustes los huecos los pone el panel, no el
   párrafo. */
.tm-shell-cuerpo .tm-panel > p,
.tm-shell-cuerpo .tm-tarjeta > p {
  margin: 0;
}

.tm-shell-cuerpo .tm-panel > h2 + p,
.tm-shell-cuerpo .tm-tarjeta > .tm-tarjeta-titulo + p {
  margin-top: -8px;
}

.tm-shell-cuerpo .tm-vista-proximamente {
  font-size: 14px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* --- Panel de dudas --- */

.tm-ayuda {
  padding: 16px;
  border: 1px solid var(--linea);
  border-radius: 16px;
  background: var(--papel-hondo);
}

.tm-ayuda-cabeza {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 12px;
  color: var(--accion);
}

.tm-ayuda-cabeza svg { flex-shrink: 0; margin-top: 1px; }
.tm-ayuda-cabeza strong { display: block; font-size: 14.5px; color: var(--tinta); }
.tm-ayuda-cabeza small { display: block; font-size: 12px; color: var(--tinta-tenue); line-height: 1.35; }

.tm-ayuda-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }

.tm-ayuda-tema button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 46px;
  padding: 8px 10px;
  border: none;
  border-radius: 10px;
  background: var(--papel-alto);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  text-align: left;
  color: var(--tinta);
  cursor: pointer;
}

.tm-ayuda-tema button:hover { color: var(--accion); }

.tm-ayuda-flecha { flex-shrink: 0; font-size: 18px; color: var(--tinta-tenue); transition: transform 0.15s ease; }
.tm-ayuda-tema--abierta .tm-ayuda-flecha { transform: rotate(90deg); }

.tm-ayuda-respuesta {
  margin: 2px 0 6px;
  padding: 4px 10px 8px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

@media (min-width: 900px) {
  /* Tres columnas: la lista, lo que se está ajustando, y las dudas. */
  .tm-shell-ajustes {
    grid-template-columns: 250px minmax(0, 1fr);
    align-items: start;
  }

  .tm-shell-ajustes:has([data-rol="ayuda"] .tm-ayuda) {
    grid-template-columns: 250px minmax(0, 1fr) 300px;
  }

  .tm-shell-ajustes[data-paso] .tm-shell-lista,
  .tm-shell-ajustes[data-paso] .tm-shell-cuerpo,
  .tm-shell-ajustes[data-paso] [data-rol="ayuda"] { display: block; }

  .tm-shell-cuerpo { display: flex; }
  .tm-shell-volver { display: none; }

  .tm-shell-lista,
  [data-rol="ayuda"] { position: sticky; top: 12px; }

  /* Un botón de guardar a todo lo ancho de la tarjeta en la computadora es
     una franja azul de 600 pixeles para una palabra. */
  .tm-shell-cuerpo .tm-panel > .tm-boton--primario { align-self: flex-end; }
}

/* Con el menú de la izquierda, la lista y las dudas a los lados, en una
   pantalla de 1280 lo que se está ajustando se quedaba con 410 pixeles: la
   columna más angosta era justo la de trabajar. Hasta que sobre espacio de
   verdad, las dudas van debajo, como en el celular. */
@media (min-width: 900px) and (max-width: 1499px) {
  .tm-shell-ajustes:has([data-rol="ayuda"] .tm-ayuda) {
    grid-template-columns: 250px minmax(0, 1fr);
  }

  .tm-shell-ajustes .tm-shell-lista { grid-row: 1 / span 2; }

  .tm-shell-ajustes [data-rol="ayuda"] {
    grid-column: 2;
    position: static;
  }
}

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

/* ---------- La bandeja en pantalla grande ---------- */
/*
   Abajo de 1024px NO cambia nada: el índice se esconde y las tarjetas se
   apilan como siempre. Ahí el ancho del ticket es el ancho de la pantalla,
   que es justo por lo que se veía bien.
*/

.tm-bandeja-indice { display: none; }

.tm-avatar { line-height: 1; }

@media (min-width: 1024px) {
  .tm-bandeja-dos {
    display: grid;
    grid-template-columns: 320px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
  }

  .tm-bandeja-indice {
    display: flex;
    flex-direction: column;
    gap: 6px;
    position: sticky;
    top: 12px;
  }

  /* Solo se ve el elegido. Los demás siguen montados —con sus escuchas y su
     ajuste a medias si lo tenían— nada más que escondidos. */
  .tm-bandeja-detalle .tm-pedido { display: none; }
  .tm-bandeja-detalle .tm-pedido--elegido { display: block; }

  /* El papel tiene un ancho y no crece: un recibo mide 80 mm. Sin tope, el
     nombre se queda en una orilla y el precio en la otra, que es justo lo
     que se veía mal. */
  .tm-bandeja-detalle .tm-pedido-papel,
  .tm-bandeja-detalle .tm-pedido-acciones { max-width: 680px; }
}

.tm-indice-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  font: inherit;
  text-align: left;
  color: var(--tinta);
  cursor: pointer;
}

.tm-indice-fila:hover { border-color: var(--tinta-tenue); }

.tm-indice-fila--elegida {
  border-color: var(--accion);
  box-shadow: 0 0 0 1px var(--accion);
}

/* El punto dice el estado sin leer: azul se está atendiendo, ámbar espera a
   alguien, verde se acabó, rojo ya se tardó. */
.tm-indice-punto {
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  border-radius: 999px;
}

.tm-indice-fila .tm-avatar {
  width: 34px;
  height: 34px;
  font-size: 12.5px;
}

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

.tm-indice-nombre {
  font-size: 14px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-indice-señas { font-size: 11.5px; color: var(--tinta-tenue); font-variant-numeric: tabular-nums; }

.tm-indice-derecha {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
}

.tm-indice-total { font-size: 14.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tm-indice-espera { font-size: 11.5px; color: var(--tinta-tenue); }
.tm-indice-espera--tarde { color: var(--peligro); font-weight: 700; }

/* ---------- Borrar y restablecer ---------- */
/*
   Esta pantalla se ve a propósito apagada. Los botones que borran son los
   únicos con color, y el color es el de peligro. Nada aquí invita a que lo
   aprieten: el que llegó, ya sabía a qué venía.
*/

.tm-aviso {
  padding: 12px 14px;
  border-radius: var(--radio-panel);
  border-left: 3px solid var(--alerta);
  background: var(--papel-hondo);
  color: var(--tinta);
  font-size: 13.5px;
  line-height: 1.5;
}

.tm-aviso--alerta { border-left-color: var(--alerta); }

.tm-areas {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 12px 0;
}

.tm-area {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 48px;
  padding: 11px 13px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  cursor: pointer;
}

.tm-area input {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  accent-color: var(--peligro);
}

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

.tm-area-nombre {
  font-size: 14px;
  font-weight: 600;
}

/* Lo que se arrastra se dice aquí, en la casilla que lo arrastra: es donde
   se está tomando la decisión, no en el resumen de hasta abajo. */
.tm-area-arrastra {
  color: var(--peligro);
  font-size: 12.5px;
  line-height: 1.45;
}

.tm-area-cuantos {
  flex-shrink: 0;
  color: var(--tinta-suave);
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tm-area--elegida {
  border-color: var(--peligro);
  background: var(--peligro-fondo);
}

.tm-area--vacia {
  cursor: default;
  opacity: 0.55;
}

.tm-area--vacia .tm-area-cuantos {
  color: var(--tinta-tenue);
  font-weight: 500;
}

.tm-resumen-borrado {
  padding: 14px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-resumen-borrado h3 {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tinta-suave);
}

/* La lista de números. Tabulares porque se leen en columna y bailando no se
   comparan. */
.tm-cuentas {
  margin: 0;
  padding-left: 18px;
  font-size: 14px;
  line-height: 1.7;
}

.tm-cuentas b { font-variant-numeric: tabular-nums; }

.tm-resumen-nota {
  margin: 10px 0 12px;
  color: var(--tinta-suave);
  font-size: 13px;
  line-height: 1.5;
}

.tm-conserva {
  margin: 0 0 12px;
  color: var(--tinta-suave);
  font-size: 13px;
  line-height: 1.5;
}

.tm-panel--peligro { border: 1px solid var(--peligro); }

.tm-panel-enlace--peligro .tm-panel-enlace-titulo { color: var(--peligro); }

/* --- El diálogo del PIN --- */

.tm-modal--pin { max-width: 420px; }

.tm-modal-titulo {
  margin: 0 0 12px;
  font-size: 17px;
  font-weight: 700;
}

.tm-modal-detalle {
  margin-bottom: 14px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-modal-detalle ul { margin: 0; }

.tm-modal-nota {
  margin: 10px 0 0;
  color: var(--tinta-suave);
  font-size: 12.5px;
}

.tm-campo--pin { display: block; }

.tm-campo--pin > span {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: 600;
}

.tm-campo--pin input {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
  font-family: var(--fuente-mono);
  font-size: 20px;
  letter-spacing: 0.3em;
}

.tm-modal-error {
  margin: 8px 0 0;
  color: var(--peligro);
  font-size: 13px;
}

/* ---------- Elegir el sonido del escáner ---------- */
/*
   Cuadrícula, no lista: son seis y se comparan entre sí. Cada uno suena al
   tocarlo, así que el botón es a la vez la muestra y la elección.
*/

/* Dos columnas en el celular y tres en pantalla ancha: seis caben parejos
   en 3+3 o 2+2+2. Con `auto-fill` en la computadora salían 4+2. */
.tm-sonidos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 10px 0 8px;
}

@media (min-width: 560px) {
  .tm-sonidos {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.tm-sonido {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-height: 48px;
  padding: 10px 12px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-sonido-nombre {
  font-size: 14px;
  font-weight: 600;
}

.tm-sonido-pista {
  color: var(--tinta-suave);
  font-size: 12px;
  line-height: 1.4;
}

.tm-sonido--elegido {
  border-color: var(--accion);
  box-shadow: inset 0 0 0 1px var(--accion);
}

.tm-sonido--elegido .tm-sonido-nombre { color: var(--accion); }

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

/* Subir y bajar el logo: los dos botones y, en medio, dónde quedó. */
/* [−] valor [+] en un solo renglón, pase lo que pase.
   Antes envolvía: con la palabra dentro del botón ("↑ Subir") no cabían en
   pantalla chica y el control se partía en TRES filas de 48px para elegir un
   número. La flecha pegada al valor dice lo mismo en un tercio del alto. */
.tm-logo-sitio {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 6px 0;
  flex-wrap: nowrap;
}

.tm-logo-sitio-medida {
  flex: 1;
  min-width: 0;
  text-align: center;
  color: var(--tinta);
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Cuadrado, del mínimo táctil. Sin `padding: 0` el ancho lo mandaba el
   relleno de 20px que traen todos los botones. */
.tm-paso {
  flex: 0 0 46px;
  width: 46px;
  min-height: 46px;
  padding: 0;
  font-size: 18px;
}

/* Las dos maneras de darle su ticket al cliente, juntas y del mismo peso:
   ninguna es "la buena". */
.tm-ultima-venta-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tm-ultima-venta-acciones .tm-boton {
  flex: 1;
  min-width: 140px;
}

/* El atajo del diálogo: pegado bajo el campo que llena, y visiblemente
   menos importante que el botón que sí hace algo. */
.tm-dato-atajo {
  margin-top: 8px;
  min-height: 40px;
  font-size: 13px;
}

/* Cómo está la tienda ahorita: tres estados, uno prendido. Se toca con el
   pulgar y a las once de la noche, así que van grandes. */
.tm-cortina {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 8px;
  margin-top: 10px;
}

.tm-cortina-opcion {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-height: 64px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-cortina-nombre { font-size: 15px; font-weight: 700; }

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

.tm-cortina-opcion--activa {
  border-color: var(--accion);
  box-shadow: inset 0 0 0 1px var(--accion);
}

.tm-cortina-opcion--activa .tm-cortina-nombre { color: var(--accion); }

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

/* ---------- Cajas ---------- */

.tm-cajas-barra {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-cajas-titulo {
  color: var(--tinta-suave);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.tm-cajas-opciones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tm-caja-chip {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 48px;
  padding: 8px 14px;
  border: 1px solid var(--boton-borde);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-caja-chip-nombre { font-size: 14px; font-weight: 700; }

.tm-caja-chip-quien {
  color: var(--tinta-suave);
  font-size: 12px;
}

.tm-caja-chip--activa {
  border-color: var(--accion);
  box-shadow: inset 0 0 0 1px var(--accion);
}

.tm-caja-chip--activa .tm-caja-chip-nombre { color: var(--accion); }

.tm-cajas-lista {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 0;
}

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

.tm-caja-fila--apagada { opacity: 0.6; }

.tm-caja-datos {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 140px;
}

.tm-caja-nombre { font-size: 14px; font-weight: 600; }

.tm-caja-estado {
  color: var(--tinta-suave);
  font-size: 12.5px;
}

/* Cuál de todas es la pantalla donde estoy parado. */
.tm-caja-esta {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--accion);
  color: #ffffff;
  font-size: 11px;
  font-weight: 700;
}

.tm-caja-acciones {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

/* Quién hizo un movimiento de caja, al lado de su motivo. */
.tm-corte-quien { color: var(--tinta-suave); }

/* Un código extra y su botón de quitar, en el mismo renglón. Se apilan en
   pantalla angosta: el campo de un código de barras necesita todo el ancho
   que pueda, son trece dígitos. */
.tm-codigo-fila {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}

.tm-codigo-fila input {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 0 14px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-variant-numeric: tabular-nums;
}

.tm-codigo-fila .tm-boton { flex-shrink: 0; }

@media (max-width: 420px) {
  .tm-codigo-fila { flex-wrap: wrap; }
  .tm-codigo-fila input { flex-basis: 100%; }
  /* Con cámara, el campo y su cámara juntos; «Quitar» abajo. */
  .tm-codigo-fila:has(.tm-boton-camara) input { flex-basis: calc(100% - 56px); }
  .tm-codigo-fila:has(.tm-boton-camara) [data-quitar-codigo] { flex-basis: 100%; }
}

/* ---------- El botón de la cámara (core/camara_codigos.js, botonCamara) ----------

   Junto a un buscador o a un campo de código, solo en el teléfono: en la
   computadora no se pinta (ahí está la pistola, que sigue sirviendo igual). */
.tm-boton-camara {
  flex: none;
  width: 48px;
  height: 48px;
  display: inline-grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--boton-borde);
  box-shadow: var(--boton-sombra);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
  cursor: pointer;
}

.tm-boton-camara:active { background: var(--accion-tenue); color: var(--accion); }
.tm-boton-camara:focus-visible { outline: 2px solid var(--accion); outline-offset: 2px; }

.tm-campo-camara { display: flex; gap: 8px; align-items: stretch; }
.tm-campo-camara input { flex: 1; min-width: 0; }
.tm-env-buscar .tm-boton-camara { width: 52px; height: 52px; }

/* El aviso de lo que no se ve en la tienda. No es una barra de
   herramientas: aparece cuando hay algo oculto y se va solo cuando ya no
   queda nada. Dos botones fijos arriba de la lista estarían estorbando
   todos los días por algo que se hace después de importar y casi nunca más. */
.tm-aviso-tienda {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 10px 0;
  padding: 12px 14px;
  border-left: 3px solid var(--alerta);
  border-radius: 0 12px 12px 0;
  background: var(--papel-hondo);
}

.tm-aviso-tienda-texto {
  color: var(--tinta);
  font-size: 13.5px;
  line-height: 1.5;
}

.tm-aviso-tienda strong { font-variant-numeric: tabular-nums; }

/* El antes y el después de arreglar mayúsculas. El "antes" va apagado para
   que la vista se lea de un golpe: lo que importa es cómo va a quedar. */
.tm-mayusculas-muestra li {
  line-height: 1.7;
  font-size: 13px;
}

.tm-mayusculas-muestra span {
  color: var(--tinta-tenue);
}

/* ---------- Recibir mercancía ---------- */

/* El aviso de lo que viene en camino, al pie de Compras. Nadie entra a
   "recibir" por su cuenta: se acuerda cuando ve el camión, y para entonces
   ya está en esta pantalla. */
.tm-compras-encamino {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  padding: 14px 16px;
  border: 1px solid var(--linea);
  border-left: 3px solid var(--alerta);
  border-radius: 0 14px 14px 0;
  background: var(--papel-alto);
  color: var(--tinta);
  text-decoration: none;
}

.tm-compras-encamino-texto {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 14px;
}

.tm-compras-encamino-texto span {
  color: var(--tinta-suave);
  font-size: 12.5px;
}

.tm-recibir-lista {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}

.tm-recibir-fila {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-recibir-datos { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tm-recibir-proveedor { font-size: 15px; font-weight: 600; }
.tm-recibir-senas { color: var(--tinta-suave); font-size: 12.5px; }

.tm-recibir-total {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tm-recibir-renglones {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 0;
}

.tm-recibir-renglon {
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
}

/* Lo que se corrigió se marca: al final hay que poder ver de un golpe qué
   se cambió respecto al papel, sin releer los veinte renglones. */
.tm-recibir-renglon--cambiado {
  border-color: var(--alerta);
  box-shadow: inset 3px 0 0 var(--alerta);
}

.tm-recibir-nombre { margin: 0; font-size: 14px; font-weight: 600; }

.tm-recibir-pedido {
  margin: 2px 0 8px;
  color: var(--tinta-suave);
  font-size: 12.5px;
}

.tm-recibir-campos {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.tm-recibir-campos .tm-campo { flex: 1; min-width: 120px; }

.tm-recibir-campos span {
  display: block;
  margin-bottom: 4px;
  color: var(--tinta-suave);
  font-size: 12px;
  font-weight: 600;
}

.tm-recibir-campos input {
  width: 100%;
  min-height: 48px;
  padding: 0 12px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-variant-numeric: tabular-nums;
}

.tm-recibir-aviso {
  margin: 8px 0 0;
  color: var(--alerta);
  font-size: 12.5px;
}

.tm-recibir-pie {
  position: sticky;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.06);
}

.tm-recibir-cuenta { display: flex; flex-direction: column; gap: 2px; }
.tm-recibir-cuenta span { color: var(--tinta-suave); font-size: 12.5px; }
.tm-recibir-cuenta strong { font-size: 20px; font-variant-numeric: tabular-nums; }

/* ---------- Reporte de actividad ---------- */

.tm-actividad-filtros {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 14px 0;
}

.tm-actividad-grupo {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}

.tm-actividad-grupo::-webkit-scrollbar { display: none; }

.tm-actividad-grupo .tm-chip {
  flex-shrink: 0;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--boton-borde);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}

.tm-actividad-grupo .tm-chip--activo {
  border-color: transparent;
  background: var(--accion);
  color: #ffffff;
}

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

/* La barra de color es lo que hace legible el reporte: sin ella, una venta
   cancelada se ve igual que abrir la caja y hay que leerlo entero. */
.tm-actividad-renglon {
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-left: 3px solid var(--linea);
  border-radius: 0 14px 14px 0;
  background: var(--papel-alto);
}

.tm-actividad-renglon--delicada { border-left-color: var(--peligro); }
.tm-actividad-renglon--ojo { border-left-color: var(--alerta); }
.tm-actividad-renglon--normal { border-left-color: var(--linea); }

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

.tm-actividad-titulo {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  text-wrap: pretty;
}

.tm-actividad-renglon--delicada .tm-actividad-titulo { color: var(--peligro); }

.tm-actividad-cuando {
  flex-shrink: 0;
  color: var(--tinta-tenue);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tm-actividad-apunte {
  margin: 4px 0 0;
  color: var(--tinta-suave);
  font-size: 13px;
  line-height: 1.45;
}

.tm-actividad-quien {
  margin: 6px 0 0;
  color: var(--tinta-tenue);
  font-size: 12px;
  font-weight: 600;
}

/* ---------- Probar la pistola ----------
   El blanco es grande a propósito: se dispara desde lejos, de pie, con la
   pistola en una mano, y hay que poder leer el resultado sin acercarse. */

.tm-pistola-blanco {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 160px;
  margin: 16px 0;
  padding: 20px;
  border: 2px dashed var(--tinta-tenue);
  border-radius: 18px;
  color: var(--tinta-tenue);
  text-align: center;
}

.tm-pistola-blanco p {
  margin: 0;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 22px;
  font-weight: 600;
  color: var(--tinta);
  word-break: break-all;
}

.tm-pistola-blanco--ok {
  border-color: var(--ok);
  border-style: solid;
  background: #E4F5E8;
  color: var(--ok);
}

.tm-pistola-blanco--alerta {
  border-color: var(--alerta);
  border-style: solid;
  color: var(--alerta);
}

.tm-pistola-blanco--peligro {
  border-color: var(--peligro);
  border-style: solid;
  background: #F4E4E4;
  color: var(--peligro);
}

.tm-pistola-fallo {
  margin: 0 0 16px;
  padding: 14px 16px;
  border-left: 4px solid var(--tinta-tenue);
  border-radius: 0 12px 12px 0;
  background: var(--papel-hondo);
}

.tm-pistola-fallo--ok { border-left-color: var(--ok); }
.tm-pistola-fallo--alerta { border-left-color: var(--alerta); }
.tm-pistola-fallo--peligro { border-left-color: var(--peligro); }

.tm-pistola-fallo h2 {
  margin: 0 0 6px;
  font-size: 16px;
}

.tm-pistola-fallo p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

.tm-pistola-arreglo {
  margin-top: 8px !important;
  color: var(--tinta) !important;
}

.tm-pistola-datos {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.tm-pistola-datos th,
.tm-pistola-datos td {
  padding: 9px 0;
  text-align: left;
  border-bottom: 1px solid var(--linea);
  vertical-align: top;
}

.tm-pistola-datos th {
  width: 45%;
  font-weight: 600;
  color: var(--tinta-suave);
}

.tm-pistola-datos td {
  font-variant-numeric: tabular-nums;
}

.tm-pistola-datos code {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  word-break: break-all;
}

.tm-pistola-limite {
  color: var(--tinta-tenue);
}

/* El icono de WhatsApp lleva su propio verde y no el color del botón que lo
   contiene: es lo que lo hace reconocible antes de leer la palabra. Por eso
   se sale del `currentColor` que siguen los demás iconos del sistema.

   El tamaño se manda desde aquí y no desde el JavaScript: así crece en
   pantalla chica sin tener que tocar las seis pantallas que lo usan. */
.tm-icono-whatsapp {
  width: 22px;
  height: 22px;
  color: var(--whatsapp);
  flex-shrink: 0;
}

/* En el teléfono se ve más grande, no más chico. Es la pantalla donde el
   dueño trabaja a diario y donde un icono de 22px se pierde: la superficie
   es menor pero la mano está más lejos de la letra. */
@media (max-width: 767px) {
  .tm-icono-whatsapp {
    width: 26px;
    height: 26px;
  }
}

/* Cuando va metido dentro de un texto —la etiqueta de Ajustes— se mide en
   `em` para seguir a la letra que lo rodea. En píxeles fijos se encimaba
   con el renglón. */
.tm-icono-whatsapp--enlinea {
  width: 1.25em;
  height: 1.25em;
  vertical-align: -0.25em;
}

@media (max-width: 767px) {
  .tm-icono-whatsapp--enlinea {
    width: 1.4em;
    height: 1.4em;
  }
}

/* ---------- Ajustes del ticket en pantalla chica ----------
   El panel medía 1481px de alto en un teléfono: para mover un logo había
   que recorrerlo entero. Más de la mitad se la llevaba la vista previa, y
   el resto eran huecos entre cosas de una línea. */

@media (max-width: 767px) {
  /* La vista previa es para orientarse, no para revisar: lo que se revisa
     de verdad es "Ver como saldría impreso", que abre el ticket completo.
     El ticket sigue desplazándose dentro del marco, no se pierde nada. */
  .tm-ajustes-ticket-iframe {
    height: 300px;
  }

  .tm-ajustes-ticket,
  .tm-ajustes-ticket-controles {
    gap: 14px;
  }

  .tm-ajustes-ticket-previa {
    padding: 12px;
    gap: 10px;
  }

  /* Una etiqueta, un control y una línea de ayuda no necesitan el mismo
     aire que un formulario completo. */
  .tm-ajustes-ticket-controles .tm-campo {
    gap: 4px;
  }

  .tm-ajustes-ticket-controles .tm-ajustes-pista {
    line-height: 1.35;
    margin-top: 2px;
  }
}

/* ---------- Ajustes del ticket, en tarjetas ----------
   La forma viene de una referencia que pasó el dueño: cada grupo en su
   tarjeta con icono y título, los valores en deslizadores con su número al
   lado, y la vista previa a la derecha en pantalla grande y hasta abajo en
   el teléfono. Los colores NO se copiaron: son los del proyecto.

   Los deslizadores sustituyen a los pasos de [−] y [+]. Con dos botones y
   un valor, cada ajuste ocupaba un renglón entero de 46px y había que
   picarle diez veces para cruzar el rango; con la barra se ve dónde está el
   número dentro de lo posible, que es la mitad de la información. */

.tm-panel--ticket {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.tm-tarjeta-cabeza {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tm-tarjeta-cabeza h2 {
  margin: 0;
  font-size: 18px;
}

.tm-tarjeta-sub {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-tarjeta-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 13px;
  background: var(--accion-tenue);
  color: var(--accion);
}

.tm-tarjeta {
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: var(--radio-tarjeta);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.tm-tarjeta-titulo {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--tinta);
}

.tm-tarjeta-titulo svg {
  color: var(--tinta-suave);
  flex-shrink: 0;
}

/* Dos campos por renglón cuando caben, apilados cuando no.

   `minmax(0, 1fr)` y no `1fr` a secas: `1fr` no deja que la columna sea
   más angosta que el ancho natural de su campo, y en la computadora, con la
   tarjeta en medio de Ajustes, RFC y WhatsApp se salían por el borde.

   «Cuando caben» lo dice el ancho de la TARJETA, no el de la pantalla: en
   la computadora la tarjeta de Formato del ticket es angosta (la vista
   previa va a su lado) y con dos columnas «80 mm — térmica grande» salía
   cortado, mientras que la de Mi negocio sí tiene espacio de sobra. */
.tm-tarjeta:has(> .tm-tarjeta-par) {
  container-type: inline-size;
}

.tm-tarjeta-par {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

@container (min-width: 400px) {
  .tm-tarjeta-par {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* ---------- Palanca de encendido ---------- */

/* `position: relative` sujeta aquí la casilla de verdad, que va escondida
   con `position: absolute`. Sin él, la casilla colgaba del documento
   entero en vez de la zona que se desliza, y el documento crecía hasta
   donde estuviera la última palanca: en Ajustes → Venta, con cinco, la
   pantalla se seguía deslizando 470 pixeles en blanco después del final. */
.tm-palanca {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  cursor: pointer;
}

.tm-palanca input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.tm-palanca-riel {
  position: relative;
  width: 44px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 999px;
  background: var(--papel-hondo);
  border: 1px solid var(--linea);
  transition: background-color 0.15s ease;
}

.tm-palanca-riel::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--papel-alto);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  transition: transform 0.15s ease;
}

.tm-palanca input:checked + .tm-palanca-riel {
  background: var(--accion);
  border-color: var(--accion);
}

.tm-palanca input:checked + .tm-palanca-riel::after {
  transform: translateX(18px);
}

.tm-palanca input:focus-visible + .tm-palanca-riel {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* El texto de la palanca se esconde en pantalla chica: el título de la
   tarjeta ya dice de qué es, y ahí el ancho es lo que escasea. */
.tm-palanca-texto {
  font-size: 13px;
  font-weight: 600;
  color: var(--tinta-suave);
}

@media (max-width: 560px) {
  .tm-palanca-texto {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
}

/* ---------- Deslizador con su número ---------- */

.tm-deslizador {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tm-deslizador > label {
  font-size: 13px;
  font-weight: 600;
  color: var(--tinta-suave);
}

.tm-deslizador-fila {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tm-deslizador-fila input[type="range"] {
  flex: 1;
  min-width: 0;
  height: 44px;
  accent-color: var(--accion);
}

/* El número en su recuadro, como en la referencia: se lee sin buscarlo y no
   baila al cambiar, porque las cifras van tabulares. */
.tm-deslizador-valor {
  flex-shrink: 0;
  min-width: 74px;
  padding: 7px 10px;
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--papel-hondo);
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ---------- El apunte con foco ---------- */

.tm-pista-tip {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--accion-pastel);
  color: var(--tinta-suave);
  font-size: 12.5px;
  line-height: 1.4;
}

.tm-pista-tip svg {
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--accion);
}

/* ---------- La vista previa: al lado en grande, abajo en el teléfono ---------- */

@media (min-width: 1024px) {
  .tm-ajustes-ticket {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 352px;
    align-items: start;
    gap: 16px;
  }

  /* Se queda a la vista mientras se recorren los controles: el punto de
     tener la vista previa es no perderla de vista al ajustar. */
  .tm-ajustes-ticket-previa {
    position: sticky;
    top: 16px;
  }
}

/* ---------- Horario: un renglón por día ----------
   Antes cada día ocupaba tres: el nombre en su propia línea (porque llevaba
   `flex: 1 0 100%`), la casilla de cerrado, y las dos horas. Siete días así
   son veintiún renglones para capturar lo que casi siempre es el mismo
   horario repetido. */

.tm-dia {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--linea);
}

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

.tm-dia-nombre {
  width: 32px;
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 700;
}

.tm-dia-horas {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.tm-dia-hora {
  min-width: 0;
  flex: 1;
  min-height: 40px;
  padding: 0 6px;
  border: 1px solid var(--linea);
  border-radius: 9px;
  background: var(--papel-alto);
  font: inherit;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.tm-dia-hora:disabled {
  opacity: 0.4;
}

.tm-dia-a {
  flex-shrink: 0;
  font-size: 12px;
  color: var(--tinta-tenue);
}

/* El día cerrado se apaga entero, no solo sus campos: así se distingue de
   un vistazo sin leer las horas. */
.tm-dia--cerrado .tm-dia-nombre {
  color: var(--tinta-tenue);
}

.tm-dia-copiar {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border: 1px solid var(--boton-borde);
  box-shadow: var(--boton-sombra);
  border-radius: 9px;
  background: var(--papel-alto);
  color: var(--tinta-suave);
  font-size: 15px;
  cursor: pointer;
}

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

/* En pantalla angosta el botón de copiar estorba más de lo que ayuda: se
   copia desde el ancho, que es donde se captura un horario nuevo. */
@media (max-width: 400px) {
  .tm-dia-copiar {
    display: none;
  }
}

/* En el celular el relojito de cada hora se comía el espacio del texto y
   se leía «08:00 a. n». Ahí sobra: tocar el campo ya abre el selector. */
@media (max-width: 480px) {
  .tm-dia-hora {
    padding: 0 8px;
  }

  .tm-dia-hora::-webkit-calendar-picker-indicator {
    display: none;
  }
}

/* ---------- Datos del negocio: el logo y la barra de guardar ---------- */

.tm-chip-opcional {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--papel-hondo);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--tinta-tenue);
}

/* El logo dejaba de ser un `input type=file` pelón: ese control no dice qué
   hay puesto ahora ni qué se espera, y en el teléfono sale con el aspecto
   que le dé la gana a cada navegador. */
/* `relative`: sujeta el campo de archivo escondido, igual que la palanca. */
.tm-suelta {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px dashed var(--tinta-tenue);
  border-radius: 14px;
}

.tm-suelta-previa {
  width: 60px;
  height: 60px;
  flex-shrink: 0;
  border-radius: 12px;
  background: var(--papel-hondo);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.tm-suelta-previa img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Si al texto no le quedan 140 pixeles, el botón baja a su propio
   renglón en vez de exprimirlo. */
.tm-suelta-texto {
  flex: 1 1 140px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tm-suelta-texto strong { font-size: 13px; }
.tm-suelta-texto span { font-size: 12px; color: var(--tinta-suave); }

/* El <input type=file> se esconde y su <label> hace de botón: es la única
   manera de darle aspecto propio sin JavaScript de por medio. Se esconde
   sin `display:none` para que siga siendo alcanzable con el teclado. */
.tm-archivo-oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
}

.tm-archivo-oculto:focus-visible + label,
.tm-suelta .tm-archivo-oculto:focus-visible ~ label {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* Guardar deja de esconderse al final del formulario: en el teléfono había
   que recorrer toda la pantalla para encontrarlo. */
.tm-barra-guardar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border-radius: 14px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  box-shadow: var(--sombra-suave);
}

.tm-barra-guardar span {
  flex: 1;
  font-size: 12.5px;
  color: var(--tinta-suave);
}

/* ---------- Estado del producto en la tienda, por producto ----------
   Antes solo se podía cambiar en bloque ("poner los 1,297 en la tienda").
   El color del carrito es el mensaje: se reconoce sin leer, que es de lo
   que se trata cuando hay que revisar mil trescientos renglones. */

.tm-acciones-producto {
  position: relative;
  display: inline-flex;
  gap: 6px;
  align-items: center;
}

.tm-carrito-estado--ok { color: var(--ok); }
.tm-carrito-estado--peligro { color: var(--peligro); }
.tm-carrito-estado--apagado { color: var(--tinta-tenue); }

.tm-boton-falta--puesto {
  color: var(--alerta);
  background: #fdf3e3;
}

/* `fixed` y colgado del BODY. Dentro de la tarjeta no servía: la tarjeta
   lleva `transform` para deslizarse, y un ancestro con transform convierte
   `fixed` en `absolute` — el menú quedaba dentro del renglón y su
   `overflow: hidden` lo recortaba. */
.tm-menu-web {
  position: fixed;
  z-index: 90;
  width: 250px;
  padding: 6px;
  border-radius: 14px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.14);
}

.tm-menu-web-opcion {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  width: 100%;
  padding: 9px 10px;
  border: none;
  border-radius: 10px;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-menu-web-opcion--activa {
  background: var(--papel-hondo);
}

.tm-menu-web-opcion:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: -2px;
}

.tm-menu-web-punto {
  width: 11px;
  height: 11px;
  margin-top: 3px;
  flex-shrink: 0;
  border-radius: 999px;
}

.tm-menu-web-punto--ok { background: var(--ok); }
.tm-menu-web-punto--peligro { background: var(--peligro); }
.tm-menu-web-punto--apagado { background: var(--tinta-tenue); }

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

.tm-menu-web-texto strong { font-size: 13px; }
.tm-menu-web-texto span { font-size: 11.5px; color: var(--tinta-suave); line-height: 1.3; }

/* En pantalla angosta el menú se salía de la pantalla: anclado al botón, y
   el botón vive pegado a la orilla derecha del renglón. Mover el ancla no
   alcanza —el renglón entero está allá—, así que abajo de 560px deja de
   colgar del botón y se vuelve una hoja que sube desde el pie. Ahí siempre
   cabe, se lee sin apretar y se alcanza con el pulgar. */
@media (max-width: 560px) {
  .tm-menu-web {
    position: fixed;
    top: auto;
    right: 8px;
    bottom: 8px;
    left: 8px;
    width: auto;
    padding: 8px;
    border-radius: 18px;
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.18);
  }

  .tm-menu-web-opcion {
    padding: 13px 12px;
  }

  .tm-menu-web-texto strong { font-size: 14px; }
  .tm-menu-web-texto span { font-size: 12.5px; }
}

/* ---------- Elegir cómo se ven los productos ----------
   Hasta ahora lo decidía el ancho de la pantalla y ya: tabla arriba de
   768px, tarjetas abajo. En la pantalla del mostrador conviene la tabla,
   pero en el celular a veces se quiere ver la foto y a veces caben más
   productos en filas. Se elige, y la elección es de ESTE aparato. */

.tm-barra-lista {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 12px;
}

.tm-barra-lista .tm-busqueda {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
}

/* Un botón, no dos. Dos ocupaban el doble de ancho para ofrecer lo mismo,
   y ese ancho le hacía falta al buscador. */
/* Las dos clases: .tm-vista-boton, más abajo, le quitaba el borde. */
.tm-vista-boton.tm-vista-boton--solo {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--boton-borde);
  box-shadow: var(--boton-sombra);
  border-radius: 12px;
  background: var(--papel-alto);
  color: var(--tinta-suave);
  cursor: pointer;
}

.tm-vista-boton {
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  color: var(--tinta-tenue);
  cursor: pointer;
}

/* ---------- El buscador de la lista ----------
   Llevaba adentro el botón de filtros. Los filtros son ahora la tira de
   pastillas de abajo, y el campo recuperó todo su ancho. */

.tm-busca-caja {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
}

.tm-busca-caja .tm-busqueda {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
}

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

/* Tres clases para ganarle al media query y a .store-grid, que fija su
   propio display sin condición y se carga después. */
.tm-vista--tarjetas .tm-tabla-productos {
  display: none;
}

.tm-vista--tarjetas .tm-tarjetas-productos-movil.store-grid {
  display: grid;
}

.tm-vista--filas .tm-tarjetas-productos-movil.store-grid {
  display: grid;
}

@media (min-width: 768px) {
  /* En pantalla ancha "filas" es la tabla de verdad. */
  .tm-vista--filas .tm-tabla-productos {
    display: table;
  }

  .tm-vista--filas .tm-tarjetas-productos-movil.store-grid {
    display: none;
  }
}

/* En el teléfono "filas" NO es la tabla: una tabla de cinco columnas ahí
   solo cabe con barra horizontal, y eso lo prohíbe CLAUDE.md sección 11.
   Es la misma tarjeta acostada — mismo HTML, otra forma.

   Las medidas NO se inventaron: son las mismas de la fila de la tienda en
   línea (.tm-fila-producto en store/store.css), que el dueño probó con la
   Coca-Cola y funcionó. Copiarlas en vez de afinar unas propias evita que
   dos listas que hacen lo mismo terminen viéndose distinto. Si allá se
   cambian, aquí hay que venir a igualarlas: son dos componentes, no uno. */
@media (max-width: 767px) {
  .tm-vista--filas .tm-tarjetas-productos-movil.store-grid {
    grid-template-columns: 1fr;
    justify-content: stretch;
    gap: 8px;
  }

  /* Orilla fina que sí se ve y esquina menos redonda, como los botones y el
     Checador. La sombra corta va en el envoltorio: el renglón vive dentro
     de uno que recorta lo que se le sale. */
  .tm-vista--filas .store-product-card {
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 10px 10px 10px 12px;
    border-radius: 14px;
    border: 1px solid var(--boton-borde);
  }

  .tm-vista--filas .tm-deslizable {
    border-radius: 14px;
    box-shadow: var(--boton-sombra);
  }

  /* El botón de editar, que aquí va solo: orilla fina, fondo blanco, y se
     hunde al apretarlo. */
  .tm-vista--filas .store-product-controls--admin .tm-boton-lapiz {
    border: 1px solid var(--boton-borde);
    background: var(--papel-alto);
    box-shadow: var(--boton-sombra);
  }

  .tm-vista--filas .store-product-controls--admin .tm-boton-lapiz:active {
    transform: translateY(var(--boton-hundir));
    box-shadow: none;
  }

  /* Uno sobre otro y pegados a la derecha: el nombre se queda con el resto
     del renglón. */
  .tm-vista--filas .tm-dos-precios {
    flex-direction: column;
    align-items: flex-end;
  }

  .tm-vista--filas .store-product-image {
    width: 64px;
    height: 64px;
    flex-shrink: 0;
    margin: 0;
    border-radius: 12px;
    display: grid;
    place-items: center;
    font-size: 10px;
    font-weight: 700;
    color: var(--tinta-tenue);
    text-align: center;
    background: var(--papel-hondo);
  }

  .tm-vista--filas .store-product-image:has(img) {
    background: #ffffff;
  }

  .tm-vista--filas .store-product-name {
    order: 1;
    flex: 1;
    min-width: 0;
    min-height: 0;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    -webkit-line-clamp: 2;
    line-clamp: 2;
  }

  .tm-vista--filas .store-product-description {
    display: none;
  }

  .tm-vista--filas .store-price-status-row {
    order: 2;
    flex-shrink: 0;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
  }

  .tm-vista--filas .store-product-price {
    font-size: 16px;
    font-weight: 800;
  }

  /* La insignia de existencias, dentro de la miniatura, al centro y pegada
     abajo. Es donde la quiere el dueño.

     Antes se sacaba a `position: static` para que no tapara la foto, pero
     con eso pasaba a ser un hijo más de la rejilla del chip —que está
     centrada— y el número acababa encima del cartel de «Sin foto». Puesta
     abajo tapa una franja de tres milímetros y deja el resto libre, que es
     lo que se quería desde el principio.

     Los 64px del chip son el motivo de que la insignia lleve solo la cifra
     y no la presentación completa (ver tarjeta_producto.js). */
  .tm-vista--filas .store-product-status {
    position: absolute;
    bottom: 2px;
    font-size: 9.5px;
    padding: 0 5px;
  }

  /* El chip es el marco de referencia de esa insignia. Sin esto se
     posicionaría contra la tarjeta entera y aparecería abajo del renglón. */
  .tm-vista--filas .store-product-image {
    position: relative;
  }

  .tm-vista--filas .store-product-controls {
    order: 3;
    flex-shrink: 0;
    margin-top: 0;
  }

  .tm-vista--filas .store-product-controls--admin .tm-fila-boton {
    flex: 0 0 38px;
    width: 38px;
    min-height: 38px;
  }

  /* El carrito de estado se fue detrás, al deslizar, y el lápiz se quedó a
     la vista. El dueño lo pidió al revés de como estaba: «creo que será más
     útil el lápiz que el carrito como acceso rápido». Tiene razón — editar
     un producto se hace a diario y cambiar cómo se ve en la tienda no. */
  .tm-vista--filas .tm-carrito-estado {
    display: none;
  }
}

/* ---------- Deslizar un renglón para ver sus atajos ----------
   Con tres botones a la vista el nombre se cortaba en «ACEITE NUTRIOLI…», y
   con mil trescientos productos el nombre es lo único que distingue uno de
   otro. El lápiz y el bote se van detrás y salen al deslizar. */

.tm-deslizable {
  position: relative;
  overflow: hidden;
  border-radius: var(--radio-tarjeta);
}

.tm-cajon {
  position: absolute;
  /* En el extremo DERECHO: el pulgar sale de ahí y el gesto natural es
     empujar el renglón hacia adentro, no jalarlo desde el otro lado. */
  inset: 0 0 0 auto;
  width: 96px;
  display: flex;
  /* APILADOS, uno encima del otro. El dueño lo prefiere así en el teléfono.
     Antes iban en fila y no cabían: dos botones de 40px con 8 de separación
     piden 88px, y descontando el margen quedaban 86 disponibles. Como el
     contenedor traía `wrap`, el segundo se caía a un segundo renglón que
     el alto del cajón no tenía — y el `overflow: hidden` del renglón se lo
     comía. Se veía medio botón rojo asomando por debajo de la tarjeta. */
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  justify-content: center;
  gap: 6px;
  padding: 6px 10px 6px 0;
}

/* Botones, no losas. Antes ocupaban todo el alto del renglón y se veían
   como dos rebanadas de color pegadas al borde; con la misma forma que el
   carrito se leen como lo que son —dos botones más— y el color se queda
   nada más de relleno. */
.tm-cajon-boton {
  /* Se reparten el alto del renglón en vez de medir un número fijo. Así
     caben siempre, mida lo que mida la tarjeta —cambia con el nombre, con
     la miniatura, con el tamaño de letra del teléfono— y nunca vuelve a
     asomar medio botón por fuera.
     Anchos completos y bajitos: pierden alto pero ganan ancho, así que el
     área que toca el dedo se mantiene. */
  width: 100%;
  flex: 1 1 0;
  min-height: 30px;
  max-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  color: #ffffff;
}

.tm-cajon-boton--editar { background: var(--accion); }
.tm-cajon-boton--borrar { background: var(--peligro); }

.tm-cajon-boton:focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: -3px;
}

/* La tarjeta va encima y se corre. El fondo es opaco a propósito: si fuera
   transparente se verían los atajos por debajo del texto. */
.tm-deslizable > .store-product-card {
  position: relative;
  /* El JavaScript guarda "cuánto se descubrió" en positivo; el signo vive
     aquí y en un solo sitio. */
  transform: translateX(calc(var(--corrido, 0px) * -1));
  transition: transform 0.18s ease;
  background: var(--papel-alto);
}

.tm-deslizable--moviendo > .store-product-card {
  transition: none;
}

.tm-deslizable--abierto > .store-product-card {
  transform: translateX(-96px);
}

@media (prefers-reduced-motion: reduce) {
  .tm-deslizable > .store-product-card {
    transition: none;
  }
}

/* El gesto vive SOLO en la vista de filas del teléfono, que es donde falta
   el ancho. En tarjetas y en la tabla el lápiz sigue a la vista: ahí sobra
   sitio y un gesto escondido sería una función que nadie encuentra. */
.tm-deslizable {
  touch-action: pan-y;
}

@media (min-width: 768px) {
  .tm-cajon,
  .tm-accion-pedir { display: none; }
  .tm-deslizable > .store-product-card { transform: none; }
}

.tm-vista--tarjetas .tm-cajon,
.tm-vista--tarjetas .tm-accion-pedir { display: none; }
.tm-vista--tarjetas .tm-deslizable > .store-product-card { transform: none; }


/* ---------- La hoja de filtros ----------
   Sube desde el pie en vez de colgar del icono. Un panel colgado de un
   botón que vive pegado a la orilla derecha se sale de la pantalla — ya
   pasó con el menú del carrito. Desde abajo siempre cabe. */

.tm-hoja {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.tm-hoja-fondo {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
}

.tm-hoja-cuerpo {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  background: var(--papel-alto);
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -10px 34px rgba(0, 0, 0, 0.2);
}

@media (min-width: 768px) {
  /* En pantalla grande no es una hoja: es una ventana centrada. Subir desde
     el pie en un monitor deja el contenido a un palmo de la vista. */
  .tm-hoja { align-items: center; }
  .tm-hoja-cuerpo { border-radius: 20px; max-height: 78vh; }
}

.tm-hoja-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--linea);
}

.tm-hoja-cabeza strong { font-size: 16px; }

.tm-hoja-contenido {
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.tm-hoja-pie {
  display: flex;
  gap: 10px;
  padding: 12px 16px;
  border-top: 1px solid var(--linea);
}

.tm-hoja-pie .tm-boton { flex: 1; }

.tm-filtro-grupo {
  border: none;
  margin: 0;
  padding: 0;
}

.tm-filtro-grupo legend {
  padding: 0 0 8px;
  font-size: 12px;
  font-weight: 800;
  color: var(--tinta-suave);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ---------- Empujar a la derecha: apuntar «por pedir» ----------
   El dueño quitó el botón de la cara del renglón para recuperar ancho de
   nombre, y la función se mudó a este gesto. La franja asoma mientras el
   dedo arrastra para que el gesto avise qué va a pasar antes de soltarlo. */

.tm-accion-pedir {
  position: absolute;
  /* En el extremo IZQUIERDO: es de donde sale el renglón al empujarlo. */
  inset: 0 auto 0 0;
  width: 88px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: var(--alerta);
  color: #ffffff;
}

/* Cuando el producto YA está apuntado, el gesto lo quita. Va en tinta y no
   en rojo: quitar algo de una lista no es un peligro, y el rojo de este
   sistema significa cancelar. */
.tm-accion-pedir--quitar {
  background: var(--tinta);
}

.tm-accion-pedir-icono {
  display: flex;
  opacity: 0.85;
}

.tm-accion-pedir-texto {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* Pasado el umbral, la franja se afirma: es la señal de «suelta y se hace».
   Sin ella el gesto es una apuesta — no sabes si ya llegó. */
.tm-deslizable--va-a-hacer .tm-accion-pedir {
  filter: brightness(1.12);
}

.tm-deslizable--va-a-hacer .tm-accion-pedir-icono {
  opacity: 1;
  transform: scale(1.12);
}

@media (prefers-reduced-motion: no-preference) {
  .tm-accion-pedir-icono {
    transition: transform 0.14s ease, opacity 0.14s ease;
  }
}

/* El botón de «por pedir» se va SOLO de la vista de filas del teléfono, que
   es donde el gesto lo reemplaza y donde falta el ancho.
   
   En la tabla de escritorio se queda: ahí no hay gesto —el deslizamiento
   solo responde al dedo— y quitarlo dejaría la función existiendo nada más
   en el celular, que es justo lo que prohíbe la sección 11 de CLAUDE.md. */
@media (max-width: 767px) {
  .tm-vista--filas .tm-deslizable .tm-boton-falta {
    display: none;
  }
}

/* El carrito de estado, ya dentro del cajón. Conserva su color —que es todo
   su mensaje— pero como relleno, igual que el lápiz y el bote: ahí adentro
   los tres se leen como botones, no como tres rebanadas distintas. */
.tm-cajon-boton--carrito { color: #ffffff; }
.tm-cajon-boton--carrito-ok { background: var(--ok); }
.tm-cajon-boton--carrito-peligro { background: var(--peligro); }
.tm-cajon-boton--carrito-apagado { background: var(--tinta-suave); }

/* El cajón lleva dos botones y su ancho ya estaba pensado para dos: el
   carrito entró en el hueco que dejó el lápiz, no se agregó uno más. */

/* Un icono dentro de un flex se encoge cuando el texto no cabe, y queda
   aplastado. `flex: none` lo evita en todos los botones y enlaces de una
   vez, en lugar de ir persiguiéndolo pantalla por pantalla. */
button > svg,
a > svg,
label > svg {
  flex: none;
}

/* Los dos botones del aviso de productos escondidos. En el teléfono se
   apilan: uno al lado del otro a 360px deja los dos con dos letras. */
.tm-aviso-tienda-botones {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

@media (max-width: 479px) {
  .tm-aviso-tienda-botones {
    width: 100%;
  }
  .tm-aviso-tienda-botones .tm-boton {
    flex: 1;
  }
}

/* ---------- La barra de arriba de una lista: se esconde al bajar ----------
 *
 * El buscador, los botones y los filtros viajan en una sola pieza. En el
 * teléfono se queda pegada arriba, se esconde al bajar por la lista y vuelve
 * al subir (core/esconder_al_bajar.js). Lo pidió el dueño —«así le hacen
 * varias apps»— y lo dejó como regla para todo lo que tenga buscador.
 *
 * Esconder es un `transform`: la lista no cambia de alto ni brinca. Lo pone
 * el JavaScript pixel por pixel, siguiendo al dedo (la C de la maqueta,
 * 2026-10-15), así que aquí no hay transición.
 *
 * El fondo de orilla a orilla lo pinta un seudoelemento que se sale 16px por
 * cada lado (12 del relleno del cascarón más 4 de la vista): sin eso, los
 * productos se asomarían por los lados al pasar por debajo. La barra misma
 * NO se sale: ensancharla con márgenes negativos le sacaba una barra de
 * desplazamiento horizontal a toda la pantalla.
 *
 * En pantalla ancha no se pega ni se esconde: ahí sobra alto.
 */
.tm-pegada {
  position: relative;
  z-index: 20;
}

@media (max-width: 767px) {
  .tm-pegada {
    position: sticky;
    /* Menos los 12px de relleno del cascarón (pos.css, `.tm-contenido`):
       Chrome pega un sticky donde EMPIEZA ese relleno, no en la orilla, y
       con `top: 0` quedaba un hueco de 12px bajo la barra de color por
       donde se asomaba la lista. El dueño lo marcó en una captura de
       Productos: «arregla ese hueco… que no se vea el fondo». */
    top: -12px;
    /* El relleno de arriba es el aire que le queda contra la barra de color
       cuando está pegada; el margen negativo lo compensa cuando no. */
    margin-top: -10px;
    padding: 10px 0 8px;
  }

  .tm-pegada::before {
    content: "";
    position: absolute;
    inset: 0 -16px;
    z-index: -1;
    background: var(--papel);
  }

  /* Más fuera que dentro: lo que asoma ya no se toca por accidente. */
  .tm-pegada--escondida {
    pointer-events: none;
  }

  .tm-pegada .tm-barra-lista {
    margin-bottom: 8px;
  }

  .tm-pegada .tm-barra-filtros {
    margin: 0;
    gap: 8px;
  }
}

/* ---------- Los filtros, como tira de pastillas ----------
 *
 * Una por filtro. Sustituyen al botón de filtrar que vivía dentro del
 * buscador —«no me gustaba el estilo del botón de filtrar, quiero algo
 * nuevo»— y al renglón de «filtros puestos»: la pastilla ya dice lo que se
 * escogió.
 */
.tm-pastillas {
  display: flex;
  gap: 6px;
  min-width: 0;
  padding: 2px 0;
  overflow-x: auto;
  scrollbar-width: none;
}

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

/* En el teléfono la tira se desvanece en su orilla derecha: así se nota que
   sigue hacia allá. */
@media (max-width: 767px) {
  .tm-pegada .tm-pastillas {
    padding-right: 22px;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
  }
}

.tm-pastilla {
  position: relative;
  flex: none;
  min-height: 38px;
  padding: 0 10px 0 13px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--boton-borde);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta-suave);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  box-shadow: var(--boton-sombra);
  cursor: pointer;
}

/* Área táctil de 48px sin engordar la pastilla. */
.tm-pastilla::before {
  content: "";
  position: absolute;
  inset: -5px 0;
}

/* Un nombre largo —«Abarrotes y Despensa Básica»— se corta con puntos en
   vez de llevarse la tira entera. */
.tm-pastilla > span {
  max-width: 13em;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tm-pastilla svg {
  flex: none;
  transition: transform 0.15s ease;
}

.tm-pastilla[aria-expanded="true"] {
  border-color: var(--accion);
  color: var(--accion);
}

.tm-pastilla[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

/* Con algo escogido: se pinta y dice qué. */
.tm-pastilla--puesta,
.tm-pastilla--puesta[aria-expanded="true"] {
  background: var(--accion);
  border-color: var(--accion);
  color: #ffffff;
}

.tm-pastilla--puesta[aria-expanded="true"] {
  box-shadow: 0 0 0 3px var(--accion-tenue);
}

/* «Categoría» mientras no hay departamento escogido: se puede tocar, y
   explica por qué todavía no ofrece nada. */
.tm-pastilla--apagada {
  opacity: 0.55;
}

.tm-pastilla[data-palanca-filtro],
.tm-pastilla--limpiar {
  padding-right: 13px;
}

.tm-pastilla--limpiar {
  border-style: dashed;
  box-shadow: none;
}

.tm-pastilla:active {
  transform: translateY(var(--boton-hundir));
  box-shadow: none;
}

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

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

/* ---------- El acordeón: las opciones de la pastilla abierta ----------
 *
 * Se abre justo debajo de la barra y por encima de la lista, sin empujarla:
 * si la empujara, cerrarlo mientras uno se desplaza haría brincar los
 * renglones.
 */
.tm-acordeon {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  max-width: 420px;
  border: 1px solid var(--boton-borde);
  border-radius: 12px;
  background: var(--papel-alto);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
  overflow: hidden;
}

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

@media (max-width: 767px) {
  .tm-acordeon {
    top: calc(100% - 4px);
    max-width: none;
  }
}

.tm-acordeon-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 6px 6px 14px;
  border-bottom: 1px solid var(--linea);
  color: var(--tinta-tenue);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.tm-acordeon-cerrar {
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 9px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.tm-acordeon-opciones {
  list-style: none;
  margin: 0;
  padding: 4px;
  max-height: min(52vh, 320px);
  overflow-y: auto;
}

.tm-acordeon-opcion {
  width: 100%;
  min-height: 48px;
  padding: 6px 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.tm-acordeon-nombre {
  flex: 1;
  min-width: 0;
}

/* Cuántos productos hay en cada opción. Va apagado: acompaña, no compite
   con el nombre. */
.tm-acordeon-cuantos {
  color: var(--tinta-tenue);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}

/* La palomita ocupa su sitio siempre, para que los renglones no salten al
   cambiar de opción. */
.tm-acordeon-opcion svg {
  flex: none;
  color: var(--accion);
  visibility: hidden;
}

.tm-acordeon-opcion[aria-checked="true"] {
  background: var(--accion-tenue);
  color: var(--accion);
}

.tm-acordeon-opcion[aria-checked="true"] svg {
  visibility: visible;
}

.tm-acordeon-opcion:focus-visible,
.tm-acordeon-cerrar:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: -2px;
}

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

/* ---------- Los dos precios de un producto, en la lista ----------
 *
 * Arriba y en gris, el de tarjeta; abajo y en verde, el de efectivo o
 * transferencia, igual que en la tienda (ámbar hasta el 2026-10-15). Sin
 * iconos: el dueño los quitó «para que no roben espacio a productos con
 * nombres largos».
 */
.tm-dos-precios {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.tm-precio {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 0 8px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tm-precio small {
  margin-left: 2px;
  font-size: 11px;
  font-weight: 600;
  opacity: 0.8;
}

.tm-precio--tarjeta {
  background: var(--papel-hondo);
  color: var(--tinta);
}

.tm-precio--efectivo {
  background: var(--ok-fondo);
  color: var(--ok);
}

/* El que falta: un hueco punteado que dice cuál es y se toca para ponerlo. */
.tm-precio--falta {
  position: relative;
  border: 1px dashed var(--peligro);
  background: transparent;
  color: var(--peligro);
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}

/* Área táctil más alta que la pastilla, sin engordarla. */
.tm-precio--falta::before {
  content: "";
  position: absolute;
  inset: -5px -6px;
}

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

/* En la tabla de pantalla ancha van uno sobre otro, pegados a la izquierda
   de su columna. */
.tm-tabla-precio .tm-dos-precios {
  flex-direction: column;
  align-items: flex-start;
}

/* La hojita para escribir el precio que falta: los dos campos, grandes. */
.tm-hoja-precios {
  gap: 12px;
}

.tm-hoja-precios .tm-campo input {
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ---------- El icono de editar ----------
 *
 * Una hoja con su lápiz, de trazo. Sustituye al carácter «✎», que cada
 * teléfono dibujaba a su manera.
 *
 * En el renglón del teléfono va solo, y ahí lleva la orilla fina de los
 * demás botones (ver «.tm-vista--filas», arriba). En la tabla y en las
 * tarjetas va junto a otros dos y se queda como ellos.
 */
.tm-boton-lapiz {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* La barra de filtros de la lista de productos.

   **Se llamaba `tm-fila-acciones` y eso la rompía todo.** Ese nombre ya
   era de los botones de una fila —departamentos, categorías, listas de
   precio—, y como esta regla va después en el archivo, ganaba. En el
   teléfono su `column-reverse` apilaba los tres botones de cada
   categoría uno encima de otro y en orden invertido, inflando cada fila
   a doscientos cincuenta píxeles.

   Lo cazó el dueño sin saber de CSS, describiendo el síntoma: «el botón
   visual donde toco para rellenar está más abajo… es como falsa la
   ubicación». Tenía razón: con las filas infladas, lo que se ve y lo que
   se toca dejan de coincidir.

   Los filtros puestos y los botones de acción comparten renglón.
   Antes iban uno debajo del otro y entre los dos se comían casi cien
   píxeles de alto sin decir nada — en escritorio, dos productos menos a la
   vista antes de tener que desplazarse. */
.tm-barra-filtros {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* En un solo renglón, SIN partirse: las pastillas no se parten, se
     desplazan de lado. Con `wrap` la tira medía lo que todas sus pastillas
     juntas y ensanchaba la pantalla entera. */
  flex-wrap: nowrap;
  margin: 10px 0 6px;
}

/* Las pastillas mandan en el espacio sobrante y se desplazan de lado si no
   caben. Los botones miden lo que miden. */
.tm-barra-filtros > .tm-pastillas {
  flex: 1 1 auto;
}

.tm-barra-filtros-botones {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

/* La barra de acciones ya no necesita su propio margen: lo pone el renglón
   que la contiene. Sin esto quedaba un hueco de más justo debajo. */
.tm-barra-filtros-botones > * {
  margin: 0;
}

/* En el teléfono se apilan, con los botones arriba: son lo que se toca. */
@media (max-width: 639px) {
  .tm-barra-filtros {
    flex-direction: column-reverse;
    align-items: stretch;
  }
  .tm-barra-filtros-botones {
    margin-left: 0;
  }
}

/* ---------- El final de la lista, que se carga solo ----------
   El dueño pidió quitar el botón de «cargar más»: «es molesto, hazlo
   automático». Sigue existiendo un botón de verdad debajo, para quien
   navega con teclado o lector de pantalla — esas personas no «se acercan al
   final» de ninguna manera. Con el dedo o el ratón nunca hace falta. */

.tm-mas-productos {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 22px 0 8px;
}

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

/* Un hilo que late mientras llega la siguiente tanda. Dice «hay más» sin
   pedir nada: es el final de la lista, no una acción. */
.tm-mas-productos-hilo {
  display: block;
  width: 54px;
  height: 3px;
  border-radius: 999px;
  background: var(--linea);
  overflow: hidden;
  position: relative;
}

.tm-mas-productos-hilo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--marca);
  animation: tm-hilo 1.2s ease-in-out infinite;
}

@keyframes tm-hilo {
  0%, 100% { transform: translateX(-100%); }
  50% { transform: translateX(100%); }
}

/* El botón de respaldo va callado: quien lo necesita lo encuentra con el
   tabulador, y quien no, ni lo mira. */
.tm-mas-productos-boton {
  border: 0;
  background: none;
  padding: 6px 12px;
  border-radius: 999px;
  color: var(--tinta-tenue);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}

.tm-mas-productos-boton:focus-visible {
  outline: 3px solid var(--accion);
  outline-offset: 2px;
  color: var(--tinta);
}

@media (prefers-reduced-motion: reduce) {
  .tm-mas-productos-hilo::after {
    animation: none;
    opacity: 0.5;
  }
}

/* ---------- Ficha de producto: acomodo compacto ----------

   27 controles en una columna medían 3,312 px en un teléfono: cuatro
   pantallas y media para corregir un precio. La palanca que de verdad baja
   ese número no es apretar los campos —el área táctil no se toca— sino
   dejar de desperdiciar la mitad derecha: los campos cortos van de dos en
   dos, y las existencias de tres en tres.

   Los pares no son al azar. Público con Tarjeta porque son el mismo producto
   pagado de dos maneras y se comparan al capturarlos; Mayoreo con sus piezas
   por bloque porque uno no significa nada sin el otro. Emparejar mal es peor
   que no emparejar.

   Nombre y descripción se quedan a todo lo ancho porque son los únicos que
   lo necesitan. */

/* El nombre de la sección deja de ser un panel con título y pasa a ser una
   línea fina: seis títulos con su relleno costaban más alto que varios
   campos juntos. */
.tm-rotulo {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--fuente-mono);
  font-size: 10px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
  padding-top: 6px;
}

.tm-rotulo::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--linea);
}

.tm-caja-campos {
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  border-radius: var(--radio-panel);
  box-shadow: var(--sombra-suave);
  padding: 11px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.tm-par,
.tm-trio {
  display: grid;
  gap: 9px;
  align-items: stretch;
}

.tm-par { grid-template-columns: 1fr 1fr; }
.tm-trio { grid-template-columns: 1fr 1fr 1fr; gap: 7px; }

/* Un `.tm-par` con un solo campo —el Costo— lo deja a media caja en vez de
   estirarlo a lo ancho. Así la columna del dinero queda alineada de arriba
   abajo, que es como se leen los precios. */

/* La etiqueta encoge y se pega a su campo; el campo NO. Los 48 px de área
   táctil son regla del proyecto y aquí es donde más importan: con dos
   campos por renglón, errarle a uno significa escribir el precio en el de
   al lado. */
.tm-caja-campos .tm-campo { gap: 3px; }

.tm-caja-campos .tm-campo label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.tm-caja-campos .tm-campo input,
.tm-caja-campos .tm-campo select,
.tm-caja-campos .tm-campo textarea {
  padding: 0 11px;
  border-radius: 10px;
  border-color: var(--tinta-tenue);
  font-size: 15px;
}

.tm-caja-campos .tm-campo textarea { padding: 10px 11px; }

/* Las cifras en columna se comparan; en tipografía normal bailan. */
.tm-caja-campos .tm-campo input[type="number"] { font-variant-numeric: tabular-nums; }

/* Con dos por renglón, el nombre del campo no siempre cabe en una línea.
   Que corte en dos antes que recortarse con puntos suspensivos: media
   palabra no dice qué campo es.

   Y cuando uno corta y el otro no, los dos campos se alinean por ABAJO, no
   por arriba. Reservarle dos líneas a toda etiqueta —que fue el primer
   intento— costaba 19 px en cada uno de los nueve renglones emparejados
   para arreglar un caso que se da en dos. */
.tm-par .tm-campo label,
.tm-trio .tm-campo label { line-height: 1.25; }

.tm-par .tm-campo,
.tm-trio .tm-campo { justify-content: flex-end; }

.tm-caja-campos .tm-checkbox {
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 14px;
}

/* Se leen una vez en la vida y luego estorban; que ocupen lo que valen. */
.tm-pista-corta {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--tinta-suave);
}



/* El rótulo y su caja son una sola cosa: pegados se lee a qué pertenece cada
   uno. Los 14 px que la columna pone entre todos sus hijos los separaba por
   igual, y con seis secciones eso era pura pérdida. El aire va ENTRE
   secciones, que es donde significa algo — el `padding-top` del rótulo. */
.tm-formulario-col { gap: 0; }
.tm-formulario-col > .tm-caja-campos { margin-top: 5px; }

/* El selector de archivo es un control que se toca, como cualquier otro. */
.tm-caja-campos input[type="file"] {
  min-height: 48px;
  display: flex;
  align-items: center;
}

/* Los campos emparejados se salían de la pantalla. Un `<input>` trae un ancho
   propio de unos 20 caracteres, y una columna `1fr` no baja de ahí salvo que
   se le diga que puede: sin esto, la caja de la derecha —Tarjeta, Promoción,
   Mínimo— quedaba cortada en el borde del teléfono y no se veía lo escrito. */
.tm-caja-campos .tm-campo,
.tm-par > *,
.tm-trio > * { min-width: 0; }

.tm-caja-campos .tm-campo input,
.tm-caja-campos .tm-campo select,
.tm-caja-campos .tm-campo textarea {
  width: 100%;
  min-width: 0;
}

/* ---------- La barra de la ficha ----------

   Guardar vivía hasta abajo, y con 27 controles eso son cuatro pantallas de
   recorrido para confirmar un cambio de una letra: «da flojera bajar tanto
   para guardar».

   Va pegada arriba, y no cuesta un solo pixel extra porque ocupa la fila que
   ya estaba ahí —la del botón de volver y «Más acciones»—. El nombre en medio
   hace el otro trabajo que faltaba: con mil trescientos productos, saber en
   cuál estás sin tener que subir hasta el campo Nombre. */
.tm-barra-ficha {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 6px 4px;
  margin: -4px -4px 2px;
  background: var(--papel);
  border-bottom: 1px solid var(--linea);
}

.tm-barra-ficha-volver {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accion);
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  text-decoration: none;
}

.tm-barra-ficha-volver:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* El nombre cede el ancho: si no cabe, se recorta él, nunca el botón. */
.tm-barra-ficha-nombre {
  flex: 1;
  min-width: 0;
  font-weight: 600;
  font-size: 14px;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-barra-ficha .tm-boton { flex: none; min-height: 44px; padding: 0 18px; }

/* El hueco de la foto mide lo mismo con foto y sin ella. Antes, subir una
   foto a un producto que no tenía empujaba 127 px de contenido hacia abajo y
   le movía la pantalla a quien estaba mirando otra cosa. */
.tm-hueco-foto {
  width: 108px;
  height: 108px;
  flex: none;
  border-radius: 14px;
  border: 1px dashed var(--tinta-tenue);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--papel-hondo);
}

/* Con foto, el marco punteado sobra: la foto ES el marco. */
.tm-hueco-foto:has(.tm-imagen-previa) { border-style: solid; border-color: var(--linea); }

.tm-hueco-foto .tm-imagen-previa { margin: 0; border: none; border-radius: 0; }

.tm-hueco-foto-vacio {
  font-size: 12px;
  color: var(--tinta-tenue);
}

/* ---------- Acceso remoto (Telegram) ---------- */

.tm-remoto-cabeza {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

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

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

/* La clave se va a copiar a mano en otra aplicación. Grande, monoespaciada y
   muy separada, por el mismo motivo por el que el sistema usa esa tipografía
   para los códigos de barras: para no confundir un carácter con otro. */
.tm-remoto-clave {
  margin-top: 14px;
  padding: 16px;
  border-radius: 14px;
  border: 1px dashed var(--accion);
  background: var(--papel-hondo);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
}

.tm-remoto-clave b {
  font-family: var(--fuente-mono);
  font-size: 32px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--accion);
  line-height: 1.2;
  /* La última letra hereda el espaciado y desalinea el bloque. */
  text-indent: 0.18em;
}

.tm-remoto-clave-rotulo { font-size: 13px; color: var(--tinta-suave); }
.tm-remoto-clave-pie { font-size: 12px; color: var(--tinta-tenue); }

.tm-remoto-lista { display: flex; flex-direction: column; }

.tm-remoto-renglon {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 0;
  border-bottom: 1px solid var(--linea);
}

.tm-remoto-lista .tm-remoto-renglon:last-child { border-bottom: none; }

.tm-remoto-quien { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.tm-remoto-quien b { font-weight: 600; font-size: 14px; }
.tm-remoto-quien span { font-size: 12px; color: var(--tinta-suave); }

.tm-remoto-desde {
  font-size: 12px;
  color: var(--tinta-tenue);
  font-variant-numeric: tabular-nums;
  flex: none;
}

/* A 360 px el nombre y el botón no caben en un renglón sin apretarse. */
@media (max-width: 420px) {
  .tm-remoto-renglon { flex-wrap: wrap; }
  .tm-remoto-renglon .tm-boton { width: 100%; }
}

/* Los avisos que quiere recibir cada quien, debajo de su propio enlace. */
.tm-remoto-avisos {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--linea);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.tm-remoto-avisos .tm-checkbox {
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
}

/* ---------- Quién lleva el pedido ---------- */

.tm-pedido-reparto {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 10px 0 0;
  flex-wrap: wrap;
}

.tm-pedido-reparto-rotulo {
  font-size: 12.5px;
  color: var(--tinta-suave);
  flex: none;
}

.tm-pedido-reparto select {
  flex: 1;
  min-width: 150px;
  min-height: 44px;
  padding: 0 10px;
  border-radius: 10px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
  font: inherit;
  font-size: 14px;
}

/* Ya entregado: se dice quién lo llevó y ya no se toca. */
.tm-pedido-reparto--cerrado {
  font-size: 13px;
  color: var(--tinta-suave);
}

/* ---------- Dónde trabaja el cliente ---------- */

.tm-empresa .tm-checkbox {
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
}

.tm-empresa-pista {
  margin: 0 0 6px 34px;
  font-size: 12.5px;
  color: var(--tinta-suave);
}

.tm-empresa-elegir {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-left: 34px;
}

.tm-empresa-elegir select {
  min-height: 48px;
  padding: 0 12px;
  border-radius: 12px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
  font: inherit;
}

/* El campo del nombre y su botón caben juntos mientras haya ancho; en el
   celular se apilan solos. */
.tm-empresa-nueva {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.tm-empresa-nueva input {
  flex: 1;
  min-width: 160px;
  min-height: 48px;
  padding: 0 12px;
  border-radius: 12px;
  border: 1px solid var(--tinta-tenue);
  background: var(--papel-alto);
  font: inherit;
}

/* En la lista, junto al nombre: es lo que hace encontrar a alguien de un
   vistazo cuando hay trescientos clientes. */
.tm-cliente-empresa {
  font-size: 12px;
  color: var(--tinta-suave);
  display: inline-flex;
  align-items: center;
  gap: 4px;
}


/* ---------- Piezas de las dos puertas ----------

   Viven aquí y no en acceso.css porque las usan los DOS accesos: el del
   personal, que tiene su propio cascarón, y el del cliente, que vive dentro
   de la tienda. Estaban solo en acceso.css, así que el aviso de error de la
   tienda salía sin ningún estilo. */

/* La etiqueta escondida.

   El diseño de referencia no traía etiquetas, solo textos de ejemplo dentro
   del campo. Se conserva el aspecto pero la etiqueta SIGUE AHÍ, escondida a
   la vista y visible para un lector de pantalla: un campo cuyo único nombre
   es su texto de ejemplo se queda sin nombre en cuanto uno escribe. */
.tm-acceso-etiqueta {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* El error no se disculpa y no es vago: dice qué pasó (CLAUDE.md §11). */
.tm-acceso-error {
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: #F4E4E4;
  color: var(--peligro);
  font-size: 13px;
  font-weight: 600;
}

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


/* ---------- Inicio de la Trastienda ---------- */

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

/* ---------- Cómo va el día ----------
 *
 * Se llama `tm-hoy` y no `tm-dia`: ese nombre ya era del horario del negocio
 * en Ajustes —lunes, martes, sus horas— y como este bloque va después en el
 * archivo, le estaba pisando los estilos.
 */
.tm-hoy {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px 20px;
  border-radius: 16px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  box-shadow: var(--sombra-suave);
}

.tm-hoy-cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
}

.tm-hoy-total {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tm-hoy-titulo {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-hoy-total strong {
  font-family: var(--fuente-mono, monospace);
  font-size: 34px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.tm-hoy-cuantas {
  font-size: 12.5px;
  color: var(--tinta-suave);
}

/* ---------- Contra ayer a esta hora ---------- */

.tm-hoy-ayer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-hoy-ayer-flecha {
  font-size: 18px;
  font-weight: 800;
  line-height: 1;
}

.tm-hoy-ayer--arriba .tm-hoy-ayer-flecha { color: var(--ok); }
.tm-hoy-ayer--abajo .tm-hoy-ayer-flecha { color: var(--peligro); }
.tm-hoy-ayer--igual .tm-hoy-ayer-flecha { color: var(--tinta-tenue); }

.tm-hoy-ayer-texto {
  display: flex;
  flex-direction: column;
  line-height: 1.3;
  font-size: 12px;
  color: var(--tinta-suave);
}

.tm-hoy-ayer-texto b {
  font-size: 13.5px;
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
}

/* ---------- Los tres métodos ----------
 *
 * Salen los tres SIEMPRE, aunque estén en cero: un renglón que aparece y
 * desaparece obliga a releer dónde quedó cada cosa, y un cero es
 * información —hoy nadie pagó con tarjeta—, no un hueco.
 */
.tm-hoy-metodos {
  display: grid;
  gap: 8px;
}

/* En el teléfono, los tres apilados. Con `auto-fit` caben dos arriba y el
   tercero se quedaba solo abajo, y esa fila coja se lee peor que una lista
   pareja. Desde 480px sí caben los tres en línea. */
@media (min-width: 480px) {
  .tm-hoy-metodos {
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  }
}

.tm-hoy-metodo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

/* El que está en cero se apaga, no se esconde: sigue ahí para que la fila no
   cambie de forma entre un día y otro. */
.tm-hoy-metodo--cero {
  opacity: 0.55;
}

.tm-hoy-metodo-icono {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: var(--papel-alto);
}

.tm-hoy-metodo-icono svg {
  width: 20px;
  height: 20px;
}

.tm-hoy-metodo-icono--efectivo { color: var(--ok); }
.tm-hoy-metodo-icono--tarjeta { color: var(--accion); }
.tm-hoy-metodo-icono--transferencia { color: var(--alerta); }

.tm-hoy-metodo-texto {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.25;
}

.tm-hoy-metodo-nombre {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-hoy-metodo-cifra {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Lo que de verdad entra al banco. En otro color y más chico que lo cobrado:
   la cifra que manda sigue siendo la que se cobró. */
.tm-hoy-deposito {
  font-style: normal;
  font-size: 11px;
  font-weight: 600;
  color: var(--alerta);
}

/* ---------- La semana en chiquito ----------
 *
 * No es una gráfica —esa vive en Reportes— sino la forma de la semana de un
 * vistazo, y la puerta para ir a verla con calma.
 */
.tm-hoy-semana {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--linea);
  text-decoration: none;
  color: inherit;
}

.tm-hoy-semana-tira {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 42px;
}

.tm-hoy-semana-barra {
  flex: 1 1 0;
  min-height: 3px;
  border-radius: 4px 4px 0 0;
  background: var(--papel-hondo);
}

/* Hoy en color: es la barra que se está mirando. */
.tm-hoy-semana-barra--hoy {
  background: var(--accion);
}

.tm-hoy-semana-pie {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--tinta-suave);
}

/* ---------- Cuando no hay nada pendiente ---------- */

.tm-inicio-limpio {
  flex-direction: row;
  align-items: center;
  gap: 14px;
}

.tm-inicio-limpio-marca {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #E4F5E8;
  color: var(--ok);
}

.tm-inicio-limpio-marca svg {
  width: 24px;
  height: 24px;
}

.tm-inicio-limpio-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-inicio-limpio-texto b {
  font-size: 15px;
  color: var(--tinta);
}

/* ---------- Los avisos ---------- */

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

.tm-aviso {
  display: flex;
  align-items: stretch;
  gap: 8px;
  border-radius: 14px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  overflow: hidden;
}

/* Los urgentes llevan una franja de color en el canto. Es lo único donde
   tardar le cuesta a una persona de carne y hueso. */
.tm-aviso--urgente { border-left: 4px solid var(--peligro); }

.tm-aviso-cuerpo {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  padding: 10px 14px;
  text-decoration: none;
  color: inherit;
}

.tm-aviso-cuerpo:hover { background: var(--papel-hondo); }

.tm-aviso-cuantos {
  flex: none;
  min-width: 42px;
  text-align: center;
  font-size: 22px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--tinta-suave);
}

.tm-aviso--urgente .tm-aviso-cuantos { color: var(--peligro); }

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

.tm-aviso-texto strong { font-size: 14.5px; }

.tm-aviso-texto > span {
  font-size: 12.5px;
  color: var(--tinta-suave);
}

/* Posponer: chiquito y al margen. Es una salida, no una acción principal. */
.tm-aviso-posponer {
  flex: none;
  display: flex;
  align-items: center;
  gap: 4px;
  padding-right: 10px;
}

.tm-aviso-posponer button {
  min-height: 34px;
  padding: 0 10px;
  border: 1px solid var(--boton-borde);
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--tinta-tenue);
  cursor: pointer;
  white-space: nowrap;
}

.tm-aviso-posponer button:hover {
  background: var(--papel-hondo);
  color: var(--tinta);
}

/* «Ya no» va al final y más apagado que los otros dos. No es peligro —no
 * borra nada y se deshace abajo— pero sí es el único que no vuelve solo,
 * así que no puede verse igual que «2 h». */
.tm-aviso-quitar {
  border-style: dashed !important;
}

.tm-aviso-quitar:hover {
  border-color: var(--peligro) !important;
  color: var(--peligro) !important;
}

/* La línea de vuelta: letra chica, abajo de todo, fuera del camino. Es la
 * salida de emergencia de «Ya no», no una sección de la pantalla. */
.tm-avisos-quitados {
  margin: 14px 2px 0;
  font-size: 12.5px;
  line-height: 2;
  color: var(--tinta-tenue);
}

.tm-avisos-quitado {
  min-height: 34px;
  padding: 0 10px;
  margin-left: 4px;
  border: 1px dashed var(--linea);
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--tinta-suave);
  cursor: pointer;
}

.tm-avisos-quitado:hover {
  background: var(--papel-hondo);
  color: var(--tinta);
}

.tm-inicio-limpio {
  padding: 28px 20px;
  border-radius: 16px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  text-align: center;
  color: var(--tinta-suave);
}

/* En pantalla angosta, posponer se va abajo antes que aplastar el aviso. */
@media (max-width: 560px) {
  .tm-aviso {
    flex-direction: column;
    align-items: stretch;
  }

  .tm-aviso-posponer {
    padding: 0 14px 10px 70px;
  }
}

/* ---------- Zonas de reparto ----------
 *
 * Se dibuja primero para 360px: cada zona es una tarjeta apilada, y a partir
 * de 768px las mismas piezas se acomodan en una sola línea. No hay tabla con
 * barra horizontal en ningún ancho.
 */
.tm-zonas {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tm-zonas-cabeza h2 {
  margin: 0 0 4px;
  font-size: 16px;
  font-weight: 700;
}

.tm-zonas-cabeza p {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--tinta-suave);
  max-width: 58ch;
}

.tm-zonas-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* En el teléfono cada zona son tres renglones: quién es, cuántas lleva, y
 * la hora junto a su Guardar. Con seis o siete rumbos la lista sigue
 * cabiendo de un vistazo en vez de volverse un scroll largo. */
.tm-zona {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "nombre  quitar"
    "cuantas cuantas"
    "hora    guardar";
  align-items: center;
  gap: 6px 10px;
  padding: 10px 12px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
}

.tm-zona-nombre {
  grid-area: nombre;
  font-size: 15px;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.tm-zona-cuantas {
  grid-area: cuantas;
  font-size: 12px;
  color: var(--tinta-tenue);
}

.tm-zona-hora {
  grid-area: hora;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-zona-hora > span {
  white-space: nowrap;
}

.tm-zona-hora input {
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-variant-numeric: tabular-nums;
}

.tm-zona-guardar {
  grid-area: guardar;
  justify-content: center;
}

/* La × de quitar se queda arriba a la derecha, lejos de «Guardar»: son las
 * dos acciones de la tarjeta y no pueden estar pegadas. */
.tm-zona .tm-fila-boton {
  grid-area: quitar;
}

.tm-zona-nueva {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--linea);
}

.tm-zona-nueva input {
  flex: 1 1 160px;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
}

.tm-zona-nueva input[type="time"] {
  flex: 0 1 130px;
  font-variant-numeric: tabular-nums;
}

.tm-zona-nueva button {
  flex: 1 1 120px;
  justify-content: center;
}

/* ---------- La zona de cada domicilio, dentro de la ficha ---------- */
.tm-campo-titulo {
  font-size: 13px;
  font-weight: 700;
  color: var(--tinta);
}

.tm-campo-ayuda {
  margin: 2px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

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

.tm-dir-zona {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-hondo);
}

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

.tm-dir-zona-texto b {
  font-size: 14px;
}

.tm-dir-zona-texto small {
  font-size: 12px;
  color: var(--tinta-suave);
  overflow-wrap: anywhere;
}

.tm-dir-zona-select {
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
}

@media (min-width: 768px) {
  /* Cabe todo en un renglón: nombre, cuántas, la hora y los dos botones. */
  .tm-zona {
    grid-template-columns: minmax(0, 1fr) auto auto auto auto;
    grid-template-areas: "nombre cuantas hora guardar quitar";
    gap: 12px;
    padding: 12px 14px;
  }

  /* Solo aquí cabe el botón a su ancho natural; en el teléfono se estira
   * para que sea fácil de picar con el pulgar. */
  .tm-zona-nueva button {
    flex: 0 1 auto;
  }

  .tm-dir-zona {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
  }

  .tm-dir-zona-select {
    flex: 0 1 260px;
  }
}

/* ---------- Comisión de la terminal ----------
 *
 * El campo es angosto a propósito: un porcentaje son tres o cuatro
 * caracteres, y una caja del ancho de la pantalla invita a escribir ahí
 * cualquier otra cosa. El «%» va pegado al número, dentro del mismo marco,
 * para que se lea como una sola cifra.
 */
.tm-comision {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 14px 0;
}

.tm-comision-campo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}

.tm-comision-entrada {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 0 12px 0 4px;
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--papel-alto);
  color: var(--tinta-suave);
  font-weight: 700;
}

.tm-comision-entrada:focus-within {
  border-color: var(--accion);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accion) 18%, transparent);
}

.tm-comision-entrada input {
  width: 5.5ch;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--tinta);
  font: inherit;
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.tm-comision-entrada input:focus {
  outline: none;
}

/* Las flechitas del number roban ancho y en el teléfono no se pican. */
.tm-comision-entrada input::-webkit-outer-spin-button,
.tm-comision-entrada input::-webkit-inner-spin-button {
  appearance: none;
  margin: 0;
}

.tm-comision-entrada input[type="number"] {
  appearance: textfield;
  -moz-appearance: textfield;
}

/* La cuenta hecha con dinero de verdad: es lo que convierte «4.6%» en una
 * respuesta. Se recalcula mientras se escribe, así que un dedazo se ve
 * antes de guardarlo. */
.tm-comision-ejemplo {
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--papel-hondo);
  font-size: 14px;
  line-height: 1.6;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

.tm-comision-ejemplo b {
  color: var(--tinta);
}

.tm-comision-ejemplo em {
  font-style: normal;
  color: var(--tinta-tenue);
}

@media (min-width: 768px) {
  .tm-comision {
    flex-direction: row;
    align-items: center;
    gap: 16px;
  }

  .tm-comision-ejemplo {
    flex: 1 1 auto;
  }
}

/* ---------- La pantalla que no existe ----------
 *
 * Se pinta dentro del cascarón, con el menú intacto: quien tecleó mal una
 * dirección sigue adentro y a un clic de donde iba. No es una pantalla de
 * error de las que asustan; es un aviso corto y una salida.
 */
.tm-sin-pantalla {
  align-items: flex-start;
  gap: 10px;
  max-width: 46rem;
}

.tm-sin-pantalla h1 {
  margin: 0;
  font-size: 19px;
  font-weight: 700;
}

.tm-sin-pantalla p {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--tinta-suave);
}

/* La dirección va en su propio renglón y no embutida en la frase: es un dato
 * que se lee letra por letra y se copia entero, y metida entre palabras se
 * mezcla con ellas. */
.tm-sin-pantalla-ruta {
  align-self: stretch;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--papel-hondo);
  color: var(--tinta);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 13px;
  overflow-wrap: anywhere;
}

.tm-sin-pantalla .tm-boton {
  margin-top: 4px;
}


/* ---------- El menú como cajón, en el teléfono ----------
 *
 * La otra manera de tener el menú en pantalla chica: fuera de la vista, y
 * sale por la izquierda cuando se pide. Con doce secciones, la barra de
 * abajo obliga a arrastrar para llegar a las últimas y se come una franja de
 * alto; el cajón las enseña todas de una y no ocupa nada mientras está
 * cerrado.
 *
 * Todo esto vive DENTRO de `max-width: 767px`. Arriba de eso el menú es la
 * barra lateral fija de siempre y este interruptor no pinta nada: en la
 * computadora sobra el espacio y esconder el menú solo daría trabajo.
 */
/* El botón viene siempre en el HTML (para que no empuje a la marca al
   aparecer) y solo se enseña en modo cajón. */
.tm-menu-boton {
  display: none;
}

@media (max-width: 767px) {
  body[data-menu="cajon"] .tm-nav {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 60;
    /* Tan ancho como el renglón del negocio —nombre, tres espacios y el
       letrero— y ahí se acaba. Medía 78% de la pantalla siempre, y el dueño
       lo vio con el letrero ya puesto: «sobra mucho espacio en blanco…
       cuando termine el botón, desde ahí termina el menú blanco». El piso es
       para que un negocio de nombre corto no deje el menú flaco; el tope es
       el ancho que tenía. */
    width: max-content;
    min-width: 228px;
    max-width: min(78vw, 300px);
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 8px 10px calc(10px + env(safe-area-inset-bottom));
    border-top: none;
    border-right: 1px solid var(--linea);
    background: var(--papel-alto);
    overflow-y: auto;
    /* Cerrado no se ve, pero sigue existiendo: sacarlo del documento
       perdería el foco de quien lo estaba usando con teclado. */
    transform: translateX(-100%);
    transition: transform 180ms ease;
    box-shadow: 0 0 40px rgba(0, 0, 0, 0.18);
  }

  body[data-menu="cajon"][data-menu-abierto] .tm-nav {
    transform: translateX(0);
  }

  /* La franja de abajo desaparece de la rejilla: ese alto es justamente lo
     que se gana. */
  body[data-menu="cajon"] .tm-shell {
    grid-template-rows: auto 1fr;
    grid-template-areas:
      "topbar"
      "contenido";
  }

  /* En columna, cada renglón se lee como una lista: icono y texto en línea,
     como en la barra lateral de escritorio. */
  body[data-menu="cajon"] .tm-nav-enlace {
    flex: 0 0 auto;
    width: auto;
    min-height: 48px;
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    padding: 0 12px;
    border-radius: 12px;
    font-size: 14px;
  }

  /* Solo el renglón del negocio le dice al cajón cuánto medir. Los demás se
     acomodan a ese ancho en vez de estirarlo: sin esto, un favorito de
     nombre largo o un empleado de dos apellidos volvían a ensanchar el menú
     y dejaban blanco a la derecha del letrero. */
  body[data-menu="cajon"] .tm-nav > .tm-nav-sesion,
  body[data-menu="cajon"] .tm-nav > .tm-favoritos,
  body[data-menu="cajon"] .tm-nav > .tm-nav-enlace,
  body[data-menu="cajon"] .tm-nav > .tm-nav-salida {
    contain: inline-size;
  }

  /* «Pronto» va debajo del nombre, como el renglón chico de los favoritos.
     A la derecha, «Recargas y servicios» con su «Pronto» pedía más ancho
     que el cajón entero. */
  body[data-menu="cajon"] .tm-nav-enlace--pendiente {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-content: center;
    row-gap: 0;
  }

  body[data-menu="cajon"] .tm-nav-enlace--pendiente .tm-nav-icono {
    grid-row: 1 / span 2;
  }

  body[data-menu="cajon"] .tm-nav-enlace--pendiente .tm-nav-pronto {
    grid-column: 2;
  }

  /* El nombre, tres espacios, y el letrero, como lo pidió el dueño: nueve
     pixeles de aquí más los tres de margen que ya trae cada renglón del
     menú. Si no caben los dos ni con el cajón en su tope —un nombre largo—
     el letrero baja al renglón siguiente en vez de cortar el nombre a tres
     letras. */
  body[data-menu="cajon"] .tm-nav-negocio {
    flex-wrap: wrap;
    gap: 0 9px;
    margin-bottom: 8px;
    padding: 0 2px 8px 0;
    border-bottom: 1px solid var(--linea);
  }

  /* Sin relleno a la derecha: la separación con el letrero la pone el
     renglón, y con las dos se abría de más. */
  body[data-menu="cajon"] .tm-nav-negocio .tm-nav-enlace--negocio {
    flex: 1 1 auto;
    min-width: 0;
    padding-right: 0;
  }

  body[data-menu="cajon"] .tm-nav-negocio .tm-nav-estado {
    margin-left: auto;
  }

  .tm-menu-velo {
    position: fixed;
    inset: 0;
    z-index: 55;
    background: rgba(0, 0, 0, 0.35);
  }

  .tm-menu-cerrar {
    align-self: flex-end;
    width: 44px;
    height: 44px;
    margin-bottom: 4px;
    border: 0;
    border-radius: 12px;
    background: var(--papel-hondo);
    color: var(--tinta-suave);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
  }

  body[data-menu="cajon"] .tm-menu-boton {
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    margin-right: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 10px;
    background: transparent;
    /* Blanco explícito y no `inherit`: la barra pinta su fondo con el color
       del tema pero no fija el color del texto —cada pieza pone el suyo—, así
       que heredar traía la tinta oscura del documento y las rayas se veían
       casi negras sobre el morado. */
    color: #ffffff;
    cursor: pointer;
  }

  .tm-menu-boton svg {
    width: 26px;
    height: 26px;
  }

  .tm-menu-boton:focus-visible,
  .tm-menu-cerrar:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
  }
}

/* De 768px para arriba el cajón no existe: ni el botón, ni la ✕, ni el velo,
   pase lo que pase en el interruptor. */
@media (min-width: 768px) {
  .tm-menu-boton,
  .tm-menu-cerrar,
  .tm-menu-velo {
    display: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  body[data-menu="cajon"] .tm-nav {
    transition: none;
  }
}

/* ---------- Elegir dónde vive el menú ----------
 *
 * Dos tarjetas con un dibujito cada una. El dibujo hace el trabajo: «cajón a
 * la izquierda» se entiende viéndolo, y leyéndolo hay que imaginárselo.
 */
/* Una debajo de la otra en el celular: lado a lado, cada texto quedaba
   en una columna de setenta pixeles y se partía palabra por palabra. */
.tm-menu-formas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
}

.tm-menu-forma {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  grid-template-areas:
    "dibujo nombre"
    "dibujo detalle";
  align-items: center;
  gap: 2px 12px;
  padding: 12px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-menu-forma--activa {
  border-color: var(--accion);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accion) 22%, transparent);
}

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

.tm-menu-forma-dibujo {
  grid-area: dibujo;
  width: 48px;
  height: 48px;
  color: var(--accion);
}

.tm-menu-forma-nombre {
  grid-area: nombre;
  font-size: 14px;
  font-weight: 700;
}

.tm-menu-forma-detalle {
  grid-area: detalle;
  font-size: 12px;
  line-height: 1.5;
  color: var(--tinta-suave);
}

/* ---------- Quién está en esta sesión ----------
 *
 * En la barra lateral de escritorio y en el cajón del teléfono. En la barra
 * de abajo NO: ahí los iconos van en fila y una tarjeta con nombre y rol no
 * cabe sin robarle el sitio a una sección.
 *
 * Con turno abierto, lo que se cobre queda a nombre de quien esté aquí. Que
 * se pueda mirar de reojo de quién es la sesión no es un adorno.
 */
.tm-nav-sesion {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  margin-bottom: 6px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-nav-sesion-avatar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.tm-nav-sesion-datos {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.25;
}

.tm-nav-sesion-nombre {
  font-size: 14px;
  font-weight: 700;
  color: var(--tinta);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-nav-sesion-rol {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

/* En el teléfono solo con el cajón: la barra de abajo no tiene dónde. */
@media (max-width: 767px) {
  body[data-menu="cajon"] .tm-nav-sesion {
    display: flex;
  }
}

@media (min-width: 768px) {
  .tm-nav-sesion {
    display: flex;
  }
}

/* ---------- Reportes ---------- */

.tm-nav-icono--reportes {
  color: var(--alerta);
}

.tm-reportes-periodos {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.tm-reportes-periodo {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--boton-borde);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta-suave);
  font: inherit;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}

.tm-reportes-periodo--activo {
  background: var(--accion);
  border-color: var(--accion);
  color: #ffffff;
}

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

/* ---------- La cifra del periodo ---------- */

.tm-reportes-total {
  gap: 16px;
}

.tm-reportes-cifra {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tm-reportes-etiqueta {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

.tm-reportes-cifra strong {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 34px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.tm-reportes-detalle {
  font-size: 13px;
  color: var(--tinta-suave);
}

/* Mostrador y línea, uno al lado del otro: son dos negocios con el mismo
   cajón y la gracia está en poder compararlos de un vistazo. */
.tm-reportes-origenes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

.tm-reportes-origen {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--papel-hondo);
}

.tm-reportes-origen-nombre {
  font-size: 12px;
  font-weight: 700;
  color: var(--tinta-suave);
}

.tm-reportes-origen-cifra {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.tm-reportes-origen-parte {
  font-size: 11px;
  color: var(--tinta-tenue);
}

/* ---------- La gráfica de barras ----------
 *
 * Dibujada a mano con alturas en porcentaje. Sin librería: aquí no hay paso
 * de compilación ni CDNs, y cientos de kilobytes para pintar siete barras no
 * se los puede permitir una Raspberry que además sirve el catálogo.
 */
.tm-reportes-cabeza {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.tm-reportes-cabeza h2 {
  margin: 0;
  font-size: 16px;
}

.tm-reportes-leyenda {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--tinta-suave);
}

.tm-reportes-punto {
  width: 10px;
  height: 10px;
  border-radius: 3px;
}

.tm-reportes-punto--ganancia {
  background: var(--dato-ganancia);
}

.tm-reportes-punto--costo {
  background: var(--dato-costo);
}

.tm-barras {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  align-items: end;
  gap: 6px;
  height: 190px;
  /* Con treinta días las barras se hacen finísimas; entonces la lista se
     desliza en su propio marco y la página no se ensancha. */
  overflow-x: auto;
  scrollbar-width: thin;
}

.tm-barra {
  display: grid;
  grid-template-rows: auto 1fr auto;
  align-items: end;
  justify-items: center;
  gap: 4px;
  /* Lo que mide la cifra corta —«$7.3k»— más aire. Por debajo de esto las
     etiquetas de dos barras vecinas se enciman. */
  min-width: 46px;
  height: 100%;
}

.tm-barra-cifra {
  font-size: 10px;
  font-weight: 700;
  color: var(--tinta-tenue);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tm-barra-caja {
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 100%;
}

/* El día en cero deja una raya, no un hueco: que se vea que ese día existió
   y no vendió es la mitad de la información. */
.tm-barra-alto {
  position: relative;
  width: 100%;
  min-height: 2px;
  border-radius: 6px 6px 0 0;
  overflow: hidden;
  background: var(--papel-hondo);
  display: flex;
  flex-direction: column;
}

.tm-barra-parte--ganancia {
  background: var(--dato-ganancia);
}

.tm-barra-parte--costo {
  flex: 1;
  background: var(--dato-costo);
}

.tm-barra-dia {
  font-size: 11px;
  color: var(--tinta-suave);
  white-space: nowrap;
}

/* ---------- Cómo te pagaron ---------- */

.tm-reportes-metodo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--linea);
  font-size: 15px;
}

.tm-reportes-metodo:last-of-type {
  border-bottom: 0;
}

.tm-reportes-metodo-cifra {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.tm-reportes-deposito {
  display: block;
  font-style: normal;
  font-size: 12px;
  font-weight: 600;
  color: var(--alerta);
}

/* ---------- Quién vendió ---------- */

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

.tm-vendedor {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
}

.tm-vendedor-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-size: 13px;
  font-weight: 800;
}

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

.tm-vendedor-nombre {
  font-size: 15px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-vendedor-detalle {
  font-size: 12px;
  color: var(--tinta-suave);
}

/* La barrita compara sin hacer cuentas: quién vendió el doble se ve, no se
   calcula. */
.tm-vendedor-riel {
  height: 6px;
  border-radius: 999px;
  background: var(--papel-hondo);
  overflow: hidden;
}

.tm-vendedor-parte {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accion);
}

.tm-vendedor-total {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- Lo que más se vende ---------- */

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

.tm-mas-vendido-fila {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) auto;
  grid-template-areas:
    "puesto nombre importe"
    "puesto piezas importe";
  align-items: center;
  gap: 0 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--linea);
}

.tm-mas-vendido-fila:last-child {
  border-bottom: 0;
}

.tm-mas-vendido-puesto {
  grid-area: puesto;
  font-size: 12px;
  font-weight: 800;
  color: var(--tinta-tenue);
  font-variant-numeric: tabular-nums;
}

.tm-mas-vendido-nombre {
  grid-area: nombre;
  font-size: 14px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-mas-vendido-piezas {
  grid-area: piezas;
  font-size: 12px;
  color: var(--tinta-tenue);
}

.tm-mas-vendido-importe {
  grid-area: importe;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tm-reportes-vacio {
  align-items: flex-start;
  gap: 6px;
}

@media (min-width: 768px) {
  .tm-reportes-total {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    align-items: center;
    gap: 24px;
  }

  .tm-reportes-cifra strong {
    font-size: 42px;
  }

  .tm-barras {
    height: 230px;
  }
}

/* ---------- El letrero de abierto, en el menú ----------
 *
 * Junto al nombre del negocio. Va sobre papel y no sobre el color del tema,
 * así que se pinta al revés que cuando vivía en la barra: fondo diluido,
 * letra y orilla del color del estado. Tres tonos y no dos: el ámbar es
 * «abierto pero sin repartir» y «cerrado pero sigo tomando pedidos», que ni
 * son abierto ni son cerrado.
 */
.tm-nav-estado {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--tinta-suave);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

/* Mientras no se sabe cómo está la tienda ocupa su lugar sin verse: que el
   menú no brinque cuando llega la respuesta. */
.tm-nav-estado[data-sin-pintar] {
  visibility: hidden;
}

.tm-nav-estado-punto {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

/* ---------- El letrero que corre ----------
 *
 * «Solo recoger» no cabía junto al nombre del negocio sin ensanchar el cajón.
 * El dueño: «¿qué tal si usabas el estilo letrero LED? Así corre». Escogió
 * entre tres maquetas la más callada: el mismo botón de siempre, que en el
 * cajón del teléfono mide siempre lo mismo, y solo corre el texto que no
 * cabe. «Abierto» y «Cerrado» caben y se quedan quietos, que es como se leen
 * de un vistazo.
 *
 * El texto se asoma por una ventana y lleva una copia detrás: al correr la
 * pista la mitad de su largo, la copia queda justo donde empezó el original
 * y la vuelta no tiene costura. Quién corre lo decide core/banner.js
 * midiendo; aquí solo va cómo.
 */
.tm-nav-estado-ventana {
  display: block;
  min-width: 0;
  overflow: hidden;
}

.tm-nav-estado-pista {
  display: inline-flex;
  vertical-align: top;
  white-space: nowrap;
}

.tm-nav-estado-copia {
  display: none;
}

.tm-nav-estado--corre .tm-nav-estado-pista {
  animation: tm-letrero-corre var(--letrero-tarda, 4s) linear infinite;
}

/* El hueco entre el texto y su copia. Es margen y no relleno a propósito:
   banner.js mide el texto con offsetWidth, que no cuenta el margen, y tiene
   que valer lo mismo que su PX_DE_HUECO. */
.tm-nav-estado--corre .tm-nav-estado-pista > span {
  margin-right: 26px;
}

.tm-nav-estado--corre .tm-nav-estado-copia {
  display: inline;
}

@keyframes tm-letrero-corre {
  to {
    transform: translateX(-50%);
  }
}

/* La ventana de ancho fijo es solo del cajón del teléfono, que es donde el
   letrero le pone el ancho al menú. En la columna de la computadora y en la
   barra de abajo mide lo que su texto, así que ahí nunca corre.

   Y solo si el aparato deja moverse a las cosas: con las animaciones
   apagadas la ventana vuelve a medir lo que el texto, el letrero se lee
   entero y quieto, y el cajón se ensancha lo justo, como antes. */
@media (max-width: 767px) and (prefers-reduced-motion: no-preference) {
  body[data-menu="cajon"] .tm-nav-estado-ventana {
    width: 4em;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tm-nav-estado--corre .tm-nav-estado-pista {
    animation: none;
  }
}

.tm-nav-estado--abierto {
  background: var(--ok-fondo);
  border-color: var(--ok);
  color: var(--ok);
}

.tm-nav-estado--medio {
  background: var(--alerta-fondo);
  border-color: var(--alerta);
  color: var(--alerta);
}

.tm-nav-estado--cerrado {
  background: var(--peligro-fondo);
  border-color: var(--peligro);
  color: var(--peligro);
}

/* Para quien puede cambiarlo, el letrero es el interruptor de la cortina
 * (core/cortina_rapida.js): la decisión que más veces se toma al día, y que
 * vivía en Ajustes, a tres pantallas de distancia. Lleva su flechita, su
 * sombra corta y se hunde al apretarlo, como los demás botones.
 */
.tm-nav-estado--tocable {
  min-height: 36px;
  padding-right: 10px;
  cursor: pointer;
  user-select: none;
  box-shadow: var(--boton-sombra);
}

/* Área táctil de 48px sin engordar la pastilla. */
.tm-nav-estado--tocable::before {
  content: "";
  position: absolute;
  inset: -6px -4px;
}

.tm-nav-estado--tocable::after {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  margin: -3px 2px 0 1px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}

.tm-nav-estado--tocable:active {
  transform: translateY(var(--boton-hundir));
  box-shadow: none;
}

.tm-nav-estado--tocable:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

/* La capa no oscurece la pantalla: no es un diálogo que interrumpa, es un
   menú que se asoma. Solo está para cachar el toque de fuera. */
.tm-cortina-capa {
  position: fixed;
  inset: 0;
  z-index: 70;
}

.tm-cortina-menu {
  position: fixed;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  border-radius: 16px;
  background: var(--papel-alto);
  border: 1px solid var(--linea);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
  max-height: calc(100vh - 90px);
  overflow-y: auto;
}

.tm-cortina-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 2px 8px 10px;
  border-bottom: 1px solid var(--linea);
  margin-bottom: 6px;
}

.tm-cortina-titulo {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tinta-tenue);
}

/* La ✕ no es un adorno: en el teléfono el dueño se quedó atrapado buscando
   dónde picar para salir. */
.tm-cortina-cerrar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 10px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

/* ---------- Cada estado, como una tarjeta con su color ----------
 *
 * Antes eran renglones con un puntito y se leían como una lista de radio: el
 * dueño dijo que no le gustaba. Ahora el color entra de verdad —el icono en
 * su cuadro teñido— y el que está puesto se marca con palomita y su franja,
 * no con un fondo gris que no dice de qué color es lo que uno tiene.
 */
.tm-cortina-modo {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) 22px;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: 14px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tm-cortina-icono {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
}

.tm-cortina-icono svg {
  width: 22px;
  height: 22px;
}

.tm-cortina-modo--abierto .tm-cortina-icono {
  background: #E4F5E8;
  color: var(--ok);
}

.tm-cortina-modo--medio .tm-cortina-icono {
  background: #FBF0CC;
  color: var(--alerta);
}

.tm-cortina-modo--cerrado .tm-cortina-icono {
  background: #F4E4E4;
  color: var(--peligro);
}

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

.tm-cortina-nombre {
  font-size: 14.5px;
  font-weight: 700;
}

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

/* La palomita solo en el que está puesto. Ocupa su sitio siempre, para que
   las cuatro filas midan lo mismo y no salten al cambiar de estado. */
.tm-cortina-palomita {
  width: 22px;
  height: 22px;
  opacity: 0;
}

.tm-cortina-palomita svg {
  width: 22px;
  height: 22px;
}

.tm-cortina-modo--activo {
  border-color: currentColor;
  background: var(--papel-hondo);
}

.tm-cortina-modo--activo .tm-cortina-palomita {
  opacity: 1;
}

.tm-cortina-modo--abierto.tm-cortina-modo--activo {
  border-color: var(--ok);
  background: #F2FBF4;
}

.tm-cortina-modo--abierto.tm-cortina-modo--activo .tm-cortina-palomita { color: var(--ok); }

.tm-cortina-modo--medio.tm-cortina-modo--activo {
  border-color: var(--alerta);
  background: #FDF8E8;
}

.tm-cortina-modo--medio.tm-cortina-modo--activo .tm-cortina-palomita { color: var(--alerta); }

.tm-cortina-modo--cerrado.tm-cortina-modo--activo {
  border-color: var(--peligro);
  background: #FAF1F1;
}

.tm-cortina-modo--cerrado.tm-cortina-modo--activo .tm-cortina-palomita { color: var(--peligro); }

.tm-cortina-modo:focus-visible,
.tm-cortina-cerrar:focus-visible,
.tm-cortina-horario:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: -2px;
}

.tm-cortina-horario {
  margin-top: 4px;
  padding: 10px;
  min-height: 44px;
  border: 0;
  border-top: 1px solid var(--linea);
  border-radius: 0 0 10px 10px;
  background: none;
  color: var(--accion);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

/* ---------- El costo partido en sus pedazos ----------
   En la ficha del producto, debajo del costo. Se pinta solo cuando hay
   impuestos que enseñar: tres renglones que dicen cero, cero y el mismo
   número no informan de nada. */

.tm-costo-desglose {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 10px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-hondo);
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-costo-desglose > span {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.tm-costo-desglose-total {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--linea);
  font-weight: 800;
  color: var(--tinta);
}

/* ---------- El botón de descargar ----------
 *
 * Vive aquí y no en la hoja del asistente porque lo usan los dos: el
 * chat, cuando genera un reporte, y la pantalla de importar, para bajar
 * el catálogo. El dueño lo pidió así: «me interesa tener el mismo estilo
 * de botón» en todo lo que se descarga.
 *
 * El globo del tamaño es OPCIONAL: solo se pinta donde se sabe cuánto
 * pesa el archivo antes de bajarlo. El catálogo se genera al vuelo, así
 * que ahí el botón va sin globo.
 *
 * El diseño lo trajo el dueño (uiverse.io) y lo quiso en español: en reposo
 * dice «Descargar»; al tocarlo se encoge al icono, cambia de tono y aparece
 * arriba la etiqueta con el tamaño del archivo.
 *
 * **La etiqueta NO depende del cursor.** El diseño original la enseña al
 * pasar el ratón por encima, y CLAUDE.md sección 11 lo prohíbe: «nada que
 * dependa de pasar el cursor por encima; en pantalla táctil no existe el
 * hover», y el dueño trabaja desde el teléfono. Así que la animación solo
 * existe donde SÍ hay cursor —`@media (hover: hover)`— y en el teléfono el
 * tamaño se lee siempre, debajo del nombre del archivo. Se ve distinto en
 * cada aparato y es a propósito: en los dos se puede saber cuánto pesa antes
 * de bajarlo, que es lo que el diseño quería.
 *
 * El color de reposo es --accion, el del tema que el dueño tenga puesto, no
 * el azul fijo de la referencia: su POS está en morado ahora mismo y un
 * botón azul ahí dentro se vería pegado de otro lado. El tono de contacto se
 * saca del mismo color, aclarándolo. */

.tm-descarga {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    align-self: flex-start;
    margin-top: 2px;
    min-height: 44px;
    padding: 0 18px;
    border: 0;
    border-radius: 12px;
    background: var(--accion);
    color: #ffffff;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
    /* La misma curva que usa el diseño original: arranca lento y se acomoda,
       que es lo que hace que el encogido no se sienta un salto. */
    transition: background 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                padding 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                border-radius 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.tm-descarga svg {
    width: 19px;
    height: 19px;
    flex-shrink: 0;
}

/* La etiqueta del tamaño, con su piquito hacia abajo. */
.tm-descarga-globo {
    position: absolute;
    bottom: calc(100% + 9px);
    left: 50%;
    transform: translateX(-50%);
    padding: 5px 10px;
    border-radius: 8px;
    background: var(--papel-alto);
    color: var(--tinta);
    border: 1px solid var(--linea);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    font-size: 11.5px;
    font-weight: 700;
    white-space: nowrap;
    /* Nunca se toca: es un letrero, y estando encima del botón se comería el
       toque que iba a descargar. */
    pointer-events: none;

    /* **Se asoma y se va solo.** Es el arreglo de un defecto que reportó el
       dueño: «le falta la animación para que se quite el tamaño del archivo,
       porque se queda ahí siempre y no deja ver atrás». Tenía razón — el
       globo flota ENCIMA del mensaje anterior, así que quedarse fijo es
       taparle la conversación.

       El error de origen fue mío y es de los que solo se ven en el aparato:
       la animación de la referencia depende del cursor, y en un teléfono no
       hay cursor, así que el bloque `@media (hover: hover)` de más abajo
       —donde vivía el esconderse— sencillamente no aplicaba. El globo se
       quedaba en su estado inicial, que era «visible», para siempre.

       Tres segundos alcanzan para leer «Tamaño: 8 KB». `forwards` deja
       puesto el último fotograma —invisible— en vez de devolverlo al
       primero, que sería volver a taparlo todo justo al terminar. */
    animation: tm-descarga-asomar 3s ease forwards;
}

@keyframes tm-descarga-asomar {
    0%       { opacity: 0; transform: translateX(-50%) translateY(4px); }
    10%, 72% { opacity: 1; transform: translateX(-50%) translateY(0); }
    100%     { opacity: 0; transform: translateX(-50%) translateY(4px);
               visibility: hidden; }
}

/* Sin animaciones no se asoma solo: se queda escondido y sale al acercar el
   cursor. Un letrero que aparece y desaparece por su cuenta es justo lo que
   molesta a quien pidió menos movimiento. */
@media (prefers-reduced-motion: reduce) {
    .tm-descarga-globo {
        animation: none;
        opacity: 0;
        visibility: hidden;
    }
}

.tm-descarga-globo::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    margin-left: -6px;
    border: 6px solid transparent;
    border-top-color: var(--papel-alto);
}

/* ---------- En el teléfono: sin animación, todo a la vista ---------- */

.tm-descarga-pie {
    display: block;
    margin-top: 4px;
    font-size: 11px;
    color: var(--tinta-tenue);
}

@media (hover: hover) {
    /* Solo donde hay cursor. El globo empieza escondido y sale al acercarse;
       en el teléfono este bloque entero no aplica y el globo nunca se pinta
       —el tamaño se lee en el pie, que ahí sí siempre está. */
    .tm-descarga-globo {
        transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                    transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                    visibility 0.25s;
    }

    .tm-descarga:hover .tm-descarga-globo,
    .tm-descarga:focus-visible .tm-descarga-globo {
        /* `animation: none` es lo que le gana al fotograma final que dejó
           `forwards`. Sin esto, una vez terminada la animación el globo ya
           no volvería a salir por más que uno se acerque. */
        animation: none;
        opacity: 1;
        visibility: visible;
        transform: translateX(-50%) translateY(0);
    }

    /* El texto se encoge y queda solo el icono, como en la referencia. */
    .tm-descarga-texto {
        max-width: 160px;
        overflow: hidden;
        white-space: nowrap;
        transition: max-width 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                    opacity 0.18s ease, margin 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .tm-descarga:hover .tm-descarga-texto,
    .tm-descarga:focus-visible .tm-descarga-texto {
        max-width: 0;
        opacity: 0;
        margin-left: -8px;
    }

    .tm-descarga:hover,
    .tm-descarga:focus-visible {
        /* El mismo color, más vivo. `color-mix` no lo entienden los
           navegadores viejos y ahí simplemente no cambia de tono: el botón
           sigue funcionando, que es lo que importa. */
        background: color-mix(in srgb, var(--accion) 72%, #8b5cf6);
        padding: 0 14px;
        border-radius: 999px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .tm-descarga,
    .tm-descarga-texto,
    .tm-descarga-globo {
        transition: none;
    }
}


/* El acabado de la foto, en la ficha del producto.
 *
 * Lleva su explicación debajo y no un simple nombre, porque los tres
 * acabados no se explican solos y este es un ajuste que se toca una vez
 * cada muchos meses: para la siguiente ya se olvidó cuál hacía qué. */
.tm-campo--acabado {
  margin-top: 12px;
}

.tm-nota-acabado {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* La fila que se acaba de crear, marcada un instante.
 *
 * Una categoría nueva cae al final de la lista de su departamento, a veces
 * fuera de la pantalla. Sin esta marca, quien la creó jura que no se creó:
 * fue justo lo que reportó el dueño con «Gelatina» en Cremería. */
.tm-fila--recien-creada {
  animation: tm-recien-creada 2s ease;
}

@keyframes tm-recien-creada {
  0%, 55% { background: #E4F5E8; box-shadow: 0 0 0 2px var(--ok); }
  100% { background: var(--papel); box-shadow: 0 0 0 0 transparent; }
}

@media (prefers-reduced-motion: reduce) {
  .tm-fila--recien-creada { animation: none; box-shadow: 0 0 0 2px var(--ok); }
}

/* El cambio que hay que llevar, debajo del total del pedido.
 *
 * En grande y aparte porque es un número que alguien va a contar con las
 * manos antes de salir. El dueño lo pidió así: «que aparezca en la pantalla
 * para darle su cambio, o llevárselo más bien». */
.tm-pedido-cambio {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 10px;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--papel-hondo);
  border: 1px solid var(--linea);
}

.tm-pedido-cambio span {
  font-size: 12.5px;
  color: var(--tinta-suave);
}

.tm-pedido-cambio strong {
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  color: var(--tinta);
}


/* ---------- La pastilla de filtro, para el POS y la Trastienda ----------

   `.tm-chip` solo existía en `store.css`, y el POS no carga ese archivo. Así
   que cada pastilla del POS —«Solo lo que falta» en Compras, las rutas de un
   proveedor, los pasillos del selector— salía como botón pelado del
   navegador, con su marquito gris. Nadie lo había notado hasta que el dueño
   abrió el selector y se vio junto a todo lo demás.

   La bandeja de pedidos ya se había topado con esto y lo resolvió con su
   propio estilo (`.tm-bandeja-filtros .tm-chip`); esa sigue ganando porque es
   más específica. Y en la tienda sigue mandando la suya, con el degradado
   rojo de marca: `store.css` se carga después y pesa lo mismo.

   Activa en azul y plana, no en rojo con degradado: en el POS el rojo es para
   cancelar y borrar (CLAUDE.md sección 11). */
.tm-chip {
  flex-shrink: 0;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--boton-borde);
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.tm-chip--activo {
  border-color: var(--accion);
  background: var(--accion);
  color: #ffffff;
}

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

/* ---------- Compras: el menú de Opciones ---------- */

/* El título y el botón en un renglón. `position: relative` porque el panel
   del menú se cuelga de aquí: en el celular `.tm-menu` es estático y el panel
   toma el ancho del renglón entero, como en Productos. */
.tm-compras-cabeza--con-menu { position: relative; }

.tm-compras-titulo-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.tm-compras-titulo-fila h1 { margin: 0; }

/* El menú de Productos usa enlaces; aquí son botones, y un botón trae su
   propio borde, fondo y letra. Se le quitan para que las dos opciones se vean
   idénticas a las de Productos. */
button.tm-menu-opcion {
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

/* ---------- Compras: lo que saben los otros proveedores ---------- */

/* Ya viene en camino con alguien. Tinta y no color de alarma: no hay nada
   mal, al contrario, ya está resuelto. */
.tm-compra-yapedido {
  display: inline-block;
  margin-top: 2px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 11.5px;
  font-weight: 600;
}

.tm-compra-otros {
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--tinta-tenue);
  font-variant-numeric: tabular-nums;
}

.tm-compra-otros small { color: var(--tinta-tenue); }

/* Solo cuando de verdad hay uno más barato se enciende: ese es el único caso
   en que la cifra pide hacer algo. */
.tm-compra-otros--barato { color: var(--ok); font-weight: 600; }

.tm-compras-agregar--suave {
  background: var(--papel-alto);
  color: var(--tinta);
}

/* ---------- Escoger muchos de un jalón ----------

   Como se escogen archivos: se toca el renglón entero, se palomean varios, y
   abajo aparece qué hacer con ellos. La barra de abajo solo existe cuando hay
   algo escogido: antes no hay nada que confirmar. */

/* **95, y el número importa.** Estaba en 210 y así rompió lo único que tenía
   que hacer: el dueño tocó «Ligar 106 a Bimbo General», el botón se puso
   pálido y no pasó nada. La pregunta «¿seguro?» sí se abrió —pero DEBAJO
   del selector, que estaba más alto—, y el botón se quedó esperando una
   respuesta que nadie podía dar.

   La escalera de capas de la casa es esta, y el selector va en su peldaño:

     70–90   cortina, hojas y menú       (lo que tapa la pantalla)
     95      el selector                   ← aquí
     100     los avisos                    (tienen que verse encima)
     200     las preguntas                 (¿seguro?, escribe un dato)

   Encima de los menús porque tapa la pantalla entera; debajo de los avisos y
   de las preguntas porque esas se le hacen A él. */
.tm-selector-fondo {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
}

.tm-selector {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: min(640px, 100%);
  height: 100%;
  background: var(--papel);
}

@media (min-width: 768px) {
  .tm-selector-fondo { align-items: center; padding: 24px; }
  .tm-selector { height: min(860px, 100%); border-radius: var(--radio-panel); overflow: hidden; }
}

.tm-selector-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 12px 8px 16px;
  background: var(--papel-alto);
  border-bottom: 1px solid var(--linea);
}

.tm-selector-cabeza h2 { margin: 0; font-size: 17px; }

.tm-selector-cerrar {
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 12px;
  background: none;
  color: var(--tinta-suave);
  font-size: 18px;
  cursor: pointer;
}

.tm-selector-buscar {
  margin: 10px 12px 0;
  min-height: 46px;
  padding: 0 14px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  font: inherit;
  font-size: 15px;
}

/* Los pasillos se arrastran de lado, como en la tienda: en una fila no le
   quitan altura a la lista, que es lo que se viene a usar. */
.tm-selector-pasillos {
  display: flex;
  gap: 6px;
  padding: 10px 12px 2px;
  overflow-x: auto;
  scrollbar-width: none;
}

.tm-selector-pasillos::-webkit-scrollbar { display: none; }
.tm-selector-pasillos .tm-chip { flex: none; }

.tm-selector-barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  font-size: 13px;
  color: var(--tinta-suave);
}

/* Propio y no `.tm-enlace-suave`: ese vive solo en `store.css`, y el POS no
   lo carga. Salía como botón pelado con marco gris —el mismo problema que
   tenían las pastillas—. */
.tm-selector-todos {
  min-height: 40px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--accion);
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
}

.tm-selector-todos:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
  border-radius: 6px;
}

.tm-selector-lista {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  margin: 0;
  padding: 0 12px 12px;
  list-style: none;
}

.tm-selector-fila {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  margin-bottom: 6px;
  padding: 8px 12px;
  border: 1px solid var(--linea);
  border-radius: 12px;
  background: var(--papel-alto);
  cursor: pointer;
  user-select: none;
}

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

/* Escogido: el renglón entero cambia, no solo la casilla. Con veinte
   palomeados en pantalla, se tiene que ver de un vistazo cuáles son. */
.tm-selector-fila--puesta {
  border-color: var(--accion);
  background: color-mix(in srgb, var(--accion) 8%, var(--papel-alto));
}

.tm-selector-casilla {
  flex: none;
  width: 22px;
  height: 22px;
  border: 2px solid var(--tinta-tenue);
  border-radius: 6px;
  background: var(--papel-alto);
}

.tm-selector-fila--puesta .tm-selector-casilla {
  border-color: var(--accion);
  background: var(--accion)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 16px no-repeat;
}

.tm-selector-foto {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 9px;
  background: var(--papel-hondo);
  object-fit: cover;
}

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

.tm-selector-texto b { font-size: 14px; font-weight: 600; line-height: 1.3; }
.tm-selector-texto small { font-size: 11.5px; color: var(--tinta-tenue); }

/* El precio de cada renglón, al cambiar precios a varios. */
.tm-selector-precio {
  flex: none;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--tinta);
}

/* Las opciones del menú que abren algo en vez de navegar son <button>: sin
   esto traen el borde, el fondo y la letra del navegador. */
button.tm-menu-opcion {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

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

.tm-selector-vacio {
  padding: 30px 10px;
  text-align: center;
  color: var(--tinta-suave);
}

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

.tm-selector-cuantos { font-size: 13.5px; font-weight: 700; }

.tm-selector-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tm-selector-acciones .tm-boton { flex: 1 1 auto; min-height: 48px; }


/* ---------- El costo en dos cajitas y la palomita de IEPS ----------

   El mismo control en la ficha del producto y en el diálogo de Compras.
   Las dos cajitas del mismo ancho, una encima de la otra, con la palomita en
   medio: se lee de arriba abajo como la cuenta que es —sin impuesto, más el
   IEPS, igual a con impuesto—. */

.tm-costo-ieps {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-costo-ieps .tm-campo input { font-variant-numeric: tabular-nums; }

/* La palomita en su propio renglón de 44 de alto: se toca con el pulgar, y
   equivocarse aquí cambia el costo de un producto. */
.tm-costo-ieps-palomita {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 4px;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
}

.tm-costo-ieps-palomita input {
  width: 22px;
  height: 22px;
  accent-color: var(--accion);
}

/* La tasa en negritas pero sin cajita: se ve, y no invita a escribirla. */
.tm-costo-ieps-palomita b { color: var(--accion); }

.tm-costo-ieps-pista {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* ---------- El cartel de «qué hay de nuevo» ----------
   Sale una vez por versión, al abrir. Se ve como un modal normal —el dueño
   no tiene por qué aprender otra forma— con la versión arriba en chico y las
   novedades como lista: se leen de un vistazo, que es todo lo que se les
   pide. */

.tm-novedades {
  max-width: min(460px, 100%);
  /* Nunca más alto que la pantalla. Sin esto, con muchas notas el botón de
     cerrar quedaba FUERA y el cartel no se podía quitar: el peor error
     posible en algo que sale solo al abrir. */
  max-height: min(78vh, 620px);
  display: flex;
  flex-direction: column;
  text-align: left;
}

/* La lista es lo único que se desplaza; el título y el botón se quedan
   quietos, cada uno en su orilla. */
.tm-novedades .tm-novedades-lista {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

.tm-novedades .tm-modal-acciones {
  flex: none;
  padding-top: 10px;
  border-top: 1px solid var(--linea);
}

.tm-novedades-version {
  display: inline-block;
  margin-bottom: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--accion-suave, var(--papel-hondo));
  color: var(--accion);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.tm-novedades-lista {
  margin: 10px 0 4px;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--tinta);
}

.tm-novedades-lista li::marker {
  color: var(--accion);
}

/* ---------- Reportes: lo que no se mueve ----------
   Renglones, no tarjetas: es una lista para recorrer con el pulgar buscando
   el nombre que a uno le sorprenda, y el dinero detenido a la derecha para
   poder compararlos de un vistazo. */
.tm-reportes-quietos {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.tm-reportes-quieto {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--linea);
}

.tm-reportes-quieto:last-child {
  border-bottom: 0;
}

.tm-reportes-quieto-nombre {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  font-size: 14.5px;
  font-weight: 600;
}

.tm-reportes-quieto-nombre small,
.tm-reportes-quieto-cifras small {
  font-size: 12px;
  font-weight: 500;
  color: var(--tinta-suave);
}

.tm-reportes-quieto-cifras {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  font-size: 15px;
}


/* ---------- Borrar un cliente, y limpiar varios ---------- */
/*
   El botón de borrar vivió un rato en la tarjeta, como un ladrillo rojo de
   ancho completo debajo de «Editar». El dueño lo cachó de inmediato: «es un
   peligro tener el botón borrar ahí, y además se ve mal». Las dos cosas
   ciertas. Ahora vive DENTRO del formulario de editar, al fondo, donde hay
   que ir a propósito. */

.tm-cliente-peligro {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--linea);
}

.tm-cliente-peligro-texto {
  flex: 1 1 220px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--tinta-tenue);
}

.tm-cliente-peligro .tm-boton { flex: none; min-height: 40px; }

/* La palomita del modo limpieza: grande, que se toca con prisa. */
.tm-cliente-palomita {
  display: flex;
  align-items: center;
  flex: none;
  padding-right: 2px;
}

.tm-cliente-palomita input { width: 24px; height: 24px; }

/* Mientras se limpia, la tarjeta entera es el botón. */
.tm-cliente--escogiendo { cursor: pointer; }

.tm-cliente--escogido {
  border-color: var(--peligro);
  background: var(--peligro-fondo);
}

/* La barra de la tanda va pegada abajo: es donde cae el pulgar, y la lista
   se recorre con ella a la vista. */
.tm-limpieza-barra {
  position: sticky;
  bottom: 0;
  z-index: 3;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.06);
}

.tm-limpieza-cuenta {
  font-size: 14px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

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

.tm-limpieza-acciones .tm-boton { min-height: 44px; }

/* ---------- La cámara para escanear ---------- */
/*
   Se encima a lo que haya, como el carrito de la tienda. El dueño lo
   describió así al pedirla: «que se pueda encimar al abrir la cámara, algo
   como el carrito».

   Negra y sin adornos a propósito: lo único que importa aquí es ver lo que
   enfoca la cámara, y cualquier color alrededor compite con eso. */

.tm-camara {
  position: fixed;
  inset: 0;
  /* Por encima de todo, avisos incluidos: mientras se apunta a un código no
     hay nada más importante en la pantalla. */
  z-index: 300;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 20px;
  background: #0b0b10;
}

/* La proporción la pone el video al cargar, no este archivo.
   Estaba clavada en 4/3 y el `object-fit: cover` de abajo RECORTABA lo que
   no cabía. El dueño lo sintió tal cual: «lo siento con mucho zoom». Y
   había algo peor que lo feo: el detector lee el cuadro COMPLETO, así que
   se escaneaba más de lo que se veía — uno apuntaba a la mira y el código
   podía estar entrando por una orilla invisible. */
.tm-camara-marco {
  position: relative;
  width: min(92vw, 460px);
  aspect-ratio: 3 / 4;
  border-radius: 18px;
  overflow: hidden;
  background: #000;
}

/* `contain` y no `cover`: se ve TODO lo que la cámara está mandando, que es
   exactamente lo que el detector está leyendo. Si sobra negro a los lados,
   sobra — es preferible a recortar y mentir sobre dónde hay que apuntar. */
.tm-camara-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* La mira. No recorta nada —se lee todo el cuadro— pero le dice al ojo
   dónde poner el código, que es la diferencia entre apuntar y adivinar. */
.tm-camara-mira {
  position: absolute;
  left: 8%;
  right: 8%;
  top: 50%;
  height: 92px;
  transform: translateY(-50%);
  border: 2px solid rgba(255, 255, 255, 0.9);
  border-radius: 12px;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.35);
}

.tm-camara-aviso {
  margin: 0;
  max-width: 460px;
  text-align: center;
  font-size: 14.5px;
  line-height: 1.5;
  color: #f2f2f7;
}

.tm-camara-cerrar {
  min-height: 48px;
  min-width: 140px;
  background: #f2f2f7;
  color: #1f1f1f;
  border: none;
}

/* La cámara del checador, dentro de su buscador (pos/pos.css). */

/* Un `display` de clase le gana al `hidden` del navegador, y por eso el
   botón salía aunque el sistema hubiera decidido esconderlo — o sea, en
   teléfonos donde la cámara NO iba a poder funcionar. Un botón que aparece
   y no puede cumplir es peor que no tenerlo. */
.tm-checador-camara[hidden] { display: none; }

.tm-checador-camara {
  flex: none;
  /* 48px: se toca con prisa y a veces con las manos ocupadas. */
  width: 48px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: var(--accion-tenue);
  color: var(--accion);
  cursor: pointer;
}

.tm-checador-camara svg {
  width: 23px;
  height: 23px;
}

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

/* ---------- La salida del menú ---------- */
/*
   «Ver la tienda» y «Cerrar sesión», hasta abajo del menú. Faltaban, y
   «Cerrar sesión» era el grave: existía solo dentro de la pantalla de
   Personal, que pide permiso de personal, así que un cajero no podía cerrar
   su propia sesión al terminar el turno.

   Van separadas por una línea y en tono apagado: se encuentran cuando se
   buscan y no compiten con el trabajo, igual que «Soy del personal» al pie
   del menú de la tienda. */

.tm-nav-salida {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--linea);
}

/* En la barra de abajo los iconos van en fila, y este bloque —pensado para
   la columna— ponía sus dos botones uno encima del otro: la fila entera se
   estiraba a su alto y la barra medía 144 pixeles en vez de 64. Aquí van en
   fila como los demás, separados por una línea vertical. */
@media (max-width: 767px) {
  body:not([data-menu="cajon"]) .tm-nav-salida {
    display: flex;
    flex: 0 0 auto;
    margin: 0;
    padding: 0 0 0 3px;
    border-top: none;
    border-left: 1px solid var(--linea);
  }
}

.tm-nav-enlace--apagado {
  color: var(--tinta-suave);
}

.tm-nav-enlace--apagado .tm-nav-icono { opacity: 0.75; }

/* Los dos botones del pie de la cámara. */
.tm-camara-botones {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

.tm-camara-cambiar {
  min-height: 48px;
  min-width: 140px;
  background: transparent;
  color: #f2f2f7;
  border: 1px solid rgba(255, 255, 255, 0.45);
}

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

/* ---------- Opciones en lista ----------
 *
 * Nacieron en el checkout de la tienda y su estilo se quedó en
 * `css/store/store.css`, pero quien las dibuja es `core/paneles_ajustes.js`,
 * que montan también el POS y la Trastienda. Ahí salían sin una sola regla:
 * una fila de botones pelones donde debía haber opciones con su punto de
 * elegido. Nadie lo reportó porque no truena, solo se ve mal.
 */

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

.tm-opcion-lista {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 12px 14px;
  border: 2px solid var(--linea);
  border-radius: 14px;
  background: var(--papel-alto);
  font: inherit;
  color: var(--tinta);
  text-align: left;
  cursor: pointer;
}

.tm-opcion-lista--activa {
  border-color: var(--opcion-activa, var(--accion));
  background: var(--opcion-activa-fondo, #EEF2FE);
}

/* El punto de la izquierda hace de radio: se ve cuál está elegida sin leer
   los textos. */
.tm-opcion-marca {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  border: 2px solid var(--tinta-tenue);
}

.tm-opcion-lista--activa .tm-opcion-marca {
  border-color: var(--opcion-activa, var(--accion));
  border-width: 6px;
}

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

.tm-opcion-titulo {
  font-size: 14.5px;
  font-weight: 700;
}

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

/* La casilla del checkout usa el mismo mando que las opciones, pero
   cuadrada: se marca y se desmarca, no se elige entre varias. */
.tm-opcion-marca--casilla {
  border-radius: 7px;
}

.tm-opcion-lista--activa .tm-opcion-marca--casilla {
  border-width: 2px;
  background: var(--opcion-activa, var(--accion));
  box-shadow: inset 0 0 0 3px #ffffff;
}

/* ---------- Números que ruedan (rueda.js) ----------

   Cada cifra es una cajita del alto de un renglón que recorta; la que
   cambia lleva dentro la vieja y la nueva, una sobre otra, y se desliza.
   Todas las cajitas miden lo mismo para que las quietas y las que ruedan
   queden en la misma línea que el texto de alrededor. */

.tm-rueda {
  display: inline-flex;
  vertical-align: bottom;
  font-variant-numeric: tabular-nums;
}

.tm-rueda-cifra {
  display: block;
  height: 1.25em;
  height: 1lh;
  overflow: hidden;
  white-space: pre;
}

.tm-rueda-tira {
  display: flex;
  flex-direction: column;
}

.tm-rueda-tira > span {
  height: 1.25em;
  height: 1lh;
}

/* Blindadas: una regla de fuera como «.tm-carrito-cantidad span» alcanzaba
   a cada cajita y le daba ancho y relleno; mientras rodaba, «250 g» se
   abría en «2 5 0 g» y aplastaba el nombre del producto (lo vio el dueño,
   2026-10-05). Con dos clases le ganan a cualquier «.algo span». */
.tm-rueda .tm-rueda-cifra,
.tm-rueda .tm-rueda-tira > span {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
}

/* El número entero, solo para el lector de pantalla mientras rueda. */
.tm-rueda-leido {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- A granel: «¿Cuánto quieres?» ----------
   La ventanita que sube al tocar «Agregar» en algo de granel. Se arma una
   vez por apertura y luego solo ruedan los números (core/granel.js). La
   usan la tienda y el POS: es la misma, en espejo. */

.tm-granel {
  --granel-acento: var(--accion);
}

.tm-granel-fondo {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(10, 10, 20, 0.45);
  animation: tm-granel-funde 0.25s ease both;
}

.tm-granel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 301;
  width: min(480px, 100%);
  margin: 0 auto;
  padding: 10px 16px max(20px, env(safe-area-inset-bottom));
  border-radius: 26px 26px 0 0;
  background: var(--papel-alto);
  color: var(--tinta);
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-shadow: 0 -12px 30px rgba(0, 0, 0, 0.2);
  animation: tm-granel-sube 0.32s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.tm-granel--sale {
  animation: tm-granel-baja 0.22s ease-in both;
}

.tm-granel-fondo--sale {
  animation: tm-granel-funde 0.22s ease reverse both;
}

@keyframes tm-granel-funde {
  from { opacity: 0; }
}

@keyframes tm-granel-sube {
  from { translate: 0 100%; }
}

@keyframes tm-granel-baja {
  to { translate: 0 100%; }
}

.tm-granel-asa {
  align-self: center;
  width: 42px;
  height: 5px;
  border-radius: 999px;
  background: var(--linea);
}

.tm-granel-cabeza {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tm-granel-foto {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  overflow: hidden;
  background: #ffffff;
  border: 1px solid var(--linea);
}

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

.tm-granel-quien {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tm-granel-quien b {
  font-size: 15.5px;
  line-height: 1.25;
}

.tm-granel-quien small {
  font-size: 13px;
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}

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

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

.tm-granel-pregunta {
  margin: 0;
  text-align: center;
  font-size: 18px;
  font-weight: 800;
}

.tm-granel-modo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 4px;
  border-radius: 14px;
  background: var(--papel-hondo);
}

.tm-granel-modo button {
  min-height: 44px;
  border: none;
  border-radius: 11px;
  background: none;
  color: var(--tinta-suave);
  font: inherit;
  font-size: 14.5px;
  font-weight: 700;
  cursor: pointer;
}

.tm-granel-modo button[aria-pressed="true"] {
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.tm-granel-paso {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px;
  border-radius: 999px;
  background: var(--papel-hondo);
}

.tm-granel-paso button {
  flex: none;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 999px;
  background: var(--papel-alto);
  color: var(--tinta);
  font: inherit;
  font-size: 26px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.07);
}

.tm-granel-paso button:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.tm-granel-valor {
  flex: 1;
  text-align: center;
  font-family: var(--fuente-mono, monospace);
  font-size: 26px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tm-granel-equivale {
  margin: -6px 0 0;
  text-align: center;
  font-size: 14.5px;
  color: var(--tinta-suave);
}

.tm-granel-equivale b {
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
}

.tm-granel-atajos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.tm-granel-atajos button {
  min-height: 46px;
  border-radius: 12px;
  border: 1px solid var(--boton-borde);
  box-shadow: var(--boton-sombra);
  background: var(--papel);
  color: var(--tinta);
  font: inherit;
  font-size: 14.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.tm-granel-atajos button[aria-pressed="true"] {
  border-color: var(--granel-acento);
  box-shadow: inset 0 0 0 1px var(--granel-acento);
  color: var(--granel-acento);
}

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

.tm-granel-poner {
  min-height: 56px;
  justify-content: center;
  border-radius: 16px;
  font-size: 16px;
}

.tm-granel button:focus-visible {
  outline: 2px solid var(--granel-acento);
  outline-offset: 2px;
}

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

/* En el POS: lo que marque la báscula, gramo por gramo. */
.tm-granel-bascula {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 12px;
  border-radius: 12px;
  border: 2px dashed var(--linea);
  background: var(--papel);
}

.tm-granel-bascula:focus-within {
  border-style: solid;
  border-color: var(--granel-acento);
}

.tm-granel-bascula span {
  font-weight: 700;
  color: var(--tinta-suave);
}

.tm-granel-bascula input {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  color: var(--tinta);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  outline: none;
}

/* El depósito del envase propio, en la ficha del producto retornable. */
.tm-campo-deposito {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 8px;
  font-size: 14px;
  font-weight: 600;
}

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

.tm-campo-pesos {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}

.tm-campo-pesos input {
  width: 96px;
  min-height: 44px;
  text-align: right;
}

/* El verde de WhatsApp: se reconoce antes de leerse. */
.tm-boton--whatsapp {
  background: #1fa855;
  border-color: #1fa855;
  color: #ffffff;
  box-shadow: var(--boton-sombra-color);
}

/* ---------- El mapa (core/mapa.js, OpenStreetMap) ----------
   Mide poco a propósito: en el teléfono la página se sigue bajando tocando
   fuera de él, y adentro un dedo lo mueve como cualquier mapa. */

.tm-mapa-osm {
  height: 260px;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--linea);
  background: var(--papel-hondo);
  /* Leaflet pone sus capas con z-index altos; aquí se encierran para que
     no se encimen al menú ni a las ventanitas. */
  isolation: isolate;
  z-index: 0;
}

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

/* Los íconos propios (la tienda y el pin), sin el cuadro blanco que Leaflet
   le pone a los suyos. */
.tm-mapa-icono {
  background: none;
  border: 0;
}

.tm-mapa-icono svg {
  display: block;
  width: 100%;
  height: 100%;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.3));
}

.tm-mapa-tienda {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-mapa-etiqueta {
  font-size: 13px;
  font-weight: 700;
  color: var(--tinta-suave);
}

.tm-mapa-botones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tm-mapa-botones .tm-boton {
  flex: 1 1 200px;
  min-height: 44px;
  justify-content: center;
}

/* «Cómo llegar» en el pedido: abre la navegación del repartidor. */
.tm-como-llegar {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  margin-left: 6px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--accion-tenue);
  color: var(--accion);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

/* ---------- Pedidos por grupo y su bolsa (2026-10-05) ---------- */

.tm-bandeja-grupos {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  margin-bottom: 4px;
}

.tm-bandeja-grupos::-webkit-scrollbar {
  display: none;
}

.tm-bandeja-grupos:empty {
  display: none;
}

.tm-bolsa {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 12px;
  padding: 14px;
  border-radius: 18px;
  background: var(--papel-alto);
  border: 2px solid var(--accion);
  box-shadow: 0 8px 20px rgba(27, 77, 228, 0.12);
}

.tm-bolsa-cabeza {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tm-bolsa-icono {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--accion-tenue);
  color: var(--accion);
}

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

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

.tm-bolsa-datos span {
  font-size: 13px;
  color: var(--tinta-suave);
}

.tm-bolsa-total {
  font-family: var(--fuente-mono);
  font-size: 20px;
  font-variant-numeric: tabular-nums;
}

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

.tm-bolsa-salir {
  min-height: 52px;
  justify-content: center;
  font-size: 15.5px;
}

/* «Versión nueva lista · Actualizar» (js/core/version.js). Arriba y no
   abajo: abajo están el botón de cobrar del POS y la barra del pedido de la
   tienda, y un aviso que no es urgente no debe tapar ninguno de los dos.

   Cristal oscuro con el color de donde sale: lo escogió el dueño en la
   maqueta del 2026-10-16 (la D) porque la pastilla negra se veía sin acabar.
   El color es `--aviso-version-color`: el de acción en el POS, y la tienda
   lo cambia por su rojo de marca. En tema oscuro se invierte, como antes. */
.tm-aviso-version {
  --aviso-version-color: var(--accion);
  position: fixed;
  left: 50%;
  top: max(10px, env(safe-area-inset-top, 0px));
  z-index: 350;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(440px, calc(100vw - 24px));
  padding: 12px 4px 12px 12px;
  border-radius: 20px;
  background: color-mix(in srgb, var(--tinta) 88%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  color: var(--papel);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  animation: tm-aviso-version-entra 450ms cubic-bezier(0.22, 1.2, 0.36, 1);
}

.tm-aviso-version--sale {
  animation: tm-aviso-version-sale 260ms ease-in forwards;
}

.tm-aviso-version-icono {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: var(--aviso-version-color);
  color: #ffffff;
}

.tm-aviso-version-icono svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tm-aviso-version-textos {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.tm-aviso-version-textos b {
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.25;
}

/* Hasta dos renglones: en un teléfono de 360 el título de las novedades no
   cabe en uno y cortado a la mitad no dice nada. */
.tm-aviso-version-textos small {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 12.5px;
  line-height: 1.3;
  color: color-mix(in srgb, var(--papel) 72%, transparent);
}

.tm-aviso-version-boton {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: 12px;
  background: var(--aviso-version-color);
  color: #ffffff;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}

.tm-aviso-version-boton:disabled {
  cursor: progress;
}

.tm-aviso-version-rueda {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  animation: tm-aviso-version-gira 0.9s linear infinite;
}

.tm-aviso-version-rueda circle {
  stroke-opacity: 0.3;
}

.tm-aviso-version-cerrar {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: none;
  color: color-mix(in srgb, var(--papel) 72%, transparent);
  cursor: pointer;
}

.tm-aviso-version-cerrar svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
}

.tm-aviso-version-boton:focus-visible,
.tm-aviso-version-cerrar:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

@keyframes tm-aviso-version-entra {
  from { opacity: 0; translate: -50% -24px; }
}

@keyframes tm-aviso-version-sale {
  to { opacity: 0; translate: -50% -24px; }
}

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

@media (prefers-reduced-motion: reduce) {
  .tm-aviso-version,
  .tm-aviso-version--sale,
  .tm-aviso-version-rueda { animation: none; }
}

/* ---------- Favoritos (maqueta aprobada 2026-10-08) ----------
 *
 * La estrellita junto al nombre de la pantalla, en la barra de arriba, y el
 * acordeón «Favoritos» debajo del nombre del negocio, en el menú. Los
 * renglones de adentro son copias de los de siempre: usan la misma clase y
 * se ven igual.
 */
.tm-estrella {
  flex: none;
  width: 40px;
  height: 44px;
  margin-left: -4px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: #ffffff;
  cursor: pointer;
}

.tm-estrella svg { width: 22px; height: 22px; }
.tm-estrella path { fill: none; stroke: currentColor; }
.tm-estrella[aria-pressed="true"] path { fill: currentColor; }

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

.tm-estrella--salta svg { animation: tm-estrella-salta 0.32s ease; }

@keyframes tm-estrella-salta {
  50% { transform: scale(1.3); }
}

/* Termina con su línea, abierto o cerrado: lo de abajo ya es el menú de
   siempre. */
.tm-favoritos {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--linea);
}

.tm-favoritos-cabeza {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 0 12px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--tinta);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

.tm-favoritos-cabeza .tm-nav-texto { flex: 1; min-width: 0; }

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

.tm-favoritos-estrella { color: var(--alerta); }
.tm-favoritos-estrella path { fill: currentColor; }

.tm-favoritos-cuenta {
  min-width: 24px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--papel-hondo);
  color: var(--tinta-suave);
  font-size: 12px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.tm-favoritos-flecha {
  flex: none;
  color: var(--tinta-suave);
  transition: transform 0.2s ease;
}

.tm-favoritos-cabeza[aria-expanded="true"] .tm-favoritos-flecha { transform: rotate(180deg); }

.tm-favoritos-lista {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* «Nuevo producto», y debajo, en chiquito, de qué sección es. */
.tm-favoritos-de {
  display: block;
  font-size: 11px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--tinta-tenue);
}

.tm-nav-enlace--favorito .tm-nav-texto { line-height: 1.25; }

@media (min-width: 768px) {
  .tm-favoritos-cabeza { font-size: 13px; gap: 10px; }
}

/* Con la barra de abajo no hay columna donde abrir un acordeón: los
   favoritos van primero en la fila, como un icono más, y siempre a la vista. */
@media (max-width: 767px) {
  body:not([data-menu="cajon"]) .tm-favoritos,
  body:not([data-menu="cajon"]) .tm-favoritos-lista,
  body:not([data-menu="cajon"]) .tm-favoritos-lista[hidden] {
    display: contents !important;
  }

  body:not([data-menu="cajon"]) .tm-favoritos-cabeza,
  body:not([data-menu="cajon"]) .tm-favoritos-de {
    display: none;
  }

  body:not([data-menu="cajon"]) .tm-nav-enlace--favorito .tm-nav-texto {
    text-align: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tm-estrella--salta svg { animation: none; }
  .tm-favoritos-flecha { transition: none; }
}

/* ---------- Mantener sesión abierta (Ajustes → Personal) ---------- */
.tm-sesion-icono {
  grid-area: dibujo;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: color-mix(in srgb, var(--accion) 10%, var(--papel-alto));
  color: var(--accion);
}

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

.tm-sesion-aviso {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--peligro-fondo, #F4E4E4);
  color: var(--peligro);
  font-size: 13.5px;
  line-height: 1.45;
}

.tm-sesion-aviso svg { flex: none; width: 20px; height: 20px; margin-top: 1px; }

.tm-sesion-cerrar-todas {
  width: 100%;
  margin-top: 4px;
}

/* En el teléfono, con el menú escondido (el de fábrica desde el
   2026-10-08), el nombre de la pantalla toma el lugar de «TeleMarket POS».
   Ahí se escondía porque la barra de abajo ya marcaba la sección; sin barra,
   nada en pantalla decía dónde estás, y la estrellita de Favoritos quedaba
   suelta sin saber qué marca. La marca sigue en el icono y en el menú.

   En TODO teléfono, no solo en el angosto. Hasta el 2026-10-13 esto llegaba
   a 419px, y en un teléfono más ancho —o con la letra de pantalla más
   chica— volvía «TeleMarket POS / Checador de…», las dos cosas cortadas.
   El dueño lo vio en el celular de su otro administrador: «¿mi admin tiene
   la misma vista que yo?». Ahora sí, la misma. */
@media (max-width: 767px) {
  body[data-menu="cajon"] .tm-pos-shell .tm-topbar-identidad,
  body[data-menu="cajon"] .tm-pos-shell .tm-topbar-separador {
    display: none;
  }

  body[data-menu="cajon"] .tm-pos-shell .tm-topbar-seccion {
    display: block;
    color: #ffffff;
    font-size: 17px;
  }

  /* El asistente y la campanita se van a la derecha: la estrella se queda
     pegada al nombre que marca. */
  body[data-menu="cajon"] .tm-pos-shell .tm-ia-boton,
  body[data-menu="cajon"] .tm-pos-shell .tm-campanita {
    order: 1;
  }

  /* Y van JUNTOS. La campanita trae su propio margen automático, que se
     repartía el hueco con el de la estrella y dejaba al asistente flotando a
     media barra. Antes lo disimulaba el letrero de abierto, que iba al final;
     sin él se nota. El margen de la estrella basta para empujar a los dos. */
  body[data-menu="cajon"] .tm-pos-shell .tm-campanita {
    margin-left: 0;
  }

  body[data-menu="cajon"] .tm-pos-shell .tm-estrella,
  body[data-menu="cajon"] .tm-pos-shell .tm-topbar:has(.tm-estrella[hidden]) .tm-topbar-seccion {
    margin-right: auto;
  }
}

/* Los botones dibujados por su cuenta también se hunden al apretarlos,
   igual que .tm-boton (estilo Stripe, 2026-10-09). */
.tm-opciones-boton:active,
.tm-boton-icono:active,
.tm-boton-camara:active,
.tm-dia-copiar:active,
.tm-vista-boton.tm-vista-boton--solo:active,
.tm-desc-ver-todas:active,
.tm-ia-ejemplos button:active,
.tm-billete:active {
  transform: translateY(var(--boton-hundir));
  box-shadow: none;
}


/* ---------- Reportes «como tu app del banco» (2026-10-09) ----------
 *
 * El color dice qué es el dinero, no de qué tema es la pantalla: verde lo
 * que ganas, rojo lo que pierdes, azul lo que está parado, gris lo que
 * costó. El azul es fijo a propósito: con el tema morado, «parado» no puede
 * verse igual que un botón.
 */
[data-rol="reportes"] {
  --dato-ganancia: var(--ok);
  --dato-ganancia-fondo: var(--ok-fondo);
  --dato-perdida: var(--peligro);
  --dato-perdida-fondo: var(--peligro-fondo);
  --dato-parado: #1b4de4;
  --dato-costo: color-mix(in srgb, var(--tinta-tenue) 40%, var(--papel-alto));
}

.tm-reportes-saldo {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 4px 2px;
}

.tm-reportes-saldo-titulo {
  font-size: 14px;
  color: var(--tinta-suave);
}

.tm-reportes-saldo-cifra {
  font-family: var(--fuente-mono);
  font-size: clamp(34px, 9vw, 44px);
  line-height: 1.08;
  color: var(--dato-ganancia);
  font-variant-numeric: tabular-nums;
}

.tm-reportes-saldo-cifra--menos { color: var(--dato-perdida); }

.tm-reportes-saldo-comparacion {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--tinta-suave);
}

.tm-reportes-saldo-comparacion--sube { color: var(--dato-ganancia); }
.tm-reportes-saldo-comparacion--baja { color: var(--dato-perdida); }

.tm-reportes-movs {
  padding-top: 4px;
  padding-bottom: 4px;
  gap: 0;
}

.tm-reportes-mov {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 64px;
  padding: 10px 0;
  border: 0;
  border-top: 1px solid var(--linea);
  background: none;
  color: var(--tinta);
  font: inherit;
  text-align: left;
}

.tm-reportes-movs > .tm-reportes-mov:first-child { border-top: 0; }
button.tm-reportes-mov { cursor: pointer; }
button.tm-reportes-mov:focus-visible { outline: 2px solid var(--accion); outline-offset: 2px; border-radius: 8px; }

.tm-reportes-mov-icono {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 17px;
}

.tm-reportes-mov-icono svg { width: 20px; height: 20px; }
.tm-reportes-mov-icono--entra { background: var(--dato-ganancia-fondo); color: var(--dato-ganancia); }
.tm-reportes-mov-icono--costo { background: var(--papel-hondo); color: var(--tinta-suave); }
.tm-reportes-mov-icono--pierde { background: var(--dato-perdida-fondo); color: var(--dato-perdida); }

.tm-reportes-mov-texto {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-size: 15px;
  font-weight: 700;
}

.tm-reportes-mov-texto small {
  font-size: 12.5px;
  font-weight: 400;
  color: var(--tinta-tenue);
}

.tm-reportes-mov-cifra {
  font-family: var(--fuente-mono);
  font-size: 15.5px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tm-reportes-mov-cifra--costo { color: var(--tinta-suave); }
.tm-reportes-mov-cifra--pierde { color: var(--dato-perdida); }

.tm-reportes-desglose {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 10px 52px;
  padding-left: 12px;
  border-left: 2px solid var(--linea);
}

.tm-reportes-desglose-renglon {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: 14px;
}

.tm-reportes-desglose-renglon span { display: flex; flex-direction: column; }
.tm-reportes-desglose-renglon small { font-size: 12px; color: var(--tinta-tenue); }
.tm-reportes-desglose-renglon b { font-family: var(--fuente-mono); font-weight: 600; font-variant-numeric: tabular-nums; }

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

.tm-reportes-desglose-enlace {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 44px;
  font-size: 14px;
  font-weight: 600;
  color: var(--tinta);
  text-decoration: none;
  border-top: 1px solid var(--linea);
}

.tm-reportes-parado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 12px 16px;
  border: 1px solid var(--linea);
  border-radius: var(--radio-tarjeta);
  background: var(--papel-alto);
  color: var(--tinta-suave);
  font: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}

.tm-reportes-parado b {
  font-family: var(--fuente-mono);
  font-weight: 600;
  color: var(--dato-parado);
}

.tm-reportes-parado-ir {
  font-size: 20px;
  font-weight: 700;
  color: var(--dato-parado);
}

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

.tm-reportes-verde { color: var(--dato-ganancia); }

.tm-mas-vendido-nombre small {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: var(--tinta-tenue);
}

.tm-reportes-donde-detalle {
  display: block;
  font-size: 12px;
  color: var(--tinta-tenue);
}


/* ---------- Empezar de cero (Ajustes → Sistema, 2026-10-12) ----------
   Dos listas con su número: lo que se queda en verde y lo que se borra en
   rojo. El color va solo en el título y en la cifra de lo que se borra. */
.tm-decero-listas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px 28px;
}

.tm-decero-titulo {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.tm-decero-titulo--queda { color: var(--ok); }
.tm-decero-titulo--borra { color: var(--peligro); }

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

.tm-decero-renglon {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid var(--linea);
  font-size: 14.5px;
}

.tm-decero-renglon span { display: flex; flex-direction: column; min-width: 0; }
.tm-decero-renglon small { font-size: 12px; color: var(--tinta-tenue); }

.tm-decero-renglon b {
  font-family: var(--fuente-mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tm-decero-lista--borra .tm-decero-renglon b { color: var(--peligro); }

.tm-decero-nota {
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--papel-hondo);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--tinta-suave);
}

/* El aviso del PIN de fábrica es un párrafo, no una tarjeta del Inicio:
   `.tm-aviso` se volvió a definir más abajo como caja flexible y aquí le
   partía el texto en tres renglones («(», «1234», «)»). */
[data-rol="aviso-pin"] .tm-aviso {
  display: block;
  padding: 12px 14px;
  border: 0;
  border-left: 3px solid var(--alerta);
  background: var(--papel-hondo);
}

/* ---------- La hoja de caja: tarjeta de cliente o vale escaneado ----------
   (js/core/hoja_caja.js; maqueta aprobada el 2026-10-17). Abajo en el
   teléfono, al centro en pantalla grande; encima de la venta, sin tocarla. */
.tm-hoja-caja-fondo {
  align-items: flex-end;
  padding: 0;
}

.tm-hoja-caja {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  max-width: 460px;
  max-height: calc(100dvh - 40px);
  overflow: auto;
  padding: 18px 16px max(18px, env(safe-area-inset-bottom));
  border-radius: 22px 22px 0 0;
  background: var(--papel-alto);
  color: var(--tinta);
  box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.18);
}

@media (min-width: 768px) {
  .tm-hoja-caja-fondo {
    align-items: center;
    padding: 16px;
  }

  .tm-hoja-caja {
    border-radius: 22px;
  }
}

.tm-hoja-caja-cargando {
  margin: 8px 0;
  color: var(--tinta-suave);
  text-align: center;
}

.tm-hoja-caja-cabeza {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tm-hoja-caja-cara {
  flex: none;
  width: 56px;
  height: 56px;
  border-radius: 999px;
  object-fit: cover;
  box-shadow: 0 0 0 2px var(--papel-alto), 0 0 0 4px var(--accion);
}

.tm-hoja-caja-cara--iniciales,
.tm-hoja-caja-cara--vale {
  display: grid;
  place-items: center;
  color: #ffffff;
  font-size: 20px;
  font-weight: 700;
}

.tm-hoja-caja-cara--vale {
  background: var(--papel-hondo);
  color: var(--accion);
}

.tm-hoja-caja-cara--vale svg {
  width: 28px;
  height: 28px;
}

.tm-hoja-caja-quien {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.tm-hoja-caja-quien b {
  font-size: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tm-hoja-caja-quien small {
  color: var(--tinta-suave);
  font-size: 13px;
}

.tm-hoja-caja-etiqueta {
  margin-left: auto;
  align-self: flex-start;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--ok-fondo);
  color: var(--ok);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.tm-hoja-caja-etiqueta--vencido {
  background: var(--peligro-fondo);
  color: var(--peligro);
}

.tm-hoja-caja-seccion {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border-radius: 14px;
  background: var(--papel);
}

.tm-hoja-caja-seccion h3 {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin: 0;
  font-size: 14px;
}

.tm-hoja-caja-seccion h3 span {
  color: var(--ok);
  font-variant-numeric: tabular-nums;
}

.tm-hoja-caja-vale {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: 12px;
  background: var(--papel-alto);
  border: 1px solid var(--boton-borde);
}

.tm-hoja-caja-vale-texto {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.tm-hoja-caja-vale-texto b {
  font-size: 13.5px;
}

.tm-hoja-caja-vale-texto small {
  color: var(--tinta-suave);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.tm-hoja-caja-vale .tm-boton {
  flex: none;
  white-space: nowrap;
}

.tm-hoja-caja-hecho {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ok);
  font-size: 13px;
  font-weight: 700;
}

.tm-hoja-caja-hecho svg {
  width: 16px;
  height: 16px;
}

.tm-hoja-caja-nada,
.tm-hoja-caja-nota {
  margin: 0;
  color: var(--tinta-suave);
  font-size: 13px;
  line-height: 1.45;
}

.tm-hoja-caja-pronto {
  flex-direction: row;
  justify-content: space-between;
  color: var(--tinta-tenue);
  font-size: 13.5px;
}

.tm-hoja-caja-pronto b {
  color: var(--tinta-suave);
}

.tm-hoja-caja-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px 6px 0;
  text-align: center;
}

.tm-hoja-caja-error svg {
  width: 44px;
  height: 44px;
  color: var(--alerta);
}

.tm-hoja-caja-error b {
  font-size: 17px;
}

.tm-hoja-caja-error p {
  margin: 0;
  color: var(--tinta-suave);
  font-size: 14px;
  line-height: 1.45;
}

.tm-hoja-caja-pie {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tm-hoja-caja-pie .tm-boton {
  min-height: 48px;
  justify-content: center;
}

/* Con varios vales, o uno vencido, cada uno lleva su casilla: los que
   trae. El vencido nace sin marcar; marcarlo es aceptarlo. */
.tm-hoja-caja-marca {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1.5px solid var(--boton-borde);
  border-radius: 8px;
  background: var(--papel-alto);
  color: transparent;
  cursor: pointer;
}

.tm-hoja-caja-marca[aria-checked="true"] {
  border-color: var(--ok);
  background: var(--ok);
  color: #ffffff;
}

.tm-hoja-caja-marca svg {
  width: 18px;
  height: 18px;
}

.tm-hoja-caja-marca:focus-visible {
  outline: 2px solid var(--accion);
  outline-offset: 2px;
}

.tm-hoja-caja-vale--vencido .tm-hoja-caja-vale-texto small {
  color: var(--peligro);
}

.tm-hoja-caja-nota--centro {
  text-align: center;
}

.tm-hoja-caja-pregunta b {
  font-size: 20px;
}
