/* =================================================================================================
   dameti-components.css - componentes de Framework1000
   Framework1000 · .NET 10.00

   Un bloque por componente, con el mismo nombre de clase que usa el .razor. Todos los valores
   salen de las variables de dameti.css: aqui no se escribe ningun color a mano.
   ================================================================================================= */

/* =================================================================================================
   Barra lateral
   ================================================================================================= */

/* La barra es oscura y el resto de la aplicacion claro, asi que no usa las superficies del tema
   sino sus propias variables: son las que la organizacion cambia en las variables de configuracion. */
.sidebar {
    display: flex;
    flex-direction: column;
    flex: 0 0 var(--dm-sidebar-width);
    width: var(--dm-sidebar-width);
    color: var(--dm-sidebar-text);
    background: var(--dm-sidebar-bg);
    border-right: 1px solid var(--dm-sidebar-border);
    transition: width .15s ease, flex-basis .15s ease;
}

.sidebar--collapsed {
    flex-basis: var(--dm-sidebar-width-collapsed);
    width: var(--dm-sidebar-width-collapsed);
}

.sidebar__brand {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--dm-space-2);
    height: var(--dm-header-height);
    padding: 0 var(--dm-space-4);
    border-bottom: 1px solid var(--dm-sidebar-border);
}

/* La marca es un ENLACE al panel: pulsar el nombre de la casa lleva a la portada es lo que todo el
   mundo prueba, y hasta ahora no hacia nada porque era un <span>. Se pinta igual que el texto que
   era —sin subrayado y con el color de la barra—, asi que el cambio no se ve hasta que se pulsa. */
.sidebar__title {
    text-decoration: none;
    color: var(--dm-sidebar-text-strong);
    font-size: var(--dm-text-lg);
    font-weight: 600;
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar__toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: transparent;
    border: none;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
}

.sidebar__toggle:hover {
    background: var(--dm-sidebar-hover);
}

/* Las tres rayas, dibujadas con sombras sobre una sola caja. El contenido de texto que habia aqui
   —el caracter ≡— dependia de que la fuente del sistema lo tuviera y salia de un tamano distinto
   en cada maquina. */
.sidebar__toggle-icon {
    display: block;
    width: 15px;
    height: 1.5px;
    background: currentColor;
    border-radius: 1px;
    box-shadow: 0 -5px 0 currentColor, 0 5px 0 currentColor;
}

.sidebar__nav {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: var(--dm-space-2) 0;
}

.sidebar__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Cada entrada del menu. La vineta se quita en la lista; esto es solo el gancho del <li>. */
.sidebar__item {
    margin: 0;
}

/* La entrada de menu.

   El resaltado de la activa era una banda de color a sangre, de borde a borde de la barra y con
   una raya de 3px pegada al canto izquierdo. Pesaba mas que el propio menu. Ahora la pastilla se
   mete dentro de la barra y se redondea: sigue siendo el elemento mas visible de la columna, pero
   ya no la parte en dos. */
.sidebar__link {
    display: flex;
    align-items: center;
    gap: var(--dm-space-3);
    margin: 1px var(--dm-space-2);
    padding: 7px var(--dm-space-3);
    color: var(--dm-sidebar-text);
    font-size: var(--dm-text-base);
    text-decoration: none;
    border-radius: var(--dm-radius-sm);
    transition: background-color .1s ease, color .1s ease;
}

.sidebar__link:hover {
    color: var(--dm-sidebar-text-strong);
    background: var(--dm-sidebar-hover);
    text-decoration: none;
}

.sidebar__link--active {
    color: var(--dm-sidebar-active-text);
    background: var(--dm-sidebar-active-bg);
    font-weight: 600;
}

/* El icono de la entrada apagada va mas suave que su texto: si los dos pesan igual, una columna de
   ocho entradas se lee como ocho manchas y no como una lista. En la activa recupera el color
   entero, que es parte de lo que la distingue. */
.sidebar__icon {
    flex: 0 0 auto;
    opacity: .72;
}

.sidebar__link--active .sidebar__icon,
.sidebar__link:hover .sidebar__icon {
    opacity: 1;
}

.sidebar__text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Titulo de un tramo del menu. No lo pinta nadie todavia -el armazon no agrupa las entradas de
   primer nivel-, pero es el gancho para cuando una aplicacion tenga doce y necesite separarlas. */
.sidebar__section {
    padding: var(--dm-space-4) var(--dm-space-4) var(--dm-space-1);
    font-size: var(--dm-text-xs);
    font-weight: 600;
    color: var(--dm-sidebar-text);
    text-transform: uppercase;
    letter-spacing: .06em;
    opacity: .5;
}

/* El pie no lleva relleno lateral: lo que va dentro es el grupo desplegable, que ya trae el suyo en
   cada entrada. Con relleno aqui, las entradas quedarian metidas hacia dentro respecto del menu. */
.sidebar__footer {
    padding: var(--dm-space-2) 0;
    border-top: 1px solid var(--dm-sidebar-border);
}

/* --- El grupo desplegable del pie -------------------------------------------------------------
   Es un <details> con su <summary>: se abre y se cierra sin circuito, que es lo unico que vale en
   SSR estatico.
--------------------------------------------------------------------------------------------- */

.sidebar__group-summary {
    cursor: pointer;
    list-style: none;          /* quita el triangulo del navegador; el nuestro es .sidebar__group-arrow */
    user-select: none;
}

.sidebar__group-summary::-webkit-details-marker {
    display: none;
}

.sidebar__group-arrow {
    margin-left: auto;
    font-size: .6rem;
    opacity: .6;
    transition: transform .15s ease;
}

.sidebar__group[open] .sidebar__group-arrow {
    transform: rotate(180deg);
}

/* --- La sangria de las entradas hijas ----------------------------------------------------------
   ESTO SE VE O NO ES NADA. Antes las hijas quedaban 16px a la derecha de su padre y el fondo del
   bloque era un negro un 18% mas oscuro: sobre una barra que YA es casi negra, esa diferencia no
   existe en pantalla. Abrir «Configuracion» daba cuatro entradas mas, al mismo nivel aparente que
   el resto del menu, y nada decia que colgaran de ella.

   Ahora la jerarquia la dicen tres cosas a la vez, y ninguna sola bastaba: el ICONO del hijo
   arranca donde arranca el TEXTO del padre —la sangria clasica de un arbol—, una raya vertical
   recorre el bloque por la izquierda uniendo a los hermanos, y el texto baja un escalon de cuerpo.

   La raya se pinta con un ::before del <ul> y no con un border-left del enlace: asi es UNA linea
   continua de arriba abajo del grupo y no cuatro trozos sueltos, uno por entrada.
--------------------------------------------------------------------------------------------- */

.sidebar__list--nested {
    position: relative;
    margin: 0 0 var(--dm-space-2);
    padding: 0;
    list-style: none;
}

/* La raya cae justo BAJO EL CENTRO DEL ICONO del padre, no en un punto cualquiera: asi se lee como
   algo que cuelga de esa entrada y no como un adorno vertical suelto. */
.sidebar__list--nested::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 4px;
    left: 28px;
    width: 1px;
    background: currentColor;
    opacity: .35;
}

/* El icono del hijo arranca donde arranca el TEXTO del padre. Es la sangria clasica de un arbol, y
   es la que se lee sin pensarlo. */
.sidebar__link--nested {
    gap: var(--dm-space-2);
    margin-left: var(--dm-space-2);
    padding-left: 33px;
    font-size: var(--dm-text-sm);
}

/* El icono del hijo es mas pequeno que el del padre. Es la misma idea que la sangria: la
   diferencia de tamano se lee como nivel antes de que nadie lea los textos. */
.sidebar__link--nested .sidebar__icon {
    --dm-icon-size: 15px;
}

/* =================================================================================================
   Cabecera
   ================================================================================================= */

.app-header {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--dm-space-4);
    height: var(--dm-header-height);
    padding: 0 var(--dm-space-4);
    background: var(--dm-surface);
    border-bottom: 1px solid var(--dm-border);
}

/* El hamburguesa va delante del titulo, y los dos juntos en un contenedor que empuja las
   herramientas al otro extremo. */
.app-header__start {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    min-width: 0;
}

/*
   Contenedor del titulo. Es de maquetacion y su ausencia se veia: sin el, el titulo no empuja
   las herramientas al otro extremo de la cabecera.
*/
.app-header__title {
    flex: 1 1 auto;
    min-width: 0;
}

/* --- El hamburguesa ---------------------------------------------------------------------------
   Es un <button data-shell-toggle>, y lo atiende wwwroot/js/ui.js poniendo data-sidebar en <html>.
   Era un <label for> de un checkbox del armazon —plegaba sin una linea de script—, y lo que se
   perdio al cambiarlo es exactamente eso; lo que se gana es que el plegado SOBREVIVA a la
   navegacion, que es lo que no hacia. El porque completo esta en dameti.css, en «La barra plegada».
--------------------------------------------------------------------------------------------- */

.app-header__burger {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    margin-right: var(--dm-space-2);
    color: var(--dm-text-soft);
    background: transparent;
    border: none;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
    transition: background-color .1s ease, color .1s ease;
}

.app-header__burger:hover {
    color: var(--dm-text);
    background: var(--dm-surface-alt);
}

/* Tres rayas sobre una sola caja, con dos sombras. Con ::before y ::after hacian falta tres reglas
   y un position: relative para lo mismo. */
.app-header__burger-icon {
    display: block;
    width: 16px;
    height: 1.5px;
    background: currentColor;
    border-radius: 1px;
    box-shadow: 0 -5px 0 currentColor, 0 5px 0 currentColor;
}

/* El titulo de la cabecera. NO es un <h1>: el encabezado del documento es el titulo de la pantalla,
   el que va dentro del contenido. Aqui hay un nombre, y un nombre no es un encabezado. */
.app-header__heading {
    margin: 0;
    font-size: var(--dm-text-lg);
    font-weight: 600;
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-header__tools {
    display: flex;
    align-items: center;
    gap: var(--dm-space-4);
}

/* Aqui estaban .app-header__bell y su hover: la campana suelta que hubo antes de que las cuatro
   piezas del usuario tuvieran cada una su desplegable. Ningun componente emite ya esa clase —hay
   dos tests que comprueban precisamente que no vuelva—, asi que su estilo era marcado muerto. */

/* El contador. Va con un aro del color de la cabecera para que no se confunda con el icono que hay
   debajo: sin el, un «3» rojo pegado a la campana se lee como parte del dibujo. */
.app-header__badge {
    position: absolute;
    top: -2px;
    right: -3px;
    min-width: 15px;
    padding: 0 4px;
    font-size: .625rem;
    font-weight: 600;
    line-height: 15px;
    text-align: center;
    color: #fff;
    background: var(--dm-danger);
    border-radius: 999px;
    box-shadow: 0 0 0 2px var(--dm-surface);
}

.app-header__user {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    text-align: right;
}

.app-header__user-name {
    font-size: var(--dm-text-base);
    font-weight: 600;
}

.app-header__user-role {
    font-size: var(--dm-text-xs);
    color: var(--dm-text-muted);
    text-transform: capitalize;
}

/* Debajo de 720px el nombre y el rol desaparecen y se queda el avatar. Es el unico sitio de la
   cabecera que puede irse sin que se pierda una funcion: el menu entero sigue colgando del avatar. */
@media (max-width: 720px) {
    .app-header__user { display: none; }
}

/* Aqui estaban .app-header__signout y .app-header__signout-button, el boton suelto de «Salir» en
   la cabecera. Salir vive ahora dentro del menu de cuenta y usa .account-menu__item, que es lo que
   pinta AppHeader: dos reglas para un boton que ya no existe son marcado muerto. */

/* --- El avatar y su menu de cuenta ------------------------------------------------------------
   Otro <details>: el menu se abre sin circuito. Dentro van el nombre, el correo, «Mi perfil» y
   «Cerrar sesion», que es un <form> con su boton.
--------------------------------------------------------------------------------------------- */

.app-header__account {
    position: relative;
}

.app-header__account-summary {
    display: flex;
    align-items: center;
    gap: var(--dm-space-3);
    padding: var(--dm-space-1) var(--dm-space-2);
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
    list-style: none;
    user-select: none;
}

.app-header__account-summary::-webkit-details-marker {
    display: none;
}

.app-header__account-summary:hover {
    background: var(--dm-surface-alt);
}

.app-header__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: var(--dm-avatar-size);
    height: var(--dm-avatar-size);
    font-size: var(--dm-text-sm);
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--dm-primary-contrast);
    background: var(--dm-primary);
    border-radius: 50%;
    user-select: none;
}

.account-menu {
    position: absolute;
    top: calc(100% + var(--dm-space-2));
    right: 0;
    z-index: 30;
    min-width: 232px;
    padding: var(--dm-space-1) 0;
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow-lg);
}

.account-menu__meta {
    padding: 3px var(--dm-space-3);
    font-size: var(--dm-text-xs);
    color: var(--dm-text-muted);
}

.account-menu__separator {
    height: 1px;
    margin: var(--dm-space-2) 0;
    background: var(--dm-border);
}

.account-menu__item {
    display: block;
    width: 100%;
    padding: var(--dm-space-2) var(--dm-space-3);
    font: inherit;
    font-size: var(--dm-text-base);
    color: var(--dm-text);
    text-align: left;
    text-decoration: none;
    background: transparent;
    border: none;
    cursor: pointer;
}

.account-menu__item:hover {
    background: var(--dm-surface-alt);
    text-decoration: none;
}

.account-menu__item--danger:hover {
    color: var(--dm-danger);
}

.account-menu__signout {
    margin: 0;
}

/* =================================================================================================
   Boton
   ================================================================================================= */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--dm-space-2);
    padding: 6px var(--dm-space-4);
    font-size: var(--dm-text-base);
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
    transition: background-color .12s ease, border-color .12s ease, color .12s ease, box-shadow .12s ease;
}

/* Un enlace con aspecto de boton no se subraya al pasar por encima: la regla `a:hover` de la base
   se lo ponia, y un boton subrayado no es un boton. */
.btn:hover {
    text-decoration: none;
}

.btn:disabled {
    opacity: .55;
    cursor: not-allowed;
}

.btn--primary {
    color: var(--dm-primary-contrast);
    background: var(--dm-primary);
    box-shadow: var(--dm-shadow-sm);
}

.btn--primary:hover:not(:disabled) {
    background: var(--dm-primary-dark);
}

.btn--primary:active:not(:disabled) {
    box-shadow: none;
}

.btn--secondary {
    color: var(--dm-text);
    background: var(--dm-surface);
    border-color: var(--dm-border-strong);
}

.btn--secondary:hover:not(:disabled) {
    background: var(--dm-surface-alt);
}

/* Cancelar es un boton igual que Guardar, pero sin peso: sin fondo y con el borde. .btn--secondary
   no vale porque lleva fondo de superficie, que sobre una tarjeta blanca no se distingue de un
   boton primario apagado. */
.btn--outline {
    color: var(--dm-text-soft);
    background: transparent;
    border-color: var(--dm-border-strong);
}

.btn--outline:hover:not(:disabled) {
    color: var(--dm-text);
    border-color: var(--dm-text-soft);
}

.btn--ghost {
    color: var(--dm-text-soft);
    background: transparent;
}

.btn--ghost:hover:not(:disabled) {
    color: var(--dm-text);
    background: var(--dm-surface-alt);
}

.btn--danger {
    color: var(--dm-primary-contrast);
    background: var(--dm-danger);
}

.btn--danger:hover:not(:disabled) {
    filter: brightness(.92);
}

.btn--small {
    padding: var(--dm-space-1) var(--dm-space-3);
    font-size: var(--dm-text-sm);
}

.btn--large {
    padding: var(--dm-space-3) var(--dm-space-5);
    font-size: var(--dm-text-lg);
}

/*
   El tamano normal. Es el valor POR DEFECTO de BtnSize, asi que lo lleva casi todo boton que se
   pinte, y no estaba definido: la clase salia al DOM y no aplicaba nada. Aqui no cambia el
   aspecto —el relleno y el tamano de letra ya son los de .btn—, pero existe, y quien quiera
   afinar el tamano medio tiene donde hacerlo sin pisar la clase base.
*/
.btn--medium {
    padding: 6px var(--dm-space-4);
    font-size: var(--dm-text-base);
}

.btn--block {
    display: flex;
    width: 100%;
}

/*
   Boton con la accion en marcha. Es distinto de :disabled, que es una accion prohibida: aqui el
   usuario espera respuesta, y el cursor lo dice.
*/
.btn--busy {
    cursor: progress;
}

/*
   Los dos ganchos del contenido del boton. El icono y el texto van en span propios para que el
   gap de .btn los separe y para que quepa un icono sin texto.
*/
.btn__icon,
.btn__label {
    display: inline-flex;
    align-items: center;
}

.btn__label {
    line-height: 1;
}

.btn__spinner {
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: dm-spin .7s linear infinite;
}

@keyframes dm-spin {
    to { transform: rotate(360deg); }
}

/* Quien tenga activado "reducir movimiento" no ve girar nada. */
@media (prefers-reduced-motion: reduce) {
    .btn__spinner { animation: none; }
    .sidebar { transition: none; }
}

/* =================================================================================================
   Tarjetas
   ================================================================================================= */

.card {
    display: flex;
    flex-direction: column;
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow);
}

.card__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--dm-space-4);
    padding: var(--dm-space-3) var(--dm-space-4);
    border-bottom: 1px solid var(--dm-border);
}

/*
   Contenedor del titulo y el subtitulo dentro de la cabecera. Es de maquetacion y su ausencia
   se veia: sin el, el titulo y las acciones no se separan y el subtitulo cae al lado del
   titulo en vez de debajo.
*/
.card__heading {
    display: flex;
    flex-direction: column;
    gap: var(--dm-space-1);
    min-width: 0; /* deja que un titulo largo se corte en vez de empujar a las acciones */
}

.card__title {
    font-size: var(--dm-text-lg);
}

.card__subtitle {
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

.card__actions {
    display: flex;
    gap: var(--dm-space-2);
}

.card__body {
    flex: 1 1 auto;
    padding: var(--dm-space-4);
}

.card--flush > .card__body {
    padding: 0;
}

.card__footer {
    padding: var(--dm-space-3) var(--dm-space-4);
    background: var(--dm-surface-alt);
    border-top: 1px solid var(--dm-border);
    border-radius: 0 0 var(--dm-radius) var(--dm-radius);
}

/* --- La tarjeta que es un enlace -------------------------------------------------------------
   Con la que se compone una PORTADA: una pantalla cuyo contenido es a donde se puede ir desde
   aqui. Lo que se pulsa es la caja entera —el <a> ES la tarjeta—, y no un enlace metido dentro de
   una: con un enlace dentro, el ochenta por ciento de la tarjeta no responde al clic, que es justo
   donde la gente pulsa.
--------------------------------------------------------------------------------------------- */

.card-link {
    display: flex;
    align-items: flex-start;
    gap: var(--dm-space-3);
    padding: var(--dm-space-4);
    color: var(--dm-text);
    text-decoration: none;
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow-sm);
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}

.card-link:hover {
    color: var(--dm-text);
    text-decoration: none;
    border-color: var(--dm-primary);
    box-shadow: var(--dm-shadow-md);
}

.card-link:focus-visible {
    outline: none;
    border-color: var(--dm-primary);
    box-shadow: var(--dm-ring);
}

/* El icono en el color de marca y sobre su propio fondo suave: es lo que distingue una tarjeta de
   otra de un vistazo, antes de leer un solo titulo. */
.card-link__icon {
    flex: 0 0 auto;
    padding: 7px;
    color: var(--dm-primary);
    background: var(--dm-primary-light);
    border-radius: var(--dm-radius-sm);
    box-sizing: content-box;
}

.card-link__body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.card-link__title {
    font-size: var(--dm-text-base);
    font-weight: 600;
    line-height: 1.3;
}

.card-link__description {
    font-size: var(--dm-text-xs);
    color: var(--dm-text-muted);
    line-height: 1.45;
}

/* La rejilla de una portada. auto-fit y NO auto-fill: auto-fill deja columnas vacias a la derecha y
   las tarjetas se quedan estrechas en mitad de una pantalla ancha; auto-fit las colapsa y el 1fr
   reparte el ancho entre las que hay de verdad. Es la misma linea que dejaba el panel a medio
   ancho. */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--dm-space-3);
    align-items: stretch;
}

/* --- Indicador ------------------------------------------------------------------------------ */

.stat-card {
    display: flex;
    align-items: flex-start;
    gap: var(--dm-space-4);
    padding: var(--dm-space-4);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow);
}

.stat-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    color: var(--dm-primary);
    background: var(--dm-primary-light);
    border-radius: var(--dm-radius);
}

/*
   Todo lo que no es el icono. Es de maquetacion y su ausencia se veia: sin el, el icono y el
   texto no forman dos columnas y las cinco lineas del indicador caen una debajo de otra.
*/
.stat-card__body {
    display: flex;
    flex-direction: column;
    gap: var(--dm-space-1);
    min-width: 0;
}

.stat-card__label {
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

.stat-card__value {
    font-size: var(--dm-text-2xl);
    font-weight: 600;
    line-height: 1.2;
}

.stat-card__unit {
    margin-left: var(--dm-space-1);
    font-size: var(--dm-text-base);
    font-weight: 400;
    color: var(--dm-text-muted);
}

.stat-card__trend {
    font-size: var(--dm-text-sm);
    font-weight: 500;
}

.stat-card__trend--success { color: var(--dm-success); }
.stat-card__trend--danger  { color: var(--dm-danger); }
.stat-card__trend--warning { color: var(--dm-warning); }
.stat-card__trend--info    { color: var(--dm-info); }
.stat-card__trend--neutral { color: var(--dm-text-muted); }

.stat-card__caption {
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

/* =================================================================================================
   Tabla
   ================================================================================================= */

.tbl {
    width: 100%;
    overflow-x: auto; /* una tabla ancha se desplaza dentro de su caja, no empuja la pagina */
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow-sm);
}

/* Una tabla de tres columnas cortas no tiene por que ocupar el ancho de la pantalla: se queda en lo
   que necesite y no mas. La lleva quien la pinta, porque el framework no sabe cuantas columnas hay
   ni de que anchura. */
.tbl--narrow {
    width: auto;
    max-width: 100%;
}

.tbl--narrow .tbl__table {
    width: auto;
    min-width: 380px;
}

.tbl--narrow .tbl__head-cell,
.tbl--narrow .tbl__cell {
    padding-right: var(--dm-space-5);
}

.tbl__declarations {
    display: none; /* las columnas solo se declaran; no se pintan */
}

.tbl__table {
    width: 100%;
    border-collapse: collapse;
}

/* La cabecera de columna es un ROTULO, no un dato: cuerpo pequeno, versalita y letra espaciada. Con
   el mismo tamano que las celdas, una tabla de cinco columnas tiene dos filas que compiten por ser
   la primera. */
.tbl__head-cell {
    padding: var(--dm-space-2) var(--dm-space-3);
    font-size: var(--dm-text-xs);
    font-weight: 600;
    color: var(--dm-text-muted);
    text-align: left;
    text-transform: uppercase;
    letter-spacing: .05em;
    white-space: nowrap;
    background: var(--dm-surface-alt);
    border-bottom: 1px solid var(--dm-border);
}

/*
   La izquierda es el valor POR DEFECTO de ColAlign, y era la unica de las tres que no estaba
   definida: toda celda de toda tabla la lleva. Funcionaba de milagro, porque .tbl__head-cell ya
   alinea a la izquierda; pero una tabla dentro de un contenedor con direction: rtl, o cualquier
   regla del consumidor que cambie el text-align heredado, dejaba las columnas "por defecto"
   alineadas de otra forma que las declaradas a la izquierda a proposito.
*/
.tbl__head-cell--left   { text-align: left; }
.tbl__head-cell--center { text-align: center; }
.tbl__head-cell--right  { text-align: right; }

/* Los dos ganchos de las secciones de la tabla. */
.tbl__head,
.tbl__body {
    display: table-row-group;
}

.tbl__head {
    display: table-header-group;
}

.tbl__row {
    border-bottom: 1px solid var(--dm-border);
    transition: background-color .08s ease;
}

.tbl__row:last-child {
    border-bottom: none;
}

/*
   TODA fila responde al paso del raton, no solo las de una tabla marcada como seleccionable.

   Antes solo lo hacian las de .tbl--selectable, y eso confundia dos cosas distintas: que una fila
   se pueda ELEGIR, y que se sepa cual se esta mirando. Lo segundo hace falta siempre —en una tabla
   de cinco columnas y veinte filas, seguir la linea de un nombre hasta su boton de borrar sin nada
   que la resalte es como leer un horario de trenes—. Lo primero sigue siendo lo que anade el
   cursor de mano.
*/
.tbl__body .tbl__row:not(.tbl__row--state):hover {
    background: var(--dm-surface-alt);
}

.tbl--selectable .tbl__row:not(.tbl__row--state) {
    cursor: pointer;
}

.tbl__row--selected {
    background: var(--dm-primary-light);
}

.tbl__cell {
    padding: var(--dm-space-2) var(--dm-space-3);
    vertical-align: middle;
}

.tbl__cell--left   { text-align: left; }
.tbl__cell--center { text-align: center; }
.tbl__cell--right  { text-align: right; }

.tbl--dense .tbl__cell,
.tbl--dense .tbl__head-cell {
    padding: var(--dm-space-2) var(--dm-space-3);
}

.tbl__state {
    padding: var(--dm-space-6);
    color: var(--dm-text-muted);
    text-align: center;
}

/* --- Acciones de fila ----------------------------------------------------------------------- */

/*
   LAS ACCIONES DE UNA FILA TIENEN QUE VERSE. Aqui estaban en gris suave, sin borde, sin fondo y con
   un dibujo de 14px: en la lista de usuarios eran dos manchitas casi del color del fondo, y al
   preguntarle a alguien como se edita un usuario, la respuesta era que no se puede. La accion
   existia y funcionaba; lo que no existia era la forma de encontrarla.

   Ahora cada una es una caja de 30px con su borde, el mismo color de texto que los datos de la
   fila, y color propio al pasar por encima —azul editar, rojo borrar—. Sigue sin llevar texto: en
   una tabla de cinco columnas «Editar» y «Borrar» escritos pesan mas que los datos. El nombre esta
   en el title y en el aria-label.
*/
.row-actions {
    display: inline-flex;
    gap: 3px;
}

.row-action {
    display: inline-flex;
    align-items: center;
    gap: var(--dm-space-1);
    padding: var(--dm-space-1) var(--dm-space-2);
    color: var(--dm-text-soft);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
    transition: color .1s ease, background-color .1s ease, border-color .1s ease;
}

.row-action:hover:not(:disabled) {
    color: var(--dm-primary);
    background: var(--dm-primary-light);
    border-color: color-mix(in srgb, var(--dm-primary) 30%, transparent);
    text-decoration: none;
}

.row-action--danger:hover:not(:disabled) {
    color: var(--dm-danger);
    background: var(--dm-danger-light);
    border-color: color-mix(in srgb, var(--dm-danger) 30%, transparent);
}

.row-action:disabled {
    opacity: .45;
    cursor: not-allowed;
}

.row-action__icon,
.row-action__label {
    display: inline-flex;
    align-items: center;
}

.row-action__label {
    font-size: var(--dm-text-sm);
}

/* --- Acciones de fila con icono ---------------------------------------------------------------
   Editar y borrar son un lapiz y una papelera, no dos palabras: en una tabla de cinco columnas el
   texto de las acciones pesa mas que los datos. El nombre sigue estando en el title y en el
   aria-label, que es lo que lee quien no ve el icono.

   Dibujados con CSS, sin fuente de iconos: mismo criterio que el resto del proyecto.
--------------------------------------------------------------------------------------------- */

.row-action--icon {
    width: 30px;
    height: 30px;
    padding: 0;
    color: var(--dm-text-soft);
    border-color: var(--dm-border);
    justify-content: center;
}

/* Los dibujos de .icon-edit y .icon-delete se han ido a dameti-icons.css, donde ahora vive el
   juego entero: un icono es una mascara SVG, no diez lineas de ::before y ::after. Aqui se queda
   solo la caja del boton, que es lo unico de esto que es «accion de fila». */

/* =================================================================================================
   Paginador
   ================================================================================================= */

.pagination {
    display: flex;
    align-items: center;
    gap: var(--dm-space-1);
    padding: var(--dm-space-3) 0;
}

.pagination__step,
.pagination__page {
    min-width: 32px;
    padding: var(--dm-space-1) var(--dm-space-2);
    color: var(--dm-text-soft);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
}

.pagination__step:hover:not(:disabled),
.pagination__page:hover {
    background: var(--dm-surface-alt);
}

.pagination__step:disabled {
    opacity: .45;
    cursor: not-allowed;
}

.pagination__page--current {
    color: var(--dm-primary-contrast);
    background: var(--dm-primary);
    border-color: var(--dm-primary);
}

.pagination__gap {
    padding: 0 var(--dm-space-1);
    color: var(--dm-text-muted);
}

.pagination__summary {
    margin-left: auto;
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

/* =================================================================================================
   Etiqueta
   ================================================================================================= */

.tag {
    display: inline-flex;
    align-items: center;
    gap: var(--dm-space-1);
    padding: 2px var(--dm-space-2);
    font-size: var(--dm-text-sm);
    font-weight: 500;
    white-space: nowrap;
    border: 1px solid transparent;
    border-radius: 999px;
}

.tag__icon {
    display: inline-flex;
    align-items: center;
    font-size: .9em; /* el icono acompana al texto, no compite con el */
}

.tag--neutral { color: var(--dm-neutral);  background: var(--dm-neutral-light); }
.tag--info    { color: var(--dm-info);     background: var(--dm-info-light); }
.tag--success { color: var(--dm-success);  background: var(--dm-success-light); }
.tag--warning { color: var(--dm-warning);  background: var(--dm-warning-light); }
.tag--danger  { color: var(--dm-danger);   background: var(--dm-danger-light); }

.tag--outline {
    background: transparent;
    border-color: currentColor;
}

/* =================================================================================================
   Aviso
   ================================================================================================= */

.banner {
    display: flex;
    align-items: flex-start;
    gap: var(--dm-space-3);
    padding: var(--dm-space-2) var(--dm-space-3);
    margin-bottom: var(--dm-space-3);
    border: 1px solid transparent;
    border-radius: var(--dm-radius);
}

.banner--info    { color: var(--dm-info);    background: var(--dm-info-light);    border-color: var(--dm-info); }
.banner--success { color: var(--dm-success); background: var(--dm-success-light); border-color: var(--dm-success); }
.banner--warning { color: var(--dm-warning); background: var(--dm-warning-light); border-color: var(--dm-warning); }
.banner--danger  { color: var(--dm-danger);  background: var(--dm-danger-light);  border-color: var(--dm-danger); }

/* El icono no encoge: es el cuerpo del aviso el que se lleva el ancho que sobra. */
.banner__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
}

.banner__body {
    flex: 1 1 auto;
}

.banner__title {
    font-weight: 600;
    line-height: 1.35;
}

.banner__text {
    color: var(--dm-text);
    line-height: 1.35;
}

.banner__close {
    padding: 0 var(--dm-space-1);
    font-size: 1.25rem;
    line-height: 1;
    color: inherit;
    background: transparent;
    border: none;
    cursor: pointer;
}

/* =================================================================================================
   Campo de formulario
   ================================================================================================= */

.form-field {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    margin-bottom: var(--dm-space-3);
}

.form-field--inline {
    flex-direction: row;
    align-items: center;
    gap: var(--dm-space-3);
}

.form-field__label {
    font-size: var(--dm-text-xs);
    font-weight: 600;
    color: var(--dm-text-soft);
    letter-spacing: .01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.form-field__required {
    margin-left: 2px;
    color: var(--dm-danger);
}

/*
   El campo entero, marcado como obligatorio. El asterisco de arriba ya se veia; esta clase la
   emite el componente y no la definia nadie, asi que una aplicacion que quisiera destacar los
   obligatorios de otra forma —un borde, un fondo— no tenia gancho al que agarrarse. La regla es
   deliberadamente minima: quien mande es la hoja del consumidor.
*/
.form-field--required > .form-field__label {
    font-weight: 600;
}

/*
   align-items: flex-start NO ES DECORACION, y aqui esta el fallo que arregla.

   Este contenedor es un flex en columna, y un flex en columna estira a sus hijos a lo ancho salvo
   que se le diga lo contrario. Con los campos de texto eso es justo lo que se quiere. Con una
   CASILLA no: la casilla se estiraba al ancho entero de su columna de la rejilla, y Chrome dibuja
   el cuadradito CENTRADO dentro de la caja que le den. Resultado: la etiqueta «Activo» a la
   izquierda y su casilla flotando en mitad de la nada, a un palmo de distancia, sin nada entre
   las dos. Se veia en la ficha de usuario y en toda pantalla con una casilla.

   El width:auto de la regla de mas abajo no lo evitaba: «auto» es precisamente la condicion que
   hace que el estiramiento se aplique.
*/
.form-field__control {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    min-width: 0;
}

.form-field__control input,
.form-field__control select,
.form-field__control textarea {
    width: 100%;
    min-width: 0;
    padding: 5px var(--dm-space-2);
    font: inherit;
    font-size: var(--dm-text-base);
    line-height: 1.35;
    color: var(--dm-text);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border-strong);
    border-radius: var(--dm-radius-sm);
    transition: border-color .1s ease, box-shadow .1s ease;
}

.form-field__control input::placeholder,
.form-field__control textarea::placeholder {
    color: var(--dm-text-muted);
}

/* Una casilla mide lo que mide una casilla, y se queda pegada al borde izquierdo del campo, debajo
   de su etiqueta. Ver el comentario de .form-field__control. */
.form-field__control input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin: 3px 0;
    accent-color: var(--dm-primary);
    cursor: pointer;
}

/* --- Una casilla con su texto al lado ----------------------------------------------------------
   Una casilla suelta debajo de una etiqueta no dice nada: «Activo» encima de un cuadrado vacio deja
   sin saber si marcado significa activo o lo contrario. Aqui la frase va A LA DERECHA de la casilla
   y dentro del mismo <label>, asi que pulsar el texto marca —que es lo que todo el mundo intenta—.

   El texto NO se estira: la caja del label mide lo que mide la frase, y no toda la columna, para
   que el area que responde al clic termine donde termina lo que se ve.
--------------------------------------------------------------------------------------------- */

.check-field {
    display: inline-flex;
    align-items: center;
    gap: var(--dm-space-2);
    padding: 3px 0;
    cursor: pointer;
    user-select: none;
}

.check-field__text {
    font-size: var(--dm-text-base);
    color: var(--dm-text);
    line-height: 1.3;
}

/* --- Elegir un color --------------------------------------------------------------------------
   Un color se elige con el selector del navegador, no escribiendo «#0f172a» a mano. El valor se
   pinta al lado porque es lo que se copia y se pega cuando el color viene dado por una marca.

   El cuadro tampoco se estira, por lo mismo: un selector de color de 400 pixeles de ancho no dice
   nada mas que uno de 40.
--------------------------------------------------------------------------------------------- */

.color-field {
    display: inline-flex;
    align-items: center;
    gap: var(--dm-space-2);
}

.form-field__control .color-field input[type="color"] {
    width: 40px;
    height: 26px;
    padding: 2px;
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius-sm);
    background: var(--dm-surface);
    cursor: pointer;
}

.color-field__value {
    font-size: var(--dm-text-sm);
    color: var(--dm-text-soft);
}

.form-field__control input:focus,
.form-field__control select:focus,
.form-field__control textarea:focus {
    border-color: var(--dm-primary);
    outline: none;
    box-shadow: var(--dm-ring);
}

/* La casilla se enfoca con el anillo del tema, no con el que trae el navegador: dentro de una
   rejilla apretada, el anillo de 3px del sistema se sale de la celda. */
.form-field__control input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--dm-primary);
    outline-offset: 1px;
    box-shadow: none;
}

.form-field--invalid .form-field__control input,
.form-field--invalid .form-field__control select,
.form-field--invalid .form-field__control textarea {
    border-color: var(--dm-danger);
}

.form-field__hint {
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

.form-field__error {
    font-size: var(--dm-text-sm);
    color: var(--dm-danger);
}

/* -------------------------------------------------------------------------------------------------
   Las clases que pone BLAZOR, no nosotros.

   Un <InputText> marca su campo con `modified`, `valid` o `invalid` segun el estado de
   validacion, y aqui no habia estilo para ninguna: el unico rastro de un formulario rechazado
   era un atributo class que no pintaba nada, asi que el usuario pulsaba «Guardar», la pagina se
   repintaba igual, y no habia forma de saber que campo estaba mal. El resumen de arriba
   (ValidationBanner) dice QUE falla; esto dice DONDE.

   Va sobre el elemento y no sobre .form-field porque la clase la pone Blazor en el propio
   control, y estas pantallas usan los <Input*> de Blazor, no los del framework -que tienen su
   propio .input__control--invalid, en dameti-inputs.css-.
   ------------------------------------------------------------------------------------------------- */

.form-field__control input.invalid,
.form-field__control select.invalid,
.form-field__control textarea.invalid,
input.invalid,
select.invalid,
textarea.invalid {
    border-color: var(--dm-danger);
    background-color: var(--dm-danger-light, transparent);
}

.form-field__control input.invalid:focus,
.form-field__control select.invalid:focus,
.form-field__control textarea.invalid:focus,
input.invalid:focus,
select.invalid:focus,
textarea.invalid:focus {
    outline: none;
    border-color: var(--dm-danger);
    box-shadow: 0 0 0 3px var(--dm-danger-light, rgba(220, 38, 38, .18));
}

/* La lista de errores del ValidationBanner. */
.banner__list {
    margin: 0;
    padding-left: var(--dm-space-5);
}

.banner__list li + li {
    margin-top: var(--dm-space-1);
}

/* =================================================================================================
   Bloque de configuracion (ConfigSection)
   ================================================================================================= */

/* El tope de ancho no es un capricho de maquetacion: un formulario que se estira hasta el borde de
   un monitor de 27 pulgadas obliga a recorrer medio metro de pantalla entre la etiqueta de un campo
   y la del siguiente. Una lista SI quiere todo el ancho —son datos en columnas—; una ficha, no. */
.config-section {
    display: flex;
    flex-direction: column;
    gap: var(--dm-space-3);
    max-width: 1180px;
    padding: var(--dm-space-4);
    margin-bottom: var(--dm-space-3);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow-sm);
}

.config-section__head {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.config-section__title {
    margin: 0;
    font-size: var(--dm-text-base);
    font-weight: 600;
    color: var(--dm-text);
}

.config-section__description {
    margin: 0;
    font-size: var(--dm-text-xs);
    color: var(--dm-text-muted);
}

/* --- Cuantos campos quepan por linea, y NINGUNO estirado ---------------------------------------
   UN CAMPO MIDE LO QUE MIDE SU DATO. Aqui habia `repeat(auto-fit, minmax(230px, 1fr))`, y ese
   `1fr` es el problema: auto-fit hace que las columnas vacias colapsen y el `1fr` reparte TODO el
   ancho sobrante entre las que quedan. En una pantalla de 1400px con cuatro campos, cada uno se
   comia 340px. Un codigo postal de cinco cifras en una caja de 340px, y una ficha de doce campos
   ocupando dos pantallas de alto: eso es lo que se veia en Organizacion y en Variables de
   configuracion.

   `auto-fill` con un maximo FIJO lo corta de raiz: las columnas miden entre 180 y 250px, se
   colocan tantas como quepan, y lo que sobra se queda a la derecha en vez de repartirse. En 1400px
   salen cinco campos por linea; en 900, tres; en el movil, uno. Y ninguno mas ancho de lo que su
   contenido necesita.

   `align-items: end` alinea los controles por su LINEA DE BASE de abajo y no por arriba: en una
   fila donde un campo lleva etiqueta de dos lineas y su vecino de una, sin esto las dos cajas
   quedan a distinta altura.

   Lo que no cabe en una columna -un area de texto, un bloque de texto, una tabla- se marca --wide
   o cae de hijo directo, y ocupa toda la fila.
--------------------------------------------------------------------------------------------- */

.config-section__body {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(155px, 215px));
    justify-content: start;
    align-items: end;
    gap: var(--dm-space-3) var(--dm-space-4);
}

.config-section__body > .form-field {
    margin-bottom: 0;
}

/* Un campo que necesita el doble: una direccion, una descripcion corta, un nombre largo. */
.form-field--wide {
    grid-column: span 2;
}

.config-section__body > pre,
.config-section__body > p,
.config-section__body > .tbl,
.config-section__body > .form-field--full {
    grid-column: 1 / -1;
}

/* Un boton suelto dentro del cuerpo de la seccion se estiraba al ancho de su celda de la rejilla y
   quedaba como una caja vacia de doscientos pixeles. Un boton mide lo que mide su texto. */
/* Varios botones seguidos van en UNA fila y no en una columna de la rejilla cada uno: sueltos, se
   reparten a lo ancho de la seccion y dejan de leerse como un grupo. */
.btn-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--dm-space-2);
}

.config-section__body > .btn-row {
    grid-column: 1 / -1;
}

.config-section__body > .btn,
.config-section__body > .tbl--narrow {
    justify-self: start;
}

/* Un <pre> NO ROMPE LINEA de fabrica, y aqui dentro eso no es un scroll feo: es una pagina mas ancha
   que la ventana. La celda de una rejilla se ensancha hasta caber su contenido, asi que una sola
   linea larga —el bloque «copia esto a mano» de la instalacion lleva una cadena de conexion— empuja
   la columna, empuja el area de contenido y saca el armazon entero fuera de la pantalla.

   Se envuelve por donde haga falta: es un valor para copiar y pegar, y partirlo por la mitad no lo
   estropea. El overflow queda de respaldo para lo que no se pueda partir. */
.config-section__body > pre {
    min-width: 0;
    max-width: 100%;
    margin: 0;
    overflow-x: auto;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.config-section__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--dm-space-2);
    padding-top: var(--dm-space-3);
    border-top: 1px solid var(--dm-border);
}


/* #################################################################################################
   LAS CUATRO PIEZAS DEL USUARIO — notificaciones, correo, tareas y mensajes

   Venian del bloque 7 de MonoTenant/Mockups/style.css, que es donde vive lo que el mockup propone y
   el framework todavia no tiene. Ya lo tiene, asi que aquel bloque desaparece.

   No dependen de lo que la aplicacion haga sino de quien ha entrado, y por eso su icono esta en la
   cabecera y no en el menu. Aqui va todo lo suyo: los cuatro desplegables, el modal, el compositor,
   el detalle de fila y los iconos.

   Todo funciona sin circuito salvo el modal, que necesita showModal(): eso es wwwroot/js/ui.js,
   doce lineas propias y ninguna biblioteca.
   ################################################################################################# */

/* --- Las cuatro piezas de la cabecera ----------------------------------------------------------
   Mismo patron que .app-header__account: un <details> con position relative y el panel colgando
   en absolute. Sin circuito.
--------------------------------------------------------------------------------------------- */

.app-header__tool {
    position: relative;
}

.app-header__tool-summary {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    color: var(--dm-text-soft);
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
    list-style: none;
    user-select: none;
}

.app-header__tool-summary::-webkit-details-marker {
    display: none;
}

.app-header__tool-summary:hover {
    color: var(--dm-primary);
    background: var(--dm-surface-alt);
}

/* El contador ya existe en dameti-components.css y se posiciona contra el ancestro relativo, que
   ahora es .app-header__tool. Solo se le quita el fondo cuando no hay nada que contar. */
.app-header__badge--empty {
    display: none;
}

.app-header__tool-icon {
    display: inline-flex;
}

.app-header__tools {
    gap: var(--dm-space-2);
}

/* El avatar se separa del grupo de iconos: son dos cosas distintas. */
.app-header__account {
    margin-left: var(--dm-space-2);
}


/* --- El desplegable de cada pieza --------------------------------------------------------------
   Los ultimos cinco y un enlace a la pantalla. No es la pantalla: es el vistazo.
--------------------------------------------------------------------------------------------- */

.tool-menu {
    position: absolute;
    top: calc(100% + var(--dm-space-2));
    right: 0;
    z-index: 10;
    width: 320px;
    padding: var(--dm-space-2) 0;
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow-lg);
}

.tool-menu__title {
    padding: var(--dm-space-1) var(--dm-space-4);
    font-size: var(--dm-text-sm);
    font-weight: 600;
    color: var(--dm-text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.tool-menu__list {
    margin: var(--dm-space-1) 0;
    list-style: none;
}

.tool-menu__item {
    display: block;
    padding: var(--dm-space-2) var(--dm-space-4);
    color: var(--dm-text);
    text-decoration: none;
}

.tool-menu__item:hover {
    background: var(--dm-surface-alt);
    text-decoration: none;
}

.tool-menu__item-title {
    display: block;
    font-size: var(--dm-text-sm);
    font-weight: 600;
}

.tool-menu__item-text {
    display: block;
    overflow: hidden;
    font-size: var(--dm-text-sm);
    color: var(--dm-text-soft);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tool-menu__item-moment {
    display: block;
    font-size: var(--dm-text-xs);
    color: var(--dm-text-muted);
}

.tool-menu__separator {
    height: 1px;
    margin: var(--dm-space-1) 0;
    background: var(--dm-border);
}

.tool-menu__all {
    display: block;
    padding: var(--dm-space-2) var(--dm-space-4);
    font-size: var(--dm-text-sm);
    color: var(--dm-primary);
    text-align: center;
}


/* Los cuatro iconos de la cabecera -campana, sobre, tareas, mensajes- y los dos de marcar y
   abrir estaban dibujados aqui con ::before y ::after. Se han ido a dameti-icons.css con el
   resto del juego. */

/* En SSR lo que ACTUA es un <button> dentro de un formulario, y un formulario es un bloque: sin
   esto cada accion de fila cae en una linea distinta. */
.row-form {
    display: inline;
}


/* --- Las bandejas -------------------------------------------------------------------------------
   Lo que no se ha leido pesa mas que lo leido, y se ve sin tener que buscar la etiqueta.
--------------------------------------------------------------------------------------------- */

.is-unread {
    font-weight: 600;
}

.inbox-preview {
    display: block;
    max-width: 42ch;
    overflow: hidden;
    font-size: var(--dm-text-sm);
    color: var(--dm-text-soft);
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* --- El modal ------------------------------------------------------------------------------------
   <dialog> nativo, y de ahi salen gratis el top layer -se pinta por encima de TODO, sin z-index y
   sin sacarlo del sitio en el marcado-, el cierre con Escape, el foco atrapado dentro y el
   aria-modal. Lo abre modal.js llamando a showModal(); no hay mas JavaScript en la aplicacion.

   Que lo hace un modal y no un aviso con borde:

   - Ocupa la ventana entera y centra su panel. El <dialog> es el LIENZO; el cuadro que se ve es
     .modal__panel, su hijo. Por eso un clic cuyo destino sea el <dialog> es un clic fuera del
     cuadro, y cierra.
   - Fondo oscurecido y desenfocado. El desenfoque es lo que separa las dos capas: sin el, el modal
     parece pegado sobre la pagina; con el, la pagina se va detras.
   - Entra y sale con animacion, y la salida tambien: con @starting-style y allow-discrete no hace
     falta ni una linea de script. Donde no se soporten, aparece y desaparece de golpe, que es
     exactamente lo de antes.
   - Cabecera con el icono del tipo en su color, un antetitulo con el tipo y el momento, y el titulo
     grande. El cuerpo tiene su propio scroll y el pie sus acciones: cabeza, cuerpo y pie no se
     empujan entre si por mucho texto que llegue.
   - La pagina de debajo no scrollea mientras hay un modal abierto.
--------------------------------------------------------------------------------------------- */

.modal {
    position: fixed;
    inset: 0;
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    padding: var(--dm-space-4);
    color: var(--dm-text);
    background: transparent;
    border: none;
    overflow: hidden;
}

/* Un <dialog> cerrado no se pinta, y el UA ya lo sabe: la rejilla solo se enciende al abrirse. */
.modal[open] {
    display: grid;
    place-items: center;
}

.modal::backdrop {
    background: rgba(15, 18, 24, .55);
    backdrop-filter: blur(3px);
}

/* La pagina de debajo se queda quieta. Sin esto la rueda del raton scrollea el fondo y el modal se
   queda flotando sobre un contenido que se mueve. */
body:has(.modal[open]) {
    overflow: hidden;
}


/* --- El panel ------------------------------------------------------------------------------- */

.modal__panel {
    display: flex;
    flex-direction: column;
    width: min(640px, 100%);
    max-height: min(80dvh, 720px);
    background: var(--dm-surface);
    border-radius: var(--dm-radius-lg);
    box-shadow: 0 24px 48px -12px rgba(15, 18, 24, .35), 0 0 0 1px rgba(15, 18, 24, .06);
    overflow: hidden;
}


/* --- La cabecera ---------------------------------------------------------------------------- */

.modal__head {
    display: flex;
    align-items: flex-start;
    gap: var(--dm-space-3);
    padding: var(--dm-space-5) var(--dm-space-5) var(--dm-space-4);
}

/* El icono del tipo, en su color. Es lo primero que se ve y dice de que va esto antes de leer. */
.modal__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 50%;
}

.modal__icon--task    { color: var(--dm-info);    background: var(--dm-info-light); }
.modal__icon--alert   { color: var(--dm-danger);  background: var(--dm-danger-light); }
.modal__icon--message { color: var(--dm-neutral); background: var(--dm-neutral-light); }

.modal__heading {
    flex: 1;
    min-width: 0;
}

.modal__eyebrow {
    margin-bottom: 2px;
    font-size: var(--dm-text-xs);
    font-weight: 600;
    color: var(--dm-text-muted);
    text-transform: uppercase;
    letter-spacing: .06em;
}

.modal__title {
    font-size: var(--dm-text-2xl);
    font-weight: 600;
    line-height: 1.25;
}

.modal__close {
    position: relative;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    color: var(--dm-text-muted);
    background: transparent;
    border: none;
    border-radius: 50%;
    cursor: pointer;
}

.modal__close:hover {
    color: var(--dm-danger);
    background: var(--dm-danger-light);
}

/* La aspa, dibujada: el caracter × de la fuente ni queda centrado ni tiene el grosor del resto de
   los iconos. */
.modal__close-icon::before,
.modal__close-icon::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 2px;
    background: currentColor;
    border-radius: 1px;
}

.modal__close-icon::before { transform: translate(-50%, -50%) rotate(45deg); }
.modal__close-icon::after  { transform: translate(-50%, -50%) rotate(-45deg); }


/* --- El cuerpo ------------------------------------------------------------------------------ */

.modal__body {
    flex: 1;
    padding: 0 var(--dm-space-5) var(--dm-space-5);
    overflow-y: auto;
}

.modal__text {
    color: var(--dm-text-soft);
    line-height: 1.55;
}

.modal__text p + p {
    margin-top: var(--dm-space-3);
}

/* Los datos que acompanan: de quien viene, cuando llego, en que estado esta. */
.modal__facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--dm-space-1) var(--dm-space-4);
    padding-top: var(--dm-space-4);
    margin-top: var(--dm-space-4);
    border-top: 1px solid var(--dm-border);
    font-size: var(--dm-text-sm);
}

.modal__facts dt {
    color: var(--dm-text-muted);
}


/* --- El pie --------------------------------------------------------------------------------- */

.modal__foot {
    display: flex;
    align-items: center;
    gap: var(--dm-space-2);
    padding: var(--dm-space-4) var(--dm-space-5);
    background: var(--dm-surface-alt);
    border-top: 1px solid var(--dm-border);
}

/* Lo que informa a la izquierda, lo que se pulsa a la derecha. */
.modal__foot-spacer {
    flex: 1;
}

/* Un formulario es un bloque, y el pie es una fila: sin esto el <form> parte el pie en dos y el
   separador flexible deja de funcionar. El control que se envia tiene que estar DENTRO del <form>
   -si se queda fuera, el boton guarda el valor que ya estaba-, asi que el pie ES el formulario. */
.modal__form {
    display: flex;
    align-items: center;
    gap: var(--dm-space-3);
    flex: 1;
}


/* --- Entrar y salir --------------------------------------------------------------------------
   Sin una linea de script: @starting-style da el estado del que se entra, y allow-discrete deja
   que display y overlay participen en la transicion, que es lo que permite animar TAMBIEN la
   salida. Donde no se soporte, el modal aparece y desaparece de golpe.
--------------------------------------------------------------------------------------------- */

.modal,
.modal::backdrop {
    transition: opacity .18s ease, display .18s allow-discrete, overlay .18s allow-discrete;
    opacity: 0;
}

.modal[open],
.modal[open]::backdrop {
    opacity: 1;
}

@starting-style {
    .modal[open],
    .modal[open]::backdrop {
        opacity: 0;
    }
}

.modal__panel {
    transition: transform .2s cubic-bezier(.2, .8, .3, 1);
    transform: translateY(8px) scale(.97);
}

.modal[open] .modal__panel {
    transform: none;
}

@starting-style {
    .modal[open] .modal__panel {
        transform: translateY(8px) scale(.97);
    }
}

/* Quien tenga puesto que no quiere movimiento, no lo tiene. */
@media (prefers-reduced-motion: reduce) {
    .modal,
    .modal::backdrop,
    .modal__panel {
        transition: none;
        transform: none;
    }
}


/* El tirador que abre el modal es un <button> -abre algo, no navega- pero se lee como el titulo de
   la fila, no como un boton. */
.link-button {
    padding: 0;
    font: inherit;
    color: var(--dm-text);
    text-align: left;
    background: transparent;
    border: none;
    cursor: pointer;
}

.link-button:hover {
    color: var(--dm-primary);
    text-decoration: underline;
}


/* --- La barra de filtro -------------------------------------------------------------------------
   Un interruptor y un boton. NO se aplica al marcar la casilla -eso seria filtro en vivo, y en SSR
   estatico no hay-: se aplica al enviar.
--------------------------------------------------------------------------------------------- */

.filter-bar {
    display: flex;
    align-items: center;
    gap: var(--dm-space-3);
    padding: var(--dm-space-2) var(--dm-space-3);
    margin-bottom: var(--dm-space-4);
    background: var(--dm-surface-alt);
    border-radius: var(--dm-radius);
}

.filter-bar__field {
    display: flex;
    align-items: center;
    gap: var(--dm-space-2);
    font-size: var(--dm-text-sm);
    cursor: pointer;
}

.filter-bar__field input {
    width: auto;
}


/* --- Leer sin cambiar de pantalla ---------------------------------------------------------------
   El asunto es el tirador y el cuerpo se despliega debajo, en la propia fila. Asi la bandeja no
   necesita una segunda pantalla de detalle -ni un modal, que en SSR estatico no hay-.
--------------------------------------------------------------------------------------------- */

.row-detail {
    display: block;
}

.row-detail__summary {
    cursor: pointer;
    list-style: none;
}

.row-detail__summary::-webkit-details-marker {
    display: none;
}

.row-detail__body {
    max-width: 60ch;
    padding-top: var(--dm-space-2);
    font-size: var(--dm-text-sm);
    color: var(--dm-text-soft);
    white-space: pre-line;
}


/* --- Redactar, sin salir de la pantalla ---------------------------------------------------------
   El alta de un mensaje, un correo o una tarea vive DENTRO de su bandeja, en un <details> que se
   abre encima de la lista. Una pantalla por pieza, como se pidio, y sin circuito.
--------------------------------------------------------------------------------------------- */

.compose {
    margin-bottom: var(--dm-space-4);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
}

.compose__summary {
    display: flex;
    align-items: center;
    gap: var(--dm-space-2);
    padding: var(--dm-space-3) var(--dm-space-4);
    font-weight: 600;
    cursor: pointer;
    list-style: none;
    user-select: none;
}

.compose__summary::-webkit-details-marker {
    display: none;
}

.compose__arrow {
    margin-left: auto;
    font-size: var(--dm-text-xs);
    color: var(--dm-text-muted);
}

.compose[open] .compose__arrow {
    transform: rotate(180deg);
}

.compose__body {
    padding: var(--dm-space-4);
    border-top: 1px solid var(--dm-border);
}

/* Los campos se reparten igual que en una seccion de configuracion: la misma rejilla, para que un
   formulario no se vea de dos maneras distintas segun donde este. */
.compose__body form {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: var(--dm-space-2) var(--dm-space-4);
    align-items: start;
}

.compose__body .form-field {
    margin-bottom: 0;
}

.compose__actions {
    grid-column: 1 / -1;
}

.compose__actions {
    display: flex;
    gap: var(--dm-space-2);
    justify-content: flex-end;
    margin-top: var(--dm-space-3);
}

/* Los iconos de las entradas de menu -panel, configuracion, usuarios, roles, organizacion,
   perfil y variables- estaban dibujados aqui uno a uno. Viven en dameti-icons.css. */


/* =================================================================================================
   Listas: el recuento, el filtro y las celdas que dicen algo mas
   =================================================================================================

   Anadido el 2026-08-24 con el catalogo de clientes, que es la primera lista del proyecto con
   filtro. Todo lo de aqui es generico -recuento, acciones del filtro, notas de celda-, asi que vive
   en la hoja del framework y no en la de una aplicacion: la siguiente lista lo hereda.
   ============================================================================================== */

/* El recuento va SIEMPRE, tenga filtro o no. Una lista sin numero obliga a contar con el dedo, y
   con filtro puesto ademas no se sabe si lo que falta es que no hay o que no encaja. */
.list-count {
    margin: 0 0 var(--dm-space-3) 0;
    color: var(--dm-text-muted);
    font-size: var(--dm-text-sm);
}

/* Las acciones del filtro se empujan al final de la barra: los campos a la izquierda, lo que se
   pulsa a la derecha, que es donde se busca. */
.filter-bar__actions {
    display: flex;
    align-items: center;
    gap: var(--dm-space-3);
    margin-left: auto;
}

/* Quitar el filtro es un enlace y no un boton, y se pinta como tal: no es una accion de la misma
   importancia que filtrar, es deshacer. */
.filter-bar__clear {
    color: var(--dm-text-muted);
    font-size: var(--dm-text-sm);
    text-decoration: underline;
}

.filter-bar__clear:hover {
    color: var(--dm-text);
}

/* El dato de debajo del principal en una celda: el slug bajo el nombre, la referencia bajo el
   codigo. En su propia linea y mas apagado, para que el de arriba siga leyendose primero. */
.cell-note {
    display: block;
    color: var(--dm-text-muted);
    font-size: var(--dm-text-xs);
}

/* Un hueco vacio no se deja en blanco: en blanco no se distingue «no tiene» de «no ha cargado». */
.cell-empty {
    color: var(--dm-text-muted);
    font-style: italic;
}


/* =================================================================================================
   La lista de definiciones de una ficha
   =================================================================================================

   Pares etiqueta-valor de SOLO LECTURA -lo que no se edita aqui pero hay que ver-: el cliente en el
   que se esta trabajando, su base de datos, quien ha entrado. Un <dl> y no una tabla, porque no es
   una tabla: es un dato y su nombre.
   ============================================================================================== */

.settings-summary {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--dm-space-2) var(--dm-space-4);
    margin: 0;
}

.settings-summary dt {
    color: var(--dm-text-muted);
    font-size: var(--dm-text-sm);
}

.settings-summary dd {
    margin: 0;
    font-weight: 500;
}
