/* ═══════════════════════════════════════════════════════════════
   SALVAVENTAS — GENESYS VI (2026-10)
   Capa global que se carga DESPUÉS de app.css. Los bloques <style> de
   cada página/layout llegan más tarde en el documento y ganan a igual
   especificidad, por eso las reglas que deben imponerse usan el prefijo
   `html body` (o `:root`) en vez de !important.

   1. Tipografía propia y tokens de marca
   2. Íconos de línea (SvIcon)
   3. Tablas desplazables
   4. Ventanas emergentes en móvil
   5. Motion design (animaciones sutiles)
═══════════════════════════════════════════════════════════════ */

/* ── 1. TIPOGRAFÍA Y TOKENS ────────────────────────────────────
   La misma familia tipográfica de salvaventas.com.pe: Geist para el
   texto y los números, Bricolage Grotesque para los títulos. Servidas
   desde wwwroot/fonts (CSP font-src 'self'), licencia OFL. */
@font-face {
    font-family: 'Bricolage Grotesque Variable';
    font-style: normal; font-display: swap;
    font-weight: 200 800; font-stretch: 75% 100%;
    src: url(../fonts/bricolage-grotesque-latin-standard-normal.woff2) format('woff2-variations');
}
@font-face {
    font-family: 'Geist Variable';
    font-style: normal; font-display: swap; font-weight: 100 900;
    src: url(../fonts/geist-latin-wght-normal.woff2) format('woff2-variations');
}

:root {
    --gv-font-text: 'Geist Variable', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --gv-font-display: 'Bricolage Grotesque Variable', 'Geist Variable', 'Segoe UI', system-ui, sans-serif;

    /* Paleta de marca (misma que la web pública) */
    --gv-ink:      #08122B;
    --gv-tinta:    #0F172A;
    --gv-azul:     #2563EB;
    --gv-azul-osc: #1D4ED8;
    --gv-celeste:  #38BDF8;
    --gv-oro:      #F5A500;
    --gv-zorro:    #EE6A2A;
    --gv-verde:    #15A05A;
    --gv-gris:     #5B6478;
    --gv-surface:  #ffffff;
    --gv-line:     #E3E8F1;

    --gv-ease-out: cubic-bezier(.16, 1, .3, 1);
    --gv-ease:     cubic-bezier(.4, 0, .2, 1);
}
:root[data-theme="dark"] { --gv-surface: #111a2e; --gv-line: #24314a; }

html body,
html body button,
html body input,
html body select,
html body textarea {
    font-family: var(--gv-font-text);
}
html body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    font-feature-settings: "ss01" 0, "cv11" 1;
}

/* Títulos de página y de ventanas con la tipografía display */
html body h1,
html body h2,
html body [class*="modal"] h3,
html body .sa2d-title {
    font-family: var(--gv-font-display);
    letter-spacing: -0.015em;
    font-optical-sizing: auto;
}

/* Cifras alineadas en tablas, KPIs y montos */
html body td, html body th,
html body [class*="kpi-value"], html body [class*="-monto"], html body [class*="-total"] {
    font-variant-numeric: tabular-nums;
}

html body ::selection { background: rgba(37, 99, 235, .18); color: inherit; }

html body :focus-visible {
    outline: 2px solid var(--sv-primary, var(--gv-azul));
    outline-offset: 2px;
}

/* ── 2. ÍCONOS DE LÍNEA ─────────────────────────────────────── */
.sv-ico { display: inline-block; flex-shrink: 0; vertical-align: middle; }

/* Menú lateral del negocio */
/* El ícono hereda el color del texto: el menú es blanco en PC y azul
   oscuro en el cajón móvil, y debe leerse bien en los dos. El acento de
   la empresa se aplica solo al ítem activo en el menú claro. */
html body .sv-nav-icon .sv-ico { width: 17px; height: 17px; }
html body .sv-nav-sub { gap: 10px; }
html body .sv-nav-sub > .sv-ico { opacity: .72; transition: opacity .18s var(--gv-ease), transform .18s var(--gv-ease); }
html body .sv-nav-sub:hover > .sv-ico,
html body .sv-nav-sub.active > .sv-ico { opacity: 1; }
html body .sv-nav-sub:hover > .sv-ico { transform: translateX(1px); }
@media (min-width: 769px) {
    html body :is(.sv-nav-item.active, .sv-grupo-header.abierto) .sv-nav-icon { color: var(--sv-primary, #0d2f5e); }
}
html body .sv-nav-lock { margin-left: auto; color: #94a3b8; display: inline-flex; }
html body .sv-plan-icon { color: var(--gv-oro); display: inline-flex; }
html body .sv-btn-salir, html body .sv-topbar-usuario-item { display: inline-flex; align-items: center; gap: 8px; }
html body .sv-btn-tema, html body .sv-hamburger { display: inline-flex; align-items: center; justify-content: center; }
html body .sv-tn-item, html body .sv-tn-sub { display: inline-flex; align-items: center; gap: 7px; }
html body .sv-tn-sub { display: flex; }

/* Barra inferior móvil */
html body .sv-bn-ico { display: inline-flex; height: 24px; align-items: center; }
html body .sv-bn-item { transition: color .18s var(--gv-ease); }
html body .sv-bn-item.active .sv-bn-ico { color: var(--sv-primary, #0d2f5e); }
html body .sv-bn-item.active .sv-ico { animation: gvBounce .4s var(--gv-ease-out); }

/* Pestañas */
html body .sv-tab-ico, html body .sa2-tab-ico { display: inline-flex; align-items: center; opacity: .85; }

/* SuperAdmin */
html body .sa2-ni { color: #9fb2cf; }
html body .sa2-nav-item:hover .sa2-ni { color: #e2e8f0; }
html body .sa2-nav-item.active .sa2-ni { color: var(--gv-celeste); }
html body .sa2-mobile-burger, html body .sa2-chevron { display: inline-grid; place-items: center; }

/* ── 2b. BARRA SUPERIOR EN MÓVIL ────────────────────────────────
   Hallazgo verificando en navegador (2026-10-19): en un teléfono de
   375px la barra superior medía 851px (selector de sede de 326px, título,
   fecha y nombre de usuario) y la campana y el usuario quedaban fuera de
   la pantalla. En móvil se muestra solo lo accionable. */
/* Tablet: mismo problema a menor escala (a 800px la fecha y el usuario
   quedaban cortados). */
@media (max-width: 1180px) {
    html body :is(.sv-topbar-fecha, .sv-topbar-usuario-nombre, .sv-topbar-titulo) { display: none; }
    html body .sv-topbar-right { min-width: 0; }
}
@media (max-width: 768px) {
    html body .sv-topbar { gap: 6px; padding-left: 10px; padding-right: 10px; }
    html body .sv-topbar-left { flex-shrink: 0; gap: 6px; }
    html body .sv-topbar-right { min-width: 0; flex: 1; justify-content: flex-end; gap: 6px; }
    html body :is(.sv-topbar-titulo, .sv-topbar-fecha, .sv-topbar-usuario-nombre, .sv-chevron-down, .sc-empresa) { display: none; }
    html body .sc-wrap { min-width: 0; flex-shrink: 1; }
    html body .sc-selector { max-width: 132px; min-width: 0; padding: 7px 9px; }
    html body .sc-ctx-nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    html body .sc-panel { position: fixed; top: 62px; left: 12px; right: 12px; width: auto; }
    html body .sv-topbar-usuario-menu { right: 0; }
}

/* ── 3. TABLAS DESPLAZABLES ────────────────────────────────────
   Pedido del propietario: "poder navegar libremente en el desplazamiento
   de las tablas". Toda tabla dentro de su contenedor *-wrap ya scrollea
   en X (app.css); aquí se agrega una sombra a los costados que avisa que
   hay más columnas, y en pantallas chicas cualquier tabla suelta (sin
   contenedor propio) se vuelve desplazable en vez de recortarse. */
html body [class*="tabla-wrap"],
html body [class*="table-wrap"],
html body [class*="tablewrap"] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: rgba(13, 47, 94, .22) transparent;
    background:
        linear-gradient(to right, var(--gv-surface) 30%, rgba(255,255,255,0)) left center / 28px 100% no-repeat local,
        linear-gradient(to left,  var(--gv-surface) 30%, rgba(255,255,255,0)) right center / 28px 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, rgba(15,23,42,.13), transparent) left center / 12px 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, rgba(15,23,42,.13), transparent) right center / 12px 100% no-repeat scroll,
        var(--gv-surface);
}
html body [class*="tabla-wrap"]::-webkit-scrollbar,
html body [class*="table-wrap"]::-webkit-scrollbar { height: 8px; }
html body [class*="tabla-wrap"]::-webkit-scrollbar-thumb,
html body [class*="table-wrap"]::-webkit-scrollbar-thumb { background: rgba(13, 47, 94, .2); border-radius: 8px; }

html body tbody tr { transition: background-color .15s var(--gv-ease); }

@media (max-width: 900px) {
    :is(.sv-tab-pane, .sv-content, .sa2-main) :not([class*="wrap"]):not([class*="scroll"]) > table:not([class*="print"]):not([class*="ticket"]) {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
    }
    html body th { white-space: nowrap; }
    /* Filas de pestañas internas de las páginas (ej. Suscripciones):
       desplazables de lado en vez de ensanchar toda la página. */
    html body :is([class$="-tabs"], [class*="-tabs "]) {
        max-width: 100%;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }
}

/* ── 4. VENTANAS EMERGENTES EN MÓVIL ───────────────────────────
   Reporte real del propietario (2026-10-19): en el POS desde el
   celular, el modal "Nuevo Cliente" quedaba fijo y el botón para
   registrar no se alcanzaba. Con el teclado abierto el modal anclado
   abajo quedaba detrás del teclado y no había scroll. El meta viewport
   ahora usa interactive-widget=resizes-content (el área visible se
   achica con el teclado) y aquí se garantiza que ningún modal sea más
   alto que la pantalla visible y que el fondo permita desplazarse. */
@media (max-width: 768px) {
    .modal-overlay, .sv-modal-backdrop, .pos-overlay, .pos-modal-bg,
    [class$="-overlay"], [class*="-overlay "] {
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
    }
    .modal-box, .sv-modal, .pos-modal,
    [class$="-modal"], [class*="-modal "] {
        max-height: calc(100dvh - 16px);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
    /* Pie de los modales siempre visible al final del contenido */
    .modal-footer, .modal-ft, .sv-modal-footer, .pos-modal-ft,
    [class*="-modal-ft"], [class*="-modal-footer"], [class*="-modal-foot"] {
        position: sticky;
        bottom: 0;
        z-index: 2;
        background-color: var(--gv-surface);
    }
}

/* Salvita no debe tapar los botones de una ventana emergente: mientras
   haya un modal abierto en la pestaña visible (las pestañas ocultas
   siguen en el DOM con display:none, por eso se acota a la visible), o
   el menú lateral móvil esté abierto, el asistente se oculta. */
.sv-layout:has(.sv-tab-pane-visible :is(.modal-overlay, .sv-modal-backdrop, .pos-modal-bg, [class$="-overlay"], [class*="-overlay "]),
               .sv-content :is(.modal-overlay, .sv-modal-backdrop, .pos-modal-bg, [class$="-overlay"], [class*="-overlay "]),
               .sv-overlay) .sv-zorro {
    display: none;
}

/* Captura real del propietario en iPhone (2026-10-19): la barra inferior y
   Salvita quedaban ENCIMA del modal "Nuevo Cliente" y tapaban el botón.
   En Safari iOS "-webkit-overflow-scrolling: touch" crea un contexto de
   apilamiento en .sv-tab-pane, así que el z-index 9999 del modal queda
   encerrado dentro de la pestaña. Se quita esa propiedad obsoleta (iOS 13+
   ya desplaza con inercia por defecto) y, como segunda barrera, la barra
   inferior se oculta mientras haya un modal abierto. */
html body .sv-tab-pane, html body .sv-content { -webkit-overflow-scrolling: auto; }
.sv-layout:has(.sv-tab-pane-visible :is(.modal-overlay, .sv-modal-backdrop, .pos-overlay, .pos-modal-bg, [class$="-overlay"], [class*="-overlay "]),
               .sv-content :is(.modal-overlay, .sv-modal-backdrop, .pos-overlay, .pos-modal-bg, [class$="-overlay"], [class*="-overlay "])) .sv-bottom-nav {
    display: none;
}

/* ── 5. MOTION DESIGN ──────────────────────────────────────────
   Movimiento corto y con propósito: entrada de pestañas, ventanas y
   menús, respuesta al tocar botones. Solo opacity/transform (no
   provoca relayout) y todo se apaga con prefers-reduced-motion.
   La pestaña completa solo cambia de opacidad: un transform en el
   contenedor rompería los position:fixed de sus modales. */
@keyframes gvFadeIn   { from { opacity: 0; } to { opacity: 1; } }
@keyframes gvRise     { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes gvModalIn  { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes gvSheetIn  { from { transform: translateY(100%); } to { transform: none; } }
@keyframes gvBounce   { 0% { transform: scale(1); } 40% { transform: scale(1.16) translateY(-1px); } 100% { transform: scale(1); } }
@keyframes gvSlideIn  { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }

/* Siempre fill-mode "backwards", nunca "both"/"forwards": una animación
   de opacidad que queda "rellenando" mantiene un contexto de apilamiento
   permanente en la pestaña, y entonces sus modales (z-index 9999) quedan
   DEBAJO de la barra inferior y la superior. Verificado en navegador. */
html body .sv-tab-pane-visible { animation: gvFadeIn .22s var(--gv-ease) backwards; }
html body .sv-tab-pane-visible > :first-child > :is(h1, header, [class*="header"], [class*="hdr"]):first-child {
    animation: gvRise .38s var(--gv-ease-out) backwards;
}
html body .sa2-main > * { animation: gvFadeIn .22s var(--gv-ease) backwards; }

html body .sv-grupo-items > * { animation: gvSlideIn .24s var(--gv-ease-out) backwards; }
html body .sv-grupo-items > :nth-child(2) { animation-delay: .02s; }
html body .sv-grupo-items > :nth-child(3) { animation-delay: .04s; }
html body .sv-grupo-items > :nth-child(4) { animation-delay: .06s; }
html body .sv-grupo-items > :nth-child(5) { animation-delay: .08s; }
html body .sv-grupo-items > :nth-child(n+6) { animation-delay: .1s; }

html body :is(.modal-overlay, .sv-modal-backdrop, .pos-overlay, .pos-modal-bg, [class$="-overlay"]) {
    animation: gvFadeIn .18s var(--gv-ease) backwards;
}
html body :is(.modal-box, .sv-modal, .pos-modal, [class$="-modal"]) {
    animation: gvModalIn .26s var(--gv-ease-out) backwards;
}
@media (max-width: 768px) {
    html body .pos-modal { animation: gvSheetIn .3s var(--gv-ease-out) backwards; }
}

/* Respuesta táctil de botones (sin afectar los deshabilitados) */
html body button:not(:disabled):active,
html body [role="button"]:active {
    transform: scale(.97);
    transition: transform .08s var(--gv-ease);
}
html body .sa2-tab:active, html body .sv-tab:active { transform: none; }

/* Tarjetas de indicadores: elevación suave al pasar el mouse */
@media (hover: hover) {
    html body :is([class$="-kpi"], [class*="-kpi "], [class$="kpi-card"]) {
        transition: box-shadow .22s var(--gv-ease), border-color .22s var(--gv-ease), transform .22s var(--gv-ease);
    }
    html body :is([class$="-kpi"], [class*="-kpi "], [class$="kpi-card"]):hover {
        box-shadow: 0 10px 28px rgba(13, 47, 94, .10);
        transform: translateY(-2px);
    }
}

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