/* ============================================================
   JSmart Suite — CSS Global
   Design system adoptado de: crm_eo_xspreadsheet / crm_postventa
   (frontend/css/style.css) — tema claro fijo, sidebar navy,
   topbar blanca, tarjetas blancas con sombra suave, primario #3b82f6.
   ============================================================ */

/* ========================================
   1. Variables :root (design system CRM)
   ======================================== */
:root {
    /* Fondos */
    --bg-app: oklch(0.984 0.003 247.9);             /* era var(--bg-card-hover) */
    --bg-sidebar: oklch(0.279 0.037 260.0);         /* era var(--bg-sidebar) */
    --sidebar-text: oklch(0.929 0.013 255.5);       /* era var(--border-color) */
    --sidebar-hover: oklch(0.372 0.039 257.3);      /* era var(--sidebar-hover) */
    --bg-card: oklch(1.000 0.000 89.9);             /* era #ffffff */
    --bg-card-hover: oklch(0.984 0.003 247.9);      /* era var(--bg-card-hover) */
    --bg-input: oklch(1.000 0.000 89.9);            /* era #ffffff */

    /* Bordes */
    --border-color: oklch(0.929 0.013 255.5);       /* era var(--border-color) */

    /* Texto */
    --text-primary: oklch(0.208 0.040 265.8);       /* era var(--text-primary) */
    --text-secondary: oklch(0.446 0.037 257.3);     /* era var(--text-secondary) */
    --text-muted: oklch(0.554 0.041 257.4);         /* era var(--text-muted) */

    /* Primario */
    --color-accent: oklch(0.623 0.188 259.8);       /* era #3b82f6 */
    --color-accent-hover: oklch(0.546 0.215 262.9); /* era #2563eb */
    /* --color-accent-glow eliminado (Fase C.1): sin usos */

    /* Colores de estado */
    --color-success: oklch(0.723 0.192 149.6);      /* era #22c55e */
    /* --color-success-glow eliminado (Fase C.1): sin usos */

    --color-fail: oklch(0.637 0.208 25.3);          /* era #ef4444 */
    /* --color-fail-glow eliminado (Fase C.1): sin usos */

    --color-process: oklch(0.606 0.219 292.7);      /* era #8b5cf6 */
    /* --color-process-glow eliminado (Fase C.1): sin usos */

    --color-warning: oklch(0.769 0.165 70.1);       /* era #f59e0b */
    /* --color-warning-glow eliminado (Fase C.1): sin usos */

    /* Llamada en curso (F2): texto de la píldora (fondo var(--text-primary)) */
    --call-pill-fg: oklch(0.985 0 0);               /* era var(--bg-card-hover) */

    /* Tipografía */
    --font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --font-mono: ui-monospace, 'Cascadia Code', 'JetBrains Mono', monospace;

    /* Layout */
    --sidebar-width: 260px;
    --sidebar-shrunk: 64px;
    --header-height: 64px;
    --transition-speed: 0.2s;

    /* Radios */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 12px;
    --radius-full: 9999px;

    /* Sombras */
    --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.08);
    --shadow-lg: 0 20px 50px rgba(0, 0, 0, 0.2);

    /* ===== FASE 17: hooks de estética (Alba = valores históricos) =====
       Los temas (frontend/themes.css) sobrescriben SOLO estos tokens + un
       puñado de reglas de sabor. Alba no cambia (0 diff). */
    --bg-app-image: none;                           /* degradado de fondo (cristal) */
    --surface-blur: 0px;                            /* backdrop-filter de superficies */
    --border-width: 1px;                            /* vivo usa 2px */
    --shadow-hard: none;                            /* vivo: sombra sólida */
    --font-display: var(--font-sans);               /* papel: serif en titulares */
    --color-accent-2: var(--color-accent);          /* acento secundario de tema */
    --bg-subtle: oklch(0.968 0.007 247.9);          /* era #f1f5f9 */
    --border-strong: oklch(0.869 0.020 252.9);      /* era #cbd5e1 */
    --text-faint: oklch(0.711 0.035 256.8);         /* era #94a3b8 */

    /* B.3: chevron de .form-select — data-URI (idéntico en style.css y ot.css)
       extraído a variable única; las dos reglas .form-select lo referencian */
    --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364748B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
}

/* ========================================
   2. Reset & Core Styles
   ======================================== */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html, body {
    height: 100%;
    overflow: hidden;
}

body {
    background-color: var(--bg-app);
    background-image: var(--bg-app-image);
    background-attachment: fixed;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

/* FASE 17: titulares con la tipografía de display del tema (papel = serif).
   En Alba --font-display = --font-sans → mismo aspecto (0 diff). */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
}

a {
    color: var(--color-accent); text-decoration: none;
    &:hover { text-decoration: underline; }
}

/* Scrollbar */
/* Firefox: scrollbar fina con el mismo color del thumb de webkit */
html { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
    &-track {
        background: transparent;
    }
    &-thumb {
        background: var(--border-strong);
        border-radius: 4px;
        &:hover {
            background: var(--text-muted);
        }
    }
}

/* ========================================
   3. Clases de Estado
   ======================================== */
.hidden {
    display: none !important;
}

.loading {
    border-color: var(--color-process) !important;
}

.success {
    border-color: var(--color-success) !important;
}

.fail {
    border-color: var(--color-fail) !important;
}

.skipped {
    opacity: 0.45;
    border-style: dashed;
}

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes slideInRight {
    from { opacity: 0; transform: translateX(100%); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes slideOutRight {
    from { opacity: 1; transform: translateX(0); }
    to   { opacity: 0; transform: translateX(100%); }
}

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

/* ========================================
   4. Layout App Container
   ======================================== */
.app-container {
    display: flex;
    height: 100vh;
    /* FASE 6: dvh como mejora progresiva — en iOS/Android la barra del navegador
       hace 100vh > viewport visible y el final del contenido quedaba inaccesible.
       En desktop dvh == vh (sin cambio visible). */
    height: 100dvh;
    width: 100vw;
    position: relative;
}

/* ========================================
   5. Sidebar (navy, estilo CRM EO)
   ======================================== */
/* Sidebar: off-canvas en móvil (translateX), fijo a la izquierda en escritorio */
.sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: var(--sidebar-width);
    background-color: var(--bg-sidebar);
    color: var(--sidebar-text);
    display: flex;
    flex-direction: column;
    padding: 0;
    z-index: 50;
    overflow-y: auto;
    transform: translateX(-100%);
    transition: transform 0.3s ease, width 0.3s ease;

    &.mobile-open {
        transform: translateX(0);
    }
}

/* Overlay oscuro para el drawer móvil */
.sidebar-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 40;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s;

    &.active {
        opacity: 1;
        pointer-events: auto;
    }
}

/* Escritorio: sidebar fijo en el flujo (no drawer) */
@media (min-width: 768px) {
    .sidebar {
        position: relative;
        transform: translateX(0);
    }

    .sidebar-overlay {
        display: none;
    }
}

.logo-container {
    height: 64px;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 1.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    flex-shrink: 0;
    white-space: nowrap;
    overflow: hidden;
}

.logo-icon {
    width: 26px;
    height: 26px;
    min-width: 26px;
    border-radius: 6px;
    background: linear-gradient(135deg, var(--color-success) 0%, var(--color-accent) 100%);
}

.logo-text {
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: -0.01em;
    color: #fff;
    transition: opacity 0.2s;
}

.logo-subtext {
    font-weight: 500;
    font-size: 0.72rem;
    color: rgba(226, 232, 240, 0.55);
    margin-left: 4px;
}

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex-grow: 1;
    padding: 1rem 0;
}

.nav-group-label {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(148, 163, 184, 0.55);
    padding: 12px 1.5rem 4px;
    white-space: nowrap;
    overflow: hidden;
}

.nav-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    background: none;
    border: none;
    border-left: 3px solid transparent;
    border-radius: 0;
    color: var(--sidebar-text);
    padding: 0.7rem 1.5rem;
    cursor: pointer;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    text-align: left;
    transition: background-color 0.2s, border-left 0.2s;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    /* H5: de suite.css — ancla para el .nav-badge (absolute) */
    position: relative;

    &:hover {
        background-color: var(--sidebar-hover);
        color: #fff;
    }

    &.active {
        background-color: var(--sidebar-hover);
        border-left-color: var(--color-accent);
        color: #fff;
    }

    & i {
        width: 18px;
        height: 18px;
        flex-shrink: 0;
        min-width: 18px;
    }
}

.sidebar-footer {
    padding: 1rem 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    margin-top: auto;
    white-space: nowrap;
    overflow: hidden;
}

.server-status {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background-color: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--radius-sm);
    font-size: 0.8rem;
}

.status-indicator {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--text-faint);
    flex-shrink: 0;

    &.online {
        background-color: var(--color-success);
        box-shadow: 0 0 8px rgba(34, 197, 94, 0.5);
    }

    &.offline {
        background-color: var(--color-fail);
        box-shadow: 0 0 8px rgba(239, 68, 68, 0.5);
    }
}

.status-text {
    color: var(--text-faint);
    font-size: 0.78rem;
}

/* ========================================
   6. Main Content + Topbar (blanca, sombra)
   ======================================== */
.main-content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: var(--bg-app);
    overflow: hidden;
    position: relative;
    min-width: 0;
    /* D.1 (FASE 8): query container — los @container de esta app responden al
       ancho real de contenido (ventana − sidebar), no al ancho de ventana. */
    container-type: inline-size;
}

.app-header {
    height: var(--header-height);
    background: var(--bg-card);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 1.5rem;
    z-index: 5;
    flex-shrink: 0;
}

.header-left {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-width: 0;
}

.toggle-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem;
    border-radius: 6px;

    &:hover {
        background-color: var(--bg-app);
    }

    & i {
        width: 20px;
        height: 20px;
    }
}

.page-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-controls {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* Chip de usuario (estilo "admin" de CRM EO) */
.user-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    font-size: 0.85rem;
    color: var(--text-primary);
    background: var(--bg-card);
    white-space: nowrap;

    & i {
        width: 16px;
        height: 16px;
        color: var(--text-muted);
    }
}

.logout-btn {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.2s;

    &:hover {
        background-color: var(--bg-app);
    }
}

.content-scroll {
    flex-grow: 1;
    overflow-y: auto;
    padding: 2rem;
}

#view-container { view-transition-name: view-content; }
::view-transition-old(view-content) { animation: vt-fade-out 0.18s ease-out; }
::view-transition-new(view-content) { animation: vt-fade-in 0.22s ease-in; }
@keyframes vt-fade-out { to { opacity: 0; } }
@keyframes vt-fade-in { from { opacity: 0; } }

/* ========================================
   7. Cards
   ======================================== */
.card {
    background-color: var(--bg-card);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: 1.5rem;
    margin-bottom: 1.5rem;
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border-color);
    flex-wrap: wrap;
}

.card-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 8px;

    & i {
        color: var(--color-accent);
        width: 18px;
        height: 18px;
    }
}

.card-subtitle {
    font-size: 0.78rem;
    color: var(--text-muted);
}

/* ========================================
   8. Buttons
   ======================================== */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.5rem 1rem;
    border-radius: 6px;
    font-family: var(--font-sans);
    font-size: 0.85rem;
    font-weight: 500;
    cursor: pointer;
    border: 1px solid transparent;
    transition: all 0.2s;
    text-decoration: none;
    white-space: nowrap;

    & i {
        width: 16px;
        height: 16px;
    }

    &:disabled {
        opacity: 0.55;
        cursor: not-allowed;
    }
}

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

    &:hover:not(:disabled) {
        background-color: var(--color-accent-hover);
        border-color: var(--color-accent-hover);
    }
}

.btn-secondary {
    background-color: transparent;
    color: var(--text-primary);
    border-color: var(--border-color);

    &:hover:not(:disabled) {
        background-color: var(--bg-app);
    }
}

.btn-danger {
    background-color: var(--color-fail);
    color: #fff;
    border-color: var(--color-fail);

    &:hover:not(:disabled) {
        filter: brightness(0.95);
    }
}

.btn-success {
    background-color: var(--color-success);
    color: #fff;
    border-color: var(--color-success);

    &:hover:not(:disabled) {
        filter: brightness(0.95);
    }
}

.btn-sm {
    padding: 0.3rem 0.6rem;
    font-size: 0.8rem;

    & i {
        width: 14px;
        height: 14px;
    }
}

.btn-icon {
    width: 36px;
    height: 36px;
    padding: 0;
    border-radius: var(--radius-sm);
}

/* ========================================
   9. Form Inputs
   ======================================== */
.form-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 1.25rem;

    /* C.2: feedback visual de error — el JS añade .invalid al campo cuando
       valida (sin tocar toasts ni spans .form-error existentes) */
    &:has(.form-input.invalid) .form-input,
    &:has(.form-select.invalid) .form-select,
    &:has(.form-textarea.invalid) .form-textarea {
        border-color: var(--color-fail);
        box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-fail) 12%, transparent);
    }
}

.form-label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-primary);
}

.form-input,
.form-select,
.form-textarea {
    background-color: var(--bg-input);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 0.9rem;
    transition: border-color 0.2s, box-shadow 0.2s;
    outline: none;
    width: 100%;

    &:focus {
        border-color: var(--color-accent);
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
    }
}

.form-input::placeholder {
    color: var(--text-muted);
}

.form-select {
    appearance: none;
    background-image: var(--icon-chevron); /* B.3: data-URI unificado en :root */
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 40px;
}

.form-textarea {
    resize: vertical;
    min-height: 80px;
}

.form-hint {
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

.form-error {
    font-size: 0.8rem;
    color: var(--color-fail);
    margin-top: 0.25rem;
}

/* Rango (slider) */
.form-range {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 6px;
    border-radius: var(--radius-full);
    background: var(--border-color);
    outline: none;
    cursor: pointer;

    &::-webkit-slider-thumb {
        -webkit-appearance: none;
        appearance: none;
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: var(--color-accent);
        border: 2px solid #fff;
        box-shadow: 0 1px 3px rgba(0,0,0,0.2);
        cursor: pointer;
        transition: transform 0.15s ease;
        &:hover { transform: scale(1.15); }
    }
    &::-moz-range-thumb {
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: var(--color-accent);
        border: 2px solid #fff;
        box-shadow: 0 1px 3px rgba(0,0,0,0.2);
        cursor: pointer;
    }
}

/* ========================================
   10. Tables (Base para DataGrid)
   ======================================== */
.table-wrapper {
    overflow-x: auto;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-card);
}

table.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;

    & thead {
        background-color: var(--bg-app);
        position: sticky;
        top: 0;
        z-index: 2;
    }

    & th {
        padding: 0.75rem 1rem;
        text-align: left;
        font-weight: 600;
        font-size: 0.75rem;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: var(--text-muted);
        border-bottom: 2px solid var(--border-color);
        white-space: nowrap;
        cursor: pointer;
        user-select: none;

        &:hover {
            color: var(--text-primary);
        }
    }

    & td {
        padding: 0.75rem 1rem;
        border-bottom: 1px solid var(--border-color);
        color: var(--text-secondary);
        vertical-align: middle;
    }

    & tbody tr {
        transition: background-color 0.15s;

        &:last-child td {
            border-bottom: none;
        }
    }

    & .mono {
        font-family: var(--font-mono);
        font-size: 0.8rem;
    }
}

/* B.3: tr:hover unificado — desanidada de table.data-table (el selector agrupado
   no puede vivir anidado: el prefijo contaminaría .datatable-table) y se borra la
   copia de .datatable-table (§27). Misma declaración y misma especificidad por selector. */
table.data-table tbody tr:hover,
.datatable-table tbody tr:hover {
    background-color: var(--bg-card-hover);
}

/* ========================================
   11. Tabs
   ======================================== */
.tabs-container {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.tabs-header {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--border-color);
    overflow-x: auto;
}

.tab-btn {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-family: var(--font-sans);
    font-size: 0.88rem;
    font-weight: 500;
    padding: 12px 20px;
    cursor: pointer;
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    transition: color 0.2s;
    white-space: nowrap;

    & i {
        width: 16px;
        height: 16px;
    }

    &:hover {
        color: var(--text-primary);
    }

    &.active {
        color: var(--text-primary);
        font-weight: 600;

        &::after {
            content: '';
            position: absolute;
            bottom: -1px;
            left: 0;
            width: 100%;
            height: 2px;
            background-color: var(--color-accent);
        }
    }
}

.tab-pane {
    padding-top: 20px;
    animation: fadeIn 0.2s ease;
}

/* ========================================
   12. Metric Cards (estilo stat-card CRM)
   ======================================== */
.metric-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.metric-card {
    background-color: var(--bg-card);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 8px;
    transition: transform 0.15s, box-shadow 0.15s;

    &:hover {
        transform: translateY(-1px);
        box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    }

    &.metric-success .metric-icon { background: #dcfce7; color: #16a34a; }
    &.metric-fail    .metric-icon { background: #fee2e2; color: #ef4444; }
    &.metric-accent  .metric-icon { background: #dbeafe; color: #3b82f6; }
    &.metric-process .metric-icon { background: #f3e8ff; color: #8b5cf6; }
}

/* Tile de icono de color (estilo .stat-icon CRM) */
.metric-icon {
    width: 48px;
    height: 48px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #dbeafe;
    color: var(--color-accent);
    flex-shrink: 0;

    & i {
        width: 22px;
        height: 22px;
    }
}

.metric-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.metric-label {
    font-size: 0.78rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-muted);
}

.metric-value {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1;
}

.metric-delta {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-muted);
}

/* ========================================
   13. Tag Bubbles
   ======================================== */
.tag-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.tag-bubble {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    border-radius: var(--radius-full);
    font-size: 0.78rem;
    font-weight: 500;
    border: 1px solid var(--border-color);
    background: var(--bg-subtle);
    color: var(--text-secondary);
    animation: fadeIn 0.2s ease;
}

.tag-remove {
    background: none;
    border: none;
    color: inherit;
    opacity: 0.6;
    cursor: pointer;
    display: flex;
    align-items: center;
    padding: 0;
    transition: opacity 0.2s;

    &:hover {
        opacity: 1;
    }

    & i {
        width: 12px;
        height: 12px;
    }
}

/* ========================================
   14. Expander
   ======================================== */
.expander {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
    margin-bottom: 12px;
    background: var(--bg-card);
}

.expander-header {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    background: var(--bg-card);
    border: none;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.2s;
    text-align: left;

    &:hover {
        background: var(--bg-card-hover);
    }

    & i {
        width: 18px;
        height: 18px;
        color: var(--color-accent);
    }
}

.expander-chevron {
    margin-left: auto;
    width: 18px;
    height: 18px;
    color: var(--text-muted) !important;
    transition: transform 0.3s ease;
}

.expander-body {
    padding: 16px 18px;
    background: var(--bg-app);
    border-top: 1px solid var(--border-color);
    animation: fadeIn 0.2s ease;
}

/* ========================================
   15. Dropdown
   ======================================== */
.dropdown-trigger {
    display: flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-family: var(--font-sans);
    font-weight: 500;
    cursor: pointer;
    padding: 6px 12px;
    border-radius: var(--radius-full);
    transition: background 0.2s, color 0.2s;

    &:hover {
        background-color: var(--bg-app);
        color: var(--text-primary);
    }

    & i {
        width: 14px;
        height: 14px;
    }
}

.dropdown-menu {
    position: absolute;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 8px;
    box-shadow: var(--shadow-lg);
    z-index: 100;
    display: flex;
    flex-direction: column;
    gap: 4px;
    transform: translateY(10px);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s;

    &:not(.hidden) {
        transform: translateY(0);
        opacity: 1;
        pointer-events: auto;
    }
}

.dropdown-bottom {
    bottom: calc(100% + 8px);
    left: 0;
}

.dropdown-top {
    top: calc(100% + 8px);
    left: 0;
}

.dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background 0.15s;
    color: var(--text-secondary);
    text-align: left;
    white-space: nowrap;

    &:hover {
        background-color: var(--bg-app);
        color: var(--text-primary);
    }

    &.active {
        background-color: #dbeafe;
        color: #1e40af;
    }

    & i {
        width: 18px;
        height: 18px;
        flex-shrink: 0;
    }
}

.dropdown-item-text {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.item-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-primary);
}

.item-desc {
    font-size: 0.72rem;
    color: var(--text-muted);
}

/* ========================================
   16. Segmented Control
   ======================================== */
.segmented-control-custom {
    position: relative;
    display: flex;
    background-color: var(--bg-subtle);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-full);
    padding: 4px;

    & input[type="radio"] {
        display: none;

        &:checked + .seg-tab {
            color: var(--text-primary);
            font-weight: 600;
        }
    }
}

.seg-tab {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--text-secondary);
    cursor: pointer;
    z-index: 2;
    transition: color 0.2s;
    border-radius: var(--radius-full);
    user-select: none;
    padding: 6px 12px;

    & i {
        width: 14px;
        height: 14px;
    }
}

.seg-slider {
    position: absolute;
    top: 4px;
    height: calc(100% - 8px);
    background-color: #fff;
    border-radius: var(--radius-full);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
    transition: left 0.25s cubic-bezier(0.4, 0, 0.2, 1), width 0.25s;
    z-index: 1;
}


/* ========================================
   17. Toggle Switch
   ======================================== */
.toggle-switch-label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
    font-size: 0.85rem;
    color: var(--text-secondary);

    & input[type="checkbox"] {
        display: none;
    }

    /* B.2: movido antes que .toggle-switch-slider — gana por especificidad (0,3,1)/(0,4,1) > (0,1,0)/(0,1,1) */
    & input:checked + .toggle-switch-slider {
        background-color: var(--color-accent);
        border-color: var(--color-accent);
    }

    & input:checked + .toggle-switch-slider::after {
        transform: translateX(18px);
        background-color: #fff;
    }
}

.toggle-switch-slider {
    position: relative;
    width: 40px;
    height: 22px;
    background-color: var(--border-strong);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    transition: all 0.3s ease;
    flex-shrink: 0;

    &::after {
        content: '';
        position: absolute;
        top: 2px;
        left: 2px;
        width: 16px;
        height: 16px;
        background-color: #fff;
        border-radius: 50%;
        box-shadow: 0 1px 2px rgba(0,0,0,0.2);
        transition: all 0.3s ease;
    }
}

.toggle-switch-text {
    font-weight: 500;
    letter-spacing: 0.02em;
}

/* ========================================
   18. Toast Notifications
   ======================================== */
.toast-container {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 10000;
    display: flex;
    flex-direction: column-reverse;
    gap: 10px;
    pointer-events: none;
}

/* Variante «junto al pill» (FASE 12 D7): mismo right que la píldora y por
   encima de ella — la presentación del toast es la del contenedor base. */
.toast-container--pill {
    right: 22px;   /* == .call-pill right */
    bottom: 84px;  /* pill (22+46 px) + respiro */
    z-index: 8550; /* > pill 8500, < toasts base (no se solapan: distinta right) */
}

.toast {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-width: 320px;
    max-width: 420px;
    padding: 14px 18px;
    border-radius: 8px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
    color: var(--text-primary);
    font-size: 0.88rem;
    pointer-events: auto;
    transform: translateX(120%);
    opacity: 0;
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.35s;

    /* B.2: movido antes que .toast-visible/.toast-hiding — selectores sobre elementos distintos (icono vs toast), sin props en común */
    & i {
        width: 20px;
        height: 20px;
        flex-shrink: 0;
        margin-top: 1px;
    }
}

.toast-visible {
    transform: translateX(0);
    opacity: 1;
}

.toast-hiding {
    transform: translateX(120%);
    opacity: 0;
}

.toast-success { border-left: 4px solid var(--color-success);

    & i { color: var(--color-success); }
}

.toast-error { border-left: 4px solid var(--color-fail);

    & i { color: var(--color-fail); }
}

.toast-warning { border-left: 4px solid var(--color-warning);

    & i { color: var(--color-warning); }
}

.toast-info { border-left: 4px solid var(--color-accent);

    & i { color: var(--color-accent); }
}

.toast-message {
    flex-grow: 1;
    line-height: 1.4;
    color: var(--text-secondary);
}

/* Chip compacto junto al mensaje (F3: `📞 #482` en toasts con llamada en
   curso). Solo existe si el toast se creó con `chip` — sin chip, idéntico. */
.toast-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
    margin-top: 1px;
    padding: 1px 9px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-full);
    background-color: var(--bg-card-hover);
    color: var(--text-secondary);
    font-size: 0.72rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;

    & i {
        width: 12px;
        height: 12px;
        color: var(--color-fail);
    }
}

.toast-dismiss {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    padding: 0;
    transition: color 0.2s;

    &:hover {
        color: var(--text-primary);
    }

    & i {
        width: 14px;
        height: 14px;
    }
}

/* ========================================
   19. Modal
   ======================================== */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9000;
    padding: 1rem;
    animation: fadeIn 0.2s ease;
}

.modal {
    background: var(--bg-card);
    border-radius: var(--radius-lg);
    width: 90%;
    max-width: 560px;
    max-height: 90vh;
    max-height: 90dvh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
    animation: fadeIn 0.25s ease;
}

.modal-modal-sm { max-width: 400px; }
.modal-modal-md { max-width: 560px; }
.modal-modal-lg { max-width: 720px; }
.modal-modal-xl { max-width: 900px; }

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--border-color);
}

.modal-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
}

.modal-close {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    padding: 4px;
    border-radius: var(--radius-sm);
    transition: all 0.2s;

    &:hover {
        color: var(--text-primary);
        background: var(--bg-app);
    }

    & i {
        width: 18px;
        height: 18px;
    }
}

.modal-body {
    padding: 1.25rem;
    overflow-y: auto;
    flex-grow: 1;
    color: var(--text-secondary);
    line-height: 1.6;
}

.modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 0 1.25rem 1.25rem;
}

/* ========================================
   20. Loading / Spinner
   ======================================== */
.spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--border-color);
    border-top-color: var(--color-accent);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

.view-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 80px 0;
    color: var(--text-muted);

    /* FASE 6: los hijos se dimensionan a fit-content (align-items:center);
       con max-width:100% el que sea más ancho que el contenedor (p. ej.
       .datatable-wrapper en /usuarios) se corta al ancho en vez de desbordar. */
    & > * { max-width: 100%; }

    & span {
        font-size: 0.88rem;
    }
}

.view-error {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 80px 0;
    text-align: center;
    color: var(--text-secondary);

    & h3 {
        color: var(--color-fail);
    }

    & p {
        font-size: 0.88rem;
        color: var(--text-muted);
    }
}

/* ========================================
   21. Page Not Found / Login (estilo auth CRM)
   ======================================== */
.page-not-found {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 80px 0;
    text-align: center;

    & h2 {
        font-size: 1.4rem;
        color: var(--text-primary);
    }

    & p {
        color: var(--text-muted);
    }

    & code {
        background: var(--bg-subtle);
        padding: 2px 8px;
        border-radius: 4px;
        font-family: var(--font-mono);
        font-size: 0.82rem;
        color: var(--color-accent);
    }
}

/* Login: fondo degradado navy + tarjeta blanca (como .auth-wrapper / .auth-card CRM) */
.login-view {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: linear-gradient(135deg, var(--bg-sidebar) 0%, var(--sidebar-hover) 100%);
    padding: 1rem;
}

.login-card {
    background: var(--bg-card);
    border-radius: 12px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
    padding: 2.5rem;
    width: 100%;
    max-width: 420px;
    text-align: center;

    & h1 {
        font-size: 1.5rem;
        margin-bottom: 8px;
        color: var(--text-primary);
    }

    & p {
        font-size: 0.88rem;
        color: var(--text-muted);
        margin-bottom: 2rem;
    }

    & .form-group {
        text-align: left;
    }

    /* El logo de la tarjeta de login debe ser oscuro (no navy) */
    & .logo-text {
        color: var(--text-primary);
    }

    & .logo-subtext {
        color: var(--text-muted);
    }
}

/* Cuando sidebar está oculto (login), main ocupa todo y sin topbar */
.sidebar.hidden + .main-content {
    margin-left: 0;
    width: 100%;

    & .app-header {
        display: none;
    }
}

/* ========================================
   22. Placeholder / Empty State
   ======================================== */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 60px 20px;
    text-align: center;
    color: var(--text-muted);

    & i {
        width: 48px;
        height: 48px;
        opacity: 0.4;
    }

    & h3 {
        font-size: 1rem;
        color: var(--text-primary);
    }

    & p {
        font-size: 0.85rem;
    }
}

/* ========================================
   23. Badges / Chips (estilo .badge CRM)
   ======================================== */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0.2rem 0.6rem;
    border-radius: var(--radius-full);
    font-size: 0.72rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    white-space: nowrap;
}

.badge-success { background: #dcfce7; color: #166534; }
.badge-fail    { background: #fee2e2; color: #991b1b; }
.badge-warning { background: #fef3c7; color: #92400e; }
.badge-accent  { background: #dbeafe; color: #1e40af; }
.badge-muted   { background: var(--bg-subtle); color: var(--text-secondary); }

/* ========================================
   24. Divider
   ======================================== */
.divider {
    border: none;
    border-top: 1px solid var(--border-color);
    margin: 24px 0;
}

/* ========================================
   25. Code Block
   ======================================== */
pre.code-block {
    background-color: var(--bg-subtle);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 14px 18px;
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--sidebar-hover);
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-all;
}

code.inline {
    background: var(--bg-subtle);
    border: 1px solid var(--border-color);
    padding: 1px 6px;
    border-radius: 4px;
    font-family: var(--font-mono);
    font-size: 0.82em;
    color: #1e40af;
}

/* ========================================
   26. Alert / Info Boxes (estilo .alert CRM)
   ======================================== */
.alert-box {
    display: flex;
    gap: 14px;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    font-size: 0.85rem;
    line-height: 1.5;
    margin-bottom: 1rem;

    & i {
        width: 18px;
        height: 18px;
        flex-shrink: 0;
        margin-top: 2px;
    }
}

.alert-info {
    background: #dbeafe;
    color: #1e40af;

    & i { color: #3b82f6; }
}

.alert-warning {
    background: #fef3c7;
    color: #92400e;

    & i { color: #f59e0b; }
}

.alert-error {
    background: #fee2e2;
    color: #991b1b;

    & i { color: #ef4444; }
}

.alert-success {
    background: #dcfce7;
    color: #166534;

    & i { color: #22c55e; }
}

/* ========================================
   27. DataTable (DataGrid component)
   ======================================== */
.datatable-wrapper {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--bg-card);
    /* FASE 6: como flex-item (p. ej. dentro de .view-loading) el min-width auto
       dejaba crecer la tabla a su min-content y desbordaba 375 px a la derecha. */
    min-width: 0;
}

/* D.1c (FASE 8): con < 560 px de ANCHO DE CONTENIDO (contenedor .main-content, FASE D.1)
   se ocultan las columnas 4..n de la tabla.
   Corte n+4 verificado contra las tablas reales:
   - incidencias (6 cols visibles): quedan Ref SP + Serie + Estado.
   - fleet dashboard (11 cols visibles): quedan Red + Tags + Serial.
   (3 columnas útiles: identificador + estado/conectividad + una más.)
   DESVIACIÓN DOCUMENTADA: el plan literal ponía container-type: inline-size en
   .datatable-wrapper, pero se verificó en Chromium 152 que rompe el layout en
   TODOS los anchos: el size-containment anula el tamaño intrínseco del wrapper y
   sus padres (#inc-list-table, #alerts-container — clase .view-loading, display:flex
   con fit-content) colapsan la tabla a 2 px (500 px) / ~348 px (1440 px).
   Con el contenedor .main-content el resultado es equivalente en todos los casos
   reales: las 5 DataTables de la app (alertas, en proceso, fleet, incidencias,
   usuarios) viven en el flujo de vistas, ninguna dentro de un modal (el caso
   "modal estrecho" del tip no existe en esta app).
   F18 (2026-09-15): la flota del dashboard SOBREESCRIBE el corte genérico bajo
   560 px: en vez de Red + Tags + Serial muestra Red · Serial · Estado · Máquina
   (oculta Tags —col. 2— y re-muestra Estado —col. 4— y Máquina —col. 9—), y la
   columna «Red» queda reducida a la bola (🟢/🔴/⚪) ocultando .con-dot-label. */
@container (max-width: 560px) {
    /* D.1c: corte genérico n+4 para TODAS las DataTables (3 primeras columnas). */
    .datatable-wrapper .datatable-table th:nth-child(n+4),
    .datatable-wrapper .datatable-table td:nth-child(n+4) {
        display: none;
    }

    /* F18-A1: columna «Red» = solo la bola (sin «Online/Offline/Sin Datos»).
       El texto sigue en el DOM (a11y/búsqueda/tests); solo se oculta. */
    .datatable-wrapper .datatable-table .badge .con-dot-label {
        display: none;
    }

    /* F18-A2: flota del dashboard = Red · Serial · Estado · Máquina.
       El id (#fleet-table) gana en especificidad al corte genérico n+4:
       display sin !important. Las demás DataTables conservan su corte. */
    #fleet-table .datatable-table th:nth-child(2),
    #fleet-table .datatable-table td:nth-child(2) {
        display: none;
    }
    #fleet-table .datatable-table th:nth-child(4),
    #fleet-table .datatable-table td:nth-child(4),
    #fleet-table .datatable-table th:nth-child(9),
    #fleet-table .datatable-table td:nth-child(9) {
        display: table-cell;
    }

    /* F18-A3: las 4 columnas móviles caben siempre (sin scroll horizontal).
       Los width vienen inline desde components/table.js → requieren !important.
       Reparto: Red 12% · Serial 36% · Estado 28% · Máquina 24%. */
    #fleet-table .datatable-table {
        table-layout: fixed;
        width: 100%;
    }
    #fleet-table .datatable-table th:nth-child(1),
    #fleet-table .datatable-table td:nth-child(1) { width: 12% !important; }
    #fleet-table .datatable-table th:nth-child(3),
    #fleet-table .datatable-table td:nth-child(3) { width: 36% !important; }
    #fleet-table .datatable-table th:nth-child(4),
    #fleet-table .datatable-table td:nth-child(4) { width: 28% !important; }
    #fleet-table .datatable-table th:nth-child(9),
    #fleet-table .datatable-table td:nth-child(9) { width: 24% !important; }
}

.datatable-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    background-color: var(--bg-card);
    border-bottom: 1px solid var(--border-color);
}

.datatable-search-box {
    display: flex;
    align-items: center;
    gap: 8px;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 6px 12px;
    flex: 1;
    max-width: 360px;
    transition: border-color 0.2s, box-shadow 0.2s;

    &:focus-within {
        border-color: var(--color-accent);
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
    }
}

.datatable-search-icon {
    width: 16px;
    height: 16px;
    color: var(--text-muted);
    flex-shrink: 0;
}

.datatable-search-input {
    background: none;
    border: none;
    outline: none;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 0.85rem;
    width: 100%;

    &::placeholder {
        color: var(--text-muted);
    }
}

.datatable-count {
    font-size: 0.82rem;
    color: var(--text-muted);
    font-weight: 500;
    white-space: nowrap;
}

.datatable-table-container {
    overflow-x: auto;
    max-height: 600px;
    overflow-y: auto;
}

.datatable-table {
    min-width: 100%;

    & thead tr th {
        position: relative;
    }

    /* B.2: movidas antes que las reglas .datatable-th/* — selectores sobre elementos distintos (td/tr vs th), sin props en común */
    & tbody tr.clickable {
        cursor: pointer;
    }

    & tbody tr.row-selected {
        background-color: rgba(59, 130, 246, 0.08) !important;
        border-left: 2px solid var(--color-accent);
    }

    /* B.3: & tbody tr:hover movida a la regla agrupada de la sección 10 */

    & td {
        word-break: break-word;
        overflow-wrap: anywhere;
    }
}

.datatable-th.sortable {
    cursor: pointer;
    user-select: none;

    &:hover {
        color: var(--text-primary);
        background: var(--bg-app);
    }
}

.datatable-th-content {
    display: flex;
    align-items: center;
    gap: 6px;
}

.datatable-sort-icon {
    width: 14px;
    height: 14px;
    opacity: 0.4;
    transition: opacity 0.2s;
}

.datatable-th.sortable:hover .datatable-sort-icon,
.datatable-th:has(.datatable-sort-icon[style*="opacity: 1"]) .datatable-sort-icon {
    opacity: 1;
}

.datatable-td {
    vertical-align: middle;

    &.text-right {
        text-align: right;
    }

    & .mono {
        font-family: var(--font-mono);
        font-size: 0.8rem;
    }
}

/* Chips legibles para el campo details de alertas (JSON de telemetría) */
.alert-detail {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 6px;
}

.alert-detail-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: var(--bg-subtle);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    padding: 1px 8px;
    font-size: 0.75rem;
    color: var(--text-secondary);
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;

    & .chip-k {
        color: var(--text-muted);
        font-weight: 600;
    }

    &.chip-danger {
        background: #fee2e2;
        border-color: #fecaca;
        color: #991b1b;
    }

    &.chip-danger .chip-k {
        color: #991b1b;
        opacity: 0.7;
    }
}

.alert-detail-raw {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--text-muted);
    word-break: break-all;
}

.text-null {
    color: var(--text-muted);
    font-style: italic;
    font-size: 0.82rem;
}

/* Empty state */
.datatable-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 48px 20px;
    text-align: center;
    color: var(--text-muted);
}

.datatable-empty-icon {
    width: 48px;
    height: 48px;
    opacity: 0.3;
}

.datatable-empty-text {
    font-size: 0.88rem;
}

/* Pagination */
.datatable-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 12px 16px;
    background-color: var(--bg-card);
    border-top: 1px solid var(--border-color);
}

.datatable-page-info {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-right: 12px;
}

.datatable-page-btn {
    min-width: 32px;
    padding: 4px 8px;
    font-size: 0.8rem;

    &.active {
        background-color: var(--color-accent);
        color: #fff;
        border-color: var(--color-accent);
    }
}

/* Loading state */
.datatable-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 60px 0;
    color: var(--text-muted);
}

/* ========================================
   28. Dashboard View
   ======================================== */
.dashboard-section {
    margin-bottom: 2rem;
}

.dashboard-section-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
    /* FASE 6: en 375 px título + acciones (segmented + botones) no cabían en
       una línea y cortaban la derecha → las acciones bajan de línea. */
    flex-wrap: wrap;
    row-gap: 6px;

    & i {
        width: 20px;
        height: 20px;
        color: var(--color-accent);
    }

    & .badge {
        margin-left: auto;
    }
}

/* Server info bar */
.server-info-bar {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 12px 20px;
    background: var(--bg-card);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    margin-bottom: 24px;
    font-size: 0.82rem;
}

.server-info-item {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);

    & i {
        width: 14px;
        height: 14px;
        color: var(--text-muted);
    }

    & strong {
        color: var(--text-primary);
        font-family: var(--font-mono);
        font-size: 0.78rem;
    }
}

/* Omnibox search bar */
.omnibox-bar {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 12px;
    align-items: end;
    margin-bottom: 16px;

    & .form-group {
        margin-bottom: 0;
    }

    & .form-input,
    & .form-select {
        font-size: 0.88rem;
    }
}

/* Tags selector */
.tags-selector {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 10px;
    min-height: 42px;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    cursor: default;
    transition: border-color 0.2s;

    &:focus-within,
    &:hover {
        border-color: var(--color-accent);
    }
}

.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 500;
    /* Colores reales de la tag (F13-1): el catálogo pinta las vars desde el chip */
    color: var(--chip-tx, var(--text-secondary));
    background-color: var(--chip-bg, var(--bg-card-hover));
    border: 1px solid var(--chip-bd, var(--border-color));
    cursor: pointer;
    transition: all 0.15s ease;
    user-select: none;
    white-space: nowrap;

    &:hover {
        border-color: var(--chip-bd, var(--color-accent));
        color: var(--chip-tx, var(--text-primary));
    }

    &.active {
        color: var(--bg-card);
        background-color: var(--chip-tx, var(--color-accent));
        border-color: var(--chip-tx, var(--color-accent));
    }

    & .chip-count {
        font-weight: 400;
        opacity: 0.7;
        font-size: 0.72rem;
    }
}

.no-tags-msg {
    font-size: 0.82rem;
    color: var(--text-muted);
    padding: 6px 0;
}

/* Results summary */
.results-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    font-size: 0.85rem;
    color: var(--text-secondary);

    & strong {
        color: var(--text-primary);
    }
}

/* ========================================
   29. Vista Detalle de Batería
   ======================================== */

/* Layout principal: sidebar interno + body */
.detalle-layout {
    display: flex;
    gap: 0;
    min-height: calc(100vh - var(--header-height, 64px));
}

/* Body principal de detalle (sin sidebar interno desde F14-4) */
.detalle-main {
    flex: 1;
    padding: 24px 32px;
    /* FASE 6: el único scroller es .content-scroll — .detalle-main NO tiene
       overflow propio (con él, la barra sticky del nº de serie quedaba
       atrapada en un scroller muerto y se iba con el scroll). */
}

.detalle-title {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 0 0 16px 0;
    color: var(--text-primary);
}

/* LOTE2 F1: barra sticky fina del nº de serie. El scrollport real es
   .content-scroll (FASE 6); la barra se queda arriba al scrollear con
   fondo opaco por token (patrón thead sticky). ::before tapa la franja
   de padding de .content-scroll (respeta sus queries: 32 / 24 ≤1200 /
   16 ≤768) para que el contenido no se asome por encima al quedar stuck.
   Solo se pinta con pack seleccionado (atributo [hidden] sin él). */
.detalle-serial-bar {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 12px;
    padding: 6px 12px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-card);
    font-size: 0.85rem;

    &::before {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        top: -32px;
        height: 32px;
        background: var(--bg-card);
    }
}

@container (max-width: 1200px) {
    .detalle-serial-bar::before { top: -24px; height: 24px; }
}

.detalle-serial-label {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.detalle-serial-value {
    font-weight: 600;
    color: var(--text-primary);
}

.detalle-serial-modelo,
.detalle-serial-maquina {
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    &::before {
        content: "·";
        margin-right: 10px;
        color: var(--text-muted);
    }
}

/* Móvil (≤768): solo serie + modelo (se oculta el nº de máquina) y la
   franja ::before se ajusta al padding móvil de .content-scroll */
@media (max-width: 768px) {
    .detalle-serial-bar::before { top: -16px; height: 16px; }
    .detalle-serial-maquina { display: none; }
}

/* Tags section */
.detalle-tags-section {
    margin-bottom: 20px;
    padding: 12px 16px;
    background: var(--bg-card);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

.detalle-tags-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

/* Metrics row */
.detalle-metrics-section {
    margin-bottom: 24px;
}

.metrics-row {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 12px;
}

/* Info grid (ficha técnica) */
.detalle-info-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-bottom: 24px;
}

.detalle-info-card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.info-card-header {
    padding: 8px 12px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    background: var(--bg-app);
    border-bottom: 1px solid var(--border-color);
}

.info-card-body {
    padding: 12px;
}

.info-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 3px 0;
    font-size: 0.88rem;
}

.info-label {
    color: var(--text-muted);
    font-size: 0.82rem;
    min-width: 80px;
}

/* Incidences header */
.detalle-incidences-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;

    & h3 {
        font-size: 1.1rem;
        font-weight: 600;
        color: var(--text-primary);
    }
}

/* Divider */
.detalle-divider {
    height: 1px;
    background: var(--border-color);
    margin: 20px 0;
}

/* Action card */
.action-card {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 12px;
    margin-bottom: 8px;
    background: var(--bg-card);
}

/* Section subtitle */
.section-subtitle {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 12px;
}

/* Tabs bar */
.tabs-bar {
    display: flex;
    gap: 0;
    border-bottom: 2px solid var(--border-color);
    margin-bottom: 20px;
}

.tab-panel.hidden {
    display: none;
}

/* Checkbox group */
.checkbox-group {
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 8px;
    background: var(--bg-card);
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
    cursor: pointer;
    font-size: 0.88rem;
    color: var(--text-secondary);
}

/* Skeleton loading */
.skeleton {
    background: #fff;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 16px;
    opacity: 0.5;
}

.skeleton-text {
    color: var(--text-muted);
    font-size: 0.82rem;
}

/* Spin animation for icons */
.spin-icon {
    animation: spin 1s linear infinite;
}

/* ========================================
   30. Responsive
   ======================================== */
/* D.1 (FASE 8): el padding del contenido pasa a responder al ANCHO DE
   CONTENIDO real (.main-content es query container), no a la ventana.
   Consecuencia documentada: a 1440px con sidebar expandido (260px),
   .main-content=1180<1200 → el padding pasa de 32px a 24px. */
@container (max-width: 1200px) {
    .content-scroll {
        padding: 24px;
    }
}

@media (max-width: 1200px) {
    .omnibox-bar {
        grid-template-columns: 1fr;
    }

    .metrics-row {
        grid-template-columns: repeat(3, 1fr);
    }

    .detalle-info-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {
    /* D.1a (FASE 8): eliminada la override .metric-grid 1fr — el auto-fit
       minmax(200px,1fr) ya es responsive al ancho real del grid. */
    .app-header {
        height: auto;
        padding: 12px 16px;
    }

    .content-scroll {
        padding: 16px;
    }

    .modal {
        width: 95%;
        max-height: 90vh;
        max-height: 90dvh;
    }

    .omnibox-bar {
        grid-template-columns: 1fr;
    }

    .server-info-bar {
        flex-wrap: wrap;
        gap: 12px;
    }

    .datatable-toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    .datatable-search-box {
        max-width: none;
    }

    .datatable-pagination {
        flex-wrap: wrap;
    }

    .detalle-layout {
        flex-direction: column;
        /* FASE 6: en móvil el min-height calc(100vh − 64px) está descalibrado
           (header auto + 100vh iOS) y podía crear un scroller anidado muerto en
           .detalle-main. #content-scroll sigue siendo el único scroller. */
        min-height: 0;
    }

    .detalle-main {
        padding: 16px;
    }

    .metrics-row {
        grid-template-columns: repeat(2, 1fr);
    }

    .detalle-info-grid {
        grid-template-columns: 1fr;
    }

    .tabs-bar {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* ========================================
   31. Sidebar principal colapsado (solo escritorio)
   ======================================== */

/* Estado colapsado */
.sidebar-collapsed {
    width: var(--sidebar-shrunk) !important;
    min-width: var(--sidebar-shrunk) !important;

    /* En colapsado: ocultar textos del logo, group-labels, footer */
    & .logo-text,
    & .logo-subtext,
    & .nav-btn span,
    & .nav-group-label,
    & .sidebar-footer {
        display: none;
    }

    /* Logo centrado en colapsado */
    & .logo-container {
        justify-content: center;
        padding: 0;
    }

    /* Nav container en colapsado */
    & .sidebar-nav {
        align-items: center;
        padding-left: 0;
        padding-right: 0;
    }

    /* En colapsado: centrar iconos y asegurar visibilidad */
    & .nav-btn {
        display: flex !important;
        align-items: center !important;
        justify-content: center !important;
        padding: 0.7rem 0;
        position: relative;
    }

    & .nav-btn i,
    & .nav-btn svg {
        display: block !important;
        width: 18px !important;
        height: 18px !important;
        flex-shrink: 0 !important;
    }

    /* Iconos del botón de colapso */
    /* Tooltip al hover en sidebar colapsada */
    & .nav-btn:hover::after {
        content: attr(title);
        position: absolute;
        left: 72px;
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        padding: 4px 10px;
        border-radius: var(--radius-sm);
        font-size: 0.82rem;
        white-space: nowrap;
        z-index: 100;
        box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
        color: var(--text-primary);
    }
}

/* ========================================
   32. Chart (Plotly wrapper)
   ======================================== */

.chart-container {
    width: 100%;
    margin: 12px 0;
}

.chart-error {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 450px;
    color: var(--color-fail);
    text-align: center;
    padding: 24px;
}

.chart-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 450px;
    color: var(--text-muted);
}

/* Plotly overrides (tema claro) */
.js-plotly-plot .plotly .modebar {
    top: 8px !important;
    right: 8px !important;
}

.js-plotly-plot .plotly .modebar-btn {
    background-color: #fff !important;
    border: 1px solid var(--border-color) !important;
}

.js-plotly-plot .plotly .modebar-btn svg path {
    fill: var(--text-secondary) !important;
}

.js-plotly-plot .plotly .modebar-btn:hover svg path {
    fill: var(--text-primary) !important;
}

/* Selectores de métricas para gráficos */
.metric-selectors {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-bottom: 16px;
    /* F14: el panel del chip-select de métricas es absolute y crece por debajo —
       ningún ancestro debe recortarlo */
    overflow: visible;
}

.metric-selector-group {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 12px;
    overflow: visible;

    & h4 {
        margin: 0 0 8px 0;
        font-size: 0.85rem;
        color: var(--text-secondary);
        font-weight: 500;
    }

    & h4 span {
        font-size: 0.75rem;
        opacity: 0.6;
        font-weight: 400;
    }
}

.metric-multiselect {
    width: 100%;
    /* F14: este contenedor ya no es un <select> nativo (F13-3 lo sustituyó por
       chip-select). Se NEUTRALIZA: sin cota de altura (120px recortaba el
       desplegable a 1-2 opciones) y sin overflow — es el <parent> que el
       grupo padre expande al abrir la lista de métricas. */
    min-height: 0;
    max-height: none;
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0;
    overflow: visible;
}

/* ========================================
   33. Log Viewer (tema claro)
   ======================================== */

.log-viewer {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--bg-card);
}

.log-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 16px;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-color);
    gap: 12px;
    flex-wrap: wrap;
}

.log-toolbar-left {
    flex-shrink: 0;
}

.log-toolbar-right {
    display: flex;
    gap: 8px;
    flex: 1;
    min-width: 200px;
}

.log-file-info {
    font-size: 0.78rem;
    color: var(--text-muted);
    font-family: var(--font-mono);
}

.log-filter-input,
.log-search-input {
    flex: 1;
    min-width: 120px;
    padding: 6px 10px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-size: 0.82rem;
    font-family: var(--font-mono);
}

.log-filter-input:focus,
.log-search-input:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}

/* Controles de navegación (flotantes) */
.log-nav-controls {
    position: absolute;
    top: 80px;
    right: 20px;
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 4px 10px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);
    z-index: 100;
    font-size: 0.82rem;
    color: var(--text-secondary);
}

.log-nav-btn {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    padding: 2px 8px;
    border-radius: 4px;
    cursor: pointer;
    font-weight: bold;
    font-size: 0.75rem;
    line-height: 1.4;

    &:hover {
        background: var(--color-accent);
        color: #fff;
        border-color: var(--color-accent);
    }
}

.log-match-counter {
    min-width: 50px;
    text-align: center;
    font-family: var(--font-mono);
    font-size: 0.75rem;
}

/* Contenido del log */
.log-content {
    height: 500px;
    overflow-y: auto;
    padding: 8px 12px;
    font-family: var(--font-mono);
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--sidebar-hover);
    background: var(--bg-card-hover);
    position: relative;
}

.log-line {
    min-height: 1.5em;
    padding: 1px 4px;
    border-radius: 2px;
    white-space: pre-wrap;
    word-break: break-all;

    &:hover {
        background: rgba(0, 0, 0, 0.04);
    }
}

.log-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--text-muted);
    text-align: center;
    font-style: italic;
}

/* Resaltado de búsqueda */
.search-match {
    background: rgba(245, 158, 11, 0.25);
    color: #92400e;
    padding: 1px 2px;
    border-radius: 2px;
    border: 1px solid rgba(245, 158, 11, 0.4);
}

.search-match-active {
    background: rgba(59, 130, 246, 0.25);
    color: #1e3a8a;
    border: 1px solid rgba(59, 130, 246, 0.5);
}

/* ========================================
   34. Accesibilidad — prefers-reduced-motion
   ======================================== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ========================================
   35. Barra de lectura scroll-driven (FASE 8, D.3)
   ======================================== */
/* Barra de lectura scroll-driven (Fase D.3): Chrome/Edge 115+; el resto no ve nada.
   El timeline es NOMBRE (--app-scroll) porque el scroll lo hace .content-scroll
   (no el root del documento). La barra vive DENTRO de .content-scroll como primer
   hijo (position: sticky) porque una named timeline solo está en scope para el
   elemento que la define y sus descendientes: en el header (hermano del scroller)
   la referencia no resuelve, la animación degenera a reloj de tiempo y la barra
   queda siempre en scaleX(1) — verificado en Chromium 152. */
@supports (animation-timeline: scroll()) {
    .content-scroll { scroll-timeline: --app-scroll block; }
    .reading-progress {
        position: sticky; top: 0; z-index: 20;
        width: 100%; height: 2px; margin-bottom: -2px;
        background: var(--color-accent);
        transform: scaleX(0); transform-origin: left center;
        animation: reading-grow linear both;
        animation-timeline: --app-scroll;
    }
    @keyframes reading-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}
@media (prefers-reduced-motion: reduce) {
    .reading-progress { display: none; }
}

/* ========================================
   36. Llamada en curso (pill + drawer) — F2
   ======================================== */
/* Componente global de la llamada en curso (plan §2): píldora flotante abajo-
derecha + drawer lateral (370 px). Port del mockup opcion2 v2 traducido a tokens.
   z-index 8500/8400: por debajo de modal (9000) y toasts (10000).
   Animaciones con animation/transition → el bloque global de reduced-motion
   (§34) las cubre. */

.call-start-btn {
    & #call-start-label { font-variant-numeric: tabular-nums; }
}

.call-pill {
    position: fixed;
    right: 22px;
    bottom: 22px;
    z-index: 8500;
    display: flex;
    align-items: center;
    gap: 10px;
    background-color: var(--text-primary);
    color: var(--call-pill-fg);
    border-radius: var(--radius-full);
    padding: 11px 18px;
    font-size: 0.85rem;
    font-weight: 600;
    box-shadow: var(--shadow-lg);
    cursor: pointer;
    user-select: none;
    opacity: 0;
    pointer-events: none;
    transition: right 0.25s ease, opacity 0.2s ease;

    &.is-open {
        opacity: 1;
        pointer-events: auto;
        animation: call-pulse 1.3s infinite;
    }

    & i.call-pill-ic {
        width: 16px;
        height: 16px;
        color: var(--color-fail);
    }

    & .call-pill-time { color: var(--color-success); }

    & .call-pill-go { opacity: 0.7; }

    /* Estado «inactiva» (Q3): ámbar, sin pulso, cronómetro congelado */
    &.is-inactiva {
        animation: none;
        box-shadow: var(--shadow-lg),
            0 0 0 2px color-mix(in oklch, var(--color-warning) 55%, transparent);

        & i.call-pill-ic { color: var(--color-warning); }
        & .call-pill-time { color: var(--color-warning); }
    }

    /* Micro-aviso 1ª vez (Q2): burbuja sobre la píldora, 4 s */
    & .call-hint {
        position: absolute;
        bottom: calc(100% + 10px);
        right: 0;
        width: max-content;
        max-width: 260px;
        background-color: var(--bg-card);
        color: var(--text-primary);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-lg);
        padding: 8px 12px;
        font-size: 0.78rem;
        font-weight: 500;
        line-height: 1.4;
        opacity: 0;
        pointer-events: none;

        &.is-visible { animation: call-hint-in 0.25s ease forwards; }
    }
}

/* Drawer abierto → la píldora se desplaza a su izquierda (370 + 22 px) */
body:has(.call-drawer.is-open) .call-pill { right: 392px; }
body:has(.call-drawer.is-open) .toast-container--pill { right: 392px; }

.call-drawer {
    position: fixed;
    top: 0;
    right: 0;
    height: 100%;
    width: 370px;
    max-width: 92vw;
    z-index: 8400;
    display: flex;
    flex-direction: column;
    background-color: var(--bg-card);
    border-left: 1px solid var(--border-color);
    box-shadow: var(--shadow-lg);
    transform: translateX(105%);
    transition: transform 0.3s cubic-bezier(0.22, 0.8, 0.36, 1);

    &.is-open { transform: translateX(0); }
}

.call-timer { font-variant-numeric: tabular-nums; }

.call-timer-lg {
    font-size: 1.9rem;
    font-weight: 800;
    letter-spacing: 1px;
    margin-top: 6px;
}

.call-drawer-hd {
    padding: 16px 18px 12px;
    border-bottom: 1px solid var(--border-color);

    & .call-drawer-hdrow {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
    }

    & .call-drawer-hdright {
        display: flex;
        align-items: center;
        gap: 8px;
    }

    & .call-drawer-title { font-size: 1rem; }

    & .call-drawer-badge {
        text-transform: uppercase;
        letter-spacing: 0.03em;
        font-weight: 700;
    }

    & .call-drawer-sub {
        font-size: 0.8rem;
        color: var(--text-muted);
        margin-top: 4px;
    }
}

.call-drawer-bd {
    flex: 1;
    overflow-y: auto;
    padding: 14px 18px;

    & .form-group { margin-bottom: 0.9rem; }
}

.call-drawer-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 8px;
    margin-bottom: 4px;

    & .call-span-2 { grid-column: 1 / -1; }
}

.call-drawer-ft {
    padding: 12px 18px 16px;
    border-top: 1px solid var(--border-color);
}

.call-finish { width: 100%; }

.call-jrn-head {
    font-weight: 700;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
    margin: 14px 0 8px;
}

.call-jrn {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 7px;

    & li {
        display: flex;
        align-items: flex-start;
        gap: 8px;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
        padding: 8px 10px;
        font-size: 0.8rem;
        line-height: 1.4;
        background-color: var(--bg-card);
    }

    /* Ítems de contexto (vistas): atenuados */
    & li.ctx {
        opacity: 0.6;
        background-color: var(--bg-card-hover);
    }

    & li.call-jrn-empty { cursor: default; }

    & .call-jrn-ic {
        flex: 0 0 auto;
        margin-top: 1px;
        width: 15px;
        height: 15px;
        color: var(--color-accent);
    }

    & li.ctx .call-jrn-ic { color: var(--text-muted); }

    & .call-jrn-tx { flex: 1; }

    & .call-jrn-tm {
        font-family: var(--font-mono);
        font-size: 0.7rem;
        font-variant-numeric: tabular-nums;
        color: var(--text-muted);
    }

    & .call-jrn-chip { flex: 0 0 auto; }
}

.call-resumen-req { color: var(--color-fail); }

/* ------- Cierre: modal de checklist (F3, estrategia A) y modal de éxito ------- */
.call-close {
    /* Fila de datos (duración / persona / tipo·dirección) */
    & .call-close-data {
        display: flex;
        align-items: flex-end;
        gap: 18px;
        flex-wrap: wrap;
        padding: 10px 14px;
        margin-bottom: 1rem;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
        background-color: var(--bg-card-hover);
    }

    & .call-close-k {
        display: block;
        margin-bottom: 2px;
        font-size: 0.68rem;
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--text-muted);
    }

    & .call-close-v { font-weight: 600; font-size: 0.9rem; }

    /* Cabecera del checklist: label + «Todo / nada» */
    & .call-close-clhead {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 8px;

        & .form-label { margin-bottom: 0; }
    }

    & .call-close-tornada {
        white-space: nowrap;
        font-size: 0.75rem;
        color: var(--text-muted);

        & .cl-all { color: var(--color-accent); font-weight: 600; cursor: pointer; }
        & .cl-sep { opacity: 0.6; }
    }

    /* Lista de acciones (pre-marcada, scrollable si es larga) */
    & .cl-checks {
        display: flex;
        flex-direction: column;
        gap: 5px;
        max-height: 260px;
        margin: 6px 0 0;
        padding: 0;
        overflow-y: auto;
        list-style: none;
    }

    & .cl-row {
        display: flex;
        align-items: flex-start;
        gap: 8px;
        padding: 6px 8px;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-sm);
        font-size: 0.82rem;
        line-height: 1.4;
        cursor: pointer;

        /* Desmarcado → atenuado (estado sin class extra) */
        &:has(.cl-chk:not(:checked)) { opacity: 0.55; }
    }

    & .cl-chk { margin-top: 3px; }

    & .cl-ic {
        flex: 0 0 auto;
        width: 15px;
        height: 15px;
        color: var(--color-accent);
    }

    & .cl-tm {
        font-family: var(--font-mono);
        font-size: 0.7rem;
        font-variant-numeric: tabular-nums;
        color: var(--text-muted);
    }

    /* Clasificación Q7: el contenedor se muestra/oculta con [hidden] en vivo */
    & .call-clasi select { max-width: 220px; }
}

/* Contexto (vistas) — no vinculable, gris atenuado (checklist y éxito) */
.cl-ctx {
    margin: 8px 0 0;
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* Modal de éxito (sustituye al checklist en el mismo overlay) */
.call-success {
    & .call-success-hd {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
        padding: 6px 0 14px;
        text-align: center;

        & > i {
            width: 44px;
            height: 44px;
            color: var(--color-success);
        }
    }

    & .call-success-title { font-size: 1.05rem; font-weight: 800; }

    & .call-success-resumen { font-size: 0.85rem; color: var(--text-secondary); }

    & .cl-vinc {
        display: flex;
        flex-direction: column;
        gap: 5px;
        margin: 0;
        padding: 0;
        list-style: none;

        & li {
            display: flex;
            align-items: flex-start;
            gap: 8px;
            font-size: 0.82rem;
            line-height: 1.4;
        }

        & li i {
            flex: 0 0 auto;
            width: 14px;
            height: 14px;
            margin-top: 2px;
            color: var(--color-accent);
        }

        & .cl-ctx { margin: 0; }
    }

    & .call-success-link {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        font-size: 0.9rem;
        font-weight: 700;

        & i { width: 15px; height: 15px; color: var(--color-accent); }
    }
}

/* Pulso de la píldora (en curso): anillo rojo que se difumina (mockup mkpulse) */
@keyframes call-pulse {
    0% {
        box-shadow: var(--shadow-lg),
            0 0 0 0 color-mix(in oklch, var(--color-fail) 55%, transparent);
    }
    70% {
        box-shadow: var(--shadow-lg),
            0 0 0 9px color-mix(in oklch, var(--color-fail) 0%, transparent);
    }
    100% {
        box-shadow: var(--shadow-lg),
            0 0 0 0 transparent;
    }
}

/* Entrada de la hint de píldora (1ª vez, Q2) */
@keyframes call-hint-in {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: none; }
}

/* Móvil (<768 px, único breakpoint genuinamente de dispositivo): el drawer
   pasa a hoja completa (slide-up) y la píldora no se desplaza con el drawer
   abierto (queda tras la hoja). */
@media (max-width: 768px) {
    .call-pill { right: 16px; bottom: 16px; }
    .toast-container--pill { right: 16px; }

    /* FASE 6: la píldora (fixed, ~46 px de alto a 16 px del borde) tapaba el final
       del contenido (paginaciones, botón RESET VARDIN, …) con llamada en curso.
       Se aparta el fondo scrolleable para que nada quede bajo ella:
       alto píldora + 16 px bottom + holgura, más safe-area de iOS. */
    body:has(#call-pill.is-open) .content-scroll {
        padding-bottom: calc(72px + env(safe-area-inset-bottom));
    }

    .call-drawer {
        top: 0;
        left: 0;
        right: 0;
        width: 100%;
        max-width: none;
        border-left: none;
        transform: translateY(105%);

        &.is-open { transform: translateY(0); }
    }

    body:has(.call-drawer.is-open) .call-pill { right: 16px; }
    body:has(.call-drawer.is-open) .toast-container--pill { right: 16px; }
}

/* ========================================
   37. Reporte matutino (F4, PLAN_LLAMADA_EN_CURSO §2.6)
   ======================================== */
/* Vista de solo lectura: cabecera + fecha, 3 contadores (.metrics-row reutilizado
   con un grid de 3 columnas — el reglamento §5 prohíbe revivir .metric-grid) y dos
   bloques de tabla (.card + .table-wrapper/.data-table existentes). Sin colores
   nuevos: solo tokens. */

/* FASE 6: la tabla de tiempos (6 columnas) desbordaba 375 px sin scroller →
   las columnas derechas (Incidencias/Reparto) eran inaccesibles en móvil. */
#rep-tiempos-tabla { overflow-x: auto; }

.rep-view {
    & .rep-head {
        display: flex;
        align-items: flex-end;
        justify-content: space-between;
        gap: 12px;
        flex-wrap: wrap;
        margin-bottom: 20px;

        & h2 {
            margin: 0 0 4px;
            font-size: 1.35rem;
            font-weight: 700;
            color: var(--text-primary);
        }

        & .rep-fecha {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            font-size: 0.85rem;
            font-weight: 600;
            color: var(--text-secondary);

            & i { width: 15px; height: 15px; color: var(--color-accent); }
        }
    }
}

/* 3 contadores (el .metrics-row default es de 5 columnas). El @media de 768px
   (sección 30) baja a 2 columnas con especificidad inferior: se replica aquí
   para que la variante gane también en móvil. */
.metrics-row.rep-metrics {
    grid-template-columns: repeat(3, 1fr);
    margin-bottom: 20px;
}

@media (max-width: 768px) {
    .metrics-row.rep-metrics { grid-template-columns: repeat(2, 1fr); }
}

/* ========================================
   38. Sugerencias de vinculación al cierre (FA-2, PLAN_LLAMADA_V2 §3.2)
   ======================================== */
/* Nueva sección del modal de cierre, entre «Datos» y «Acciones»: una fila
   por batería referida (⚡) con sus INCs abiertas como checkboxes —o, si no
   tiene INC abierta, «Vincular batería» + botón «＋ Crear incidencia» (.btn
   .btn-sm canónicas)— y una fila por INC referida y abierta (📋). Solo
   tokens y layout; el desmarcado atenúa con :has() (patrón .cl-row). */
.sug-wrap {
    margin-bottom: 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background-color: var(--bg-card-hover);

    & .sug-title {
        padding: 10px 14px 0;
        font-size: 0.68rem;
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--text-muted);
    }

    & .sug-row {
        padding: 10px 14px 12px;
        font-size: 0.85rem;

        & + .sug-row { border-top: 1px solid var(--border-color); }
    }

    & .sug-hd {
        display: flex;
        align-items: center;
        gap: 8px;
        font-weight: 600;
    }

    & .sug-ic { flex: 0 0 auto; font-size: 0.95rem; line-height: 1; }

    & .sug-mut { font-weight: 400; font-size: 0.78rem; color: var(--text-muted); }
    & .sug-adv { font-weight: 600; font-size: 0.74rem; color: var(--color-warning); }

    & .sug-sub {
        display: flex;
        flex-direction: column;
        gap: 4px;
        margin: 6px 0 0;
        padding: 0 0 0 24px;
        list-style: none;
    }

    & .sug-line {
        display: flex;
        align-items: center;
        gap: 8px;
        font-weight: 400;
        cursor: pointer;

        /* Desmarcado → atenuado (estado derivado sin clase extra) */
        &:has(input:not(:checked)) { opacity: 0.55; }
    }

    & .sug-estado { font-size: 0.78rem; color: var(--text-muted); }

    & .sug-create {
        margin: 6px 0 0 24px;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;

        /* FASE 4: aviso inline — el pack ya tiene INCs abiertas (segunda INC). */
        & .sug-adv-multi { font-weight: 400; font-size: 0.74rem; color: var(--text-muted); }
    }
}

/* ---------- Combobox de persona del drawer (FA-3, D6 — PLAN_LLAMADA_V2
   §3.3; mockup aprobado persona_typeahead.html). El <select> #call-d-persona
   pasa a ser input text (role=combobox) + dropdown absolute: quick-picks
   (recientes, fila horizontal) + lista filtrada top 12. Estado «con
   selección» (avatar + ✕) = clase .cp-has-sel toggleada en JS (el valor del
   input no es detectable fiable con :has()). Avatar = color de empresa vía
   --cp-av-color (literal dinámico por dato, reglamento §4.2); sin empresa →
   var(--text-secondary). En <768px el drawer ocupa el ancho (sección 36) y
   el dropdown hereda (left:0; right:0). */
.cp-field {
    position: relative;

    & .cp-input {
        display: flex;
        align-items: center;
        gap: 8px;
        background-color: var(--bg-input);
        border: 1px solid var(--border-color);
        border-radius: 6px;
        padding: 0.5rem 0.6rem;
        transition: border-color 0.2s, box-shadow 0.2s;

        &:focus-within {
            border-color: var(--color-accent);
            box-shadow: 0 0 0 3px color-mix(in oklch, var(--color-accent) 12%, transparent);
        }
    }

    & .cp-input-el {
        flex: 1;
        min-width: 0;
        border: none;
        outline: none;
        background: transparent;
        color: var(--text-primary);
        font-family: var(--font-sans);
        font-size: 0.9rem;

        &::placeholder { color: var(--text-muted); }

        /* FASE 21: burbuja sellada — la persona seleccionada se pinta como
           pill (color suave de empresa vía --cp-av-color, como .cp-qp-chip).
           El clic entra en modo edición de nombre (call-session.js). */
        &.is-bubble {
            cursor: pointer;
            border-radius: 999px;
            transition: background-color 0.15s, box-shadow 0.15s;

            &:hover {
                background-color: color-mix(in oklch, var(--cp-av-color, var(--text-secondary)) 14%, transparent);
                box-shadow: 0 0 0 1px color-mix(in oklch, var(--cp-av-color, var(--text-secondary)) 35%, transparent);
            }
        }
    }

    & .cp-avatar {
        flex: 0 0 auto;
        width: 26px;
        height: 26px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 0.62rem;
        font-weight: 800;
        color: var(--bg-card);
        background-color: var(--text-secondary);
        background-color: var(--cp-av-color, var(--text-secondary));
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    & .cp-clear {
        flex: 0 0 auto;
        display: none;
        align-items: center;
        justify-content: center;
        width: 22px;
        height: 22px;
        border: none;
        border-radius: 50%;
        background-color: var(--bg-card-hover);
        color: var(--text-muted);
        font-size: 0.7rem;
        line-height: 1;
        cursor: pointer;

        &:hover {
            background-color: var(--border-color);
            color: var(--text-secondary);
        }
    }

    /* Con selección: avatar del input + botón ✕ (clase toggleada en JS) */
    &.cp-has-sel .cp-clear { display: flex; }
    &.cp-has-sel .cp-input > .cp-avatar { display: flex; }
    & .cp-input > .cp-avatar { display: none; }

    & .cp-panel {
        position: absolute;
        top: calc(100% + 6px);
        left: 0;
        right: 0;
        z-index: 60;
        background-color: var(--bg-card);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md, 8px);
        box-shadow: 0 14px 34px color-mix(in oklch, var(--text-primary) 16%, transparent);
        overflow: hidden;
    }

    /* Quick-picks: fila horizontal de recientes (scroll-x) */
    & .cp-qp {
        padding: 8px 10px 9px;
        border-bottom: 1px solid var(--bg-card-hover);
    }

    & .cp-qp-lbl {
        margin-bottom: 6px;
        font-size: 0.65rem;
        font-weight: 700;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--text-muted);
    }

    & .cp-qp-row {
        display: flex;
        gap: 8px;
        overflow-x: auto;
        padding-bottom: 2px;
    }

    & .cp-qp-chip {
        flex: 0 0 auto;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 4px;
        width: 52px;
        padding: 0;
        border: none;
        background: transparent;
        cursor: pointer;
        font-family: var(--font-sans);

        & .cp-avatar {
            width: 38px;
            height: 38px;
            font-size: 0.8rem;
            border: 2px solid transparent;
            transition: border-color 0.12s, transform 0.12s;
        }

        &:hover .cp-avatar {
            border-color: var(--color-accent);
            transform: translateY(-1px);
        }
    }

    & .cp-qp-nm {
        max-width: 52px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 0.62rem;
        color: var(--text-secondary);
    }

    /* Lista de resultados (top 12) */
    & .cp-res {
        max-height: 264px;
        overflow-y: auto;
        padding: 4px;
    }

    & .cp-row {
        display: flex;
        align-items: center;
        gap: 9px;
        padding: 7px 8px;
        border-radius: 8px;
        cursor: pointer;
        font-size: 0.85rem;
        color: var(--text-primary);

        & + .cp-row { margin-top: 1px; }

        &:hover, &.active {
            background-color: color-mix(in oklch, var(--color-accent) 7%, transparent);
        }

        &.active {
            outline: 2px solid color-mix(in oklch, var(--color-accent) 35%, transparent);
            outline-offset: -2px;
        }

        & .cp-tx { flex: 1; min-width: 0; }

        & .cp-nm { font-weight: 600; }

        & .cp-alias { color: var(--text-muted); font-weight: 400; }

        & .cp-sub {
            display: block;
            margin-top: 1px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-size: 0.75rem;
            color: var(--text-muted);
            font-variant-numeric: tabular-nums;
        }
    }

    & .cp-row.empty {
        cursor: default;
        padding: 14px;
        justify-content: center;
        color: var(--text-muted);
        font-size: 0.8rem;

        &:hover { background-color: transparent; }

        & b { color: var(--text-secondary); }
    }
}

/* --- Mejoras ficha: pill de alcance + alta de contacto al vuelo --- */
/* Pill sobre el campo: «🔗 Alcance: REYBESA + APROLÍS — Mostrar todos». */
.cp-scope {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    padding: 4px 10px;
    border: 1px solid color-mix(in oklch, var(--color-accent) 30%, transparent);
    border-radius: var(--radius-full);
    background-color: color-mix(in oklch, var(--color-accent) 6%, transparent);
    font-size: 0.72rem;
    color: var(--text-secondary);
    cursor: pointer;
    user-select: none;
    width: fit-content;
    max-width: 100%;
}
.cp-scope b { font-weight: 700; }
.cp-scope .cp-scope-toggle {
    color: var(--color-accent);
    font-weight: 600;
    white-space: nowrap;
}
.cp-scope.is-open {
    background-color: var(--bg-card-hover);
    border-color: var(--border-color);
    color: var(--text-muted);
}

/* Fila «＋ Crear nuevo contacto» al pie del panel. */
.cp-create-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    margin-top: 4px;
    padding: 8px;
    border: none;
    border-top: 1px solid var(--border-color);
    background: none;
    color: var(--color-accent);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}
.cp-create-row:hover { background-color: color-mix(in oklch, var(--color-accent) 6%, transparent); }

/* FASE 21: error inline bajo la fila «＋ Nuevo contacto» (antes vivía en el
   mini-form #call-d-persona-newbox, eliminado). */
.cp-create-err {
    display: block;
    margin-top: 2px;
    padding: 0 8px 4px;
    font-size: 0.72rem;
    color: var(--color-fail);
}

/* Sección «Alta rápida» del drawer de llamada. */
.cp-sec-alta {
    padding: 6px 8px 2px;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}
/* Badges de pendiente bajo el campo persona (drawer de llamada). */
.cd-pb-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;

    & .badge { font-size: 0.66rem; padding: 2px 8px; }
}

/* Formulario inline de alta dentro del panel. */
.cp-create {
    margin-top: 6px;
    padding: 10px;
    border: 1.5px dashed color-mix(in oklch, var(--color-accent) 45%, transparent);
    border-radius: var(--radius-md);
    background-color: color-mix(in oklch, var(--color-accent) 4%, transparent);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.cp-create-hd { font-size: 0.78rem; font-weight: 700; color: var(--text-primary); }
.cp-create-inp {
    width: 100%;
    border: 1px solid var(--border-strong, var(--border-color));
    border-radius: 6px;
    padding: 6px 9px;
    font: inherit;
    font-size: 0.8rem;
    background: var(--bg-card);
    color: var(--text-primary);
}
.cp-create-inp:focus { outline: 2px solid color-mix(in oklch, var(--color-accent) 40%, transparent); outline-offset: -1px; }
.cp-create-row2 { display: flex; gap: 8px; }
.cp-create-row2 > * { flex: 1; min-width: 0; }
.cp-create-foot { display: flex; align-items: center; gap: 8px; }
.cp-create-foot .cp-create-err { font-size: 0.72rem; color: var(--color-fail); }

/* ========================================
   39. Vista individual de llamada (FA-4, PLAN_LLAMADA_V2 §3.4, D7/D8/D9)
   ======================================== */
/* Cabecera (avatar + persona + badge estado + chips + metadatos), tarjetas de
   contexto/vínculos/diario y enlaces entrantes (#id en la lista Llamadas y
   «ver llamada» en el timeline de la ficha). Solo tokens; layout reutiliza
   .card/.ll-block/.card-title/.badge/.btn/.call-jrn/.cl-* existentes. */

.ll-view {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* --- Cabecera --- */
.llm-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background-color: var(--bg-card);
    box-shadow: var(--shadow-card);
}

.llm-ava {
    display: inline-grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    flex-shrink: 0;
    font-weight: 700;
    font-size: 15px;
    color: #fff;
    background-color: var(--llm-av-color, var(--text-secondary));

    &.llm-ava-empty {
        background-color: var(--bg-card-hover);
        color: var(--text-muted);

        & i { width: 22px; height: 22px; }
    }
}

.llm-head-main { min-width: 0; flex: 1; }

.llm-head-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

.llm-title {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.llm-head-sub {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin-top: 4px;
    font-size: 0.82rem;
    color: var(--text-muted);
}

.llm-persona { font-weight: 600; color: var(--text-secondary); }

.llm-meta {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-variant-numeric: tabular-nums;

    & i { color: var(--text-muted); }
}

.llm-edited { color: var(--text-muted); font-style: italic; }

/* --- Tarjeta de contexto (tipo/dirección/teléfono/asunto) --- */
.llm-ctx {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px 18px;
    font-size: 0.86rem;

    & .k {
        display: block;
        margin-bottom: 2px;
        font-size: 0.7rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.04em;
        color: var(--text-muted);
    }
}

.llm-resumen {
    margin: 0;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background-color: var(--bg-card-hover);
    font-size: 0.88rem;
    color: var(--text-secondary);
}

.llm-actions-wrap { margin-top: 14px; }
.llm-actions { display: flex; flex-wrap: wrap; gap: 10px; }

.llm-actions .btn.is-confirm {
    background-color: var(--color-warning);
    border-color: var(--color-warning);
    color: var(--bg-card);
}

/* --- Vínculos --- */
.llm-vinc-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.llm-vinc {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: 0.86rem;
    color: var(--text-secondary);

    &:hover {
        background-color: var(--bg-card-hover);
        border-color: var(--color-accent);
        text-decoration: none;
    }

    & .llm-vinc-ic {
        flex: 0 0 auto;
        width: 16px;
        height: 16px;
        color: var(--color-accent);
    }
}

.llm-vinc-empty { font-size: 0.82rem; color: var(--text-muted); }

/* --- Enlace entrante: «ver llamada» en el timeline de la ficha --- */
.ct-call-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
    font-size: 0.74rem;
    font-weight: 600;
    white-space: nowrap;
}

/* --- Modal de edición (reutiliza .call-close para el checklist) --- */
.call-edit {
    & .cl-ctx { margin-top: 6px; }
}

/* ========================================
   40. FASE 11 — Drawer de «Llamada en curso»
   ======================================== */

/* FP-1 (D1): los inputs de formulario deshabilitados (p. ej. «segundos antes
   de ocultar» de la sección «Llamada en curso» de Administración, inerte con
   el colapso OFF — el estado lo gestiona JS). */
.form-input:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* FP-2 (D2): drawer ABIERTO (≥768 px) → el contenido se adapta con un margen
   derecho = ancho del drawer (370 px) + respiro (390; el pill ya usa 392 para
   no solaparse). El drawer sigue position:fixed right:0; el margen lo vuelve
   «fluido».
   `body.call-drawer-open` es SINÓNIMO de `.call-drawer.is-open` (existe en
   body por simplicidad CSS, puestas por call-session._setDrawerLayout). El
   colapso del sidebar (`.sidebar-collapsed`, el mecanismo real del toggle
   manual — no se re-expande al cerrar, D2/F1) lo gestiona ese mismo JS, no
   este CSS.
   Transición en el margen, coherente con la del sidebar (0.3s ease);
   prefers-reduced-motion la neutraliza el bloque global §34.
   Móvil (<768, bottom sheet): el media no aplica → cero cambios (sidebar
   off-canvas intacto). */
@media (min-width: 768px) {
    .main-content {
        transition: margin-right 0.3s ease;
    }

    body.call-drawer-open .main-content {
        margin-right: 390px;
    }
}

/* FP-5 (D5): footer del drawer con 2 estados — botones normales (Finalizar +
   Cancelar, en 2 columnas) ↔ confirmación inline de cancelar (aviso + [Sí]/
   [Volver]) sin modal nuevo. `.call-finish` conserva su `width: 100%` (llena
   su columna del grid); los botones son `.btn-*` existentes (tokens).
   Las clases ocultas usan `.hidden` (display:none !important, mecanismo
   canónico del proyecto). */
.call-ft-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;

    /* El atributo `hidden` del markup se alterna por JS; sin esto `display:grid`
       anularía el `[hidden] { display:none }` del UA. */
    &[hidden] { display: none; }
}

.call-ft-confirm {
    display: flex;
    flex-direction: column;
    gap: 8px;

    &[hidden] { display: none; }

    & .call-ft-warn {
        margin: 0;
        text-align: center;
        font-size: 0.8rem;
        font-weight: 600;
        color: var(--color-fail);
    }

    & .call-ft-actions {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;
    }
}

/* ========================================
   41. FASE 11 — Dashboard 2 columnas + franja de alertas (FP-3, D3)
   ======================================== */

/* FP-3 (D3): el dashboard distribuye «Anomalías y Eventos» (col A) y
   «Seguimiento de Incidencias» (col B) en 2 columnas ≥768 px; <768 apila
   (equivalente a cómo estaba, con los margins de .dashboard-section intactos).
   minmax(0, …) evita el overflow de las tablas en la columna estrecha.
   `.server-info-bar` y `#fleet-section` quedan FUERA (ancho completo);
   dentro del grid el gap sustituye al margin-bottom de sección (2rem sería
   el doble del gap y crearía asimetría vertical). */
.dash-cols {
    display: grid;
    grid-template-columns: 1fr;
    align-items: stretch; /* A-2: alturas iguales de las 2 columnas (panes SIEMPRE al mismo alto) */

    @media (min-width: 768px) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 20px;

        & .dashboard-section {
            margin-bottom: 0;
        }
    }
}

/* FASE 21: cajas de contenido con SCROLL INTERNO para las dos secciones del
   dashboard (Anomalías e Incidencias). Scrollea el CONTENIDO (toolbar + tabla
   + paginación); el título de sección y la franja de counts quedan fijos
   fuera del scroll. A-2 (LOTE DASHBOARD ANOMALIAS): `--dash-section-h`
   (420px / 360px móvil) ahora es TOPE (max-height), no suelo: con ≤5 filas no hace
   falta scroll. */
:root {
    --dash-section-h: 420px;
}
@media (max-width: 767px) {
    :root { --dash-section-h: 360px; }
}

.dash-scroll {
    max-height: var(--dash-section-h);   /* A-2: tope (no suelo): con ≤5 filas no hace falta scroll */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;   /* el gesto no arrastra el scroll de la página */
    border-top: 1px solid var(--border-color);
    scrollbar-width: thin;          /* Firefox */
}
/* LOTE DASHBOARD ANOMALIAS A-2: sección completa (título + caja + footer) en
   columna flex para que las dos columnas terminen a la MISMA altura:
   .dash-scroll crece (flex) hasta el max-height y el footer «ver más» se pega
   al pie (margin-top:auto). */
.dash-cols > .dashboard-section {
    display: flex;
    flex-direction: column;
}

/* A-2: footer «ver más» de los paneles (útil solo en dashboard, nombre
   genérico → aquí, junto a las .dash-*). margin-top:auto → se pega al pie
   de la columna aunque no exista (alturas iguales garantizadas). */
.dash-see-more {
    margin-top: auto;
    padding: 8px 2px 0;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-accent);
    text-decoration: none;
    cursor: pointer;
}
.dash-see-more:hover {
    color: var(--color-accent-hover);
    text-decoration: underline;
}

.dash-scroll::-webkit-scrollbar { width: 8px; }
.dash-scroll::-webkit-scrollbar-track { background: transparent; }
.dash-scroll::-webkit-scrollbar-thumb {
    background: color-mix(in oklch, var(--text-muted) 40%, transparent);
    border-radius: 4px;
}

/* Cabecera de la DataTable pegada arriba al scrollear (fondo opaco por token:
   válido en los 3 temas; sin él se verían las filas por debajo). */
.dash-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--bg-card);
    box-shadow: 0 1px 0 var(--border-color);
}

/* Estados vacío/error/cargando dentro de la caja: centrados en la altura fija */
.dash-scroll .alert-box {
    min-height: 100%;
    display: grid;
    place-items: center;
}

/* Franja resumen de alertas (FP-3, D3): sustituye al .alert-box «Atención»
   independiente. Compacta, alineada a la derecha del título (margin-left:auto
   — .dashboard-section-title es flex), con el patrón de tamaño del .badge.
   COLORES: tokens de estado existentes con color-mix (patrón FASE 8-C.1) —
   las .badge-* y .alert-* usan hex heredado FUERA de :root, así que la franja
   usa el token exacto del icono de cada alert-box (fail/warning/accent) y su
   tinte suave derivado (12-16 %), sin hex nuevos. */
.dash-alerts-strip {
    margin-left: auto;
    padding: 0.2rem 0.6rem;
    border-radius: var(--radius-full);
    font-size: 0.72rem;
    font-weight: 500;
    white-space: nowrap;

    &.is-error {
        background: color-mix(in oklch, var(--color-fail) 12%, transparent);
        color: var(--color-fail);
    }

    &.is-warning {
        background: color-mix(in oklch, var(--color-warning) 16%, transparent);
        color: var(--color-warning);
    }

    &.is-info {
        background: color-mix(in oklch, var(--color-accent) 12%, transparent);
        color: var(--color-accent);
    }
}

/* Espacios en blanco (queja del usuario — P3): el gap título→contenido del
   dashboard se reduce SOLO en el contexto de esta vista (evita romper otras
   vistas que usan .dashboard-section-title / .view-loading / .divider):
   - margin-bottom del título 16 → 12 px;
   - flex-wrap + row-gap: la franja no desborda el título en columnas/390 px
     (se envuelve a la derecha si no cabe);
   - .view-loading: padding vertical de 80 → 40 px SOLO mientras carga (los
     contenedores del dashboard se quitan la clase al pintar contenido real
     desde JS — el 176 px que medía el gap era en gran parte ese padding de
     80 px + el .alert-box resumen eliminado);
   - el hr.divider antes de la flota se CONSERVA (separa la zona de resumen de
     la flota a ancho completo) con márgenes más compactos en el dashboard. */
.dashboard-view {
    & .dashboard-section-title {
        margin-bottom: 12px;
        flex-wrap: wrap;
        row-gap: 6px;
    }

    & .view-loading {
        padding: 40px 0;
    }

    & .divider {
        margin: 12px 0 20px;
    }
}

/* ========================================
   43. Empresas y personal (FASE 12 FP-E)
   ======================================== */
.emp-view {
    display: grid;
    grid-template-columns: 300px 1fr;
    gap: 16px;
    align-items: start;

    /* FASE 6: los items de grid con min-width:auto dejaban que el min-content
       (botones nowrap, inputs) inflara la columna y cortara la vista a 375 px. */
    & > * { min-width: 0; }

    @media (max-width: 768px) {
        grid-template-columns: 1fr;
    }
}

.emp-list {
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: calc(100vh - 180px);
    max-height: calc(100dvh - 180px);
    overflow-y: auto;
}

.emp-list-hd {
    display: flex;
    gap: 8px;
    align-items: center;

    & .form-input { flex-grow: 1; }
    & .btn { white-space: nowrap; }
}

.emp-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.emp-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color 0.15s;

    &:hover { background-color: var(--bg-hover, oklch(0.96 0 0)); }
    &.is-active { background-color: oklch(0.93 0.02 240 / 0.4); }
    &.is-off { opacity: 0.5; }
}

.emp-item-tx {
    display: flex;
    flex-direction: column;
    min-width: 0;

    & b { font-size: 0.88rem; }
    & span { font-size: 0.76rem; color: var(--text-muted); }
}

.emp-detail {
    padding: 16px;
    min-height: 280px;
}

.emp-hd {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
    /* FASE 6: avatar + nombre + botones nowrap no cabían en 375 px y el botón
       "Desactivar" quedaba fuera del viewport → saltan de línea. */
    flex-wrap: wrap;
    row-gap: 8px;
}

.emp-hd-tx {
    display: flex;
    flex-direction: column;
    flex-grow: 1;

    & b { font-size: 1.05rem; }
    & span { font-size: 0.8rem; color: var(--text-muted); }
}

.emp-hd-acts {
    display: flex;
    gap: 8px;
}

/* Avatar con imagen (logo/avatar de persona) o iniciales sobre color */
.emp-av {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-full);
    background-color: var(--emp-c, var(--color-accent));
    color: oklch(0.985 0 0);
    font-weight: 700;
    font-size: 0.8rem;
    overflow: hidden;
    flex-shrink: 0;

    & img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
    & > span { position: relative; }

    &.emp-av--sm { background-color: var(--color-accent); }
}

.emp-meta {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px 16px;
    margin: 0 0 16px;
    padding: 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    background-color: oklch(0.985 0 0);

    @media (max-width: 768px) { grid-template-columns: 1fr; }

    & div { display: flex; gap: 8px; }
    & dt { color: var(--text-muted); font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.04em; }
    & dd { margin: 0; font-size: 0.86rem; }
}

.emp-sub {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 10px 0 8px;

    & h4 { margin: 0; }
}

.emp-personas {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.emp-persona {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);

    &.is-off { opacity: 0.5; }

    & .btn { margin-left: auto; }
}

.emp-persona-tx {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-width: 0;

    & b { font-size: 0.88rem; }
    & span { font-size: 0.76rem; color: var(--text-muted); }
}

.emp-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 560px;
}

.form-row2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.form-row3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 12px;
}

.emp-form-acts {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 8px;
}

.emp-empty {
    color: var(--text-muted);
    font-size: 0.88rem;
    padding: 8px 0;
    text-align: center;
}

/* ========================================
   44. Gráficas del reporte (FASE 12 FP-F)
   ======================================== */
.rep-charts .card-header { flex-wrap: wrap; }

.rep-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 16px;
    margin-bottom: 12px;

    & .form-select { width: auto; min-width: 170px; }
}

.chart-ok {
    min-height: 120px;
}

.chart-ok svg {
    display: block;
    width: 100%;
    height: auto;
    color: var(--text-secondary);
}

.chart-axis {
    font-size: 10px;
    fill: var(--text-muted);
}

.chart-legend-row {
    display: flex;
    gap: 16px;
    margin-top: 6px;
}

.chart-legend {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.76rem;
    color: var(--text-secondary);

    & i {
        width: 10px;
        height: 10px;
        border-radius: 2px;
        display: inline-block;
    }
}

.chart-empty {
    color: var(--text-muted);
    font-size: 0.86rem;
    padding: 26px 0;
    text-align: center;
}

.bar-cell {
    display: flex;
    align-items: center;
    gap: 8px;

    & .bar-fill {
        height: 8px;
        border-radius: var(--radius-full);
        background-color: var(--color-accent);
        min-width: 2px;
        flex-shrink: 0;
    }
    & span {
        font-size: 0.74rem;
        color: var(--text-muted);
        white-space: nowrap;
    }
}

/* ========================================
   45. Detalle de pack: rejilla de gráficas y burbujas pequeñas de tag (FASE 13 F13-1)
   ======================================== */
.det-charts-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

.det-chart-cell {
    min-height: 450px;
}

.tag-bubble--sm {
    padding: 2px 8px;
    font-size: 0.72rem;
    gap: 4px;
}

@media (max-width: 768px) {
    /* P1: los gráficos de monitorización se apilan (uno arriba, otro abajo) */
    .det-charts-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .det-chart-cell {
        min-height: 320px;
    }
}

/* --- F13-2: pantalla completa de gráficas --- */
.det-chart-cell:fullscreen {
    background: var(--bg-card);
    padding: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.det-chart-cell:fullscreen .js-plotly-plot {
    max-width: 100%;
}

.chart-maximized {
    width: 100%;
    height: 70vh;
    min-height: 340px;
}

/* --- F13-3: chip-select (textbox predictivo con burbujas) --- */
.chip-select {
    position: relative;
    width: 100%;
}

.cs-field {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
    min-height: 38px;
    padding: 4px 8px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-input);
    cursor: text;
    transition: border-color 0.15s ease;

    &:focus-within {
        border-color: var(--color-accent);
    }
}

.cs-chips {
    display: contents;
}

.cs-input {
    border: none;
    outline: none;
    background: transparent;
    font-size: 0.85rem;
    color: var(--text-primary);
    padding: 4px 2px;
    flex: 1;
    min-width: 60px;

    &::placeholder {
        color: var(--text-muted);
    }
}

.cs-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 6px 2px 10px;
    border-radius: var(--radius-full);
    font-size: 0.75rem;
    font-weight: 500;
    background: var(--bg-card-hover);
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
    animation: fadeIn 0.15s ease;
}

.cs-x {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.9rem;
    line-height: 1;
    color: inherit;
    opacity: 0.65;
    padding: 0 4px;
    border-radius: 50%;

    &:hover {
        opacity: 1;
    }
}

.cs-clear {
    align-self: center;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 0.8rem;
    padding: 2px 6px;
    border-radius: var(--radius-full);

    &:hover {
        color: var(--text-primary);
        background: var(--bg-card-hover);
    }
}

.cs-panel {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 60;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px oklch(0.2 0.02 260 / 0.16);
    max-height: 340px;
    overflow-y: auto;
    padding: 4px;
}

.cs-opt {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    text-align: left;
    padding: 7px 10px;
    border: none;
    background: none;
    border-radius: var(--radius-sm);
    font-size: 0.83rem;
    color: var(--text-primary);
    cursor: pointer;

    &.active,
    &:hover {
        background: var(--bg-card-hover);
    }
}

.cs-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: none;
}

.cs-opt-sub {
    margin-left: auto;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.cs-empty {
    padding: 10px;
    font-size: 0.8rem;
    color: var(--text-muted);
    text-align: center;
}

/* --- F13-5: banner de ámbito por empresa (llamada en curso) --- */
.scope-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 8px 20px;
    font-size: 0.83rem;
    color: var(--text-primary);
    background: oklch(0.93 0.05 220 / 0.55);
    border-bottom: 1px solid oklch(0.85 0.06 225 / 0.6);

    &[hidden] {
        display: none;
    }

    &--warn {
        background: oklch(0.93 0.05 75 / 0.5);
        border-bottom-color: oklch(0.85 0.08 75 / 0.6);
    }

    & .btn {
        white-space: nowrap;
    }
}

.scope-banner-txt b {
    font-weight: 600;
}

/* --- F14-4: fila de rango de análisis bajo las pestañas del detalle --- */
.detalle-range-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 12px 0;
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-card);

    &[hidden] {
        display: none;
    }
}

.detalle-range-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.detalle-range-input {
    width: auto;
    min-width: 130px;
    font-size: 0.8rem;
}

.detalle-range-sep {
    color: var(--text-muted);
    font-size: 0.85rem;
}

.detalle-range-presets {
    display: inline-flex;
    gap: 4px;
    margin-left: 4px;
}

.detalle-range-err {
    font-size: 0.75rem;
    color: var(--color-fail);
}

@media (max-width: 768px) {
    .detalle-range-row {
        gap: 6px;
    }

    .detalle-range-input {
        width: 46%;
        min-width: 0;
        flex: 1;
    }
}

/* Escritorio: las dos fechas en la MISMA fila que los presets (si caben)
   — sin saltos de línea fortuitos entre fechas y atajos */
@media (min-width: 768px) {
    .detalle-range-row {
        flex-wrap: nowrap;
    }

    .detalle-range-input {
        flex: 1 1 130px;
        min-width: 0;
        max-width: 170px;
    }

    .detalle-range-presets {
        flex-shrink: 1;
        white-space: nowrap;
    }
}

/* --- F14 (retoque 2): el panel de métricas entra en FLUJO para que sea el
   CONTENEDOR QUE AGRUPA LOS DOS SELECTORES (el .metric-selector-group de
   Y1/Y2) el que crezca cuando se abre la lista — no un panel flotante que
   superponga el contenido de abajo. --- */
.metric-multiselect .cs-panel {
    position: static;
    top: auto;
    left: auto;
    right: auto;
    z-index: auto;
    margin-top: 4px;
    max-height: min(520px, 70vh);
}

/* --- F15: multiselección de personas (burbujas en persona-combobox) --- */
.cp-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 0 0 6px;

    &[hidden] {
        display: none;
    }
}

.cp-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 1px 6px 1px 3px;
    border-radius: var(--radius-full);
    background: var(--bg-card-hover);
    border: 1px solid var(--border-color);
    font-size: 0.76rem;
    color: var(--text-primary);
    animation: fadeIn 0.15s ease;

    & .cp-avatar {
        width: 18px;
        height: 18px;
        font-size: 0.55rem;
    }
}

.cp-chip-x {
    background: none;
    border: none;
    color: inherit;
    opacity: 0.65;
    cursor: pointer;
    font-size: 0.95rem;
    line-height: 1;
    padding: 0 2px;

    &:hover {
        opacity: 1;
    }
}

/* modo multi: el avatar de "selección única" sobra (hay burbujas) */
.cp-multi .cp-input .cp-avatar:first-child {
    display: none;
}

/* el input multi funciona como buscador perpetuo (sin texto de selección) */
.cp-multi .cp-input-el {
    flex: 1;
}

/* ========================================
   47. Calendario (FASE 16 F16-2 + retoque estético F16)
   ======================================== */
/* FASE 6: la fila de navegación (‹ mes › Hoy Mis trabajos) no cabía en 375 px
   y cortaba el botón de la derecha → puede saltar de línea. */
.cal-nav {
    flex-wrap: wrap;
    row-gap: 6px;
}

/* FASE 6: la leyenda superior vive FUERA de .cal-view (no hereda los chips de
   .cal-view .cal-legend) y en 375 px el último ítem se cortaba. Solo en móvil
   se convierte en fila con wrap; escritorio no cambia. */
@container (max-width: 480px) {
    #cal-root > .cal-legend {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
    }
}

.cal-view {
    --cal-llamada: #1f77b4;
    --cal-incidencia: #ef4444;
    --cal-reparacion: #2ca02c;
    --cal-recordatorio: #f59e0b;

    & .cal-week {
        display: grid;
        grid-template-columns: repeat(7, minmax(0, 1fr));
        gap: 6px;
        margin-bottom: 6px;

        & .cal-week-h {
            text-align: center;
            font-size: 0.7rem;
            font-weight: 700;
            color: var(--text-secondary);
            text-transform: uppercase;
            letter-spacing: .06em;
            padding: 4px 0;
        }
    }

    & .cal-mesh {
        display: grid;
        grid-template-columns: repeat(7, minmax(0, 1fr));
        gap: 6px;

        &--week .cal-day {
            min-height: 160px;
        }
    }

    & .cal-day {
        position: relative;
        min-height: 104px;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
        background: var(--bg-card);
        padding: 4px 5px;
        overflow: hidden;
        transition: box-shadow .15s ease;

        &:hover {
            box-shadow: 0 2px 8px oklch(0.2 0.02 260 / 0.10);
        }

        &--today {
            border-color: var(--color-accent);
            box-shadow: 0 0 0 1px var(--color-accent) inset;
        }

        &--muted {
            opacity: .42;
        }

        & .cal-day-num {
            position: relative;
            z-index: 2;
            display: inline-block;
            min-width: 20px;
            text-align: center;
            font-size: 0.72rem;
            font-weight: 700;
            color: var(--text-secondary);
            padding: 1px 5px;
            border-radius: 999px;
        }

        &--today .cal-day-num {
            background: var(--color-accent);
            color: var(--bg-card);
        }

        /* F17-6: el número de día es un botón (salto a la agenda del día) */
        & .cal-day-num--btn {
            background: none;
            border: 0;
            padding: 1px 5px;
            margin: 0;
            font: inherit;
            color: inherit;
            cursor: pointer;
            border-radius: 999px;

            &:hover { background: var(--bg-subtle); }
            &:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
        }

        /* F17-6: bandas y dots son navegables (click/Enter → ficha) */
        & .cal-band[data-ruta], & .cal-dot[data-ruta] {
            &:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
        }
    }

    & .cal-day-layer {
        position: relative;
        height: 100%;
        min-height: 64px;
    }

    & .cal-band {
        position: absolute;
        left: 3px;
        right: 3px;
        top: 24px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: 0.66rem;
        line-height: 1.25;
        font-weight: 600;
        padding: 2px 6px;
        border-radius: 6px;
        cursor: pointer;
        display: flex;
        align-items: center;
        gap: 5px;
        transition: filter .15s ease, box-shadow .15s ease;

        & > i {
            width: 7px;
            height: 7px;
            border-radius: 50%;
            flex: none;
            background: oklch(1 0 0 / .85);
            box-shadow: 0 0 0 1px oklch(0 0 0 / .08);
        }

        &:hover {
            filter: brightness(1.1);
            box-shadow: 0 3px 10px oklch(0.2 0.02 260 / 0.25);
        }

        &--llamada { background: var(--cal-llamada); color: #fff; }
        &--incidencia { background: var(--cal-incidencia); color: #fff; }
        &--reparacion { background: var(--cal-reparacion); color: #fff; }
        &--recordatorio { background: var(--cal-recordatorio); color: oklch(0.25 0.04 70); }
    }

    /* banda de la AGENDA: en flujo, con icono y estado */
    & .cal-band--agenda {
        position: static;
        display: inline-flex;
        align-items: center;
        margin: 0 6px 6px 0;

        & > i {
            width: 13px;
            height: 13px;
            border-radius: 3px;
            background: none;
            box-shadow: none;
        }

        & b {
            font-weight: 700;
            font-variant-numeric: tabular-nums;
        }

        & em {
            font-style: normal;
            font-weight: 500;
            font-size: 0.62rem;
            opacity: .85;
            border: 1px solid oklch(0 0 0 / .18);
            border-radius: 999px;
            padding: 0 6px;
        }
    }

    & .cal-dot {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        margin: 1px 4px 1px 0;
        font-size: 0.64rem;
        font-weight: 600;
        color: var(--text-secondary);
        cursor: pointer;

        &::before {
            content: '';
            width: 8px;
            height: 8px;
            border-radius: 50%;
        }

        &:hover::before { transform: scale(1.25); }

        &--llamada::before { background: var(--cal-llamada); }
        &--incidencia::before { background: var(--cal-incidencia); }
        &--reparacion::before { background: var(--cal-reparacion); }
        &--recordatorio::before { background: var(--cal-recordatorio); }
    }

    & .cal-item {
        display: inline-flex;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 0.68rem;
        color: var(--text-secondary);
        border-left: 3px solid var(--cal-llamada);
        background: var(--bg-card-hover);
        padding: 1px 6px;
        margin: 2px 0;
        border-radius: 4px;

        &--llamada { border-color: var(--cal-llamada); }
        &--incidencia { border-color: var(--cal-incidencia); }
        &--reparacion { border-color: var(--cal-reparacion); }
        &--recordatorio { border-color: var(--cal-recordatorio); }
    }

    & .cal-event-hit {
        display: block;
        cursor: pointer;
        text-decoration: none;
        color: inherit;

        &:hover { filter: brightness(1.05); }
    }

    & .cal-agenda-day {
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
        margin-bottom: 10px;
        padding: 10px 14px;
        background: var(--bg-card);

        &--today {
            border-color: var(--color-accent);
        }

        & .cal-agenda-date {
            font-size: 0.8rem;
            font-weight: 700;
            color: var(--text-secondary);
            text-transform: capitalize;
        }

        /* F17-7: cabecera de día (weekday · HOY · contador) */
        & .cal-agenda-head {
            display: flex;
            align-items: baseline;
            gap: 8px;
            margin-bottom: 8px;
        }
        & .cal-agenda-hoy {
            font-size: 0.6rem;
            font-weight: 800;
            letter-spacing: .05em;
            color: #fff;
            background: var(--color-accent);
            border-radius: 999px;
            padding: 1px 8px;
        }
        & .cal-agenda-count {
            margin-left: auto;
            font-size: 0.66rem;
            font-weight: 700;
            color: var(--text-muted);
            font-variant-numeric: tabular-nums;
        }
    }

    /* F17-7: densidad compacta de la agenda */
    & .cal-agenda--compacta {
        & .cal-agenda-day { padding: 8px 12px; margin-bottom: 8px; }
        & .cal-agenda-head { margin-bottom: 6px; }
        & .cal-band--agenda { font-size: 0.66rem; padding: 1px 6px; margin: 0 4px 4px 0; }
    }

    & .cal-legend {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        margin: 6px 0 14px;

        & .cal-legend-item {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            font-size: 0.72rem;
            font-weight: 600;
            color: var(--text-secondary);
            background: var(--bg-card);
            border: 1px solid var(--border-color);
            border-radius: 999px;
            padding: 3px 10px;

            & i {
                width: 10px;
                height: 10px;
                border-radius: 3px;
                display: inline-block;
            }

            /* F17-6: contador de eventos por tipo */
            & .cal-legend-cnt {
                margin-left: 4px;
                font-size: 0.66rem;
                font-weight: 800;
                color: var(--text-muted);
                font-variant-numeric: tabular-nums;
            }
        }
    }

    & .cal-mios-on {
        background: var(--color-accent);
        color: #fff;
        border-color: var(--color-accent);
    }

    & .cal-truncado {
        margin-left: auto;
        color: var(--color-fail);
        cursor: pointer;

        &:hover { text-decoration: underline; }
        &:focus-visible { outline: 2px solid var(--color-fail); outline-offset: 2px; border-radius: 4px; }
    }

    & .cal-empty--bar {
        display: flex;
        align-items: center;
        gap: 10px;
        flex-wrap: wrap;
        padding: 14px 18px;
        text-align: left;
        border: 1px dashed var(--border-strong);
        border-radius: var(--radius-md);
        background: var(--bg-subtle);
        margin-top: -2px;
    }

    & .cal-empty {
        padding: 40px;
        text-align: center;
        color: var(--text-muted);
    }
}

@media (max-width: 768px) {
    .cal-view .cal-day { min-height: 56px; }
    .cal-view .cal-day-layer { min-height: 34px; }
    .cal-view .cal-dot { font-size: 0.58rem; }
    /* F17 (retoque): chips «puntos» compactos en móvil */
    .cal-view .cal-day-events--puntos { max-height: 60px; }
    /* F17-7: agenda móvil compacta: chips a una línea, estado fuera */
    .cal-view .cal-agenda-day { padding: 8px 10px; }
    .cal-view .cal-band--agenda { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .cal-view .cal-band--agenda em { display: none; }
}

/* --- F16-3 (D6): móvil + panel de llamada abierto → el toast del pill sube
   ARRIBA y el footer deja espacio (los botones Finalizar/Cancelar quedan más
   arriba, nunca tapados). Con el panel cerrado todo vuelve a la normalidad. --- */
@media (max-width: 768px) {
    body:has(.call-drawer.is-open) .toast-container--pill {
        bottom: auto;
        top: 12px;
    }

    body:has(.call-drawer.is-open) .call-drawer-ft {
        padding-bottom: 84px;
    }
}

/* F16 retoque: chip «+N más → agenda» cuando un día supera las filas de bandas */
.cal-view .cal-more {
    position: absolute;
    left: 3px;
    right: 3px;
    top: calc(26px + 4 * 20px);
    font-size: 0.64rem;
    font-weight: 700;
    color: var(--color-accent);
    background: oklch(0.93 0.04 250 / 0.7);
    border: 1px dashed var(--color-accent);
    border-radius: 6px;
    padding: 1px 4px;
    cursor: pointer;
    text-align: center;

    &:hover {
        background: var(--color-accent);
        color: var(--bg-card);
    }
}

/* F16 (desborde): el chip «+N más» en modo inicios/cierres va al pie de la celda */
.cal-view .cal-more--dots {
    top: auto;
    bottom: 4px;
}

/* ========================================
   48. Asignaciones (FASE 17 F17-8 shell)
   ======================================== */
.asig-view {
    & .asig-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        margin-bottom: 14px;
        flex-wrap: wrap;
    }

    & .asig-kpis {
        display: flex;
        gap: 8px;
        flex-wrap: wrap;
        margin-bottom: 12px;

        & .asig-kpi {
            display: inline-flex;
            align-items: baseline;
            gap: 6px;
            background: var(--bg-card);
            border: 1px solid var(--border-color);
            border-radius: 12px;
            padding: 6px 12px;
            font-size: 0.72rem;
            font-weight: 600;
            color: var(--text-secondary);

            & b { font-size: 1rem; }

            &.k-cur b { color: #0e7490; }
            &.k-ven b { color: var(--color-fail); }
            &.k-sin b { color: #9a6b10; }
            &.k-tot b { color: var(--text-primary); }
        }

        & .asig-trunc {
            margin-left: auto;
            font-size: 0.68rem;
            font-weight: 700;
            color: var(--color-fail);
        }
    }

    & .asig-toolbar {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-wrap: wrap;
        margin-bottom: 14px;

        & .asig-chip-group {
            display: flex;
            gap: 6px;
            flex-wrap: wrap;
        }

        & .asig-chip {
            border: 1px solid var(--border-color);
            background: var(--bg-card);
            border-radius: 999px;
            padding: 4px 12px;
            font-size: 0.74rem;
            font-weight: 600;
            color: var(--text-muted);
            cursor: pointer;

            &:hover { border-color: var(--color-accent); color: var(--text-primary); }
            &.on { background: var(--text-primary); color: var(--bg-card); border-color: var(--text-primary); }
        }
    }

    & .asig-pane {
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-lg);
        padding: 14px 16px;

        & .asig-pane-head {
            display: flex;
            align-items: baseline;
            gap: 10px;
            margin-bottom: 6px;

            & h4 { margin: 0; font-size: 0.95rem; }
            & h4 small { color: var(--text-muted); font-weight: 600; font-size: 0.7rem; }
            & .asig-pane-total { margin-left: auto; font-size: 0.7rem; font-weight: 700; color: var(--text-muted); }
        }

        & .asig-hint {
            font-size: 0.74rem;
            color: var(--text-muted);
            margin: 0 0 10px;
            max-width: 720px;
        }

        & .asig-stub-list {
            display: flex;
            flex-direction: column;
            gap: 6px;

            & .asig-stub-card {
                display: flex;
                align-items: center;
                gap: 8px;
                flex-wrap: wrap;
                font-size: 0.74rem;
                background: var(--bg-card-hover);
                border: 1px solid var(--border-color);
                border-left: 3px solid var(--color-success);
                border-radius: 8px;
                padding: 6px 10px;

                &.tag-inc { border-left-color: var(--color-fail); }

                & b { font-weight: 700; }
                & .asig-stub-tec { margin-left: auto; color: var(--text-muted); font-size: 0.68rem; }
                & .asig-stub-est {
                    font-size: 0.64rem;
                    color: var(--text-secondary);
                    border: 1px solid var(--border-color);
                    border-radius: 999px;
                    padding: 0 8px;
                }
                & .asig-live { color: #0e7490; font-weight: 800; }
                & .asig-vnc { color: var(--color-fail); font-weight: 800; }
            }
        }

        & .asig-empty-stub {
            padding: 20px;
            text-align: center;
            color: var(--text-muted);
            font-size: 0.8rem;
            border: 1px dashed var(--border-strong);
            border-radius: var(--radius-md);

            & .btn { margin-top: 8px; }
        }
    }
}

/* badge de tipo y urgencia (stub + futuras pestañas) */
.asig-tag {
    font-size: 0.56rem;
    font-weight: 800;
    border-radius: 5px;
    padding: 1px 6px;
    color: #fff;

    &.OT  { background: var(--color-success); }
    &.INC { background: var(--color-fail); }
}
.asig-stub-urg {
    font-size: 0.58rem;
    font-weight: 800;
    border-radius: 5px;
    padding: 0 6px;
    border: 1px solid;

    &.u-critica { color: var(--color-fail); border-color: color-mix(in oklch, var(--color-fail), white 75%); background: color-mix(in oklch, var(--color-fail), white 92%); }
    &.u-alta    { color: #d97706; border-color: #fde68a; background: #fef3c7; }
    &.u-media   { color: #a16207; border-color: #fef08a; background: #fefce8; }
    &.u-baja    { color: #64748b; border-color: #e2e8f0; background: #f1f5f9; }
}

/* ========================================
   48b. Asignaciones — Kanban (F17-9)
   ======================================== */
.asig-kanban {
    & .asig-board-movil { display: none; }

    & .asig-board {
        display: grid;
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: 12px;
        align-items: start;
        overflow-x: auto;
    }

    & .asig-col {
        background: var(--bg-subtle);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-lg);
        padding: 8px;
        min-height: 220px;
        transition: box-shadow .15s ease, background .15s ease;

        &.is-over { background: oklch(0.95 0.03 250); box-shadow: inset 0 0 0 2px var(--color-accent); }
        &.is-invalid { box-shadow: inset 0 0 0 2px var(--color-fail); }
    }

    & .asig-col-h {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 4px 6px 10px;

        & .asig-col-dot { width: 9px; height: 9px; border-radius: 3px; flex: none; }
        & b { font-size: 0.82rem; font-weight: 700; }
        & small { display: block; font-size: 0.6rem; color: var(--text-muted); font-weight: 500; }
        & .asig-col-cnt {
            margin-left: auto;
            background: var(--bg-card);
            border: 1px solid var(--border-color);
            border-radius: 999px;
            font-size: 0.66rem;
            font-weight: 700;
            color: var(--text-primary);
            padding: 1px 9px;

            &.is-wip { color: var(--color-fail); border-color: color-mix(in oklch, var(--color-fail), white 70%); }
        }
    }

    & .asig-col-body { display: flex; flex-direction: column; gap: 8px; }
    & .asig-col-empty { font-size: 0.68rem; color: var(--text-muted); padding: 10px; text-align: center; }

    & .asig-card {
        position: relative;
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        border-left: 4px solid var(--color-success);
        border-radius: 10px;
        padding: 9px 11px;
        cursor: grab;
        box-shadow: var(--shadow-card);
        transition: transform .1s ease, box-shadow .15s ease;

        &.tag-inc { border-left-color: var(--color-fail); }
        &.is-vencida { background: color-mix(in oklch, var(--color-fail), var(--bg-card) 93%); }
        &.is-dragging { opacity: .45; }
        &.pop-open { z-index: 50; box-shadow: 0 10px 26px rgba(40, 60, 110, 0.25); }
        &:hover { box-shadow: 0 6px 16px rgba(60, 80, 120, 0.14); }
        &:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
    }

    & .asig-card-menu {
        position: absolute;
        top: 7px;
        right: 8px;
        width: 20px;
        height: 20px;
        border: 0;
        background: none;
        color: var(--text-muted);
        font-weight: 800;
        font-size: 0.8rem;
        line-height: 1;
        cursor: pointer;
        border-radius: 6px;

        &:hover { background: var(--bg-subtle); color: var(--text-primary); }
    }

    & .asig-card-top {
        display: flex;
        gap: 6px;
        align-items: center;
        flex-wrap: wrap;
        padding-right: 46px;
        margin-bottom: 6px;

        & .asig-live { font-size: 0.56rem; font-weight: 800; color: #0e7490; border: 1px solid #a5f3fc; background: #cffafe; border-radius: 5px; padding: 0 6px; }
        & .asig-vnc { font-size: 0.56rem; font-weight: 800; color: #b91c1c; background: #fee2e2; border-radius: 5px; padding: 0 6px; }
    }

    & .asig-card-title { margin: 0 0 4px; font-size: 0.76rem; font-weight: 600; line-height: 1.3; }
    & .asig-card-meta { margin: 0 0 8px; font-size: 0.66rem; color: var(--text-muted); }
    & .asig-card-ft { display: flex; align-items: center; gap: 6px; }
    & .asig-avs { display: inline-flex; }
    & .asig-av {
        width: 18px; height: 18px; border-radius: 50%;
        color: #fff; font-size: 0.54rem; font-weight: 800;
        display: inline-flex; align-items: center; justify-content: center;
        margin-right: -4px; border: 1.5px solid var(--bg-card);
    }
    & .asig-av--mas { background: var(--bg-subtle); color: var(--text-secondary); }
    & .asig-card-tec { margin-left: auto; font-size: 0.64rem; color: var(--text-muted); font-weight: 600; }

    & .asig-pop {
        position: absolute;
        top: 30px;
        right: 6px;
        z-index: 60;
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        border-radius: 12px;
        box-shadow: var(--shadow-lg);
        padding: 10px;
        width: 210px;
    }
    & .asig-pop-lbl { display: block; font-size: 0.62rem; font-weight: 700; color: var(--text-muted); margin: 6px 0 3px; }
    & .asig-kanban-hint { margin-top: 12px; font-size: 0.72rem; color: var(--text-muted); }
}

/* móvil: una columna a la vez + selector de fase */
@container (max-width: 768px) {
    .asig-kanban .asig-board { display: block; }
    .asig-kanban .asig-board-movil { display: block; margin-bottom: 10px; max-width: 280px; }
    .asig-kanban .asig-col { display: none; }
    .asig-kanban .asig-col.is-sel { display: block; }
}

/* ========================================
   48c. Asignaciones — Carga por técnico (F17-10)
   ======================================== */
.asig-carga {
    display: flex;
    flex-direction: column;
    gap: 12px;

    & .asig-tray {
        background: oklch(0.97 0.03 85);
        border: 1px dashed oklch(0.80 0.07 75);
        border-radius: var(--radius-lg);
        padding: 10px 12px;

        &.is-over { background: oklch(0.94 0.05 80); }
    }

    & .asig-deck {
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-lg);
        padding: 12px 14px;
        transition: box-shadow .15s ease, background .15s ease;

        &.is-over { background: oklch(0.96 0.02 250); box-shadow: inset 0 0 0 2px var(--color-accent); }
    }

    & .asig-deck-h {
        display: flex;
        align-items: center;
        gap: 10px;
        flex-wrap: wrap;

        & .asig-deck-tt b { font-size: 0.92rem; display: block; line-height: 1.15; }
        & .asig-deck-tt small { font-size: 0.64rem; color: var(--text-muted); }
        & .asig-deck-stats { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
        & .st {
            font-size: 0.62rem; font-weight: 800; border-radius: 999px; padding: 2px 9px;
            &.ej { background: #dbeafe; color: #1d4ed8; }
            &.pend { background: #fef3c7; color: #92400e; }
            &.ven { background: #fee2e2; color: #b91c1c; }
            &.cer { background: #e2f6ea; color: #15803d; }
        }
    }

    & .asig-bar {
        margin: 8px 0 4px;
        height: 7px;
        background: var(--bg-subtle);
        border-radius: 999px;
        overflow: hidden;

        & i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--color-accent), var(--color-success)); transition: width .35s; }
        &.warn i { background: linear-gradient(90deg, var(--color-warning), var(--color-fail)); }
    }
    & .asig-deck-sub { font-size: 0.64rem; color: var(--text-muted); margin-bottom: 8px; }

    & .asig-deck-rows { display: flex; flex-direction: column; gap: 6px; }

    & .asig-fila {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 0.72rem;
        background: var(--bg-card-hover);
        border: 1px solid var(--border-color);
        border-left: 4px solid var(--color-success);
        border-radius: 8px;
        padding: 6px 10px;
        cursor: grab;

        &.tag-inc { border-left-color: var(--color-fail); }
        &.is-vencida { background: color-mix(in oklch, var(--color-fail), var(--bg-card) 94%); }
        &.is-dragging { opacity: .45; }
        &:hover { box-shadow: 0 4px 12px rgba(60, 80, 120, 0.12); }

        & .asig-fila-ref { font-weight: 800; flex: none; }
        & .asig-fila-tt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
        & .asig-fila-pack { color: var(--text-muted); font-size: 0.64rem; flex: none; }
        & .asig-fila-est {
            margin-left: auto;
            font-size: 0.6rem; font-weight: 700; color: var(--text-secondary);
            border: 1px solid var(--border-color); border-radius: 999px; padding: 0 7px;
        }
        & .asig-live, & .asig-vnc { font-size: 0.6rem; font-weight: 800; }
        & .asig-live { color: #0e7490; }
        & .asig-vnc { color: var(--color-fail); }
    }
}

@container (max-width: 768px) {
    .asig-carga .asig-deck-h { align-items: flex-start; }
    .asig-carga .asig-deck-stats { margin-left: 0; width: 100%; }
    .asig-carga .asig-fila-pack { display: none; }
}

/* ========================================
   48d. Asignaciones — Tabla (F17-11)
   ======================================== */
.asig-tabla {
    & .asig-tabla-bar {
        display: flex; align-items: center; gap: 10px;
        margin-bottom: 8px; font-size: 0.72rem; color: var(--text-muted);
    }
    & .asig-tabla-order { margin-left: auto; font-weight: 700; }
    & .asig-tabla-wrap {
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-lg);
        overflow-x: auto;
    }
    & table.asig-table { width: 100%; border-collapse: collapse; font-size: 0.74rem; min-width: 1080px; }
    & .asig-table th {
        background: var(--bg-subtle);
        text-align: left;
        padding: 9px 12px;
        font-size: 0.64rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
        color: var(--text-muted);
        border-bottom: 1px solid var(--border-color);
        white-space: nowrap; user-select: none;

        &.is-sortable { cursor: pointer; }
        &.is-sortable:hover { color: var(--text-primary); }
        &.is-sorted { color: var(--text-primary); }
    }
    & .asig-table td { padding: 8px 12px; border-bottom: 1px solid var(--border-color); vertical-align: middle; }
    & .asig-table tr:hover td { background: var(--bg-card-hover); }
    & .asig-tr.is-curso td:first-child { box-shadow: inset 3px 0 0 #06b6d4; }
    & .asig-tr.is-vencida td:first-child { box-shadow: inset 3px 0 0 var(--color-fail); }

    & .asig-td-sub { font-size: 0.66rem; color: var(--text-muted); margin-top: 2px; }
    & .asig-td-mut { color: var(--text-muted); }
    & .asig-td-trabajo b { font-weight: 700; }
    & .asig-td-fechas { white-space: nowrap; color: var(--text-muted); }

    & .asig-live, & .asig-vnc { font-size: 0.54rem; font-weight: 800; border-radius: 5px; padding: 0 6px; margin-left: 6px; }
    & .asig-live { color: #0e7490; border: 1px solid #a5f3fc; background: #cffafe; }
    & .asig-vnc { color: #b91c1c; background: #fee2e2; }

    & .asig-tec-btn {
        border: 1px solid var(--border-color);
        background: var(--bg-card);
        border-radius: 8px; padding: 3px 8px;
        font-size: 0.7rem; font-family: inherit; color: var(--text-primary);
        cursor: pointer; max-width: 170px;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;

        &.is-vacio { color: var(--text-muted); border-style: dashed; }
        &:hover { border-color: var(--color-accent); }
    }
    & .asig-tec-edit { min-width: 180px; }
    & select.asig-td-estado { max-width: 150px; font-size: 0.7rem; padding: 3px 6px; }
    & .asig-abrir {
        border: 0; background: none; color: var(--text-muted);
        cursor: pointer; font-size: 0.9rem;
        &:hover { color: var(--color-accent); }
    }
    & .asig-pag {
        display: flex; align-items: center; gap: 10px; justify-content: flex-end;
        margin-top: 10px; font-size: 0.72rem; color: var(--text-muted);
    }
}

/* ========================================
   48e. Asignaciones — Timeline (F17-12, una fila por trabajo)
   ======================================== */
.asig-timeline {
    --tl-lbl-w: 220px;

    & .asig-tl-bar {
        display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
        margin-bottom: 10px;

        & .asig-tl-title { min-width: 170px; font-size: 0.82rem; }
        & .asig-tl-info { margin-left: auto; font-size: 0.7rem; color: var(--text-muted); }
    }

    & .asig-tl-axis {
        position: sticky; top: 0; z-index: 3;
        display: grid; grid-template-columns: var(--tl-lbl-w) 1fr;
        background: var(--bg-card); border-bottom: 1px solid var(--border-color);
        padding-bottom: 2px;
    }
    & .asig-tl-axis-cells { position: relative; height: 22px; }
    & .asig-tl-d {
        position: absolute; top: 2px; text-align: center;
        font-size: 0.6rem; font-weight: 700; color: var(--text-muted);
        font-variant-numeric: tabular-nums;

        &.is-we { color: color-mix(in oklch, var(--text-muted), transparent 30%); }
        &.is-hoy { color: var(--color-accent); }
    }

    & .asig-tl-body { position: relative; }
    & .asig-tl-overlay {
        position: absolute; left: var(--tl-lbl-w); right: 0; top: 0; bottom: 0;
        pointer-events: none;

        & .asig-tl-we { position: absolute; top: 0; bottom: 0; background: color-mix(in oklch, var(--bg-subtle), transparent 35%); }
        & .asig-tl-hoy { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--color-warning); }
    }

    & .asig-tl-group { margin-bottom: 10px; }
    & .asig-tl-gh {
        display: flex; align-items: center; gap: 8px;
        padding: 4px 0 6px;
        position: relative; z-index: 2;

        & b { font-size: 0.8rem; }
        & small { font-size: 0.64rem; color: var(--text-muted); }
    }

    & .asig-tl-row {
        display: grid; grid-template-columns: var(--tl-lbl-w) 1fr;
        align-items: center; min-height: 30px;

        &:hover { background: color-mix(in oklch, var(--bg-card-hover), transparent 40%); }
    }
    & .asig-tl-lbl {
        display: flex; align-items: center; gap: 6px;
        border: 0; background: none; font-family: inherit; text-align: left;
        cursor: pointer; padding: 3px 8px 3px 0; min-width: 0;

        & b { font-size: 0.72rem; white-space: nowrap; }
        & small { font-size: 0.62rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        &:hover b { color: var(--color-accent); }
    }
    & .asig-tl-lane {
        position: relative; height: 100%; min-height: 30px;
        background-image: repeating-linear-gradient(90deg,
            var(--border-color) 0 1px, transparent 1px 100%);
        background-size: calc(100% / var(--tl-dias, 30)) 100%;
    }
    & .asig-tl-band {
        position: absolute; top: 5px; height: 20px;
        border-radius: 6px;
        background: var(--color-success); color: #fff;
        font-size: 0.62rem; font-weight: 700;
        display: flex; align-items: center; gap: 5px;
        padding: 0 7px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
        cursor: pointer; border: 1px solid color-mix(in oklch, black, transparent 85%);

        &.tl-INC { background: var(--color-fail); }
        &.is-abierta { border-top-right-radius: 0; border-bottom-right-radius: 0; border-right-style: dashed; }
        &.is-cerrada { opacity: .62; }
        &.is-vencida { outline: 1.5px solid var(--color-fail); outline-offset: 1px; }
        &:hover { filter: brightness(1.06); }
    }
    & .asig-tl-dot {
        width: 7px; height: 7px; border-radius: 50%; background: #fff; flex: none;
        animation: asig-pulse 1.4s ease-in-out infinite;
    }
}

@keyframes asig-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

@container (max-width: 768px) {
    .asig-timeline { --tl-lbl-w: 150px; }
    .asig-timeline .asig-tl-info { margin-left: 0; width: 100%; }
}

/* ========================================
   F17 (retoque): calendario «puntos» (look *_puntos + desborde elegante)
   ======================================== */
.cal-view .cal-day-events--puntos {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 4px;
    max-height: 104px;
    overflow: hidden;
}
.cal-view .cal-punto {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 0.62rem;
    font-weight: 600;
    background: color-mix(in oklch, var(--cal-llamada), white 88%);
    border-left: 3px solid var(--cal-llamada);
    border-radius: 0 7px 7px 0;
    padding: 1px 7px;
    cursor: pointer;

    & i {
        width: 7px; height: 7px; border-radius: 50%;
        background: var(--cal-llamada);
        flex: none;
        box-shadow: 0 0 4px color-mix(in oklch, var(--cal-llamada), transparent 35%);
    }
    & .cal-punto-t { overflow: hidden; text-overflow: ellipsis; }
    & .cal-punto-dur {
        font-style: normal; font-size: 0.56rem; font-weight: 700;
        color: var(--text-muted);
        border-left: 1px solid var(--border-strong);
        padding-left: 6px; margin-left: auto;
    }
    &:hover { filter: brightness(0.97); }
}
.cal-view .cal-punto.cal-band--incidencia {
    background: color-mix(in oklch, var(--cal-incidencia), white 88%);
    border-left-color: var(--cal-incidencia);
    & i { background: var(--cal-incidencia); box-shadow: none; }
}
.cal-view .cal-punto.cal-band--reparacion {
    background: color-mix(in oklch, var(--cal-reparacion), white 88%);
    border-left-color: var(--cal-reparacion);
    & i { background: var(--cal-reparacion); box-shadow: none; }
}
.cal-view .cal-punto.cal-band--recordatorio {
    background: color-mix(in oklch, var(--cal-recordatorio), white 88%);
    border-left-color: var(--cal-recordatorio);
    & i { background: var(--cal-recordatorio); box-shadow: none; }
}

/* agenda: píldora de hora + icono (look de los mockups agenda_02/04/05) */
.cal-view .cal-band--agenda > i {
    width: 12px; height: 12px; border-radius: 50%;
    background: rgba(255, 255, 255, 0.95);
    box-shadow: 0 0 6px rgba(255, 255, 255, 0.6);
}
.cal-view .cal-band--agenda b {
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    font-size: 0.7rem;
    background: rgba(0, 0, 0, 0.14);
    border-radius: 999px;
    padding: 0 7px;
    flex: none;
}
.cal-view .cal-band--agenda.cal-band--recordatorio b { background: rgba(91, 66, 18, 0.14); }

/* el botón «+N más» de los chips va como item del stack (no absoluto) */
.cal-view .cal-more--fit {
    position: static;
    top: auto; left: auto; bottom: auto;
    display: inline-flex;
    flex: none;
    align-self: flex-start;
    margin-top: 3px;
    white-space: nowrap;
}

/* ============================================================
   52. Base de conocimiento OKF (FASE 19 F19-3)
   ============================================================ */
.kb-view { display: flex; flex-direction: column; gap: 14px; }
.kb-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.kb-title { display: flex; align-items: center; gap: 8px; font-size: 1.05rem; font-weight: 700; margin: 0; }
.kb-bar-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.kb-actions { display: flex; gap: 4px; align-items: center; }
.kb-del { color: var(--color-fail) !important; }
.kb-okf-card {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
    padding: 12px 14px; border: 1px solid var(--border-color); border-radius: var(--radius-md);
    background: var(--bg-card); margin-bottom: 10px;
}
.kb-okf-card.is-inactiva { opacity: .62; }
.kb-okf-card h4 { margin: 0 0 6px; font-size: .95rem; }
.kb-okf-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
.kb-tag {
    background: var(--bg-subtle); border: 1px solid var(--border-color); border-radius: 999px;
    padding: 1px 9px; font-size: .68rem; font-weight: 600; color: var(--text-secondary);
}
.kb-tag.is-off { background: #fdeaea; border-color: #f5c6c6; color: #a33; }
.kb-okf-resum { margin: 0; font-size: .8rem; color: var(--text-secondary); }
.kb-okf-actions { display: flex; gap: 4px; align-items: center; flex-shrink: 0; }
.kb-md {
    background: var(--bg-app); border: 1px solid var(--border-color); border-radius: var(--radius-sm);
    padding: 10px 12px; font-family: var(--font-mono); font-size: .74rem; line-height: 1.5;
    max-height: 320px; overflow: auto; white-space: pre-wrap; word-break: break-word;
}
.kb-json {
    background: #0f172a; color: #dbe4f3; border-radius: var(--radius-sm); padding: 10px 12px;
    font-family: var(--font-mono); font-size: .72rem; line-height: 1.5; max-height: 360px;
    overflow: auto; white-space: pre-wrap;
}
.kb-details { margin-top: 10px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 8px 12px; }
.kb-details summary { cursor: pointer; font-size: .78rem; font-weight: 600; color: var(--text-secondary); }
.kb-pasos { margin: 8px 0 0 20px; font-size: .8rem; }
.kb-pasos li { margin: 3px 0; }
.kb-okf-view .blk { border: 1px solid var(--border-color); border-radius: var(--radius-sm); padding: 8px 11px; margin-bottom: 8px; background: var(--bg-card); }
.kb-okf-view .lbl { font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); font-weight: 700; margin-bottom: 4px; }
.kb-okf-view .txt { font-size: .82rem; }
.kb-okf-view ul, .kb-okf-view ol { margin-left: 18px; font-size: .8rem; }

/* =====================================================================
   F20: Banner «Batería / Pack afectado» de la ficha de incidencia
   (referencia destacada + enlace directo al detalle del pack)
   ===================================================================== */
.ficha-bateria {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-left: 4px solid var(--color-accent);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: 12px 16px;
    margin-bottom: 20px;
}
.ficha-bateria-icon {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in oklch, var(--color-accent) 14%, transparent);
    color: var(--color-accent);
    & i { width: 20px; height: 20px; }
}
.ficha-bateria-body { flex: 1 1 auto; min-width: 0; }
.ficha-bateria-label {
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    font-weight: 700;
    color: var(--text-muted);
    margin-bottom: 2px;
}
.ficha-bateria-value code {
    font-size: .95rem;
    font-weight: 600;
    background: transparent;
}
.ficha-bateria-sub {
    display: block;
    font-size: .76rem;
    color: var(--text-muted);
    margin-top: 2px;
    overflow-wrap: anywhere;
}
@media (max-width: 640px) {
    .ficha-bateria { flex-wrap: wrap; }
    .ficha-bateria .btn { width: 100%; justify-content: center; }
}

/* =====================================================================
   LOTE 2 P4: Trazabilidad LLM — split 40/60 (tabla|detalle) + modo
   inmersivo (detalle abierto → sidebar colapsado + sin pill de llamada)
   ===================================================================== */
.llm-tr-wrap {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    align-items: start;

    & > * { min-width: 0; }

    /* Traza seleccionada (solo escritorio; móvil ≤767 px se queda en 1
       columna con el detalle debajo — lo decide el JS con matchMedia,
       mismo mecanismo de app.js). 2fr/3fr = 40% / 60%. Altura contenida:
       header (--header-height) + paddings de .content-scroll + holgura. */
    &.traces-split {
        grid-template-columns: 2fr 3fr;

        /* las 2 columnas (lista + detalle) con scroll interno propio */
        & > * {
            max-height: calc(100vh - var(--header-height) - 100px);
            overflow-y: auto;
        }
    }
}

/* Modo inmersivo: con el detalle de traza abierto, la pill y el drawer de
   llamada desaparecen. El sidebar NO se oculta desde aquí: desde LOTE 3 F3
   se COLAPSA vía .sidebar-collapsed (el mecanismo del toggle manual, con
   su transición 0.3s global) y core/llm-traces.js guarda/restaura su
   estado previo al entrar/salir de la inmersión.
   El drawer se cierra por JS (CallSession.closeDrawer); esta regla es
   red de seguridad para que no se vea si queda en is-open. */
body.traces-fs #call-pill,
body.traces-fs #call-drawer {
    display: none;
}

/* ========================================
   45. Relaciones entre empresas (FASE F4)
   Diagrama SVG sin libs + ficha de nodo + popover de arista
   ======================================== */
.rel-tab {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;

    & > * { min-width: 0; }
}

.rel-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 16px;

    & .rel-legend {
        display: flex;
        flex-wrap: wrap;
        gap: 6px 14px;
        font-size: 0.74rem;
        color: var(--text-muted);
    }
    & .rel-legend-item { display: inline-flex; align-items: center; gap: 6px; }
    & .rel-toolbar-acts { display: flex; gap: 8px; }
}

/* Muestras de la leyenda */
.rel-sw {
    display: inline-block;
    width: 18px;
    height: 0;
    border-top: 2px solid var(--border-strong);

    &.rel-sw--ded { border-top-style: dashed; }
    &.rel-sw--indef {
        width: 10px;
        height: 10px;
        border: 1px solid var(--border-strong);
        border-radius: var(--radius-full);
        background-color: var(--bg-subtle);
    }
}

.rel-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 720px;
    padding: 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background-color: var(--bg-card);
}

.rel-main {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 14px;
    align-items: start;

    & > * { min-width: 0; }

    /* Ancho de componente → @container contra .main-content (sin @media) */
    @container (max-width: 1080px) {
        grid-template-columns: 1fr;
    }
}

.rel-canvas {
    padding: 12px;
    overflow-x: auto;   /* móvil: scroll horizontal del diagrama */

    & svg {
        display: block;
        width: 100%;
        height: auto;
        max-width: 900px;
        min-width: 640px;
        margin: 0 auto;
    }
}

/* Nodos del diagrama (colores de empresa via style=, el resto por clase) */
.rel-node {
    cursor: pointer;
    outline: none;

    & circle {
        stroke: var(--bg-card);
        stroke-width: 2;
    }
    &.rel-node--ded circle {
        /* solo evidencia deducida → borde discontinuo del color de la empresa */
        stroke: var(--emp-nc, var(--color-accent));
        stroke-dasharray: 4 3;
    }
    &:hover circle,
    &:focus circle,
    &.rel-node--sel circle {
        stroke: var(--color-accent);
        stroke-width: 3;
        stroke-dasharray: none;
    }
}

.rel-node-ini {
    fill: oklch(0.985 0 0);
    font-weight: 700;
    font-family: var(--font-sans);
    pointer-events: none;
}

.rel-node-name {
    fill: var(--text-secondary);
    font-size: 11px;
    font-family: var(--font-sans);
    pointer-events: none;
}

.rel-node-count {
    fill: var(--text-muted);
    font-size: 9.5px;
    font-family: var(--font-sans);
    pointer-events: none;
}

.rel-col-hd {
    fill: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    font-family: var(--font-sans);
}

.rel-sep {
    stroke: var(--border-color);
    stroke-dasharray: 6 4;
}

/* Aristas: deducida neutra / manual acento; hit-path gordo transparente */
.rel-edge {
    fill: none;
    stroke: var(--text-faint);
    stroke-width: 1.4;
    pointer-events: none;

    &.rel-edge--manual {
        stroke: var(--color-accent);
        stroke-width: 2;
    }
}

.rel-edge-hit {
    fill: none;
    stroke: transparent;
    stroke-width: 14;
    cursor: pointer;
}

.rel-edge-label {
    fill: var(--text-muted);
    font-size: 10px;
    font-family: var(--font-sans);
    paint-order: stroke;
    stroke: var(--bg-card);
    stroke-width: 3px;
    pointer-events: none;
}

.rel-arrow { fill: var(--text-faint); }
.rel-arrow--manual { fill: var(--color-accent); }

/* Ficha del nodo (panel derecho) */
.rel-detail {
    padding: 14px;
    max-height: calc(100dvh - 200px);
    overflow-y: auto;
}

.rel-tipo-grp { margin-bottom: 10px; }

.rel-rel { flex-wrap: wrap; }

.rel-pp-add {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 10px;
    padding: 10px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
}

.rel-pp-act { text-align: right; }

table.data-table tr.is-off { opacity: 0.5; }

/* Popover de evidencia de arista */
.rel-pop {
    position: absolute;
    z-index: 40;
    min-width: 240px;
    max-width: 320px;
    padding: 12px;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    font-size: 0.84rem;

    & .rel-pop-hd { font-weight: 600; margin-bottom: 6px; }
    & .rel-pop-row {
        display: flex;
        justify-content: space-between;
        gap: 12px;
        color: var(--text-muted);

        & b { color: var(--text-primary); }
    }
    & .rel-pop-det {
        margin-top: 6px;
        font-size: 0.8rem;
        color: var(--text-secondary);
    }
    & .rel-pop-acts {
        display: flex;
        justify-content: flex-end;
        gap: 8px;
        margin-top: 10px;
    }
}

/* ====== D2 (PLAN_LOTE_REFACTOR_EVIDENCIAS): evidencias en vivo de relación
   (ficha del nodo, pestaña Relaciones/F4 de /empresas). Listado compacto
   agrupado por Incidencias/Llamadas; filas clicables → deep-link vía Router.
   Reutiliza .badge-* y .emp-empty; solo tokens de :root, sin colores nuevos. */
.rel-ev {
    flex: 0 0 100%;
    display: flex;
    flex-direction: column;
    gap: 8px;

    & .rel-ev-load { margin: 0; }

    & .rel-ev-grp-hd {
        margin: 0 0 4px;
        font-size: 0.7rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--text-muted);
    }

    & .rel-ev-list {
        display: flex;
        flex-direction: column;
        gap: 4px;
        max-height: 300px;
        overflow-y: auto;
    }

    & .rel-ev-row {
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
        padding: 6px 8px;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-sm);
        background-color: var(--bg-card);
        color: var(--text-primary);
        font-family: inherit;
        font-size: 0.8rem;
        text-align: left;
        cursor: pointer;
        transition: background-color var(--transition-speed),
                    border-color var(--transition-speed);

        &:hover {
            background-color: var(--bg-card-hover);
            border-color: var(--border-strong);
        }
        &:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }

        & svg { flex: 0 0 auto; color: var(--text-muted); }
        & .rel-ev-tx {
            flex: 1 1 auto;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        & .rel-ev-fd { flex: 0 0 auto; font-size: 0.74rem; color: var(--text-muted); }
        & .badge { flex: 0 0 auto; }
    }

    & .rel-ev-empty {
        margin: 0;
        padding: 8px 10px;
        border: 1px dashed var(--border-strong);
        border-radius: var(--radius-sm);
        font-size: 0.8rem;
        font-weight: 400;
        cursor: help;
    }

    & .rel-ev-err { margin: 0; font-size: 0.78rem; color: var(--text-muted); }
}

/* ====== FASE E2: teléfono en el drawer + prompt de empresa al cierre ======
   El campo teléfono reutiliza .form-group/.form-input (design system global);
   el prompt del modal de cierre reutiliza el marco de .sug-wrap (clase puesta
   en JS sobre #call-cl-empresa). Solo tokens de :root. */
.call-tel-fg {
    & .form-label { white-space: nowrap; }
}

.call-emp-wrap {
    & .call-emp-row {
        display: flex;
        align-items: center;
        gap: 10px;
        flex-wrap: wrap;
        padding: 10px 14px 12px;
        font-size: 0.85rem;
    }

    & .call-emp-q { font-weight: 600; }

    & .call-emp-acts {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-wrap: wrap;
    }

    & .call-emp-sel {
        max-width: 260px;
        padding: 4px 8px;
        font-size: 0.82rem;
    }

    & .call-emp-ok {
        font-size: 0.82rem;
        font-weight: 600;
        color: var(--color-success);
    }

    & .call-emp-busy { font-size: 0.82rem; color: var(--text-muted); }
}

/* ====== H5 (PLAN_LOTE_HARDENING_PERF): utilerías compartidas consolidadas
   desde suite.css / ot.css (lazy H5) ======
   Estas clases se usaban en vistas deambulatorias (dashboard, preferences,
   admin, calendario, reporte, conocimiento…) pero vivían duplicadas en
   suite.css/ot.css — reglas que "parecen globales" van aquí (§1.4/§1.8).
   Diferencias resueltas documentando:
     · .hint — suite .78rem / ot .76rem → canónica .78rem (valor de la
       mayoría de vistas; en las hojas OT el cambio es imperceptible).
     · .seg-btn.is-active — suite color text-primary / ot color accent →
       canónica var(--color-accent) (estética de acento de la app; las
       vistas de solo-suite — calendario — adoptan el acento en el botón
       activo, cambio intencional y verificado en snapshot).
     · .grid-2 — fusión de la base (idéntica en ambos) + "min-width:0"
       (ot.css, FASE 6) + colapso a 1fr en 720px (suite.css, breakpoint
       de dispositivo, §1.5). */

.hint { font-size: .78rem; color: var(--text-muted); }

.caption { font-size: .8rem; color: var(--text-muted); }

.grid-2 {
    display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px;

    /* FASE 6 (de ot.css): sin min-width:0 la rejilla 1fr 1fr con inputs
       datetime desborda a la derecha en 375 px. */
    & > * { min-width: 0; }

    @media (max-width: 720px) { grid-template-columns: 1fr; }
}

/* segmented (idéntico en suite.css y ot.css — copia única) */
.segmented {
    display: inline-flex;
    background: var(--bg-subtle);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-full);
    padding: 2px;
    gap: 2px;
}
.seg-btn {
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-family: var(--font-sans);
    font-size: .76rem;
    font-weight: 500;
    padding: 4px 12px;
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: all .16s;

    &:hover { color: var(--text-primary); }
    &.is-active { background: #fff; color: var(--color-accent); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); }
}

.checkbox-row {
    display: flex; align-items: center; gap: 8px;
    font-size: 0.85rem; color: var(--text-primary);
    cursor: pointer; user-select: none;
    margin-top: 2px;

    & input { width: 16px; height: 16px; accent-color: var(--color-accent); cursor: pointer; }
}

/* Badge de OTs abiertas en el sidebar (Fase 4; de suite.css — el sidebar es
   global y no puede depender de una hoja lazy). */
.nav-badge {
    position: absolute;
    top: 4px;
    right: 6px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 9px;
    background: var(--color-accent);
    color: #fff;
    font-size: .64rem;
    font-weight: 700;
    display: grid;
    place-items: center;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
}

/* ========================================
   53. Dashboard minimalista (DS-F1, PLAN_LOTE_DASHBOARD_NC_AUTH)
   ========================================
   Seis piezas del mockup mockup/dashboard-minimal/index.html (bloques 1 y 2):
   - 4 estilos de tabla conmutables por .dashboard-view[data-dash-style]
     (A terminal / B plana / C minimal / D grafana). Default de código:
     grafana (DS-F1 atributo fijo; la preferencia por usuario llega en DS-P).
   - «Sin contenedor»: .datatable-wrapper.dash-plain (solo lo aplica
     views/dashboard.js — 0 cambios fuera del dashboard, verificación
     css_snapshot).
   - «1 línea por fila»: .dash-1line (nowrap + ellipsis + altura 34 px =
     mockup --row-h; table-layout: fixed SOLO con singleLine, decisión D-3).
   - Línea fina de filtros de flota sin etiquetas de formulario (D-5).
   Solo tokens oklch de :root (reglamento §1.2); los colores de severidad
   del mockup en hex literal (#b45309/#a16207) se sustituyen por el token
   --color-warning existente (los estados reales se pintan con las .badge
   de la app — el DOM no usa las clases sev-*, dot y chip-s del mockup). */

/* D-2: sin contenedor — la tabla se dibuja directa sobre el fondo de la app
   (borde/radio/fondo de tarjeta eliminados; solo se usa en el dashboard). */
.datatable-wrapper.dash-plain {
    border: 0;
    border-radius: 0;
    background: transparent;
}

/* D-3: 1 línea por fila garantizada. El tooltip nativo (title) lo añade
   DataTable con singleLine: true (components/table.js). */
.datatable-wrapper.dash-1line {
    /* fixed SOLO aquí: col.width reparte el ancho y una celda larga no
       fuerza el min-content (rompería el panel de media columna). */
    & .datatable-table { table-layout: fixed; }

    & .datatable-table th,
    & .datatable-table td {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* El span flex de la cabecera trunca con «…» (texto + icono sort). */
    & .datatable-th-content {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Chips de detalles de alerta: una sola línea (el resto se recorta). */
    & .alert-detail { flex-wrap: nowrap; }

    & .datatable-table tbody td { height: 34px; } /* mockup --row-h */
}

.dashboard-view {
    /* ---------- Estilo A: consola de terminal (mockup .t-term) ----------
       Monoespaciada, sin bordes verticales, severidad = badges de la app.
       Separador de fila = línea punteada muy tenue. */
    &[data-dash-style="terminal"] .data-table {
        font-family: var(--font-mono);
        font-size: 12.5px;

        & thead th {
            text-align: left;
            font-weight: 400;
            color: var(--text-faint);
            font-size: 11px;
            text-transform: lowercase;
            letter-spacing: 0;
            border-bottom: 1px solid var(--border-color);
            padding: 0 8px 4px 0;
        }

        & tbody td {
            padding: 3px 8px 3px 0;
            border-bottom: 1px dotted color-mix(in oklch, var(--border-strong) 55%, var(--bg-card));
            color: var(--text-secondary);
        }

        & tbody tr:hover td { background: var(--bg-subtle); }
    }

    /* ---------- Estilo B: tabla plana (mockup .t-flat) ----------
       Sans, sin zebra, sin borde vertical. Cabecera con subrayado fuerte;
       filas con hairline inferior. */
    &[data-dash-style="plana"] .data-table {
        font-size: 13px;

        & thead th {
            text-align: left;
            font-weight: 600;
            font-size: 11.5px;
            color: var(--text-muted);
            padding: 0 10px 6px 0;
            border-bottom: 1.5px solid var(--border-strong);
        }

        & tbody td {
            padding: 6px 10px 6px 0;
            border-bottom: 1px solid var(--border-color);
            color: var(--text-primary);
        }

        & tbody tr:hover td { background: var(--bg-subtle); }
    }

    /* ---------- Estilo C: minimalista / aire (mockup .t-air) ----------
       Sin NI UN borde en filas: solo la cabecera tiene un hairline.
       Filas separadas por aire (padding). */
    &[data-dash-style="minimal"] .data-table {
        font-size: 13px;

        & thead th {
            text-align: left;
            font-weight: 500;
            font-size: 11px;
            color: var(--text-faint);
            text-transform: uppercase;
            letter-spacing: .05em;
            padding: 0 12px 8px;
        }

        & thead tr { border-bottom: 1px solid var(--border-color); }

        & tbody td {
            padding: 8px 12px 8px 0;
            border: none;
        }

        & tbody tr:hover td { background: var(--bg-subtle); }
    }

    /* ---------- Estilo D: grafana (mockup .t-gf) ----------
       Cabecera con fondo gris lavado y texto semibold; filas compactas con
       hairline completo; barra de color de 3px en el margen izquierdo
       (mockup .rowbar) → box-shadow inset sobre td:first-child con tokens
       de estado existentes; si la primera celda lleva badge de estado
       (p. ej. flota → columna «Red») la barra toma su color (:has, §1.6). */
    &[data-dash-style="grafana"] .data-table {
        font-size: 12.5px;

        & thead th {
            text-align: left;
            font-weight: 600;
            font-size: 11px;
            color: var(--text-secondary);
            background: var(--bg-subtle);
            border-top: 1px solid var(--border-color);
            border-bottom: 1px solid var(--border-color);
            padding: 0 10px;
            height: 30px;
        }

        & thead th:first-child {
            border-left: 1px solid var(--border-color);
            border-top-left-radius: 6px;
        }

        & thead th:last-child {
            border-right: 1px solid var(--border-color);
            border-top-right-radius: 6px;
        }

        & tbody td {
            padding: 0 10px;
            border-bottom: 1px solid var(--border-color);
        }

        & tbody td:first-child {
            border-left: 1px solid var(--border-color);
            box-shadow: inset 3px 0 0 var(--color-accent);

            &:has(.badge-success) { box-shadow: inset 3px 0 0 var(--color-success); }
            &:has(.badge-fail) { box-shadow: inset 3px 0 0 var(--color-fail); }
            &:has(.badge-warning) { box-shadow: inset 3px 0 0 var(--color-warning); }
            &:has(.badge-process) { box-shadow: inset 3px 0 0 var(--color-process); }
        }

        & tbody td:last-child { border-right: 1px solid var(--border-color); }

        & tbody tr:hover td {
            background: color-mix(in oklch, var(--color-accent) 5%, var(--bg-card));
        }
    }

    /* ---------- D-5: filtros ligeros de flota en UNA línea fina inline,
       sin cajas ni etiquetas de formulario (mockup .fleet-filters) ----------
       Conservan los mismos controles (texto / red / tags), sin labels. */
    & .fleet-filters {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-wrap: wrap;
        margin-bottom: 10px;

        & input[type="text"] { flex: 1 1 180px; max-width: 300px; }
        & select { flex: 0 0 auto; max-width: 170px; }

        /* El contenedor de tags pierde su caja (padding/borde/min-height)
           y pasa a ser una hilera de chips dentro de la línea fina. */
        & .tags-selector {
            padding: 0;
            min-height: 0;
            background: transparent;
            border: 0;
        }
    }
}

/* ========================================
   54. No conformidades (NC-F, PLAN_LOTE_DASHBOARD_NC_AUTH)
   ========================================
   Sección «No conformidades» (Postventa): mockup
   mockup/dashboard-minimal/index.html bloque 3. Cabecera con franja de
   recuento + pill de origen («SharePoint · conector pendiente»), lista
   1 línea (DataTable singleLine — reutiliza .dash-1line de la sección 53)
   y fila expandida editable con panel de análisis de alcance (7 filtros).
   Solo tokens oklch de :root (reglamento §1.2); nesting (reglamento §1.1). */
.nc-view {
    display: flex;
    flex-direction: column;
    gap: 12px;

    & .nc-view-head {
        display: flex;
        align-items: center;
        gap: 10px;
        flex-wrap: wrap;

        & .nc-view-icon { width: 18px; height: 18px; color: var(--color-accent); }

        & .nc-view-title {
            margin: 0;
            font-size: 14px;
            font-weight: 600;
            color: var(--text-secondary);
            text-transform: uppercase;
            letter-spacing: .04em;
        }

        & .nc-count-strip {
            font-size: 11.5px;
            font-weight: 600;
            color: var(--text-secondary);
            background: var(--bg-subtle);
            border: 1px solid var(--border-color);
            border-radius: 99px;
            padding: 2px 9px;
        }

        /* Pill de origen (mockup .nc-source): el punto azul SharePoint
           usa el token --color-process (el hex #038387 del mockup no se
           lleva a la app — regla §1.2). */
        & .nc-src-pill {
            margin-left: auto;
            display: inline-flex;
            align-items: center;
            gap: 6px;
            font-size: 11px;
            font-weight: 600;
            color: var(--text-secondary);
            background: var(--bg-subtle);
            border: 1px solid var(--border-color);
            border-radius: 99px;
            padding: 2px 10px;

            & .nc-src-dot {
                width: 7px;
                height: 7px;
                border-radius: 99px;
                background: var(--color-process);
            }
        }
    }

    & .nc-legend {
        margin: 0;
        font-size: 12px;
        color: var(--text-faint);
    }

    & .nc-view-error {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 18px;
        color: var(--color-fail);
        background: color-mix(in oklch, var(--color-fail) 8%, var(--bg-card));
        border: 1px solid color-mix(in oklch, var(--color-fail) 25%, var(--border-color));
        border-radius: 8px;

        & i { width: 20px; height: 20px; }
        & p { margin: 0; }
    }
}

/* ---- Fila expandida (detalle editable + panel de alcance) ----
   La fila vive DENTRO de la tabla singleLine: anula nowrap/ellipsis/
   altura fija de .dash-1line SOLO en sus celdas (regla más específica). */
tr.nc-detail-row {
    & td {
        background: var(--bg-subtle);
        border-bottom: 1px solid var(--border-color);
        padding: 16px 18px 18px 8px;
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        height: auto;
    }
}
.datatable-wrapper.dash-1line tr.nc-detail-row td {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    height: auto;
}

.nc-detail-grid {
    display: grid;
    grid-template-columns: 1.2fr 1fr;
    gap: 20px;

    & .nc-detail-col { min-width: 0; }

    & .nc-field {
        margin-bottom: 10px;

        & label {
            display: block;
            font-size: 11px;
            font-weight: 600;
            color: var(--text-muted);
            text-transform: uppercase;
            letter-spacing: .04em;
            margin-bottom: 3px;
        }
    }

    & .nc-input {
        width: 100%;
        font-family: var(--font-sans);
        font-size: 13px;
        color: var(--text-primary);
        background: var(--bg-card);
        border: 1px solid var(--border-strong);
        border-radius: 6px;
        padding: 6px 9px;

        &:read-only {
            background: var(--bg-subtle);
            color: var(--text-secondary);
            border-style: dashed;
        }
    }

    & textarea.nc-input { min-height: 74px; resize: vertical; }

    & .nc-field-row {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 10px;
    }

    & .nc-btns {
        display: flex;
        gap: 8px;
        margin-top: 4px;
    }

    & .nc-note {
        margin: 8px 0 0;
        font-size: 11.5px;
        color: var(--text-faint);
    }

    /* ---- Panel de análisis de alcance (7 filtros) ---- */
    & .nc-scope {
        border-top: 1px solid var(--border-color);
        padding-top: 14px;

        & h4 {
            margin: 0 0 10px;
            font-size: 12px;
            font-weight: 700;
            text-transform: uppercase;
            letter-spacing: .05em;
            color: var(--text-secondary);
        }

        & .scope-filters {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 10px;

            & .nc-field { margin-bottom: 0; }
        }

        & .nc-scope-result {
            margin-top: 14px;
            display: flex;
            align-items: center;
            gap: 12px;
            flex-wrap: wrap;
        }

        & .nc-res-count {
            font-size: 13px;
            font-weight: 600;
            color: var(--text-secondary);
        }

        & .nc-res-empty {
            font-size: 12px;
            color: var(--text-muted);
        }

        & .nc-scope-packs { display: flex; gap: 6px; flex-wrap: wrap; }

        & .nc-pk {
            font-family: var(--font-mono);
            font-size: 11.5px;
            color: var(--text-secondary);
            background: var(--bg-card);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            padding: 3px 8px;
            cursor: default; /* tooltip nativo (title) con el detalle */

            & small { color: var(--text-faint); }
        }
    }
}

/* Ancho de COMPONENTE → @container contra .main-content (reglamento §1.5). */
@container (max-width: 860px) {
    .nc-detail-grid { grid-template-columns: 1fr; }
}
@container (max-width: 640px) {
    .nc-detail-grid .scope-filters { grid-template-columns: 1fr 1fr; }
}
