body {
    font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* ============================================================
   Login / verificación OTP — shell de 2 columnas (2026-10-01,
   pedido explícito: "mejora la interfaz del login, toma en cuenta
   la estructura de esta imagen", mockup de referencia Stitch).
   Reemplaza el `.auth-wrapper`/`.auth-card` viejo (una sola card
   chica centrada, sin contexto de marca) por un split: panel
   izquierdo oscuro de marca/contexto (compartido entre login y
   verificación OTP vía `accounts/_auth_base.html`) + panel derecho
   blanco con el form del paso puntual (`{% block auth_right %}`).
   Reusa los MISMOS tokens `--ordix-*` que el resto de la plataforma
   — acá, sin empresa resuelta todavía (nadie inició sesión aún), caen
   a sus valores default de `:root`, no se inventó una paleta nueva
   solo para esta pantalla.
   Copy deliberadamente MÁS CONSERVADOR que el mockup de referencia,
   mismo criterio que ya aplicó el launcher real (ver "Descartado a
   propósito, por falta de dato real detrás" en este archivo): el
   mockup traía varios indicadores que PARECEN telemetría real sin
   estar conectados a nada ("TLS 1.3 AUDITADO", "99.98% disponibilidad",
   "ID NODO ERP: TX-01", "Operational Status: Online", "ID de Operador"
   como modo de login alterno, "¿Olvidaste tu contraseña?" con un flujo
   de reset que no existe) — ninguno se portó. Lo que sí se mantuvo son
   hechos reales de esta plataforma: ORDIX operativo, Cardix "próximamente"
   (mismo texto que ya usa `core/launcher.html`), y el flujo real de 2
   pasos con OTP por correo (`apps/ordix/accounts/services.py`). */
.auth-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    padding: 2rem 1rem;
    background: linear-gradient(135deg, #26235f 0%, #58AEAA 100%);
}

.auth-card {
    display: flex;
    width: 100%;
    max-width: 920px;
    min-height: 560px;
    border-radius: 1.25rem;
    overflow: hidden;
    box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, .35);
}

@media (max-width: 860px) {
    .auth-card { flex-direction: column; min-height: 0; }
}

/* ---- Panel izquierdo: marca/contexto, compartido entre los 2 pasos.
   Oculto en mobile (pedido implícito de espacio — el form es lo único
   imprescindible en pantalla chica, igual que cualquier login de
   producto SaaS comparable). ---- */
/* Foto de fondo (2026-10-01, pedido explícito: "agregale imagen a esta
   regla css con esta imagen") — `static/img/background_login.jpg`.
   Viñeta de 3 paradas, no un degradé parejo de 2 (2026-10-01, pedido
   explícito: "adapta el contenido de auth-panel-left para que se
   adapte a esta sección" — al sacar los tiles de ORDIX/Cardix
   (comentados más abajo) quedó un hueco vacío en el medio del panel,
   y con el overlay parejo de antes esa zona se veía tan apagada como
   el resto, sin ninguna razón (ahí no hay texto que proteger). Ahora
   oscuro arriba (contraste real para el kicker/título/subtítulo) y
   abajo (contraste real para "Verificación en dos pasos"), pero
   MUCHO más liviano en el medio — esa franja es justo donde caen las
   dos personas de la foto, así que en vez de un hueco muerto queda
   una foto real mostrándose con fuerza, a propósito. */
.auth-panel-left {
    flex: 1 1 42%;
    background:
        linear-gradient(
            180deg,
            rgb(18 10 101 / 86%) 0%,
            rgb(18 10 101 / 86%) 26%,
            rgb(18 10 101 / 22%) 46%,
            rgb(35 32 58 / 28%) 64%,
            rgb(20 18 36 / 88%) 84%,
            rgb(20 18 36 / 88%) 100%
        ),
        url("../img/background_login.56d2e59448fc.jpg") center / cover no-repeat;
    color: #fff;
    padding: 2.5rem 2.25rem;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2rem;
}

@media (max-width: 860px) {
    .auth-panel-left { display: none; }
}

.auth-kicker {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-family: "IBM Plex Sans", sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ordix-primary);
    margin-bottom: 1.1rem;
}

.auth-left-title {
    font-family: "Sora", sans-serif;
    font-weight: 700;
    font-size: 1.55rem;
    line-height: 1.28;
    margin: 0 0 .85rem;
}

.auth-left-sub {
    font-size: .9rem;
    line-height: 1.55;
    color: rgba(255, 255, 255, .72);
    margin: 0;
}

.auth-tiles {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .75rem;
    margin-top: 1.5rem;
}

.auth-tile {
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .1);
    border-radius: .75rem;
    padding: .9rem 1rem;
}

.auth-tile-value {
    font-family: "Sora", sans-serif;
    font-weight: 700;
    font-size: 1.05rem;
}

.auth-tile-muted .auth-tile-value { color: rgba(255, 255, 255, .6); }

.auth-tile-label {
    font-size: .74rem;
    color: rgba(255, 255, 255, .58);
    margin-top: .2rem;
}

.auth-panel-left-bottom {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, .1);
}

.auth-panel-left-bottom i {
    font-size: 1.3rem;
    color: var(--ordix-primary);
}

.auth-security-title { font-size: .85rem; font-weight: 700; }
.auth-security-sub { font-size: .76rem; color: rgba(255, 255, 255, .58); }

/* ---- Panel derecho: form del paso puntual (login o verificación). ---- */
.auth-panel-right {
    flex: 1 1 58%;
    background: var(--ordix-surface);
    padding: 3rem 2.75rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

@media (max-width: 860px) {
    .auth-panel-right { padding: 2.25rem 1.5rem; }
}

.auth-step-icon {
    width: 56px;
    height: 56px;
    border-radius: 1rem;
    background: linear-gradient(135deg, var(--ordix-brand), var(--ordix-matrix));
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    margin: 0 auto 1rem;
}

.auth-step-pill {
    display: flex;
    width: fit-content;
    align-items: center;
    gap: .35rem;
    margin: 0 auto 1rem;
    padding: .3rem .75rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--ordix-primary) 16%, transparent);
    color: var(--ordix-matrix);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.auth-title-block { text-align: center; margin-bottom: 1.75rem; }

.auth-title-block h1 {
    font-family: "Sora", sans-serif;
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--ordix-heading);
    margin: 0 0 .4rem;
}

.auth-title-block p {
    font-size: .85rem;
    color: var(--ordix-heading-subtitle);
    margin: 0;
}

.auth-field { margin-bottom: 1.1rem; }

.auth-field-label {
    display: block;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ordix-text-tertiary);
    margin-bottom: .35rem;
}

.auth-field-control-wrap { position: relative; }

.auth-field-control-wrap .auth-field-icon {
    position: absolute;
    left: .85rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ordix-text-tertiary);
    pointer-events: none;
}

.auth-field-control-wrap .form-control {
    padding-left: 2.4rem;
    padding-right: 2.4rem;
    height: 46px;
    border-color: var(--ordix-border);
}

.auth-field-toggle {
    position: absolute;
    right: .6rem;
    top: 50%;
    transform: translateY(-50%);
    border: none;
    background: none;
    color: var(--ordix-text-tertiary);
    cursor: pointer;
    padding: .25rem;
    line-height: 1;
}

.auth-field-toggle:hover { color: var(--ordix-heading); }

.auth-row-between {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
    margin-bottom: 1.25rem;
    font-size: .82rem;
    color: var(--ordix-heading-subtitle);
}

.auth-remember-label {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin: 0;
    cursor: pointer;
}

.auth-submit-btn {
    width: 100%;
    padding: .75rem;
    border-radius: .65rem;
    border: none;
    background: linear-gradient(135deg, var(--ordix-brand), var(--ordix-matrix));
    color: #fff;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
}

.auth-submit-btn:hover { filter: brightness(1.08); color: #fff; }

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

.auth-submit-btn-outline {
    width: 100%;
    padding: .65rem;
    border-radius: .65rem;
    border: 1px solid var(--ordix-border);
    background: #fff;
    color: var(--ordix-heading);
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
}

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

.auth-help-note {
    text-align: center;
    font-size: .78rem;
    color: var(--ordix-text-tertiary);
    margin-top: 1rem;
}

.auth-shell-footer {
    font-size: .78rem;
    color: rgba(255, 255, 255, .55);
    text-align: center;
}

.auth-alert-error {
    background: var(--ordix-error-bg);
    border: 1px solid var(--ordix-error);
    color: var(--ordix-error-text);
    border-radius: .6rem;
    padding: .65rem .85rem;
    font-size: .85rem;
    margin-bottom: 1rem;
}

.otp-input {
    letter-spacing: .85rem;
    font-size: 1.7rem;
    font-weight: 700;
    text-align: center;
    height: 54px;
}

.badge-scenario-A { background-color: #198754; }
.badge-scenario-B { background-color: #fd7e14; }
.badge-scenario-C { background-color: #dc3545; }
.badge-scenario-D { background-color: #6c757d; }

.dynamic-field-card {
    border-left: 4px solid #0d6efd;
}

.worklist-order-row {
    cursor: pointer;
}

.worklist-order-row:hover {
    background-color: rgba(79, 70, 229, .06);
}

.worklist-order-row .bi-chevron-right {
    transition: transform .15s ease-in-out;
    display: inline-block;
}

.worklist-order-row[aria-expanded="true"] .bi-chevron-right {
    transform: rotate(90deg);
}

/* ---------------------------------------------------------------------
   Plataforma (erpgtt) — identidad del navbar/launcher. Hasta el
   2026-09-22 era fija (índigo #221D3B + dorado #D9A441, aprobada por
   Sergio 2026-09-14 tras comparar 3 propuestas) a propósito, para que
   "erpgtt" se sintiera como un producto propio, sin usar
   `Empresa.primary_color`/etc.

   **Revertido el 2026-09-23** (pedido explícito: "toma en cuenta el
   código de color que se configura dentro de la administración") — el
   launcher pasa a seguir el MISMO branding por empresa que ya usa ORDIX
   (`Empresa.brand_color`/`matrix_color`/`primary_color`, ver
   `templates/base.html` bloque `extra_head`, mismo mecanismo que
   `templates/ordix/base.html`). En vez de reescribir cada regla
   `.platform-*` con su propio `Empresa.*_color`, estos tokens quedan
   como ALIAS de los `--ordix-*` de más abajo (mismo `:root`, el orden
   textual no importa — la cascada de `:root` se resuelve completa antes
   de calcular cualquier valor) — un solo lugar (el override de
   `--ordix-*`) alcanza para todo el bloque de plataforma. `--platform-
   ink-soft`/`-mute`/`-canvas`/`-surface*`/`-border*`/`-warn*` se quedan
   FIJOS (texto secundario/fondos neutros del body claro, sin relación
   con la marca) — solo lo que pintaba índigo/dorado pasa a seguir la
   empresa. */
:root {
    --platform-ink: var(--ordix-heading);
    --platform-ink-soft: #6B6580;
    --platform-ink-mute: #9B96AD;
    --platform-canvas: #F5F4FA;
    --platform-surface: #FFFFFF;
    --platform-surface-mute: #F7F7FB;
    --platform-gold: var(--ordix-primary);
    --platform-gold-deep: var(--ordix-brand);
    --platform-border: rgba(34, 29, 59, .09);
    --platform-border-dashed: rgba(34, 29, 59, .18);
    --platform-warn-bg: #F8EFDE;
    --platform-warn-text: #654C1E;
    --platform-warn-dot: #B98C38;
}

/* Gradiente del nav — usa `--ordix-matrix`/`--ordix-brand` DIRECTO (no
   `--platform-ink`, que acá arriba quedó alias de `--ordix-heading`,
   pensado para texto sobre fondo claro, no para un fondo grande) —
   mismos 2 tokens que ya arma el degradé del sidebar de ORDIX
   (`.ordix-sidebar`), para que plataforma y módulo compartan la MISMA
   sensación de marca de la empresa activa. */
.platform-nav {
    background: linear-gradient(160deg, var(--ordix-matrix) 0%, var(--ordix-brand) 100%);
    padding: 32px 64px 44px;
}

.platform-hero-content {
    position: relative;
    z-index: 1;
    width: 100%;
}

.platform-util-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
}

.platform-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
}

.platform-brand-mark {
    width: 40px;
    height: 40px;
    border-radius: 11px;
    flex: none;
    /* `color-mix` en vez del rgba(217,164,65,...) dorado fijo de antes —
       reacciona al `--ordix-primary` de la empresa activa (ver alias de
       `--platform-gold` más arriba), no queda pegado al dorado viejo. */
    background: color-mix(in srgb, var(--ordix-primary) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--ordix-primary) 40%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--platform-gold);
    font-size: 1.15rem;
}

/* Punto chico junto al wordmark "erpgtt" (mockup 2026-09-23) — mismo
   verde de "activo/operativo" que ya usan otros indicadores de estado
   del proyecto, decorativo (marca de producto "en línea"). */
.platform-brand-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ordix-success);
    display: inline-block;
    margin-left: 4px;
    vertical-align: super;
}

.platform-brand-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.platform-brand-word {
    font-family: "Sora", sans-serif;
    font-weight: 700;
    font-size: 19px;
    letter-spacing: .01em;
    color: #fff;
    line-height: 1;
}

.platform-brand-tag {
    font-family: "IBM Plex Sans", sans-serif;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .42);
    line-height: 1;
}

/* Etiqueta "Empresa activa" arriba del selector — clase neutra en el
   parcial compartido, oculta por defecto (así ORDIX no la muestra) y
   solo visible dentro de .platform-nav, mismo mecanismo que el resto
   de este parcial. */
.platform-empresa-label { display: none; }

.platform-nav .platform-empresa-label {
    display: block;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--platform-gold);
    margin-bottom: 0;
}

/* Selector de empresa como "pill" de dos líneas (label arriba, valor
   abajo) — la clase va en el CONTENEDOR (`.platform-empresa-block` en
   el parcial), no en el botón/badge interno; ese queda transparente,
   solo texto+ícono. Clase neutra en el parcial compartido, coloreada
   acá SOLO dentro de .platform-nav; en ORDIX (.ordix-main-header) no
   tiene efecto, queda con su look de badge/btn de siempre. */
.platform-nav .platform-empresa-pill {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 7px 16px;
    border-radius: 12px;
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .14);
}

.platform-nav .platform-empresa-value {
    display: flex;
    align-items: center;
    gap: 7px;
}

.platform-nav .platform-empresa-value .btn,
.platform-nav .platform-empresa-value.badge {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: transparent !important;
    border: none;
    box-shadow: none;
    color: #fff;
    padding: 0;
    font-size: 14px;
    font-weight: 700;
    border-radius: 0;
}

/* Chevron propio (reemplaza el caret nativo de Bootstrap en el toggle
   del dropdown) — oculto por defecto, solo se muestra dentro de
   .platform-nav; el caret nativo también solo se oculta ahí, así
   ORDIX conserva su flechita de siempre sin cambios. */
.platform-empresa-chevron { display: none; }

.platform-nav .platform-empresa-value.dropdown-toggle::after {
    display: none;
}

.platform-nav .platform-empresa-chevron {
    display: inline-block;
    font-size: 13px;
    color: rgba(255, 255, 255, .4);
    margin-left: 2px;
}

/* Punto de estado antes del ícono de empresa (mockup 2026-09-23) —
   mismo verde "operativo" que `.platform-brand-dot`, decorativo. Oculto
   por defecto (clase neutra del parcial compartido) y coloreado SOLO
   dentro de .platform-nav — en ORDIX (.ordix-main-header) el selector de
   empresa no lo usa, ya tiene su propio look de tarjeta sin punto. */
.platform-empresa-status-dot { display: none; }

.platform-nav .platform-empresa-status-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ordix-success);
    flex: none;
}

/* Menú desplegable de empresas dentro de plataforma — misma tarjeta
   (borde + sombra + radio + check-item) que ya usa ORDIX
   (.ordix-main-header .platform-empresa-menu, más abajo), para que el
   selector se sienta igual en los dos contextos aunque el TRIGGER que
   lo abre tenga cada uno su propio fondo (oscuro acá, claro en ORDIX).
   Bootstrap ya lo renderiza sobre fondo blanco por defecto — esto solo
   pule bordes/sombra/spacing para que coincida con el patrón. */
.platform-nav .platform-empresa-menu {
    width: 260px;
    max-width: 90vw;
    border: 1px solid var(--ordix-border);
    border-radius: .65rem;
    box-shadow: 0 16px 32px rgba(23, 47, 61, .16);
    padding: .5rem;
}

.platform-nav .platform-empresa-menu-label {
    display: block;
    padding: .45rem .6rem .35rem;
    font-size: .68rem;
    font-weight: 700;
    color: var(--ordix-text-tertiary);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.platform-nav .platform-empresa-menu form { margin: 0; }

.platform-nav .platform-empresa-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem .6rem;
    border-radius: .45rem;
    font-size: .8rem;
    font-weight: 500;
    color: var(--ordix-text-tertiary);
}

.platform-nav .platform-empresa-menu .dropdown-item:hover {
    background: var(--ordix-surface-2);
}

.platform-nav .platform-empresa-menu .dropdown-item.active {
    background: transparent;
    color: var(--ordix-text);
    font-weight: 600;
}

.platform-nav .platform-empresa-check {
    width: 16px;
    height: 16px;
    border-radius: 4px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--ordix-border);
    background: var(--ordix-surface);
    font-size: .6rem;
    color: transparent;
}

.platform-nav .platform-empresa-menu .dropdown-item.active .platform-empresa-check {
    background: var(--ordix-brand);
    border-color: var(--ordix-brand);
    color: #fff;
}

/* Usuario logueado: avatar con iniciales + nombre/rol apilados — el
   avatar y el padding tipo pill quedan ocultos/neutros por defecto y
   solo se activan dentro de .platform-nav, mismo mecanismo que arriba. */
.platform-user-avatar { display: none; }
.platform-user-icon { }

.platform-nav .platform-account-cluster {
    gap: 18px;
}

.platform-nav .platform-user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--platform-gold) 0%, var(--platform-gold-deep) 100%);
    color: var(--platform-ink);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: .02em;
    flex: none;
}

.platform-nav .platform-user-icon { display: none; }

.platform-nav .platform-user-card {
    display: flex;
    align-items: center;
    gap: 11px;
    background: transparent;
    border-radius: 0;
    padding: 0;
}

.platform-user-meta { }

.platform-nav .platform-user-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    line-height: 1;
}

.platform-nav .platform-role-badge {
    background: rgba(255, 255, 255, .09) !important;
    color: rgba(255, 255, 255, .72) !important;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 20px;
    padding: 2px 8px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .02em;
}

/* Botón "Salir": texto visible solo dentro de .platform-nav (mismo
   mecanismo oculto-por-defecto) — en ORDIX sigue siendo ícono solo,
   como hoy. */
.platform-logout-text { display: none; }

.platform-nav .platform-logout-text { display: inline; }

.platform-nav .platform-logout-btn {
    width: auto;
    height: auto;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 13px;
    border: 1px solid rgba(255, 255, 255, .16);
    color: rgba(255, 255, 255, .65);
    font-size: 12px;
    font-weight: 600;
}

.platform-nav .platform-logout-btn i {
    font-size: .95rem;
}

.platform-nav .platform-logout-btn:hover {
    background: rgba(255, 255, 255, .14);
    color: #fff;
}

/* Saludo del hero ("Buenos días, ..."), blanco sobre el degradé —
   vive dentro de .platform-nav (bloque hero_greeting de base.html),
   no en el cuerpo claro de la página. */
.platform-greeting {
    margin-top: 46px;
    max-width: 640px;
}

/* Badge "Sesión iniciada con éxito · <fecha>" (mockup 2026-09-23) —
   copy fijo (cierto por definición: si ves esta pantalla, tu sesión ya
   se inició) + fecha real (`{% now %}`, no inventada). Reusa
   `.platform-brand-dot` (mismo verde de "operativo") como indicador. */
.platform-session-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 20px;
    background: rgba(255, 255, 255, .07);
    border: 1px solid rgba(255, 255, 255, .14);
    color: rgba(255, 255, 255, .78);
    font-size: 11.5px;
    font-weight: 600;
}

.platform-session-badge .platform-brand-dot {
    margin-left: 0;
    vertical-align: middle;
}

.platform-greeting h2 {
    margin: 14px 0 0;
    font-family: "Sora", sans-serif;
    font-weight: 700;
    font-size: 40px;
    line-height: 1.15;
    color: #fff;
}

.platform-greeting p {
    margin: 10px 0 0;
    font-size: 16px;
    line-height: 1.6;
    color: rgba(255, 255, 255, .72);
}

.platform-greeting .accent-text {
    color: var(--platform-gold);
    font-weight: 700;
}

.platform-module-grid {
    max-width: 1080px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 28px;
    padding: 0 0 2rem;
}

.platform-module-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--platform-surface);
    border: 1px solid var(--platform-border);
    border-radius: 20px;
    padding: 28px;
    text-align: left;
    text-decoration: none;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 12px 24px -14px rgba(16, 24, 40, .14);
    transition: transform .15s ease, box-shadow .15s ease;
}

/* Badge "Operativo" (mockup 2026-09-23) — mismo lugar/forma que
   `.platform-module-badge-soon` de Cardix, más abajo, solo que en
   verde. Real: `modulos` (apps/core/views.py::launcher) YA filtra por
   `Modulo.is_active=True` antes de llegar acá, así que toda tarjeta que
   entra a este loop está, por definición, activa. */
.platform-module-badge-active {
    position: absolute;
    top: 20px;
    right: 20px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: "IBM Plex Sans", sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ordix-success-text);
    background: var(--ordix-success-bg);
    border-radius: 20px;
    padding: 4px 10px;
}

.platform-module-badge-active .platform-module-badge-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ordix-success);
    flex: none;
}

.platform-module-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 24px rgba(34, 29, 59, .12);
}

.platform-module-icon {
    width: 58px;
    height: 58px;
    margin: 0 0 18px;
    border-radius: 15px;
    background: var(--module-color, var(--platform-ink));
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6875rem;
}

/* ORDIX es hoy el único módulo real — degradé exacto de su propia
   identidad de marca (--ordix-brand → --ordix-primary, ya definidos
   más abajo en este archivo), igual que en el mockup. Un módulo nuevo
   sin regla propia cae al color plano de MODULE_META (--module-color,
   fijado inline por apps/core/views.py) vía el fallback de arriba. */
.platform-module-icon[data-modulo="ordix"] {
    background: linear-gradient(135deg, var(--ordix-brand) 0%, var(--ordix-primary) 100%);
}

.platform-module-stat {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--platform-warn-bg);
    color: var(--platform-warn-text);
    border-radius: 12px;
    padding: 12px 14px;
    font-size: 13.5px;
    font-weight: 700;
    margin-top: 20px;
}

.platform-module-stat-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--platform-warn-dot);
    flex: none;
}

.platform-module-name {
    font-family: "Sora", sans-serif;
    font-weight: 700;
    color: var(--platform-ink);
    font-size: 21px;
}

.platform-module-desc {
    font-family: "IBM Plex Sans", sans-serif;
    color: var(--platform-ink-mute);
    font-size: 13.5px;
    margin-top: 4px;
}

.platform-module-cta {
    font-family: "IBM Plex Sans", sans-serif;
    font-weight: 700;
    font-size: 14px;
    color: var(--platform-ink);
    margin-top: auto;
    padding-top: 20px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.platform-module-cta i {
    color: var(--platform-gold-deep);
    font-size: 15px;
}

.platform-module-card:hover .platform-module-cta { text-decoration: underline; }

/* Tarjeta "en construcción" (ej. Cardix) — visible como referencia de
   hoja de ruta, pero claramente NO activa: borde punteado, sin link,
   sin hover, logo real del módulo (no un ícono genérico). */
.platform-module-card-soon {
    position: relative;
    border-style: dashed;
    border-color: var(--platform-border-dashed);
    cursor: default;
}

.platform-module-card-soon:hover {
    transform: none;
    box-shadow: 0 1px 3px rgba(34, 29, 59, .06);
}

.platform-module-badge-soon {
    position: absolute;
    top: 20px;
    right: 20px;
    font-family: "IBM Plex Sans", sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--platform-ink-mute);
    background: var(--platform-surface-mute);
    border: 1px solid var(--platform-border);
    border-radius: 20px;
    padding: 4px 10px;
}

.platform-module-icon-soon {
    background: var(--platform-surface-mute);
    border: 1px solid var(--platform-border);
    padding: 8px;
}

.platform-module-logo {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.platform-module-cta-soon {
    color: var(--platform-ink-mute) !important;
}

.platform-module-card-soon:hover .platform-module-cta-soon { text-decoration: none; }

/* Franja de soporte técnico (mockup 2026-09-23) — mismo max-width que
   `.platform-module-grid`/`.platform-modules-section` para quedar
   alineada con la grilla de arriba. Los dos botones quedan `disabled`
   a propósito (ver launcher.html) — no hay destino real todavía. */
.platform-support-banner {
    max-width: 1080px;
    margin: 8px auto 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    background: var(--platform-surface);
    border: 1px solid var(--platform-border);
    border-radius: 16px;
    padding: 20px 24px;
}

.platform-support-info {
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0;
}

.platform-support-icon {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--platform-surface-mute);
    color: var(--platform-ink-mute);
    font-size: 1.2rem;
}

.platform-support-title {
    font-family: "IBM Plex Sans", sans-serif;
    font-weight: 700;
    color: var(--platform-ink);
    font-size: 14.5px;
}

.platform-support-sub {
    font-family: "IBM Plex Sans", sans-serif;
    color: var(--platform-ink-mute);
    font-size: 13px;
    margin-top: 2px;
}

.platform-support-actions {
    display: flex;
    gap: 10px;
    flex: none;
}

.platform-support-btn-outline,
.platform-support-btn-solid {
    font-family: "IBM Plex Sans", sans-serif;
    font-weight: 600;
    font-size: 13.5px;
    padding: 9px 18px;
    border-radius: 10px;
    white-space: nowrap;
}

.platform-support-btn-outline {
    background: transparent;
    border: 1px solid var(--platform-border);
    color: var(--platform-ink);
}

.platform-support-btn-solid {
    background: var(--platform-ink);
    border: 1px solid var(--platform-ink);
    color: #fff;
}

/* `disabled` (sin destino real todavía, ver launcher.html) con opacidad
   propia — más sutil que el `.6` default de Bootstrap, para que no se
   lean como "rotos", solo como "todavía no disponibles". */
.platform-support-btn-outline:disabled,
.platform-support-btn-solid:disabled {
    opacity: .85;
    cursor: not-allowed;
}

.platform-modules-section {
    max-width: 1080px;
    margin: 0 auto 28px;
}

.platform-modules-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}

.platform-modules-title {
    font-family: "Sora", sans-serif;
    font-weight: 700;
    font-size: 24px;
    color: var(--platform-ink);
    margin: 0;
}

/* Cantidad de tarjetas listadas (mockup 2026-09-23) — conteo real de lo
   que el loop de abajo efectivamente renderiza (`modulos` + la tarjeta
   fija de Cardix), no un número aparte inventado. */
.platform-modules-count {
    display: inline-flex;
    align-items: center;
    background: var(--ordix-secondary);
    color: var(--ordix-secondary-text);
    border-radius: 20px;
    padding: 3px 11px;
    font-size: 11.5px;
    font-weight: 700;
}

.platform-modules-sub {
    font-family: "IBM Plex Sans", sans-serif;
    color: var(--platform-ink-mute);
    font-size: 13.5px;
}

/* ---------------------------------------------------------------------
   ORDIX — colores propios del módulo (manual de marca aprobado,
   ORDIX-mockups-v2/1.Branding), valores por defecto. brand/matrix/
   primary/secondary y los 3 tokens de encabezado (--ordix-heading*, más
   abajo) SÍ varían por empresa desde 2026-09-16 — ver
   `templates/ordix/base.html` (bloque extra_head), que los sobreescribe
   inline con `Empresa.brand_color`/etc. de la empresa activa
   (`apps.core.context_processors.empresa_branding`). El resto de esta
   hoja (canvas/surface/border, estados, texto no-encabezado) se queda
   fijo al diseño del mockup, no varía por empresa.
--------------------------------------------------------------------- */
:root {
    --ordix-brand: #2C5856;      /* verde petróleo — logo, títulos, iconos principales (Empresa.brand_color) */
    --ordix-matrix: #172F3D;     /* azul estructural (Empresa.matrix_color) */
    --ordix-primary: #58AEAA;    /* teal — botones, CTA, hover (Empresa.primary_color) */
    --ordix-secondary: #DFEDF7;  /* azul suave — fondos informativos, estado activo (Empresa.secondary_color) */
    --ordix-secondary-text: #2C5856; /* texto sobre --ordix-secondary — propio, NO copiar --ordix-heading-subtitle (Empresa.secondary_text_color) */
    --ordix-canvas: #F8FAFC;     /* fondo general de la app */
    --ordix-surface: #FFFFFF;    /* cards, sidebar, modales */
    --ordix-surface-2: #F1F5F7;  /* secciones secundarias, headers de tabla */
    --ordix-border: #E4EAED;
    --ordix-text: #172A30;
    --ordix-text-secondary: #66777B;
    --ordix-text-tertiary: #98A6AA;
    --ordix-success: #29966B;    --ordix-success-bg: #EAF7F1;    --ordix-success-text: #176B4A;
    --ordix-warning: #D99A22;    --ordix-warning-bg: #FFF7E6;    --ordix-warning-text: #8A6115;
    --ordix-error: #D64545;      --ordix-error-bg: #FDECEC;      --ordix-error-text: #A52F2F;
    --ordix-info: #3B82B6;       --ordix-info-bg: #EAF4FB;       --ordix-info-text: #245C82;
    --ordix-special: #7C6AC8;    --ordix-special-bg: #F1EEFC;    --ordix-special-text: #5B4AA5;
    --ordix-nav-muted: #A9BFD1;  /* texto de nav inactivo sobre el sidebar oscuro — "azul calma" del manual */

    /* Encabezados (h1/h2/h3 y subtítulos de sección) — ÚNICO texto
       configurable por empresa (Empresa.title_color/subtitle_color/
       tertiary_title_color, ver apps/core/models.py). El resto del texto
       del módulo (--ordix-text/-secondary/-tertiary de arriba) se queda
       fijo al diseño del mockup, no varía por empresa. */
    --ordix-heading: #172A30;
    --ordix-heading-subtitle: #66777B;
    --ordix-heading-tertiary: #98A6AA;
}

.ordix-main-header,
.ordix-shell {
    font-family: "Inter", system-ui, -apple-system, sans-serif;
}

/* Color de encabezado configurable por empresa — solo h1/h2/h3 reales y
   los subtítulos de sección (.ordix-page-subtitle, .wizard-step-sub).
   Todo lo demás (valores de KPI, tablas, body) usa --ordix-text* fijo. */
.ordix-shell h1,
.ordix-shell h2,
.ordix-shell h3 {
    color: var(--ordix-heading);
}

.ordix-page-subtitle {
    color: var(--ordix-heading-subtitle);
}

/* Header propio de CADA pantalla de ORDIX, DENTRO de `.ordix-main`
   (2026-10-01, reemplaza al topstrip global que vivía ARRIBA de todo
   el shell — ver el comment grande en `templates/ordix/base.html`,
   bloque `navbar`). Sticky `top:0` SIEMPRE (antes era opcional, solo
   el wizard lo pedía vía `.ordix-main-header` — ahora no hace
   falta esa variante: al no competir con ningún otro componente
   sticky arriba, no hay motivo para que el resto de ORDIX NO lo sea
   también, y así el comportamiento es el mismo en toda pantalla, no
   solo el wizard). El margin negativo cancela el padding propio de
   `.ordix-main` (mismo truco que ya usaba `.wizard-stepper` antes de
   esta fecha) para que quede pegado a los 3 bordes — arriba e
   izquierda/derecha — y `.ordix-main-header-row` vuelve a meter ese
   padding adentro, para que el contenido (breadcrumb/menú de cuenta)
   quede alineado con el resto de la página. */
.ordix-main-header {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--ordix-surface);
    border-bottom: 1px solid var(--ordix-border);
    margin: -1.75rem -2rem 1.5rem;
}

.ordix-main-header-row {
    display: flex;
    align-items: center;
    padding: .7rem 2rem;
}

@media (max-width: 767.98px) {
    .ordix-main-header {
        margin: -1.25rem -1rem 1.25rem;
    }

    .ordix-main-header-row {
        padding: .7rem 1rem;
    }
}

.ordix-home-link {
    color: var(--ordix-text) !important;
    text-decoration: none;
    border-radius: .5rem;
    font-weight: 700;
}

.ordix-home-link:hover {
    color: var(--ordix-brand) !important;
    background: var(--ordix-surface-2);
}

/* core/_menu_cuenta.html es un parcial COMPARTIDO entre el navbar oscuro
   de plataforma (templates/base.html, navbar-dark) y el header blanco de
   cada pantalla de ORDIX (.ordix-main-header, dentro de .ordix-main) —
   antes traía texto fijo en blanco (pensado solo para el navbar
   oscuro), invisible sobre el fondo blanco de ORDIX. Colores por
   contexto acá, nada fijo en el parcial. */
.account-menu-text,
.account-menu-link {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    text-decoration: none;
}

.platform-nav .account-menu-text,
.platform-nav .account-menu-link {
    color: rgba(255, 255, 255, .85);
}

/* Separador vertical entre el selector de empresa y el bloque de
   usuario — igual que el chevron/pill de arriba, invisible por
   defecto y solo se dibuja dentro de .platform-nav. */
.account-menu-divider { display: none; }

.platform-nav .account-menu-divider {
    display: block;
    width: 1px;
    height: 38px;
    background: rgba(255, 255, 255, .13);
    flex: none;
}

.platform-nav .account-menu-link:hover {
    color: #fff;
}

.ordix-main-header .account-menu-text,
.ordix-main-header .account-menu-link {
    color: var(--ordix-text-secondary);
}

.ordix-main-header .account-menu-link:hover {
    color: var(--ordix-brand);
}

/* core/_menu_cuenta.html dentro de ORDIX — mismo mecanismo ya documentado
   arriba para .platform-nav (parcial neutro, coloreado acá SOLO dentro de
   .ordix-main-header): avatar + rol al estilo del header-row de la plantilla
   (ordix-plantilla/dashboard.html — círculo de 34px en --ordix-secondary/
   --ordix-brand, nombre+rol apilados), salir como ícono circular.
   Reemplaza el look de btn/badge de Bootstrap por defecto que tenía antes. */

/* Selector de empresa — tarjeta blanca con borde, igual al toggle del
   dropdown de ordix-plantilla/dashboard-modulos.html (no el chip Soft que
   tenía antes). */
.ordix-main-header .platform-empresa-value .btn,
.ordix-main-header .platform-empresa-value.badge {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .45rem .85rem;
    border-radius: .5rem;
    background: var(--ordix-surface) !important;
    border: 1px solid var(--ordix-border);
    color: var(--ordix-text) !important;
    font-size: .8rem;
    font-weight: 600;
}

.ordix-main-header .platform-empresa-value.dropdown-toggle::after {
    display: none;
}

.ordix-main-header .platform-empresa-chevron {
    display: inline-block;
    font-size: .7rem;
    color: var(--ordix-text-secondary);
}

/* Menú desplegable de empresas — misma tarjeta (borde + sombra suave +
   radio 10px + padding 8px) y el mismo patrón de check-item que la
   plantilla usa en su selector "Empresas · selecciona una o varias"
   (guia-componentes / dashboard-modulos.html), adaptado a selección
   única: el check marca la empresa activa, no un multi-toggle en vivo —
   clickear cualquier ítem cambia de empresa y cierra el menú. */
.ordix-main-header .platform-empresa-menu {
    width: 260px;
    max-width: 90vw;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .65rem;
    box-shadow: 0 16px 32px rgba(23, 47, 61, .16);
    padding: .5rem;
}

.ordix-main-header .platform-empresa-menu form {
    margin: 0;
}

.ordix-main-header .platform-empresa-menu-label {
    display: block;
    padding: .45rem .6rem .35rem;
    font-size: .68rem;
    font-weight: 700;
    color: var(--ordix-text-tertiary);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.ordix-main-header .platform-empresa-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem .6rem;
    border-radius: .45rem;
    font-size: .8rem;
    font-weight: 500;
    color: var(--ordix-text-tertiary);
}

.ordix-main-header .platform-empresa-menu .dropdown-item:hover {
    background: var(--ordix-surface-2);
}

.ordix-main-header .platform-empresa-menu .dropdown-item.active {
    background: transparent;
    color: var(--ordix-text);
    font-weight: 600;
}

.ordix-main-header .platform-empresa-check {
    width: 16px;
    height: 16px;
    border-radius: 4px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--ordix-border-strong, var(--ordix-border));
    background: var(--ordix-surface);
    font-size: .6rem;
    color: transparent;
}

.ordix-main-header .platform-empresa-menu .dropdown-item.active .platform-empresa-check {
    background: var(--ordix-brand);
    border-color: var(--ordix-brand);
    color: #fff;
}

.ordix-main-header .platform-user-card {
    display: flex;
    align-items: center;
    gap: .6rem;
}

.ordix-main-header .platform-user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--ordix-secondary);
    color: var(--ordix-secondary-text);
    font-weight: 700;
    font-size: .75rem;
    flex: none;
}

.ordix-main-header .platform-user-icon {
    display: none;
}

.ordix-main-header .platform-user-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .1rem;
    line-height: 1.2;
    font-size: .82rem;
    font-weight: 600;
    color: var(--ordix-text);
}

/* Antes bg surface-2 + texto tertiary: gris claro sobre gris claro,
   casi ilegible. Fondo secondary + texto de --ordix-secondary-text da
   contraste real manteniéndolo "suave" (mismo par de tokens que el
   resto de los chips soft del módulo), en vez de oscurecer el gris
   neutro. */
.ordix-main-header .platform-role-badge {
    background: var(--ordix-secondary) !important;
    color: var(--ordix-secondary-text) !important;
    border: none;
    border-radius: 20px;
    padding: 1px 8px;
    font-size: .66rem;
    font-weight: 700;
}

.ordix-main-header .platform-logout-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--ordix-surface-2);
    color: var(--ordix-text-secondary);
}

.ordix-main-header .platform-logout-btn:hover {
    background: var(--ordix-error-bg);
    color: var(--ordix-error);
}

.ordix-shell {
    background: var(--ordix-canvas);
    min-height: 100vh;
    width: 100%;
}

/* Fijo al hacer scroll (2026-09-18, feedback de Sergio: con "Servicios
   de la orden" largo había que subir todo el scroll para volver a ver
   el menú) — son pocas opciones, no hace falta que se pierdan de
   vista. `position:sticky` (no `fixed`) para no salirse del layout
   flex de `.ordix-shell` ni necesitar un margin-left manual en
   `.ordix-main`; `align-self:flex-start` para que NO se estire con
   `align-items:stretch` (default de flex) a la altura de `.ordix-main`
   cuando este es más alto — así conserva su propia altura acotada a
   `100vh` y se puede pegar arriba de verdad. Solo tiene efecto en
   desktop (`d-none d-md-flex` en el HTML ya lo oculta en mobile, donde
   el menú vive en el offcanvas). */
.ordix-sidebar {
    width: 220px;
    flex: none;
    align-self: flex-start;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    background: var(--ordix-matrix);
    padding: 1.1rem .75rem;
    gap: .25rem;
}

.ordix-sidebar-brand {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: 0 .4rem .9rem .4rem;
    text-decoration: none;
}

.ordix-logo-mark {
    width: 8px;
    height: 8px;
    border-radius: 3px;
    background: var(--ordix-primary);
    flex: none;
}

.ordix-logo-text {
    font-weight: 700;
    color: #FFFFFF;
    font-size: .82rem;
    letter-spacing: -.01em;
}

.ordix-nav {
    display: flex;
    flex-direction: column;
    gap: .2rem;
}

.ordix-nav-divider {
    border: 0;
    height: 1px;
    background: rgba(255, 255, 255, .12);
    margin: .5rem 0;
}

.ordix-nav-link {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem .68rem;
    border-radius: 7px;
    color: var(--ordix-nav-muted);
    text-decoration: none;
    font-size: .8rem;
    font-weight: 500;
}

.ordix-nav-link i {
    font-size: .95rem;
    width: 1rem;
    text-align: center;
}

.ordix-nav-link:hover {
    background: rgba(255, 255, 255, .06);
    color: #FFFFFF;
}

.ordix-nav-link.active {
    background: var(--ordix-brand);
    color: #FFFFFF;
    font-weight: 600;
}

.ordix-nav-link.active::before {
    content: "";
    display: block;
    width: 3px;
    height: 12px;
    border-radius: 2px;
    /*background: var(--ordix-primary);*/
    background: #ffffff;
    flex: none;
}

.ordix-main {
    flex: 1;
    min-width: 0;
    padding: 1.75rem 2rem;
}

/* --- Nav mobile: topbar + offcanvas (<768px, ver ordix-shell) -------- */

.ordix-mobile-topbar {
    align-items: center;
    justify-content: space-between;
    background: var(--ordix-matrix);
    padding: .85rem 1.1rem;
}

.ordix-mobile-topbar .ordix-sidebar-brand {
    padding: 0;
}

.ordix-mobile-topbar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    background: rgba(255, 255, 255, .08);
    border: none;
    color: #FFFFFF;
    font-size: 1.1rem;
}

.ordix-offcanvas {
    background: var(--ordix-matrix);
    width: 220px;
}

.ordix-offcanvas .offcanvas-body {
    padding: .75rem;
}

@media (max-width: 767.98px) {
    .ordix-main {
        padding: 1.25rem 1rem;
    }
}

/* --- Overlay de carga (Mis Órdenes tarda unos segundos — sincroniza con
   TINA vía túnel SSH). Fondo TRANSPARENTE a propósito (no blanco sólido)
   para que se siga viendo que estás en la página correcta, solo que hay
   que esperar — ver static/js/ordix.js, que lo muestra al hacer clic en
   cualquier link hacia Mis Órdenes, antes de navegar. */
.ordix-loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(23, 47, 61, .18);
    backdrop-filter: blur(1.5px);
}

.ordix-loading-overlay.show {
    display: flex;
}

/* Imagen/spinner arriba (más grande), texto centrado debajo — a
   propósito en columna, no en fila, para que la animación sea lo
   primero que se ve. */
.ordix-loading-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1.5rem 1.6rem;
    box-shadow: 0 16px 32px rgba(23, 47, 61, .25);
    max-width: 320px;
}

.ordix-spinner {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 4px solid var(--ordix-secondary);
    border-top-color: var(--ordix-brand);
    flex: none;
    animation: ordix-spin .7s linear infinite;
}

@keyframes ordix-spin {
    to { transform: rotate(360deg); }
}

/* Variante chica para meter DENTRO de un botón (ej. "Agregando
   servicios…" del drawer de buscar servicio, 2026-09-21) — el spinner
   grande usa colores pensados para fondo claro (--ordix-secondary/
   --ordix-brand), ilegibles sobre un botón sólido de color; acá el
   anillo es blanco translúcido con el segmento superior blanco sólido,
   patrón estándar de spinner sobre fondo de color. */
.ordix-spinner-sm {
    width: 14px;
    height: 14px;
    border-width: 2px;
    border-color: rgba(255, 255, 255, .4);
    border-top-color: #fff;
    display: inline-block;
    vertical-align: -2px;
    margin-right: .45rem;
}

/* GIF propio por etapa (core.ModuloLoadingState.imagen) — reemplaza al
   spinner CSS de arriba cuando esa etapa tiene imagen cargada; JS
   alterna cuál de los dos queda visible (ver static/js/ordix.js). */
.ordix-loading-gif {
    width: 56px;
    height: 56px;
    flex: none;
    object-fit: contain;
}

/* Mismo GIF de etapa, pero en miniatura DENTRO de un botón (ej. "Sumar
   seleccionados a esta orden" del drawer de buscar servicio, 2026-09-22)
   — mismo footprint que `.ordix-spinner-sm` (14px + separación) para que
   el botón no cambie de tamaño al alternar entre spinner CSS e imagen. */
.wizard-btn-loading-gif {
    width: 14px;
    height: 14px;
    object-fit: contain;
    display: inline-block;
    vertical-align: -2px;
    margin-right: .45rem;
}

.ordix-loading-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .3rem;
}

.ordix-loading-text strong {
    font-size: .92rem;
    color: var(--ordix-text);
}

.ordix-loading-text span {
    font-size: .78rem;
    color: var(--ordix-text-secondary);
}

/* --- Toasts de Django messages (templates/core/_toasts.html) --------
   Reemplazan a los alerts de Bootstrap de antes (2026-09-18, pedido de
   Sergio: "¿podemos reemplazar este tipo de alertas por otro diseño
   como sweetalert o alguna otra alternativa?" — se descartó sumar una
   librería nueva a propósito, ver la nota de esa conversación; esto es
   custom, mismos tokens de color que el resto de ORDIX). Antes los
   alerts vivían FIJOS arriba del contenido — empujaban todo hacia
   abajo y había que cerrarlos a mano. Ahora flotan arriba a la
   derecha, no mueven el layout, y se auto-ocultan solos (static/js/
   ordix.js maneja el timer y el cierre manual). Compartido entre el
   shell de plataforma y el de ORDIX — un solo lugar. */
.ordix-toast-container {
    position: fixed;
    top: 1.25rem;
    right: 1.25rem;
    z-index: 2100;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    max-width: 380px;
    width: calc(100% - 2.5rem);
    pointer-events: none;
}

.ordix-toast {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-left: 4px solid var(--ordix-text-tertiary);
    border-radius: .6rem;
    padding: .85rem 1rem;
    box-shadow: 0 12px 28px rgba(23, 47, 61, .18);
    font-size: .85rem;
    line-height: 1.4;
    color: var(--ordix-text);
    pointer-events: auto;
    animation: ordix-toast-in .22s ease;
}

.ordix-toast.ordix-toast-hide {
    animation: ordix-toast-out .18s ease forwards;
}

@keyframes ordix-toast-in {
    from { opacity: 0; transform: translateX(20px); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes ordix-toast-out {
    from { opacity: 1; transform: translateX(0); }
    to { opacity: 0; transform: translateX(20px); }
}

.ordix-toast > i:first-child {
    font-size: 1.05rem;
    flex: none;
    margin-top: .1rem;
}

.ordix-toast-text { flex: 1; min-width: 0; }

.ordix-toast-close {
    background: none;
    border: none;
    padding: 0;
    flex: none;
    font-size: 1rem;
    line-height: 1;
    color: var(--ordix-text-tertiary);
}

.ordix-toast-close:hover { color: var(--ordix-text); }

.ordix-toast-success { border-left-color: var(--ordix-success); }
.ordix-toast-success > i:first-child { color: var(--ordix-success); }

.ordix-toast-error { border-left-color: var(--ordix-error); }
.ordix-toast-error > i:first-child { color: var(--ordix-error); }

.ordix-toast-warning { border-left-color: var(--ordix-warning); }
.ordix-toast-warning > i:first-child { color: var(--ordix-warning); }

.ordix-toast-info,
.ordix-toast-debug { border-left-color: var(--ordix-info); }
.ordix-toast-info > i:first-child,
.ordix-toast-debug > i:first-child { color: var(--ordix-info); }

@media (max-width: 575.98px) {
    .ordix-toast-container {
        top: auto;
        bottom: 1rem;
        left: .75rem;
        right: .75rem;
        max-width: none;
        width: auto;
    }
}

/* --- Mis Órdenes: tabs de vista, buscador, KPIs y tabla ------------- */

.ordix-view-tabs {
    display: flex;
    align-items: center;
}

.ordix-view-tab {
    border: none;
    background: transparent;
    color: var(--ordix-text-secondary);
    font-size: .85rem;
    font-weight: 600;
    padding: .4rem .8rem;
    border-radius: .5rem;
}

.ordix-view-tab:hover {
    background: var(--ordix-surface-2);
}

.ordix-view-tab.active {
    background: var(--ordix-matrix);
    color: #fff;
}

.ordix-view-tab i {
    margin-right: .3rem;
    font-size: .78rem;
}

.ordix-search {
    position: relative;
    width: 280px;
    max-width: 100%;
}

.ordix-search i {
    position: absolute;
    left: .75rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ordix-text-tertiary);
    font-size: .9rem;
}

.ordix-search input {
    width: 100%;
    border: 1px solid var(--ordix-border);
    background: var(--ordix-surface);
    border-radius: .5rem;
    padding: .45rem .75rem .45rem 2.1rem;
    font-size: .85rem;
    color: var(--ordix-text);
}

.ordix-search input:focus {
    outline: none;
    border-color: var(--ordix-primary);
    box-shadow: 0 0 0 3px rgba(88, 174, 170, .18);
}

.ordix-kpi-row {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: .9rem;
}

@media (max-width: 900px) {
    .ordix-kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.ordix-kpi-tile {
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

.ordix-kpi-label {
    font-size: .8rem;
    color: var(--ordix-text-secondary);
}

.ordix-kpi-value {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--ordix-text);
    font-variant-numeric: tabular-nums;
}

.ordix-kpi-value.ordix-kpi-warning { color: var(--ordix-warning); }
.ordix-kpi-value.ordix-kpi-error { color: var(--ordix-error); }

.ordix-card {
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    overflow: hidden;
}

.ordix-table {
    font-size: .88rem;
}

.ordix-table thead th {
    background: var(--ordix-surface-2);
    color: var(--ordix-text-tertiary);
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    border-bottom: 1px solid var(--ordix-border);
    padding: .7rem .9rem;
}

.ordix-table tbody td {
    padding: .7rem .9rem;
    border-bottom: 1px solid var(--ordix-border);
}

.ordix-table tbody tr:last-child td {
    border-bottom: none;
}

.ordix-order-row[data-bs-toggle] {
    cursor: pointer;
}

.ordix-order-row[data-bs-toggle]:hover {
    background-color: var(--ordix-surface-2);
}

/* Fila con un borrador ya empezado (ImportedOrder abierto, sin enviar
   todavía) — resaltado a nivel de fila, no solo el badge de estado, para
   que "ya empecé esta orden" salte a la vista sin ir a otra pantalla. */
.ordix-order-row.has-draft td, .ordix-order-row td {
    background-color: var(--ordix-canvas);
}

.ordix-order-row.has-draft:hover td , .ordix-order-row:hover td {
    background-color: var(--ordix-success-bg);
}

.ordix-order-row.worklist-order-row:hover td {
    background-color: var(--ordix-success-bg);
}
.worklist-detail.table tbody tr:hover td {
    background-color: var(--ordix-success-bg);
}

.ordix-draft-flag {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .72rem;
    font-weight: 600;
    color: var(--ordix-info);
    margin-top: .15rem;
}

.ordix-draft-flag i {
    font-size: .68rem;
}

.ordix-type-badge {
    display: inline-block;
    padding: .2rem .55rem;
    border-radius: .35rem;
    font-size: .72rem;
    font-weight: 700;
}

.ordix-type-individual {
    background: var(--ordix-info-bg);
    color: var(--ordix-info);
}

.ordix-type-agrupada {
    background: var(--ordix-special-bg);
    color: var(--ordix-special);
}

/* Orden creada con "Crear orden manual" — no existe en TINA todavía,
   por eso no es ni "individual" ni "agrupada" (esos dos son conceptos
   de TINA). Mismo tratamiento visual que "warning" porque necesita
   acción de la vendedora para llegar a existir de verdad. */
.ordix-type-manual {
    background: var(--ordix-warning-bg);
    color: var(--ordix-warning);
}

.ordix-type-error {
    background: var(--ordix-error-bg);
    color: var(--ordix-error);
}

/* Neutral, no de error — "sin identificar" es el estado normal de la
   mayoría de órdenes hoy (el match automático por CO= casi nunca
   dispara, ver apps/ordix/CLAUDE.md), no una falla puntual. Pintarlo
   de rojo como si fuera un error genera alarma falsa en toda la tabla. */
.ordix-type-neutral {
    background: var(--ordix-surface-2);
    color: var(--ordix-text-tertiary);
    border: 1px dashed var(--ordix-border);
}

.ordix-ticket-chip {
    background: var(--ordix-surface-2);
    color: var(--ordix-text-secondary);
    border-radius: .35rem;
    padding: .1rem .4rem;
    font-size: .74rem;
    font-variant-numeric: tabular-nums;
}

/* Badge de estado — pill rellena (bg suave + texto oscuro + punto en el
   tono base), igual que "Badges de estado en uso" de la guía de
   componentes. El punto (bi-circle-fill) usa el tono BASE (más saturado
   que el texto) — se sobreescribe aparte por variante, más abajo. */
.ordix-status-pill {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .28rem .7rem;
    border-radius: 999px;
    font-size: .78rem;
    font-weight: 600;
    width: fit-content;
}

.ordix-status-pill i {
    font-size: .45rem;
}

.ordix-status-pendiente { background: var(--ordix-warning-bg); color: var(--ordix-warning-text); }
.ordix-status-pendiente i { color: var(--ordix-warning); }
.ordix-status-en_proceso { background: var(--ordix-info-bg); color: var(--ordix-info-text); }
.ordix-status-en_proceso i { color: var(--ordix-info); }
.ordix-status-procesada { background: var(--ordix-success-bg); color: var(--ordix-success-text); }
.ordix-status-procesada i { color: var(--ordix-success); }
.ordix-status-error { background: var(--ordix-error-bg); color: var(--ordix-error-text); }
.ordix-status-error i { color: var(--ordix-error); }
.ordix-status-activo { background: var(--ordix-success-bg); color: var(--ordix-success-text); }
.ordix-status-activo i { color: var(--ordix-success); }
.ordix-status-inactivo { background: var(--ordix-surface-2); color: var(--ordix-text-tertiary); }
.ordix-status-inactivo i { color: var(--ordix-text-tertiary); }

/* --- Clientes: chips de código GDS, select de filtro y link de acción --- */

.ordix-chip {
    display: inline-block;
    padding: .18rem .6rem;
    border-radius: 999px;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    color: var(--ordix-text);
    font-size: .72rem;
    font-weight: 600;
}

.ordix-select {
    border: 1px solid var(--ordix-border);
    background: var(--ordix-surface);
    border-radius: .5rem;
    padding: .45rem .75rem;
    font-size: .85rem;
    color: var(--ordix-text);
}

.ordix-select:focus {
    outline: none;
    border-color: var(--ordix-primary);
    box-shadow: 0 0 0 3px rgba(88, 174, 170, .18);
}

/* --- Cliente / Perfil: header de identidad + layout de tabs verticales
   (client_detail.html, profile_detail.html) — mismo patrón que el
   "ordix-split" de la plantilla (sidebar de tabs 210px + card de
   contenido), reutilizado acá para las 2 pantallas que separan Cliente
   (Datos generales + Códigos GDS) de Perfil (Datos del perfil +
   Formulario dinámico + Reglas QA y facturación). --- */

.ordix-profile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1rem 1.3rem;
}

.ordix-profile-header-identity {
    display: flex;
    align-items: center;
    gap: .9rem;
}

.ordix-profile-header-icon {
    width: 40px;
    height: 40px;
    border-radius: .6rem;
    background: var(--ordix-secondary);
    color: var(--ordix-secondary-text);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    font-size: 1.1rem;
}

.ordix-profile-layout {
    display: flex;
    align-items: flex-start;
    gap: 1.25rem;
}

@media (max-width: 900px) {
    .ordix-profile-layout {
        flex-direction: column;
    }
}

.ordix-profile-nav {
    width: 210px;
    flex: none;
    display: flex;
    flex-direction: column;
    gap: .2rem;
}

@media (max-width: 900px) {
    .ordix-profile-nav {
        width: 100%;
        flex-direction: row;
        flex-wrap: wrap;
    }
}

.ordix-profile-nav-link {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem .75rem;
    border-radius: .5rem;
    font-size: .8rem;
    font-weight: 500;
    color: var(--ordix-text-secondary);
    text-decoration: none;
}

.ordix-profile-nav-link:hover {
    background: var(--ordix-surface-2);
    color: var(--ordix-text);
}

.ordix-profile-nav-link.active {
    background: var(--ordix-secondary);
    color: var(--ordix-secondary-text);
    font-weight: 600;
}

.ordix-profile-nav-link.active::before {
    content: "";
    display: block;
    width: 3px;
    height: 14px;
    border-radius: 2px;
    background: var(--ordix-brand);
    flex: none;
}

.ordix-profile-content {
    flex: 1 1 0;
    min-width: 0;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1.4rem 1.5rem;
}

/* Tarjeta destacada para el vínculo Cliente↔Perfil dentro de Datos
   generales — el perfil puede aplicar a uno o más clientes (decisión de
   Sergio, 2026-09-16), por eso queda como su propia tarjeta con el
   nombre del perfil actual + selector para reasignarlo, no mezclado
   como un campo más del grid. */
.ordix-profile-link-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
    background: var(--ordix-surface-2);
    border: 1px dashed var(--ordix-border);
    border-radius: .6rem;
    padding: .85rem 1rem;
}

/* Inputs/selects de Bootstrap dentro de ORDIX — sin esto, los forms de
   Cliente/Perfil (ClientForm, ClientProfileForm, los formsets) se ven
   con el estilo azul default de Bootstrap en vez de los tokens del
   módulo. Scoped a .ordix-shell para no afectar el admin ni el login. */
.ordix-shell .form-control,
.ordix-shell .form-select {
    border: 1px solid var(--ordix-border);
    border-radius: .5rem;
    padding: .5rem .75rem;
    font-size: .85rem;
    color: var(--ordix-text);
    background-color: var(--ordix-surface);
}

.ordix-shell .form-control:focus,
.ordix-shell .form-select:focus {
    border-color: var(--ordix-primary);
    box-shadow: 0 0 0 3px rgba(88, 174, 170, .18);
}

.ordix-shell .form-control:disabled,
.ordix-shell .form-control[readonly] {
    background-color: var(--ordix-surface-2);
    color: var(--ordix-text-tertiary);
}

.ordix-shell .form-check-input:checked {
    background-color: var(--ordix-brand);
    border-color: var(--ordix-brand);
    padding: 10px;
}

.form-check-input[type=checkbox]{
    padding: 10px;
}

.form-check-input[type=checkbox]:hover{
    padding: 10px;
    cursor:pointer;
}

.ordix-shell label.form-label,
.ordix-shell .form-label {
    font-size: .78rem;
    font-weight: 600;
    color: var(--ordix-text-secondary);
    margin-bottom: .3rem;
}

.ordix-link-action {
    color: var(--ordix-brand);
    font-weight: 600;
    font-size: .82rem;
    text-decoration: none;
}

.ordix-link-action:hover {
    color: var(--ordix-primary);
}

.ordix-btn-primary,
.ordix-btn-outline,
.ordix-btn-soft,
.ordix-table .btn-outline-danger {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-weight: 600;
    padding: .4rem .85rem;
    border-radius: .55rem;
    /* La columna "Acción" de la tabla de Mis Órdenes no tiene ancho fijo
       (solo Nº de orden/Servicios lo tienen, ver dashboard.html) — con
       table-layout:auto (default del navegador) su ancho disponible
       varía de forma NO monótona según el viewport (reportado: el botón
       "Continuar borrador" envolvía a 2 líneas solo entre ~1300-1669px,
       no antes ni después). Un media query fijo a ese rango sería frágil
       — ese rango es un efecto secundario del reparto de columnas, se
       corre si cambia el contenido de CUALQUIER otra columna (nombre de
       cliente, chips de servicio). `nowrap` ataca la causa real (el
       texto del botón envolviendo dentro de su propio flex) en vez del
       síntoma puntual — la tabla ya vive en `.table-responsive`
       (dashboard.html), así que si algún día no entra ni así, scrollea
       en vez de romper el botón. */
    white-space: nowrap;
    transition: transform .1s ease, box-shadow .15s ease, background-color .15s ease;
}

.ordix-btn-primary:hover,
.ordix-btn-outline:hover,
.ordix-btn-soft:hover,
.ordix-table .btn-outline-danger:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px -4px rgba(23, 47, 61, .35);
}

/* "Enviar a planillar" (orden todavía sin abrir/sin borrador) — Outline
   de la guía de componentes: sin relleno, borde y texto en brand. */
.ordix-btn-outline {
    background: var(--ordix-surface);
    border: 1.5px solid var(--ordix-brand);
    color: var(--ordix-brand);
}

.ordix-btn-outline:hover {
    background: var(--ordix-brand);
    border-color: var(--ordix-brand);
    color: #fff;
}

.ordix-btn-outline-success {
    background: var(--ordix-success-bg);
    border: 1.5px solid var(--ordix-success);
    color: var(--ordix-success-text);
}

.ordix-btn-success {
    background: var(--ordix-success);
    border: 1.5px solid var(--ordix-success);
    color: #ffffff;
}

.ordix-btn-success:hover {
    background: var(--ordix-success-text);
    border-color: var(--ordix-success-text);
    color: #fff;
}

.ordix-btn-outline-success:hover {
    background: var(--ordix-success);
    border-color: var(--ordix-success);
    color: #fff;
}

.btn-add{
    height: 43px;
    width: 45px;
}

.btn-add .bi::before {
    vertical-align:0px;
}

.btn-light, .btn-light:hover{
    color: lightgrey !important;
    cursor: not-allowed;
    background: #E4EAED !important;
}


.btn-sm{
    border-radius: .55rem;
}
/* "Continuar borrador" (ya hay un borrador abierto) — Soft de la guía de
   componentes: relleno suave, sin borde. A propósito más "presente" que
   el Outline de arriba, para que la fila con trabajo ya avanzado se
   note primero que las que todavía no se empezaron. El texto usaba
   `--ordix-heading-subtitle` "prestado" (pensado para subtítulos de
   encabezado, no para contrastar contra `--ordix-secondary`) — pedido
   explícito 2026-09-24: pasa a `--ordix-secondary-text`, propio para
   este par fondo/texto y configurable por empresa sin arrastrar
   ningún otro lugar que use subtitle_color. */
.ordix-btn-soft {
    background: var(--ordix-secondary);
    border: none;
    color: var(--ordix-secondary-text);
}

.ordix-btn-soft:hover {
    background: var(--ordix-primary);
    color: #fff;
}

.ordix-btn-primary {
    background: var(--ordix-primary);
    border-color: var(--ordix-primary);
    color: #fff;
}

.ordix-btn-primary:hover {
    background: var(--ordix-brand);
    border-color: var(--ordix-brand);
    color: #fff;
}

/* SweetAlert2 (2026-09-22) — solo para el diálogo de confirmación de
   "Quitar"/"Sacar del grupo" en el wizard (ver _wizard_step1.html).
   `buttonsStyling: false` en el JS deja los botones sin el estilo default
   de la librería para poder reusar las clases reales del proyecto
   (`.ordix-btn-primary`/`.ordix-btn-outline`) en vez de un color hardcodeado
   aparte — así el popup se siente parte de ORDIX, no un widget ajeno
   pegado encima. Solo tipografía/radius/espaciado acá, nada de color: los
   botones ya traen el suyo por sus propias clases. */
.ordix-swal-popup {
    font-family: 'Inter', sans-serif;
    border-radius: 1rem;
}

.ordix-swal-popup .swal2-actions {
    gap: .5rem;
}

.ordix-summary {
    display: flex;
    align-items: stretch;
    gap: .9rem;
    flex-wrap: wrap;
}

.ordix-summary .ordix-kpi-row {
    flex: 1 1 420px;
}

.ordix-status-chart {
    flex: 0 0 auto;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 1.1rem;
}

.ordix-donut {
    width: 84px;
    height: 84px;
    border-radius: 50%;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ordix-donut-hole {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--ordix-surface);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1.1;
}

.ordix-donut-total {
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--ordix-text);
    font-variant-numeric: tabular-nums;
}

.ordix-donut-total-label {
    font-size: .6rem;
    color: var(--ordix-text-tertiary);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.ordix-donut-legend {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(2, auto);
    gap: .4rem 1.4rem;
    font-size: .78rem;
    color: var(--ordix-text-secondary);
    white-space: nowrap;
}

.ordix-donut-legend b {
    color: var(--ordix-text);
    font-variant-numeric: tabular-nums;
    margin-left: .25rem;
}

.ordix-donut-legend .dot {
    display: inline-block;
    width: .55rem;
    height: .55rem;
    border-radius: 50%;
    margin-right: .4rem;
}

.dot-pendiente { background: var(--ordix-warning); }
.dot-en_proceso { background: var(--ordix-info); }
.dot-procesada { background: var(--ordix-success); }
.dot-error { background: var(--ordix-error); }

@media (max-width: 900px) {
    .ordix-status-chart { flex: 1 1 100%; }
}

.worklist-detail {
    background-color: #f8f9fb;
    border-top: 1px solid #e9ecef;
    border-bottom: 1px solid #e9ecef;
    padding: .5rem 1rem .5rem 3rem;
}

/* =====================================================================
   Wizard de orden (group_workspace) — 4 pasos, ORDIX-mockups-v2/
   4.Planillaje. Reusa tokens --ordix-* y clases ya definidas arriba
   (ordix-card, ordix-type-badge, ordix-status-pill, ordix-btn-*).
===================================================================== */

/* Header del wizard (group_workspace.html) — reemplaza el contenido
   default de {% block navbar_left %} ("Ir al Panel principal") en el
   MISMO topstrip compartido, en vez de un bloque .wizard-topbar aparte
   debajo (rediseño 2026-09-18, para que quede en una sola fila con el
   selector de empresa/usuario, como en el mockup). Un solo `<div>`
   flex (no varios elementos sueltos) para que se comporte como un
   único flex-item dentro de `.container-fluid` del navbar, con su
   propio gap interno — si no, cada `<a>`/`<span>` quedaría espaciado
   por el `justify-content` del navbar en vez de por un gap parejo. */
.wizard-header-left {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .6rem;
}

.wizard-back {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    color: var(--ordix-text-secondary);
    text-decoration: none;
    font-size: .85rem;
    font-weight: 600;
}

.wizard-back:hover { color: var(--ordix-brand); }

/* Separador vertical fino entre "Volver a Mis Órdenes" y "OrderId" —
   pedido explícito del mockup, no solo el gap del flex. */
.wizard-header-sep {
    width: 1px;
    height: 18px;
    background: var(--ordix-border);
    flex: none;
}

.wizard-orderid {
    font-weight: 700;
    color: var(--ordix-text);
}

.wizard-client-name {
    color: var(--ordix-text-secondary);
    font-size: .88rem;
}

/* Sidebar colapsable en TODO ORDIX (generalizado 2026-09-29 — antes
   "modo foco" exclusivo del wizard, pedido explícito: "aplicar el botón
   de ocultar/mostrar sidebar a todas las pantallas que no sea exclusivo
   del wizard"). El estado colapsado ahora es una clase genérica en
   `#ordixShell` (`.ordix-sidebar-collapsed`, agregada/quitada por
   static/js/ordix.js), no atada a `.ordix-shell-focus` — esa clase
   sigue viviendo SOLO en group_workspace.html (el wizard,
   `{% block shell_class %}`) pero ahora es apenas la señal de "esta
   pantalla arranca colapsada por defecto" que lee el JS antes de mirar
   localStorage (decisión original de Sergio, 2026-09-18: minimizar
   distracciones durante el planillaje) — el resto de ORDIX (Mis
   Órdenes, Clientes, Perfiles, etc.) arranca expandido, que es su
   comportamiento de siempre, pero AHORA con la misma pestaña disponible
   para colapsarlo si el usuario quiere. Preferencia recordada en
   localStorage por navegador, una sola clave para todo el módulo — no
   por pantalla (ver static/js/ordix.js).
   Colapsa por WIDTH, no por display (2026-09-18: con display:none/flex
   el cambio era instantáneo, sin transición posible — "se cierra y
   abre bruscamente", feedback de Sergio). No hace falta pelear con el
   !important de d-md-flex de Bootstrap para esto: a partir de 768px
   ese breakpoint YA deja `.ordix-sidebar` en `display:flex` siempre,
   así que alcanza con animar su ancho. `.ordix-main` (flex:1) rellena
   el espacio solo, sin reglas nuevas — por eso el contenido también se
   desliza suave en vez de saltar.
   Colapsa a un RIEL de íconos (64px), no a 0 (2026-09-30, pedido
   explícito: "el sidebar comprimido debe mostrar al menos los
   íconos" — antes desaparecía del todo, `width:0`/`opacity:0`/
   `pointer-events:none`). Sigue siendo clickeable/tabulable en los dos
   estados — ya no hace falta `pointer-events:none` ni animar
   `opacity`, el contenido nunca deja de ser visible, solo más angosto.
   El texto de cada link se oculta con las reglas de más abajo
   (`.ordix-nav-link`), no acá. */
#ordixShell.ordix-sidebar-collapsed .ordix-sidebar {
    width: 64px;
    min-width: 64px;
    padding-left: .5rem;
    padding-right: .5rem;
    overflow-x: hidden;
    transition: width .24s ease, padding .24s ease;
}

/* Sin la clase (default en toda pantalla que no sea el wizard, o el
   wizard una vez que el usuario lo abrió) el ancho/padding ya vienen
   de `.ordix-sidebar` de más arriba — acá solo se agrega la
   transición, para la animación de REVELAR al salir del estado
   colapsado. */
#ordixShell:not(.ordix-sidebar-collapsed) .ordix-sidebar {
    transition: width .24s ease, padding .24s ease;
}

/* Riel de íconos: el ancho colapsado (64px, arriba) alcanza para el
   ícono pero no para el texto del link — se oculta con `font-size:0`
   en el contenedor (el HTML de `_sidebar_nav.html` no envuelve el
   texto en un `<span>` propio, es un nodo de texto suelto junto al
   `<i>` del ícono, así que no hay un elemento para esconder con
   `display:none`) y se lo devuelve explícito en `.ordix-nav-link i`
   (que ya fija su propio `font-size`, no hereda el 0 del padre). Cada
   link tiene además `title` (ver `_sidebar_nav.html`) como tooltip
   nativo que reemplaza al texto visible mientras está colapsado. La
   barra de acento del link activo (`::before`) se esconde — centrada
   junto a un ícono solo, sin el texto al lado, se leía como un adorno
   suelto; el fondo de color de `.active` ya alcanza para marcar cuál
   es. */
#ordixShell.ordix-sidebar-collapsed .ordix-logo-text {
    display: none;
}

#ordixShell.ordix-sidebar-collapsed .ordix-sidebar-brand {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

#ordixShell.ordix-sidebar-collapsed .ordix-nav-link {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
    font-size: 0;
}

#ordixShell.ordix-sidebar-collapsed .ordix-nav-link i {
    font-size: 1.05rem;
}

#ordixShell.ordix-sidebar-collapsed .ordix-nav-link.active::before {
    display: none;
}

/* Suprime la transición para el estado inicial al cargar la página
   (ver static/js/ordix.js) — sin esto, una preferencia recordada
   "expandido" animaría de 64px→220px apenas carga, como si el usuario
   hubiera hecho click. */
.ordix-sidebar-no-transition .ordix-sidebar,
.ordix-sidebar-no-transition .ordix-sidebar-toggle-tab {
    transition: none !important;
}

/* Pestaña única de abrir/cerrar sidebar — reemplaza al botón chico que
   vivía en .wizard-topbar (2026-09-18, feedback de Sergio: se perdía
   ahí arriba y el usuario tenía que pensarlo dos veces). Un solo
   control, siempre en la misma altura vertical (top:50%) tanto para
   abrir como para cerrar — colapsado (riel de íconos, 64px) queda
   pegada al borde derecho de ese riel; expandido (default en toda
   pantalla que no sea el wizard) se desplaza a 220px (el ancho de
   .ordix-sidebar) para quedar pegada al borde derecho del sidebar,
   como si fuera parte de él. El ícono lo swapea static/js/ordix.js
   (chevron-right = "abrir", chevron-left = "cerrar") para que la
   flecha siempre apunte hacia adonde se va a mover el sidebar. Mismo
   fondo oscuro que el sidebar para que se lea como parte de él. Fija
   al viewport (no al scroll de la página) para que siga alcanzable
   aunque el usuario haya bajado en el contenido. Visible en TODO
   ORDIX en desktop (2026-09-29, ver comentario de arriba) — en mobile
   el sidebar ya vive en el offcanvas de siempre (hamburguesa en
   .ordix-mobile-topbar), no hace falta otra manija más. */
.ordix-sidebar-toggle-tab {
    display: none;
    position: fixed;
    left: 220px;
    top: 50%;
    transform: translateY(-50%);
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 64px;
    border: none;
    border-radius: 0 .6rem .6rem 0;
    background: var(--ordix-matrix);
    color: #fff;
    font-size: .9rem;
    z-index: 40;
    box-shadow: 2px 0 10px rgba(23, 47, 61, .22);
    transition: left .24s ease, width .12s ease, background-color .12s ease;
}

@media (min-width: 768px) {
    .ordix-sidebar-toggle-tab {
        display: flex;
    }
}

#ordixShell.ordix-sidebar-collapsed .ordix-sidebar-toggle-tab {
    left: 64px;
}

.ordix-sidebar-toggle-tab:hover {
    width: 27px;
    background: var(--ordix-brand);
}

@media (max-width: 767.98px) {
    .ordix-sidebar-toggle-tab {
        display: none !important;
    }
}

/* Rediseño 2026-09-18 (mockup): antes era una "card" flotante (borde +
   radius + sombra) con el número ARRIBA y la etiqueta DEBAJO de cada
   paso. Ahora va pegada directo debajo del header (mismo fondo blanco)
   y cada paso es número+etiqueta en una misma fila, no apilados —
   igual que en el mockup.
   Vive DENTRO de `.ordix-main-header` (2026-10-01, bloque
   `main_header_extra` de `group_workspace.html`) — ya NO es sticky por
   su cuenta ni necesita `top`/`margin` propios: hereda la posición y
   el ancho completo de su contenedor, que ya está pegado arriba y
   cancelado el padding de `.ordix-main`. Solo le queda separarse
   visualmente de la fila de breadcrumb de arriba (`border-top`) y
   centrar los pasos. */
.wizard-stepper {
    display: flex;
    align-items: center;
    justify-content: center;
    border-top: 1px solid var(--ordix-border);
    padding: 1.1rem 2rem;
    overflow-x: auto;
}

@media (max-width: 767.98px) {
    .wizard-stepper {
        padding: 1rem;
    }
}

.wizard-step {
    display: flex;
    align-items: center;
    gap: .6rem;
    text-decoration: none;
    flex: none;
}

.wizard-step-circle {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 2px solid var(--ordix-border);
    color: var(--ordix-text-tertiary);
    background: var(--ordix-surface);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: .8rem;
    flex: none;
}

.wizard-step-label {
    font-size: .88rem;
    font-weight: 600;
    color: var(--ordix-text-tertiary);
    white-space: nowrap;
}

.wizard-step.active .wizard-step-circle {
    background: var(--ordix-matrix);
    border-color: var(--ordix-matrix);
    color: #fff;
}

.wizard-step.active .wizard-step-label { color: var(--ordix-text); }

.wizard-step.done .wizard-step-circle {
    border-color: var(--ordix-success);
    background: var(--ordix-success);
    color: #fff !important;
}

.wizard-step.done .wizard-step-label { color: var(--ordix-success); }

/* Ancho fijo, no `flex:1` (2026-09-29, pedido explícito con mockup de
   referencia) — antes la línea conectora crecía para llenar TODO el
   ancho del stepper, empujando los pasos a los extremos de la pantalla
   en vez de mantenerlos agrupados como un solo bloque compacto (así se
   ve en el mockup de referencia: los pasos quedan pegados entre sí a la
   izquierda, con espacio vacío a la derecha del último paso, no
   repartidos a lo ancho de toda la barra). */
.wizard-step-line {
    flex: none;
    width: 56px;
    height: 2px;
    background: var(--ordix-border);
    margin: 0 1rem;
}

.wizard-step-line.done { background: var(--ordix-success); }

.wizard-body {
    display: grid;
    grid-template-columns: 1fr 350px;
    gap: 1.25rem;
    align-items: start;
    min-height: 680px;
}

.wizard-body-single { display: block; }

@media (max-width: 900px) {
    .wizard-body { grid-template-columns: 1fr; }
}

/* Título + subtítulo de cada paso del wizard, en la MISMA línea (antes
   el subtítulo quedaba apilado debajo como párrafo aparte — pedido de
   Sergio 2026-09-18: "esto en una sola línea"). `align-items:baseline`
   para que el subtítulo (más chico) se alinee con la línea de base del
   título en vez del centro; `flex-wrap:wrap` como respaldo — si el
   subtítulo es largo (ej. el de Remarks y Documentos) igual pasa a la
   línea de abajo solo, no se lo fuerza a desbordar. */
.wizard-step-header {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .5rem;
    margin-bottom: 1.1rem;
}

.wizard-step-title {
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--ordix-text);
    margin: 0;
}

.wizard-step-sub {
    color: var(--ordix-heading-subtitle);
    font-size: .9rem;
    margin: 0;
}

/* Mismo tratamiento visual que `.wizard-client-error` (2026-09-18,
   pedido de Sergio: "aplicar el mismo estilo... pero en verde") — solo
   cambia el color (éxito, no error). Panel único sin borde, fondo
   tintado, ícono en badge. */
.wizard-client-card {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    background: var(--ordix-success-bg);
    border-radius: .75rem;
    padding: 1.1rem 1.25rem;
    margin-bottom: 1rem;
}


/* El bloque de texto (nombre del cliente / aviso de "sin cliente") es
   flex-grow-1 — sin min-width:0 un nombre largo empuja el ancho del
   flex row entero más allá de la pantalla en vez de truncar/wrapear
   (el bug clásico de flexbox: los items no encogen bajo su contenido
   por default). Aplica tanto al card con cliente como al vacío. */
.wizard-client-card .flex-grow-1,
.wizard-client-error .flex-grow-1 {
    min-width: 0;
}

/* Selector de cliente con búsqueda (combobox liviano, sin dependencias
   externas) — antes un <select> nativo con TODOS los clientes activos
   como <option>, incómodo para tipear/encontrar con una cartera grande
   y con nombres de cliente largos apretados en un ancho fijo chico.
   Reutilizable vía orders/_client_select.html en cualquier form que
   pida elegir un cliente (hoy: asignar/cambiar cliente en el wizard
   paso 1) — ver static/js/ordix.js para el comportamiento. */
.ordix-searchable-select {
    position: relative;
    flex: 1 1 300px;
    min-width: 0;
}

.ordix-searchable-select input[type="text"] {
    width: 100%;
}

.ordix-searchable-select input[type="text"]:hover{
    cursor: text;
}

.ordix-searchable-select-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 20;
    max-height: 240px;
    overflow-y: auto;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .5rem;
    box-shadow: 0 12px 28px rgba(23, 47, 61, .18);
    display: none;
    padding: .3rem;
}

.ordix-searchable-select.open .ordix-searchable-select-menu {
    display: block;
}

.ordix-searchable-select-option {
    padding: .45rem .6rem;
    border-radius: .4rem;
    font-size: .82rem;
    color: var(--ordix-text);
    cursor: pointer;
}

.ordix-searchable-select-option:hover {
    background: var(--ordix-surface-2);
}

.ordix-searchable-select-option-sub {
    font-size: .74rem;
    color: var(--ordix-text-tertiary);
}

.ordix-searchable-select-empty {
    padding: .5rem .6rem;
    font-size: .8rem;
    color: var(--ordix-text-tertiary);
}

@media (max-width: 575.98px) {
    /* El form de asignar/cambiar cliente (buscador + botón) pasa a
       ocupar todo el ancho de la tarjeta, debajo del ícono+texto, en
       vez de compartir la misma fila apretados. */
    .wizard-client-card > form,
    .wizard-client-error > form,
    .wizard-change-client {
        width: 100%;
    }

    .wizard-client-card form,
    .wizard-client-error form {
        flex-wrap: wrap;
    }

    .wizard-client-card .ordix-searchable-select,
    .wizard-client-error .ordix-searchable-select {
        flex-basis: 100%;
        width: 100%;
    }

    .wizard-client-card form button,
    .wizard-client-error form button {
        width: 100%;
    }
}

.wizard-client-icon {
    width: 40px;
    height: 40px;
    border-radius: .6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    flex: none;
}

/* Variante "hay cliente" (verde) — misma lógica que
   `.wizard-client-icon-danger`: mismo fondo que el panel que lo
   contiene, con un borde propio para que igual se distinga como badge
   en vez de perderse contra el fondo. */
.wizard-client-icon-success {
    background: var(--ordix-success-bg);
    color: var(--ordix-success);
    border: 1.5px solid var(--ordix-success);
}

.wizard-client-card-label {
    font-size: .74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--ordix-text-tertiary);
}

.wizard-client-card-name {
    font-weight: 700;
    color: var(--ordix-text);
}

.wizard-client-card-hint {
    font-size: .78rem;
    color: var(--ordix-text-tertiary);
}

/* "Cambiar cliente" pasó de link de texto suelto a botón outline real
   (2026-09-18, pedido de Sergio: "para que los usuarios sepan que ahí
   hay un botón") — las clases `btn btn-sm ordix-btn-outline` ya
   definen color/padding/borde; acá solo hace falta anular el marcador
   nativo de `<summary>` (list-style + el pseudo-elemento de Chrome/
   Safari) para que no le queden ni el triángulo ni la viñeta al lado
   del ícono. `display:inline-flex` (heredado de `.ordix-btn-outline`)
   ya alcanza para sacarlo del `display:list-item` default de
   `<summary>`, pero el marcador de WebKit es un pseudo-elemento aparte
   — necesita su propia regla. */
.wizard-change-client summary {
    cursor: pointer;
    list-style: none;
}

.wizard-change-client summary::-webkit-details-marker { display: none; }

/* Al abrirse, el pill "Cambiar cliente" (el <summary>) se esconde — antes
   se quedaba visible arriba del select+"Cambiar" que aparece debajo, dos
   llamados a la acción compitiendo a la vez (reportado 2026-09-22). El
   "Cancelar" del form (ver _wizard_step1.html) cierra el <details> de
   nuevo, que lo vuelve a mostrar solo. */
.wizard-change-client[open] summary { display: none; }

/* `padding` horizontal igual al de `.wizard-client-card`/
   `.wizard-client-error` de arriba (1.25rem) — antes era 1rem, un
   desalineamiento de 4px entre el borde izquierdo del bloque de
   cliente y el de servicios que se notaba al tener los dos bloques
   apilados uno debajo del otro (pedido de Sergio 2026-09-18: "que
   vaya alineado igual que el bloque de empresa asignada"). */
/* Tira de progreso del paso 2 (2026-09-24) — mapa rápido de todos los
   servicios (completos o no) con acceso directo por punto; el template
   solo la renderiza para órdenes de 2 a 20 servicios (ver
   _wizard_step2.html) — con más, una fila de puntos deja de ser
   legible y el buscador/filtro es el mecanismo real de navegación. */
.wizard-progress-strip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .6rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: .75rem 1.25rem;
    margin-bottom: 1rem;
}

.wizard-progress-strip-text {
    font-size: .85rem;
    color: var(--ordix-text);
}

.wizard-progress-strip-text strong { color: var(--ordix-brand); }

.wizard-progress-dots {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}

.wizard-progress-dot {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 1.5px solid var(--ordix-border);
    background: var(--ordix-canvas);
    color: var(--ordix-text-tertiary);
    font-size: .75rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}

.wizard-progress-dot:hover {
    border-color: var(--ordix-brand);
    color: var(--ordix-brand);
}

/* Verde: servicio completo — mismo tono que `.wizard-status-ok`. */
.wizard-progress-dot.is-complete {
    border-color: var(--ordix-success);
    color: var(--ordix-success);
}

/* Oscuro y relleno: el servicio que está abierto AHORA MISMO — se
   sincroniza en `setOpen()` (_wizard_step2.html), así que sigue siendo
   fiel aunque se abra/cierre una tarjeta por cualquier otro camino
   (clic en el header, un link con `#servicio-N`, un punto de acá
   mismo). Gana sobre `.is-complete` si las dos aplican a la vez. */
.wizard-progress-dot.is-active {
    background: var(--ordix-matrix);
    border-color: var(--ordix-matrix);
    color: #fff;
}

.wizard-services-card {
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1.25rem;
}

.wizard-services-header {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--ordix-text-tertiary);
    margin: 0;
}

/* Rediseño 2026-09-18 (mockup, pedido explícito de Sergio): la card de
   servicios ganó una cabecera propia (título+descripción / toggle
   cuadrícula-lista / botón agregar) y una fila de filtros Todos-
   Vinculados-Manuales (`linked_orders`/`manual_orders`, ya calculados
   en la vista, ver orders/views.py — no hay que recontar nada acá). */
.wizard-services-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .85rem;
    margin-bottom: 1rem;
}

.wizard-services-intro {
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.wizard-services-desc {
    margin: 0;
    font-size: .82rem;
    color: var(--ordix-text-secondary);
}

.wizard-services-controls {
    display: flex;
    align-items: center;
    gap: .6rem;
    flex-wrap: wrap;
}

/* Control segmentado (dos botones, uno "presionado") — mismo patrón
   visual que `.ordix-btn-outline`/`.ordix-btn-primary` pero como un
   único grupo con borde compartido, no dos botones sueltos. */
.wizard-view-toggle {
    display: inline-flex;
    border: 1px solid var(--ordix-border);
    border-radius: .55rem;
    overflow: hidden;
}

.wizard-view-btn {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    border: none;
    background: var(--ordix-surface);
    color: var(--ordix-text-secondary);
    font-size: .8rem;
    font-weight: 600;
    padding: .4rem .75rem;
}

.wizard-view-btn + .wizard-view-btn {
    border-left: 1px solid var(--ordix-border);
}

.wizard-view-btn.active {
    background: var(--ordix-matrix);
    color: #fff;
}

.wizard-services-filters {
    margin-bottom: 1rem;
    padding-bottom: .85rem;
    border-bottom: 1px solid var(--ordix-border);
}

.wizard-filter-count {
    font-size: .74rem;
    opacity: .75;
}

/* Servicios de la orden — cuadrícula de cartas (mockup "cuadrícula
   exploración"), no una lista de filas apiladas. */
.wizard-services-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: .75rem;
}

.wizard-service-card {
    background: var(--ordix-surface-2);
    border: 1px solid transparent;
    border-radius: .6rem;
    padding: .85rem .95rem;
    display: flex;
    flex-direction: column;
    gap: .55rem;
}

.wizard-service-card-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .6rem;
}

.wizard-service-badges {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .35rem;
}

/* Reemplaza al título fijo "Servicio Pasajes Aéreos" — ícono del tipo +
   nombre del pasajero (o "Sin pasajero en TINA" si TINA no lo mandó
   para ese ticket), pedido explícito de Sergio: "quita el título...
   y en su lugar agrega el nombre". */
.wizard-service-card-main {
    display: flex;
    align-items: center;
    gap: .6rem;
}

.wizard-service-name {
    font-weight: 700;
    color: var(--ordix-text);
    font-size: .92rem;
}

.wizard-service-type-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .55rem;
    border-radius: .4rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    color: var(--ordix-text-secondary);
    font-size: .72rem;
    font-weight: 600;
}

/* Antes solo texto plano — pasó a badge (pill) real para que se lea al
   mismo nivel que el badge de tipo al lado. */
.wizard-locked-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .55rem;
    border-radius: .4rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    font-size: .72rem;
    font-weight: 600;
    color: var(--ordix-text-tertiary);
    white-space: nowrap;
}

.wizard-crossgroup-badge {
    color: var(--ordix-accent, #a0632c);
    border-color: var(--ordix-accent, #a0632c);
}

.wizard-manual-badge {
    color: var(--ordix-primary);
    border-color: var(--ordix-primary);
}

/* Botón de quitar/sacar del grupo — icono nomás, mismo tratamiento que
   otros botones-ícono chicos del proyecto (ej. `.ordix-sidebar-
   toggle-tab:hover`: se pone más "presente" recién al hover). */
.wizard-service-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    /*border: none;*/
    /*border-radius: .4rem;*/
    background: transparent;
    /*color: var(--ordix-text-tertiary);*/
    font-size: .8rem;
    flex: none;
    border: 2px solid #ddd;
    border-radius: 50%;
    color: var(--ordix-error);
    border: 1px solid var(--ordix-error);
}

.wizard-service-remove:hover {
    background: var(--ordix-error-bg);
    border: 1px solid var(--ordix-error);
    border-radius: 50%;
    color: var(--ordix-error);
}

.wizard-service-icon {
    width: 34px;
    height: 34px;
    border-radius: .5rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ordix-text-secondary);
    flex: none;
}

/* Cuadrícula Y Lista del paso 1 (pedido explícito 2026-09-24, la Lista
   sumada a pedido — mismo formato en las dos vistas): el ícono lleva
   ADEMÁS la descripción del tipo de servicio adentro (ver el `<p>` en
   _wizard_step1.html, tanto en `.wizard-service-card-main
   .wizard-service-icon` como en `.wizard-service-row-icon`) — sin este
   selector, ícono y texto quedaban amontonados lado a lado en la misma
   caja de 34px pensada para un ícono solo. Acá se agranda la caja y se
   apilan en columna (ícono arriba, descripción abajo). */
.wizard-service-card-main .wizard-service-icon,
.wizard-service-row-icon {
    width: 56px;
    /* Antes height:56px fijo — con la descripción en 2 líneas (ver el
       párrafo de abajo) el contenido puede pasarse de 56px de alto y
       se cortaba contra el ícono; min-height mantiene el tamaño de
       antes como piso, pero deja crecer la caja si hace falta. */
    min-height: 56px;
    height: auto;
    flex-direction: column;
    gap: .15rem;
    padding: .3rem;
    border-radius: .65rem;
    font-size: 1.3rem;
}

/* Antes truncado a 1 línea con "…" (pedido explícito 2026-09-24: en 2
   líneas para que se lea completo, no cortado) — `-webkit-line-clamp`
   corta recién a la 3ª línea con "…" si el nombre del tipo es MUY
   largo, en vez de un `white-space:nowrap` que cortaba casi cualquier
   nombre real ("Pasajes Aéreos" ya no entraba en una sola línea de
   56px). Soporte de `-webkit-line-clamp` es universal en navegadores
   modernos (Chrome/Edge/Firefox/Safari), no hace falta fallback. */
.wizard-service-card-main .wizard-service-icon p,
.wizard-service-row-icon p {
    margin: 0;
    max-width: 100%;
    font-size: .55rem;
    font-weight: 600;
    line-height: 1.15;
    text-align: center;
    color: var(--ordix-text-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}

/* Recuadro "Agregar servicio" al final de la cuadrícula (2026-09-21,
   pedido explícito de Sergio: mantenerlo como estaba antes de que el
   botón se moviera al header de la card, ver `.wizard-services-controls`
   más arriba — ese botón de header se sacó, este recuadro + el botón de
   `.wizard-add-service-row` de la lista son ahora el único punto de
   entrada, uno por vista). Sin `data-service-filter`, así el filtro
   Todos/Vinculados/Manuales de `_wizard_step1.html` nunca lo esconde. */
.wizard-add-service-tile {
    background: none;
    border: 1px dashed var(--ordix-border);
    border-radius: .6rem;
    padding: 1.2rem;
    color: var(--ordix-primary);
    font-weight: 600;
    font-size: .88rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: 108px;
}

.wizard-add-service-tile:hover {
    background: var(--ordix-surface-2);
    border-color: var(--ordix-primary);
}

.wizard-add-service-tile:disabled {
    color: var(--ordix-text-tertiary);
    border-color: var(--ordix-border);
    cursor: not-allowed;
    opacity: .6;
}

.wizard-add-service-tile:disabled .wizard-add-service-icon {
    background: var(--ordix-surface);
    color: var(--ordix-text-tertiary);
}

.wizard-add-service-icon {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--ordix-secondary);
    color: var(--ordix-secondary-text);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
}

/* Vista "Lista" (mockup wizard-paso1b-individual.html) — filas
   horizontales en vez de cuadrícula de cartas, mismo dato, otro
   acomodo: útil cuando hay muchos servicios y conviene escanear
   verticalmente en vez de en cuadrícula. */
.wizard-services-list {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.wizard-service-row {
    display: flex;
    align-items: center;
    gap: .85rem;
    background: var(--ordix-surface-2);
    border-radius: .6rem;
    padding: .7rem .95rem;
}

.wizard-service-row-icon {
    background: var(--ordix-surface);
}

.wizard-service-row-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .2rem;
}

.wizard-service-row-badges {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .35rem;
    flex: none;
}

@media (max-width: 575.98px) {
    .wizard-service-row {
        flex-wrap: wrap;
    }

    .wizard-service-row-badges {
        width: 100%;
        order: 3;
    }
}

/* Mismo recuadro "Agregar servicio" que `.wizard-add-service-tile`
   arriba, pero como fila de ancho completo al final del listado — pedido
   explícito de Sergio (2026-09-21): en modo Lista el botón va al final
   del listado, no arriba del todo. */
.wizard-add-service-row {
    width: 100%;
    background: none;
    border: 1px dashed var(--ordix-border);
    border-radius: .6rem;
    padding: .7rem .95rem;
    color: var(--ordix-primary);
    font-weight: 600;
    font-size: .88rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
}

.wizard-add-service-row:hover {
    background: var(--ordix-surface-2);
    border-color: var(--ordix-primary);
}

.wizard-add-service-row:disabled {
    color: var(--ordix-text-tertiary);
    border-color: var(--ordix-border);
    cursor: not-allowed;
    opacity: .6;
}

.wizard-add-service-row:disabled .wizard-add-service-icon {
    background: var(--ordix-surface);
    color: var(--ordix-text-tertiary);
}

/* Fijo y con scroll propio, acotado al viewport (2026-09-24, mismo
   pedido de "header y footer fijos, scroll solo en el contenido") —
   ANTES `.wizard-body` (CSS Grid de una sola fila, contenido + este
   sidebar) se estiraba a la altura del que fuera más alto de los dos;
   con "Validaciones de este paso" largo (muchos pendientes) y el
   contenido principal corto (ej. un servicio ya "Completo" colapsado),
   el sidebar terminaba dictando una fila gigante — dejaba un hueco en
   blanco enorme antes de `.wizard-footer` y, como el footer quedó
   sticky, ese hueco se leía como "scroll extra de toda la página que
   no lleva a ningún lado" (reportado con captura, 2026-09-24;
   confirmado midiendo en vivo: sidebar 1049px vs contenido 269px en un
   caso real). `max-height` acá evita que el sidebar (y por lo tanto la
   fila entera del grid) crezca sin límite — si sus propias tarjetas no
   entran, scrollea DENTRO del sidebar, no empuja el layout. `top`
   coincide con el alto real de `.ordix-main-header` (2026-10-01: antes
   había que sumar DOS números — el topstrip global aparte más el
   stepper — ahora el stepper vive DENTRO de `.ordix-main-header`, así
   que es un solo bloque, una sola medida) para que quede pegado justo
   debajo, sin superponerse. */
.wizard-sidebar {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: sticky;
    top: 123px;
    max-height: calc(100vh - 123px - 1.5rem);
    overflow-y: auto;
}

.wizard-summary-card,
.wizard-help-card {
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1.1rem 1.2rem;
}

.wizard-summary-title,
.wizard-help-title {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--ordix-text-tertiary);
    margin-bottom: .6rem;
}

.wizard-summary-orderid {
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--ordix-text);
    margin-bottom: .7rem;
}

.wizard-summary-row {
    display: flex;
    justify-content: space-between;
    font-size: .85rem;
    color: var(--ordix-text-secondary);
    padding: .3rem 0;
}

.wizard-summary-row b { color: var(--ordix-text); font-variant-numeric: tabular-nums; }

.wizard-summary-total {
    display: flex;
    justify-content: space-between;
    border-top: 1px solid var(--ordix-border);
    margin-top: .5rem;
    padding-top: .6rem;
    font-weight: 600;
    color: var(--ordix-text);
}

.wizard-summary-total b { color: var(--ordix-brand); }

.wizard-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin: .5rem 0;
}

.wizard-chip {
    background: var(--ordix-surface-2);
    border-radius: .4rem;
    padding: .25rem .55rem;
    font-size: .76rem;
    font-weight: 600;
    color: var(--ordix-text-secondary);
    font-variant-numeric: tabular-nums;
}

.wizard-chip-manual {
    background: var(--ordix-error-bg);
    color: var(--ordix-error);
}

.wizard-help-card p { font-size: .82rem; color: var(--ordix-text-secondary); margin: 0; }

.wizard-help-warning { border-color: var(--ordix-warning); background: var(--ordix-warning-bg); }
.wizard-help-warning .wizard-help-title { color: var(--ordix-warning); }
.wizard-help-warning p { color: var(--ordix-text); }

/* Banner de advertencia si falta cliente */
.wizard-client-warning {
    background: var(--ordix-warning-bg);
    border: 1px solid var(--ordix-warning);
    border-radius: .6rem;
    padding: .75rem .95rem;
    font-size: .85rem;
    color: var(--ordix-text);
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .75rem;
}


.wizard-client-warning i {
    color: var(--ordix-warning);
    font-size: .95rem;
    flex: none;
}


/* Rediseño 2026-09-18 (mockup): antes vivía DENTRO de un
   .wizard-client-card.wizard-client-card-empty (borde punteado extra
   alrededor de este mismo box con borde sólido) — un doble-borde que
   no está en el mockup, que muestra un solo panel. Se sacó ese
   wrapper; este es ahora el único box. */
.wizard-client-error {
    background: var(--ordix-error-bg);
    border-radius: .75rem;
    padding: 1.1rem 1.25rem;
    font-size: .85rem;
    color: var(--ordix-error-text);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1rem;
}


.wizard-client-error i {
    color: var(--ordix-error);
    font-size: .95rem;
    flex: none;
}

/* Título del aviso — a propósito NO reutiliza .wizard-client-card-label
   (fuerza uppercase con text-transform, y el mockup solo tiene en caps
   la primera oración; la segunda va en minúscula tal cual el mockup). */
.wizard-client-error-title {
    font-size: .95rem;
    color: var(--ordix-error-text);
    line-height: 1.4;
}

/* Variante roja del badge de ícono (`.wizard-client-icon` por defecto
   usa los tonos "hay cliente" — secondary/brand); acá es la variante
   "falta cliente". */
.wizard-client-icon-danger {
    background: var(--ordix-error-bg);
    color: var(--ordix-error);
    border: 1.5px solid var(--ordix-error);
}

/* Fijo al fondo del viewport mientras se scrollea (2026-09-24, pedido
   explícito) — mismo patrón `position: sticky; bottom: 0;` que ya usa
   `.ordix-sticky-actionbar` (drawer de "Buscar servicio existente"),
   adaptado: acá el fondo es `--ordix-canvas` (el gris del body de
   ORDIX, no `--ordix-surface` blanco) porque `.wizard-footer` vive
   suelto en `.wizard-main`, no dentro de una card blanca — sin un fondo
   opaco propio, el contenido de más arriba se vería pasar por DEBAJO
   del footer al scrollear. `.ordix-main` no tiene su propio scroll
   interno (no hay `overflow`/`height` en esa clase) — el que scrollea
   es el documento entero, así que `sticky` engancha contra el viewport
   como se espera, sin necesitar ningún wrapper nuevo.
   `margin-bottom` negativo (2026-10-02, bug real reportado: "el footer
   fijo aún se ve margen de espacio hacia abajo... debe estar al ras de
   la pantalla") — mismo truco que ya usa `.ordix-main-header` para el
   padding de ARRIBA de `.ordix-main`, acá para el de ABAJO: sin esto,
   el padding-bottom de `.ordix-main` (1.75rem) queda como "pista" de
   más después del footer, así que `sticky bottom:0` se despegaba del
   borde real del viewport apenas el scroll llegaba al final — quedaba
   un hueco visible (mismo color, por eso no se notaba como "borde",
   pero SÍ como espacio de scroll de más que no llevaba a ningún lado).
   Con el margin cancelado, el padding-bottom de `.ordix-main` termina
   ANTES del footer en vez de después, y el footer sticky llega
   realmente al borde. */
.wizard-footer {
    position: sticky;
    bottom: 0;
    z-index: 10;
    display: flex;
    justify-content: center;
    margin-top: 1.5rem;
    margin-bottom: -1.75rem;
    padding: 1rem 0 1.5rem;
    background: transparent;
    pointer-events: none;
}

.wizard-footer > * {
    pointer-events: auto;
}

@media (max-width: 767.98px) {
    .wizard-footer {
        margin-bottom: -1.25rem;
    }
}

/* Footer flotante y centrado (2026-10-01, pedido explícito: "rediseñar
   el footer del wizard y agregarlo como flotante centrado para que
   aparezcan los botones de anterior y siguiente centrados... así el
   usuario no se moviliza de derecha a izquierda") — reemplaza el
   patrón anterior de barra sticky de ancho completo con
   `justify-content: space-between` (Anterior a la izquierda, Siguiente
   a la derecha, obligando a mover el mouse/la vista de un extremo al
   otro). `.wizard-footer` pasa a ser solo el CONTENEDOR sticky
   (transparente, ancho completo, `pointer-events: none` para no tapar
   clics sobre el contenido que pasa por abajo en las zonas vacías a
   los costados de la píldora) — la barra visible, con fondo/borde/
   sombra, es esta píldora, centrada por el `justify-content: center`
   del contenedor. Los botones quedan uno junto al otro DENTRO de la
   píldora, en la misma zona visual, así cualquiera de las 2 acciones
   está a un solo movimiento corto del cursor.
   El hueco respecto al borde inferior real del viewport es
   INTENCIONAL acá (`padding: 1rem 0 1.5rem` en `.wizard-footer`, con
   `margin-bottom: -1.75rem` siguiendo cancelando el padding de
   `.ordix-main` como antes) — a diferencia de la barra vieja de ancho
   completo (que SÍ debía quedar al ras, ver el bug de 2026-10-02 más
   arriba en este archivo), una píldora flotante se espera que
   "flote" con aire alrededor, no pegada al borde. El truco de
   cancelar el padding del ancestro sigue evitando el bug real de
   antes (scroll extra sin contenido): el padding-bottom ahora vive
   DENTRO de `.wizard-footer` (antes del borde sticky), no como
   remanente del ancestro DESPUÉS de él, así que no genera scroll
   fantasma — solo el aire visual deseado. */
.wizard-footer-pill {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
    justify-content: center;
    padding: .65rem 1rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: 999px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .12);
}

@media (max-width: 575.98px) {
    .wizard-footer-pill {
        border-radius: 1rem;
        width: 100%;
    }
}

/* Label de destino de "Anterior", JUNTO al botón, ADEMÁS del
   indicador "Paso X de N" (2026-10-01, corrección del mismo día: "me
   quitaste los pasos, eso sí había que mantenerse, solo agregar lo
   que te mencioné") — el indicador "Paso X de N · <paso actual>" con
   su círculo numerado (mockup Stitch, más abajo en este bloque) se
   restaura TAL CUAL estaba, sin tocarlo; esto de acá es SOLO el
   agregado pedido antes ("junto al botón anterior... agregar el label
   al que pertenece ese paso... si es el paso uno que el label diga Mis
   Órdenes"), como elemento aparte, no un reemplazo. */
.wizard-footer-anterior-label {
    font-size: .85rem;
    color: var(--ordix-text-tertiary);
    white-space: nowrap;
    padding: 0 .25rem;
}

/* Indicador de progreso "Paso X de N · <nombre>" dentro de la píldora
   (2026-10-01, mockup de referencia Stitch) — ver el comment de
   `_wizard_footer_progress.html` para el porqué. `.wizard-step-circle`
   es la MISMA clase del stepper de arriba, solo más chica acá (24px en
   vez de 28px, cabe mejor en una fila de un solo renglón junto a los
   botones). */
.wizard-footer-progress {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: 0 .25rem;
}

.wizard-footer-progress .wizard-step-circle {
    width: 24px;
    height: 24px;
    font-size: .78rem;
    flex: none;
}

.wizard-footer-progress-text {
    font-size: .85rem;
    color: var(--ordix-text-tertiary);
    white-space: nowrap;
}

.wizard-footer-progress-text strong {
    color: var(--ordix-text);
    font-weight: 700;
}

.wizard-footer-progress-sep {
    margin: 0 .3rem;
}

/* Botón "Siguiente" deshabilitado DENTRO de la píldora (2026-10-01,
   bug real reportado: "se ve como que está activa y solo es un botón
   outline") — es un `<a class="btn ordix-btn-success disabled"
   aria-disabled="true">` (ancla, no un `<button disabled>` nativo), así
   que SOLO el `.disabled` de Bootstrap aplicaba (`opacity:.65;
   pointer-events:none`), que únicamente atenúa el verde de
   `.ordix-btn-success` — sigue leyéndose como un botón normal con
   borde, no como "bloqueado". Mismo patrón gris ya usado para otros
   controles deshabilitados del wizard (`.wizard-add-service-tile:
   disabled`/`.wizard-add-service-row:disabled`, más arriba en este
   archivo): fondo gris, borde gris, texto terciario, `cursor:
   not-allowed` — y `opacity: 1` explícito para anular el `.65` de
   Bootstrap y que el gris se vea sólido, no una versión lavada del
   color original. Cubre `.disabled` (el que ya ponen las plantillas) Y
   `[aria-disabled="true"]` (mismo estado, por si algún botón solo trae
   el atributo ARIA sin la clase). */
.wizard-footer-pill .btn.disabled,
.wizard-footer-pill .btn[aria-disabled="true"] {
    background: var(--ordix-surface-2);
    border-color: var(--ordix-border);
    color: var(--ordix-text-tertiary);
    opacity: 1;
    cursor: not-allowed;
    box-shadow: none;
}

.wizard-footer-pill .btn.disabled:hover,
.wizard-footer-pill .btn[aria-disabled="true"]:hover {
    background: var(--ordix-surface-2);
    border-color: var(--ordix-border);
    color: var(--ordix-text-tertiary);
}

/* Paso 2: acordeón por servicio (rediseño de usabilidad, 2026-09-18 —
   ver mockup "09 - 07.2 - Wizard Remarks y Documentos (por servicio)").
   Ya no es `<details>` nativo (sin animación, sin control de "solo uno
   abierto a la vez") — es un div + botón controlado por JS
   (`_wizard_step2.html`), con el colapsado animado vía la técnica
   `grid-template-rows: 0fr -> 1fr` (sin medir alturas a mano). */

.wizard-services-header-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
}

.wizard-services-header-counts {
    font-size: .72rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--ordix-text-tertiary);
}

.wizard-accordion-item {
    border-bottom: 1px solid var(--ordix-border);
    transition: background-color .35s ease, border-color .35s ease;
}

.wizard-accordion-item:last-of-type { border-bottom: none; }

/* Tarjeta abierta: se "despega" de la lista plana con su propio borde
   redondeado — rojo si todavía tiene pendientes (estás acá, falta
   algo), neutro si la abriste solo para revisar una ya completa. */
.wizard-accordion-item.is-open {
    /*margin: .6rem 0;*/
    border: 1px solid var(--ordix-border);
    border-radius: .6rem;
    overflow: hidden;
}

/* El borde de TODA la tarjeta se tiñe de rojo, pero el fondo tenue solo
   va en la franja del ENCABEZADO (código de servicio + botón de
   colapsar) — como el mockup. Pintar todo el fondo del formulario de
   rojo (primera versión) quedaba demasiado agresivo; el cuerpo del
   formulario se queda neutro, y lo que se resalta en rojo ahí son los
   campos puntuales que faltan (ver `.wizard-field-required-empty`). */
.wizard-accordion-item.is-open.is-pending {
    border-color: var(--ordix-error);
}

.wizard-accordion-item.is-open.is-pending .wizard-accordion-summary {
    background: var(--ordix-error-bg);
}

/* Toast de "servicio completo" (2026-09-24, 3ª versión) — pasó por un
   overlay full-card (2026-09-23, confuso, bloqueaba los campos recién
   tipeados) y un banner inline con botones "Quedarme acá"/"Continuar"
   (2026-09-24) antes de esta. Se sacaron los botones a pedido explícito
   ("menos clics para los usuarios") — la tira de progreso y el botón
   "Siguiente" del footer ya cubren esas acciones, siempre visibles, así
   que el toast pasó a ser puramente informativo y se auto-oculta solo.
   Sube desde ARRIBA de `.wizard-footer` (que ya es `position:sticky`,
   así que también actúa como containing block para este `absolute` —
   no hace falta agregarle `position:relative` aparte) en vez de vivir
   arriba-derecha como los toasts de Django messages (`_toasts.html`):
   ese lugar está lejos de donde la vendedora tiene la vista puesta
   (el campo que acaba de completar) y de la acción real (el botón
   "Siguiente" mismo, justo debajo). Un solo elemento compartido por
   TODOS los servicios del paso (`#wizardCompleteToast`, JS
   `showCompleteToast` en _wizard_step2.html) — si se completa otro
   servicio mientras el anterior sigue visible, le pisa el texto en vez
   de apilarse encima. */
.wizard-complete-toast {
    position: absolute;
    left: 50%;
    bottom: calc(100% + .6rem);
    transform: translateX(-50%) translateY(6px);
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem 1.1rem;
    background: var(--ordix-success-bg);
    border: 1px solid var(--ordix-success);
    border-radius: .6rem;
    color: var(--ordix-success-text);
    font-weight: 700;
    font-size: .85rem;
    white-space: nowrap;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .25s ease, transform .25s ease, visibility 0s linear .25s;
}

.wizard-complete-toast.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
    transition: opacity .25s ease, transform .25s ease;
}

/* Fondo gris permanente (no solo al pasar el mouse) — 2026-09-24, pedido
   de Sergio: con una tarjeta abierta (cuerpo blanco) seguida de otras
   colapsadas, costaba distinguir a simple vista "esto es el botón para
   abrir OTRO servicio" de "esto es contenido que ya completé en el
   servicio anterior". El gris marca SIEMPRE la franja del header como
   una barra de acción, distinta del cuerpo. Los estados pendiente
   (`.is-open.is-pending`, rojo) y completo-con-destello
   (`.is-open.is-success-pending`, verde) siguen ganando — sus selectores
   son más específicos, ver más abajo. */
.wizard-accordion-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    width: 100%;
    padding: .9rem 1rem;
    cursor: pointer;
    background: var(--ordix-surface-2);
    border: none;
    text-align: left;
}

.wizard-accordion-item:not(.is-open) .wizard-accordion-summary:hover { background: var(--ordix-border); }

.wizard-accordion-summary-left { display: flex; align-items: center; gap: .6rem; min-width: 0; }
.wizard-accordion-summary-right { display: flex; align-items: center; gap: .6rem; }

/* Ícono de tipo de servicio en el header de cada tarjeta (2026-09-24) —
   mismo patrón ya usado en el "Desglose de valores" del paso 1 y en la
   tira de progreso: ícono con tooltip del nombre real, no el nombre en
   texto (no hay espacio en esta fila sin competir con el ticket). */
.wizard-accordion-summary-icon {
    color: var(--ordix-brand);
    font-size: .95rem;
    flex-shrink: 0;
}

/* Slot único de estado en la cabecera de cada tarjeta (2026-09-23,
   reemplaza al badge de autoguardado de la izquierda + el chip suelto de
   la derecha — 2 lugares distintos, "hacía perder al usuario", pedido de
   Sergio). Los 4 roles (`chip`/`saving`/`saved`/`error`) viven todos en
   el HTML a la vez; `setStatusSlot` (_wizard_step2.html) alterna cuál
   se ve con el atributo `hidden` — el `[hidden]` de acá abajo pisa el
   `display` propio de cada rol (mayor especificidad que la clase sola),
   si no el `display` del atributo nativo perdería contra el nuestro. */
.wizard-status-slot { display: flex; align-items: center; }

.wizard-status-saving,
.wizard-status-saved,
.wizard-status-error {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .72rem;
    font-weight: 600;
    padding: .25rem .6rem;
    border-radius: .4rem;
    white-space: nowrap;
}

.wizard-status-saving[hidden],
.wizard-status-saved[hidden],
.wizard-status-error[hidden] {
    display: none;
}

.wizard-status-saving {
    background: var(--ordix-surface-2);
    color: var(--ordix-text-tertiary);
}

.wizard-status-saving-gif {
    width: 18px;
    height: 18px;
    object-fit: contain;
}

.wizard-status-saved {
    background: var(--ordix-success-bg);
    color: var(--ordix-success-text);
}

.wizard-status-error {
    background: var(--ordix-error-bg);
    color: var(--ordix-error-text);
}

/* Popup "Copiar solicitante a otros servicios" (2026-09-22) — lista de
   checkboxes armada por JS, ver _wizard_step2.html. */
.wizard-copy-target-list {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    max-height: 320px;
    overflow-y: auto;
}

.wizard-copy-target-row {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem .7rem;
    border: 1px solid var(--ordix-border);
    border-radius: .5rem;
    font-size: .85rem;
    cursor: pointer;
}

.wizard-copy-target-row:hover { background: var(--ordix-surface-2); }
.wizard-copy-target-row input[type="checkbox"] { flex-shrink: 0; }

.wizard-copy-select-all {
    background: var(--ordix-surface-2);
    margin-bottom: .6rem;
}

/* Caja "Configuración a aplicar" del modal "Aplicar Fee o Cargo a
   servicios" (paso 3) — 3ª versión (2026-09-25, 2º mockup). Ya NO es una
   única caja ámbar: son 2 tarjetas lado a lado (Fee/Cargo, ver
   `.wizard-fee-cargo-card` abajo) dentro de un contenedor neutro, y el
   ámbar quedó reservado para el aviso de sobreescritura de más abajo
   (`.wizard-fee-cargo-warning`) — mismos tokens `--ordix-warning*` que
   ya usa `.wizard-help-warning` de este mismo paso, no un color nuevo. */
.wizard-fee-cargo-config {
    margin-bottom: 1rem;
}

.wizard-fee-cargo-config-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: .75rem;
}

.wizard-fee-cargo-config-title {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ordix-text-tertiary);
}

/* Tarjeta Fee/Cargo (2026-09-25) — borde neutro por default, se resalta
   con el borde/fondo de marca cuando su checkbox está tildado
   (`.is-active`, JS la agrega/saca en `_wizard_step3.html`) para que se
   note a simple vista cuál sección va a aplicarse sin tener que mirar
   el checkbox chico. */
.wizard-fee-cargo-card {
    height: 100%;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .6rem;
    padding: 1rem;
}

.wizard-fee-cargo-card.is-active {
    border-color: var(--ordix-brand);
    background: color-mix(in srgb, var(--ordix-brand) 5%, var(--ordix-surface));
}

.wizard-fee-cargo-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: .75rem;
    padding-bottom: .6rem;
    border-bottom: 1px solid var(--ordix-border);
    cursor: pointer;
}

.wizard-fee-cargo-card-badge {
    font-size: .68rem;
    font-weight: 700;
    padding: .15rem .5rem;
    border-radius: 1rem;
    background: var(--ordix-brand);
    color: #fff;
}

/* Aviso combinado "se sobreescribirá..." (2026-09-25, 2º mockup) — un
   solo banner ámbar debajo de las 2 tarjetas, en vez de un texto chico
   por tarjeta; el texto se arma en JS listando cuál(es) sección(es)
   están tildadas. */
.wizard-fee-cargo-warning {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    background: var(--ordix-warning-bg);
    border: 1px solid var(--ordix-warning);
    border-radius: .5rem;
    padding: .65rem .9rem;
    margin-top: 1rem;
    font-size: .82rem;
    color: var(--ordix-warning-text);
}

.wizard-fee-cargo-warning i { color: var(--ordix-warning); margin-top: .1rem; }

/* Ícono del título del modal en insignia circular ámbar (2026-09-25,
   tomado del mockup original). */
.wizard-fee-cargo-title-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--ordix-warning-bg);
    color: var(--ordix-warning);
    margin-right: .4rem;
    font-size: .85rem;
}

/* Ícono de ayuda de la columna "Servicio" del paso 3 (2026-09-28) —
   mostrar/ocultar sigue siendo CSS puro (`:hover`/`:focus-within`, sin
   componente de terceros — mismo criterio que el resto del proyecto, ver
   la nota de SweetAlert2 en el CLAUDE.md de plataforma). `tabindex="0"`
   en el trigger (ver el HTML) es lo que habilita `:focus-within` para
   teclado/lector de pantalla, no solo mouse.
   `.wizard-service-info-popover` es `position:fixed` (no `absolute`) a
   propósito — bug real encontrado probando esto: `.table-responsive`
   (Bootstrap, envuelve `#feeCargoTable`) tiene `overflow:auto` en LOS 2
   ejes (no solo `overflow-x`, confirmado con getComputedStyle), y eso
   recorta cualquier `position:absolute` que se salga de su borde aunque
   el trigger esté DENTRO — mezclar `overflow-x:auto` con
   `overflow-y:visible` en el mismo elemento no evita el recorte, porque
   por spec el navegador trata 'visible' como 'auto' igual cuando el otro
   eje no es 'visible'. Con `position:fixed` no hay ancestro que recorte,
   pero se necesita `top`/`left` calculados en JS (`mouseenter`/`focus`
   del trigger, ver el `<script>` de este archivo) porque `fixed` posiciona
   contra el viewport, no contra el trigger. */
.wizard-service-info-trigger {
    position: relative;
    display: inline-flex;
    margin-right: .35rem;
}

.wizard-service-info-icon {
    color: var(--ordix-text-tertiary);
    cursor: help;
}

.wizard-service-info-trigger:hover .wizard-service-info-icon,
.wizard-service-info-trigger:focus-within .wizard-service-info-icon {
    color: var(--ordix-brand);
}

.wizard-service-info-popover {
    display: none;
    position: fixed;
    z-index: 1070;
    width: 240px;
    padding: .75rem .85rem;
    border-radius: .5rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    box-shadow: 0 16px 32px rgba(23, 47, 61, .16);
    font-weight: 400;
    text-transform: none;
    white-space: normal;
    cursor: default;
}

.wizard-service-info-trigger:hover .wizard-service-info-popover,
.wizard-service-info-trigger:focus-within .wizard-service-info-popover {
    display: block;
}

.wizard-service-info-badges { margin-bottom: .4rem; }

.wizard-service-info-row {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .8rem;
    color: var(--ordix-text-secondary);
    margin-bottom: .25rem;
}

.wizard-service-info-name {
    font-size: .85rem;
    font-weight: 600;
    color: var(--ordix-text);
    margin-bottom: .35rem;
}

.wizard-service-info-detail {
    font-size: .75rem;
    color: var(--ordix-text-secondary);
    line-height: 1.5;
}

.wizard-service-info-amount {
    margin-top: .4rem;
    padding-top: .4rem;
    border-top: 1px solid var(--ordix-border);
    font-size: .8rem;
    font-weight: 700;
    color: var(--ordix-text);
}

.wizard-accordion-chevron {
    color: var(--ordix-text-tertiary);
    transition: transform .35s ease;
}

.wizard-accordion-item.is-open .wizard-accordion-chevron { transform: rotate(90deg); }

/* Colapsado animado sin JS de alturas: la fila de grid pasa de 0fr a 1fr
   y el contenido (con overflow:hidden) sigue su tamaño natural. */
.wizard-accordion-panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .45s ease;
}

.wizard-accordion-item.is-open .wizard-accordion-panel { grid-template-rows: 1fr; }

.wizard-accordion-panel-inner { overflow: hidden; min-height: 0; }

.wizard-accordion-body {
    padding: 0 1.1rem 1.2rem;
}

.wizard-status-chip {
    font-size: .72rem;
    font-weight: 700;
    padding: .25rem .6rem;
    border-radius: .4rem;
    white-space: nowrap;
}

.wizard-status-ok { background: var(--ordix-success-bg); color: var(--ordix-success); }
.wizard-status-pending { background: var(--ordix-error-bg); color: var(--ordix-error); }

.wizard-subsection-title {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--ordix-text-tertiary);
    margin: 1.5rem 0 .7rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ordix-border);
}

/* La PRIMERA sección de la tarjeta (siempre "Remarks", o su texto de
   reemplazo cuando el cliente no tiene ninguno configurado) no necesita
   el separador de arriba — pegada al borde superior del cuerpo se ve
   mejor sin la línea "flotando" antes de que empiece nada. */
.wizard-subsection-title:first-of-type {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

/* Etiqueta de remark: clave real en mayúsculas (ej. "LOWFARE-") en
   negrita + la descripción humana entre paréntesis al lado — mismo
   estilo que el mockup, en vez de mostrar solo una de las dos. */
.wizard-field-key { font-weight: 700; color: var(--ordix-text); }
.wizard-field-desc { color: var(--ordix-text-tertiary); font-weight: 400; margin-left: .1rem; }

.wizard-field-required-empty {
    border-color: var(--ordix-error) !important;
    background: var(--ordix-error-bg) !important;
}

/* Campo con VALOR pero de formato inválido (ej. data_type=email con
   texto suelto) — distinto de vacío-obligatorio de arriba: acá el
   problema no es que falte, es que lo que hay no pasa. Reportado por
   Sergio, 2026-09-18: el chip decía "1 formato inválido" pero ningún
   input se veía distinto. */
.wizard-field-col.has-invalid-format .form-control,
.wizard-field-col.has-invalid-format .form-select {
    border-color: var(--ordix-error) !important;
    background: var(--ordix-error-bg) !important;
}

/* Legibilidad de los campos del paso 2 (2026-09-18, contra el mockup
   "09 - 07.2"): la etiqueta ("LOWFARE- (tarifa más baja)") y el borde
   del input venían con el tamaño/contraste genérico de
   `.ordix-shell .form-label`/`.form-control` (pensado para formularios
   más chicos, ej. Cliente/Perfil) — acá, con muchos campos por
   servicio, quedaba difícil distinguir a primera vista el nombre del
   campo y hasta dónde llegaba su borde. Escalado SOLO adentro del
   acordeón del wizard, no globalmente (no se tocan Cliente/Perfil). */
.wizard-accordion-body .form-label {
    font-size: 1rem;
    font-weight: 700;
    color: var(--ordix-text);
    margin-bottom: .45rem;
}

.wizard-accordion-body .wizard-field-key,
.wizard-accordion-body .wizard-field-desc {
    font-size: 1rem;
}

.wizard-accordion-body .wizard-field-key { font-weight: 800; }
.wizard-accordion-body .wizard-field-desc { font-weight: 500; }

.wizard-accordion-body .form-control,
.wizard-accordion-body .form-select {
    border: 1.5px solid #C7D0D5;
    border-radius: .5rem;
    padding: .6rem .85rem;
    font-size: .95rem;
}

.wizard-doc-list { display: flex; flex-direction: column; gap: .5rem; margin-bottom: .75rem; }

.wizard-doc-row-uploaded {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: .75rem;
    background: var(--ordix-surface-2);
    border-radius: .5rem;
    padding: .6rem .85rem;
    font-size: .85rem;
}

.wizard-doc-name { display: flex; align-items: center; gap: .4rem; }

.wizard-doc-status { font-size: .78rem; font-weight: 600; }
.wizard-doc-ok { color: var(--ordix-success); }
.wizard-doc-missing { color: var(--ordix-warning); }

.wizard-doc-replace-btn {
    font-size: .78rem;
    font-weight: 600;
    color: var(--ordix-primary);
    cursor: pointer;
    margin: 0;
}

.wizard-doc-replace-btn:hover { text-decoration: underline; }

/* Zona de subida: dropzone punteada con drag-and-drop real (no solo
   cosmética) además del clic-para-elegir — ver JS en `_wizard_step2.html`. */
.wizard-doc-dropzone {
    display: flex;
    align-items: center;
    gap: .85rem;
    border: 1.5px dashed var(--ordix-border);
    border-radius: .6rem;
    padding: .9rem 1rem;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.wizard-doc-dropzone:hover,
.wizard-doc-dropzone.is-dragover {
    border-color: var(--ordix-primary);
    background: var(--ordix-surface-2);
}

.wizard-doc-dropzone-icon { font-size: 1.3rem; color: var(--ordix-text-tertiary); flex: none; }

.wizard-doc-dropzone-text {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    font-size: .82rem;
    flex: 1 1 auto;
}

.wizard-doc-dropzone-text strong { color: var(--ordix-text); font-size: .85rem; }
.wizard-doc-dropzone-text span { color: var(--ordix-text-tertiary); font-size: .78rem; }
.wizard-doc-dropzone-btn { flex: none; pointer-events: none; }

.wizard-info-callout {
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    margin-top: 1rem;
    padding: .75rem 1rem;
    background: var(--ordix-surface-2);
    border-radius: .6rem;
    color: var(--ordix-text-tertiary);
    font-size: .82rem;
}

/* Sidebar: panel "Validaciones de este paso" — checklist en vivo,
   actualizado por JS con cada autoguardado (ver `updateValidationsCard`
   en `_wizard_step2.html`), sin esperar a recargar la página. */
.wizard-validations-card {
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .75rem;
    padding: 1rem 1.1rem;
    margin-bottom: 1rem;
}

.wizard-validations-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ordix-text-tertiary);
    margin-bottom: .7rem;
}

/* Contador "N pendientes" al lado del título — mismo lenguaje visual que
   `.ordix-ticket-chip`, para que de un vistazo (sin leer la lista) se
   sepa cuánto falta en TODA la orden, no solo en el servicio abierto. */
.wizard-validations-count {
    text-transform: none;
    letter-spacing: normal;
    font-weight: 700;
    font-size: .72rem;
    padding: .1rem .5rem;
    border-radius: 999px;
    background: var(--ordix-warning-bg);
    color: var(--ordix-warning);
    white-space: nowrap;
}

.wizard-validations-count.is-ok {
    background: var(--ordix-success-bg);
    color: var(--ordix-success);
}

/* Checklist específico (2026-09-21) — un item por campo puntual que
   falta, CLICKEABLE (`<a href="#servicio-N">`, interceptado por JS para
   abrir el acordeón de ese servicio en vez de solo saltar el ancla) —
   el sidebar es el "mapa" de qué falta y dónde, sin tener que abrir cada
   tarjeta a adivinar. `.is-ok` (sin pendientes) se queda como texto
   simple, no clickeable. */
.wizard-validation-row {
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    font-size: .82rem;
    padding: .4rem .5rem;
    border-radius: .4rem;
    margin: 0 -.5rem;
    text-decoration: none;
}

.wizard-validation-row i { font-size: .95rem; flex: none; margin-top: .1rem; }
.wizard-validation-row.is-ok { color: var(--ordix-text-tertiary); }
.wizard-validation-row.is-ok i { color: var(--ordix-success); }
.wizard-validation-row.is-pending { color: var(--ordix-text); cursor: pointer; }
.wizard-validation-row.is-pending i { color: var(--ordix-warning); }
.wizard-validation-row.is-pending:hover { background: var(--ordix-surface-2); }

.wizard-validation-ticket {
    color: var(--ordix-text-tertiary);
    font-weight: 400;
}

/* Paso 3: fee y cargos */

.wizard-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .6rem;
    padding: .85rem 1rem;
    margin-bottom: .6rem;
}

.wizard-toggle {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    cursor: pointer;
    flex: 1;
}

.wizard-toggle input[type="checkbox"] { margin-top: .3rem; }

.wizard-toggle-value { width: 140px; flex: none; }

/* Paso 4: procesado */

.wizard-process-banner {
    display: flex;
    align-items: center;
    gap: .9rem;
    border-radius: .75rem;
    padding: 1.1rem 1.25rem;
    font-size: 1.4rem;
}

.wizard-process-banner h2 { font-size: 1.15rem; font-weight: 700; }

.wizard-process-ok { background: var(--ordix-success-bg); color: var(--ordix-success); }
.wizard-process-warning { background: var(--ordix-warning-bg); color: var(--ordix-warning); }
.wizard-process-pending { background: var(--ordix-surface-2); color: var(--ordix-text-tertiary); }

.wizard-process-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--ordix-border);
}

.wizard-process-row:last-child { border-bottom: none; }

/* ---------------------------------------------------------------------
   "Buscar servicio existente para vincular" — estilos compartidos entre
   la página completa (`orders/search_service_for_group.html`, sigue
   existiendo tal cual, acceso directo por URL) y el drawer nuevo del
   wizard paso 1 (`orders/_search_service_drawer.html`, 2026-09-21,
   mockup de Sergio) — mismas clases, así un solo lugar define el look
   de "grupo de TINA"/"servicio de esta orden" para los dos puntos de
   entrada. Antes vivían en un <style> inline de search_service_for_
   group.html; se movieron acá para no duplicarlas.
--------------------------------------------------------------------- */
.panel-titulo {
    padding: .5rem .1rem .6rem;
    border-bottom: 2px solid var(--ordix-border);
    margin-bottom: .75rem;
}

.mini-card {
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .5rem;
    padding: .5rem .75rem;
    margin-bottom: .5rem;
}

.grupo-card {
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-left: 4px solid var(--ordix-border);
    border-radius: .5rem;
    margin-bottom: .75rem;
    overflow: hidden;
}
.grupo-card.grupo-estado-todo-disponible { border-left-color: var(--ordix-success); }
.grupo-card.grupo-estado-mixto { border-left-color: var(--ordix-warning); }
.grupo-card.grupo-estado-nada-disponible { border-left-color: var(--ordix-border); }

.grupo-card-header {
    background: var(--ordix-surface-2);
    border-bottom: 1px solid var(--ordix-border);
    transition: background-color .15s ease;
}
.grupo-card-header.header-seleccionado {
    background: var(--ordix-secondary);
}

.ticket-row.seleccionada {
    background: var(--ordix-secondary);
}

.ordix-sticky-actionbar {
    position: sticky;
    bottom: 0;
    z-index: 10;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: .75rem;
    background: var(--ordix-surface);
    border: 1px solid var(--ordix-border);
    border-radius: .5rem;
    padding: .6rem 1rem;
    margin-top: .75rem;
    box-shadow: 0 -2px 10px rgba(0,0,0,.08);
}

/* Chips de conteo "Disponibles (N)" / "En conflicto (M)" — informativos,
   no filtran (el filtro por texto ya cubre esa necesidad) — mockup de
   Sergio 2026-09-21. */
.drawer-chip-group {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

.drawer-chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .25rem .65rem;
    border-radius: 999px;
    font-size: .76rem;
    font-weight: 700;
    border: 1px solid transparent;
    white-space: nowrap;
}

.drawer-chip-success {
    background: var(--ordix-success-bg);
    color: var(--ordix-success);
    border-color: var(--ordix-success);
}

.drawer-chip-warning {
    background: var(--ordix-warning-bg);
    color: var(--ordix-warning);
    border-color: var(--ordix-warning);
}

/* "Ya actualizado en TINA" — ni éxito ni advertencia, simplemente no
   disponible (no se puede tildar). Mismo tratamiento gris que
   `.ordix-type-neutral`, para no competir visualmente con los estados
   verde/ámbar que sí requieren leer algo. */
.drawer-chip-muted {
    background: var(--ordix-surface-2);
    color: var(--ordix-text-tertiary);
    border-color: var(--ordix-border);
}

/* ---------------------------------------------------------------------
   Tabla de resultados dentro de cada "Orden TINA" (orders/_search_
   result_group.html, 2026-09-21, mockup de Sergio) — reemplaza el
   `<table class="table table-sm">` de Bootstrap puro (bordes de celda
   por todos lados, header sin jerarquía) por un look más compacto:
   encabezado chico en mayúsculas, una sola línea divisoria fina entre
   filas, columna Ticket/Tipo combinada (número + badge apilados en vez
   de dos columnas separadas) y el estado como chip (.drawer-chip*, las
   mismas clases que ya usan los contadores de arriba) en vez de
   `<span class="badge ...">` suelto.
--------------------------------------------------------------------- */
.ordix-search-table-scroll {
    overflow-x: auto;
}

.ordix-search-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .84rem;
}

.ordix-search-table thead th {
    padding: .5rem .9rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ordix-text-tertiary);
    border-bottom: 1px solid var(--ordix-border);
    white-space: nowrap;
}

.ordix-search-table tbody td {
    padding: .6rem .9rem;
    border-bottom: 1px solid var(--ordix-border);
    vertical-align: middle;
}

.ordix-search-table tbody tr:last-child td {
    border-bottom: none;
}

.ordix-search-table tbody tr:hover td {
    background: var(--ordix-surface-2);
}

.ordix-search-th-check {
    width: 40px;
    padding-right: 0 !important;
}

.ordix-search-ticket {
    font-weight: 700;
    color: var(--ordix-text);
    margin-bottom: .25rem;
    white-space: nowrap;
}

.drawer-search-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .6rem;
    margin-bottom: .85rem;
}

td.background-grey-1{
    background: #DCE8F3 !important;
}

td.background-grey-2{
    background: #C6D8E9 !important;
}

td.background-grey-3{
    background: #B7C9DA !important;
}

/* ---------------------------------------------------------------------
   Drawer "Buscar servicio existente" del wizard paso 1 — panel deslizante
   desde el borde derecho (2026-09-21, pedido explícito de Sergio: al
   click en "Buscar un servicio que ya existe en TINA" dentro del modal
   "Agregar servicio", en vez de navegar a /buscar-servicio/ de página
   completa, se despliega este panel encima del wizard, animando hacia
   la izquierda). La página completa NO se tocó — sigue siendo el mismo
   view/URL, accesible directo — este es un SEGUNDO punto de entrada a la
   misma funcionalidad, a propósito ("conservar los 2 procesos por
   ahora").
--------------------------------------------------------------------- */
.wizard-search-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(20, 33, 58, .45);
    opacity: 0;
    visibility: hidden;
    transition: opacity .28s ease, visibility .28s ease;
    /* Por encima del modal Bootstrap (.modal=1055) — se abre justo cuando
       ese modal todavía se está cerrando (fade ~300ms), así que tiene
       que ganarle siempre, no solo cuando ya terminó de desaparecer. */
    z-index: 1060;
}

.wizard-search-drawer-backdrop.open {
    opacity: 1;
    visibility: visible;
}

.wizard-search-drawer {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(760px, 94vw);
    background: var(--ordix-surface);
    box-shadow: -12px 0 32px rgba(20, 33, 58, .18);
    transform: translateX(100%);
    transition: transform .32s ease;
    z-index: 1061;
    display: flex;
    flex-direction: column;
}

.wizard-search-drawer-backdrop.open .wizard-search-drawer {
    transform: translateX(0);
}

.wizard-search-drawer-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.1rem 1.4rem;
    border-bottom: 1px solid var(--ordix-border);
    flex: none;
}

.wizard-search-drawer-back {
    background: none;
    border: none;
    color: var(--ordix-text-secondary);
    font-size: .8rem;
    font-weight: 600;
    padding: 0 0 .5rem;
}

.wizard-search-drawer-close {
    background: none;
    border: none;
    color: var(--ordix-text-tertiary);
    font-size: 1.3rem;
    line-height: 1;
    flex: none;
}

.wizard-search-drawer-title {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--ordix-text);
}

.wizard-search-drawer-body {
    flex: 1 1 auto;
    overflow-y: auto;
    margin-top:10px;
    padding: 0 1.4rem 1.4rem 1.4rem;
}

/* "Buscar en"/"Filtrar servicios" pegado arriba del scroll del drawer
   (2026-09-21, pedido de Sergio: con muchos grupos de resultados había
   que subir todo el scroll para volver a tocar el filtro) — sticky
   relativo a `.wizard-search-drawer-body` (su propio scroll container,
   no la página), con fondo opaco para que las tarjetas de abajo no se
   transparenten al quedar debajo mientras se scrollea. */
.wizard-search-drawer-sticky-filters {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--ordix-surface);
    padding-bottom: .75rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--ordix-border);
}

.wizard-search-drawer-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 0;
    color: var(--ordix-text-tertiary);
}
.wizard-process-row-error { background: var(--ordix-error-bg); }

/* ---------------------------------------------------------------------
   Panel "Ver detalles" de una orden procesada, en Mis Órdenes
   (2026-09-30, pedido explícito con mockup de referencia: un panel que
   se despliega del lado derecho, encima del listado, sin navegar). Es
   el MISMO mecanismo visual que `.wizard-search-drawer-*` de arriba
   (backdrop + panel fijo que se desliza desde la derecha, header fijo +
   body reemplazado por fetch) pero con su propio juego de clases — esta
   página (`orders/dashboard.html`) no es el wizard, así que reusar el
   prefijo `wizard-*` ahí hubiera sido engañoso. Más angosto que el
   drawer de búsqueda (420px vs 760px): acá no hay que leer una tabla de
   resultados, es una ficha de resumen — mismo criterio que el panel
   "Invoice" del mockup de referencia. */
.ordix-detail-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(20, 33, 58, .45);
    opacity: 0;
    visibility: hidden;
    transition: opacity .28s ease, visibility .28s ease;
    z-index: 1060;
}

.ordix-detail-drawer-backdrop.open {
    opacity: 1;
    visibility: visible;
}

.ordix-detail-drawer {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(420px, 94vw);
    background: var(--ordix-surface);
    box-shadow: -12px 0 32px rgba(20, 33, 58, .18);
    transform: translateX(100%);
    transition: transform .32s ease;
    z-index: 1061;
    display: flex;
    flex-direction: column;
}

.ordix-detail-drawer-backdrop.open .ordix-detail-drawer {
    transform: translateX(0);
}

.ordix-detail-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.1rem 1.4rem;
    border-bottom: 1px solid var(--ordix-border);
    flex: none;
}

.ordix-detail-drawer-title {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: 1rem;
    font-weight: 700;
    color: var(--ordix-text);
}

.ordix-detail-drawer-close {
    background: none;
    border: none;
    color: var(--ordix-text-tertiary);
    font-size: 1.3rem;
    line-height: 1;
    flex: none;
}

.ordix-detail-drawer-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1.25rem 1.4rem;
}

.ordix-detail-drawer-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 0;
    color: var(--ordix-text-tertiary);
}

/* Cabecera del panel — ícono circular + "Orden #N" (equivalente al
   thumbnail + nombre de archivo del mockup "Invoice"). */
.ordix-detail-summary {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: 1rem;
}

.ordix-detail-summary-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: .6rem;
    background: var(--ordix-surface-2);
    color: var(--ordix-brand);
    font-size: 1.2rem;
    flex: none;
}

.ordix-detail-summary-title {
    font-weight: 700;
    color: var(--ordix-text);
}

/* Lista "Propiedades" (equivalente a TYPE/SIZE/LAST MODIFIED del
   mockup "Invoice") — filas simples etiqueta/valor, sin tabla. */
.ordix-detail-properties-title {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ordix-text-tertiary);
    margin-bottom: .5rem;
}

.ordix-detail-property-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .75rem;
    padding: .4rem 0;
    border-bottom: 1px solid var(--ordix-border);
    font-size: .85rem;
}

.ordix-detail-property-row:last-child { border-bottom: none; }

.ordix-detail-property-row span { color: var(--ordix-text-secondary); }

.ordix-detail-property-row b { color: var(--ordix-text); font-variant-numeric: tabular-nums; }

/* Monto del servicio (offerTotalValue de TINA) en cuadrícula/lista del paso 1, y desglose del resumen. */
.wizard-service-amount {
    font-weight: 700;
    font-size: .85rem;
    color: var(--ordix-text);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.wizard-service-row .wizard-service-amount { margin-left: auto; padding-right: .75rem; }

.wizard-summary-breakdown {
    border-top: 1px solid var(--ordix-border);
    margin-top: .8rem;
    padding-top: .7rem;
}

.wizard-summary-breakdown .wizard-summary-title { margin-bottom: .3rem; }
.wizard-summary-breakdown .wizard-summary-row > span { display: flex; gap: .35rem; align-items: baseline; min-width: 0; }
.wizard-summary-breakdown .wizard-summary-row i { color: var(--ordix-brand); }

/* Ticket largo (ej. "22KKAR-5266801957_svcFee") — se acorta con "…" en
   vez de pasar a una segunda línea o invadir la columna del monto; el
   número completo queda accesible en el tooltip nativo (`title`, ver
   _wizard_step1.html), no se pierde el dato, solo se resume la vista. */
.wizard-summary-ticket {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.wizard-summary-grand {
    border-top: 1px dashed var(--ordix-border);
    margin-top: .3rem;
    padding-top: .5rem;
    font-weight: 700;
    color: var(--ordix-text);
}

.wizard-summary-grand b { color: var(--ordix-brand); font-size: 1rem; }

/* Fee/Cargo con tonos distintos dentro de "RESUMEN DE LA ORDEN"
   (2026-10-03, pedido explícito: "para poder diferenciar los labels de
   Fee Total... y Cargo total... para que visualmente los usuarios
   puedan apreciarlo") — Fee en `--ordix-brand` (mismo verde que ya usa
   el total general, `.wizard-summary-grand` arriba, así "Fee" se lee
   como el acento "primario" de la card); Cargo en `--ordix-warning-text`
   (el mismo ámbar que ya usa el aviso "Cargo GF / Cargo SP" de este
   paso — reusa una asociación de color que la vendedora ya ve en la
   misma pantalla, no un tono inventado nuevo). Etiqueta Y monto los dos
   en el mismo tono, no solo el número, para que la diferencia se note
   aunque no se llegue a leer el texto. */
.wizard-summary-row-fee span,
.wizard-summary-row-fee b { color: var(--ordix-brand); }

.wizard-summary-row-cargo span,
.wizard-summary-row-cargo b { color: var(--ordix-warning-text); }

/* Chip de servicio en el listado de Mis Órdenes: ícono + nombre del tipo + ticket. */
.ordix-ticket-chip i { margin-right: .25rem; }

/* Franja "Solicitante para toda la orden" del paso 2 — mismo look que las filas "Aplicar ... para todos" del paso 3. */
.wizard-solicitante-all { flex-wrap: wrap; margin-bottom: 1rem; }
.wizard-solicitante-all-text { flex: 1 1 18rem; }
.wizard-solicitante-all-controls { display: flex; gap: .5rem; align-items: center; flex: 0 1 26rem; }
.wizard-solicitante-all-controls .form-select { min-width: 0; }
