﻿/* ===========================================================================
   Modular UI — shared design-system primitives (prefix: mui-)
   Reusable building blocks for the modern page treatment. Use the PageHeader
   and SearchBox components for the common pieces; these classes back them and
   cover the rest (cards, empty states, count chips, row icons, toggles).
   Loaded once in App.razor after brand-theme.css so --bs-theme is available.
   See docs/design-system.md.
   =========================================================================== */

/* Foco de navegacion ----------------------------------------------------- */
/* Routes.razor lleva <FocusOnNavigate Selector="h1" />: al cambiar de pagina enfoca el titulo
   para que un lector de pantalla aterrice ahi en vez de quedarse donde estaba. Es accesibilidad
   de verdad y NO se quita. Lo que sobra es el recuadro negro que le pinta el navegador.

   La primera version de esta regla llevaba :not(:focus-visible), para conservar el anillo a quien
   navega con teclado. NO SIRVIO, y conviene saber por que: Chrome marca el foco como "visible"
   cuando la ultima interaccion fue de teclado, y entrar al portal es enviar un formulario con
   Enter. Asi que justo en el caso que reportaba el problema -- recien iniciada la sesion -- la
   condicion se cumplia y el recuadro salia igual. Probandolo navegando por URL no se reproduce.

   Para un H1 se quita sin condicion: no es un control, no se puede hacer nada con el, y el anillo
   no le dice nada a quien ve la pantalla. Quien usa lector de pantalla lo oye igual, que es lo
   que FocusOnNavigate persigue. Para el resto de elementos enfocados por programa se conserva el
   matiz, porque ahi si puede haber algo con lo que interactuar. */
h1:focus {
    outline: none;
}

[tabindex="-1"]:focus:not(:focus-visible) {
    outline: none;
}

/* Page shell ------------------------------------------------------------- */
.mui-page {
    padding: 0.5rem 0.25rem 2rem;
}

/* Header (icon chip + title + subtitle + actions) ------------------------ */
.mui-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.mui-heading {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.mui-heading-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background: rgba(var(--bs-theme-rgb, 31, 107, 255), 0.1);
    color: var(--bs-theme);
    flex: 0 0 auto;
}

    .mui-heading-icon .rzi {
        font-size: 1.5rem;
    }

.mui-title {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
    margin: 0;
    color: #1f2937;
}

.mui-subtitle {
    margin: 0;
    font-size: 0.85rem;
    color: #6b7280;
}

.mui-header-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* Los botones de accion de la cabecera no parten su texto en varias lineas.

   Sin esto, "Nueva ficha" se partia en vertical al lado del buscador. El culpable es que
   .mui-search es `flex: 1 1 240px`: reclama 240px y ademas crece, asi que cuando la fila se
   queda corta el unico que puede ceder es el boton, que por defecto es flex-shrink: 1. Y el
   boton no tiene ancho minimo propio, asi que cede hasta partir la palabra.

   Se invierte quien cede: el boton nunca, el buscador si -su input ya lleva min-width: 0 y esta
   pensado para encoger-. Y si aun asi no cabe, .mui-header-actions envuelve, que es la
   degradacion que ya estaba prevista. */
.mui-header-actions .rz-button {
    flex-shrink: 0;
    white-space: nowrap;
}

/* ...y para que ceda la caja de busqueda hace falta ESTO, o no cede nadie.

   Un elemento flex trae min-width: auto, o sea que su suelo es su propio contenido: la fila de
   acciones prefiere desbordar antes que estrecharse, y con la caja ya ancha eso dejaba "Nueva
   ficha" fuera de la pantalla por debajo de unos 600 px. Los tres niveles tienen que soltar ese
   suelo -la fila, el stack de dentro y la caja-; con soltar solo uno o dos no cambia nada.

   Comprobado a 560 px: sin esto el boton se sale del area visible; con esto la caja baja de 352
   a 322 y el boton entra. */
.mui-header-actions,
.mui-header-actions > * {
    min-width: 0;
}

/* Pero la caja tiene suelo: soltandola del todo se quedaba en 26 px -solo la lupa- en cuanto la
   columna se estrechaba, que es peor que desbordar. Por debajo de este ancho ya no encoge y es
   el RadzenStack el que parte en dos lineas (Wrap="FlexWrap.Wrap" en Fichas.razor), asi que el
   boton baja en vez de irse fuera de la pantalla.

   Hace falta porque el lateral no se pliega hasta bien entrado el movil: a 560 px de ventana la
   columna de contenido mide 262, y ahi no caben caja y boton en la misma linea. */
.mui-header-actions .mui-search {
    min-width: 180px;
}

/* Toolbar (search + actions row) ----------------------------------------- */
.mui-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

/* Search box ------------------------------------------------------------- */
.mui-search {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1 1 240px;
    /* Techo cuando sobra sitio. Subido de 360 para que quepa la caja mas ancha de abajo. */
    max-width: 460px;
    padding: 0.45rem 0.75rem;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

    .mui-search:focus-within {
        border-color: var(--bs-theme);
        box-shadow: 0 0 0 3px rgba(var(--bs-theme-rgb, 31, 107, 255), 0.12);
    }

    .mui-search > .rzi {
        color: #9ca3af;
        font-size: 1.15rem;
    }

.mui-search-input {
    flex: 1;
    /* Lo que ENSANCHA la caja es esto, no el flex-basis de .mui-search.

       .mui-header-actions se dimensiona por contenido -tiene sitio de sobra al lado del titulo,
       no esta apretada-, y en ese caso el ancho que sale es el intrinseco del contenido, no el
       flex-basis. El intrinseco lo ponia el <input>, que sin width mide los ~179 px de fabrica y
       dejaba la caja en 231. Se comprobo en el navegador: subir el basis a 320 no movio nada y
       dar width al input la llevo a 352.

       Sigue encogiendo en pantallas estrechas, que es lo que hay que conservar: el min-width: 0
       de aqui abajo se lo permite, y en una fila corta cede la caja antes que el boton. */
    width: 300px;
    border: none;
    outline: none;
    background: transparent;
    font-size: 0.9rem;
    color: #1f2937;
    min-width: 0;
}

.mui-search-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: #9ca3af;
    cursor: pointer;
    padding: 0;
}

    .mui-search-clear:hover {
        color: #4b5563;
    }

/* Count chip ------------------------------------------------------------- */
.mui-count-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--bs-theme);
    background: rgba(var(--bs-theme-rgb, 31, 107, 255), 0.1);
    padding: 0.35rem 0.7rem;
    border-radius: 999px;
}

    .mui-count-chip .rzi {
        font-size: 1rem;
    }

/* Card container --------------------------------------------------------- */
.mui-card {
    background: #fff;
    border: 1px solid #eceef1;
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
    padding: 0.75rem;
}

/* Row icon chip (small leading icon in grid/list rows) ------------------- */
.mui-row-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    margin-right: 0.6rem;
    background: rgba(var(--bs-theme-rgb, 31, 107, 255), 0.1);
    color: var(--bs-theme);
    flex: 0 0 auto;
}

    .mui-row-icon .rzi {
        font-size: 1rem;
    }

/* Empty / no-results state ---------------------------------------------- */
.mui-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 3rem 1rem;
    color: #6b7280;
}

    .mui-empty .rzi {
        font-size: 2.75rem;
        color: #cbd2da;
        margin-bottom: 0.5rem;
    }

.mui-empty-title {
    font-size: 1.1rem;
    font-weight: 600;
    color: #374151;
}

.mui-empty-text {
    font-size: 0.9rem;
    margin-bottom: 1rem;
}

.mui-empty-btn {
    border: 1px solid var(--bs-theme);
    color: var(--bs-theme);
    background: transparent;
    border-radius: 8px;
    padding: 0.4rem 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.12s ease;
}

    .mui-empty-btn:hover {
        background: rgba(var(--bs-theme-rgb, 31, 107, 255), 0.08);
    }

/* Toggle switch (boolean on/off) ---------------------------------------- */
.mui-toggle {
    position: relative;
    width: 38px;
    height: 22px;
    border-radius: 999px;
    background: #d1d5db;
    border: none;
    padding: 0;
    cursor: pointer;
    flex: 0 0 auto;
    transition: background-color 0.15s ease;
}

    .mui-toggle.on {
        background: var(--bs-theme);
    }

.mui-toggle-knob {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: transform 0.15s ease;
}

.mui-toggle.on .mui-toggle-knob {
    transform: translateX(16px);
}

/* Loading skeleton card -------------------------------------------------- */
.mui-skeleton {
    height: 200px;
    border-radius: 14px;
    background: linear-gradient(90deg, #f1f3f5 25%, #e9ecef 37%, #f1f3f5 63%);
    background-size: 400% 100%;
    animation: mui-shimmer 1.4s ease infinite;
}

@keyframes mui-shimmer {
    0% {
        background-position: 100% 50%;
    }

    100% {
        background-position: 0 50%;
    }
}
