/* HEB TRACK — estilos del shell y componentes propios.
 * Solo lo que Smart.UI + heb-theme.css no cubren.
 * NUNCA hardcodear colores: usar var(--token) definido en heb-theme.css.
 */

/* ====================================================================
   Tokens extra del shell (los visuales viven en heb-theme.css)
   ==================================================================== */
:root {
    --topbar-height: 56px;       /* alto fijo de la topbar; usado por el panel lateral para posicionarse debajo */
    --status-warning: #C47700;   /* ámbar para avisos (no error). Usado en banners informativos sin gravedad. */
    --status-info: #4E72AC;      /* azul informativo. Mismo valor que --smart-info; expuesto como token para usar fuera de Smart.UI. */
}

/* ====================================================================
   Reset global mínimo (el shell ocupa exactamente la pantalla)
   ==================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    overflow: hidden;
}
button { font-family: inherit; }
a { color: inherit; text-decoration: none; }

/* ====================================================================
   App shell (sidebar + main + content)
   ==================================================================== */
.app {
    display: grid;
    grid-template-columns: var(--sidebar-w, 260px) 1fr;
    height: 100vh;
    overflow: hidden;
    transition: grid-template-columns var(--t-base);
}
.app[data-sidebar="collapsed"] { --sidebar-w: 64px; }

.main {
    display: flex; flex-direction: column;
    overflow: hidden; min-width: 0;
}

.content {
    flex: 1; overflow-y: auto;
    padding: 24px;
    background: var(--bg-app);
}
.content__inner { max-width: 1440px; margin: 0 auto; }

/* ====================================================================
   Sidebar (siempre oscuro, no cambia con dark mode)
   ==================================================================== */
.sidebar {
    background: var(--sidebar-bg);
    color: var(--sidebar-fg);
    border-right: 1px solid var(--sidebar-border);
    display: flex; flex-direction: column;
    overflow: hidden;
}

.sidebar__brand {
    padding: 16px 18px 14px;
    display: flex; align-items: center; gap: 10px;
    border-bottom: 1px solid var(--sidebar-border);
    flex-shrink: 0;
    height: 56px;
}
.sidebar__logo {
    width: 32px; height: 32px;
    background: var(--heb-red);
    border-radius: var(--r-md);
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-weight: 700;
    font-family: var(--font-sans);
    letter-spacing: -0.02em;
    font-size: 13px;
    flex-shrink: 0;
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.08), inset 0 1px 0 rgb(255 255 255 / 0.12);
}
.sidebar__brand-text { min-width: 0; }
.sidebar__brand-name {
    font-weight: 600; font-size: 14px; letter-spacing: -0.015em;
    color: var(--sidebar-fg-strong);
    white-space: nowrap;
}
.sidebar__brand-sub {
    font-size: 10.5px; letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sidebar-fg-muted);
    margin-top: 1px;
}
.sidebar__collapse {
    margin-left: auto;
    width: 26px; height: 26px;
    border-radius: var(--r-sm);
    border: 0;
    background: transparent;
    color: var(--sidebar-fg-muted);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background var(--t-fast), color var(--t-fast);
}
.sidebar__collapse:hover { background: var(--sidebar-hover); color: var(--sidebar-fg-strong); }

.sidebar__search { padding: 12px 12px 6px; }
.sidebar__search .input {
    background: var(--sidebar-bg-elev);
    border-color: var(--sidebar-border);
    color: var(--sidebar-fg-strong);
    height: 32px;
    font-size: 12.5px;
}
.sidebar__search .input::placeholder { color: var(--sidebar-fg-muted); }
.sidebar__search .input-icon { color: var(--sidebar-fg-muted); }

/* Búsqueda en el menú: shell.js marca con .search-hidden lo que no coincide. */
.sidebar__nav .search-hidden { display: none; }
.sidebar__search-empty {
    margin: 8px 12px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--sidebar-fg-muted);
}

.sidebar__nav { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 6px 8px 16px; }
.sidebar__section {
    padding: 12px 12px 4px;
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--sidebar-fg-muted);
    font-weight: 600;
}

.sidebar__foot {
    padding: 12px;
    border-top: 1px solid var(--sidebar-border);
    display: flex; align-items: center; gap: 10px;
    flex-shrink: 0;
}
.sidebar__foot .avatar { width: 28px; height: 28px; font-size: 11px; }
.sidebar__foot-text { flex: 1; min-width: 0; }
.sidebar__foot-name {
    font-size: 12.5px; font-weight: 500;
    color: var(--sidebar-fg-strong);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar__foot-role { font-size: 11px; color: var(--sidebar-fg-muted); }

/* Sidebar colapsado: ocultar texto, centrar iconos */
.sidebar[data-collapsed="true"] .sidebar__brand-text,
.sidebar[data-collapsed="true"] .sidebar__search,
.sidebar[data-collapsed="true"] .sidebar__search-empty,
.sidebar[data-collapsed="true"] .nav-item__label,
.sidebar[data-collapsed="true"] .nav-item__chev,
.sidebar[data-collapsed="true"] .sidebar__section,
.sidebar[data-collapsed="true"] .nav-children,
.sidebar[data-collapsed="true"] .sidebar__foot-text { display: none; }
.sidebar[data-collapsed="true"] .nav-item { justify-content: center; padding: 0; }

/* ====================================================================
   Navegación lateral (items y subitems)
   ==================================================================== */
.nav-group { margin-bottom: 2px; }
.nav-item {
    display: flex; align-items: center; gap: 10px;
    padding: 0 12px;
    width: 100%;
    height: 36px;
    border-radius: var(--r-md);
    border: 0;
    background: transparent;
    color: var(--sidebar-fg);
    font-size: 13px; font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--t-fast), color var(--t-fast);
    position: relative;
    white-space: nowrap;
    text-align: left;
}
.nav-item:hover { background: var(--sidebar-hover); color: var(--sidebar-fg-strong); }
.nav-item.active {
    background: var(--sidebar-active);
    color: var(--sidebar-fg-strong);
}
.nav-item.active::before {
    content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
    width: 2px; background: var(--heb-red); border-radius: 2px;
}
.nav-item__icon { width: 18px; height: 18px; flex-shrink: 0; color: var(--sidebar-fg-muted); display: inline-flex; }
.nav-item.active .nav-item__icon { color: var(--heb-red); }
.nav-item__label { flex: 1; }
.nav-item__chev {
    margin-left: auto; width: 14px; height: 14px;
    color: var(--sidebar-fg-muted);
    transition: transform var(--t-base);
    display: inline-flex;
}
.nav-group.open > .nav-item .nav-item__chev { transform: rotate(90deg); }

.nav-children {
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows var(--t-base);
}
.nav-group.open > .nav-children { grid-template-rows: 1fr; }
.nav-children__inner { overflow: hidden; padding: 2px 0 4px 22px; }

/* Acordeón nivel 2 dentro del sidebar dinámico: Menu (sub-grupo dentro de la Responsabilidad). */
.nav-item--menu {
    height: 28px;
    padding: 0 10px;
    font-size: 12px;
    font-weight: 400;
    color: var(--sidebar-fg-muted);
    gap: 8px;
}
.nav-item--menu:hover { color: var(--sidebar-fg-strong); }
.nav-item--menu .nav-item__icon { width: 14px; height: 14px; }
.nav-item--menu .nav-item__chev { width: 12px; height: 12px; }
.nav-item--menu .nav-item__bullet {
    width: 4px; height: 4px; border-radius: 50%;
    background: var(--sidebar-fg-muted);
    flex-shrink: 0; margin: 0 5px;
}
.nav-group:has(> .nav-item--menu) > .nav-children > .nav-children__inner { padding-left: 14px; }

.nav-sub {
    display: flex; align-items: center; gap: 8px;
    padding: 0 12px;
    height: 30px;
    border-radius: var(--r-sm);
    color: var(--sidebar-fg);
    font-size: 12.5px;
    text-decoration: none;
    position: relative;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast);
}
.nav-sub::before {
    content: ""; position: absolute;
    left: 0; top: 0; bottom: 0; width: 1px;
    background: var(--sidebar-border);
}
.nav-sub:hover { background: var(--sidebar-hover); color: var(--sidebar-fg-strong); }
.nav-sub.active { color: var(--heb-red); font-weight: 500; }
.nav-sub.active::before { background: var(--heb-red); width: 2px; }
.nav-sub__badge {
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 2px 6px;
    border-radius: 999px;
    background: var(--heb-red-soft);
    color: var(--heb-red);
    margin-left: auto;
    text-transform: uppercase;
}

/* ====================================================================
   Topbar
   ==================================================================== */
.topbar {
    height: var(--topbar-height);
    background: var(--bg-elevated);
    border-bottom: 1px solid var(--border);
    display: flex; align-items: center; gap: 10px;
    padding: 0 20px;
    flex-shrink: 0;
}
.topbar__crumbs { flex: 1; min-width: 0; }
.topbar__btn {
    width: 36px; height: 36px;
    border-radius: var(--r-md);
    border: 0;
    background: transparent;
    color: var(--fg-muted);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    position: relative;
    transition: background var(--t-fast), color var(--t-fast);
}
.topbar__btn:hover { background: var(--bg-hover); color: var(--fg-strong); }
.topbar__search { width: 280px; position: relative; }
.topbar__profile {
    display: flex; align-items: center; gap: 10px;
    padding: 4px 8px 4px 4px;
    border-radius: 999px;
    transition: background var(--t-fast);
    cursor: pointer;
    text-decoration: none;
    color: inherit;
}
.topbar__profile:hover { background: var(--bg-hover); }
.topbar__profile.active { background: var(--bg-hover); }
.topbar__profile:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.notif-dot {
    position: absolute;
    top: 6px; right: 6px;
    width: 8px; height: 8px;
    background: var(--heb-red);
    border-radius: 50%;
    border: 2px solid var(--bg-elevated);
}

/* ====================================================================
   Breadcrumbs
   ==================================================================== */
.crumbs {
    display: flex; align-items: center; gap: 6px;
    font-size: 12.5px;
    color: var(--fg-muted);
    flex-wrap: wrap;
}
.crumbs a { color: inherit; text-decoration: none; }
.crumbs a:hover { color: var(--fg-strong); }
.crumbs__sep { color: var(--fg-subtle); width: 12px; height: 12px; flex-shrink: 0; display: inline-flex; }
.crumbs__current { color: var(--fg-strong); font-weight: 500; }

/* ====================================================================
   Avatar
   ==================================================================== */
.avatar {
    width: 32px; height: 32px;
    border-radius: 50%;
    background: linear-gradient(135deg, oklch(0.65 0.12 25), oklch(0.45 0.15 15));
    color: #fff;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 600; font-size: 12px;
    flex-shrink: 0;
    letter-spacing: -0.01em;
    overflow: hidden;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar--sm { width: 24px; height: 24px; font-size: 10px; }
.avatar[data-hue="0"] { background: linear-gradient(135deg, oklch(0.65 0.12 25), oklch(0.45 0.15 15)); }
.avatar[data-hue="1"] { background: linear-gradient(135deg, oklch(0.62 0.12 260), oklch(0.45 0.15 250)); }
.avatar[data-hue="2"] { background: linear-gradient(135deg, oklch(0.65 0.12 145), oklch(0.48 0.15 145)); }
.avatar[data-hue="3"] { background: linear-gradient(135deg, oklch(0.65 0.13 60), oklch(0.50 0.15 50)); }
.avatar[data-hue="4"] { background: linear-gradient(135deg, oklch(0.65 0.12 310), oklch(0.48 0.15 300)); }
.avatar[data-hue="5"] { background: linear-gradient(135deg, oklch(0.65 0.10 200), oklch(0.45 0.12 200)); }

/* ====================================================================
   Inputs y botones base (compatibles con Smart.UI cuando no se usa WC)
   ==================================================================== */
.input {
    height: var(--input-h);
    padding: 0 12px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    color: var(--fg-strong);
    font-size: 13.5px;
    font-family: var(--font-sans);
    transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
    outline: none;
    width: 100%;
    box-sizing: border-box;
}
.input::placeholder { color: var(--fg-subtle); }
.input:hover { border-color: oklch(0.78 0.005 260); }
.input:focus, .input:focus-visible {
    border-color: var(--heb-red);
    box-shadow: 0 0 0 3px var(--heb-red-soft);
}
/* Campo de texto libre con sugerencias (`smart-input`). Lleva además la clase
   .input para heredar la caja, pero su texto vive en un <input> interno que hay
   que desnudar para que no pinte su propio borde y su propia altura encima.
   Primer uso en el sistema: 3.55, el número Oracle de las áreas. */
smart-input.heb-sugerencias {
    padding: 0;
    /* Un componente nace en línea y se sienta sobre la línea base del texto:
       dentro de un renglón con etiqueta al lado quedaba descolgado. */
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
}
smart-input.heb-sugerencias input {
    width: 100%;
    height: 100%;
    padding: 0 12px;
    border: none;
    outline: none;
    background: transparent;
    color: inherit;
    font: inherit;
    box-sizing: border-box;
}
smart-input.heb-sugerencias input::placeholder { color: var(--fg-subtle); }
/* La lista desplegable: la del navegador no se podía acotar y tapaba el panel
   entero (Salma 28-ago). El alto lo fija dropDownHeight desde el JS. */
.smart-input-drop-down-menu {
    background: var(--bg-elevated);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-md, 0 8px 24px rgb(0 0 0 / 12%));
    font-family: var(--font-mono);
    font-size: 13px;
}

.input--with-icon { padding-left: 36px; }
.input-icon {
    position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; color: var(--fg-subtle); pointer-events: none;
    display: inline-flex;
}

/* ====================================================================
   Tweaks panel (ajustes de apariencia)
   ==================================================================== */
.tweaks {
    position: fixed;
    right: 16px;
    bottom: 16px;
    width: 280px;
    max-height: calc(100vh - 32px);
    display: flex; flex-direction: column;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    box-shadow: 0 12px 40px rgb(0 0 0 / 0.18), 0 1px 0 rgb(255 255 255 / 0.5) inset;
    z-index: 1000;
    overflow: hidden;
    font-size: 12px;
}
.tweaks[hidden] { display: none; }

.tweaks__head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 10px 8px 10px 14px;
    border-bottom: 1px solid var(--border);
}
.tweaks__head strong { font-size: 12px; font-weight: 600; letter-spacing: 0.01em; color: var(--fg-strong); }
.tweaks__close {
    border: 0; background: transparent;
    width: 24px; height: 24px;
    border-radius: var(--r-sm);
    color: var(--fg-muted);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}
.tweaks__close:hover { background: var(--bg-hover); color: var(--fg-strong); }

.tweaks__body {
    padding: 12px 14px;
    display: flex; flex-direction: column; gap: 10px;
    overflow-y: auto;
}
.tweaks__section {
    font-size: 10px; font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
    padding-top: 8px;
}
.tweaks__section:first-child { padding-top: 0; }

.tweaks__seg {
    display: flex;
    padding: 2px;
    border-radius: var(--r-md);
    background: var(--bg-subtle);
}
.tweaks__seg button {
    flex: 1;
    border: 0;
    background: transparent;
    color: var(--fg);
    font: inherit;
    font-weight: 500;
    font-family: var(--font-sans);
    padding: 5px 8px;
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast);
}
.tweaks__seg button:hover { color: var(--fg-strong); }
.tweaks__seg button.active {
    background: var(--bg-elevated);
    color: var(--fg-strong);
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.08);
}

.tweaks__chips {
    display: flex; gap: 6px;
}
.tweaks__chips button {
    flex: 1; height: 36px;
    border: 1.5px solid transparent;
    border-radius: var(--r-md);
    cursor: pointer;
    transition: transform var(--t-fast), border-color var(--t-fast);
}
.tweaks__chips button:hover { transform: translateY(-1px); }
.tweaks__chips button.active { border-color: var(--fg-strong); }

.tweaks__reset {
    margin-top: 6px;
    height: 30px;
    border: 0;
    border-radius: var(--r-md);
    background: var(--bg-subtle);
    color: var(--fg);
    font: inherit;
    font-family: var(--font-sans);
    font-weight: 500;
    cursor: pointer;
}
.tweaks__reset:hover { background: var(--bg-hover); }

/* ====================================================================
   Placeholder screen (módulos en construcción)
   ==================================================================== */
.placeholder-screen {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    min-height: 60vh;
    text-align: center;
    padding: 40px 20px;
    gap: 12px;
}
.placeholder-screen__icon {
    width: 64px; height: 64px;
    border-radius: var(--r-xl);
    background: var(--bg-subtle);
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--heb-red);
    margin-bottom: 8px;
}
.placeholder-screen__title {
    font-size: 22px; font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--fg-strong);
    margin: 0;
}
.placeholder-screen__desc {
    font-size: 14px; color: var(--fg-muted);
    margin: 0; max-width: 480px;
    line-height: 1.5;
}
.placeholder-screen__phase {
    font-size: 11px; font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--heb-red);
    background: var(--heb-red-soft);
    padding: 4px 10px;
    border-radius: 999px;
    margin-top: 4px;
}

/* ====================================================================
   Pantalla de inicio (épica 4.1): una sección por tablero de módulo.
   Las tarjetas reusan `.stat` y los tonos del tablero de Logística.
   ==================================================================== */
.inicio-modulo { margin-bottom: var(--gap); }
.inicio-modulo__head {
    display: flex; align-items: baseline; gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.inicio-modulo__title {
    font-size: 14px; font-weight: 600;
    color: var(--fg-strong);
    margin: 0;
}
.inicio-modulo__sub { font-size: 11.5px; color: var(--fg-muted); }
.inicio-modulo__liga {
    margin-left: auto;
    font-size: 12.5px; font-weight: 500;
    color: var(--heb-red);
    text-decoration: none;
}
.inicio-modulo__liga:hover { text-decoration: underline; }
.inicio-modulo__liga:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.inicio-vacio { color: var(--fg-muted); font-size: 14px; margin: 0; }

/* ==========================================================================
   Estándar CRUD — page header, card, toolbar, tabla, formulario, modal
   ========================================================================== */

/* Page header (titulo + acciones) */
.page-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--gap);
    margin-bottom: 16px;
}
.page-header__titles { display: flex; flex-direction: column; gap: 4px; }
.page-header__titles--with-back {
    flex-direction: row;
    align-items: center;
    gap: 14px;
}
.page-header__titles--with-back .page-title,
.page-header__titles--with-back .page-subtitle {
    margin: 0;
}
.page-header__titles--with-back .page-subtitle {
    margin-top: 2px;
}
.page-header__separator {
    width: 1px;
    height: 28px;
    background: var(--border);
    flex-shrink: 0;
}
.page-header__actions { display: flex; gap: 8px; flex-wrap: wrap; }
.page-title {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--fg-strong);
}
.page-subtitle {
    margin: 0;
    font-size: 13px;
    color: var(--fg-muted);
    max-width: 720px;
    /* Truncado a 1 línea: evita empuje del grid y doble scroll vertical
       (página + grid interno) cuando la descripción del programa es larga. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Card */
.card {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--pad-card);
    box-shadow: var(--shadow-xs);
}
.card--narrow { max-width: 640px; }

/* Card que contiene un grid HEB: padding compacto + toolbar pegada.
   El grid ya tiene su propio borde + footer, así que el padding generoso
   de la .card se siente como aire muerto alrededor. */
.card:has(> .heb-grid) {
    padding: 12px 16px;
}
.card:has(> .heb-grid) .toolbar {
    margin-bottom: 8px;
}

/* El atributo `hidden` debe ocultar SIEMPRE. Componentes con `display` propio
   (.btn, .btn-icon, combos, etc.) lo sobreescriben porque `[hidden]` del UA es
   de baja prioridad; este global lo garantiza en todo el sistema (evita el bug
   de botones que quedan visibles con hidden=true). Caso justificado de !important. */
[hidden] {
    display: none !important;
}

/* Botones */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--input-h);
    padding: 0 14px;
    border: 1px solid transparent;
    border-radius: var(--r-md);
    font: inherit;
    font-weight: 500;
    font-size: 13px;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
    text-decoration: none;
    line-height: 1;
}
.btn:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.btn__icon { display: inline-flex; align-items: center; }

/* ====================================================================
   Estados deshabilitados por privilegios — ver DESIGN_SYSTEM.md §11.
   Patrón general: atributo HTML `disabled` + `title="Requiere ..."`.
   ==================================================================== */

/* Botones-ícono deshabilitados (lápiz, basurero, etc. en columna Acciones) */
.btn-icon[disabled],
.btn-icon[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
}
.btn-icon[disabled]:hover {
    background: transparent;
    color: var(--fg-muted);
    border-color: transparent;
}

/* Inputs read-only o disabled (slide panels en modo lectura) */
.input[readonly],
.input[disabled] {
    background: var(--bg-subtle);
}
/* Deshabilitado: apagado, no se usa. */
.input[disabled] {
    color: var(--fg-muted);
    cursor: not-allowed;
}
/* Sólo lectura: es un dato, no un campo apagado (épica 4.2). Texto legible,
   sin la rayita de escribir —que invitaba a teclear donde no se puede— y
   seleccionable, para poder copiar un código o un importe. */
.input[readonly] {
    color: var(--fg);
    caret-color: transparent;
    cursor: default;
}
.input[readonly]:focus,
.input[disabled]:focus {
    outline: none;
    box-shadow: none;
    border-color: var(--border);
}

/* Labels que envuelven un input file disabled (ej. "Cambiar foto" del slide
   panel de Usuarios cuando el usuario no tiene MOD). DESIGN_SYSTEM §11. */
label.is-disabled {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
}

.btn--primary {
    background: var(--heb-red);
    color: var(--fg-on-accent);
}
.btn--primary:hover:not([disabled]) { background: var(--heb-red-hover); }

.btn--ghost {
    background: transparent;
    color: var(--fg);
    border-color: var(--border-strong);
}
.btn--ghost:hover:not([disabled]) { background: var(--bg-hover); color: var(--fg-strong); }

.btn--secondary {
    background: var(--bg-elevated);
    color: var(--fg-strong);
    border-color: var(--border-strong);
}
.btn--secondary:hover:not([disabled]) { background: var(--bg-hover); }

.btn--danger {
    background: var(--status-danger);
    color: var(--fg-on-accent);
}
.btn--danger:hover:not([disabled]) { filter: brightness(0.92); }

.btn--icon-only { width: 32px; height: 32px; padding: 0; }
.btn--sm { height: 28px; padding: 0 10px; font-size: 12px; }

/* Botón icon-only para acciones en celdas (lápiz, x, etc.) */
.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    margin-left: 2px;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--fg-muted);
    cursor: pointer;
    text-decoration: none;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.btn-icon:hover {
    background: var(--bg-hover);
    color: var(--fg-strong);
    border-color: var(--border-strong);
}
.btn-icon:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.btn-icon--danger:hover {
    background: var(--status-danger-bg);
    color: var(--status-danger);
    border-color: var(--status-danger);
}

/* Toolbar (búsqueda + filtros sobre la tabla) */
.toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap);
    margin-bottom: 14px;
    flex-wrap: wrap;
}
.toolbar__search { position: relative; flex: 1 1 280px; max-width: 360px; }
.toolbar__filters { display: flex; gap: 14px; align-items: center; margin-left: auto; }
.toolbar__group { display: flex; gap: 10px; align-items: center; }

/* Selector de almacén (Control de Inventarios / Ubicaciones): ancho (~mitad de pantalla). */
#mov-almacen-selector { width: clamp(360px, 42vw, 680px); }
/* En Ubicaciones comparte renglón con Zonas, Proyectos y Generar (épica 4.3):
   más angosto, para que en 1366×768 la barra no se parta en dos. */
#ubi-almacen-selector { width: clamp(260px, 22vw, 480px); }
.toolbar__group .btn { white-space: nowrap; }

/* Encabezado de sección con acción a la derecha (p. ej. Partidas + Agregar). */
.form-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 4px 0 12px;
}
.form-section-head .form-section-title { margin: 0; }
.form-section-head__actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Sub-panel anidado: segundo slide por encima del panel principal y su backdrop. */
/* Con doble clase para ganarle a la regla base .slide-panel (misma
   especificidad, definida después): el panel anidado SIEMPRE va encima. */
.slide-panel-backdrop.slide-panel-backdrop--nested { z-index: 110; }
.slide-panel.slide-panel--nested { z-index: 120; }
.slide-panel__crumbs {
    margin: 0 0 3px;
    font-size: 12px;
    color: var(--fg-muted);
}
.toolbar__meta { margin-left: auto; }

.grid-counter {
    font-size: 12px;
    color: var(--fg-muted);
}
.grid-counter--note {
    color: var(--status-warning, var(--heb-red));
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 12px;
}

/* Utility classes mínimas usadas por viewers de Bitácora (1.38 / 1.39) */
.u-mono { font-family: var(--font-mono); font-size: 12px; }
.u-text-mute { color: var(--fg-muted); }
.u-text-xs { font-size: 11px; }

/* Slide panel de detalle (Viewer Bitácora Acción — 1.39) */
.kv-grid {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 6px 12px;
    margin: 0 0 20px;
    font-size: 13px;
}
.kv-grid dt {
    color: var(--fg-muted);
    font-weight: 500;
}
.kv-grid dd { margin: 0; color: var(--fg-strong); word-break: break-word; }

.diff-section { border-top: 1px solid var(--border); padding-top: 16px; }
.diff-section__title {
    font-size: 13px;
    font-weight: 600;
    color: var(--fg-strong);
    margin: 0 0 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.diff-row {
    display: grid;
    grid-template-columns: 200px 1fr 1fr;
    gap: 0 12px;
    padding: 8px 10px;
    border-radius: var(--r-sm);
    align-items: start;
    font-size: 12.5px;
}
.diff-row + .diff-row { margin-top: 2px; }
.diff-row__key {
    color: var(--fg-muted);
    font-weight: 500;
    align-self: start;
    word-break: break-word;
}
.diff-row__cell {
    font-family: var(--font-mono);
    font-size: 12px;
    white-space: pre-wrap;
    word-break: break-word;
}
.diff-row__cell--empty { color: var(--fg-subtle); font-style: italic; font-family: inherit; }
.diff-row--changed { background: color-mix(in oklab, var(--heb-red) 6%, transparent); }
.diff-row--changed .diff-row__cell--antes { color: var(--status-danger); text-decoration: line-through; }
.diff-row--changed .diff-row__cell--despues { color: var(--status-active); font-weight: 500; }
.diff-section__header {
    display: grid;
    grid-template-columns: 200px 1fr 1fr;
    gap: 0 12px;
    padding: 4px 10px;
    margin-bottom: 4px;
    font-size: 11px;
    font-weight: 600;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.diff-empty {
    text-align: center;
    color: var(--fg-muted);
    font-size: 12.5px;
    padding: 16px;
}

.skeleton-block {
    color: var(--fg-muted);
    padding: 24px;
    text-align: center;
    font-size: 12.5px;
}
/* Botón "Limpiar filtros" que el shell inyecta en el pie del grid: sólo se ve
   cuando hay filtros de columna puestos. La regla es necesaria porque [hidden]
   y .btn empatan en especificidad y el display del botón le ganaría. */
.grid-footer__clear[hidden] { display: none; }

.grid-counter strong {
    color: var(--fg-strong);
    font-weight: 600;
}

/* Checkbox + label inline */
.check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    color: var(--fg);
}
.check input[type="checkbox"] {
    accent-color: var(--heb-red);
    width: 16px;
    height: 16px;
}

/* Tabla */
.table-wrap { overflow-x: auto; border-top: 1px solid var(--border); }
.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}
.table thead th {
    text-align: left;
    font-weight: 600;
    color: var(--fg-muted);
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-subtle);
    white-space: nowrap;
}
.table tbody td {
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    color: var(--fg);
    vertical-align: middle;
}
.table tbody tr:hover { background: var(--bg-hover); }
.table__empty td {
    text-align: center;
    color: var(--fg-muted);
    padding: 28px 12px;
}
.col-actions { width: 100px; text-align: right; white-space: nowrap; }

/* Tabla compacta: renglones más bajos. Pensada para listas dentro de un modal,
   donde el alto acumulado es lo que decide si la ventana cabe en una laptop de
   768 px. Las utilidades .num y .mono viven aquí dentro porque las globales
   están acotadas a .data-table. */
.table--compact thead th { padding: 6px 10px; }
.table--compact tbody td { padding: 4px 10px; }
.table--compact .num { text-align: right; font-variant-numeric: tabular-nums; }
.table--compact .mono { font-family: var(--font-mono); }
.table--compact .col-actions { width: 56px; }
.table--compact .btn-icon { width: 28px; height: 28px; }  /* 28px = densidad compacta */
.table--compact .table__empty td { padding: 16px 10px; }
.col-actions .btn { margin-left: 4px; }

.sortable { cursor: pointer; user-select: none; }
.sortable:hover { color: var(--fg-strong); }
.sortable[data-direction="asc"]::after { content: " ↑"; color: var(--heb-red); }
.sortable[data-direction="desc"]::after { content: " ↓"; color: var(--heb-red); }

/* Pill de estado activo/inactivo en celdas */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 500;
    line-height: 1.4;
}
/* Variante compacta: agregados de estatus en celdas densas (Detallado P4). */
.pill--sm { padding: 1px 6px; font-size: 10px; }
.pill--active { background: var(--status-active-bg); color: var(--status-active); }
.pill--inactive { background: var(--status-inactive-bg); color: var(--status-inactive); }
.pill--pending { background: var(--status-pending-bg); color: var(--status-pending); }
.pill--danger { background: var(--status-danger-bg); color: var(--status-danger); }

/* Paginación */
.pagination {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    padding-top: 14px;
}
.pagination__info { color: var(--fg-muted); font-size: 12px; }

/* Formulario */
.form-row { margin-bottom: 18px; }
.form-label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
    margin-bottom: 6px;
}
.form-required { color: var(--heb-red); }
.form-help {
    margin-top: 4px;
    font-size: 12px;
    color: var(--fg-muted);
}
/* Variante para avisos que informan una consecuencia, no un error: el campo es
   válido y se puede guardar (ej. elegir un tipo de usuario privilegiado). */
.form-help--warn {
    color: var(--status-warning);
}
/* Fila de formulario que se oculta SIN salirse de la rejilla: conserva su
   celda para que los campos de abajo no se recorran y queden emparejados con
   quien no les toca (el panel es de dos columnas). `visibility` en vez de
   `hidden` también la saca del orden de tabulación. */
.form-row--reservada {
    visibility: hidden;
}

.form-error {
    margin-top: 4px;
    font-size: 12px;
    color: var(--status-danger);
}
.form-row.has-error .input { border-color: var(--status-danger); }
.form-row.has-error .input:focus { outline-color: var(--status-danger); }
.form-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    border-top: 1px solid var(--border);
    padding-top: 16px;
    margin-top: 8px;
}
.form-global-error {
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: var(--r-md);
    background: var(--status-danger-bg);
    color: var(--status-danger);
    font-size: 13px;
}

/* Smart.UI Grid override mínimo para integrarlo al theme HEB */
.heb-grid {
    width: 100%;
    height: calc(100vh - 280px);
    min-height: 220px;
    display: block;
    border: 1px solid var(--border);
    border-radius: var(--r-md) var(--r-md) 0 0;
    border-bottom: 0;
    /* Fuente compacta para todos los grids (antes heredaba 13.5px del token global). */
    --smart-font-size: 11px;
    --smart-grid-row-height: 30px;
    --smart-grid-column-header-height: 36px;
}
.heb-grid smart-grid-cell .btn { margin-left: 4px; }

/* Fila seleccionada / con foco: neutralizamos el rojo HEB dentro del grid
   sobreescribiendo los tokens internos que Smart.UI usa para "estado activo".
   El rojo lo aplican varias reglas !important del bundle vía estos tokens;
   atacarlos por variable es más limpio que pelear con especificidad. */
.heb-grid {
    --smart-primary: var(--border);
    --smart-primary-rgb: 241, 240, 237;
    --smart-primary-color: var(--fg-strong);
    --smart-outline: var(--border);
    --smart-grid-row-selected-background: var(--bg-hover);
    --smart-grid-row-selected-hover-background: var(--bg-active);
    --smart-grid-cell-background-freeze-selected: var(--bg-hover);
    --smart-ui-state-selected: var(--bg-hover);
    --smart-ui-state-color-selected: var(--fg-strong);
    --smart-ui-state-active: var(--bg-hover);
    --smart-ui-state-color-active: var(--fg-strong);
}

/* El outline rojo del grid al recibir focus viene de la regla global
   `*:focus-visible { outline: 2px solid var(--heb-red); }` de heb-theme.css.
   Sobreescribimos solo para el grid: borde sutil gris en vez del halo rojo. */
.heb-grid:focus,
.heb-grid:focus-visible {
    outline: 1px solid var(--border);
    outline-offset: 0;
}


/* Footer del grid (pegado debajo, mismo ancho, borde superior) */
.grid-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    /* Separa contadores cuando hay más de uno (candidatas + seleccionadas). */
    gap: 16px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 0 0 var(--r-md) var(--r-md);
    background: var(--bg-subtle);
    font-size: 12px;
}

/* Modal nativo <dialog> */
.modal {
    border: 1px solid var(--border-strong);
    border-radius: var(--r-lg);
    padding: 0;
    box-shadow: var(--shadow-pop);
    background: var(--bg-elevated);
    color: var(--fg);
    max-width: 440px;
    width: calc(100% - 32px);
    /* Defensivo: en viewports bajos, modal nunca sale de pantalla.
       El scroll lo hacen los contenedores internos (.row-list--scroll). */
    max-height: calc(100vh - 64px);
    overflow: hidden;
}
.modal::backdrop { background: rgb(0 0 0 / 0.35); backdrop-filter: blur(2px); }
/* Modales con smart combo adentro: el dropdown se renderiza en el propio
   modal (en body quedaría detrás del top-layer del dialog), así que debe
   poder desbordar sus bordes. */
.modal--combo { overflow: visible; }
/* En viewports bajos (laptop) el contenido puede exceder el alto del modal:
   el form es el área con scroll y la botonera queda sticky al fondo, siempre
   visible. Scoped a [open] para no pisar el display:none del dialog cerrado. */
.modal[open] { display: flex; flex-direction: column; }
.modal__form {
    padding: 20px 20px 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
    overflow-y: auto;
    min-height: 0;
}
/* Los modales con smart combo no llevan scroll propio: su dropdown debe poder
   desbordar el borde del dialog (son cortos; no lo necesitan). */
.modal--combo .modal__form { overflow: visible; }
/* Una tabla dentro del modal no se encoge para hacerle lugar al formulario:
   en 1366×768 quedaba reducida a su encabezado (épica 4.3). Si el modal no
   cabe, lo resuelve el scroll del form. */
.modal__form > .table-wrap { flex-shrink: 0; }
/* En un modal con combo —sin scroll propio— la tabla lleva tope y scroll
   interno, para que crezca con los datos sin empujar los botones fuera. */
.modal__form > .table-wrap--tope { max-height: 120px; overflow-y: auto; }
.modal__title { margin: 0; font-size: 16px; font-weight: 600; color: var(--fg-strong); }
.modal__body { margin: 0; font-size: 13px; color: var(--fg-muted); line-height: 1.5; }
/* Lista de referencias afectadas dentro de un modal de decisión: enumerar lo
   que va a cambiar se lee mejor que una frase con diez códigos pegados. */
.modal__lista {
    margin: 0;
    padding-left: 18px;
    font-size: 13px;
    color: var(--fg-muted);
    line-height: 1.6;
    max-height: 180px;
    overflow-y: auto;
}
.modal__lista[hidden] { display: none; }
.modal__actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    position: sticky;
    bottom: 0;
    background: var(--bg-elevated);
    padding: 6px 0 20px;
}

/* Acciones con el primer botón anclado a la izquierda (p. ej. Cerrar) y el
   resto a la derecha, todo en un solo renglón: ahorra el alto de una fila
   extra, que es lo que decide si el modal cabe en una laptop. */
.modal__actions--split > :first-child { margin-right: auto; }
/* Alturas de laptop: se compacta el aire vertical del modal. */
@media (max-height: 820px) {
    .modal__form { gap: 10px; }
    .modal__actions { padding-bottom: 16px; }
}

/* ==========================================================================
   Slide panel (drawer lateral) — patrón estándar de alta/edición
   ========================================================================== */

.slide-panel-backdrop {
    position: fixed;
    top: var(--topbar-height);
    right: 0;
    bottom: 0;
    left: 0;
    background: rgb(0 0 0 / 0.18);    /* sutil, sin blur, deja ver lo que hay atrás */
    z-index: 99;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--t-base), visibility var(--t-base);
}
.slide-panel-backdrop[data-open="true"] {
    opacity: 1;
    visibility: visible;
}

.slide-panel {
    position: fixed;
    top: var(--topbar-height);
    right: 0;
    bottom: 0;
    width: var(--slide-panel-width, 480px);
    max-width: 92vw;
    background: var(--bg-elevated);
    border-left: 1px solid var(--border);
    box-shadow: var(--shadow-pop);
    z-index: 100;
    transform: translateX(100%);
    transition: transform var(--t-base);
    display: flex;
    flex-direction: column;
}
.slide-panel[data-open="true"] { transform: translateX(0); }

/* Variantes de ancho (para pantallas con más contenido como OT) */
.slide-panel--sm { --slide-panel-width: 420px; }   /* form básico, 3-5 campos */
.slide-panel--md { --slide-panel-width: 640px; }   /* form con grid 2 columnas */
.slide-panel--lg { --slide-panel-width: 920px; }   /* form con tabs + sub-tabla */
.slide-panel--xl { --slide-panel-width: 1200px; }  /* casi pantalla completa, OTs */

.slide-panel__header {
    padding: 14px 24px 12px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-shrink: 0;
}
.slide-panel__title {
    margin: 0 0 2px;
    font-size: 16px;
    font-weight: 600;
    color: var(--fg-strong);
    letter-spacing: -0.01em;
}
/* Icono basurero del header: rojo siempre (no solo en hover) para que se note
   como acción destructiva. Selector específico al header del panel: NO afecta
   los btn-icon--danger del grid (donde el rojo solo aparece al hover). */
.slide-panel__header .btn-icon--danger {
    color: var(--status-danger);
}
.slide-panel__header .btn-icon--danger:hover {
    background: var(--status-danger-bg);
    color: var(--status-danger);
    border-color: var(--status-danger);
}
.slide-panel__subtitle {
    margin: 0;
    font-size: 13px;
    color: var(--fg-muted);
}
/* Acciones del header (Eliminar + Cerrar). El X siempre a la derecha. */
.slide-panel__header-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

.slide-panel__body {
    flex: 1;
    overflow-y: auto;
    padding: 18px 28px;
}

/* Densidad compacta dentro del slide panel (decisión 2026-05-24):
   inputs 32px, gap 12px entre filas, helper text más chico. Permite ~5-6
   campos sin scroll en laptops 1366×768. NO afecta forms fuera del panel. */
.slide-panel__body .form-row { margin-bottom: 12px; }
.slide-panel__body .input { height: 32px; }
/* Las áreas de texto sí crecen en alto (el 32px de arriba es para inputs de 1 línea). */
.slide-panel__body textarea.input {
    height: auto;
    min-height: 64px;
    padding: 8px 12px;
    line-height: 1.4;
    resize: vertical;
}
.slide-panel__body .form-label { margin-bottom: 4px; font-size: 12.5px; }
.slide-panel__body .form-help { margin-top: 3px; font-size: 11.5px; }
.slide-panel__body .form-error { margin-top: 3px; font-size: 11.5px; }

/* Estado de carga en edición: panel abierto, esperando que llegue el GET
   del registro. El subtítulo dice "Cargando…" y el body baja opacidad. */
.slide-panel[data-loading="true"] .slide-panel__body {
    opacity: 0.45;
    pointer-events: none;
}

/* Toggle booleano dentro de un form-row (smart-switch-button + label Sí/No) */
.pa-panel-valor-bool {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    height: 32px;
}
.pa-panel-valor-bool[hidden] { display: none; }
.pa-panel-valor-bool__label {
    font-size: 13px;
    color: var(--fg-strong);
    font-weight: 500;
    min-width: 24px;
}

.slide-panel__footer {
    padding: 14px 28px;
    border-top: 1px solid var(--border);
    background: var(--bg-subtle);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-shrink: 0;
}
.slide-panel__footer-note {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    color: var(--fg-muted);
}
/* margin-left:auto: alinea los botones a la derecha SIEMPRE, aunque el footer no
   tenga la nota de la izquierda (sub-paneles sin "bitácora"). */
.slide-panel__footer-actions { display: flex; gap: 8px; margin-left: auto; }

/* ====================================================================
   Tabs dentro de un slide-panel (épica 1.8 Usuario CRUD)
   ==================================================================== */
.tabs {
    display: flex;
    gap: 4px;
    padding: 0 24px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-elevated);
    flex-shrink: 0;
}
.tab {
    background: transparent;
    border: 0;
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-muted);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color var(--t-fast), border-color var(--t-fast);
}
.tab:hover { color: var(--fg-strong); }
.tab--active {
    color: var(--heb-red);
    border-bottom-color: var(--heb-red);
}
.tab:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; border-radius: var(--r-sm); }

.tab-panel { display: none; }
.tab-panel--active { display: block; }

/* ====================================================================
   Grid de formulario a 2 columnas
   ==================================================================== */
.form-grid--2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px 16px;
}
.form-grid--2 .form-row { margin-bottom: 0; }
@media (max-width: 640px) {
    .form-grid--2 { grid-template-columns: 1fr; }
}

/* Grid de formulario a 3 columnas (p. ej. Cantidad / Costo / Importe). */
.form-grid--3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 12px 16px;
}
.form-grid--3 .form-row { margin-bottom: 0; }
@media (max-width: 640px) {
    .form-grid--3 { grid-template-columns: 1fr; }
}

/* Input numérico alineado a la derecha (costo, mínimo/máximo, volumen, peso). */
.input--num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Título de sección dentro de un formulario (p. ej. "Dirección"). */
.form-section-title {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--fg-strong);
    margin: 4px 0 10px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

/* Lista vertical de checkboxes (.check) — p. ej. movimientos por almacén. */
.check-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ====================================================================
   Input con icono — wrapper posicionado (.input-icon ya existe)
   ==================================================================== */
.input-with-icon {
    position: relative;
    display: block;
}

/* ====================================================================
   Separador horizontal dentro del slide panel
   ==================================================================== */
.divider {
    border: 0;
    border-top: 1px solid var(--border);
    margin: 16px 0;
}

/* ====================================================================
   Encabezado de sección dentro del slide panel
   ==================================================================== */
.section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}
.section-head__title {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--fg-strong);
}
.section-head__actions {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

/* ====================================================================
   Badge de estado de cuenta (Pendiente / Activo / Inactivo)
   ==================================================================== */
.estado-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 500;
    background: var(--status-inactive-bg);
    color: var(--status-inactive);
    line-height: 1.6;
}
.estado-badge--active   { background: var(--status-active-bg);   color: var(--status-active); }
.estado-badge--pending  { background: var(--status-pending-bg);  color: var(--status-pending); }
.estado-badge--inactive { background: var(--status-inactive-bg); color: var(--status-inactive); }

/* ====================================================================
   Access state card (Tab Acceso — informa estado de la cuenta)
   ==================================================================== */
.access-state {
    display: flex;
    gap: 12px;
    padding: 14px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.access-state--muted { opacity: 0.85; }
.access-state__icon {
    width: 36px;
    height: 36px;
    border-radius: var(--r-md);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: var(--status-inactive-bg);
    color: var(--status-inactive);
}
.access-state__icon--pending  { background: var(--status-pending-bg);  color: var(--status-pending); }
.access-state__icon--active   { background: var(--status-active-bg);   color: var(--status-active); }
.access-state__icon--inactive { background: var(--status-inactive-bg); color: var(--status-inactive); }
.access-state__body { flex: 1; min-width: 0; }
.access-state__title {
    font-size: 13px;
    font-weight: 600;
    color: var(--fg-strong);
    margin-bottom: 2px;
}
.access-state__sub {
    font-size: 12.5px;
    color: var(--fg-muted);
    line-height: 1.5;
}
.access-state__actions {
    display: flex;
    gap: 8px;
    margin-top: 10px;
    flex-wrap: wrap;
}

/* ====================================================================
   Security card (sección 2FA del Tab Acceso)
   ==================================================================== */
.security-card {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
/* El atributo `hidden` debe ganarle al display:flex de arriba. */
.security-card[hidden] { display: none; }
.security-card__icon {
    width: 32px;
    height: 32px;
    border-radius: var(--r-md);
    background: var(--heb-red-soft);
    color: var(--heb-red);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.security-card__body { flex: 1; min-width: 0; }
.security-card__title {
    font-size: 13.5px;
    font-weight: 500;
    color: var(--fg-strong);
    margin-bottom: 2px;
}
.security-card__sub {
    font-size: 12.5px;
    color: var(--fg-muted);
    line-height: 1.5;
}
.security-card__actions {
    display: flex;
    gap: 8px;
    margin-top: 10px;
    flex-wrap: wrap;
}

/* ====================================================================
   User photo (Tab Datos Personales — upload + preview)
   ==================================================================== */
.user-photo-row {
    display: flex;
    gap: 16px;
    align-items: center;
    padding: 14px;
    background: var(--bg-subtle);
    border-radius: var(--r-lg);
    margin-bottom: 16px;
}
.user-photo {
    flex-shrink: 0;
}
.user-photo__preview {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--fg-muted);
    font-size: 20px;
    font-weight: 600;
}
.user-photo__preview[data-hue] { color: #fff; border: 0; }
.user-photo__preview[data-hue="0"] { background: linear-gradient(135deg, oklch(0.65 0.12 25), oklch(0.45 0.15 15)); }
.user-photo__preview[data-hue="1"] { background: linear-gradient(135deg, oklch(0.62 0.12 260), oklch(0.45 0.15 250)); }
.user-photo__preview[data-hue="2"] { background: linear-gradient(135deg, oklch(0.65 0.12 145), oklch(0.48 0.15 145)); }
.user-photo__preview[data-hue="3"] { background: linear-gradient(135deg, oklch(0.65 0.13 60), oklch(0.50 0.15 50)); }
.user-photo__preview[data-hue="4"] { background: linear-gradient(135deg, oklch(0.65 0.12 310), oklch(0.48 0.15 300)); }
.user-photo__preview[data-hue="5"] { background: linear-gradient(135deg, oklch(0.65 0.10 200), oklch(0.45 0.12 200)); }
.user-photo__preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.user-photo__initials { user-select: none; }
.user-photo__actions {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
}
.user-photo__actions .btn { display: inline-flex; cursor: pointer; }
.user-photo__actions .btn[hidden] { display: none; }  /* `hidden` gana al display de arriba */
.user-photo__buttons { display: flex; gap: 8px; flex-wrap: wrap; }

/* ====================================================================
   Form meta (datos administrativos read-only en footer del tab)
   ==================================================================== */
.form-meta {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px dashed var(--border);
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 16px;
}
.form-meta__item { font-size: 11.5px; }
.form-meta__label { color: var(--fg-muted); margin-right: 6px; }
.form-meta__value { color: var(--fg-strong); }

/* ====================================================================
   Toolbar variante con filtros
   ==================================================================== */
.toolbar--filters .toolbar__filters {
    margin-left: auto;
}
.toolbar--filters .toolbar__search {
    flex: 0 1 320px;
    max-width: 360px;
    position: relative;
}

/* ====================================================================
   Cell avatar dentro del grid (columna Nombre)
   ==================================================================== */
.grid-user-cell {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.grid-user-cell__avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    overflow: hidden;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    color: var(--fg-muted);
}
.grid-user-cell__avatar[data-hue] { color: #fff; border: 0; }
.grid-user-cell__avatar[data-hue="0"] { background: linear-gradient(135deg, oklch(0.65 0.12 25), oklch(0.45 0.15 15)); }
.grid-user-cell__avatar[data-hue="1"] { background: linear-gradient(135deg, oklch(0.62 0.12 260), oklch(0.45 0.15 250)); }
.grid-user-cell__avatar[data-hue="2"] { background: linear-gradient(135deg, oklch(0.65 0.12 145), oklch(0.48 0.15 145)); }
.grid-user-cell__avatar[data-hue="3"] { background: linear-gradient(135deg, oklch(0.65 0.13 60), oklch(0.50 0.15 50)); }
.grid-user-cell__avatar[data-hue="4"] { background: linear-gradient(135deg, oklch(0.65 0.12 310), oklch(0.48 0.15 300)); }
.grid-user-cell__avatar[data-hue="5"] { background: linear-gradient(135deg, oklch(0.65 0.10 200), oklch(0.45 0.12 200)); }
.grid-user-cell__avatar img {
    width: 100%; height: 100%; object-fit: cover;
}
.grid-user-cell__text { min-width: 0; line-height: 1.25; }
.grid-user-cell__name { font-weight: 500; color: var(--fg-strong); }
.grid-user-cell__email { font-size: 11.5px; color: var(--fg-muted); }

/* ====================================================================
   Tipo badge (columna Tipo del grid + select del slideover)
   Color token semántico viene del TipoUsuario (success/warning/danger/info/neutral)
   ==================================================================== */
.tipo-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: var(--r-sm);
    font-size: 11.5px;
    font-weight: 500;
    line-height: 1.6;
    background: var(--status-inactive-bg);
    color: var(--status-inactive);
}
.tipo-badge--success { background: var(--status-active-bg);   color: var(--status-active); }
.tipo-badge--warning { background: var(--status-pending-bg);  color: var(--status-pending); }
.tipo-badge--danger  { background: var(--status-danger-bg);   color: var(--status-danger); }
.tipo-badge--info    { background: color-mix(in oklab, var(--smart-info) 15%, transparent); color: var(--smart-info); }
.tipo-badge--neutral { background: var(--status-inactive-bg); color: var(--status-inactive); }

/* ====================================================================
   Radio cards (grupo vertical de opciones con título + descripción)
   Patrón: input a la izquierda, título al lado, descripción debajo.
   Uso: Programa CRUD (selector de Tipo), futuros selectores tipo-encuesta.
   ==================================================================== */
.radio-cards {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.radio-card {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: background 80ms ease, border-color 80ms ease;
}
.radio-card:hover { background: var(--bg-subtle); }
.radio-card input[type="radio"] {
    flex-shrink: 0;
    margin: 3px 0 0 0;
    accent-color: var(--heb-red);
}
.radio-card__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.radio-card__title {
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
    line-height: 1.3;
}
.radio-card__desc {
    font-size: 12px;
    color: var(--fg-muted);
    line-height: 1.4;
}
.radio-card:has(input:checked) {
    border-color: var(--heb-red);
    background: var(--heb-red-soft);
}

/* ====================================================================
   Panel info banner (slideover tabs — info aclaratoria al inicio)
   ==================================================================== */
.panel-info {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    margin-bottom: 14px;
    background: var(--bg-subtle);
    border-radius: var(--r-sm);
    font-size: 12.5px;
    color: var(--fg-muted);
    line-height: 1.5;
}
.panel-info svg {
    flex-shrink: 0;
    margin-top: 2px;
    color: var(--fg-muted);
}
/* El atributo `hidden` debe ganarle al display:flex de arriba. */
.panel-info[hidden] { display: none; }
/* 3.63: aviso de Seguimiento cuando se llega filtrado desde el Dashboard. */
.seg-atencion { align-items: center; }
.seg-atencion__texto { flex: 1; min-width: 0; color: var(--fg); }
.panel-info--muted {
    font-size: 11.5px;
    margin-top: 12px;
    margin-bottom: 0;
}

/* ====================================================================
   Tab counter (badge en pestañas con conteo)
   ==================================================================== */
.tab__count {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 10px;
    background: var(--bg-subtle);
    color: var(--fg-muted);
    font-size: 10.5px;
    font-weight: 500;
    line-height: 1.5;
    vertical-align: middle;
}
.tab--active .tab__count {
    background: var(--heb-red-soft);
    color: var(--heb-red);
}

/* ====================================================================
   Chip list (lista vertical de tarjetas horizontales con clave + nombre)
   Uso: tab "Privilegios disponibles" de Programa CRUD.
   ==================================================================== */
.chip-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 12px;
}
.chip-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    transition: border-color 80ms ease, background 80ms ease;
}
.chip-item__key {
    flex-shrink: 0;
    min-width: 64px;
    padding: 4px 8px;
    text-align: center;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--fg-strong);
    background: var(--bg-subtle);
    border-radius: var(--r-sm);
}
.chip-item__body {
    flex: 1;
    min-width: 0;
}
.chip-item__title {
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
    line-height: 1.3;
}
.chip-item__lock {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--heb-red);
}
.chip-item--required {
    border-color: var(--heb-red);
    background: var(--heb-red-soft);
}
.chip-item--required .chip-item__key {
    background: rgba(204, 0, 0, 0.15);
    color: var(--heb-red);
}

/* ====================================================================
   Empty state (estado vacío dentro de listas/tabs)
   ==================================================================== */
.empty-state {
    padding: 24px 16px;
    text-align: center;
    color: var(--fg-muted);
    font-size: 12.5px;
    background: var(--bg-subtle);
    border-radius: var(--r-sm);
}
.empty-state--inline {
    padding: 14px 16px;
    background: transparent;
}

/* ====================================================================
   Modal extras: header con close + variantes de ancho
   ==================================================================== */
.modal--md { max-width: 560px; }
.modal--lg { max-width: 720px; }

.modal__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}
.modal__header .modal__title {
    flex: 1;
    min-width: 0;
}

/* ====================================================================
   Row list (contenedor de filas para selección — modales tipo "Agregar")
   ==================================================================== */
.row-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.row-list--bordered {
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    padding: 8px;
    gap: 4px;
}
.row-list--scroll {
    max-height: 340px;
    overflow-y: auto;
}

/* ====================================================================
   Row pick (fila seleccionable con checkbox/radio + clave + título)
   Uso: modal Agregar privilegio, modal Asignar subprograma.
   ==================================================================== */
.row-pick {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: border-color 80ms ease, background 80ms ease;
}
.row-pick:hover { background: var(--bg-subtle); }
.row-pick input[type="checkbox"],
.row-pick input[type="radio"] {
    flex-shrink: 0;
    accent-color: var(--heb-red);
    margin: 0;
}
.row-pick__key {
    flex-shrink: 0;
    min-width: 64px;
    padding: 4px 8px;
    text-align: center;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--fg-strong);
    background: var(--bg-subtle);
    border-radius: var(--r-sm);
}
.row-pick__body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.row-pick__title {
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
    line-height: 1.3;
}
.row-pick__sub {
    font-size: 12px;
    color: var(--fg-muted);
    line-height: 1.4;
}
.row-pick--active {
    border-color: var(--heb-red);
    background: var(--heb-red-soft);
}
.row-pick--active .row-pick__key {
    background: rgba(204, 0, 0, 0.15);
    color: var(--heb-red);
}

/* ====================================================================
   Row item (fila informativa con título + sub + badge + acción)
   Uso: tab "Subprogramas" del slideover de Programa CRUD.
   ==================================================================== */
.row-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
}
.row-item__body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.row-item__title {
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
    line-height: 1.3;
}
.row-item__sub {
    font-size: 11.5px;
    color: var(--fg-muted);
    line-height: 1.3;
}

/* ====================================================================
   Icon picker — grid visual de iconos seleccionables
   Usado en slide panel de Responsabilidades (épica 1.9) y reusable en
   cualquier formulario que requiera elegir un icono Lucide del catálogo.
   ==================================================================== */
.icon-picker {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
    padding: 8px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.icon-picker__item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 36px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    color: var(--fg-muted);
    cursor: pointer;
    transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    padding: 0;
}
.icon-picker__item:hover {
    border-color: var(--heb-red);
    color: var(--fg-strong);
}
.icon-picker__item.is-active {
    background: var(--heb-red);
    border-color: var(--heb-red);
    color: #fff;
}
.icon-picker__item:focus-visible {
    outline: 2px solid var(--heb-red);
    outline-offset: 2px;
}
.icon-picker__item[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}
.icon-picker__item[disabled]:hover {
    background: var(--bg-elevated);
    border-color: var(--border);
    color: var(--fg-muted);
}

/* ====================================================================
   Celda con ícono + texto (para columnas tipo "Nombre" con icono)
   ==================================================================== */
.cell-icon-name {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
.cell-icon-name__icon {
    width: 28px;
    height: 28px;
    border-radius: var(--r-md);
    background: var(--heb-red-soft);
    color: var(--heb-red);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.cell-icon-name__icon svg {
    width: 14px;
    height: 14px;
}
.cell-icon-name__icon--empty {
    background: var(--bg-subtle);
    color: var(--fg-subtle);
}
.cell-icon-name__text {
    font-weight: 500;
    color: var(--fg-strong);
}

/* ====================================================================
   Split pane — layout izq (aside) + der (main) usado en el centro de
   comando de Responsabilidades (Vistas B y C de la épica 1.9).
   ==================================================================== */
.split-pane {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 16px;
    align-items: stretch;
    /* Fuerza altura al viewport disponible (topbar + page-header + padding ≈ 180px)
       para que ambos paneles llenen el espacio sin desbordar en laptops. */
    height: calc(100vh - 180px);
    min-height: 360px;
}
.split-pane__aside {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-width: 0;
    min-height: 0;
}
.split-pane__aside-head {
    padding: 14px 14px 10px;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.split-pane__aside-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin: 0;
}
.split-pane__aside-list {
    flex: 1;
    overflow-y: auto;
    padding: 4px 0;
    min-height: 220px;
}
.split-pane__aside-empty {
    padding: 32px 16px;
    text-align: center;
    font-size: 12.5px;
    color: var(--fg-muted);
}
.split-pane__aside-foot {
    padding: 12px;
    border-top: 1px solid var(--border);
    background: var(--bg-subtle);
}
.split-pane__main {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
}
/* Wrappers de detalle dentro del split-pane__main (centro de comando Vista B
   y editor de menús Vista C). Sin esto, el cuerpo crece libre y el save bar
   se sale del viewport en pantallas con menos alto disponible (ej. con
   barra de favoritos del browser). Ver DESIGN_SYSTEM §11 y bug pre-existente
   del centro de comando. */
#cc-detail,
#mn-detail,
#ac-detail {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}
.split-pane__main-head {
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 16px;
}
.split-pane__main-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--fg-strong);
    margin: 0;
}
.split-pane__main-sub {
    font-size: 12.5px;
    color: var(--fg-muted);
    margin-top: 2px;
}
.split-pane__main-toolbar {
    padding: 12px 20px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-subtle);
    display: flex;
    gap: 8px;
    align-items: center;
}
.split-pane__main-body {
    flex: 1;
    overflow: hidden;
    padding: 0;
    min-height: 0;
}
.split-pane__main-body smart-grid {
    display: block;
    height: 100%;
    width: 100%;
    min-height: 220px;
}
.split-pane__empty {
    padding: 48px 24px;
    text-align: center;
    color: var(--fg-muted);
    font-size: 13.5px;
}

/* ====================================================================
   Lista seleccionable (filas con estado activo) — usada en split-pane
   ==================================================================== */
.row-select {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    cursor: pointer;
    border-left: 2px solid transparent;
    transition: background var(--t-fast), border-color var(--t-fast);
}
.row-select:hover {
    background: var(--bg-subtle);
}
.row-select.is-active {
    background: var(--heb-red-soft);
    border-left-color: var(--heb-red);
}
.row-select__icon {
    width: 28px;
    height: 28px;
    border-radius: var(--r-md);
    background: var(--heb-red-soft);
    color: var(--heb-red);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.row-select__icon svg {
    width: 14px;
    height: 14px;
}
.row-select__body {
    flex: 1;
    min-width: 0;
}
.row-select__title {
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.row-select__meta {
    font-size: 11.5px;
    color: var(--fg-muted);
    line-height: 1.3;
    margin-top: 2px;
}
.row-select__actions {
    display: inline-flex;
    gap: 2px;
    flex-shrink: 0;
    opacity: 0;
    transition: opacity var(--t-fast);
}
.row-select:hover .row-select__actions,
.row-select.is-active .row-select__actions {
    opacity: 1;
}

/* ====================================================================
   Avatar tamaño grande — usado en header del centro de comando
   ==================================================================== */
.avatar--lg {
    width: 44px;
    height: 44px;
    font-size: 16px;
    border-radius: var(--r-md);
}

/* ====================================================================
   Counter pill — píldora con valor grande + label (centro de comando)
   ==================================================================== */
.counter-pill {
    background: var(--heb-red-soft);
    border-radius: var(--r-md);
    padding: 6px 12px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.1;
    flex-shrink: 0;
}
.counter-pill__num {
    font-size: 18px;
    font-weight: 700;
    color: var(--heb-red);
    letter-spacing: -0.02em;
}
.counter-pill__lbl {
    font-size: 10.5px;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-top: 2px;
    white-space: nowrap;
}

/* ====================================================================
   Save bar — pie fijo del centro de comando con cambios sin guardar
   ==================================================================== */
.save-bar {
    border-top: 1px solid var(--border);
    background: var(--bg-subtle);
    padding: 10px 16px;
    display: flex;
    align-items: center;
    gap: 12px;
}
.save-bar__msg {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--fg);
}
.save-bar__count {
    color: var(--fg-muted);
    margin-left: 4px;
}
.save-bar__actions {
    display: flex;
    gap: 8px;
}

/* ====================================================================
   Matriz de privilegios — bloques por Menú con tabla Programa x Privilegio
   (usado en Vista B del Centro de comando, épica 1.9)
   ==================================================================== */
.priv-menublock {
    border-bottom: 1px solid var(--border);
}
.priv-menublock__head {
    padding: 10px 20px;
    background: var(--bg-subtle);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 10px;
    position: sticky;
    top: 0;
    z-index: 2;
}
.priv-menublock__icon {
    width: 22px;
    height: 22px;
    border-radius: var(--r-sm);
    background: var(--heb-red-soft);
    color: var(--heb-red);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.priv-menublock__icon svg { width: 12px; height: 12px; }
.priv-menublock__name {
    font-size: 13px;
    font-weight: 600;
    color: var(--fg-strong);
    flex: 1;
    min-width: 0;
}
.priv-menublock__meta {
    font-size: 11.5px;
    color: var(--fg-muted);
}
.priv-menublock__body {
    overflow-x: auto;
}
.priv-table {
    /* min-width 100% para llenar el contenedor con pocas columnas; width auto
       permite a la tabla crecer (con scroll horizontal del padre) cuando hay
       muchas columnas, sin amontonar los checkboxes. */
    min-width: 100%;
    width: auto;
    border-collapse: collapse;
    font-size: 12.5px;
}
.priv-table thead th {
    background: var(--bg-elevated);
    border-bottom: 1px solid var(--border);
    text-align: center;
    padding: 8px 8px;
    font-size: 11px;
    font-weight: 600;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    min-width: 64px;
}
.priv-table th.priv-table__prog,
.priv-table td.priv-table__prog {
    text-align: left;
    padding-left: 20px;
    /* Columna Programa: ancho fijo + sticky para que quede visible al hacer
       scroll horizontal de la matriz (igual que el prototipo). */
    width: 280px;
    min-width: 280px;
    position: sticky;
    left: 0;
    background: var(--bg-elevated);
    z-index: 1;
}
.priv-table thead th.priv-table__prog {
    z-index: 2;
}
.priv-table td {
    border-bottom: 1px solid var(--border);
    padding: 8px 8px;
    text-align: center;
}
.priv-table tr:last-child td { border-bottom: 0; }
.priv-table__row--sub td.priv-table__prog {
    padding-left: 44px;
    color: var(--fg-muted);
}
.priv-table__progname {
    font-weight: 500;
    color: var(--fg-strong);
}
.priv-table__progkey {
    font-family: var(--font-mono, monospace);
    font-size: 11px;
    color: var(--fg-muted);
    margin-top: 1px;
}
.priv-table__warn {
    margin-left: 6px;
    color: oklch(0.55 0.16 60);
    display: inline-flex;
    vertical-align: middle;
}
.priv-cell {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.priv-cell:has(input[disabled]) {
    cursor: not-allowed;
}
.priv-cell input { display: none; }
.priv-cell input[disabled] + .priv-cell__box {
    opacity: 0.5;
}
.priv-cell__box {
    width: 18px;
    height: 18px;
    border-radius: 4px;
    border: 1.5px solid var(--border);
    background: var(--bg-elevated);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    transition: background var(--t-fast), border-color var(--t-fast);
}
.priv-cell input:checked + .priv-cell__box {
    background: var(--heb-red);
    border-color: var(--heb-red);
}
.priv-cell__box svg { width: 11px; height: 11px; }
.priv-cell__box--on {
    background: var(--heb-red);
    border-color: var(--heb-red);
}
.priv-cell__na {
    color: var(--fg-subtle);
    font-size: 14px;
}

/* ====================================================================
   Bloque por Responsabilidad — usado en accesos del usuario (épica 1.42)
   ==================================================================== */
.resp-block {
    border-bottom: 6px solid var(--bg-subtle);
}
.resp-block:last-child {
    border-bottom: 0;
}
.resp-block__head {
    padding: 14px 20px;
    background: var(--bg-elevated);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 12px;
    position: sticky;
    top: 0;
    z-index: 3;
}
.resp-block__icon {
    width: 28px;
    height: 28px;
    border-radius: var(--r-md);
    background: var(--heb-red-soft);
    color: var(--heb-red);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.resp-block__icon svg { width: 14px; height: 14px; }
.resp-block__name {
    font-size: 14px;
    font-weight: 600;
    color: var(--fg-strong);
    flex: 1;
    min-width: 0;
}
.resp-block__meta {
    font-size: 12px;
    color: var(--fg-muted);
}
.resp-block__empty {
    padding: 16px 20px;
    color: var(--fg-muted);
    font-size: 12.5px;
}


/* =============================================================
   Dashboard del módulo Seguridad (épica 1.24)
   ============================================================= */
.dash-seg { display: flex; flex-direction: column; gap: var(--gap); }

.dash-seg .page-header { margin: 0; }

.dash-seg__period {
    display: inline-flex; align-items: center; gap: 6px;
    height: var(--input-h);
    padding: 0 12px;
    border-radius: var(--r-md);
    background: var(--bg-elevated);
    border: 1px solid var(--border-strong);
    color: var(--fg-muted);
    font-size: 13px;
    font-weight: 500;
}

.dash-seg__period svg { color: var(--fg-subtle); }

.dash-seg__refresh-icon {
    display: inline-flex;
    align-items: center;
    transition: transform var(--t-base);
}
.dash-seg[data-loading="true"] .dash-seg__refresh-icon { animation: dash-seg-spin 0.9s linear infinite; }
@keyframes dash-seg-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

.dash-seg__error {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 16px;
    border-radius: var(--r-md);
    background: var(--status-danger-bg);
    color: var(--status-danger);
    font-size: 13px;
}
.dash-seg__error[hidden] { display: none; }
.dash-seg__error button { margin-left: auto; }

/* --- KPI grid --- */
.dash-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: var(--gap);
}
@media (max-width: 1280px) { .dash-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 720px)  { .dash-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px)  { .dash-grid { grid-template-columns: 1fr; } }

/* --- Reporte de Existencias: barra de filtros (rejilla 3 col, etiqueta a la izquierda) --- */
.rpt-filters {
    display: grid;
    /* Col 1: Almacén/Tienda · Col 2: Familia/Producto (más ancha) · Col 3: Mostrar/Fecha (angosta). */
    grid-template-columns: 1fr 1.35fr 0.85fr;
    gap: 10px 24px;
    align-items: center;
    margin-bottom: 12px;
}
@media (max-width: 1100px) { .rpt-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Variante de 2 columnas (usada por el Reporte de Kardex): la izquierda
   (Producto / Almacén) más ancha que la derecha (Tienda / Fecha Corte). */
.rpt-filters--2col { grid-template-columns: 2fr 1fr; max-width: 1040px; }
/* Variante del Control de Existencias: dos columnas, la 1 (Almacén / Producto)
   más ancha para que se lea el nombre del producto; la 2 (Tienda destino /
   Ubicación) más angosta. Aprovecha el ancho disponible de la pantalla. */
.rpt-filters--2eq { grid-template-columns: 1.7fr 1fr; max-width: 1500px; }
/* Variante del Reporte de Inventarios: col 1 (Almacén/Producto) ancha para que
   se vea el nombre del producto; col 2 (Familia) angosta; col 3 media. */
.rpt-filters--inv { grid-template-columns: 1.5fr 1.1fr 0.9fr; }
/* Variante del Reporte Presupuesto/Gasto (3.35): rejilla 3x3 de columnas
   iguales (9 filtros candidatos ICB 5). */
.rpt-filters--3eq { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.rpt-filters .toolbar__group {
    flex-direction: row;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.rpt-filters .form-label {
    margin: 0;
    flex-shrink: 0;
    width: 96px;
    text-align: right;
}
.rpt-filters .heb-combo,
.rpt-filters .toolbar__group .input {
    flex: 1 1 auto;
    min-width: 0;
    width: auto;
}
/* Letra de los campos de filtro un poco más chica (combos, select y fecha). */
.rpt-filters .heb-combo { --smart-font-size: 12px; }
/* El valor mostrado en el combo (single-select) y el buscador van en elementos
   internos que no siempre heredan la variable: se fijan a 12px explícitamente. */
.rpt-filters .heb-combo .smart-action-button,
.rpt-filters .heb-combo input { font-size: 12px; }
.rpt-filters .toolbar__group .input { font-size: 12px; }
/* Opciones del desplegable del combo (cada smart-list-item fija su propia
   --smart-font-size, así que se ataca a nivel del item, no del list-box). */
.rpt-filters .heb-combo smart-list-item { font-size: 12px; }

/* Reporte de Existencias: el contenido llena el alto disponible y el grid toma
   el espacio sobrante (alto flexible). Así la PÁGINA no genera scroll vertical
   aunque crezcan los filtros; solo el grid hace scroll interno. Acotado al
   reporte (.rpt-screen) para NO alterar el alto fijo de .heb-grid en las demás
   pantallas. */
.content__inner:has(.rpt-screen) {
    display: flex;
    flex-direction: column;
    min-height: 100%;
}
.rpt-screen {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}
/* El grid vive en un contenedor flex con alto resuelto; el grid toma 100% de él
   (Smart grid necesita un alto concreto para calcular su viewport, por eso no se
   usa height:auto). */
.rpt-grid-wrap {
    flex: 1 1 0;
    min-height: 220px;
}
.rpt-screen .heb-grid {
    height: 100%;
}
/* Control de Existencias: el grid hijo (distribución física por ubicación) se
   muestra angosto y centrado, con filas/header más bajos que el maestro, para
   distinguirlo como tabla de apoyo. */
.ex-nested {
    margin: 8px auto;
    max-width: 760px;
    --smart-grid-row-height: 24px;
    --smart-grid-column-header-height: 26px;
    --smart-grid-cell-padding: 3px 10px;
}
/* Historial de reubicaciones (pestaña del panel): las salidas automáticas
   (generadas por movimientos, no reubicaciones manuales) van atenuadas. */
.ex-hist-auto td {
    color: var(--fg-muted);
}
/* Multi-selección: las fichas de los seleccionados no crecen el combo; se topan
   a ~2 renglones con scroll interno. */
.rpt-filters .heb-combo .smart-buttons-container {
    max-height: 58px;
    overflow-y: auto;
}

.stat {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 16px;
    display: flex; flex-direction: column; gap: 8px;
    transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.stat:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }

.stat__top {
    display: flex; align-items: center; justify-content: space-between;
    gap: 8px;
}
.stat__label {
    font-size: 12px; font-weight: 500;
    color: var(--fg-muted);
    text-transform: none;
    letter-spacing: 0;
}
.stat__icon {
    width: 32px; height: 32px;
    border-radius: var(--r-md);
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.stat__icon--accent { background: var(--heb-red-soft); color: var(--heb-red); }
.stat__icon--alert  { background: var(--status-pending-bg); color: var(--status-warning); }

.stat__value {
    font-size: 26px;
    font-weight: 600;
    color: var(--fg-strong);
    letter-spacing: -0.015em;
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
}

.stat__delta {
    font-size: 11.5px;
    display: inline-flex; align-items: center; gap: 4px;
    color: var(--fg-muted);
}
.stat__delta--up    { color: var(--status-active); }
.stat__delta--down  { color: var(--fg-muted); }
.stat__delta--alert { color: var(--status-warning); }
.stat__delta--flat  { color: var(--fg-muted); }
.stat__delta svg { width: 12px; height: 12px; }

/* --- 2-col rows --- */
.dash-2col {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: var(--gap);
}
.dash-2col + .dash-2col { grid-template-columns: 1fr 1fr; }
@media (max-width: 1100px) {
    .dash-2col, .dash-2col + .dash-2col { grid-template-columns: 1fr; }
}

/* --- Card chrome propio del dashboard (más compacto que .card global) --- */
.dash-seg .card {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 0;
    display: flex; flex-direction: column;
    overflow: hidden;
}
.card__header {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px;
    padding: 16px 20px 12px;
    border-bottom: 1px solid var(--border);
}
.card__title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--fg-strong);
    letter-spacing: -0.005em;
}
.card__sub {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--fg-muted);
}
.card__link {
    font-size: 12.5px;
    color: var(--heb-red);
    font-weight: 500;
    cursor: pointer;
    flex-shrink: 0;
}
.card__link:hover { color: var(--heb-red-hover); text-decoration: underline; }

.card__body { padding: 16px 20px; }
.card__body--flush { padding: 0; }

/* --- Chart 7d --- */
.chart-area { padding: 20px 12px; }
.chart-area svg { width: 100%; height: 240px; display: block; }
.chart-grid line { stroke: var(--border); stroke-width: 1; }
.chart-line { fill: none; stroke: var(--heb-red); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.chart-axis-label { font-size: 10.5px; fill: var(--fg-muted); font-family: var(--font-mono); }

/* --- Donut --- */
.donut-wrap {
    padding: 12px 20px 20px;
    display: flex; align-items: center; gap: 20px;
    flex-wrap: wrap;
    justify-content: center;
}
.donut { width: 160px; height: 160px; flex-shrink: 0; }
.donut-legend {
    flex: 1;
    min-width: 180px;
    display: flex; flex-direction: column;
    gap: 6px;
}
.donut-legend__row {
    display: flex; align-items: center; gap: 8px;
    font-size: 12.5px;
    color: var(--fg);
}
.donut-legend__sw {
    width: 10px; height: 10px;
    border-radius: var(--r-sm);
    flex-shrink: 0;
}
.donut-legend__label { flex: 1; min-width: 0; }
.donut-legend__val { font-variant-numeric: tabular-nums; color: var(--fg-strong); font-weight: 500; }
.donut-legend__pct { width: 38px; text-align: right; color: var(--fg-muted); font-size: 11.5px; font-variant-numeric: tabular-nums; }

/* --- Listas --- */
.dash-list { display: flex; flex-direction: column; }
.dash-list__row {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 20px;
    border-bottom: 1px solid var(--border);
    min-height: 56px;
}
.dash-list__row:last-child { border-bottom: 0; }
.dash-list__row--clickable { cursor: pointer; }
.dash-list__row--clickable:hover { background: var(--bg-hover); }
.dash-list__row--skeleton { gap: 12px; }

.dash-list__name {
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
    line-height: 1.3;
}
.dash-list__meta {
    font-size: 11.5px;
    color: var(--fg-muted);
    line-height: 1.3;
    margin-top: 2px;
}
.dash-list__meta--mono { font-family: var(--font-mono); }
.dash-list__time {
    font-size: 11.5px;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
.dash-list__right {
    display: flex; flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    flex-shrink: 0;
}
.dash-list__empty {
    padding: 20px;
    text-align: center;
    color: var(--fg-muted);
    font-size: 12.5px;
}

.dash-list__avatar {
    width: 32px; height: 32px;
    border-radius: 50%;
    background: var(--heb-red-soft);
    color: var(--heb-red);
    font-size: 11.5px;
    font-weight: 600;
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}

/* --- Iconos / dots para listas --- */
.dash-suspicious__icon {
    width: 28px; height: 28px;
    border-radius: var(--r-md);
    background: var(--status-pending-bg);
    color: var(--status-warning);
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.dash-suspicious__meta { color: var(--fg-muted); }

.dash-audit__dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--fg-subtle);
    flex-shrink: 0;
}
.dash-audit__dot--warn { background: var(--status-warning); }
.dash-audit__dot--info { background: var(--heb-red); }
.dash-audit__actor { color: var(--fg-strong); font-weight: 500; }
.dash-audit__target { color: var(--fg-strong); font-weight: 500; }

/* ==========================================================================
   Mi cuenta — Perfil + Seguridad (épica 1.37)
   Card con tabs a todo lo ancho + cuerpo con padding propio (las .tabs ya
   traen su propio padding lateral, así que la card va sin padding).
   ========================================================================== */
/* La tarjeta cabe en la pantalla y la pestaña se desplaza por dentro: a
   1366×768 el Perfil era 217 px más alto que el área visible (épica 4.3).
   176 px = barra superior + encabezado de la página + relleno del contenido. */
.mc-card {
    padding: 0; overflow: hidden;
    display: flex; flex-direction: column;
    max-height: calc(100vh - 176px);
}
.mc-card > .tabs { flex-shrink: 0; }
.mc-body { padding: 24px; overflow-y: auto; min-height: 0; }

/* Fila acción + descripción (cambiar contraseña, 2FA, etc.) */
.mc-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.mc-row__title { font-size: 13px; font-weight: 500; color: var(--fg-strong); }
.mc-row__sub { font-size: 12px; color: var(--fg-muted); margin-top: 2px; }

/* Bloque de información administrativa read-only */
.mc-readonly {
    margin-top: 20px;
    padding: 16px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.mc-readonly__title {
    font-size: 12px;
    font-weight: 600;
    color: var(--fg-strong);
    margin-bottom: 12px;
}
.mc-readonly__label { font-size: 11px; color: var(--fg-muted); margin-bottom: 2px; }
.mc-readonly__value { font-size: 13px; color: var(--fg-strong); }
.mc-readonly__hint {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    font-size: 11.5px;
    color: var(--fg-muted);
}

/* Barra de acciones del formulario (Cancelar / Guardar) */
.mc-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
    /* Pegada al pie mientras la pestaña se desplaza: Guardar siempre a la
       vista. El -24px cubre el relleno inferior de .mc-body. */
    position: sticky;
    bottom: -24px;
    margin-bottom: -24px;
    padding-bottom: 24px;
    background: var(--bg-elevated);
}

/* Enlace-botón en texto (Cambiar correo, Cancelar cambio) */
.mc-linkbtn {
    background: none;
    border: 0;
    padding: 0;
    margin-top: 6px;
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    color: var(--heb-red);
    cursor: pointer;
}
.mc-linkbtn:hover { text-decoration: underline; }
.mc-linkbtn:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; border-radius: var(--r-sm); }
.mc-linkbtn--danger { color: var(--status-danger); flex-shrink: 0; }

/* Editor inline de cambio de correo */
.mc-correo-edit {
    margin: 0 0 16px;
    padding: 16px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.mc-correo-edit__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 12px;
}

/* Banner de cambio de correo pendiente */
.mc-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 16px;
    padding: 12px 14px;
    background: var(--status-pending-bg);
    border: 1px solid var(--status-pending);
    border-radius: var(--r-md);
    font-size: 12.5px;
    color: var(--fg-strong);
}
.mc-banner__icon { color: var(--status-pending); display: inline-flex; flex-shrink: 0; }
.mc-banner__text { flex: 1; min-width: 0; }
/* El atributo `hidden` debe ganarle al display:flex de arriba. */
.mc-banner[hidden] { display: none; }

/* Variante "verificado" (verde) del banner — correo SMTP propio (épica 1.53) */
.mc-banner--ok {
    background: var(--status-active-bg);
    border-color: var(--status-active);
}
.mc-banner--ok .mc-banner__icon { color: var(--status-active); }
.mc-smtp-fecha { color: var(--fg-muted); }

/* Checklist de reglas de contraseña (modal de cambio) */
.mc-pwd-rules {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: grid;
    gap: 4px;
}
.mc-pwd-rules li {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11.5px;
    color: var(--fg-muted);
}
.mc-pwd-rules li::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--fg-subtle);
    flex-shrink: 0;
}
.mc-pwd-rules li.ok { color: var(--fg); }
.mc-pwd-rules li.ok::before { background: var(--status-active); }

/* Sesiones activas (CU-SEG-035) */
.mc-sesiones { display: grid; gap: 8px; margin-top: 8px; }
.mc-sesion {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-subtle);
}
.mc-sesion__icon { color: var(--fg-muted); display: inline-flex; flex-shrink: 0; }
.mc-sesion__info { flex: 1; min-width: 0; }
.mc-sesion__device {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 500;
    color: var(--fg-strong);
}
.mc-sesion__meta { font-size: 11.5px; color: var(--fg-muted); margin-top: 2px; }
.mc-sesion__actual {
    font-size: 11px;
    font-weight: 500;
    color: var(--status-active);
    background: var(--status-active-bg);
    padding: 1px 8px;
    border-radius: 999px;
}
.mc-sesiones__vacio { font-size: 12.5px; color: var(--fg-muted); margin: 4px 0 0; }

/* Configurador 2FA (CU-SEG-008/009/030) */
.mc-2fa-card {
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-subtle);
    margin-bottom: 14px;
}
.mc-2fa-card--on { border-color: var(--status-active); background: var(--status-active-bg); }
.mc-2fa-card--off { border-color: var(--status-pending); background: var(--status-pending-bg); }
.mc-2fa-card__title { font-size: 14px; font-weight: 600; color: var(--fg-strong); display: flex; align-items: center; }
.mc-2fa-card__badge { margin-left: 8px; }
.mc-2fa-card__sub { font-size: 12px; color: var(--fg-muted); margin-top: 4px; }

.mc-2fa-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.mc-2fa-policy {
    display: flex; align-items: center; gap: 6px;
    font-size: 11.5px; color: var(--status-warning, var(--fg-muted));
    margin-bottom: 12px;
}

.mc-2fa-picker { margin-top: 8px; }
.mc-2fa-picker__title { font-size: 12px; font-weight: 600; color: var(--fg-strong); margin-bottom: 8px; }
.mc-2fa-options { display: grid; gap: 8px; }
.mc-2fa-opt {
    text-align: left;
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-elevated);
    cursor: pointer;
    transition: border-color var(--t-fast), background var(--t-fast);
}
.mc-2fa-opt:hover:not([disabled]) { border-color: var(--border-strong); background: var(--bg-hover); }
.mc-2fa-opt:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.mc-2fa-opt[disabled] { opacity: 0.55; cursor: not-allowed; }
.mc-2fa-opt__title { font-size: 13px; font-weight: 500; color: var(--fg-strong); }
.mc-2fa-opt__sub { font-size: 11.5px; color: var(--fg-muted); margin-top: 2px; }

.mc-2fa-enroll { display: grid; gap: 10px; }
.mc-2fa-enroll__actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
.mc-2fa-qr {
    width: 180px; height: 180px;
    padding: 8px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.mc-2fa-qr svg { width: 100%; height: 100%; display: block; }
.mc-2fa-secret {
    padding: 8px 12px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    font-size: 13px;
    letter-spacing: 0.04em;
}
.mc-otp {
    max-width: 180px;
    font-family: var(--font-mono);
    font-size: 18px;
    letter-spacing: 0.3em;
    text-align: center;
}

.mc-2fa-backup { display: grid; gap: 12px; }
.mc-2fa-backup__warn {
    padding: 10px 12px;
    background: var(--status-pending-bg);
    border: 1px solid var(--status-pending);
    border-radius: var(--r-md);
    font-size: 12px;
    color: var(--fg-strong);
}
.mc-2fa-codes { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.mc-2fa-code {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    background: var(--bg-subtle);
    font-size: 13px;
}
.mc-2fa-code__num { font-size: 11px; color: var(--fg-muted); width: 18px; flex-shrink: 0; }
.mc-2fa-backup__tools { display: flex; gap: 8px; flex-wrap: wrap; }
.mc-2fa-backup__confirm { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--fg); }
@media (max-width: 640px) { .mc-2fa-codes { grid-template-columns: 1fr; } }

/* Toast global de confirmación (esquina superior derecha, bajo el topbar).
   Antes .mc-toast, solo de Mi cuenta; promovido a común en la mejora #11 —
   lo crea la función toast() de crud-utils.js. Movido de abajo a arriba
   (decisión Salma 2026-07-05): abajo tapaba los botones del pie de los
   slide panels (Guardar / Autorizar). */
.toast {
    position: fixed;
    top: calc(var(--topbar-height) + 16px);
    right: 24px;
    z-index: 120;
    padding: 10px 16px;
    border-radius: var(--r-md);
    background: var(--fg-strong);
    color: var(--bg-elevated);
    font-size: 13px;
    font-weight: 500;
    box-shadow: var(--shadow-pop);
    opacity: 0;
    transform: translateY(-8px);
    pointer-events: none;
    transition: opacity var(--t-fast), transform var(--t-fast);
}
.toast--show { opacity: 1; transform: translateY(0); }

/* Banner de error de carga de un grid (mejora #11): la pantalla lo inserta
   arriba del grid cuando el GET de datos falla — sin él, el grid quedaba
   vacío en silencio y no se distinguía de "no hay registros". */
.grid-error {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
    padding: 10px 14px;
    border: 1px solid var(--status-danger);
    border-radius: var(--r-md);
    background: var(--status-danger-bg);
    color: var(--status-danger);
    font-size: 13px;
}

/* Enlace del pie del sidebar (avatar + nombre → Mi cuenta) */
.sidebar__foot-link {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    text-decoration: none;
    color: inherit;
    padding: 4px 6px;
    margin: -4px -6px;
    border-radius: var(--r-md);
    transition: background var(--t-fast);
}
.sidebar__foot-link:hover { background: var(--sidebar-hover); }
.sidebar__foot-link.active { background: var(--sidebar-hover); }
.sidebar__foot-link:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }

/* ====================================================================
   Acceso a Almacenes (INV-10) — tarjeta de almacén con sus movimientos
   dentro del split-pane (patrón Responsabilidades). Cada tarjeta lista
   los movimientos habilitados del almacén como casillas seleccionables.
   ==================================================================== */
.acceso-cards {
    overflow-y: auto;
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.acceso-cards__empty {
    padding: 40px;
    border: 1px dashed var(--border);
    border-radius: var(--r-md);
    text-align: center;
    color: var(--fg-muted);
    font-size: 13px;
}
.acceso-card {
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    background: var(--bg-elevated);
}
.acceso-card__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    background: var(--bg-subtle);
    border-bottom: 1px solid var(--border);
}
.acceso-card__icon {
    width: 30px;
    height: 30px;
    border-radius: var(--r-sm);
    background: var(--heb-red-soft);
    color: var(--heb-red);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.acceso-card__icon svg { width: 16px; height: 16px; }
.acceso-card__titles { flex: 1; min-width: 0; }
.acceso-card__name {
    font-weight: 600;
    color: var(--fg-strong);
    font-size: 13.5px;
}
.acceso-card__key {
    font-size: 11.5px;
    color: var(--fg-muted);
}
.acceso-card__all {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--fg-muted);
    cursor: pointer;
    white-space: nowrap;
}
.acceso-card__movs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 8px;
    padding: 12px;
}
.acceso-card__movs-empty {
    grid-column: 1 / -1;
    padding: 4px 2px;
    font-size: 12.5px;
    color: var(--fg-muted);
}
.mov-pick {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    cursor: pointer;
    background: transparent;
    transition: background var(--t-fast), border-color var(--t-fast);
}
.mov-pick:hover { border-color: var(--border-strong); }
.mov-pick--on {
    background: var(--heb-red-soft);
    border-color: var(--heb-red-soft-strong);
}
.mov-pick--disabled {
    cursor: default;
    opacity: 0.7;
}
.mov-pick__label {
    min-width: 0;
    font-size: 12.5px;
    color: var(--fg-strong);
}
.acceso-card__all input[type="checkbox"],
.mov-pick input[type="checkbox"] {
    accent-color: var(--heb-red);
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    cursor: pointer;
}
.mov-pick--disabled input[type="checkbox"] { cursor: default; }

/* ---------------------------------------------------------------------------
   Valores de solo lectura (paneles de detalle) y tablas internas de detalle
   (partidas de un movimiento). Las grids principales usan Smart.UI; estas son
   tablas chicas dentro de los slide panels.
--------------------------------------------------------------------------- */
.readonly-value {
    padding: 7px 0;
    min-height: 20px;
    color: var(--fg-strong);
    font-size: 13px;
    line-height: 1.4;
}
.readonly-value.mono,
.data-table .mono { font-family: var(--font-mono); }
/* Renglón anulado del historial de costos: se conserva como rastro pero dejó de
   contar para el costo vigente, y eso debe verse sin tener que leer la fila. */
.data-table tr.is-anulado td {
    color: var(--fg-muted);
    text-decoration: line-through;
}

/* Historial de costos: una tabla de ocho columnas dentro de un panel, que va a
   crecer con cada compra. Con la letra de las demás tablas no cabe sin barrer
   de lado, y aquí lo que importa es comparar renglones de un vistazo. */
#prod-costo-tabla {
    font-size: 11.5px;
}
#prod-costo-tabla th,
#prod-costo-tabla td {
    padding: 5px 8px;
    white-space: nowrap;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 8px;
    font-size: 13px;
}
.data-table th {
    padding: 8px 10px;
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--fg-muted);
    border-bottom: 1px solid var(--border);
}
.data-table td {
    padding: 8px 10px;
    color: var(--fg-strong);
    border-bottom: 1px solid var(--border);
}
.data-table tbody tr:hover { background: var(--bg-hover); }
.data-table tfoot td {
    border-bottom: none;
    border-top: 1px solid var(--border-strong);
    color: var(--fg-strong);
}
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* Combo buscable de Smart.UI (catálogos grandes como tiendas): solo el ancho;
   el resto del estilo lo dan smart.default.css + los tokens HEB de heb-theme. */
smart-combo-box.heb-combo { width: 100%; }

/* Variante de selección múltiple (buscadores de mercancía). Los elegidos se
   pintan como fichas dentro del combo, así que con seis o siete el campo crece
   hacia abajo y empuja el formulario. Se le pone techo y scroll propio: las
   fichas se desplazan dentro del combo y el panel no se mueve. */
smart-combo-box.heb-combo--multi {
    max-height: 84px;
    overflow-y: auto;
}

/* Separación extra arriba de un renglón que sigue a una rejilla de campos. */
.form-row--spaced { margin-top: 16px; }
/* Segundo campo de un par encadenado (zona -> ubicaciones): el label
   respira del combo de arriba sin abrir otro renglón de formulario. */
.form-label--spaced { margin-top: 14px; }

/* Inputs numéricos: valor alineado a la derecha. */
.input--num { text-align: right; }

/* Oculta las flechas (spinners) de un input number en webkit y firefox. */
.input--no-spin::-webkit-outer-spin-button,
.input--no-spin::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.input--no-spin {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* =========================================================================
   Dashboard de Inventarios (épica 2.21)
   Reusa el chrome del dashboard de Seguridad (.dash-seg) y suma el layout de
   gráficas smart-chart, la tira de movimientos y los filtros.
   ========================================================================= */
.dash-inv { display: flex; flex-direction: column; gap: var(--gap); }

/* Card chrome (igual que .dash-seg .card) */
.dash-inv .card {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 0;
    display: flex; flex-direction: column;
    overflow: hidden;
}

/* Botón Actualizar con spin durante la carga */
.dash-inv__refresh-icon {
    display: inline-flex;
    align-items: center;
    transition: transform var(--t-base);
}
.dash-inv[data-loading="true"] .dash-inv__refresh-icon { animation: dash-seg-spin 0.9s linear infinite; }

/* Banner de error */
.dash-inv__error {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 16px;
    border-radius: var(--r-md);
    background: var(--status-danger-bg);
    color: var(--status-danger);
    font-size: 13px;
}
.dash-inv__error[hidden] { display: none; }
.dash-inv__error button { margin-left: auto; }

/* Filtros: etiqueta AL LADO del campo (mismo patrón que los reportes).
   Specificity .dash-inv .card.dash-inv__filters (0,3,0) para ganarle a
   .dash-inv .card { padding: 0 } (0,2,0), que si no deja el card sin padding. */
.dash-inv .card.dash-inv__filters { padding: 16px 20px; }
/* justify-content: flex-start anula el space-between de .toolbar base, que
   repartía los grupos de borde a borde (pegando "Hasta" a la derecha). */
.dash-inv__toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 14px 24px;
    flex-wrap: wrap;
}
.dash-inv__toolbar .toolbar__group {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
}
/* Etiqueta alineada a la derecha en ancho fijo (igual que los reportes): deja
   el espacio a la izquierda antes de "Almacén". */
.dash-inv__toolbar .form-label {
    margin: 0;
    flex-shrink: 0;
    width: 96px;
    text-align: right;
}
.dash-inv__toolbar .input { min-width: 200px; font-size: 12px; }
/* El aviso va en su propio renglón debajo de los filtros (no flotando a la derecha) */
.dash-inv__hint {
    flex-basis: 100%;
    margin: 4px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    color: var(--fg-muted);
    line-height: 1.4;
}

/* KPI grid de 4 columnas (vs las 5 del dashboard de Seguridad) */
.dash-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .dash-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px)  { .dash-grid--4 { grid-template-columns: 1fr; } }

/* KPI grid de 3 columnas (pantalla de inicio, épica 4.1) */
.dash-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 720px) { .dash-grid--3 { grid-template-columns: 1fr; } }

/* Fila de 2 gráficas iguales */
.inv-dash-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--gap);
}
@media (max-width: 1100px) { .inv-dash-row { grid-template-columns: 1fr; } }

/* Contenedor de la gráfica smart-chart.
   Las gráficas de distribución rotulan el eje con nombres (almacén, tienda,
   familia), que van en vertical para que no se encimen ni se salte ninguno.
   Esas etiquetas se comen alto, así que la tarjeta lo compensa: con menos, la
   zona de barras queda aplastada contra el eje. */
.inv-dash-chart {
    display: block;
    width: 100%;
    height: 420px;
    padding: 8px 12px 12px;
}
.inv-dash-chart--tall { height: 340px; }

/* Tira de movimientos del periodo */
.inv-movstat {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 8px;
}
.inv-movstat__cell {
    text-align: center;
    padding: 8px 4px;
    border-radius: var(--r-md);
    background: var(--bg-subtle);
}
.inv-movstat__n {
    font-size: 24px;
    font-weight: 600;
    color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.inv-movstat__n--in  { color: var(--status-active); }
.inv-movstat__n--out { color: var(--heb-red); }
.inv-movstat__n--tra { color: var(--status-info); }
.inv-movstat__l {
    margin-top: 4px;
    font-size: 11.5px;
    color: var(--fg-muted);
}
.inv-movstat__total {
    display: flex; align-items: center; justify-content: space-between;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.inv-movstat__total-l { font-size: 12.5px; color: var(--fg-muted); }
.inv-movstat__total-v {
    font-size: 16px;
    font-weight: 600;
    color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
}

/* Icono de producto crítico (triángulo de alerta) */
.dash-crit__icon {
    width: 26px; height: 26px;
    border-radius: var(--r-sm);
    background: var(--status-pending-bg);
    color: var(--status-warning);
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}

/* Etiquetas del eje de las gráficas de distribución. Van en vertical con el
   nombre completo de la tienda o la familia, y con muchas barras esa altura
   invade el área de las barras: con menos tamaño, la etiqueta cabe. */
.inv-dash-chart__eje {
    font-size: 10px;
}

/* Tooltip de las gráficas del dashboard (smart-chart).
   El contenido es de dos renglones (nombre de la tienda arriba, cantidad
   abajo, vía <br> en el JS). Smart mide el contenido y fija ancho/alto en el
   elemento, pero por redondeo del ancho puede quedar 1px corto y partir un
   nombre largo en un renglón extra que se desborda de la caja. Se fuerza que el
   texto no se parta y que la caja crezca a su contenido.
   !important: es la única forma de ganarle al width/height que Smart pone
   inline en el elemento (caso justificado de override de Smart.UI). */
.smart-chart-tooltip-content {
    width: auto !important;
    height: auto !important;
}
.smart-chart-tooltip-text {
    white-space: nowrap;
}

/* ============================================================
   Ubicación geográfica — cascada País › Estado › Municipio
   (épicas 3.3/3.4/3.5; vista de columnas tipo Miller del prototipo)
   ============================================================ */

/* Ruta de la selección (breadcrumb de cascada) */
.geo-path {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 10px 14px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    margin-bottom: var(--gap, 16px);
}
.geo-path__seg {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; font-weight: 500;
    color: var(--fg-subtle);
}
.geo-path__seg svg { opacity: 0.7; }
.geo-path__seg--on { color: var(--fg-strong); }
.geo-path__seg--on svg { opacity: 1; color: var(--heb-red); }
.geo-path__arrow { color: var(--fg-subtle); flex-shrink: 0; }

/* Columnas en cascada */
.geo-cascade {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--gap, 16px);
    align-items: stretch;
}

.geo-col {
    display: flex; flex-direction: column;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    overflow: hidden;
    /* Con 480 de mínimo la página tenía scroll a 1366×768 (épica 4.3); las
       listas ya se desplazan dentro de su columna. */
    min-height: 300px;
    max-height: calc(100vh - 280px);
    transition: opacity var(--t-fast);
}
.geo-col[data-dimmed="true"] { opacity: 0.72; }

.geo-col__head {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--bg-subtle);
}
.geo-col__title { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.geo-col__titles { min-width: 0; }
.geo-col__icon {
    width: 30px; height: 30px; flex-shrink: 0;
    border-radius: var(--r-md);
    background: var(--heb-red-soft); color: var(--heb-red);
    display: inline-flex; align-items: center; justify-content: center;
}
.geo-col__label {
    font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
    color: var(--fg-strong);
}
.geo-col__sub {
    font-size: 11px; color: var(--fg-muted); margin-top: 1px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.geo-col__sub b { color: var(--fg-strong); font-weight: 600; }
/* El + de cada columna es un "Nuevo" compacto: rojo desde el inicio con el
   hover estándar de botón primario (no rojo-solo-en-hover). */
.geo-col__add {
    width: 30px; height: 30px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid transparent;
    border-radius: var(--r-md);
    background: var(--heb-red); color: var(--fg-on-accent);
    cursor: pointer;
    transition: all var(--t-fast);
}
.geo-col__add:hover:not(:disabled) { background: var(--heb-red-hover); }
.geo-col__add:disabled { opacity: 0.4; cursor: not-allowed; }

.geo-col__search { position: relative; padding: 10px 12px 6px; }
.geo-col__search .input-icon { top: calc(50% + 2px); }

.geo-col__list { flex: 1; overflow-y: auto; padding: 4px 6px 8px; }
.geo-col__list::-webkit-scrollbar { width: 9px; }
.geo-col__list::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: 999px;
    border: 2px solid var(--bg-elevated);
}

/* Renglón de la columna */
.geo-row {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px;
    border-radius: var(--r-md);
    cursor: pointer;
    transition: background var(--t-fast);
}
.geo-row:hover { background: var(--bg-hover); }
.geo-row--active { background: var(--heb-red-soft); }
.geo-row--active:hover { background: var(--heb-red-soft); }
.geo-row--off { opacity: 0.5; }

.geo-row__code {
    flex-shrink: 0;
    min-width: 38px;
    font-family: var(--font-mono);
    font-size: 11px; font-weight: 600;
    color: var(--fg-muted);
    text-align: center;
    padding: 2px 6px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
}
.geo-row--active .geo-row__code {
    background: rgba(255, 255, 255, 0.6);
    border-color: color-mix(in oklab, var(--heb-red) 25%, transparent);
    color: var(--heb-red);
}
[data-theme="dark"] .geo-row--active .geo-row__code { background: var(--bg-subtle); }

.geo-row__body { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
.geo-row__name {
    font-size: 13.5px; font-weight: 500;
    color: var(--fg-strong);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.geo-row--active .geo-row__name { color: var(--heb-red); }
.geo-row__tag {
    flex-shrink: 0;
    font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
    color: var(--fg-muted);
    padding: 1px 6px;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
}
.geo-row__count {
    flex-shrink: 0;
    font-size: 11px; font-weight: 600;
    color: var(--fg-muted);
    min-width: 22px; text-align: center;
    padding: 1px 6px;
    background: var(--bg-subtle);
    border-radius: 999px;
}

/* Acciones por renglón (lápiz + basurero); aparecen al hover como el prototipo */
.geo-row__action {
    flex-shrink: 0;
    width: 26px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border: none; background: transparent;
    color: var(--fg-muted);
    border-radius: var(--r-md);
    cursor: pointer;
    opacity: 0;
    transition: all var(--t-fast);
}
.geo-row:hover .geo-row__action { opacity: 1; }
.geo-row__action:disabled { cursor: not-allowed; opacity: 0; }
.geo-row:hover .geo-row__action:disabled { opacity: 0.35; }
.geo-row__action--edit:hover:not(:disabled) { background: var(--bg-elevated); color: var(--heb-red); }
.geo-row__action--del:hover:not(:disabled) { background: var(--heb-red-soft); color: var(--heb-red); }
.geo-row__chev { color: var(--fg-subtle); flex-shrink: 0; }
.geo-row--active .geo-row__chev { color: var(--heb-red); }

/* Estado vacío de columna (sin padre seleccionado o sin registros) */
.geo-col__empty {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 10px; padding: 32px 24px;
    text-align: center;
    color: var(--fg-subtle);
}
.geo-col__empty p { font-size: 12.5px; color: var(--fg-muted); margin: 0; max-width: 200px; }
.geo-col__empty--sm { padding: 24px; }

.geo-col__foot {
    padding: 8px 14px;
    border-top: 1px solid var(--border);
    font-size: 11.5px; color: var(--fg-muted);
    background: var(--bg-subtle);
}

/* Nota informativa del editor (slide panel) */
.geo-editor-note {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    font-size: 12.5px; color: var(--fg); line-height: 1.5;
    margin-top: 4px;
}
.geo-editor-note svg { flex-shrink: 0; margin-top: 1px; color: var(--heb-red); }
/* Variante con aire inferior: para cuando la nota va seguida de un form-row
   (que solo trae margen inferior) y quedarían pegados. Mismo ritmo de 18px. */
.geo-editor-note--spaced { margin-bottom: 18px; }

/* Grid de partidas dentro del slideover de Control PO: letra compacta y
   altura propia con scroll (una OC real puede traer decenas de líneas). */
.grid-partidas {
    height: 480px;
    font-size: 12.5px;
}

/* ============================================================
   Unidades de Negocio — widget de doble número Oracle ↔ HEB
   (LOG-09; referencia visual cat-doble de oc-catalogos.jsx)
   ============================================================ */
.un-doble {
    display: flex; align-items: flex-end; gap: 12px;
    padding: 12px 14px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    margin-bottom: 10px;
}
.un-doble__item { flex: 1; min-width: 0; }
.un-doble__arrow {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--heb-red);
    padding-bottom: 8px;
}

/* ============================================================
   Tarjetas de sub-registros (Proveedores: Ubicaciones/Contactos;
   referencia visual cat-card de oc-catalogos.jsx). Reutilizable
   por cualquier panel con listas hijas.
   ============================================================ */
.subcards__head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    margin: 4px 0 12px;
    font-size: 13px; font-weight: 600; color: var(--fg-strong);
}
.sub-card {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 14px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    margin-bottom: 8px;
}
.sub-card__main { flex: 1; min-width: 0; }
.sub-card__title {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    font-size: 13.5px; font-weight: 600; color: var(--fg-strong);
}
.sub-card__sub {
    font-size: 12px; color: var(--fg-muted); margin-top: 2px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sub-card__actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.pill--tag {
    display: inline-flex; align-items: center;
    font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
    color: var(--fg-muted);
    padding: 1px 8px;
    background: var(--bg-subtle);
    border: 1px solid var(--border-strong);
    border-radius: 999px;
}
.pill--principal {
    color: var(--heb-red);
    background: var(--heb-red-soft);
    border-color: transparent;
}
.subcards__empty {
    padding: 28px 16px;
    text-align: center;
    font-size: 12.5px; color: var(--fg-muted);
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-md);
}

/* ---------------------------------------------------------------------------
   Swatch de color para catálogos con color de badge (Tipos de Proyecto, LOG-07).
   El fondo se aplica inline desde el dato (hex del registro); aquí solo la forma.
   --------------------------------------------------------------------------- */
.color-swatch {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: var(--r-sm);
    margin-right: 8px;
    vertical-align: middle;
    border: 1px solid var(--border-strong);
}

/* ---------------------------------------------------------------------------
   Reordenar pasos: flechas apiladas al inicio de la sub-tarjeta (Flujos, LOG-34).
   --------------------------------------------------------------------------- */
.sub-card__reorder {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-right: 8px;
}
.sub-card__reorder .btn-icon {
    width: 22px;
    height: 20px;
}

/* ---------------------------------------------------------------------------
   Seguimiento OC (LOG-21, épica 3.27) — pills de estatus, marcas del grid
   denso y bitácora de la partida.
   --------------------------------------------------------------------------- */
.seg-filtros {
    display: flex;
    align-items: flex-start;
    /* En viewports angostos (o con DevTools abierto) las columnas envuelven
       en vez de empujar el botón Consultar fuera de la pantalla. */
    flex-wrap: wrap;
    gap: 12px 24px;
    padding: 14px 16px;
}
.seg-filtros__col {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.seg-filtros__campo {
    display: grid;
    grid-template-columns: 84px minmax(180px, 1fr);
    align-items: center;
    gap: 10px;
}
/* El proyecto se identifica con la clave de Oracle, de 15 dígitos: con el
   ancho estándar se cortaba en las laptops de 1366px (hallazgo Salma 09-sep). */
.seg-filtros__campo--ancho { grid-template-columns: 84px minmax(250px, 1fr); }

.seg-filtros__campo .form-label {
    margin: 0;
    text-align: right;
    justify-self: end;
}
/* Los controles llenan su celda (el smart-combo-box trae ancho propio fijo). */
.seg-filtros__campo .input,
.seg-filtros__campo select,
.seg-filtros__campo .heb-combo {
    width: 100%;
    min-width: 0;
}
.seg-filtros__col--ancha .seg-filtros__campo {
    grid-template-columns: 84px minmax(420px, 1fr);
}
/* Anchos de laptop: la columna ancha cede su mínimo y se aprietan los gaps
   para que las tres columnas sigan cabiendo en dos renglones (cada renglón
   extra de filtros se come alto del grid). */
@media (max-width: 1440px) {
    .seg-filtros { gap: 8px 12px; padding: 12px 14px; }
    .seg-filtros__campo { grid-template-columns: 84px minmax(130px, 1fr); }
    .seg-filtros__col--ancha .seg-filtros__campo {
        grid-template-columns: 84px minmax(200px, 1fr);
    }
}
/* Alturas de laptop: cada px vertical arriba del grid se lo quita al grid y
   puede dejar su barra horizontal abajo del viewport. */
@media (max-height: 720px) {
    .page-header { margin-bottom: 8px; }
    .seg-filtros { padding-top: 8px; padding-bottom: 8px; }
    .seg-pills { padding-bottom: 8px; }
}

/* El alto del grid de Seguimiento lo fija el JS midiendo su posición real
   contra el viewport (ajustarAltoGrid): se adapta a cualquier resolución sin
   generar scroll de página. Aquí solo el piso. */
.heb-grid.grid-seguimiento {
    /* Mismo piso que ajustarAltoGrid: si difieren, el CSS le gana al alto
       inline y la tarjeta desborda el viewport en laptops. */
    min-height: 200px;
}
.seg-filtros__accion {
    margin-left: auto;
    align-self: flex-start;
}

.form-row--full { grid-column: 1 / -1; }

.seg-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 0 16px 12px;
}
.seg-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    background: var(--bg-elevated);
    color: var(--fg-muted);
    font-size: 12px;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease;
}
.seg-pill:hover { border-color: var(--fg-muted); }
.seg-pill--active {
    border-color: var(--heb-red);
    color: var(--text-primary);
}
.seg-pill__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--border-strong);
    flex: none;
}
.seg-pill__num {
    font-weight: 600;
    color: var(--text-primary);
}

/* Checkboxes propios del grid principal, estilizados como los nativos del
   Smart Grid (mismo look en ambos grids de la pantalla). */
.heb-grid input.seg-sel,
.heb-grid input.seg-sel-all {
    appearance: none;
    width: 14px;
    height: 14px;
    margin: 0;
    border: 1px solid var(--border-strong);
    border-radius: var(--r-sm);
    background: var(--bg-elevated);
    cursor: pointer;
    display: inline-grid;
    place-content: center;
    vertical-align: middle;
}
.heb-grid input.seg-sel:hover,
.heb-grid input.seg-sel-all:hover {
    border-color: var(--fg-muted);
}
.heb-grid input.seg-sel:checked,
.heb-grid input.seg-sel-all:checked {
    background: var(--heb-red);
    border-color: var(--heb-red);
}
.heb-grid input.seg-sel:checked::after,
.heb-grid input.seg-sel-all:checked::after {
    content: "";
    width: 8px;
    height: 4px;
    border-left: 2px solid var(--sidebar-fg-strong);
    border-bottom: 2px solid var(--sidebar-fg-strong);
    transform: rotate(-45deg) translate(0, -1px);
}

.seg-sel-vacio { color: var(--fg-subtle); }

/* Ícono de partida detallada (base de datos, como el prototipo). */
.seg-det {
    display: inline-flex;
    align-items: center;
    color: var(--status-pending);
}
.seg-inc {
    color: var(--status-danger);
    font-weight: 700;
}

.seg-bitacora {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 12px;
}
.seg-evento {
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    padding: 10px 12px;
    background: var(--bg-elevated);
}
.seg-evento--regreso {
    border-color: var(--status-danger);
}
.seg-evento__head {
    display: flex;
    align-items: center;
    gap: 8px;
}
.seg-evento__fecha {
    margin-left: auto;
    font-size: 11.5px;
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}
.seg-evento__comentario {
    margin-top: 6px;
    font-size: 13px;
    color: var(--text-primary);
}
.seg-evento__meta {
    margin-top: 4px;
    font-size: 11.5px;
    color: var(--fg-muted);
}

/* Bitácora fusionada (detallado P4): filtro por nivel + distintivo de a qué
   sub-unidad pertenece cada evento. */
.seg-bit-filtro {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}
.seg-bit-filtro .form-label { margin: 0; }
.seg-bit-filtro .input { max-width: 220px; }
.seg-evento__unidad {
    background: var(--bg-subtle);
    color: var(--fg-muted);
    border: 1px solid var(--border);
}

/* Detalle de productos del movimiento ligado (pestaña Movimientos): muestra
   el alcance completo de la reversión Canc/Inv antes de cancelar. La tabla
   scrollea con encabezado pegajoso (un movimiento puede traer cientos de
   partidas). */
.seg-mov-tabla { margin-top: 8px; }
.seg-mov-tabla__titulo {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--fg);
    margin-bottom: 4px;
}
.seg-mov-tabla__scroll {
    max-height: 240px;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
}
.seg-mov-tabla table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11.5px;
}
.seg-mov-tabla th,
.seg-mov-tabla td {
    padding: 3px 8px;
    border-bottom: 1px solid var(--border);
    text-align: left;
    white-space: nowrap;
}
.seg-mov-tabla tbody tr:last-child td { border-bottom: 0; }
.seg-mov-tabla th {
    font-weight: 600;
    color: var(--fg-muted);
    background: var(--bg-subtle);
    position: sticky;
    top: 0;
    z-index: 1;
}
.seg-mov-tabla th.num,
.seg-mov-tabla td.num { text-align: right; }
.seg-mov-tabla .seg-mov-tabla__desc {
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Distintivo de sub-unidad en las ligas del movimiento (uN). */
.seg-mov-tabla__sub {
    color: var(--fg-muted);
    font-size: 10px;
}

/* Celda Cantidad sol · rec · ent con barra de avance (maqueta): ámbar =
   recibida en almacén, verde = entregada (la entregada pinta ENCIMA). */
.seg-qty {
    display: flex;
    flex-direction: column;
    gap: 3px;
    line-height: 1.2;
}
.seg-qty__nums { display: inline-flex; gap: 4px; font-variant-numeric: tabular-nums; }
.seg-qty__sep { color: var(--fg-subtle); }
.seg-qty__rec { color: var(--status-pending); }
.seg-qty__ent { color: var(--status-active); }
.seg-qty__bar {
    position: relative;
    height: 4px;
    border-radius: 999px;
    background: var(--bg-subtle);
    overflow: hidden;
}
.seg-qty__bar-rec,
.seg-qty__bar-ent {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    border-radius: 999px;
}
.seg-qty__bar-rec { background: var(--status-pending); }
.seg-qty__bar-ent { background: var(--status-active); }

/* ==========================================================================
   Tab Unidades (Detallado, P4): chips + smart grid de sub-unidades (mismo
   funcionamiento que el grid principal) y pie de acciones. El slideover
   crece a XL mientras este tab está activo.
   ========================================================================== */
.seg-uni-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}
.seg-uni-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.grid-unidades {
    width: 100%;
    height: calc(100vh - var(--topbar-height) - 310px);
    min-height: 260px;
}
.seg-uni-total {
    margin-top: 8px;
    text-align: right;
    font-size: 12px;
    color: var(--fg-muted);
}
.seg-uni-total strong { color: var(--fg-strong); }
.seg-uni-movern {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--fg-muted);
}
.seg-uni-movern input { width: 64px; height: 28px; font-size: 12px; }

/* Barra de acciones de la selección (cambio de estatus masivo, P2).
   Flotante sobre el contenido, como en el prototipo: no empuja el layout. */
.seg-actionbar {
    position: fixed;
    left: calc(50% + var(--sidebar-w, 260px) / 2);
    transform: translateX(-50%);
    bottom: 24px;
    z-index: 60;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 10px 16px;
    border: 1px solid var(--sidebar-border);
    border-radius: var(--r-md);
    background: var(--sidebar-bg);
    color: var(--sidebar-fg-strong);
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.35);
}
/* Variante dentro del slideover (tab Unidades del Detallado): anclada al
   fondo del panel, por encima de su footer. */
.seg-actionbar--panel {
    position: absolute;
    left: 24px;
    right: 24px;
    bottom: 78px;
    transform: none;
    z-index: 5;
}
/* El texto de la izquierda no puede empujar la barra fuera de la pantalla: en
   una laptop los botones se salían del borde. La barra se acota al viewport y
   el resumen se recorta con "…" — el detalle completo vive en el tooltip de
   los botones. */
.seg-actionbar { max-width: calc(100vw - 48px); }
.seg-actionbar__count {
    font-size: 12.5px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.seg-actionbar__actions { flex: none; }
.seg-actionbar__sub { color: var(--sidebar-fg-muted); }
.seg-actionbar__actions {
    margin-left: auto;
    display: flex;
    gap: 8px;
}
.seg-actionbar .btn--ghost {
    color: var(--sidebar-fg);
    border-color: var(--sidebar-border);
    background: transparent;
}
.seg-actionbar .btn--ghost:hover {
    background: var(--sidebar-hover);
    color: var(--sidebar-fg-strong);
}

/* Los textarea con clase .input heredan el alto fijo de input (36px) y se
   aplastan dentro de los modales: se les regresa el alto por contenido. */
.modal__form textarea.input,
.slide-panel textarea.input {
    height: auto;
    min-height: 90px;
    resize: vertical;
}

/* Menús desplegables de la barra (Acciones ▾ / Fletes ▾) — abren hacia
   arriba porque la barra vive pegada al borde inferior. */
.seg-menu { position: relative; }
.seg-menu__lista {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 0;
    min-width: 210px;
    padding: 6px;
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    background: var(--bg-elevated);
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.25);
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 61;
}
.seg-menu__item {
    text-align: left;
    padding: 7px 10px;
    font-size: 12.5px;
    border: 0;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--fg);
    cursor: pointer;
}
.seg-menu__item:hover:not(:disabled) { background: var(--bg-subtle); }
.seg-menu__item:disabled { color: var(--fg-subtle); cursor: not-allowed; }

/* Menú de camiones del flete (épica 3.32). Ancho fijo y renglón de dos líneas
   parejas: la razón social de un transportista puede ser kilométrica y, sin
   recorte, un solo camión estiraba el menú cuatro líneas hacia arriba. Lo que
   distingue un camión de otro va arriba; el transportista, recortado abajo con
   el nombre completo en el tooltip. */
.seg-menu__lista--camiones { width: 340px; }

/* Lista de avisos del tab Mercancía (épica 3.32). Va acotada y con scroll
   propio: una asignación masiva puede dejar cientos de renglones fuera, y sin
   tope el recuadro empujaba el grid hasta sacarlo de la pantalla. */
.fl-avisos {
    max-height: 108px;
    overflow-y: auto;
    margin: 6px 0 0;
    padding-left: 18px;
}
.fl-avisos li { margin-bottom: 2px; }
.fl-avisos__mas { margin-top: 4px; font-style: italic; }
.fl-camion__linea { display: block; }
.fl-camion__sub {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--fg-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.seg-menu__item:disabled .fl-camion__sub { color: var(--fg-subtle); }

/* Diálogo Avanzar estatus: visual De → A. */
.seg-fromto {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 14px;
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    background: var(--bg-subtle);
}
.seg-fromto__col { display: flex; flex-direction: column; gap: 6px; }
.seg-fromto__arrow { color: var(--fg-muted); display: inline-flex; }
.seg-fromto__num { font-weight: 600; font-size: 12px; margin-left: 4px; }

.seg-afectadas {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.seg-afectada {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    padding: 4px 0;
    border-bottom: 1px dashed var(--border-strong);
}
.seg-afectada__desc {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--fg-muted);
}
.seg-afectada__oc { color: var(--fg-muted); font-size: 11px; }

/* Sub-panel del buscador de mercancía cross-OC. Dos renglones de filtros
   (Almacén + Unidad de negocio grande / Proveedor + OC + Buscar) y el grid
   llena el alto restante del panel (sin scroll vertical, se adapta a la
   resolución). */
.seg-merc-filtros {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 8px;
    flex: none;
}
.seg-merc-filtros__fila {
    display: flex;
    align-items: center;
    gap: 10px;
}
.seg-merc-filtros .heb-combo {
    width: 240px;
    min-width: 200px;
    flex: none;
    /* Letra compacta para que quepan razones sociales y pedidos largos
       (mismo ajuste que los filtros de Reportes). */
    --smart-font-size: 12px;
}
.seg-merc-filtros .heb-combo .smart-action-button,
.seg-merc-filtros .heb-combo input {
    font-size: 12px;
}
.seg-merc-filtros .seg-merc-filtros__grande {
    flex: 1 1 auto;
    width: auto;
    min-width: 280px;
}
#seg-merc-panel .slide-panel__body {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
#seg-merc-panel .form-help { flex: none; }
.heb-grid.seg-merc-grid {
    flex: 1 1 auto;
    height: auto;
    min-height: 180px;
}
/* Partidas afectadas del diálogo de avance: alto adaptable a la resolución
   con scroll propio (vertical y horizontal) cuando la operación crece. */
.heb-grid.seg-av-grid {
    height: calc(100vh - 560px);
    min-height: 240px;
}
.check--inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--fg);
}

/* ============================================================
   Presupuesto del Proyecto (LOG-32, épica 3.34)
   ============================================================ */

/* Cifras del comparativo en el panel de ajuste (colocado/recibido/faltante). */
.pp-figs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-bottom: 14px;
}
.pp-fig {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 8px 10px;
}
.pp-fig__label {
    font-size: 11px;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.pp-fig__num {
    font-size: 14px;
    font-weight: 600;
    margin-top: 2px;
    /* Cantidades alineadas a la derecha (uso es-MX). */
    text-align: right;
}
.pp-num--rebasa {
    color: var(--status-danger);
}

/* Total fondeado calculado en vivo bajo los dos montos. */
.pp-total {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 2px;
    border-top: 1px dashed var(--border);
    margin-top: 10px;
    font-size: 13px;
    color: var(--fg-muted);
}
.pp-total strong {
    font-size: 14px;
    color: var(--fg-strong);
}

/* Aviso de rebase (control tipo aviso: nunca bloquea). */
.pp-aviso {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    background: var(--status-pending-bg);
    color: var(--status-warning);
    border-radius: var(--r-md);
    padding: 10px 12px;
    font-size: 12.5px;
    margin-top: 10px;
}
.pp-aviso svg {
    flex: 0 0 auto;
    margin-top: 1px;
}

/* Historial permanente de ajustes (D1) — tab propio del panel. */
.pp-audit {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-elevated);
    margin-bottom: 6px;
    font-size: 12.5px;
}
.pp-audit__linea {
    display: flex;
    gap: 8px;
    align-items: baseline;
    flex-wrap: wrap;
}
.pp-audit__monto {
    font-weight: 600;
}
.pp-audit__prev {
    color: var(--fg-muted);
    text-decoration: line-through;
}
.pp-audit__meta {
    color: var(--fg-muted);
    font-size: 11.5px;
}
.pp-audit__motivo {
    color: var(--fg);
}


/* ==========================================================================
   Wizard de Importación de OC (LOG-19, épica 3.24) — modal de 3 pasos
   dentro de Control PO.
   ========================================================================== */

.modal--wizard {
    max-width: min(1120px, calc(100vw - 48px));
    width: calc(100vw - 48px);
    max-height: calc(100vh - 64px);
    overflow: hidden;
}

.wizard { display: flex; flex-direction: column; max-height: calc(100vh - 64px); }

.wizard__header {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}
.wizard__titulos { min-width: 0; }
.wizard__subtitulo { margin: 2px 0 0; font-size: 12px; color: var(--fg-muted); }

.wizard__pasos {
    display: flex;
    gap: 6px;
    margin: 0 auto;
    padding: 0;
    list-style: none;
}
.wizard__paso-tab {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 12.5px;
    color: var(--fg-muted);
    background: var(--bg-subtle);
    white-space: nowrap;
}
.wizard__paso-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 11px;
    font-weight: 600;
    background: var(--bg-active);
    color: var(--fg-muted);
}
.wizard__paso-tab--activo { background: var(--heb-red-soft); color: var(--heb-red); font-weight: 600; }
.wizard__paso-tab--activo .wizard__paso-num { background: var(--heb-red); color: var(--fg-on-accent); }
.wizard__paso-tab--hecho { color: var(--status-active); }
.wizard__paso-tab--hecho .wizard__paso-num { background: var(--status-active); color: var(--fg-on-accent); }

.wizard__cuerpo { padding: 18px 20px; overflow-y: auto; flex: 1; min-height: 320px; }
.wizard__seccion-titulo {
    margin: 0 0 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--fg-strong);
}

.wizard__cols { display: grid; grid-template-columns: 1.4fr 1fr; gap: 20px; align-items: start; }
.wizard__cols--paso3 { grid-template-columns: 1.2fr 1fr; }

/* --- Paso 1: dropzone --------------------------------------------------- */
.dropzone {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 260px;
    border: 2px dashed var(--border-strong);
    border-radius: var(--r-lg);
    background: var(--bg-subtle);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
/* Liga dentro del toast (flete generado desde Seguimiento, 01-ago) y ligas
   dentro de celdas del grid (columna Flete): heredan color para no pelear
   con el fondo del toast / los estados del grid. */
.toast .toast__link {
    color: inherit;
    text-decoration: underline;
    font-weight: 600;
}

.heb-grid .grid-link {
    color: var(--heb-red);
    text-decoration: none;
}

.heb-grid .grid-link:hover {
    text-decoration: underline;
}

/* Grids con celdas envolventes (mercancía del flete, 31-jul): la descripción
   se lee completa; requiere layout.autoRowHeight en el grid. */
.heb-grid--wrap smart-grid-cell,
.heb-grid--wrap .smart-grid-cell {
    white-space: normal;
}

/* Combos con multi-selección (tokens): tope de crecimiento con scroll
   interno — con varias selecciones el combo se comía el form (fletes 31-jul).
   Solo afecta combos en modo tokens; los de selección única no tienen
   contenedor de tokens. */
.heb-combo .smart-action-button {
    max-height: 64px; /* ~2 renglones de tokens */
    overflow-y: auto;
}

/* Variante compacta para campos de archivo dentro de forms (fletes 31-jul). */
.dropzone--compacta { min-height: 96px; }
.dropzone--compacta .dropzone__estado { padding: 12px; gap: 4px; }

.dropzone:hover, .dropzone:focus-visible, .dropzone--sobre {
    border-color: var(--heb-red);
    background: var(--heb-red-soft);
    outline: none;
}
.dropzone__estado { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; padding: 24px; }
.dropzone__icono { color: var(--fg-muted); }
.dropzone__icono--ok { color: var(--status-active); }
.dropzone__titulo { margin: 0; font-size: 14px; font-weight: 600; color: var(--fg-strong); }
.dropzone__hint { margin: 0; font-size: 12px; color: var(--fg-muted); }
.dropzone__spinner {
    width: 26px;
    height: 26px;
    border: 3px solid var(--border);
    border-top-color: var(--heb-red);
    border-radius: 50%;
    animation: imp-girar 0.8s linear infinite;
}
@keyframes imp-girar { to { transform: rotate(360deg); } }

.wizard__info {
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-subtle);
}
.wizard__info-titulo { margin: 0 0 6px; font-size: 12.5px; font-weight: 600; color: var(--fg-strong); }
.wizard__info-titulo + .wizard__info-lista { margin-bottom: 12px; }
.wizard__info-lista { margin: 0; padding-left: 18px; font-size: 12.5px; color: var(--fg-muted); line-height: 1.55; }
.wizard__info-lista li + li { margin-top: 4px; }
.wizard__hint { margin: 8px 0 0; font-size: 12px; color: var(--fg-muted); line-height: 1.5; }

/* --- Paso 2: bloqueos, cabecera, detecciones, resolución ----------------- */
.wizard__bloqueos {
    margin-bottom: 14px;
    padding: 12px 14px;
    border: 1px solid var(--status-danger);
    border-radius: var(--r-md);
    background: var(--heb-red-soft);
}
.wizard__bloqueos-titulo { margin: 0 0 6px; font-size: 13px; font-weight: 600; color: var(--status-danger); }
.wizard__bloqueos ul { margin: 0; padding-left: 18px; font-size: 12.5px; color: var(--fg); line-height: 1.55; }

.wizard__grid2 { display: grid; grid-template-columns: 1.2fr 1fr; gap: 16px; margin-bottom: 14px; }

.wizard__cabecera {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 4px 14px;
    margin: 0;
    font-size: 12.5px;
}
.wizard__cabecera dt { color: var(--fg-muted); }
.wizard__cabecera dd { margin: 0; color: var(--fg-strong); font-weight: 500; overflow-wrap: anywhere; }

.wizard__detecciones { display: flex; flex-wrap: wrap; gap: 8px; align-content: start; }
.imp-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    color: var(--fg);
}
.imp-chip__num { font-weight: 700; }
.imp-chip--ok { border-color: var(--status-active); color: var(--status-active); }
.imp-chip--aviso { border-color: var(--status-warning); color: var(--status-warning); }
.imp-chip--gris { color: var(--fg-muted); }

.wizard__resolucion { margin-bottom: 14px; }
.imp-res-fila {
    display: grid;
    grid-template-columns: 170px 1fr auto;
    gap: 10px;
    align-items: center;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    margin-bottom: 6px;
    font-size: 12.5px;
}
.imp-res-fila--pendiente { border-color: var(--status-warning); }
.imp-res-fila__etiqueta { color: var(--fg-muted); }
.imp-res-fila__detalle { color: var(--fg-strong); overflow-wrap: anywhere; }
.imp-res-fila__detalle .input, .imp-res-fila__detalle select { max-width: 360px; }
/* El campo de sugerencias del área nueva va separado del nombre que lo precede. */
.imp-res-fila__detalle smart-input.heb-sugerencias { margin-left: 8px; max-width: 260px; }
.imp-res-fila__estado { font-size: 12px; font-weight: 600; white-space: nowrap; }
.imp-res-fila__estado--ok { color: var(--status-active); }
.imp-res-fila__estado--pendiente { color: var(--status-warning); }
.imp-res-fila__nota { display: block; margin-top: 3px; font-size: 11.5px; color: var(--fg-muted); }

.wizard__aviso-mod {
    margin: 8px 0 0;
    padding: 8px 12px;
    border: 1px solid var(--status-warning);
    border-radius: var(--r-md);
    font-size: 12.5px;
    color: var(--status-warning);
}

.wizard__grid-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.wizard__toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--fg-muted); cursor: pointer; }

.heb-grid--wizard { height: 300px; }

.imp-marca {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
    margin-right: 4px;
    white-space: nowrap;
}
.imp-marca--cancelada { background: var(--bg-active); color: var(--fg-muted); }
.imp-marca--servicio { background: var(--heb-red-soft); color: var(--heb-red); }
.imp-marca--otra-tienda { border: 1px solid var(--status-warning); color: var(--status-warning); }

/* --- Paso 3: montos y resumen -------------------------------------------- */
.wizard__montos {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 6px 14px;
    margin: 0 0 14px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-subtle);
    font-size: 13px;
}
.wizard__montos dt { color: var(--fg-muted); }
.wizard__montos dd { margin: 0; text-align: right; font-weight: 600; color: var(--fg-strong); font-variant-numeric: tabular-nums; }
.wizard__montos dd.wizard__montos-total { font-size: 15px; color: var(--heb-red); }

.wizard__resumen { margin: 0 0 14px; padding: 0; list-style: none; font-size: 12.5px; color: var(--fg); }
.wizard__resumen li { display: flex; gap: 8px; align-items: baseline; padding: 3px 0; }
.wizard__resumen li::before { content: "•"; color: var(--status-active); font-weight: 700; }

.wizard__footer {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 20px;
    border-top: 1px solid var(--border);
}
.wizard__footer-espacio { flex: 1; }

/* Tab Documentos de Control PO — documento de origen de una OC importada */
.doc-origen {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 16px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-subtle);
    margin-bottom: 16px;
}
.doc-origen__datos { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.doc-origen__nombre { font-weight: 600; color: var(--fg-strong); font-size: 13px; overflow-wrap: anywhere; }

/* ============================================================
   Reporte Presupuesto/Gasto + Dashboard (LOG-RPT, épica 3.35)
   ============================================================ */

/* Tiles del dashboard de presupuestos: montos a la derecha (uso es-MX),
   scoped a esta pantalla para no mover los KPI de otros dashboards. */
#rpp-dashboard .stat__value,
#rpp-dashboard .stat__delta {
    text-align: right;
}

/* Toggle Dashboard / Reporte del encabezado. */
.rpp-toggle {
    display: inline-flex;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    background: var(--bg-elevated);
}
.rpp-toggle__btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    font-size: 12.5px;
    font-family: inherit;
    color: var(--fg-muted);
    background: transparent;
    border: none;
    cursor: pointer;
}
.rpp-toggle__btn:hover {
    background: var(--bg-hover);
}
.rpp-toggle__btn--active {
    background: var(--heb-red);
    color: #ffffff;
}
.rpp-toggle__btn:focus-visible {
    outline: 2px solid var(--border-focus);
    outline-offset: -2px;
}

/* Sección de tarjetas del dashboard. */
.rpp-seccion {
    margin-top: 14px;
    padding: 16px;
}
.rpp-seccion__head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 12px;
}
.rpp-seccion__title {
    font-size: 14px;
    font-weight: 600;
    margin: 0;
}
.rpp-seccion__sub {
    font-size: 12px;
    color: var(--fg-muted);
}
.rpp-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 12px;
}
.rpp-card {
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    background: var(--bg-elevated);
    padding: 12px 14px;
}
.rpp-card--rebasado {
    border-color: var(--status-danger);
}
.rpp-card__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 8px;
}
.rpp-card__name {
    font-weight: 600;
    font-size: 13px;
}
.rpp-card__sub {
    font-size: 11.5px;
    color: var(--fg-muted);
    margin-top: 1px;
}
/* Barra fondeado: colocado (base) + recibido (encimado). */
.rpp-card__bar {
    position: relative;
    height: 8px;
    border-radius: 999px;
    background: var(--bg-hover);
    margin: 10px 0 8px;
    overflow: hidden;
}
.rpp-card__bar-col {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--status-warning);
    border-radius: 999px;
}
.rpp-card__bar-rec {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--status-active);
    border-radius: 999px;
}
.rpp-card__figs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-top: 8px;
}
.rpp-card__lbl {
    font-size: 10.5px;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.rpp-card__num {
    font-size: 13px;
    font-weight: 600;
    margin-top: 1px;
}
/* Cantidades alineadas a la derecha (uso es-MX); la etiqueta acompana. */
.rpp-card__figs > div {
    text-align: right;
}
.rpp-card__num--rec { color: var(--status-active); }
.rpp-card__num--ok { color: var(--status-active); }
.rpp-card__num--over { color: var(--status-danger); }
/* Split equipos vs servicio del colocado. */
.rpp-card__split {
    height: 5px;
    border-radius: 999px;
    background: var(--status-pending-bg);
    margin-top: 10px;
    overflow: hidden;
}
.rpp-card__split-eq {
    height: 100%;
    background: var(--status-info, var(--heb-red));
    border-radius: 999px;
}
.rpp-card__leyenda {
    display: flex;
    justify-content: space-between;
    font-size: 11px;
    color: var(--fg-muted);
    margin-top: 5px;
}
.rpp-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-right: 4px;
    vertical-align: baseline;
}
.rpp-dot--eq { background: var(--status-info, var(--heb-red)); }
.rpp-dot--ab { background: var(--status-pending-bg); border: 1px solid var(--status-warning); }
.rpp-card__foot {
    font-size: 11px;
    color: var(--fg-muted);
    border-top: 1px dashed var(--border);
    margin-top: 10px;
    padding-top: 7px;
}

/* Banda "propuesta funcional" (pendiente HEB, ICB 5). */
.rpp-pendiente {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 11.5px;
    color: var(--fg-muted);
    padding: 6px 2px;
    border-top: 1px dashed var(--border);
}

/* Franja de totales del corte. */
.rpp-totales {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
    padding: 10px 2px;
    border-top: 1px solid var(--border);
}
.rpp-total {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 12.5px;
    color: var(--fg-muted);
}
.rpp-total strong {
    font-size: 14px;
    color: var(--fg-strong);
}
.rpp-total--muted strong {
    color: var(--fg-muted);
}

/* Tabla agrupada del reporte (a mano, D5). */
.rpp-tablewrap {
    overflow: auto;
    /* Alto fijo: el scroll vertical vive en la tabla, no en la pagina
       (header + 3 filas de filtros + banda + totales ~455px). */
    height: calc(100vh - 455px);
    min-height: 240px;
    border-top: 1px solid var(--border);
}
.rpp-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
    /* Columnas con aire: los montos no se parten; el excedente se resuelve
       con el scroll horizontal de la tabla. */
    min-width: 1680px;
}
.rpp-table th {
    position: sticky;
    top: 0;
    background: var(--bg-elevated);
    text-align: left;
    font-weight: 600;
    font-size: 11px;
    color: var(--fg-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 8px 8px;
    border-bottom: 1px solid var(--border);
    z-index: 1;
}
.rpp-table td {
    padding: 6px 8px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
    white-space: nowrap;
}
.rpp-table th.rpp-r,
.rpp-table td.rpp-r {
    text-align: right;
}
.rpp-grp {
    cursor: pointer;
}
.rpp-grp:hover td {
    background: var(--bg-hover);
}
.rpp-grp--t td {
    background: var(--bg-hover);
    font-weight: 600;
}
.rpp-grp--fa td {
    color: var(--fg-muted);
}
.rpp-grp__chevron {
    display: inline-flex;
    vertical-align: -2px;
    margin-right: 4px;
}
.rpp-leaf td {
    color: var(--fg);
}
.rpp-desc {
    max-width: 260px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rpp-badge-estatus {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
    color: #ffffff;
    background: var(--fg-muted);
}
.rpp-vacio {
    text-align: center;
    color: var(--fg-muted);
    padding: 36px 0;
    font-size: 12.5px;
}

/* =====================================================================
   Orden de cambio (épica 3.26) — tab Documentos de Control PO:
   historial de versiones en tarjetas + sub-panel "Subir orden de cambio"
   ===================================================================== */

.oc-doc-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap);
    margin: 4px 0 14px;
}
.oc-doc-head .form-section-title { margin-bottom: 0; }

/* --- Historial de versiones (tarjetas colapsables, prototipo oc-listado) --- */
.oc-versiones {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 10px;
}
.oc-version {
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-elevated);
}
.oc-version__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    cursor: pointer;
    list-style: none;
}
.oc-version__head::-webkit-details-marker { display: none; }
.oc-version__head--simple { cursor: default; }
.oc-version__nombre {
    font-weight: 600;
    color: var(--fg-strong);
    font-size: 12.5px;
}
.oc-version__sub {
    color: var(--fg-muted);
    font-size: 12px;
    flex: 1;
    min-width: 0;
}
.oc-version__actual {
    font-size: 11px;
    font-weight: 600;
    color: var(--status-active);
    background: var(--status-active-bg);
    border-radius: var(--r-sm);
    padding: 2px 8px;
    white-space: nowrap;
}
.oc-version__body {
    border-top: 1px solid var(--border);
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.oc-version__nota {
    color: var(--fg-muted);
    font-size: 12px;
}
.oc-version__diffrow {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 12.5px;
    color: var(--fg);
}
.oc-version__diffrow--total {
    margin-top: 4px;
    color: var(--fg-strong);
}
.oc-version__pdf {
    margin-top: 6px;
    font-size: 12px;
    align-self: flex-start;
}
.oc-difftag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: var(--r-sm);
    font-size: 11px;
    font-weight: 700;
    flex: none;
}
.oc-difftag--add { color: var(--status-active); background: var(--status-active-bg); }
.oc-difftag--del { color: var(--status-danger); background: var(--status-danger-bg); }
.oc-difftag--mod { color: var(--status-pending); background: var(--status-pending-bg); }

/* --- Sub-panel: avisos, review y efectos --- */
.oc-cambio-aviso {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 10px 12px;
    font-size: 12.5px;
    color: var(--fg);
    margin-bottom: 14px;
}
.oc-cambio-aviso svg { flex: none; margin-top: 2px; color: var(--fg-muted); }

.oc-cambio-bloqueos {
    border: 1px solid var(--status-danger);
    background: var(--status-danger-bg);
    border-radius: var(--r-md);
    padding: 10px 12px;
    margin-bottom: 14px;
}
.oc-cambio-bloqueos__titulo {
    display: flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    color: var(--status-danger);
    font-size: 12.5px;
}
.oc-cambio-bloqueos ul,
.oc-cambio-avisos ul {
    margin: 6px 0 0;
    padding-left: 20px;
    font-size: 12.5px;
    color: var(--fg);
}
.oc-cambio-avisos {
    border: 1px solid var(--border);
    background: var(--status-pending-bg);
    border-radius: var(--r-md);
    padding: 8px 12px;
    margin-bottom: 14px;
}

.oc-cambio-pill {
    display: inline-flex;
    align-items: center;
    border-radius: var(--r-sm);
    padding: 2px 8px;
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
}
.oc-cambio-pill--info { color: var(--fg); background: var(--bg-subtle); border: 1px solid var(--border); }
.oc-cambio-pill--add { color: var(--status-active); background: var(--status-active-bg); }
.oc-cambio-pill--del { color: var(--status-danger); background: var(--status-danger-bg); }
.oc-cambio-pill--warn { color: var(--status-pending); background: var(--status-pending-bg); }

.oc-cambio-efectos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 10px;
    margin-bottom: 14px;
}
.oc-cambio-card {
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--bg-elevated);
    padding: 10px 12px;
}
.oc-cambio-card--add { border-color: var(--status-active); }
.oc-cambio-card--del { border-color: var(--status-danger); }
.oc-cambio-card--warn { border-color: var(--status-pending); }
.oc-cambio-card__titulo {
    font-weight: 600;
    font-size: 12.5px;
    color: var(--fg-strong);
    margin-bottom: 4px;
}
.oc-cambio-card__texto {
    font-size: 12px;
    color: var(--fg-muted);
}

.oc-cambio-totales {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    border-top: 1px solid var(--border);
    padding-top: 10px;
    font-size: 12.5px;
    color: var(--fg);
}

.oc-cambio-unidades {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 6px;
}
.oc-cambio-unidad {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--fg);
}
.oc-cambio-unidad--llegada { color: var(--fg-subtle); }

.oc-cambio-listo {
    text-align: center;
    padding: 40px 20px 20px;
    color: var(--fg);
}
.oc-cambio-listo__icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    color: var(--status-active);
    background: var(--status-active-bg);
    margin-bottom: 10px;
}
.oc-cambio-listo__titulo {
    font-weight: 600;
    font-size: 14px;
    color: var(--fg-strong);
}

/* =====================================================================
   Reclasificación de tienda (épica 3.28) — chip ámbar del grid de
   Seguimiento (prototipo §6 D2: tooltip con tienda original y motivo)
   ===================================================================== */

.seg-reclas-chip {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--status-pending);
    background: var(--status-pending-bg);
    white-space: nowrap;
    cursor: help;
}

/* Variante que envuelve el nombre de la tienda destino: el nombre se trunca
   DENTRO del pill para que el estado "prestada" siempre quede visible aunque
   la tienda sea larga (hallazgo del smoke 11-jul). */
.seg-reclas-chip--tienda {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
}

/* ---------------------------------------------------------------------------
   PreLista de Envío (épica 3.32) — la hoja de carga de un camión.

   El progreso encabeza el tab Carga, que es de lo que habla; los datos de la
   hoja viven en su propio tab. De corrido en un solo panel había que bajar
   mucho para llegar a la tabla de líneas, que es lo que se usa todo el tiempo.
   --------------------------------------------------------------------------- */
.pl-progreso {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
}
.pl-progreso__barra {
    flex: 1;
    height: 8px;
    border-radius: 999px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    overflow: hidden;
}
.pl-progreso__barra span {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: var(--heb-red);
    transition: width 0.2s ease;
}
.pl-progreso__texto {
    font-size: 12.5px;
    color: var(--fg-muted);
    white-space: nowrap;
}
/* Los cuatro números de la carga en una fila: se capturan juntos y se leen
   juntos, así que ocupan una sola línea del formulario. */
.pl-carga { display: flex; gap: 8px; }
.pl-carga__campo { flex: 1; min-width: 0; }
.pl-carga__campo span {
    display: block;
    margin-bottom: 4px;
    font-size: 12px;
    color: var(--fg-muted);
}

/* Casilla de "marcar toda la hoja" en el encabezado de la columna Cargada
   (PreLista). Va en el header y no como botón de la barra: es el gesto que la
   gente ya conoce de cualquier grid. */
.pl-todos {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
}
.pl-todos input { cursor: pointer; }
.pl-todos input:disabled { cursor: not-allowed; }


/* ===================================================================
   Resumen de Logística (épica 3.36)
   Tablero de arranque del módulo. Reusa .stat y .card; sólo agrega la
   barra del pipeline, las barras de avance y las cajas de cifras.
   =================================================================== */

.dashlog-seccion { margin-bottom: var(--gap); }
.dashlog-seccion__head {
    display: flex; align-items: baseline; gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.dashlog-seccion__title {
    font-size: 14px; font-weight: 600;
    color: var(--fg-strong);
    margin: 0;
}
.dashlog-seccion__sub { font-size: 11.5px; color: var(--fg-muted); }

.dashlog-corte { font-size: 11.5px; color: var(--fg-muted); align-self: center; }

/* Dos columnas parejas; en pantallas angostas se apilan. */
.dashlog-2col {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap);
    margin-bottom: var(--gap);
}
@media (max-width: 1100px) { .dashlog-2col { grid-template-columns: 1fr; } }

.dashlog-panel { display: flex; flex-direction: column; gap: 12px; }

/* --- Tarjetas de atención --- */
.dashlog-liga { text-decoration: none; color: inherit; display: block; }
.dashlog-liga:hover .stat__delta { color: var(--heb-red); }
.dashlog-liga:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }

.dashlog-atencion__card--danger { border-left: 3px solid var(--status-danger); }
.dashlog-atencion__card--warn   { border-left: 3px solid var(--status-warning); }
.dashlog-atencion__card--ok     { border-left: 3px solid var(--border); }
.dashlog-atencion__card--ok .stat__value { color: var(--fg-muted); }

.dashlog-punto {
    width: 8px; height: 8px; border-radius: 50%;
    flex-shrink: 0;
}
.dashlog-punto--danger { background: var(--status-danger); }
.dashlog-punto--warn   { background: var(--status-warning); }
.dashlog-punto--ok     { background: var(--status-active); }

/* --- Pipeline --- */
.dashlog-pipe { display: flex; flex-direction: column; gap: 9px; }
.dashlog-pipe__row {
    display: grid;
    grid-template-columns: minmax(90px, 1.1fr) 3fr auto auto;
    align-items: center;
    gap: 10px;
    font-size: 12px;
}
.dashlog-pipe__nombre {
    display: inline-flex; align-items: center; gap: 7px;
    color: var(--fg);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dashlog-pipe__punto { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
.dashlog-pipe__barra {
    height: 8px;
    background: var(--bg-hover);
    border-radius: 999px;
    overflow: hidden;
}
.dashlog-pipe__relleno { display: block; height: 100%; border-radius: 999px; }
.dashlog-pipe__valor {
    font-weight: 600; color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
    min-width: 34px; text-align: right;
}
.dashlog-pipe__pct {
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
    min-width: 34px; text-align: right;
}

/* --- Avance --- */
.dashlog-avance { display: flex; flex-direction: column; gap: 14px; }
.dashlog-avance__row {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: "head head" "barra pct";
    align-items: center;
    gap: 6px 10px;
}
.dashlog-avance__head {
    grid-area: head;
    display: flex; justify-content: space-between; align-items: baseline;
    gap: 10px;
    font-size: 12px; color: var(--fg-muted);
}
.dashlog-avance__head strong {
    color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
}
.dashlog-avance__barra {
    grid-area: barra;
    height: 10px;
    background: var(--bg-hover);
    border-radius: 999px;
    overflow: hidden;
}
.dashlog-avance__relleno { display: block; height: 100%; border-radius: 999px; }
.dashlog-avance__relleno--mex { background: var(--status-warning); }
.dashlog-avance__relleno--entregadas { background: var(--status-active); }
.dashlog-avance__pct {
    grid-area: pct;
    font-size: 12px; font-weight: 600; color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
    min-width: 34px; text-align: right;
}

/* --- Cajas de cifras (órdenes, mercancía congelada) --- */
.dashlog-ordenes { margin-top: auto; }
.dashlog-ordenes__caja {
    display: flex; gap: 22px; flex-wrap: wrap;
    padding: 12px 14px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
/* 3.63: cada cifra es su propia liga (autorizadas / por autorizar). */
a.dashlog-ordenes__cifra:hover strong { color: var(--heb-red); }
.dashlog-ordenes__cifra { display: flex; flex-direction: column; gap: 2px; }
.dashlog-ordenes__cifra strong {
    font-size: 20px; font-weight: 600; color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.dashlog-ordenes__cifra span { font-size: 11.5px; color: var(--fg-muted); }
.dashlog-ordenes__cifra--alerta strong { color: var(--status-warning); }

/* --- Lista de proyectos rebasados --- */
.dashlog-bloque { display: flex; flex-direction: column; gap: 8px; }
a.dashlog-bloque:hover .dashlog-lista__titulo { color: var(--heb-red); }
.dashlog-lista__titulo {
    font-size: 12px; font-weight: 600;
    color: var(--status-warning);
}
.dashlog-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.dashlog-lista__row {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) auto auto;
    align-items: baseline;
    gap: 10px;
    font-size: 12px;
    padding-bottom: 7px;
    border-bottom: 1px solid var(--border);
}
.dashlog-lista__row:last-child { border-bottom: 0; padding-bottom: 0; }
.dashlog-lista__nombre {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--fg);
}
.dashlog-lista__monto {
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.dashlog-lista__exceso {
    color: var(--status-danger);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.dashlog-lista__resto { font-size: 11.5px; }

.dashlog-vacio {
    display: flex; align-items: center;
    padding: 14px;
    font-size: 12px; color: var(--fg-muted);
    background: var(--bg-subtle);
    border: 1px dashed var(--border);
    border-radius: var(--r-md);
}

/* --- Órdenes activas: una tarjeta por OC, calcada del prototipo --- */
.dashlog-ocs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}
@media (max-width: 1100px) { .dashlog-ocs { grid-template-columns: 1fr; } }

.dashlog-oc {
    display: flex; flex-direction: column; gap: 8px;
    padding: 12px 14px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
a.dashlog-oc:hover { border-color: var(--border-strong); background: var(--bg-hover); }

.dashlog-oc__head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px;
}
.dashlog-oc__ident { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dashlog-oc__folio {
    font-size: 13px; font-weight: 600; color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
}
.dashlog-oc__tienda {
    font-size: 11.5px; color: var(--fg-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dashlog-oc__meta {
    display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
    flex-shrink: 0;
}
.dashlog-oc__dias { font-size: 11.5px; font-weight: 600; white-space: nowrap; }
.dashlog-oc__dias--danger { color: var(--status-danger); }
.dashlog-oc__dias--warn   { color: var(--status-warning); }
.dashlog-oc__dias--ok     { color: var(--status-active); }
.dashlog-oc__dias--neutro { color: var(--fg-muted); }
.dashlog-oc__pct {
    font-size: 11.5px; color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
}

/* Barra doble: el recibido de fondo, el entregado encima — leerlas juntas
   dice de un vistazo cuánto llegó y cuánto ya salió. */
.dashlog-oc__barra {
    position: relative;
    display: block;
    height: 8px;
    /* El track va contra el fondo de la tarjeta, que ya es gris: con
       --bg-hover se pierde y una orden en 0% parecía no tener barra. */
    background: var(--border);
    border-radius: 999px;
    overflow: hidden;
}
.dashlog-oc__rec,
.dashlog-oc__ent {
    position: absolute; top: 0; left: 0; height: 100%;
    border-radius: 999px;
}
.dashlog-oc__rec { background: var(--status-warning); opacity: 0.55; }
.dashlog-oc__ent { background: var(--status-active); }

.dashlog-oc__foot {
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between;
    gap: 6px 12px;
    font-size: 11.5px; color: var(--fg-muted);
}
.dashlog-oc__stats b { color: var(--fg); font-variant-numeric: tabular-nums; }
.dashlog-oc__chips { display: inline-flex; flex-wrap: wrap; gap: 8px; }
.dashlog-oc__chip {
    display: inline-flex; align-items: center; gap: 5px;
    white-space: nowrap;
}
.dashlog-oc__chip b { color: var(--fg); font-variant-numeric: tabular-nums; }

/* --- Por proveedor: barra comparativa con el avance dentro --- */
.dashlog-proveedores { display: flex; flex-direction: column; gap: 11px; }

.dashlog-prov { display: flex; flex-direction: column; gap: 5px; }
.dashlog-prov__head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px;
    font-size: 11.5px; color: var(--fg-muted);
}
.dashlog-prov__nombre {
    color: var(--fg);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    min-width: 0;
}
.dashlog-prov__nums { white-space: nowrap; flex-shrink: 0; }
.dashlog-prov__nums b { color: var(--fg); font-variant-numeric: tabular-nums; }
.dashlog-prov__pct { margin-left: 8px; font-variant-numeric: tabular-nums; }
/* 3.63: incumplimiento contra la VTO del proveedor. */
.dashlog-prov__venc { margin-left: 8px; color: var(--status-danger); font-variant-numeric: tabular-nums; }

/* El ancho de la base compara volúmenes entre proveedores; el relleno verde
   de adentro es el avance DE ESE proveedor, no del total. */
.dashlog-prov__track {
    display: block;
    height: 9px;
    background: var(--bg-hover);
    border-radius: 999px;
    overflow: hidden;
}
.dashlog-prov__base {
    display: block; height: 100%;
    background: var(--border-strong);
    border-radius: 999px;
    position: relative;
}
.dashlog-prov__ent {
    display: block; height: 100%;
    background: var(--status-active);
    border-radius: 999px;
}

/* --- Actividad reciente: quién movió qué y cuándo --- */
.dashlog-actividad { display: flex; flex-direction: column; gap: 10px; }

.dashlog-act { display: flex; align-items: flex-start; gap: 9px; }
.dashlog-act__cuerpo { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dashlog-act__texto { font-size: 12px; color: var(--fg); line-height: 1.4; }
.dashlog-act__texto b { color: var(--fg-strong); }
.dashlog-act__estatus {
    display: inline-flex; align-items: center; gap: 5px;
    white-space: nowrap;
}
.dashlog-act__meta {
    display: flex; align-items: center; gap: 6px;
    font-size: 11px; color: var(--fg-muted);
}
.dashlog-act__folio { font-variant-numeric: tabular-nums; }

/* --- Por proyecto: una tarjeta por proyecto con su barra apilada --- */
.dashlog-proyectos {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
}
@media (max-width: 1400px) { .dashlog-proyectos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px)  { .dashlog-proyectos { grid-template-columns: 1fr; } }

.dashlog-proy {
    display: flex; flex-direction: column; gap: 8px;
    padding: 12px 14px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
.dashlog-proy__head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px;
}
.dashlog-proy__nombre {
    font-size: 12.5px; font-weight: 600; color: var(--fg-strong);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dashlog-proy__clave {
    font-size: 10.5px; color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    max-width: 40%;
}

/* Barra apilada al 100%: los pasos del flujo en orden, de izquierda a
   derecha, como avanza la mercancía. */
.dashlog-proy__barra {
    display: flex;
    height: 10px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--border);
}
.dashlog-proy__seg { display: block; height: 100%; }

.dashlog-proy__leyenda {
    display: flex; flex-wrap: wrap; gap: 4px 10px;
    font-size: 11px; color: var(--fg-muted);
}
.dashlog-proy__chip { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.dashlog-proy__chip b { color: var(--fg); font-variant-numeric: tabular-nums; }
.dashlog-proy__pie { font-size: 11px; color: var(--fg-muted); }
.dashlog-proy__pie b { color: var(--fg); font-variant-numeric: tabular-nums; }

/* --- Próximas recepciones: los días en grande, a la izquierda --- */
.dashlog-etr { display: flex; flex-direction: column; gap: 8px; }

.dashlog-etr__row {
    display: flex; align-items: center; gap: 12px;
    padding: 9px 12px;
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}
a.dashlog-etr__row:hover { border-color: var(--border-strong); background: var(--bg-hover); }

.dashlog-etr__dias {
    display: flex; flex-direction: column; align-items: center;
    min-width: 46px;
    line-height: 1.05;
    flex-shrink: 0;
}
.dashlog-etr__dias strong {
    font-size: 20px; font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.dashlog-etr__dias span { font-size: 10px; text-transform: lowercase; }
.dashlog-etr__dias--warn { color: var(--status-warning); }
.dashlog-etr__dias--ok   { color: var(--status-active); }

.dashlog-etr__cuerpo { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.dashlog-etr__folio {
    font-size: 12.5px; font-weight: 600; color: var(--fg-strong);
    font-variant-numeric: tabular-nums;
}
.dashlog-etr__tienda {
    font-size: 11.5px; color: var(--fg);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dashlog-etr__meta { font-size: 11px; color: var(--fg-muted); }
.dashlog-etr__meta b { color: var(--fg); font-variant-numeric: tabular-nums; }
