/* ══════════════════════════════════════════════════════════════════════════════════════════════
   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. */
.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—. */
.md-columnas {
    display: flex;
    gap: .75rem;
    overflow-x: auto;
    padding-bottom: .25rem;
}

/* ⚠ 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 {
    flex: 1 0 240px;
    min-width: 240px;
    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;
}
