/* Generado por `php artisan health:css` — no editar a mano.
   La fuente es css/cannis_health/app.css y los archivos que importa. */

/* === css/cannis_health/tokens.css === */
/* =============================================================
   TOKENS — Identidad Cannis Health (portal de profesionales)
   Único archivo del módulo donde viven valores de color.
   El resto del CSS consume exclusivamente var(--ch-*).
   ============================================================= */
:root {
  /* ---- Paleta de marca ----
     Verde clínico: la familia Cannis, corrida hacia el azul para
     leerse sobre fondo claro y diferenciarse del verde neón del portal. */
  --ch-verde:        #0E8F6F; /* primarios, acentos, links */
  --ch-verde-hondo:  #0A6B53; /* hover de primarios, títulos densos */
  --ch-verde-suave:  #E6F4F0; /* fondos de chips y filas seleccionadas */
  --ch-aqua:         #14B8A6; /* acento secundario: gráficos, destacados */
  --ch-noche:        #101C3D; /* azul del logotipo: "Cannis" y el isotipo */
  --ch-menta:        #3DDC97; /* verde del logotipo: "HEALTH" y la bajada */
  --ch-menta-clara:  #8CF0C9; /* el mismo verde, para acentos SOBRE oscuro:
                                 el #3DDC97 sobre verde hondo da 3,6:1 y en
                                 un panel con foto se acerca peligrosamente
                                 al piso de WCAG para texto grande */
  --ch-lienzo:       #EFF4F3; /* fondo de la app: las tarjetas apoyan acá */
  --ch-off-white:    #F5F8F7; /* tintes suaves: cabeceras de tabla, zebra */
  --ch-blanco:       #FFFFFF; /* superficie de cards y tablas */

  /* Dos tintas que NO son la superficie, aunque en claro coincidan con ella.
     Se separaron al hacer el modo oscuro: ahí --ch-blanco pasa a ser una
     superficie oscura, y un botón primario con la tinta de la superficie
     queda ilegible.
       · --ch-tinta-invertida va sobre un relleno saturado u oscuro que no
         cambia con el tema (el rojo de un contador, el panel del núcleo).
       · --ch-sobre-marca acompaña a --ch-verde: si el verde se aclara para
         leerse en oscuro, su tinta se oscurece. */
  --ch-tinta-invertida: #FFFFFF;
  --ch-sobre-marca:     #FFFFFF;
  --ch-sobre-riesgo:    #FFFFFF;

  /* Fondo translúcido de la topbar (estaba literal en layout.css). */
  --ch-topbar-fondo: rgba(255, 255, 255, 0.86);
  --ch-gris:         #DCE4E2; /* bordes de controles y divisores fuertes */
  --ch-gris-suave:   #E8EEEC; /* hairlines internas: borde de card, filas */
  --ch-tinta:        #16211F; /* texto principal */

  /* ---- Derivados (tintes y transparencias) ----
     Las opacidades subieron: a 0.66 / 0.42 el dato secundario —un mail, un
     DNI, la hora de un turno— se perdía contra el blanco. La jerarquía la
     tiene que dar el TAMAÑO y el PESO, no el desvanecido. */
  --ch-tinta-suave:  rgba(22, 33, 31, 0.78);  /* dato secundario: se lee */
  --ch-tinta-tenue:  rgba(22, 33, 31, 0.58);  /* etiquetas y textos de ayuda */
  --ch-tinta-fantasma: rgba(22, 33, 31, 0.40); /* placeholders y deshabilitado */
  --ch-tinta-borde:  rgba(22, 33, 31, 0.50);  /* bordes de campos (≥3:1) */
  --ch-verde-tinte:  rgba(14, 143, 111, 0.10); /* hover sutil de filas */
  --ch-verde-anillo: rgba(14, 143, 111, 0.26); /* anillo de foco */
  --ch-velo:         rgba(22, 33, 31, 0.55);   /* backdrop de modales */

  /* ---- Tinta sobre superficie oscura ----
     El login y cualquier panel de marca invierten el contraste: acá el
     blanco es la tinta y la opacidad sí construye jerarquía, porque el
     fondo es una foto y no una hoja. */
  --ch-sobre-oscuro:        rgba(255, 255, 255, 0.94); /* texto corrido */
  --ch-sobre-oscuro-tenue:  rgba(255, 255, 255, 0.82); /* firma, pies */
  --ch-sobre-oscuro-borde:  rgba(255, 255, 255, 0.28); /* borde de chips */
  --ch-sobre-oscuro-vidrio: rgba(255, 255, 255, 0.10); /* relleno de chips */
  --ch-sobre-oscuro-chip:   rgba(255, 255, 255, 0.14); /* fondo de los tildes */
  --ch-sobre-oscuro-linea:  rgba(255, 255, 255, 0.16); /* divisores */

  /* ---- Capas del panel de acceso ----
     El fondo del login se arma con halos + foto oscurecida + velo. Lo que
     garantiza que el texto se lea NO es tapar la foto sino bajarle el brillo
     antes de mezclarla: una imagen clara —el collage lo es— sube la
     luminancia del panel entera y el blanco desaparece. Los números salen de
     medir el contraste real, no a ojo. Ver vistas/login.css. */
  --ch-acceso-foto-brillo: 0.5;   /* recorte de brillo de la foto, ver abajo */
  --ch-acceso-halo-menta:  rgba(61, 220, 151, 0.30);
  --ch-acceso-halo-aqua:   rgba(20, 184, 166, 0.34);
  --ch-acceso-velo-fuerte: rgba(10, 107, 83, 0.74);
  --ch-acceso-velo-medio:  rgba(10, 107, 83, 0.56);
  --ch-acceso-velo-leve:   rgba(10, 107, 83, 0.30);
  --ch-acceso-velo-pie:    rgba(16, 28, 61, 0.45);

  /* ---- Núcleo de Cannis AI (pantalla de Agentes) ----
     El panel oscuro que muestra el sistema encendido. Mismo criterio que el
     login: sobre oscuro el blanco es la tinta. */
  --ch-nucleo-fondo:   #08543F;                        /* más hondo que el verde de marca */
  --ch-nucleo-halo:    rgba(61, 220, 151, 0.28);
  --ch-nucleo-halo-b:  rgba(20, 184, 166, 0.30);
  --ch-nucleo-anillo:  rgba(140, 240, 201, 0.22);      /* las órbitas */
  --ch-nucleo-barrido: rgba(140, 240, 201, 0.14);      /* el barrido que recorre */

  /* ---- Semáforo clínico ---- */
  --ch-ok:           #0F9D6B;
  --ch-ok-suave:     #E4F5EE;
  --ch-alerta:       #B45309;
  --ch-alerta-suave: #FDF1E3;
  --ch-riesgo:       #BE123C;
  --ch-riesgo-suave: #FDEAEF;
  --ch-info:         #1D6FB8;
  --ch-info-suave:   #E7F1FA;

  /* ---- Sombras ----
     Con el lienzo apenas más hondo que el blanco, la tarjeta ya no necesita
     un borde marcado: la separa la sombra. Dos capas —contacto + difusa—
     para que se lea como papel apoyado y no como un recuadro. */
  --ch-sombra-sm: 0 1px 2px rgba(22, 33, 31, 0.04), 0 4px 12px rgba(22, 33, 31, 0.05);
  --ch-sombra-md: 0 2px 4px rgba(22, 33, 31, 0.05), 0 10px 26px rgba(22, 33, 31, 0.08);
  --ch-sombra-lg: 0 4px 10px rgba(22, 33, 31, 0.06), 0 22px 46px rgba(22, 33, 31, 0.12);
  --ch-sombra-boton: 0 1px 2px rgba(10, 107, 83, 0.24), 0 4px 12px rgba(10, 107, 83, 0.18);

  /* ---- Tipografía ---- */
  --ch-font: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* Escala con saltos grandes a propósito: entre un dato y su etiqueta hay
     que ver la diferencia de un vistazo, sin leerlas. El profesional
     escanea la pantalla, no la lee de arriba a abajo. */
  --ch-tipo-pagina:   clamp(1.55rem, 1.1rem + 1.6vw, 1.95rem); /* título de pantalla */
  --ch-tipo-seccion:  1.0625rem;                               /* título de card */
  --ch-tipo-cifra:    clamp(1.75rem, 1.4rem + 1.2vw, 2.25rem); /* números del resumen */
  --ch-tipo-dato:     1rem;        /* EL dato: nombre del paciente, hora, valor */
  --ch-tipo-body:     0.9375rem;   /* texto corrido */
  --ch-tipo-body-sm:  0.8438rem;   /* dato secundario: contacto, fecha, detalle */
  --ch-tipo-overline: 0.6875rem;   /* etiquetas, badges, ayudas */

  /* ---- Espaciado ---- */
  --ch-sp-1: 4px;
  --ch-sp-2: 8px;
  --ch-sp-3: 12px;
  --ch-sp-4: 16px;
  --ch-sp-5: 24px;
  --ch-sp-6: 32px;
  --ch-sp-7: 48px;

  /* ---- Controles de formulario ----
     Una sola altura para input, select y botón: en una grilla de campos, dos
     controles de alto distinto en la misma fila se ven como un error. */
  --ch-alto-control: 2.75rem;
  --ch-campo-fondo:  #F7FAF9;                  /* el campo se ve sin depender del borde */
  --ch-campo-borde:  rgba(22, 33, 31, 0.16);   /* reposo: apenas insinuado */
  --ch-riesgo-anillo: rgba(190, 18, 60, 0.20); /* anillo de foco en error */

  /* ---- Formas y movimiento ---- */
  --ch-radio-sm: 8px;
  --ch-radio-md: 12px;
  --ch-radio-lg: 18px;
  --ch-radio-pill: 999px;
  --ch-transicion: 150ms ease;
  --ch-transicion-suave: 220ms cubic-bezier(0.2, 0.7, 0.3, 1);

  /* ---- Medidas del chrome ---- */
  --ch-ancho-barra: 252px;   /* barra lateral en escritorio */
  /* La banda de marca de la barra usa este mismo alto para quedar alineada
     con la topbar: con el logotipo grande a 60px no le quedaba aire arriba
     ni abajo, así que la banda subió y el logo bajó un punto. */
  --ch-alto-topbar: 72px;
  --ch-ancho-contenido: 1280px;
}

/* =============================================================
   MODO OSCURO
   -------------------------------------------------------------
   Un solo bloque: el atributo `data-tema` del <html> lo pone el
   layout desde la cookie `ch_tema` —así funciona sin JS y no hay
   parpadeo— y, si no hay cookie, el script del <head> lo deduce de
   prefers-color-scheme antes del primer pintado.

   No se toca ninguna hoja de vista: acá se redefinen los tokens y el
   resto del CSS, que sólo consume var(--ch-*), acompaña.

   Tres cosas que NO se invierten:
     · --ch-tinta-invertida y las capas --ch-sobre-oscuro-*, que ya son
       "tinta sobre oscuro" y valen igual en los dos temas;
     · las capas del login (--ch-acceso-*) y del núcleo de Agentes
       (--ch-nucleo-*): esos paneles son oscuros también en modo claro;
     · el espaciado, la tipografía y las formas.
   ============================================================= */
:root[data-tema="oscuro"] {
  /* ---- Superficies ----
     En claro la tarjeta se separa del lienzo por la sombra. En oscuro la
     sombra no se ve: la jerarquía la da la CLARIDAD, así que la tarjeta es
     más clara que el lienzo y los tintes internos, más claros todavía. */
  --ch-lienzo:      #0E1614;
  --ch-blanco:      #16211F;
  --ch-off-white:   #1D2A27;
  --ch-gris:        #35443F;
  --ch-gris-suave:  #26332F;
  --ch-topbar-fondo: rgba(22, 33, 31, 0.88);

  /* ---- Tinta ----
     Mismo criterio que en claro: la jerarquía es tamaño y peso, no
     desvanecido. Sobre oscuro un texto al 50 % directamente no se lee, así
     que los escalones arrancan más arriba. */
  --ch-tinta:          #E9F1EE;
  --ch-tinta-suave:    rgba(233, 241, 238, 0.82);
  --ch-tinta-tenue:    rgba(233, 241, 238, 0.66);
  --ch-tinta-fantasma: rgba(233, 241, 238, 0.45);
  --ch-tinta-borde:    rgba(233, 241, 238, 0.48);

  /* ---- Marca ----
     El #0E8F6F se apaga contra un fondo oscuro: el verde se aclara y, como
     ahora es un relleno claro, su tinta se da vuelta. El hover ACLARA en vez
     de oscurecer, que es lo que espera el ojo sobre fondo oscuro. */
  --ch-verde:        #2FC48D;
  --ch-verde-hondo:  #57DDA8;
  --ch-verde-suave:  #12332B;
  --ch-verde-tinte:  rgba(61, 220, 151, 0.10);
  --ch-verde-anillo: rgba(61, 220, 151, 0.32);
  --ch-sobre-marca:  #05231A;
  --ch-aqua:         #2DD4BF;

  /* ---- Semáforo clínico ----
     Los plenos se aclaran para leerse como texto; los suaves dejan de ser
     casi blancos y pasan a ser tintes oscuros del mismo tono. */
  --ch-ok:           #34D399;
  --ch-ok-suave:     #123328;
  --ch-alerta:       #FBBF24;
  --ch-alerta-suave: #33260F;
  --ch-riesgo:       #FB7185;
  --ch-riesgo-suave: #3A1620;
  /* Mismo caso que --ch-sobre-marca: el rojo se aclaró para poder leerse
     como texto, así que la tinta de los contadores que lo usan de relleno
     se da vuelta. Con blanco daban 2,7:1. */
  --ch-sobre-riesgo: #2B0710;
  --ch-riesgo-anillo: rgba(251, 113, 133, 0.28);
  --ch-info:         #60A5FA;
  --ch-info-suave:   #12243A;

  /* ---- Controles ----
     El campo se hunde en vez de sobresalir: más oscuro que la tarjeta. */
  --ch-campo-fondo:  #101A18;
  --ch-campo-borde:  rgba(233, 241, 238, 0.20);

  /* ---- Velos y sombras ----
     La sombra sobre oscuro casi no se ve; se profundiza para que la tarjeta
     flotante (menús, modales) siga despegando del fondo. */
  --ch-velo:      rgba(3, 8, 7, 0.72);
  --ch-sombra-sm: 0 1px 2px rgba(0, 0, 0, 0.30), 0 4px 12px rgba(0, 0, 0, 0.26);
  --ch-sombra-md: 0 2px 4px rgba(0, 0, 0, 0.34), 0 10px 26px rgba(0, 0, 0, 0.34);
  --ch-sombra-lg: 0 4px 10px rgba(0, 0, 0, 0.38), 0 22px 46px rgba(0, 0, 0, 0.44);
  --ch-sombra-boton: 0 1px 2px rgba(0, 0, 0, 0.40), 0 4px 12px rgba(5, 35, 26, 0.40);

  /* Le dice al navegador de qué color pintar scrollbars, controles nativos
     y el fondo del <select> abierto. Sin esto quedan claros sobre oscuro. */
  color-scheme: dark;
}

/* === css/cannis_health/base.css === */
/* =============================================================
   BASE — reset y tipografía del portal Cannis Health
   Sin colores literales: todo sale de tokens.css
   ============================================================= */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

/* Cualquier display de autor le gana al [hidden] del navegador: sin este
   !important, esconder un .ch-campo (display:flex) con el atributo no hace
   nada. Lo usan los paneles de pestañas y los campos condicionales. */
[hidden] {
    display: none !important;
}

body {
    margin: 0;
    background: var(--ch-lienzo);
    color: var(--ch-tinta);
    font-family: var(--ch-font);
    font-size: var(--ch-tipo-body);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
    margin: 0;
    line-height: 1.2;
    letter-spacing: -0.01em;
    font-weight: 700;
    /* Reparte el título entre sus líneas en vez de dejar una palabra sola
       colgando. Donde no está soportado, no pasa nada. */
    text-wrap: balance;
}

p {
    text-wrap: pretty;
}

p {
    margin: 0 0 var(--ch-sp-3);
}

p:last-child {
    margin-bottom: 0;
}

a {
    color: var(--ch-verde);
    text-decoration: none;
}

a:hover {
    color: var(--ch-verde-hondo);
    text-decoration: underline;
}

ul, ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

img, svg {
    max-width: 100%;
    display: block;
}

button {
    font: inherit;
    color: inherit;
}

/* Anillo de foco único para todo el portal: teclado incluido. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--ch-verde);
    outline-offset: 2px;
    border-radius: var(--ch-radio-sm);
}

/* Cifras clínicas alineadas en columna */
.ch-cifra,
.ch-tabla td {
    font-variant-numeric: tabular-nums;
}

/* Sólo para lectores de pantalla */
.ch-oculto {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* === css/cannis_health/componentes.css === */
/* =============================================================
   COMPONENTES — piezas reutilizables del portal Cannis Health
   Prefijo ch-, BEM. Sin colores literales.
   ============================================================= */

/* ── Botones ─────────────────────────────────────────────── */

.ch-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ch-sp-2);
    padding: 0.55rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--ch-radio-sm);
    background: var(--ch-blanco);
    color: var(--ch-tinta);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--ch-transicion), border-color var(--ch-transicion),
                color var(--ch-transicion), box-shadow var(--ch-transicion),
                transform var(--ch-transicion);
}

.ch-btn:hover {
    text-decoration: none;
}

/* El botón se hunde al apretarlo. Es la única confirmación táctil que hay
   antes de que responda el servidor. */
.ch-btn:active {
    transform: translateY(1px);
}

.ch-btn--primario {
    background: var(--ch-verde);
    color: var(--ch-sobre-marca);
    box-shadow: var(--ch-sombra-boton);
}

.ch-btn--primario:hover {
    background: var(--ch-verde-hondo);
    color: var(--ch-sobre-marca);
    transform: translateY(-1px);
}

.ch-btn--primario:active {
    transform: translateY(0);
    box-shadow: var(--ch-sombra-sm);
}

.ch-btn--secundario {
    border-color: var(--ch-gris);
    color: var(--ch-tinta);
    box-shadow: var(--ch-sombra-sm);
}

.ch-btn--secundario:hover {
    border-color: var(--ch-verde);
    color: var(--ch-verde-hondo);
    background: var(--ch-verde-suave);
}

.ch-btn--fantasma {
    background: transparent;
    color: var(--ch-tinta-suave);
}

.ch-btn--fantasma:hover {
    background: var(--ch-verde-tinte);
    color: var(--ch-verde-hondo);
}

.ch-btn--riesgo {
    border-color: var(--ch-riesgo);
    color: var(--ch-riesgo);
}

.ch-btn--riesgo:hover {
    background: var(--ch-riesgo-suave);
}

.ch-btn--chico {
    padding: 0.35rem 0.7rem;
    font-size: var(--ch-tipo-overline);
}

.ch-btn--bloque {
    width: 100%;
}

.ch-btn[disabled],
.ch-btn--inhabilitado {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.ch-btn__icono {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
}

/* ── Card ────────────────────────────────────────────────── */

/* El borde pasa a hairline: con el lienzo un punto más hondo que el blanco,
   quien separa la tarjeta es la sombra. Un borde marcado encima la hacía
   ver como un recuadro dibujado. */
/* Los otros dos contenedores de cards del portal, además de .ch-contenido:
   el <form> de un formulario largo y el panel de una pestaña. Sus cards NO
   son hijas de .ch-contenido, así que no les llegaba su gap y se separaban
   con un style="margin-top" repetido card por card — la que se olvidaba
   quedaba pegada a la anterior. Mismo gap, una sola vez.

   El panel escondido sigue escondido: [hidden] de base.css lleva !important
   justamente porque un display de autor le ganaría. */
.ch-form,
[role="tabpanel"] {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-5);
    min-width: 0;
}

.ch-form > *,
[role="tabpanel"] > * {
    min-width: 0;
}

/* Red de seguridad: dos cards hermanas NUNCA van pegadas.
   Los tres contenedores de arriba ya las separan con su gap, y esta regla
   los excluye para no sumar doble espacio. Cubre el caso que ya falló dos
   veces: un contenedor nuevo —un <div> puesto para agrupar, un parcial que
   devuelve varias cards— que nadie se acordó de darle el gap.

   :where() no suma especificidad, así que cualquier regla propia le gana. */
:where(div, section, form, main, article):not(.ch-contenido, .ch-form, [role="tabpanel"])
    > .ch-card + .ch-card {
    margin-top: var(--ch-sp-5);
}

.ch-card {
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

.ch-card__cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris-suave);
}

/* En el teléfono el control de la derecha no entra al lado del título:
   baja completo en vez de quedar aplastado contra el borde. */
@media (max-width: 720px) {
    .ch-card__cabecera {
        flex-wrap: wrap;
        align-items: flex-start;
    }

    .ch-card__cabecera > * {
        min-width: 0;
    }

    .ch-card__cabecera .ch-seguimiento-control {
        flex: 1 1 100%;
    }

    .ch-card__cabecera .ch-select--chico {
        width: 100%;
    }
}

.ch-card__titulo {
    font-size: var(--ch-tipo-seccion);
    letter-spacing: -0.01em;
}

.ch-card__ayuda {
    margin: 2px 0 0;
    font-size: var(--ch-tipo-body-sm);
    line-height: 1.45;
    color: var(--ch-tinta-tenue);
}

/* Cuando la ayuda es hermana directa del título, comparte renglón con él si
   le entran 22 rem y si no baja completa. Una bajada larga estrujada contra
   el título se lee peor que en su propio renglón. */
.ch-card__cabecera {
    flex-wrap: wrap;
}

.ch-card__cabecera > .ch-card__ayuda {
    flex: 1 1 22rem;
}

.ch-card__cuerpo {
    padding: var(--ch-sp-5);
}

.ch-card__cuerpo--liso {
    padding: 0;
}

/* ── Resumen: la fila de cifras del consultorio ──────────── */

.ch-resumen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: var(--ch-sp-4);
}

.ch-resumen__item {
    position: relative;
    overflow: hidden;
    padding: var(--ch-sp-4) var(--ch-sp-5);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

.ch-resumen__item::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: linear-gradient(90deg, var(--ch-verde), var(--ch-aqua));
}

.ch-resumen__etiqueta {
    display: block;
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-cifra {
    display: block;
    margin: var(--ch-sp-1) 0;
    font-size: var(--ch-tipo-cifra);
    font-weight: 700;
    line-height: 1.05;
}

.ch-resumen__nota {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-resumen__nota--alerta { color: var(--ch-riesgo); font-weight: 600; }
.ch-resumen__nota--ok     { color: var(--ch-ok); }

/* ── Badges ──────────────────────────────────────────────── */

.ch-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-1);
    padding: 0.15rem 0.55rem;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-blanco);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--ch-tinta-suave);
    white-space: nowrap;
}

.ch-badge--ok     { background: var(--ch-ok-suave);     border-color: transparent; color: var(--ch-ok); }
.ch-badge--alerta { background: var(--ch-alerta-suave); border-color: transparent; color: var(--ch-alerta); }
.ch-badge--riesgo { background: var(--ch-riesgo-suave); border-color: transparent; color: var(--ch-riesgo); }
.ch-badge--info   { background: var(--ch-info-suave);   border-color: transparent; color: var(--ch-info); }
.ch-badge--marca  { background: var(--ch-verde-suave);  border-color: transparent; color: var(--ch-verde-hondo); }

/* ── Chips (metadatos del profesional) ───────────────────── */

.ch-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-1);
    padding: 0.2rem 0.6rem;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-blanco);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-chip__icono {
    width: 0.875rem;
    height: 0.875rem;
    flex-shrink: 0;
    color: var(--ch-tinta-tenue);
}

/* ── Tabla ───────────────────────────────────────────────── */

.ch-tabla-scroll {
    overflow-x: auto;
    /* Cierra la cadena de min-width del layout: si este contenedor no puede
       achicarse, no hay scroll horizontal que valga. */
    min-width: 0;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
    /* Bloque contenedor de los .ch-oculto de los <th>: sin esto se posicionan
       contra el viewport y estiran la página unos píxeles. */
    position: relative;
}

.ch-tabla {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--ch-tipo-body-sm);
}

.ch-tabla th {
    padding: var(--ch-sp-3) var(--ch-sp-4);
    text-align: left;
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
    background: var(--ch-off-white);
    border-bottom: 1px solid var(--ch-gris-suave);
    white-space: nowrap;
}

.ch-tabla td {
    /* Vertical corto a propósito: una lista se escanea, y cada píxel de más
       por fila es una fila menos en pantalla. */
    padding: var(--ch-sp-3) var(--ch-sp-4);
    border-bottom: 1px solid var(--ch-gris-suave);
    vertical-align: middle;
    transition: background var(--ch-transicion);
}

.ch-tabla tbody tr:last-child td {
    border-bottom: 0;
}

.ch-tabla tbody tr:hover td {
    background: var(--ch-verde-tinte);
}

.ch-tabla tr.es-alerta td {
    background: var(--ch-riesgo-suave);
}

/* El dato principal de la fila: es lo que el profesional busca al
   escanear la tabla, así que va más grande y más oscuro que todo lo
   demás de la celda. */
.ch-tabla__principal {
    display: inline-block;
    font-size: var(--ch-tipo-dato);
    font-weight: 650;
    line-height: 1.35;
    color: var(--ch-tinta);
}

/* Cinco vistas ponen la clase sobre el <td> en vez de sobre un <span> de
   adentro. Ahí el inline-block saca la celda del layout de tabla y el borde
   inferior queda colgando del ancho del texto, como un subrayado suelto. */
td.ch-tabla__principal {
    display: table-cell;
}

a.ch-tabla__principal:hover {
    color: var(--ch-verde-hondo);
    text-decoration: underline;
}

/* Lo de apoyo —contacto, documento, fecha— se lee sin esfuerzo pero
   no compite. Antes estaba en overline + 42% de opacidad y se perdía. */
.ch-tabla__secundario {
    display: block;
    margin-top: 1px;
    font-size: var(--ch-tipo-body-sm);
    line-height: 1.4;
    color: var(--ch-tinta-tenue);
}

.ch-tabla__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
    justify-content: flex-end;
}

/* En el teléfono una tabla de siete columnas es ilegible aunque scrollee.
   Las marcadas como opcionales se esconden y su dato, cuando importa, ya
   está repetido como texto secundario de la columna principal. */
@media (max-width: 720px) {
    .ch-tabla__col--opcional {
        display: none;
    }

    .ch-tabla th,
    .ch-tabla td {
        padding: var(--ch-sp-3);
    }
}

/* ── Tabla apilable ──────────────────────────────────────────
   En el teléfono la fila deja de ser una fila y pasa a ser una tarjeta:
   nada de scroll horizontal ni de celdas de 40 px. Cada celda muestra su
   propio rótulo con el data-titulo del <td>, así que no hay que duplicar
   markup ni mantener dos listados en paralelo. */
@media (max-width: 720px) {
    .ch-tabla--apilable,
    .ch-tabla--apilable tbody,
    .ch-tabla--apilable tr,
    .ch-tabla--apilable td {
        display: block;
        width: 100%;
    }

    .ch-tabla--apilable thead {
        display: none;
    }

    /* La columna opcional sigue escondida: la tarjeta es para escanear, no
       para leer la ficha entera. La que sí hace falta se marca a mano.
       Los dos selectores repiten .ch-tabla--apilable para ganarle en
       especificidad al display:block que la apila. */
    .ch-tabla--apilable td.ch-tabla__col--opcional {
        display: none;
    }

    .ch-tabla--apilable td.ch-tabla__col--opcional.ch-tabla__col--movil {
        display: block;
    }

    .ch-tabla--apilable tr {
        padding: var(--ch-sp-4);
        border: 1px solid var(--ch-gris-suave);
        border-radius: var(--ch-radio-lg);
        background: var(--ch-blanco);
        box-shadow: var(--ch-sombra-sm);
    }

    /* El tinte de la fila con alerta pinta la tarjeta entera. Pintando las
       celdas quedaban bandas de color con el padding en blanco. */
    .ch-tabla--apilable tbody tr.es-alerta {
        background: var(--ch-riesgo-suave);
    }

    .ch-tabla--apilable tbody tr.es-alerta td,
    .ch-tabla--apilable tbody tr:hover td {
        background: transparent;
    }

    .ch-tabla--apilable tbody tr + tr {
        margin-top: var(--ch-sp-3);
    }

    .ch-tabla--apilable td {
        padding: 0;
        border: 0;
    }

    /* Renglón etiquetado: rótulo chico arriba, dato abajo. */
    .ch-tabla--apilable td[data-titulo] {
        margin-top: var(--ch-sp-3);
        padding-top: var(--ch-sp-3);
        border-top: 1px dashed var(--ch-gris);
    }

    .ch-tabla--apilable td[data-titulo]::before {
        content: attr(data-titulo);
        display: block;
        margin-bottom: var(--ch-sp-1);
        font-size: var(--ch-tipo-overline);
        font-weight: 600;
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--ch-tinta-tenue);
    }

    /* La primera celda es el encabezado de la tarjeta. */
    .ch-tabla--apilable td:first-child .ch-tabla__principal {
        font-size: var(--ch-tipo-seccion);
    }

    .ch-tabla--apilable .ch-tabla__acciones {
        justify-content: stretch;
    }

    .ch-tabla--apilable .ch-tabla__acciones .ch-btn {
        flex: 1 1 auto;
        justify-content: center;
    }

    /* Sin ancho de columna que la achique, el select respira. */
    .ch-tabla--apilable .ch-select--chico {
        width: 100%;
        max-width: none;
    }
}

/* ── Cabecera de ficha ───────────────────────────────────────
   Identidad + acciones de una entidad con nombre propio: el paciente en su
   ficha y en la consulta, el trámite en la gestión REPROCANN. El markup lo
   arma cada pantalla —los campos no son los mismos— pero la forma es una. */

.ch-ficha-cabecera {
    /* Dos columnas: quién es a la izquierda, qué se puede hacer a la
       derecha. Con flex-wrap las acciones caían debajo y la cabecera
       quedaba con media tarjeta vacía. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    gap: var(--ch-sp-5);
    padding: var(--ch-sp-5);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

.ch-ficha-cabecera__identidad {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-4);
    min-width: 0;
}

.ch-avatar {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 3rem;
    height: 3rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-verde-suave);
    color: var(--ch-verde-hondo);
    font-size: var(--ch-tipo-body);
    font-weight: 700;
    letter-spacing: 0.02em;
}

.ch-ficha-cabecera__nombre {
    font-size: var(--ch-tipo-pagina);
    letter-spacing: -0.02em;
    line-height: 1.15;
}

.ch-ficha-cabecera__meta {
    margin-top: 2px;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-ficha-cabecera__marcas {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
    margin-top: var(--ch-sp-3);
}

.ch-ficha-cabecera__acciones {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--ch-sp-2);
    max-width: 22rem;
}

/* El contacto es accionable, no un dato para leer: va con los botones. */
.ch-ficha-cabecera__contacto {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    width: 100%;
    text-align: right;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-ficha-cabecera__contacto a {
    color: var(--ch-tinta-suave);
}

/* En pantalla angosta la cabecera vuelve a una sola columna. */
@media (max-width: 900px) {
    .ch-ficha-cabecera {
        grid-template-columns: minmax(0, 1fr);
    }

    .ch-ficha-cabecera__acciones {
        justify-content: flex-start;
        max-width: none;
    }

    .ch-ficha-cabecera__contacto {
        align-items: flex-start;
        text-align: left;
    }
}

@media (max-width: 720px) {
    .ch-ficha-cabecera {
        padding: var(--ch-sp-4);
        gap: var(--ch-sp-4);
    }

    .ch-ficha-cabecera__acciones {
        width: 100%;
    }

    .ch-ficha-cabecera__acciones .ch-btn {
        flex: 1 1 auto;
        justify-content: center;
    }
}

/* ── Formularios ─────────────────────────────────────────── */

/* Grilla por defecto: columnas que se acomodan solas. Sirve para un
   formulario cualquiera, sin decidir nada. */
.ch-form__grilla {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--ch-sp-4) var(--ch-sp-4);
}

/* Grilla de 12 columnas: cuando el ancho del campo tiene que decir algo.
   Un DNI y un domicilio no piden lo mismo, y con columnas iguales el
   formulario se lee como una planilla en vez de como una ficha. */
.ch-form__grilla--12 {
    grid-template-columns: repeat(12, minmax(0, 1fr));
}

.ch-form__grilla--12 > .ch-campo {
    grid-column: span 6;
}

.ch-form__grilla--12 > .ch-campo--corto { grid-column: span 3; }   /* DNI, edad, fecha */
.ch-form__grilla--12 > .ch-campo--medio { grid-column: span 4; }   /* celular, código */
.ch-form__grilla--12 > .ch-campo--ancho { grid-column: 1 / -1; }   /* domicilio, texto */

/* Tablet: la mitad de las divisiones, para que nada baje de ~200 px. */
@media (max-width: 1080px) {
    .ch-form__grilla--12 > .ch-campo--corto,
    .ch-form__grilla--12 > .ch-campo--medio {
        grid-column: span 6;
    }
}

@media (max-width: 720px) {
    .ch-form__grilla--12 > .ch-campo,
    .ch-form__grilla--12 > .ch-campo--corto,
    .ch-form__grilla--12 > .ch-campo--medio {
        grid-column: 1 / -1;
    }
}

.ch-campo {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-1);
    min-width: 0;
}

.ch-campo--ancho {
    grid-column: 1 / -1;
}

.ch-campo__label {
    display: flex;
    align-items: baseline;
    gap: var(--ch-sp-2);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    color: var(--ch-tinta);
}

/* El asterisco rojo grita en un formulario donde casi todo es obligatorio.
   Lo que de verdad ayuda es marcar lo que NO lo es. */
.ch-campo__label .ch-req {
    color: var(--ch-riesgo);
}

.ch-campo__label .ch-opcional {
    font-size: var(--ch-tipo-overline);
    font-weight: 500;
    color: var(--ch-tinta-tenue);
}

.ch-campo__ayuda {
    font-size: var(--ch-tipo-overline);
    line-height: 1.45;
    color: var(--ch-tinta-tenue);
}

.ch-campo__error {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-1);
    font-size: var(--ch-tipo-overline);
    font-weight: 600;
    color: var(--ch-riesgo);
}

.ch-campo__error::before {
    content: '!';
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-riesgo);
    color: var(--ch-sobre-riesgo);
    font-size: 0.625rem;
    line-height: 1;
}

/* ── Los controles ───────────────────────────────────────────
   Misma altura, mismo radio y un fondo apenas más frío que la card: el
   campo se distingue de la superficie sin depender de un borde marcado,
   y al enfocarlo pasa a blanco, que es la señal de "acá estás escribiendo". */
.ch-input,
.ch-select,
.ch-textarea {
    width: 100%;
    min-height: var(--ch-alto-control);
    padding: 0.6rem 0.8rem;
    border: 1px solid var(--ch-campo-borde);
    border-radius: var(--ch-radio-sm);
    background: var(--ch-campo-fondo);
    color: var(--ch-tinta);
    font-family: inherit;
    font-size: var(--ch-tipo-body);
    line-height: 1.35;
    transition: border-color var(--ch-transicion), box-shadow var(--ch-transicion),
                background-color var(--ch-transicion);
}

.ch-input:hover:not(:disabled):not(:focus),
.ch-select:hover:not(:disabled):not(:focus),
.ch-textarea:hover:not(:disabled):not(:focus) {
    border-color: var(--ch-tinta-borde);
}

.ch-input::placeholder,
.ch-textarea::placeholder {
    color: var(--ch-tinta-fantasma);
}

.ch-input:focus,
.ch-select:focus,
.ch-textarea:focus {
    outline: none;
    border-color: var(--ch-verde);
    background: var(--ch-blanco);
    box-shadow: 0 0 0 3px var(--ch-verde-anillo);
}

.ch-input:disabled,
.ch-select:disabled,
.ch-textarea:disabled,
.ch-input[readonly],
.ch-textarea[readonly] {
    background: var(--ch-off-white);
    color: var(--ch-tinta-tenue);
    cursor: not-allowed;
}

.ch-input.es-invalido,
.ch-select.es-invalido,
.ch-textarea.es-invalido {
    border-color: var(--ch-riesgo);
    background: var(--ch-riesgo-suave);
}

.ch-input.es-invalido:focus,
.ch-select.es-invalido:focus,
.ch-textarea.es-invalido:focus {
    box-shadow: 0 0 0 3px var(--ch-riesgo-anillo);
}

/* Un número es un dato tabular: alineado y sin las flechitas del navegador,
   que en un DNI o un teléfono sólo se pulsan sin querer. */
.ch-input[type='number'],
.ch-input[inputmode='numeric'],
.ch-input[type='tel'] {
    font-variant-numeric: tabular-nums;
}

.ch-input[type='number']::-webkit-outer-spin-button,
.ch-input[type='number']::-webkit-inner-spin-button {
    margin: 0;
    -webkit-appearance: none;
}

.ch-input[type='number'] {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* El icono nativo de fecha/hora es gris pálido y se pierde. */
.ch-input[type='date']::-webkit-calendar-picker-indicator,
.ch-input[type='time']::-webkit-calendar-picker-indicator {
    padding: 2px;
    border-radius: 4px;
    cursor: pointer;
    opacity: 0.55;
    transition: opacity var(--ch-transicion);
}

.ch-input[type='date']:hover::-webkit-calendar-picker-indicator,
.ch-input[type='time']:hover::-webkit-calendar-picker-indicator {
    opacity: 1;
}

/* La flecha del select la dibuja cada sistema a su manera: con una propia,
   el control se ve igual en todos lados y queda alineado con el resto. */
.ch-select {
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%2316211F' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    background-size: 1.1rem;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
}

.ch-textarea {
    min-height: 5.5rem;
    line-height: 1.5;
    resize: vertical;
}

/* ── Campo con adorno (prefijo o sufijo) ─────────────────────
   Para el "+54" del celular o el "días" de una frecuencia: el dato entra
   sin la muletilla, y la muletilla no ocupa una etiqueta aparte. */
.ch-campo__control {
    position: relative;
    display: flex;
    align-items: center;
}

.ch-campo__adorno {
    position: absolute;
    z-index: 1;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
    pointer-events: none;
}

.ch-campo__adorno--izq { left: 0.8rem; }
.ch-campo__adorno--der { right: 0.8rem; }

/* Cuando el input lleva un ancho propio, el adorno no puede ir anclado al
   borde del contenedor: va al lado, en el flujo. */
.ch-campo__control--suelto {
    gap: var(--ch-sp-2);
}

.ch-campo__control--suelto .ch-campo__adorno {
    position: static;
}

.ch-campo__control:has(.ch-campo__adorno--izq) .ch-input { padding-left: 3.25rem; }
.ch-campo__control:has(.ch-campo__adorno--der) .ch-input { padding-right: 3.5rem; }

/* ── Casillas y radios ───────────────────────────────────────
   La casilla nativa mide 13 px y no se ve. Se dibuja una propia del alto de
   una línea, y el input real queda debajo para no perder accesibilidad. */
.ch-check {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-3);
    font-size: var(--ch-tipo-body-sm);
    cursor: pointer;
}

.ch-check input {
    flex-shrink: 0;
    width: 1.15rem;
    height: 1.15rem;
    margin: 0.1rem 0 0;
    accent-color: var(--ch-verde);
    cursor: pointer;
}

/* Una opción con su explicación abajo: el <small> aclara qué implica
   prenderla, sin robarle peso a la etiqueta. */
.ch-check small {
    display: block;
    margin-top: 2px;
    font-size: var(--ch-tipo-overline);
    font-weight: 400;
    line-height: 1.45;
    color: var(--ch-tinta-tenue);
}

/* ── Opción como tarjeta ─────────────────────────────────────
   Una decisión del formulario que arrastra consecuencias —activar el
   seguimiento, declarar el REPROCANN— no es un renglón más: es una
   tarjeta que se prende, con su campo dependiente adentro. */
.ch-opcion {
    padding: var(--ch-sp-4);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-md);
    background: var(--ch-blanco);
    cursor: pointer;
    transition: border-color var(--ch-transicion), background-color var(--ch-transicion),
                box-shadow var(--ch-transicion);
}

.ch-opcion:hover {
    border-color: var(--ch-verde);
}

.ch-opcion:has(input:checked) {
    border-color: var(--ch-verde);
    background: var(--ch-verde-suave);
}

.ch-opcion:has(input:focus-visible) {
    box-shadow: 0 0 0 3px var(--ch-verde-anillo);
}

.ch-opcion__cabecera {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-3);
    cursor: pointer;
}

.ch-opcion__titulo {
    font-size: var(--ch-tipo-body);
    font-weight: 600;
}

.ch-opcion__ayuda {
    display: block;
    margin-top: 2px;
    font-size: var(--ch-tipo-body-sm);
    font-weight: 400;
    line-height: 1.45;
    color: var(--ch-tinta-tenue);
}

/* Lo que sólo tiene sentido con la opción prendida cuelga de ella, indentado
   a la altura del texto para que se lea como consecuencia y no como
   un campo más del formulario. */
.ch-opcion__dependiente {
    margin: var(--ch-sp-4) 0 0 calc(1.15rem + var(--ch-sp-3));
    padding-top: var(--ch-sp-4);
    border-top: 1px dashed var(--ch-gris);
}

@media (max-width: 720px) {
    .ch-opcion__dependiente {
        margin-left: 0;
    }
}

/* Lista de opciones sueltas dentro de un formulario. */
.ch-opciones {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4);
    background: var(--ch-off-white);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
}

.ch-form__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-3);
    justify-content: flex-end;
    margin-top: var(--ch-sp-5);
    padding-top: var(--ch-sp-4);
    border-top: 1px solid var(--ch-gris);
}

/* ── Barra de filtros de los listados ─────────────────────────
   Grilla, no flex. Con `flex-wrap` + `flex: 1 1 170px` el ancho de cada
   filtro salía de cuántos hubiera y de cuánto sobrara en la última fila: el
   mismo select medía distinto en cada pantalla y el último quedaba estirado
   de punta a punta. Con columnas de ancho fijo (auto-fill) un filtro mide lo
   mismo en las seis pantallas y una fila incompleta no deforma nada.

   La barra lleva el tinte interno de la card —como la cabecera de una tabla—
   para que se lea como herramienta y no como un formulario más. */
.ch-filtros {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris);
    background: var(--ch-off-white);
}

/* La barra: el buscador —lo que más se usa— y el botón que abre el resto.
   Desplegados, seis filtros empujaban la tabla media pantalla para abajo. */
.ch-filtros__barra {
    display: flex;
    align-items: flex-end;
    gap: var(--ch-sp-3);
}

.ch-filtros__barra .ch-campo--buscador {
    flex: 1 1 auto;
    min-width: 0;
}

.ch-filtros__abrir {
    flex-shrink: 0;
    gap: var(--ch-sp-2);
}

/* Cuántos filtros del panel están puestos: con el panel cerrado es la única
   señal de que hay algo aplicado ahí adentro. */
.ch-filtros__cuenta {
    display: inline-grid;
    place-items: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.3rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-verde);
    color: var(--ch-sobre-marca);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
}

/* El panel: columnas de ancho fijo. Con `flex-wrap` el ancho de cada filtro
   salía de cuántos hubiera y de cuánto sobrara en la última fila, así que el
   mismo select medía distinto en cada pantalla. */
.ch-filtros__panel {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
    align-items: end;
    gap: var(--ch-sp-3);
    min-width: 0;
}

.ch-filtros__panel:empty {
    display: none;
}

/* Un rango ocupa dos columnas: son dos controles. */
.ch-filtros .ch-campo--rango {
    grid-column: span 2;
}

.ch-filtros__lupa {
    position: absolute;
    left: 0.75rem;
    width: 1rem;
    height: 1rem;
    color: var(--ch-tinta-tenue);
    pointer-events: none;
}

.ch-campo--buscador .ch-campo__control .ch-input {
    padding-left: 2.4rem;
}

/* Un <select> angosto CORTA la opción a la mitad de una letra en vez de
   marcarla como recortada: con puntos suspensivos al menos se ve que sigue. */
.ch-filtros .ch-select {
    text-overflow: ellipsis;
}

/* Un rango es un filtro con dos extremos, no dos filtros. */
.ch-rango {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: var(--ch-sp-2);
}

.ch-rango__a {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

/* El pie ocupa la fila entera: lo aplicado a la izquierda, los botones a la
   derecha. Antes las acciones eran un item más entre los campos y terminaban
   donde les tocara. */
.ch-filtros__pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    min-width: 0;
}

.ch-filtros__aplicados {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ch-sp-2);
    min-width: 0;
}

.ch-filtros__rotulo {
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-filtros__acciones {
    display: flex;
    gap: var(--ch-sp-2);
    margin-left: auto;
}

/* La pastilla de un filtro aplicado. No es `.ch-chip` —que son los metadatos
   del profesional, estáticos—: ésta se saca con un clic y tiene que parecerlo. */
.ch-aplicado {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
    max-width: 100%;
    padding: 0.22rem 0.5rem 0.22rem 0.7rem;
    border: 1px solid transparent;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-verde-suave);
    color: var(--ch-verde-hondo);
    font-size: var(--ch-tipo-body-sm);
    text-decoration: none;
    transition: background-color var(--ch-transicion), border-color var(--ch-transicion);
}

.ch-aplicado:hover,
.ch-aplicado:focus-visible {
    border-color: var(--ch-verde);
    background: var(--ch-verde-suave);
}

.ch-aplicado__campo {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    opacity: 0.75;
}

.ch-aplicado__valor {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ch-aplicado__quitar {
    flex-shrink: 0;
    width: 0.875rem;
    height: 0.875rem;
}

/* En el teléfono una sola columna: dos selects de 12 rem no entran, y el
   `span 2` del rango crearía una columna implícita que desborda. */
@media (max-width: 600px) {
    .ch-filtros {
        padding: var(--ch-sp-4);
    }

    .ch-filtros__panel {
        grid-template-columns: minmax(0, 1fr);
    }

    .ch-filtros .ch-campo--rango {
        grid-column: auto;
    }

    .ch-filtros__acciones .ch-btn {
        flex: 1 1 auto;
        justify-content: center;
    }
}

/* ── El markdown del modelo ───────────────────────────────────
   El asistente contesta en markdown y pintarMarkdown() de health.js lo
   pinta como nodos. Los bloques son span/strong/ul, no <p>, para no
   heredar los márgenes de párrafo del navegador dentro de la burbuja.

   Va acá y no en vistas/asistente.css porque ya lo pintan DOS pantallas:
   la burbuja y Cannis AI › Chat. El contenedor lo marca el propio
   pintarMarkdown() con la clase .ch-md, así que ninguna hoja de vista
   tiene que repetir estas reglas.
   ──────────────────────────────────────────────────────────── */

.ch-md__parrafo,
.ch-md__titulo {
    display: block;
    white-space: pre-wrap;
}

.ch-md__parrafo + .ch-md__parrafo,
.ch-md__titulo + .ch-md__parrafo,
.ch-md__parrafo + .ch-md__titulo,
.ch-md__lista + .ch-md__parrafo,
.ch-md__lista + .ch-md__titulo {
    margin-top: var(--ch-sp-2);
}

.ch-md__titulo {
    font-weight: 650;
}

.ch-md .ch-md__lista {
    margin: var(--ch-sp-2) 0 0;
    padding-left: 1.15rem;
}

.ch-md .ch-md__lista li + li {
    margin-top: 2px;
}

.ch-md strong {
    font-weight: 650;
}

.ch-md code {
    padding: 1px 4px;
    border-radius: var(--ch-radio-sm);
    background: var(--ch-gris-suave);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.92em;
}

/* ── Avisos ──────────────────────────────────────────────── */

.ch-aviso {
    display: flex;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-md);
    background: var(--ch-blanco);
    font-size: var(--ch-tipo-body-sm);
}

.ch-aviso__titulo {
    font-weight: 700;
    margin-bottom: var(--ch-sp-1);
}

.ch-aviso--exito  { background: var(--ch-ok-suave);     border-color: transparent; }
.ch-aviso--alerta { background: var(--ch-alerta-suave); border-color: transparent; }
.ch-aviso--error  { background: var(--ch-riesgo-suave); border-color: transparent; }
.ch-aviso--info   { background: var(--ch-info-suave);   border-color: transparent; }

.ch-aviso__icono {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
}

.ch-aviso--exito  .ch-aviso__icono { color: var(--ch-ok); }
.ch-aviso--alerta .ch-aviso__icono { color: var(--ch-alerta); }
.ch-aviso--error  .ch-aviso__icono { color: var(--ch-riesgo); }
.ch-aviso--info   .ch-aviso__icono { color: var(--ch-info); }

/* ── Estado vacío ────────────────────────────────────────── */

.ch-vacio {
    padding: var(--ch-sp-7) var(--ch-sp-5);
    text-align: center;
    color: var(--ch-tinta-suave);
}

.ch-vacio__icono {
    width: 2.5rem;
    height: 2.5rem;
    margin: 0 auto var(--ch-sp-3);
    color: var(--ch-tinta-tenue);
}

.ch-vacio__titulo {
    font-size: var(--ch-tipo-seccion);
    color: var(--ch-tinta);
    margin-bottom: var(--ch-sp-2);
}

/* ── Paginación ──────────────────────────────────────────── */

.ch-paginacion {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-3) var(--ch-sp-5);
    border-top: 1px solid var(--ch-gris);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

/* Con muchas páginas la tira no entra en un teléfono: envuelve en vez de
   estirar el documento a lo ancho (la bandeja de resueltas llegaba a 593 px
   sobre un viewport de 390). */
.ch-paginacion__links {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--ch-sp-1);
    min-width: 0;
}

.ch-paginacion__link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 var(--ch-sp-2);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
    color: var(--ch-tinta-suave);
    font-weight: 600;
}

.ch-paginacion__link:hover {
    border-color: var(--ch-verde);
    color: var(--ch-verde-hondo);
    text-decoration: none;
}

.ch-paginacion__link.es-actual {
    background: var(--ch-verde);
    border-color: var(--ch-verde);
    color: var(--ch-sobre-marca);
}

.ch-paginacion__link.es-inhabilitado {
    opacity: 0.45;
    pointer-events: none;
}

/* ── Barra de progreso de cupo ───────────────────────────── */

.ch-cupo {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-1);
}

.ch-cupo__barra {
    height: 6px;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-gris);
    overflow: hidden;
}

.ch-cupo__relleno {
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, var(--ch-verde), var(--ch-aqua));
}

.ch-cupo__relleno.es-agotado {
    background: var(--ch-riesgo);
}

/* ── Lista de definiciones (fichas) ──────────────────────── */

.ch-datos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--ch-sp-4);
}

.ch-dato__etiqueta {
    display: block;
    margin-bottom: 2px;
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

/* El valor manda sobre su etiqueta: más grande, más oscuro, más pesado.
   Es la regla de todo el portal — la etiqueta orienta, el dato informa. */
.ch-dato__valor {
    font-size: var(--ch-tipo-dato);
    font-weight: 600;
    line-height: 1.4;
    color: var(--ch-tinta);
}

/* Un valor que es un texto largo (observaciones, antecedentes) vuelve al
   peso normal: ahí se lee de corrido, no se escanea. */
.ch-dato__valor--texto {
    font-size: var(--ch-tipo-body);
    font-weight: 400;
    color: var(--ch-tinta-suave);
}

/* ── Select compacto para editar dentro de una tabla ─────── */

.ch-select--chico {
    padding: 0.25rem 1.6rem 0.25rem 0.5rem;
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    /* Un select toma el ancho de su opción más larga: dentro de una celda
       eso le impone el ancho a toda la tabla. */
    max-width: 100%;
}

.ch-seguimiento-control {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-2);
}

.ch-seguimiento-control__cuenta {
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
    white-space: nowrap;
}

/* ── Tooltip ──────────────────────────────────────────────────
   El del sistema operativo tarda un segundo en salir, se ve distinto en
   cada máquina y no responde al teclado. Éste lo monta health.js como un
   único nodo colgado del <body>: dentro de una card lo recortaría el
   overflow de la tarjeta.

   Va con la tinta de fondo y la superficie de texto —al revés que todo lo
   demás— para que se lea como una capa por encima de la pantalla y no como
   otra superficie más. Los dos tokens se dan vuelta con el tema, así que en
   oscuro queda claro sobre oscuro sin ninguna regla extra.
   ──────────────────────────────────────────────────────────── */

.ch-tip {
    position: absolute;
    z-index: 1000;
    max-width: 18rem;
    padding: 0.4rem 0.6rem;
    border-radius: var(--ch-radio-sm);
    background: var(--ch-tinta);
    color: var(--ch-blanco);
    font-size: 0.78rem;
    line-height: 1.35;
    font-weight: 500;
    white-space: pre-line;
    box-shadow: var(--ch-sombra-md);
    pointer-events: none;   /* no puede taparse a sí mismo el hover */
}

/* La flechita, del lado por el que salió. */
.ch-tip::after {
    content: '';
    position: absolute;
    left: 50%;
    margin-left: -5px;
    border: 5px solid transparent;
}

.ch-tip:not(.es-abajo)::after {
    top: 100%;
    border-top-color: var(--ch-tinta);
}

.ch-tip.es-abajo::after {
    bottom: 100%;
    border-bottom-color: var(--ch-tinta);
}

/* Un elemento con tooltip que además es enfocable no lleva contorno de
   botón: el foco se ve porque aparece el tooltip. */
[data-tip] {
    cursor: default;
}

/* ── Modal ────────────────────────────────────────────────────
   <dialog> nativo. El navegador ya pone el fondo, atrapa el foco y
   cierra con Escape: acá sólo se le da la forma del portal.
   ──────────────────────────────────────────────────────────── */

.ch-modal {
    width: min(32rem, calc(100vw - 2rem));
    padding: 0;
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    background: var(--ch-blanco);
    color: var(--ch-tinta);
    box-shadow: var(--ch-sombra-md);
}

/* El fondo del dialog nativo es negro puro y en modo oscuro no se ve. */
.ch-modal::backdrop {
    background: rgba(14, 22, 20, 0.55);
    backdrop-filter: blur(2px);
}

.ch-modal__caja {
    display: flex;
    flex-direction: column;
}

.ch-modal__cabecera {
    padding: var(--ch-sp-5) var(--ch-sp-5) 0;
}

.ch-modal__titulo {
    margin: 0;
    font-size: var(--ch-tipo-seccion);
    font-weight: 650;
}

.ch-modal__bajada {
    margin: var(--ch-sp-2) 0 0;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-modal__cuerpo {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-5);
}

.ch-modal__pie {
    display: flex;
    justify-content: flex-end;
    gap: var(--ch-sp-2);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-top: 1px solid var(--ch-gris-suave);
    background: var(--ch-off-white);
}

/* === css/cannis_health/layout.css === */
/* =============================================================
   LAYOUT — chrome del portal Cannis Health
   Escritorio: barra lateral fija + topbar.
   Móvil: la barra se vuelve cajón y aparece la tab-bar inferior.
   ============================================================= */

.ch-portal {
    display: flex;
    min-height: 100vh;
}

/* ── Barra lateral ───────────────────────────────────────── */

.ch-barra {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    width: var(--ch-ancho-barra);
    background: var(--ch-blanco);
    border-right: 1px solid var(--ch-gris-suave);
    overflow-y: auto;
}

.ch-barra__marca {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-2);
    height: var(--ch-alto-topbar);
    padding: 0 var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris-suave);
    flex-shrink: 0;
}

.ch-barra__marca:hover {
    text-decoration: none;
}

/* El logotipo es azul noche sobre transparente: sobre la barra oscura
   desaparece. Se pasa a blanco con un filtro en vez de mantener un segundo
   archivo, que es lo que ya hace el panel del login. Si algún día el logo
   deja de ser monocromo, este filtro deja de servir. */
:root[data-tema="oscuro"] .ch-barra__logo {
    filter: brightness(0) invert(1);
}

.ch-barra__logo {
    /* El logotipo lleva la bajada "by cannis.org" debajo de HEALTH, así que
       necesita más alto que un wordmark de una línea. A 60px dentro de una
       banda de 60 no le quedaba aire: la banda subió a 72 y el logo a 52. */
    height: 52px;
    width: auto;
    max-width: 100%;
}

.ch-barra__nav {
    padding: var(--ch-sp-5) var(--ch-sp-3);
    flex: 1;
}

.ch-barra__grupo + .ch-barra__grupo {
    margin-top: var(--ch-sp-6);
}

.ch-barra__grupo-titulo {
    padding: 0 var(--ch-sp-3);
    margin-bottom: var(--ch-sp-3);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-barra__link {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-3);
    padding: 0.625rem var(--ch-sp-3);
    border-radius: var(--ch-radio-md);
    color: var(--ch-tinta-suave);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    transition: background var(--ch-transicion), color var(--ch-transicion);
}

.ch-barra__link + .ch-barra__link {
    margin-top: 2px;
}

.ch-barra__link:hover {
    background: var(--ch-verde-tinte);
    color: var(--ch-verde-hondo);
    text-decoration: none;
}

.ch-barra__link.es-actual {
    background: var(--ch-verde-suave);
    color: var(--ch-verde-hondo);
    box-shadow: inset 3px 0 0 0 var(--ch-verde);
}

/* El ícono acompaña al estado: apagado cuando el link está en reposo, en
   verde de marca cuando es la pantalla actual. Sin esto los nueve íconos
   pesaban lo mismo y la barra se leía como una lista plana. */
.ch-barra__icono {
    width: 1.15rem;
    height: 1.15rem;
    flex-shrink: 0;
    color: var(--ch-tinta-tenue);
    transition: color var(--ch-transicion);
}

.ch-barra__link:hover .ch-barra__icono,
.ch-barra__link.es-actual .ch-barra__icono {
    color: var(--ch-verde);
}

.ch-barra__contador {
    margin-left: auto;
    padding: 0.05rem 0.4rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-riesgo);
    color: var(--ch-sobre-riesgo);
    font-size: 0.65rem;
    font-weight: 700;
}

.ch-barra__pie {
    padding: var(--ch-sp-4);
    border-top: 1px solid var(--ch-gris-suave);
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
}

/* ── Columna de contenido ────────────────────────────────── */

.ch-columna {
    flex: 1;
    min-width: 0;
    margin-left: var(--ch-ancho-barra);
    display: flex;
    flex-direction: column;
}

/* ── Topbar ──────────────────────────────────────────────── */

.ch-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: var(--ch-sp-3);
    height: var(--ch-alto-topbar);
    padding: 0 var(--ch-sp-5);
    background: var(--ch-topbar-fondo);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    border-bottom: 1px solid var(--ch-gris-suave);
}

.ch-topbar__abrir {
    display: none;
    padding: var(--ch-sp-2);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
    background: var(--ch-blanco);
    cursor: pointer;
}

.ch-topbar__titulo {
    font-size: var(--ch-tipo-seccion);
    font-weight: 700;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ch-topbar__derecha {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-3);
    margin-left: auto;
}

/* Estado del plan */
/* ── Toggle claro / oscuro ────────────────────────────────
   Un solo botón con los dos íconos encima: se muestra el del tema al que
   se va a cambiar, no el actual. Así el botón dice qué hace. */
.ch-tema {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-blanco);
    color: var(--ch-tinta-suave);
    cursor: pointer;
    transition: color var(--ch-transicion), border-color var(--ch-transicion);
}

.ch-tema:hover {
    color: var(--ch-verde-hondo);
    border-color: var(--ch-verde);
}

/* Los dos íconos comparten celda para que el botón no cambie de tamaño. */
.ch-tema__icono {
    grid-area: 1 / 1;
    display: grid;
    place-items: center;
}

.ch-tema__icono--claro { display: none; }

:root[data-tema="oscuro"] .ch-tema__icono--claro  { display: grid; }
:root[data-tema="oscuro"] .ch-tema__icono--oscuro { display: none; }

.ch-plan-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
    padding: 0.25rem 0.7rem;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-pill);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    color: var(--ch-tinta-suave);
    white-space: nowrap;
}

.ch-plan-pill:hover {
    border-color: var(--ch-verde);
    color: var(--ch-verde-hondo);
    text-decoration: none;
}

.ch-plan-pill__punto {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-ok);
    box-shadow: 0 0 0 3px var(--ch-ok-suave);
}

.ch-plan-pill__punto.es-inactivo {
    background: var(--ch-tinta-tenue);
    box-shadow: none;
}

/* Menú de usuario */
.ch-usuario {
    position: relative;
}

.ch-usuario__boton {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-2);
    padding: 0.25rem 0.5rem 0.25rem 0.25rem;
    border: 1px solid transparent;
    border-radius: var(--ch-radio-pill);
    background: transparent;
    cursor: pointer;
}

.ch-usuario__boton:hover {
    border-color: var(--ch-gris);
}

.ch-usuario__avatar {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-verde-suave);
    color: var(--ch-verde-hondo);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 700;
}

.ch-usuario__nombre {
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    max-width: 12rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ch-usuario__menu {
    position: absolute;
    top: calc(100% + var(--ch-sp-2));
    right: 0;
    z-index: 50;
    min-width: 12rem;
    padding: var(--ch-sp-2);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-md);
    box-shadow: var(--ch-sombra-lg);
}

.ch-usuario__item {
    display: block;
    width: 100%;
    padding: 0.45rem var(--ch-sp-3);
    border: 0;
    border-radius: var(--ch-radio-sm);
    background: transparent;
    text-align: left;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
    cursor: pointer;
}

.ch-usuario__item:hover {
    background: var(--ch-verde-tinte);
    color: var(--ch-verde-hondo);
    text-decoration: none;
}

.ch-usuario__item--salir {
    color: var(--ch-riesgo);
}

.ch-usuario__separador {
    height: 1px;
    margin: var(--ch-sp-2) 0;
    background: var(--ch-gris);
}

/* ── Main ────────────────────────────────────────────────── */

.ch-main {
    flex: 1;
    /* min-width: auto es el default de un flex item y significa "no me
       achiques por debajo de mi contenido". Con una tabla ancha adentro, el
       main crecía más que la pantalla y el overflow-x de .ch-tabla-scroll no
       llegaba a activarse nunca: la página entera se iba al costado. */
    min-width: 0;
    padding: var(--ch-sp-6) var(--ch-sp-5) var(--ch-sp-7);
}

.ch-contenido {
    max-width: var(--ch-ancho-contenido);
    width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-5);
    min-width: 0;
}

/* Lo mismo para cada card: sin esto una tabla ancha estira su tarjeta. */
.ch-contenido > * {
    min-width: 0;
}

.ch-pagina__encabezado {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--ch-sp-4);
}

.ch-pagina__titulo {
    font-size: var(--ch-tipo-pagina);
    letter-spacing: -0.02em;
}

/* La bajada explica la pantalla una vez; después estorba. Va en el tono
   de las ayudas para que el ojo caiga en el contenido, no en ella. */
.ch-pagina__bajada {
    margin: var(--ch-sp-1) 0 0;
    font-size: var(--ch-tipo-body-sm);
    line-height: 1.5;
    color: var(--ch-tinta-tenue);
    max-width: 68ch;
}

.ch-pagina__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
}

.ch-migas {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ch-sp-2);
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
}

.ch-migas__sep {
    color: var(--ch-gris);
}

/* Grilla de dos columnas para pantallas con panel lateral */
.ch-grilla-2 {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: var(--ch-sp-5);
    align-items: start;
}

/* ── Cajón móvil ─────────────────────────────────────────── */

.ch-velo {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 35;
    background: var(--ch-velo);
}

.ch-velo.es-visible {
    display: block;
}

/* ── Tab-bar móvil ───────────────────────────────────────── */

.ch-tabbar {
    display: none;
    position: fixed;
    inset: auto 0 0 0;
    z-index: 40;
    background: var(--ch-blanco);
    border-top: 1px solid var(--ch-gris);
    padding-bottom: env(safe-area-inset-bottom);
}

.ch-tabbar__item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: var(--ch-sp-2) 0;
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--ch-tinta-tenue);
}

.ch-tabbar__item:hover,
.ch-tabbar__item.es-actual {
    color: var(--ch-verde);
    text-decoration: none;
}

.ch-tabbar__icono {
    width: 1.25rem;
    height: 1.25rem;
}

/* ── Adaptación ──────────────────────────────────────────── */

@media (max-width: 1024px) {
    .ch-grilla-2 {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 768px) {
    .ch-barra {
        transform: translateX(-100%);
        transition: transform var(--ch-transicion);
        box-shadow: var(--ch-sombra-lg);
    }

    .ch-barra.es-abierta {
        transform: translateX(0);
    }

    .ch-columna {
        margin-left: 0;
    }

    .ch-topbar__abrir {
        display: inline-flex;
    }

    .ch-main {
        padding: var(--ch-sp-4);
        padding-bottom: calc(64px + env(safe-area-inset-bottom) + var(--ch-sp-4));
    }

    .ch-tabbar {
        display: flex;
    }

    .ch-usuario__nombre,
    .ch-plan-pill__texto {
        display: none;
    }
}

/* === css/cannis_health/vistas/login.css === */
/* =============================================================
   LOGIN — acceso al portal Cannis Health

   Pantalla partida: relato de marca a la izquierda, formulario a la
   derecha. En móvil el relato se esconde y el formulario queda como
   tarjeta centrada.

   El panel de marca se arma por capas para que la foto sea OPCIONAL:
     fondo del panel  → degradé de marca (siempre está)
     ::before         → la foto, sólo con .es-con-foto
     ::after          → velo verde que le devuelve contraste al texto
   Si no hay foto, el degradé queda solo y la pantalla se ve terminada
   igual. La ruta la resuelve AccesoController y llega por la custom
   property --ch-acceso-foto.
   ============================================================= */

.ch-acceso {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(460px, 620px);
    min-height: 100vh;
}

/* ── Panel de marca ──────────────────────────────────────── */

.ch-acceso__marca {
    position: relative;
    isolation: isolate;
    overflow: hidden;

    /* Tres bandas: logo arriba, relato al medio, firma abajo. Antes era un
       flex centrado y el logo flotaba a media altura, sin anclar la
       composición a ningún borde. */
    display: grid;
    grid-template-rows: auto 1fr auto;
    gap: var(--ch-sp-6);
    padding: clamp(var(--ch-sp-6), 5vw, var(--ch-sp-7)) clamp(var(--ch-sp-6), 7vw, 5.5rem);
    color: var(--ch-tinta-invertida);
    background:
        radial-gradient(120% 90% at 12% 12%, var(--ch-acceso-halo-menta) 0%, transparent 58%),
        radial-gradient(110% 90% at 92% 88%, var(--ch-acceso-halo-aqua) 0%, transparent 60%),
        var(--ch-verde-hondo);
}

.ch-acceso__marca > * {
    position: relative;
    z-index: 1;
}

/* Capa fotográfica. Sin .es-con-foto no hay imagen y no hay pedido al
   servidor: el degradé de arriba es el fondo definitivo.

   `luminosity` la deja como textura tonal dentro del verde de marca en vez
   de meter su propia paleta —el collage trae amarillos y turquesas que se
   pelean con el logo—. Pero luminosity copia la LUMINANCIA de la foto, y una
   foto clara sube la del panel entero: el blanco encima deja de leerse. Por
   eso el brillo se recorta ANTES de mezclar. Tapar la foto con más velo
   también funcionaría, pero entonces no se vería la foto: oscurecerla la
   deja visible de punta a punta y el texto igual se lee. */
.ch-acceso__marca::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -2;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    /* El brillo es un token para poder tocarlo sin bucear el archivo, pero
       NO se sube a ojo: subirlo baja el contraste del texto sobre la foto.
       Medido contra una imagen casi blanca —el peor caso posible— 0.5 deja
       todo por encima de WCAG; a 0.55 los ítems de la lista ya caen abajo de
       4.5:1 y a 0.62 caen cuatro zonas. Si lo tocás, verificá el contraste
       real antes de subirlo. */
    filter: brightness(var(--ch-acceso-foto-brillo)) contrast(1.12);
    opacity: 0.88;
    mix-blend-mode: luminosity;
}

.ch-acceso__marca.es-con-foto::before {
    background-image: var(--ch-acceso-foto);
}

/* Velo: segunda red de seguridad. Más denso sobre la columna de texto —la
   mitad izquierda— y casi transparente a la derecha, que es donde la foto
   puede lucirse sin nada encima. */
.ch-acceso__marca::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        linear-gradient(100deg,
            var(--ch-acceso-velo-fuerte) 0%,
            var(--ch-acceso-velo-fuerte) 32%,
            var(--ch-acceso-velo-medio) 58%,
            var(--ch-acceso-velo-leve) 100%),
        linear-gradient(to top, var(--ch-acceso-velo-pie) 0%, transparent 42%);
}

.ch-acceso__logo {
    /* align-self: sin esto la grilla lo estira y el logo queda centrado. */
    align-self: start;
    justify-self: start;
    height: 46px;
    width: auto;
    /* El logotipo es azul noche sobre transparente: sobre el panel oscuro
       desaparecía. Se pasa a blanco por filtro para no mantener dos
       archivos que después quedan desincronizados. */
    filter: brightness(0) invert(1);
    opacity: 0.96;
}

.ch-acceso__relato {
    align-self: center;
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-5);
    max-width: 30rem;
}

.ch-acceso__claim {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: var(--ch-sp-2);
    margin: 0;
    padding: 0.3rem 0.75rem;
    border: 1px solid var(--ch-sobre-oscuro-borde);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-sobre-oscuro-vidrio);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.ch-acceso__titular {
    margin: 0;
    font-size: clamp(2rem, 1.2rem + 2.6vw, 3rem);
    line-height: 1.08;
    letter-spacing: -0.03em;
    max-width: 15ch;
}

.ch-acceso__titular em {
    font-style: normal;
    color: var(--ch-menta-clara);
}

.ch-acceso__lista {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-4);
    max-width: 42ch;
    font-size: var(--ch-tipo-body);
}

.ch-acceso__lista li {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-3);
    color: var(--ch-sobre-oscuro);
}

.ch-acceso__tilde {
    flex-shrink: 0;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0.3rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-sobre-oscuro-chip);
    color: var(--ch-menta-clara);
}

.ch-acceso__pie {
    align-self: end;
    margin: 0;
    padding-top: var(--ch-sp-4);
    border-top: 1px solid var(--ch-sobre-oscuro-linea);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-sobre-oscuro-tenue);
}

/* ── Panel del formulario ────────────────────────────────── */

/* Campo claro y el formulario como tarjeta, también en escritorio: sobre
   blanco liso el bloque quedaba flotando en medio de un vacío enorme y no
   se leía como "la pieza" de la pantalla. Con la tarjeta tiene borde,
   apoyo y peso frente al panel de marca. */
.ch-acceso__panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--ch-sp-7) clamp(var(--ch-sp-5), 4vw, var(--ch-sp-6));
    background: var(--ch-off-white);
}

.ch-acceso__caja {
    width: 100%;
    max-width: 27rem;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-5);
    padding: clamp(var(--ch-sp-5), 3vw, var(--ch-sp-6));
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-md);
}

.ch-acceso__logo-movil {
    display: none;
    height: 44px;
    width: auto;
    margin: 0 auto var(--ch-sp-2);
}

.ch-acceso__titulo {
    margin: 0;
    font-size: 1.625rem;
    letter-spacing: -0.025em;
}

.ch-acceso__bajada {
    margin: var(--ch-sp-1) 0 0;
    font-size: var(--ch-tipo-body);
    color: var(--ch-tinta-tenue);
}

/* El link de recuperar contraseña estaba en tamaño de etiqueta (0.69rem):
   es una acción, no un rótulo. */
.ch-acceso__olvido {
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
}

.ch-acceso__label-fila {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ch-sp-2);
}

.ch-acceso__separador {
    margin: 0;
    padding-top: var(--ch-sp-5);
    border-top: 1px solid var(--ch-gris);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
    text-align: center;
}

/* ── Tablet: el relato se comprime antes de desaparecer ──── */

@media (max-width: 1180px) {
    .ch-acceso {
        grid-template-columns: minmax(0, 1fr) minmax(380px, 440px);
    }

    .ch-acceso__lista {
        gap: var(--ch-sp-3);
        font-size: var(--ch-tipo-body-sm);
    }
}

@media (max-width: 900px) {
    .ch-acceso {
        grid-template-columns: minmax(0, 1fr);
    }

    .ch-acceso__marca {
        display: none;
    }

    .ch-acceso__panel {
        padding: var(--ch-sp-6) var(--ch-sp-4);
    }

    .ch-acceso__logo-movil {
        display: block;
    }

    .ch-acceso__titulo {
        font-size: 1.5rem;
        text-align: center;
    }

    .ch-acceso__bajada {
        text-align: center;
    }
}

/* === css/cannis_health/vistas/consultorio.css === */
/* =============================================================
   CONSULTORIO — tablero de entrada del profesional
   ============================================================= */

/* ── Encabezado del profesional ──────────────────────────── */

.ch-saludo {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-5);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-lg);
    background:
        linear-gradient(120deg, var(--ch-verde-suave) 0%, transparent 62%),
        var(--ch-blanco);
    box-shadow: var(--ch-sombra-sm);
}

.ch-saludo__fecha {
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-saludo__nombre {
    margin: var(--ch-sp-1) 0 var(--ch-sp-3);
    font-size: var(--ch-tipo-pagina);
}

.ch-saludo__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
}

.ch-saludo__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
}

/* ── Accesos rápidos ─────────────────────────────────────── */

.ch-accesos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: var(--ch-sp-3);
}

.ch-acceso-rapido {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-md);
    background: var(--ch-blanco);
    color: var(--ch-tinta);
    transition: border-color var(--ch-transicion), transform var(--ch-transicion), box-shadow var(--ch-transicion);
}

a.ch-acceso-rapido:hover {
    border-color: var(--ch-verde);
    transform: translateY(-2px);
    box-shadow: var(--ch-sombra-md);
    text-decoration: none;
}

.ch-acceso-rapido--bloqueado {
    opacity: 0.55;
    cursor: not-allowed;
}

.ch-acceso-rapido__icono {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: var(--ch-radio-sm);
    background: var(--ch-verde-suave);
    color: var(--ch-verde-hondo);
}

.ch-acceso-rapido__icono svg {
    width: 1.2rem;
    height: 1.2rem;
}

.ch-acceso-rapido__texto strong {
    display: block;
    font-size: var(--ch-tipo-body);
}

.ch-acceso-rapido__texto small {
    display: block;
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-suave);
}

.ch-acceso-rapido__flecha {
    width: 1rem;
    height: 1rem;
    margin-left: auto;
    flex-shrink: 0;
    color: var(--ch-tinta-tenue);
}

/* ── Gráfico de actividad ────────────────────────────────── */

.ch-actividad {
    display: flex;
    align-items: flex-end;
    gap: var(--ch-sp-2);
    height: 180px;
    padding-top: var(--ch-sp-4);
    /* En el teléfono doce meses no entran, y encoger las columnas hasta que
       la etiqueta se corte pierde el dato. Scrollea, como las tablas. */
    overflow-x: auto;
    overflow-y: hidden;
}

.ch-actividad__mes {
    /* La base mínima es la que hace aparecer el scroll: sin ella el mes se
       achica por debajo de su etiqueta y desborda la tarjeta. */
    flex: 1 0 2.6rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ch-sp-2);
    height: 100%;
    min-width: 0;
}

.ch-actividad__barras {
    flex: 1;
    display: flex;
    align-items: flex-end;
    gap: 3px;
    width: 100%;
    justify-content: center;
}

.ch-actividad__barra {
    width: 40%;
    max-width: 14px;
    min-height: 3px;
    border-radius: 3px 3px 0 0;
    background: var(--ch-verde);
}

.ch-actividad__barra--recetas {
    background: var(--ch-aqua);
}

.ch-actividad__etiqueta {
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--ch-tinta-tenue);
    text-transform: capitalize;
}

.ch-leyenda {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-4);
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-suave);
}

.ch-leyenda__item {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
}

.ch-leyenda__muestra {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 3px;
    background: var(--ch-verde);
}

.ch-leyenda__muestra--recetas {
    background: var(--ch-aqua);
}

/* ── Turno del día ───────────────────────────────────────── */

.ch-turno-hora {
    font-weight: 700;
    white-space: nowrap;
}

.ch-turno-hora small {
    display: block;
    font-weight: 500;
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
}

/* === css/cannis_health/vistas/turnos.css === */
/* =============================================================
   TURNOS — agenda diaria del profesional
   Grilla horaria, no listado: la hora manda y los huecos libres
   se ven tanto como los ocupados.
   ============================================================= */

/* ── Barra de control ────────────────────────────────────── */

.ch-controles {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: var(--ch-sp-4);
}

.ch-control {
    padding: var(--ch-sp-4) var(--ch-sp-5);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

.ch-control__titulo {
    font-size: var(--ch-tipo-body-sm);
    font-weight: 700;
}

.ch-control__ayuda {
    margin: 2px 0 var(--ch-sp-3);
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
}

.ch-control__fila {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ch-sp-2);
}

.ch-control__fila .ch-input,
.ch-control__fila .ch-select {
    flex: 1 1 150px;
    min-width: 0;
}

/* Navegación día anterior / siguiente */
.ch-paso {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
    background: var(--ch-blanco);
    color: var(--ch-tinta-suave);
    font-size: 1rem;
    line-height: 1;
}

.ch-paso:hover {
    border-color: var(--ch-verde);
    color: var(--ch-verde-hondo);
    text-decoration: none;
}

/* ── Chips de días de la semana ──────────────────────────── */

.ch-semana {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: var(--ch-sp-1);
    margin-top: var(--ch-sp-3);
}

.ch-dia {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    padding: var(--ch-sp-2) 0;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
    background: var(--ch-blanco);
    color: var(--ch-tinta-suave);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    line-height: 1.1;
    text-align: center;
}

.ch-dia:hover {
    border-color: var(--ch-verde);
    color: var(--ch-verde-hondo);
    text-decoration: none;
}

/* Día con turnos cargados: fondo verde suave, como en la referencia. */
.ch-dia.tiene-turnos {
    background: var(--ch-verde-suave);
    border-color: transparent;
    color: var(--ch-verde-hondo);
}

.ch-dia.es-actual {
    background: var(--ch-verde);
    border-color: var(--ch-verde);
    color: var(--ch-sobre-marca);
}

.ch-dia.es-hoy:not(.es-actual) {
    border-color: var(--ch-verde);
    border-width: 2px;
}

.ch-dia.es-finde:not(.tiene-turnos):not(.es-actual) {
    background: var(--ch-off-white);
    color: var(--ch-tinta-tenue);
}

.ch-dia__numero {
    font-size: var(--ch-tipo-body);
    font-weight: 700;
}

.ch-dia__cuenta {
    font-size: 0.6rem;
    font-weight: 600;
    opacity: 0.8;
}

/* ── Cabecera del día ────────────────────────────────────── */

.ch-dia-cabecera {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris);
}

.ch-dia-cabecera__fecha {
    font-size: var(--ch-tipo-seccion);
}

.ch-dia-cabecera__resumen {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
}

/* ── La jornada: los turnos del día ──────────────────────
   Cada turno es una fila con peso propio. Son pocos y son lo
   que el profesional vino a ver: se leen como una lista de
   personas, no como una grilla horaria.
   ──────────────────────────────────────────────────────── */

.ch-jornada {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ch-turno {
    display: grid;
    grid-template-columns: 78px minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris);
}

.ch-turno:last-child {
    border-bottom: 0;
}

.ch-turno:hover {
    background: var(--ch-verde-tinte);
}

/* Un turno que ya pasó sigue siendo el registro del día, pero no
   compite con lo que viene. */
.ch-turno.es-pasado {
    opacity: 0.55;
}

.ch-turno.es-pasado:hover {
    opacity: 1;
}

/* Agendado fuera de las franjas actuales: se marca, no se esconde. */
.ch-turno.es-fuera {
    box-shadow: inset 3px 0 0 0 var(--ch-alerta);
}

.ch-turno__hora {
    display: flex;
    flex-direction: column;
}

.ch-turno__inicio {
    font-size: 1.125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}

.ch-turno__fin {
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
}

.ch-turno__paciente {
    min-width: 0;
}

.ch-turno__nombre {
    display: block;
    font-size: var(--ch-tipo-dato);
    font-weight: 650;
    line-height: 1.3;
}

.ch-turno__detalle {
    display: block;
    margin-top: 1px;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-turno__nota {
    display: inline-block;
    margin-top: var(--ch-sp-1);
    font-size: var(--ch-tipo-overline);
    font-weight: 600;
    color: var(--ch-alerta);
}

.ch-turno__acciones {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-3);
    justify-content: flex-end;
}

/* ── Horarios libres ─────────────────────────────────────
   Pastillas, no renglones: son un dato de apoyo para llenar
   el día. Veinte huecos en renglones tapaban el único turno.
   ──────────────────────────────────────────────────────── */

.ch-libres {
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-top: 1px solid var(--ch-gris);
    background: var(--ch-off-white);
}

.ch-libres__cabecera {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ch-sp-2);
    margin-bottom: var(--ch-sp-3);
}

.ch-libres__titulo {
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-libres__titulo small {
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
}

.ch-libres__cuenta {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-libres__lista {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
}

.ch-libres__lista.es-pasada {
    margin-top: var(--ch-sp-3);
}

.ch-libres__vacio {
    font-size: var(--ch-tipo-body-sm);
    font-style: italic;
    color: var(--ch-tinta-tenue);
}

.ch-libres__toggle {
    margin-top: var(--ch-sp-3);
    padding: 0;
    border: 0;
    background: none;
    font-family: inherit;
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    color: var(--ch-verde-hondo);
    cursor: pointer;
    text-decoration: underline;
}

/* Un hueco: se toca y lleva a agendar en ese horario. */
.ch-hueco {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-blanco);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--ch-tinta-suave);
}

a.ch-hueco:hover {
    border-color: var(--ch-verde);
    background: var(--ch-verde-suave);
    color: var(--ch-verde-hondo);
    text-decoration: none;
}

.ch-hueco.es-pasado {
    background: transparent;
    border-style: dashed;
    color: var(--ch-tinta-fantasma);
}

/* Selector de estado embebido en la fila: cambia con un submit. */
.ch-estado-form {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-1);
}

.ch-estado-select {
    padding: 0.2rem 1.4rem 0.2rem 0.5rem;
    border: 1px solid transparent;
    border-radius: var(--ch-radio-pill);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    line-height: 1.5;
    cursor: pointer;
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: right 0.6rem center, right 0.4rem center;
    background-size: 4px 4px, 4px 4px;
    background-repeat: no-repeat;
}

.ch-estado-select.es-reservado  { background-color: var(--ch-info-suave);   color: var(--ch-info); }
.ch-estado-select.es-confirmado { background-color: var(--ch-ok-suave);     color: var(--ch-ok); }
.ch-estado-select.es-finalizado { background-color: var(--ch-verde-suave);  color: var(--ch-verde-hondo); }
.ch-estado-select.es-cancelado  { background-color: var(--ch-riesgo-suave); color: var(--ch-riesgo); }
.ch-estado-select.es-reprogramado { background-color: var(--ch-alerta-suave); color: var(--ch-alerta); }

/* Marca del recordatorio que ya mandó el CRON. */
.ch-recordatorio {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--ch-tinta-tenue);
    white-space: nowrap;
}

.ch-recordatorio__punto {
    width: 0.4rem;
    height: 0.4rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-gris);
}

.ch-recordatorio__punto.es-enviado {
    background: var(--ch-ok);
}

/* ── Pestañas de la sección ──────────────────────────────
   Subrayado y no caja. La versión anterior era una píldora dentro de una
   caja con borde: dos contornos para separar tres palabras, y el activo se
   distinguía por un fondo blanco sobre otro casi blanco. Acá la línea de
   base une las pestañas, el indicador dice cuál está abierta y el peso
   tipográfico hace el resto. Sirve igual para los <a> de Turnos y para los
   <button role="tab"> de la ficha y del trámite.
   ────────────────────────────────────────────────────────── */

.ch-pestanas {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-5);
    margin-bottom: var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris-suave);
}

.ch-pestana {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
    padding: 0.55rem 0.15rem;
    /* Las pestañas de la ficha y del trámite son <button>: sin este reset el
       navegador les dibuja su borde de botón en los cuatro lados, que es de
       dónde salía el aire de formulario viejo. El indicador ocupa lugar desde
       el vamos: si naciera con el estado activo, el texto saltaría dos
       píxeles al cambiar de pestaña. */
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    background: none;
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    color: var(--ch-tinta-suave);
    cursor: pointer;
    transition: color var(--ch-transicion), border-color var(--ch-transicion);
}

.ch-pestana:hover {
    color: var(--ch-tinta);
    text-decoration: none;
    border-bottom-color: var(--ch-gris);
}

.ch-pestana.es-actual {
    color: var(--ch-verde-hondo);
    border-bottom-color: var(--ch-verde);
}

.ch-pestana:focus-visible {
    outline: 2px solid var(--ch-verde);
    outline-offset: 3px;
    border-radius: var(--ch-radio-sm);
}

/* El contador rojo es una alerta: lo usa "Por resolver". Cuando sólo cuenta
   cosas —tratamientos, versiones— va la variante neutra (es-neutra). */
.ch-pestana__cuenta {
    min-width: 1.15rem;
    padding: 0 0.35rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-riesgo);
    color: var(--ch-sobre-riesgo);
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 1.15rem;
    text-align: center;
}

/* ── Adaptación ──────────────────────────────────────────── */

@media (max-width: 900px) {
    .ch-controles {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 640px) {
    /* En el teléfono el turno se apila: hora y estado arriba, paciente
       debajo y las acciones al final. */
    .ch-turno {
        grid-template-columns: 68px minmax(0, 1fr);
        align-items: start;
        row-gap: var(--ch-sp-2);
        column-gap: var(--ch-sp-3);
        padding: var(--ch-sp-4);
    }

    .ch-turno__hora     { grid-column: 1; grid-row: 1; }
    .ch-turno__paciente { grid-column: 2; grid-row: 1; }
    .ch-turno__estado   { grid-column: 2; grid-row: 2; }
    .ch-turno__acciones { grid-column: 2; grid-row: 3; justify-content: flex-start; }

    .ch-dia__cuenta {
        display: none;
    }
}

/* ── Tipos de turno ───────────────────────────────────────────
   Las tarjetas de "¿Qué tipo de turno vas a gestionar?". Se perdieron al
   reescribir la sección de la agenda de este archivo y la pantalla quedó
   como texto plano: si tocás rangos acá, revisá que las clases de
   turnos/nuevo.blade.php sigan teniendo definición. */

.ch-tipos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--ch-sp-4);
}

.ch-tipo {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-2);
    padding: var(--ch-sp-5);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
    color: inherit;
}

a.ch-tipo:hover {
    border-color: var(--ch-verde);
    box-shadow: var(--ch-sombra-md);
    text-decoration: none;
}

.ch-tipo.es-bloqueado {
    opacity: 0.75;
    background: var(--ch-off-white);
}

.ch-tipo__icono {
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--ch-radio-sm);
    background: var(--ch-verde-suave);
    color: var(--ch-verde-hondo);
}

.ch-tipo__icono svg {
    width: 1.25rem;
    height: 1.25rem;
}

.ch-tipo.es-bloqueado .ch-tipo__icono {
    background: var(--ch-gris);
    color: var(--ch-tinta-tenue);
}

.ch-tipo__titulo {
    font-size: var(--ch-tipo-seccion);
}

.ch-tipo__bajada {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
    line-height: 1.5;
}

.ch-tipo__accion {
    margin-top: auto;
    padding-top: var(--ch-sp-3);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 700;
    color: var(--ch-verde-hondo);
}

.ch-tipo__bloqueo {
    margin-top: auto;
    padding-top: var(--ch-sp-3);
    font-size: var(--ch-tipo-overline);
    font-weight: 600;
    color: var(--ch-alerta);
}

/* ── Celda de turno en las bandejas ──────────────────────── */

.ch-turno-celda {
    display: inline-flex;
    flex-direction: column;
    gap: 3px;
    align-items: flex-start;
}

.ch-turno-celda__fecha {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ch-turno-celda.es-vencido .ch-turno-celda__fecha {
    color: var(--ch-riesgo);
}

.ch-turno-celda__relativo {
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
}

/* Express: el paciente pagó y no eligió horario. Tiene que gritar. */
.ch-badge--express {
    background: var(--ch-alerta-suave);
    color: var(--ch-alerta);
    font-weight: 700;
    letter-spacing: 0.04em;
}

/* ── Contexto del turno ───────────────────────────────────────
   Los datos del turno —cuándo, de qué tipo, en qué estado y con qué motivo
   se agendó— arriba de la consulta. Antes el motivo era un banner ancho que
   competía con lo clínico; acá es un dato más de la misma tira. */
.ch-turno-contexto {
    display: grid;
    /* Cuatro columnas fijas y la fecha ocupa dos: con columnas iguales,
       'Mar. 08/09/2026 · 10:00 hs' se partía en dos renglones. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

.ch-turno-contexto__dato {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.ch-turno-contexto__dato--ancho {
    grid-column: 1 / -1;
}

.ch-turno-contexto__dato--fecha {
    grid-column: span 2;
}

@media (max-width: 900px) {
    .ch-turno-contexto {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 560px) {
    .ch-turno-contexto {
        grid-template-columns: minmax(0, 1fr);
    }

    .ch-turno-contexto__dato--fecha {
        grid-column: 1 / -1;
    }
}

/* ── Turnos ya cerrados ───────────────────────────────────────
   Registro del día, plegado. Es una franja más de la tarjeta de la jornada,
   igual que los horarios libres: sin el padding propio el botón quedaba
   colgando contra el borde izquierdo, fuera de todo. */
.ch-cerrados {
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-top: 1px solid var(--ch-gris);
}

/* El toggle abre la franja: sin turnos arriba es lo único que hay, así que
   no necesita el margen que lo separa de una lista. */
.ch-cerrados .ch-libres__toggle {
    margin-top: 0;
}

.ch-jornada.es-cerrada {
    margin-top: var(--ch-sp-3);
    opacity: 0.85;
}

/* ── Pagaron y no eligieron horario ───────────────────────────
   No tienen turno del que colgar en la bandeja y son las que hay que
   empujar: van arriba, en su propio bloque. */
.ch-sin-agendar {
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris);
    background: var(--ch-alerta-suave);
}

/* El express no es una alerta: no hay a quién apurar, es trabajo propio.
   Va en el tinte informativo para que se lea distinto del bloque de arriba. */
.ch-sin-agendar.es-express {
    background: var(--ch-info-suave);
}

.ch-sin-agendar__lista {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--ch-sp-2) var(--ch-sp-4);
    padding: 0;
    margin: 0;
    list-style: none;
}

/* === css/cannis_health/vistas/finanzas.css === */
/* ── Finanzas ─────────────────────────────────────────────────
   La billetera y las operaciones del profesional.
   ──────────────────────────────────────────────────────────── */

/* La billetera NO es una card más: es la cifra que el profesional busca
   apenas entra. Lleva el fondo de marca para separarse del resto de la
   pantalla sin gritar. */
.ch-billetera {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-4) var(--ch-sp-5);
    padding: var(--ch-sp-5);
    border: 1px solid var(--ch-verde-anillo);
    border-radius: var(--ch-radio-lg);
    background: var(--ch-verde-suave);
}

.ch-billetera__principal {
    min-width: 0;
}

.ch-billetera__etiqueta {
    display: block;
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ch-verde-hondo);
}

/* El monto es el dato: todo lo demás en la tarjeta lo acompaña. */
.ch-billetera__monto {
    margin: var(--ch-sp-1) 0 0;
    font-size: clamp(1.75rem, 4vw, 2.4rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: var(--ch-tinta);
    font-variant-numeric: tabular-nums;
}

.ch-billetera__periodo {
    margin: var(--ch-sp-2) 0 0;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-billetera__cifras {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-5);
}

.ch-billetera__cifra {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ch-billetera__cifra-etiqueta {
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-billetera__cifra-valor {
    font-size: var(--ch-tipo-dato);
    font-weight: 600;
    color: var(--ch-tinta);
    font-variant-numeric: tabular-nums;
}

/* En el teléfono la fila se apila y el botón queda al ancho completo. */
@media (max-width: 640px) {
    .ch-billetera {
        flex-direction: column;
        align-items: stretch;
    }

    .ch-billetera__cifras {
        gap: var(--ch-sp-4);
    }
}

/* ── El detalle ───────────────────────────────────────────── */

/* Los importes alineados a la derecha y con cifras de ancho fijo: así una
   columna de montos se compara de un vistazo. */
.ch-monto__celda {
    text-align: right;
}

.ch-monto {
    font-size: var(--ch-tipo-dato);
    font-weight: 650;
    color: var(--ch-tinta);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Apilada, el importe vuelve a la izquierda como el resto de los datos. */
.ch-tabla--apilable td.ch-monto__celda {
    text-align: left;
}

/* === css/cannis_health/vistas/seguimientos.css === */
/* =============================================================
   SEGUIMIENTOS — escalas del cuestionario
   El número solo no dice nada: manda el concepto, y el color
   lo pone el tono() del enum, no el valor.
   ============================================================= */

.ch-escalas {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--ch-sp-3);
}

.ch-escala {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 2px var(--ch-sp-3);
    padding: var(--ch-sp-3) var(--ch-sp-4);
    border: 1px solid var(--ch-gris);
    border-left-width: 3px;
    border-radius: var(--ch-radio-sm);
    background: var(--ch-blanco);
}

.ch-escala__etiqueta {
    grid-column: 1 / -1;
    font-size: var(--ch-tipo-overline);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-escala__valor {
    grid-column: 1;
    font-size: var(--ch-tipo-body);
    font-weight: 700;
}

.ch-escala__valor.es-vacio {
    grid-column: 1 / -1;
    font-weight: 500;
    font-style: italic;
    color: var(--ch-tinta-tenue);
}

.ch-escala__cifra {
    grid-column: 2;
    grid-row: 2;
    font-size: var(--ch-tipo-body-sm);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ch-tinta-suave);
}

.ch-escala__cifra small {
    font-size: 0.7em;
    font-weight: 500;
    opacity: 0.7;
}

.ch-escala__pista {
    grid-column: 1 / -1;
    height: 4px;
    margin-top: var(--ch-sp-2);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-off-white);
    overflow: hidden;
}

.ch-escala__relleno {
    display: block;
    height: 100%;
    border-radius: var(--ch-radio-pill);
    background: currentColor;
}

/* El borde izquierdo y el relleno toman el tono; el texto queda legible. */
.ch-escala.es-ok      { border-left-color: var(--ch-ok);     color: var(--ch-ok); }
.ch-escala.es-info    { border-left-color: var(--ch-info);   color: var(--ch-info); }
.ch-escala.es-alerta  { border-left-color: var(--ch-alerta); color: var(--ch-alerta); }
.ch-escala.es-riesgo  { border-left-color: var(--ch-riesgo); color: var(--ch-riesgo); }
.ch-escala.es-vacio   { border-left-color: var(--ch-gris);   color: var(--ch-tinta-tenue); }

.ch-escala__etiqueta,
.ch-escala__cifra {
    color: var(--ch-tinta-tenue);
}

.ch-escala__valor {
    color: var(--ch-tinta);
}

/* Pastillas compactas para la tabla del listado. */
.ch-escala-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-1);
}

.ch-escala-chip {
    display: inline-flex;
    align-items: baseline;
    gap: var(--ch-sp-1);
    padding: 0.15rem 0.5rem;
    border-radius: var(--ch-radio-pill);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    white-space: nowrap;
}

.ch-escala-chip small {
    font-weight: 500;
    opacity: 0.75;
}

.ch-escala-chip.es-ok     { background: var(--ch-ok-suave);     color: var(--ch-ok); }
.ch-escala-chip.es-info   { background: var(--ch-info-suave);   color: var(--ch-info); }
.ch-escala-chip.es-alerta { background: var(--ch-alerta-suave); color: var(--ch-alerta); }
.ch-escala-chip.es-riesgo { background: var(--ch-riesgo-suave); color: var(--ch-riesgo); }

/* ── La conversación de WhatsApp ──────────────────────────────
   Se lee como un chat, no como una tabla: es lo que el paciente
   escribió y el profesional lo está leyendo para decidir algo
   clínico. El paciente a la izquierda, Cannis a la derecha, como
   en cualquier app de mensajería — con la diferencia de que acá
   el "propio" es Cannis, no quien mira.
   ──────────────────────────────────────────────────────────── */

.ch-charla {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-2);
}

/* Separador de día: una línea con la fecha al medio. */
.ch-charla__dia {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-3);
    margin: var(--ch-sp-3) 0 var(--ch-sp-1);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-charla__dia::before,
.ch-charla__dia::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--ch-gris-suave);
}

.ch-charla__dia:first-child {
    margin-top: 0;
}

.ch-charla__mensaje {
    max-width: min(34rem, 82%);
    padding: var(--ch-sp-3);
    border-radius: var(--ch-radio-md);
    background: var(--ch-off-white);
}

/* Los dos lados se distinguen por relleno vs. contorno, no sólo por color:
   en oscuro el verde suave y el off-white quedan casi a la misma claridad y
   las burbujas se confundían entre sí. */
.ch-charla__mensaje.es-paciente {
    align-self: flex-start;
    /* La esquina que "apunta" al autor queda recta. */
    border-bottom-left-radius: var(--ch-radio-sm);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
}

.ch-charla__mensaje.es-cannis {
    align-self: flex-end;
    border-bottom-right-radius: var(--ch-radio-sm);
    background: var(--ch-verde-suave);
    border: 1px solid transparent;
}

.ch-charla__autor {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-2);
    margin: 0 0 var(--ch-sp-1);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-charla__mensaje.es-cannis .ch-charla__autor {
    color: var(--ch-verde-hondo);
}

/* Los OUT por plantilla se guardan como [template:HX…]: conviene que se
   vea que el texto salió de una plantilla y no lo escribió una persona. */
.ch-charla__marca {
    padding: 0.05rem 0.35rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-gris-suave);
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ch-tinta-suave);
}

.ch-charla__texto {
    margin: 0;
    font-size: var(--ch-tipo-body-sm);
    line-height: 1.45;
    color: var(--ch-tinta);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.ch-charla__hora {
    margin: var(--ch-sp-1) 0 0;
    font-size: 0.7rem;
    color: var(--ch-tinta-tenue);
    text-align: right;
}

/* Estado vacío dentro de una card: el de afuera respira demasiado. */
.ch-vacio--chico {
    padding: var(--ch-sp-4) var(--ch-sp-3);
    font-size: var(--ch-tipo-body-sm);
}


/* ── Envío manual ─────────────────────────────────────────────
   Elegir un paciente y mandarle el cuestionario sin esperar a que le
   toque. El select y el botón en una línea, que baja en el teléfono.
   ──────────────────────────────────────────────────────────── */

.ch-envio-manual {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--ch-sp-3);
}

.ch-envio-manual .ch-campo {
    flex: 1 1 260px;
}

/* Los botones de la cabecera de una card: "enviar los que tocan" al lado
   de "ver todos". Sin esto el <form> del primero rompía la línea. */
.ch-card__acciones {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-2);
    flex-shrink: 0;
}

/* === css/cannis_health/vistas/reprocann.css === */
/* =============================================================
   REPROCANN — gestión del trámite
   Formulario largo agrupado en pestañas, con repetidores para
   los diagnósticos y las indicaciones médicas.
   ============================================================= */

/* ── Barra de estado + guardar ───────────────────────────── */

.ch-barra-guardar {
    display: grid;
    /* 300 px: 'Pendiente de revisión médica' es la opción más larga y a
       240 quedaba cortada con puntos suspensivos. */
    grid-template-columns: minmax(240px, 300px) minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    margin-bottom: var(--ch-sp-4);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

.ch-barra-guardar__ayuda {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
    line-height: 1.5;
}

/* ── Repetidores ─────────────────────────────────────────── */

.ch-repetidor__cabecera {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    margin-bottom: var(--ch-sp-3);
}

.ch-repetidor__vacio {
    padding: var(--ch-sp-4);
    border: 1px dashed var(--ch-gris);
    border-radius: var(--ch-radio-sm);
    font-size: var(--ch-tipo-body-sm);
    font-style: italic;
    color: var(--ch-tinta-tenue);
    text-align: center;
}

.ch-repetidor__item {
    padding: var(--ch-sp-4);
    margin-bottom: var(--ch-sp-3);
    background: var(--ch-off-white);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
}

.ch-repetidor__item-cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    margin-bottom: var(--ch-sp-3);
}

.ch-repetidor__item-titulo {
    font-size: var(--ch-tipo-body-sm);
    font-weight: 700;
}

/* Tope de caracteres al lado de la etiqueta del campo. */
.ch-campo__tope {
    margin-left: var(--ch-sp-2);
    font-size: var(--ch-tipo-overline);
    font-weight: 500;
    color: var(--ch-tinta-tenue);
}

/* ── Adaptación ──────────────────────────────────────────── */

@media (max-width: 860px) {
    .ch-barra-guardar {
        grid-template-columns: minmax(0, 1fr);
    }

    .ch-barra-guardar__ayuda {
        order: 3;
    }
}

/* ── Cannis AI ───────────────────────────────────────────
   Se distingue del resto del trámite: lo que hay adentro
   genera texto que después el profesional firma.
   ──────────────────────────────────────────────────────── */

.ch-ai {
    margin-bottom: var(--ch-sp-4);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-verde);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
    overflow: hidden;
}

.ch-ai__cabecera {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    background: var(--ch-verde-tinte);
}

.ch-ai__titulo {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-2);
    font-size: var(--ch-tipo-seccion);
    color: var(--ch-verde-hondo);
}

.ch-ai__icono {
    width: 1.15rem;
    height: 1.15rem;
}

.ch-ai__bajada {
    margin-top: 2px;
    max-width: 62ch;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
    line-height: 1.5;
}

.ch-ai__cuerpo {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-5);
    padding: var(--ch-sp-5);
    border-top: 1px solid var(--ch-gris);
}

.ch-ai__bloque {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4);
    background: var(--ch-off-white);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
}

.ch-ai__subtitulo {
    font-size: var(--ch-tipo-body);
    font-weight: 700;
}

.ch-ai__ayuda {
    margin-top: 2px;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
    line-height: 1.5;
}

.ch-ai__fila {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--ch-sp-3);
}

.ch-ai__fila .ch-campo {
    flex: 1 1 260px;
    min-width: 0;
}

/* Título de cada paso del asistente: generar, y las plantillas. */
.ch-ai__seccion {
    font-size: var(--ch-tipo-seccion);
    font-weight: 700;
}

.ch-ai__atajos {
    display: flex;
    gap: var(--ch-sp-1);
}

.ch-ai__secciones {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: var(--ch-sp-2) var(--ch-sp-4);
    margin-top: var(--ch-sp-2);
}

/* La lista de diagnósticos puede ser larga: scrollea en su caja en vez de
   empujar el botón de generar fuera de la pantalla. */
.ch-ai__diagnosticos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--ch-sp-2) var(--ch-sp-4);
    max-height: 15rem;
    overflow-y: auto;
    margin-top: var(--ch-sp-2);
    padding: var(--ch-sp-3);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-sm);
}

.ch-ai__acciones {
    display: flex;
    justify-content: flex-end;
}

/* === css/cannis_health/vistas/pacientes.css === */
/* =============================================================
   PACIENTES — la ficha
   Se lee como una historia clínica: quién es, qué toma, cómo
   viene. La carga de datos va al final, en su pestaña.
   ============================================================= */

/* ── Las dos tarjetas de estado ──────────────────────────── */

.ch-estado-paciente {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: var(--ch-sp-4);
    /* Cada tarjeta mide lo que dice. Estiradas a la más alta, la del
       tratamiento queda con medio panel en blanco. */
    align-items: start;
}

.ch-tarjeta-estado {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-5);
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-left: 3px solid var(--ch-verde);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

.ch-tarjeta-estado.es-vacia {
    border-left-color: var(--ch-gris);
    background: var(--ch-off-white);
}

.ch-tarjeta-estado__etiqueta {
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-tarjeta-estado__vacio {
    font-size: var(--ch-tipo-body);
    color: var(--ch-tinta-tenue);
}

.ch-tarjeta-estado__pie {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-tarjeta-estado__alerta {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-2);
    width: 100%;
    padding: var(--ch-sp-3);
    border-radius: var(--ch-radio-sm);
    background: var(--ch-riesgo-suave);
    color: var(--ch-riesgo);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    line-height: 1.45;
}

.ch-tarjeta-estado__alerta-icono {
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    margin-top: 1px;
}

/* El esquema vigente: la dosis es lo que se lee de un vistazo. */
.ch-esquema {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-3);
    width: 100%;
}

.ch-esquema__dosis {
    display: block;
    font-size: 1.0625rem;
    font-weight: 650;
    line-height: 1.3;
}

.ch-esquema__via {
    display: block;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-esquema__obs {
    display: block;
    margin-top: 2px;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

/* Cómo viene: una línea por escala respondida, con su tono. */
.ch-evolucion {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-2);
    width: 100%;
}

.ch-evolucion__item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    padding-bottom: var(--ch-sp-2);
    border-bottom: 1px solid var(--ch-gris);
}

.ch-evolucion__item:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.ch-evolucion__que {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-evolucion__valor {
    font-size: var(--ch-tipo-body);
    font-weight: 700;
    text-align: right;
}

.ch-evolucion__item.es-ok     .ch-evolucion__valor { color: var(--ch-ok); }
.ch-evolucion__item.es-info   .ch-evolucion__valor { color: var(--ch-info); }
.ch-evolucion__item.es-alerta .ch-evolucion__valor { color: var(--ch-alerta); }
.ch-evolucion__item.es-riesgo .ch-evolucion__valor { color: var(--ch-riesgo); }

/* ── Historia clínica ────────────────────────────────────── */

.ch-clinica {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--ch-sp-5);
}

.ch-clinica__bloque p {
    margin-top: var(--ch-sp-1);
    white-space: pre-line;
}

.ch-clinica__vacio {
    font-size: var(--ch-tipo-body);
    color: var(--ch-tinta-tenue);
}

/* ── Historial de tratamientos ───────────────────────────── */

.ch-alta-tratamiento {
    border-bottom: 1px solid var(--ch-gris);
    background: var(--ch-off-white);
}

.ch-versiones {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ch-version {
    display: grid;
    grid-template-columns: 130px minmax(0, 1fr) auto;
    align-items: start;
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    border-bottom: 1px solid var(--ch-gris);
}

.ch-version:last-child {
    border-bottom: 0;
}

/* La vigente se distingue sin necesidad de leer la fecha. */
.ch-version.es-vigente {
    background: var(--ch-verde-tinte);
    box-shadow: inset 3px 0 0 0 var(--ch-verde);
}

.ch-version__fecha {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ch-sp-1);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.ch-version__indicacion + .ch-version__indicacion {
    margin-top: var(--ch-sp-3);
    padding-top: var(--ch-sp-3);
    border-top: 1px dashed var(--ch-gris);
}

.ch-version__dosis {
    display: block;
    font-weight: 600;
}

.ch-version__via,
.ch-version__obs {
    display: block;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

/* Un botón que se ve como enlace, para las llamadas dentro de un texto. */
.ch-enlace {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: var(--ch-verde-hondo);
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
}

/* Contador neutro en una pestaña, cuando no es una alerta. */
.ch-pestana__cuenta.es-neutra {
    background: var(--ch-gris);
    color: var(--ch-tinta-suave);
}

/* ── Adaptación ──────────────────────────────────────────── */

@media (max-width: 720px) {
    .ch-version {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--ch-sp-2);
        padding: var(--ch-sp-4);
    }

    .ch-version__fecha {
        flex-direction: row;
        align-items: center;
    }
}

/* ── Listado de pacientes en el teléfono ──────────────────────
   La tarjeta apilable de componentes.css ordena las celdas una debajo de
   otra. Acá se acomoda la del paciente: el estado de REPROCANN sube al
   renglón del nombre, que es donde el profesional lo busca al escanear. */
@media (max-width: 720px) {
    .ch-tabla--fichas tbody tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: start;
        column-gap: var(--ch-sp-3);
    }

    .ch-tabla--fichas tbody td {
        grid-column: 1 / -1;
    }

    .ch-tabla--fichas tbody td:first-child {
        grid-column: 1;
        grid-row: 1;
    }

    /* Repite el contexto para ganarle a la regla que estira las celdas. */
    .ch-tabla--fichas tbody td.ch-fila__marca {
        grid-column: 2;
        grid-row: 1;
        justify-self: end;
    }
}

/* === css/cannis_health/vistas/plan.css === */
/* =============================================================
   MI PLAN — estado de la suscripción y comparativa de planes
   ============================================================= */

.ch-plan-actual {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--ch-sp-5);
    padding: var(--ch-sp-5);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-lg);
    background:
        linear-gradient(120deg, var(--ch-verde-suave) 0%, transparent 60%),
        var(--ch-blanco);
    box-shadow: var(--ch-sombra-sm);
}

.ch-plan-actual__nombre {
    margin: var(--ch-sp-1) 0 var(--ch-sp-2);
    font-size: var(--ch-tipo-pagina);
    color: var(--ch-verde-hondo);
}

.ch-plan-actual__descripcion {
    max-width: 52ch;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-plan-actual__estado {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
    margin-top: var(--ch-sp-3);
}

.ch-plan-actual__cupos {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-3);
}

.ch-plan-actual__cupos .ch-resumen__item {
    min-width: 190px;
}

/* ── Comparativa ─────────────────────────────────────────── */

.ch-planes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: var(--ch-sp-4);
}

.ch-plan-opcion {
    padding: var(--ch-sp-5);
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-md);
    background: var(--ch-off-white);
}

.ch-plan-opcion.es-actual {
    border-color: var(--ch-verde);
    background: var(--ch-blanco);
    box-shadow: 0 0 0 3px var(--ch-verde-tinte);
}

.ch-plan-opcion__cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-2);
    font-size: var(--ch-tipo-seccion);
}

.ch-plan-opcion__precio {
    margin: var(--ch-sp-2) 0 var(--ch-sp-4);
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--ch-verde-hondo);
}

.ch-plan-opcion__precio small {
    font-size: var(--ch-tipo-body-sm);
    font-weight: 500;
    color: var(--ch-tinta-tenue);
}

.ch-plan-opcion__beneficios {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-2);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-plan-opcion__beneficios li {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-2);
}

.ch-plan-opcion__tilde {
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    margin-top: 0.15rem;
    color: var(--ch-verde);
}

.ch-plan-opcion__vacio {
    font-style: italic;
    color: var(--ch-tinta-tenue);
}

.ch-plan-soporte {
    margin-top: var(--ch-sp-5);
    padding-top: var(--ch-sp-4);
    border-top: 1px solid var(--ch-gris);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

/* === css/cannis_health/vistas/agentes.css === */
/* =============================================================
   AGENTES — Cannis AI

   Dos piezas: el núcleo (el panel oscuro que muestra el sistema
   encendido) y las tarjetas de agente. El movimiento es de adorno,
   así que no hace falta apagarlo a mano: base.css ya lo frena con
   prefers-reduced-motion.
   ============================================================= */

/* ── El núcleo ───────────────────────────────────────────── */

.ch-nucleo {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    min-height: 15rem;
    padding: var(--ch-sp-6) clamp(var(--ch-sp-5), 4vw, var(--ch-sp-7));
    border-radius: var(--ch-radio-lg);
    color: var(--ch-tinta-invertida);
    background:
        radial-gradient(90% 120% at 8% 10%, var(--ch-nucleo-halo) 0%, transparent 55%),
        radial-gradient(80% 110% at 95% 90%, var(--ch-nucleo-halo-b) 0%, transparent 58%),
        var(--ch-nucleo-fondo);
    box-shadow: var(--ch-sombra-md);
}

.ch-nucleo__cuerpo {
    position: relative;
    z-index: 1;
    max-width: 34rem;
}

.ch-nucleo__marca {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
    margin: 0 0 var(--ch-sp-3);
    padding: 0.3rem 0.75rem;
    border: 1px solid var(--ch-sobre-oscuro-borde);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-sobre-oscuro-vidrio);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.ch-nucleo__chispa {
    width: 0.95rem;
    height: 0.95rem;
    color: var(--ch-menta-clara);
}

.ch-nucleo__titular {
    margin: 0;
    font-size: clamp(1.4rem, 1rem + 1.6vw, 2rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.02em;
}

.ch-nucleo__bajada {
    margin: var(--ch-sp-2) 0 0;
    max-width: 42ch;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-sobre-oscuro-tenue);
}

/* Dos renglones que se comparten: los valores arriba, las etiquetas abajo.
   Con flex en columna cada cifra alineaba por su cuenta y el nombre del plan
   —que es texto y no número— quedaba flotando más arriba que los dos
   números. La grilla de dos filas hace que las tres compartan la línea base
   del valor Y la de la etiqueta; `display: contents` en cada cifra deja que
   sus dos partes caigan directo en la grilla. */
.ch-nucleo__cifras {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    grid-template-rows: auto auto;
    align-items: baseline;
    gap: 2px var(--ch-sp-6);
    margin-top: var(--ch-sp-5);
    padding-top: var(--ch-sp-4);
    border-top: 1px solid var(--ch-sobre-oscuro-linea);
}

.ch-nucleo__cifra {
    display: contents;
}

.ch-nucleo__valor {
    font-size: var(--ch-tipo-cifra);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--ch-menta-clara);
}

/* El nombre del plan no es una cifra: no puede ir al tamaño de una. Comparte
   la línea base con los números (ver .ch-nucleo__cifras). */
.ch-nucleo__valor--texto {
    font-size: 1.25rem;
    color: var(--ch-tinta-invertida);
}

.ch-nucleo__etiqueta {
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ch-sobre-oscuro-tenue);
}

/* ── La malla: órbitas + barrido ──────────────────────────── */

.ch-nucleo__malla {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

.ch-nucleo__anillo {
    position: absolute;
    top: 50%;
    right: clamp(-6rem, -4vw, 2rem);
    width: 17rem;
    height: 17rem;
    margin-top: -8.5rem;
    border: 1px solid var(--ch-nucleo-anillo);
    border-radius: 50%;
    animation: ch-nucleo-latido 6s ease-in-out infinite;
}

.ch-nucleo__anillo--dos {
    width: 24rem;
    height: 24rem;
    margin-top: -12rem;
    animation-delay: 1.2s;
    opacity: 0.7;
}

.ch-nucleo__anillo--tres {
    width: 31rem;
    height: 31rem;
    margin-top: -15.5rem;
    animation-delay: 2.4s;
    opacity: 0.45;
}

@keyframes ch-nucleo-latido {
    0%, 100% { transform: scale(1);    opacity: 0.85; }
    50%      { transform: scale(1.06); opacity: 0.35; }
}

/* Barrido: una banda de luz que cruza el panel cada tanto. Es lo que
   hace que el bloque se lea como "encendido" y no como una foto. */
.ch-nucleo__barrido {
    position: absolute;
    inset: 0 auto 0 -40%;
    width: 40%;
    background: linear-gradient(100deg, transparent 0%, var(--ch-nucleo-barrido) 50%, transparent 100%);
    animation: ch-nucleo-barrido 7s ease-in-out infinite;
}

@keyframes ch-nucleo-barrido {
    0%        { transform: translateX(0); }
    60%, 100% { transform: translateX(360%); }
}

/* ── Las tarjetas ────────────────────────────────────────── */

.ch-agentes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
    gap: var(--ch-sp-5);
}

.ch-agente {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--ch-blanco);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    box-shadow: var(--ch-sombra-sm);
}

/* La cinta de arriba: verde y en movimiento si el agente corre, gris
   y quieta si el plan no lo habilita. Es el estado leído de lejos. */
.ch-agente::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: var(--ch-gris);
}

.ch-agente.es-activo::before {
    background: linear-gradient(90deg,
        var(--ch-verde) 0%, var(--ch-menta) 35%, var(--ch-aqua) 65%, var(--ch-verde) 100%);
    background-size: 250% 100%;
    animation: ch-agente-cinta 5s linear infinite;
}

@keyframes ch-agente-cinta {
    from { background-position: 0 0; }
    to   { background-position: 250% 0; }
}

.ch-agente__cabecera {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-5);
    padding-top: calc(var(--ch-sp-5) + 3px);
}

.ch-agente__capsula {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--ch-radio-md);
    background: var(--ch-off-white);
    color: var(--ch-tinta-tenue);
}

.ch-agente.es-activo .ch-agente__capsula {
    background: var(--ch-verde-suave);
    color: var(--ch-verde);
    box-shadow: 0 0 0 4px var(--ch-verde-tinte);
}

.ch-agente__icono {
    width: 1.5rem;
    height: 1.5rem;
}

.ch-agente__identidad {
    min-width: 0;
    flex: 1;
}

.ch-agente__nombre {
    margin: 0;
    font-size: var(--ch-tipo-seccion);
    letter-spacing: -0.01em;
}

.ch-agente__titular {
    margin: var(--ch-sp-1) 0 0;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
}

.ch-agente__estado {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
    padding: 0.25rem 0.65rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-ok-suave);
    color: var(--ch-ok);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.ch-agente__estado.es-bloqueado {
    background: var(--ch-off-white);
    color: var(--ch-tinta-tenue);
}

/* El punto que late: el agente está corriendo ahora. */
.ch-agente__pulso {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--ch-radio-pill);
    background: var(--ch-ok);
    animation: ch-agente-pulso 2.2s ease-in-out infinite;
}

@keyframes ch-agente-pulso {
    0%, 100% { box-shadow: 0 0 0 0 var(--ch-verde-anillo); }
    50%      { box-shadow: 0 0 0 5px transparent; }
}

.ch-agente__cuerpo {
    flex: 1;
    padding: 0 var(--ch-sp-5) var(--ch-sp-5);
}

.ch-agente__descripcion {
    margin: 0;
    font-size: var(--ch-tipo-body-sm);
    line-height: 1.6;
    color: var(--ch-tinta-suave);
}

.ch-agente__capacidades {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-2);
    margin-top: var(--ch-sp-4);
    padding-top: var(--ch-sp-4);
    border-top: 1px solid var(--ch-gris-suave);
}

.ch-agente__capacidades li {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-3);
    font-size: var(--ch-tipo-body-sm);
}

.ch-agente__tilde {
    flex-shrink: 0;
    width: 1.05rem;
    height: 1.05rem;
    margin-top: 0.2rem;
    color: var(--ch-verde);
}

.ch-agente:not(.es-activo) .ch-agente__tilde {
    color: var(--ch-tinta-fantasma);
}

.ch-agente__pie {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4) var(--ch-sp-5);
    background: var(--ch-off-white);
    border-top: 1px solid var(--ch-gris-suave);
}

.ch-agente__senal {
    display: flex;
    align-items: baseline;
    gap: var(--ch-sp-2);
    margin: 0;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-agente__senal-valor {
    font-size: var(--ch-tipo-dato);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ch-tinta);
}

.ch-agente__senal--bloqueada {
    font-style: normal;
}

.ch-agentes__nota {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-3);
    margin: 0;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-agentes__nota-icono {
    flex-shrink: 0;
    width: 1.1rem;
    height: 1.1rem;
    margin-top: 0.15rem;
}

/* ── Teléfono ────────────────────────────────────────────── */

@media (max-width: 720px) {
    .ch-nucleo {
        min-height: 0;
    }

    /* Las órbitas se salen de un panel angosto y sólo ensucian. */
    .ch-nucleo__malla {
        display: none;
    }

    .ch-nucleo__cifras {
        gap: var(--ch-sp-5);
    }

    .ch-agente__cabecera {
        flex-wrap: wrap;
    }

    .ch-agente__pie {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* === css/cannis_health/vistas/programa.css === */
/* ── Lo programado por un agente ───────────────────────────────
   La agenda de un agente de Cannis AI: los tres escalones de un
   recordatorio y el estado de cada uno. La pieza nueva es .ch-escalon; el
   resto de la pantalla son card, tabla y vacío del sistema.

   El estado se lee por la marca y por el texto, nunca sólo por el color:
   "Enviado" y "Sin envío" tienen que distinguirse también en gris.
   ────────────────────────────────────────────────────────────── */

.ch-escalones {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ch-escalon {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
    white-space: nowrap;
}

.ch-escalon__marca {
    flex: none;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    border: 1.5px solid var(--ch-gris);
    background: transparent;
}

.ch-escalon__texto {
    font-weight: 600;
    color: var(--ch-tinta);
}

.ch-escalon__estado {
    font-size: 0.78rem;
    color: var(--ch-tinta-tenue);
}

/* Ya salió: es el único estado que se da por hecho. */
.ch-escalon.es-enviado .ch-escalon__marca {
    border-color: var(--ch-ok);
    background: var(--ch-ok);
}

.ch-escalon.es-enviado .ch-escalon__estado {
    color: var(--ch-ok);
    font-weight: 600;
}

/* Falta, y tiene fecha. */
.ch-escalon.es-programado .ch-escalon__marca {
    border-color: var(--ch-verde);
}

/* Entró en ventana: sale con la próxima corrida del cron. */
.ch-escalon.es-inminente .ch-escalon__marca {
    border-color: var(--ch-verde);
    background: var(--ch-verde);
    animation: ch-escalon-latido 1.8s ease-in-out infinite;
}

.ch-escalon.es-inminente .ch-escalon__estado {
    color: var(--ch-verde-hondo);
    font-weight: 600;
}

/* El turno se agendó con menos anticipación que el escalón: la ventana ya
   había pasado y el comando lo marca sin enviar. */
.ch-escalon.es-perdido .ch-escalon__texto,
.ch-escalon.es-suspendido .ch-escalon__texto {
    color: var(--ch-tinta-tenue);
    font-weight: 500;
}

.ch-escalon.es-perdido .ch-escalon__marca,
.ch-escalon.es-suspendido .ch-escalon__marca {
    border-style: dashed;
}

@keyframes ch-escalon-latido {
    0%, 100% { box-shadow: 0 0 0 0 var(--ch-verde-anillo); }
    50%      { box-shadow: 0 0 0 5px transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .ch-escalon.es-inminente .ch-escalon__marca {
        animation: none;
    }
}

/* ── Adelanto de los próximos envíos ───────────────────────────
   Va en la bandeja de Seguimientos, arriba de los filtros: lo que la
   tabla no puede mostrar porque todavía no existe como fila. */

.ch-proximos {
    margin-bottom: var(--ch-sp-5);
}

.ch-proximos__lista {
    display: flex;
    flex-wrap: wrap;
    /* Cada pastilla ahora lleva su botón de enviar adentro: con el gap de
       antes las de dos filas se tocaban entre sí. */
    gap: var(--ch-sp-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ch-proximos__item {
    display: inline-flex;
    /* center y no baseline: el botón de adentro es más alto que el texto y
       con baseline quedaba desalineado. */
    align-items: center;
    gap: var(--ch-sp-2);
    padding: 0.35rem 0.4rem 0.35rem 0.85rem;
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-off-white);
}

.ch-proximos__paciente {
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    color: var(--ch-tinta);
}

/* El que ya entró en ventana se distingue por la pastilla: el rótulo de la
   fecha tiene que decir siempre qué es ese dato, no el estado. */
.ch-proximos__item.es-listo {
    border-color: transparent;
    background: var(--ch-alerta-suave);
}

.ch-proximos__cuando {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
    font-size: 0.78rem;
    color: var(--ch-tinta-tenue);
}

.ch-proximos__rotulo {
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.ch-proximos__item.es-listo .ch-proximos__cuando {
    color: var(--ch-alerta);
}

/* === css/cannis_health/vistas/ai-progreso.css === */
/* =============================================================
   PROGRESO DE CANNIS AI

   La pantalla que ocupa todo mientras la IA redacta el trámite. El
   POST es sincrónico, así que esto vive lo que dura la espera y
   muere con la navegación.

   El movimiento es adorno: base.css ya lo frena con
   prefers-reduced-motion, así que no hace falta apagarlo acá.
   ============================================================= */

/* El fondo no scrollea mientras la pantalla está puesta. */
.ch-sin-scroll {
    overflow: hidden;
}

.ch-aip {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: grid;
    place-items: center;
    padding: var(--ch-sp-5);
    overflow: hidden;
    isolation: isolate;
    color: var(--ch-tinta-invertida);
    background:
        radial-gradient(90% 90% at 50% 40%, var(--ch-nucleo-halo) 0%, transparent 60%),
        var(--ch-nucleo-fondo);
    animation: ch-aip-entrar 320ms ease both;
}

@keyframes ch-aip-entrar {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ── El fondo: órbitas alrededor de un núcleo que late ───── */

.ch-aip__fondo {
    position: absolute;
    inset: 0;
    z-index: -1;
    display: grid;
    place-items: center;
    pointer-events: none;
}

.ch-aip__nucleo {
    width: 5rem;
    height: 5rem;
    border-radius: 50%;
    background: radial-gradient(circle, var(--ch-menta-clara) 0%, transparent 70%);
    opacity: 0.5;
    animation: ch-aip-latido 2.6s ease-in-out infinite;
}

.ch-aip__orbita {
    position: absolute;
    width: 20rem;
    height: 20rem;
    border: 1px solid var(--ch-nucleo-anillo);
    border-radius: 50%;
    animation: ch-aip-orbita 9s linear infinite;
}

.ch-aip__orbita--dos {
    width: 32rem;
    height: 32rem;
    animation-duration: 14s;
    animation-direction: reverse;
    opacity: 0.7;
}

.ch-aip__orbita--tres {
    width: 46rem;
    height: 46rem;
    animation-duration: 20s;
    opacity: 0.4;
}

/* Las órbitas no son círculos perfectos: el borde superior más marcado
   hace que se note que giran. */
.ch-aip__orbita {
    border-top-color: var(--ch-menta-clara);
}

@keyframes ch-aip-orbita {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

@keyframes ch-aip-latido {
    0%, 100% { transform: scale(1);    opacity: 0.5; }
    50%      { transform: scale(1.25); opacity: 0.8; }
}

/* ── El panel ────────────────────────────────────────────── */

.ch-aip__panel {
    width: 100%;
    max-width: 34rem;
    padding: clamp(var(--ch-sp-5), 4vw, var(--ch-sp-6));
    border: 1px solid var(--ch-sobre-oscuro-borde);
    border-radius: var(--ch-radio-lg);
    background: var(--ch-sobre-oscuro-vidrio);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: var(--ch-sombra-lg);
}

.ch-aip__marca {
    display: inline-flex;
    align-items: center;
    gap: var(--ch-sp-2);
    margin: 0 0 var(--ch-sp-3);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ch-sobre-oscuro-tenue);
}

.ch-aip__chispa {
    width: 0.95rem;
    height: 0.95rem;
    color: var(--ch-menta-clara);
}

.ch-aip__titulo {
    margin: 0;
    font-size: clamp(1.25rem, 1rem + 1vw, 1.6rem);
    line-height: 1.2;
    letter-spacing: -0.02em;
}

.ch-aip__bajada {
    margin: var(--ch-sp-2) 0 0;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-sobre-oscuro-tenue);
}

/* ── Los pasos ───────────────────────────────────────────── */

.ch-aip__pasos {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-3);
    margin: var(--ch-sp-5) 0 0;
    padding: 0;
}

.ch-aip__paso {
    display: flex;
    align-items: center;
    gap: var(--ch-sp-3);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-sobre-oscuro-tenue);
    opacity: 0.45;
    transition: opacity var(--ch-transicion), color var(--ch-transicion);
}

.ch-aip__paso.es-curso,
.ch-aip__paso.es-hecho {
    opacity: 1;
}

.ch-aip__paso.es-curso {
    color: var(--ch-tinta-invertida);
    font-weight: 600;
}

.ch-aip__estado {
    position: relative;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 1.4rem;
    height: 1.4rem;
    border: 1px solid var(--ch-sobre-oscuro-borde);
    border-radius: 50%;
}

/* Pendiente: el círculo vacío. El tilde sólo aparece al completarse. */
.ch-aip__tilde {
    width: 0.8rem;
    height: 0.8rem;
    color: var(--ch-nucleo-fondo);
    opacity: 0;
    transform: scale(0.4);
    transition: opacity var(--ch-transicion), transform var(--ch-transicion);
}

.ch-aip__paso.es-hecho .ch-aip__estado {
    background: var(--ch-menta-clara);
    border-color: var(--ch-menta-clara);
}

.ch-aip__paso.es-hecho .ch-aip__tilde {
    opacity: 1;
    transform: scale(1);
}

/* En curso: el anillo gira. Es la señal de que ESE paso es el que está
   pasando ahora, y no se completa hasta que el servidor conteste. */
.ch-aip__paso.es-curso .ch-aip__estado {
    border-color: var(--ch-sobre-oscuro-borde);
    border-top-color: var(--ch-menta-clara);
    animation: ch-aip-girar 900ms linear infinite;
}

@keyframes ch-aip-girar {
    to { transform: rotate(360deg); }
}

/* ── La barra ────────────────────────────────────────────── */

.ch-aip__barra {
    height: 4px;
    margin-top: var(--ch-sp-5);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-sobre-oscuro-vidrio);
    overflow: hidden;
}

.ch-aip__barra-relleno {
    display: block;
    width: 0;
    height: 100%;
    border-radius: var(--ch-radio-pill);
    background: linear-gradient(90deg, var(--ch-menta) 0%, var(--ch-menta-clara) 100%);
    transition: width 1.4s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.ch-aip__pie {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-2);
    margin: var(--ch-sp-4) 0 0;
    font-size: var(--ch-tipo-overline);
    color: var(--ch-sobre-oscuro-tenue);
}

.ch-aip__pie-icono {
    flex-shrink: 0;
    width: 0.95rem;
    height: 0.95rem;
    margin-top: 0.1rem;
}

@media (max-width: 720px) {
    /* En el teléfono las órbitas grandes se salen y sólo cargan la pantalla. */
    .ch-aip__orbita--tres {
        display: none;
    }
}

/* === css/cannis_health/vistas/asistente.css === */
/* ── El asistente del consultorio ──────────────────────────────
   La burbuja flotante y su panel. La burbuja tiene que leerse como
   inteligencia trabajando —dos anillos que respiran y un degradé que
   gira— sin volverse un cartel: está en todas las pantallas del portal.

   Todo el movimiento se apaga con prefers-reduced-motion.
   ────────────────────────────────────────────────────────────── */

.ch-ia {
    position: fixed;
    right: var(--ch-sp-5);
    bottom: var(--ch-sp-5);
    z-index: 60;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--ch-sp-3);
}

/* ── La burbuja ───────────────────────────────────────────── */

.ch-ia__burbuja {
    position: relative;
    display: grid;
    place-items: center;
    width: 3.5rem;
    height: 3.5rem;
    border: 0;
    border-radius: var(--ch-radio-pill);
    background: linear-gradient(135deg, var(--ch-verde-hondo), var(--ch-verde) 45%, var(--ch-aqua));
    background-size: 200% 200%;
    box-shadow: var(--ch-sombra-md);
    color: var(--ch-tinta-invertida);
    cursor: pointer;
    animation: ch-ia-flote 5s ease-in-out infinite, ch-ia-degrade 9s ease infinite;
    transition: transform var(--ch-transicion-suave), box-shadow var(--ch-transicion);
}

.ch-ia__burbuja:hover {
    transform: scale(1.06);
    box-shadow: var(--ch-sombra-lg);
}

.ch-ia__sigla {
    position: relative;
    font-size: 0.95rem;
    font-weight: 800;
    letter-spacing: 0.06em;
}

/* Dos anillos que salen de la burbuja: el pulso de algo encendido. */
.ch-ia__anillo {
    position: absolute;
    inset: 0;
    border-radius: var(--ch-radio-pill);
    border: 1px solid var(--ch-verde);
    opacity: 0;
    animation: ch-ia-pulso 3.2s ease-out infinite;
}

.ch-ia__anillo--dos {
    animation-delay: 1.6s;
}

@keyframes ch-ia-flote {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-6px); }
}

@keyframes ch-ia-degrade {
    0%, 100% { background-position: 0% 50%; }
    50%      { background-position: 100% 50%; }
}

@keyframes ch-ia-pulso {
    0%   { opacity: 0.55; transform: scale(1); }
    70%  { opacity: 0;    transform: scale(1.65); }
    100% { opacity: 0;    transform: scale(1.65); }
}

/* ── El panel ─────────────────────────────────────────────── */

.ch-ia__panel {
    display: flex;
    flex-direction: column;
    width: min(380px, calc(100vw - var(--ch-sp-5) * 2));
    /* Descuenta la burbuja, su separación y los márgenes: sin esto el panel
       crece más que la ventana y el pie queda fuera de pantalla. */
    max-height: min(560px, calc(100vh - 3.5rem - var(--ch-sp-3) - var(--ch-sp-5) * 2));
    overflow: hidden;
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-lg);
    background: var(--ch-blanco);
    box-shadow: var(--ch-sombra-lg);
    animation: ch-ia-entrada var(--ch-transicion-suave) both;
}

@keyframes ch-ia-entrada {
    from { opacity: 0; transform: translateY(10px) scale(0.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

.ch-ia__cabecera {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--ch-sp-3);
    padding: var(--ch-sp-4);
    border-bottom: 1px solid var(--ch-gris-suave);
    background: var(--ch-off-white);
}

.ch-ia__identidad {
    display: flex;
    align-items: flex-start;
    gap: var(--ch-sp-3);
    /* Con tres botones a la derecha, el título se partía en dos renglones:
       que se recorte antes de envolver. */
    min-width: 0;
}

.ch-ia__identidad > div {
    min-width: 0;
}

.ch-ia__chispa {
    width: 1.25rem;
    height: 1.25rem;
    flex-shrink: 0;
    margin-top: 2px;
    color: var(--ch-verde);
}

.ch-ia__titulo {
    margin: 0;
    font-size: var(--ch-tipo-dato);
    font-weight: 650;
    color: var(--ch-tinta);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ch-ia__bajada {
    margin: 2px 0 0;
    font-size: 0.78rem;
    color: var(--ch-tinta-tenue);
}

.ch-ia__acciones {
    display: flex;
    gap: var(--ch-sp-1);
    flex-shrink: 0;
}

.ch-ia__icono {
    display: grid;
    place-items: center;
    width: 1.7rem;
    height: 1.7rem;
    border: 0;
    border-radius: var(--ch-radio-sm);
    background: none;
    color: var(--ch-tinta-tenue);
    cursor: pointer;
}

.ch-ia__icono:hover {
    background: var(--ch-verde-tinte);
    color: var(--ch-verde-hondo);
}

/* ── El hilo ──────────────────────────────────────────────── */

.ch-ia__hilo {
    flex: 1 1 auto;
    /* Sin min-height:0 un item flex no baja de su contenido: el hilo crecía
       hasta pasarse del panel en vez de scrollear, y los últimos mensajes
       quedaban cortados. */
    min-height: 0;
    overflow-y: auto;
    padding: var(--ch-sp-4);
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-3);
}

.ch-ia__bienvenida {
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-tenue);
}

.ch-ia__ejemplos {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ch-sp-2);
    margin-top: var(--ch-sp-3);
}

.ch-ia__ejemplo {
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--ch-gris);
    border-radius: var(--ch-radio-pill);
    background: var(--ch-blanco);
    font-size: 0.78rem;
    color: var(--ch-tinta-suave);
    cursor: pointer;
}

.ch-ia__ejemplo:hover {
    border-color: var(--ch-verde);
    color: var(--ch-verde-hondo);
}

.ch-ia__mensaje {
    max-width: 88%;
    padding: var(--ch-sp-3);
    border-radius: var(--ch-radio-md);
    background: var(--ch-off-white);
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta);
}

/* El del profesional va a la derecha y con el color de marca. */
.ch-ia__mensaje.es-propio {
    align-self: flex-end;
    background: var(--ch-verde-suave);
    color: var(--ch-tinta);
}

.ch-ia__mensaje.es-pensando {
    color: var(--ch-tinta-tenue);
    font-style: italic;
}

.ch-ia__texto {
    margin: 0;
    overflow-wrap: anywhere;
}

/* Qué miró para responder: es lo que hace auditable la respuesta. */
.ch-ia__fuentes {
    margin: var(--ch-sp-2) 0 0;
    font-size: 0.72rem;
    color: var(--ch-tinta-tenue);
}

/* ── La acción propuesta ──────────────────────────────────── */

.ch-ia__propuesta {
    padding: var(--ch-sp-3) var(--ch-sp-4);
    border-top: 1px solid var(--ch-gris-suave);
    background: var(--ch-alerta-suave);
}

.ch-ia__propuesta-texto {
    margin: 0 0 var(--ch-sp-3);
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    color: var(--ch-tinta);
}

.ch-ia__propuesta-botones {
    display: flex;
    gap: var(--ch-sp-2);
}

/* ── El pie ───────────────────────────────────────────────── */

.ch-ia__pie {
    display: flex;
    gap: var(--ch-sp-2);
    padding: var(--ch-sp-3) var(--ch-sp-4) var(--ch-sp-4);
    border-top: 1px solid var(--ch-gris-suave);
}

.ch-ia__pie .ch-input {
    flex: 1 1 auto;
    min-width: 0;
}

.ch-ia__enviar {
    display: grid;
    place-items: center;
    width: var(--ch-alto-control);
    height: var(--ch-alto-control);
    flex-shrink: 0;
    border: 0;
    border-radius: var(--ch-radio-md);
    background: var(--ch-verde);
    color: var(--ch-sobre-marca);
    cursor: pointer;
}

.ch-ia__enviar:hover {
    background: var(--ch-verde-hondo);
}

/* ── Adaptación ───────────────────────────────────────────── */

@media (max-width: 720px) {
    /* La tab-bar del teléfono ocupa el borde inferior: la burbuja sube. */
    .ch-ia {
        right: var(--ch-sp-4);
        bottom: calc(var(--ch-alto-topbar) + var(--ch-sp-4));
    }

    .ch-ia__panel {
        max-height: min(68vh, 520px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .ch-ia__burbuja,
    .ch-ia__anillo,
    .ch-ia__panel {
        animation: none;
    }
}


/* ── Las conversaciones anteriores ────────────────────────────
   Ocupan el lugar del hilo, no van debajo: en 380 px de ancho dos
   listas apiladas dejan a las dos sin aire.
   ──────────────────────────────────────────────────────────── */

.ch-ia__lista {
    flex: 1;
    min-height: 0;          /* sin esto no scrollea: ver la trampa del hilo */
    overflow-y: auto;
    padding: var(--ch-sp-3);
}

.ch-ia__lista-titulo {
    margin: 0 0 var(--ch-sp-2);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ch-tinta-tenue);
}

.ch-ia__lista-vacia {
    margin: var(--ch-sp-4) 0 0;
    font-size: var(--ch-tipo-body-sm);
    color: var(--ch-tinta-suave);
    text-align: center;
}

.ch-ia__conversacion {
    display: flex;
    align-items: stretch;
    gap: var(--ch-sp-1);
    border-radius: var(--ch-radio-md);
}

.ch-ia__conversacion:hover {
    background: var(--ch-off-white);
}

.ch-ia__conversacion.es-activa {
    background: var(--ch-verde-suave);
}

.ch-ia__conversacion-abrir {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--ch-sp-2) var(--ch-sp-3);
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
}

.ch-ia__conversacion-titulo {
    font-size: var(--ch-tipo-body-sm);
    font-weight: 600;
    color: var(--ch-tinta);
    /* Un título largo se recorta acá, no estira el panel. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ch-ia__conversacion-cuando {
    font-size: 0.72rem;
    color: var(--ch-tinta-tenue);
}

.ch-ia__conversacion-borrar {
    flex: none;
    width: 2rem;
    border: 0;
    border-radius: var(--ch-radio-md);
    background: none;
    font-size: 1.1rem;
    line-height: 1;
    color: var(--ch-tinta-fantasma);
    cursor: pointer;
}

.ch-ia__conversacion-borrar:hover {
    color: var(--ch-riesgo);
}

/* === css/cannis_health/vistas/chat.css === */
/* =============================================================
   CANNIS HEALTH — Cannis AI › Chat
   El registro de lo hablado con el asistente. La burbuja tiene su
   propio panel (ch-ia__*); esto es la MISMA conversación leída como
   documento: ancho de lectura, sin scroll propio y sin caja flotante.
   ============================================================= */

.ch-charla {
    display: flex;
    flex-direction: column;
    gap: var(--ch-sp-4);
    padding: var(--ch-sp-5);
}

.ch-charla__mensaje {
    /* Un hilo se lee mejor angosto: a 900 px el ojo pierde el renglón. */
    max-width: 46rem;
    padding: var(--ch-sp-4);
    border: 1px solid var(--ch-gris-suave);
    border-radius: var(--ch-radio-md);
    background: var(--ch-off-white);
}

/* Lo que preguntó el profesional va del lado opuesto y con el tinte de
   marca: se distingue de un vistazo quién dijo qué sin leer el rótulo. */
.ch-charla__mensaje.es-propio {
    margin-left: auto;
    border-color: transparent;
    background: var(--ch-verde-suave);
}

.ch-charla__quien {
    display: flex;
    align-items: baseline;
    gap: var(--ch-sp-2);
    margin-bottom: var(--ch-sp-2);
    font-size: var(--ch-tipo-overline);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ch-tinta-suave);
}

.ch-charla__cuando {
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ch-tinta-tenue);
}

.ch-charla__texto {
    font-size: var(--ch-tipo-body);
    line-height: 1.55;
    color: var(--ch-tinta);
    /* Una respuesta puede traer un ID largo o una URL sin espacios. */
    overflow-wrap: anywhere;
    /* Antes de que health.js lo repinte, el texto llega crudo: sin esto los
       saltos de línea del modelo se pierden y queda un bloque ilegible. */
    white-space: pre-wrap;
}

/* Ya repintado, los saltos los ponen los bloques .ch-md__*. */
.ch-charla__texto.ch-md {
    white-space: normal;
}

.ch-charla__fuentes {
    margin-top: var(--ch-sp-3);
    padding-top: var(--ch-sp-2);
    border-top: 1px dashed var(--ch-gris);
    font-size: var(--ch-tipo-overline);
    color: var(--ch-tinta-tenue);
}

@media (max-width: 600px) {
    .ch-charla {
        padding: var(--ch-sp-4);
    }

    .ch-charla__mensaje {
        max-width: 100%;
    }
}

/* =============================================================
   CANNIS HEALTH — hoja de entrada del portal de profesionales
   Orden: tokens → base → componentes → chrome → vistas
   Se sirve cruda desde public/: no hay build, no hay Vite.
   ============================================================= */
