/* ==========================================================================
   ERP-Pro — base de accesibilidad e idioma (2.3.0).
   --------------------------------------------------------------------------
   QUE ES ESTO. La parte de la auditoria de UX que tiene que valer con
   CUALQUIER capa de diseño, tambien con `classic` -que no carga
   erp-modern.css-: el foco visible, las etiquetas de estado legibles, el menu
   del movil por encima del contenido, el dialogo de confirmacion y el campo
   de fichero en el idioma del usuario.

   Se carga SIEMPRE en el panel, en el portal y en las pantallas de acceso,
   detras del tema (style.css) y DELANTE de la capa de diseño: lo que la capa
   moderna redefina con el mismo selector gana por orden de cascada, y en la
   clasica quedan estos valores.

   POR QUE LLEVA RESPALDOS EN CADA var(). En `classic` los tokens `--erp-*` no
   existen (los declara erp-modern.css), y un var() sin respaldo deja la
   propiedad en «invalido en tiempo de computo»: un color transparente sin
   error en ninguna parte. Todo color de aqui es var(--token, respaldo).

   ORGANIZACION
     1. Enlaces: el token --erp-link
     2. Foco visible
     3. Etiquetas de estado (label, badge) en tono suave AA
     4. Menu del movil: cajon por encima del contenido
     5. Dialogo de confirmacion (.erp-confirm)
     6. Campo de fichero (.erp-file)
     7. Movil: letra de los campos a 16 px
     8. Utilidades
   ========================================================================== */

/* ============================================================ 1. ENLACES === */

/* El color de los enlaces del CONTENIDO. Lo fija «Estilo del tema» (modulo
   ThemeStyle) escribiendo `--erp-link-custom` y su variante para el modo
   oscuro, que calcula el servidor hasta 4,5:1; sin color propio es la tinta
   del acento. La regla que lo APLICA la imprime ThemeStyle solo cuando hay un
   color guardado, y deja fuera botones, pestañas, logotipo y menus: ver
   `theme_style_links_selector()`. */
:root {
    --erp-link: var(--erp-link-custom, var(--erp-accent-text, #1d4ed8));
    /* El anillo de foco. Un tema propio lo puede redefinir. */
    --erp-focus: var(--erp-accent-text, #1d4ed8);
}

/* El modo oscuro solo existe en la capa moderna: en la clasica el panel se
   sigue pintando claro aunque el ajuste diga «oscuro», asi que ahi el enlace
   se queda con su color de modo claro. */
:root[data-erp-style="modern"][data-erp-mode="dark"] {
    --erp-link: var(--erp-link-custom-dark, var(--erp-accent-text, #93b4fb));
}

@media (prefers-color-scheme: dark) {
    :root[data-erp-style="modern"][data-erp-mode="auto"] {
        --erp-link: var(--erp-link-custom-dark, var(--erp-accent-text, #93b4fb));
    }
}

/* ======================================================= 2. FOCO VISIBLE === */

/* Un anillo unico y claro en todo lo que se maneja con el teclado, tambien en
   el boton de bootstrap-select. `:focus-visible` hace que no aparezca al
   pulsar con el raton, salvo en los campos de texto, donde el navegador lo
   enseña siempre (y ahi es justo donde hace falta).

   El `!important` es a proposito y es la UNICA excepcion de la hoja: el tema
   y el bundle de Tailwind apagan el contorno con reglas como
   `focus:tw-outline-none`, `.btn:focus { outline: 0 }` o
   `input.form-control:focus`, cualificadas por elemento. Un foco que se puede
   apagar con una utilidad no es un foco garantizado. */
/* Bastino trae su propio foco (turquesa, con el cuadro de texto marcado por
   fuera con :focus-within), así que se queda fuera. */
:root :is(a, button, input, select, textarea, summary, [tabindex], [role="button"], [contenteditable="true"], .btn):not([class*="bst-"], #bastino-root *):focus-visible {
    outline: 2px solid var(--erp-focus, var(--erp-accent-text, #1d4ed8)) !important;
    outline-offset: 2px !important;
}

/* En los campos el anillo va pegado al borde: con 2 px de separacion parece
   otro campo. */
:root :is(input, select, textarea, .form-control):not(#bastino-root *):focus-visible {
    outline-offset: 0 !important;
}

/* El desplegable de bootstrap-select es un <button> dentro del grupo: el
   anillo va en el boton, no en el <select> escondido. */
:root .bootstrap-select > .dropdown-toggle:focus-visible,
:root .bootstrap-select.open > .dropdown-toggle {
    outline: 2px solid var(--erp-focus, var(--erp-accent-text, #1d4ed8)) !important;
    outline-offset: 0 !important;
}

/* ======================================== 3. ETIQUETAS DE ESTADO (AA) ===== */

/* Fondo claro y tinta oscura del mismo tono, con 4,5:1 como minimo medido en
   claro y en oscuro (ver el informe de la tanda 1). En la capa moderna los
   tokens salen de erp-modern.css; en la clasica, de los respaldos, que son los
   mismos valores del modo claro. La capa moderna vuelve a declarar estas
   clases con su forma de pastilla y gana por orden.

   Las etiquetas que pintan un color ELEGIDO EN UN CATALOGO (estados de lead,
   de ticket, de expediente, de factura...) llevan el color en el atributo
   `style`; esas las tiñe `app-ux.js` respetando el tono elegido, porque desde
   CSS no se puede leer el color de fondo de otro elemento. */
.label-default {
    background-color: var(--erp-surface-3, #eef2f6);
    color: var(--erp-ink-soft, #334155);
}

.label-primary {
    background-color: var(--erp-a-14, #e8effd);
    color: var(--erp-accent-text, #1d4ed8);
}

.label-success {
    background-color: var(--erp-ok-bg, #e7f6ed);
    color: var(--erp-ok, #166534);
}

.label-info {
    background-color: var(--erp-info-bg, #e8effd);
    color: var(--erp-info, #1d4ed8);
}

.label-warning {
    background-color: var(--erp-warn-bg, #fdf1dd);
    color: var(--erp-warn, #92400e);
}

.label-danger {
    background-color: var(--erp-danger-bg, #fdeaea);
    color: var(--erp-danger, #b91c1c);
}

/* El pie de los listados («Mostrando 1–10 de 21 registros»): el bundle lo
   deja en #6b7280 con una regla cualificada por elemento, que en oscuro daba
   3,6:1. */
div.dataTables_wrapper div.dataTables_info {
    color: var(--erp-ink-muted, #5b6577);
}

/* Los textos semanticos del tema. En la capa clasica el bundle de Tailwind
   los pinta con los 500/600 de la paleta -#ef4444 (3,8:1), #ca8a04 (2,9:1),
   #16a34a (3,3:1)-, que no llegan a 4,5:1 sobre blanco; la moderna ya los
   saca de los tokens y los vuelve a declarar detras. */
.text-danger  { color: var(--erp-danger, #b91c1c); }
.text-warning { color: var(--erp-warn, #92400e); }
.text-success { color: var(--erp-ok, #166534); }
.text-info    { color: var(--erp-info, #1d4ed8); }
.text-muted   { color: var(--erp-ink-muted, #5b6577); }

/* El boton informativo de la capa clasica: blanco sobre #0284c7 daba 4,1:1. */
:root:not([data-erp-style="modern"]) .btn-info {
    background-color: #0369a1;
    border-color: #0369a1;
    color: #ffffff;
}

:root:not([data-erp-style="modern"]) .btn-info:hover,
:root:not([data-erp-style="modern"]) .btn-info:focus {
    background-color: #075985;
    border-color: #075985;
    color: #ffffff;
}

/* Variante «maciza» (Ajustes → Apariencia → Etiquetas de estado): el color
   lleno de toda la vida, con la tinta que contrasta. Los rellenos estan
   elegidos para dar 4,5:1 o mas con letra blanca. */
:root[data-erp-badges="solid"] .label-default {
    background-color: #475569;
    border-color: transparent;
    color: #ffffff;
}

:root[data-erp-badges="solid"] .label-primary { background-color: var(--erp-accent, #2563eb); border-color: transparent; color: var(--erp-accent-ink, #ffffff); }
:root[data-erp-badges="solid"] .label-success { background-color: #15803d; border-color: transparent; color: #ffffff; }
:root[data-erp-badges="solid"] .label-info    { background-color: #1d4ed8; border-color: transparent; color: #ffffff; }
:root[data-erp-badges="solid"] .label-warning { background-color: #b45309; border-color: transparent; color: #ffffff; }
:root[data-erp-badges="solid"] .label-danger  { background-color: #b91c1c; border-color: transparent; color: #ffffff; }

/* ============================================== 4. MENU DEL MOVIL ========== */

/* El tema empujaba la pagina 230 px a la derecha al abrir el menu en un
   movil, con un velo a medias (`#wrapper:after`) que no cerraba nada. Ahora
   es un cajon: va POR ENCIMA del contenido, debajo de la cabecera -el boton
   de menu sigue a la vista para cerrarlo-, con su velo, y se cierra al tocar
   fuera o con Escape (app-ux.js).

   Solo en el panel: `page-small` lo pone main.js por debajo de 769 px, igual
   que su manejador del boton. El portal tiene su propio cajon (portal.css). */
body.page-small #menu {
    position: fixed !important;
    top: 57px;
    bottom: 0;
    left: 0;
    /* Por encima del boton flotante de Bastino (1035-1037). */
    z-index: 1041;
    width: min(320px, 86vw) !important;
    margin-left: 0 !important;
    padding-bottom: 24px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    transform: translateX(-105%);
    visibility: hidden;
    transition: transform .2s ease, visibility 0s linear .2s;
    box-shadow: none;
}

body.page-small.show-sidebar #menu {
    transform: none;
    visibility: visible;
    transition: transform .2s ease, visibility 0s;
    box-shadow: 0 18px 40px -12px rgba(15, 23, 42, .45);
}

/* La pagina no se mueve. */
body.page-small.show-sidebar #wrapper {
    margin-left: 0 !important;
}

/* El velo del tema no cerraba nada y tapaba la cabecera: se sustituye por el
   de app-ux.js, que si es un elemento y se puede tocar. */
body.page-small.show-sidebar #wrapper::after {
    content: none !important;
}

/* El hueco de 68 px que deja el menu arriba es para la cabecera fija del
   escritorio; en el cajon ya empieza debajo de ella. */
body.page-small #menu > #side-menu {
    margin-top: 8px !important;
}

/* Entradas tactiles de 44 px. */
body.page-small #side-menu > li > a,
body.page-small #side-menu .nav-second-level > li > a {
    min-height: 44px;
    padding-top: 12px !important;
    padding-bottom: 12px !important;
    line-height: 20px;
}

.erp-menu-scrim {
    position: fixed;
    top: 57px;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1040;
    background: rgba(15, 23, 42, .42);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s ease, visibility 0s linear .2s;
}

body.page-small.show-sidebar .erp-menu-scrim {
    opacity: 1;
    visibility: visible;
    transition: opacity .2s ease, visibility 0s;
}

/* Sin el cajon abierto no se desplaza la pagina de detras al hacer scroll en el
   menu: solo el menu. */
body.page-small.show-sidebar {
    overflow: hidden;
}

/* El boton de menu: 44 x 44 de zona tactil (WCAG 2.5.5), con el icono del
   mismo tamaño de siempre. */
#header .hide-menu.erp-menu-toggle {
    width: 44px;
    height: 44px;
    margin-top: 6px !important;
    padding: 0 !important;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
}

#header .hide-menu.erp-menu-toggle svg {
    width: 20px;
    height: 20px;
}

@media (prefers-reduced-motion: reduce) {
    body.page-small #menu,
    .erp-menu-scrim,
    .erp-confirm,
    .erp-confirm__box {
        transition: none !important;
    }
}

/* ===================================== 5. DIALOGO DE CONFIRMACION ========== */

/* Sustituye al `confirm()` del navegador en los borrados y en cualquier
   «¿seguro?» del panel (app-ux.js). No es un modal de Bootstrap a proposito:
   puede abrirse con otro modal ya abierto (borrar una linea dentro de un
   modal) y tiene que quedar encima, con su propio foco atrapado. */
.erp-confirm {
    position: fixed;
    inset: 0;
    z-index: 10060;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    opacity: 0;
    transition: opacity .15s ease;
}

.erp-confirm[hidden] {
    display: none !important;
}

.erp-confirm.is-open {
    opacity: 1;
}

.erp-confirm__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .5);
}

.erp-confirm__box {
    position: relative;
    width: 100%;
    max-width: 440px;
    background: var(--erp-surface, #ffffff);
    color: var(--erp-ink, #0f1723);
    border: 1px solid var(--erp-border, #e3e8f0);
    border-radius: var(--erp-radius, 12px);
    box-shadow: 0 2px 6px rgba(15, 23, 42, .12), 0 24px 48px -12px rgba(15, 23, 42, .35);
    padding: 22px 22px 18px;
    transform: translateY(6px) scale(.98);
    transition: transform .15s ease;
}

.erp-confirm.is-open .erp-confirm__box {
    transform: none;
}

.erp-confirm__head {
    display: flex;
    gap: 14px;
    align-items: flex-start;
}

.erp-confirm__icon {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    background: var(--erp-info-bg, #e8effd);
    color: var(--erp-info, #1d4ed8);
}

.erp-confirm--danger .erp-confirm__icon {
    background: var(--erp-danger-bg, #fdeaea);
    color: var(--erp-danger, #b91c1c);
}

.erp-confirm__title {
    margin: 2px 0 6px;
    font-size: 16px;
    line-height: 1.35;
    font-weight: 650;
    color: var(--erp-ink, #0f1723);
    overflow-wrap: anywhere;
}

.erp-confirm__body,
.erp-confirm__note {
    margin: 0 0 4px;
    font-size: 14px;
    line-height: 1.5;
    color: var(--erp-ink-soft, #3d4759);
    white-space: pre-line;
}

.erp-confirm__note {
    font-weight: 600;
    color: var(--erp-danger, #b91c1c);
}

.erp-confirm__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 18px;
}

.erp-confirm__actions .btn {
    min-height: 40px;
    min-width: 96px;
    font-weight: 600;
}

/* El boton de peligro: rojo macizo con tinta calculada (6,5:1), tambien en la
   capa clasica, donde .btn-danger de Bootstrap da 3,9:1. */
.erp-confirm .erp-confirm__ok.btn-danger {
    background-color: var(--erp-danger-solid, #b91c1c);
    border-color: var(--erp-danger-solid, #b91c1c);
    color: var(--erp-danger-solid-ink, #ffffff);
}

.erp-confirm .erp-confirm__ok.btn-danger:hover,
.erp-confirm .erp-confirm__ok.btn-danger:focus {
    background-color: #991b1b;
    border-color: #991b1b;
    color: #ffffff;
}

@media (max-width: 480px) {
    .erp-confirm {
        align-items: flex-end;
        padding: 0;
    }

    .erp-confirm__box {
        max-width: none;
        border-radius: 16px 16px 0 0;
        padding-bottom: max(18px, env(safe-area-inset-bottom));
    }

    .erp-confirm__actions .btn {
        flex: 1 1 0;
        min-height: 44px;
    }
}

/* Lo que arrastra el borrado (2.3.2): lo que se va con el y lo que se queda
   sin el vinculo, con su recuento; y, si hay mucho en juego, escribir el
   nombre para confirmar. */
.erp-confirm__impact {
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: var(--erp-radius-sm, 8px);
    background: var(--erp-surface-2, #f6f8fb);
    border: 1px solid var(--erp-border, #e3e8f0);
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--erp-ink-soft, #3d4759);
    max-height: 40vh;
    overflow-y: auto;
}

.erp-confirm__impact[hidden],
.erp-confirm__type[hidden],
.erp-confirm__ok[hidden] {
    display: none !important;
}

.erp-confirm__impact p {
    margin: 0;
}

.erp-confirm__impact-head {
    font-weight: 650;
    color: var(--erp-ink, #0f1723);
}

.erp-confirm__impact-head--removed {
    color: var(--erp-danger, #b91c1c);
}

.erp-confirm__impact-list {
    margin: 4px 0 8px;
    padding-left: 18px;
}

.erp-confirm__impact-list:last-child {
    margin-bottom: 0;
}

.erp-confirm__impact-list strong {
    font-variant-numeric: tabular-nums;
    color: var(--erp-ink, #0f1723);
}

.erp-confirm__impact-loading,
.erp-confirm__impact-none {
    color: var(--erp-ink-muted, #5b6577);
}

.erp-confirm__impact-error {
    color: var(--erp-warn, #92400e);
    font-weight: 600;
}

.erp-confirm__type {
    margin-top: 12px;
}

.erp-confirm__type-label {
    display: block;
    margin-bottom: 6px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--erp-ink, #0f1723);
    overflow-wrap: anywhere;
}

/* Mientras el dialogo esta abierto no se desplaza la pagina de detras. */
html.erp-confirm-open,
html.erp-confirm-open body {
    overflow: hidden;
}

/* ================================================ 6. CAMPO DE FICHERO ===== */

/* El «Choose File / No file chosen» lo escribe el navegador en SU idioma, no
   en el del usuario, y no hay forma de traducirlo. app-ux.js envuelve cada
   <input type="file"> en un <label class="erp-file"> con el boton y el nombre
   del fichero en el idioma activo; el campo sigue ahi, enfocable y
   funcionando igual (es el que se envia). */
.erp-file {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    max-width: 100%;
    margin: 0;
    font-weight: 400;
    cursor: pointer;
    vertical-align: middle;
}

.erp-file > input[type="file"] {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
    opacity: 0;
}

.erp-file__button {
    flex: 0 0 auto;
    pointer-events: none;
}

.erp-file__name {
    min-width: 0;
    max-width: 40vw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--erp-ink-muted, #5b6577);
    font-size: 13px;
}

.erp-file.has-file .erp-file__name {
    color: var(--erp-ink, #0f1723);
}

.erp-file:focus-within .erp-file__button {
    outline: 2px solid var(--erp-focus, var(--erp-accent-text, #1d4ed8));
    outline-offset: 2px;
}

/* Dentro de un `.input-group` de Bootstrap (que es una tabla) el campo ocupa
   la celda que ocupaba el <input>, y el nombre se recorta antes: si no, en un
   movil empujaba el boton de al lado fuera de la pantalla. */
.input-group > .erp-file {
    display: table-cell;
    width: 100%;
    vertical-align: middle;
    white-space: nowrap;
    padding-right: 8px;
}

.input-group > .erp-file > .erp-file__button,
.input-group > .erp-file > .erp-file__name {
    display: inline-block;
    vertical-align: middle;
}

.input-group > .erp-file > .erp-file__name {
    max-width: 30vw;
    margin-left: 8px;
}

.erp-file.is-disabled {
    cursor: not-allowed;
    opacity: .6;
}

/* ==================================== 7. MOVIL: LETRA DE LOS CAMPOS ======= */

/* Con menos de 16 px, iOS amplia la pagina al enfocar un campo y el usuario
   tiene que reducirla a mano. Cualificado por elemento porque el tema declara
   `input.form-control`. */
@media (max-width: 767px) {
    input.form-control,
    select.form-control,
    textarea.form-control,
    .bootstrap-select > .dropdown-toggle,
    .bootstrap-select .bs-searchbox input.form-control,
    #search_input,
    .bst-input textarea {
        font-size: 16px !important;
    }
}

/* ===================================================== 8. UTILIDADES ===== */

/* Texto solo para lectores de pantalla, sin `display: none` (que lo saca del
   arbol de accesibilidad). */
.erp-sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}
