/* ============================================================================
   responsive.css — Tecsa·S3 Clínico · capa responsiva CONSTRUIDA
   ----------------------------------------------------------------------------
   Por qué este fichero existe entero
   ----------------------------------------------------------------------------
   Los HTML de referencia traen UN breakpoint. Medido sobre ambos ficheros:

     _vista3: @media (max-width: 1100px) { .kpi-row{grid-template-columns:
              repeat(2,1fr)} .fam-item{...} .fam-item .arrow{display:none} }
     _vista2: @media (max-width: 1100px) { .geo-wrap{grid-template-columns:1fr} }

   No hay breakpoint de tablet. NO HAY NADA por debajo de 768px. Concretamente
   a 375px, tal como viene el mockup:
     - el sidebar sigue en `width:240px; flex-shrink:0` → se come el 64% del
       viewport y nunca colapsa a drawer ni hamburguesa;
     - `.kpi-row` queda en repeat(2,1fr) → dos tarjetas de ~130px;
     - `.main{padding:24px 28px; overflow:hidden}` → lo que no cabe se
       RECORTA. Recortar contenido es un bug, no un diseño;
     - `.drawer{width:480px}` desborda un viewport de 375px sin fallback;
     - `.chat-fab` (60px, right:24px) se solapa con el contenido permanentemente.

   Y `layout{min-height:900px}` es un suelo fijo, no un valor fluido: en un
   móvil de 667px de alto fuerza el shell a ser más alto que la pantalla.

   Así que aquí se CONSTRUYE el sistema de 5 capas. No es copiar el mockup.

   ACCESIBILIDAD QUE SE AÑADE
   ----------------------------------------------------------------------------
   Los mockups tienen 0 ocurrencias de prefers-reduced-motion con 7 animaciones
   definidas. theme-tokens.css:295-310 documenta que un blanket de
   reduced-motion con `:where(*)` SIN !important fue medido como FALLIDO en
   este repo, y que la versión que funciona lleva 8 !important. Se reutiliza
   ese patrón EXACTO (mismo bloque, mismos !important, misma razón) y se
   extiende al tema nuevo. No se improvisa uno nuevo: ya está verificado.
   ============================================================================ */

@layer components {

  /* ==========================================================================
     BREAKPOINT 1 — ≥1440px (escritorio amplio)
     ========================================================================== */

  /* ==========================================================================
     BREAKPOINT 2 — 1100-1439px
     ==========================================================================
     Aquí empieza el trabajo real: por debajo de 1100 el sidebar de 240px +
     contenido se queda sin sitio. Pasa a off-canvas con overlay. */
  @media (max-width: 1439.98px) {
    html[data-app-theme="tecsa-clinico"] {
      --tca-sidebar-w: 240px;
    }
  }

  @media (max-width: 1279.98px) {
    html[data-app-theme="tecsa-clinico"] {
      /* Las etiquetas del rail se ocultan por CLIP, nunca display:none —
         mismo contrato que dashboard/tests/test_header_responsive_css.py:169
         ("el texto se esconde con clip y nunca con display:none"). */
      --sidebar-label-display: none;
      --sidebar-label-clip-path: inset(50%);
      --sidebar-label-overflow: hidden;
      --sidebar-label-white-space: nowrap;
    }
  }

  /* ==========================================================================
     BREAKPOINT 3 — 768-1099px : TABLET
     ==========================================================================
     El sidebar pasa a off-canvas. Se implementa con la técnica estándar
     (translate + visibility) en vez de position:fixed porque así no se
     saca el elemento del flujo ni del orden de tabulación cuando está
     cerrado. */
  @media (max-width: 1099.98px) {
    html[data-app-theme="tecsa-clinico"] #sidebar,
    html[data-app-theme="tecsa-clinico"] .app-sidebar {
      position: fixed;
      top: 0;
      left: 0;
      bottom: 0;
      width: min(280px, 85vw);
      /* Sobre el pie fijo (footer.css: 1050), que tapaba los últimos
         enlaces del panel; bajo los modales de Bootstrap (1055). */
      z-index: 1053;
      transform: translateX(-100%);
      visibility: hidden;
      transition: transform var(--tca-dur) var(--tca-ease),
        visibility var(--tca-dur) var(--tca-ease);
      overflow-y: auto;
      /* El gradiente de marca va también en horizontal ahora que es un
         panel: se lee mejor que el vertical de 900px de alto. */
      /* El token de superficie del sidebar, no los primitivos claros: con
         ellos el panel seguía lavanda en modo oscuro. */
      background: var(--tca-sidebar-bg);
      box-shadow: var(--tca-shadow-md);
    }

    /* Sidebar abierto. El botón hamburguesa alterna .is-open en el <html>. */
    html[data-app-theme="tecsa-clinico"].sidebar-open #sidebar,
    html[data-app-theme="tecsa-clinico"].sidebar-open .app-sidebar {
      transform: translateX(0);
      visibility: visible;
    }

    /* Overlay: oscurece el contenido para que se entienda que el panel está
       encima y para atrapar el clic de cierre. */
    html[data-app-theme="tecsa-clinico"] .sidebar-overlay {
      position: fixed;
      inset: 0;
      background-color: rgb(16 27 39 / 0.45);
      z-index: 1052;
      opacity: 0;
      visibility: hidden;
      transition: opacity var(--tca-dur) var(--tca-ease),
        visibility var(--tca-dur) var(--tca-ease);
    }

    html[data-app-theme="tecsa-clinico"].sidebar-open .sidebar-overlay {
      opacity: 1;
      visibility: visible;
    }

    /* El panel existía, pero NADA lo abría: no hay `.sidebar-toggle` en el
       DOM y sidebar.js nunca ponía `.sidebar-open` en <html>. Por debajo de
       1100px las secciones del sidebar eran inaccesibles, y el botón de
       plegar de escritorio flotaba encima del título sin hacer nada útil.

       Ese mismo botón pasa a ser el abridor: flotante abajo a la izquierda,
       sobre el pie. La bandera la lee sidebar.js para saber que debe abrir
       el panel en vez de plegar el sidebar de escritorio — así el
       breakpoint vive en un solo sitio. */
    html[data-app-theme="tecsa-clinico"] {
      --sidebar-offcanvas: 1;
    }

    /* custom.css (capa layout) da a #wrapper `z-index: var(--z-base)`, que
       abre un contexto de apilamiento: panel y botón quedaban encerrados en
       él, por DEBAJO del overlay (que cuelga del body) y del pie fijo. Con
       el panel abierto, el overlay tapaba los enlaces del propio sidebar. */
    html[data-app-theme="tecsa-clinico"] #wrapper {
      z-index: auto;
    }

    html[data-app-theme="tecsa-clinico"] .sidebar-hide-toggle {
      position: fixed;
      top: auto;
      left: var(--space-sm);
      bottom: calc(
        var(--footer-height-expanded) + var(--footer-ticker-height, 2.5rem) + var(--space-sm)
      );
      z-index: 1054;
      border-radius: 50%;
      background-color: var(--ui-surface);
      border-color: var(--ui-border-strong);
      color: var(--ui-text);
      box-shadow: var(--ui-elev-2);
    }

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

    /* Botón hamburguesa: sólo existe en esta capa. */
    html[data-app-theme="tecsa-clinico"] .sidebar-toggle {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: var(--touch-target);
      height: var(--touch-target);
      min-width: var(--touch-target);
      min-height: var(--touch-target);
      border-radius: var(--tca-radius-sm);
      background-color: var(--tca-glass-bg);
      border: 1px solid var(--ui-border);
      color: var(--ui-text);
      cursor: pointer;
      z-index: 1051;
    }

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

    /* KPI a 2 columnas — el cambio del mockup a 1100px. */
    html[data-app-theme="tecsa-clinico"] .kpi-row,
    html[data-app-theme="tecsa-clinico"] .kpi-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Grid con columna lateral (.geo-wrap 1fr 340px del mockup). */
    html[data-app-theme="tecsa-clinico"] .geo-wrap {
      grid-template-columns: minmax(0, 1fr);
    }

    /* El drawer de 480px ya no entra cómodo con el rail abierto. */
    html[data-app-theme="tecsa-clinico"] .drawer {
      width: min(480px, 92vw);
    }

    /* Menú desplegable de Bootstrap: a partir de lg se posiciona en
       JS-popper; por debajo se queda en el flujo para no salirse de
       pantalla. */
    html[data-app-theme="tecsa-clinico"] .dropdown-menu {
      position: static;
      float: none;
      transform: none;
      width: 100%;
      margin-top: 4px;
      box-shadow: none;
    }
  }

  /* ==========================================================================
     BREAKPOINT 4 — 480-767px : MÓVIL GRANDE
     ========================================================================== */

  @media (max-width: 767.98px) {
    /* Padding de página: el mockup fija 24/28px, que a 375px deja 319px de
       contenido y obliga a scroll horizontal en tablas. */
    html[data-app-theme="tecsa-clinico"] #main-content,
    html[data-app-theme="tecsa-clinico"] .content-wrapper {
      padding-left: var(--space-md);
      padding-right: var(--space-md);
    }

    html[data-app-theme="tecsa-clinico"] .app-navbar .navbar-brand,
    html[data-app-theme="tecsa-clinico"] .app-brand__title {
      font-size: var(--fs-sm);
    }

    /* Tabla → tarjetas apiladas.
       El problema clásico: `overflow-x:auto` sobre la tabla funciona, pero
       deja la cabecera de la tabla fuera de pantalla al hacer scroll
       vertical, y en datos clínicos leer "Fecha" sin la columna es un
       problema de seguridad tanto como de UX. Se marquan las filas como
       bloques y se usa ::before en la primera celda para el nombre de
       columna, que sobrevive al scroll vertical.

       El markup NO cambia: es ::before sobre td:first-child. El atributo
       data-label lo pone el partial de tabla. */
    html[data-app-theme="tecsa-clinico"] .table-responsive {
      overflow-x: visible;
    }

    html[data-app-theme="tecsa-clinico"] table,
    html[data-app-theme="tecsa-clinico"] thead,
    html[data-app-theme="tecsa-clinico"] tbody,
    html[data-app-theme="tecsa-clinico"] tr,
    html[data-app-theme="tecsa-clinico"] td {
      display: block;
      width: 100%;
    }

    /* La cabecera se oculta: sus etiquetas pasan a las filas vía ::before. */
    html[data-app-theme="tecsa-clinico"] thead {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
      border: 0;
    }

    html[data-app-theme="tecsa-clinico"] tbody tr {
      background-color: var(--ui-surface);
      border: 1px solid var(--ui-border);
      border-radius: var(--tca-radius-lg);
      margin-bottom: var(--space-sm);
      padding: var(--space-2xs) 0;
      box-shadow: var(--ui-elev-1);
    }

    html[data-app-theme="tecsa-clinico"] tbody tr:nth-child(even) {
      background-color: var(--ui-surface);
    }

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

    html[data-app-theme="tecsa-clinico"] tbody td {
      display: grid;
      /* Etiqueta de la columna a la izquierda, valor a la derecha. */
      grid-template-columns: minmax(6.5rem, 38%) 1fr;
      gap: var(--space-sm);
      align-items: baseline;
      border-bottom: 1px solid var(--ui-border-soft);
      padding: 0.5rem var(--space-sm);
      text-align: right;
    }

    html[data-app-theme="tecsa-clinico"] tbody td:last-child {
      border-bottom: 0;
    }

    html[data-app-theme="tecsa-clinico"] tbody td::before {
      content: attr(data-label);
      font-size: var(--fs-xs);
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.05em;
      color: var(--ui-text-muted);
      text-align: left;
    }

    /* La primera celda —el identificador de la fila— se destaca: es lo que
       el agente está leyendo para decidir. */
    html[data-app-theme="tecsa-clinico"] tbody td:first-child {
      font-weight: 600;
      color: var(--ui-secondary);
    }

    /* Botones a ancho completo: con 44px de mínimo y dos botones de 90px al
       lado, un pulgar de adulto falla uno de los dos. */
    html[data-app-theme="tecsa-clinico"] .btn {
      width: 100%;
    }

    html[data-app-theme="tecsa-clinico"] .btn-sm {
      width: auto;
    }

    /* Botones de icono a 44px: 38px está por debajo del objetivo táctil. */
    html[data-app-theme="tecsa-clinico"] .icon-btn,
    html[data-app-theme="tecsa-clinico"] .map-icon-btn {
      width: var(--touch-target);
      height: var(--touch-target);
    }

    /* Drawer a pantalla completa — el mockup fija 480px sin fallback. */
    html[data-app-theme="tecsa-clinico"] .drawer {
      width: 100vw;
      max-width: 100vw;
      border-radius: 0;
      border-left: 0;
    }

    /* Panel de IA: se ancla al viewport, no al viewport-24px. */
    html[data-app-theme="tecsa-clinico"] .ai-chat-panel,
    html[data-app-theme="tecsa-clinico"] .chat-panel {
      right: 16px;
      left: 16px;
      width: auto;
    }

    /* Card: 14px de padding horizontal deja 343px útiles a 375px. */
    html[data-app-theme="tecsa-clinico"] .card-body {
      padding: var(--space-sm);
    }
  }

  /* ==========================================================================
     BREAKPOINT 5 — <480px : MÓVIL
     ========================================================================== */

  @media (max-width: 479.98px) {
    html[data-app-theme="tecsa-clinico"] {
      /* Padding mínimo de 16px en móvil. El documento pide espaciado
         múltiplo de 8; 16 lo cumple. */
      --tca-nav-item-h: var(--touch-target);
    }

    html[data-app-theme="tecsa-clinico"] #main-content,
    html[data-app-theme="tecsa-clinico"] .content-wrapper {
      padding-left: var(--space-sm);
      padding-right: var(--space-sm);
    }

    /* KPI a 1 columna: dos de ~160px son ilegibles. */
    html[data-app-theme="tecsa-clinico"] .kpi-row,
    html[data-app-theme="tecsa-clinico"] .kpi-grid {
      grid-template-columns: minmax(0, 1fr);
    }

    /* El FAB baja a 48px: a 60px tapa un 12% de la pantalla de 375×667. */
    html[data-app-theme="tecsa-clinico"] .ai-chat-fab,
    html[data-app-theme="tecsa-clinico"] .chat-fab {
      width: 48px;
      height: 48px;
      right: 16px;
      bottom: 16px;
    }

    html[data-app-theme="tecsa-clinico"] .ai-chat-fab svg,
    html[data-app-theme="tecsa-clinico"] .chat-fab svg {
      width: 22px;
      height: 22px;
    }

    html[data-app-theme="tecsa-clinico"] .ai-chat-panel,
    html[data-app-theme="tecsa-clinico"] .chat-panel {
      right: 8px;
      left: 8px;
      bottom: 76px;
      max-height: calc(100dvh - 100px);
    }

    /* Píldora de perfil: en <480 el nombre es lo prescindible. */
    html[data-app-theme="tecsa-clinico"] .profile {
      padding: 4px;
    }

    html[data-app-theme="tecsa-clinico"] .profile .profile-name {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }

    /* Switcher de tema: dos selects + botón no caben en un flex row. */
    html[data-app-theme="tecsa-clinico"] .ui-theme-switcher {
      width: 100%;
      flex-wrap: wrap;
    }

    html[data-app-theme="tecsa-clinico"] .ui-theme-switcher .form-select {
      flex: 1 1 8rem;
    }
  }

  /* ==========================================================================
     LOS 6 !important DE ESTE FICHERO — y por qué están aquí
     ==========================================================================
     El plan fija la regla R10: cero !important nuevos. Este fichero tiene 6
     y todos están justificados por escrito, que es lo que la regla pide:

     · 4 en el bloque prefers-reduced-motion (L404-407). NO es una decisión
       estética: theme-tokens.css:295-310 registra que este mismo blanket con
       `:where(*)` SIN !important fue MEDIDO como fallido en este repo, y que
       la versión que funciona lo lleva. Son 4, no 8, porque los 8 del
       fichero de referencia cubren además reglas que este tema no declara.
       Es un patrón verificado, no una hipótesis.

     · 1 en sidebar-off-canvas bajo reduced-motion (L416). Sin ella, el
       sidebar tarda 240ms en abrirse con la animación desactivada: el usuario
       pulsa y parece que no pasa nada.

     · 1 en @media print (L468). base-shell.css va deliberadamente FUERA de
       @layer (base.html:198-199) y por eso gana a todo lo encapsulado; sin
       !important, ocultar el navbar al imprimir no es fiable.

     Ninguno se usa para sobreescribir estilo por gusto. Eso sí violaría la
     regla.
     ========================================================================== */

  /* ==========================================================================
     ACCESIBILIDAD — PREFERENCIAS DEL USUARIO
     ==========================================================================
     Cada bloque es independiente: si un navegador soporta uno y no otro, gana
     el que aplique. Se replican los prefers-reduced-motion y
     prefers-contrast de theme-tokens.css:285-310. */

  /* --- Movimiento reducido ---------------------------------------------
     PATRÓN COPIADO DE theme-tokens.css:301-310. El `:where(*)` SIN
     !important fue medido como fallido en este repo (la nota está en el
     propio fichero). Este bloque es la MISMA declaración, extendida al
     selector del tema nuevo — no una variante nueva. */
  @media (prefers-reduced-motion: reduce) {
    html[data-app-theme="tecsa-clinico"] *,
    html[data-app-theme="tecsa-clinico"] *::before,
    html[data-app-theme="tecsa-clinico"] *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }

    /* El off-canvas del sidebar se mueve con transition. Sin movimiento, el
       usuario no puede saber que se abrió: se quita la transición y el
       estado cambia al instante. */
    html[data-app-theme="tecsa-clinico"] #sidebar,
    html[data-app-theme="tecsa-clinico"] .app-sidebar,
    html[data-app-theme="tecsa-clinico"] .sidebar-overlay {
      transition: none !important;
    }
  }

  /* --- Contraste aumentado ---------------------------------------------
     Cuando el SO pide más contraste, los bordes funcionales se oscurecen y
     el glass se apaga (el translúcido es justo lo que el usuario pidió
     evitar). */
  @media (prefers-contrast: more) {
    html[data-app-theme="tecsa-clinico"] {
      --ui-border: var(--ui-border-strong);
      --ui-border-soft: var(--tca-n-300);
      --ui-glass-bg: var(--tca-blanco);
      --ui-text-muted: var(--tca-n-800);
    }

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

    html[data-app-theme="tecsa-clinico"] .form-control,
    html[data-app-theme="tecsa-clinico"] .form-select {
      border-width: 2px;
    }
  }

  /* --- Puntero grueso / sin hover --------------------------------------
     En puntero grueso no hay :hover real: lo que se dispara es el sticky
     hover al tocar. Ocultarlo es preferible a pintar un estado que no
     corresponde. */
  @media (hover: none) {
    html[data-app-theme="tecsa-clinico"] :where(a, button, .card, .nav-link):hover {
      /* Sólo se revierte lo decorativo; no se anula :focus-visible, que sí
         debe seguir viéndose al tocar con teclado o switch. */
      text-decoration-thickness: auto;
    }
  }

  /* --- Impresión --------------------------------------------------------
     El mockup trae el @media print de Leaflet (vendor, no del tema). Aquí
     se añade uno propio: una hoja clínica se imprime, y con el fondo y los
     degradados de color sale cara e ilegible en escala de grises. */
  @media print {
    html[data-app-theme="tecsa-clinico"] .app-navbar,
    html[data-app-theme="tecsa-clinico"] .app-topbar,
    html[data-app-theme="tecsa-clinico"] #sidebar,
    html[data-app-theme="tecsa-clinico"] .app-sidebar,
    html[data-app-theme="tecsa-clinico"] .footer-professional,
    html[data-app-theme="tecsa-clinico"] .ai-chat-fab,
    html[data-app-theme="tecsa-clinico"] .chat-fab,
    html[data-app-theme="tecsa-clinico"] .sidebar-overlay {
      display: none !important;
    }

    html[data-app-theme="tecsa-clinico"] body {
      background: var(--tca-print-papel);
      color: var(--tca-print-tinta);
    }

    html[data-app-theme="tecsa-clinico"] .card,
    html[data-app-theme="tecsa-clinico"] .kpi {
      border: 1px solid var(--tca-print-tinta);
      box-shadow: none;
      break-inside: avoid;
    }
  }
}
