/* ============================================================
   RestoMind - Design System
   Mobile-first, pensado para gama media/baja: sin webfonts, sin
   backdrop-filter, sin animaciones costosas. Solo transform/opacity.
   ============================================================ */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}

/* Sin esto, algunos navegadores móviles esperan ~300ms antes de registrar
   un tap en botones/links, por si el usuario hace doble-tap para zoom.
   El toque se siente "lento" en mesas/botones sin esta línea. */
button, a {
    touch-action: manipulation;
}

:root {
    --bg: #F6F4F1;
    --surface: #FFFFFF;
    --surface-alt: #FFF0EA;
    --text: #1A1A1A;
    --text-muted: #6B7280;
    --border: #ECE7E1;
    --accent: #FF5A3C;
    --accent-dark: #E0431F;
    --accent-contrast: #FFFFFF;
    --success: #16A34A;
    --success-bg: #DCFCE7;
    --danger: #E23744;
    --danger-bg: #FDE7E8;
    --warning: #F59E0B;
    --warning-bg: #FEF3C7;
    --money: #0E7C7B;
    --radius-lg: 20px;
    --radius-md: 14px;
    --radius-sm: 10px;
    --shadow-sm: 0 1px 3px rgba(20, 20, 20, 0.07);
    --shadow-md: 0 6px 20px rgba(20, 20, 20, 0.10);
    --nav-height: 64px;
    --topbar-height: 52px;

    /* Gradientes 3D del ícono de mesa (mozo.js) y accents con relieve.
       Solo linear/radial-gradient — sin filter/blur, mismo costo de
       pintado que un color plano, apto para gama baja. */
    --mesa-top-a: #FFFFFF;
    --mesa-top-b: #E7E2DA;
    --mesa-top-c: #C7BFB2;
    --mesa-top-a-ocupada: #FFC1AC;
    --mesa-top-b-ocupada: #FF5A3C;
    --mesa-top-c-ocupada: #C43718;
    --silla-a: #AEB4BE;
    --silla-b: #7C8291;
    --silla-a-ocupada: #FF9478;
    --silla-b-ocupada: #D9451F;
    /* Tercer juego, solo para la Vista Unificada: "esperando la cuenta".
       El ícono tiene que distinguir TRES situaciones, no dos — "la comida
       está en cocina" y "hay plata sobre la mesa" se atienden distinto.
       Ámbar, el mismo del resto de los avisos de cobro de la app. */
    --mesa-top-a-cobrar: #FDE8B4;
    --mesa-top-b-cobrar: #F5A623;
    --mesa-top-c-cobrar: #B77400;
    --silla-a-cobrar: #F7C66B;
    --silla-b-cobrar: #C98A12;
    --accent-gradient: linear-gradient(135deg, #FF7A5C 0%, var(--accent) 55%, var(--accent-dark) 100%);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #121212;
        --surface: #1C1C1E;
        --surface-alt: #2A1D18;
        --text: #F2F2F2;
        --text-muted: #9CA3AF;
        --border: #2E2E30;
        --accent: #FF6B4E;
        --accent-dark: #FF8465;
        --success-bg: #0F2A1B;
        --danger-bg: #331417;
        --warning-bg: #332707;
        --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
        --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.5);

        --mesa-top-a: #3A3A3C;
        --mesa-top-b: #2A2A2C;
        --mesa-top-c: #1A1A1B;
        --mesa-top-a-ocupada: #FF9478;
        --mesa-top-b-ocupada: #FF6B4E;
        --mesa-top-c-ocupada: #8A2A12;
        --silla-a: #55565C;
        --silla-b: #3A3B40;
        --silla-a-ocupada: #FF9478;
        --silla-b-ocupada: #B3391A;
        --mesa-top-a-cobrar: #F7C66B;
        --mesa-top-b-cobrar: #D99500;
        --mesa-top-c-cobrar: #7A5200;
        --silla-a-cobrar: #D9A93F;
        --silla-b-cobrar: #8A6200;
        --accent-gradient: linear-gradient(135deg, #FF9478 0%, var(--accent) 55%, var(--accent-dark) 100%);
    }
}

html, body {
    height: 100%;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

.app-container {
    display: flex;
    flex-direction: column;
    /* 100vh MIENTE en un celular: incluye el alto de la barra de
       direcciones, que se retrae al hacer scroll. El contenedor queda más
       alto que la pantalla, así que el final del contenido y la barra de
       navegación de abajo quedan fuera de alcance — se ve como "esto no se
       arrastra", cuando en realidad ya no hay a dónde ir.
       100dvh es la altura DINÁMICA, la de verdad. Se deja 100vh primero
       como respaldo para navegadores que no la entienden. */
    height: 100vh;
    height: 100dvh;
    max-width: 560px;
    margin: 0 auto;
    background: var(--bg);
}

/* ============ LOGIN ============ */

.login-screen {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    min-height: 100dvh;  /* ver el comentario de .app-container */
    max-width: 560px;
    margin: 0 auto;
    padding: 24px;
}

.login-card {
    width: 100%;
    max-width: 360px;
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 32px 24px;
}

.btn-reset-login {
    position: fixed;
    top: 16px;
    right: 16px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 20px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
    z-index: 100;
}

.btn-reset-login:active {
    background: var(--surface-alt);
    color: var(--accent);
    transform: scale(0.95);
}

.login-logo {
    font-size: 24px;
    font-weight: 900;
    color: var(--accent);
    text-align: center;
    letter-spacing: -0.02em;
}

.login-subtitulo {
    font-size: 13px;
    color: var(--text-muted);
    text-align: center;
    margin: 6px 0 24px;
}

.login-error {
    font-size: 13px;
    font-weight: 600;
    color: var(--danger);
    background: var(--danger-bg);
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 14px;
}

.login-tabs {
    display: flex;
    gap: 8px;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--border);
}

.login-tab {
    flex: 1;
    padding: 12px 8px;
    background: none;
    border: none;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: all 0.2s;
}

.login-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

.login-form {
    display: none;
}

.login-form.active {
    display: block;
}

/* ============ TOP BAR ============ */

.top-bar {
    min-height: var(--topbar-height);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px;
    background: var(--bg);
    position: sticky;
    top: 0;
    z-index: 50;
}

.top-bar h1 {
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.2;
}


.header-cliente-nombre {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    margin: 0;
}

.header-cliente-nombre:empty {
    display: none;
}

.top-bar-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.rol-badge {
    border: none;
    background: var(--surface-alt);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 700;
    padding: 6px 12px;
    border-radius: 999px;
    cursor: pointer;
}

.rol-badge:active {
    transform: scale(0.96);
}

/* ============ CONTENT ============ */

.content {
    flex: 1;
    overflow-y: auto;
    padding: 4px 16px 24px;
    -webkit-overflow-scrolling: touch;
    /* Al llegar al final, el gesto NO se propaga al documento de atrás:
       sin esto el navegador móvil dispara su "pull to refresh" o mueve la
       página entera, y el arrastre se siente trabado o recarga la app a
       mitad de un pedido. */
    overscroll-behavior-y: contain;
}

.tab-content {
    display: none;
    animation: fade-in 0.18s ease-out;
}

.tab-content.active {
    display: block;
}

@keyframes fade-in {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: translateY(0); }
}

.section-title {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    margin: 18px 0 10px;
}

.section-title:first-child {
    margin-top: 4px;
}

/* ============ BOTTOM NAV ============ */

.bottom-nav {
    display: flex;
    background: var(--surface);
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom, 0);
    position: sticky;
    bottom: 0;
    z-index: 100;
}

.nav-btn {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    height: var(--nav-height);
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    position: relative;
}

.nav-btn svg {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    position: relative;
    z-index: 1;
    transition: transform 0.15s cubic-bezier(.34,1.4,.64,1);
}

.nav-btn .nav-label {
    font-size: 11px;
    font-weight: 600;
    position: relative;
    z-index: 1;
}

.nav-btn.active {
    color: var(--accent);
}

.nav-btn.active::before {
    /* Píldora de fondo tras el ícono activo, look de app nativa (iOS/Android)
       en vez del texto simplemente cambiando de color. Solo opacity/transform. */
    content: '';
    position: absolute;
    top: 6px;
    width: 44px;
    height: 44px;
    border-radius: 14px;
    background: var(--surface-alt);
    animation: nav-pill-in 0.18s ease-out;
}

@keyframes nav-pill-in {
    from { transform: scale(0.6); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.nav-btn.active svg {
    transform: translateY(-1px);
}

.nav-btn:active {
    transform: scale(0.94);
}

/* ============ CARDS ============ */

.card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 16px;
    box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05), var(--shadow-sm);
    margin-bottom: 14px;
}

.card-title {
    font-size: 14px;
    font-weight: 700;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
}

.card-title .card-title-hint {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
}

/* ============ MESAS GRID ============ */

.mesas-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}

.mesa-btn {
    position: relative;
    aspect-ratio: 1;
    border: 1.5px solid var(--border);
    background: var(--surface);
    border-radius: var(--radius-md);
    cursor: pointer;
    /* Sombra en dos capas: una de contacto (pegada) + una difusa (elevación),
       simula profundidad real sin usar filter — mismo costo que shadow-sm. */
    box-shadow: 0 1px 2px rgba(20, 20, 20, 0.06), var(--shadow-sm);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 6px 4px;
    transition: transform 0.15s cubic-bezier(.34,1.4,.64,1), box-shadow 0.15s ease;
}

.mesa-btn:active {
    /* Se "hunde": baja y pierde elevación, como un botón físico. */
    transform: scale(0.94) translateY(1px);
    box-shadow: 0 1px 1px rgba(20, 20, 20, 0.08);
}

.mesa-btn .mesa-icono {
    width: 30px;
    height: 30px;
    margin-bottom: 2px;
    overflow: visible;
}

.mesa-btn .mesa-icono-mesa {
    stroke: rgba(0, 0, 0, 0.12);
    stroke-width: 0.4;
}

.mesa-btn .mesa-icono-silla {
    stroke: none;
}

.mesa-btn .mesa-icono-sombra {
    fill: rgba(0, 0, 0, 0.16);
}

.mesa-btn .mesa-icono-brillo {
    fill: rgba(255, 255, 255, 0.55);
}

.mesa-btn .mesa-numero {
    font-size: 22px;
    font-weight: 800;
    color: var(--text);
    line-height: 1;
}

.mesa-btn .mesa-capacidad,
.mesa-btn .mesa-ubicacion {
    font-size: 10px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mesa-btn .mesa-estado-dot {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--success);
    box-shadow: 0 0 0 3px var(--success-bg);
}

.mesa-btn .mesa-cuenta {
    font-size: 12px;
    font-weight: 800;
    color: var(--money);
    margin-top: 1px;
}

.mesa-btn.ocupada {
    background: var(--surface-alt);
    border-color: var(--accent);
    /* Halo cálido además de la elevación normal: distingue "ocupada" de
       un vistazo en una grilla de 15+ mesas sin depender solo del color. */
    box-shadow: 0 0 0 3px rgba(255, 90, 60, 0.10), var(--shadow-md);
}

.mesa-btn.ocupada .mesa-icono-mesa {
    stroke: rgba(120, 30, 10, 0.25);
}

.mesa-btn.ocupada .mesa-estado-dot {
    background: var(--accent);
    box-shadow: 0 0 0 3px rgba(255, 90, 60, 0.18);
}

.mesa-btn-inactiva {
    opacity: 0.4;
    cursor: default;
}

.mesa-btn-inactiva:active {
    transform: none;
    box-shadow: 0 1px 2px rgba(20, 20, 20, 0.06), var(--shadow-sm);
}

/* ============ SELECTOR DE ROL ============ */

.rol-opciones {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-bottom: 8px;
}

.rol-opcion {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    text-align: left;
    border: 1px solid var(--border);
    background: var(--surface-alt);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    cursor: pointer;
}

.rol-opcion:active {
    transform: scale(0.98);
}

.rol-opcion strong {
    font-size: 15px;
    color: var(--text);
}

.rol-opcion span {
    font-size: 13px;
    color: var(--text-muted);
}

/* ============ MODAL (bottom sheet) ============ */

.modal {
    position: fixed;
    inset: 0;
    background: rgba(10, 10, 10, 0.45);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 1000;
    /* El fondo oscuro no se arrastra: un gesto que empieza ahí no puede
       mover la pantalla que quedó abajo. */
    overscroll-behavior: contain;
}

.modal.hidden {
    display: none;
}

.modal-content {
    background: var(--surface);
    width: 100%;
    max-width: 560px;
    max-height: 92vh;
    max-height: 92dvh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: sheet-up 0.2s ease-out;
}

@keyframes sheet-up {
    from { transform: translateY(24px); opacity: 0.6; }
    to { transform: translateY(0); opacity: 1; }
}

.modal-small {
    max-width: 480px;
    margin: auto;
    border-radius: var(--radius-lg);
    max-height: 88vh;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

.modal-header h2 {
    font-size: 17px;
    font-weight: 700;
}

.btn-close {
    background: var(--bg);
    border: none;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    font-size: 16px;
    cursor: pointer;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
}

.modal-scroll {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
    /* Los dos faltaban y se notaba justo donde más molesta: un modal largo
       (carta con muchos platos, historial) arrastraba la pantalla de atrás
       en vez de su propio contenido. */
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

.modal-footer {
    padding: 16px;
    border-top: 1px solid var(--border);
    background: var(--surface);
    flex-shrink: 0;
}

/* ============ CATEGORÍAS / CHIPS ============ */

.categorias-tabs {
    display: flex;
    gap: 8px;
    padding: 12px 16px 0;
    overflow-x: auto;
    flex-shrink: 0;
    -webkit-overflow-scrolling: touch;
    /* Sin esto, arrastrar los chips hasta el extremo empuja el modal
       entero de costado en iOS. */
    overscroll-behavior-x: contain;
}

/* Filtro de categorías en Admin > Carta: mismo chip que ya usa el mozo para
   elegir platos, pero sin el padding pensado para el modal de comanda. */
#admin-categorias-filtro {
    padding: 0 0 12px;
}

#admin-categorias-filtro:empty {
    display: none;
}

.categoria-btn {
    padding: 8px 16px;
    border: none;
    background: var(--bg);
    border-radius: 999px;
    cursor: pointer;
    white-space: nowrap;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
}

.categoria-btn.active {
    background: var(--accent);
    color: var(--accent-contrast);
}

/* ============ PLATOS LIST (mozo) ============ */

.platos-list {
    padding: 8px 0;
}

.platos-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    padding: 8px 0;
}

@media (min-width: 600px) {
    .platos-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

.plato-card {
    border: none;
    background: var(--surface);
    border-radius: var(--radius-md);
    overflow: hidden;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.plato-card:active {
    transform: scale(0.96);
    box-shadow: var(--shadow-md);
}

.plato-card-imagen {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    background: var(--bg);
    display: block;
}

.plato-card-sin-imagen {
    display: flex;
    align-items: center;
    justify-content: center;
}

.plato-card-sin-imagen svg {
    width: 32px;
    height: 32px;
    stroke: var(--text-muted);
    fill: none;
    stroke-width: 1.5;
}

.plato-card-contenido {
    display: flex;
    flex-direction: column;
    padding: 12px;
    flex: 1;
}

.plato-card-nombre {
    font-weight: 700;
    font-size: 14px;
    color: var(--text);
    margin-bottom: 4px;
    line-height: 1.2;
}

.plato-card-descripcion {
    font-size: 11px;
    color: var(--text-muted);
    margin-bottom: 8px;
    line-height: 1.35;
    flex: 1;
}

.plato-card-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: auto;
}

.plato-card-precio {
    color: var(--money);
    font-weight: 800;
    font-size: 15px;
}

.plato-card-btn-add {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--accent-contrast);
    border: none;
    font-size: 18px;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.12s ease;
}

.plato-card-btn-add:active {
    transform: scale(0.9);
}

/* ============ FOTOS DE PLATOS ============ */

.item-thumb {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    flex-shrink: 0;
    background: var(--bg);
}

.item-thumb-placeholder {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--text-muted);
}

.item-thumb-placeholder svg {
    width: 18px;
    height: 18px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.5;
}

.imagen-upload {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    width: 100%;
    height: 140px;
    border-radius: var(--radius-md);
    border: 2px dashed var(--border);
    background: var(--bg);
    overflow: hidden;
    cursor: pointer;
}

.imagen-preview {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.imagen-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: 12px;
    text-align: center;
    padding: 0 16px;
}

.imagen-placeholder svg {
    width: 28px;
    height: 28px;
    stroke: var(--text-muted);
    fill: none;
    stroke-width: 1.5;
}


/* ============ CARRITO ============ */

.carrito-items {
    margin-bottom: 10px;
    max-height: 140px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

.carrito-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 6px 0;
}

.carrito-item-nombre {
    font-weight: 600;
    font-size: 13.5px;
}

.carrito-item-cantidad {
    color: var(--text-muted);
    font-size: 12px;
}

.carrito-item-precio {
    font-weight: 700;
    font-size: 13.5px;
    margin-right: 10px;
}

.carrito-item-remove {
    background: var(--danger-bg);
    color: var(--danger);
    border: none;
    border-radius: 50%;
    width: 26px;
    height: 26px;
    cursor: pointer;
    font-size: 13px;
    flex-shrink: 0;
}

.carrito-total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 13px;
    color: var(--text-muted);
    margin-bottom: 12px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
}

.carrito-total strong {
    font-size: 20px;
    color: var(--text);
    font-weight: 800;
}

.carrito-vacio {
    text-align: center;
    color: var(--text-muted);
    font-size: 13px;
    padding: 20px 0;
}

/* ============ CUENTA DE MESA ============ */

.cuenta-comanda-bloque {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 12px;
    margin-bottom: 10px;
}

.cuenta-comanda-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}

.badge {
    font-size: 11px;
    font-weight: 700;
    padding: 3px 9px;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.badge-cocina {
    background: var(--warning-bg);
    color: var(--warning);
}

.badge-entregado {
    background: var(--success-bg);
    color: var(--success);
}

.cuenta-plato-linea {
    display: flex;
    justify-content: space-between;
    font-size: 13px;
    padding: 3px 0;
    color: var(--text-muted);
}

.cuenta-total-global {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 14px 0 4px;
}

.cuenta-total-global .label {
    font-size: 13px;
    color: var(--text-muted);
    font-weight: 600;
}

.cuenta-total-global .value {
    font-size: 26px;
    font-weight: 800;
    color: var(--money);
}

/* ============ COCINA ============ */

.cocina-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.cocina-tarjeta {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 16px;
    box-shadow: var(--shadow-sm);
    border-left: 4px solid var(--warning);
}

.cocina-tarjeta.alerta {
    border-left-color: var(--danger);
}

.cocina-tarjeta-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 10px;
}

.cocina-mesa {
    font-size: 24px;
    font-weight: 800;
}

.cocina-tiempo {
    font-size: 12px;
    font-weight: 700;
    color: var(--warning);
    background: var(--warning-bg);
    padding: 4px 10px;
    border-radius: 999px;
}

.cocina-tiempo.alerta {
    color: var(--danger);
    background: var(--danger-bg);
}

.cocina-platos {
    margin-bottom: 14px;
}

.cocina-plato {
    padding: 5px 0;
    font-size: 13.5px;
    border-bottom: 1px solid var(--border);
}

.cocina-plato:last-child {
    border-bottom: none;
}

.btn-listo {
    width: 100%;
    padding: 14px;
    background: var(--success);
    color: white;
    border: none;
    border-radius: var(--radius-md);
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
}

.btn-listo:active {
    transform: scale(0.98);
}

.empty-state {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-muted);
}

.empty-state svg {
    width: 48px;
    height: 48px;
    stroke: var(--text-muted);
    fill: none;
    stroke-width: 1.5;
    margin-bottom: 12px;
}

.empty-state p {
    font-size: 14px;
}

/* ============ DASHBOARD ============ */

.dashboard-header {
    margin-bottom: 20px;
}

.periodo-selector {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 8px;
}

.date-range-inputs {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: 10px;
    padding: 12px;
    background: var(--surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}

.date-input-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.date-input-group label {
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.date-input-group input[type="date"] {
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg);
    color: var(--text);
    font-size: 13px;
    /* Sin esto, el input reserva su propio ancho mínimo de contenido (el
       texto dd/mm/aaaa + el ícono nativo del calendario) además del ancho
       que le da el grid — en una fila de 3 columnas (Desde/Hasta/Aplicar)
       eso empuja el total más allá del viewport en un celular angosto, y
       "Aplicar" queda literalmente fuera de la tarjeta. min-width: 0 deja
       que el input se encoja hasta el espacio que el grid le da de verdad. */
    min-width: 0;
}

/* En pantallas angostas, tres columnas (Desde/Hasta/Aplicar) no entran con
   el ancho mínimo real de un <input type="date"> nativo — el botón queda
   empujado fuera de la tarjeta. Se pasa a 2 columnas para las fechas y
   "Aplicar" ocupa su propia fila completa, en vez de competir por espacio. */
@media (max-width: 480px) {
    .date-range-inputs {
        grid-template-columns: 1fr 1fr;
    }

    .date-range-inputs #btn-aplicar-filtro {
        grid-column: 1 / -1;
    }
}

.periodo-presets {
    display: flex;
    gap: 6px;
    padding: 8px;
    background: var(--bg);
    border-radius: 999px;
}

.periodo-btn {
    padding: 8px 12px;
    border: none;
    background: transparent;
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text-muted);
    cursor: pointer;
    transition: all 0.12s ease;
}

.periodo-btn:active {
    transform: scale(0.95);
}

.periodo-btn.active {
    background: var(--accent);
    color: var(--accent-contrast);
    box-shadow: var(--shadow-sm);
}

.dashboard-rango-label {
    font-size: 12px;
    color: var(--text-muted);
    padding: 0 4px;
    font-weight: 600;
}

.stats-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    margin-bottom: 20px;
}

@media (max-width: 500px) {
    .stats-row {
        grid-template-columns: 1fr;
    }
}

.stat-tile {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 20px;
    box-shadow: var(--shadow-md);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.stat-tile:active {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.stat-tile .label {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 10px;
}

.stat-tile .value {
    font-size: 24px;
    font-weight: 900;
    line-height: 1;
    margin-bottom: 8px;
}

.stat-tile .value.money {
    color: var(--money);
    background: linear-gradient(135deg, var(--money), #0A4C4B);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.stat-tile .value.expense {
    color: var(--danger);
    background: linear-gradient(135deg, var(--danger), #C1121F);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.stat-tile .value.profit {
    color: var(--success);
    background: linear-gradient(135deg, var(--success), #1F9646);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.stat-tile .delta {
    font-size: 12px;
    font-weight: 700;
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    display: inline-block;
}

.stat-tile .delta.up {
    color: var(--success);
    background: var(--success-bg);
}

.stat-tile .delta.down {
    color: var(--danger);
    background: var(--danger-bg);
}

.chart-legend {
    display: flex;
    gap: 16px;
    margin-top: 6px;
}

.chart-legend-item {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
}

.chart-legend-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.top-plato-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 12px;
    border-radius: var(--radius-md);
    background: var(--surface);
    border: 1px solid var(--border);
    margin-bottom: 8px;
    transition: all 0.12s ease;
}

.top-plato-item:active {
    transform: translateX(2px);
    box-shadow: var(--shadow-sm);
}

.top-plato-num {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--surface-alt);
    color: var(--accent);
    font-size: 13px;
    font-weight: 900;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* Tabla de ganancias por día (dashboard.js: renderTablaDiaria) */
.tabla-diaria-wrapper {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

.tabla-diaria {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

.tabla-diaria th {
    text-align: right;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    padding: 8px 10px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.tabla-diaria th.th-fecha {
    text-align: left;
}

.tabla-diaria td {
    padding: 10px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.tabla-diaria tr:last-child td {
    border-bottom: none;
}

.tabla-diaria .td-fecha {
    text-align: left;
    color: var(--text);
    font-weight: 600;
}

.tabla-diaria .td-num {
    text-align: right;
    color: var(--text-muted);
}

.tabla-diaria .td-ganancia {
    font-weight: 700;
}

.tabla-diaria .fila-positiva .td-ganancia {
    color: var(--success);
}

.tabla-diaria .fila-negativa {
    background: var(--danger-bg);
}

.tabla-diaria .fila-negativa .td-ganancia {
    color: var(--danger);
}

.tabla-diaria .fila-neutro .td-ganancia {
    color: var(--text-muted);
}

/* En móvil, ocultar Gastos y Margen — Fecha/Ventas/Ganancia son las
   columnas que realmente se necesitan de un vistazo en pantalla chica. */
@media (max-width: 480px) {
    .tabla-diaria .th-oculto-movil,
    .tabla-diaria .td-margen,
    .tabla-diaria td:nth-child(3) {
        display: none;
    }
}

.top-plato-info {
    flex: 0 0 auto;
    min-width: 0;
}

.top-plato-nombre {
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
    margin-bottom: 3px;
    line-height: 1.2;
}

.top-plato-detalle {
    display: flex;
    align-items: center;
    gap: 6px;
}

.cantidad-badge {
    font-size: 10px;
    font-weight: 800;
    color: var(--accent);
    background: var(--surface-alt);
    padding: 2px 7px;
    border-radius: 999px;
    white-space: nowrap;
}

.cantidad-badge-gasto {
    color: var(--danger);
    background: var(--danger-bg);
}

.top-plato-monto {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-muted);
}

.top-gasto-monto {
    color: var(--danger);
}

.top-plato-bar-wrapper {
    flex: 1;
    min-width: 60px;
    height: 6px;
    background: var(--bg);
    border-radius: 999px;
    overflow: hidden;
}

.top-plato-bar {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent), #FF7D63);
    transition: width 0.3s ease;
}

.top-gasto-bar {
    background: linear-gradient(90deg, var(--danger), #C1121F);
}

.top-gasto-num {
    color: var(--danger);
}

.empty-hint {
    font-size: 13px;
    color: var(--text-muted);
    text-align: center;
    padding: 16px 0;
}

/* ============ ADMIN ============ */

.admin-tabs {
    display: flex;
    gap: 6px;
    margin-bottom: 14px;
    background: var(--bg);
    border-radius: 999px;
    padding: 4px;
    /* Con 5 pestañas (Carta/Gastos/Personal/Boletas/Caja) ya no entran
       cómodas en flex:1 a 320px — scroll horizontal en vez de apretarlas
       hasta truncar el texto. */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.admin-tab-btn {
    flex: 1 0 auto;
    padding: 9px 14px;
    background: transparent;
    border: none;
    border-radius: 999px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 700;
    color: var(--text-muted);
    white-space: nowrap;
}

.admin-tab-btn.active {
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-sm);
}

.admin-section {
    display: none;
}

.admin-section.active {
    display: block;
}

.admin-item {
    background: var(--surface);
    padding: 14px;
    margin-bottom: 10px;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}

.admin-item-main {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    flex: 1;
}

.admin-item.inactivo {
    opacity: 0.55;
}

.admin-item-info h3,
.admin-item-info h4 {
    font-size: 14px;
    font-weight: 700;
    margin-bottom: 3px;
}

.admin-item-info p {
    color: var(--text-muted);
    font-size: 12px;
}

.admin-item-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

.icon-btn {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    background: var(--bg);
    color: var(--text-muted);
}

.icon-btn svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
}

.icon-btn.danger {
    background: var(--danger-bg);
    color: var(--danger);
}

.day-group-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-muted);
    margin: 16px 0 8px;
    display: flex;
    justify-content: space-between;
}

/* ============ BOTONES ============ */

.btn {
    padding: 10px 18px;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 700;
    transition: transform 0.12s cubic-bezier(.34,1.4,.64,1), box-shadow 0.12s ease;
}

.btn:active {
    transform: scale(0.98) translateY(1px);
}

.btn-primary {
    background: var(--accent-gradient);
    color: var(--accent-contrast);
    box-shadow: 0 3px 10px rgba(255, 90, 60, 0.28);
}

.btn-primary:active {
    box-shadow: 0 1px 4px rgba(255, 90, 60, 0.22);
}

.btn-secondary {
    background: var(--bg);
    color: var(--text);
}


.btn-success {
    background: var(--success);
    color: white;
}

.btn-large {
    padding: 15px;
    font-size: 15px;
    width: 100%;
}

.btn-block {
    width: 100%;
}

.btn-fab {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin-bottom: 16px;
}

.admin-actions-row {
    display: flex;
    gap: 8px;
}

.admin-actions-row .btn-fab {
    margin-bottom: 16px;
}

.btn-fab-aux {
    flex: 0 0 auto;
    width: auto;
    padding: 10px 16px;
    white-space: nowrap;
}

.btn-fab-aux svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
}

.form-inline-add {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
}

.form-inline-add input {
    flex: 1;
    padding: 11px 12px;
    border: 1px solid var(--border);
    background: var(--bg);
    border-radius: var(--radius-sm);
    font-size: 14.5px;
    color: var(--text);
}

.form-inline-add input:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
}

.icono-picker {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 6px;
    margin-bottom: 12px;
}

.icono-opcion {
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    border: 2px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--bg);
    cursor: pointer;
}

.icono-opcion.selected {
    border-color: var(--accent);
    background: var(--accent-bg, var(--bg));
}

.categoria-icono-chip {
    font-size: 18px;
    margin-right: 6px;
}

.btn-fab svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2.5;
}

/* ============ FORMS ============ */

.form-group {
    margin-bottom: 14px;
}

.form-group label {
    display: block;
    margin-bottom: 7px;
    font-weight: 700;
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.form-group input,
.form-group textarea,
.form-group select {
    width: 100%;
    padding: 12px 14px;
    border: 1.5px solid var(--border);
    background: var(--surface);
    border-radius: var(--radius-md);
    font-size: 14.5px;
    font-family: inherit;
    color: var(--text);
    /* Relieve sutil "hundido": distingue el campo de la tarjeta que lo
       contiene sin gastar más que un box-shadow (mismo costo que un borde). */
    box-shadow: inset 0 1px 2px rgba(20, 20, 20, 0.04);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-group input::placeholder,
.form-group textarea::placeholder {
    color: var(--text-muted);
    opacity: 0.65;
}

.form-group input:hover,
.form-group textarea:hover,
.form-group select:hover {
    border-color: color-mix(in srgb, var(--border) 40%, var(--text-muted));
}

.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: inset 0 1px 2px rgba(20, 20, 20, 0.04), 0 0 0 3.5px rgba(255, 90, 60, 0.14);
}

.form-group textarea {
    resize: vertical;
    min-height: 70px;
    line-height: 1.5;
}

.form-group input:disabled {
    background: var(--surface-alt);
    color: var(--text-muted);
    box-shadow: none;
    cursor: not-allowed;
}

.form-hint {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    color: var(--text-muted);
}

/* Dos campos cortos en una línea (stock actual / mínimo): separarlos en dos
   filas completas desperdicia altura de pantalla en un celular. */
.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

.form-row .form-group {
    margin-bottom: 0;
}

.form-group select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px;
    padding-right: 36px;
}

/* Valor no editable dentro de un form (email de admin, rol fijo, etc.) */
.campo-fijo {
    padding: 12px 14px;
    background: var(--surface-alt);
    border: 1.5px solid transparent;
    border-radius: var(--radius-md);
    font-size: 14.5px;
    font-weight: 600;
    color: var(--text-muted);
}

/* ============ INVENTARIO (Admin > Gastos) ============ */

.insumo-section {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05), var(--shadow-sm);
    margin-bottom: 14px;
    overflow: hidden;
}

.insumo-toggle {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 16px;
    border: none;
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    text-align: left;
}

.insumo-toggle-titulo {
    display: flex;
    align-items: center;
    gap: 9px;
}

.insumo-toggle-titulo svg {
    width: 18px;
    height: 18px;
    stroke: var(--accent);
    fill: none;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}

.insumo-toggle-derecha {
    display: flex;
    align-items: center;
    gap: 8px;
}

.insumo-chevron {
    width: 18px;
    height: 18px;
    stroke: var(--text-muted);
    fill: none;
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform 0.18s ease;
}

.insumo-toggle.abierto .insumo-chevron {
    transform: rotate(180deg);
}

.insumo-resumen {
    font-size: 11.5px;
    font-weight: 700;
    padding: 3px 9px;
    border-radius: 999px;
    white-space: nowrap;
}

.insumo-resumen:empty {
    display: none;
}

.insumo-resumen.ok { background: var(--success-bg); color: var(--success); }
.insumo-resumen.bajo { background: var(--warning-bg); color: var(--warning); }
.insumo-resumen.critico { background: var(--danger-bg); color: var(--danger); }

.insumo-panel {
    padding: 0 16px 16px;
}

.insumo-alertas {
    background: var(--warning-bg);
    border-radius: var(--radius-md);
    padding: 10px 12px;
    margin-bottom: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.insumo-alerta-fila {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--text);
}

.insumo-alerta-fila span:last-child {
    color: var(--text-muted);
    margin-left: auto;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* El punto de color es el semáforo: acompaña al texto en vez de
   reemplazarlo, para que el estado no dependa solo de distinguir colores. */
.insumo-punto {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    display: inline-block;
}

.insumo-punto.ok { background: var(--success); }
.insumo-punto.bajo { background: var(--warning); }
.insumo-punto.critico { background: var(--danger); }

.insumo-tabla-wrap {
    overflow-x: auto;
    margin-bottom: 12px;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

.insumo-tabla {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.insumo-tabla th {
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    text-align: left;
    padding: 6px 8px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.insumo-tabla td {
    padding: 10px 8px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.insumo-tabla tr:last-child td {
    border-bottom: none;
}

.insumo-tabla .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.insumo-tabla td:first-child {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
}

.insumo-fila.critico td:first-child { color: var(--danger); }
.insumo-fila.bajo td:first-child { color: var(--warning); }

.insumo-acciones {
    display: flex;
    justify-content: flex-end;
    gap: 4px;
}

/* ============ MOVIMIENTOS DE STOCK ============ */

/* Entrada y salida se distinguen por color además del ícono: en una lista
   de movimientos, la dirección es lo primero que el ojo busca. */
.icon-btn.entrada svg { stroke: var(--success); }
.icon-btn.salida svg { stroke: var(--warning); }
.icon-btn.entrada:hover { background: var(--success-bg); }
.icon-btn.salida:hover { background: var(--warning-bg); }

.mov-contexto {
    background: var(--surface-alt);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    margin-bottom: 14px;
    font-size: 13.5px;
    color: var(--text);
}

.mov-cantidad-wrap {
    position: relative;
    display: flex;
    align-items: center;
}

.mov-cantidad-wrap input {
    padding-right: 62px;
}

/* La unidad va dentro del campo, no como texto suelto al lado: el admin
   escribe "5" viendo "kg" pegado al número, sin dudar de qué está tipeando. */
.mov-unidad {
    position: absolute;
    right: 14px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    pointer-events: none;
}

/* Una salida no es una acción "primaria positiva": el botón usa el color de
   advertencia para que registrar una salida no se sienta igual que sumar. */
.btn-primary.btn-salida {
    background: linear-gradient(135deg, #FBBF4D 0%, var(--warning) 55%, #D97706 100%);
}

.btn-link-danger {
    display: block;
    width: 100%;
    margin-top: 14px;
    padding: 10px;
    border: none;
    background: none;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    color: var(--danger);
    cursor: pointer;
    text-align: center;
}

.btn-link-danger:hover {
    text-decoration: underline;
}

/* ============ PANEL DE HISTORIAL ============ */

.historial-overlay {
    position: fixed;
    inset: 0;
    background: rgba(20, 20, 20, 0.35);
    z-index: 1400;
}

.historial-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(360px, 88vw);
    background: var(--surface);
    box-shadow: var(--shadow-md);
    z-index: 1500;
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 0.24s ease;
}

.historial-panel.abierto {
    transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
    .historial-panel { transition: none; }
}

.historial-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    padding: 16px;
    border-bottom: 1px solid var(--border);
}

.historial-header h3 {
    font-size: 16px;
    font-weight: 700;
    margin: 0 0 2px;
}

.historial-subtitulo {
    font-size: 12.5px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.historial-lista {
    flex: 1;
    overflow-y: auto;
    padding: 8px 16px 16px;
    -webkit-overflow-scrolling: touch;
}

.mov-fila {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 0;
    border-bottom: 1px solid var(--border);
}

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

/* Un movimiento deshecho sigue visible (es parte del historial) pero
   atenuado y tachado, para que no se lea como stock vigente. */
.mov-fila.revertido {
    opacity: 0.55;
}

.mov-fila.revertido .mov-monto {
    text-decoration: line-through;
}

.mov-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    flex-shrink: 0;
}

.mov-badge svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.mov-badge.entrada { background: var(--success-bg); }
.mov-badge.entrada svg { stroke: var(--success); }
.mov-badge.salida { background: var(--warning-bg); }
.mov-badge.salida svg { stroke: var(--warning); }

.mov-cuerpo {
    flex: 1;
    min-width: 0;
}

.mov-linea {
    display: flex;
    align-items: baseline;
    gap: 7px;
}

.mov-monto {
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.mov-saldo {
    font-size: 12px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.mov-meta {
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 2px;
}

/* ============ TOASTS ============ */

.toast-container {
    position: fixed;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: calc(100% - 32px);
    max-width: 480px;
}

.toast {
    background: var(--text);
    color: var(--bg);
    padding: 12px 16px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    font-weight: 600;
    box-shadow: var(--shadow-md);
    animation: toast-in 0.2s ease-out;
}

.toast.success { background: var(--success); color: white; }
.toast.error { background: var(--danger); color: white; }
.toast.warning { background: var(--warning); color: white; }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ============ MODO OFFLINE ============ */

/* Barra persistente (no un toast que desaparece solo): mientras haya
   pedidos sin enviar, el mozo necesita verlo todo el tiempo que dure la
   caída de señal, no solo un instante. */
.offline-banner {
    position: fixed;
    bottom: calc(var(--nav-height) + env(safe-area-inset-bottom, 0px));
    left: 50%;
    transform: translateX(-50%);
    z-index: 1500;
    width: calc(100% - 32px);
    max-width: 480px;
    padding: 10px 16px;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    font-size: 12.5px;
    font-weight: 700;
    text-align: center;
    box-shadow: 0 -2px 10px rgba(20, 20, 20, 0.12);
    animation: toast-in 0.2s ease-out;
}

.offline-banner.offline {
    background: var(--warning);
    color: #1A1A1A;
}

.offline-banner.syncing {
    background: var(--accent);
    color: var(--accent-contrast);
}

/* Backend sirviendo código viejo (ver avisarSiElServidorEstaDesactualizado
   en app.js). Rojo y no ámbar a propósito: no es un estado degradado que
   se resuelve solo como "sin conexión", es algo que hay que ir a arreglar
   — y mientras tanto, cualquier bug que se vea en pantalla puede ser un
   fantasma. En producción nunca aparece. */
.offline-banner.servidor-viejo {
    background: var(--danger);
    color: #FFFFFF;
}

/* ============ CAJA (Validador de Caja) ============ */

.caja-card {
    padding: 0;
    overflow: hidden;
}

.caja-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 18px 16px;
    background: var(--surface-alt);
}

.caja-banner-abierta {
    background: var(--success-bg);
}

.caja-banner-cuadrada {
    background: var(--success-bg);
}

.caja-banner-leve {
    background: var(--warning-bg);
}

.caja-banner-grave {
    background: var(--danger-bg);
}

.caja-banner-icon {
    font-size: 30px;
    line-height: 1;
    flex-shrink: 0;
}

.caja-banner-title {
    font-size: 16px;
    font-weight: 900;
}

.caja-banner-sub {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

.caja-live-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    padding: 16px;
}

.caja-live-stat {
    display: flex;
    flex-direction: column;
    gap: 4px;
    text-align: center;
    padding: 12px;
    background: var(--bg);
    border-radius: var(--radius-sm);
}

.caja-live-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    font-weight: 700;
}

.caja-live-valor {
    font-size: 20px;
    font-weight: 900;
    font-variant-numeric: tabular-nums;
}

.caja-live-valor.money {
    color: var(--money);
}

.caja-live-valor.expense {
    color: var(--danger);
}

.caja-atrasada-aviso {
    margin: 0 16px 16px;
    padding: 10px 12px;
    background: var(--warning-bg);
    border-left: 3px solid var(--warning);
    border-radius: var(--radius-sm);
    font-size: 12px;
    line-height: 1.4;
}

/* ============ BLOQUEO POR CAJA CERRADA (Mesas/Cocina) ============ */

.caja-bloqueo-banner {
    display: none;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding: 48px 24px;
    margin-top: 40px;
}

.caja-bloqueo-banner h3 {
    font-size: 18px;
    font-weight: 900;
    margin-top: 4px;
}

.caja-bloqueo-banner p {
    font-size: 14px;
    color: var(--text-muted);
    max-width: 320px;
    line-height: 1.5;
}

.caja-bloqueo-banner .btn {
    margin-top: 12px;
}

.caja-bloqueo-icon {
    font-size: 48px;
}

/* Cuando la pestaña (Mesas/Cocina) queda bloqueada por falta de caja
   abierta: se muestra SOLO el banner, todo lo demás (grilla, modales,
   botones) se oculta con un único selector genérico — no depende de la
   estructura interna de cada pestaña. */
.tab-content.caja-bloqueada > *:not(.caja-bloqueo-banner) {
    display: none !important;
}

.tab-content.caja-bloqueada .caja-bloqueo-banner {
    display: flex;
}

/* ============ SWITCH DE NOTIFICACIONES (Admin > Personal) ============ */

.notif-settings-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 16px;
    margin-bottom: 16px;
    display: flex;
    align-items: center;
    gap: 14px;
}

.notif-settings-icon {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: var(--radius-md);
    background: var(--surface-alt);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
}

.notif-settings-icon svg {
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.notif-settings-text {
    flex: 1 1 auto;
    min-width: 0;
}

.notif-settings-title {
    font-weight: 700;
    font-size: 14px;
}

.notif-settings-hint {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

/* Switch tipo iOS: input real (accesible, togglable con teclado) oculto
   visualmente pero presente para foco/lectores de pantalla; el "riel" y la
   "perilla" son dos capas con solo transform/box-shadow — misma restricción
   de rendimiento que el resto del rediseño 3D (ver cabecera del archivo). */
.switch {
    position: relative;
    flex: 0 0 auto;
    width: 48px;
    height: 28px;
}

.switch input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
    z-index: 1;
}

.switch-track {
    position: absolute;
    inset: 0;
    background: var(--border);
    border-radius: 999px;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15);
    transition: background 0.2s ease;
}

.switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: #FFFFFF;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
    transition: transform 0.2s ease;
}

.switch input:checked ~ .switch-track {
    background: var(--accent-gradient);
}

.switch input:checked ~ .switch-thumb {
    transform: translateX(20px);
}

.switch input:focus-visible ~ .switch-track {
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15), 0 0 0 3px var(--surface-alt);
}

.switch input:disabled ~ .switch-track {
    opacity: 0.5;
}

.switch input:disabled {
    cursor: not-allowed;
}

/* Fila de un switch de rol en el modal "Nueva Cuenta"/"Editar Cuenta" —
   una por rol combinable (Mozo/Cajero/Cocina), mismo componente .switch
   de arriba, sin CSS nuevo salvo el layout de la fila. */
.rol-switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 0;
    font-size: 14px;
}

.rol-switch-row + .rol-switch-row {
    border-top: 1px solid var(--border);
}

/* Rol incompatible con el que ya está marcado (ver aplicarExclusividadRoles
   en admin.js). Se atenúa en vez de esconderse: el admin tiene que poder
   ver que la opción existe y deducir por qué no está disponible. */
.rol-switch-row.rol-switch-bloqueada {
    opacity: 0.42;
}

.rol-switch-row .rol-hint {
    display: block;
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--text-muted);
    margin-top: 2px;
}

.rol-switch-row.rol-switch-destacada {
    align-items: flex-start;
}

/* ============ UTILS ============ */

.hidden {
    display: none !important;
}

@media (prefers-reduced-motion: reduce) {
    * {
        animation: none !important;
        transition: none !important;
    }
}

/* ============ VISTA UNIFICADA ("Todo en uno") ============

   Las tres etapas de una mesa —pedir, cocinar, cobrar— en una sola pantalla,
   para quien atiende solo y no puede darse el lujo de ir y volver entre
   pestañas. Ver frontend/js/vista-unificada.js.

   SIN backdrop-filter, a propósito: la cabecera de este archivo lo descarta
   para toda la app (gama media/baja). Los modales ya se ven "flotantes" con
   un fondo rgba plano, que cuesta lo mismo que pintar un color.

   El gate de caja sigue mandando: `.tab-content.caja-bloqueada > *` usa
   !important, así que sin caja abierta este panel queda oculto igual que la
   grilla de siempre. */

.vu-switch {
    display: flex;
    gap: 4px;
    padding: 4px;
    margin-bottom: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}

.vu-switch-btn {
    flex: 1;
    padding: 9px 12px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-muted);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 0.18s, color 0.18s;
}

.vu-switch-btn.active {
    background: var(--accent-gradient);
    color: var(--accent-contrast);
    box-shadow: var(--shadow-sm);
}

/* El panel solo existe cuando el interruptor está en "Todo en uno"; en la
   vista de siempre la grilla de mesas queda exactamente como estaba. */
.vu-panel { display: none; }

#mozo-tab.vu-activa .vu-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

#mozo-tab.vu-activa #mozo-mesas { display: none; }

/* Estorba entre tres columnas de trabajo; sigue disponible en "Solo mesas". */
#mozo-tab.vu-activa #btn-gestionar-mesas { display: none; }

.vu-grid {
    display: grid;
    grid-template-columns: 1fr 1.35fr 1fr;
    gap: 12px;
    align-items: start;
}

.vu-col {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 12px;
    min-width: 0;
}

.vu-col-title {
    margin: 0;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.vu-lista {
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* El scroll vive dentro de cada columna, no en la página: así el pie con
       los totales y las otras dos columnas nunca se van de la vista. */
    max-height: 62vh;
    max-height: 62dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.vu-vacio {
    margin: 0;
    padding: 18px 6px;
    text-align: center;
    font-size: 0.82rem;
    color: var(--text-muted);
}

/* ---- Columna 1: mesas ---- */

.vu-mesas-grid {
    display: grid;
    /* 96px y no 64: la mesa dejó de ser un cuadradito con un número y ahora
       lleva ícono, monto y tiempo de espera. Sigue siendo auto-fill, así
       que en una tablet ancha entran igual de muchas por fila. */
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 10px;
    max-height: 62vh;
    max-height: 62dvh;
    overflow-y: auto;
    padding: 2px;  /* aire para que el halo de :focus no quede cortado */
}

.vu-mesa {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px 6px 8px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    overflow: hidden;
    transition: transform 0.12s, box-shadow 0.12s, border-color 0.2s;
}

/* Franja de estado arriba. El color ya lo dice, pero una franja lo dice
   también por POSICIÓN y GROSOR — se lee de reojo y sin depender del
   matiz, que es lo que falla con daltonismo rojo/verde. */
.vu-mesa-barra {
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--border);
    transition: background 0.2s;
}

.vu-mesa-cabecera {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 5px;
    width: 100%;
}

.vu-mesa-num {
    font-size: 1.35rem;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.vu-mesa-icono {
    width: 38px;
    height: 38px;
    display: block;
}

/* Los rellenos del ícono salen de acá, no de un atributo fill en el SVG:
   el render de la vista unificada reconcilia en vez de reescribir, así que
   cambiar la clase del botón repinta la mesa sin tocar el SVG. */
.vu-mesa-tapa   { fill: url(#mesaTopLibre); }
.vu-mesa-silla  { fill: url(#sillaLibre); }
/* Mismos valores que .mesa-icono-* de la grilla clásica, a propósito: es
   el mismo objeto visto en dos pantallas. */
.vu-mesa-sombra { fill: rgba(0, 0, 0, 0.16); }
.vu-mesa-brillo { fill: rgba(255, 255, 255, 0.55); }

.vu-mesa.cocinando .vu-mesa-tapa  { fill: url(#mesaTopOcupada); }
.vu-mesa.cocinando .vu-mesa-silla { fill: url(#sillaOcupada); }
.vu-mesa.por-cobrar .vu-mesa-tapa  { fill: url(#mesaTopCobrar); }
.vu-mesa.por-cobrar .vu-mesa-silla { fill: url(#sillaCobrar); }

.vu-mesa-detalle {
    font-size: 0.74rem;
    font-weight: 800;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* Tres estados, no dos: "cocinando" (no hay nada que hacer todavía) es muy
   distinto de "por cobrar" (hay plata esperando sobre la mesa). El borde
   grueso acompaña al color para que se distingan también sin ver bien el
   matiz — daltonismo rojo/verde es justo el par que se usa acá. */
.vu-mesa.libre { border-color: var(--success); }
.vu-mesa.libre .vu-mesa-num { color: var(--success); }
.vu-mesa.libre .vu-mesa-barra { background: var(--success); }

.vu-mesa.cocinando {
    border-color: var(--accent);
    border-width: 2.5px;
    background: var(--surface-alt);
}
.vu-mesa.cocinando .vu-mesa-num { color: var(--accent-dark); }
.vu-mesa.cocinando .vu-mesa-barra { background: var(--accent); }

.vu-mesa.por-cobrar {
    border-color: var(--warning);
    border-width: 2.5px;
    background: var(--warning-bg);
    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.16);
}
.vu-mesa.por-cobrar .vu-mesa-num { color: #92400E; }
.vu-mesa.por-cobrar .vu-mesa-detalle { color: #92400E; }
.vu-mesa.por-cobrar .vu-mesa-barra { background: var(--warning); }
.vu-mesa.urgente .vu-mesa-barra { background: var(--danger); }

/* ---- Lo que hace que la grilla se sienta viva ----

   Tres efectos, y cada uno significa algo. Nada de esto es decoración: una
   animación que no informa cansa la vista en un turno de ocho horas, y
   termina ignorándose justo cuando hace falta.

   Todo se pinta con transform/box-shadow/opacity, las tres primitivas que
   compone la GPU sin recalcular píxeles — misma restricción de rendimiento
   de gama media/baja que rige el resto de esta hoja. */

/* (a) El tiempo de espera: el dato que decide a qué mesa ir primero. */
.vu-mesa-tiempo {
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--text-muted);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* (b) Hay plata esperando sobre la mesa. Latido lento y muy leve: se nota
       con la vista periférica, que es como se mira una grilla de mesas
       mientras se hace otra cosa, sin gritar desde el centro de la pantalla. */
.vu-mesa.por-cobrar {
    animation: vu-respira 2.6s ease-in-out infinite;
}

@keyframes vu-respira {
    0%, 100% { box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.16); }
    50%      { box-shadow: 0 0 0 6px rgba(245, 158, 11, 0.26); }
}

/* (c) Ya esperó demasiado (VU_MINUTOS_ALERTA, el mismo umbral que usa el
       monitor de cocina). El latido se acelera y el tiempo se pinta en
       rojo: la urgencia se lee por movimiento Y por color, no solo por
       color — el par rojo/ámbar es difícil justo para quien no distingue
       bien esos matices. */
.vu-mesa.urgente {
    border-color: var(--danger);
    animation-duration: 1.3s;
}

.vu-mesa.urgente .vu-mesa-tiempo {
    color: var(--danger);
}

.vu-mesa.cocinando.urgente {
    animation: vu-respira-alerta 1.3s ease-in-out infinite;
}

@keyframes vu-respira-alerta {
    0%, 100% { box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.14); }
    50%      { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.28); }
}

/* (d) La mesa acaba de CAMBIAR de estado (salió de cocina, se cobró). Un
       solo pulso, una vez: avisa que algo pasó ahí sin obligar a comparar
       la pantalla con lo que uno recordaba de hace cinco segundos.
       Funciona porque el render ya no destruye el nodo en cada vuelta
       (ver vuRenderMesas) — antes esta animación se reiniciaba sola y no
       llegaba a verse nunca. */
.vu-mesa--cambio {
    animation: vu-cambio 0.55s ease-out;
}

@keyframes vu-cambio {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.13); }
    100% { transform: scale(1); }
}

/* El toque tiene que ganarle a cualquier animación en curso: si el dedo
   está sobre la mesa, lo que se ve es la respuesta al dedo. */
.vu-mesa:active {
    animation: none;
    transform: scale(0.94);
}

/* Respeta la preferencia del sistema. La regla global de más abajo ya
   acorta todas las animaciones, pero una que se repite para siempre hay
   que APAGARLA, no acelerarla: a 0.01s queda parpadeando. El color y el
   borde siguen diciendo lo mismo sin movimiento. */
@media (prefers-reduced-motion: reduce) {
    .vu-mesa,
    .vu-mesa.por-cobrar,
    .vu-mesa.cocinando.urgente,
    .vu-mesa--cambio {
        animation: none !important;
    }
}

/* ---- Columnas 2 y 3: tarjetas ---- */

.vu-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 10px;
    background: var(--bg);
    animation: vu-entra 0.22s ease-out;
}

.vu-card.tarde {
    border-color: var(--danger);
    background: var(--danger-bg);
}

.vu-card.cobro {
    border-color: var(--warning);
    background: var(--warning-bg);
}

.vu-card.saliendo {
    opacity: 0;
    transform: scale(0.96);
    transition: opacity 0.25s, transform 0.25s;
}

@keyframes vu-entra {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: none; }
}

.vu-card-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}

.vu-card-mesa { font-size: 0.95rem; font-weight: 800; }

.vu-card-tiempo {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.vu-card-tiempo.tarde { color: var(--danger); }

.vu-card-total {
    font-size: 1rem;
    font-weight: 800;
    color: var(--money);
    font-variant-numeric: tabular-nums;
}

.vu-card-platos {
    margin: 0 0 8px;
    padding-left: 16px;
    font-size: 0.8rem;
    line-height: 1.5;
}

.vu-card-nota {
    margin: 0 0 8px;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.vu-btn-listo,
.vu-btn-cobrar {
    width: 100%;
    /* 44px: el mínimo táctil cómodo con el pulgar, mismo criterio que el
       resto de la app (botones grandes en CLAUDE.md). */
    min-height: 44px;
    border: none;
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    font-weight: 800;
    color: #FFFFFF;
    cursor: pointer;
    transition: transform 0.12s, filter 0.12s;
}

.vu-btn-listo { background: var(--success); }
.vu-btn-cobrar { background: var(--money); }

.vu-btn-listo:active,
.vu-btn-cobrar:active { transform: scale(0.97); filter: brightness(0.94); }

/* ---- Pie con los totales ---- */

.vu-pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
    margin-top: 12px;
    padding: 10px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    font-size: 0.78rem;
    color: var(--text-muted);
    /* Pegado al fondo del área que scrollea: los totales del turno se ven
       siempre, sin importar cuánto se haya bajado en una columna. */
    position: sticky;
    bottom: 0;
    z-index: 5;
}

.vu-pie-item b {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.vu-pie-fuerte b { color: var(--money); }

.vu-pie-hora {
    font-variant-numeric: tabular-nums;
    margin-left: auto;
}

.vu-pie-caja {
    padding: 3px 10px;
    border-radius: 999px;
    font-weight: 800;
    font-size: 0.72rem;
}

.vu-pie-caja.ok { background: var(--success-bg); color: var(--success); }
.vu-pie-caja.cerrada { background: var(--danger-bg); color: var(--danger); }

/* ---- Pestañas: solo en pantallas chicas ---- */

.vu-tabs { display: none; }

.vu-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    margin-left: 4px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--accent-contrast);
    font-size: 0.68rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.vu-badge.cero { background: var(--border); color: var(--text-muted); }

/* Debajo de 960px las tres columnas no entran sin encogerse a un ancho donde
   ya no se leen. Se pasa a pestañas y NO a columnas apiladas: apilar obliga a
   scrollear para llegar al botón Cobrar, que es justo lo que esta vista viene
   a evitar. Sigue siendo una sola pantalla lógica — cambiar de pestaña acá no
   recarga nada ni pierde el contexto, solo muestra otra columna. */
@media (max-width: 960px) {
    .vu-tabs {
        display: flex;
        gap: 6px;
        margin-bottom: 10px;
    }

    .vu-tab {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 42px;
        padding: 6px 8px;
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
        background: var(--surface);
        color: var(--text-muted);
        font-size: 0.8rem;
        font-weight: 700;
        cursor: pointer;
    }

    .vu-tab.active {
        border-color: var(--accent);
        background: var(--surface-alt);
        color: var(--accent-dark);
    }

    .vu-grid { grid-template-columns: 1fr; }

    .vu-col { display: none; }
    .vu-panel[data-col="mesas"]  .vu-col[data-col="mesas"],
    .vu-panel[data-col="cocina"] .vu-col[data-col="cocina"],
    .vu-panel[data-col="cobro"]  .vu-col[data-col="cobro"] { display: flex; }

    /* El título de la columna lo dice ya la pestaña activa. */
    .vu-col-title { display: none; }

    .vu-lista, .vu-mesas-grid { max-height: none; overflow-y: visible; }

    /* 88px y no 72: la mesa ahora lleva ícono además del número, el monto
       y el tiempo. Por debajo de eso el ícono y el monto se pisan. En un
       celular de 360px siguen entrando tres por fila. */
    .vu-mesas-grid { grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
    .vu-card { animation: none; }
    .vu-mesa, .vu-btn-listo, .vu-btn-cobrar, .vu-switch-btn { transition: none; }
}

/* ============ NOMBRE DEL COMPRADOR (consulta de RUC) ============

   Aparece bajo el campo de DNI/RUC del cobro cuando se completa un RUC.
   Ver la nota de onDocumentoInput() en frontend/js/mozo.js.

   Deliberadamente discreto: en esa pantalla lo importante es el TOTAL A
   COBRAR, y un cartel de colores compitiendo por la atención justo cuando
   hay alguien esperando el vuelto es exactamente lo que no se quiere.
   Ocupa una línea, no empuja el botón de cobrar fuera de la vista y se
   reserva su alto aunque esté vacío, para que nada salte al aparecer. */

.doc-info {
    /* min-height y no height: si el nombre es largo puede ocupar dos
       líneas, pero el alto mínimo evita el salto del layout al aparecer. */
    min-height: 1.15rem;
    margin-top: 5px;
    font-size: 0.76rem;
    line-height: 1.15rem;
    font-weight: 600;
    color: var(--text-muted);
    /* Un nombre muy largo no puede romper el ancho del modal. */
    overflow-wrap: anywhere;
}

/* Encontrado y en regla: se puede facturar sin más. */
.doc-info.ok { color: var(--money); }

/* De baja / no habido, o un número que no parece válido. Ámbar y no rojo a
   propósito: no es un error del cajero ni impide cobrar, es un dato que
   conviene mirar antes de emitir. El rojo acá haría pensar que algo se
   rompió. */
.doc-info.aviso { color: #92400E; }

/* No está en el padrón: puede ser un RUC nuevo o la copia local estar
   vieja. Tono neutro — no es un problema. */
.doc-info.neutro { color: var(--text-muted); }

.doc-info.buscando {
    color: var(--text-muted);
    opacity: 0.75;
}

/* ============ ACTIVACIÓN DE FACTURACIÓN (Admin > Boletas) ============

   Formulario de dos pasos que aparece al intentar prender el interruptor sin
   tener el certificado cargado. Ver abrirActivacionSunat() en admin.js.

   Reusa .form-group, .btn y los tokens de color de la app — nada de estilos
   nuevos para lo que ya existe, así se ve igual que el resto en un celular. */

.sunat-activacion {
    margin-top: 12px;
    padding: 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    animation: sunat-baja 0.22s ease-out;
}

@keyframes sunat-baja {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: none; }
}

/* Los dos pasos, para que se vea dónde está parado y cuánto falta. */
.sunat-pasos {
    display: flex;
    gap: 8px;
    margin: 0 0 16px;
    padding: 0;
    list-style: none;
}

.sunat-paso-chip {
    flex: 1;
    padding: 7px 6px;
    text-align: center;
    border-radius: 999px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    /* En 360px los dos textos entran justos: se permite romper antes que
       desbordar el ancho de la tarjeta. */
    overflow-wrap: anywhere;
}

.sunat-paso-chip.activo {
    background: var(--surface-alt);
    border-color: var(--accent);
    color: var(--accent-dark);
}

.sunat-paso-intro {
    margin: 0 0 14px;
    font-size: 0.83rem;
    line-height: 1.45;
    color: var(--text-muted);
}

/* Input + botón "Validar" en una línea; en pantallas muy angostas el botón
   pasa abajo a lo ancho, en vez de comprimir el campo del RUC. */
.sunat-fila-validar {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.sunat-fila-validar input {
    flex: 1 1 auto;
    min-width: 0;   /* sin esto, un flex item no baja de su ancho de contenido */
}

.sunat-fila-validar .btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

@media (max-width: 380px) {
    .sunat-fila-validar { flex-direction: column; }
}

/* Un campo de solo lectura tiene que VERSE de solo lectura: si parece
   editable, el usuario intenta corregirlo y no pasa nada. */
.sunat-activacion input[readonly] {
    background: var(--bg);
    color: var(--text-muted);
    cursor: default;
}

.sunat-activacion input[type="file"] {
    padding: 10px;
    font-size: 0.8rem;
}

.sunat-error {
    margin: 10px 0;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--danger-bg);
    color: var(--danger);
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.4;
}

/* "Cancelar": una salida que no compite con la acción principal. */
.btn-texto {
    display: block;
    width: 100%;
    margin-top: 10px;
    padding: 10px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}

/* ============ TIPO DE COMPROBANTE EN EL COBRO ============ */

/* Un RUC produce FACTURA, no boleta. Se muestra antes de cobrar para que
   nadie se entere después de recibir un comprobante distinto del que pidió. */
.comprobante-chip {
    display: inline-block;
    margin-left: 8px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--border);
    color: var(--text-muted);
    font-size: 0.64rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    vertical-align: middle;
}

.comprobante-chip.factura {
    background: var(--money);
    color: #FFFFFF;
}

/* ============ AVISO DE LA REGLA DE S/ 700 ============ */

.modal-content.aviso-sunat {
    max-width: 420px;
    padding: 26px 22px 22px;
    text-align: center;
    /* Centrado y no pegado abajo como los otros modales: no es un formulario
       para operar, es un mensaje para leer. */
    border-radius: var(--radius-lg);
    align-self: center;
    margin: auto 16px;
}

.aviso-sunat-icono {
    font-size: 2.4rem;
    line-height: 1;
    margin-bottom: 10px;
}

.modal-content.aviso-sunat h2 {
    margin: 0 0 10px;
    font-size: 1.15rem;
    /* Verde: lo PRIMERO que tiene que quedar claro es que la plata entró.
       Un título en rojo haría pensar que el cobro falló. */
    color: var(--success);
}

.modal-content.aviso-sunat p {
    margin: 0 0 12px;
    font-size: 0.87rem;
    line-height: 1.5;
    color: var(--text);
    text-wrap: balance;
}

.aviso-sunat-nota {
    padding: 11px 13px;
    border-radius: var(--radius-sm);
    background: var(--warning-bg);
    color: #92400E !important;
    font-size: 0.82rem !important;
}

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

/* Aviso del ambiente de pruebas. Ámbar y bien visible: sin esto, alguien
   podría creer que los comprobantes que emite acá son reales. */
.sunat-aviso-beta {
    margin-bottom: 14px;
    padding: 11px 13px;
    border-radius: var(--radius-sm);
    background: var(--warning-bg);
    color: #92400E;
    font-size: 0.8rem;
    line-height: 1.45;
}

/* Chip "Boleta · RUC del comprador" — Nuevo RUS.
   Azul y NO verde a propósito: verde es el chip de factura, y el cajero
   tiene que ver de un golpe que este comprobante es OTRA cosa. Un azul
   sobrio dice "esto es correcto y deliberado", mientras que un ámbar o un
   rojo harían pensar que algo salió mal — y no salió mal: es exactamente
   lo que la ley le permite emitir a un contribuyente del Nuevo RUS. */
.comprobante-chip.ruc-en-boleta {
    background: #1E40AF;
    color: #FFFFFF;
}

/* Bajo 360px (un Galaxy A51 en vertical entra justo) el chip más largo
   —"Boleta · RUC del comprador"— no cabe en la misma línea que el total.
   Se le permite romper y pasar a línea propia en vez de empujar el importe
   fuera de la pantalla, que es el dato que el cajero está mirando. */
@media (max-width: 380px) {
    .comprobante-chip {
        display: block;
        margin-left: 0;
        margin-top: 6px;
        width: fit-content;
        max-width: 100%;
        overflow-wrap: anywhere;
        white-space: normal;
        line-height: 1.35;
    }
}

/* Panel de la regla de S/ 700 — fondo verde.
   Lo PRIMERO que tiene que quedar claro es que la plata entró: el cajero
   está parado frente al cliente y esa es su duda inmediata. El pendiente
   del comprobante va abajo, en ámbar, como lo secundario que es. */
.modal-content.aviso-sunat {
    background: var(--success-bg);
    border: 1px solid var(--success);
}

.modal-content.aviso-sunat p {
    color: #14532D;
}

/* ============ MODAL DE COBRO (3 pestañas) ============
   Ver el bloque de abrirModalCobro() en frontend/js/mozo.js. */


.cobro-tabs {
    display: flex;
    gap: 4px;
    margin-bottom: 16px;
    border-bottom: 2px solid var(--border);
}

.cobro-tab-btn {
    flex: 1;
    /* 44px: el mínimo táctil cómodo con el pulgar, mismo criterio que el
       resto de la app. */
    min-height: 44px;
    padding: 10px 6px;
    border: none;
    border-bottom: 3px solid transparent;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
    transition: color 0.18s, border-color 0.18s;
    /* En 360px las tres etiquetas entran justas: se permite romper antes
       que desbordar el modal. */
    overflow-wrap: anywhere;
    line-height: 1.25;
}

.cobro-tab-btn.active {
    color: var(--accent-dark);
    border-bottom-color: var(--accent);
}

.cobro-tab {
    animation: cobro-entra 0.18s ease-out;
}

@keyframes cobro-entra {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.cobro-ayuda {
    margin: 0 0 14px;
    font-size: 0.83rem;
    line-height: 1.45;
    color: var(--text-muted);
    text-wrap: balance;
}

/* Aviso del tope de S/ 700. Ámbar: no es un error del cajero, es una regla
   de SUNAT que conviene ver ANTES de cobrar. */
.cobro-aviso {
    margin-bottom: 14px;
    padding: 11px 13px;
    border-radius: var(--radius-sm);
    background: var(--warning-bg);
    color: #92400E;
    font-size: 0.8rem;
    line-height: 1.45;
}

.cobro-empresa {
    padding: 12px 13px;
    margin-bottom: 14px;
    background: var(--surface-alt);
    border-radius: var(--radius-sm);
}

.cobro-empresa-label {
    display: block;
    margin-bottom: 6px;
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.cobro-empresa input {
    width: 100%;
    font-weight: 700;
}

/* Un campo de solo lectura tiene que VERSE de solo lectura: si parece
   editable, alguien intenta corregirlo y no pasa nada. */
#modal-cobro input[readonly] {
    background: var(--bg);
    color: var(--text-muted);
    cursor: default;
}

.cobro-botonera {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 8px;
}

/* Bajo 360px los dos botones lado a lado dejan el principal demasiado
   angosto para el pulgar; se apilan, con "Cobrar" arriba. */
@media (max-width: 360px) {
    .cobro-botonera { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
    .cobro-tab { animation: none; }
    .cobro-tab-btn { transition: none; }
}

/* El chip del comprobante dentro de la pestaña RUC. Va arriba del nombre de
   la empresa: es lo primero que el cajero necesita confirmar —qué documento
   va a salir— antes de mirar a nombre de quién. */
.cobro-chip-fila {
    margin-bottom: 10px;
}

.cobro-chip-fila .comprobante-chip {
    margin-left: 0;
    font-size: 0.7rem;
    padding: 5px 11px;
}
