/* ============================================================================
   components.css — Tecsa·S3 Clínico · el shell y sus piezas
   ----------------------------------------------------------------------------
   Este fichero responde a la Fase 0 del plan. Con tecsa-clinico como default,
   las reglas `html[data-app-theme="tricorder"]` de custom.css (66),
   chrome-tricorder.css (62), footer.css (28), sidebar.css (27) y navbar.css
   (4) dejan de matchear. Aquí se cubren las superficies que quedaron.

   INVENTARIO (F0.2) Y CÓMO SE CUBRE
   ----------------------------------------------------------------------------
   - .btn-primary, .card, .card-title, .card-body, .card-text, .card-header
     Bootstrap 5.3 → re-tematizado abajo.
   - .form-control, .form-select, .form-label      → sección Formularios.
   - .dropdown-menu, .dropdown-item, .dropdown-divider, .dropdown-header
                                                 → sección Dropdown.
   - .modal-content, .modal-header, .modal-footer → sección Modal.
   - .app-navbar, .app-topbar, .app-brand__*, .nav-link, .app-theme-toggle
                                                 → sección Cromo/navbar.
   - #sidebar, .nav-link, .sidebar-section-*, .sidebar-mini-card,
     .sidebar-hide-toggle                        → sección Sidebar.
   - .footer-* (copyright, ticker, stat, toggle) → sección Footer.

   LAS REGLAS DE MARCA QUE NO SE NEGOCIAN
   ----------------------------------------------------------------------------
   1. Botón primario = #378ADD, en toda la app, en todos los sitios. Sin
      variación entre secciones.
   2. El morado es IA y sólo IA. `.ai-chat-*` es el único consumidor de
      --ui-accent. Nunca un botón normal: si el morado aparece en un botón
      de "Guardar", el usuario no sabe si es una acción de IA.
   3. El texto sobre el azul primario es tinta (#101B27), NO blanco: blanco
      sobre #378ADD da 3.59:1 y falla AA a tamaño normal.
   4. Selects: campo cerrado radio 8px; el MENÚ desplegado baja a 4-8px,
      casi cuadrado, para diferenciarse visualmente de las tarjetas (12-16).
   5. Sombras planas. Nada de sombras marcadas.

   ICONOS: SVG outline inline, viewBox 0 0 24 24, stroke 1.75-2, fill none.
   ============================================================================ */

@layer components {

  /* ==========================================================================
     1. SUPERFICIE BASE
     ==========================================================================
     El mockup: .fam-card / .map-card / .side-card comparten receta
     (background #fff; border 1px solid rgba(55,138,221,.10);
     border-radius 14px; box-shadow 0 1px 2px rgba(24,95,165,.05)).
     Se aplica a las dos familias de tarjeta del proyecto (Bootstrap .card y
     las propias del dashboard) para que no queden dos estilos en la misma
     pantalla. */
  html[data-app-theme="tecsa-clinico"] .card,
  html[data-app-theme="tecsa-clinico"] .fam-card,
  html[data-app-theme="tecsa-clinico"] .map-card,
  html[data-app-theme="tecsa-clinico"] .side-card {
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--tca-radius-lg);
    box-shadow: var(--ui-elev-1);
    color: var(--ui-text);
  }

  html[data-app-theme="tecsa-clinico"] .card:hover,
  html[data-app-theme="tecsa-clinico"] .fam-card:hover {
    border-color: var(--ui-border-strong);
    box-shadow: var(--ui-elev-2);
  }

  html[data-app-theme="tecsa-clinico"] .card-header {
    background-color: transparent;
    border-bottom: 1px solid var(--ui-border-soft);
    color: var(--ui-text);
    padding: var(--space-sm) var(--space-md);
  }

  html[data-app-theme="tecsa-clinico"] .card-title,
  html[data-app-theme="tecsa-clinico"] .fam-head h3,
  html[data-app-theme="tecsa-clinico"] .map-head h3 {
    color: var(--ui-text);
    font-size: var(--fs-md);
    font-weight: 600;
  }

  html[data-app-theme="tecsa-clinico"] .card-body {
    color: var(--ui-text);
    padding: var(--space-md);
  }

  html[data-app-theme="tecsa-clinico"] .card-text,
  html[data-app-theme="tecsa-clinico"] .subtitle,
  html[data-app-theme="tecsa-clinico"] .breadcrumb {
    color: var(--ui-text-muted);
  }

  /* ==========================================================================
     2. BOTONES
     ==========================================================================
     El documento: primario #378ADD siempre, en toda la app, en ambos modos.
     Secundario = mismo azul en versión outline, "en vez de un color
     distinto". Ese matiz importa: dos azules, no azul+gris.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .btn-primary {
    background-color: var(--ui-primary);
    border-color: var(--ui-primary);
    /* Tinta, no blanco — ver regla 3 del cabecera. 4.84:1. */
    color: var(--ui-text-on-fill);
    border-radius: var(--tca-radius);
    font-weight: 600;
    padding: 0.5rem 1rem;
    min-height: var(--touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    transition: background-color var(--tca-dur-fast) var(--tca-ease),
      border-color var(--tca-dur-fast) var(--tca-ease);
  }

  html[data-app-theme="tecsa-clinico"] .btn-primary:hover,
  html[data-app-theme="tecsa-clinico"] .btn-primary:focus-visible {
    background-color: var(--ui-primary-hover);
    border-color: var(--ui-primary-hover);
    color: var(--ui-text-on-fill);
  }

  html[data-app-theme="tecsa-clinico"] .btn-primary:active {
    background-color: var(--tca-azul-900);
    border-color: var(--tca-azul-900);
  }

  /* Secundario = el mismo azul en outline. */
  html[data-app-theme="tecsa-clinico"] .btn-outline-primary,
  html[data-app-theme="tecsa-clinico"] .btn-secondary {
    background-color: transparent;
    border: 1px solid var(--ui-primary);
    color: var(--ui-secondary);
    border-radius: var(--tca-radius);
    font-weight: 600;
    min-height: var(--touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
  }

  html[data-app-theme="tecsa-clinico"] .btn-outline-primary:hover,
  html[data-app-theme="tecsa-clinico"] .btn-secondary:hover {
    background-color: var(--ui-tint-primary);
    border-color: var(--ui-primary);
    color: var(--ui-secondary);
  }

  /* Neutro (ghost): sólo texto y borde tenue. */
  html[data-app-theme="tecsa-clinico"] .btn-ghost,
  html[data-app-theme="tecsa-clinico"] .btn-light {
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    color: var(--ui-text);
    border-radius: var(--tca-radius);
    min-height: var(--touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
  }

  html[data-app-theme="tecsa-clinico"] .btn-ghost:hover,
  html[data-app-theme="tecsa-clinico"] .btn-light:hover {
    background-color: var(--ui-surface-3);
    border-color: var(--ui-border-strong);
    color: var(--ui-text);
  }

  /* Estados no textuales — los mockups no tienen ni un :disabled. Un botón
     deshabilitado que no lo parece es un invitations de hacer clic en
     nothing; uno que parece deshabilitado pero responde frustra. */
  html[data-app-theme="tecsa-clinico"] .btn-primary:disabled,
  html[data-app-theme="tecsa-clinico"] .btn-outline-primary:disabled,
  html[data-app-theme="tecsa-clinico"] .btn-secondary:disabled,
  html[data-app-theme="tecsa-clinico"] .btn-ghost:disabled,
  html[data-app-theme="tecsa-clinico"] .btn-light:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: none;
  }

  /* Botón de icono — el .icon-btn del mockup: 38px, radio 10px, superficie
     translúcida, icono 18px. Se sube a 44px en táctil (responsive.css). */
  html[data-app-theme="tecsa-clinico"] .icon-btn,
  html[data-app-theme="tecsa-clinico"] .map-icon-btn {
    width: 38px;
    height: 38px;
    border-radius: var(--tca-radius);
    display: grid;
    place-items: center;
    background-color: var(--tca-glass-bg);
    border: 1px solid var(--ui-border);
    color: var(--ui-text);
    cursor: pointer;
    transition: background-color var(--tca-dur-fast) var(--tca-ease);
  }

  html[data-app-theme="tecsa-clinico"] .icon-btn:hover,
  html[data-app-theme="tecsa-clinico"] .map-icon-btn:hover {
    background-color: var(--ui-surface);
    border-color: var(--ui-border-strong);
  }

  /* ==========================================================================
     3. TARJETA KPI (las 4 variantes de acento)
     ==========================================================================
     Del mockup: .kpi{border-left:4px solid <acento>}. Cuatro variantes:
     azul, lavanda, verde, ámbar. El acento va en el BORDE (elemento no
     textual, umbral 3:1) y el valor en texto de alto contraste — nunca al
     revés, que es el fallo que theme-tokens.css documenta en su §3b.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .kpi,
  html[data-app-theme="tecsa-clinico"] .kpi-card {
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-left: 4px solid var(--ui-primary);
    border-radius: var(--tca-radius-lg);
    box-shadow: var(--ui-elev-1);
    padding: var(--space-md);
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
  }

  html[data-app-theme="tecsa-clinico"] .kpi.k-lav,
  html[data-app-theme="tecsa-clinico"] .kpi-card.k-lav {
    border-left-color: var(--ui-accent);
  }

  html[data-app-theme="tecsa-clinico"] .kpi.k-green,
  html[data-app-theme="tecsa-clinico"] .kpi-card.k-green {
    border-left-color: var(--ui-success);
  }

  html[data-app-theme="tecsa-clinico"] .kpi.k-peach,
  html[data-app-theme="tecsa-clinico"] .kpi-card.k-peach {
    border-left-color: var(--ui-warn);
  }

  /* Etiqueta: 12px, 700, MAYÚSCULAS, letter-spacing .6px. El patrón de los
     mockups es "uppercase sólo para etiquetas de sección/estado a 11-12px",
     nunca para títulos ni cuerpo. */
  html[data-app-theme="tecsa-clinico"] .kpi-label {
    font-size: var(--fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ui-text-muted);
  }

  html[data-app-theme="tecsa-clinico"] .kpi-value {
    font-size: var(--fs-xl);
    font-weight: 600;
    line-height: 1.1;
    color: var(--ui-text);
    letter-spacing: -0.02em;
  }

  /* Tendencia: verde/rojo como TEXTO → 5.30:1 y 6.47:1, no los 3.39 del
     mockup. El icono de flecha acompaña; el color no es el único portador
     de significado (WCAG 1.4.1). */
  html[data-app-theme="tecsa-clinico"] .kpi-trend.up {
    color: var(--ui-success-text);
  }

  html[data-app-theme="tecsa-clinico"] .kpi-trend.dn {
    color: var(--ui-danger);
  }

  /* ==========================================================================
     4. TABLAS — construidas desde cero
     ==========================================================================
     Los mockups NO tienen tablas: cero <table>, cero thead/tbody/th/td,
     cero zebra. Su `.fam-item` es una lista CSS-grid. El proyecto sí tiene
     tablas en todas partes, así que esta sección es diseño nuevo dentro del
     lenguaje del tema.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] table {
    width: 100%;
    border-collapse: collapse;
    color: var(--ui-text);
    font-size: var(--fs-sm);
  }

  html[data-app-theme="tecsa-clinico"] thead th {
    background-color: var(--ui-surface-3);
    color: var(--ui-text);
    font-size: var(--fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    text-align: left;
    padding: var(--space-sm);
    border-bottom: 1px solid var(--ui-border);
    /* Sticky sólo si la tabla scrollea verticalmente; sin contexto de altura
       un thead sticky se despegaría del header de la página. */
    position: static;
  }

  html[data-app-theme="tecsa-clinico"] tbody td,
  html[data-app-theme="tecsa-clinico"] tbody th {
    padding: var(--space-sm);
    border-bottom: 1px solid var(--ui-border-soft);
    color: var(--ui-text);
    vertical-align: middle;
  }

  /* Zebra con tinte suave, no gris plano: menos ruido visual que #ECEEF2 y
     mantiene la lavanda de la marca. Se mezcla --ui-accent (que sigue el
     modo) y no la primitiva clara --tca-lav-050: con ésta, en oscuro, la fila
     par salía gris medio (#6A6F7E) y el texto claro caía a 4.35:1. */
  html[data-app-theme="tecsa-clinico"] tbody tr:nth-child(even) {
    background-color: color-mix(in oklab, var(--ui-accent) 7%, var(--ui-surface));
  }

  html[data-app-theme="tecsa-clinico"] tbody tr:hover {
    background-color: var(--ui-tint-primary);
  }

  /* Fila accionable: cursor + foco. */
  html[data-app-theme="tecsa-clinico"] tbody tr:focus-within {
    background-color: var(--ui-tint-primary);
    outline: var(--tca-focus-width) solid var(--tca-linea-campo);
    outline-offset: -2px;
  }

  /* ==========================================================================
     5. FORMULARIOS
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .form-label {
    color: var(--ui-text);
    font-weight: 500;
    font-size: var(--fs-sm);
    /* El documento: 15-16px body. Una etiqueta a 12px es el componente más
       frecuente en una pantalla clínica y el primero que se sacrifica. */
  }

  html[data-app-theme="tecsa-clinico"] .form-control,
  html[data-app-theme="tecsa-clinico"] .form-select {
    background-color: var(--ui-surface);
    /* Borde FUNCIONAL: --ui-border (1px tenue) no llega a 3:1 y un campo
       sin borde visible no se ve como campo. --ui-border-strong = 4.31:1. */
    border: 1px solid var(--ui-border-strong);
    border-radius: 8px; /* documento: inputs 8px */
    color: var(--ui-text);
    font-size: var(--fs-sm);
    min-height: var(--touch-target);
    padding: 0.5rem 0.75rem;
    transition: border-color var(--tca-dur-fast) var(--tca-ease),
      box-shadow var(--tca-dur-fast) var(--tca-ease);
  }

  html[data-app-theme="tecsa-clinico"] .form-control:focus,
  html[data-app-theme="tecsa-clinico"] .form-select:focus {
    background-color: var(--ui-surface);
    color: var(--ui-text);
    border-color: var(--ui-primary);
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--ui-primary) 30%, transparent);
    outline: none; /* el anillo lo pone box-shadow: mismo resultado, 1 sombra */
  }

  html[data-app-theme="tecsa-clinico"] .form-control::placeholder {
    color: var(--tca-gris-500);
    /* 3.05:1 — placeholder no es texto real y WCAG lo trata aparte, pero se
       oscurece lo justo para que no desaparezca. */
    opacity: 1;
  }

  html[data-app-theme="tecsa-clinico"] .form-control:disabled,
  html[data-app-theme="tecsa-clinico"] .form-select:disabled,
  html[data-app-theme="tecsa-clinico"] .form-control[readonly] {
    background-color: var(--ui-surface-3);
    color: var(--ui-text-muted);
    border-color: var(--ui-border-soft);
    cursor: not-allowed;
  }

  html[data-app-theme="tecsa-clinico"] .form-check-input {
    border-color: var(--ui-border-strong);
    /* 20px: por debajo el objetivo táctil se pierde en dedo. */
    width: 1.25em;
    height: 1.25em;
    margin-top: 0.15em;
  }

  html[data-app-theme="tecsa-clinico"] .form-check-input:checked {
    background-color: var(--ui-primary);
    border-color: var(--ui-primary);
  }

  html[data-app-theme="tecsa-clinico"] .form-check-input:focus-visible {
    border-color: var(--ui-primary);
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--ui-primary) 30%, transparent);
    outline: none;
  }

  html[data-app-theme="tecsa-clinico"] .form-text,
  html[data-app-theme="tecsa-clinico"] .form-hint {
    color: var(--ui-text-muted);
    font-size: var(--fs-xs);
  }

  /* ==========================================================================
     6. DROPDOWN / SELECT
     ==========================================================================
     REGLA DE MARCA: el campo cerrado conserva el radio 8px de input; el MENÚ
     desplegado baja a 4-8px, casi cuadrado, y cada opción es un bloque
     rectangular separado por una línea divisoria sutil — sin redondeo entre
     opciones. Eso lo diferencia visualmente de las tarjetas (12-16) y da la
     sensación "técnica/estructurada" que pide el documento.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .dropdown-menu {
    background-color: var(--ui-surface);
    /* 6px, casi cuadrado — deliberadamente distinto de --tca-radius-lg. */
    border-radius: var(--tca-radius-sm);
    border: 1px solid var(--ui-border);
    box-shadow: var(--ui-elev-3);
    padding: 0;
    min-width: 12rem;
  }

  html[data-app-theme="tecsa-clinico"] .dropdown-item {
    color: var(--ui-text);
    font-size: var(--fs-sm);
    padding: 0.5rem 0.875rem;
    /* Bloque rectangular: sin radio propio, la separación la da la línea. */
    border-radius: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: var(--touch-target);
  }

  html[data-app-theme="tecsa-clinico"] .dropdown-item:hover,
  html[data-app-theme="tecsa-clinico"] .dropdown-item:focus {
    background-color: var(--ui-tint-primary);
    color: var(--ui-text);
  }

  html[data-app-theme="tecsa-clinico"] .dropdown-item.active,
  html[data-app-theme="tecsa-clinico"] .dropdown-item:active {
    background-color: var(--ui-primary);
    color: var(--ui-text-on-fill);
  }

  /* Línea divisoria sutil entre opciones. */
  html[data-app-theme="tecsa-clinico"] .dropdown-item + .dropdown-item {
    border-top: 1px solid var(--ui-border-soft);
  }

  html[data-app-theme="tecsa-clinico"] .dropdown-divider {
    border-top: 1px solid var(--ui-border);
    margin: 0;
  }

  html[data-app-theme="tecsa-clinico"] .dropdown-header {
    color: var(--ui-text-muted);
    font-size: var(--fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: var(--space-xs) 0.875rem;
  }

  /* ==========================================================================
     7. MODAL / DRAWER
     ==========================================================================
     El documento: modales 16-20px, sombra 0 4px 12px rgba(0,0,0,.1).
     El .drawer del mockup NO declara radio — se lo pone aquí.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .modal-content {
    background-color: var(--ui-surface);
    color: var(--ui-text);
    border: 1px solid var(--ui-border);
    border-radius: var(--tca-radius-xl);
    box-shadow: var(--ui-elev-3);
  }

  html[data-app-theme="tecsa-clinico"] .modal-header,
  html[data-app-theme="tecsa-clinico"] .modal-footer {
    border-color: var(--ui-border-soft);
    padding: var(--space-md);
  }

  html[data-app-theme="tecsa-clinico"] .modal-header .modal-title {
    color: var(--ui-text);
    font-size: var(--fs-lg);
    font-weight: 600;
  }

  html[data-app-theme="tecsa-clinico"] .modal-backdrop {
    background-color: rgb(16 27 39 / 0.45);
  }

  /* Drawer lateral: el .drawer del mockup va a 480px fijo y sin radio, lo que
     a 375px desborda la pantalla. responsive.css lo lleva a 100vw. */
  html[data-app-theme="tecsa-clinico"] .drawer {
    background-color: var(--ui-surface);
    border-left: 1px solid var(--ui-border);
    border-radius: var(--tca-radius-xl) 0 0 var(--tca-radius-xl);
    box-shadow: var(--tca-shadow-md);
    color: var(--ui-text);
  }

  html[data-app-theme="tecsa-clinico"] .drawer-head {
    background: var(--tca-grad-avatar);
    color: var(--tca-blanco);
  }

  html[data-app-theme="tecsa-clinico"] .drawer-title h3 {
    color: inherit;
    font-size: var(--fs-md);
    font-weight: 600;
  }

  /* ==========================================================================
     8. NAVBAR / TOPBAR
     ==========================================================================
     El mockup: .top-bar background --c-azul-100 (#E6F1FB), borde inferior
     1px #cfe1f3, padding 12px 24px. El proyecto usa .app-navbar y .app-topbar
     sobre Bootstrap.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .app-topbar {
    background-color: var(--tca-topbar-bg);
    border-bottom: 1px solid var(--tca-topbar-border);
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar {
    background-color: var(--tca-glass-bg);
    border-bottom: 1px solid var(--ui-border);
    -webkit-backdrop-filter: var(--ui-glass);
    backdrop-filter: var(--ui-glass);
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .navbar-brand,
  html[data-app-theme="tecsa-clinico"] .app-brand__title {
    color: var(--ui-text);
    font-weight: 700;
    font-size: var(--fs-md);
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .nav-link {
    color: var(--ui-text-muted);
    font-weight: 500;
    font-size: var(--fs-sm);
    padding: 0.5rem 0.75rem;
    border-radius: var(--tca-radius-sm);
    min-height: var(--touch-target);
    display: inline-flex;
    align-items: center;
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .nav-link:hover,
  html[data-app-theme="tecsa-clinico"] .app-navbar .nav-link:focus-visible {
    color: var(--ui-text);
    background-color: var(--ui-tint-primary);
  }

  /* La página actual: ellavanda de la marca como relleno con tinta encima.
     El mockup usa blanco sobre lavanda = 3.76:1 (falla); aquí tinta =
     4.62:1 conservando el color. */
  html[data-app-theme="tecsa-clinico"] .app-navbar .nav-link[aria-current="page"] {
    background-color: var(--ui-accent);
    color: var(--ui-text-on-fill);
    font-weight: 600;
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .nav-link i {
    color: currentcolor;
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .navbar-toggler {
    border-color: var(--ui-border-strong);
  }

  /* ==========================================================================
     9. SIDEBAR
     ==========================================================================
     El gradiente azul -> lavanda a 0/45/100% es la firma visual del tema.
     El mockup lo fija en 240px sin collapse; responsive.css lo pasa a
     off-canvas por debajo de 1100px.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] #sidebar,
  html[data-app-theme="tecsa-clinico"] .app-sidebar {
    background: var(--tca-sidebar-bg);
    border-right: 1px solid var(--tca-sidebar-border);
  }

  html[data-app-theme="tecsa-clinico"] #sidebar .nav-link {
    color: var(--ui-text);
    font-size: var(--fs-sm);
    font-weight: 500;
    border-radius: var(--tca-nav-item-radius);
    padding: 0.625rem 0.75rem;
    margin-bottom: 2px;
    min-height: var(--tca-nav-item-h);
    display: flex;
    align-items: center;
    gap: 0.625rem;
    transition: background-color var(--tca-dur-fast) var(--tca-ease),
      color var(--tca-dur-fast) var(--tca-ease);
  }

  html[data-app-theme="tecsa-clinico"] #sidebar .nav-link:hover,
  html[data-app-theme="tecsa-clinico"] #sidebar .nav-link:focus-visible {
    background-color: color-mix(in oklab, var(--ui-accent) 20%, transparent);
    color: var(--tca-lav-500); /* 5.43:1 — el mockup usa 3.15:1 aquí */
  }

  html[data-app-theme="tecsa-clinico"] #sidebar .nav-link[aria-current="page"] {
    background-color: var(--ui-accent);
    color: var(--ui-text-on-fill);
    font-weight: 700;
    box-shadow: 0 3px 10px color-mix(in oklab, var(--ui-accent) 35%, transparent);
  }

  html[data-app-theme="tecsa-clinico"] #sidebar .nav-link i {
    color: currentcolor;
    /* 19px: el mockup lo sube de los 18 del icono de toolbar. */
    font-size: 1.1875rem;
    flex-shrink: 0;
  }

  /* Etiqueta de sección: 12px, 700, MAYÚSCULAS, .7px. */
  html[data-app-theme="tecsa-clinico"] .sidebar-section-title,
  html[data-app-theme="tecsa-clinico"] .nav-title {
    font-size: var(--fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--tca-lav-500);
    margin: var(--space-xs) 0 var(--space-xs) 0.625rem;
  }

  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-section-card {
    background-color: color-mix(in oklab, var(--ui-surface) 55%, transparent);
    border: 1px solid var(--ui-border-soft);
    border-radius: var(--tca-radius);
    padding: var(--space-xs) var(--space-sm);
    color: var(--ui-text-muted);
  }

  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-divider {
    border-top: 1px solid color-mix(in oklab, var(--ui-accent) 18%, transparent);
    margin: var(--space-sm) 0;
  }

  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-brand-text span {
    color: var(--ui-text);
    font-weight: 600;
  }

  html[data-app-theme="tecsa-clinico"] .sidebar-mini-card {
    background-color: var(--tca-glass-bg);
    border: 1px solid var(--ui-border);
    border-radius: var(--tca-radius);
    padding: var(--space-xs);
    color: var(--ui-text);
  }

  html[data-app-theme="tecsa-clinico"] .sidebar-hide-toggle {
    color: var(--ui-text-muted);
    min-height: var(--touch-target);
    min-width: var(--touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--tca-radius-sm);
    background: transparent;
    border: 1px solid transparent;
  }

  html[data-app-theme="tecsa-clinico"] .sidebar-hide-toggle:hover,
  html[data-app-theme="tecsa-clinico"] .sidebar-hide-toggle:focus-visible {
    background-color: var(--ui-surface);
    color: var(--ui-text);
    border-color: var(--ui-border);
  }

  /* ==========================================================================
     SIDEBAR — LA TINTA, QUE ESTABA HECHA PARA UN FONDO QUE ESTE TEMA NO USA
     ==========================================================================
     MEDIDO en Chromium con composición de alfa (axe NO lo detecta: con un
     fondo en degradado no puede resolver un color de fondo fiable y se
     rinde). Resultado antes de esto, texto blanco sobre fondo casi blanco:

         .sidebar-section-title ..............  1.17:1   FALLA
         .sidebar-section-icon ................  1.15:1   FALLA
         .sidebar-section-arrow ...............  1.12:1   FALLA
         #sidebar .nav-link ...................  1.19:1   FALLA
         #sidebar .sidebar-brand-text span ....  1.22:1   FALLA

     Es exactamente lo que se ve en pantalla: los títulos de sección y los
     enlaces se confunden con las tarjetas y no se leen.

     LA CAUSA, y es de fondo
     ----------------------
     `sidebar.css` declara su propia paleta en `:root` y su propio comentario
     (líneas 29-41) dice, con razón para entonces: «El sidebar tiene fondo
     oscuro fijo en los DOS temas». Ese supuesto es justo el que este tema
     incumple: aquí el sidebar se pinta con `--tca-grad-sidebar`, un degradado
     CLARO (#E6F1FB → #ECE6F4). La superficie cambió; la tinta no.

     Es la misma clase de agujero que el del pie (que pintaba el fondo y
     dejaba el enlace en el azul de Bootstrap): el tema cambiaba superficies
     y no el texto que va encima.

     POR QUÉ TOKENS Y NO SELECTORES SUELTOS
     -------------------------------------
     `sidebar.css` ya ofrece el punto de extensión: escribe
     `color: var(--sidebar-fg) !important` en `.btn-toggle` y en `.nav-link`.
     El `!important` está en la DECLARACIÓN, no en el valor: al cambiar el
     token, el valor nuevo llega igual. Redefiniendo los tokens se arreglan de
     una vez los botones de sección y los enlaces, sin tocar sus selectores.

     Los selectores con tinta blanca ESCRITA a pelo (los de sección y el
     lockup de marca) sí necesitan override, y con `#sidebar-container` en el
     selector: uno de ID gana a cualquier cantidad de clases, así que la regla
     del tema sin ID (0,2,1) perdía contra la de sidebar.css (1,1,0). Eso era
     literalmente por qué la tinta del tema no se aplicaba.

     Tintas, todas medidas contra los fondos reales del navegador
     (#E2EFF8 la tarjeta de sección, #ECE6F4 el degradado del sidebar):

         --tca-azul-900  #185FA5 ....  5.57:1 / 5.34:1   <- usada
         --tca-azul-700  #1F588B ....  6.34:1 / 6.08:1   <- hover
         --tca-ink-900   #0F172A .... 15.25:1 / 14.61:1  <- lockup de marca
         --tca-lav-500   #7F77DD ....  3.21:1 / 3.08:1   <- NO: falla 4.5:1

     El lavanda que este tema usaba para los títulos de sección se queda en
     3.21:1. Con 13.6px y peso 600 no cuenta como «texto grande» (WCAG pide
     18.66px en negrita o 24px), así que el mínimo es 4.5:1. Por eso los
     títulos van en azul de marca y no en lavanda: el lavanda se queda para lo
     que sí es decorativo, y aquí ya hay otro icono junto al texto.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] {
    /* Tinta propia del sidebar, para la superficie CLARA de este tema. */
    --sidebar-bg: var(--tca-sidebar-bg);
    --sidebar-border: var(--tca-sidebar-border);
    /* Semánticos, no primitivos: mismo valor en claro (#185FA5 / #1F588B) y
       se invierten en oscuro. Con --tca-azul-900 fijo, en modo oscuro los
       enlaces del menú quedaban azul oscuro sobre el panel oscuro. */
    --sidebar-fg: var(--ui-secondary);
    --sidebar-fg-hover: var(--ui-secondary-hover);
    --sidebar-fg-active: var(--ui-secondary);
    --sidebar-text: var(--ui-secondary);

    /* Estas dos las consumen dos reglas de sidebar.css que llevan
       `!important`, y un `!important` gana a cualquier declaración normal
       sin importar la capa ni la especificidad: sin definir estas variables
       NO hay forma de cambiar la tinta de los enlaces del menú desde fuera.
       El fallback de cada una en sidebar.css es el literal que tenía antes,
       así que los temas que no definen las variables se ven igual que hasta
       ahora. Es el mismo punto de extensión que ya usa aquel fichero con
       --sidebar-text y --sidebar-card-bg. */
    --sidebar-nav-fg: var(--ui-secondary);
    --sidebar-link-fg: var(--ui-secondary);
    --sidebar-link-fg-hover: var(--ui-secondary-hover);

    /* Estados de los enlaces del menú: sidebar.css los declara con
       `!important` y los expone como variables (2026-10-08). Valores del
       tema: hover y activo como TINTES del azul de marca con la tinta de
       marca encima, sin desplazamiento ni brillo animado. Los literales de
       antes (blanco sobre celeste al 80%) daban ~1.5:1 al pasar el ratón. */
    --sidebar-nav-fg-hover: var(--ui-secondary-hover);
    --sidebar-nav-bg-hover: color-mix(in oklab, var(--ui-primary) 9%, transparent);
    --sidebar-nav-shift: none;
    --sidebar-nav-bg-active: var(--ui-tint-primary-2);
    --sidebar-nav-active-anim: none;
    --sidebar-nav-active-shadow: none;
    --sidebar-nav-indicator: var(--ui-primary);

    /* Tinta sobre chip claro: la que trae sidebar.css (rgb(6 43 61)) ya es
       oscura y sigue sirviendo; se deja para que el valor quede explícito y
       no dependa del fallback de otro fichero. */
    --sidebar-chip-fg: rgb(6 43 61);
    /* Superficie de la INSIGNIA del logo, y solo de ella: este token lo
       consumen `.sidebar-brand-icon` (sidebar.css:339) y
       `.sidebar-section-card` (sidebar.css:470), pero las tarjetas de sección
       las repinta el tema con su propia regla `background-color`, que gana
       por orden. Así que en la práctica este valor decide el fondo del logo.

       MEDIDO, y es la causa de que el logo no se viera: el PNG tiene DOS
       tonos —blanco #FAFAFA (17 474 px) y azul #458BBA (2 666 px)— y un solo
       fondo no hace legibles los dos:

           fondo                 #FAFAFA    #458BBA   veredicto
           #FFFFFF (lo que habia)  1.04:1      3.71:1   solo un tono
           #185FA5 azul 900        6.25:1      1.76:1   solo un tono
           #1F588B azul 700        7.12:1      2.00:1   solo un tono
           #0F172A tinta          17.10:1      4.81:1   LOS DOS

       Con el azul de marca el blanco del logo se ve y el azul se pierde; con
       blanco pasa lo contrario. La tinta profunda es el único de los cuatro
       que deja los dos tonos por encima de 3:1, que es lo que pide WCAG 1.4.11
       para un objeto gráfico. Y encaja con la marca: la insignia es el único
       elemento oscuro del sidebar, que es justo la jerarquía que se quiere. */
    --sidebar-card-bg: var(--tca-ink-900);
  }

  /* Títulos de sección: 13.6px/600 en MAYÚSCULAS. Necesitan 4.5:1, y el
     selector lleva ID para ganar a `#sidebar-container .sidebar-section-title`. */
  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-section-title {
    color: var(--ui-secondary);
    text-shadow: none;
  }

  /* Icono de sección: es objeto gráfico, así que WCAG 1.4.11 pide 3:1. Va en
     azul de marca y queda en 5.57:1. */
  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-section-icon {
    color: var(--ui-secondary);
  }

  /* El chevron va un punto más suave para no competir con el título, pero
     sigue por encima de 3:1 (6.34:1 medidos). */
  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-section-arrow {
    color: var(--ui-secondary-hover);
  }

  /* Lockup de marca del sidebar. El `text-shadow` de sidebar.css era una
     sombra oscura pensada para texto blanco: sobre superficie clara
     embarra la tinta, así que se anula. */
  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-brand-text,
  html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-brand-text span {
    color: var(--ui-text-strong);
    text-shadow: none;
  }

  /* ==========================================================================
     10. FOOTER
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .footer-professional,
  html[data-app-theme="tecsa-clinico"] .footer-ticker-wrapper {
    background-color: var(--ui-surface-3);
    border-top: 1px solid var(--ui-border);
    color: var(--ui-text-muted);
  }

  html[data-app-theme="tecsa-clinico"] .footer-stat-value {
    color: var(--ui-text);
    font-weight: 600;
    font-size: var(--fs-md);
  }

  html[data-app-theme="tecsa-clinico"] .footer-stat-label,
  html[data-app-theme="tecsa-clinico"] .footer-ticker-label {
    font-size: var(--fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ui-text-muted);
  }

  html[data-app-theme="tecsa-clinico"] .footer-ticker-badge.news {
    background-color: var(--ui-info);
    color: var(--ui-text-on-fill);
  }

  html[data-app-theme="tecsa-clinico"] .footer-ticker-badge.stat {
    background-color: var(--ui-accent);
    color: var(--ui-text-on-fill);
  }

  html[data-app-theme="tecsa-clinico"] .footer-ticker-badge.is-alert {
    background-color: var(--ui-danger);
    color: var(--ui-text-on-fill);
  }

  html[data-app-theme="tecsa-clinico"] .footer-copyright {
    background-color: var(--ui-surface-3);
    color: var(--ui-text-muted);
    font-size: var(--fs-xs);
  }

  html[data-app-theme="tecsa-clinico"] .footer-copyright a {
    color: var(--ui-secondary);
  }

  html[data-app-theme="tecsa-clinico"] .footer-toggle {
    color: var(--ui-text);
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--tca-radius-sm);
    min-height: var(--touch-target);
    padding: 0 var(--space-sm);
  }

  html[data-app-theme="tecsa-clinico"] .footer-toggle:hover {
    background-color: var(--ui-surface-2);
    border-color: var(--ui-border-strong);
  }

  /* ==========================================================================
     11. STATUS PILLS Y BADGES
     ==========================================================================
     El mockup usa #1D9E75 sobre #E6F7F1 = 3.05:1. Aquí el par de tinte usa
     las variantes legibles: --ui-success-text sobre --tint-success = 5.0:1.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .pill,
  html[data-app-theme="tecsa-clinico"] .badge-soft {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3xs);
    font-size: var(--fs-2xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.2rem 0.5rem;
    border-radius: var(--tca-radius-pill);
  }

  html[data-app-theme="tecsa-clinico"] .pill.ok,
  html[data-app-theme="tecsa-clinico"] .badge-soft.ok {
    background-color: var(--ui-tint-success);
    color: var(--ui-success-text);
  }

  html[data-app-theme="tecsa-clinico"] .pill.amber,
  html[data-app-theme="tecsa-clinico"] .badge-soft.amber {
    background-color: var(--ui-tint-warn);
    color: var(--ui-warn);
  }

  html[data-app-theme="tecsa-clinico"] .pill.red,
  html[data-app-theme="tecsa-clinico"] .badge-soft.red {
    background-color: var(--ui-tint-danger);
    color: var(--ui-danger);
  }

  /* Contador numérico del header: relleno sólido + tinta encima. */
  html[data-app-theme="tecsa-clinico"] .badge-counter,
  html[data-app-theme="tecsa-clinico"] .app-topbar .badge-counter.bg-danger {
    background-color: var(--ui-danger);
    color: var(--ui-text-on-fill);
    border: 1.5px solid var(--tca-azul-100);
  }

  /* ==========================================================================
     12. BARRAS DE PROGRESO
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .prog-bar {
    background-color: var(--tca-gris-100);
    border-radius: var(--tca-radius-pill);
    height: 8px;
    overflow: hidden;
  }

  html[data-app-theme="tecsa-clinico"] .prog-fill {
    background: var(--tca-grad-progress-ok);
    border-radius: var(--tca-radius-pill);
    height: 100%;
    transition: width var(--tca-dur) var(--tca-ease);
  }

  html[data-app-theme="tecsa-clinico"] .prog-fill.amber {
    background: var(--tca-grad-progress-warn);
  }

  html[data-app-theme="tecsa-clinico"] .prog-fill.red {
    background: var(--tca-grad-progress-ko);
  }

  /* ==========================================================================
     13. SEGMENTED CONTROL / FILTER PILLS
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .view-toggle,
  html[data-app-theme="tecsa-clinico"] .filter-pills {
    background-color: var(--tca-gris-100);
    border-radius: 8px;
    padding: 3px;
    display: inline-flex;
    gap: 2px;
  }

  html[data-app-theme="tecsa-clinico"] .view-toggle button,
  html[data-app-theme="tecsa-clinico"] .filter-pills button {
    font-family: inherit;
    font-size: var(--fs-xs);
    font-weight: 600;
    color: var(--ui-text-muted);
    background: transparent;
    border: 0;
    border-radius: var(--tca-radius-sm);
    padding: 0.375rem 0.75rem;
    min-height: 2rem;
    cursor: pointer;
    transition: background-color var(--tca-dur-fast) var(--tca-ease),
      color var(--tca-dur-fast) var(--tca-ease);
  }

  html[data-app-theme="tecsa-clinico"] .view-toggle button.active,
  html[data-app-theme="tecsa-clinico"] .filter-pills button.active {
    background-color: var(--ui-surface);
    color: var(--ui-secondary);
    box-shadow: var(--ui-elev-1);
  }

  /* ==========================================================================
     14. SWITCHER DE TEMA
     ==========================================================================
     Renderizado por {% ui_theme_switcher %}. Es el reemplazo del toggle de
     3 estados histórico (.app-theme-toggle), que sigue existiendo para el
     tema actual — este fichero NO lo toca, sólo le da el mismo tratamiento
     visual que al resto de controles cuando el tema nuevo está activo.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .ui-theme-switcher {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
  }

  /* El toggle legacy de 3 estados (light→tricorder→auto) queda INOPERATIVO
     bajo el tema nuevo: el guard de base.html (__applyAppTheme) hace que no
     escriba nada cuando el servidor ya emitió data-app-theme. Un botón que
     no responde es peor que no tenerlo, así que se oculta y su sitio lo
     ocupa {% ui_theme_switcher %}. Sólo se oculta en este tema: los temas
     actuales siguen viendo su toggle intacto.

     Estas DOS reglas tenían el MISMO selector, y la segunda declaraba
     display:inline-flex. Al ir después y con igual especificidad, ANULABA el
     display:none de la primera: el toggle legacy volvía a verse, y dead para
     siempre (el guard lo dejaba sin efecto). Se fusionan en una sola. */
  html[data-app-theme="tecsa-clinico"] .app-theme-toggle {
    display: none;
  }

  html[data-app-theme="tecsa-clinico"] .ui-theme-switcher .form-select {
    min-height: 2.25rem;
    font-size: var(--fs-xs);
    padding: 0.25rem 1.75rem 0.25rem 0.5rem;
    border-radius: var(--tca-radius-sm);
  }

  /* ==========================================================================
     15. IA — CHAT FLOTANTE
     ==========================================================================
       El ÚNICO consumidor de --ui-accent como superficie de marca. El
       documento: círculo, esquina inferior derecha, 56-60px, lavanda, icono
       chispa o burbuja outline 24px. Al abrir: panel no a pantalla completa,
       radio 16-20, sombra de modal.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .ai-chat-fab,
  html[data-app-theme="tecsa-clinico"] .chat-fab {
    position: fixed;
    right: 24px;
    bottom: 24px;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background-color: var(--ui-accent);
    /* Tinta, no blanco: blanco sobre lavanda da 3.76:1. */
    color: var(--ui-text-on-fill);
    box-shadow: 0 4px 12px color-mix(in oklab, var(--ui-accent) 40%, transparent);
    border: 0;
    cursor: pointer;
    z-index: 1050; /* sobre el footer fijo, bajo el navbar */
    transition: transform var(--tca-dur-fast) var(--tca-ease),
      box-shadow var(--tca-dur-fast) var(--tca-ease);
  }

  html[data-app-theme="tecsa-clinico"] .ai-chat-fab:hover,
  html[data-app-theme="tecsa-clinico"] .chat-fab:hover,
  html[data-app-theme="tecsa-clinico"] .chat-fab:focus-visible {
    color: var(--ui-text-on-fill);
    transform: scale(1.05);
    box-shadow: 0 6px 18px color-mix(in oklab, var(--ui-accent) 50%, transparent);
  }

  html[data-app-theme="tecsa-clinico"] .ai-chat-fab svg,
  html[data-app-theme="tecsa-clinico"] .chat-fab svg {
    width: 28px;
    height: 28px;
    fill: none;
    stroke: currentcolor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* Panel de IA: ventana flotante, NO pantalla completa. */
  html[data-app-theme="tecsa-clinico"] .ai-chat-panel,
  html[data-app-theme="tecsa-clinico"] .chat-panel {
    position: fixed;
    right: 24px;
    bottom: 96px;
    width: min(380px, calc(100vw - 32px));
    max-height: min(560px, calc(100dvh - 140px));
    display: flex;
    flex-direction: column;
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--tca-radius-xl);
    box-shadow: var(--ui-elev-3);
    z-index: 1050;
    overflow: hidden;
  }

  html[data-app-theme="tecsa-clinico"] .ai-chat-panel[hidden],
  html[data-app-theme="tecsa-clinico"] .chat-panel[hidden] {
    display: none;
  }

  html[data-app-theme="tecsa-clinico"] .ai-chat-panel__head,
  html[data-app-theme="tecsa-clinico"] .chat-panel__head {
    background: var(--tca-grad-avatar);
    color: var(--tca-blanco);
    padding: var(--space-sm) var(--space-md);
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
  }

  html[data-app-theme="tecsa-clinico"] .ai-chat-panel__body,
  html[data-app-theme="tecsa-clinico"] .chat-panel__body {
    padding: var(--space-md);
    overflow-y: auto;
    color: var(--ui-text);
    font-size: var(--fs-sm);
    flex: 1;
  }

  html[data-app-theme="tecsa-clinico"] .ai-chat-panel__foot,
  html[data-app-theme="tecsa-clinico"] .chat-panel__foot {
    padding: var(--space-sm) var(--space-md);
    border-top: 1px solid var(--ui-border-soft);
    display: flex;
    gap: var(--space-2xs);
  }

  /* ==========================================================================
     16. AVATARES
     ==========================================================================
     El mockup: círculo, gradiente azul->lavanda, anillo blanco 2px,
     iniciales 12px/700, letter-spacing -.5px.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .profile .pa,
  html[data-app-theme="tecsa-clinico"] .avatar-initial {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: -0.5px;
    color: var(--tca-blanco);
    background: var(--tca-grad-avatar);
    box-shadow: 0 2px 6px color-mix(in oklab, var(--ui-accent) 35%, transparent);
    border: 2px solid var(--tca-blanco);
    flex-shrink: 0;
  }

  /* Variante neutra para avatar de agente/paciente. */
  html[data-app-theme="tecsa-clinico"] .patient .av,
  html[data-app-theme="tecsa-clinico"] .agents-mini .av {
    background-color: var(--tca-lav-050);
    border: 1.5px solid var(--tca-agente-border);
    color: var(--tca-lav-500); /* 5.43:1 — el mockup da 3.29:1 */
    display: grid;
    place-items: center;
    border-radius: 50%;
    font-weight: 700;
  }

  /* Píldora de perfil. */
  html[data-app-theme="tecsa-clinico"] .profile {
    display: inline-flex;
    align-items: center;
    gap: 0.5625rem;
    padding: 5px 12px 5px 5px;
    border-radius: var(--tca-radius-pill);
    background-color: var(--tca-glass-bg);
    border: 1px solid var(--ui-border);
    color: var(--ui-text);
    font-size: var(--fs-xs);
    font-weight: 600;
    cursor: pointer;
  }

  html[data-app-theme="tecsa-clinico"] .profile:hover {
    background-color: var(--ui-surface);
    border-color: var(--ui-border-strong);
  }

  /* ==========================================================================
     17. ESTADOS: vacío, error, alerta
     ==========================================================================
     Los mockups no tienen ninguno: cero empty-state, cero rama de cero
     resultados. Son las pantallas que más se ven en una plataforma de salud
     rural con datos reales, así que se construyen aquí.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-xl) var(--space-md);
    text-align: center;
    color: var(--ui-text-muted);
  }

  html[data-app-theme="tecsa-clinico"] .empty-state svg {
    width: 40px;
    height: 40px;
    fill: none;
    stroke: var(--tca-gris-500);
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  html[data-app-theme="tecsa-clinico"] .empty-state h3 {
    color: var(--ui-text);
    font-size: var(--fs-md);
    font-weight: 600;
    margin: 0;
  }

  html[data-app-theme="tecsa-clinico"] .alert {
    border-radius: var(--tca-radius);
    border: 1px solid transparent;
    padding: var(--space-sm) var(--space-md);
  }

  html[data-app-theme="tecsa-clinico"] .alert-success {
    background-color: var(--ui-tint-success);
    border-color: color-mix(in oklab, var(--ui-success) 35%, transparent);
    color: var(--ui-success-text);
  }

  html[data-app-theme="tecsa-clinico"] .alert-warning {
    background-color: var(--ui-tint-warn);
    border-color: color-mix(in oklab, var(--ui-warn) 35%, transparent);
    color: var(--ui-warn);
  }

  html[data-app-theme="tecsa-clinico"] .alert-danger {
    background-color: var(--ui-tint-danger);
    border-color: color-mix(in oklab, var(--ui-danger) 35%, transparent);
    color: var(--ui-danger);
  }

  html[data-app-theme="tecsa-clinico"] .alert-info {
    background-color: var(--ui-tint-info);
    border-color: color-mix(in oklab, var(--ui-info) 35%, transparent);
    color: var(--ui-info-text);
  }

  /* ==========================================================================
     18. PAGINACIÓN
     ==========================================================================
     También ausente de los mockups (cero ocurrencias de "pagination").
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .pagination {
    gap: var(--space-3xs);
    display: flex;
    flex-wrap: wrap;
  }

  html[data-app-theme="tecsa-clinico"] .page-link,
  html[data-app-theme="tecsa-clinico"] .page-item .page-link {
    color: var(--ui-secondary);
    background-color: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--tca-radius-sm);
    min-width: var(--touch-target);
    min-height: var(--touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.625rem;
    margin: 0;
  }

  html[data-app-theme="tecsa-clinico"] .page-item.active .page-link {
    background-color: var(--ui-primary);
    border-color: var(--ui-primary);
    color: var(--ui-text-on-fill);
    font-weight: 600;
  }

  html[data-app-theme="tecsa-clinico"] .page-link:hover,
  html[data-app-theme="tecsa-clinico"] .page-item .page-link:hover {
    background-color: var(--ui-tint-primary);
    color: var(--ui-secondary);
    border-color: var(--ui-border-strong);
  }

  html[data-app-theme="tecsa-clinico"] .page-item.disabled .page-link {
    opacity: 0.5;
    pointer-events: none;
    background-color: var(--ui-surface-3);
  }

  /* ==========================================================================
     19. SKIP LINK
     ==========================================================================
     Ya existe en el repo (base-shell.css), pero se le da el color del
     tema. Off-screen por defecto, se revela al recibir foco.
     ========================================================================== */
  html[data-app-theme="tecsa-clinico"] .skip-link {
    background-color: var(--ui-primary);
    color: var(--ui-text-on-fill);
    font-weight: 700;
    padding: 10px 16px;
    border-radius: var(--tca-radius-sm);
  }

  html[data-app-theme="tecsa-clinico"] .skip-link:focus {
    outline: 3px solid var(--tca-blanco);
    outline-offset: 2px;
    color: var(--ui-text-on-fill);
  }
}


/* ============================================================================
   SECCION SIN @layer — conflicto MEDIDO con Bootstrap
   ----------------------------------------------------------------------------
   MEDIDO en Chromium a 375px con axe-core, y medido TAMBIÉN por qué no aplicaba
   desde dentro de la capa: bootstrap.min.css NO usa @layer (0 ocurrencias,
   verificado). En CSS una regla sin capa gana SIEMPRE a cualquier regla
   dentro de una capa, sea cual sea su especificidad. Poner estas correcciones
   dentro de @layer components es, por tanto, inútil.

   No es un defecto de este tema: es el problema que MASTER.md sección 6 ya
   documenta ("El contrato de capas está roto en la raíz: Bootstrap va SIN
   capa") y para el que el repo ya tiene precedente — base-shell.css se carga
   el último y a propósito SIN capa por el mismo motivo.

   Regla de la casa: cero !important (R10 del plan). Para vencer a Bootstrap
   sin !important la unica via es salirse de la capa.

   Selectores PLENS, sin anidar: la especificidad de una regla anidada es la
   del padre mas la propia, y conviene no depender de ese calculo para un
   ajuste de acessibilidade.

   TODO lo que esté en este bloque debe ser un conflicto real y MEDIDO con
   Bootstrap. Si añades algo aquí sin haberlo medido, casi seguro que no
   hace falta estar fuera de la capa.
   ============================================================================ */

/* --- Checkbox "recordarme" (WCAG 2.2 AA 2.5.8 target-size) -----------------
   MEDIDO: .form-check-input mide 18x18 en Chromium a 375px. El minimo
   exigido es 24x24. El espaciado no compensa porque el label va pegado.

   El defecto es del tema actual y vive en Bootstrap + login.css, que este
   trabajo no toca. Se corrige aqui, scopado al tema nuevo, porque el tema
   nuevo es el default y es el unico sitio donde puede corregirse sin tocar
   el CSS del tema vigente. */
html[data-app-theme="tecsa-clinico"] .form-check-input {
  width: 1.55rem;
  height: 1.55rem;
  margin-top: 0.05em;
}

/* El label pasa a ser superficie tactica real: pulsar la palabra
   "Recordarme" es igual de valido que pulsar la casilla, y con un pulgar
   adulto es lo que se hace. */
html[data-app-theme="tecsa-clinico"] .form-check {
  min-height: var(--touch-target);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding-left: 1.9rem;
}

html[data-app-theme="tecsa-clinico"] .form-check-label {
  min-height: var(--touch-target);
  display: inline-flex;
  align-items: center;
}

/* --- Boton "mostrar contrasena" superpuesto (WCAG 2.2 AA 2.5.8) ----------
   MEDIDO:
       #id_password   281x48   (cumple de sobra)
       el boton        280x44   SUPERPUESTO encima del campo

   El template lo declara position-absolute y .btn-link de Bootstrap no lleva
   width, asi que con position:absolute sin left el boton se estira al ancho
   completo de su input-group. Resultado: un objetivo de 280px montado encima
   del campo de 281px.

   axe-core lo reporta como target-size sobre #id_password, no porque el campo
   sea pequeno sino porque los dos objetivos adyacentes se solapan y no dejan
   el espacio libre que la pauta exige. El arreglo no es agrandar el campo: es
   quitar el solape. */
html[data-app-theme="tecsa-clinico"] .input-group .btn-link.position-absolute {
  width: auto;
  left: auto;
  right: 0.25rem;
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.75rem;
  border-radius: var(--tca-radius-sm);
  text-decoration: none;
}

html[data-app-theme="tecsa-clinico"] .input-group .btn-link.position-absolute:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: -2px;
}

/* El input recupera el ancho que el boton dejaba tapado. */
html[data-app-theme="tecsa-clinico"] .input-group:has(.btn-link.position-absolute) .form-control {
  padding-right: 3.25rem;
}

/* ============================================================================
   HEADER — marca, control de tema desplegable y etiquetas opcionales
   ----------------------------------------------------------------------------
   MEDIDO con Chromium (scripts/measure_header.py) ANTES de cada decisión. No
   se supone nada: si una regla de aquí no corresponde a una medición, sobra.

   Sin @layer a propósito, por el mismo motivo que el bloque anterior: para
   vencer a Bootstrap sin !important hay que salirse de la capa. Todas estas
   reglas compiten con utilidades de Bootstrap (.nav-link, .dropdown-menu,
   .navbar-brand) que están sin capa.
   ============================================================================ */

/* --- Marca: sólo el símbolo ----------------------------------------------- */
html[data-app-theme="tecsa-clinico"] .app-brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--touch-target);
  height: var(--touch-target);
  max-width: none;
  margin-right: 0.5rem;
  border-radius: var(--tca-radius);
  transition: background-color var(--tca-dur-fast) var(--tca-ease);
}

html[data-app-theme="tecsa-clinico"] .app-brand:hover,
html[data-app-theme="tecsa-clinico"] .app-brand:focus-visible {
  background-color: var(--ui-tint-primary);
}

html[data-app-theme="tecsa-clinico"] .app-brand:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: 2px;
}

html[data-app-theme="tecsa-clinico"] .app-brand__mark {
  width: 30px;
  height: 30px;
  display: block;
  flex-shrink: 0;
  /* MEDIDO: el navbar se pinta con un gradiente `linear-gradient(135deg,
     rgb(19,77,109)…)`, o sea #134D6D, no con una superficie clara. El símbolo
     con los tokens de superficie clara daba 1.39:1 y 2.53:1 sobre ese fondo:
     invisible. `--tca-azul-100` (#E6F1FB) da 7.94:1.

     El SVG dibuja con `currentColor` en vez de con tokens, por dos razones:
     el contraste de arriba, y que `--tca-*` sólo existe bajo este tema —con
     tokens en el atributo `stroke`, bajo `tricorder` y `tecsa` la variable no
     existía, el `stroke` caía a `none` y la marca no se pintaba. Así el
     símbolo es visible en los tres temas sin una regla por tema. */
  color: var(--tca-azul-100);
}

/* El lockup de texto desaparece; su nombre queda en el aria-label del <a>. */
html[data-app-theme="tecsa-clinico"] .app-brand__title,
html[data-app-theme="tecsa-clinico"] .app-brand__subtitle,
html[data-app-theme="tecsa-clinico"] .app-brand__accent {
  display: none;
}

/* --- Control de tema desplegable ------------------------------------------ */
html[data-app-theme="tecsa-clinico"] .ui-theme-control {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
}

html[data-app-theme="tecsa-clinico"] .ui-theme-control__trigger {
  display: inline-grid;
  place-items: center;
  width: var(--touch-target);
  height: var(--touch-target);
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  padding: 0;
  border: 1px solid var(--ui-border);
  border-radius: var(--tca-radius);
  background-color: var(--tca-glass-bg);
  color: var(--ui-text);
  cursor: pointer;
  transition: background-color var(--tca-dur-fast) var(--tca-ease),
    border-color var(--tca-dur-fast) var(--tca-ease);
}

html[data-app-theme="tecsa-clinico"] .ui-theme-control__trigger:hover {
  background-color: var(--ui-surface);
  border-color: var(--ui-border-strong);
  color: var(--ui-text);
}

html[data-app-theme="tecsa-clinico"] .ui-theme-control__trigger:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: 2px;
}

html[data-app-theme="tecsa-clinico"] .ui-theme-control__trigger[aria-expanded="true"] {
  background-color: var(--ui-tint-primary);
  border-color: var(--ui-primary);
}

html[data-app-theme="tecsa-clinico"] .ui-theme-control__icon {
  width: 20px;
  height: 20px;
  display: block;
}

/* El panel: radio de tarjeta, NO el cuadrado de dropdown de Bootstrap, para
   que se lea como un control de la marca y no como un menú genérico. */
html[data-app-theme="tecsa-clinico"] .ui-theme-panel {
  min-width: 15rem;
  padding: var(--space-sm);
  border-radius: var(--tca-radius-lg);
  border: 1px solid var(--ui-border);
  box-shadow: var(--ui-elev-3);
  background-color: var(--ui-surface);
  /* Por debajo del navbar: si no, el panel queda cortado por el borde
     superior de la barra. */
  z-index: 1060;
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__title {
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ui-text-muted);
  margin: var(--space-xs) 0 var(--space-3xs);
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__title:first-of-type {
  margin-top: 0;
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__item {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--touch-target);
  padding: 0.5rem 0.75rem;
  border: 1px solid transparent;
  border-radius: var(--tca-radius-sm);
  background: transparent;
  color: var(--ui-text);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--tca-dur-fast) var(--tca-ease);
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__item:hover {
  background-color: var(--ui-tint-primary);
  color: var(--ui-text);
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__item:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: -2px;
}

/* El estado activo se marca con relleno Y con aria-pressed, nunca sólo con
   color: WCAG 1.4.1 (el color no es el único portador de significado). */
html[data-app-theme="tecsa-clinico"] .ui-theme-panel__item.is-active {
  background-color: var(--ui-tint-primary-2);
  border-color: var(--ui-primary);
  color: var(--ui-secondary);
  font-weight: 700;
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__item.is-active::before {
  content: "✓";
  font-weight: 700;
  margin-right: 0.5rem;
  color: var(--ui-primary-hover);
}

html[data-app-theme="tecsa-clinico"] .ui-theme-panel__empty {
  display: block;
  padding: 0.5rem 0.75rem;
  color: var(--ui-text-muted);
  font-size: var(--fs-sm);
}

/* --- Enlaces del sidebar: Bootstrap va SIN capa y gana por orden ------------
   MEDIDO: los enlaces del menú son `<a class="nav-link link-body-emphasis">`
   y salían en `rgba(255, 255, 255, 0.85)` — 1.19:1 sobre el degradado claro.

   La causa NO es la especificidad ni el orden de capas, que es lo que se
   sospechó primero: `bootstrap.min.css` no usa @layer (0 ocurrencias), así que
   mover la regla fuera de la capa debería haber bastado, y NO bastó.

   MEDIDO en el navegador para descartarlo: el enlace NO tiene ancestro con
   `data-bs-theme`, y `--bs-emphasis-color-rgb` resuelve a `0,0,0`. La causa real
   es que `sidebar.css:820` declara su PROPIA

       .link-body-emphasis { color: rgba(255,255,255,0.85) !important }

   y `bootstrap.min.css` tiene la suya, también con `!important`. Un
   `!important` gana a cualquier declaración normal sin importar la capa ni la
   especificidad, así que ninguna ajuste de cascada podía competir con ellas.

   El arreglo no necesita tocar el marcado: `sidebar.css` pasa a exponer
   `--sidebar-nav-fg` y `--sidebar-link-fg`, con el literal de siempre como
   valor por defecto. Los `!important` se conservan intactos y los temas que no
   definen esas variables se ven EXACTAMENTE igual — medido: tricorder sigue en
   11.90:1 con el mismo blanco de siempre, y sidebar.html queda con cero líneas
   de diff.

   Se probó antes quitar `link-body-emphasis` de los 125 enlaces: arreglaba el
   tema nuevo, pero cambiaba el color de los enlaces de tricorder (de blanco a
   cian). Se descartó por eso, no por la causa raíz. */
html[data-app-theme="tecsa-clinico"] #sidebar-container .btn-toggle-nav a {
  color: var(--ui-secondary);
  text-decoration: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar-container .btn-toggle-nav a:hover,
html[data-app-theme="tecsa-clinico"] #sidebar-container .btn-toggle-nav a:focus-visible {
  color: var(--ui-secondary-hover);
}

html[data-app-theme="tecsa-clinico"] #sidebar-container .btn-toggle-nav a:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: -2px;
}

html[data-app-theme="tecsa-clinico"] #sidebar-container .btn-toggle-nav a.disabled,
html[data-app-theme="tecsa-clinico"] #sidebar-container .btn-toggle-nav a[aria-disabled="true"] {
  color: var(--ui-text-muted);
}

html[data-app-theme="tecsa-clinico"] #sidebar-container .nav-link {
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] #sidebar-container .nav-link:hover,
html[data-app-theme="tecsa-clinico"] #sidebar-container .nav-link:focus-visible {
  color: var(--ui-secondary-hover);
}

html[data-app-theme="tecsa-clinico"] #sidebar-container .nav-link:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: -2px;
}

/* El enlace activo lo pinta el tema con `--ui-accent` de fondo, asi que su
   texto usa la tinta para superficies de color, no el azul de marca. */
html[data-app-theme="tecsa-clinico"] #sidebar-container .nav-link[aria-current="page"],
html[data-app-theme="tecsa-clinico"] #sidebar-container .nav-link.active {
  color: var(--ui-text-on-fill);
}


/* --- Los enlaces del pie, que el tema dejaba a medias ------------------------
   MEDIDO con axe-core: al hacer que los tokens se apliquen (ver tokens.css),
   aparecieron 8 nodos nuevos de color-contrast, todos `a[href$="tecsas3.com"]`
   y `a[href$="digosystems.com"]` en el pie de /dashboard/.

   La causa es que el tema pinta el FONDO del pie (`--ui-surface-2`, #EDF3FA) y
   deja el color de enlace al azul por defecto de Bootstrap (#0D6EFD). Sobre
   ese fondo el contraste queda en 4.28:1, por debajo del 4.5:1 de WCAG AA.

   O sea: el tema cambiaba la superficie y no el texto que va sobre ella. Eso
   es un agujero de cobertura, no un descuido deBootstrap.

   `--tca-azul-900` (#185FA5) da 5.99:1 sobre el mismo fondo. Se acota al pie
   a propósito: poner un color de enlace global pisaría los colores que cada
   zona usa como identidad —el ámbar de `--ui-privilege`, el lavanda de IA—,
   que es justo lo que este tema no debe tocar. */
html[data-app-theme="tecsa-clinico"] .footer-copyright a {
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] .footer-copyright a:hover,
html[data-app-theme="tecsa-clinico"] .footer-copyright a:focus-visible {
  color: var(--ui-secondary-hover);
}

/* --- Las etiquetas de navegación, con el corte MEDIDO y no supuesto -------
   MEDIDO en Chromium a 9 anchos, la posición del <ul class="navbar-nav
   ms-auto"> dentro de #navcol-1 (scripts/measure_header.py):

       1200px  ->  ul en x=-282      <- se sale por la izquierda
       1280px  ->  ul en x=-202
       1366px  ->  ul en x=-116
       1440px  ->  ul en x= -42
       1480px  ->  ul en x=  -2
       1520px  ->  ul en x=  28      <- todavia encima de la marca (12..56)
       1560px  ->  ul en x=  28      <- idem
       1600px  ->  ul en x=  64      <- ya despeja la marca
       1920px  ->  ul en x= 384

   O sea: con las etiquetas visibles la fila NO cabe por debajo de 1600px. El
   `ms-auto` del <ul> lo alinea a la derecha dentro de #navcol-1; cuando es mas
   ancho que su contenedor se sale por la IZQUIERDA y se pinta encima de la
   marca.

   MEDIDO también en el estado previo a este rediseño: allí #navcol-1 medía 0px
   de ancho y el <ul> llegaba a x=-294. O sea que el solape es PREEXISTENTE, y
   este rediseño lo reduce pero no lo elimina.

   chrome-tricorder.css:762 ya oculta las etiquetas de 992 a 1199.98px, con
   `display:none !important` DENTRO de @layer. Ganarle exigiría un `!important`
   propio, que R10 prohíbe — y no hace falta: aquí no hay que sobreescribir la
   regla preexistente, hay que AÑADIR una en una franja donde aquella no
   aplica. Cero `!important` y cero conflicto.

   El rail de identidad mide 727px y los nombres del cliente y del usuario
   cambian su largo, así que el umbral exacto depende del contenido. 1600 es
   el punto medido con este entorno; por eso la banda se redondea a un valor
   redondo y holgado en lugar de ajustarse al pixel.

   Consecuencia de diseño, y es deliberada: las etiquetas sólo se ven desde
   1600px. Antes se veían desde 1200 pero pintadas encima de la marca y parte
   saliéndose de la pantalla, que es peor que no verlas. */
@media (min-width: 1200px) and (max-width: 1599.98px) {
  html[data-app-theme="tecsa-clinico"] .app-navbar .nav-label {
    display: none;
  }
}

/* ==========================================================================
   BANDA DE ESTADÍSTICAS DEL PIE — RECONSTRUIDA
   ==========================================================================
   AUDITORÍA, medida en Chromium componiendo alfa y degradado a mano. La banda
   está sobre `#134e4a`, un teal oscuro, y:

       chip  icono   glifo   valor        etiqueta
       1     #51b968  2.47:1  #185fa5 1.45:1   #444441 1.03:1
       2     #357abd  4.50:1  #185fa5 1.45:1   #444441 1.03:1
       3     #ee5a52  3.38:1  #185fa5 1.45:1   #444441 1.03:1
       4     #ffc312  1.61:1  #185fa5 1.45:1   #444441 1.03:1
       5     #51b968  2.47:1  #185fa5 1.45:1   #444441 1.03:1

   Los CINCO valores a 1.45:1 y las CINCO etiquetas a 1.03:1: la banda entera
   era ilegible, no «un par de elementos». Los glifos iban de 1.61 a 4.50:1, y
   sólo uno pasaba. Los anchos además eran desiguales (130, 139, 148, 157), así
   que la fila no leía como una fila de iguales.

   Y POR QUÉ LA BANDA QUEDA CLARA, Y CÓMO SE CONSIGUE
   --------------------------------------------------
   Aquí se cometió un error de método y conviene que quede escrito. La primera
   versión de esta reconstrucción dio por hecho —sin medirlo— que el pie era
   claro, porque el ticker y el copyright sí lo son, y puso tinta oscura en los
   valores y las etiquetas. MEDIDO después:

       div.footer-content ....... linear-gradient(135deg, rgb(19,78,74) …)
       div.footer-professional ... rgb(237, 243, 250)

   El degradado teal oscuro de `.footer-content` se pintaba ENCIMA de la banda.
   `background: transparent` en la fila no lo quita: lo deja ver. Resultado:
   valores a 1.83:1 y etiquetas a 1.12:1, es decir, letra negra sobre fondo
   oscuro — lo que el usuario reportó.

   Arreglo: que `.footer-content` deje de pintar su degradado bajo este tema.
   Su contenedor, `.footer-professional`, ya es `#EDF3FA`; con el degradado
   fuera, la banda hereda esa superficie clara y todo lo demás del pie queda
   coherente con ella (el ticker ya la usaba). Con eso:

       valor     #101B27 sobre #EDF3FA ... 15.56:1
       etiqueta  #444E5A sobre #EDF3FA ...  7.57:1
       separador #E3EAF3 sobre #EDF3FA ...  1.08:1  (decorativo)
       iconos: glifo sobre su tinte .... 5.72 / 5.70 / 5.66 / 5.28 / 4.57:1

   La lección no es «cuidarse con los degradados»: es que «el resto del pie es
   claro» es una afirmación sobre una superficie que hay que MEDIR, igual que
   el contraste.
   ========================================================================== */
html[data-app-theme="tecsa-clinico"] .footer-professional .footer-content {
  background-image: none;
  background-color: transparent;
  /* La altura va por --footer-height-expanded (ver PIE — TICKER, SOLAPA,
     ALTURA Y BREAKPOINTS): la misma variable reserva el padding del body. */
  max-height: calc(var(--footer-height-expanded) + var(--footer-ticker-height));
}

/* ==========================================================================
   POR QUÉ CLARA Y NO OSCURA, Y CÓMO SE CONSIGUE
   POR QUÉ CLARA Y NO OSCURA
   -------------------------
   Bandearla de oscuro obligaría a inventar una quinta superficie clara para el
   copyright y otra para el ticker. Bandearla de clara la deja speak la misma
   voz que el resto del pie y deja la tinta del tema, que ya está medida.

   CÓMO SE ARMA UNA BANDA DE ESTADÍSTICAS QUE FUNCIONA
   ---------------------------------------------------
   1. CINCO CELDAS IGUALES. `flex: 1 1 0` en vez de ancho por contenido: la
      fila deja de leerse como cinco elementos de tamaño disparatado y pasa a
      leerse como una rejilla. Con `gap` y `max-width` para que no se estire en
      pantallas anchas.

   2. SEPARADORES VERTICALES entre celdas, no cajas. Es el patrón de las
     Applications grandes (Datadog, Stripe, Grafana): una fila, un hairline,
      cinco cifras. Las cajas compiten con el contenido; los separadores lo
      ordenan.

   3. EL ICONO ES UN TINTE CLARO CON GLIFO OSCURO, al revés que antes. Antes
      era un círculo saturado con glifo blanco, y sobre amarillo (#ffc312) eso
      da 1.61:1 — no hay forma de que un blanco se lea sobre amarillo. Ahora el
      tinte es una mezcla del color con blanco al 14% y el glifo es la versión
      oscura del mismo color. Cada chip conserva su identidad semántica y las
      cinco son legibles:

          Pacientes  #186B40 sobre #E6F3EB ....  5.72:1
          Familias   #185FA5 sobre #E6F1FB ....  5.70:1
          Riesgo Alto #B3261E sobre #FCEBE9 ....  5.66:1
          Perfiles   #8A5A00 sobre #FBF1DC ....  5.28:1
          Nuevos 30d #117A63 sobre #E4F2EE ....  4.57:1

   4. CIFRA Y ETIQUETA CON JERARQUÍA, no del mismo peso. La cifra manda:
      18px, 700, cifras tabulares. La etiqueta informa: 11px, 500, mayúsculas
      con interletraje, en tinta atenuada. 17.85:1 y 8.46:1 sobre blanco.

   5. SIN TRANSFORM EN EL HOVER. El hover cambia fondo y borde, no escala: un
      `translateY` en una fila de cifras las descentra de la línea base y hace
      que la fila «balee» al pasar el ratón. Ya venía un `translateY(-2px)` en el
      CSS del pie y aquí se anula.

   6. OBJETIVO TÁCTIL. Cada celda es un enlace: 44px de alto mínimo, que es el
      mínimo del proyecto (WCAG 2.2 AA 2.5.8 pide 24).
   ========================================================================== */
html[data-app-theme="tecsa-clinico"] .footer-stats-row {
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  justify-content: center;
  gap: 0;
  max-width: 72rem;
  margin: 0 auto;
  /* Aire arriba y abajo: es una banda, no una tira pegada al borde. */
  padding: 0.25rem 0;
  background: transparent;
}

html[data-app-theme="tecsa-clinico"] .footer-stats-row .footer-stat {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  /* El contenido se centra dentro de la celda: con celdas de 252px y un
     grupo de ~110px, alineado a la izquierda queda media celda vacía y la
     fila no lee como una rejilla sino como cinco textos con hueco. */
  justify-content: center;
  /* MEDIDO: con la celda a 151px (el pie mide 756px para cinco celdas), un
     padding de 1rem por lado + icono de 36px + hueco de 12px dejaban 79px
     para la etiqueta y «RIESGO ALTO» mide ~95px: se truncaba a «RIESGO A…».
     Con 32px de icono, 6px de hueco y padding de 6px por lado quedan 95px
     justos para «RIESGO ALTO» y «NUEVOS 30D», que son las dos largas. */
  gap: 0.375rem;
  padding: 0.875rem 0.375rem;
  /* footer.css pinta cada celda con blanco al 10%: invisible sobre el pie
     claro, pero en oscuro levantaba una caja gris detrás de cada cifra. */
  background: transparent;
  min-height: var(--touch-target);
  border-radius: var(--tca-radius);
  text-decoration: none;
  /* El hover cambia superficie, no posición: ver punto 5 del comentario. */
  transition: background-color var(--tca-dur-fast) var(--tca-ease),
    color var(--tca-dur-fast) var(--tca-ease);
}

/* Separador vertical entre celdas. Es lo que hace que cinco elementos se lean
   como una fila y no como cinco tarjetas sueltas. Se usa `--ui-border` y no
   `--ui-border-soft` porque el soft medía 1.08:1 sobre la banda: un separador
   que no se ve no separa. */
html[data-app-theme="tecsa-clinico"] .footer-stats-row .footer-stat + .footer-stat {
  border-left: 1px solid var(--ui-border);
  border-radius: 0;
}

html[data-app-theme="tecsa-clinico"] .footer-stats-row .footer-stat:hover,
html[data-app-theme="tecsa-clinico"] .footer-stats-row .footer-stat:focus-visible {
  background-color: var(--ui-tint-primary);
  transform: none;
  box-shadow: none;
  text-decoration: none;
}

html[data-app-theme="tecsa-clinico"] .footer-stats-row .footer-stat:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: -2px;
}

/* Icono: tinte claro del color semántico, con borde del mismo tono. */
html[data-app-theme="tecsa-clinico"] .footer-stat-icon {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  flex-shrink: 0;
  font-size: 0.9375rem;
  background: var(--stat-tinte, var(--ui-surface-2));
  border: 1px solid var(--stat-borde, var(--ui-border-soft));
  color: var(--stat-glifo, var(--ui-text));
}

html[data-app-theme="tecsa-clinico"] .footer-stat-icon i,
html[data-app-theme="tecsa-clinico"] .footer-stat-icon svg {
  color: inherit;
}

html[data-app-theme="tecsa-clinico"] .footer-stat-icon.patients {
  --stat-tinte: var(--tca-stat-pacientes-bg);
  --stat-borde: var(--tca-stat-pacientes-bd);
  --stat-glifo: var(--tca-stat-pacientes-fg);
}

html[data-app-theme="tecsa-clinico"] .footer-stat-icon.families {
  --stat-tinte: var(--tca-stat-familias-bg);
  --stat-borde: var(--tca-stat-familias-bd);
  --stat-glifo: var(--tca-stat-familias-fg);
}

html[data-app-theme="tecsa-clinico"] .footer-stat-icon.risk-high {
  --stat-tinte: var(--tca-stat-riesgo-bg);
  --stat-borde: var(--tca-stat-riesgo-bd);
  --stat-glifo: var(--tca-stat-riesgo-fg);
}

html[data-app-theme="tecsa-clinico"] .footer-stat-icon.risk-medium {
  --stat-tinte: var(--tca-stat-perfiles-bg);
  --stat-borde: var(--tca-stat-perfiles-bd);
  --stat-glifo: var(--tca-stat-perfiles-fg);
}

html[data-app-theme="tecsa-clinico"] .footer-stat-icon.risk-low {
  --stat-tinte: var(--tca-stat-nuevos-bg);
  --stat-borde: var(--tca-stat-nuevos-bd);
  --stat-glifo: var(--tca-stat-nuevos-fg);
}

/* Jerarquía cifra/etiqueta: la cifra manda, la etiqueta informa. */
html[data-app-theme="tecsa-clinico"] .footer-stat-info {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
  min-width: 0;
  line-height: 1.15;
}

html[data-app-theme="tecsa-clinico"] .footer-stat-value {
  color: var(--tca-stat-valor);
  font-size: 1.125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1.15;
  text-transform: none;
}

/* La etiqueta SE PARTE en dos líneas en vez de truncarse.

   MEDIDO: el pie deja 756px para cinco celdas, o sea 151px por celda. Con
   icono de 32px, hueco y padding, a la etiqueta le quedan ~95px, y «RIESGO
   ALTO» y «NUEVOS 30D» miden un poco más. Con `nowrap` + `ellipsis` salían
   «RIESGO A…» y «NUEVOS 3…».

   Probar primero apretando el espaciado NO lo resolvió: el cuello de botella
   no es el padding, es que la celda no crece. Dejar que la etiqueta baje a
   una segunda línea es la solución robusta —no depende del ancho ni del
   idioma, que es el problema real: un «Riesgo alto» o un «Riesgo elevado» en
   otro idioma no caben igual— y mantiene las cinco celdas con la misma
   altura gracias al min-height de abajo.

   Se reserva la altura de dos líneas en TODAS las celdas, no solo en las que
   hacen falta: si dependiera del contenido, las cinco celdas tendrían
   alturas distintas y la fila dejaría de leerse como una fila. */
html[data-app-theme="tecsa-clinico"] .footer-stat-label {
  color: var(--tca-stat-label);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  line-height: 1.2;
  white-space: normal;
  overflow-wrap: break-word;
  min-height: 2.4em;
  display: flex;
  align-items: center;
}

html[data-app-theme="tecsa-clinico"] .footer-stat-link:hover .footer-stat-value,
html[data-app-theme="tecsa-clinico"] .footer-stat-link:focus-visible .footer-stat-value {
  color: var(--ui-secondary-hover);
}

html[data-app-theme="tecsa-clinico"] .footer-stat-link:hover .footer-stat-icon,
html[data-app-theme="tecsa-clinico"] .footer-stat-link:focus-visible .footer-stat-icon {
  border-color: var(--tca-azul-300);
}

/* ==========================================================================
   PIE — TICKER, SOLAPA, ALTURA Y BREAKPOINTS
   ==========================================================================
   MEDIDO en /profile/ a 1440px, modo claro:

       .footer-content ......... 219px de contenido en un max-height de 140px:
                                 el copyright quedaba fuera de pantalla
       solapa «Info» ........... 44px de alto con `top: -32px`: invadía 12px
       etiqueta «Noticias» ..... #444441 sobre el degradado marino legacy, ~1.6:1
       enlaces del ticker ...... #0D6EFD de Bootstrap, 4.03:1

   Y una causa de cascada: footer.css vive en `@layer components` y la banda
   reconstruida de arriba NO tiene capa, así que gana siempre — también a los
   `display: none` responsive del legacy, que quedaron muertos. Por eso los
   breakpoints se re-declaran aquí, sin capa.

   La altura va por `--footer-height-expanded`, no por `max-height` suelto:
   es la misma variable con la que footer.css reserva el `padding-bottom` del
   body, así que pie y reserva no pueden desincronizarse. */
html[data-app-theme="tecsa-clinico"] {
  --footer-height-expanded: 11.25rem;
}

/* La solapa: superficie del tema y tinta heredada. Con `background` (y no
   sólo `background-color`) se quita el degradado marino legacy, que es el
   que se pintaba encima del color que el tema declaraba. */
html[data-app-theme="tecsa-clinico"] .footer-toggle {
  top: calc(-1 * var(--touch-target));
  height: var(--touch-target);
  background: var(--ui-surface);
  color: var(--ui-text);
  border-bottom: 0;
  border-radius: var(--tca-radius-sm) var(--tca-radius-sm) 0 0;
  box-shadow: var(--ui-elev-1);
}

html[data-app-theme="tecsa-clinico"] .footer-toggle:hover {
  background: var(--ui-surface-2);
  transform: translateX(-50%);
}

html[data-app-theme="tecsa-clinico"] .footer-toggle-icon,
html[data-app-theme="tecsa-clinico"] .footer-toggle-text {
  color: inherit;
}

html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-label {
  background: var(--ui-tint-primary-2);
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-item,
html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-item span {
  color: var(--ui-text);
}

html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-item a {
  color: var(--ui-secondary);
  text-decoration-color: var(--ui-border-strong);
}

html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-item a:hover,
html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-item a:focus-visible {
  color: var(--ui-secondary-hover);
  text-decoration-color: currentColor;
}

/* Las insignias usan los rellenos del tema, ya medidos con tinta on-fill;
   el degradado legacy se pintaba encima de ellos. */
html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-badge {
  background-image: none;
}

html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-item .footer-ticker-badge {
  color: var(--ui-text-on-fill);
}

@media (max-width: 767.98px) {
  html[data-app-theme="tecsa-clinico"] {
    /* MEDIDO a 600px: banda sin etiquetas + ticker + copyright = 150px. */
    --footer-height-expanded: 9.5rem;
  }

  html[data-app-theme="tecsa-clinico"] .footer-stats-row .footer-stat {
    padding: 0.5rem 0.25rem;
  }

  html[data-app-theme="tecsa-clinico"] .footer-stat-label {
    display: none;
  }
}

@media (max-width: 575.98px) {
  html[data-app-theme="tecsa-clinico"] {
    /* MEDIDO a 500px: ticker + copyright = 80px. */
    --footer-height-expanded: 5rem;
  }

  html[data-app-theme="tecsa-clinico"] .footer-stats-row {
    display: none;
  }
}

/* ==========================================================================
   DRAWER DE FILTROS (#filter-section) — SUPERFICIE Y TINTA
   ==========================================================================
   AUDITORÍA sobre /profile/, con el fondo compuesto a mano. El panel es
   `rgba(8, 20, 32, 0.6)` —cristal oscuro de la piel anterior— que sobre la
   página clara compone a `#687179`. Encima, MEDIDO:

       título "Filtros y período de análisis" ..  2.75:1   FALLA
       chevron .................................  1.76:1   FALLA
       "Períodos rápidos:" ....................  2.38:1   FALLA
       badge del rango de fechas ..............  3.09:1   FALLA
       etiquetas de campo .....................  4.36:1   FALLA
       chips de periodo ........................  4.36:1   FALLA
       botón "Limpiar" ........................  2.75:1   FALLA
       botón "Filtrar" .........................  4.99:1   OK

   SEIS DE NUEVE ELEMENTOS POR DEBAJO. Y hay un dato que decide el arreglo:
   sobre `#687179` sólo pasan `#F2F7FD` (4.61:1) y el blanco. NO hay sitio
   para una tinta atenuada: la más clara que seleysabe, `#B9CEE4`, cae a
   3.08:1. Un panel a media luz no puede sostener jerarquía de texto —todo
   tendría que ir casi blanco y entonces nada se distingue de nada.

   Por eso el arreglo no es retocar los ocho colores: es cambiar la
   SUPERFICIE. El drawer pasa a la misma familia que la cabecera y que las
   pestañas, que ya son blancas, y con superficie clara vuelve a haber sitio
   para una jerarquía real:

       título    #101B27 sobre #FFFFFF ...... 17.85:1
       etiquetas #444E5A sobre #FFFFFF ......  7.57:1
       secundario #5B6B78 sobre #FFFFFF .....  5.50:1
       acento    #185FA5 sobre #FFFFFF ......  5.50:1

   Un dato más que sale de la medición: los chips y las etiquetas ya usaban
   tinta clara (`#E6F1FB`) porque el panel era oscuro. Al aclarar el panel
   hay que devolverles tinta oscura, o se quedan ilegibles al revés.

   Se acota a `#filter-section` y a lo que dibuja, que es lo que esta
   plantilla renderiza; no se toca `dashboard-profile.css`.
   ========================================================================== */
html[data-app-theme="tecsa-clinico"] #filter-section {
  background: var(--ui-surface);
  border: 1px solid var(--ui-border);
  border-radius: var(--tca-radius-lg);
  box-shadow: 0 1px 2px rgb(16 27 39 / 0.04), 0 8px 24px rgb(16 27 39 / 0.06);
}

html[data-app-theme="tecsa-clinico"] #filter-section .profile-filter__label,
html[data-app-theme="tecsa-clinico"] #filter-section .profile-filter__toggle {
  color: var(--ui-text-strong);
}

html[data-app-theme="tecsa-clinico"] #filter-section .profile-filter__label {
  font-weight: 700;
  letter-spacing: 0.02em;
}

html[data-app-theme="tecsa-clinico"] #filter-section .profile-filter__icon {
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] #filter-section .profile-filter__chevron {
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] #filter-section .profile-filter__toggle:hover,
html[data-app-theme="tecsa-clinico"] #filter-section .profile-filter__toggle:focus-visible {
  background-color: var(--ui-tint-primary);
  color: var(--ui-text-strong);
}

html[data-app-theme="tecsa-clinico"] #filter-section .form-label {
  color: var(--tca-stat-label);
  font-weight: 600;
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
}

html[data-app-theme="tecsa-clinico"] #filter-section .form-label i,
html[data-app-theme="tecsa-clinico"] #filter-section .form-label svg {
  color: var(--ui-secondary);
}

/* Los chips vuelven a tinta oscura: el panel ya no es oscuro. */
html[data-app-theme="tecsa-clinico"] #filter-section .preset-date-btn {
  color: var(--ui-secondary);
  background: var(--ui-surface);
  border-color: var(--tca-azul-300);
  font-weight: 600;
  min-height: var(--touch-target);
}

html[data-app-theme="tecsa-clinico"] #filter-section .preset-date-btn:hover,
html[data-app-theme="tecsa-clinico"] #filter-section .preset-date-btn:focus-visible {
  color: var(--ui-secondary-hover);
  background: var(--ui-tint-primary);
  border-color: var(--tca-azul-700);
}

/* Foco visible propio: el anillo heredado era --tca-azul-100, pensado para el
   panel oscuro, y sobre la superficie clara quedaba casi blanco sobre blanco. */
html[data-app-theme="tecsa-clinico"] #filter-section .preset-date-btn:focus-visible {
  outline: var(--tca-focus-width) solid var(--ui-secondary);
  outline-offset: 2px;
}

html[data-app-theme="tecsa-clinico"] #filter-section .preset-date-btn[data-active="true"] {
  color: var(--ui-text-on-fill);
  background-color: var(--ui-primary);
  border-color: var(--ui-primary);
}

html[data-app-theme="tecsa-clinico"] #filter-section .text-muted.small.fw-bold {
  color: var(--tca-stat-label);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-size: var(--fs-xs);
}

html[data-app-theme="tecsa-clinico"] #filter-section .text-muted.small.fw-bold i,
html[data-app-theme="tecsa-clinico"] #filter-section .text-muted.small.fw-bold svg {
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] #filter-section #date-range-badge {
  color: var(--tca-stat-label);
  background: var(--ui-surface-2);
  border: 1px solid var(--ui-border-soft);
  font-variant-numeric: tabular-nums;
}

html[data-app-theme="tecsa-clinico"] #filter-section .btn-secondary-custom {
  color: var(--ui-secondary);
  border-color: var(--tca-azul-300);
}

html[data-app-theme="tecsa-clinico"] #filter-section .btn-secondary-custom:hover,
html[data-app-theme="tecsa-clinico"] #filter-section .btn-secondary-custom:focus-visible {
  color: var(--ui-secondary-hover);
  background-color: var(--ui-tint-primary);
  border-color: var(--tca-azul-700);
}

html[data-app-theme="tecsa-clinico"] #filter-section .form-control,
html[data-app-theme="tecsa-clinico"] #filter-section .form-select {
  background: var(--ui-surface);
  border-color: var(--ui-border);
  color: var(--ui-text-strong);
  min-height: var(--touch-target);
}

html[data-app-theme="tecsa-clinico"] #filter-section :is(.form-control, .form-select):focus {
  border-color: var(--tca-azul-500);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--tca-azul-500) 25%, transparent);
  color: var(--ui-text-strong);
}

/* --- /profile: título de la cabecera y ticker del pie ------------------------
   MEDIDO en Chromium sobre /profile/, componiendo alfa a mano. Los dos son
   el mismo defecto que el del sidebar —tinta blanca de la piel oscura sobre
   una superficie que este tema vuelve clara— pero aquí el que más se nota es
   el título:

       h2.dashboard-header__title ... 1.00:1   blanco sobre blanco
       .footer-ticker-separator ..... 1.12:1   blanco sobre #EDF3FA
       .profile-tab.is-active ..... 2.16:1   (arreglado arriba)

   El título se ve directamente en /app/static/assets/css/dashboard-v2.css:117
   como `color: var(--tricorder-text, #E0F7FA)`, y `--tricorder-text` SÍ vale
   `#16303f` (medurado sobre el propio elemento). O sea: la cadena está
   escrita bien y el valor llega bien, pero el color computado sigue siendo
   blanco — hay algo que gana más arriba. Se corrige declarando la tinta aquí,
   que es donde este tema ya resuelve sus conflictos con las hojas previas. */
html[data-app-theme="tecsa-clinico"] .dashboard-header__title {
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] .dashboard-header__subtitle {
  color: var(--ui-text-muted);
}

/* El ticker del pie sí es CLARO bajo este tema, así que aquí la tinta va
   oscura: `--tca-azul-900` da 5.84:1 sobre `--ui-surface-2` (#EDF3FA). */
html[data-app-theme="tecsa-clinico"] .footer-ticker-separator,
html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-separator {
  color: var(--ui-secondary);
}


/* --- Tamaño de las etiquetas del navbar --------------------------------------
   MEDIDO antes de tocarlo: las tres etiquetas heredaban 16px del enlace, que
   es el tamaño de cuerpo de la página, no el de una etiqueta de navegación.
   Suman 120 + 90 + 90 = 300px de texto antes de iconos y padding.

   Se bajan a `--fs-sm` (clamp 13→14px), que es el token que el tema ya usa
   para toda su UI, y se aprieta el interletraje un poco. Con eso los tres
   rótulos pasan de 300px a 263px medidos: se recuperan 37px, que es
   justamente lo que hacía falta para que la barra no se solape con el rail
   de identidad.

   14px con peso 400 sigue siendo texto NORMAL a efectos de WCAG (la
   exemption de «texto grande» pide 18.66px en negrita o 24px), así que el
   mínimo sigue siendo 4.5:1 y no baja el listón. Sobre el navbar azul
   marino la tinta clara lo cumple de sobra. */
html[data-app-theme="tecsa-clinico"] .app-navbar .nav-label {
  font-size: var(--fs-sm);
  letter-spacing: 0.01em;
  line-height: 1.2;
}

/* --- Los enlaces de navegación en la franja solo-iconos, al ancho justo ---
   MEDIDO: en la franja 992-1199.98px —donde la etiqueta se oculta y queda
   sólo el icono— el enlace mide ~33x44px. Pasa el mínimo de WCAG 2.2 AA
   2.5.8 (24px) pero no el del proyecto (--touch-target, 44px), y 33px es
   una franja incómoda para un dedo adulto en un portátil pequeño.

   Por qué se puede arreglar aquí sin `!important` (R10):
   `chrome-tricorder.css:770` fija el PADDING de esa franja con
   `padding: 0.48rem 0.55rem !important`, dentro de @layer. Ganarle con
   `!important` propio está prohibido, y no hace falta: `min-width` es otra
   propiedad, no la que ese bloque toca. Se declara min-width y NO se toca el
   padding, así que el ajuste estilístico preexistente se respeta y sólo
   cambia el suelo del objetivo táctil.

   `min-height` ya lo pone chrome-tricorder.css (`.nav-link { min-height:
   var(--touch-target, 44px) }`); se repite aquí para que el bloque se lea
   por sí mismo. */
html[data-app-theme="tecsa-clinico"] .app-navbar .nav-link {
  min-width: var(--touch-target);
  min-height: var(--touch-target);
}

/* Por debajo de 480px el rail se aprieta más: menos padding lateral y la
   marca algo menor, sin bajar nunca del objetivo táctil. */
@media (max-width: 479.98px) {
  html[data-app-theme="tecsa-clinico"] .app-navbar {
    padding-left: var(--space-2xs);
    padding-right: var(--space-2xs);
  }

  html[data-app-theme="tecsa-clinico"] .app-brand__mark {
    width: 26px;
    height: 26px;
  }

  html[data-app-theme="tecsa-clinico"] .ui-theme-panel {
    min-width: min(15rem, calc(100vw - 1.5rem));
  }

  /* MEDIDO a 375px: 13.6 + 44 (marca) + 281 (rail) + 44 (menú) + 13.6 =
     396px. El botón de menú —el único acceso a la navegación en móvil—
     quedaba 21px fuera de pantalla. El padding de arriba no llegaba: el que
     sobraba era el del .container-fluid interior. Y la píldora de
     privilegio medía 63px para un icono de 20: queda en el objetivo táctil,
     sin el punto (el borde ámbar sigue marcando el privilegio, y la
     etiqueta va en el title). */
  html[data-app-theme="tecsa-clinico"] .app-navbar > .container-fluid {
    padding-left: var(--space-2xs);
    padding-right: var(--space-2xs);
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .admin-global-pill {
    min-width: var(--touch-target);
    padding-left: 0;
    padding-right: 0;
    gap: 0;
    justify-content: center;
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .admin-global-pill__dot {
    display: none;
  }
}

/* --- Botón de éxito ----------------------------------------------------------
   custom.css:681 lo pinta con un degradado verde claro (#6CCB7A → #51B968) y
   texto blanco: 2.1-2.5:1, «Programar Reporte» en la cabecera de /profile/ no
   pasaba. Mismo criterio que el primario: relleno de marca y tinta on-fill
   (#101B27 sobre #1D9E75 ≈ 5:1), igual en ambos modos. */
html[data-app-theme="tecsa-clinico"] .btn-success,
html[data-app-theme="tecsa-clinico"] .btn-success:hover,
html[data-app-theme="tecsa-clinico"] .btn-success:focus-visible {
  background: var(--ui-success);
  border-color: var(--ui-success);
  color: var(--ui-text-on-fill);
}

/* --- Enlaces que Bootstrap repinta ------------------------------------------
   bootstrap.min.css no tiene capa, así que su `a { color: #0D6EFD }` gana a
   cualquier `color` de las hojas legacy, que sí la tienen. MEDIDO en /profile/:

       «Administración global» (sidebar) ... #0D6EFD sobre tinte ámbar  4.27:1
       «Ver casos» (alertas críticas) ...... #0D6EFD sobre tinte rojo   3.91:1

   Se declaran aquí, sin capa. «Ver casos» va en el rojo de la banda de
   riesgo del pie (5.66:1 sobre su tinte), que theme-dark.css ya invierte. */
html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-admin-launcher__title {
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] #sidebar-container .sidebar-admin-launcher__hint {
  color: var(--ui-text-muted);
  opacity: 1;
}

html[data-app-theme="tecsa-clinico"] .kpi-alert-action,
html[data-app-theme="tecsa-clinico"] .kpi-alert-action:hover {
  color: var(--tca-stat-riesgo-fg);
}

/* Insignia ALERTA del ticker: la tinta on-fill (#101B27) sobre --ui-danger
   daba 3.60:1 en claro. Con la superficie como tinta: blanco sobre #DC2626 =
   4.83:1 en claro, #101B27 sobre #EF4444 = 4.62:1 en oscuro. */
html[data-app-theme="tecsa-clinico"] .footer-professional .footer-ticker-item .footer-ticker-badge.is-alert {
  color: var(--ui-surface);
}

/* --- X de cierre en cabeceras de modal con relleno de color ------------------
   dashboard-v2.css pinta .modal-header.bg-primary/.bg-success con un relleno
   que va al revés que la página: oscuro en modo claro (azul 900, verde) y
   claro en modo oscuro (azul 300, verde menta). Bootstrap decide la X por
   el modo de la página, así que en las dos combinaciones salía del mismo
   tono que el relleno. Aquí se invierte sólo en esas cabeceras. */
html[data-app-theme="tecsa-clinico"]:not([data-color-mode="dark"]) .modal-header:is(.bg-primary, .bg-success) .btn-close {
  filter: var(--bs-btn-close-white-filter);
}

html[data-app-theme="tecsa-clinico"][data-color-mode="dark"] .modal-header:is(.bg-primary, .bg-success) .btn-close {
  filter: none;
}

/* ==========================================================================
   BARRA SUPERIOR — REDISEÑO (consola clínica)
   ==========================================================================
   MEDIDO a 1865px antes de tocarla:

       alto ........................ 90px, con la fila centrada en 44px
       fondo ....................... #134D6D plano, teal del tema anterior
       distribución ................ marca en x=12, selector de plan en
                                     x≈345 (`ms-auto` empujaba los enlaces
                                     a la derecha) y todo el rail apiñado
                                     al final: un hueco de ~300px sin nada
       hamburguesa ................. visible en escritorio, sin función
       tema ........................ un cuadrado blanco opaco en mitad de
                                     la barra marina
       «Admin global» .............. azul de Bootstrap sobre marino ~2.5:1
       tipografía .................. JetBrains Mono (ver --font-base)

   La barra nueva es una sola composición: [marca | destinos ……… contexto
   · herramientas · identidad · salida]. Marino de marca con una línea de
   firma azul→lavanda (el mismo degradado del sidebar) y controles
   «fantasma» que sólo se materializan al pasar o al enfocar. Todo con
   los tokens --tca-nav-* (contrastes en tokens.css). Sin capa: tiene que
   ganar a chrome-tricorder.css y navbar.css, que viven en
   `@layer components`. */
html[data-app-theme="tecsa-clinico"] .app-navbar {
  padding-top: 0;
  padding-bottom: 0;
  background-color: var(--tca-nav-950);
  background-image: linear-gradient(
    100deg,
    var(--tca-nav-950) 0%,
    var(--tca-nav-950) 40%,
    var(--tca-nav-800) 100%
  );
  border-bottom: 0;
  box-shadow: 0 10px 28px -16px rgb(11 30 51 / 0.55);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Línea de firma: 2px de marca a lo largo del borde inferior. */
html[data-app-theme="tecsa-clinico"] .app-navbar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: linear-gradient(
    90deg,
    var(--tca-azul-500) 0%,
    var(--tca-lav-700) 55%,
    transparent 100%
  );
  pointer-events: none;
}

html[data-app-theme="tecsa-clinico"] .app-navbar > .container-fluid {
  flex-wrap: nowrap;
  gap: var(--space-xs);
}

/* --- Marca: el símbolo sobre una baldosa de marca -------------------------
   Sigue siendo sólo el símbolo, a 44x44 (contrato de
   test_header_clinico_e2e). Blanco sobre la baldosa: 3.40:1 en el azul y
   3.56:1 en la lavanda (WCAG 1.4.11, objeto gráfico, pide 3:1); sobre la
   barra, 15.93:1. */
html[data-app-theme="tecsa-clinico"] .app-navbar .app-brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 var(--touch-target);
  width: var(--touch-target);
  height: var(--touch-target);
  margin: 0;
  padding: 0;
  border-radius: 12px;
  position: relative;
  isolation: isolate;
  box-shadow: 0 6px 18px -6px rgb(55 138 221 / 0.65);
  color: var(--tca-nav-ink);
}

/* La baldosa va en un pseudo-elemento: navbar.css impone
   `.navbar-brand { background: none !important }` desde @layer components,
   y un !important con capa gana a cualquier regla sin capa. */
html[data-app-theme="tecsa-clinico"] .app-navbar .app-brand::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(135deg, var(--tca-azul-500) 0%, var(--tca-lav-700) 100%);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.14);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .app-brand__mark {
  width: 26px;
  height: 26px;
  color: var(--tca-nav-ink);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .app-brand:focus-visible {
  outline: 2px solid var(--tca-azul-300);
  outline-offset: 3px;
}

/* --- Destinos ------------------------------------------------------------ */
html[data-app-theme="tecsa-clinico"] .app-navbar #navcol-1 .nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: var(--touch-target);
  padding: 0 0.875rem;
  border-radius: 10px;
  background: transparent;
  color: var(--tca-nav-ink-muted);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-shadow: none;
  transition:
    background-color var(--tca-dur-fast) var(--tca-ease),
    color var(--tca-dur-fast) var(--tca-ease);
}

html[data-app-theme="tecsa-clinico"] .app-navbar #navcol-1 .nav-link :is(i, svg) {
  color: var(--tca-azul-300);
  width: 1.1em;
}

html[data-app-theme="tecsa-clinico"] .app-navbar #navcol-1 .nav-link:hover,
html[data-app-theme="tecsa-clinico"] .app-navbar #navcol-1 .nav-link:focus-visible {
  background: rgb(255 255 255 / 0.08);
  color: var(--tca-nav-ink);
}

html[data-app-theme="tecsa-clinico"] .app-navbar #navcol-1 .nav-link.active {
  background: rgb(255 255 255 / 0.1);
  color: var(--tca-nav-ink);
  font-weight: 600;
}

/* --- Selector de plan: botón fantasma, no un `btn-primary btn-lg` -------- */
html[data-app-theme="tecsa-clinico"] .app-navbar .plan-selector-btn {
  /* El parcial trae un <style> en línea con min-width: 180px (y
     chrome-tricorder.css, 200px) para un botón que en la barra sólo muestra
     icono y flecha. */
  min-width: var(--touch-target);
  width: auto;
  min-height: var(--touch-target);
  padding: 0 0.75rem;
  border-radius: 10px;
  background: rgb(255 255 255 / 0.06);
  border: 1px solid rgb(255 255 255 / 0.14);
  color: var(--tca-nav-ink);
  box-shadow: none;
  font-size: var(--fs-sm);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .plan-selector-btn:hover,
html[data-app-theme="tecsa-clinico"] .app-navbar .plan-selector-btn:focus-visible,
html[data-app-theme="tecsa-clinico"] .app-navbar .plan-selector-btn[aria-expanded="true"] {
  background: rgb(255 255 255 / 0.12);
  border-color: rgb(255 255 255 / 0.28);
  color: var(--tca-nav-ink);
}

/* --- Rail: contexto · herramientas · identidad · salida ------------------ */
html[data-app-theme="tecsa-clinico"] .app-navbar__actions {
  align-items: center;
  gap: 0.25rem;
}

html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill {
  min-height: var(--touch-target);
  max-width: 17rem;
  margin-right: 0.375rem;
  padding: 0.25rem 0.875rem 0.25rem 0.375rem;
  gap: 0.625rem;
  border-radius: 12px;
  background: rgb(255 255 255 / 0.06);
  color: var(--tca-nav-ink);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill--activo {
  border: 1px solid rgb(255 255 255 / 0.14);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill > :is(svg, i) {
  flex: 0 0 auto;
  width: 1.125rem;
  height: 1.125rem;
  margin-left: 0.375rem;
  color: var(--tca-azul-300);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill__body {
  min-width: 0;
}

html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill__tenant,
html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill__plan {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  line-height: 1.25;
}

html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill__tenant {
  color: var(--tca-nav-ink);
  font-size: 0.8125rem;
  font-weight: 600;
}

html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill__plan {
  color: var(--tca-nav-ink-muted);
  font-size: var(--fs-xs);
  font-weight: 400;
}

/* Herramientas: un separador fino las aparta del contexto. */
html[data-app-theme="tecsa-clinico"] .app-navbar .ui-theme-control {
  padding-left: 0.375rem;
  border-left: 1px solid rgb(255 255 255 / 0.12);
}

html[data-app-theme="tecsa-clinico"] .app-navbar :is(.ui-theme-control__trigger, .med-logout-btn, .med-login-btn, .admin-global-pill) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  padding: 0 0.625rem;
  border-radius: 10px;
  background: transparent;
  border: 1px solid transparent;
  box-shadow: none;
  color: var(--tca-nav-ink-muted);
  font-size: var(--fs-sm);
  font-weight: 500;
  text-decoration: none;
  transition:
    background-color var(--tca-dur-fast) var(--tca-ease),
    color var(--tca-dur-fast) var(--tca-ease);
}

html[data-app-theme="tecsa-clinico"] .app-navbar :is(.ui-theme-control__trigger, .med-logout-btn, .med-login-btn, .admin-global-pill):is(:hover, :focus-visible) {
  background: rgb(255 255 255 / 0.08);
  color: var(--tca-nav-ink);
}

/* Privilegio: ámbar en icono y borde (10.33:1 sobre la barra); la etiqueta
   en tinta clara. El punto sobraba: el borde ya dice lo mismo. */
html[data-app-theme="tecsa-clinico"] .app-navbar .admin-global-pill {
  border-color: rgb(255 193 7 / 0.4);
  background: rgb(255 193 7 / 0.08);
  color: var(--tca-privilege);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .admin-global-pill .admin-global-pill__label {
  color: var(--tca-nav-ink);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .admin-global-pill__dot {
  display: none;
}

/* Identidad: avatar con anillo de marca, nombre en tinta clara. */
html[data-app-theme="tecsa-clinico"] .app-navbar .med-user-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: var(--touch-target);
  padding: 0.25rem 0.75rem 0.25rem 0.25rem;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.06);
  border: 1px solid rgb(255 255 255 / 0.14);
  color: var(--tca-nav-ink);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .med-user-chip:is(:hover, :focus-visible, [aria-expanded="true"]) {
  background: rgb(255 255 255 / 0.12);
  border-color: rgb(255 255 255 / 0.28);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .med-user-avatar {
  width: 34px;
  height: 34px;
  box-shadow:
    0 0 0 2px var(--tca-nav-950),
    0 0 0 3.5px var(--tca-azul-300);
}

html[data-app-theme="tecsa-clinico"] .app-navbar .med-user-name {
  color: var(--tca-nav-ink);
  font-size: var(--fs-sm);
  font-weight: 600;
  max-width: 10rem;
}

html[data-app-theme="tecsa-clinico"] .app-navbar .med-user-chip.dropdown-toggle::after {
  color: var(--tca-nav-ink-muted);
}

html[data-app-theme="tecsa-clinico"] .app-navbar :is(.nav-link, .plan-selector-btn, .tenant-pill, .ui-theme-control__trigger, .admin-global-pill, .med-user-chip, .med-logout-btn):focus-visible {
  outline: 2px solid var(--tca-azul-300);
  outline-offset: 2px;
}

/* --- Botón de ocultar la barra -------------------------------------------
   Era una caja flotante encima del borde derecho. Ahora es un control más
   de la barra, centrado en su alto, con su carril reservado. */
@media (min-width: 992px) {
  html[data-app-theme="tecsa-clinico"] .app-navbar > .container-fluid {
    padding-left: var(--space-md);
    padding-right: calc(var(--space-md) + var(--touch-target) + var(--space-xs));
  }

  /* Destinos pegados a la marca, separados por un filete. */
  html[data-app-theme="tecsa-clinico"] .app-navbar #navcol-1 {
    margin-left: var(--space-xs);
    padding-left: var(--space-sm);
    border-left: 1px solid rgb(255 255 255 / 0.12);
  }

  /* Centrado en la barra de escritorio, que el shell fija en 90px
     (theme-tokens.css): (90 - 44) / 2. El tema no puede leer esa variable
     (contrato del shell, test_ningun_tema_reescribe_el_shell). */
  html[data-app-theme="tecsa-clinico"] .header-collapse-toggle {
    top: 1.4375rem;
    right: var(--space-sm);
    width: var(--touch-target);
    height: var(--touch-target);
    border-radius: 10px;
    background: transparent;
    border: 1px solid rgb(255 255 255 / 0.14);
    box-shadow: none;
    color: var(--tca-nav-ink-muted);
  }

  html[data-app-theme="tecsa-clinico"] .header-collapse-toggle:is(:hover, :focus-visible) {
    background: rgb(255 255 255 / 0.08);
    color: var(--tca-nav-ink);
  }
}

/* Con la barra oculta, o en móvil (donde baja bajo la barra), el botón
   queda sobre el contenido: necesita superficie propia. */
html[data-app-theme="tecsa-clinico"] body.navbar-is-collapsed .header-collapse-toggle {
  top: var(--space-xs);
  background: var(--tca-nav-950);
  color: var(--tca-nav-ink);
  border-color: rgb(255 255 255 / 0.18);
  box-shadow: var(--ui-elev-2);
}

@media (max-width: 991.98px) {
  html[data-app-theme="tecsa-clinico"] .header-collapse-toggle {
    background: var(--tca-nav-950);
    color: var(--tca-nav-ink);
    border-color: rgb(255 255 255 / 0.18);
    box-shadow: var(--ui-elev-2);
  }

  /* Panel del hamburger: continúa la barra, no un bloque de otro color. */
  html[data-app-theme="tecsa-clinico"] .app-navbar .navbar-collapse {
    background: var(--tca-nav-950);
    border-top: 1px solid rgb(255 255 255 / 0.08);
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .navbar-collapse .nav-link {
    width: 100%;
    justify-content: flex-start;
  }
}

html[data-app-theme="tecsa-clinico"] .header-collapse-toggle:focus-visible {
  outline: 2px solid var(--tca-azul-300);
  outline-offset: 2px;
}

/* --- Fondo de la página ---------------------------------------------------
   Bajo la app había una fotografía (marca de agua) velada al 92% de blanco:
   ruido gris detrás de cada tarjeta. Pasa al canvas del tema con dos halos
   muy tenues de marca en las esquinas superiores, que dan profundidad sin
   competir con el contenido. Sólo en pantalla: la impresión conserva su
   papel blanco (responsive.css). */
@media screen {
  html[data-app-theme="tecsa-clinico"] body {
    background:
      radial-gradient(1100px 520px at 100% -8%, color-mix(in oklab, var(--ui-primary) 9%, transparent), transparent 70%),
      radial-gradient(900px 480px at -10% 0%, color-mix(in oklab, var(--ui-accent) 6%, transparent), transparent 70%),
      var(--ui-bg);
    background-attachment: fixed;
  }
}

/* --- Acciones de la cabecera de página: jerarquía, no cuatro colores -------
   MEDIDO en /profile/: «Reporte Gerencial» marino, «Programar Reporte»
   verde, «Mis Reportes» cian y «Centro IA» negro — cuatro rellenos que
   compiten y ninguno manda. Queda UNO primario (el marino, que ya
   comparte tono con la barra), dos secundarios suaves en el azul de
   marca y «Centro IA» en lavanda, que el branding reserva para la IA.
       secundario  #185FA5 sobre tinte azul ....... 5.83:1 (oscuro 7.11)
       IA          #655ACA sobre tinte lavanda 10% .. ~4.9:1 (oscuro 6.03)
   (El tinte lavanda estándar, lav-100, daba 4.44:1: por eso va al 10%.) */
html[data-app-theme="tecsa-clinico"] .dashboard-header__actions :is(.btn-success, .btn-info) {
  background: var(--ui-tint-primary);
  border: 1px solid color-mix(in oklab, var(--ui-primary) 28%, transparent);
  color: var(--ui-secondary);
  box-shadow: none;
}

html[data-app-theme="tecsa-clinico"] .dashboard-header__actions :is(.btn-success, .btn-info):is(:hover, :focus-visible) {
  background: var(--ui-tint-primary-2);
  border-color: color-mix(in oklab, var(--ui-primary) 45%, transparent);
  color: var(--ui-secondary);
}

html[data-app-theme="tecsa-clinico"] .dashboard-header__actions .btn-dark {
  background: color-mix(in oklab, var(--ui-accent) 10%, var(--ui-surface));
  border: 1px solid color-mix(in oklab, var(--ui-accent) 32%, transparent);
  color: var(--ui-accent-text);
  box-shadow: none;
}

html[data-app-theme="tecsa-clinico"] .dashboard-header__actions .btn-dark:is(:hover, :focus-visible, [aria-expanded="true"]) {
  background: color-mix(in oklab, var(--ui-accent) 18%, var(--ui-surface));
  border-color: color-mix(in oklab, var(--ui-accent) 50%, transparent);
  color: var(--ui-accent-text);
}

/* Por debajo de 480px la barra no tiene sitio para adornos: MEDIDO a 375px,
   la hamburguesa acababa en x=378. Fuera el filete del grupo de
   herramientas y el hueco del rail baja a 2px; los objetivos táctiles no
   se tocan. Va al final para ganar a las reglas base de arriba. */
@media (max-width: 479.98px) {
  html[data-app-theme="tecsa-clinico"] .app-navbar__actions {
    gap: 0.125rem;
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .ui-theme-control {
    padding-left: 0;
    border-left: 0;
  }

  html[data-app-theme="tecsa-clinico"] .app-navbar .tenant-pill {
    margin-right: 0;
  }
}

/* ==========================================================================
   SIDEBAR — REDISEÑO DE LAS SECCIONES
   ==========================================================================
   MEDIDO en /profile/ a 1865px antes de tocarlo:

       tarjeta de sección ...... 94px de alto (115 si el rótulo parte) para
                                 un icono y una palabra; con su <hr> cada
                                 sección ocupaba 112px
       menú .................... 1111px en un hueco de 780: seis opciones y
                                 ya hacía falta scroll
       panel ................... `bottom: 20px` sin contar el pie fijo (z
                                 1050, ~220px): los últimos ~200px del menú
                                 quedaban siempre debajo del pie
       hover de enlace ......... blanco sobre celeste al 80%, ~1.5:1
       subgrupos ............... texto centrado y partido en dos líneas;
                                 enlaces a 16px y a 14px mezclados
       nombre accesible ........ aria-label en inglés («Management») sobre
                                 un rótulo visible en español (WCAG 2.5.3)

   Las secciones pasan a FILAS de navegación de 44px: icono en baldosa
   tintada, rótulo legible y chevron atenuado. Sin sombra, sin filetes. La
   barra lateral de marca sólo aparece en la sección abierta, que es la
   que la necesita. Los subniveles cuelgan de una línea guía alineada con
   el centro del icono de su sección.

   Selectores con `#sidebar #sidebar-container`: dos IDs ganan a las reglas
   de sidebar.css (un ID) y no repiten los selectores del tema de más
   arriba. Lo que sidebar.css declara con !important se cambia por sus
   variables (ver el bloque de --sidebar-nav-* en este fichero). */

/* --- Panel ---------------------------------------------------------------- */
html[data-app-theme="tecsa-clinico"] #sidebar {
  padding: 0.75rem 0;
  border: 1px solid var(--ui-border-soft);
  box-shadow: var(--ui-elev-1);
  scrollbar-width: thin;
  scrollbar-color: color-mix(in oklab, var(--ui-primary) 30%, transparent) transparent;
}

@media (min-width: 1100px) {
  /* Termina encima del pie. Misma variable con la que footer.css reserva el
     padding del body; el pie plegado ocupa ~40px. */
  html[data-app-theme="tecsa-clinico"] #sidebar {
    height: auto;
    max-height: none;
    bottom: calc(var(--footer-height-expanded) + var(--footer-ticker-height, 2.5rem) + 0.75rem);
  }

  html[data-app-theme="tecsa-clinico"] body.footer-collapsed #sidebar {
    bottom: 3.5rem;
  }
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container {
  padding: 0 0.75rem;
}

/* --- Marca: de 159px a ~100 ----------------------------------------------- */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-brand {
  padding: 0.25rem 0 0.5rem;
  gap: 0.5rem;
}

/* Su filete interior repetía la separación que ya da el margen del bloque:
   ~34px de hueco muerto bajo el nombre del plan. */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-brand .sidebar-divider {
  display: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-brand-icon {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 14px;
  box-shadow: var(--ui-elev-2);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-brand-icon img {
  max-width: 100%;
  max-height: 100%;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-brand-text span {
  font-size: 0.75rem;
  letter-spacing: 0.06em;
}

/* --- Administración global: una fila compacta, no un bloque de 97px ------- */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-admin-launcher {
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  border-radius: 12px;
  border: 1px solid color-mix(in oklab, var(--tca-privilege) 40%, transparent);
  border-left-width: 1px;
  background: color-mix(in oklab, var(--tca-privilege) 10%, var(--ui-surface));
  text-decoration: none;
  box-shadow: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-admin-launcher:is(:hover, :focus-visible) {
  background: color-mix(in oklab, var(--tca-privilege) 18%, var(--ui-surface));
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-admin-launcher :is(.sidebar-admin-launcher__title, .sidebar-admin-launcher__hint) {
  text-decoration: none;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-admin-launcher__title {
  color: var(--ui-text-strong);
  font-size: var(--fs-sm);
  font-weight: 600;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-admin-launcher__hint {
  color: var(--ui-text-muted);
  font-size: var(--fs-xs);
}

/* --- Secciones: filas de 44px --------------------------------------------- */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card {
  position: relative;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 10px;
  /* sidebar.css pinta #sidebar .card con !important; su superficie se
     cambia por la variable que expone, estado a estado. */
  --sidebar-section-bg: transparent;
  box-shadow: none;
  transform: none;
  transition:
    background-color var(--tca-dur-fast) var(--tca-ease),
    border-color var(--tca-dur-fast) var(--tca-ease);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card:hover {
  --sidebar-section-bg: color-mix(in oklab, var(--ui-primary) 7%, transparent);
  transform: none;
  box-shadow: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card[aria-expanded="true"] {
  --sidebar-section-bg: var(--ui-tint-primary);
  border-color: color-mix(in oklab, var(--ui-primary) 16%, transparent);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card:focus-visible {
  outline: var(--tca-focus-width) solid var(--tca-linea-campo);
  outline-offset: 2px;
}

/* La barra de marca, sólo en la sección abierta. */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card::before {
  display: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card[aria-expanded="true"]::before {
  display: block;
  top: 22%;
  height: 56%;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--ui-primary);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card__body {
  --bs-card-spacer-y: 0.375rem;
  --bs-card-spacer-x: 0.5rem;
  min-height: var(--touch-target);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-icon {
  box-sizing: border-box;
  flex: 0 0 2rem;
  width: 2rem;
  height: 2rem;
  padding: 0.5rem;
  border-radius: 8px;
  background: var(--ui-tint-primary);
  color: var(--ui-secondary);
  font-size: 1rem;
  vertical-align: middle;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-card[aria-expanded="true"] .sidebar-section-icon {
  background: var(--ui-surface);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-title {
  margin: 0;
  color: var(--ui-text-strong);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.3;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-section-arrow {
  font-size: 0.6875rem;
  color: var(--ui-text-muted);
}

/* Los filetes entre secciones sobran con filas: el ritmo lo da el hueco. */
html[data-app-theme="tecsa-clinico"] #sidebar .sidebar-main-content .sidebar-divider,
html[data-app-theme="tecsa-clinico"] #sidebar .sidebar-main-content li.my-3:empty {
  display: none;
}

/* --- Subniveles: línea guía alineada con el centro del icono -------------- */
html[data-app-theme="tecsa-clinico"] #sidebar .sidebar-main-content > ul > li > ul {
  margin: 0.25rem 0 0.375rem 1.5rem;
  padding-left: 0.5rem;
  border-left: 1px solid var(--ui-border);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle-nav {
  margin: 0 0 0.25rem 0.875rem;
  padding: 0.125rem 0 0.125rem 0.5rem;
  border-left: 1px solid var(--ui-border-soft);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle-nav li {
  margin-bottom: 1px;
}

/* Subgrupo («Historia Clínica Digital»): fila alineada a la izquierda. */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle {
  display: flex;
  width: 100%;
  min-height: 2.5rem;
  justify-content: flex-start;
  gap: 0.625rem;
  padding: 0.375rem 0.5rem;
  border-radius: 8px;
  background: transparent;
  box-shadow: none;
  transform: none;
  text-align: left;
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1.3;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle:is(:hover, :focus-visible) {
  background: color-mix(in oklab, var(--ui-primary) 7%, transparent);
  box-shadow: none;
  transform: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle[aria-expanded="true"] {
  background: transparent;
  box-shadow: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle::after {
  font-size: 0.625rem;
  color: var(--ui-text-muted);
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle :is(i, svg) {
  box-sizing: border-box;
  flex: 0 0 1.75rem;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0.4rem;
  border-radius: 7px;
  background: color-mix(in oklab, var(--ui-primary) 9%, transparent);
  color: var(--ui-secondary);
  font-size: 0.875rem;
  transform: none;
}

/* Enlaces: una sola tipografía, 40px, icono sin caja pesada. */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .nav-link {
  min-height: 2.5rem;
  gap: 0.625rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.3;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .nav-link.active {
  font-weight: 600;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .nav-link > :is(i, svg) {
  flex: 0 0 1rem;
  width: 1rem;
  color: var(--ui-secondary);
  font-size: 0.875rem;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-mini-card {
  flex: 0 0 1.75rem;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border: 0;
  border-radius: 7px;
  background: color-mix(in oklab, var(--ui-primary) 9%, transparent);
  color: var(--ui-secondary);
  transform: none;
}

html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .sidebar-mini-card :is(i, svg) {
  color: var(--ui-secondary);
  font-size: 0.8125rem;
}

/* El guion animado de sidebar.css choca con el indicador del activo. */
html[data-app-theme="tecsa-clinico"] #sidebar #sidebar-container .btn-toggle-nav a:not(.active)::before {
  display: none;
}

/* --- Paginación activa ------------------------------------------------------
   La regla de .page-item.active de arriba está en capa y pierde contra
   `.active > .page-link` de Bootstrap (sin capa), que pinta texto blanco por
   variable: blanco sobre #378ADD = 3.59:1 (medido en /hce/lista/). Se fijan
   las variables de Bootstrap, sin capa, para que su propia regla pinte el par
   del tema: tinta sobre --ui-primary = 4.84:1. */
html[data-app-theme="tecsa-clinico"] .pagination {
  --bs-pagination-active-bg: var(--ui-fill-primary-solid);
  --bs-pagination-active-border-color: var(--ui-fill-primary-solid);
  --bs-pagination-active-color: var(--ui-text-on-fill-primary);
}

html[data-app-theme="tecsa-clinico"] .page-item.active .page-link {
  background-image: var(--ui-fill-primary);
}

/* --- Botón primario: degradado de marca con texto blanco ------------------
   #378ADD plano no admitía un texto limpio (blanco 3.59:1; la tinta 4.84
   cumplía pero se veía turbia). azul-600 → azul-900 con blanco: 5.11 → 6.52.
   El hover oscurece el degradado (azul-900 → azul-700, 6.52 → 7.43) en vez
   de aclararlo. Las variables de Bootstrap pintan el color de base (también
   el de :disabled) y el degradado va encima como imagen. */
html[data-app-theme="tecsa-clinico"] .btn-primary {
  background-image: var(--ui-fill-primary);
  --bs-btn-bg: var(--ui-fill-primary-solid);
  --bs-btn-border-color: var(--ui-fill-primary-solid);
  --bs-btn-color: var(--ui-text-on-fill-primary);
  --bs-btn-hover-bg: var(--ui-fill-primary-solid);
  --bs-btn-hover-border-color: var(--ui-fill-primary-solid);
  --bs-btn-hover-color: var(--ui-text-on-fill-primary);
  --bs-btn-active-bg: var(--ui-fill-primary-solid);
  --bs-btn-active-border-color: var(--ui-fill-primary-solid);
  --bs-btn-active-color: var(--ui-text-on-fill-primary);
  --bs-btn-disabled-bg: var(--ui-fill-primary-solid);
  --bs-btn-disabled-border-color: var(--ui-fill-primary-solid);
  --bs-btn-disabled-color: var(--ui-text-on-fill-primary);
}

html[data-app-theme="tecsa-clinico"] .btn-primary:is(:hover, :focus-visible, :active) {
  background-image: var(--ui-fill-primary-hover);
}

/* --- Restos legacy y Bootstrap fijo, en un solo sitio ------------------------
   Medidos en el barrido de contraste de dashboard/templates (oct-2026); cada
   lote los estaba parcheando en su página. Sin capa, como el resto de esta
   cola: Bootstrap y custom.css se colaban por propiedades que el tema, en
   capa, no puede ganar.

   - custom.css pinta .card .card-header y .table thead th con un degradado
     #134D6D (background-image). El tema sólo fijaba background-color, así que
     la imagen sobrevivía: texto #212529 sobre #134D6D = 1.7:1. */
html[data-app-theme="tecsa-clinico"] .card-header,
html[data-app-theme="tecsa-clinico"] thead th {
  background-image: none;
}

/* custom.css: .table con fondo blanco al 95 % y pre.language-json #F5F5F5,
   fijos — bloques blancos en modo oscuro. */
html[data-app-theme="tecsa-clinico"] .table {
  background-color: transparent;
}

html[data-app-theme="tecsa-clinico"] pre.language-json {
  background-color: var(--ui-surface-3);
  color: var(--ui-text-strong);
}

/* Botones con degradado legacy (custom.css): blanco sobre #FF6B6B = 2.78:1
   (.btn-danger); .btn-secondary con degradado marino. Se usan las variables
   de Bootstrap, que es quien pinta el color de fondo. */
html[data-app-theme="tecsa-clinico"] .btn-danger {
  background-image: none;
  --bs-btn-bg: var(--ui-danger-fill);
  --bs-btn-border-color: var(--ui-danger-fill);
  --bs-btn-color: var(--ui-text-on-danger);
  --bs-btn-hover-bg: var(--ui-danger-fill);
  --bs-btn-hover-border-color: var(--ui-danger-fill);
  --bs-btn-hover-color: var(--ui-text-on-danger);
  --bs-btn-active-bg: var(--ui-danger-fill);
  --bs-btn-active-color: var(--ui-text-on-danger);
  --bs-btn-disabled-bg: var(--ui-danger-fill);
  --bs-btn-disabled-color: var(--ui-text-on-danger);
}

html[data-app-theme="tecsa-clinico"] .btn-secondary {
  background-image: none;
  --bs-btn-bg: var(--ui-surface);
  --bs-btn-border-color: var(--ui-border-strong);
  --bs-btn-color: var(--ui-primary-strong);
  --bs-btn-hover-bg: var(--ui-tint-primary);
  --bs-btn-hover-border-color: var(--ui-primary);
  --bs-btn-hover-color: var(--ui-primary-strong);
  --bs-btn-active-bg: var(--ui-tint-primary-2);
  --bs-btn-active-color: var(--ui-primary-strong);
}

/* Contornos: Bootstrap deja #0D6EFD / #6C757D / #DC3545 / #0DCAF0, que en
   oscuro dan 3.1–3.8:1 y en claro btn-outline-info 1.96:1. */
html[data-app-theme="tecsa-clinico"] :is(.btn-outline-primary, .btn-outline-info) {
  --bs-btn-color: var(--ui-primary-strong);
  --bs-btn-border-color: var(--ui-border-strong);
  --bs-btn-hover-bg: var(--ui-tint-primary);
  --bs-btn-hover-border-color: var(--ui-primary);
  --bs-btn-hover-color: var(--ui-primary-strong);
  --bs-btn-active-bg: var(--ui-fill-primary-solid);
  --bs-btn-active-border-color: var(--ui-fill-primary-solid);
  --bs-btn-active-color: var(--ui-text-on-fill-primary);
  --bs-btn-disabled-color: var(--ui-text-muted);
  --bs-btn-disabled-border-color: var(--ui-border);
}

html[data-app-theme="tecsa-clinico"] .btn-outline-secondary {
  --bs-btn-color: var(--ui-text-strong);
  --bs-btn-border-color: var(--ui-border-strong);
  --bs-btn-hover-bg: var(--ui-surface-3);
  --bs-btn-hover-border-color: var(--ui-border-strong);
  --bs-btn-hover-color: var(--ui-text-strong);
  --bs-btn-active-bg: var(--ui-surface-3);
  --bs-btn-active-color: var(--ui-text-strong);
  --bs-btn-disabled-color: var(--ui-text-muted);
}

html[data-app-theme="tecsa-clinico"] .btn-outline-danger {
  --bs-btn-color: var(--ui-danger-text);
  --bs-btn-border-color: var(--ui-danger);
  --bs-btn-hover-bg: var(--ui-tint-danger);
  --bs-btn-hover-border-color: var(--ui-danger);
  --bs-btn-hover-color: var(--ui-danger-text);
  --bs-btn-active-bg: var(--ui-danger-fill);
  --bs-btn-active-border-color: var(--ui-danger-fill);
  --bs-btn-active-color: var(--ui-text-on-danger);
}

html[data-app-theme="tecsa-clinico"] .btn-outline-success {
  --bs-btn-color: var(--ui-success-text);
  --bs-btn-border-color: var(--ui-success);
  --bs-btn-hover-bg: var(--ui-tint-success, var(--ui-tint-primary));
  --bs-btn-hover-border-color: var(--ui-success);
  --bs-btn-hover-color: var(--ui-success-text);
  --bs-btn-active-bg: var(--ui-success);
  --bs-btn-active-border-color: var(--ui-success);
  --bs-btn-active-color: var(--ui-text-on-fill);
}

/* messages.error de Django etiqueta "error" (no hay MESSAGE_TAGS), y Bootstrap
   no tiene .alert-error: se le dan las variables de .alert-danger, que siguen
   el modo. Los degradados legacy de base-shell.css ya no aplican al clínico. */
html[data-app-theme="tecsa-clinico"] .alert-error {
  --bs-alert-color: var(--bs-danger-text-emphasis);
  --bs-alert-bg: var(--bs-danger-bg-subtle);
  --bs-alert-border-color: var(--bs-danger-border-subtle);
  --bs-alert-link-color: var(--bs-danger-text-emphasis);
}
