/* ===========================================================================
   app.css — estilos de aplicación
   Igual que el resto de esta capa: ningún color literal, todo derivado
   del tema activo a través de los tokens de alier-tokens.css.
   =========================================================================== */



/* --- Foco programático: el recuadro que aparece "solo" ---------------------
   Blazor mueve el foco al primer <h1> en cada navegación y en cada recarga:
   lo hace <FocusOnNavigate Selector="h1"> en Components/Routes.razor, que
   viene de fábrica en la plantilla de Blazor Web App. AlModal hace lo mismo
   con el contenedor del diálogo al abrirlo.

   En una recarga no hay interacción previa con el ratón, así que el navegador
   trata ese foco como foco de teclado y pinta su anillo por defecto: el título
   de la página aparece rodeado de un recuadro, como si estuviera seleccionado.
   No lo pinta ninguna hoja de este proyecto; es el estilo de agente de usuario.

   El foco se mantiene —es lo que hace que un lector de pantalla anuncie la
   página nueva—; aquí solo se oculta el anillo. Estos elementos llevan
   tabindex="-1", o sea que no están en el orden de tabulación: nadie llega a
   ellos con Tab y no se pierde ninguna indicación de foco. La regla no toca
   ningún control real, solo encabezados y contenedores de diálogo.

   Detalle y variantes en knowledge/wiki/frontend/foco-al-navegar.md. */
:is(h1, h2, h3, [role="dialog"], [role="alertdialog"])[tabindex="-1"]:focus {
    outline: none;
}

/* --- Contenedor de página ------------------------------------------------
   Es el que reparte la altura: cabecera y barras ocupan lo suyo y la tabla
   se queda con el resto. min-block-size:0 es obligatorio. */
.al-page {
    display: flex;
    flex-direction: column;
    gap: var(--al-space-3);
    flex: 1 1 0;
    min-block-size: 0;
    padding: var(--al-space-4) var(--al-space-5);
    overflow-y: auto;
}

@media (max-width: 640px) {
    .al-page {
        padding: var(--al-space-3);
        gap: var(--al-space-2);
    }
}

/* --- Botones -------------------------------------------------------------
   Tres roles y solo tres: primaria (una por pantalla), fantasma (el resto),
   peligro (destructivas). Hoy todos los botones de DeCAs son del mismo azul,
   incluido "Cancelar documento". */
.al-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--al-space-2);
    min-block-size: 2.25rem;
    padding-inline: var(--al-space-4);
    border: 1px solid transparent;
    border-radius: var(--al-radius-control);
    background: transparent;
    color: var(--al-text);
    font-size: var(--al-text-base);
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: background 120ms ease, border-color 120ms ease;
}
.al-btn:focus-visible { box-shadow: var(--al-focus-ring); outline: none; }
.al-btn:disabled { opacity: 0.45; cursor: not-allowed; }

.al-btn--primary {
    background: var(--al-accent-fill);
    color: var(--al-on-accent);
    font-weight: 600;
}
.al-btn--primary:hover:not(:disabled) {
    background: var(--al-accent-fill-hover);
    color: var(--al-on-accent);
}

.al-btn--ghost {
    border-color: var(--al-border);
    background: var(--al-surface);
    color: var(--al-text-muted);
}
.al-btn--ghost:hover:not(:disabled) { background: var(--al-row-hover); color: var(--al-text); }

.al-btn--danger { color: var(--al-danger); border-color: transparent; background: transparent; }
.al-btn--danger:hover:not(:disabled) { background: var(--al-danger-bg); color: var(--al-danger); border-color: transparent; }

.al-iconbtn {
    display: grid;
    place-items: center;
    inline-size: 2.25rem;
    block-size: 2.25rem;
    border: 1px solid transparent;
    border-radius: var(--al-radius-control);
    background: transparent;
    color: var(--al-text-muted);
    cursor: pointer;
}
.al-iconbtn:hover { background: var(--al-row-hover); color: var(--al-text); }
.al-iconbtn:focus-visible { box-shadow: var(--al-focus-ring); outline: none; }

/* --- Buscador ------------------------------------------------------------ */
.al-searchwrap {
    position: relative;
    display: flex;
    align-items: center;
    flex: 0 1 24rem;
    min-inline-size: 12rem;
}
.al-searchwrap__icon {
    position: absolute;
    inset-inline-start: var(--al-space-3);
    inline-size: 1rem;
    block-size: 1rem;
    color: var(--al-text-subtle);
    pointer-events: none;
    z-index: 1;
}
.al-searchwrap__input {
    inline-size: 100%;
    min-block-size: 2.25rem;
    padding-inline: 2.25rem var(--al-space-3);
    border: 1px solid var(--al-border);
    border-radius: var(--al-radius-control);
    background: var(--al-surface);
    color: var(--al-text);
    font-size: var(--al-text-base);
    font-family: inherit;
}
.al-searchwrap__input::placeholder { color: var(--al-text-subtle); }
.al-searchwrap__input:focus-visible { box-shadow: var(--al-focus-ring); outline: none; border-color: var(--al-accent); }

/* --- Filtros por estado --------------------------------------------------
   Sustituyen al filtro por columna escondido tras un embudo. El recuento
   por estado es la información que un jefe de tráfico mira primero. */
.al-chipfilter { display: flex; gap: var(--al-space-1); flex-wrap: wrap; }
.al-chipfilter__btn {
    display: inline-flex;
    align-items: center;
    gap: var(--al-space-2);
    min-block-size: 2.25rem;
    padding-inline: var(--al-space-3);
    border: 1px solid var(--al-border-hairline);
    border-radius: var(--al-radius-pill);
    background: var(--al-surface);
    color: var(--al-text-muted);
    font-size: var(--al-text-sm);
    font-family: inherit;
    cursor: pointer;
}
.al-chipfilter__btn:hover { background: var(--al-row-hover); color: var(--al-text); }
.al-chipfilter__btn.is-active {
    background: var(--al-accent-quiet);
    border-color: var(--al-accent);
    color: var(--al-accent);
    font-weight: 600;
}
.al-chipfilter__btn:focus-visible { box-shadow: var(--al-focus-ring); outline: none; }
.al-chipfilter__n { font-variant-numeric: tabular-nums; opacity: 0.7; font-size: var(--al-text-xs); }

/* --- Celda de dos líneas -------------------------------------------------
   Destinatario + población en una sola columna: ahorra una columna entera
   sin perder el dato. */
.al-cell-2line { display: flex; flex-direction: column; line-height: 1.25; }
.al-cell-2line small { color: var(--al-text-subtle); font-size: var(--al-text-xs); }

/* --- Aviso de prototipo -------------------------------------------------- */
.al-notice {
    display: flex;
    align-items: flex-start;
    gap: var(--al-space-3);
    padding: var(--al-space-3) var(--al-space-4);
    background: var(--al-info-bg);
    border: 1px solid color-mix(in srgb, var(--bs-info) 40%, transparent);
    border-radius: var(--al-radius-control);
    font-size: var(--al-text-base);
    color: var(--al-text);
}
.al-notice b { font-weight: 600; }

/* --- Error de Blazor ----------------------------------------------------- */
#blazor-error-ui {
    display: none;
    position: fixed;
    inset-block-end: 0;
    inset-inline: 0;
    z-index: 1000;
    padding: var(--al-space-3) var(--al-space-5);
    background: var(--al-warn-bg);
    color: var(--al-text);
    box-shadow: var(--al-shadow-2);
}
#blazor-error-ui .dismiss { cursor: pointer; float: inline-end; }

/* --- Scrollbars discretos ------------------------------------------------ */
.tms-ui * { scrollbar-width: thin; scrollbar-color: var(--al-border) transparent; }



/* ===========================================================================
   Añadidos de la revisión funcional
   =========================================================================== */

/* Botón de vista en estado activo (fila de filtros, panel de agrupación). */
.al-iconbtn.is-on {
    background: var(--al-accent-quiet);
    color: var(--al-accent);
}
.al-iconbtn--sm { inline-size: 1.75rem; block-size: 1.75rem; }
.al-iconbtn:disabled { opacity: 0.4; cursor: not-allowed; }

.al-btn--xs { min-block-size: 1.625rem; padding-inline: var(--al-space-2); font-size: var(--al-text-xs); }

/* Destructiva de confirmación: sólida, porque es la acción que se confirma. */
.al-btn--solid-danger {
    background: var(--al-danger-fill);
    color: var(--al-on-danger);
    font-weight: 600;
}
.al-btn--solid-danger:hover:not(:disabled) {
    background: var(--al-danger-fill-hover);
    color: var(--al-on-danger);
}

/* Dato ausente y dato monoespaciado dentro de celdas. */
.al-dash { color: var(--al-text-subtle); }
.al-mono {
    font-family: var(--bs-font-monospace, ui-monospace, "SFMono-Regular", Menlo, monospace);
    font-size: var(--al-text-sm);
    letter-spacing: -0.01em;
}

/* --- Elección entre opciones dentro de un modal (formatos de exportación) - */
.al-choices { display: flex; flex-direction: column; gap: var(--al-space-2); }
.al-choice {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--al-space-3) var(--al-space-4);
    border: 1px solid var(--al-border);
    border-radius: var(--al-radius-control);
    background: var(--al-surface);
    color: var(--al-text);
    text-align: start;
    font-family: inherit;
    cursor: pointer;
}
.al-choice:hover { border-color: var(--al-accent); background: var(--al-accent-quiet); }
.al-choice:focus-visible { box-shadow: var(--al-focus-ring); outline: none; }
.al-choice b { font-size: var(--al-text-md); font-weight: 600; }
.al-choice span { font-size: var(--al-text-sm); color: var(--al-text-muted); }

/* --- Vistas guardadas ----------------------------------------------------- */
.al-ws { display: flex; flex-direction: column; gap: var(--al-space-4); }
.al-ws__intro { margin: 0; font-size: var(--al-text-base); color: var(--al-text-muted); max-inline-size: 60ch; }
.al-ws__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
/* Cada fila son dos zonas: el texto, que cede, y las acciones, que no.
   Antes eran cuatro elementos compitiendo en una sola línea, todos con
   white-space: nowrap y un mínimo de 14rem en el nombre: con el detalle más
   largo la fila medía ~706px dentro de un diálogo de 654px, así que la
   papelera se salía y el cuerpo del modal sacaba barra horizontal. */
.al-ws__row {
    display: flex;
    align-items: center;
    gap: var(--al-space-3);
    padding: var(--al-space-2) var(--al-space-3);
    border: 1px solid transparent;
    border-radius: var(--al-radius-control);
}
.al-ws__row:hover { background: var(--al-row-hover); }
.al-ws__row.is-active { background: var(--al-accent-quiet); border-color: var(--al-accent); }

/* flex: 1 1 auto + min-inline-size: 0 es el par que hace que esto ceda.
   Sin el min-inline-size, un elemento flex no baja de su contenido mínimo
   y desborda al contenedor en vez de encoger: es la causa habitual de este
   tipo de fallo. */
.al-ws__pick {
    display: flex;
    align-items: center;
    gap: var(--al-space-2);
    cursor: pointer;
    flex: 1 1 auto;
    min-inline-size: 0;
}
.al-ws__pick > input { flex: 0 0 auto; }
.al-ws__text { display: flex; flex-direction: column; min-inline-size: 0; }
.al-ws__name { font-weight: 500; }

/* Sin truncados: el detalle va debajo del nombre y ocupa lo que necesite.
   Si algún día uno es larguísimo, se parte en dos líneas; nunca desborda. */
.al-ws__meta { font-size: var(--al-text-xs); color: var(--al-text-subtle); }

/* Las acciones no ceden nunca: son el ancho que sea y el texto cede por ellas. */
.al-ws__actions {
    display: flex;
    align-items: center;
    gap: var(--al-space-3);
    flex: 0 0 auto;
    margin-inline-start: auto;
}
.al-ws__makedefault {
    border: 0; background: transparent; padding: 0;
    color: var(--al-accent); font-size: var(--al-text-xs); font-family: inherit;
    cursor: pointer; text-decoration: underline; white-space: nowrap;
}
.al-ws__confirm { display: flex; align-items: center; gap: var(--al-space-2); font-size: var(--al-text-sm); }
.al-ws__new {
    display: flex;
    align-items: flex-end;
    gap: var(--al-space-3);
    padding-block-start: var(--al-space-4);
    border-block-start: 1px solid var(--al-border-hairline);
}
.al-ws__new .al-field { flex: 1 1 auto; }

/* --- Panel de agrupación de DevExpress ------------------------------------
   El original lo muestra con el texto en inglés y sin ningún estilo, como una
   línea de texto suelta encima de la tabla. Aquí se lee como una zona de
   soltar, que es lo que es. */
.al-grid-host .dxbl-grid-group-panel {
    padding: var(--al-space-2) var(--al-space-3);
    background: var(--al-surface-sunken);
    border-block-end: 1px solid var(--al-border-hairline);
    font-size: var(--al-text-sm);
    color: var(--al-text-subtle);
    min-block-size: 2.5rem;
    display: flex;
    align-items: center;
    gap: var(--al-space-2);
}

/* Fila de filtros: se distingue de las filas de datos. */
.al-grid-host .dxbl-grid-filter-row > td {
    background: var(--al-surface-sunken);
    border-block-end: 1px solid var(--al-border);
    padding: var(--al-space-1) var(--al-space-2);
}

/* Paginador */
.al-grid-host .dxbl-grid-pager {
    padding: var(--al-space-2) var(--al-space-3);
    border-block-start: 1px solid var(--al-border-hairline);
    background: var(--al-surface);
}

/* ---------------------------------------------------------------------------
   Etiqueta de expedición (maqueta).

   En el TMS actual el botón "Etiqueta" pide el documento al transportista y
   devuelve un PDF o un ZPL. Aquí no hay integración, así que se dibuja el
   CONTENIDO de la etiqueta: sirve para que el equipo vea qué datos tiene que
   pedirle a cada API y en qué jerarquía se leen en el muelle.

   Sin colores literales, como el resto de la capa.
   --------------------------------------------------------------------------- */
.al-label {
    display: flex;
    flex-direction: column;
    gap: var(--al-space-4);
    padding: var(--al-space-5);
    border: 2px solid var(--al-border);
    border-radius: var(--al-radius-surface);
    background: var(--al-surface);
    max-inline-size: 26rem;
}

.al-label__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--al-space-3);
    padding-block-end: var(--al-space-3);
    border-block-end: 2px solid var(--al-border);
}

.al-label__carrier { font-size: var(--al-text-xl); font-weight: 700; color: var(--al-text); }
.al-label__svc { font-size: var(--al-text-sm); color: var(--al-text-muted); }

.al-label__eyebrow {
    display: block;
    font-size: var(--al-text-xs);
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--al-text-muted);
}

/* El destinatario es lo que se lee a un metro de distancia en el muelle:
   es lo único grande de la etiqueta. */
.al-label__to b { display: block; font-size: var(--al-text-lg); color: var(--al-text); }
.al-label__to span:not(.al-label__eyebrow) { color: var(--al-text-muted); }

.al-label__meta { display: flex; gap: var(--al-space-5); }
.al-label__meta b { font-size: var(--al-text-md); color: var(--al-text); font-variant-numeric: tabular-nums; }

.al-label__code {
    padding: var(--al-space-3);
    background: var(--al-surface-sunken);
    border-radius: var(--al-radius-control);
    text-align: center;
    letter-spacing: .08em;
}
