/* ══════════════════════════════════════════════════════════════════════════════════════════════
   Salón: la disponibilidad de las mesas de un vistazo.

   Lo que esta pantalla tiene que resolver desde la puerta del local es UNA pregunta: ¿dónde
   sentar a esta gente? Por eso las mesas son cuadradas, grandes y con el estado en el color —no
   en un rótulo que haya que leer— y la capacidad es lo segundo que se ve.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

.ms-zona + .ms-zona { margin-top: 1.5rem; }

.ms-zona-titulo {
    font-size: .8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--ins-secondary-color, #6c757d);
    margin-bottom: .5rem;
    display: flex;
    align-items: center;
    gap: .5rem;
}

/* La línea que acompaña al nombre de la zona: separa sin gritar. */
.ms-zona-titulo::after {
    content: '';
    flex: 1 1 auto;
    height: 1px;
    background: var(--ins-border-color);
}

.ms-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: .75rem;
}

/* ⚠ La mesa ENTERA es el área tocable. En un salón se toca de pie y de refilón; un botón chico
   adentro de la tarjeta sería el defecto que esto evita. */
.ms-mesa {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-height: 118px;
    padding: .75rem;
    border: 2px solid var(--ins-border-color);
    border-radius: var(--ins-border-radius, .375rem);
    background: var(--ins-secondary-bg, #fff);
    text-align: left;
    width: 100%;
    cursor: pointer;
    transition: transform .1s ease, box-shadow .15s ease;
}

.ms-mesa:hover { box-shadow: 0 4px 14px rgba(0, 0, 0, .1); }
.ms-mesa:active { transform: scale(.98); }

.ms-mesa:focus-visible {
    outline: 2px solid var(--ins-primary);
    outline-offset: 2px;
}

.ms-mesa-nombre { font-weight: 600; font-size: .95rem; line-height: 1.2; }

.ms-mesa-capacidad {
    font-size: .75rem;
    color: var(--ins-secondary-color, #6c757d);
    display: flex;
    align-items: center;
    gap: .25rem;
}

.ms-mesa-total {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.ms-mesa-pie {
    font-size: .72rem;
    color: var(--ins-secondary-color, #6c757d);
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .5rem;
    margin-top: .5rem;
}

/* ── Los estados ──────────────────────────────────────────────────────────────────────────────
   El color va en el BORDE y en un fondo apenas teñido, no en un relleno sólido: una pared de
   tarjetas de color pleno cansa la vista y hace que ninguna destaque. Lo que tiene que saltar es
   la excepción —la que pidió la cuenta—, no el conjunto. */
.ms-mesa.desocupada  { border-color: var(--ins-border-color); }
.ms-mesa.sin_atender { border-color: var(--ins-danger);  background: var(--ins-danger-bg-subtle, #fde6e9); }
.ms-mesa.atendida    { border-color: var(--ins-success); background: var(--ins-success-bg-subtle, #e3f7ef); }
.ms-mesa.pedida      { border-color: var(--ins-warning); background: var(--ins-warning-bg-subtle, #fff6e0); }
.ms-mesa.por_limpiar { border-color: var(--ins-purple, #7e5fc7); background: var(--ins-purple-bg-subtle, #f0e9fb); }
.ms-mesa.reservada   { border-color: var(--ins-info);    background: var(--ins-info-bg-subtle, #e3f6fb); }

/* Los puntos de la leyenda.

   ⚠ El color lo pone el JS desde la paleta elegida, no el CSS: desde que Mario elige los seis,
   un punto pintado con el token del tema le miente al plano —su «sin atender» es #ff175d y el
   token es #f1556c—. Lo de acá es solo el arranque, hasta que llega la configuración. */
.ms-punto {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: .35rem;
    border: 2px solid var(--ins-border-color);
    background: var(--ins-tertiary-bg, #f4f4f4);
}

/* Las muestras de los pisos que trae el sistema. Cuadradas y con el dibujo a tamaño natural
   reducido: así se ve cómo repite, que es lo que se está eligiendo. */
.ms-piso {
    width: 56px;
    height: 56px;
    padding: 0;
    border: 2px solid var(--ins-border-color, #dee2e6);
    border-radius: var(--ins-border-radius, .375rem);
    background-size: 56px;
    background-position: center;
    cursor: pointer;
}

.ms-piso:hover { border-color: var(--ins-secondary-color, #6c757d); }

/* El elegido, con el color del tema y un realce: el borde solo se pierde sobre una madera clara. */
.ms-piso.elegido {
    border-color: var(--ins-primary);
    box-shadow: 0 0 0 3px rgba(var(--ins-primary-rgb), .25);
}

/* ── Los pisos PROPIOS ──────────────────────────────────────────────────────────────────────
   Los del sistema no llevan papelera: viven en `assets/` y los comparten todas las empresas, así
   que quitar uno se lo quitaría a todo el mundo (Mario, 2026-09-27). Solo los subidos se borran,
   y por eso solo ellos van envueltos. */
.ms-piso-propio {
    position: relative;
    display: inline-block;
    line-height: 0;
}

.ms-piso-quitar {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;

    border: 0;
    border-radius: 50%;
    background: var(--ins-danger, #ef5f5f);
    color: #fff;
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    /* Un halo blanco para que se despegue de la muestra sea cual sea el piso que tenga debajo. */
    box-shadow: 0 0 0 2px var(--ins-secondary-bg, #fff);
}

.ms-piso-quitar:hover { filter: brightness(.92); }

/* El aviso de «por limpiar» dentro de la modal, del mismo morado que la mesa en el plano: quien
   lo ve acá ya vio la mesa allá. */
.ms-aviso-limpiar {
    display: none;
    padding: .75rem;
    border-radius: var(--ins-border-radius, .375rem);
    background: var(--ins-purple, #7e5fc7);
    color: #fff;
}

.ms-aviso-limpiar:not(.d-none) { display: flex; }

/* Cuántas cuentas lleva: solo aparece con cuenta dividida, que es cuando importa. */
.ms-cuentas {
    position: absolute;
    top: .4rem;
    right: .4rem;
    font-size: .7rem;
}

/* ── Las cuentas dentro de la modal ─────────────────────────────────────────────────────────── */
.ms-cuenta {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .75rem;
    border: 1px solid var(--ins-border-color);
    border-radius: var(--ins-border-radius, .375rem);
    margin-bottom: .5rem;
}

.ms-cuenta-datos { flex: 1 1 auto; min-width: 0; }

/* En el teléfono, los botones de la cuenta al 50 % y en dos filas, como el resto del sistema. */
@media (max-width: 767.98px) {
    .ms-cuenta { flex-wrap: wrap; }
    .ms-cuenta-acciones { width: 100%; display: flex; gap: .5rem; }
    .ms-cuenta-acciones .btn { flex: 1 1 0; }
    .ms-grid { grid-template-columns: repeat(auto-fill, minmax(135px, 1fr)); }
}

/* ══════════════════════════ EL PLANO ══════════════════════════
   El salón como es: mesas colocadas donde están, con sus sillas alrededor.

   ⚠ El lienzo mide 1200×800 SIEMPRE y se escala con `transform`. Las posiciones se guardan en
   esas coordenadas, no en las de la pantalla: guardar píxeles de pantalla haría que el salón se
   desarmara al abrirlo en un monitor de otro tamaño. */

/* ⚠ `overflow: hidden` y NUNCA desplazamiento nativo. El plano se mueve con `transform` desde
   el JS, igual que el lienzo del flujo de WhatsApp: así no hay borde contra el que chocar —el
   movimiento es libre— ni barras que dibujar (Mario, 2026-09-26). La versión anterior usaba
   `overflow: auto` y quedaba acotada a la caja del lienzo. */
/* ── La tarjeta del salón llega hasta abajo ───────────────────────────────────────────────────
   El plano se mira entero de una vez, así que todo lo que quede debajo es alto que no se usa.
   Se van el margen inferior de la tarjeta (24 px) y el relleno bajo el plano (25 px); el pie lo
   quita `mesas.php`, como en el lienzo del flujo.

   ⚠ Por clase propia y NO tocando `.card`: esa la usan las 48 pantallas del sistema. Es el mismo
   criterio de `.flujo-full` y `.wa-pantalla`, de donde sale este patrón.

   ⚠ El relleno se quita en el `card-body` DEL PLANO y no en todos: la cabecera de zonas y la
   leyenda viven en su propio `card-body` y ahí el aire sí hace falta. */
/* ⚠ Un respiro, no el margen entero. A ras del borde la tarjeta queda pegada a la barra de
   tareas de la tablet y el mosaico del piso muere contra el filo (Mario, 2026-10-20). Son 12 px
   afuera y 8 adentro: se nota que la tarjeta termina, sin devolver los 49 que se habían
   recuperado.
   ⚠ No hay ninguna cuenta de alto que ajustar con esto: `medirMarco()` mide el margen y el
   relleno reales en vez de suponerlos, así que cambiar estos dos números reajusta el plano solo. */
.ms-tarjeta-plano { margin-bottom: .75rem; }
.ms-tarjeta-plano > #msSalon { padding-bottom: .5rem; }

.pl-marco {
    position: relative;
    overflow: hidden;
    border-radius: var(--ins-border-radius, .375rem);
    background: var(--ins-tertiary-bg, #f4f4f4);

    /* La cuadrícula, atada a la cámara: se acerca, se aleja y se desplaza con el plano. Sin eso,
       al alejar parecía papel milimetrado y al arrastrar se quedaba quieta debajo de las mesas. */
    background-image:
        linear-gradient(to right, rgba(0,0,0,.05) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(0,0,0,.05) 1px, transparent 1px);
    background-size: var(--rejilla, 20px) var(--rejilla, 20px);
    background-position: var(--piso-pos, 0 0);
}

/* Con foto de piso, la cuadrícula sobra: serían dos pisos encimados. */
.pl-marco.pl-con-foto { background-image: none; }

/* ── El piso INFINITO ─────────────────────────────────────────────────────────────────────────
   En mosaico el piso se pinta acá, en el MARCO, y no en el lienzo: pegado al lienzo terminaba
   donde terminaba el lienzo y dejaba una franja muerta en cuanto uno se alejaba o se movía. En el
   marco se repite hasta donde alcance la vista, y el tamaño y el origen los pone la cámara.

   ⚠ En una capa propia por la opacidad: aplicada al elemento se llevaría también las mesas. */
.pl-marco.pl-mosaico::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: var(--piso-marco, none);
    background-repeat: repeat;
    background-size: var(--piso-marco-tam, auto);
    background-position: var(--piso-pos, 0 0);
    opacity: var(--piso-opacidad, 1);
    pointer-events: none;
}

/* El lienzo va por encima del piso del marco. */
.pl-lienzo { z-index: 1; }

/* ⚠ `absolute` y no `relative`: la cámara lo mueve con `transform`, que NO cambia la caja de
   maquetación, y en flujo normal el lienzo empujaba el alto del marco.
   ⚠ Ojo: esto NO elimina el área desplazable del marco —un hijo absoluto sigue contando para el
   contenedor posicionado, y en el teléfono `scrollWidth` supera a `clientWidth`—. Es inerte
   porque el marco es `overflow: hidden` y nada lo desplaza: todo el movimiento pasa por la
   cámara. Anotado para que nadie lea de más en este `absolute`. */
.pl-lienzo {
    position: absolute;
    top: 0;
    left: 0;
    width: 1200px;
    height: 800px;
    transform-origin: top left;
}

/* ── El piso ──────────────────────────────────────────────────────────────────────────────────
   La foto que se subió, en una CAPA propia debajo de las mesas.

   ⚠ Va en un `::before` y no en el fondo del lienzo porque la opacidad tiene que afectar solo a
   la imagen: aplicada al elemento se llevaría también las mesas y las sillas.

   ⚠ Y por eso las mesas necesitan `z-index`: sin él, una capa posicionada creada DESPUÉS en el
   orden de pintado taparía a hermanos sin apilamiento propio. */
.pl-lienzo::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: var(--piso, none);
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    opacity: var(--piso-opacidad, 1);
    pointer-events: none;
}

.pl-lienzo[data-ajuste="contener"]::before { background-size: contain; }

/* ⚠ En mosaico el tamaño lo decide Mario: `--piso-tam` es el ANCHO de cada repetición en píxeles
   del lienzo, y el alto va en proporción. `auto` = el tamaño natural del archivo. */
.pl-lienzo[data-ajuste="mosaico"]::before {
    background-size: var(--piso-tam, auto);
    background-repeat: repeat;
}

.pl-mesa {
    z-index: 1;
    /* La rotación va desde el CENTRO: desde la esquina, girar también mueve la mesa de sitio. */
    transform-origin: center center;
}

/* ── La mesa ─────────────────────────────────────────────────────────────────────────────────
   Es un bloque posicionado: adentro van el tablero y las sillas. El tamaño lo decide la forma y
   la capacidad — una mesa de 12 no puede dibujarse igual que una de 2. */
.pl-mesa {
    position: absolute;
    display: grid;
    place-items: center;
    cursor: pointer;
    /* El arrastre lo maneja el puntero; sin esto, en el teléfono se lo lleva el scroll. */
    touch-action: none;
}

.pl-tablero {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    gap: 1px;
    padding: .35rem .5rem;
    width: 100%;
    height: 100%;
    overflow: hidden;

    /* ── El cuerpo ────────────────────────────────────────────────────────────────────────────
       El color lo pone el JS en `--mesa-color` (el elegido, o el del tema si no hay ninguno).
       Encima va un degradado claro arriba y oscuro abajo: ESE es el brillo de la referencia —una
       luz que cae desde arriba—, y es lo que hace que la mesa se vea como un objeto y no como un
       rectángulo de color. */
    background:
        linear-gradient(to bottom,
            rgba(255, 255, 255, .35) 0%,
            rgba(255, 255, 255, .08) 45%,
            rgba(0, 0, 0, .06) 100%),
        var(--mesa-color, var(--ins-secondary-bg, #fff));

    border: 0;
    /* ⚠ Proporcional y no fijo: con 12 px una mesa chica se veía casi cuadrada y una barra
       larga, con las puntas afiladas. El 15 % es lo medido en la referencia que pasó Mario —sus
       cuadradas redondean como una quinta parte del lado—; con el 22 % del primer intento se
       veían infladas. */
    border-radius: clamp(8px, 15%, 20px);

    /* Sombra propia + un halo del mismo color: es lo que despega la mesa del piso. */
    box-shadow:
        0 2px 4px rgba(0, 0, 0, .18),
        0 6px 16px var(--mesa-halo, rgba(0, 0, 0, .12));

    /* El texto lo decide el JS según lo claro que sea el color: sobre amarillo, negro. */
    color: var(--mesa-texto, #212529);
}

/* El destello: una franja clara arriba, como la luz sobre una superficie pulida. */
.pl-tablero::after {
    content: '';
    position: absolute;
    top: 0;
    left: 6%;
    right: 6%;
    height: 32%;
    border-radius: 0 0 50% 50% / 0 0 100% 100%;
    background: linear-gradient(to bottom, rgba(255, 255, 255, .45), rgba(255, 255, 255, 0));
    pointer-events: none;
}

.pl-mesa.redonda .pl-tablero { border-radius: 50%; }
.pl-mesa.tipo-barra:not(.redonda) .pl-tablero { border-radius: 8px; }

/* ⚠ La barra CURVA es medio disco y no un círculo: el lado plano —el de abajo— es la pared o el
   lado de quien atiende, y ahí no se sienta nadie. Dibujada redonda entera se leía como una mesa
   a la que le faltan las sillas de abajo. */
.pl-mesa.tipo-barra.redonda .pl-tablero {
    border-radius: 50% 50% 4px 4px / 100% 100% 4px 4px;
    /* El texto baja hacia el lado plano: arriba el medio disco es un filo y no cabe nada. */
    justify-content: flex-end;
    padding-bottom: 4px;
}

/* ── El estado ES el color ────────────────────────────────────────────────────────────────────
   Decisión de Mario (2026-09-25). Antes el cuerpo llevaba un color elegido a mano y el estado iba
   en un anillo: una mesa pintada de verde con gente sentada parecía libre desde el otro lado del
   salón, que es justo lo que un plano viene a evitar. Ahora el cuerpo dice el estado y no hay
   color propio — el selector se quitó y la columna se soltó.

   ⚠ Van en ORDEN DE URGENCIA y con esa lógica se eligieron los colores: rojo lo que hay que
   atender ya, ámbar lo que espera, verde lo que está en orden, morado la tarea de limpieza,
   celeste lo comprometido y blanco lo que se puede dar.

   ⚠ El texto va OSCURO sobre los cinco colores del tema y blanco solo sobre el morado, y eso está
   MEDIDO, no elegido a ojo: el nombre de la mesa son 13 px en negrita, o sea texto normal para el
   contraste, que pide 4,5:1. Con blanco encima, los colores del tema dan 3,36 (rojo), 2,41
   (verde), 2,14 (celeste) y 1,76 (ámbar) — ilegibles. Con texto oscuro los mismos colores dan
   4,6 · 6,4 · 7,22 · 8,75. El morado es al revés: 3,19 oscuro contra 4,83 en blanco. */
.pl-mesa {
    --mesa-color: #fff;
    --mesa-texto: #495057;
    --mesa-halo: rgba(0, 0, 0, .12);
}

/* Se sentaron y nadie ha ido: es el único que tiene que verse desde la puerta. */
.pl-mesa.sin_atender {
    --mesa-color: var(--ins-danger);
    --mesa-texto: #212529;
    --mesa-halo: rgba(var(--ins-danger-rgb), .45);
}

/* Piden la cuenta: la mesa está por desocuparse y alguien espera. */
.pl-mesa.pedida {
    --mesa-color: var(--ins-warning);
    --mesa-texto: #212529;
    --mesa-halo: rgba(var(--ins-warning-rgb), .45);
}

/* Ya tiene lo suyo: todo en orden. */
.pl-mesa.atendida {
    --mesa-color: var(--ins-success);
    --mesa-texto: #212529;
    --mesa-halo: rgba(var(--ins-success-rgb), .45);
}

/* Se fueron y quedó servida: no se le puede dar a nadie hasta que alguien la recoja.

   ⚠ `--ins-purple` NO existe en el tema desplegado —está en otras pieles del Ubold, no en la
   activa: medido en vivo devuelve vacío—, y sin respaldo la mesa salía BLANCA con texto blanco.
   El respaldo es el mismo morado que ya usa el sistema para el producto simple y para la IA, en
   `personalizados.css`. */
.pl-mesa.por_limpiar {
    --mesa-color: var(--ins-purple, #7e5fc7);
    --mesa-texto: #fff;
    --mesa-halo: rgba(var(--ins-purple-rgb, 126, 95, 199), .45);
}

/* Libre, pero comprometida. */
.pl-mesa.reservada {
    --mesa-color: var(--ins-info);
    --mesa-texto: #212529;
    --mesa-halo: rgba(var(--ins-info-rgb), .45);
}

/* ⚠ La desocupada va en blanco y necesita borde propio: sobre el piso claro, sin él se pierde. */
.pl-mesa.desocupada .pl-tablero {
    border: 1px solid var(--ins-border-color, #dee2e6);
}

/* ── Dividir la cuenta: las cuentas en columnas ───────────────────────────────────────────────
   ⚠ En COLUMNAS y no en pestañas: el gesto es comparar dos listas y pasar cosas de una a otra, y
   con pestañas hay que recordar lo que hay del otro lado. Con más de dos personas son más
   columnas y la fila se desplaza en horizontal —eso sí es mejor que apilarlas—. */
/* ⚠ **GRID y no flex con scroll** (Mario, 2026-10-04: «no debería hacer scroll sino colocar las
   fichas dentro de la ventana disponible»). Con `flex: 1 0 240px` las columnas no se encogían:
   con cuatro cuentas pedían 996 px dentro de 752 y aparecía una barra horizontal que dejaba la
   primera columna cortada por la mitad.

   `auto-fit` + `minmax` reparte el ancho en partes iguales y **solo baja a otra fila cuando ya no
   caben**.

   ⚠ **El mínimo es UN TERCIO, no una medida en píxeles** (Mario, 2026-10-04: «máximo 3 por fila:
   col-4»). Con `170px` entraban cuatro y los nombres quedaban recortados a «Camis…»; con un
   tercio, la cuarta nunca cabe y baja sola. Puesto en porcentaje y no en píxeles para que valga
   igual en la ventana de 800 px y en una pantalla angosta, sin un número que recalcular.
   El `- 0.5rem` descuenta la parte de los dos huecos que le toca a cada columna.

   Queda: 2 cuentas → una fila de dos mitades · 3 → una fila de tercios · 4 → tres arriba y una
   abajo, del mismo ancho que las demás (no estirada, porque el track sigue siendo de un tercio).

   ⚠ `align-items: start` para que una columna con un artículo no se estire al alto de la que
   tiene seis: en grid, por omisión, todas se igualan a la más alta. */
.md-columnas {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(calc(33.333% - 0.5rem), 1fr));
    gap: .75rem;
    align-items: start;
}

/* ⚠ Cada cuenta lleva SU tono, y de ahí cuelga todo lo suyo (`--md-color`). No es decoración:
   el gesto de esta pantalla es mover artículos de una columna a otra, y como el color se hereda
   del contenedor, al soltar una ficha del otro lado **cambia de color sola**. Eso es lo que
   confirma que el artículo cambió de dueño, que es justo lo que uno quiere ver al arrastrar.

   ⚠ Los tonos salen de las variables CRUDAS del tema (`--ins-blue`, `--ins-cyan`…), NO de las
   semánticas: `--ins-primary` y `--ins-info` están definidas varias veces en el `app.min.css`
   desplegado —cambian con la piel— y además significan algo. Un tono crudo es solo un tono.
   Se salta el rojo a propósito: en este módulo ya quiere decir «cancelado». */
.md-cuenta {
    /* ⚠ `min-width: 0` y NO los 240 px de antes: en grid, un mínimo propio le gana al `minmax()`
       del contenedor y vuelve a forzar el desbordamiento que se vino a quitar. */
    min-width: 0;
    border: 1px solid var(--ins-border-color);
    border-radius: var(--ins-border-radius, .375rem);
    display: flex;
    flex-direction: column;
    --md-color: var(--ins-indigo, #6b5eae);
}

.md-cuenta:nth-child(6n + 2) { --md-color: var(--ins-cyan,   #43bfe5); }
.md-cuenta:nth-child(6n + 3) { --md-color: var(--ins-green,  #0acf97); }
.md-cuenta:nth-child(6n + 4) { --md-color: var(--ins-orange, #fd7e14); }
.md-cuenta:nth-child(6n + 5) { --md-color: var(--ins-pink,   #f672a7); }
.md-cuenta:nth-child(6n)     { --md-color: var(--ins-blue,   #4a81d4); }

.md-cuenta-cabeza {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: .5rem;
    padding: .45rem .6rem;
    border-bottom: 2px solid var(--md-color);
    /* El tono, pero lavado: la cabecera identifica la columna, no compite con los artículos. */
    background: color-mix(in srgb, var(--md-color) 12%, transparent);
}

/* ⚠ Alto mínimo aunque esté vacía: una columna sin artículos se encogería a nada y no quedaría
   dónde soltar, que es justo lo que hay que hacer con ella. */
.md-lineas {
    min-height: 120px;
    padding: .35rem;
    flex: 1 1 auto;
}

/* ⚠ Una sola línea cuando la cantidad es 1, que es el caso normal. Antes iba siempre en dos, y
   la segunda decía «1 × ₡1 681,42» al lado de un total que decía «₡1 681,42»: el mismo número
   escrito dos veces ocupando el doble de alto. La segunda línea vuelve sola en cuanto hay más de
   uno, que es cuando el precio unitario sí agrega algo. */
.md-linea {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .3rem .45rem;
    border: 1px solid var(--ins-border-color);
    border-left: 3px solid var(--md-color);
    border-radius: var(--ins-border-radius, .375rem);
    background: var(--ins-secondary-bg, #fff);
    margin-bottom: .25rem;
    cursor: grab;
    font-size: .78rem;
    line-height: 1.25;
}

.md-linea:active { cursor: grabbing; }

/* La cantidad al frente, como en el tablero de cocina: da un riel izquierdo parejo y deja de
   competir con la descripción por el mismo renglón. */
.md-cant {
    flex-shrink: 0;
    min-width: 1.35rem;
    padding: 0 .25rem;
    border-radius: var(--ins-border-radius, .375rem);
    background: color-mix(in srgb, var(--md-color) 18%, transparent);
    color: color-mix(in srgb, var(--md-color) 75%, #000);
    font-weight: 700;
    font-size: .72rem;
    text-align: center;
}

/* ⚠ El precio NO se encoge y NO se parte. Es el dato predecible de la ficha; la descripción es
   la impredecible, y es la que tiene que ceder (ya trae `text-truncate` + `min-w-0`). Sin esto
   los dos se repartían el ancho: en la columna de descripciones largas el monto salía cortado a
   media cifra —«₡3 451,3»—, que es peor que no mostrarlo. */
.md-precio {
    flex-shrink: 0;
    white-space: nowrap;
    font-weight: 600;
}

/* El botón de partir solo estorba hasta que hace falta: chico y sin fondo. */
.md-linea .btn { --ins-btn-padding-y: .1rem; --ins-btn-padding-x: .3rem; }

.md-fantasma { opacity: .4; }

/* ── El globo que sigue al puntero ────────────────────────────────────────────────────────────
   Quién está en la mesa y desde cuándo. Vive fuera del dibujo para que el número quede centrado.

   ⚠ `pointer-events: none` NO es un detalle de estilo: es lo que impide que el globo —que va
   pegado al puntero— se coma el clic sobre la mesa que hay debajo. Sin eso, acercarse a una mesa
   la volvería inalcanzable.

   ⚠ Y `position: fixed` porque se coloca con las coordenadas del PUNTERO, que son de la ventana:
   dentro de un contenedor desplazado, `absolute` lo pondría corrido justo esa cantidad. */
.pl-globo {
    position: fixed;
    z-index: 1080;                 /* por encima del plano y de las pestañas, debajo de modales */
    pointer-events: none;
    max-width: 260px;
    padding: .5rem .65rem;
    border-radius: var(--ins-border-radius, .375rem);
    border-left: 3px solid var(--globo-color, var(--ins-secondary-color));
    background: rgba(33, 37, 41, .94);
    color: #fff;
    font-size: .75rem;
    line-height: 1.35;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .28);
}

.pl-globo[hidden] { display: none; }

.pl-globo-nombre { font-weight: 700; margin-bottom: .1rem; }
.pl-globo-quien  { opacity: .95; }
.pl-globo-estado { opacity: .85; }

/* El punto del estado, del mismo color que la mesa: el globo y el plano dicen lo mismo. */
.pl-globo-punto {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: .3rem;
    border-radius: 50%;
    background: var(--globo-color, currentColor);
}

/* ── El círculo del centro ────────────────────────────────────────────────────────────────────
   El número de la mesa dentro de un círculo del mismo color en un tono más fuerte (referencia de
   Mario, 2026-09-25). Es lo que se busca de lejos: el nombre completo vive en el título y en el
   rótulo accesible.

   ⚠ El tamaño lo calcula el JS y llega en `--mesa-nucleo-tam`, porque depende de la mesa: uno
   fijo se ve diminuto en una barra de 300 px y tapa entera una mesa de dos. */
.pl-nucleo {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: var(--mesa-nucleo-tam, 46px);
    height: var(--mesa-nucleo-tam, 46px);
    border-radius: 50%;
    background: var(--mesa-fuerte, rgba(0, 0, 0, .15));
    /* ⚠ El texto se decide por luminancia igual que el de la mesa: sobre un círculo claro
       —el de una mesa desocupada, que es blanca— el blanco no se lee. */
    color: var(--mesa-fuerte-texto, #fff);
    font-weight: 700;
    font-size: calc(var(--mesa-nucleo-tam, 46px) * .42);
    line-height: 1;
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, .15);
}

.pl-nombre { font-weight: 700; font-size: .82rem; line-height: 1.1; }

.pl-quien {
    font-size: .68rem;
    line-height: 1.1;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    opacity: .85;
}

/* ⚠ En una línea y recortado con puntos suspensivos: partido en dos renglones se salía por la
   curva de una mesa redonda —medido: 84 px de texto en una caja de 95—. */
.pl-estado {
    font-size: .64rem;
    line-height: 1.1;
    opacity: .85;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ⚠ La mesa redonda necesita aire a los lados: su ancho útil a la altura del texto es la cuerda,
   no el diámetro, y sin esto el renglón toca el borde curvo. */
.pl-mesa.redonda .pl-tablero { padding-left: 14%; padding-right: 14%; }

/* ── Las sillas ───────────────────────────────────────────────────────────────────────────────
   Del mismo color que la mesa y pegadas a ella, como en la referencia: se leen como parte del
   mueble y no como puntos sueltos. */
/* ⚠ Las sillas van del TONO FUERTE, el mismo del círculo del centro, y pegadas al tablero —así
   es la referencia que pasó Mario—. Antes eran el color de la mesa apenas oscurecido y separadas
   10 px: la mesa parecía flotar entre piezas sueltas. */
.pl-silla {
    position: absolute;
    background: var(--mesa-fuerte, var(--ins-secondary-color, #adb5bd));
    border-radius: 3px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
}

/* ⚠ Anchas y con poca esquina: en la referencia la silla es un taco, no una rayita ni una
   pastilla. Medido sobre su dibujo, ocupa cerca de un tercio del lado de la mesa —150 px de mesa
   con sillas de 50—, y acá quedó en 34. */
.pl-silla.h { width: 34px; height: 14px; }
.pl-silla.v { width: 14px; height: 34px; }

/* ⚠ La banqueta de una barra curva: redonda, y por eso se ve igual en cualquier punto del arco.
   El taco rectangular solo cae derecho en las cuatro posiciones cardinales; en las de en medio
   apunta a cualquier lado y la barra se ve desordenada (Mario, 2026-09-27).
   Algo más chica que el taco a propósito: una banqueta ocupa menos que una silla con respaldo,
   pero no tanto como para perderse. Arrancó en 18 px y Mario la pidió un poco más grande. */
.pl-silla.redonda {
    width: 22px;
    height: 22px;
    border-radius: 50%;
}

/* ── Modo acomodar ───────────────────────────────────────────────────────────────────────────
   Se ve distinto a propósito: mientras está puesto, tocar una mesa la mueve en vez de abrirla, y
   eso tiene que ser evidente antes del primer toque. */
.pl-lienzo.acomodando .pl-mesa { cursor: move; }
.pl-lienzo.acomodando .pl-tablero { border-style: dashed; border-color: var(--ins-primary); }
.pl-mesa.moviendo { z-index: 10; }
.pl-mesa.moviendo .pl-tablero { box-shadow: 0 8px 20px rgba(0, 0, 0, .25); }

/* ── «Tu mesa está lista» ───────────────────────────────────────────────────────────────────
   La campana que aparece sobre una mesa cuando su comanda terminó en la cocina (2026-09-26).

   ⚠ No reemplaza la franja de estado: una mesa con comida lista sigue estando ocupada, y pisar
     su color haría que el salón mintiera sobre lo único que promete. Esto se SUMA. */

.pl-aviso-lista {
    position: absolute;
    top: -10px;
    right: -10px;
    z-index: 3;

    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;

    border-radius: 50%;
    background: var(--ins-success, #22c55e);
    color: #fff;
    font-size: 15px;
    /* El halo blanco la despega de la mesa sea cual sea su color de estado. */
    box-shadow: 0 0 0 2px #fff, 0 2px 6px rgba(0, 0, 0, .3);

    /* ⚠ Contra-escala: el lienzo entero va dentro de un `scale()`, así que sin esto la campana
       se encoge con el plano —12 px al 45 %, 8 px en el teléfono— y deja de ser un aviso. El
       número de la mesa hace lo mismo con la rotación, por la misma razón. */
    transform: scale(var(--pl-inversa, 1));
    transform-origin: center;

    animation: pl-lista-late 1.6s ease-in-out infinite;
    pointer-events: none;
}

@keyframes pl-lista-late {
    0%, 100% { transform: scale(var(--pl-inversa, 1)); }
    50%      { transform: scale(calc(var(--pl-inversa, 1) * 1.15)); }
}

/* ⚠ Quien pidió menos movimiento no lo pierde de vista: se queda la campana, se va el latido.
   Un aviso que solo existe mientras parpadea es un aviso que algunas personas no reciben. */
@media (prefers-reduced-motion: reduce) {
    .pl-aviso-lista { animation: none; }
}

/* El contador sobre el botón de cocina: cuántos platos quedan sin mandar (2026-09-26).
   ⚠ Va con número y no solo con color: «ámbar» dice que falta algo, el número dice cuánto, y el
     color solo no le sirve a quien no lo distingue. */
.ms-cocina-cuenta {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--ins-danger, #ef5f5f);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

/* Mover el lienzo arrastrando el fondo (2026-09-26).
   ⚠ Acomodando el marco se puede desplazar, y el gesto es arrastrar el fondo en vez de buscar la
     barra sin soltar la mesa. Sirve donde el plano NO cabe entero —el teléfono, o un salón más
     ancho que la pantalla—; donde cabe, no hay nada que mover y está bien que así sea. */
/* ⚠ `touch-action: none` sobre el plano: sin esto el navegador se queda con el pellizco —hace
   zoom de la PÁGINA entera— y con el arrastre de un dedo, y el gesto nunca llega al lienzo. Es
   la misma renuncia que hace cualquier mapa: dentro del plano los dedos son del plano. La página
   se sigue desplazando desde fuera del marco. */
.pl-marco { touch-action: none; }

/* ⚠ La mano SOLO en modo acomodar: es el único donde el plano se mueve (Mario, 2026-09-27), y un
   cursor que promete arrastre donde no lo hay es peor que no ponerlo. */
.pl-marco.pl-editando { cursor: grab; }
.pl-marco.pl-agarrando { cursor: grabbing; user-select: none; }

/* ⚠ La barra del lienzo y el minimapa NO se estilan acá: usan las clases de LogicFlow
   (`lf-control`, `lf-mini-map`) y su definición vive UNA sola vez en `personalizados.css`,
   compartida con la pantalla del flujo. Acá solo queda el contenedor del que cuelgan.

   ⚠ Cuelgan de `.pl-zona` y NO de `.pl-marco`: el marco es el contenedor de la cámara, y un hijo
     suyo posicionado se iría con el plano al arrastrarlo. */
.pl-zona { position: relative; }



/* Mover el lienzo arrastrando el fondo (2026-09-26).
   ⚠ Acomodando el marco se puede desplazar, y el gesto es arrastrar el fondo en vez de buscar la
     barra sin soltar la mesa. Sirve donde el plano NO cabe entero —el teléfono, o un salón más
     ancho que la pantalla—; donde cabe, no hay nada que mover y está bien que así sea. */

/* Mover el lienzo arrastrando el fondo (2026-09-26).
   ⚠ Acomodando el marco se puede desplazar, y el gesto es arrastrar el fondo en vez de buscar la
     barra sin soltar la mesa. Sirve donde el plano NO cabe entero —el teléfono, o un salón más
     ancho que la pantalla—; donde cabe, no hay nada que mover y está bien que así sea. */

/* Las cuentas dentro del globo, con nombre (2026-09-26).
   ⚠ Existe porque el globo mostraba una sola cuenta —la primera— y le pegaba el estado de la
     MESA al lado, atribuyéndole a alguien lo que había hecho otro. */
.pl-globo-cuentas {
    list-style: none;
    margin: 2px 0 0;
    padding: 0;
}
.pl-globo-cuentas li {
    padding-left: 10px;
    position: relative;
    opacity: .85;
}
.pl-globo-cuentas li::before {
    content: '·';
    position: absolute;
    left: 2px;
}
/* La que pidió va destacada: es la única que pide una acción. */
.pl-globo-cuentas li.pidio {
    color: var(--ins-warning, #f9c851);
    opacity: 1;
}

/* Una nota de cocina tachada, dentro de la ventana de envío (2026-09-27).
   ⚠ La clase envuelve SOLO el texto. Sobre el contenedor, `text-decoration` se propaga a los
     hijos y no se puede quitar desde adentro: la hora salía tachada, y la hora es lo que EXPLICA
     el tachado, no parte de lo que se retiró. */
.ms-nota-anulada {
    text-decoration: line-through;
    text-decoration-thickness: 2px;
}

/* ── El nombre de la cuenta se edita en su propia línea ───────────────────────────────────────
   ⚠ Sin adornos permanentes: la lista se LEE mucho más de lo que se edita, y un campo dibujado
   en cada fila la convierte en un formulario. La pista aparece al pasar por encima. */
.ms-cuenta-nombre {
    cursor: text;
    padding: 0 .25rem;
    margin-left: -.25rem;
    border-radius: var(--ins-border-radius-sm, .25rem);
}

/* ⚠ Solo con puntero fino: en una pantalla táctil el `:hover` se queda pegado tras el toque y la
   fila parece seleccionada para siempre. */
@media (hover: hover) and (pointer: fine) {
    .ms-cuenta-nombre:hover {
        background-color: var(--ins-tertiary-bg);
    }
}

/* ⚠ El `text-truncate` del span recorta también al campo: mientras se edita hay que soltarlo, o
   el nombre largo se escribe a ciegas sobre una caja de 60 px. */
.ms-cuenta-nombre:has(input) {
    overflow: visible;
    padding: 0;
    margin-left: 0;
}

.ms-cuenta-nombre input {
    width: 100%;
}

/* ══════════════════════════ LA DECORACIÓN DEL PLANO ══════════════════════════
   Plantas, jardineras y setos (2026-10-08). Y mañana sillones y separadores.

   ⚠ Comparte la clase `.pl-mesa` A PROPÓSITO, no por pereza: de ella salen el posicionamiento
     absoluto, el `transform-origin: center` del giro y el `touch-action: none` del arrastre, y
     sobre todo es el selector con el que el plano ya sabe arrastrar, encuadrar y dibujar el
     mapa. Con una clase propia habría que repetir esas cinco cosas y acordarse de las cinco
     cada vez que una cambie. Lo que NO comparte —el tablero, las sillas, el color del estado—
     no cuelga de `.pl-mesa` sino de `.pl-tablero`, que la decoración no tiene.

   ⚠ El dibujo va de FONDO y no en un `<img>`: una imagen de verdad trae el arrastre nativo del
     navegador, que pelea con el de punteros del plano —se lleva el fantasma translúcido y suelta
     la planta donde no es—. */
.pl-deco {
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    /* ⚠ Debajo de las mesas: lo que se atiende se toca, y una palmera no tiene que poder taparle
       el número a la mesa 7. `.pl-mesa` es `z-index: 1`. */
    z-index: 0;
    /* Fuera del modo acomodar no hace nada: el cursor no debe prometer que sí. */
    cursor: default;
}

/* Acomodando se nota que se puede tomar. ⚠ El CURSOR no se toca acá: `.pl-lienzo.acomodando
   .pl-mesa` ya lo pone en `move` y gana por especificidad —medido—, así que un `grab` propio
   sería una línea que no hace nada y que el próximo que lea el archivo creería cierta. El
   contorno sí hace falta: una planta no tiene borde propio y sin él no se ve cuál se va a
   tomar. */
.acomodando .pl-deco:hover { outline: 2px dashed var(--ins-primary); outline-offset: 3px; }
.pl-deco.moviendo { opacity: .85; }

/* ── Las muestras del catálogo, en el panel de administración ──────────────────────────────
   ⚠ Rejilla que se acomoda sola (`auto-fill`) y no un número fijo de columnas: el panel mide
     560 px en escritorio y el ancho de la pantalla en el teléfono. */
.ma-deco-rejilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: .5rem;
}

.ma-deco {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .25rem;
    padding: .4rem .25rem;
    border: var(--ins-border-width) solid var(--ins-border-color);
    border-radius: .375rem;
    background: var(--ins-secondary-bg);
    cursor: pointer;
    transition: border-color .15s, transform .15s;
}

.ma-deco:hover { border-color: var(--ins-primary); transform: translateY(-2px); }
.ma-deco:disabled { opacity: .5; cursor: progress; transform: none; }

/* ⚠ `contain` y no `cover`: recortar una jardinera larga para llenar un cuadro deja ver un
   pedazo de tierra que no se parece a nada. */
.ma-deco img { width: 100%; height: 56px; object-fit: contain; }

.ma-deco span {
    font-size: .7rem;
    line-height: 1.1;
    text-align: center;
    color: var(--ins-secondary-color);
    /* ⚠ Dos renglones SIEMPRE: «Árbol» ocupa uno y «Árbol de tres copas» dos, y con alto
       automático las fichas de una misma fila quedaban de alturas distintas y la rejilla se
       veía descuadrada. */
    min-height: 2.2em;
}

/* ⚠ Con la cuarta pestaña («Decoración»), `nav-justified` ya no reparte bien en el teléfono:
   medido a 390 px, entraban tres arriba y «Apariencia» quedaba sola en una segunda fila,
   centrada y sin alinearse con ninguna. Dos por dos se lee como una rejilla y no como un
   sobrante. */
@media (max-width: 575.98px) {
    #maTabs .nav-item { flex: 0 0 50%; max-width: 50%; }
}

/* ── Lo que se va a quitar, marcado antes de preguntar ─────────────────────────────────────
   Pedido de Mario (2026-10-08). La lista del panel dice «Palmera 3» y en el plano hay cinco
   palmeras iguales: el resalte es lo que contesta «cuál».

   ⚠ `z-index` alto: la marca tiene que verse POR ENCIMA de las mesas vecinas, y una decoración
     vive en la capa 0 —debajo de todo— justo para no taparlas. Mientras está señalada, manda.

   ⚠ Con `outline` y no con `border`: el borde cambiaría el tamaño del elemento y la mesa se
     movería un par de píxeles al preguntar, que se lee como que ya pasó algo. */
.pl-por-borrar {
    outline: 3px solid var(--ins-danger);
    outline-offset: 4px;
    border-radius: 4px;
    z-index: 3;
    animation: pl-latido 1s ease-in-out infinite;
}

@keyframes pl-latido {
    50% { outline-color: color-mix(in srgb, var(--ins-danger) 35%, transparent); }
}

/* ⚠ Sin latido para quien pidió menos movimiento: es una marca, no un aviso que haya que
   perseguir, y el contorno rojo ya la distingue sin parpadear. */
@media (prefers-reduced-motion: reduce) {
    .pl-por-borrar { animation: none; }
}

/* El diálogo de «¿quitar esto?» NO desenfoca el plano: el resalte que lo contesta está detrás.
   Ver el comentario largo de `personalizados.css` sobre por qué las confirmaciones sí lo llevan
   en el resto del sistema — esta es la excepción, y por eso es una clase que se pide a mano. */
.swal2-container.pl-confirmar-nitido {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* ── Señalado desde la lista: «este es» ────────────────────────────────────────────────────
   Pedido de Mario (2026-10-08): la miniatura marca, y recién después se borra.

   ⚠ AZUL, y el de borrar es rojo. Son dos cosas distintas —mirar y estar a un clic de
     perderlo— y con el mismo color señalar para identificar daría un susto cada vez. */
.pl-senalado {
    outline: 3px solid var(--ins-primary);
    outline-offset: 4px;
    border-radius: 4px;
    z-index: 3;
    /* ⚠ Un halo además del contorno. Medido en el plano del salón: sobre un piso oscuro y entre
       plantas verdes, tres píxeles de línea se pierden — y el trabajo de esta marca es que NO
       haya que buscarla. El halo la despega del fondo sin taparla. */
    box-shadow: 0 0 0 7px color-mix(in srgb, var(--ins-primary) 22%, transparent);
}

/* Un destello al aparecer y nada más: la marca se queda puesta, así que una animación eterna
   sería un elemento del salón parpadeando sin motivo mientras se hace otra cosa. */
.pl-senalado { animation: pl-aparece .9s ease-out 1; }

@keyframes pl-aparece {
    0%   { outline-width: 14px; outline-color: color-mix(in srgb, var(--ins-primary) 25%, transparent); }
    100% { outline-width: 3px; }
}

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

/* ── El botón que señala: la miniatura de la fila ──────────────────────────────────────────
   ⚠ Es un `<button>` de verdad y no un `<img>` con `onclick`: se llega con el tabulador, se
     activa con Enter y el lector de pantalla lee «Ver "Palmera 3" en el plano». */
.ma-lupa {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: var(--ins-border-width) solid transparent;
    border-radius: .375rem;
    background: transparent;
    color: var(--ins-secondary-color);
    cursor: pointer;
    transition: border-color .15s, background-color .15s;
}

.ma-lupa:hover,
.ma-lupa:focus-visible { border-color: var(--ins-primary); background: var(--ins-tertiary-bg); }

/* ── «Hay algo listo para levantar» ───────────────────────────────────────────────────────
   ⚠ Pedido de Mario (2026-10-08): la campana tiene que distinguirse. Antes compartía el verde
     sólido con «todo en orden» y, en una lista de cinco cuentas, los botones se veían todos
     iguales: la diferencia era el ícono, que en un `btn-sm` no se lee a un metro.

   ⚠ Late, y por eso late: en esa lista el estado no se BUSCA, se encuentra de reojo mientras
     se hace otra cosa. Un verde quieto entre otros verdes no se encuentra. Es el único
     movimiento de la pantalla; los demás estados están quietos a propósito. */
@keyframes ms-cocina-late {
    0%, 100% { box-shadow: 0 0 0 0 rgba(47, 199, 112, .55); }
    70%      { box-shadow: 0 0 0 8px rgba(47, 199, 112, 0); }
}

.ms-cocina-lista {
    animation: ms-cocina-late 1.8s ease-out infinite;
}

/* La campanita se inclina, como una campana de verdad. */
@keyframes ms-cocina-tilde {
    0%, 60%, 100% { transform: rotate(0); }
    65%, 75%, 85% { transform: rotate(-12deg); }
    70%, 80%, 90% { transform: rotate(12deg); }
}

.ms-cocina-lista i { display: inline-block; animation: ms-cocina-tilde 1.8s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
    .ms-cocina-lista,
    .ms-cocina-lista i { animation: none; }
}

/* ── La cantidad en la ventana de «Enviar a cocina» ────────────────────────────────────────
   ⚠ Es EL dato de la fila: lo que se va a cocinar. Estaba como un `badge` chico del mismo
     tamaño que el texto de al lado, y con un «9» y un «3» en gris violáceo había que buscarlos
     (Mario, 2026-10-08). Mismo tratamiento que la cantidad en la pantalla de cocina: un cuadro
     propio con el número grande, que es como se lee una comanda. */
.mk-cant {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    min-width: 40px;
    height: 40px;
    padding: 0 8px;
    border-radius: 10px;
    background: var(--ins-primary);
    color: #fff;
    font-size: 20px;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* El ícono de actualizar gira mientras trae los datos: es lo único que distingue «lo pedí» de
   «no pasó nada» cuando la respuesta llega en 200 ms y nada cambia a la vista. */
@keyframes ms-girar { to { transform: rotate(360deg); } }
.ms-girando { display: inline-block; animation: ms-girar .8s linear infinite; }

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