/* ==============================================================================
   theme-tokens.css — Capa semántica dual (claro por defecto / oscuro opt-in)
   ------------------------------------------------------------------------------
   PROBLEMA QUE RESUELVE
   Hasta ahora el único remapeo a paleta clara vivía en dashboard-v2.css:1423,
   scopeado a `.dashboard-shell` / `.modal-content`. `.dashboard-shell` existe en
   2 de 545 templates, así que el modo claro sólo funcionaba de verdad en
   /dashboard/profile/. Este archivo eleva ese mecanismo a `:root` mediante un
   set semántico nuevo (--ui-*, --n-*, --risk-*) correcto en AMBOS temas.

   CONTRATO DE USO
   - Todo CSS nuevo usa SOLO: --ui-*, --n-*, --risk-*, --space-*, --radius-*,
     --fs-*, --lh-*, --duration-*, --ease-*, --z-*, --touch-target.
   - Nunca --tricorder-* ni --tecsa-* ni hex literal en reglas nuevas.
   - Capa: `tokens` (declarada en custom.css:22).

   ACTIVACIÓN DE TEMA
   - Claro  = ausencia de data-app-theme en <html>  (default)
   - Oscuro = html[data-app-theme="tricorder"]      (opt-in declarativo)
   Ver design-system/MASTER.md §1 y §2b.

   CONTRASTE
   Todos los pares fondo/texto de este archivo se verificaron ≥ 4.5:1 (WCAG 2.2
   AA texto normal). Los valores del semáforo NO son los de hce-wizard.css tal
   cual: allí sirven de borde/punto, y en badge con texto blanco #16A34A daba
   3.30:1 y #CA8A04 daba 2.94:1. Aquí se corrigieron.
   ============================================================================== */

@layer tokens {

  /* ==========================================================================
     1. TEMA CLARO (default — ausencia de data-app-theme)
     ========================================================================== */
  :root {
    /* `dark light` hacía que los controles nativos (select, date, scrollbar)
       se pintaran oscuros en páginas claras cuando el SO prefiere oscuro.
       El tema de la app es declarativo, no depende del SO. */
    color-scheme: light;

    /* ---------- Rampa neutra ---------- */
    --n-0:   #FFFFFF;
    --n-25:  #FAFBFC;
    --n-50:  #F8FAFC;
    --n-100: #F1F5F9;
    --n-200: #E2E8F0;
    --n-300: #CBD5E1;
    --n-400: #94A3B8;
    --n-500: #64748B;
    --n-600: #475569;
    --n-700: #334155;
    --n-800: #1E293B;
    --n-900: #0F172A;

    /* ---------- Superficies ---------- */
    --ui-bg:        #EEF4FA;
    --ui-surface:   #FFFFFF;
    --ui-surface-2: #F3F8FC;
    --ui-surface-3: #E9F1F8;

    /* ---------- Texto (todos ≥4.5:1 sobre --ui-surface) ---------- */
    --ui-text:            #16303F;  /* 13.74:1 */
    --ui-text-muted:      #5B6B78;  /*  5.50:1 */
    --ui-text-on-primary: #FFFFFF;  /*  8.78:1 sobre --ui-primary */
    /* Texto sobre CUALQUIER relleno semántico (primary/secondary/accent/
       success/warn/danger/info). En claro los siete rellenos son oscuros y el
       blanco da >=5.02:1 en todos. Es un token aparte de --ui-surface: usar el
       token de superficie como color de texto fue precisamente el bug que dejó
       los botones en cian sobre cian al pasar a oscuro. */
    --ui-text-on-fill: #FFFFFF;

    /* ---------- Marca y semánticos (≥4.5:1 sobre --ui-surface) ---------- */
    --ui-primary:        #0F4E7A;   /* 8.78:1 */
    --ui-primary-strong: #0B3A5C;
    --ui-secondary:      #1F6E9D;
    --ui-accent:         #117A63;   /* 5.27:1 */
    --ui-success:        #1A7F4B;   /* 5.02:1 */
    --ui-warn:           #8A5A00;   /* 5.93:1 */
    --ui-danger:         #B02A1E;   /* 6.57:1 */
    --ui-info:           #1565C0;   /* 5.75:1 */

    /* ---------- Bordes ---------- */
    --ui-border:      rgba(15, 78, 122, 0.22);
    --ui-border-soft: rgba(15, 78, 122, 0.12);

    /* ---------- Elevación / efectos ---------- */
    --ui-elev-1: 0 1px 3px rgba(19, 77, 109, 0.10);
    --ui-elev-2: 0 2px 10px rgba(19, 77, 109, 0.08);
    --ui-elev-3: 0 12px 32px rgba(19, 77, 109, 0.14);
    --ui-focus-ring: 0 0 0 3px rgba(15, 78, 122, 0.45);
    /* En claro no hay glassmorphism ni glow: los componentes escriben
       `backdrop-filter: var(--ui-glass)` y aquí vale `none`. Así el
       desglaseado no necesita !important. */
    --ui-glass: none;
    --ui-glow:  none;

    /* ---------- Tints derivados (evitan inventar hex nuevos) ---------- */
    --ui-tint-primary:   color-mix(in oklab, var(--ui-primary) 8%,  var(--ui-surface));
    --ui-tint-primary-2: color-mix(in oklab, var(--ui-primary) 16%, var(--ui-surface));
    --ui-tint-success:   color-mix(in oklab, var(--ui-success) 12%, var(--ui-surface));
    --ui-tint-warn:      color-mix(in oklab, var(--ui-warn) 12%,    var(--ui-surface));
    --ui-tint-danger:    color-mix(in oklab, var(--ui-danger) 12%,  var(--ui-surface));
    --ui-tint-info:      color-mix(in oklab, var(--ui-info) 12%,    var(--ui-surface));

    /* ---------- Semáforo de riesgo HL7 ----------
       Códigos: terminology.hl7.org/CodeSystem-risk-probability
       Espejo CSS de dashboard/constants/colores_riesgo.py.
       -bg/-fg = par de badge (≥4.5:1). -bd = trazo/punto (≥3:1 sobre surface). */
    --risk-blanco-bg: #FFFFFF; --risk-blanco-fg: #334155; --risk-blanco-bd: #94A3B8;
    --risk-verde-bg:  #15803D; --risk-verde-fg:  #FFFFFF; --risk-verde-bd:  #15803D;
    --risk-amarillo-bg: #FFC107; --risk-amarillo-fg: #3F2D00; --risk-amarillo-bd: #A16207;
    --risk-naranja-bg: #C2410C; --risk-naranja-fg: #FFFFFF; --risk-naranja-bd: #C2410C;
    --risk-rojo-bg:   #DC2626; --risk-rojo-fg:   #FFFFFF; --risk-rojo-bd:   #DC2626;
    --risk-negro-bg:  #1E293B; --risk-negro-fg:  #FFFFFF; --risk-negro-bd:  #1E293B;
    --risk-azul-bg:   #1D4ED8; --risk-azul-fg:   #FFFFFF; --risk-azul-bd:   #1D4ED8;
    --risk-sin-bg:    #E2E8F0; --risk-sin-fg:    #334155; --risk-sin-bd:    #94A3B8;

    /* ---------- Pares SUAVES (fondo de tinte + texto) ----------
       Un badge sobre tinte claro NO puede usar el color "sobre relleno sólido":
       texto blanco sobre un verde al 18% sobre blanco da ~1:1. Estos pares
       están medidos aparte (todos >= 7:1 en claro, >= 8:1 en oscuro). */
    --risk-verde-soft-bg:    #DCFCE7; --risk-verde-soft-fg:    #0F5132;
    --risk-amarillo-soft-bg: #FFF3CD; --risk-amarillo-soft-fg: #664D03;
    --risk-naranja-soft-bg:  #FFE5D0; --risk-naranja-soft-fg:  #7A3300;
    --risk-rojo-soft-bg:     #F8D7DA; --risk-rojo-soft-fg:     #842029;
    --risk-azul-soft-bg:     #CFE2FF; --risk-azul-soft-fg:     #084298;
    --risk-sin-soft-bg:      #E9ECEF; --risk-sin-soft-fg:      #343A40;
    --risk-blanco-soft-bg:   #FFFFFF; --risk-blanco-soft-fg:   #334155;
    --risk-negro-soft-bg:    #E2E8F0; --risk-negro-soft-fg:    #1E293B;
    /* Alias semánticos sobre los mismos pares */
    --ui-success-soft-bg: var(--risk-verde-soft-bg);    --ui-success-soft-fg: var(--risk-verde-soft-fg);
    --ui-warn-soft-bg:    var(--risk-amarillo-soft-bg); --ui-warn-soft-fg:    var(--risk-amarillo-soft-fg);
    --ui-danger-soft-bg:  var(--risk-rojo-soft-bg);     --ui-danger-soft-fg:  var(--risk-rojo-soft-fg);
    --ui-info-soft-bg:    var(--risk-azul-soft-bg);     --ui-info-soft-fg:    var(--risk-azul-soft-fg);
    --ui-neutral-soft-bg: var(--risk-sin-soft-bg);      --ui-neutral-soft-fg: var(--risk-sin-soft-fg);
  }

  /* ==========================================================================
     2. TEMA OSCURO (opt-in — html[data-app-theme="tricorder"])
     ========================================================================== */
  html[data-app-theme="tricorder"] {
    color-scheme: dark;

    /* Rampa neutra invertida */
    --n-0:   #050E1A;
    --n-25:  #08131F;
    --n-50:  #0A1628;
    --n-100: #12233A;
    --n-200: #1B3350;
    --n-300: #2A4766;
    --n-400: #4E6E8C;
    --n-500: #7FA3BC;
    --n-600: #A0C8D8;
    --n-700: #C3E3EF;
    --n-800: #DCF2F8;
    --n-900: #E0F7FA;

    --ui-bg:        var(--tricorder-bg);
    --ui-surface:   var(--tricorder-surface-1);
    --ui-surface-2: var(--tricorder-surface-2);
    --ui-surface-3: var(--tricorder-surface-3);

    --ui-text:            var(--tricorder-text);
    --ui-text-muted:      var(--tricorder-muted);
    --ui-text-on-primary: var(--tricorder-dark);
    /* En oscuro los siete rellenos son brillantes; el navy da >=5.68:1
       (primary 11.79, warn 12.99, danger 5.68). El blanco daría 1.40-3.19. */
    --ui-text-on-fill: var(--tricorder-dark);

    --ui-primary:        var(--tricorder-primary);
    --ui-primary-strong: var(--tricorder-secondary);
    --ui-secondary:      var(--tricorder-secondary);
    --ui-accent:         var(--tricorder-accent);
    --ui-success:        var(--tricorder-success);
    --ui-warn:           var(--tricorder-warn);
    --ui-danger:         var(--tricorder-danger);
    --ui-info:           var(--tricorder-info);

    --ui-border:      var(--tricorder-border);
    --ui-border-soft: var(--tricorder-border-soft);

    --ui-elev-1: 0 1px 2px rgba(0, 0, 0, 0.40);
    --ui-elev-2: 0 4px 18px rgba(0, 0, 0, 0.45);
    --ui-elev-3: 0 12px 36px rgba(0, 229, 255, 0.22);
    --ui-focus-ring: 0 0 0 3px rgba(0, 229, 255, 0.50);
    --ui-glass: blur(12px);
    --ui-glow:  var(--glow-primary);

    /* Semáforo recalibrado: rellenos claros + texto oscuro, para mantener
       ≥4.5:1 sobre el fondo deep-space. */
    --risk-blanco-bg: #E2E8F0; --risk-blanco-fg: #0F172A; --risk-blanco-bd: #94A3B8;
    --risk-verde-bg:  #4ADE80; --risk-verde-fg:  #052E16; --risk-verde-bd:  #4ADE80;
    --risk-amarillo-bg: #FDE047; --risk-amarillo-fg: #3F2D00; --risk-amarillo-bd: #FDE047;
    --risk-naranja-bg: #FB923C; --risk-naranja-fg: #431407; --risk-naranja-bd: #FB923C;
    --risk-rojo-bg:   #F87171; --risk-rojo-fg:   #450A0A; --risk-rojo-bd:   #F87171;
    --risk-negro-bg:  #94A3B8; --risk-negro-fg:  #0F172A; --risk-negro-bd:  #94A3B8;
    --risk-azul-bg:   #93C5FD; --risk-azul-fg:   #0B2447; --risk-azul-bd:   #93C5FD;
    --risk-sin-bg:    #334155; --risk-sin-fg:    #E2E8F0; --risk-sin-bd:    #4E6E8C;

    /* Pares suaves recalibrados sobre fondo deep-space */
    --risk-verde-soft-bg:    #10352A; --risk-verde-soft-fg:    #6EE7B7;
    --risk-amarillo-soft-bg: #3A2F05; --risk-amarillo-soft-fg: #FDE047;
    --risk-naranja-soft-bg:  #3A1D0B; --risk-naranja-soft-fg:  #FDBA74;
    --risk-rojo-soft-bg:     #3F1518; --risk-rojo-soft-fg:     #FCA5A5;
    --risk-azul-soft-bg:     #0E2A47; --risk-azul-soft-fg:     #93C5FD;
    --risk-sin-soft-bg:      #22303F; --risk-sin-soft-fg:      #CBD5E1;
    --risk-blanco-soft-bg:   #22303F; --risk-blanco-soft-fg:   #E2E8F0;
    --risk-negro-soft-bg:    #1B2634; --risk-negro-soft-fg:    #CBD5E1;
  }

  /* ==========================================================================
     3. PUENTE LEGACY — .theme-surface
     --------------------------------------------------------------------------
     Los componentes existentes están escritos contra --tricorder-*. Renombrarlos
     sería una migración de miles de sitios. En su lugar, una página adopta
     light/dark añadiendo la clase `theme-surface` a su contenedor raíz, y los
     tokens --tricorder-* se remapean a la paleta clara sólo dentro de ella.

     Valores idénticos a dashboard-v2.css:1423-1442 (que se mantiene intacto
     durante la transición: vive en @layer modern-ux, gana a esta regla, y al
     ser el mismo valor actúa como no-op — cero regresión en /dashboard/profile/).

     No se hace a nivel :root a propósito: hay CSS (landing-tricorder.css, 71
     usos sin scope de tema) que asume fondo oscuro y quedaría con texto oscuro
     sobre oscuro. Ver design-system/MASTER.md §2b.
     ========================================================================== */
  html:not([data-app-theme="tricorder"])
    :is(.theme-surface, .dashboard-shell, .modal-content) {
      --tricorder-card-bg:    var(--ui-surface);
      --tricorder-surface-0:  var(--ui-bg);
      --tricorder-surface-1:  var(--ui-surface);
      --tricorder-surface-2:  var(--ui-surface-2);
      --tricorder-surface-3:  var(--ui-surface-3);
      --tricorder-dark:       var(--ui-text-on-primary);
      --tricorder-text:       var(--ui-text);
      --tricorder-muted:      var(--ui-text-muted);
      --tricorder-primary:    var(--ui-primary);
      --tricorder-secondary:  var(--ui-secondary);
      --tricorder-accent:     var(--ui-accent);
      --tricorder-success:    var(--ui-success);
      --tricorder-warn:       var(--ui-warn);
      --tricorder-danger:     var(--ui-danger);
      --tricorder-info:       var(--ui-info);
      --tricorder-border:     var(--ui-border);
      --tricorder-border-soft: var(--ui-border-soft);
  }

  /* ==========================================================================
     3b. CHROME DE LAYOUT — altura del header fijo (fuente única)
     ==========================================================================
     El navbar (.fixed-top en navbar.css) mide 90px en desktop y 70px en
     <=991.98px. Todo offset que dependa de él (body padding-top, min-height
     de #wrapper, sticky top del toolbar/dashboard-toolbar, capas fijas como
     el sidebar o contenedores del wizard HCE) debe derivar de este token.
     El valor 90/70 es medido sobre navbar.css; si cambia la altura allí,
     cambiar SOLO aquí. */
  :root {
    --app-header-height: 90px;
  }

  @media (max-width: 991.98px) {
    :root {
      --app-header-height: 70px;
    }
  }
}

/* ==============================================================================
   4. BASE — preferencias globales de movimiento y layout
   ============================================================================== */
@layer base {
  /* Evita el salto horizontal al abrir/cerrar modales que bloquean el scroll. */
  html { scrollbar-gutter: stable; }

  /* prefers-reduced-motion: anulación real, no aspiracional.
     La primera versión usaba `:where(*)` (especificidad 0) sin !important,
     buscando ser "educada". No funcionaba: cualquier regla de componente
     —p.ej. `.stat-card { transition: all var(--duration-base) }`— la vencía
     por especificidad, y encima el CSS de página va sin capa y las capadas
     siempre pierden contra él. El test
     paciente/tests/test_a11y_paciente_list.py::test_reduced_motion_desactiva_animaciones
     lo detectó.

     !important es aquí la práctica establecida (es el patrón del reset de
     Andy Bell y del de Josh Comeau): una preferencia de accesibilidad
     declarada por la persona usuaria debe ganar a cualquier decoración. */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}
