/* =================================================================================================
   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
   ================================================================================================= */

.sidebar {
    display: flex;
    flex-direction: column;
    flex: 0 0 var(--dm-sidebar-width);
    width: var(--dm-sidebar-width);
    background: var(--dm-sidebar-bg);
    color: var(--dm-sidebar-text);
    border-right: 1px solid var(--dm-sidebar-bg);
    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-3);
    border-bottom: 1px solid var(--dm-sidebar-border);
}

.sidebar__title {
    font-weight: 600;
    color: var(--dm-sidebar-text-strong);
    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-bg);
}

.sidebar__toggle-icon::before {
    content: "\2261"; /* tres rayas, sin depender de ninguna fuente de iconos */
    font-size: 1.1rem;
    color: var(--dm-sidebar-text);
}

.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;
}

.sidebar__link {
    display: flex;
    align-items: center;
    gap: var(--dm-space-3);
    padding: var(--dm-space-2) var(--dm-space-4);
    color: var(--dm-sidebar-text);
    text-decoration: none;
    border-left: 3px solid transparent;
}

.sidebar__link:hover {
    color: var(--dm-sidebar-text-strong);
    background: var(--dm-sidebar-hover-bg);
    text-decoration: none;
}

.sidebar__link--active {
    color: var(--dm-sidebar-text-strong);
    background: var(--dm-sidebar-active-bg);
    border-left-color: var(--dm-sidebar-text-strong);
    font-weight: 600;
}

.sidebar__icon {
    flex: 0 0 auto;
    width: 18px;
    text-align: center;
}

.sidebar__text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Las entradas de pie: mismo aspecto que las de arriba, separadas por una linea y pegadas al
   fondo. El margin-top:auto es lo que las empuja abajo, porque .sidebar__nav ya crece. */
.sidebar__bottom {
    margin-top: auto;
    padding: var(--dm-space-2) 0;
    border-top: 1px solid var(--dm-sidebar-border);
}

.sidebar__footer {
    padding: var(--dm-space-3);
    border-top: 1px solid var(--dm-sidebar-border);
}

/* =================================================================================================
   Pestanas
   ================================================================================================= */

.tabs {
    display: flex;
    gap: var(--dm-space-1);
    margin-bottom: var(--dm-space-5);
    border-bottom: 1px solid var(--dm-border);
    overflow-x: auto;
}

.tabs__tab {
    padding: var(--dm-space-3) var(--dm-space-4);
    color: var(--dm-text-soft);
    text-decoration: none;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}

.tabs__tab:hover {
    color: var(--dm-text);
    text-decoration: none;
}

.tabs__tab--active {
    color: var(--dm-primary);
    border-bottom-color: var(--dm-primary);
    font-weight: 600;
}

/* =================================================================================================
   Cabecera
   ================================================================================================= */

.app-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--dm-space-4);
    height: var(--dm-header-height);
    padding: 0 var(--dm-space-5);
    background: var(--dm-surface);
    border-bottom: 1px solid var(--dm-border);
}

/*
   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;
}

/* <span> y no <h1>: ver el porque en AppHeader.razor. Se le dan a mano el peso y el tamano que
   antes traia de serie por ser un encabezado. */
.app-header__heading {
    display: block;
    font-size: var(--dm-text-lg);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-header__tools {
    display: flex;
    align-items: center;
    gap: var(--dm-space-4);
}

.app-header__bell {
    position: relative;
    width: 32px;
    height: 32px;
    background: transparent;
    border: none;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
}

.app-header__bell:hover {
    background: var(--dm-surface-alt);
}

.app-header__bell-icon::before {
    content: "\1F514";
}

.app-header__badge {
    position: absolute;
    top: 0;
    right: 0;
    min-width: 16px;
    padding: 0 4px;
    font-size: .625rem;
    line-height: 16px;
    color: var(--dm-primary-contrast);
    background: var(--dm-danger);
    border-radius: 8px;
}

/* --- Avatar y su desplegable -------------------------------------------------------------
   El contenedor es el ancla del desplegable: position:relative aqui y absolute dentro, para que
   el panel cuelgue del avatar y no de la cabecera entera. */
.app-header__account {
    position: relative;
    display: flex;
    align-items: center;
}

.app-header__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    overflow: hidden;
    color: var(--dm-primary-contrast);
    background: var(--dm-primary);
    border: none;
    border-radius: 999px;
    cursor: pointer;
}

.app-header__avatar:hover {
    background: var(--dm-primary-dark);
}

.app-header__avatar-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.app-header__avatar-initials {
    font-size: var(--dm-text-sm);
    font-weight: 600;
    letter-spacing: .02em;
}

.app-header__menu {
    position: absolute;
    top: calc(100% + var(--dm-space-2));
    right: 0;
    z-index: 30;
    min-width: 240px;
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
    box-shadow: var(--dm-shadow-lg);
    overflow: hidden;
}

.app-header__menu-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--dm-space-3) var(--dm-space-4);
    border-bottom: 1px solid var(--dm-border);
}

.app-header__menu-name { font-weight: 600; }

.app-header__menu-email {
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
    word-break: break-all;
}

.app-header__menu-facts {
    padding: var(--dm-space-2) var(--dm-space-4);
    border-bottom: 1px solid var(--dm-border);
}

.app-header__menu-fact {
    display: flex;
    justify-content: space-between;
    gap: var(--dm-space-3);
    padding: 2px 0;
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

.app-header__menu-fact > span:last-child {
    color: var(--dm-text);
    font-weight: 500;
}

/* El mismo aspecto para el <a> y para el <button> de salir: en el desplegable son la misma
   cosa, aunque por dentro uno navegue y el otro haga POST. */
.app-header__menu-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--dm-space-3);
    width: 100%;
    padding: var(--dm-space-3) var(--dm-space-4);
    color: var(--dm-text);
    text-align: left;
    text-decoration: none;
    background: transparent;
    border: none;
    font: inherit;
    cursor: pointer;
}

.app-header__menu-item:hover {
    background: var(--dm-surface-alt);
    text-decoration: none;
}

.app-header__menu-item--button {
    border-top: 1px solid var(--dm-border);
    color: var(--dm-danger);
}

.app-header__menu-signout { margin: 0; }

.app-header__menu-count {
    min-width: 18px;
    padding: 0 6px;
    font-size: .625rem;
    line-height: 18px;
    text-align: center;
    color: var(--dm-primary-contrast);
    background: var(--dm-danger);
    border-radius: 9px;
}

.app-header__user {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.app-header__user-name {
    font-weight: 600;
}

.app-header__user-role {
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

.app-header__signout {
    margin: 0;
}

.app-header__signout-button {
    padding: var(--dm-space-1) var(--dm-space-3);
    color: var(--dm-text-soft);
    background: transparent;
    border: 1px solid var(--dm-border-strong);
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
}

.app-header__signout-button:hover {
    color: var(--dm-danger);
    border-color: var(--dm-danger);
}

/* =================================================================================================
   Banda de comunicados

   Va DEBAJO de la cabecera y a todo lo ancho, no dentro de ella: ver el porque en AppHeader.razor.
   Los colores son los mismos tres de .banner porque es el mismo vocabulario -- que un aviso de
   plataforma se pinte con otro amarillo distinto al de la aplicacion solo consigue que nadie sepa
   que significa cada amarillo.
   ================================================================================================= */

.app-notices {
    display: flex;
    flex-direction: column;
}

.app-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--dm-space-4);
    padding: var(--dm-space-3) var(--dm-space-5);
    border-bottom: 1px solid var(--dm-border);
}

.app-notice--info    { color: var(--dm-info);    background: var(--dm-info-light);    border-bottom-color: var(--dm-info); }
.app-notice--warning { color: var(--dm-warning); background: var(--dm-warning-light); border-bottom-color: var(--dm-warning); }
.app-notice--danger  { color: var(--dm-danger);  background: var(--dm-danger-light);  border-bottom-color: var(--dm-danger); }

/* min-width: 0 para que un texto largo se ajuste en vez de empujar al boton fuera de la pantalla. */
.app-notice__text {
    flex: 1 1 auto;
    min-width: 0;
}

.app-notice__title {
    font-weight: 600;
    margin-right: var(--dm-space-2);
}

.app-notice__body {
    color: var(--dm-text);
}

.app-notice__when {
    margin-left: var(--dm-space-3);
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

.app-notice__dismiss {
    flex: 0 0 auto;
    margin: 0;
}

.app-notice__button {
    padding: var(--dm-space-1) var(--dm-space-3);
    font-size: var(--dm-text-sm);
    color: inherit;
    background: transparent;
    border: 1px solid currentColor;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
}

.app-notice__button:hover {
    background: var(--dm-surface);
}

/* =================================================================================================
   Conversacion

   La usan las dos aplicaciones -- el ticket de soporte se ve igual desde el cliente y desde la
   consola -, y por eso vive aqui y no en la hoja de ninguna de las dos. Los mensajes de la
   plataforma se separan por el borde de color y por la sangria, no por el lado: alinear a la
   derecha lo de uno y a la izquierda lo del otro se lee bien en un movil y fatal en una pantalla
   ancha, que es donde se trabaja aqui.
   ================================================================================================= */

.thread {
    display: flex;
    flex-direction: column;
    gap: var(--dm-space-3);
    margin-bottom: var(--dm-space-5);
}

.thread__message {
    padding: var(--dm-space-3) var(--dm-space-4);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-left: 3px solid var(--dm-border);
    border-radius: var(--dm-radius-sm);
}

.thread__message--platform {
    margin-left: var(--dm-space-5);
    border-left-color: var(--dm-primary);
}

.thread__meta {
    display: flex;
    justify-content: space-between;
    gap: var(--dm-space-3);
    margin-bottom: var(--dm-space-2);
    font-size: var(--dm-text-sm);
}

.thread__author {
    font-weight: 600;
}

.thread__when {
    color: var(--dm-text-muted);
}

/* pre-line y no pre: conserva los saltos de linea que escribio la persona y sigue ajustando las
   lineas largas al ancho. El cuerpo se pinta como TEXTO, nunca como HTML -- ver SupportTicket. */
.thread__body {
    margin: 0;
    white-space: pre-line;
}

/* =================================================================================================
   Boton
   ================================================================================================= */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--dm-space-2);
    padding: var(--dm-space-2) var(--dm-space-4);
    font-weight: 500;
    white-space: nowrap;
    border: 1px solid transparent;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
    transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}

.btn:disabled {
    opacity: .55;
    cursor: not-allowed;
}

.btn--primary {
    color: var(--dm-primary-contrast);
    background: var(--dm-primary);
}

.btn--primary:hover:not(:disabled) {
    background: var(--dm-primary-dark);
}

/*
   «Sin cambios»: el mismo boton de guardar cuando no hay nada que guardar.

   Azul claro y no gris: gris es «no puedes», y aqui si puedes -- es que no hace falta. La
   diferencia importa en una pantalla de configuracion, donde lo que se pregunta al mirar el boton
   es «¿me he dejado algo sin guardar?».

   La pone y la quita masterconfiguration.js. Sin JavaScript el boton se queda como sale del
   servidor -azul, «Guardar», y guarda-, que es exactamente lo que hacia antes: esto ANADE un
   estado, no sustituye al que ya funcionaba.

   El :disabled de abajo lo escribe el mismo script; se declara aparte de la regla general de
   botones deshabilitados para que este no se vea apagado, que es justo lo que no queremos decir.
*/
.btn--sin-cambios,
.btn--sin-cambios:disabled {
    color: var(--dm-primary-dark);
    background: var(--dm-primary-light);
    border-color: var(--dm-primary-light);
    opacity: 1;
    cursor: default;
}

.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);
}

.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: var(--dm-space-2) 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-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);
}

/* --- 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);
}

.tbl__declarations {
    display: none; /* las columnas solo se declaran; no se pintan */
}

.tbl__table {
    width: 100%;
    border-collapse: collapse;
}

.tbl__head-cell {
    padding: var(--dm-space-3) var(--dm-space-4);
    font-size: var(--dm-text-sm);
    font-weight: 600;
    color: var(--dm-text-soft);
    text-align: left;
    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);
}

.tbl__row:last-child {
    border-bottom: none;
}

.tbl--selectable .tbl__row:not(.tbl__row--state) {
    cursor: pointer;
}

.tbl--selectable .tbl__row:not(.tbl__row--state):hover {
    background: var(--dm-surface-alt);
}

.tbl__row--selected {
    background: var(--dm-primary-light);
}

.tbl__cell {
    padding: var(--dm-space-3) var(--dm-space-4);
    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 ----------------------------------------------------------------------- */

.row-actions {
    display: inline-flex;
    gap: var(--dm-space-1);
}

.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: none;
    border-radius: var(--dm-radius-sm);
    cursor: pointer;
}

.row-action:hover:not(:disabled) {
    color: var(--dm-primary);
    background: var(--dm-surface-alt);
}

.row-action--danger:hover:not(:disabled) {
    color: var(--dm-danger);
    background: var(--dm-danger-light);
}

.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);
}

/* =================================================================================================
   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-3) var(--dm-space-4);
    margin-bottom: var(--dm-space-4);
    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;
}

.banner__text {
    color: var(--dm-text);
}

.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: var(--dm-space-1);
    margin-bottom: var(--dm-space-4);
}

.form-field--inline {
    flex-direction: row;
    align-items: center;
    gap: var(--dm-space-3);
}

.form-field__label {
    font-size: var(--dm-text-sm);
    font-weight: 500;
    color: var(--dm-text-soft);
}

.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;
}

.form-field__control {
    display: flex;
    flex-direction: column;
}

.form-field__control input,
.form-field__control select,
.form-field__control textarea {
    width: 100%;
    padding: var(--dm-space-2) var(--dm-space-3);
    font: inherit;
    color: var(--dm-text);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border-strong);
    border-radius: var(--dm-radius-sm);
}

.form-field__control input:focus,
.form-field__control select:focus,
.form-field__control textarea:focus {
    border-color: var(--dm-primary);
    outline: none;
    box-shadow: 0 0 0 3px var(--dm-primary-light);
}

.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);
}

/* =================================================================================================
   Validacion de EditForm

   Las clases de esta seccion NO las pone el framework: las pone Blazor. `.validation-errors` y
   `.validation-message` salen de <ValidationSummary /> y <ValidationMessage />; `.invalid` /
   `.modified` las pone EditForm en cada <input> segun el estado del campo.

   Sin estas reglas la validacion existia y no se veia por ninguna parte: los once EditForm del
   arbol llevaban <DataAnnotationsValidator />, que INVALIDA el envio, y no habia ni un solo
   ValidationSummary ni un solo estilo para `.invalid`. Medido en el navegador el 2026-08-11:
   pulsar «Guardar» con un campo obligatorio vacio no guardaba, no navegaba y no decia nada --
   exactamente un boton muerto, que es lo que este proyecto lleva tres revisiones persiguiendo.
   ================================================================================================= */

.validation-errors {
    margin: 0 0 var(--dm-space-4);
    padding: var(--dm-space-3) var(--dm-space-4);
    list-style: none;
    background: var(--dm-danger-light);
    border: 1px solid var(--dm-danger);
    border-radius: var(--dm-radius-sm);
}

.validation-errors li,
.validation-message {
    font-size: var(--dm-text-sm);
    color: var(--dm-danger);
}

.validation-message {
    display: block;
    margin-top: var(--dm-space-1);
}

/* El campo que falla, marcado. Es lo que lleva la vista al sitio cuando el resumen dice que algo
   falta pero no donde. */
.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);
}

.form-field__control input.modified.valid,
.form-field__control select.modified.valid,
.form-field__control textarea.modified.valid {
    border-color: var(--dm-success);
}

/* =================================================================================================
   Bloque de configuracion (ConfigSection)
   ================================================================================================= */

.config-section {
    display: flex;
    flex-direction: column;
    gap: var(--dm-space-4);
    padding: var(--dm-space-5);
    margin-bottom: var(--dm-space-5);
    background: var(--dm-surface);
    border: 1px solid var(--dm-border);
    border-radius: var(--dm-radius);
}

.config-section__head {
    display: flex;
    flex-direction: column;
    gap: var(--dm-space-1);
}

.config-section__title {
    margin: 0;
    font-size: var(--dm-text-lg);
    font-weight: 600;
    color: var(--dm-text);
}

.config-section__description {
    margin: 0;
    font-size: var(--dm-text-sm);
    color: var(--dm-text-muted);
}

.config-section__body {
    display: flex;
    flex-direction: column;
    gap: var(--dm-space-3);
}

.config-section__actions {
    display: flex;
    gap: var(--dm-space-3);
    padding-top: var(--dm-space-3);
    border-top: 1px solid var(--dm-border);
}

/* La fila de acciones que va debajo de las pestanas de una pantalla de configuracion: hoy solo
   lleva el boton de «nuevo», pero es donde iran el buscador y los filtros. */
.settings-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--dm-space-3);
    margin-bottom: var(--dm-space-4);
}
