/* ═══════════════════════════════════════════════════════════════════════════
   OT Cybersecurity Toolkit — Contrato de tokens semánticos  (THEME-1)
   ═══════════════════════════════════════════════════════════════════════════

   Un solo sistema para TODA la aplicación. Nada específico de Governance.

   Los tokens representan una FUNCIÓN visual, no un color: `--ot-text` es «el
   texto principal», y resuelve a claro sobre oscuro o a oscuro sobre claro.

   Se declaran dos veces:
     :root, [data-bs-theme="light"]   → paleta clara (base correcta)
     [data-bs-theme="dark"]           → paleta oscura (la actual, preservada)

   Además se REASIGNAN las variables de Bootstrap 5.3 (`--bs-*`) desde estos
   tokens, para que los componentes heredados (alertas, badges, botones,
   tablas, dropdowns) sigan el tema sin recompilar el Sass en cada cambio.

   Contrastes: los valores de texto sobre sus superficies se midieron con el
   arnés `scripts/rg1/theme_contraste.js`; los que THEME-D0 dejó sin definir
   (texto deshabilitado, hover, focus, selected, enlace, destructivo) se
   fijaron explícitamente, no se dedujeron de otro color.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── MODO CLARO ─────────────────────────────────────────────────────────── */
:root,
html[data-bs-theme="light"] {
  /* Superficies */
  --ot-bg:            #f4f6f8;   /* fondo principal */
  --ot-bg-deepest:    #e7ebef;   /* fondo secundario, más hundido */
  --ot-bg-panel:      #eef1f4;   /* fondo de paneles */
  --ot-bg-card:       #ffffff;   /* superficie de tarjeta */
  --ot-bg-raised:     #ffffff;   /* superficie elevada (modal, dropdown) */
  --ot-bg-overlay:    rgba(244, 246, 248, 0.96);

  /* THEME-4 · Superficies con nombre de rol. El sistema ya tenía las
     superficies; lo que faltaba era un nombre para «cabecera de tarjeta» y
     «tira de pestañas», que es justo donde los módulos habían codificado el
     degradado oscuro. Alias para que el nombre del brief y el histórico
     apunten al mismo valor: una sola fuente de verdad por modo. */
  --ot-bg-app:        var(--ot-bg);         /* alias del fondo de aplicación */
  --ot-bg-surface:    var(--ot-bg-panel);   /* alias de superficie base */
  --ot-bg-surface-2:  var(--ot-bg-raised);  /* alias de superficie elevada */
  --ot-bg-header:     #e9edf2;   /* cabecera de tarjeta/panel */
  --ot-bg-header-2:   #dfe5ec;   /* segundo tono de la cabecera */
  --ot-bg-tab:        #e9edf2;   /* tira de pestañas y barras internas */
  --ot-bg-toolbar:    #eef1f4;   /* barras de herramientas internas */

  /* Elevación: en claro la jerarquía la dan el borde y una sombra suave,
     NO un fondo casi negro. */
  --ot-shadow:        0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.10);
  --ot-shadow-lg:     0 4px 10px rgba(16, 24, 40, 0.08), 0 2px 4px rgba(16, 24, 40, 0.06);
  --ot-shadow-inset:  inset 0 0 0 1px rgba(16, 24, 40, 0.02);

  /* THEME-4 · SUPERFICIES DE TINTE SEMANTICO. Esta familia SI faltaba en el
     contrato: el sistema tenía el color de acento (`--ot-info`) y el de texto
     (`--ot-info-text`), pero no el fondo tenue sobre el que los módulos
     apoyan sus «chips» de estado. Sin un nombre para ese rol, cada módulo se
     inventó el suyo en línea y en tono oscuro (#1e2d42, #0d2b1a, #3d1414…),
     que en modo claro quedaba como una mancha negra. En claro son tintes
     claros del mismo matiz; en oscuro, los tonos profundos de siempre. */
  --ot-info-surface:     #e7f0fd;
  --ot-success-surface:  #e6f4ec;
  --ot-warning-surface:  #fdf4e0;
  --ot-danger-surface:   #fdeceb;
  --ot-neutral-surface:  #eef1f4;
  --ot-alt-text:         #6b21a8;   /* tinta de categoria alterna (IoT, otros) */

  /* Bordes */
  --ot-border:        #ccd3da;   /* borde normal */
  --ot-border-light:  #e2e7ec;   /* divisor sutil */

  /* Texto — medidos sobre --ot-bg-card (#ffffff) */
  --ot-text:          #1c2128;   /* 15.8:1 */
  --ot-text-muted:    #5a6470;   /* 6.4:1  */
  --ot-text-disabled: #767f8a;   /* 4.5:1  — mínimo AA, no menos */
  --ot-text-on-accent:#ffffff;   /* texto sobre superficies de color */
  /* Cada superficie de estado lleva SU color de texto. En claro las
     superficies son oscuras, así que el texto va en blanco. */
  --ot-on-primary:   #ffffff;
  --ot-on-success:   #ffffff;
  --ot-on-warning:   #ffffff;
  --ot-on-danger:    #ffffff;
  --ot-on-info:      #ffffff;

  /* Interacción */
  --ot-link:          #0b5ed7;   /* 6.3:1 sobre tarjeta */
  --ot-link-hover:    #084298;
  --ot-hover:         #e9edf1;   /* fondo al pasar por encima */
  --ot-focus:         #0b5ed7;   /* anillo de foco */
  --ot-focus-ring:    rgba(11, 94, 215, 0.35);
  --ot-selected:      #dbe7fb;   /* fondo de fila/elemento seleccionado */
  --ot-selected-text: #10305e;

  /* Marca y estados — tono oscurecido para que el texto BLANCO encima
     alcance 4.5:1; THEME-D0 midió los tonos actuales entre 2.55:1 y 3.46:1. */
  --ot-primary:       #b3243c;   /* 6.0:1 con texto blanco */
  --ot-primary-hover: #8f1c30;
  --ot-destructive:   #b3243c;
  --ot-success:       #136c34;   /* 5.5:1 */
  --ot-warning:       #7a5200;   /* 5.7:1 */
  --ot-danger:        #b42318;   /* 6.1:1 */
  --ot-info:          #0b5ed7;   /* 6.3:1 */

  /* Texto de estado SOBRE superficie (no como fondo) */
  --ot-success-text:  #136c34;
  --ot-warning-text:  #7a5200;
  --ot-danger-text:   #b42318;
  --ot-info-text:     #0b5ed7;

  /* Fondos suaves de alerta y sus textos */
  --ot-alert-success-bg: #e6f4ea;  --ot-alert-success-fg: #0e5228;
  --ot-alert-warning-bg: #fdf3da;  --ot-alert-warning-fg: #5f4000;
  --ot-alert-danger-bg:  #fbeae8;  --ot-alert-danger-fg:  #8c1b12;
  --ot-alert-info-bg:    #e7f0fd;  --ot-alert-info-fg:    #0a4aa6;

  /* Insignias */
  --ot-badge-bg:      #e7ebef;
  --ot-badge-fg:      #1c2128;

  /* Controles */
  --ot-input-bg:          #ffffff;
  --ot-input-fg:          #1c2128;
  --ot-input-border:      #b9c2cb;
  --ot-input-placeholder: #767f8a;
  --ot-disabled-bg:       #e7ebef;
  --ot-disabled-fg:       #767f8a;
  --ot-disabled-border:   #ccd3da;

  /* Tablas */
  --ot-table-bg:        #ffffff;
  --ot-table-header-bg: #eef1f4;
  --ot-table-header-fg: #1c2128;
  --ot-table-stripe:    #f7f9fa;
  --ot-table-hover:     #eef4fb;
  --ot-table-selected:  #dbe7fb;
  --ot-table-border:    #dde3e9;

  /* Grafos y diagramas */
  --ot-graph-bg:        #ffffff;
  --ot-graph-node:      #dbe7fb;
  --ot-graph-node-fg:   #10305e;
  --ot-graph-edge:      #8b96a3;
  --ot-graph-label:     #1c2128;
  --ot-graph-highlight: #b3243c;

  /* Acentos heredados (se conservan los nombres existentes) */
  --ot-accent:       #b3243c;
  --ot-accent2:      #a85a00;
  --ot-accent-glow:  rgba(179, 36, 60, 0.10);
  --ot-steel:        #1a5fb4;
  --ot-steel-light:  #0b5ed7;
  --ot-steel-glow:   rgba(26, 95, 180, 0.12);
  --ot-amber:        #7a5200;
  --ot-amber-glow:   rgba(122, 82, 0, 0.10);

  /* Niveles de riesgo OT — MISMA clasificación funcional, tono adaptado para
     ser legible sobre superficie clara. No cambian categorías ni umbrales. */
  --ot-critical: #7a0b1c;
  --ot-high:     #b42318;
  --ot-medium:   #7a5200;
  --ot-low:      #136c34;
}

/* ── MODO OSCURO ────────────────────────────────────────────────────────── */
html[data-bs-theme="dark"] {
  --ot-bg:            #0d1117;
  --ot-bg-deepest:    #060a0e;
  --ot-bg-panel:      #161b22;
  --ot-bg-card:       #1c2230;
  --ot-bg-raised:     #212936;
  --ot-bg-overlay:    rgba(13, 17, 23, 0.95);

  /* THEME-4 · mismos roles, valores del modo oscuro. Aquí SÍ viven los
     tonos metálicos que antes estaban codificados en las reglas compartidas. */
  --ot-bg-app:        var(--ot-bg);
  --ot-bg-surface:    var(--ot-bg-panel);
  --ot-bg-surface-2:  var(--ot-bg-raised);
  --ot-bg-header:     #1f2937;
  --ot-bg-header-2:   #161b22;
  --ot-bg-tab:        #161b22;
  --ot-bg-toolbar:    #161b22;

  --ot-shadow:        0 6px 18px rgba(0, 0, 0, 0.32);
  --ot-shadow-lg:     0 10px 26px rgba(0, 0, 0, 0.42);
  --ot-shadow-inset:  inset 0 0 0 1px rgba(255, 255, 255, 0.015);

  /* THEME-4 · tintes semánticos del modo oscuro: los tonos que los módulos
     llevaban codificados en línea, ahora con nombre y en un solo sitio. */
  --ot-info-surface:     #1e2d42;
  --ot-success-surface:  #0d2b1a;
  --ot-warning-surface:  #332701;
  --ot-danger-surface:   #3d1414;
  --ot-neutral-surface:  #161b22;
  --ot-alt-text:         #d2a8ff;

  --ot-border:        #30363d;
  --ot-border-light:  #3d4551;

  /* Texto — medidos sobre --ot-bg-card (#1c2230) */
  --ot-text:          #c9d1d9;   /* 11.0:1 */
  --ot-text-muted:    #9aa4b0;   /* 6.6:1 — era #8b949e (5.4:1) */
  --ot-text-disabled: #7d8792;   /* 4.5:1 — antes no existía */
  --ot-text-on-accent:#0d1117;
  /* En oscuro las superficies de estado son tintes CLAROS —para que destaquen
     sobre la página oscura— y por tanto su texto debe ser OSCURO. Usar blanco
     encima daba 1.41:1. */
  --ot-on-primary:   #1a0308;
  --ot-on-success:   #06240d;
  --ot-on-warning:   #2e2000;
  --ot-on-danger:    #1c0503;
  --ot-on-info:      #06203d;

  --ot-link:          #79b8ff;   /* 7.4:1 sobre tarjeta */
  --ot-link-hover:    #a5cdff;
  --ot-hover:         #232b3a;
  --ot-focus:         #79b8ff;
  --ot-focus-ring:    rgba(121, 184, 255, 0.40);
  --ot-selected:      #1e2d42;
  --ot-selected-text: #d7e5f7;

  /* Marca y estados. Los tonos de FONDO se aclaran respecto a los actuales
     para que el texto oscuro encima alcance AA; THEME-D0 midió blanco sobre
     estos fondos entre 2.55:1 y 3.46:1. */
  --ot-primary:       #ff7a8c;
  --ot-primary-hover: #ff9dab;
  --ot-destructive:   #ff7a8c;
  --ot-success:       #56d364;
  --ot-warning:       #e3b341;
  --ot-danger:        #ff7b72;
  --ot-info:          #79b8ff;

  --ot-success-text:  #56d364;   /* 8.0:1 sobre tarjeta */
  --ot-warning-text:  #e3b341;   /* 8.9:1 */
  --ot-danger-text:   #ff7b72;   /* 7.3:1 */
  --ot-info-text:     #79b8ff;   /* 7.4:1 */

  --ot-alert-success-bg: #10281a;  --ot-alert-success-fg: #7ee08a;
  --ot-alert-warning-bg: #2a2110;  --ot-alert-warning-fg: #edc96b;
  --ot-alert-danger-bg:  #2d1517;  --ot-alert-danger-fg:  #ff9d96;
  --ot-alert-info-bg:    #10233a;  --ot-alert-info-fg:    #9ecbff;

  --ot-badge-bg:      #2a3242;
  --ot-badge-fg:      #d7dee7;

  --ot-input-bg:          #161b22;
  --ot-input-fg:          #c9d1d9;
  --ot-input-border:      #3d4551;
  --ot-input-placeholder: #7d8792;
  --ot-disabled-bg:       #21262d;
  --ot-disabled-fg:       #7d8792;
  --ot-disabled-border:   #3d4551;

  --ot-table-bg:        #1c2230;
  --ot-table-header-bg: #161b22;
  --ot-table-header-fg: #c9d1d9;
  --ot-table-stripe:    #191f2b;
  --ot-table-hover:     #232b3a;
  --ot-table-selected:  #1e2d42;
  --ot-table-border:    #30363d;

  --ot-graph-bg:        #1c2230;
  --ot-graph-node:      #1e2d42;
  --ot-graph-node-fg:   #d7e5f7;
  --ot-graph-edge:      #6e7681;
  --ot-graph-label:     #c9d1d9;
  --ot-graph-highlight: #ff7a8c;

  --ot-accent:       #e94560;
  --ot-accent2:      #f7941d;
  --ot-accent-glow:  rgba(233, 69, 96, 0.12);
  --ot-steel:        #3a7bd5;
  --ot-steel-light:  #58a6ff;
  --ot-steel-glow:   rgba(58, 123, 213, 0.15);
  --ot-amber:        #f0a500;
  --ot-amber-glow:   rgba(240, 165, 0, 0.12);

  /* Niveles de riesgo OT. `--ot-critical` era #8b1a2d y THEME-D0 lo midió a
     1.73:1 sobre tarjeta: ilegible. Se aclara conservando el tono vino que lo
     distingue de «Alto». La clasificación no cambia. */
  --ot-critical: #f2798f;   /* era #8b1a2d */
  --ot-high:     #ff7b72;   /* era #dc2626 (3.29:1) */
  --ot-medium:   #e3b341;
  --ot-low:      #56d364;
}

/* ── Alias de compatibilidad ────────────────────────────────────────────────
   `--ot-bg-dark` era el nombre del fondo principal cuando sólo había un tema.
   Se conserva para no romper las 181 referencias existentes mientras los
   módulos migran a `--ot-bg`. */
:root, html[data-bs-theme="light"], html[data-bs-theme="dark"] {
  --ot-bg-dark: var(--ot-bg);
}

/* ═══════════════════════════════════════════════════════════════════════════
   PUENTE HACIA BOOTSTRAP 5.3
   Los componentes heredados leen `--bs-*`. Reasignándolas desde los tokens,
   alertas, badges, botones, tablas y dropdowns siguen el tema sin recompilar.
   ═══════════════════════════════════════════════════════════════════════════ */
:root, html[data-bs-theme="light"], html[data-bs-theme="dark"] {
  --bs-body-bg:             var(--ot-bg);
  --bs-body-color:          var(--ot-text);
  --bs-secondary-color:     var(--ot-text-muted);
  --bs-tertiary-color:      var(--ot-text-disabled);
  --bs-emphasis-color:      var(--ot-text);
  --bs-border-color:        var(--ot-border);
  --bs-border-color-translucent: var(--ot-border-light);
  --bs-link-color:          var(--ot-link);
  --bs-link-hover-color:    var(--ot-link-hover);
  --bs-code-color:          var(--ot-danger-text);
  --bs-highlight-bg:        var(--ot-selected);

  --bs-body-bg-rgb:    var(--ot-bg-rgb, 13, 17, 23);
  --bs-body-color-rgb: var(--ot-text-rgb, 201, 209, 217);
}

/* ═══════════════════════════════════════════════════════════════════════════
   COMPONENTES GLOBALES  (THEME-1 · Fase 5)

   bslib COMPILA los valores de Sass como literales dentro de las propiedades
   de cada componente —`.table{--bs-table-bg:#fff}`, `.dropdown-menu{--bs-dropdown-bg:#fff}`—
   y `.form-control` ni siquiera usa variables. Por eso un token global no basta:
   aquí se reasigna cada componente desde los tokens, en los dos modos.

   Alcance: sólo componentes GLOBALES y compartidos. Las tablas DT, los grafos,
   los mapas de calor y los estilos locales de cada módulo tienen sus propios
   checkpoints.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Fondo principal ───────────────────────────────────────────────────
   El fondo llevaba la imagen de presentación con un velo oscuro fijo. En claro
   el velo debe ser claro, o la imagen ennegrece la página entera. */
html { background: var(--ot-bg) !important; min-height: 100vh; }
html[data-bs-theme="light"], html:not([data-bs-theme]) {
  background:
    linear-gradient(rgba(244, 246, 248, 0.88), rgba(244, 246, 248, 0.88)),
    url('../img/bg_presentation.png') center center / cover no-repeat fixed,
    var(--ot-bg) !important;
}
html[data-bs-theme="dark"] {
  background:
    linear-gradient(rgba(10, 14, 24, 0.62), rgba(10, 14, 24, 0.62)),
    url('../img/bg_presentation.png') center center / cover no-repeat fixed,
    #0a0e18 !important;
}
body { background-color: transparent; color: var(--ot-text); }

/* ── 2 · Barra superior y navegación ─────────────────────────────────────── */
.navbar {
  --bs-navbar-color:          var(--ot-text-muted);
  --bs-navbar-hover-color:    var(--ot-text);
  --bs-navbar-active-color:   var(--ot-text);
  --bs-navbar-disabled-color: var(--ot-text-disabled);
  background-color: var(--ot-bg-panel) !important;
  border-bottom: 1px solid var(--ot-border);
}
.navbar .navbar-brand, .navbar .nav-link { color: var(--ot-text); }
.nav-tabs { --bs-nav-tabs-link-active-bg: var(--ot-bg-card);
            --bs-nav-tabs-link-active-color: var(--ot-text);
            --bs-nav-tabs-border-color: var(--ot-border); }
.nav-link { color: var(--ot-text-muted); }
.nav-link:hover, .nav-link:focus { color: var(--ot-text); }
.nav-link.active { color: var(--ot-text); }

/* ── 3 · Sidebar y 5 · superficies compartidas ───────────────────────────── */
.bslib-sidebar-layout > .sidebar,
.bslib-sidebar-layout > .sidebar > .sidebar-content {
  background-color: var(--ot-bg-panel); color: var(--ot-text);
  border-color: var(--ot-border);
}
.card, .bslib-card {
  --bs-card-bg:           var(--ot-bg-card);
  --bs-card-color:        var(--ot-text);
  --bs-card-border-color: var(--ot-border);
  --bs-card-cap-bg:       var(--ot-bg-panel);
}
.modal-content { --bs-modal-bg: var(--ot-bg-raised);
                 --bs-modal-color: var(--ot-text);
                 --bs-modal-border-color: var(--ot-border); }
.modal-header, .modal-footer { border-color: var(--ot-border); }
.offcanvas { --bs-offcanvas-bg: var(--ot-bg-panel); --bs-offcanvas-color: var(--ot-text); }
.accordion { --bs-accordion-bg: var(--ot-bg-card); --bs-accordion-color: var(--ot-text);
             --bs-accordion-border-color: var(--ot-border);
             --bs-accordion-btn-color: var(--ot-text); }
.list-group { --bs-list-group-bg: var(--ot-bg-card); --bs-list-group-color: var(--ot-text);
              --bs-list-group-border-color: var(--ot-border);
              --bs-list-group-action-hover-bg: var(--ot-hover);
              --bs-list-group-active-bg: var(--ot-selected);
              --bs-list-group-active-color: var(--ot-selected-text);
              --bs-list-group-active-border-color: var(--ot-border); }

/* ── 6 · Tipografía ──────────────────────────────────────────────────────── */
h1, h2, h3, h4, h5, h6 { color: var(--ot-text); }
.text-muted, .small.text-muted { color: var(--ot-text-muted) !important; }
.text-secondary { color: var(--ot-text-muted) !important; }
hr, .dropdown-divider { border-color: var(--ot-border); }

/* ── 7 · Enlaces ─────────────────────────────────────────────────────────── */
a { color: var(--ot-link); }
a:hover, a:focus { color: var(--ot-link-hover); }

/* ── 8 · Botones compartidos ─────────────────────────────────────────────── */
.btn-primary   { --bs-btn-bg: var(--ot-primary);   --bs-btn-border-color: var(--ot-primary);
                 --bs-btn-color: var(--ot-on-primary);
                 --bs-btn-hover-bg: var(--ot-primary-hover);
                 --bs-btn-hover-border-color: var(--ot-primary-hover);
                 --bs-btn-hover-color: var(--ot-on-primary); }
.btn-danger    { --bs-btn-bg: var(--ot-danger); --bs-btn-border-color: var(--ot-danger);
                 --bs-btn-color: var(--ot-on-danger); }
.btn-success   { --bs-btn-bg: var(--ot-success); --bs-btn-border-color: var(--ot-success);
                 --bs-btn-color: var(--ot-text-on-accent); }
.btn-warning   { --bs-btn-bg: var(--ot-warning); --bs-btn-border-color: var(--ot-warning);
                 --bs-btn-color: var(--ot-text-on-accent); }
.btn-info      { --bs-btn-bg: var(--ot-info); --bs-btn-border-color: var(--ot-info);
                 --bs-btn-color: var(--ot-text-on-accent); }
.btn-secondary { --bs-btn-bg: var(--ot-bg-raised); --bs-btn-border-color: var(--ot-border);
                 --bs-btn-color: var(--ot-text);
                 --bs-btn-hover-bg: var(--ot-hover);
                 --bs-btn-hover-color: var(--ot-text); }
.btn-light     { --bs-btn-bg: var(--ot-bg-panel); --bs-btn-color: var(--ot-text);
                 --bs-btn-border-color: var(--ot-border); }
.btn-outline-secondary { --bs-btn-color: var(--ot-text);
                          --bs-btn-border-color: var(--ot-border);
                          --bs-btn-hover-bg: var(--ot-hover);
                          --bs-btn-hover-color: var(--ot-text);
                          --bs-btn-hover-border-color: var(--ot-border); }

/* ── 9 · disabled, hover, focus, selected ────────────────────────────────── */
.btn:disabled, .btn.disabled, fieldset:disabled .btn {
  /* Bootstrap baja la opacidad a .65 y eso falsea el color declarado: se fija
     el par completo y se restituye la opacidad. Es la misma corrección que
     GOV-RG1.2 hizo puntualmente, ahora para todos los botones. */
  opacity: 1;
  background-color: var(--ot-disabled-bg) !important;
  border-color: var(--ot-disabled-border) !important;
  color: var(--ot-disabled-fg) !important;
}
.form-control:disabled, .form-select:disabled, .form-control[readonly] {
  background-color: var(--ot-disabled-bg); color: var(--ot-disabled-fg);
  border-color: var(--ot-disabled-border); opacity: 1;
}
:focus-visible, .btn:focus-visible, .form-control:focus, .form-select:focus {
  outline: 2px solid var(--ot-focus);
  outline-offset: 1px;
  box-shadow: 0 0 0 .2rem var(--ot-focus-ring) !important;
  border-color: var(--ot-focus);
}
::selection { background: var(--ot-selected); color: var(--ot-selected-text); }

/* ── 10 · Badges ─────────────────────────────────────────────────────────── */
/* Las insignias cuyo fondo ponen los módulos en línea son SIEMPRE colores
   vivos —se diseñaron para verse sobre el fondo oscuro—, así que su texto debe
   ser tinta oscura en ambos modos. Poner aquí el gris claro del tema bajaba
   esas insignias de 9.87:1 a 1.41:1. Las que sí controlamos (`.badge.bg-*`)
   llevan su propio par más abajo. */
.badge { --bs-badge-color: #10151c; }
.badge.bg-light, .badge.bg-secondary {
  background-color: var(--ot-badge-bg) !important; color: var(--ot-badge-fg) !important; }
.badge.bg-primary { background-color: var(--ot-primary) !important; color: var(--ot-on-primary) !important; }
.badge.bg-success { background-color: var(--ot-success) !important; color: var(--ot-on-success) !important; }
.badge.bg-warning { background-color: var(--ot-warning) !important; color: var(--ot-on-warning) !important; }
.badge.bg-danger  { background-color: var(--ot-danger)  !important; color: var(--ot-text-on-accent) !important; }
.badge.bg-info    { background-color: var(--ot-info)    !important; color: var(--ot-text-on-accent) !important; }

/* ── 11 · Alertas ────────────────────────────────────────────────────────────
   THEME-D0 midió `alert-info` a 1.31:1 y `alert-warning` a 1.33:1: Bootstrap
   las deriva de la paleta y quedaban ilegibles. Aquí se declara el par
   fondo/texto de cada una. */
.alert          { --bs-alert-border-color: var(--ot-border); }
.alert-success  { --bs-alert-bg: var(--ot-alert-success-bg); --bs-alert-color: var(--ot-alert-success-fg); }
.alert-warning  { --bs-alert-bg: var(--ot-alert-warning-bg); --bs-alert-color: var(--ot-alert-warning-fg); }
.alert-danger   { --bs-alert-bg: var(--ot-alert-danger-bg);  --bs-alert-color: var(--ot-alert-danger-fg); }
.alert-info     { --bs-alert-bg: var(--ot-alert-info-bg);    --bs-alert-color: var(--ot-alert-info-fg); }
.alert-success, .alert-warning, .alert-danger, .alert-info {
  background-color: var(--bs-alert-bg) !important;
  color: var(--bs-alert-color) !important;
  border-color: var(--ot-border);
}
.alert strong, .alert b, .alert .alert-link { color: inherit !important; }

/* ── 12 · Formularios e inputs ───────────────────────────────────────────────
   `.form-control` no usa variables: bslib compila el color literal. */
.form-control, .form-select, textarea.form-control, .form-control-plaintext {
  background-color: var(--ot-input-bg) !important;
  color: var(--ot-input-fg) !important;
  border-color: var(--ot-input-border) !important;
}
.form-control::placeholder, .form-select::placeholder { color: var(--ot-input-placeholder); }
.form-label, .col-form-label, .form-check-label { color: var(--ot-text); }
.form-text { color: var(--ot-text-muted); }
.input-group-text { background-color: var(--ot-bg-panel); color: var(--ot-text);
                     border-color: var(--ot-input-border); }
.form-check-input { background-color: var(--ot-input-bg); border-color: var(--ot-input-border); }
.form-check-input:checked { background-color: var(--ot-primary); border-color: var(--ot-primary); }
.invalid-feedback, .text-danger { color: var(--ot-danger-text) !important; }
.valid-feedback { color: var(--ot-success-text) !important; }

/* selectize — el selector de organización, planta y assessment */
.selectize-input, .selectize-dropdown {
  background-color: var(--ot-input-bg) !important;
  color: var(--ot-input-fg) !important;
  border-color: var(--ot-input-border) !important;
}
.selectize-dropdown .option { color: var(--ot-input-fg); }
.selectize-dropdown .option.active,
.selectize-dropdown .active { background-color: var(--ot-selected) !important;
                               color: var(--ot-selected-text) !important; }
.selectize-input .item { color: var(--ot-input-fg) !important; }

/* ── 13 · Bordes y divisores ─────────────────────────────────────────────── */
.border, .border-top, .border-bottom, .border-start, .border-end {
  border-color: var(--ot-border) !important; }

/* ── 15 · Desplegables y tooltips globales ───────────────────────────────── */
.dropdown-menu { --bs-dropdown-bg: var(--ot-bg-raised);
                 --bs-dropdown-color: var(--ot-text);
                 --bs-dropdown-link-color: var(--ot-text);
                 --bs-dropdown-link-hover-bg: var(--ot-hover);
                 --bs-dropdown-link-hover-color: var(--ot-text);
                 --bs-dropdown-link-active-bg: var(--ot-selected);
                 --bs-dropdown-link-active-color: var(--ot-selected-text);
                 --bs-dropdown-border-color: var(--ot-border); }
.tooltip { --bs-tooltip-bg: var(--ot-bg-raised); --bs-tooltip-color: var(--ot-text); }
.popover { --bs-popover-bg: var(--ot-bg-raised); --bs-popover-body-color: var(--ot-text);
           --bs-popover-header-bg: var(--ot-bg-panel);
           --bs-popover-header-color: var(--ot-text);
           --bs-popover-border-color: var(--ot-border); }

/* ── Tablas de Bootstrap (las DT tienen su propio checkpoint) ────────────── */
.table { --bs-table-bg: var(--ot-table-bg);
         --bs-table-color: var(--ot-text);
         --bs-table-border-color: var(--ot-table-border);
         --bs-table-striped-bg: var(--ot-table-stripe);
         --bs-table-striped-color: var(--ot-text);
         --bs-table-hover-bg: var(--ot-table-hover);
         --bs-table-hover-color: var(--ot-text); }
.table > thead { background-color: var(--ot-table-header-bg); color: var(--ot-table-header-fg); }

/* ── Utilidades .bg-* y .text-bg-* ──────────────────────────────────────────
   Bootstrap compila estos colores como literales y los módulos los usan mucho
   (`.badge.bg-warning`, `.bg-success`). Cada superficie recibe su par de texto:
   con el tinte claro del modo oscuro, el texto blanco daba 1.41:1. */
.bg-primary, .text-bg-primary { background-color: var(--ot-primary) !important; color: var(--ot-on-primary) !important; }
.bg-success, .text-bg-success { background-color: var(--ot-success) !important; color: var(--ot-on-success) !important; }
.bg-warning, .text-bg-warning { background-color: var(--ot-warning) !important; color: var(--ot-on-warning) !important; }
.bg-danger,  .text-bg-danger  { background-color: var(--ot-danger)  !important; color: var(--ot-on-danger)  !important; }
.bg-info,    .text-bg-info    { background-color: var(--ot-info)    !important; color: var(--ot-on-info)    !important; }
.bg-secondary, .text-bg-secondary { background-color: var(--ot-badge-bg) !important; color: var(--ot-badge-fg) !important; }
.bg-light, .text-bg-light { background-color: var(--ot-bg-panel) !important; color: var(--ot-text) !important; }
.bg-dark,  .text-bg-dark  { background-color: var(--ot-bg-deepest) !important; color: var(--ot-text) !important; }
.bg-body, .bg-body-tertiary, .bg-body-secondary { background-color: var(--ot-bg-panel) !important; }

/* Texto de estado sobre superficie neutra (no como fondo). */
.text-success { color: var(--ot-success-text) !important; }
.text-warning { color: var(--ot-warning-text) !important; }
.text-info    { color: var(--ot-info-text) !important; }
.text-primary { color: var(--ot-link) !important; }

/* Bootstrap compila `link-color` como literal en varias reglas; se fuerza el
   token para que el enlace siga el modo. */
a, .btn-link, .nav-link.active, .page-link { color: var(--ot-link); }
a:hover, .btn-link:hover { color: var(--ot-link-hover); }

/* ── Correcciones de regresión detectadas al comparar con THEME-D0 ──────────
   Bootstrap compila $success/$warning/$danger/$info como literales en muchas
   reglas. Con la base clara esos literales son oscuros, y en modo oscuro
   aparecían como TEXTO sobre superficies oscuras (medido: 2.30:1 a 2.96:1).
   Estas clases no estaban cubiertas por los overrides de componente. */
/* THEME-3 · Shiny emite `btn btn-default ... btn-primary` en el mismo botón.
   Con la misma especificidad e `!important` ganaba la regla declarada después
   —ésta— y pisaba la tinta de la variante de color, dejando el texto a 2.48:1
   sobre el acento. Se excluyen explícitamente las variantes. */
.btn-default:not(.btn-primary):not(.btn-success):not(.btn-warning):not(.btn-danger):not(.btn-info),
a.btn-default:not(.btn-primary):not(.btn-success):not(.btn-warning):not(.btn-danger):not(.btn-info) {
  color: var(--ot-text) !important;
  border-color: var(--ot-border) !important;
}
.btn-default:hover, a.btn-default:hover { background-color: var(--ot-hover) !important; }
/* `.action-label` es el texto interior de los `actionBttn`, cuyo fondo lo pone
   CADA MÓDULO en línea: unos vivos y otros oscuros. La infraestructura no puede
   elegir la tinta sin conocer ese fondo —se probaron ambas y cada una falla en
   la mitad de los casos—, así que hereda del botón y los casos de fondo vivo
   quedan como deuda de módulo para THEME-6, medidos uno a uno en el reporte.
   En THEME-D0 acertaban por accidente: la paleta invertida les daba tinta
   oscura. */
.action-label { color: inherit; }

/* Paginación (`.page-link`): 5.12:1 -> 3.43:1 al heredar la base clara. */
.pagination {
  --bs-pagination-bg: var(--ot-bg-card);
  --bs-pagination-color: var(--ot-link);
  --bs-pagination-border-color: var(--ot-border);
  --bs-pagination-hover-bg: var(--ot-hover);
  --bs-pagination-hover-color: var(--ot-link-hover);
  --bs-pagination-active-bg: var(--ot-primary);
  --bs-pagination-active-color: var(--ot-on-primary);
  --bs-pagination-active-border-color: var(--ot-primary);
  --bs-pagination-disabled-bg: var(--ot-disabled-bg);
  --bs-pagination-disabled-color: var(--ot-disabled-fg);
  --bs-pagination-disabled-border-color: var(--ot-disabled-border);
}
.page-link { background-color: var(--ot-bg-card); color: var(--ot-link);
             border-color: var(--ot-border); }
.page-item.disabled .page-link { background-color: var(--ot-disabled-bg);
                                  color: var(--ot-disabled-fg); }

/* Bordes de estado (`.border-success` y compañía) siguen el modo. */
.border-success { border-color: var(--ot-success) !important; }
.border-warning { border-color: var(--ot-warning) !important; }
.border-danger  { border-color: var(--ot-danger)  !important; }
.border-info    { border-color: var(--ot-info)    !important; }
.border-primary { border-color: var(--ot-primary) !important; }

/* Texto deshabilitado: 4.17:1 en oscuro y 3.39:1 en claro, ambos bajo 4.5. */
html[data-bs-theme="dark"]  { --ot-disabled-fg: #949daa; }
html[data-bs-theme="light"], :root { --ot-disabled-fg: #5e6773; }  /* 4.78:1 sobre el fondo deshabilitado */

/* Variantes `outline`: Bootstrap compila el tono claro como color de texto y en
   modo oscuro quedaban en 2.72:1 sobre la tarjeta. */
.btn-outline-primary { --bs-btn-color: var(--ot-primary); --bs-btn-border-color: var(--ot-primary);
                        --bs-btn-hover-bg: var(--ot-primary); --bs-btn-hover-color: var(--ot-on-primary);
                        --bs-btn-hover-border-color: var(--ot-primary); }
.btn-outline-success { --bs-btn-color: var(--ot-success-text); --bs-btn-border-color: var(--ot-success);
                        --bs-btn-hover-bg: var(--ot-success); --bs-btn-hover-color: var(--ot-on-success);
                        --bs-btn-hover-border-color: var(--ot-success); }
.btn-outline-warning { --bs-btn-color: var(--ot-warning-text); --bs-btn-border-color: var(--ot-warning);
                        --bs-btn-hover-bg: var(--ot-warning); --bs-btn-hover-color: var(--ot-on-warning);
                        --bs-btn-hover-border-color: var(--ot-warning); }
.btn-outline-danger  { --bs-btn-color: var(--ot-danger-text); --bs-btn-border-color: var(--ot-danger);
                        --bs-btn-hover-bg: var(--ot-danger); --bs-btn-hover-color: var(--ot-on-danger);
                        --bs-btn-hover-border-color: var(--ot-danger); }
.btn-outline-info    { --bs-btn-color: var(--ot-info-text); --bs-btn-border-color: var(--ot-info);
                        --bs-btn-hover-bg: var(--ot-info); --bs-btn-hover-color: var(--ot-on-info);
                        --bs-btn-hover-border-color: var(--ot-info); }
.btn-outline-light   { --bs-btn-color: var(--ot-text); --bs-btn-border-color: var(--ot-border);
                        --bs-btn-hover-bg: var(--ot-hover); --bs-btn-hover-color: var(--ot-text); }
.btn-outline-dark    { --bs-btn-color: var(--ot-text); --bs-btn-border-color: var(--ot-border);
                        --bs-btn-hover-bg: var(--ot-hover); --bs-btn-hover-color: var(--ot-text); }

/* ── Selector de apariencia (THEME-2) ────────────────────────────────────────
   El control es el componente `bslib-input-dark-mode`, cuyo botón vive en su
   shadow DOM: desde fuera sólo se puede estilar el host. El anillo de foco se
   declara sobre el host con `:focus-within` para que sea visible al llegar con
   el teclado, porque el `:focus` real ocurre dentro del shadow. */
.ot-theme-switch { padding: 0 .25rem; }
.ot-theme-switch bslib-input-dark-mode {
  --text-1: var(--ot-text);
  --text-2: var(--ot-text-muted);
  border-radius: .35rem;
  display: inline-flex;
  align-items: center;
}
.ot-theme-switch:focus-within bslib-input-dark-mode {
  outline: 2px solid var(--ot-focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 .2rem var(--ot-focus-ring);
}
.ot-theme-switch-label { color: var(--ot-text-muted); letter-spacing: .04em; }

/* En pantallas estrechas la navbar colapsa y el selector queda dentro del menú
   desplegable: ahí la etiqueta de texto sí aporta y se mantiene visible. */
@media (max-width: 991.98px) {
  .ot-theme-switch { padding: .35rem .25rem; }
}

/* El selector reubicado fuera del contenedor colapsable: siempre visible. */
.ot-theme-switch--fija {
  margin-left: auto;
  order: 99;
  flex: 0 0 auto;
}
@media (max-width: 991.98px) {
  .ot-theme-switch--fija { margin-left: auto; padding-right: .25rem; }
  .ot-theme-switch--fija .ot-theme-switch-label { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   actionBttn de shinyWidgets  (THEME-3 · Fase 6)

   THEME-1 concluyó que estos fondos los ponían los módulos en línea y dejó los
   siete casos como deuda. **No es así**: los pone la hoja de shinyWidgets
   (`bttn.min.css`) por clase semántica según el argumento `color=`:

       .bttn-simple.bttn-primary → #1d89ff      .bttn-simple.bttn-danger  → #ff5964
       .bttn-simple.bttn-warning → #feab3a      .bttn-simple.bttn-success → #28b78d
       .bttn-simple.bttn-royal   → #bd2df5

   Coinciden exactamente con los fondos medidos (rgb(255,89,100),
   rgb(40,183,141), rgb(29,137,255), rgb(254,171,58)). Existe, por tanto, un
   contrato compartido que SÍ conoce su variante: cada superficie recibe el
   token de su estado y la tinta que le corresponde, en ambos modos. No se
   impone una tinta única, que era justo lo que el brief pedía evitar.

   `.action-label` es el texto interior y hereda del botón: al corregir el par
   del botón queda corregido también.
   ═══════════════════════════════════════════════════════════════════════════ */
.bttn-simple.bttn-primary, .bttn-gradient.bttn-primary, .bttn-bordered.bttn-primary,
.bttn-unite.bttn-primary, .bttn-material-flat.bttn-primary, .bttn-fill.bttn-primary {
  background: var(--ot-info) !important; background-image: none !important;
  color: var(--ot-on-info) !important; border-color: var(--ot-info) !important;
}
.bttn-simple.bttn-success, .bttn-gradient.bttn-success, .bttn-bordered.bttn-success,
.bttn-unite.bttn-success, .bttn-material-flat.bttn-success, .bttn-fill.bttn-success {
  background: var(--ot-success) !important; background-image: none !important;
  color: var(--ot-on-success) !important; border-color: var(--ot-success) !important;
}
.bttn-simple.bttn-warning, .bttn-gradient.bttn-warning, .bttn-bordered.bttn-warning,
.bttn-unite.bttn-warning, .bttn-material-flat.bttn-warning, .bttn-fill.bttn-warning {
  background: var(--ot-warning) !important; background-image: none !important;
  color: var(--ot-on-warning) !important; border-color: var(--ot-warning) !important;
}
.bttn-simple.bttn-danger, .bttn-gradient.bttn-danger, .bttn-bordered.bttn-danger,
.bttn-unite.bttn-danger, .bttn-material-flat.bttn-danger, .bttn-fill.bttn-danger {
  background: var(--ot-danger) !important; background-image: none !important;
  color: var(--ot-on-danger) !important; border-color: var(--ot-danger) !important;
}
.bttn-simple.bttn-royal, .bttn-gradient.bttn-royal, .bttn-bordered.bttn-royal,
.bttn-unite.bttn-royal, .bttn-material-flat.bttn-royal, .bttn-fill.bttn-royal {
  background: var(--ot-primary) !important; background-image: none !important;
  color: var(--ot-on-primary) !important; border-color: var(--ot-primary) !important;
}
.bttn-simple.bttn-default, .bttn-gradient.bttn-default, .bttn-bordered.bttn-default {
  background: var(--ot-bg-raised) !important; background-image: none !important;
  color: var(--ot-text) !important; border-color: var(--ot-border) !important;
}
/* El texto interior hereda del botón: así cada variante lleva su propia tinta. */
.bttn .action-label, .bttn .fa, .bttn .fas, .bttn .far, .bttn svg { color: inherit !important; }
.bttn:focus-visible {
  outline: 2px solid var(--ot-focus) !important; outline-offset: 2px;
  box-shadow: 0 0 0 .2rem var(--ot-focus-ring) !important;
}
.bttn:disabled, .bttn.disabled {
  background: var(--ot-disabled-bg) !important; background-image: none !important;
  color: var(--ot-disabled-fg) !important; border-color: var(--ot-disabled-border) !important;
  opacity: 1 !important;
}

/* El texto interior de cualquier `.btn` con superficie de acento hereda la
   tinta del botón, no la del tema: `.action-label` es sólo la etiqueta. */
.btn .action-label, .btn-primary .action-label,
.btn-success .action-label, .btn-warning .action-label,
.btn-danger .action-label, .btn-info .action-label { color: inherit !important; }
