@import url('./icons.css');

/* Design tokens Morphi (Docs/paleta-tipografia.md) */
:root {
    --morphi-azul:        #0098DA;
    --morphi-azul-oscuro: #007AB8;
    --morphi-navy:        #212E38;
    --morphi-slate:       #8599A8;
    --morphi-mist:        #ADDBE3;

    /* Superficies/texto/bordes — tokens de skin para pantallas ABM (ver mockups Docs/mockup-rediseno-*.html) */
    --morphi-bg:                #F2F6F8;
    --morphi-surface:           #FFFFFF;
    --morphi-surface-2:         #F7FAFB;
    --morphi-border:            #DCE4E9;
    --morphi-text:              #1B242C;
    --morphi-text-secondary:    #5B6B78;
    --morphi-mist-tint:         rgba(173, 219, 227, .22);
    --morphi-azul-tint:         rgba(0, 152, 218, .07);
    --morphi-azul-tint-strong:  rgba(0, 152, 218, .14);
    --morphi-radius:            10px;
    --morphi-shadow-sm:         0 1px 2px rgba(27, 36, 44, .06);
    --morphi-shadow-md:         0 10px 28px rgba(27, 36, 44, .10);

    /* Semánticos (éxito/error/alerta) — no son "azul de marca", pero sí cambian
       de solid pastel a overlay translúcido en oscuro (ver mockup). */
    --morphi-success:    #2E7D32;
    --morphi-success-bg: #E8F5E9;
    --morphi-danger:     #C62828;
    --morphi-danger-bg:  #FDECEC;
    --morphi-warning:    #B45309;
    --morphi-warning-bg: #FFF6E5;

    /* Topbar + sidebar (chrome) — claro únicamente por ahora, ver Docs/Plan-Implementacion-Ventas.md */
    --morphi-chrome-bg:          #FFFFFF;
    --morphi-chrome-bg-2:        #F5F8FA;
    --morphi-chrome-border:      var(--morphi-border);
    --morphi-chrome-text:        var(--morphi-text);
    --morphi-chrome-text-dim:    var(--morphi-text-secondary);
    --morphi-chrome-item:        var(--morphi-text-secondary);
    --morphi-chrome-item-strong: var(--morphi-text);
    --morphi-chrome-hover-bg:    var(--morphi-azul-tint);
    --morphi-chrome-active-bg:   var(--morphi-azul-tint-strong);
    --morphi-chrome-active-text: var(--morphi-azul-oscuro);
    --morphi-chrome-pill-bg:     var(--morphi-azul-tint);
    --morphi-chrome-pill-border: var(--morphi-border);

    /* Todos los componentes DevExpress (DxButton, DxGrid, DxTextBox, DxFormLayout...)
       derivan su font-family de este único token de diseño — pisarlo acá alcanza para
       que "Graba", el filtro, el grid, etc. usen Montserrat sin tener que reescribir
       la tipografía componente por componente. */
    --dxds-font-family-sans-serif: 'Montserrat', 'Segoe UI', system-ui, sans-serif !important;
}

/* Modo oscuro — mismos valores que Docs/mockup-rediseno-*.html (bloque
   :root[data-theme="dark"]). El atributo lo escribe window.morphiTheme
   (Components/App.razor) al togglear el botón del topbar (MainLayout.razor).
   Como todos los componentes ABM y DevExpress ya consumen estos tokens
   --morphi-*, pisarlos acá alcanza para propagar el tema sin tocar cada
   pantalla por separado. */
:root[data-theme="dark"] {
    --morphi-azul:        #21A9E8;
    --morphi-azul-oscuro: #0098DA;
    --morphi-navy:        #0D1216;
    /* --slate/--mist quedan igual que en claro, el mockup no los cambia */

    --morphi-bg:                #10161B;
    --morphi-surface:           #1B242C;
    --morphi-surface-2:         #212E38;
    --morphi-border:            #2F3E49;
    --morphi-text:              #EAF3F6;
    --morphi-text-secondary:    #93A6B4;
    --morphi-mist-tint:         rgba(173, 219, 227, .10);
    --morphi-azul-tint:         rgba(33, 169, 232, .10);
    --morphi-azul-tint-strong:  rgba(33, 169, 232, .18);
    --morphi-shadow-sm:         0 1px 2px rgba(0, 0, 0, .3);
    --morphi-shadow-md:         0 10px 28px rgba(0, 0, 0, .45);

    --morphi-success:    #4CAF50;
    --morphi-success-bg: rgba(76, 175, 80, .14);
    --morphi-danger:     #E57373;
    --morphi-danger-bg:  rgba(229, 115, 115, .14);
    --morphi-warning:    #E0A030;
    --morphi-warning-bg: rgba(224, 160, 48, .14);

    --morphi-chrome-bg:          #0D1216;
    --morphi-chrome-bg-2:        #17222A;
    --morphi-chrome-border:      rgba(255, 255, 255, .10);
    --morphi-chrome-text:        rgba(255, 255, 255, .92);
    --morphi-chrome-text-dim:    rgba(255, 255, 255, .6);
    --morphi-chrome-item:        rgba(255, 255, 255, .62);
    --morphi-chrome-item-strong: #FFFFFF;
    --morphi-chrome-hover-bg:    rgba(255, 255, 255, .06);
    --morphi-chrome-active-bg:   rgba(33, 169, 232, .18);
    --morphi-chrome-active-text: #FFFFFF;
    --morphi-chrome-pill-bg:     rgba(255, 255, 255, .06);
    --morphi-chrome-pill-border: rgba(255, 255, 255, .10);
}

/* Los elementos de formulario nativos (button/input/select/textarea) no heredan
   font-family del body por default en la mayoría de los navegadores. */
button, input, select, textarea {
    font-family: inherit;
}

/* Feedback de "presionado" para TODOS los DxButton de la app (clase base del
   tema Fluent, .dxbl-btn) — por defecto DevExpress solo trae :hover, así que
   un click se siente "muerto" aunque el botón funcione. Global en vez de
   por-página para que cubra cualquier pantalla nueva sin repetir la regla. */
.dxbl-btn {
    transition: transform .1s ease, filter .1s ease, box-shadow .1s ease;
    cursor: pointer;
}
.dxbl-btn:active:not(:disabled) {
    transform: scale(.96);
    filter: brightness(.95);
}
/* El tema Fluent de DevExpress solo apaga color/hover en :disabled, pero deja
   el fondo (--dxbl-btn-bg) intacto — un botón primario deshabilitado se ve
   idéntico al habilitado (mismo azul), sin hover ni respuesta al click, lo
   que confunde muchísimo ("se ve clickeable pero no hace nada"). Bajarle la
   opacidad lo hace obviamente inerte, sin depender de que cada variante de
   color tenga su propio --dxbl-btn-*-disabled-bg bien definido. */
.dxbl-btn:disabled {
    opacity: .5;
}
.dxbl-btn:disabled {
    cursor: default;
}

/* Reskin GLOBAL de los componentes DevExpress con la paleta --morphi-* (y por
   lo tanto el modo oscuro, que ya flipea esos tokens vía :root[data-theme]).
   El tema Fluent queda fijado en modo Light a nivel de proceso (App.razor,
   ActiveTheme.Mode = ThemeMode.Light) — no reacciona al toggle propio de la
   app, así que sin esto cualquier popup/dropdown/grid se ve siempre con los
   grises de DevExpress en vez de la paleta de la página, en cualquiera de los
   dos modos. Antes esto solo se pisaba localmente (::deep) en AbmLayout y
   PreciosVenta; acá queda sin ::deep para cubrir TODA la app (modales de
   reportes, Stock Actual, dropdowns de filtro de grilla, etc.) sin tener que
   repetirlo por pantalla. !important porque el propio tema redeclara estas
   variables con el mismo peso de selector. */
.dxbl-grid {
    --dxbl-grid-font-family: 'Montserrat', 'Segoe UI', sans-serif !important;
    --dxbl-grid-bg: var(--morphi-surface) !important;
    --dxbl-grid-row-bg: var(--morphi-surface) !important;
    --dxbl-grid-color: var(--morphi-text) !important;
    --dxbl-grid-border-color: var(--morphi-border) !important;
    --dxbl-grid-header-bg: var(--morphi-surface-2) !important;
    --dxbl-grid-header-color: var(--morphi-text-secondary) !important;
    --dxbl-grid-header-font-weight: 800 !important;
    --dxbl-grid-hover-bg: var(--morphi-azul-tint) !important;
    --dxbl-grid-hover-color: var(--morphi-text) !important;
    --dxbl-grid-selection-bg: var(--morphi-azul-tint-strong) !important;
    --dxbl-grid-selection-color: var(--morphi-text) !important;
    --dxbl-grid-selected-hover-bg: var(--morphi-azul-tint-strong) !important;
    --dxbl-grid-focus-bg: var(--morphi-azul-tint-strong) !important;
    --dxbl-grid-focus-color: var(--morphi-text) !important;
    /* Flecha de expandir/colapsar fila de grupo (ShowGroupPanel) — mismo motivo
       que el pager más abajo en este archivo: el tema Fluent queda fijado en
       modo Light a nivel de proceso, así que esta variable resuelve siempre a
       texto oscuro pensado para fondo claro y en modo oscuro queda casi negra
       sobre negro. */
    --dxbl-grid-expand-btn-color: var(--morphi-text-secondary) !important;
    --dxbl-grid-expand-btn-hover-color: var(--morphi-text) !important;
    --dxbl-grid-expand-btn-hover-bg: var(--morphi-azul-tint) !important;
}

/* Pager de DxGrid (números de página + "Page Size") — el tema Fluent queda
   fijado en modo Light a nivel de proceso (ver comentario arriba de
   .dxbl-grid), así que sus variables --dxbl-pager-* resuelven siempre a
   texto oscuro pensado para fondo claro. En modo oscuro esos números quedan
   negro sobre el fondo oscuro del popup/página, prácticamente invisibles. */
.dxbl-pager {
    --dxbl-pager-btn-color: var(--morphi-text-secondary) !important;
    --dxbl-pager-btn-hover-color: var(--morphi-text) !important;
    --dxbl-pager-btn-hover-bg: var(--morphi-azul-tint) !important;
    --dxbl-pager-btn-disabled-color: var(--morphi-text-secondary) !important;
    --dxbl-pager-page-btn-color: var(--morphi-text-secondary) !important;
    --dxbl-pager-page-btn-hover-color: var(--morphi-text) !important;
    --dxbl-pager-page-btn-hover-bg: var(--morphi-azul-tint) !important;
    --dxbl-pager-page-edit-color: var(--morphi-text) !important;
    --dxbl-pager-page-edit-text-color: var(--morphi-text) !important;
    --dxbl-pager-page-edit-bg: var(--morphi-surface) !important;
}

.dxbl-text-edit {
    --dxbl-text-edit-bg: var(--morphi-surface) !important;
    --dxbl-text-edit-color: var(--morphi-text) !important;
    --dxbl-text-edit-placeholder-color: var(--morphi-text-secondary) !important;
    --dxbl-text-edit-border-color: var(--morphi-border) !important;
    --dxbl-text-edit-border-hovered-color: var(--morphi-slate) !important;
    --dxbl-text-edit-border-active-color: var(--morphi-azul) !important;
    --dxbl-text-edit-focus-border-color: var(--morphi-azul) !important;
    --dxbl-text-edit-underline-color: var(--morphi-border) !important;
    --dxbl-text-edit-underline-hovered-color: var(--morphi-azul) !important;
    --dxbl-text-edit-underline-focused-color: var(--morphi-azul) !important;
    --dxbl-text-edit-underline-active-color: var(--morphi-azul) !important;
}

/* Popups/modales (DxPopup — "Ejecutar reporte", confirmaciones, etc.) y los
   overlays de dropdown (calendario de DxDateEdit, lista de DxComboBox, panel
   de filtro/column chooser de DxGrid) comparten esta misma estructura interna
   (.dxbl-modal-content > .dxbl-modal-header + .dxbl-modal-body) y variables.
   --dxbl-popup-bg pinta el contenedor general, pero el body interno usa una
   variable DISTINTA (--dxbl-popup-body-bg) — sin pisarla quedaba un panel
   blanco entre el header y el contenido, y el botón de cerrar (×) usa otra
   variable más (--dxbl-popup-header-btn-color) que tampoco heredaba el color
   de texto del header. */
.dxbl-popup, .dxbl-modal-content {
    --dxbl-popup-bg: var(--morphi-surface) !important;
    --dxbl-popup-color: var(--morphi-text) !important;
    --dxbl-popup-border-color: var(--morphi-border) !important;
    --dxbl-popup-header-bg: var(--morphi-surface) !important;
    --dxbl-popup-header-color: var(--morphi-text) !important;
    --dxbl-popup-header-btn-color: var(--morphi-text) !important;
    --dxbl-popup-header-btn-hover-color: var(--morphi-azul) !important;
    --dxbl-popup-header-btn-bg: transparent !important;
    --dxbl-popup-header-btn-hover-bg: var(--morphi-azul-tint) !important;
    --dxbl-popup-body-bg: var(--morphi-surface) !important;
    --dxbl-popup-body-color: var(--morphi-text) !important;
    --dxbl-edit-dropdown-bg: var(--morphi-surface) !important;
    --dxbl-edit-dropdown-color: var(--morphi-text) !important;
}

/* Pills de estado/tipo usadas en columnas de grilla (AbmFieldDef.TextoDisplay puede
   devolver este markup — ver Docs/mockup-rediseno-rubros.html, .tipo-pill) */
.tipo-pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
}

.tipo-pill.tipo-venta { background: var(--morphi-azul-tint-strong); color: var(--morphi-azul-oscuro); }
.tipo-pill.tipo-mod   { background: var(--morphi-warning-bg); color: var(--morphi-warning); }
.tipo-pill.tipo-otro  { background: var(--morphi-mist-tint); color: var(--morphi-text); }

.rubro-pill {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 700;
    background: var(--morphi-mist-tint);
    color: var(--morphi-azul-oscuro);
}

.badge-mod { color: var(--morphi-success); font-weight: 700; }
.badge-off { color: var(--morphi-text-secondary); opacity: .5; }

/* Iconos de línea (mockups Docs/mockup-rediseno-*.html) — sprite SVG en Components/App.razor */
svg.ic {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vertical-align: -2px;
}

/* Tipografía institucional Morphi (Manual de Marca) — usable en todos sus pesos */
@font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('../fonts/montserrat-var.woff2') format('woff2');
}
@font-face {
    font-family: 'Montserrat';
    font-style: italic;
    font-weight: 600;
    font-display: swap;
    src: url('../fonts/montserrat-italic600.woff2') format('woff2');
}

html, body {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    margin: 0;
    font-family: 'Montserrat', 'Segoe UI', system-ui, sans-serif;
}

.w-100 {
    width: 100% !important;
}

.h-100 {
    height: 100% !important;
}

.h-auto {
    height: auto !important;
}

.overflow-hidden {
    overflow: hidden !important;
}

.text-danger {
    color: var(--dxds-color-content-danger-default-rest);
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--dxds-color-border-success-default-rest);
}

.invalid {
    outline: 1px solid var(--dxds-color-border-danger-default-rest);
}

.validation-message {
    color: var(--dxds-color-content-danger-default-rest);
}

.button-link {
    text-decoration: unset;
}

.title {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1rem 0;
}

.title.title-secondary {
    padding: 0.313rem 0 0;
    color: var(--dxds-color-content-secondary-default-rest);
}

.title-header-text {
    font-size: var(--dxds-font-size-headline-lg);
    font-weight: var(--dxds-font-weight-headline-default);
    letter-spacing: var(--dxds-letter-spacing-headline-lg);
    line-height: var(--dxds-line-height-headline-lg);
}

.title-content-text {
    font-size: var(--dxds-font-size-base-lg);
    font-weight: var(--dxds-font-weight-base-default);
    letter-spacing: var(--dxds-letter-spacing-base-lg);
    line-height: var(--dxds-line-height-base-lg);
}

.main-content {
    align-items: center;
    display: flex;
    height: 100%;
    justify-content: center;
    width: 100%;
}


/* Cartel de "Cargando..." global — ver el <div id="app-loading-indicator"> en
   App.razor (HTML estático, no un componente Blazor) y morphiLoading.show/hide.
   CSS global (no isolation) a propósito: mismo motivo, sacar cualquier duda
   sobre scope de CSS aislado de la ecuación. */
.app-loading-indicator {
    display: none;
    align-items: center;
    gap: 10px;
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 2147483000;
    padding: 12px 18px;
    background: var(--morphi-surface);
    border: 1px solid var(--morphi-border);
    border-radius: var(--morphi-radius);
    box-shadow: var(--morphi-shadow-md);
    color: var(--morphi-text);
    font-family: 'Montserrat', 'Segoe UI', sans-serif;
    font-size: .88rem;
    font-weight: 600;
}

.app-loading-indicator .ali-spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--morphi-border);
    border-top-color: var(--morphi-azul);
    border-radius: 50%;
    animation: ali-spin .7s linear infinite;
    flex-shrink: 0;
}

@keyframes ali-spin {
    to { transform: rotate(360deg); }
}

@media (max-width: 480px) {
    .app-loading-indicator {
        right: 12px;
        left: 12px;
        bottom: 12px;
    }
}

/* Cartel de "se cayó el circuito" — ver el <div id="blazor-error-ui"> en App.razor.
   display:none por defecto: blazor.web.js lo pone en "block" solo cuando el circuito
   se desconecta o hay una excepción no controlada, no hace falta tocarlo desde acá. */
#blazor-error-ui {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2147483001;
    padding: 12px 44px 12px 18px;
    background: var(--morphi-danger-bg);
    border-top: 1px solid var(--morphi-danger);
    color: var(--morphi-danger);
    font-family: 'Montserrat', 'Segoe UI', sans-serif;
    font-size: .88rem;
    font-weight: 600;
    text-align: center;
}

#blazor-error-ui .beu-reload {
    color: var(--morphi-danger);
    text-decoration: underline;
    font-weight: 700;
    margin-left: 8px;
}

#blazor-error-ui .beu-dismiss {
    position: absolute;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    cursor: pointer;
    font-weight: 700;
}