/* Sistema visual base mobile-first/tablet/escritorio; foco visible;
   contraste; prefers-reduced-motion; táctiles >=44px; SVG de barras nunca
   con style inline (hourlyBarsHtml en app.js). Pedido del dueño: radios
   generosos en todo el panel, mismo criterio en cada botón/campo/tarjeta --
   ninguna prueba fija un valor exacto de border-radius. */

* { box-sizing: border-box; }
html, body { min-height: 100%; overscroll-behavior-y: none; }
body { margin: 0; font-family: var(--font-family-base); background: var(--page-bg); color: var(--text-primary); }
.wrap { width: 100%; max-width: 900px; margin: 0 auto; padding: 12px; }
.login-box { max-width: 320px; margin: 40px auto; background: var(--surface-bg); padding: 20px; border-radius: var(--radius-xl); box-shadow: var(--shadow-raised); }
.login-box label { display: block; font-size: 13px; margin-top: 8px; }
.login-box input { width: 100%; padding: 10px; margin: 6px 0; border-radius: 10px; border: 1px solid var(--border-color); min-height: 44px; }
.login-box button { width: 100%; padding: 10px; margin-top: 10px; border: none; border-radius: 10px; background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); font-weight: 700; min-height: 44px; cursor: pointer; }
/* Cabecera: superficie clara (no banner de color), título humano sin rol
   entre paréntesis, rol como contexto discreto debajo (shellHeaderHtml en
   app.js), "Salir" sin competir en peso con el título. */
header { position: relative; overflow: hidden; display: flex; flex-wrap: nowrap; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 12px; padding: 12px 14px; background: var(--surface-bg); border-radius: var(--radius-xl); box-shadow: var(--shadow-resting); }
.header-title { position: relative; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
header > button { position: relative; }
header h2 { margin: 0; font-size: clamp(18px, 4vw, 24px); font-weight: 800; letter-spacing: -.01em; line-height: 1.12; overflow-wrap: anywhere; color: var(--text-primary); }
.header-context { align-self: flex-start; margin: 0; padding: 3px 8px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--action-primary-strong-bg) 9%, transparent); font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--action-primary-strong-bg); }
.ghost-button { flex: 0 0 auto; min-height: 44px; padding: 8px 14px; border: none; background: transparent; color: var(--text-secondary); font-weight: 700; cursor: pointer; }
table { width: 100%; border-collapse: collapse; background: var(--surface-bg); border-radius: var(--radius-xl); overflow: hidden; box-shadow: var(--shadow-resting); }
/* MC4.5 -- fondo/superficies ambientales. --page-bg (real, por familia) y
   --action-primary-strong-bg (petróleo, estable en las 6 familias) siguen
   siendo la fuente; --staff-ambient-warm (tokens.css, .theme-staff) es un
   token propio de decoración, fijo, que nunca redefine estados. */
body.theme-staff { position: relative; }
body.theme-staff::before, body.theme-staff::after {
  content: ""; position: fixed; z-index: 0; pointer-events: none;
  border-radius: 50%; filter: blur(70px);
}
body.theme-staff::before {
  top: -200px; right: -160px; width: 560px; height: 560px;
  background: radial-gradient(circle, color-mix(in srgb, var(--action-primary-strong-bg) 16%, transparent), transparent 70%);
}
body.theme-staff::after {
  bottom: -240px; left: -200px; width: 640px; height: 640px;
  background: radial-gradient(circle, color-mix(in srgb, var(--action-primary-strong-bg) 10%, transparent), transparent 72%);
}
.wrap { position: relative; }
.wrap::after {
  content: ""; position: fixed; z-index: 0; pointer-events: none;
  bottom: 10%; right: 8%; width: 360px; height: 360px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--staff-ambient-warm) 7%, transparent), transparent 72%);
  filter: blur(80px);
}
#app { position: relative; z-index: 1; }
/* Halo recortado por el propio radio del header -- nunca una línea de borde a borde. */
header::before {
  content: ""; position: absolute; top: -50px; left: -50px;
  width: 160px; height: 160px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--staff-ambient-warm) 24%, transparent), transparent 72%);
  pointer-events: none; z-index: 0;
}
th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border-subtle); font-size: 14px; }
/* Resalta la fila bajo el cursor; excluye abandonada/prioridad para no
   tapar esa señal con el resalte neutro. */
tbody tr:not(.abandoned):not(.priority-urgente):not(.priority-alta):hover td { background: var(--border-subtle); }
tr.abandoned { background: var(--state-warning-row-bg); color: var(--state-warning-row-text); }

/* Decisión del dueño (2026-09-10): "Mesas activas" se lee como bloques en
   CUALQUIER ancho, no solo en el colapso móvil de @media(max-width:767px).
   A propósito NO se toca ningún `display:` aquí -- ese `display:` solo
   vive dentro del bloque móvil (fijado por
   tests/staff-ui-visual3-css.test.ts). El efecto de "bloque" se logra con
   border-collapse:separate + espacio entre filas + esquinas redondeadas:
   sigue siendo una tabla real, solo se ve como tarjetas. */
.dashboard-table { border-collapse: separate; border-spacing: 0 12px; background: transparent; box-shadow: none; overflow: visible; }
.dashboard-table > thead th { border-bottom: none; padding-bottom: 4px; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-secondary); }
.dashboard-table > tbody > tr[data-session] { box-shadow: var(--shadow-resting); }
.dashboard-table > tbody > tr[data-session] > td { background: var(--surface-bg); border-bottom: none; }
.dashboard-table > tbody > tr[data-session] > td:first-child { border-top-left-radius: var(--radius-xl); border-bottom-left-radius: var(--radius-xl); }
.dashboard-table > tbody > tr[data-session] > td:last-child { border-top-right-radius: var(--radius-xl); border-bottom-right-radius: var(--radius-xl); }
/* Jerarquía de lectura en 3 segundos: mesa primero (más grande/oscuro),
   estado justo detrás -- el resto de columnas se queda en el tamaño base. */
.dashboard-table > tbody > tr[data-session] > td:first-child { font-weight: 800; font-size: 16px; }
.dashboard-table > tbody > tr[data-session] > td:nth-child(2) { font-weight: 700; }
/* Pisado explícito: el fondo del <td> de arriba pintaría encima del color
   de estado (abandonada/prioridad) puesto en el <tr>. */
.dashboard-table > tbody > tr[data-session].abandoned > td { background: var(--state-warning-row-bg); color: var(--state-warning-row-text); }
.dashboard-table > tbody > tr[data-session].priority-urgente > td { background: var(--state-danger-row-bg); color: var(--state-danger-row-text); }
.dashboard-table > tbody > tr[data-session].priority-alta > td { background: var(--state-warning-badge-bg); color: var(--state-warning-badge-text); }
.dashboard-table > tbody > tr.payments-row > td { background: transparent; box-shadow: none; border-radius: 0; }
.badge { padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; }
.badge-pending { background: var(--state-warning-badge-bg); color: var(--state-warning-badge-text); }
.badge-abandoned { background: var(--state-danger-badge-abandoned-bg); color: var(--state-danger-badge-abandoned-text); }
.badge-ok { background: var(--state-success-badge-bg); color: var(--state-success-badge-text); }
/* Lluvia de ideas (lista nueva), item 9 ("sustituciones sugeridas"). */
.menu-substitute-note { display: inline-block; margin-left: 8px; font-size: 12px; color: var(--text-secondary); }
/* Decisión del dueño (2026-09-10): el personal ajusta cuánto calcula
   quedarse una mesa aquí mismo (columna Inactividad, setStayEstimate en
   sessionService.ts). Tratamiento visual de control normal, no de acción
   crítica. */
.stay-estimate-select-label { display: block; margin-top: 6px; font-size: 11px; font-weight: 700; color: var(--text-secondary); }
.stay-estimate-select { display: block; width: 100%; margin-top: 2px; padding: 6px 8px; min-height: 40px; border-radius: 10px; border: 1px solid var(--border-color); background: var(--surface-bg); color: var(--text-primary); font-size: 13px; font-weight: 600; }
/* Confirmar/corregir el número real de comensales -- el estimado puede
   estar mal (columna Comensales, setExpectedParticipantCount). */
.guest-count-confirm-btn { display: block; width: 100%; margin-top: 6px; padding: 6px 8px; min-height: 40px; border: 1px solid var(--border-color); border-radius: 10px; background: var(--control-secondary-bg); color: var(--control-secondary-text); font-size: 13px; font-weight: 700; cursor: pointer; }
/* Decisión del dueño (2026-09-10): cada persona conectada se ve como un
   bloque identificable con su nombre -- tocarlo deja al personal
   ponerle/corregirle el nombre (setParticipantAlias, sessionService.ts). */
.participant-chip-list { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; padding: 0; }
.participant-chip { padding: 4px 10px; min-height: 32px; border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: var(--surface-bg); color: var(--text-primary); font-size: 12px; font-weight: 700; cursor: pointer; }
.participant-chip-placeholder { cursor: default; display: inline-flex; align-items: center; opacity: .75; }
.actions button { margin: 0 6px 6px 0; padding: 8px 10px; min-height: 44px; border: none; border-radius: 10px; cursor: pointer; }
.btn-confirm { background: var(--state-success-strong-bg); color: var(--state-success-strong-text); }
/* Coral -- la ÚNICA acción de "comprometer el pedido" (Agregar/Guardar en
   el personalizador, Enviar pedido a cocina), mismo rol que el CTA de
   Cliente. Nunca se reparte en más botones que estos dos. Escopado como
   `button.btn-emphasis` (tipo+clase): mismo hallazgo de especificidad que
   .mp-option-label -- ".accessible-dialog-content button" (dialog.css)
   también le gana a ".btn-emphasis" sola dentro del personalizador. */
button.btn-emphasis { background: var(--action-emphasis-strong-bg); color: var(--action-emphasis-strong-text); font-weight: 700; }
.btn-reactivate { background: var(--state-warning-badge-bg); color: var(--state-warning-badge-text); }
.btn-request { background: var(--state-info-strong-bg); color: var(--state-info-strong-text); }
/* Primer incremento visual -- "Cuenta / Pagos" es la acción SECUNDARIA de
   la fila de Mesas (la primaria es "Pedir cuenta", .btn-request, que
   conserva su relleno sólido sin cambios -- se usa en varias pantallas
   de Administración, fuera de alcance de este incremento). Único
   consumidor real de .btn-pay hoy: la fila de Mesas activas. */
.btn-pay { background: transparent; border: 1px solid var(--action-payment-strong-bg); color: var(--action-payment-strong-bg); font-weight: 600; }
/* Primer incremento visual -- destructiva SIEMPRE secundaria (Cerrar,
   Cancelar, Quitar, Revocar, Abandonar): contorno, nunca relleno sólido,
   mismo criterio ya usado en Cocina (.btn-reject) para que nunca compita
   en peso con la acción primaria de la misma fila/bloque. */
.btn-close { background: transparent; border: 1px solid var(--state-danger-strong-bg); color: var(--state-danger-strong-bg); font-weight: 600; }

/* MC3 -- acción secundaria junto a una primaria fuerte (.btn-request), sin competir en peso. */
.btn-secondary-inline { padding: 8px 12px; min-height: var(--touch-target-min); border: 1px solid var(--border-color); border-radius: 10px; background: transparent; color: var(--text-secondary); font-weight: 600; font-size: 13px; }
.dashboard-action-list .btn-pay { border-color: var(--action-payment-strong-bg); background: color-mix(in srgb, var(--action-payment-strong-bg) 7%, transparent); color: var(--action-payment-strong-bg); font-weight: 700; }

.payments-row td { background: var(--surface-payments-soft-bg); color: var(--surface-payments-soft-text); padding: 14px; }
.payments-panel { padding: 12px; border: 1px solid var(--border-subtle); border-radius: var(--radius-xl); background: var(--surface-bg); box-shadow: var(--shadow-resting); }
.payments-panel h4 { margin: 12px 0 6px; font-size: 14px; }
.pay-grid { display: flex; gap: 20px; flex-wrap: wrap; }
.pay-col { flex: 1; min-width: 280px; }
/* border-radius/box-shadow en 0/none a propósito: sin esto, heredaría la
   elevación de la regla `table` de arriba y quedaría una tarjeta flotando
   dentro de una fila ya resaltada (.payments-row td) -- una tabla anidada
   no es una superficie propia. */
.pay-table { width: 100%; border-collapse: collapse; background: var(--surface-bg); font-size: 13px; border-radius: 0; box-shadow: none; }
.pay-table th, .pay-table td { padding: 6px 8px; border-bottom: 1px solid var(--border-subtle); text-align: left; }
.pay-totals { margin: 8px 0; font-size: 13px; display: flex; flex-direction: column; gap: 2px; }
.pay-order-summary { margin: 12px 0; padding: 10px; border: 1px solid var(--border-subtle); border-radius: 10px; background: var(--surface-muted-bg); }
.pay-order-summary summary { min-height: 44px; display: flex; align-items: center; font-weight: 700; cursor: pointer; }
.pay-order-summary ol, .pay-order-summary ul { margin: 6px 0; padding-left: 22px; }
.payments-panel label { display: block; margin: 6px 0; font-size: 13px; }
.payments-panel select { width: 100%; padding: 8px; border-radius: 10px; border: 1px solid var(--border-color); min-height: 44px; }
.btn-register-payment { margin-top: 8px; padding: 10px 12px; min-height: 44px; border: none; border-radius: 10px; background: var(--action-payment-strong-bg); color: var(--action-payment-strong-text); font-weight: 700; cursor: pointer; }
.pay-close-ready, .pay-close-note { margin: 8px 0; padding: 12px; border: 1px solid var(--border-subtle); border-radius: 12px; background: var(--surface-muted-bg); color: var(--text-primary); }
.pay-close-ready p, .pay-close-note p { margin: 4px 0 10px; }
.btn-resume-paid { width: 100%; min-height: 44px; margin-bottom: 8px; padding: 10px 12px; border: none; border-radius: 10px; background: var(--state-warning-badge-bg); color: var(--state-warning-badge-text); font-weight: 700; cursor: pointer; }
.btn-close-paid { width: 100%; min-height: 44px; padding: 10px 12px; border: none; border-radius: 10px; background: var(--state-danger-strong-bg); color: var(--state-danger-strong-text); font-weight: 700; cursor: pointer; }
.btn-void { padding: 8px; min-height: 44px; border: none; border-radius: 10px; background: var(--state-danger-strong-bg); color: var(--state-danger-strong-text); cursor: pointer; }
.btn-force-close { margin-top: 8px; padding: 10px 12px; min-height: 44px; border: none; border-radius: 10px; background: var(--action-force-strong-bg); color: var(--action-force-strong-text); font-weight: 700; cursor: pointer; }
.btn-force-close:disabled { background: var(--control-disabled-bg); color: var(--control-disabled-text); cursor: not-allowed; }
.pay-msg { font-size: 13px; font-weight: 600; min-height: 18px; }

/* Fase 7, Incremento D1: mensajes de estado — reemplazan cualquier
   `style="color:..."` inline anterior (docs/15 sección 8). */
.msg-error { color: var(--state-danger-fg); }
.msg-success { color: var(--state-success-fg); }

/* Fase 7, Incremento D1 (docs/15 sección 3.5): navegación agrupada
   Operación/Administración — el grupo Administración lo agregan D2/D3/D4,
   sin estructura vacía en D1. */
.nav-groups { display: grid; gap: 10px; margin-bottom: 14px; }
.nav-group { margin: 0; padding: 10px; background: var(--surface-bg); border: 1px solid var(--border-subtle); border-radius: 16px; box-shadow: var(--shadow-resting); }
.nav-group-label { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-secondary); margin-bottom: 4px; }
.tabbar { display: flex; gap: 6px; flex-wrap: wrap; }
/* Hallazgo real (medido en navegador): [hidden] es una regla del USER
   AGENT -- una regla de AUTOR como ".tabbar { display:flex }" gana
   siempre sobre ella sin importar especificidad, así que #gestionPanel
   seguía visible pese a `hidden`. Mismo bug y misma corrección exactos
   que Cocina (.item-note-clamp:not([hidden])). */
#gestionPanel[hidden] { display: none; }
.tab-btn { padding: 9px 13px; min-height: 44px; border: 1px solid transparent; border-radius: 999px; background: var(--control-secondary-bg); color: var(--control-secondary-text); font-weight: 700; cursor: pointer; }
.tab-btn.active { background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); box-shadow: var(--shadow-raised); }
/* "Gestión" -- disclosure secundario a propósito (fondo plano, sin
   elevación) para que las cuatro acciones operativas de arriba dominen. */
.nav-group-secondary { background: transparent; border: none; box-shadow: none; padding: 0; }
.nav-disclosure-btn { display: inline-flex; align-items: center; gap: 6px; min-height: var(--touch-target-min); padding: 6px 14px; border: 1px solid var(--border-color); border-radius: 999px; background: transparent; color: var(--text-secondary); font-weight: 700; font-size: 13px; cursor: pointer; }
.nav-disclosure-btn::after { content: "▾"; font-size: 10px; }
.nav-disclosure-btn[aria-expanded="true"]::after { content: "▴"; }
.nav-group-secondary .tabbar { margin-top: 8px; }
.nav-group-secondary .tab-btn { min-height: var(--touch-target-min); padding: 7px 12px; font-size: 13px; font-weight: 600; }

/* Incremento 5 -- 3 bloques con título en vez de 11 píldoras planas; auto-fit colapsa a 1 columna sin media query. */
.gestion-groups { margin-top: 8px; display: grid; grid-template-columns: 1fr; gap: 14px; }
/* MC4.5 -- cada grupo como superficie reconocible (tinte marfil propio,
   borde, punto de color por grupo), nunca tarjeta-dentro-de-tarjeta. */
.gestion-group-block {
  background: color-mix(in srgb, var(--surface-bg) 92%, var(--action-primary-strong-bg) 3%);
  border: 1px solid var(--border-color); border-radius: 14px; padding: 14px 14px 8px;
}
.gestion-group-title { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-secondary); margin-bottom: 6px; padding-bottom: 6px; border-bottom: 1px solid var(--border-subtle); }
.gestion-group-title::before {
  content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--mc45-group-dot, var(--action-primary-strong-bg));
}
.gestion-group-block:nth-of-type(1) .gestion-group-title { --mc45-group-dot: var(--action-primary-strong-bg); }
.gestion-group-block:nth-of-type(2) .gestion-group-title { --mc45-group-dot: var(--staff-ambient-warm); }
.gestion-group-block:nth-of-type(3) .gestion-group-title { --mc45-group-dot: var(--text-secondary); }
.gestion-dest-list { display: flex; flex-direction: column; gap: 4px; }
.gestion-dest-btn { display: block; width: 100%; text-align: left; min-height: var(--touch-target-min); padding: 7px 10px; border-radius: 10px; font-weight: 400; background: var(--surface-bg); }
.gestion-dest-name { display: block; font-weight: 700; font-size: 13.5px; }
.gestion-dest-btn.active .gestion-dest-desc { color: inherit; opacity: .85; }
.gestion-dest-desc { display: block; font-size: 11.5px; color: var(--text-secondary); margin-top: 1px; }

/* Las tablas operativas mantienen semántica de tabla en escritorio, pero las
   acciones críticas quedan visibles sin desplazamiento lateral en teléfonos. */
.operations-action-list { display: flex; flex-wrap: wrap; gap: 6px; }
/* Acción de GESTIÓN, no la acción del mesero -- contorno discreto, nunca
   compite con las filas de solicitudes de abajo. */
.btn-config { margin-bottom: 12px; padding: 8px 12px; min-height: var(--touch-target-min); border: 1px solid var(--border-color); border-radius: 10px; background: transparent; color: var(--text-secondary); font-weight: 600; font-size: 13px; cursor: pointer; }
tr.priority-urgente { background: var(--state-danger-row-bg); color: var(--state-danger-row-text); }
tr.priority-alta { background: var(--state-warning-badge-bg); color: var(--state-warning-badge-text); }
h3 { margin: 20px 0 8px; font-size: 16px; font-weight: 800; letter-spacing: -.01em; }
/* MC3 -- historial deja de ocupar espacio permanente; <details> nativo con conteo en el resumen. */
.history-disclosure { margin-top: 20px; }
.history-disclosure summary { font-size: 16px; font-weight: 800; letter-spacing: -.01em; cursor: pointer; padding: 4px 0; }
.history-disclosure .history-table { margin-top: 8px; }

/* Fase 6, Incremento B — pestaña Analítica */
.an-toolbar { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; background: var(--surface-bg); padding: 10px 12px; border-radius: 16px; box-shadow: var(--shadow-resting); }
.an-toolbar label { font-size: 13px; display: flex; align-items: center; gap: 4px; }
.an-toolbar select, .an-toolbar input[type="date"] { padding: 8px; min-height: 44px; border-radius: 10px; border: 1px solid var(--border-color); }
.an-toolbar button { padding: 10px 14px; min-height: 44px; border: none; border-radius: 10px; background: var(--state-info-strong-bg); color: var(--state-info-strong-text); font-weight: 700; cursor: pointer; }
.an-legend { font-size: 12px; color: var(--surface-legend-text); background: var(--surface-legend-bg); padding: 8px 10px; border-radius: 10px; margin: 0 0 10px; }
.an-warning { font-size: 12px; color: var(--state-warning-soft-text); background: var(--state-warning-soft-bg); padding: 8px 10px; border-radius: 10px; margin: 0 0 10px; }
.an-cards { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.an-card { background: var(--surface-bg); border-radius: 16px; padding: 12px 14px; min-width: 160px; flex: 1; box-shadow: var(--shadow-resting); }
.an-card h4 { margin: 0 0 4px; font-size: 12px; color: var(--text-secondary); font-weight: 600; }
.an-card p { margin: 0; font-size: 20px; font-weight: 700; }
.an-card small { color: var(--text-secondary); font-size: 11px; }

/* Fase 7, Incremento D1 (docs/15 sección 8, hallazgo 3): barras por hora
   como SVG con atributos de geometría (`height` en el `<rect>`, generado en
   app.js) — nunca `style="height:...%"`. `fill` vive aquí, en la hoja de
   estilos (`'self'`), no como estilo inline. */
.hourly-bars-wrap { background: var(--surface-bg); border-radius: 16px; padding: 8px; margin-bottom: 16px; }
.hourly-bars-svg { width: 100%; height: 90px; display: block; }
.hourly-bar-rect { fill: var(--chart-primary-fill); }
.hourly-bar-labels { display: flex; }
.hourly-bar-label { flex: 1; text-align: center; font-size: 8px; color: var(--text-secondary); }

/* Pedido del dueño (2026-09-05): dona (donutChartHtml) y barras
   horizontales (horizontalBarsHtml) en app.js. Misma disciplina que las
   barras por hora: fill/stroke viven aquí (CSP), geometría como atributos
   SVG en app.js, nunca style= inline. */
.donut-chart-wrap { display: flex; align-items: center; gap: 16px; background: var(--surface-bg); border-radius: 16px; padding: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.donut-chart-svg { width: 120px; height: 120px; flex-shrink: 0; }
.donut-segment { fill: none; stroke-width: 8; }
.donut-segment-0 { stroke: var(--chart-categorical-1); }
.donut-segment-1 { stroke: var(--chart-categorical-2); }
.donut-segment-2 { stroke: var(--chart-categorical-3); }
.donut-segment-3 { stroke: var(--chart-categorical-4); }
.donut-chart-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: 13px; }
.donut-chart-legend li { display: flex; align-items: center; gap: 8px; }
.donut-legend-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; }
.donut-legend-swatch.donut-segment-0 { background: var(--chart-categorical-1); }
.donut-legend-swatch.donut-segment-1 { background: var(--chart-categorical-2); }
.donut-legend-swatch.donut-segment-2 { background: var(--chart-categorical-3); }
.donut-legend-swatch.donut-segment-3 { background: var(--chart-categorical-4); }

.hbar-chart { list-style: none; margin: 0 0 16px; padding: 12px; display: grid; gap: 8px; background: var(--surface-bg); border-radius: 16px; }
.hbar-row { display: grid; grid-template-columns: minmax(90px, 1fr) minmax(120px, 3fr) auto; align-items: center; gap: 10px; }
.hbar-label { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbar-track { width: 100%; height: 14px; display: block; }
.hbar-track-bg { fill: var(--control-secondary-bg); }
.hbar-fill { fill: var(--chart-primary-fill); }
.hbar-value { font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Fase 7, Incremento D2 (docs/15 sección 4) — formularios de administración
   (crear mesa, crear personal) dentro de "Administrar mesas"/"Personal". */
.admin-form { background: var(--surface-bg); border-radius: 16px; padding: 12px 14px; margin-bottom: 14px; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; box-shadow: var(--shadow-resting); }
.admin-field { flex: 1 1 180px; min-width: 0; }
.admin-form label { display: block; font-size: 13px; font-weight: 600; }
.admin-form input, .admin-form select { display: block; width: 100%; padding: 8px; margin-top: 4px; border-radius: 10px; border: 1px solid var(--border-color); min-height: 44px; min-width: 0; }
.admin-form button { padding: 10px 14px; min-height: 44px; border: none; border-radius: 10px; background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); font-weight: 700; cursor: pointer; }
.admin-form button[aria-busy="true"] { opacity: .7; cursor: progress; }
.admin-form .msg-error, .admin-form div[aria-live] { flex-basis: 100%; }

/* Banner de resultado incierto (docs/15 sección 4.3.3) — mismo contenedor
   para los tres caminos (Reintentar/Verificar/Abandonar). Dos clases
   semánticas (no el selector desnudo [aria-live="polite"], que antes
   coincidía con los siete contenedores sin distinguir intención). */
.uncertain-status:not(:empty), .status-notice:not(:empty) { background: var(--state-warning-soft-bg); color: var(--text-primary); border-radius: 10px; padding: 8px 10px; margin-bottom: 10px; }
.uncertain-status button { margin: 6px 6px 0 0; padding: 8px 10px; min-height: 44px; border: none; border-radius: 10px; cursor: pointer; }

/* Fase 7, Incremento D2 — secreto de credencial NFC/QR dentro del diálogo
   accesible: imagen del QR insertada vía `img.src` (nunca inline en HTML). */
.secret-qr { display: block; max-width: 220px; width: 100%; height: auto; margin: 8px 0; border: 1px solid var(--border-subtle); border-radius: 10px; }

/* .accessible-dialog* — movido íntegro a public/shared/dialog.css en el
   Incremento visual 5 (docs/24 sección 8.3): ahora compartido por los tres
   paneles, no exclusivo de Staff. */

/* Fase 7, Incremento D3 (docs/15 sección 5) — árbol Categoría→Producto→
   Grupo de modificadores→Opción. Indentación por nivel vía `padding-left` en
   cada `<ul>` anidado — nunca listas planas sin jerarquía visual, nunca
   tablas (la profundidad de 4 niveles no cabe bien en columnas). */
.menu-node { background: var(--surface-bg); border-radius: 16px; margin-bottom: 10px; box-shadow: var(--shadow-resting); }
.menu-group, .menu-option { list-style: none; border: 1px solid var(--border-subtle); padding: 8px 10px; margin-bottom: 8px; }
.menu-node-header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px; }
.menu-node-header p { margin: 0; font-size: 13px; }
.menu-group-list, .menu-option-list { list-style: none; margin: 10px 0 0; padding-left: 14px; border-left: 3px solid var(--border-menu-accent); }
.menu-layout-switch { display: inline-flex; gap: 4px; padding: 4px; border-radius: 999px; background: var(--control-secondary-bg); }
.menu-layout-switch button { min-height: 40px; padding: 7px 13px; border: 0; border-radius: 999px; background: transparent; color: var(--text-primary); font-weight: 700; cursor: pointer; }
.menu-layout-switch button[aria-pressed="true"] { background: var(--surface-bg); box-shadow: var(--shadow-resting); }
.table-guest-estimate { color: var(--text-secondary); font-size: 12px; }
.menu-empty { list-style: none; padding: 8px 0; font-size: 13px; color: var(--text-secondary); }

/* Microcierre MC-B -- .btn-request es azul informativo (compartido con
   "Pedir cuenta" en Mesas); las 4 acciones de creación del Menú necesitan
   su propio color, petróleo (--action-primary-strong-bg, estable en las 6
   familias), nunca ese azul. Focus-visible/disabled/hover ya los cubre la
   regla genérica de button de arriba -- solo superficie propia aquí. */
.menu-create-action { min-height: var(--touch-target-min); padding: 8px 14px; border: none; border-radius: 10px; background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); font-weight: 700; cursor: pointer; }

/* Master-detail (Incremento 6) -- 3 columnas desde 1024px; apiladas antes. */
.menu-md { display: flex; flex-direction: column; gap: 14px; }
.menu-col { background: var(--surface-bg); border-radius: 16px; box-shadow: var(--shadow-resting); padding: 12px; min-width: 0; }
.menu-col-header { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 8px; }
.menu-col-header h2 { margin: 0; font-size: 16px; }
.menu-category-list, .menu-product-list { list-style: none; margin: 0; padding: 0; }
.menu-col-row { border-radius: 10px; margin-bottom: 4px; }
.menu-col-row.is-selected { background: var(--control-secondary-bg); }
.menu-row-actions { padding: 0 var(--space-md) var(--space-sm); }
.menu-product-row .menu-row-select { display: flex; align-items: center; gap: 10px; }
.menu-product-row .menu-row-name, .menu-product-row .menu-row-meta { display: inline; }
.menu-detail-header { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.menu-detail-header h2 { margin: 0; font-size: 16px; }
#mt-body[data-layout="mosaic"] .menu-product-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
#mt-body[data-layout="mosaic"] .menu-product-row .menu-row-select { flex-direction: column; align-items: flex-start; }
#mt-body[data-layout="list"] .menu-product-list { display: block; }
/* Acordeón móvil (Incremento 6 MC-C) -- única copia del detalle, dentro de
   la fila del producto abierto (nunca duplicada; ver isMenuMobileViewport
   en app.js). padding-bottom respeta la safe-area del dispositivo. */
.menu-product-inline-detail {
  margin-top: var(--space-sm); padding: var(--space-sm) 0 calc(var(--space-sm) + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border-subtle);
}
@media (min-width: 768px) and (max-width: 1023px) {
  .menu-admin-wrap { max-width: 1100px; }
  .menu-md { display: grid; grid-template-columns: 1fr 1.6fr; align-items: start; gap: 14px; }
  .menu-col-detail { grid-column: 1 / -1; }
}
@media (min-width: 1024px) {
  .menu-admin-wrap { max-width: 1200px; }
  .menu-md { display: grid; grid-template-columns: 1fr 1.4fr 1.6fr; align-items: start; gap: 14px; }
}

/* Fase 7, Incremento D4 (docs/15 sección 4) — filtros y lista de auditoría. Los bloques JSON
   desplazan su propio contenido y nunca fuerzan overflow horizontal global. */
.audit-filters { background: var(--surface-bg); border-radius: 16px; padding: 12px 14px; margin-bottom: 10px; display: grid; grid-template-columns: 1fr; gap: 10px; box-shadow: var(--shadow-resting); }
.audit-filters label { font-size: 13px; font-weight: 600; }
.audit-filters small { display: block; color: var(--text-secondary); font-weight: 400; }
.audit-filters select, .audit-filters input { display: block; width: 100%; min-height: 44px; padding: 8px; margin-top: 4px; border: 1px solid var(--border-color); border-radius: 10px; }
.audit-filter-actions { display: flex; flex-wrap: wrap; align-items: end; gap: 8px; }
.audit-filter-actions button, .audit-filter-actions a, .audit-more { min-height: 44px; padding: 10px 14px; border: none; border-radius: 10px; background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); font-weight: 700; cursor: pointer; }
.audit-filter-actions .btn-secondary { background: var(--control-secondary-bg); color: var(--control-secondary-text); }
.audit-export-link { display: inline-flex; align-items: center; text-decoration: none; }
.audit-more { display: block; margin: 12px auto 0; }
.audit-more[hidden] { display: none; }

/* Bloque 2 del RELEVO 2026-09-03 (item 10) — Salud del menú: lista
   puramente informativa, sin ningún control de acción destructiva (ver
   tests/staff-ui-menu-health.test.ts). */
.menu-health-list { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 8px; }
.menu-health-item {
  background: var(--surface-bg); border-radius: 16px; padding: 10px 14px;
  box-shadow: var(--shadow-resting); display: flex; justify-content: space-between;
  align-items: center; flex-wrap: wrap; gap: 8px;
}
.menu-health-item-info { display: grid; gap: 2px; }
.menu-health-item-category { font-size: 12px; color: var(--text-secondary); }
.menu-health-item-flags { display: flex; gap: 6px; flex-wrap: wrap; }
.menu-health-flag {
  font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: var(--radius-pill);
  background: var(--state-warning-soft-bg); color: var(--state-warning-soft-text);
}

/* Pantalla de error genérica (pedido explícito del dueño) -- registro de
   incidentes técnicos, mismo lenguaje visual que .menu-health-item arriba. */
.incident-alert-badge {
  display: inline-block; min-width: 18px; padding: 1px 6px; border-radius: var(--radius-pill);
  background: var(--state-danger-strong-bg); color: var(--state-danger-strong-text);
  font-size: 11px; font-weight: 800; text-align: center;
}
.incident-list { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 8px; }
.incident-item {
  background: var(--surface-bg); border-radius: 16px; padding: 10px 14px;
  box-shadow: var(--shadow-resting); display: flex; justify-content: space-between;
  align-items: center; flex-wrap: wrap; gap: 8px;
  border-left: 4px solid var(--border-color);
}
.incident-item.incident-severity-alta { border-left-color: var(--state-danger-strong-bg); }
/* --state-warning-strong-bg es exclusivo de .theme-kitchen (no existe aquí)
   -- --action-force-strong-bg es un color sólido real YA verificado en
   .theme-staff, reutilizado solo por su valor visual (mismo criterio que
   --chart-categorical-2 más arriba en este archivo). */
.incident-item.incident-severity-media { border-left-color: var(--action-force-strong-bg); }
.incident-item.incident-severity-baja { border-left-color: var(--border-color); }
.incident-item-info { display: grid; gap: 2px; }
.incident-item-meta { font-size: 12px; color: var(--text-secondary); }
.incident-item-note { font-size: 12px; color: var(--text-secondary); font-style: italic; }
.incident-resolve-btn { background: var(--control-secondary-bg); color: var(--control-secondary-text); }

/* Pantalla de error genérica -- aviso de hora pico (¿cuánto calculas
   quedarte?), mismo lenguaje visual que .menu-health-item/.incident-item. */
.peak-hour-metric-list { list-style: none; margin: 8px 0 14px; padding: 0; display: grid; gap: 6px; }
.peak-hour-metric-row {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  background: var(--surface-bg); border-radius: 12px; padding: 8px 12px; box-shadow: var(--shadow-resting);
  font-size: 13px;
}
.peak-hour-metric-row.peak-hour-metric-active { border-left: 4px solid var(--state-danger-strong-bg); }
.peak-hour-metric-flag { font-weight: 700; }
.ph-range-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.ph-range-row input[type="number"] { width: 64px; }

/* Lluvia de ideas (lista nueva), item 12b ("colecciones con historia"). */
.collection-admin-create, .collection-admin-rename, .collection-admin-add {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; margin: 10px 0;
}
.collection-admin-field { display: grid; gap: 4px; flex: 1; min-width: 180px; font-size: 13px; font-weight: 600; }
.collection-admin-create input, .collection-admin-rename input, .collection-admin-add select {
  width: 100%; padding: 8px; min-height: 44px; border-radius: 10px; border: 1px solid var(--border-color); flex: 1; min-width: 0;
}
.collection-admin-create button, .collection-admin-rename button, .collection-admin-add button {
  padding: 10px 14px; min-height: 44px; border: none; border-radius: 10px;
  background: var(--state-info-strong-bg); color: var(--state-info-strong-text); font-weight: 700; cursor: pointer;
}
.collection-admin-list { display: grid; gap: 16px; margin-top: 14px; }
.collection-admin-card {
  background: var(--surface-bg); border-radius: 10px; padding: 14px; box-shadow: var(--shadow-resting);
}
.collection-admin-heading { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.collection-admin-heading h3 { margin: 0; }

/* Lluvia de ideas, item 5 antiguo / 12 nuevo ("galería de fotos con likes"). */
.gallery-admin-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-top: 14px; }
.gallery-admin-card { background: var(--surface-bg); border-radius: 10px; overflow: hidden; box-shadow: var(--shadow-resting); }
.gallery-admin-card img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.gallery-admin-card-body { padding: 10px; display: grid; gap: 6px; }
.gallery-admin-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.gallery-admin-actions button { min-height: 40px; padding: 6px 10px; border: none; border-radius: 10px; cursor: pointer; font-weight: 700; }
.menu-health-ok {
  display: flex; align-items: center; gap: 8px;
  background: var(--state-success-badge-bg); color: var(--state-success-badge-text);
}
.audit-entry { background: var(--surface-bg); border-radius: 16px; padding: 10px 12px; margin-bottom: 8px; box-shadow: var(--shadow-resting); }
.audit-entry summary { cursor: pointer; font-weight: 700; min-height: 44px; padding: 10px 4px; }
.audit-entry p { overflow-wrap: anywhere; }
.audit-entry h4 { margin: 12px 0 4px; font-size: 13px; }
.audit-entry pre { max-width: 100%; overflow-x: auto; padding: 10px; border-radius: 10px; background: var(--surface-muted-bg); color: var(--surface-muted-text); font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }

/* Foco visible en cualquier control interactivo — nunca `outline: none` sin
   sustituto (docs/15 sección 3.5). */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--focus-ring-color);
  outline-offset: 2px;
}

/* Retroalimentación visual al pasar el mouse/pulsar — antes ningún botón
   cambiaba hasta el clic. `filter: brightness()` funciona igual sobre
   cualquier color de fondo (botones de acento, tabs claras, tarjetas
   oscuras de cocina) sin necesitar una variante oscura por clase. Excluye
   deshabilitados para no sugerir que un botón inactivo responde al mouse. */
button:not(:disabled):hover, .tab-btn:hover { filter: brightness(0.93); }
button:not(:disabled):active, .tab-btn:active { filter: brightness(0.85); }
button:disabled { opacity: .6; cursor: not-allowed; }

/* Animaciones discretas (120-200ms) — nunca retrasan una acción operativa,
   solo decoran la aparición de tabs/diálogos. */
button, .tab-btn, .accessible-dialog { transition: background-color var(--transition-duration-base) ease, transform var(--transition-duration-base) ease, filter var(--transition-duration-fast) ease; }

/* Elevación real al pasar el mouse (mismo criterio ya usado en
   public/customer/styles.css) — antes ningún botón de Gerencia se
   despegaba de la superficie, solo cambiaba de brillo. `(hover: hover)
   and (pointer: fine)` es obligatorio: sin ese guard, tocar un botón en
   una tablet dejaría la elevación "pegada" hasta tocar otra parte de la
   pantalla. */
@media (hover: hover) and (pointer: fine) {
  button:not(:disabled):hover, .tab-btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-raised); }
}
@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.001ms !important; animation-duration: 0.001ms !important; }
}

/* Estados vacíos/de carga — antes texto plano pegado a la izquierda. Se
   aplican por selector estructural (`:only-child`, `[colspan]`), nunca
   requieren que app.js agregue una clase nueva en cada sitio. */
table td[colspan] { text-align: center; color: var(--text-secondary); padding: 28px 12px; }
#an-body > p:only-child, #am-body > p:only-child, #ap-body > p:only-child,
#mt-body > p:only-child, #au-body > p:only-child {
  text-align: center; color: var(--text-secondary); padding: 32px 16px; background: var(--surface-bg); border-radius: 16px; margin: 0;
}

/* Mobile-first: las reglas de arriba, sin media query, ya están pensadas
   para 360px (columnas apiladas, tablas con scroll horizontal). */
table { display: block; overflow-x: auto; white-space: nowrap; }

/* Tablet (768px+): más aire, tablas ya no necesitan forzar scroll si caben. */
@media (min-width: 768px) {
  .wrap { padding: 16px; }
  header { flex-direction: row; }
  table { display: table; white-space: normal; }
  .audit-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gestion-groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Escritorio (1280px+): límite de ancho más generoso para aprovechar la pantalla. */
@media (min-width: 1280px) {
  .wrap { max-width: 1100px; }
  .nav-groups { grid-template-columns: minmax(430px, auto) minmax(0, 1fr); align-items: start; }
  .audit-filters { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .gestion-groups { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Incremento visual 3 (docs/22): reglas base, válidas en todo ancho.
   .cell-label oculto visualmente pero NUNCA fuera del árbol accesible por
   sí solo (aria-hidden va en el HTML, sección 4.4); expandido dentro de
   @media(max-width:767px) más abajo. */
.dashboard-table .cell-label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.dashboard-table .dashboard-action-list { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }
/* MC4 -- Cerrar separado del resto, nunca al mismo peso visual (destructivo). */
.dashboard-table .dashboard-action-danger { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border-subtle); }

.menu-row-select {
  display: block; width: 100%; min-height: var(--touch-target-min);
  padding: var(--space-sm) var(--space-md); text-align: left; cursor: pointer;
  background: transparent; border: 0; color: inherit; font: inherit;
}
.menu-row-select:focus-visible { outline: 3px solid var(--focus-ring-color); outline-offset: 2px; }
.menu-row-name { display: block; font-weight: 700; }
.menu-row-meta { display: block; color: var(--text-secondary); font-size: 13px; }

.menu-node-header .actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.menu-product-photo {
  width: 96px; aspect-ratio: 4 / 3; border-radius: var(--radius-sm);
  overflow: hidden; background: var(--surface-muted-bg); color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center; text-align: center;
  font-size: 12px; flex-shrink: 0;
}
.menu-product-photo img { width: 100%; height: 100%; object-fit: cover; }
.product-image-editor {
  display: grid; gap: var(--space-sm); margin: var(--space-md) 0;
  padding: var(--space-md); border: 1px solid var(--border-color); border-radius: var(--radius-md);
}
.product-image-editor h3, .product-image-editor p { margin: 0; }
.product-image-preview {
  width: min(100%, 360px); aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: var(--radius-md); background: var(--surface-muted-bg);
  color: var(--text-secondary); display: flex; align-items: center; justify-content: center;
  text-align: center;
}
.product-image-preview img { width: 100%; height: 100%; object-fit: cover; }
.product-image-status { min-height: 20px; color: var(--text-secondary); }

.menu-search {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm);
  background: var(--surface-bg); padding: 10px 12px; border-radius: 16px;
  box-shadow: var(--shadow-resting); margin-bottom: var(--space-sm);
}
.menu-search label { font-size: 13px; font-weight: 600; }
.menu-search input {
  min-height: var(--touch-target-min); padding: 8px; border-radius: 10px;
  border: 1px solid var(--border-color); flex: 1; min-width: 200px;
}
.menu-search-clear {
  min-height: var(--touch-target-min); padding: 8px 14px; border: none;
  border-radius: 10px; background: var(--control-secondary-bg);
  color: var(--control-secondary-text); font-weight: 700; cursor: pointer;
}
.mt-search-icon { color: var(--text-secondary); }

/* Incremento visual 6 (docs/25 sección E.7) — motion de navegación real,
   aplicado a app.firstElementChild de cada vista, exclusivo de clics reales
   procesados por wireNavBar. */
@keyframes view-enter { from { opacity: 0; } to { opacity: 1; } }
.view-enter { animation: view-enter var(--transition-duration-base) ease; }

/* Incremento visual 6 (docs/25 sección F.6 Principio G) — indicador no
   destructivo de refresco, separado del cuerpo de cada subpanel. */
.refresh-status { font-size: 13px; color: var(--text-secondary); margin-bottom: var(--space-sm); }
.refresh-status[hidden] { display: none; }

/* Incremento visual 6 (docs/25 secciones F.7/F.9) — geometría de skeleton
   por subpanel, sobre las clases compartidas de shared/skeleton.css. */
.an-cards .an-skeleton-card { height: 70px; }
.an-skeleton-wide { height: 90px; width: 100%; margin-top: var(--space-sm); }
.an-skeleton-funnel { height: var(--touch-target-min); width: 220px; }
.skeleton-row { height: 44px; width: 100%; margin-bottom: var(--space-sm); }
#mt-body .skeleton-block { height: var(--touch-target-min); width: 100%; margin-bottom: var(--space-sm); }
#au-body .skeleton-card { height: 60px; width: 100%; margin-bottom: var(--space-sm); }

@media (max-width: 1023px) {
  .tabbar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tab-btn { width: 100%; border-radius: 12px; padding-inline: 8px; }

  .operations-table > thead {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .operations-table, .operations-table > tbody,
  .operations-table > tbody { display: block; width: 100%; }
  .operations-table { overflow: visible; box-shadow: none; background: transparent; white-space: normal; }
  .operations-table > tbody > tr {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 12px;
    width: 100%; margin-bottom: 10px; padding: 10px 12px; background: var(--surface-bg);
    border-radius: 16px; box-shadow: var(--shadow-resting);
  }
  .operations-table > tbody > tr > td {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    width: 100%; padding: 6px 0; border-bottom: 1px solid var(--border-subtle); white-space: normal;
    overflow-wrap: anywhere;
  }
  .operations-table > tbody > tr > td[data-label="Nota"],
  .operations-table > tbody > tr > td.actions,
  .operations-table > tbody > tr > td[colspan] { grid-column: 1 / -1; }
  .operations-table > tbody > tr > td:last-child { border-bottom: none; }
  .operations-table > tbody > tr > td::before {
    content: attr(data-label);
    color: var(--text-secondary); font-size: 11px; font-weight: 700; flex-shrink: 0;
  }
  .operations-table > tbody > tr > td.actions { display: block; }
  .operations-table > tbody > tr > td.actions::before { display: block; margin-bottom: 8px; }
  .operations-action-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .operations-action-list button { width: 100%; margin: 0; }
  .operations-table td[colspan] { display: block; }

  /* thead — nunca display:none (sacaría los th del árbol accesible, docs/22
     sección 4.4) — técnica clip, visible por defecto. Escopado con `>`
     (hijo directo), NUNCA un descendiente cualquiera: sin el `>` también
     ocultaba el <thead> propio de las tablas internas de pagos anidadas
     dentro de esta misma tabla -- bug real hallado en navegador. */
  .dashboard-table > thead {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .dashboard-table, .dashboard-table > tbody, .dashboard-table > tbody > tr,
  .dashboard-table > tbody > tr > td { display: block; width: 100%; }
  .dashboard-table { overflow: visible; box-shadow: none; background: transparent; }
  .dashboard-table > tbody > tr[data-session] {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0;
    background: var(--surface-bg); border-radius: 16px; box-shadow: var(--shadow-resting);
    padding: 10px 6px; margin-bottom: 10px;
  }
  .dashboard-table > tbody > tr[data-session]:not(.abandoned):not(.priority-urgente):not(.priority-alta):hover > td {
    background: var(--surface-bg);
  }
  /* [hidden] sigue siendo la fuente semántica; esto solo evita que la
     regla responsive de arriba (tr{display:block}) deje visible por
     accidente una fila marcada hidden (docs/22 sección 4.5/0). */
  .dashboard-table > tbody > tr.payments-row[hidden] { display: none; }
  .dashboard-table > tbody > tr > td {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    padding: 5px 0; border-bottom: 1px solid var(--border-subtle); white-space: normal;
  }
  .dashboard-table > tbody > tr[data-session] > td { padding-inline: 6px; }
  .dashboard-table > tbody > tr[data-session] > td:nth-child(5),
  .dashboard-table > tbody > tr[data-session] > td.actions { grid-column: 1 / -1; }
  .dashboard-table > tbody > tr[data-session] > td:last-child { border-bottom: none; }
  .dashboard-table .cell-label {
    position: static; width: auto; height: auto; padding: 0; margin: 0;
    overflow: visible; clip: auto; white-space: nowrap;
    font-weight: 700; color: var(--text-secondary); flex-shrink: 0;
  }
  .dashboard-table > tbody > tr > td.actions {
    flex-direction: column; align-items: stretch; gap: 8px; border-bottom: none;
  }
  .dashboard-table td.actions .cell-label { margin-bottom: 2px; }
  /* MC4 -- primaria arriba a todo lo ancho, secundaria(s) debajo; Cerrar en
     su propio bloque separado (.dashboard-action-danger, ya con borde). */
  .dashboard-table .dashboard-action-list { display: flex; flex-direction: column; width: 100%; gap: 8px; }
  .dashboard-table .dashboard-action-list button,
  .dashboard-table .dashboard-action-danger button { width: 100%; margin: 0; }

  /* tr.payments-row > td — la regla genérica de arriba (fila flex
     etiqueta/valor) no tiene sentido para un td[colspan="6"] que contiene
     .payments-panel completo, no un dato de columna. */
  .dashboard-table > tbody > tr.payments-row > td {
    display: block; padding: 0 12px 12px; border-bottom: none;
  }
  .dashboard-table .payments-panel { width: 100%; min-width: 0; }
  .dashboard-table .pay-grid { flex-direction: column; }
  .dashboard-table .pay-col { min-width: 0; width: 100%; }
  .dashboard-table .pay-table { display: block; overflow-x: auto; }
  .dashboard-table .pay-table.operations-table { overflow: visible; }

  /* .pay-table-history — la tabla "Pagos" de renderPaymentsPanel contiene
     una acción operativa real (botón "Anular", solo GERENTE, solo pagos
     REGISTRADO) en su última columna — columna fijada al borde derecho del
     área de scroll de ESA tabla específicamente, para que nunca quede
     descubierta solo mediante scroll (docs/22 sección 4.5, hallazgo 1 de
     la ronda v4). */
  .dashboard-table .pay-table-history th.pay-col-action,
  .dashboard-table .pay-table-history td.pay-col-action {
    position: sticky; right: 0; background: var(--surface-payments-soft-bg);
  }
  .dashboard-table .pay-table-history.operations-table td.pay-col-action {
    position: static; background: transparent;
  }
}

@media (max-width: 420px) {
  .dashboard-table > tbody > tr[data-session] { grid-template-columns: minmax(0, 1fr); }
}

/* Pestaña "Apariencia" de GERENTE -- la elección nunca depende solo de
   color: cada opción lleva el nombre real como texto, y "Guardar tema"
   comunica su estado con TEXTO, no solo con una clase visual. */
.apariencia-form { max-width: 560px; }
.apariencia-form fieldset { border: 1px solid var(--border-color); border-radius: 10px; padding: 12px; margin: 12px 0; }
.apariencia-form legend { font-weight: 700; padding: 0 6px; }
.theme-option {
  display: flex; align-items: center; gap: 10px; min-height: var(--touch-target-min);
  padding: 8px; border-radius: 16px; cursor: pointer;
}
.theme-option:has(input:checked) { background: var(--control-secondary-bg); }
.theme-option input[type="radio"] { width: 20px; height: 20px; flex-shrink: 0; }
.theme-option-label { font-weight: 600; }
.theme-option-group { flex-direction: column; align-items: flex-start; cursor: default; }
.theme-option-subgroup { display: flex; gap: 12px; margin-top: 6px; width: 100%; }
.theme-option-subgroup .theme-option { flex: 1; }
.theme-swatch { display: inline-flex; border-radius: 999px; overflow: hidden; border: 1px solid var(--border-color); flex-shrink: 0; }
.theme-swatch-dot { display: block; width: 16px; height: 24px; background: var(--action-primary-strong-bg); }
/* Fallback a --action-primary-strong-bg: nunca se usa en ejecución (cada
   muestra ya lleva su .theme-family-* propio); solo satisface la
   auditoría estática de tokens.test.ts, que no simula esa cascada. */
.theme-swatch-dot.theme-swatch-emphasis { background: var(--action-emphasis-strong-bg, var(--action-primary-strong-bg)); }
#apariencia-save { min-height: var(--touch-target-min); padding: 10px 20px; border: none; border-radius: 16px; background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); font-weight: 700; cursor: pointer; }
#apariencia-save:disabled { opacity: .6; cursor: not-allowed; }
#apariencia-feedback { margin-top: 10px; font-weight: 600; }

/* Vista previa grande y explícita del tema elegido (antes solo existían
   las muestras pequeñas). Mismo fallback que .theme-swatch-dot.
   theme-swatch-emphasis: --action-emphasis-strong-* nunca está definida
   en .theme-staff -- el fallback es real si faltara .theme-family-*. */
.apariencia-preview {
  border-radius: 16px; padding: 14px 16px; margin: 10px 0 6px; background: var(--action-primary-strong-bg);
  display: flex; flex-direction: column; gap: 10px;
}
.apariencia-preview-header { display: flex; flex-direction: column; gap: 2px; color: var(--action-primary-strong-text); }
.apariencia-preview-kicker { font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; opacity: .7; }
.apariencia-preview-btn {
  align-self: flex-start; border: none; border-radius: 999px; padding: 8px 16px; font-weight: 700; cursor: default;
  background: var(--action-emphasis-strong-bg, var(--action-primary-strong-bg));
  color: var(--action-emphasis-strong-text, var(--action-primary-strong-text));
}
.apariencia-preview-caption { font-size: 12px; color: var(--text-secondary); margin: 0 0 10px; }

/* Lluvia de ideas, item 14 ("mensaje cálido de cierre configurable"),
   mismos tokens y disciplina de botón/feedback ya usados arriba para el
   formulario de tema -- formulario visualmente distinto (separado por
   margen), pero coherente. */
.closing-message-form { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border-color); }
.closing-message-form label { display: block; font-weight: 600; margin-bottom: 6px; }
.closing-message-form textarea {
  width: 100%; min-height: 72px; padding: 10px; border: 1px solid var(--border-color);
  border-radius: 16px; font: inherit; resize: vertical;
}
.closing-message-count { font-size: 12px; color: var(--text-secondary); text-align: right; margin: 4px 0 12px; }
.closing-message-preview-label { font-size: 12px; font-weight: 700; color: var(--text-secondary); margin-bottom: 4px; }
.closing-message-preview {
  padding: 12px 14px; border-radius: 10px; background: var(--surface-legend-bg);
  color: var(--surface-legend-text); font-style: italic; margin-bottom: 14px;
}
#closing-message-save { min-height: var(--touch-target-min); padding: 10px 20px; border: none; border-radius: 16px; background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); font-weight: 700; cursor: pointer; }
#closing-message-save:disabled { opacity: .6; cursor: not-allowed; }
#closing-message-feedback { margin-top: 10px; font-weight: 600; }

.logo-form { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border-color); }
.logo-form label { display: block; font-weight: 600; margin: 10px 0 6px; }
.logo-form-preview { display: block; width: 96px; height: 96px; object-fit: contain; border-radius: 10px; background: var(--surface-legend-bg); margin: 10px 0; }
#logo-save { min-height: var(--touch-target-min); padding: 10px 20px; border: none; border-radius: 16px; background: var(--action-primary-strong-bg); color: var(--action-primary-strong-text); font-weight: 700; cursor: pointer; }
#logo-save:disabled { opacity: .6; cursor: not-allowed; }
#logo-remove { margin-left: 10px; }
#logo-feedback { margin-top: 10px; font-weight: 600; }

/* Primer incremento visual -- patrón menos intrusivo: cabe en menos
   espacio (280px, antes 420px) y menos alto (28vh, antes 38vh) sin perder
   el aviso ni su accesibilidad (role/aria-live intactos en readyAlert.js). */
.staff-ready-alert { position: fixed; inset: auto 16px 16px auto; z-index: 40; width: min(280px, calc(100vw - 32px)); max-height: 28vh; overflow: auto; box-sizing: border-box; padding: 12px; border: 2px solid var(--state-info-strong-bg); border-left-width: 6px; border-radius: 14px; background: var(--state-info-badge-bg); color: var(--state-info-badge-text); box-shadow: 0 6px 24px color-mix(in srgb, var(--state-info-strong-bg) 30%, transparent); overflow-wrap: anywhere; font-size: 13px; }
.staff-ready-alert[hidden] { display: none !important; }
.staff-ready-alert strong { font-size: 1.1rem; }
.staff-ready-alert p { margin: 8px 0; line-height: 1.4; }
.staff-ready-alert-tables { list-style: none; margin: 8px 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.staff-ready-alert-tables li { padding: 6px 10px; border-radius: 8px; background: color-mix(in srgb, var(--state-info-strong-bg) 14%, transparent); font-weight: 700; line-height: 1.3; }
.staff-ready-alert .staff-ready-alert-note { font-size: .8rem; }
.staff-ready-alert-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.staff-ready-alert-actions button { min-height: 44px; flex: 1; padding: 8px 12px; border: 1px solid var(--state-info-strong-bg); border-radius: 10px; background: var(--surface-bg); color: var(--state-info-badge-text); font: inherit; font-weight: 700; cursor: pointer; }
.staff-ready-alert-actions button:first-child { background: var(--state-info-strong-bg); color: var(--state-info-strong-text); }
.staff-ready-alert-actions button:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring-color); outline-offset: var(--focus-ring-offset); }
@media (prefers-reduced-motion: reduce) { .staff-ready-alert, .staff-ready-alert * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }

/* docs/51 sección 10 -- "Tomar pedido": el mesero arma un pedido de mesa
   desde su propio usuario. */
.tp-section { margin-bottom: 16px; padding: 14px; border-radius: 16px; background: var(--surface-bg); box-shadow: var(--shadow-resting); }
.tp-section label { display: block; margin-bottom: 10px; font-weight: 600; }
.tp-section select, .tp-product-controls input { width: 100%; min-height: var(--touch-target-min); margin-top: 4px; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: 10px; background: var(--field-bg); color: var(--field-text); font: inherit; box-sizing: border-box; }
.tp-product-list, .pending-order-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.tp-product-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; padding: 10px; border: 1px solid var(--border-color); border-radius: 12px; }
.tp-product-info { display: flex; flex-direction: column; gap: 2px; min-width: 160px; }
.tp-product-mods { margin: 4px 0 0; font-size: .8rem; color: var(--text-secondary); }
.tp-product-controls { display: grid; grid-template-columns: 70px minmax(0, 1fr) minmax(0, 1fr) auto; gap: 8px; align-items: end; flex: 1; min-width: 280px; }
/* Hallazgo real (visto en captura): un producto CON modificadores solo
   trae el botón "Personalizar" como único hijo -- heredaba la rejilla de
   4 columnas pensada para cantidad/asignar/nota/Agregar y quedaba
   aplastado en la primera columna de 70px, cortando el texto. */
.tp-product-controls:has(> button:only-child) { grid-template-columns: auto; justify-content: start; }
.tp-product-controls label { margin-bottom: 0; font-size: .75rem; }
.tp-product-controls button { min-height: var(--touch-target-min); padding: 8px 14px; border: none; border-radius: 10px; font-weight: 700; cursor: pointer; }
.pending-order-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--border-color); border-radius: 12px; }
.pending-order-info { display: flex; flex-direction: column; gap: 2px; }
/* Modificador como detalle secundario del plato -- mismo texto exacto de
   siempre, solo con su propio peso/color anulando la negrita heredada
   de <strong>. Reutiliza petróleo (ya es la acción/estructura primaria
   del panel), nunca un color nuevo. */
.item-modifiers { font-weight: 600; color: var(--action-primary-strong-bg); font-size: .9em; }
.pending-order-row button { min-height: var(--touch-target-min); padding: 6px 12px; border: none; border-radius: 10px; font-weight: 700; cursor: pointer; }
.tp-total-row { display: flex; justify-content: space-between; font-weight: 800; font-size: 1.1rem; padding: 10px 0; border-top: 1px solid var(--border-color); margin-top: 8px; }
#tp-submit { width: 100%; min-height: var(--touch-target-min); margin-top: 10px; padding: 10px; border: none; border-radius: 12px; font-weight: 700; cursor: pointer; }
@media (max-width: 640px) { .tp-product-controls { grid-template-columns: 1fr; } }

.pending-order-row { align-items: flex-start; }
.pending-order-actions { display: flex; gap: 8px; flex-shrink: 0; }
.pending-line-total, .mp-price-base { display: block; font-weight: 700; margin: 2px 0 6px; }
.pending-row-needs-review { border-color: var(--state-danger-fg); border-width: 2px; }
.pending-review-msg, .mp-group-error { margin: 4px 0 0; }
.pending-order-actions .btn-secondary { background: var(--control-secondary-bg); color: var(--control-secondary-text); }
.mp-group { border: 1px solid var(--border-color); border-radius: 10px; padding: 10px 12px; margin: 10px 0; }
.mp-group legend { font-weight: 700; padding: 0 4px; }
.mp-rule { margin: 0 0 8px; font-size: .8rem; color: var(--text-secondary); }
/* Hallazgo real (medido en navegador, no a ojo): `.accessible-dialog-content
   label` (public/shared/dialog.css) tiene MÁS especificidad (clase+tipo)
   que `.mp-option-label` (solo clase) -- ganaba siempre y forzaba
   `display: block`, apilando el radio/checkbox y el texto "NombreSin
   costo extra" sin separación real. `label.mp-option-label` iguala esa
   especificidad (tipo+clase); en un empate gana la hoja de estilos que
   carga después (styles.css, después de dialog.css) -- fila completa
   clicable (ya era un <label> real envolviendo el input), sin tocar JS. */
label.mp-option-label { display: flex; align-items: center; gap: 10px; min-height: var(--touch-target-min); padding: 6px 8px; margin: 4px 0; border-radius: 10px; font-weight: 400; cursor: pointer; }
label.mp-option-label:has(input:checked) { background: var(--control-secondary-bg); }
/* El control real vuelve a su tamaño nativo (antes 44x44, un círculo/
   cuadrado gigante) -- el objetivo táctil de 44px lo cumple la FILA
   completa de arriba, no el control dibujado. */
.mp-group input[type="checkbox"], .mp-group input[type="radio"] { width: 20px; height: 20px; min-width: 20px; min-height: 20px; margin: 0; flex-shrink: 0; accent-color: var(--action-primary-strong-bg); }
.mp-option-name { flex: 1; }
.mp-option-price { color: var(--text-secondary); font-size: .85rem; font-weight: 600; white-space: nowrap; }
.mp-subtotal { font-weight: 800; font-size: 1.05rem; margin: 10px 0; }
