/**
 * MAYTECH POS - Sistema de Diseno Global
 * Basado en la identidad visual de Servicio Tecnico > Nueva Orden (nuevo.php)
 * DISTRI MELI
 *
 * Paleta: Naranja + Gris oscuro + Blanco + Teal (acentos)
 * Tipografia: Compacta, bold, uppercase, tracking generoso
 * Formas: Bordes redondeados grandes (rounded-2xl/3xl), sombras profundas
 */

/* ═══════════════════════════════════════════════════════════════════
 * DESIGN TOKENS
 * ═══════════════════════════════════════════════════════════════════ */

:root {
    --may-orange: #f97316;
    --may-orange-dark: #c2410c;
    --may-orange-light: #fff7ed;
    --may-dark: #1f2937;
    --may-darker: #111827;
    --may-teal: #0d9488;
    --may-teal-dark: #0f766e;
    --may-surface: #ffffff;
    --may-bg: #f3f4f6;
    --may-danger: #dc2626;
    --may-success: #16a34a;
    --may-text: #1f2937;
    --may-label: #9ca3af;
    --may-border: #e5e7eb;
}

/* ═══════════════════════════════════════════════════════════════════
 * RESET & BASE
 * ═══════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    margin: 0; padding: 0;
    background-color: var(--may-bg);
    color: var(--may-text);
}

/* ═══════════════════════════════════════════════════════════════════
 * SCROLLBAR
 * ═══════════════════════════════════════════════════════════════════ */

::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: var(--may-bg); }
::-webkit-scrollbar-thumb { background: var(--may-orange); border-radius: 20px; }
.custom-scrollbar::-webkit-scrollbar { width: 5px; }
.custom-scrollbar::-webkit-scrollbar-thumb { background: var(--may-orange); border-radius: 20px; }

/* ═══════════════════════════════════════════════════════════════════
 * COMPONENTES PRINCIPALES
 * ═══════════════════════════════════════════════════════════════════ */

/* --- Dark Top Bar --- */
.may-topbar {
    background: var(--may-dark);
    height: 3.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 1rem;
    box-shadow: 0 10px 15px -3px rgba(0,0,0,0.3);
    z-index: 30;
    flex-shrink: 0;
}
.may-topbar-title {
    font-size: 1.125rem;
    font-weight: 900;
    color: white;
    text-transform: uppercase;
    letter-spacing: -0.05em;
}
.may-topbar-accent { color: #fed7aa; }

/* --- Cards --- */
.may-card {
    background: var(--may-surface);
    border: 1px solid var(--may-border);
    border-radius: 1rem;
    /* Elevación sutil: sin ella la tarjeta blanca se fundía con el fondo
     * #f3f4f6 (reporte del dueño 11-sep-2026: "tarjetas muy blancas" en los
     * formularios de producto, cliente, compra y usuario). Es la misma receta
     * de las tarjetas de Configuración (border gray-200 + shadow-sm), que sí
     * contrastan bien, con un velo difuso extra para definir el contorno. */
    box-shadow: 0 1px 3px rgba(0,0,0,0.07), 0 4px 14px rgba(0,0,0,0.05);
}
.may-card-rounded { border-radius: 1.5rem; }
/* Encabezado de sección con el grafito del sidebar (pedido del dueño,
 * 11-sep-2026): mismas paradas que #sidebar (gray-900 → gray-800) y texto
 * claro. Reemplaza las franjas bg-gray-50 de los formularios, que se
 * confundían con el cuerpo blanco de la tarjeta. */
.may-section-header {
    background-image: linear-gradient(to bottom, #111827, #1f2937);
    color: #f3f4f6;
}
.may-card-lg { border-radius: 2rem; }

/* --- Stat Card --- */
.may-stat {
    background: var(--may-surface);
    border: 1px solid var(--may-border);
    border-radius: 1rem;
    padding: 1.25rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.may-stat-label {
    font-size: 10px;
    font-weight: 900;
    color: var(--may-label);
    text-transform: uppercase;
    letter-spacing: 0.15em;
    margin-bottom: 0.25rem;
}
.may-stat-value {
    font-size: 1.5rem;
    font-weight: 900;
    color: var(--may-text);
}
.may-stat-accent { color: var(--may-orange-dark); }

/* --- Orange Vertical Bar (accent marker) --- */
.may-accent-bar {
    width: 0.75rem;
    height: 3rem;
    background: var(--may-orange);
    border-radius: 9999px;
    flex-shrink: 0;
}

/* --- Action Bar (dark section) --- */
.may-action-bar {
    background: var(--may-dark);
    border-radius: 1.5rem;
    padding: 1.25rem;
    border-top: 4px solid var(--may-orange);
    box-shadow: 0 20px 25px -5px rgba(0,0,0,0.3);
}

/* --- Page Title --- */
.may-title {
    font-size: 1.25rem;
    font-weight: 900;
    color: var(--may-text);
    letter-spacing: -0.025em;
}
.may-subtitle {
    font-size: 0.75rem;
    color: var(--may-label);
    margin-top: 0.25rem;
}
.may-section-label {
    font-size: 11px;
    font-weight: 900;
    color: var(--may-orange-dark);
    text-transform: uppercase;
    letter-spacing: 0.15em;
}

/* --- Labels --- */
.may-label {
    font-size: 10px;
    font-weight: 900;
    color: var(--may-label);
    text-transform: uppercase;
    letter-spacing: 0.2em;
}
.may-label-xs {
    font-size: 8px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.15em;
}

/* --- Buttons --- */
.may-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    transition: all 0.15s;
    cursor: pointer;
    border: none;
    text-decoration: none;
}

/* Primary (orange) */
.may-btn-primary {
    background: var(--may-orange);
    color: white;
    padding: 0.75rem 1.5rem;
    border-radius: 1rem;
    font-size: 12px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    border-bottom: 3px solid var(--may-darker);
}
.may-btn-primary:hover { background: #ea580c; }
.may-btn-primary:active { transform: scale(0.97); }

/* Big primary */
.may-btn-big {
    padding: 1.5rem 2.5rem;
    border-radius: 1.5rem;
    font-size: 14px;
    letter-spacing: 0.25em;
}

/* Dark */
.may-btn-dark {
    background: var(--may-dark);
    color: white;
    padding: 0.5rem 1.25rem;
    border-radius: 1rem;
    font-size: 10px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.15);
}
.may-btn-dark:hover { background: var(--may-darker); }

/* Outline */
.may-btn-outline {
    background: var(--may-surface);
    color: var(--may-orange);
    border: 2px solid var(--may-orange);
    padding: 0.5rem 1rem;
    border-radius: 0.75rem;
    font-size: 10px;
}
.may-btn-outline:hover { background: var(--may-orange-light); }

/* Danger */
.may-btn-danger {
    background: var(--may-danger);
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 0.75rem;
    font-size: 10px;
}
.may-btn-danger:hover { background: #b91c1c; }

/* Success */
.may-btn-success {
    background: var(--may-success);
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 0.75rem;
    font-size: 10px;
}

/* Submit bar (full width bottom bar) */
.may-submit-bar {
    width: 100%;
    padding: 1.5rem;
    background: var(--may-darker);
    color: white;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.3em;
    font-size: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    border: none;
    cursor: pointer;
    box-shadow: 0 20px 25px -5px rgba(0,0,0,0.4);
    transition: all 0.15s;
    border-top: 2px solid var(--may-darker);
}
.may-submit-bar:hover { background: #1e293b; }
.may-submit-bar:active { transform: scale(0.98); }

/* ═══════════════════════════════════════════════════════════════════
 * TABLAS
 * ═══════════════════════════════════════════════════════════════════ */

.may-table { width: 100%; border-collapse: collapse; }
.may-table thead th {
    background: var(--may-bg);
    padding: 0.75rem 1rem;
    text-align: left;
    font-size: 10px;
    font-weight: 900;
    color: var(--may-label);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    border-bottom: 2px solid var(--may-border);
}
.may-table tbody td {
    padding: 0.75rem 1rem;
    font-size: 0.8rem;
    border-bottom: 1px solid var(--may-bg);
}
.may-table tbody tr { transition: background 0.1s; }
.may-table tbody tr:hover { background: #f9fafb; }

/* Table key cell */
.may-table-key { font-weight: 700; color: var(--may-text); font-size: 0.8rem; }
.may-table-secondary { font-size: 0.75rem; color: var(--may-label); }
.may-table-price { font-weight: 900; color: var(--may-orange-dark); }
.may-table-code { font-family: monospace; font-size: 0.7rem; }

/* ═══════════════════════════════════════════════════════════════════
 * BADGES
 * ═══════════════════════════════════════════════════════════════════ */

.may-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.75rem;
    border-radius: 0.5rem;
    font-size: 10px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.may-badge-orange { background: #fff7ed; color: var(--may-orange-dark); }
.may-badge-green  { background: #f0fdf4; color: var(--may-success); }
.may-badge-red    { background: #fef2f2; color: var(--may-danger); }
.may-badge-blue   { background: #eff6ff; color: #2563eb; }
.may-badge-gray   { background: #f9fafb; color: #6b7280; }
.may-badge-yellow { background: #fffbeb; color: #d97706; }
.may-badge-dark   { background: var(--may-dark); color: white; }

/* Counter badge (red circle) */
.may-counter {
    background: var(--may-danger);
    color: white;
    font-size: 9px;
    font-weight: 900;
    min-width: 1.25rem;
    height: 1.25rem;
    border-radius: 9999px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}

/* ═══════════════════════════════════════════════════════════════════
 * FORMULARIOS
 * ═══════════════════════════════════════════════════════════════════ */

.may-input, .may-select {
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: var(--may-surface);
    border: 2px solid var(--may-border);
    border-radius: 0.75rem;
    font-size: 0.8rem;
    transition: border-color 0.15s, box-shadow 0.15s;
}

/* Campos con icono a la izquierda (el login del cliente): la utilidad pl-10
   la pisaba el shorthand `padding` de arriba —misma especificidad, y app.css
   carga despues de tailwind.css—, asi que el icono quedaba encima de lo que
   se escribia. Con dos clases la regla gana sin depender del orden de las
   hojas, y solo afecta a los campos que ya pedian pl-10 en el marcado. */
.may-input.pl-10,
.may-select.pl-10 {
    padding-left: 2.5rem;
}
.may-input:focus, .may-select:focus {
    outline: none;
    border-color: var(--may-orange);
    box-shadow: 0 0 0 3px rgba(249,115,22,0.12);
}

.may-input-dark {
    background: var(--may-darker);
    border-color: var(--may-teal-dark);
    color: var(--may-border);
}
.may-input-dark:focus {
    border-color: var(--may-teal);
    box-shadow: 0 0 0 3px rgba(13,148,136,0.15);
}

.may-form-label {
    display: block;
    font-size: 10px;
    font-weight: 900;
    color: var(--may-label);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin-bottom: 0.25rem;
}

.may-form-label-orange {
    color: var(--may-orange-dark);
}

/* ═══════════════════════════════════════════════════════════════════
 * TABS
 * ═══════════════════════════════════════════════════════════════════ */

.may-tabs {
    display: flex;
    gap: 0.25rem;
    padding: 0.25rem;
    background: var(--may-orange);
    border-radius: 1rem;
}
.may-tab {
    flex: 1;
    padding: 0.5rem;
    text-align: center;
    font-size: 10px;
    font-weight: 900;
    text-transform: uppercase;
    cursor: pointer;
    transition: all 0.15s;
    border: none;
    border-radius: 0.75rem;
}
.may-tab-active {
    background: var(--may-darker);
    color: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.may-tab-inactive {
    background: transparent;
    color: rgba(255,255,255,0.7);
}
.may-tab-inactive:hover { color: white; }

/* ═══════════════════════════════════════════════════════════════════
 * PRODUCT GRID CARDS
 * ═══════════════════════════════════════════════════════════════════ */

.may-product-card {
    background: var(--may-surface);
    border: 1px solid var(--may-border);
    border-radius: 1rem;
    padding: 1rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    cursor: pointer;
    transition: all 0.15s;
    box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.may-product-card:hover {
    border-color: var(--may-orange);
    box-shadow: 0 4px 6px rgba(0,0,0,0.06);
}
.may-product-card:active { transform: scale(0.97); }
.may-product-card-icon {
    width: 4rem;
    height: 4rem;
    background: var(--may-bg);
    border-radius: 1rem;
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s;
}
.may-product-card:hover .may-product-card-icon {
    background: var(--may-orange-light);
}
.may-product-card-name {
    font-size: 9px;
    font-weight: 900;
    color: var(--may-text);
    text-transform: uppercase;
    letter-spacing: -0.025em;
    line-height: 1.1;
}
.may-product-card-price {
    font-weight: 900;
    color: var(--may-orange-dark);
    font-size: 0.75rem;
}

/* ═══════════════════════════════════════════════════════════════════
 * TECHNICIAN / PERSON CARDS
 * ═══════════════════════════════════════════════════════════════════ */

.may-person-card {
    border: 2px solid;
    border-radius: 1rem;
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    transition: all 0.15s;
    cursor: pointer;
    position: relative;
    box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.may-person-card:hover { box-shadow: 0 4px 6px rgba(0,0,0,0.08); }
.may-person-card:active { transform: scale(0.97); }
.may-person-name {
    font-size: 8px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: -0.025em;
    text-align: center;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ═══════════════════════════════════════════════════════════════════
 * FLASH MESSAGES
 * ═══════════════════════════════════════════════════════════════════ */

.may-flash {
    margin: 1rem;
    padding: 1rem 1.5rem;
    border-left: 4px solid;
    border-radius: 0.75rem;
    font-size: 10px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.2em;
}
.may-flash-success { background: #f0fdf4; border-color: var(--may-success); color: var(--may-success); }
.may-flash-error   { background: #fef2f2; border-color: var(--may-danger); color: var(--may-danger); }
.may-flash-warning { background: #fffbeb; border-color: #d97706; color: #d97706; }

/* ═══════════════════════════════════════════════════════════════════
 * MODAL
 * ═══════════════════════════════════════════════════════════════════ */

.may-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 60;
    padding: 1rem;
}
.may-modal {
    background: var(--may-surface);
    border-radius: 0.75rem;
    box-shadow: 0 25px 50px rgba(0,0,0,0.25);
    border: 1px solid var(--may-orange);
    max-width: 90vw;
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.may-modal-header {
    background: var(--may-orange);
    padding: 0.75rem 1.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: white;
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
}
.may-modal-close {
    background: white;
    color: var(--may-orange);
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 9999px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 900;
    cursor: pointer;
    border: none;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.may-modal-body { padding: 1.5rem; overflow-y: auto; flex: 1; }
.may-modal-footer {
    background: var(--may-surface);
    padding: 1.5rem 2rem;
    display: flex;
    justify-content: center;
    gap: 1rem;
    border-top: 1px solid var(--may-border);
}

/* ═══════════════════════════════════════════════════════════════════
 * PAGINATION
 * ═══════════════════════════════════════════════════════════════════ */

.may-pagination {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}
.may-page-btn {
    padding: 0.375rem 0.75rem;
    border-radius: 0.5rem;
    font-size: 11px;
    font-weight: 700;
    transition: all 0.15s;
    cursor: pointer;
    border: none;
    text-decoration: none;
}
.may-page-active {
    background: var(--may-orange);
    color: white;
}
.may-page-inactive {
    background: var(--may-bg);
    color: var(--may-label);
}
.may-page-inactive:hover { background: var(--may-border); color: var(--may-text); }

/* ═══════════════════════════════════════════════════════════════════
 * EMPTY STATE
 * ═══════════════════════════════════════════════════════════════════ */

.may-empty {
    text-align: center;
    padding: 3rem 2rem;
    color: var(--may-label);
    font-size: 0.8rem;
    font-weight: 700;
    font-style: italic;
}

/* ═══════════════════════════════════════════════════════════════════
 * UTILITIES
 * ═══════════════════════════════════════════════════════════════════ */

.may-divider { border-top: 2px solid var(--may-orange-light); }
.may-text-orange { color: var(--may-orange); }
.may-text-orange-dark { color: var(--may-orange-dark); }
.may-text-muted { color: var(--may-label); }
.may-text-white { color: white; }
.may-font-mono { font-family: 'Courier New', monospace; }
.may-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════════
 * ANIMATIONS
 * ═══════════════════════════════════════════════════════════════════ */

@keyframes mayFadeIn {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}
.may-animate-in { animation: mayFadeIn 0.2s ease-out; }

@keyframes mayBounce {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-4px); }
}
.may-animate-bounce { animation: mayBounce 2s infinite; }

/* ═══════════════════════════════════════════════════════════════════
 * TOAST
 * ═══════════════════════════════════════════════════════════════════ */

.toast {
    position: fixed;
    top: 1rem;
    right: 1rem;
    min-width: 280px;
    padding: 1rem 1.25rem;
    border-radius: 0.75rem;
    background: white;
    box-shadow: 0 10px 25px rgba(0,0,0,0.15);
    z-index: 9999;
    animation: mayFadeIn 0.2s ease-out;
}
.toast-success { border-left: 4px solid var(--may-success); }
.toast-error   { border-left: 4px solid var(--may-danger); }
.toast-warning { border-left: 4px solid #d97706; }
.toast-info    { border-left: 4px solid var(--may-orange); }

/* ═══════════════════════════════════════════════════════════════════
 * PRINT
 * ═══════════════════════════════════════════════════════════════════ */

@media print {
    body { background: white; }
    .no-print { display: none !important; }
    .may-card, .may-stat { box-shadow: none; border: 1px solid #ddd; }
}

/* ═══════════════════════════════════════════════════════════════════
 * ESCALA TIPOGRÁFICA
 * ═══════════════════════════════════════════════════════════════════
 *
 * El sistema tenía tokens de color y NINGUNO de tamaño, así que cada vista
 * eligió el suyo. Medido sobre las 64 vistas: 2.351 declaraciones de tamaño,
 * de las cuales 572 (el 24%) por debajo de 12px — 456 a 10px, 75 a 9px y 7
 * a 8px. Un cajero mira esta interfaz toda la jornada.
 *
 * Esta escala no cambia la identidad —compacta, bold, uppercase, tracking
 * generoso— solo le pone un SUELO y pasos coherentes. Nueve escalones, del
 * 12 al 34, con las mismas proporciones que ya tenía el diseño.
 *
 * Se aplica por CSS y no tocando las vistas: 572 sustituciones en 64
 * archivos es un diff enorme para un ajuste que aquí cabe en un bloque.
 * ═══════════════════════════════════════════════════════════════════ */

:root {
    /* Etiquetas diminutas en mayúscula. Antes 8-9px. */
    --may-fs-micro: 0.75rem;    /* 12px */
    /* Etiqueta estándar del sistema. Antes 10-11px, el tamaño más usado (456
       de las 572 declaraciones diminutas). Se sube a 14px por decisión del
       usuario tras ver el espécimen: 13px seguía quedándose corto.
       CONSECUENCIA: coincide con --may-fs-data, así que la etiqueta y el dato
       que rotula miden lo mismo. Se distinguen por tratamiento —mayúscula,
       peso y tracking— y no por tamaño. */
    --may-fs-label: 0.875rem;   /* 14px */
    /* Datos de tabla. */
    --may-fs-data:  0.875rem;   /* 14px */
    /* Texto corrido. */
    --may-fs-body:  0.96875rem; /* 15.5px */
    --may-fs-md:    1.0625rem;  /* 17px */
    --may-fs-lg:    1.21875rem; /* 19.5px */
    --may-fs-xl:    1.375rem;   /* 22px */
    --may-fs-2xl:   1.6875rem;  /* 27px */
    --may-fs-3xl:   2.125rem;   /* 34px */

    /* Interlineado: la mayúscula con tracking necesita más aire que la caja
       baja, y en los tamaños pequeños es donde más se nota. */
    --may-lh-label: 1.45;
    --may-lh-body:  1.55;
}

/* ── Corrección de contraste ────────────────────────────────────────
 *
 * --may-label era #9ca3af: 2,54:1 sobre blanco y 2,31:1 sobre el fondo gris.
 * El mínimo para texto normal es 4,5:1, así que las etiquetas no solo eran
 * diminutas: además estaban al límite de lo invisible, y el poco contraste
 * se percibe como "todavía más pequeño".
 *
 * #646b78 da 5,36:1 sobre blanco y 4,87:1 sobre el fondo. Sigue leyéndose
 * como gris apagado, que es el papel que cumple en el diseño.
 */
:root {
    --may-label: #646b78;
    /* El naranja de marca se mantiene para fondos, bordes e iconos. Para
       TEXTO pequeño no llega (2,80:1), así que hay una variante que sí. */
    --may-orange-text: #c2410c;  /* 5,18:1 sobre blanco */
}

/* ── Aplicación sobre las utilidades de Tailwind ─────────────────────
 *
 * El CDN de Tailwind inyecta su hoja DESPUÉS de este archivo, así que un
 * selector de igual especificidad perdería. Se antepone `body` para subir a
 * 0,1,1 y ganar por especificidad en lugar de por !important, que dejaría
 * la clase imposible de sobrescribir en un caso puntual.
 */

/* Tamaños arbitrarios: todo lo que estaba bajo el suelo sube a él. */
body .text-\[8px\],
body .text-\[9px\]  { font-size: var(--may-fs-micro); line-height: var(--may-lh-label); }
body .text-\[10px\],
body .text-\[11px\] { font-size: var(--may-fs-label); line-height: var(--may-lh-label); }

/* Escala nombrada. */
body .text-xs   { font-size: var(--may-fs-data);  line-height: var(--may-lh-label); }
body .text-sm   { font-size: var(--may-fs-body);  line-height: var(--may-lh-body); }
body .text-base { font-size: var(--may-fs-md);    line-height: var(--may-lh-body); }
body .text-lg   { font-size: var(--may-fs-lg);    line-height: 1.4; }
body .text-xl   { font-size: var(--may-fs-xl);    line-height: 1.3; }
body .text-2xl  { font-size: var(--may-fs-2xl);   line-height: 1.2; }
body .text-3xl  { font-size: var(--may-fs-3xl);   line-height: 1.15; }

/* Los grises de etiqueta de Tailwind comparten el problema de contraste del
   token: gray-400 sobre blanco es 2,54:1. Se llevan al gris corregido. */
body .text-gray-400 { color: var(--may-label); }

/* Naranja como TEXTO. Como fondo (bg-orange-600) no se toca: ahí el
   contraste lo aporta el blanco encima. */
body .text-orange-600 { color: var(--may-orange-text); }

/* ── Cifras alineadas ───────────────────────────────────────────────
 *
 * Esto es un punto de venta: los importes se leen en columna y se comparan
 * de un vistazo. Con cifras proporcionales el 1 ocupa menos que el 8 y las
 * columnas bailan. tabular-nums las alinea sin cambiar la tipografía.
 */
body table,
body .may-stat,
body .may-money,
body [class*="text-right"] {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* ── Foco visible ───────────────────────────────────────────────────
 *
 * Una caja se opera con el teclado mientras se atiende al cliente; sin foco
 * visible no se sabe dónde se está escribiendo.
 */
body :is(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--may-orange-text);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ═══════════════════════════════════════════════════════════════════
 * MENÚ: RÓTULOS DE GRUPO
 * ═══════════════════════════════════════════════════════════════════
 *
 * El menú pasa a estar ordenado por MOMENTO DE USO en la jornada y no por
 * jerarquía. Sin rótulos, un orden así se lee como una lista barajada; con
 * ellos la lógica queda a la vista y no hay que deducirla.
 *
 * Van deliberadamente callados: son señalización, no contenido. El peso lo
 * llevan los enlaces, que es lo que se pulsa.
 */
/* ═══════════════════════════════════════════════════════════════════
 * MARCA DE AGUA DEL NEGOCIO
 * ═══════════════════════════════════════════════════════════════════
 *
 * Se pide el logo a tamaño original en el escritorio y en caja, con una
 * transparencia que permita seguir trabajando. Tres decisiones y su motivo:
 *
 *   · pointer-events: none — sin esto, una imagen que ocupa media pantalla se
 *     traga cada clic que caiga encima. Es lo que convierte una marca de agua
 *     en un obstáculo.
 *   · z-index: 0 con el contenido por encima. Las tarjetas del sistema son
 *     blancas opacas, así que el texto dentro de ellas NO pierde contraste: la
 *     marca solo asoma en los huecos entre tarjetas, que es donde se quiere.
 *   · max-width: la imagen mide 1180 px. En una pantalla más estrecha, a
 *     tamaño fijo forzaría barra horizontal; se reduce solo cuando no cabe, y
 *     en escritorio se ve al tamaño pedido.
 *
 * La opacidad es 8%: sobre el fondo de la página, el trazo más oscuro del logo
 * deja el texto principal en 11,57:1, muy por encima del mínimo.
 */
/* DOS CORRECCIONES SOBRE LA PRIMERA VERSIÓN, Y LAS DOS ERAN FALLOS MÍOS:
 *
 * 1. Para poner el contenido por encima escribí "position: relative" sobre
 *    #sidebar y header. Un selector de ID gana a una clase, así que anuló el
 *    "fixed" del sidebar y el "sticky" de la cabecera: en estas dos pantallas
 *    el menú dejaba de estar fijo y la barra superior de acompañar al
 *    desplazamiento. Eso es lo que rompía la navegación.
 *
 *    Ahora la marca va en z-index: -1 y NO se toca la posición de nada. Para
 *    que un z negativo se vea, el fondo de la página pasa al <html> y el
 *    <body> queda transparente: si el body pintara su color encima, taparía la
 *    imagen. Así todo lo demás queda por delante sin declarar nada.
 *
 * 2. Le puse ancho fijo con max-width Y max-height a la vez. Cada uno recorta
 *    por su lado sin ajustar el otro, y la imagen salía estirada. Ahora es el
 *    fondo de un elemento y el tamaño se da en una sola dimensión con "auto"
 *    en la otra: la proporción la mantiene el navegador, no yo.
 */
/* TERCERA VERSIÓN, Y EL MOTIVO DEL CAMBIO. Estaba DETRÁS de todo (z negativo).
 * Correcto para no estorbar, pero las tarjetas del sistema son blancas opacas
 * y el escritorio está lleno de ellas: la marca quedaba tapada casi entera.
 *
 * Ahora va POR ENCIMA, que es lo que hace una marca de agua de verdad, con dos
 * condiciones que la mantienen inofensiva:
 *   · pointer-events: none, así que no intercepta un solo clic;
 *   · opacidad baja, medida contra el peor caso —el trazo más oscuro del logo
 *     sobre una tarjeta blanca— para que el texto siga muy por encima del
 *     mínimo legible.
 *
 * Y se encuadra en el ÁREA DE TRABAJO, no en la ventana: descontando el ancho
 * del menú y el alto de la barra superior queda centrada en lo que el usuario
 * percibe como la página, no desplazada hacia la izquierda por detrás del
 * sidebar.
 */
.marca-agua {
    position: fixed;
    top: 3rem;      /* la barra superior mide h-12 */
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 20;    /* sobre las tarjetas; por debajo del sidebar (50) y de los modales */
    pointer-events: none;
    user-select: none;
    opacity: .10;

    background-repeat: no-repeat;
    background-position: center center;
    /* Una medida y "auto": la proporción no se puede perder. 70vmin sigue al
     * lado más corto de la ventana, así que se adapta a cualquier pantalla y
     * nunca desborda. */
    background-size: min(1180px, 70vmin) auto;
}

/* En escritorio el menú ocupa 16rem fijos a la izquierda. Sin descontarlos, el
 * centro de la imagen cae por detrás del sidebar y se ve descuadrada. */
@media (min-width: 1024px) {
    .marca-agua { left: 16rem; }
    /* Con el menú plegado ese espacio desaparece y hay que devolverlo. */
    .menu-plegado .marca-agua { left: 0; }
}

/* El precio de poner la marca por encima. Medido sobre el peor caso —el trazo
 * más oscuro del logo sobre una tarjeta blanca, que deja el fondo en #edeae8—:
 * el texto principal se queda en 12,26:1, de sobra, pero el gris secundario
 * (#6b7280) baja a 4,04:1 y deja de ser legible. Sobre blanco puro ya estaba
 * justo, en 4,83:1.
 *
 * En estas dos pantallas se oscurece un paso: 5,12:1 bajo la marca y 6,13:1
 * donde no la haya. Es la alternativa a renunciar a que se vea. */
body[data-marca-agua] .text-gray-500,
body[data-marca-agua] .text-gray-400 {
    color: #5b6270;
}

@media print {
    .marca-agua { display: none; }
}

/* Quien haya pedido menos movimiento no necesita además un fondo decorativo. */
@media (prefers-reduced-motion: reduce) {
    .marca-agua { opacity: .05; }
}

/* ═══════════════════════════════════════════════════════════════════
 * PESO DEL TEXTO EN LOS LISTADOS
 * ═══════════════════════════════════════════════════════════════════
 *
 * Los listados venían con font-black (900) y font-bold (700) repartidos por
 * casi todo: 65 en inventario, 50 en facturación, 47 en productos y ventas.
 * Con todo en negrita nada resalta y la tabla se lee como un bloque.
 *
 * Se corrige aquí y no clase por clase porque son más de 350 ocurrencias entre
 * las siete pantallas, y basta olvidar una para que quede desparejo. El módulo
 * activo viene marcado en el <body>, así que la regla no se escapa a otras
 * pantallas.
 *
 * Lo que SÍ conserva peso, y por qué:
 *   · el encabezado de la tabla, que es lo que separa títulos de datos;
 *   · las insignias de estado, minúsculas de 9 px donde el peso es lo único
 *     que las hace legibles;
 *   · la columna de importes, que es el dato que se busca de un vistazo.
 * Si prefiere quitarles el peso también a los importes, es una línea.
 */
body[data-modulo="productos"] tbody :is(td, p, span, div, a),
body[data-modulo="inventario"] tbody :is(td, p, span, div, a),
body[data-modulo="clientes"] tbody :is(td, p, span, div, a),
body[data-modulo="ventas"] tbody :is(td, p, span, div, a),
body[data-modulo="facturacion"] tbody :is(td, p, span, div, a),
body[data-modulo="compras"] tbody :is(td, p, span, div, a),
body[data-modulo="proveedores"] tbody :is(td, p, span, div, a),
body[data-modulo="creditos"] tbody :is(td, p, span, div, a) {
    font-weight: 400;
}

/* Las insignias de estado son píldoras de color: sin peso, a 9 px se
 * desdibujan. Se reconocen por llevar fondo redondeado y versalitas. */
body[data-modulo] tbody :is(span, div).rounded-full.uppercase,
body[data-modulo] tbody :is(span, div)[class*="bg-"].uppercase {
    font-weight: 700;
}

/* El importe alineado a la derecha es el dato que se busca de un vistazo. */
body[data-modulo] tbody td.text-right :is(span, div, p),
body[data-modulo] tbody td.text-right {
    font-weight: 600;
}

/* ═══════════════════════════════════════════════════════════════════
 * PATRON DE DESBLOQUEO DEL EQUIPO
 * ═══════════════════════════════════════════════════════════════════
 *
 * Vive aquí y no dentro de una vista porque lo usan dos pantallas: la de
 * recepción del equipo y la de gestión de la orden. Duplicarlo garantizaba
 * que tarde o temprano se tocara una y no la otra.
 */
.patron-vista {
    display: grid;
    grid-template-columns: repeat(3, 1.15rem);
    gap: .4rem;
}
.patron-vista-punto {
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 999px;
    background: #e5e7eb;
    font-size: 9px;
    font-weight: 800;
    color: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
}
.patron-vista-punto.activo {
    background: #ea580c;
    color: #fff;
}

/* El trazo se dibuja encima de la rejilla. Sin él, la única pista del recorrido
 * eran los números de orden dentro de los puntos, y en la misma pantalla la
 * etiqueta mostraba POSICIONES: dos numeraciones distintas a la vez, que es
 * justo lo que hizo dudar de si el patrón se guardaba bien. Se guardaba bien;
 * lo que estaba mal era leerlo. */
.patron-lienzo {
    position: relative;
    display: inline-block;
}

.patron-trazo {
    position: absolute;
    /* Encaja con el área de los puntos, dejando fuera el padding de la rejilla. */
    top: 1rem;
    left: 1rem;
    width: 12.5rem;
    height: 12.5rem;
    pointer-events: none;
}

.patron-trazo polyline {
    fill: none;
    stroke: #ea580c;
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: .65;
}

.patron-rejilla {
    display: grid;
    grid-template-columns: repeat(3, 3.5rem);
    gap: 1rem;
    justify-content: center;
    padding: 1rem;
    /* Sin esto, arrastrar por la rejilla selecciona el texto de alrededor y el
     * trazo se convierte en una mancha azul de selección. */
    user-select: none;
    touch-action: none;
}
.patron-punto {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 999px;
    border: 2px solid #e5e7eb;
    background: #f9fafb;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 900;
    font-size: 13px;
    color: #9ca3af;
    cursor: pointer;
    transition: background .12s, border-color .12s, color .12s;
}
.patron-punto:hover { border-color: #fdba74; }
.patron-punto.marcado {
    background: #ea580c;
    border-color: #ea580c;
    color: #fff;
}
.patron-punto:focus-visible {
    outline: 3px solid #fb923c;
    outline-offset: 2px;
}

/* Los enlaces del menú llevaban font-bold en las 20 y pico entradas. Con todo
 * en negrita nada destaca: la jerarquía la marcan ahora los separadores, que
 * conservan su peso. Se corrige aquí y no en las clases de cada enlace porque
 * son muchas y una sola se olvidaría.
 *
 * El activo sí mantiene algo más de peso: es el único que debe cantar. */
/* 13px frente a los 14 del text-sm original. Los separadores se quedan en 15,
 * así que la diferencia entre rótulo de grupo y opción sube de 1 px a 2 y la
 * jerarquía se lee sin depender del peso. */
body #sidebar .sidebar-text {
    font-weight: 500;
    font-size: 13px;
}

/* Los enlaces también se aprietan: py-2 en 21 entradas son 42 px solo de aire
 * vertical. Con esto y los separadores más juntos, el menú pasa de 1148 px a
 * caber en un portátil corriente. Con la entrada 24 (Rockola) el mismo
 * presupuesto exigió bajar de .3rem a .25rem: 1,6 px menos por enlace y las
 * 24 opciones vuelven a caber en 1080p (tools/tests/sidebar_estructura.php
 * es quien vigila esta cuenta). */
body #sidebar nav > a { padding-top: .25rem; padding-bottom: .25rem; }
body #sidebar a[aria-current="page"] .sidebar-text,
body #sidebar a.bg-opacity-10 .sidebar-text { font-weight: 700; }

/* Los rótulos de grupo (ABRIR Y VENDER, INVENTARIO...) eran texto suelto de
 * 10px al 38% de blanco: 3,1:1 sobre el degradado, por debajo del mínimo, y
 * tan tenues que no llegaban a separar nada.
 *
 * Ahora son una banda propia. El fondo no es otro color, es el MISMO azul
 * grisáceo del sidebar dos pasos más claro, que es lo que hace que se lea
 * como parte del mueble y no como un parche pegado encima. El filo naranja
 * a la izquierda es el acento que ya usa el resto del sistema. */
/* El naranja es el pedido, #F76F15, sin retocar. Lo que cambia es el texto:
 * en blanco sobre ese naranja quedan 2,90:1 y no se lee. En el gris casi negro
 * del propio sidebar son 6,12:1, y de paso ata la banda al mueble en el que
 * vive. La banda contra el sidebar da 5,50:1: se distingue de sobra. */
:root {
    --may-nav-grupo-fondo: #F76F15;
    --may-nav-grupo-texto: #111827;   /* 6,12:1 sobre ese naranja */
}

body .nav-grupo {
    /* De lado a lado del sidebar: sin márgenes laterales ni esquinas
     * redondeadas, la banda ocupa el ancho completo. Los márgenes negativos
     * cancelan el acolchado del contenedor de la navegación.
     *
     * Los márgenes verticales bajaron de 1.15rem/0.4rem a 0.5rem/0.25rem: seis
     * separadores a 56 px eran 336 px, casi un tercio del menú entero, y con
     * 21 enlaces detrás no cabía en ninguna pantalla. El texto conserva su
     * tamaño; lo que se recorta es el aire, que es lo que sobraba. */
    margin: .5rem -.5rem .25rem;    /* cancela el px-2 del <nav> */
    padding: .25rem 1.25rem;        /* el texto queda a plomo con el de los enlaces */
    border-radius: 0;
    /* El relieve son tres capas, no una sombra suelta:
     *   · un degradado leve, más claro arriba, que da la curvatura;
     *   · una línea clara por dentro del borde superior, que es el brillo del
     *     canto, y otra oscura por dentro del inferior, que es su grosor;
     *   · una sombra corta hacia abajo que separa la banda del sidebar.
     * Todo en el mismo naranja: aclarar y oscurecer el propio color mantiene
     * la banda de una pieza, mientras que un blanco o un negro puros la
     * ensucian y la hacen parecer pegada encima. */
    background: linear-gradient(180deg, #fb8a3c 0%, var(--may-nav-grupo-fondo) 55%, #d95f0b 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 220, 190, .55),
        inset 0 -1px 0 rgba(120, 45, 0, .45),
        0 2px 4px rgba(0, 0, 0, .35);
    /* Un realce mínimo en el texto: sin él, a 15px sobre un fondo con
     * degradado, las letras se ven planas pegadas a la banda. */
    text-shadow: 0 1px 0 rgba(255, 255, 255, .22);
    /* Mayor que el text-sm (14px) de los botones del menú, que es lo que hace
     * que se lea como encabezado y no como un elemento más de la lista. */
    font-size: 15px;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--may-nav-grupo-texto);
    user-select: none;
}

body .nav-grupo:first-child { margin-top: .35rem; }

/* Plegado por grupo. El separador es ahora un <button>, así que necesita
 * reponer lo que el navegador le quita: ancho completo, alineación y cursor. */
body .nav-grupo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    width: calc(100% + 1rem);
    text-align: left;
    border: 0;
    cursor: pointer;
    font-family: inherit;
}

body .nav-grupo:focus-visible {
    outline: 2px solid #fff;
    outline-offset: -2px;
}

.nav-grupo-flecha {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    transition: transform .18s ease;
}

/* Plegado: la flecha apunta a la izquierda y el grupo desaparece. Se usa
 * display:none y no una altura animada porque el menú ya se desplaza, y una
 * transición de altura con contenido variable deja saltos al abrir. */
body .nav-grupo[aria-expanded="false"] .nav-grupo-flecha {
    transform: rotate(-90deg);
}

body .nav-grupo-items[hidden] { display: none; }

body .nav-grupo-items {
    display: flex;
    flex-direction: column;
    gap: .125rem;
}

/* Con el menú plegado a iconos el rótulo sobra: la banda sin texto legible
 * seria una raya sin significado. */
body .menu-iconos .nav-grupo,
body .sidebar-plegado .nav-grupo { display: none; }

/* ═══════════════════════════════════════════════════════════════════
 * SUPERFICIE HUNDIDA DENTRO DE UNA TARJETA
 * ═══════════════════════════════════════════════════════════════════
 *
 * Lo que se vio en el POS no era un caso aislado. Barridas las 64 vistas:
 * 43 recuadros usan bg-gray-100 DENTRO de una tarjeta blanca. Ese gris da
 * 1,07:1 contra el blanco, es decir prácticamente invisible, y además es el
 * mismo tono que el fondo de la página, así que el recuadro se lee como un
 * hueco en vez de como una caja.
 *
 * El descendiente `.bg-white .bg-gray-100` acota el cambio exactamente a ese
 * caso: un gris-100 sobre el fondo de la página o sobre una franja oscura no
 * se toca, porque ahí sí contrasta.
 */
:root {
    --may-hundido: #e8ebf0;   /* 1,16:1 contra blanco: se ve sin gritar */
}

.bg-white .bg-gray-100 {
    background-color: var(--may-hundido);
}

/* ═══════════════════════════════════════════════════════════════════
 * EL PESO DEJA DE SER EL ESTADO POR DEFECTO
 * ═══════════════════════════════════════════════════════════════════
 *
 * Medido: 1.580 declaraciones de peso fuerte frente a 324 del resto, un 83%.
 * Doce vistas están al 100%, sin una sola excepción. Cuando casi todo va en
 * negrita, la negrita deja de significar énfasis y pasa a ser el tono normal
 * de voz: no queda nada que destacar.
 *
 * Se rebaja SOLO la combinación que aprieta —diminuto + negrita + mayúscula,
 * 835 elementos—, que son rótulos, no contenido. La mayúscula con tracking
 * ya da presencia suficiente a ese tamaño; el peso 900 encima solo tupe.
 *
 * El resto de negritas no se toca: en un importe o en un título sí está
 * ganada. La identidad —compacta, mayúscula, tracking generoso— se mantiene.
 */
body :is(.text-\[8px\], .text-\[9px\], .text-\[10px\], .text-\[11px\], .text-xs).uppercase:is(.font-bold, .font-black, .font-extrabold) {
    font-weight: 600;
}

/* ═══════════════════════════════════════════════════════════════════
 * MENÚ PLEGABLE EN ESCRITORIO
 * ═══════════════════════════════════════════════════════════════════
 *
 * El botón de menú era lg:hidden, así que en escritorio la barra ocupaba sus
 * 256px de forma permanente. En una caja ese ancho es la diferencia entre ver
 * seis productos por fila y ver nueve.
 *
 * La clase va en <html> y no en <body> para que se pueda aplicar antes de que
 * el cuerpo se pinte y no haya salto al restaurar la preferencia guardada.
 * Solo actúa a partir de 1024px: por debajo, la barra sigue superponiéndose.
 */
@media (min-width: 1024px) {
    .menu-plegado #sidebar {
        transform: translateX(-100%);
    }

    .menu-plegado #content-wrapper {
        margin-left: 0;
    }
}

/* ═══════════════════════════════════════════════════════════════════
 * PUNTO DE VENTA · FICHA DE PRODUCTO
 * ═══════════════════════════════════════════════════════════════════
 *
 * El recuadro de la imagen se veía "hueco" porque literalmente llevaba el
 * color del fondo: el marcador venía de placehold.co pintado en f3f4f6, que
 * es --may-bg. Aquí se define un tono propio, a medio camino entre la
 * tarjeta blanca y el fondo gris, para que el recuadro se lea como parte de
 * la tarjeta y no como un agujero.
 */
/*
 * EL VERDE ES EL DEL BOTÓN FACTURAR, pero como superficie y no a plena
 * saturación. La razón no es de gusto: la insignia de stock se pinta ENCIMA
 * de este recuadro, y sobre un verde-600 sólido la insignia verde queda en
 * 1,45:1 y la roja en 1,14:1 — las dos desaparecen, así que el cajero deja de
 * ver de un vistazo qué está agotado. Medido, no supuesto.
 *
 * Con el tinte, la insignia sube a 2,07:1 la verde y 3,43:1 la roja, mejor
 * incluso que con el gris anterior. El icono sí lleva el #16a34a exacto del
 * botón, de modo que el verde presente en la ficha es literalmente ese.
 *
 * Los 37 productos activos están sin imagen, así que este recuadro se ve en
 * TODAS las fichas de la rejilla: lo que aquí se elija se repite entero.
 */
:root {
    --may-facturar:  #16a34a;   /* el verde del botón Facturar */
    --may-medio:     #dcfce7;   /* su tinte claro */
    --may-medio2:    #bbf7d0;   /* segundo tono del degradado */
    --may-icono:     #16a34a;   /* el icono, en el verde exacto */
}

/* El recuadro de la imagen. Antes dependía de una altura fija (h-32) más un
 * <img> con w-full/h-full centrado por flexbox: tres reglas repartidas entre
 * la clase de utilidad y el HTML, y basta que una no aplique para que la foto
 * quede de cualquier tamaño o no se vea.
 *
 * Ahora la proporción la fija el contenedor con aspect-ratio y la imagen se
 * ancla a los cuatro lados. Es una sola regla y no depende del contexto flex,
 * así que la tarjeta mide lo mismo en cualquier vista y con cualquier imagen:
 * cuadrada, apaisada o muy grande. */
.pos-medio {
    position: relative;
    aspect-ratio: 4 / 3;
    height: auto;
    /* Tope y suelo: con aspect-ratio a secas el recuadro crece con el ancho de
     * la tarjeta, y en una pantalla ancha la foto acababa ocupando más que el
     * nombre y el precio juntos. Entre 6 y 9 rem se mantiene proporcionado en
     * cualquier tamaño de rejilla. */
    min-height: 6rem;
    max-height: 9rem;
    background: linear-gradient(135deg, var(--may-medio), var(--may-medio2));
    border-bottom: 1px solid rgba(22, 163, 74, .18);
    overflow: hidden;
}

.pos-medio > img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;   /* el producto entero, sin recortar los bordes */
    padding: .35rem;
}

/* CORRECCION DE UN FALLO PROPIO. Aquí había "grid-auto-rows: 1fr" con
 * "height: 100%" en cada tarjeta, puesto para igualar alturas. Hacía dos daños
 * a la vez, y los dos se vieron en el POS:
 *
 *   · La rejilla vive dentro de un contenedor con alto disponible (flex-1), y
 *     1fr REPARTE ese alto entre las filas que haya. Con cuatro productos —una
 *     sola fila— la fila se comía toda la pantalla y las tarjetas salían de
 *     700 px de alto.
 *   · Al revés, con muchas filas cada una queda baja; como la tarjeta estaba
 *     forzada a "height: 100%", sus hijos se comprimían y el recuadro de la
 *     imagen se aplastaba hasta desaparecer. De ahí que la foto "no se viera"
 *     con el filtro TODOS y sí con un filtro de pocos productos.
 *
 * Las filas se dimensionan por su contenido y se apilan arriba. La igualdad de
 * altura dentro de una fila ya la da align-items: stretch de la propia rejilla,
 * sin forzar nada. */
#product-grid {
    grid-auto-rows: max-content;
    align-content: start;
}

/* Y el recuadro de la imagen no se encoge nunca: es un elemento flexible
 * dentro de una tarjeta en columna, y sin esto cualquier compresión de la
 * tarjeta se la come a él primero. */
.pos-medio { flex: 0 0 auto; }

.pos-sin-imagen {
    width: 100%; height: 100%;
    display: grid; place-items: center;
    color: var(--may-icono);
}

.pos-sin-imagen svg {
    width: 34px; height: 34px;
    opacity: .55;   /* presente, sin competir con la insignia de stock */
}

/* La franja del precio: un borde define el recuadro sin necesidad de un
   relleno que compita con la tarjeta. */
.pos-precio {
    background: var(--may-surface);
    border: 1px solid var(--may-border);
}

/* Las existencias sustituyen a "Seleccionar": ocupan el mismo sitio y sí
   dicen algo. En gris de etiqueta, con contraste suficiente. */
.pos-existencias { color: var(--may-label); }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ═══════════════════════════════════════════════════════════════════
 * MÓDULO WHATSAPP CON IA
 * ═══════════════════════════════════════════════════════════════════
 *
 * Las pantallas de este módulo se portaron TAL CUAL del otro proyecto que
 * usa el mismo motor, para que las dos sean la misma herramienta y un
 * arreglo en una se pueda copiar a la otra sin traducir el marcado.
 *
 * Aquel panel es oscuro y este es claro, así que lo único que cambia es la
 * paleta: aquí se declaran las clases `neon-*` y las variables que el
 * marcado usa, con los colores de MayTech.
 *
 * TODO VA DENTRO DE `.wa-modulo`. Sin ese ámbito, redefinir utilidades como
 * `.text-white` reescribiría el color de media aplicación.
 * ═══════════════════════════════════════════════════════════════════ */

.wa-modulo {
    --primary-color: var(--may-orange);
    --text-muted: #6b7280;
    --border-color: var(--may-border);
    --wa-surface: var(--may-surface);
}

/* --- Tarjeta ---
 * Del MISMO color que la barra lateral del POS (bg-gradient-to-b
 * from-gray-900 to-gray-800). El marcado de estas pantallas nació en un
 * panel oscuro, así que dentro de la tarjeta se RESTAURA su paleta
 * original (texto blanco, acentos tono 400) en lugar del remapeo claro
 * que aplica al resto del módulo. */
.wa-modulo .neon-card {
    background: linear-gradient(180deg, #111827 0%, #1f2937 100%);
    border: 1px solid rgba(255, 255, 255, .08);
    border-radius: 0.75rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, .18);
    color: #e5e7eb;
    --text-muted: #9ca3af;
    --border-color: rgba(255, 255, 255, .1);
}

/* Dentro de la tarjeta vuelve la paleta del panel oscuro de origen. */
.wa-modulo .neon-card .text-white      { color: #ffffff; }
.wa-modulo .neon-card .neon-text       { color: #ffffff; }
.wa-modulo .neon-card .text-emerald-400 { color: #34d399; }
.wa-modulo .neon-card .text-amber-400   { color: #fbbf24; }
.wa-modulo .neon-card .text-amber-300   { color: #fcd34d; }
.wa-modulo .neon-card .text-rose-400    { color: #fb7185; }
.wa-modulo .neon-card .text-sky-400     { color: #38bdf8; }
.wa-modulo .neon-card .text-violet-400  { color: #a78bfa; }
.wa-modulo .neon-card .bg-white\/5      { background-color: rgba(255, 255, 255, .05); }
.wa-modulo .neon-card .bg-black\/30     { background-color: rgba(0, 0, 0, .3); }

/* Grises de Tailwind pensados para fondo claro: sobre gray-900 no se leen. */
.wa-modulo .neon-card .text-gray-800,
.wa-modulo .neon-card .text-gray-700 { color: #e5e7eb; }
.wa-modulo .neon-card .text-gray-600,
.wa-modulo .neon-card .text-gray-500 { color: #9ca3af; }
.wa-modulo .neon-card .text-gray-400 { color: #9ca3af; }
.wa-modulo .neon-card .bg-gray-50,
.wa-modulo .neon-card .bg-gray-100 { background-color: rgba(255, 255, 255, .06); }
.wa-modulo .neon-card .border-gray-100,
.wa-modulo .neon-card .border-gray-200 { border-color: rgba(255, 255, 255, .1); }

/* Botón neutro y campos dentro de la tarjeta, en versión oscura. */
.wa-modulo .neon-card .neon-btn {
    background: rgba(255, 255, 255, .06);
    border-color: rgba(255, 255, 255, .14);
    color: #e5e7eb;
}
.wa-modulo .neon-card .neon-btn:hover {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .22);
}
.wa-modulo .neon-card .neon-input {
    background: rgba(0, 0, 0, .35);
    border-color: rgba(255, 255, 255, .14);
    color: #f9fafb;
}
.wa-modulo .neon-card .neon-input::placeholder { color: #6b7280; }
.wa-modulo .neon-card .neon-input:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px rgba(249, 115, 22, .25);
}

/* --- Campos --- */
.wa-modulo .neon-input {
    background: #fff;
    border: 1px solid var(--border-color);
    border-radius: 0.5rem;
    padding: 0.45rem 0.7rem;
    font-size: 0.875rem;
    color: var(--may-text);
    outline: none;
}
.wa-modulo .neon-input:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px rgba(249, 115, 22, .15);
}
.wa-modulo textarea.neon-input { line-height: 1.4; }

/* --- Botones --- */
.wa-modulo .neon-btn,
.wa-modulo .neon-btn-success,
.wa-modulo .neon-btn-danger {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: 0.45rem 0.85rem;
    border-radius: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 700;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color .15s, border-color .15s, color .15s;
}
.wa-modulo .neon-btn {
    background: #fff;
    border-color: var(--border-color);
    color: var(--may-text);
}
.wa-modulo .neon-btn:hover { background: #f9fafb; border-color: #d1d5db; }
.wa-modulo .neon-btn-success { background: var(--primary-color); color: #fff; }
.wa-modulo .neon-btn-success:hover { background: var(--may-orange-dark); }
.wa-modulo .neon-btn-danger { background: var(--may-danger); color: #fff; }
.wa-modulo .neon-btn-danger:hover { background: #b91c1c; }

.wa-modulo .neon-text { font-weight: 700; color: var(--may-text); }
.wa-modulo .neon-transition { transition: all .15s ease; }
.wa-modulo .neon-badge {
    display: inline-block;
    padding: .1rem .5rem;
    border-radius: 999px;
    font-size: .75rem;
    font-weight: 700;
    background: var(--may-orange-light);
    color: var(--may-orange-dark);
}

/* --- Modal --- */
.wa-modulo .modal-overlay,
.modal-overlay.wa-modulo { background: rgba(17, 24, 39, .55); }
.wa-modulo .neon-modal,
.modal-overlay.wa-modulo .neon-modal {
    background: var(--wa-surface);
    border: 1px solid var(--border-color);
    border-radius: 0.75rem;
    box-shadow: 0 20px 40px rgba(0, 0, 0, .18);
}
.wa-modulo .neon-modal-header,
.modal-overlay.wa-modulo .neon-modal-header {
    padding: 1rem;
    border-bottom: 1px solid var(--border-color);
}

/* --- El panel de origen es OSCURO y este es CLARO -----------------
 * El marcado portado da por hecho un fondo oscuro: texto blanco y colores
 * de acento en el tono 400, que sobre blanco casi no se leen. Se remapean
 * aquí, dentro del ámbito del módulo, en vez de tocar el marcado: así una
 * corrección de allá se sigue pudiendo copiar tal cual. */
.wa-modulo .text-white     { color: var(--may-text); }
.wa-modulo .text-emerald-400 { color: #059669; }
.wa-modulo .text-amber-400   { color: #b45309; }
.wa-modulo .text-rose-400    { color: #dc2626; }
.wa-modulo .text-sky-400     { color: #0284c7; }
.wa-modulo .text-violet-400  { color: #7c3aed; }
.wa-modulo .text-amber-300   { color: #b45309; }
.wa-modulo .bg-white\/5      { background-color: #f3f4f6; }
.wa-modulo .bg-black\/30     { background-color: #f3f4f6; }

/* Pestañas del módulo */
.wa-modulo .wa-tab {
    display: inline-block;
    padding: 0.35rem 0.75rem;
    border-radius: 0.5rem;
    font-size: 0.8125rem;
    border: 1px solid var(--border-color);
    color: var(--text-muted);
    background: #fff;
    transition: all .15s ease;
}
.wa-modulo .wa-tab:hover { color: var(--may-text); border-color: #d1d5db; }
.wa-modulo .wa-tab.activa {
    border-color: var(--primary-color);
    color: var(--primary-color);
    background: var(--may-orange-light);
    font-weight: 700;
}

/* ── Tarjetas visibles sobre el fondo gris ──────────────────────────────────
 *
 * CAUSA: las tarjetas del sistema (331 usos en 57 vistas) llevan
 * border-gray-100 (#f3f4f6), que es EXACTAMENTE el color del fondo
 * bg-gray-100 del <body>: el borde existía pero era invisible y la tarjeta
 * blanca se fundía con la página, sostenida solo por un shadow-sm muy tenue.
 *
 * Se corrige AQUÍ y no vista por vista por la misma razón que documenta el
 * layout ("basta olvidar una para que quede desparejo"): un solo override
 * central —el mismo patrón que ya usa body[data-marca-agua] con
 * .text-gray-500—. El borde sube a gray-300 y la sombra de las tarjetas
 * (borde + shadow-sm juntos, que es la firma del patrón tarjeta y no toca
 * botones ni cabeceras) gana el segundo plano de shadow que Tailwind da a
 * shadow (md queda para hover). */
.border-gray-100 { border-color: #d1d5db; }
.shadow-sm.border-gray-100,
.shadow-sm.border {
    /* Sombra pedida a propósito más oscura y pronunciada que el shadow-md
     * de Tailwind (alpha .1): la tarjeta debe despegarse del fondo gris. */
    box-shadow: 0 6px 16px -2px rgba(0, 0, 0, .22), 0 3px 6px -3px rgba(0, 0, 0, .18);
}

/* ═══ Rediseño mobile-first (docs/rediseno-mobile-first-maytech.md) ═══════════
 *
 * Componentes de app nativa para el teléfono: tab bar inferior, FAB y hoja de
 * acciones (bottom sheet). Prefijo propio .mtm-* a propósito: el subset de
 * Tailwind está purgado (compilar_css.php) y estos componentes no deben
 * depender de qué utilidades sobrevivieron. Una sola base de código: el mismo
 * HTML se muestra u oculta por media query, nada de "versión móvil" aparte. */

/* Tab bar y FAB solo existen en móvil; en escritorio manda el sidebar. */
#mtm-tabbar, #mtm-fab { display: none; }

@media (max-width: 768px) {
    /* El contenido no debe quedar debajo de la barra. */
    body:has(#mtm-tabbar) main { padding-bottom: 78px; }
    /* Respaldo para navegadores sin :has() (la barra mide 66px + safe area). */
    @supports not selector(:has(*)) {
        main { padding-bottom: 78px; }
    }

    #mtm-tabbar {
        display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
        background: #111827; border-top: 1px solid #1f2937;
        padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
        box-shadow: 0 -6px 20px rgba(0, 0, 0, .25);
    }
    .mtm-tab {
        flex: 1; display: flex; flex-direction: column; align-items: center;
        justify-content: center; gap: 3px; background: none; border: none;
        cursor: pointer; padding: 6px 2px; color: #94a3b8; font-size: 11px;
        font-weight: 700; border-radius: 12px; text-decoration: none;
    }
    .mtm-tab svg { width: 22px; height: 22px; }
    .mtm-tab:active { transform: scale(.94); }
    .mtm-tab--on { color: #f97316; }

    #mtm-fab {
        display: flex; align-items: center; justify-content: center;
        position: fixed; right: 18px; bottom: 84px; z-index: 46;
        width: 58px; height: 58px; border-radius: 50%; border: none; cursor: pointer;
        background: linear-gradient(135deg, #f97316, #ea580c);
        color: #fff; box-shadow: 0 10px 25px rgba(0, 0, 0, .35);
    }
    #mtm-fab:active { transform: scale(.94); }
    #mtm-fab svg { width: 26px; height: 26px; }
}

/* ── Hoja de acciones (bottom sheet) — también sirve en escritorio ──────────
 * z-index por encima del sidebar (50) y de la tab bar; hijo directo de <body>
 * SIEMPRE: position:fixed se rompe bajo ancestros con transform/filter. */
#mtm-sheet-fondo {
    display: none; position: fixed; inset: 0;
    background: rgba(15, 23, 42, .5); z-index: 120;
}
#mtm-sheet {
    display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 121;
    background: #fff; border-radius: 20px 20px 0 0;
    box-shadow: 0 -12px 40px rgba(0, 0, 0, .25);
    padding: 10px 12px calc(12px + env(safe-area-inset-bottom, 0px));
    animation: mtmSubir .22s ease-out; max-width: 520px; margin: 0 auto;
}
@keyframes mtmSubir { from { transform: translateY(100%); } to { transform: translateY(0); } }
.mtm-sheet-asa { width: 40px; height: 4px; border-radius: 99px; background: #e5e7eb; margin: 4px auto 10px; }
.mtm-sheet-cabeza { padding: 0 8px 10px; border-bottom: 1px solid #f1f5f9; margin-bottom: 6px; }
.mtm-sheet-titulo { font-weight: 800; font-size: 16px; color: #111827; }
.mtm-sheet-sub { font-size: 12px; color: #6b7280; margin-top: 2px; }
.mtm-sheet-item {
    display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
    background: none; border: none; cursor: pointer; padding: 14px 10px;
    border-radius: 12px; font-size: 15px; font-weight: 600; color: #111827;
}
.mtm-sheet-item:hover { background: #f3f4f6; }
.mtm-sheet-item--peligro { color: #dc2626; }

/* Botón ⋮ de las filas y tarjetas. */
.mtm-kebab {
    background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 10px;
    cursor: pointer; font-size: 18px; line-height: 1; font-weight: 700;
    padding: 4px 10px; color: #374151;
}
.mtm-kebab:hover { background: #f3f4f6; }
.mtm-kebab:active { transform: scale(.94); }

/* ── Menú de avatar del header (rediseño mobile-first) ─────────────────── */
.mtm-avatar-menu {
    display: none; position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
    min-width: 220px; background: #fff; border: 1px solid #e5e7eb; border-radius: 14px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .18); padding: 6px; text-align: left;
}
.mtm-avatar-menu.mtm-abierto { display: block; }
.mtm-avatar-cabeza { padding: 8px 10px 10px; border-bottom: 1px solid #f1f5f9; margin-bottom: 4px; }
.mtm-avatar-nombre { font-weight: 800; font-size: 13px; color: #111827; }
.mtm-avatar-correo { font-size: 11px; color: #6b7280; margin-top: 1px; word-break: break-all; }
.mtm-avatar-item {
    display: block; width: 100%; text-align: left; background: none; border: none;
    cursor: pointer; padding: 10px; border-radius: 10px; font-size: 13px;
    font-weight: 600; color: #111827; text-decoration: none;
}
.mtm-avatar-item:hover { background: #f3f4f6; }
.mtm-avatar-item--peligro { color: #dc2626; }

/* ── Barra de progreso del SPA (spa-nav.js) ─────────────────────────────
   html.spa-cargando la pone el propio spa-nav mientras trae la página. */
@keyframes spa-barra {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}
html.spa-cargando::before {
    content: '';
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 3px;
    z-index: 9999;
    background: linear-gradient(90deg, transparent, #ea580c 30%, #f59e0b 70%, transparent);
    animation: spa-barra 0.9s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    html.spa-cargando::before { animation: none; background: #ea580c; }
}

/* ── Impresión del QR "para el local" (fidelización) ──────────────────────
   fidImprimirQr() marca <body class="fid-print-qr"> justo antes de print():
   se oculta TODO por visibilidad (conserva layout) y solo la hoja del QR
   queda visible, reposicionada al centro de la página. */
@media print {
    body.fid-print-qr * { visibility: hidden !important; }
    body.fid-print-qr #fidQrHoja,
    body.fid-print-qr #fidQrHoja * { visibility: visible !important; }
    body.fid-print-qr #fidQrHoja {
        position: fixed; left: 0; right: 0; top: 40px; margin: 0 auto;
        box-shadow: none !important;
    }
    body.fid-print-qr .no-print { display: none !important; }
}
