/* ============================================================================
   DeCA — Pretium Gestion · App shell (slice 1, cimientos)
   Usa SIEMPRE los tokens de tokens.css. No hardcodear colores/medidas aqui.
   Layout fiel al diseno: sidebar 248/68px + topbar 56px + contenido max 1280px.
   ============================================================================ */

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-sans);
    font-size: var(--fs-body);
    line-height: var(--lh-body);
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

a { color: var(--color-primary-600); }

.visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Recortado igual que .visually-hidden, pero se revela al enfocar por teclado (issue #48 F9
   debt: botones de envio anadidos para el H32.2 de pa11y no pueden quedar invisibles tambien
   al foco, o pasan el chequeo automatico y siguen fallando para un usuario de teclado real). */
.visually-hidden--focusable:focus-visible {
    position: static; width: auto; height: auto; margin: 0;
    padding: var(--sp-1) var(--sp-3); overflow: visible; clip: auto; white-space: nowrap;
    background: var(--color-primary-600); color: var(--color-text-invert);
    border-radius: var(--r-sm); box-shadow: var(--sh-focus);
}

.skip-link {
    position: absolute; left: -999px; top: 0; z-index: var(--z-toast);
    background: var(--color-primary-600); color: var(--color-text-invert);
    padding: var(--sp-2) var(--sp-4); border-radius: 0 0 var(--r-md) 0;
}
.skip-link:focus { left: 0; }

/* ---- Estructura ---- */
.app-shell { display: flex; min-height: 100vh; min-height: 100dvh; }
.app-body { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.app-main {
    flex: 1;
    padding: var(--sp-6);
    max-width: var(--content-max);
    width: 100%;
    margin: 0 auto;
    outline: none;
}

/* ---- Sidebar ---- */
.sidebar {
    width: var(--sidebar-w);
    background: var(--grad-brand);
    color: var(--color-text-invert);
    display: flex;
    flex-direction: column;
    transition: width var(--dur-base) var(--ease);
    overflow: hidden;
}
.sidebar__brand {
    display: flex; align-items: center; gap: var(--sp-3);
    height: var(--topbar-h); padding: 0 var(--sp-4);
    flex-shrink: 0;
}
.brand-tile {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; border-radius: var(--r-md);
    background: var(--color-primary-600); color: var(--color-text-invert);
    flex-shrink: 0;
}
.brand-text { font-weight: 600; font-size: var(--fs-h3); white-space: nowrap; }
/* Logotipo de la plataforma en blanco (issue #8); en expandido sustituye al tile.
   Issue #220: pasa a SVG en trazado. El `aspect-ratio` declara la proporcion real del
   fichero (615x140) para que el hueco este reservado antes de que el SVG pinte: sin
   el, la fila de marca de la sidebar da un salto al cargar. */
.brand-logo { height: 30px; width: auto; display: block; aspect-ratio: 615 / 140; }
.sidebar__brand .brand-tile { display: none; }

.sidebar__nav { padding: var(--sp-3) var(--sp-2); overflow-y: auto; }
.nav-group {
    margin: var(--sp-3) var(--sp-2) var(--sp-1);
    font-size: var(--fs-caption); font-weight: var(--fw-label);
    text-transform: uppercase; letter-spacing: .04em;
    color: rgba(255, 255, 255, .55); white-space: nowrap;
}
.nav-list { list-style: none; margin: 0; padding: 0; }
.nav-item {
    display: flex; align-items: center; gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3); margin-bottom: 3px;
    border-radius: var(--r-lg);
    color: rgba(255, 255, 255, .82); text-decoration: none;
    white-space: nowrap;
    transition: background var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
}
.nav-item:hover { background: rgba(255, 255, 255, .08); color: var(--color-text-invert); }
.nav-item:hover .nav-item__icon { color: var(--color-cyan-500); }
/* Activo: lavado cian semitransparente + borde fino, texto/icono claros.
   Valores tomados del prototipo (panel.dc.html). */
.nav-item.is-active {
    background: rgba(22, 166, 232, .16); color: var(--color-text-invert);
    box-shadow: inset 0 0 0 1px rgba(120, 190, 255, .45);
}
.nav-item.is-active .nav-item__icon { color: var(--color-cyan-500); }
.nav-item__icon { display: inline-flex; flex-shrink: 0; }
/* "Cerrar sesion" (issue #17): <button> dentro de un form POST+CSRF que replica .nav-item. */
.nav-logout { margin: 0; }
.nav-item--button { width: 100%; border: none; background: transparent; font: inherit; text-align: left; cursor: pointer; }

/* Sidebar contraida (68px): solo iconos (reaparece el tile; el logo no cabe) */
.app-shell.is-collapsed .sidebar { width: var(--sidebar-w-collapse); }
.app-shell.is-collapsed .brand-text,
.app-shell.is-collapsed .brand-logo,
.app-shell.is-collapsed .nav-group,
.app-shell.is-collapsed .nav-item__label { display: none; }
.app-shell.is-collapsed .sidebar__brand .brand-tile { display: inline-flex; }
.app-shell.is-collapsed .nav-item { justify-content: center; }
.app-shell.is-collapsed .sidebar__brand { justify-content: center; padding: 0; }

/* ---- Topbar ---- */
.topbar {
    height: var(--topbar-h); flex-shrink: 0;
    display: flex; align-items: center; gap: var(--sp-4);
    padding: 0 var(--sp-5);
    background: var(--color-surface);
    border-bottom: var(--bw-1) solid var(--color-border);
}
.icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border: none; border-radius: var(--r-md);
    background: transparent; color: var(--color-text-muted); cursor: pointer;
}
.icon-btn:hover { background: var(--color-surface-2); color: var(--color-text); }

.topbar__search {
    display: flex; align-items: center; gap: var(--sp-2);
    flex: 1; max-width: 420px;
    padding: 0 var(--sp-3); height: 36px;
    background: var(--color-surface-2);
    border: var(--bw-1) solid var(--color-border);
    border-radius: var(--r-md);
    color: var(--color-text-muted);
}
.topbar__search input {
    border: none; background: transparent; outline: none;
    flex: 1; font: inherit; color: var(--color-text);
}
.topbar__right { display: flex; align-items: center; gap: var(--sp-3); margin-left: auto; }

.lang-switch { display: flex; align-items: center; gap: var(--sp-2); color: var(--color-text-muted); }
.lang-switch select {
    border: var(--bw-1) solid var(--color-border-strong);
    border-radius: var(--r-md); background: var(--color-surface);
    color: var(--color-text); font: inherit; padding: var(--sp-1) var(--sp-2);
}

.account-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; border-radius: var(--r-pill);
    background: var(--color-primary-600); color: var(--color-text-invert);
    font-weight: 600; font-size: var(--fs-label);
    text-decoration: none;
}
/* Icono de cuenta interactivo (issue #17): enlace a /cuenta con estado hover visible. */
a.account-avatar:hover { background: var(--color-primary-700); box-shadow: 0 0 0 3px var(--color-surface-2); }

/* ---- Foco accesible (AA) ---- */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, [tabindex]:focus-visible {
    outline: none; box-shadow: var(--sh-focus);
    border-radius: var(--r-sm);
}
/* El avatar es el unico focable con radio pill: la regla generica lo cuadraria (issue #17);
   repetir el box-shadow tras a.account-avatar:hover mantiene visible el anillo con hover. */
a.account-avatar:focus-visible { border-radius: var(--r-pill); box-shadow: var(--sh-focus); }

/* ---- Contenido ---- */
.page-header { margin-bottom: var(--sp-5); }
.page-title { font-size: var(--fs-h1); line-height: var(--lh-h1); font-weight: var(--fw-h1); margin: 0; }
.page-subtitle { color: var(--color-text-muted); margin: var(--sp-1) 0 0; }

.card {
    background: var(--color-surface);
    border: var(--bw-1) solid var(--color-border);
    border-radius: var(--r-xl);
    box-shadow: var(--sh-md);
    padding: var(--sp-5);
    margin-bottom: var(--sp-4);
}

.mono { font-family: var(--font-mono); font-size: var(--fs-mono); }
.text-muted { color: var(--color-text-muted); }

/* ---- Barra de cuota ---- */
.quota-label { margin: 0 0 var(--sp-2); font-weight: var(--fw-label); }
.quota-bar {
    height: 8px; border-radius: var(--r-pill);
    background: var(--color-surface-3); overflow: hidden;
}
.quota-bar__fill {
    display: block; height: 100%;
    background: var(--color-accent-600);
    transition: width var(--dur-base) var(--ease);
}
.quota-bar__fill.is-warn { background: var(--color-warning); }
.quota-bar__fill.is-full { background: var(--color-danger); }

/* ============================================================================
   Autenticacion (split: panel de marca + tarjeta)
   ============================================================================ */
/* Issue #220 (14/08/2026): una sola columna centrada. Desaparece el panel lateral
   de marca que ocupaba el 40% izquierdo — Jorge pidio quitarlo y centrar el
   formulario en acceso y en registro. Se conservan los nombres de clase
   (`auth-split`, `auth-main`) para no tocar mas ficheros de los necesarios: lo que
   cambia es lo que hacen, no como se llaman. */
.auth-split { display: flex; min-height: 100vh; }

.auth-main {
    position: relative;
    flex: 1; display: flex; flex-direction: column;
    align-items: center; justify-content: center; padding: var(--sp-6); gap: var(--sp-5);
    /* issue #187: sin esto, un flex item conserva `min-width:auto` y NO encoge por debajo del
       ancho de su contenido — la tarjeta de registro (460px + 40px de padding) desbordaba el
       viewport en movil y toda la pagina se desplazaba en horizontal. Medido a 390px: el
       documento ocupaba 478px de ancho. */
    min-width: 0;
}
/* Logotipo de la plataforma centrado sobre la tarjeta. Desde el #220 es un SVG en
   trazado: nitido a cualquier tamano y sin depender de ninguna tipografia. El
   `aspect-ratio` evita el salto de maquetacion mientras carga — un SVG sin alto
   declarado hace que la tarjeta baje de golpe al pintarse. */
.auth-logo { width: min(240px, 65%); height: auto; aspect-ratio: 615 / 140; }
.auth-card {
    width: 100%; max-width: 460px;
    background: var(--color-surface); border: var(--bw-1) solid var(--color-border);
    border-radius: var(--r-lg); box-shadow: var(--sh-md); padding: var(--sp-8);
}
.auth-title { font-size: 26px; line-height: 1.25; font-weight: var(--fw-h1); margin: 0 0 var(--sp-3); }
.auth-sub { color: var(--color-text-muted); margin: 0 0 var(--sp-5); }
.auth-form { display: flex; flex-direction: column; gap: var(--sp-4); }
.auth-card .form-field input, .auth-card .form-field select { padding: var(--sp-3); }
.auth-card .btn--block { padding-top: var(--sp-3); padding-bottom: var(--sp-3); font-size: var(--fs-body-lg); }
.auth-trust { margin: var(--sp-3) 0 0; font-size: var(--fs-caption); color: var(--color-text-muted); text-align: center; }
.auth-links { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); margin-top: var(--sp-4); font-size: var(--fs-body); text-align: center; }
/* Selector de idioma en la esquina superior derecha (issue #8). */
.auth-lang { position: absolute; top: var(--sp-5); right: var(--sp-5); }
.auth-lang select { border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface); color: var(--color-text); font: inherit; padding: var(--sp-1) var(--sp-2); }

.form-field { display: flex; flex-direction: column; gap: var(--sp-1); }
.form-label { font-size: var(--fs-label); font-weight: var(--fw-label); color: var(--color-text); }
.form-hint { font-size: var(--fs-caption); color: var(--color-text-muted); }
/* issue #36 §3.7: aviso contextual NO bloqueante (recordatorio, no error). */
.form-warning { font-size: var(--fs-caption); color: var(--color-warning); background: var(--color-warning-bg); border: var(--bw-1) solid #f0dcae; border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3); margin: var(--sp-2) 0; }
.form-field input, .form-field select {
    font: inherit; color: var(--color-text);
    padding: var(--sp-2) var(--sp-3);
    border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md);
    background: var(--color-surface);
}
.form-field input.is-error, .form-field textarea.is-error { border-color: var(--color-danger); }
.form-check { display: flex; align-items: flex-start; gap: var(--sp-2); font-size: var(--fs-label); color: var(--color-text-muted); }
.form-check input { margin-top: 2px; }

/* Primera capa de informacion RGPD en el registro (issue #25 §3): componente
   informativo discreto, claramente diferenciado del checkbox contractual. */
.auth-privacy {
    background: var(--color-surface-2); border: var(--bw-1) solid var(--color-border);
    border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4);
    margin-bottom: var(--sp-3); font-size: var(--fs-caption); line-height: var(--lh-caption);
    color: var(--color-text-muted);
}
.auth-privacy__title { margin: 0 0 var(--sp-1); font-weight: var(--fw-medium); color: var(--color-text); }
.auth-privacy__line { margin: 0; }
.auth-privacy__line + .auth-privacy__line { margin-top: 2px; }
.auth-privacy a { color: var(--color-primary-600); }
/* ---- Banner (componente `Banner` del design system) ----------------------
   Icono por variante, cuerpo en texto atenuado, radio de tarjeta. El icono se
   pinta como mascara CSS posicionada en absoluto, no como <svg> en la
   plantilla: asi los 19 puntos de llamada no cambian y el contenido anidado
   (listas, botones) conserva su flujo de bloque. El resultado visual es el del
   componente. Adaptacion de codigo, no del diseno. */
.form-alert {
    position: relative;
    padding: var(--sp-3) var(--sp-4);
    padding-left: calc(var(--sp-4) + 18px + var(--sp-3));
    border-radius: var(--r-xl);
    font-size: var(--fs-label); line-height: var(--lh-body);
    color: var(--color-text-muted);
    margin-bottom: var(--sp-4);
}
.form-alert::before {
    content: ""; position: absolute;
    left: var(--sp-4); top: calc(var(--sp-3) + 1px);
    width: 18px; height: 18px;
    background-color: var(--alert-icon-color);
    -webkit-mask: var(--alert-icon) center / 18px 18px no-repeat;
    mask: var(--alert-icon) center / 18px 18px no-repeat;
}
/* El bloque de accion cuelga bajo el cuerpo, no en linea con el (ver panel.dc.html). */
.form-alert__action { margin-top: var(--sp-2); }

/* SPEC/interactions.md manda sobre el componente compilado (ver RE-ENTREGA §2): el banner
   de error va en `--color-danger-bg` / `--color-danger`, no con el cuerpo atenuado. */
.form-alert--error {
    background: var(--color-danger-bg);
    border: var(--bw-1) solid #f3c6bd;  /* literal del design system */
    color: var(--color-danger);
    --alert-icon-color: var(--color-danger);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='15' y1='9' x2='9' y2='15'/%3E%3Cline x1='9' y1='9' x2='15' y2='15'/%3E%3C/svg%3E");
}

/* issue #36 §1.1/§1.2/§1.3: guarda global del atributo [hidden]. Sin ella, reglas de autor con
   display explicito (p. ej. .btn { display: inline-flex }) ganan a la regla [hidden]{display:none}
   del navegador, de modo que element.hidden=true (Atras/Siguiente/Emitir del wizard) NO oculta el
   boton. Con !important el atributo hidden vuelve a ocultar siempre. */
[hidden] { display: none !important; }

.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
    font: inherit; font-weight: 600; cursor: pointer;
    padding: var(--sp-3) var(--sp-5); border-radius: var(--r-md); border: var(--bw-1) solid transparent;
    text-decoration: none; transition: filter var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease); }
/* Primaria: verde de accion, solido. Crear/Emitir/Guardar/Entrar. Sin degradado:
   el diseno reserva los degradados para la sidebar y la imagen de marketing. */
/* Primaria (issue #20): degradado azul→cian, texto blanco. Crear/Emitir/Guardar. */
.btn--accent { background: var(--grad-primary); color: var(--color-on-accent); }
.btn--accent:hover { filter: brightness(.96); box-shadow: var(--sh-sm); }
/* Primaria solida alternativa (navy). */
.btn--primary { background: var(--color-primary-600); color: var(--color-text-invert); }
.btn--primary:hover { background: var(--color-primary-700); }
.btn--block { width: 100%; }

@media (max-width: 768px) {
    /* issue #187: 40px de padding a cada lado se comen un tercio de una pantalla de 320px. */
    .auth-card { padding: var(--sp-5); }
    .auth-main { padding: var(--sp-4); }
}

/* Pantallas bajas de escritorio (portatiles de 14", issue #8 3a ronda): ritmo vertical
   compacto para que login/acceso quepan sin scroll; el aspecto en pantallas grandes y
   movil (ya validado por el cliente) no cambia. */
@media (min-width: 769px) and (max-height: 860px) {
    .auth-main { gap: var(--sp-4); padding: var(--sp-5); }
    .auth-logo { width: min(200px, 55%); }
    .auth-card { padding: var(--sp-6); }
}

/* ---- Responsive: sidebar oculta en movil (off-canvas + backdrop) ---- */
@media (max-width: 768px) {
    .sidebar {
        position: fixed; z-index: var(--z-sticky); height: 100%; height: 100dvh;
        transform: translateX(-100%);
    }
    .app-shell.is-mobile-open .sidebar { transform: translateX(0); box-shadow: var(--sh-lg); }
    /* Oscurece el contenido mientras la sidebar esta abierta; el JS cierra al tocar fuera. */
    .app-shell.is-mobile-open::before {
        content: ""; position: fixed; inset: 0;
        background: rgba(20, 32, 40, .45);
        z-index: calc(var(--z-sticky) - 1);
    }
}

/* ============================================================================
   crud-maestro (Slice 3): nav entidades + tabla + formulario lateral
   ============================================================================ */
.maestros {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr) 0;
    gap: var(--sp-5);
    align-items: start;
}
/* El formulario lateral ocupa columna propia cuando esta abierto (escritorio). */
.maestros.is-form-open { grid-template-columns: 200px minmax(0, 1fr) 340px; }

/* ---- Nav de entidades ---- */
.maestros__entities ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.entity-tab {
    display: flex; align-items: center; gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
    color: var(--color-text-muted); text-decoration: none;
    font-size: var(--fs-label); font-weight: var(--fw-label);
    transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.entity-tab:hover { background: var(--color-surface-2); color: var(--color-text); }
.entity-tab.is-active { background: var(--color-primary-100); color: var(--color-primary-700); }
.entity-tab__icon { display: inline-flex; flex-shrink: 0; }

/* ---- Toolbar (busqueda + filtro + nuevo) ---- */
.maestros__toolbar { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); flex-wrap: wrap; }
/* issue #24: con `min-width:0` el form absorbia todo el encogimiento y sus controles se
   salian de su caja pisando las acciones. Los filtros ocupan fila propia y envuelven;
   las acciones caen a la siguiente. Cabrian en una sola fila solo recortando el buscador
   a ~140px, que es justo el apelotonamiento que reporta el issue. */
.maestros__filters { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); flex: 1 1 100%; min-width: 0; }
.field-search {
    display: flex; align-items: center; gap: var(--sp-2);
    padding: 0 var(--sp-3); height: 36px;
    background: var(--color-surface); border: var(--bw-1) solid var(--color-border-strong);
    border-radius: var(--r-md); color: var(--color-text-muted); flex: 1; min-width: 140px;
}
.field-search input { border: none; outline: none; background: transparent; flex: 1; font: inherit; color: var(--color-text); min-width: 0; }
/* Sin encogimiento: cada select conserva el ancho de su texto y nunca lo recorta. */
.maestros__filters select {
    height: 36px; border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md);
    background: var(--color-surface); color: var(--color-text); font: inherit; padding: 0 var(--sp-2);
    flex: 0 0 auto;
}

/* ---- Botones auxiliares ---- */
/* Secundaria (issue #20): fondo blanco, borde y texto azul. Ver planes, cancelar, etc. */
.btn--ghost { background: var(--color-surface); color: var(--color-primary-600); border-color: var(--color-primary-600); }
.btn--ghost:hover { background: var(--color-primary-050); }
.icon-btn--sm { width: 30px; height: 30px; }
.icon-btn--danger:hover { background: var(--color-danger-bg); color: var(--color-danger); }
.inline-form { display: inline; }

/* ---- Tabla de datos ---- */
.table-wrap { padding: 0; overflow-x: auto; }
.data-table { width: 100%; border-collapse: collapse; font-size: var(--fs-body); }
.data-table th, .data-table td { text-align: left; padding: var(--sp-3) var(--sp-4); border-bottom: var(--bw-1) solid var(--color-border); }
.data-table th {
    font-size: var(--fs-caption); font-weight: var(--fw-label); text-transform: uppercase;
    letter-spacing: .04em; color: var(--color-text-muted); background: var(--color-surface-2);
    position: sticky; top: 0;
}
.data-table tbody tr:hover { background: var(--color-primary-050); }
.data-table tbody tr.is-editing { background: var(--color-primary-050); box-shadow: inset 3px 0 0 var(--color-primary-600); }
.data-table tr:last-child td { border-bottom: none; }
.col-actions { text-align: right; white-space: nowrap; }
.text-subtle { color: var(--color-text-muted); }

/* ============================================================================
   issue #187 — patrones reutilizables de responsive (Sprint 0)
   Se construyen aqui UNA vez y se aplican pantalla a pantalla en los sprints
   siguientes, en vez de resolver cada tabla/formulario de forma aislada.
   ============================================================================ */


.state-dot { display: inline-block; width: 8px; height: 8px; border-radius: var(--r-pill); margin-right: var(--sp-2); vertical-align: middle; }
.state-dot.is-on { background: var(--color-success); }
.state-dot.is-off { background: var(--color-text-subtle); }

/* ---- Estado vacio ---- */
.empty-state { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--sp-3); padding: var(--sp-9) var(--sp-5); color: var(--color-text-muted); }
.empty-state svg { color: var(--color-text-subtle); }
.empty-state__title { font-size: var(--fs-h3); font-weight: var(--fw-h3); margin: 0; color: var(--color-text); }
.empty-state__text { margin: 0; max-width: 360px; }

/* ---- Mensaje que explica un estado (issue #48 F11, §16) ----
   Va DEBAJO del estado, en su misma celda, con el color secundario de texto (6,0:1 sobre blanco,
   por encima del 4,5:1 que exige WCAG 2.2 AA para texto normal — no se baja a `--color-text-subtle`
   precisamente porque este texto hay que poder leerlo, no adivinarlo). Es `block` para que caiga a
   su propia linea sin depender del ancho de la columna. `--fs-caption` no se usa aqui: a 12 px un
   mensaje de dos lineas se lee peor justo cuando el cliente mas lo necesita. */
.pay-txmsg {
    display: block; margin-top: var(--sp-1);
    font-size: var(--fs-label); line-height: var(--lh-body);
    color: var(--color-text-muted); max-width: 42ch;
}

/* ---- Formulario lateral (pegajoso) ---- */
.maestros__form {
    position: sticky; top: var(--sp-5);
    background: var(--color-surface); border: var(--bw-1) solid var(--color-border);
    border-radius: var(--r-lg); box-shadow: var(--sh-sm);
    padding: var(--sp-5); display: none;
}
.maestros.is-form-open .maestros__form { display: block; }
.maestros__form-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-4); }
.maestros__form-title { font-size: var(--fs-h3); font-weight: var(--fw-h3); margin: 0; }
.maestros__form-body { display: flex; flex-direction: column; gap: var(--sp-4); }
.maestros__form-note { margin: 0; }
.maestros__form-actions { display: flex; gap: var(--sp-3); justify-content: flex-end; margin-top: var(--sp-2); }
.form-error { color: var(--color-danger); font-size: var(--fs-caption); margin: 0; }
.req { color: var(--color-danger); }
.form-field select.is-error { border-color: var(--color-danger); }
.form-check--toggle { align-items: center; }

.maestros__backdrop { display: none; }

/* ---- Toast (exito) ---- */
.toast {
    position: fixed; left: 50%; bottom: var(--sp-5); transform: translateX(-50%);
    background: var(--color-primary-700); color: var(--color-text-invert);
    padding: var(--sp-3) var(--sp-5); border-radius: var(--r-md); box-shadow: var(--sh-lg);
    z-index: var(--z-toast); font-size: var(--fs-label); font-weight: var(--fw-label);
    animation: toast-in var(--dur-base) var(--ease);
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* ---- Responsive: <=1024 nav superior; <=768 formulario en drawer ---- */
@media (max-width: 1024px) {
    /* issue #187: `minmax(0, 1fr)`, no `1fr`. `1fr` equivale a `minmax(auto, 1fr)` y ese minimo
       `auto` es el min-content de la pista: con el buscador (`min-width:140px`) y los selects
       dentro, la pista no encogia por debajo de ~373px y desbordaba el viewport a 320px, aunque
       el contenedor si cupiera. Es el equivalente en Grid del `min-width:auto` de Flexbox que
       desbordaba la pantalla de registro. */
    .maestros, .maestros.is-form-open { grid-template-columns: minmax(0, 1fr); }
    .maestros__entities ul { flex-direction: row; flex-wrap: wrap; }
    .maestros__form { position: static; }
    /* Tablet: las acciones ocupan fila propia; al llenarla, quedan alineadas a la
       izquierda y el `margin-left:auto` de su regla base deja de tener efecto. */
    .maestros__toolbar-actions { flex-basis: 100%; }
}
@media (max-width: 768px) {
    .maestros__form {
        position: fixed; top: 0; right: 0; bottom: 0; width: min(360px, 92vw);
        border-radius: 0; z-index: var(--z-modal); overflow-y: auto;
        transform: translateX(100%); transition: transform var(--dur-base) var(--ease);
        display: block;
    }
    .maestros.is-form-open .maestros__form { transform: translateX(0); }
    .maestros.is-form-open .maestros__backdrop {
        display: block; position: fixed; inset: 0; background: rgba(20,32,40,.45);
        z-index: var(--z-backdrop);
    }
    /* La pagina propia de Plantilla DeCA (--page, ver mas abajo) no vive dentro de `.maestros`, asi
       que esta regla de drawer NUNCA debe alcanzarla — sin este reset heredaria position:fixed y
       quedaria fuera de pantalla (transform:translateX(100%)) sin ningun `.is-form-open` que la
       revele. */
    .maestros__form--page {
        position: static; top: auto; right: auto; bottom: auto; width: auto;
        transform: none; display: block;
    }
}

/* ---- Plantilla DeCA: pantalla propia (issue #84, Decision D) ----
   Jorge la pidio por nombre: "el formulario de plantilla contiene muchos campos y
   previsiblemente crecera mas" (issue #84). Reutiliza el bloque visual de `.maestros__form`
   (fondo, borde, sombra, `-head`/`-body`/`-title`/`-actions`) pero ya NO vive en la columna
   lateral de 340px de `.maestros` ni depende de `.is-form-open` para mostrarse -> se sobreescriben
   aqui las tres propiedades que la hacian invisible/pegajosa/estrecha fuera de ese contexto. */
.maestros__form--page {
    display: block; position: static;
    max-width: 720px; margin: 0 auto;
}
.maestros-page-form__back {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    color: var(--color-primary-600); text-decoration: none; font-size: var(--fs-label);
    margin-bottom: var(--sp-2);
}
.maestros-page-form__back:hover { text-decoration: underline; }
/* Movil: los filtros pasan a una columna (issue #24). Las acciones se tratan mas abajo,
   junto a su regla base, para no perder la cascada. */
@media (max-width: 480px) {
    .maestros__filters .field-search,
    .maestros__filters select,
    .maestros__filters .btn { flex-basis: 100%; width: 100%; }
}

/* ============================================================================
   DeCA: listado, form-deca y detalle (Slice 4)
   ============================================================================ */

/* ---- Badges de estado de documento (badge solido, texto blanco; AA) ---- */
.badge { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: var(--r-pill); font-size: var(--fs-caption); font-weight: 600; color: #fff; white-space: nowrap; }
.badge--borrador   { background: var(--state-borrador); }
.badge--emitido    { background: var(--state-emitido); }
.badge--modificado { background: var(--state-modificado); }
.badge--anulado    { background: var(--state-anulado); }
.badge--sustituido { background: var(--state-sustituido); }
.badge--expirado   { background: var(--state-expirado); }
.badge--muted      { background: var(--state-borrador); }

/* ---- Toolbar del listado ---- */
.deca-toolbar { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); flex-wrap: wrap; }
.deca-filters { display: flex; align-items: center; gap: var(--sp-2); flex: 1; min-width: 0; flex-wrap: wrap; }
.deca-filters select { height: 36px; border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface); color: var(--color-text); font: inherit; padding: 0 var(--sp-2); }
.deca-toolbar__new { display: flex; gap: var(--sp-2); }
.deca-count { color: var(--color-text-muted); font-size: var(--fs-label); margin: 0 0 var(--sp-3); }
.data-table--clickable tbody tr { cursor: pointer; }
/* issue #174.2: paginacion del listado de Documentos, mismo criterio que .deca-toolbar */
.deca-pager { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-3); flex-wrap: wrap; }
.deca-pager__nav { display: flex; gap: var(--sp-2); }

/* ---- Banner "rellena desde tus datos" ---- */
.deca-banner { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4); background: var(--color-primary-050); border: var(--bw-1) solid var(--color-primary-100); border-radius: var(--r-lg); }
.deca-banner__text { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-label); }
.deca-banner__text span { color: var(--color-text-muted); }

/* ---- Segmented (mercancias / viajeros) ---- */
.segmented { display: inline-flex; padding: 3px; gap: 2px; background: var(--color-surface-2); border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); margin-bottom: var(--sp-4); }
.segmented__opt { padding: var(--sp-2) var(--sp-5); border-radius: var(--r-sm); text-decoration: none; color: var(--color-text-muted); font-weight: var(--fw-label); font-size: var(--fs-label); }
.segmented__opt.is-active { background: var(--color-surface); color: var(--color-primary-700); box-shadow: var(--sh-sm); }

/* ---- Rejilla form + rail ---- */
.deca-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--sp-5); align-items: start; }
.deca-grid__main { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.card-title { font-size: var(--fs-h3); font-weight: var(--fw-h3); margin: 0 0 var(--sp-4); }
.form-alert--info {
    background: var(--color-info-bg);
    border: var(--bw-1) solid var(--color-primary-100);
    --alert-icon-color: var(--color-info);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='16' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'/%3E%3C/svg%3E");
}

/* issue #39 §8: aviso de consumo al 80 % (amarillo). Reutiliza el token de aviso. */
.form-alert--warning {
    background: var(--color-warning-bg, #fbf5e6);
    border: var(--bw-1) solid #ecd9b3;
    color: #8a5c07;
    --alert-icon-color: var(--color-warning, #b5820a);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/%3E%3Cline x1='12' y1='9' x2='12' y2='13'/%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'/%3E%3C/svg%3E");
}

/* issue #98 (ampliacion): aviso al cliente tipo "exito" (verde). Mismos tokens que .banner--success. */
.form-alert--success {
    background: var(--color-success-bg);
    border: var(--bw-1) solid #b9e6d9;
    color: var(--color-success);
    --alert-icon-color: var(--color-success);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 11.08V12a10 10 0 1 1-5.93-9.14'/%3E%3Cpolyline points='22 4 12 14.01 9 11.01'/%3E%3C/svg%3E");
}

/* issue #98 (ampliacion, feedback de Jorge 03/08): aviso tipo "mantenimiento" compartia color e
   icono con "advertencia" y no se distinguian de un vistazo. Reutiliza el morado de
   --state-sustituido (ya en el sistema, documento sustituido) en vez de inventar un tono nuevo;
   icono de llave inglesa en vez del triangulo de advertencia. */
.form-alert--maintenance {
    background: var(--state-sustituido-bg);
    border: var(--bw-1) solid #d9cceb;
    color: var(--state-sustituido-fg);
    --alert-icon-color: var(--state-sustituido);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z'/%3E%3C/svg%3E");
}

/* issue #39 §7/§22: panel de consumo del cliente */
.consumo-card { margin-bottom: var(--sp-5); }
.consumo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4); }
.consumo-grid > div { display: flex; flex-direction: column; gap: 2px; }
.consumo-label { font-size: var(--fs-caption); color: var(--color-text-muted); }
.consumo-actions { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-3); flex-wrap: wrap; }
.consumo-cancel-note { font-size: var(--fs-label); color: var(--color-text-muted); }

/* ---- Partes diferenciadas (cargador vs transportista) ---- */
.party-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.party { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.party--t { border-color: #d7e6df; }
.party--c { border-color: #d6e0ea; }
.party__head { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-label); font-weight: 600; text-transform: uppercase; letter-spacing: .02em; }
.party--t .party__head { color: var(--color-accent-700); }
.party--c .party__head { color: var(--color-primary-600); }
.party__auto { margin: 0; color: var(--color-text-muted); font-size: var(--fs-label); }
.party-name { font-weight: 600; }
.party-nif { color: var(--color-text-muted); font-size: var(--fs-label); }
.party-dom { color: var(--color-text-muted); font-size: var(--fs-label); }
.tag { width: 18px; height: 18px; border-radius: 4px; color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; }
.tag--t { background: var(--color-accent-600); } .tag--c { background: var(--color-primary-600); }

/* ---- Filas/campos del formulario ---- */
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-4); margin-bottom: var(--sp-4); }
.deca-form .form-field { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-3); }
.deca-form textarea, .deca-form input[type="text"], .deca-form input[type="date"], .deca-form select {
    font: inherit; color: var(--color-text); padding: var(--sp-2) var(--sp-3);
    border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface);
}
.deca-form textarea { resize: vertical; }

/* ---- Combobox (popup) ---- */
.combo { position: relative; }
.combo__trigger { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); font: inherit; text-align: left; cursor: pointer; padding: var(--sp-2) var(--sp-3); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface); color: var(--color-text); }
.combo__value.is-placeholder { color: var(--color-text-muted); }
.combo__pop { position: absolute; z-index: var(--z-dropdown); top: calc(100% + 4px); left: 0; right: 0; background: var(--color-surface); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); box-shadow: var(--sh-md); padding: var(--sp-2); }
.combo__search { width: 100%; font: inherit; padding: var(--sp-2) var(--sp-3); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-sm); margin-bottom: var(--sp-2); }
.combo__list { list-style: none; margin: 0; padding: 0; max-height: 220px; overflow-y: auto; }
.combo-inline__list { list-style: none; margin: 2px 0 0; padding: var(--sp-1); position: absolute; z-index: var(--z-dropdown); left: 0; right: 0; background: var(--color-surface); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); box-shadow: var(--sh-md); max-height: 200px; overflow-y: auto; }
.combo__opt { display: flex; flex-direction: column; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm); cursor: pointer; }
.combo__opt:hover, .combo__opt:focus { background: var(--color-surface-2); outline: none; }
.combo__sub { font-size: var(--fs-caption); color: var(--color-text-muted); }
.combo__add { display: block; padding: var(--sp-2) var(--sp-3); margin-top: var(--sp-1); font-size: var(--fs-label); border-top: var(--bw-1) solid var(--color-border); }
.combo-inline { position: relative; }
.combo-inline__input { width: 100%; font: inherit; color: var(--color-text); padding: var(--sp-2) var(--sp-3); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface); }

/* ---- Lineas (repetidor) ---- */
.lines { display: flex; flex-direction: column; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.line-row { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4); background: var(--color-surface-2); }
.line-row__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-2); }
.line-row__num { width: 24px; height: 24px; border-radius: var(--r-pill); background: var(--color-primary-600); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: var(--fs-caption); font-weight: 600; font-family: var(--font-mono); }
.line-row__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-3); }
.form-field--wide { grid-column: 1 / -1; }

/* ---- Direccion estructurada origen/destino (issue #22 #3/#4/#5) ---- */
.addr-group { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4) var(--sp-4); margin: 0; display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.addr-group__title { font-size: var(--fs-caption); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--color-text-muted); padding: 0 var(--sp-1); }
.addr-group__row { display: grid; grid-template-columns: minmax(90px, 0.5fr) minmax(120px, 1fr); gap: var(--sp-3); }
.deca-form .addr-group .form-field { margin-bottom: 0; }

/* ---- Peso valor + unidad (issue #22 #11) + bultos/unidad logistica (issue #36 §2.2) ---- */
.peso-group { display: grid; grid-template-columns: 1fr auto; gap: var(--sp-2); }
.deca-form .peso-field .js-peso-otra { margin-top: var(--sp-2); margin-bottom: 0; }
.deca-form .peso-field .peso-field__bultos { margin-top: var(--sp-2); margin-bottom: 0; }

/* ---- Paradas individualizadas (issue #22 #9) ---- */
.paradas__list { list-style: none; margin: 0 0 var(--sp-2); padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.parada-row { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3); background: var(--color-surface); }
.parada-row__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-2); }
.parada-row__num { width: 22px; height: 22px; border-radius: var(--r-pill); background: var(--color-accent-600); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: var(--fs-caption); font-weight: 600; font-family: var(--font-mono); }
.parada-row__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--sp-2); }
.deca-form .parada-row .form-field { margin-bottom: 0; }

/* Overrides por linea (issue #22 #7/#8): fecha por envio y autobus/conductor por servicio.
   El checkbox "usar general" (marcado por defecto) oculta el cuerpo; al desmarcar se revela. */
.line-override { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3); background: var(--color-surface); }
.line-override__body { margin-top: var(--sp-3); }
.deca-form .line-override .form-field { margin-bottom: 0; }
.line-transporte { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-3); }
/* issue #36 §3.3: aviso informativo cuando se usan el autobus/conductor generales. */
.line-transporte__info { margin: var(--sp-2) 0 0; }
/* Sub-fila de override en las tablas de lineas (detalle/PDF-fallback): dato propio del envio/servicio. */
.line-sub td { background: var(--color-surface-2); font-size: var(--fs-caption); color: var(--color-text-muted); }
.line-sub__label { font-weight: 600; }
/* issue #187 (Jorge, 08/08/2026, punto 7.1): cada dato complementario del envio es su propio
   `item`, y el separador « · » lo pone el CSS en vez de venir cosido en el HTML. Asi en escritorio
   se siguen leyendo en una linea, y en movil cada uno puede convertirse en una fila etiquetada
   como el resto de la ficha — que es justo lo que Jorge pedia: «que carga y descarga se lean como
   dos datos mas del trayecto, no como un bloque anadido». Con el separador en el HTML eso era
   imposible sin duplicar el markup. */
.line-sub__item + .line-sub__item::before { content: '\00a0·\00a0'; color: var(--color-text-subtle); }

/* ---- Rail de validacion ---- */
.deca-rail { position: sticky; top: var(--sp-5); }
.deca-rail__card { background: var(--color-surface); border: var(--bw-1) solid var(--color-border); border-radius: var(--r-lg); box-shadow: var(--sh-sm); padding: var(--sp-5); }
.deca-rail__title { font-size: var(--fs-h3); font-weight: var(--fw-h3); margin: 0 0 var(--sp-4); }
.deca-rail__hint { color: var(--color-text-muted); font-size: var(--fs-label); }
.deca-rail__actions { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-4); }
.deca-rail__note { color: var(--color-text-muted); font-size: var(--fs-caption); margin: var(--sp-3) 0 0; }
.checklist { list-style: none; margin: 0 0 var(--sp-3); padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.checklist__item { display: flex; gap: var(--sp-2); align-items: flex-start; font-size: var(--fs-label); }
.checklist__item.is-error { color: var(--color-danger); }
.checklist__item.is-warn { color: var(--color-warning); }
.checklist__item.is-info { color: var(--color-info); }
.checklist__item svg { flex: none; margin-top: 1px; }
.deca-rail__hint.is-ready { color: var(--color-success); font-weight: var(--fw-label); }
/* issue #180: "se puede emitir, pero hay advertencias" — mismo tono que .checklist__item.is-warn */
.deca-rail__hint.is-warn { color: var(--color-warning); font-weight: var(--fw-label); }

/* ---- Asistente de 4 pasos (crear.md, issue #22) ---- */
.deca-wizard { max-width: 920px; }
/* Stepper: revelado solo con JS (sin JS lleva el atributo hidden). */
.wizard-steps { display: flex; flex-wrap: wrap; gap: var(--sp-2); list-style: none; margin: 0 0 var(--sp-5); padding: 0; }
.wizard-steps__item { flex: 1 1 auto; }
.wizard-steps__btn { width: 100%; display: flex; align-items: center; gap: var(--sp-2); font: inherit; text-align: left; cursor: pointer; padding: var(--sp-2) var(--sp-3); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface); color: var(--color-text-muted); }
.wizard-steps__num { flex: none; width: 26px; height: 26px; border-radius: var(--r-pill); display: inline-flex; align-items: center; justify-content: center; font-size: var(--fs-caption); font-weight: 600; font-family: var(--font-mono); border: var(--bw-1) solid var(--color-border-strong); background: var(--color-surface); }
.wizard-steps__label { font-size: var(--fs-label); font-weight: var(--fw-label); }
.wizard-steps__item.is-done .wizard-steps__num { background: var(--color-primary-600); border-color: var(--color-primary-600); color: #fff; }
.wizard-steps__item.is-active .wizard-steps__btn { border-color: var(--color-accent-600); color: var(--color-text); }
.wizard-steps__item.is-active .wizard-steps__num { background: var(--color-accent-600); border-color: var(--color-accent-600); color: #fff; }
/* issue #36 §1.8: ✓ (completo) / ✕ (pendiente) reemplazan el número cuando el JS evalúa el paso.
   El paso actual conserva su borde destacado (is-active); estos marcadores son un indicador extra. */
.wizard-steps__mark { flex: none; width: 26px; height: 26px; border-radius: var(--r-pill); display: none; align-items: center; justify-content: center; border: var(--bw-1) solid transparent; color: #fff; }
.wizard-steps__item.is-complete .wizard-steps__num,
.wizard-steps__item.is-incomplete .wizard-steps__num { display: none; }
.wizard-steps__item.is-complete .wizard-steps__mark--ok { display: inline-flex; background: var(--color-accent-600); border-color: var(--color-accent-600); }
.wizard-steps__item.is-incomplete .wizard-steps__mark--bad { display: inline-flex; background: var(--color-danger); border-color: var(--color-danger); }
/* issue #36 §2.5/§3.6: tabla de resumen de envíos/servicios en la Revisión. */
.review-lines-wrap { overflow-x: auto; margin-top: var(--sp-4); }
.review-lines { width: 100%; border-collapse: collapse; font-size: var(--fs-label); }
.review-lines th, .review-lines td { text-align: left; padding: var(--sp-2) var(--sp-3); border-bottom: var(--bw-1) solid var(--color-border); vertical-align: top; }
.review-lines thead th { font-weight: var(--fw-label); color: var(--color-text-muted); white-space: nowrap; }
.review-lines tbody tr:last-child td { border-bottom: 0; }
/* En modo paginado (JS) solo se ve el paso activo; sin JS se apilan todos. */
.deca-wizard.is-wizard .wizard-step:not(.is-active) { display: none; }
/* Barra inferior de navegacion. */
.wizard-nav { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: var(--bw-1) solid var(--color-border); }
.wizard-nav__spacer { flex: 1 1 auto; }
/* Resumen del paso 4 (issue #18). */
.review-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--sp-4); margin: 0 0 var(--sp-4); }
.review-grid__cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.review-grid__label { font-size: var(--fs-caption); text-transform: uppercase; letter-spacing: .04em; color: var(--color-text-muted); }
.review-grid__value { font-size: var(--fs-body); font-weight: var(--fw-label); overflow-wrap: anywhere; }

/* ---- Detalle ---- */
.deca-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-5); flex-wrap: wrap; }
.deca-detail-id { font-size: 22px; font-weight: 600; color: var(--color-primary-700); }
.deca-detail-meta { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-2); color: var(--color-text-muted); font-size: var(--fs-label); flex-wrap: wrap; }
.deca-detail-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
/* issue #187 punto 2 (tercera ronda, captura real de Jorge): el `display:contents` que saca a
   `.inline-form` (envuelve "Duplicar DeCA") de su propia caja de flex anidada estaba acotado a
   `@media (max-width:480px)`, pero `.deca-detail-actions` envuelve SIEMPRE (regla de arriba, sin
   media query) y la ecualizacion de alturas de la ronda anterior (`min-height:46px`,
   mas abajo) vive en `@media (max-width:768px)` — un rango mas ancho. Entre 481 y 768px el
   `.inline-form` seguia con su caja propia sin que nada lo corrigiera: exactamente lo que muestra
   la captura, "Duplicar DeCA" con una caja mas alta que sus hermanos. Sin media query: el
   formulario nunca debe competir como su propia caja, a ningun ancho. */
.deca-detail-actions .inline-form { display: contents; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn--danger-ghost { color: var(--color-danger); border-color: var(--color-border-strong); background: var(--color-surface); }
.deca-detail-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) 1fr; gap: var(--sp-5); align-items: start; }
.deca-detail-main { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; }
.deca-qr { display: flex; gap: var(--sp-4); align-items: center; }
.deca-qr__code { width: 96px; height: 96px; flex: none; border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); display: flex; align-items: center; justify-content: center; color: var(--color-text-subtle); }
.deca-qr__body { flex: 1; min-width: 0; }
.deca-qr__url { display: flex; gap: var(--sp-2); margin: var(--sp-1) 0; }
.deca-qr__url input { flex: 1; min-width: 0; font: inherit; padding: var(--sp-2) var(--sp-3); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface-2); }
.detail-facts { display: flex; gap: var(--sp-6); flex-wrap: wrap; margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: var(--bw-1) solid var(--color-border); }
.detail-facts > div { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-label); }
.detail-obs { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: var(--bw-1) solid var(--color-border); font-size: var(--fs-label); }
.detail-obs p { margin: 2px 0 0; line-height: var(--lh-body); }
.trace { list-style: none; margin: 0 0 var(--sp-3); padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.trace li { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-label); }
.deca-back { display: inline-block; margin-top: var(--sp-3); color: var(--color-primary-600); text-decoration: none; font-size: var(--fs-label); }

/* ---- Responsive ---- */
@media (max-width: 1024px) {
    .deca-grid, .deca-detail-grid { grid-template-columns: 1fr; }
    .deca-rail { position: static; }
}
@media (max-width: 768px) {
    .party-grid { grid-template-columns: 1fr; }
    /* Stepper: las pildoras se apilan con etiqueta visible (crear.md). */
    .wizard-steps { flex-direction: column; }
    /* Botonera inferior con CTAs a ancho completo. */
    .wizard-nav { flex-direction: column; align-items: stretch; }
    .wizard-nav__spacer { display: none; }
    .wizard-nav .btn { width: 100%; }
}

/* ---- Vista publica de inspeccion (Slice 5): movil primero ---- */
.pub-body { background: var(--color-bg); min-height: 100vh; }
.pub-wrap { max-width: 420px; margin: 0 auto; padding: var(--sp-6) var(--sp-4) var(--sp-8); display: flex; flex-direction: column; gap: var(--sp-5); min-height: 100vh; box-sizing: border-box; }
.pub-brand { display: flex; align-items: center; gap: var(--sp-2); color: var(--color-primary-600); }
.pub-brand__name { font-weight: 600; font-size: var(--fs-h3); letter-spacing: .02em; }
.pub-card { background: var(--color-surface); border: var(--bw-1) solid var(--color-border); border-radius: var(--r-xl); padding: var(--sp-6) var(--sp-5); box-shadow: var(--sh-sm); display: flex; flex-direction: column; gap: var(--sp-4); }
.pub-card--neutral { text-align: center; }
.pub-eyebrow { margin: 0; font-size: var(--fs-caption); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--color-text-muted); }
.pub-state { display: flex; justify-content: flex-start; }
.pub-card--neutral .pub-state { justify-content: center; }
.pub-state__badge { font-size: var(--fs-body); padding: 6px 16px; }
.pub-note { margin: 0; font-size: var(--fs-label); line-height: 1.5; }
.pub-note--warn { color: var(--color-warning); }
.pub-note--danger { color: var(--color-danger); }
.pub-note--muted { color: var(--color-text-muted); }
.pub-facts { margin: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.pub-facts div { display: flex; flex-direction: column; gap: 2px; }
.pub-facts dt { font-size: var(--fs-caption); color: var(--color-text-subtle); text-transform: uppercase; letter-spacing: .04em; }
.pub-facts dd { margin: 0; font-size: var(--fs-body-lg); color: var(--color-text); }
.pub-download { min-height: 52px; font-size: var(--fs-body-lg); }
.pub-legal { margin: 0; font-size: var(--fs-caption); color: var(--color-text-subtle); line-height: 1.5; }
.pub-foot { margin-top: auto; display: flex; justify-content: center; opacity: .8; }

/* ---- Modal de enviar al conductor (Slice 5) ---- */
.modal { width: min(440px, calc(100vw - var(--sp-6))); border: var(--bw-1) solid var(--color-border); border-radius: var(--r-xl); padding: var(--sp-5); box-shadow: var(--sh-lg); color: var(--color-text); background: var(--color-surface); }
.modal::backdrop { background: rgba(20, 58, 82, .45); }
.modal__x { display: flex; justify-content: flex-end; margin: calc(var(--sp-3) * -1) calc(var(--sp-3) * -1) 0 0; }
.modal__x .btn { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-h2); line-height: 1; }
.modal__form { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
.field-label { font-size: var(--fs-label); font-weight: 500; color: var(--color-text-muted); }
.input { font: inherit; padding: var(--sp-2) var(--sp-3); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); background: var(--color-surface); color: var(--color-text); width: 100%; box-sizing: border-box; }
.input:focus-visible { outline: 3px solid var(--color-focus-ring); outline-offset: 1px; }
.modal__divider { display: flex; align-items: center; text-align: center; gap: var(--sp-2); color: var(--color-text-subtle); font-size: var(--fs-caption); margin: var(--sp-4) 0 var(--sp-2); }
.modal__divider::before, .modal__divider::after { content: ""; flex: 1; height: 1px; background: var(--color-border); }
.btn--danger { background: var(--color-danger); border-color: var(--color-danger); color: #fff; }

/* ---- Modificacion / anulacion (Slice 6) ---- */
.modify-methods { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-3); margin-bottom: var(--sp-3); }
.modify-methods legend { padding: 0 var(--sp-1); }
.radio-row { display: flex; gap: var(--sp-2); align-items: flex-start; padding: var(--sp-2) 0; cursor: pointer; }
.radio-row input { margin-top: 3px; }
.version-timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.version-item { border-left: 2px solid var(--color-border-strong); padding-left: var(--sp-3); }
.version-item.is-current { border-left-color: var(--color-accent-600); }
.version-item__head { display: flex; align-items: center; gap: var(--sp-2); }
.version-item__meta { font-size: var(--fs-caption); color: var(--color-text-muted); margin-top: 2px; }
.version-item__reason { font-size: var(--fs-caption); color: var(--color-text); margin-top: var(--sp-1); }
.version-item__date { font-size: var(--fs-caption); color: var(--color-text-subtle); margin-top: 2px; }

/* ============================================================================
   Slice 7 — Suscripcion y pago Redsys (planes, pagos, retorno)
   ============================================================================ */
.page-note { margin-top: var(--sp-4); font-size: var(--fs-caption); color: var(--color-text-muted); }
.btn--sm { padding: 4px 10px; font-size: var(--fs-caption); }
.cell-actions { text-align: right; white-space: nowrap; }
.cell-actions .inline-form { display: inline-block; margin-left: var(--sp-2); }

/* Rejilla de planes */
.plan-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--sp-4); margin-top: var(--sp-4); }
.plan-card { display: flex; flex-direction: column; gap: var(--sp-3); }
.plan-card--current { border-color: var(--color-accent-600); box-shadow: 0 0 0 1px var(--color-accent-600); }
.plan-card__subtitle { margin: calc(-1 * var(--sp-2)) 0 0; font-size: var(--fs-label); color: var(--color-text-muted); }
.plan-card__price { margin: 0; font-size: var(--fs-body); color: var(--color-text-muted); }
.plan-card__price strong { font-size: var(--fs-h2); color: var(--color-text); }
.plan-card__period { display: inline-block; margin-left: 4px; }
.plan-card__feats { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--fs-label); color: var(--color-text); }
.plan-card__feats li { padding-left: var(--sp-4); position: relative; }
.plan-card__feats li::before { content: ""; position: absolute; left: 0; top: .5em; width: 8px; height: 8px; border-radius: 2px; background: var(--color-accent-600); }
.plan-card .btn, .plan-card .badge { margin-top: auto; }
/* issue #32.4: plan destacado (cinta + borde de acento reforzado) */
.plan-card--featured { border-color: var(--color-accent-600); box-shadow: 0 0 0 2px var(--color-accent-600); position: relative; }
.plan-card__ribbon { position: absolute; top: 0; left: 50%; transform: translate(-50%, -50%);
    background: var(--color-accent-600); color: #fff; font-size: var(--fs-caption); font-weight: 600;
    padding: 3px 12px; border-radius: var(--r-pill); white-space: nowrap; text-transform: uppercase; letter-spacing: .03em; }
.plan-card__maestros-link { font-size: var(--fs-caption); color: var(--color-accent-600); }

/* issue #33: tabla comparativa de Maestros bajo las tarjetas */
.cmp-maestros { margin: var(--sp-6) 0 var(--sp-5); }
.cmp-maestros__title { font-size: var(--fs-h3); font-weight: var(--fw-h3); margin: 0 0 var(--sp-3); }
.cmp-maestros__intro { font-size: var(--fs-label); color: var(--color-text-muted); margin: 0 0 var(--sp-2); }
.cmp-maestros__scroll { overflow-x: auto; border: var(--bw-1) solid var(--color-border); border-radius: var(--r-xl); box-shadow: var(--sh-sm); background: var(--color-surface); }
.cmp-table { min-width: 520px; margin: 0; }
.cmp-table th { background: var(--color-primary-050); color: var(--color-primary-700); }
.cmp-table td.num, .cmp-table th.num { text-align: right; }

/* Pago: retorno y redireccion (layout publico) */
.pub-card__title { margin: 0; font-size: var(--fs-h2); font-weight: var(--fw-h1, 600); color: var(--color-text); }
.pub-card__lead { margin: 0; font-size: var(--fs-body); color: var(--color-text-muted); line-height: 1.5; }
.pub-actions { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-2); }
.pub-badge { align-self: center; font-size: var(--fs-caption); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; padding: 4px 14px; border-radius: 999px; }
.pub-badge--success { background: var(--color-primary-100); color: var(--color-primary-700); }
.pub-badge--warning { background: var(--color-info-bg); color: var(--color-info); }
.pub-badge--danger { background: var(--color-danger-bg); color: var(--color-danger); }

/* ---- Banner de modo soporte (impersonacion Pretium, Slice 9b) ------------ */
.support-banner {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 28px; background: #5b4f9e; color: #fff; font-size: 13px;
}
.support-banner__text { flex: 1; }
.support-banner__exit {
    height: 30px; padding: 0 13px; border-radius: 7px;
    border: 1px solid rgba(255,255,255,.5); background: transparent; color: #fff;
    font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.support-banner__exit:hover { background: rgba(255,255,255,.12); }

/* ---- Movimiento reducido (a11y) ----------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ---- Panel de control (issue #1) ----------------------------------------- */
.page-header--actions { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; }
.home-section-title { font-size: var(--fs-h3); font-weight: var(--fw-h3); margin: 0 0 var(--sp-3); }
.home-quota-facts { display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-6); margin: var(--sp-4) 0; }
.home-quota-facts dt { font-size: var(--fs-caption); color: var(--color-text-muted); margin: 0 0 2px; }
.home-quota-facts dd { margin: 0; font-weight: 600; }
.home-quick-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-5); }
.home-quick-card { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); padding: var(--sp-4); text-decoration: none; color: var(--color-text); font-weight: 500; }
.home-quick-card:hover { border-color: var(--color-primary-600); color: var(--color-primary-600); }
.home-setup-list { list-style: none; margin: 0 0 var(--sp-4); padding: 0; }
.home-setup-item { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) 0; border-bottom: var(--bw-1) solid var(--color-border); }
.home-setup-item:last-child { border-bottom: 0; }
.home-setup-state { margin-left: auto; font-size: var(--fs-caption); }
.home-two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--sp-4); }
.home-guide-list { margin: 0; padding-left: var(--sp-5); }
.home-guide-list li { margin-bottom: var(--sp-2); }

/* ---- Tabla operativa del panel (issue #11) --------------------------------- */
.cell-clip { display: inline-block; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.row-actions { white-space: nowrap; font-size: var(--fs-label); color: var(--color-text-subtle); }
.row-actions a { color: var(--color-primary-600); text-decoration: none; }
.row-actions a:hover { text-decoration: underline; }
.row-id-link { color: inherit; text-decoration: none; }
.row-id-link:hover { text-decoration: underline; }
.link-btn { background: none; border: 0; padding: 0; font: inherit; font-size: var(--fs-label); color: var(--color-primary-600); cursor: pointer; }
.link-btn:hover { text-decoration: underline; }

/* ---- Pestanas Suscripcion y pagos (issue #11) ------------------------------ */
.subnav-tabs { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-bottom: var(--sp-5); border-bottom: var(--bw-1) solid var(--color-border); }
.subnav-tab { padding: var(--sp-2) var(--sp-3); text-decoration: none; color: var(--color-text-muted); font-size: var(--fs-label); font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.subnav-tab:hover { color: var(--color-primary-600); }
.subnav-tab.is-active { color: var(--color-primary-600); border-bottom-color: var(--color-primary-600); }

/* ---- Seccion Cuenta (issue #4) -------------------------------------------- */
.cuenta-tabs { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-bottom: var(--sp-5); border-bottom: var(--bw-1) solid var(--color-border); }
.cuenta-tab { padding: var(--sp-2) var(--sp-3); text-decoration: none; color: var(--color-text-muted); font-size: var(--fs-label); font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.cuenta-tab:hover { color: var(--color-primary-600); }
.cuenta-tab.is-active { color: var(--color-primary-600); border-bottom-color: var(--color-primary-600); }
.cuenta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 var(--sp-4); }
.cuenta-logo-form { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
/* issue #187: un `input[type=file]` tiene ancho INTRINSECO (el del texto "Ningun archivo
   seleccionado" del navegador, ~365px) y no lo cede aunque su contenedor sea mas estrecho:
   desbordaba la pantalla de Cuenta por debajo de 390px. Medido a 320px: 394px de documento. */
.cuenta-logo-form input[type="file"] { max-width: 100%; }

/* ---- Crear desde plantilla (issue #3) ------------------------------------- */
.deca-create-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.deca-create-bar .segmented { margin-bottom: 0; }
.deca-from-template select { max-width: 320px; }

/* ============================================================================
   issue #22 Fase C — UX de campos/bloques del asistente de creacion
   ============================================================================ */

/* #2 Cabecera dinamica: icono de camion/autobus + badge persistente del modulo */
.deca-header { display: flex; align-items: flex-start; gap: var(--sp-3); }
.deca-type-icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: var(--r-md); color: var(--color-primary-700); background: var(--color-primary-100, #e7eef4); }
.deca-header--viajeros .deca-type-icon { color: var(--color-accent-700); background: var(--color-accent-100, #e3f1ed); }
.deca-header__text { min-width: 0; }
.deca-badge { display: inline-block; vertical-align: middle; margin-left: var(--sp-2); padding: 2px var(--sp-2); border-radius: var(--r-pill); font-size: var(--fs-caption); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; background: var(--color-primary-600); color: #fff; }
.deca-badge--viajeros { background: var(--color-accent-700); }

/* #1 Selector de tipo visual (tarjetas grandes con check de seleccion) */
.deca-typecards { border: 0; margin: 0 0 var(--sp-4); padding: 0; }
.deca-typecards__legend { font-size: var(--fs-label); font-weight: 600; color: var(--color-text-muted); margin-bottom: var(--sp-3); padding: 0; }
.deca-typecards__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.deca-typecard { position: relative; display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-4); border: 2px solid var(--color-border); border-radius: var(--r-md); background: var(--color-surface); text-decoration: none; color: var(--color-text); transition: border-color .12s, background .12s, box-shadow .12s; }
.deca-typecard:hover { border-color: var(--color-border-strong); }
.deca-typecard__icon { flex: none; display: inline-flex; color: var(--color-text-muted); }
.deca-typecard__title { display: block; font-weight: 700; }
.deca-typecard__desc { display: block; font-size: var(--fs-label); color: var(--color-text-muted); margin-top: 2px; }
.deca-typecard__check { position: absolute; top: var(--sp-3); right: var(--sp-3); opacity: 0; color: var(--color-accent-600); }
.deca-typecard.is-active { border-color: var(--color-accent-600); background: var(--color-accent-050, #eef7f4); box-shadow: 0 0 0 1px var(--color-accent-600); }
.deca-typecard.is-active .deca-typecard__icon { color: var(--color-accent-700); }
.deca-typecard.is-active .deca-typecard__check { opacity: 1; }
.deca-typecard--viajeros.is-active { border-color: var(--color-primary-600); background: var(--color-primary-050, #eef3f7); box-shadow: 0 0 0 1px var(--color-primary-600); }
.deca-typecard--viajeros.is-active .deca-typecard__icon,
.deca-typecard--viajeros.is-active .deca-typecard__check { color: var(--color-primary-600); }
/* issue #26 §13: marca «Principal» en la tarjeta del modulo principal cuando hay dos activos. */
.deca-typecard__flag { display: inline-block; margin-left: var(--sp-2); padding: 1px 8px; font-size: var(--fs-caption, .72rem); font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--color-accent-700); background: var(--color-accent-050, #eef7f4); border: 1px solid var(--color-accent-600); border-radius: 999px; vertical-align: middle; }
.deca-typecard--viajeros .deca-typecard__flag { color: var(--color-primary-600); background: var(--color-primary-050, #eef3f7); border-color: var(--color-primary-600); }
/* issue #26 §14: acciones del dashboard (CTA principal + secundario del otro modulo). */
.page-header__actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

/* #15 Barra de plantilla integrada en el flujo */
.deca-template-bar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-4); font-size: var(--fs-label); }
.deca-template-bar__label { font-weight: var(--fw-label); color: var(--color-text); }
.deca-template-bar__tag { font-weight: 600; color: var(--color-text-muted); }
.deca-template-bar__msg { color: var(--color-accent-700); }
.deca-template-bar .deca-from-template select { max-width: 320px; }

/* #16 Tarjeta compacta de la propia empresa (datos reales, badge «Tu empresa») */
.party--own { border-color: #d7e6df; gap: var(--sp-2); }
.party__head--own { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.party__own-icon { display: inline-flex; color: var(--color-accent-700); }
.party__role { font-size: var(--fs-label); font-weight: 600; text-transform: uppercase; letter-spacing: .02em; color: var(--color-accent-700); }
.party__badge { margin-left: auto; padding: 2px var(--sp-2); border-radius: var(--r-pill); font-size: var(--fs-caption); font-weight: 700; letter-spacing: .03em; text-transform: uppercase; background: var(--color-accent-100, #e3f1ed); color: var(--color-accent-700); }
.party__company { margin: 0; font-weight: 600; }
.party__nif { margin: 0; color: var(--color-text-muted); font-size: var(--fs-label); }
.party__auto-ok { margin: var(--sp-1) 0 0; display: flex; align-items: center; gap: var(--sp-1); color: var(--color-accent-700); font-size: var(--fs-label); }
.party__view { align-self: flex-start; font-size: var(--fs-label); color: var(--color-primary-600); text-decoration: none; font-weight: 500; }
.party__view:hover { text-decoration: underline; }
.party__dom { margin: 0; color: var(--color-text-muted); font-size: var(--fs-label); }

/* issue #26 §5 «Tu papel en este transporte»: radio que decide que slot ocupa la empresa */
.deca-roleself { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-3); margin-bottom: var(--sp-4); display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.deca-roleself__legend { font-size: var(--fs-label); font-weight: 600; text-transform: uppercase; letter-spacing: .02em; color: var(--color-text); padding: 0 var(--sp-1); }
.deca-roleself__opts { display: flex; gap: var(--sp-4); }
.deca-roleself__link { margin-left: auto; font-size: var(--fs-label); color: var(--color-primary-600); text-decoration: none; font-weight: 500; }
.deca-roleself__link:hover { text-decoration: underline; }

/* issue #26 §4/§6: cada slot lleva dos vistas (empresa propia / entrada); solo cambia el badge */
.party--roleslot .party__own-view { display: flex; flex-direction: column; gap: var(--sp-2); }
.party--roleslot .party__input-view { display: flex; flex-direction: column; gap: var(--sp-3); }
/* la guarda global [hidden]{display:none !important} (issue #36) cubre estos slots */
.party--t.party--roleslot .party__own-view .party__own-icon,
.party--t.party--roleslot .party__own-view .party__role { color: var(--color-accent-700); }
.party--c.party--roleslot .party__own-view .party__own-icon,
.party--c.party--roleslot .party__own-view .party__role { color: var(--color-primary-600); }

/* #14 Acciones por linea (duplicar + eliminar) */
.line-row__actions { display: flex; align-items: center; gap: var(--sp-1); }

/* #5 Buscador de direccion guardada (rellena los campos estructurados) */
/* issue #36 §1.6: mismo estilo que el resto de inputs (altura, borde, radio, fondo) + icono de busqueda. */
.combo-addr { position: relative; margin-bottom: var(--sp-3); }
.combo-addr__icon { position: absolute; left: var(--sp-3); top: 50%; transform: translateY(-50%); color: var(--color-text-muted); pointer-events: none; display: inline-flex; }
.combo-addr__input {
    width: 100%; box-sizing: border-box; font: inherit; color: var(--color-text);
    padding: var(--sp-2) var(--sp-3) var(--sp-2) 2.25rem;
    border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md);
    background: var(--color-surface);
}
.combo-addr__input::placeholder { color: var(--color-text-muted); }
.combo-addr__list { list-style: none; margin: 2px 0 0; padding: var(--sp-1); position: absolute; z-index: var(--z-dropdown); left: 0; right: 0; background: var(--color-surface); border: var(--bw-1) solid var(--color-border-strong); border-radius: var(--r-md); box-shadow: var(--sh-md); max-height: 200px; overflow-y: auto; }

/* #4 Casilla «guardar esta direccion en Maestros» */
.addr-group__save { margin-top: var(--sp-1); }

/* #12 Autorizacion especial: No aplica / Si */
.autoriz-field__opts { display: flex; gap: var(--sp-4); margin: var(--sp-1) 0; }
.radio-inline { display: inline-flex; align-items: center; gap: var(--sp-1); font-size: var(--fs-label); cursor: pointer; }
.autoriz-field__body { margin-top: var(--sp-1); }

/* #17 Validacion clicable: contador de pendientes + items-boton que saltan al campo */
.deca-rail__count { margin: 0 0 var(--sp-2); font-weight: 600; font-size: var(--fs-label); color: var(--color-danger, #b3261e); }
.checklist__link { background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px; }
.checklist__link:hover { text-decoration-style: solid; }

@media (max-width: 640px) {
    /* issue #187 (Jorge, 07/08/2026, punto 2): apiladas, las dos tarjetas de tipo quedaban con
       distinta ALTURA (102px vs 78px medidos) porque una lleva la insignia "Principal" y la otra
       no. Mismo ancho pero distinto alto se percibe como "una es mas grande que la otra". En una
       sola columna cada tarjeta ocupa su propia fila, asi que igualarlas exige filas iguales
       (`grid-auto-rows`), no `align-items`. */
    .deca-typecards__grid { grid-template-columns: 1fr; grid-auto-rows: 1fr; }
}

/* ---- Usabilidad de maestros (issue #3) ------------------------------------ */
.entity-tab__count { margin-left: auto; font-size: var(--fs-caption); color: var(--color-text-subtle); }
.maestros__toolbar-actions { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-left: auto; }
/* issue #187 punto 3 (segunda ronda, captura real de Jorge — Samsung S22+/iPhone/Galaxy Fold):
   «Importar Excel» salia mas ANCHO que «Exportar CSV» en la misma fila, y «Importar CSV» —que
   deberia compartir columna con «Importar Excel»— salia mas ESTRECHO todavia: la prueba de que
   NO eran celdas de un mismo grid/fila, aunque el CSS lo diera por hecho. Causa identica a la del
   punto 2: `.maestros__import-form` competia como su PROPIA caja de flex/grid (con
   `display:flex` mas su boton de dentro al `width:100%`), calculando una base de tamano distinta
   a la de un `<a class="btn">` suelto con la MISMA regla de reparto. `display:contents` saca el
   formulario de la caja: su `<label class="btn">` pasa a ser un item de grid/flex MAS del grupo,
   con la misma regla que sus hermanos. */
.maestros__import-form { display: contents; }
.maestros__import-label { cursor: pointer; }
/* Movil y tablet (issue #24, ampliado a 768px en la 3.ª ronda del #187 — ver el porque en el
   comentario junto a `.maestros__toolbar-actions .btn` mas abajo): los botones de accion
   comparten fila solo si caben 140px cada uno; si no, se apilan. La rejilla (`grid`, no `flex`)
   es deliberada: sus columnas `1fr` son iguales SIEMPRE, con independencia del contenido de cada
   celda — un `<a class="btn">` suelto y un `<label class="btn">` envuelto en `.maestros__import-form`
   (con `display:contents`, arriba) ocupan la MISMA columna sin que la longitud del texto de
   ninguno de los dos la desequilibre. La accion principal ocupa siempre el ancho completo. */
@media (max-width: 768px) {
    .maestros__toolbar-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
    /* Combinador `>` A PROPOSITO (hallazgo del gate de revision, verificado que NO es un bug):
       esta regla solo debe alcanzar a un `.btn--accent` que sea hijo DIRECTO —«Descargar
       plantilla Excel» y «Nuevo vehiculo», ambos `<a>` sueltos—, nunca al `<label class="btn
       btn--accent">` de dentro de `.maestros__import-form`. Aunque los dos comparten el mismo
       color de acento, el layout que pide Jorge (issue #187, captura del punto 3) es que
       «Importar Excel» comparta fila con «Exportar CSV», NO que ocupe el ancho completo. Ampliar
       el selector para que tambien alcance al formulario (p. ej. con `.maestros__import-form >
       .btn--accent`) romperia ese layout pedido. */
    .maestros__toolbar-actions > .btn--accent { grid-column: 1 / -1; }
}
.maestros__import-errors { margin: var(--sp-2) 0 0; padding-left: var(--sp-5); }
/* Cupo del plan (issue #58 F4): el contador vive bajo la barra de acciones y solo se tine de
   aviso cuando el cupo esta agotado o el plan no incluye la entidad — los mismos dos estados en
   los que el backend bloquea el alta. El motivo del CSV bloqueado va debajo, y es el texto al que
   apuntan por aria-describedby los botones deshabilitados. */
.maestros__quota { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-2); margin: 0 0 var(--sp-3); font-size: var(--fs-caption); color: var(--color-text-muted); }
.maestros__quota-count { font-weight: 600; }
/* Sin hex de reserva a mano: el token vive en tokens.css y es la unica fuente del color. */
.maestros__quota--reached, .maestros__quota--none { color: var(--color-warning); }
.maestros__csv-locked { margin: 0 0 var(--sp-3); }
.badge--incompleto { background: var(--color-warning-bg, #fdf3e3); color: var(--color-warning, #9a6b00); border: var(--bw-1) solid currentColor; margin-left: var(--sp-2); }
.icon-btn.is-fav { color: #d99a00; }
.maestros__more { margin: var(--sp-2) 0; }
.maestros__more > summary { cursor: pointer; font-size: var(--fs-label); color: var(--color-text-muted); margin-bottom: var(--sp-2); }

/* ---- Bloques de parte de la Plantilla DeCA (issue #123) -------------------- */
.maestros__rol-block { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-4); margin: var(--sp-3) 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.maestros__rol-block legend { padding: 0 var(--sp-2); font-weight: var(--fw-label); font-size: var(--fs-label); }
.maestros__mi-empresa { background: var(--color-surface-2); border-radius: var(--r-sm); padding: var(--sp-3); }
.maestros__mi-empresa p { margin: 0 0 var(--sp-1); }
.maestros__mi-empresa p:last-child { margin-bottom: 0; }

/* ---- 2FA del tenant (issue #4) --------------------------------------------- */
.cuenta-qr { width: 180px; margin: var(--sp-3) 0; }
.cuenta-qr svg { width: 100%; height: auto; }
.auth-sub { color: var(--color-text-muted); margin: 0 0 var(--sp-4); }

/* ============================================================================
   Endurecimiento responsive (feedback del cliente, 02/07/2026): controles a
   16px en movil (iOS Safari hace zoom al enfocar fuentes menores y la pantalla
   queda "descuadrada"), topbar compacta, tarjetas y bloques a una columna.
   ============================================================================ */
@media (max-width: 768px) {
    /* Sin zoom automatico de iOS al enfocar campos. */
    input, select, textarea,
    .combo__trigger, .combo__search, .combo-inline__input { font-size: 16px; }

    .app-main { padding: var(--sp-4); }
    .card { padding: var(--sp-4); }
    .data-table th, .data-table td { padding: var(--sp-2) var(--sp-3); }

    /* Detalle: QR centrado arriba (spec detalle-deca, breakpoint <=768). */
    .deca-qr { flex-direction: column; text-align: center; }
    .deca-qr__body { width: 100%; }
    .detail-facts { gap: var(--sp-3) var(--sp-5); }
}

@media (max-width: 480px) {
    .topbar { padding: 0 var(--sp-3); gap: var(--sp-2); }
    .topbar__right { gap: var(--sp-2); }
    .lang-switch > svg { display: none; }
    .topbar__search { min-width: 0; }

    .app-main { padding: var(--sp-4) var(--sp-3); }

    /* Acciones del detalle apiladas y a ancho completo. El `display:contents` de
       `.deca-detail-actions .inline-form` (issue #187 punto 2) vive ahora SIN media query, junto
       a la regla base de `.deca-detail-actions` — ver el comentario de ahi arriba. */
    .deca-detail-actions { width: 100%; }
    .deca-detail-actions .btn { flex: 1 1 auto; }

    .deca-banner { flex-direction: column; align-items: flex-start; }
    .deca-qr__url { flex-direction: column; }
    .deca-create-bar { flex-direction: column; align-items: stretch; }
    .deca-from-template select { max-width: none; width: 100%; }
    .home-quota-facts { gap: var(--sp-3) var(--sp-4); }

    /* Panel en movil (issue #11): accesos rapidos apilados y cabecera sin desbordes. */
    /* issue #187 punto 1: a una sola columna, los cinco accesos rapidos se comian la pantalla
       antes de llegar a avisos, borradores y ultimos documentos. Dos columnas, con `minmax(0,1fr)`
       para que un rotulo largo no empuje el ancho de la columna. */
    .home-quick-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; }
    .page-header--actions { flex-wrap: wrap; gap: var(--sp-3); }
    .cell-clip { max-width: 140px; }
}

/* ============================================================================
   REDISEÑO VISUAL — Fase 1 (issue #20)
   Sistema común: banners, foco de formularios, elevación de tarjetas clicables
   y micro-ajustes de acento. Se apoya en los tokens de la paleta nueva.
   ============================================================================ */

/* ---- Banner / aviso común (info · success · warning · error) ---- */
.banner {
    display: flex; align-items: flex-start; gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border: var(--bw-1) solid; border-radius: var(--r-xl);
    background: var(--color-surface);
    font-size: var(--fs-label); line-height: var(--lh-body);
    margin-bottom: var(--sp-4);
}
.banner__icon { flex: none; margin-top: 1px; display: inline-flex; }
.banner__body { flex: 1; min-width: 0; }
.banner__title { margin: 0 0 2px; font-weight: 600; color: var(--color-text); }
.banner__text { margin: 0; color: var(--color-text-muted); }
.banner__cta { margin-top: var(--sp-2); }
.banner__action { flex: none; align-self: center; text-decoration: none; }

/* issue #26 §1: tarjetas de perfil operativo en el registro (radio-cards seleccionables) */
.perfil-cards { border: 0; padding: 0; margin: 0 0 var(--sp-3); display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
.perfil-cards__legend { padding: 0; margin-bottom: var(--sp-2); font-weight: 600; color: var(--color-text); }
.perfil-cards.is-error { outline: var(--bw-1) solid var(--color-danger); outline-offset: var(--sp-2); border-radius: var(--r-md); }
.perfil-card { position: relative; display: flex; align-items: flex-start; gap: var(--sp-2); padding: var(--sp-3); border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); cursor: pointer; background: var(--color-surface); }
.perfil-card__input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.perfil-card__icon { flex: none; display: inline-flex; color: var(--color-primary-600); }
.perfil-card__body { flex: 1; min-width: 0; }
.perfil-card__title { display: block; font-weight: 600; color: var(--color-text); }
.perfil-card__desc { display: block; margin-top: 2px; font-size: var(--fs-caption); color: var(--color-text-muted); }
.perfil-card__check { flex: none; display: inline-flex; color: var(--color-primary-600); opacity: 0; }
.perfil-card:hover { border-color: var(--color-primary-300, #a9c4dd); }
.perfil-card__input:checked ~ .perfil-card__check { opacity: 1; }
.perfil-card:has(.perfil-card__input:checked) { border-color: var(--color-primary-600); background: var(--color-info-bg); box-shadow: var(--sh-focus, 0 0 0 3px rgba(20,58,82,.12)); }
.perfil-card__input:focus-visible ~ .perfil-card__check { opacity: 1; }
.perfil-card:focus-within { border-color: var(--color-primary-600); }
@media (max-width: 560px) { .perfil-cards { grid-template-columns: 1fr; } }

/* issue #26 §9: bloques de Cuenta -> Actividad (Perfil operativo / Operativa) */
.cuenta-block { border: var(--bw-1) solid var(--color-border); border-radius: var(--r-md); padding: var(--sp-4); margin: 0 0 var(--sp-4); }
.cuenta-block__legend { padding: 0 var(--sp-1); font-size: var(--fs-label); font-weight: 600; text-transform: uppercase; letter-spacing: .02em; color: var(--color-text); }
.banner--info    { background: var(--color-info-bg);    border-color: var(--color-primary-100); }
.banner--info    .banner__icon { color: var(--color-info); }
.banner--success { background: var(--color-success-bg); border-color: #b9e6d9; }
.banner--success .banner__icon { color: var(--color-success); }
.banner--warning { background: var(--color-warning-bg); border-color: #f0dcae; }
.banner--warning .banner__icon { color: var(--color-warning); }
.banner--error   { background: var(--color-danger-bg);  border-color: #f3c6bd; }
.banner--error   .banner__icon { color: var(--color-danger); }

/* ---- Foco de formularios (issue #20): borde azul + halo suave, sin outline duro ---- */
.form-field input:focus, .form-field select:focus, .form-field textarea:focus,
.deca-form input:focus, .deca-form select:focus, .deca-form textarea:focus,
.input:focus, .combo__trigger:focus, .field-search input:focus {
    outline: none; border-color: var(--color-primary-500); box-shadow: var(--sh-focus);
}

/* ---- Tarjetas clicables: ligera elevación + borde azul en hover ---- */
.home-quick-card { transition: transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease); }
.home-quick-card:hover {
    transform: translateY(-2px); box-shadow: var(--sh-lg);
    border-color: var(--color-primary-500); color: var(--color-primary-600);
}

/* ---- Micro-ajustes de acento sobre la paleta nueva ---- */
.tag--t { background: var(--color-accent-700); }  /* AA con la etiqueta blanca */
.quota-bar__fill { background: var(--color-accent-600); }

/* ============================================================================
   Paginas legales (issue #25): ancho de lectura limitado, jerarquia clara,
   responsive sin scroll horizontal en movil. Identidad de Plataforma DeCA.
   ============================================================================ */
.legal-body {
    margin: 0; min-height: 100vh; display: flex; flex-direction: column;
    background: var(--color-bg); color: var(--color-text);
    font-family: var(--font-sans); font-size: var(--fs-body-lg); line-height: var(--lh-body-lg);
}
.legal-top {
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
    padding: var(--sp-4) var(--sp-6);
    background: var(--color-surface); border-bottom: var(--bw-1) solid var(--color-border);
}
.legal-top__brand { display: inline-flex; align-items: center; }
.legal-top__brand img { display: block; height: 28px; width: auto; }
.legal-top__lang select {
    font: inherit; font-size: var(--fs-label); color: var(--color-text);
    padding: var(--sp-1) var(--sp-3); border: var(--bw-1) solid var(--color-border-strong);
    border-radius: var(--r-md); background: var(--color-surface);
}

.legal-wrap {
    width: 100%; max-width: 760px; margin: 0 auto; flex: 1 0 auto;
    padding: var(--sp-8) var(--sp-6) var(--sp-9);
    box-sizing: border-box;
}
.legal { color: var(--color-text); }
.legal__head { padding-bottom: var(--sp-5); margin-bottom: var(--sp-6); border-bottom: var(--bw-1) solid var(--color-border); }
.legal__title { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: var(--fw-display); color: var(--color-primary-700); margin: 0 0 var(--sp-2); }
.legal__subtitle { font-size: var(--fs-body-lg); color: var(--color-text-muted); margin: 0 0 var(--sp-3); }
.legal__meta { font-size: var(--fs-caption); color: var(--color-text-subtle); margin: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.legal__meta-sep { color: var(--color-border-strong); }

.legal__section { margin: 0 0 var(--sp-7); }
.legal__section h2 {
    font-size: var(--fs-h1); line-height: var(--lh-h1); font-weight: var(--fw-h1);
    color: var(--color-primary-700); margin: 0 0 var(--sp-3); scroll-margin-top: var(--sp-6);
}
.legal__section h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: var(--fw-h3); color: var(--color-text); margin: var(--sp-4) 0 var(--sp-2); }
.legal__section p { margin: 0 0 var(--sp-3); }
.legal__section ul { margin: 0 0 var(--sp-3); padding-left: var(--sp-5); }
.legal__section li { margin: 0 0 var(--sp-2); }
.legal__section a { color: var(--color-primary-600); text-decoration: underline; word-break: break-word; }
.legal__section a:hover { color: var(--color-primary-700); }

.legal-callout {
    background: var(--color-primary-050); border: var(--bw-1) solid var(--color-primary-100);
    border-left: 3px solid var(--color-primary-500); border-radius: var(--r-lg);
    padding: var(--sp-4); margin: 0 0 var(--sp-6); font-size: var(--fs-body); line-height: var(--lh-body);
}

.legal-table-scroll { overflow-x: auto; margin: 0 0 var(--sp-3); }
.legal-table { width: 100%; border-collapse: collapse; margin: 0 0 var(--sp-3); font-size: var(--fs-body); line-height: var(--lh-body); }
.legal-table th, .legal-table td { text-align: left; vertical-align: top; padding: var(--sp-2) var(--sp-3); border: var(--bw-1) solid var(--color-border); }
.legal-table th[scope="row"] { width: 34%; background: var(--color-surface-2); color: var(--color-text); font-weight: var(--fw-medium); }
.legal-table thead th { background: var(--color-surface-2); color: var(--color-primary-700); font-weight: var(--fw-semibold); }
.legal-table--cols td { width: auto; }

.legal-foot {
    margin-top: var(--sp-8); padding-top: var(--sp-5);
    border-top: var(--bw-1) solid var(--color-border); text-align: center;
}
.legal-foot__links { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: var(--sp-2) var(--sp-3); }
.legal-foot__links a { color: var(--color-text-muted); text-decoration: none; font-size: var(--fs-label); }
.legal-foot__links a:hover { color: var(--color-primary-600); text-decoration: underline; }
.legal-foot__sep { color: var(--color-border-strong); }
.legal-foot__copy { margin: var(--sp-3) 0 0; font-size: var(--fs-caption); color: var(--color-text-subtle); }

@media (max-width: 768px) {
    .legal-top { padding: var(--sp-3) var(--sp-4); }
    .legal-wrap { padding: var(--sp-6) var(--sp-4) var(--sp-8); }
    .legal__title { font-size: var(--fs-h1); line-height: var(--lh-h1); }
    .legal__section h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); }
    .legal-table th[scope="row"] { width: 40%; }
}

/* Cuenta > Legal (issue #25 §8): listado de documentos legales. */
.cuenta-legal__intro { margin: 0 0 var(--sp-4); color: var(--color-text-muted); }
.cuenta-legal { list-style: none; margin: 0; padding: 0; }
.cuenta-legal__item {
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
    padding: var(--sp-4) 0; border-top: var(--bw-1) solid var(--color-border);
}
.cuenta-legal__item:first-child { border-top: 0; }
.cuenta-legal__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cuenta-legal__name { font-weight: var(--fw-medium); color: var(--color-text); }
.cuenta-legal__desc { font-size: var(--fs-label); color: var(--color-text-muted); }
.cuenta-legal__link { flex: 0 0 auto; white-space: nowrap; }

@media (max-width: 480px) {
    .cuenta-legal__item { flex-direction: column; align-items: stretch; }
    .cuenta-legal__link { text-align: center; }
}

/* --- Bloqueo preventivo sin plan activo (issue #39, feedback 16/07) --- */
.deca-blocked { max-width: 560px; }
.deca-blocked__msg { margin: 0 0 var(--sp-2); font-size: var(--fs-body-lg); font-weight: 600; }
.deca-blocked__hint { margin: 0 0 var(--sp-4); color: var(--color-text-muted); }
.deca-blocked__actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.maestros__blocked-msg { margin: 0 0 var(--sp-2); font-weight: 600; }
.maestros__form--blocked .btn { margin-top: var(--sp-2); }

/* --- Tarjeta de suscripcion del cliente: los seis campos del §6.2 (issue #48 F9) --- */
/* Rejilla etiqueta/valor en dos columnas, que colapsa a una sola en movil. Es un `<dl>` y no una
   tabla porque son pares campo-valor de UN registro, no filas comparables — y el lector de pantalla
   los anuncia emparejados sin marcado extra. */
.sub-facts { display: grid; grid-template-columns: max-content 1fr; gap: var(--sp-2) var(--sp-4); margin: 0 0 var(--sp-4); }
.sub-facts dt { color: var(--color-text-muted); font-size: var(--fs-body-sm); }
.sub-facts dd { margin: 0; }
@media (max-width: 560px) {
    .sub-facts { grid-template-columns: 1fr; gap: var(--sp-1) 0; }
    .sub-facts dd { margin: 0 0 var(--sp-2); }
}


/* ==========================================================================
   PATRONES RESPONSIVE (issue #187) — AL FINAL DEL FICHERO A PROPOSITO

   Estos tres patrones existen para PISAR el layout de escritorio de los
   componentes en movil. Una media query NO anade especificidad: `.deca-filters`
   y `.filters--stack` valen exactamente lo mismo, asi que gana quien se declara
   DESPUES. Escritos donde estaban (linea ~450, ANTES de los componentes),
   `.deca-toolbar { align-items: center }` y `.deca-filters { align-items: center }`
   los sobrescribian: al apilarse en columna ese `center` pasa a centrar en
   HORIZONTAL, y dejaba la barra de filtros de Documentos en 203px centrados
   dentro de 390px — exactamente el defecto que Jorge reporto (comentario del
   07/08/2026 en el #187, punto 3).

   Regla para patrones responsive nuevos: van AQUI, al final. No se arregla con
   `!important` ni inflando selectores; se arregla con el orden.
   ========================================================================== */

/* ---- Tabla -> tarjeta en movil (opt-in via `.data-table--cards`) ----
   Tecnica CSS pura sobre el MISMO <table>: no hay markup duplicado que pueda
   divergir del original (regla del proyecto contra casi-duplicados), ni doble
   verificacion i18n. Cada <td> necesita su `data-label="..."` (la misma cadena
   que ya lleva el <th> de su columna) para que `content: attr(data-label)`
   pinte la etiqueta — por eso es opt-in por tabla y no automatico para TODAS
   las `.data-table`: aplicarlo sin los atributos dejaria tarjetas con
   etiquetas vacias, peor que el scroll horizontal que sustituye. */
@media (max-width: 768px) {
    .data-table--cards, .data-table--cards tbody, .data-table--cards tr { display: block; }
    .data-table--cards thead { display: none; }
    .data-table--cards tr {
        margin-bottom: var(--sp-3); padding: var(--sp-2) var(--sp-4);
        border: var(--bw-1) solid var(--color-border); border-radius: var(--r-lg);
        background: var(--color-surface);
    }
    .data-table--cards tr:last-child { margin-bottom: 0; }
    .data-table--cards td {
        display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3);
        padding: var(--sp-2) 0; border-bottom: var(--bw-1) solid var(--color-border);
        text-align: right; white-space: normal;
        /* Una celda con varias piezas (estado + badge "Datos incompletos", importe + aviso) no
           cabe en linea a 320px: envuelve en vez de rebasar el ancho de la tarjeta. */
        flex-wrap: wrap;
    }
    .data-table--cards td:last-child { border-bottom: none; }
    .data-table--cards td::before {
        content: attr(data-label); flex: none; font-weight: var(--fw-label);
        color: var(--color-text-muted); text-align: left; padding-right: var(--sp-3);
    }
    /* Celda sin dato util en movil (icono/columna redundante): se retira entera con
       `data-label=""` en vez de dejar una etiqueta vacia. */
    .data-table--cards td[data-label=""] { display: none; }
    /* Los iconos de accion se alinean a la izquierda junto a su etiqueta "Acciones:" (mockup
       del propio issue), no a la derecha como en la columna de una tabla de escritorio.
       `.cell-actions` es el nombre que usa la misma columna en Suscripcion y pagos. */
    .data-table--cards .col-actions,
    .data-table--cards .cell-actions { text-align: left; }
    /* Varias acciones por fila (tarjetas de pago: principal/cambiar/eliminar) no caben en linea
       a 320px: envuelven y comparten ancho en vez de desbordar. */
    .data-table--cards .cell-actions { flex-wrap: wrap; }
    /* issue #187 punto 1 (segunda ronda, feedback con captura real de Jorge en Samsung S22+):
       `.data-table--cards td` reparte sus hijos con `justify-content: space-between` (pensado
       para una celda etiqueta+valor), pero `.cell-actions` tiene VARIOS botones, no un par. Con
       3 botones que envuelven, space-between fija el primero a la izquierda y el segundo al
       extremo derecho de esa linea (hueco enorme entre ambos) y el tercero cae solo a la
       siguiente linea — exactamente lo que muestra la captura: "Cambiar" desplazado y "Eliminar"
       en su propia fila. Se agrupan pegados en vez de repartirse por el ancho. */
    .data-table--cards .cell-actions { justify-content: flex-start; gap: var(--sp-2); }
    /* El margen individual de cada formulario (regla de escritorio, `.cell-actions .inline-form`
       mas arriba en el fichero) se suma al `gap` del flex de arriba: doble espaciado. En movil
       el espaciado lo da solo el `gap`. */
    .data-table--cards .cell-actions .inline-form { margin-left: 0; }
    /* Fila de continuacion (`.line-sub` del detalle de DeCA: dato propio de una linea que la
       amplia, con `colspan`). Como tarjeta suelta se leeria como un registro mas, que es
       justo lo contrario de lo que significa: se pega a la tarjeta anterior sin separacion
       ni borde superior, para que se vea como parte de ella. */
    .data-table--cards tr.line-sub {
        margin-top: calc(var(--sp-3) * -1); border-top: none;
        border-top-left-radius: 0; border-top-right-radius: 0;
    }
    /* Su contenido SI se ve (amplia la linea de arriba), pero sin etiqueta propia: no es una
       columna, es una nota. Por eso `::before` fuera aqui y no `data-label=""`, que ocultaria
       la celda entera. */
    .data-table--cards tr.line-sub td { text-align: left; }
    .data-table--cards tr.line-sub td::before { display: none; }
}

/* ---- Grupo de dos botones equilibrados ----
   Generaliza el patron que ya usaba `.deca-detail-actions` en movil: mismo ancho,
   misma altura, en fila si caben, apilados si no. Caso explicito de Jorge: "Crear
   DeCA de mercancias"/"Crear DeCA de viajeros" en el Panel de control.

   Hallazgo del gate de revision del #187 (segunda ronda): antes de este ajuste, un
   `.inline-form` aqui dentro habria caido en la MISMA caja de flex anidada (`flex:1 1 200px` en
   el formulario + `width:100%` en el boton de dentro) que causo los puntos 2 y 3 del issue —
   hoy `.btn-group--split` solo envuelve `<a class="btn">` sueltos (`views/home.php`,
   `views/deca/index.php`), asi que la trampa estaba dormida, pero el propio comentario de arriba
   invita a reutilizar este patron en mas pantallas. Se aplica aqui el mismo `display:contents`
   por adelantado, para que la trampa no pueda activarse el dia que alguien envuelva un boton de
   este grupo en un formulario. */
.btn-group--split { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.btn-group--split > .btn,
.btn-group--split .inline-form > .btn { flex: 1 1 200px; }
.btn-group--split > .inline-form { display: contents; }
@media (max-width: 480px) {
    .btn-group--split > .btn,
    .btn-group--split .inline-form > .btn { flex-basis: 100%; }
}

/* ---- Filtros apilados en movil ----
   Generaliza el patron ya usado en `.maestros__filters` (app.css:532-536): en
   movil cada control de un bloque de filtros pasa a ancho completo. Opt-in via
   `.filters--stack` para no cambiar bloques de filtros ya resueltos de otra forma. */
@media (max-width: 768px) {
    .filters--stack { flex-direction: column; align-items: stretch; }
    .filters--stack > * { width: 100%; }
    /* La barra que CONTIENE los filtros tambien se apila: si no, los controles heredan el ancho
       estrecho que les deja el resto de la fila y se quedan encogidos contra un borde. */
    .deca-toolbar { flex-direction: column; align-items: stretch; }
    /* Un identificador, email o URL larga no puede empujar el ancho de la tarjeta. */
    .data-table--cards td { overflow-wrap: anywhere; }
    /* Sin esto, un boton corto de la celda de acciones se reparte el ancho sobrante y acaba con
       una letra por linea. Conservan su tamano y envuelven. */
    .data-table--cards .col-actions > *,
    .data-table--cards .cell-actions > * { flex: none; max-width: 100%; }
    /* Una tabla ya convertida en tarjetas no necesita el scroll horizontal de su envoltorio: sin
       esto queda una barra de desplazamiento interna que no desplaza nada. Se apaga SOLO donde
       hay tarjetas (`:has`), para no tocar las tablas que aun lo necesitan. */
    .table-wrap:has(.data-table--cards) { overflow-x: visible; }
}

/* ---- Aire vertical antes de un boton en movil (issue #187, feedback de Jorge del 07/08/2026,
   punto 1) ----
   Jorge lo reporto en cinco pantallas distintas (Cuenta/Datos, Logo, Seguridad, Configuracion de
   emision, Panel de control) y pidio expresamente resolverlo "como patron global de espaciado en
   movil y no solo caso por caso". Medido: en Cuenta/Datos y en Seguridad el hueco entre el ultimo
   campo y su boton era de CERO pixeles.

   Por que solo en movil: en escritorio el boton queda a la derecha o en una fila propia y se lee
   como accion; apilado en columna, un boton pegado al campo de arriba parece parte de ese campo
   —y ademas se pulsa por error al ir a tocar el campo, que en una pantalla tactil no es un detalle
   estetico—.

   `* + .btn` (hermano ANTERIOR cualquiera) es deliberado: la regla es "un boton que viene DESPUES
   de algo necesita aire", no "este boton concreto de esta pantalla". Se acota a hijos directos de
   `form`/`.card` para no tocar los grupos de accion (`.btn-group--split`, celdas de acciones de
   las tarjetas, barras de herramientas), que ya reparten su propio `gap`.

   Todo va acotado a `main`: la primera version no lo estaba y empujo 20px hacia abajo el boton de
   buscar de la barra superior, el de cambiar idioma y el de cerrar sesion de la barra lateral, que
   son botones dentro de un `form` como cualquier otro. Un patron de espaciado de CONTENIDO no
   tiene nada que decir sobre la navegacion.

   CUARTA RONDA (09/08/2026) — el `:not(...)` de abajo es el arreglo de los puntos 2 y 3, y su causa
   raiz estaba AQUI, no en el flex ni en el grid de aquellos dos bloques. El parrafo de arriba dice
   que el patron "se acota a hijos directos de `form`/`.card` para no tocar los grupos de accion",
   pero esa exclusion nunca se escribio: `main form > * + .btn` alcanza a CUALQUIER boton dentro de
   CUALQUIER formulario de `main`, incluidos los formularios-envoltorio que existen solo para colgar
   el `method`/`action` de un boton que visualmente es un boton mas de su grupo. En esos, el hermano
   anterior del boton es el campo CSRF: `* + .btn` casa, y el boton se lleva 20px de margen superior
   que sus companeros de fila no tienen.
   Medido en Chrome sobre este mismo CSS (iframe a 390px): «Duplicar DeCA» a y=215 con Modificar y
   Anular a y=195 —20px exactos—, con el formulario en `display:contents` correcto y su caja medida
   a 0x0; el margen estaba en el BOTON (`margin: 20px 0px 0px`). Lo mismo en Maestros a 360px:
   «Importar Excel» a y=520 contra «Exportar CSV» —un `<a class="btn">` suelto, sin formulario que lo
   envuelva— a y=510.
   Por eso tres rondas de ajustes sobre el reparto HORIZONTAL no movieron nada: el reparto ya estaba
   bien y el desajuste era VERTICAL, heredado del punto 1 de este mismo issue.
   La exclusion se escribe por las dos clases que marcan esos envoltorios, que es lo que son
   estructuralmente: un formulario con una de esas clases nunca es contenido apilado, es el
   envoltorio de un boton de un grupo que ya reparte su propio `gap`. Un envoltorio nuevo debe
   llevar `.inline-form` para quedar cubierto — el caso 78 de la suite lo guarda. */
@media (max-width: 768px) {
    main form:not(.inline-form, .maestros__import-form) > * + .btn,
    main form:not(.inline-form, .maestros__import-form) > * + button[type="submit"],
    main .card > * + .btn,
    main .card > * + form,
    main .card > * + .inline-form { margin-top: var(--sp-5); }
    /* Dos botones consecutivos (el caso "Subir logo" / "Quitar logo"): sin esto el segundo se
       pega al primero y los dos se leen como un unico bloque pulsable. */
    main .card > .btn + .btn,
    main form:not(.inline-form, .maestros__import-form) > .btn + .btn,
    main .card > form + form { margin-top: var(--sp-3); }
}

/* ---- Tarjetas movil: contraste con el contenedor y titulo de la ficha ----
   (issue #187, feedback de Jorge del 07/08/2026, puntos 4 y 5) */
@media (max-width: 768px) {
    /* PUNTO 4 — "blanco sobre blanco". Medido en Documentos, Maestros y el Panel de control: la
       tarjeta de cada registro es #ffffff y el contenedor que las agrupa TAMBIEN es #ffffff, con
       un borde de 1px como unica separacion y sin sombra. Jorge dio dos opciones; se toma la SUYA
       primera (A): un listado que ya se ha convertido en fichas no necesita ademas una ficha que
       lo envuelva. Al quitarle la superficie al contenedor, asoma el fondo de pagina (#f5f8fc) y
       cada registro se recorta contra el sin inventar ningun recurso visual nuevo — ni sombras ni
       bordes mas duros, que era su reparo explicito. Se conserva el padding para que las fichas no
       queden pegadas al borde de la pantalla.

       El gate de revision hizo notar que la regla, al ser generica, tambien alcanza a Cuenta →
       Usuarios, Suscripcion y pagos y Soporte, que Jorge no probo. Se comprobaron las tres en el
       playground con datos sembrados ANTES de darla por buena: en las tres el resultado es el
       mismo que en las que si reporto —el titulo y sus controles quedan sobre el fondo de pagina y
       cada registro se recorta limpiamente—, incluidas las dos que mezclan titulo, boton y listado
       en la misma tarjeta, que era el caso que preocupaba. */
    .card:has(.data-table--cards) {
        background: transparent;
        border-color: transparent;
        box-shadow: none;
    }

    /* PUNTO 5 — jerarquia del titulo del trayecto. En la ficha de un DeCA, la tabla de lineas daba
       «# 1» y justo debajo «Trayecto: Calle...», con lo que «Trayecto» se leia como un dato mas de
       la ficha y no como su titulo. Se fusionan las dos celdas en el encabezado «Trayecto 1» con
       la ruta debajo — la opcion 1 de las dos que propuso Jorge. Es solo presentacion: la tabla de
       escritorio conserva sus columnas «#» y «Trayecto» intactas. */
    .data-table--cards td.line-num {
        justify-content: flex-start; gap: var(--sp-1);
        text-align: left; font-family: inherit; font-weight: 700; font-size: var(--fs-h3, 1.05rem);
        border-bottom: none; padding-bottom: 0;
    }
    .data-table--cards td.line-num::before {
        content: attr(data-title); font-weight: 700; font-size: inherit;
        color: var(--color-text); padding-right: 0;
    }
    /* La ruta pasa a ser el contenido de ese titulo: sin etiqueta propia y alineada a la izquierda,
       porque repetir «Trayecto:» justo debajo de «Trayecto 1» es exactamente el ruido que el punto
       5 pide quitar. */
    .data-table--cards td.line-route { text-align: left; }
    .data-table--cards td.line-route::before { display: none; }
}

/* ---- Segunda ronda de ajustes de Jorge en movil (issue #187, comentario del 08/08/2026) ----
   Va al final del fichero por la misma razon que los patrones: pisa layout de componentes, y una
   media query no anade especificidad. */
@media (max-width: 768px) {
    /* PUNTO 6 — el selector de idioma se pisaba con el logotipo. Medido a 390px: el logo ocupa
       x=70..321 (centrado, 251px) y el selector, anclado a la esquina, x=281..370 — 40px de
       solape real, no una impresion. En movil el selector sale de la esquina absoluta y pasa al
       flujo, alineado a la derecha ANTES del logo: asi no hay nada que pueda solaparse, en vez de
       ajustar margenes a ojo y esperar que ningun idioma vuelva a chocar. */
    .auth-lang { position: static; align-self: flex-end; }

    /* PUNTO 2 — tarjetas de actividad del registro con distinta altura. Medido: iguales a 360-390px
       pero 108/108/108/88 a 320px y 88/88/88/68 a 414-430px, porque la descripcion de la ultima
       opcion ocupa menos lineas. Filas iguales, no `min-height` a ojo: asi se adaptan al idioma
       —en euskara o ingles los textos rompen en otros anchos— sin numeros magicos. */
    .perfil-cards { grid-auto-rows: 1fr; }

    /* PUNTO 3 — acciones del detalle de un DeCA con alturas desiguales. Medido: 46/46/66/66/46/46.
       Los de 66px son los que viven dentro de un `.inline-form` (Modificar, Anular): el formulario
       se estiraba a la altura de la fila y el boton con el. Se igualan por el contenedor, con los
       botones centrando su texto, en vez de fijar una altura que se rompa al traducir. */
    .deca-detail-actions .btn,
    .deca-detail-actions .inline-form .btn {
        display: inline-flex; align-items: center; justify-content: center; min-height: 46px;
    }

    /* PUNTO 3 (continuacion) — no se estira: al forzar `stretch` + `height:100%` el desajuste
       simplemente se mudaba al boton que quedaba solo en su fila (medido: «Duplicar DeCA» pasaba de
       46 a 66px). Cada boton conserva su altura minima y el grupo no impone la de la fila. */
    .deca-detail-actions { align-items: flex-start; }

    /* PUNTO 7.2 — la tarjeta de trayecto se veia mas estrecha que Trazabilidad. Medido: la tabla
       quedaba en 332px arrancando en x=29, mientras las demas tarjetas son 366px en x=12. Lo causo
       el propio arreglo del punto 4 de la ronda anterior: al contenedor se le quito la superficie
       pero se le dejo el padding, asi que las fichas de dentro quedaban metidas hacia adentro. Sin
       superficie el padding ya no separa nada de nada — solo desalinea. */
    .card:has(.data-table--cards) { padding-left: 0; padding-right: 0; }

    /* PUNTO 7.1 — carga y descarga se leen como dos datos mas de la ficha, con su etiqueta a la
       izquierda y su valor a la derecha, igual que Naturaleza o Peso; ya no como un bloque cosido
       al final. El separador « · » de escritorio se apaga aqui: sobra cuando cada dato tiene su
       propia linea. */
    /* La celda con dato pasa a bloque para que cada complemento sea su propia fila; la celda VACIA
       (la del `data-label=""` que ocupa la columna «#») tiene que seguir oculta — sin el `:not` se
       colaba como una franja vacia arriba del bloque, porque esta regla va despues y gana. */
    .data-table--cards tr.line-sub td:not([data-label=""]) { display: block; padding: 0; }
    /* Fondo transparente: el `--color-surface-2` de la fila de continuacion tiene sentido en la
       tabla de escritorio (matiza que amplia la fila de arriba), pero dentro de una tarjeta lo que
       hace es partirla en dos con un bloque gris que parece un anadido, que es literalmente lo que
       Jorge describio. */
    .data-table--cards tr.line-sub td { background: transparent; font-size: inherit; }
    /* Y la fila de ARRIBA cierra su borde y su redondeo por abajo: sin esto quedaban dos tarjetas
       pegadas con una costura visible entre ellas, que es lo que hacia que el bloque siguiera
       leyendose como un anadido y no como el final de la ficha. */
    .data-table--cards tr:has(+ tr.line-sub) {
        margin-bottom: 0; border-bottom: none;
        border-bottom-left-radius: 0; border-bottom-right-radius: 0;
    }
    .data-table--cards tr.line-sub .line-sub__item {
        display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3);
        padding: var(--sp-2) 0; border-top: var(--bw-1) solid var(--color-border);
    }
    .data-table--cards tr.line-sub .line-sub__item + .line-sub__item::before { content: none; }
    .data-table--cards tr.line-sub .line-sub__label { color: var(--color-text-muted); font-weight: var(--fw-label); }
}

/* issue #187 punto 5: el indicador de estado y su palabra son UNA unidad, en toda la plataforma
   (maestros, soporte y usuarios — Jorge pidio expresamente revisar el patron en todos, no solo en
   vehiculos). Sin envolverlos, la celda de una tarjeta movil reparte sus hijos con
   `space-between` y el punto se iba al centro, separado del texto al que acompana. */
.state { display: inline-flex; align-items: center; gap: var(--sp-2); }
.state .state-dot { margin-right: 0; }

/* issue #187 punto 4/punto 3 — «Exportar CSV» e «Importar Excel»/«Importar CSV» desalineados en
   el movil de Jorge, TRES rondas:
   1.ª: NO reproducido en Chrome de escritorio (320-430px). Se documenta la asimetria
   estructural como sospechosa, sin confirmar.
   2.ª: captura real del movil de Jorge (Samsung S22+, iPhone, Galaxy Fold): «Importar Excel»
   salia mas ancho que «Exportar CSV», e «Importar CSV» —que deberia compartir columna con
   «Importar Excel»— salia MAS ESTRECHO todavia: la prueba de que `.maestros__import-form` no
   actuaba como una celda de grid igual que su hermano `<a class="btn">`. Arreglo de esa ronda:
   `display:contents` en el formulario (linea de arriba, junto a `.maestros__import-form`) — el
   `<label class="btn">` pasa a ser un item de grid/flex MAS del grupo. Y para el rango >480px se
   probo IGUALAR por flex (`flex:1 1 0; min-width:140px` en los dos selectores).
   3.ª: Jorge vuelve a probar y «Importar Excel» SIGUE mas ancho que sus dos hermanos, aunque
   mejor que antes. Causa exacta SIN CONFIRMAR: por spec, `min-width:140px` explicito deberia
   sustituir por completo al minimo automatico de contenido de un item de flex (no combinarse con
   el), asi que `flex:1 1 0` + el mismo `min-width` en los dos selectores deberia repartir el
   espacio por igual — y en la practica, en el movil real de Jorge, no lo hizo (hallazgo del gate
   de revision: el comentario anterior de este bloque atribuia la causa a un mecanismo de la spec
   que no aplica con un `min-width` explicito; no se deja constancia de una causa que no se ha
   verificado). En vez de seguir ajustando flex a ciegas, se cambia a la rejilla CSS (`grid`), que
   ESTRUCTURALMENTE no tiene esta familia de problemas: sus columnas `1fr` son iguales por
   definicion, con independencia del contenido de cada celda — es EXACTAMENTE lo que ya funciona
   bien en el punto 1 (`.cell-actions`) y en el propio `display:grid` de abajo de 480px. Arreglo:
   el `display:grid` de mas arriba (junto a `.maestros__import-form`) pasa de acotarse a 480px a
   acotarse a 768px — un UNICO `display:grid` para todo el rango movil/tablet, en vez de partirlo
   en un grid de abajo
   480px y un flex aproximado de 481 a 768px que era el que arrastraba este defecto. */
.maestros__toolbar-actions .btn { display: inline-flex; align-items: center; justify-content: center; }
