/* ==========================================================================
   Doctorísimo — sistema de la aplicación (web clínica + panel)
   ==========================================================================
   Se carga **después de Bootstrap** y hace dos cosas:

   1. Le cambia la paleta a Bootstrap (variables CSS + los pocos componentes donde Bootstrap tiene el
      color fijo). Con eso, las ~50 vistas que ya usan `btn-primary`, `badge bg-info`, `table-light`,
      `text-muted`… adoptan la paleta sin tocarlas una por una.
   2. Agrega los componentes del armazón (barra superior, menú lateral, encabezado de página, tarjetas
      de indicador, estado vacío).

   Los colores salen de `gineco.css` (`--ds-*`), que es el único archivo donde está la paleta.
   ========================================================================== */

/* ==========================================================================
   1. Bootstrap, recoloreado
   ========================================================================== */
:root {
    /* Tipografía y base */
    --bs-font-sans-serif: var(--ds-fuente);
    --bs-body-font-family: var(--ds-fuente);
    --bs-body-font-size: .9375rem;
    --bs-body-line-height: 1.5;
    --bs-body-color: var(--ds-texto);
    --bs-body-color-rgb: 32, 16, 72;
    --bs-body-bg: var(--ds-fondo);
    /* `--bs-heading-color` se deja **sin definir** a propósito (Bootstrap lo trae vacío): así el
       encabezado hereda del contenedor. Fijarlo acá pintaba de tinta los títulos que van sobre fondo
       oscuro —p. ej. el `h5` de un `card-header bg-primary text-white`, que quedaba en 2:1—, porque el
       `text-white` solo pinta al contenedor.
       En fondo claro igual queda la tinta, porque es el color de `body`. */
    --bs-secondary-color: var(--ds-texto-3);
    --bs-secondary-color-rgb: 107, 101, 128;
    --bs-emphasis-color: var(--ds-tinta);
    --bs-border-color: var(--ds-borde);
    --bs-border-color-translucent: rgba(32, 16, 72, .12);
    --bs-border-radius: var(--ds-radio);
    --bs-border-radius-sm: var(--ds-radio-sm);
    --bs-border-radius-lg: var(--ds-radio-card);

    /* Vínculos */
    --bs-link-color: var(--ds-violeta-700);
    --bs-link-color-rgb: 120, 48, 128;
    --bs-link-hover-color: var(--ds-violeta-800);
    --bs-link-hover-color-rgb: 96, 37, 106;

    /* Primario (violeta del logo) */
    --bs-primary: #783080;
    --bs-primary-rgb: 120, 48, 128;
    --bs-primary-text-emphasis: var(--ds-violeta-900);
    --bs-primary-bg-subtle: var(--ds-violeta-100);
    --bs-primary-border-subtle: var(--ds-violeta-200);

    /* Semánticos: el texto oscuro y el fondo claro, para que `text-*` y `bg-*-subtle` cumplan AA */
    --bs-success-rgb: 20, 101, 74;
    --bs-success-text-emphasis: #0f5c40;
    --bs-success-bg-subtle: var(--ds-exito-bg);
    --bs-success-border-subtle: var(--ds-exito-borde);

    --bs-danger-rgb: 179, 38, 30;
    --bs-danger-text-emphasis: #7d1a15;
    --bs-danger-bg-subtle: var(--ds-peligro-bg);
    --bs-danger-border-subtle: var(--ds-peligro-borde);

    --bs-warning-text-emphasis: var(--ds-aviso);
    --bs-warning-bg-subtle: var(--ds-aviso-bg);
    --bs-warning-border-subtle: var(--ds-aviso-borde);

    /* El celeste del latido es el acento de marca (decorativo) */
    --bs-info-rgb: 64, 176, 216;
    --bs-info-text-emphasis: var(--ds-info);
    --bs-info-bg-subtle: var(--ds-info-bg);
    --bs-info-border-subtle: var(--ds-info-borde);

    --bs-secondary-rgb: 107, 101, 128;
    --bs-dark-rgb: 32, 16, 72;
    --bs-light-rgb: 241, 239, 245;

    /* Bootstrap pinta los `code` de rosa (#d63384): 4,15:1 sobre el fondo de la app. */
    --bs-code-color: var(--ds-violeta-800);
}

body {
    background-color: var(--ds-fondo);
    color: var(--ds-texto);
    -webkit-font-smoothing: antialiased;
    /* Inter trae variantes de cifras y de letras: la "l" con cola y el cero con barra se leen sin duda
       en una cédula, una hora o un monto. */
    font-feature-settings: 'cv11', 'ss03';
}

/* Cifras de ancho fijo: las horas de la agenda y los montos se alinean en columna. */
.table td, .table th, .tnum { font-variant-numeric: tabular-nums; }

/* Quien pidió menos movimiento no ve transiciones ni animaciones. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Foco visible y consistente en todo el sitio (accesibilidad: nunca se apaga el contorno). */
:focus-visible {
    outline: 2px solid var(--ds-violeta-700);
    outline-offset: 2px;
}

/* Los encabezados **heredan** el color (Bootstrap los deja sin color propio a propósito): forzarles la
   tinta desde acá rompía los que van sobre fondo oscuro — el `text-white` de un `card-header bg-primary`
   solo pinta al contenedor, no al `h5` de adentro, y el título quedaba en 2:1. `body` ya define
   `--ds-texto`, que es el mismo color, así que heredar es exactamente lo que se busca. */

.text-muted { color: var(--ds-texto-3) !important; }
.text-info { color: var(--ds-info) !important; }
.text-warning { color: var(--ds-aviso) !important; }
.text-success { color: var(--ds-exito) !important; }
.text-danger { color: var(--ds-peligro) !important; }
.text-body-secondary { color: var(--ds-texto-2) !important; }

::selection { background: var(--ds-violeta-200); color: var(--ds-violeta-900); }

/* --- Botones --- */
/* 36 px de alto (32 px el `btn-sm`), la misma altura que un campo: en una barra de filtros quedan alineados. */
.btn {
    --bs-btn-font-weight: 500;
    --bs-btn-font-size: .875rem;
    --bs-btn-line-height: 1.25rem;
    --bs-btn-padding-y: .4375rem;
    --bs-btn-padding-x: 1rem;
    --bs-btn-border-radius: var(--ds-radio);
    transition: background-color var(--ds-dur-base) var(--ds-ease), border-color var(--ds-dur-base) var(--ds-ease),
                box-shadow var(--ds-dur-base) var(--ds-ease), transform var(--ds-dur-micro) var(--ds-ease);
}

.btn:active:not(:disabled):not(.disabled) { transform: translateY(1px); }

.btn-sm {
    --bs-btn-font-size: .8125rem;
    --bs-btn-line-height: 1rem;
    --bs-btn-padding-y: .4375rem;
    --bs-btn-padding-x: .75rem;
    --bs-btn-border-radius: var(--ds-radio);
}

.btn-lg {
    --bs-btn-font-size: 1rem;
    --bs-btn-padding-y: .625rem;
    --bs-btn-padding-x: 1.25rem;
    --bs-btn-border-radius: var(--ds-radio);
}

.btn-primary { box-shadow: var(--ds-sombra-1); }

.btn-primary {
    --bs-btn-bg: var(--ds-violeta-700);
    --bs-btn-border-color: var(--ds-violeta-700);
    --bs-btn-hover-bg: var(--ds-violeta-800);
    --bs-btn-hover-border-color: var(--ds-violeta-800);
    --bs-btn-active-bg: var(--ds-violeta-900);
    --bs-btn-active-border-color: var(--ds-violeta-900);
    --bs-btn-disabled-bg: var(--ds-violeta-300);
    --bs-btn-disabled-border-color: var(--ds-violeta-300);
    --bs-btn-focus-shadow-rgb: 120, 48, 128;
}

.btn-outline-primary {
    --bs-btn-color: var(--ds-violeta-700);
    --bs-btn-border-color: var(--ds-violeta-700);
    --bs-btn-hover-bg: var(--ds-violeta-700);
    --bs-btn-hover-border-color: var(--ds-violeta-700);
    --bs-btn-active-bg: var(--ds-violeta-800);
    --bs-btn-active-border-color: var(--ds-violeta-800);
    --bs-btn-disabled-color: var(--ds-violeta-300);
    --bs-btn-disabled-border-color: var(--ds-violeta-300);
    --bs-btn-focus-shadow-rgb: 120, 48, 128;
}

.btn-secondary {
    --bs-btn-bg: var(--ds-texto-3);
    --bs-btn-border-color: var(--ds-texto-3);
    --bs-btn-hover-bg: var(--ds-texto-2);
    --bs-btn-hover-border-color: var(--ds-texto-2);
    --bs-btn-active-bg: var(--ds-tinta);
    --bs-btn-active-border-color: var(--ds-tinta);
}

.btn-outline-secondary {
    --bs-btn-color: var(--ds-texto-2);
    --bs-btn-border-color: var(--ds-borde-2);
    --bs-btn-hover-bg: var(--ds-superficie-2);
    --bs-btn-hover-border-color: var(--ds-texto-3);
    --bs-btn-hover-color: var(--ds-tinta);
    --bs-btn-active-bg: var(--ds-borde-2);
    --bs-btn-active-border-color: var(--ds-texto-3);
    --bs-btn-active-color: var(--ds-tinta);
}

.btn-success {
    --bs-btn-bg: var(--ds-exito);
    --bs-btn-border-color: var(--ds-exito);
    --bs-btn-hover-bg: #14654a;
    --bs-btn-hover-border-color: #14654a;
    --bs-btn-active-bg: #0f5c40;
    --bs-btn-active-border-color: #0f5c40;
}

.btn-outline-success {
    --bs-btn-color: var(--ds-exito);
    --bs-btn-border-color: var(--ds-exito);
    --bs-btn-hover-bg: var(--ds-exito);
    --bs-btn-hover-border-color: var(--ds-exito);
    --bs-btn-active-bg: #14654a;
    --bs-btn-active-border-color: #14654a;
    --bs-btn-focus-shadow-rgb: 26, 127, 90;
}

.btn-danger {
    --bs-btn-bg: var(--ds-peligro);
    --bs-btn-border-color: var(--ds-peligro);
    --bs-btn-hover-bg: #94201a;
    --bs-btn-hover-border-color: #94201a;
}

/* Bootstrap deja `btn-info` en cian claro (#0dcaf0): con texto blanco da 1,9:1. */
.btn-info {
    --bs-btn-bg: var(--ds-info);
    --bs-btn-border-color: var(--ds-info);
    --bs-btn-color: #fff;
    --bs-btn-hover-bg: #0a4a63;
    --bs-btn-hover-border-color: #0a4a63;
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: #08384b;
    --bs-btn-active-border-color: #08384b;
    --bs-btn-active-color: #fff;
}

.btn-outline-danger {
    --bs-btn-color: var(--ds-peligro);
    --bs-btn-border-color: var(--ds-peligro);
    --bs-btn-hover-bg: var(--ds-peligro);
    --bs-btn-hover-border-color: var(--ds-peligro);
    --bs-btn-focus-shadow-rgb: 179, 38, 30;
}

/* Bootstrap deja el ámbar (#ffc107) como color de texto de `btn-outline-warning`: 1,5:1 sobre el fondo
   claro, ilegible. El borde sigue siendo ámbar, el texto pasa al ámbar oscuro. */
.btn-outline-warning {
    --bs-btn-color: var(--ds-aviso);
    --bs-btn-border-color: #e0a800;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--ds-aviso);
    --bs-btn-hover-border-color: var(--ds-aviso);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #5f4500;
    --bs-btn-active-border-color: #5f4500;
    --bs-btn-focus-shadow-rgb: 122, 89, 0;
}

.btn-outline-info {
    --bs-btn-color: var(--ds-info);
    --bs-btn-border-color: var(--ds-celeste-500);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--ds-info);
    --bs-btn-hover-border-color: var(--ds-info);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #0a4a63;
    --bs-btn-active-border-color: #0a4a63;
    --bs-btn-focus-shadow-rgb: 13, 94, 125;
}

/* Botón deshabilitado: Bootstrap conserva el color de la variante en `--bs-btn-disabled-color`, que
   además deja el texto casi invisible (el violeta claro daba 1,8:1). Se unifica en gris legible. */
.btn[class*="btn-outline-"]:disabled,
.btn[class*="btn-outline-"].disabled,
fieldset:disabled .btn[class*="btn-outline-"] {
    --bs-btn-disabled-color: var(--ds-texto-3);
    --bs-btn-disabled-border-color: var(--ds-borde-2);
    --bs-btn-disabled-bg: transparent;
}

.btn-outline-dark {
    --bs-btn-color: var(--ds-tinta);
    --bs-btn-border-color: var(--ds-borde-2);
    --bs-btn-hover-bg: var(--ds-tinta);
    --bs-btn-hover-border-color: var(--ds-tinta);
    --bs-btn-active-bg: var(--ds-tinta);
    --bs-btn-active-border-color: var(--ds-tinta);
}

.btn-light {
    --bs-btn-bg: var(--ds-superficie-2);
    --bs-btn-border-color: var(--ds-borde);
    --bs-btn-color: var(--ds-texto-2);
    --bs-btn-hover-bg: var(--ds-borde);
    --bs-btn-hover-border-color: var(--ds-borde-2);
    --bs-btn-hover-color: var(--ds-tinta);
}

.btn-link {
    --bs-btn-color: var(--ds-violeta-700);
    --bs-btn-hover-color: var(--ds-violeta-800);
}

.btn-check:checked + .btn-outline-primary,
.btn-outline-primary.active {
    background-color: var(--ds-violeta-700);
    border-color: var(--ds-violeta-700);
    color: #fff;
}

/* --- Insignias: pastilla suave, con texto oscuro sobre fondo claro --- */
.badge {
    --bs-badge-font-size: .75rem;
    --bs-badge-font-weight: 500;
    --bs-badge-padding-y: .25rem;
    --bs-badge-padding-x: .5rem;
    --bs-badge-border-radius: var(--ds-radio-sm);
    border: 1px solid transparent;
    line-height: 1.1;
}

.badge.bg-primary, .badge.bg-primary.text-dark {
    background-color: var(--ds-violeta-100) !important;
    border-color: var(--ds-violeta-200) !important;
    color: var(--ds-violeta-800) !important;
}

.badge.bg-success, .badge.bg-success.text-dark {
    background-color: var(--ds-exito-bg) !important;
    border-color: var(--ds-exito-borde) !important;
    color: var(--ds-exito) !important;
}

.badge.bg-warning, .badge.bg-warning.text-dark {
    background-color: var(--ds-aviso-bg) !important;
    border-color: var(--ds-aviso-borde) !important;
    color: var(--ds-aviso) !important;
}

.badge.bg-danger, .badge.bg-danger.text-dark {
    background-color: var(--ds-peligro-bg) !important;
    border-color: var(--ds-peligro-borde) !important;
    color: var(--ds-peligro) !important;
}

.badge.bg-info, .badge.bg-info.text-dark {
    background-color: var(--ds-info-bg) !important;
    border-color: var(--ds-info-borde) !important;
    color: var(--ds-info) !important;
}

.badge.bg-secondary, .badge.bg-secondary.text-dark {
    background-color: var(--ds-superficie-2) !important;
    border-color: var(--ds-borde-2) !important;
    color: var(--ds-texto-2) !important;
}

.badge.bg-light, .badge.bg-light.text-dark {
    background-color: var(--ds-superficie-2) !important;
    border-color: var(--ds-borde) !important;
    color: var(--ds-texto-2) !important;
}

/* El único sólido: el número de turno, que necesita peso visual. */
.badge.bg-dark, .badge.bg-dark.text-white {
    background-color: var(--ds-tinta) !important;
    border-color: var(--ds-tinta) !important;
    color: #fff !important;
}

/* --- Tarjetas --- */
.card {
    --bs-card-border-color: var(--ds-borde);
    --bs-card-border-radius: var(--ds-radio-card);
    --bs-card-inner-border-radius: calc(var(--ds-radio-card) - 1px);
    --bs-card-cap-bg: var(--ds-superficie);
    --bs-card-cap-color: var(--ds-tinta);
    box-shadow: var(--ds-sombra-1);
}

.card-header {
    border-bottom-color: var(--ds-borde);
    font-weight: 600;
}

.card-footer {
    background-color: var(--ds-superficie-2);
    border-top-color: var(--ds-borde);
}

/* --- Tablas --- */
.table-striped {
    --bs-table-striped-bg: var(--ds-fondo);
    --bs-table-striped-color: var(--ds-texto);
}

.table {
    --bs-table-color: var(--ds-texto);
    --bs-table-border-color: var(--ds-borde);
    --bs-table-hover-bg: var(--ds-violeta-50);
    --bs-table-hover-color: var(--ds-tinta);
    --bs-table-bg: transparent;
    margin-bottom: 0;
}

.table > thead,
.table > thead.table-light,
.table thead.table-light {
    --bs-table-bg: var(--ds-superficie-2);
    --bs-table-color: var(--ds-texto-2);
    --bs-table-border-color: var(--ds-borde);
}

/* Las fechas y horas dentro de una tabla van chicas y en una sola línea (2026-10-20): «20/10/2026 12:10 PM» partido en dos
   renglones ocupaba más alto que cualquier otro dato de la fila. 12 px (el resto de la tabla va a 15 px); el «hace 3 horas»
   de debajo, a 11 px. */
.table td.fecha-celda { font-size: .75rem; white-space: nowrap; }
.table td.fecha-celda small { font-size: .6875rem; }

/* Aire en las celdas: Bootstrap usa .5rem/.5rem y `table-sm` baja a .25rem, que dejaba el texto pegado
   al borde de la tarjeta. Se sobreescribe el mismo selector que usa Bootstrap porque el relleno de celda
   no está expuesto como variable. */
.table > :not(caption) > * > * {
    padding: .7rem .9rem;
}

.table-sm > :not(caption) > * > * {
    padding: .5rem .75rem;
}

/* Los extremos de la fila llevan un poco más, así el contenido no toca el borde de la tarjeta. */
.table > :not(caption) > * > *:first-child { padding-left: 1rem; }
.table > :not(caption) > * > *:last-child { padding-right: 1rem; }

/* Cabecera en minúsculas y peso medio, como el resto del texto: las mayúsculas gritaban sobre la tabla.
   Las etiquetas de campo (`.etiqueta`) sí siguen en mayúsculas pequeñas. */
.table thead th {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--ds-texto-2);
    white-space: nowrap;
}

/* Varias pantallas del panel usan `thead.table-dark`: la cabecera negra pesa más que la tabla y choca
   con la paleta, así que se unifica con la cabecera clara del resto. */
.table > thead.table-dark,
.table > thead.table-dark > tr > th {
    --bs-table-bg: var(--ds-superficie-2);
    --bs-table-color: var(--ds-texto-2);
    --bs-table-border-color: var(--ds-borde);
    background-color: var(--ds-superficie-2);
    color: var(--ds-texto-2);
    border-bottom: 1px solid var(--ds-borde);
}

/* Fila de cita ya atendida: sólo se tiñe el fondo, el texto sigue siendo el normal (en verde, toda la
   fila se volvería ilegible). */
.table > tbody > tr.table-success,
.table > tbody > tr.table-success > * {
    --bs-table-bg: var(--ds-exito-bg);
    --bs-table-color: var(--ds-texto);
    box-shadow: none;
}

/* --- Formularios --- */
/* 36 px de alto, igual que un botón; el borde es el de control (3,6:1), no el decorativo de las tarjetas. */
.form-control, .form-select {
    --bs-border-color: var(--ds-borde-control);
    border-color: var(--ds-borde-control);
    border-radius: var(--ds-radio);
    color: var(--ds-texto);
    background-color: var(--ds-superficie);
    font-size: .875rem;
    line-height: 1.25rem;
    padding-top: .4375rem;
    padding-bottom: .4375rem;
    transition: border-color var(--ds-dur-base) var(--ds-ease), box-shadow var(--ds-dur-base) var(--ds-ease);
}

.form-control-sm, .form-select-sm {
    font-size: .8125rem;
    line-height: 1rem;
    border-radius: var(--ds-radio);
}

/* El `textarea` no tiene alto fijo: sólo cambian el tamaño de letra y el borde. */
textarea.form-control { min-height: calc(var(--ds-control-alto) * 2); }

.form-control::placeholder { color: var(--ds-texto-3); opacity: 1; }

.form-control:focus, .form-select:focus {
    border-color: var(--ds-violeta-500);
    box-shadow: var(--ds-foco);
}

/* El icono del calendario (WEB-13.16): **uno solo** para el nativo de los `type="date"` y el botón que
   `mascara-fecha.js` pone dentro de la FUR tecleada. El de Chrome era más grande y más oscuro que el
   `bi-calendar3`; los dos son ahora el mismo dibujo (el `bi-calendar3`, como máscara) con el mismo tamaño y el
   color del token, así que también siguen el tema. Firefox no expone el icono nativo: queda el suyo. */
:root {
    --ds-calendario-icono: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M14 0H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2M1 3.857C1 3.384 1.448 3 2 3h12c.552 0 1 .384 1 .857v10.286c0 .473-.448.857-1 .857H2c-.552 0-1-.384-1-.857z'/%3E%3Cpath d='M6.5 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m-9 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m-9 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2'/%3E%3C/svg%3E");
    --ds-calendario-icono-tam: .875rem;
    --ds-calendario-icono-color: var(--ds-texto-2);
}

input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
.campo-fecha-icono {
    width: var(--ds-calendario-icono-tam);
    height: var(--ds-calendario-icono-tam);
    padding: 0;
    margin: 0;
    background: var(--ds-calendario-icono-color);
    -webkit-mask: var(--ds-calendario-icono) center / contain no-repeat;
    mask: var(--ds-calendario-icono) center / contain no-repeat;
    opacity: 1;
    cursor: pointer;
}

/* La misma distancia al borde que el botón de la FUR (`right: .75rem`): sin esto, el nativo queda a merced del
   relleno que traiga el campo y en algunos se pegaba al borde. */
input[type="date"].form-control,
input[type="datetime-local"].form-control {
    padding-right: .75rem;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
    margin-left: .5rem;
}

input[type="date"]:disabled::-webkit-calendar-picker-indicator,
input[type="datetime-local"]:disabled::-webkit-calendar-picker-indicator { cursor: default; opacity: .5; }

/* El botón de la FUR: sólo posición y foco; el dibujo es el `span.campo-fecha-icono` de adentro. */
.campo-fecha-boton {
    position: absolute;
    top: 50%;
    right: .75rem;
    transform: translateY(-50%);
    display: inline-flex;
    padding: 0;
    border: 0;
    background: none;
    line-height: 1;
}
.campo-fecha-boton:hover .campo-fecha-icono { background: var(--ds-texto); }
.campo-fecha-boton:focus-visible { outline: 0; box-shadow: var(--ds-foco); border-radius: 2px; }

.form-label {
    color: var(--ds-texto-2);
    font-weight: 600;
    margin-bottom: .25rem;
}

.form-text { color: var(--ds-texto-3); }

.form-check-input { border-color: var(--ds-borde-control); }

.form-check-input:checked {
    background-color: var(--ds-violeta-700);
    border-color: var(--ds-violeta-700);
}

.form-check-input:focus {
    border-color: var(--ds-violeta-500);
    box-shadow: var(--ds-foco);
}

.input-group-text {
    background-color: var(--ds-superficie-2);
    border-color: var(--ds-borde-control);
    color: var(--ds-texto-2);
    font-size: .875rem;
    border-radius: var(--ds-radio);
}

/* --- Avisos --- */
.alert {
    border-radius: var(--ds-radio);
    border-width: 1px;
}

/* El navegador esconde `[hidden]` con `display: none`, pero Bootstrap lo **pisa** con
   `.d-flex { display: flex !important }`: un aviso con `hidden` y utilidades de flex (el de "hay cambios
   sin guardar", WEB-4.2) se veía igual —pasó al verificar la pantalla en Chrome—. Esta regla devuelve el
   significado del atributo, que es lo que el JS usa para mostrar y ocultar. */
[hidden] { display: none !important; }

.alert-success { background-color: var(--ds-exito-bg); border-color: var(--ds-exito-borde); color: #0f5c40; }
.alert-warning { background-color: var(--ds-aviso-bg); border-color: var(--ds-aviso-borde); color: var(--ds-aviso); }
.alert-danger  { background-color: var(--ds-peligro-bg); border-color: var(--ds-peligro-borde); color: var(--ds-peligro); }
.alert-info    { background-color: var(--ds-info-bg); border-color: var(--ds-info-borde); color: var(--ds-info); }
.alert-primary { background-color: var(--ds-violeta-100); border-color: var(--ds-violeta-200); color: var(--ds-violeta-900); }

/* --- Navegación, menús y paginación --- */
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    background-color: var(--ds-violeta-700);
    color: #fff;
}

.dropdown-menu {
    --bs-dropdown-border-color: var(--ds-borde);
    --bs-dropdown-border-radius: var(--ds-radio);
    --bs-dropdown-link-active-bg: var(--ds-violeta-700);
    --bs-dropdown-link-active-color: #fff;
    --bs-dropdown-link-hover-bg: var(--ds-violeta-50);
    --bs-dropdown-link-hover-color: var(--ds-violeta-900);
    box-shadow: var(--ds-sombra-2);
    padding: .35rem;
}

/* El correo del menú del usuario va en una sola línea: si no cabe se corta con «…» (el completo queda en el `title`)
   en vez de salirse del menú. */
.menu-usuario-correo {
    max-width: min(18rem, calc(100vw - 4rem));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dropdown-item {
    border-radius: var(--ds-radio-sm);
    padding: .45rem .7rem;
    font-size: .92rem;
}

.pagination {
    --bs-pagination-color: var(--ds-violeta-700);
    --bs-pagination-hover-color: var(--ds-violeta-800);
    --bs-pagination-hover-bg: var(--ds-violeta-50);
    --bs-pagination-hover-border-color: var(--ds-violeta-200);
    --bs-pagination-focus-color: var(--ds-violeta-800);
    --bs-pagination-focus-bg: var(--ds-violeta-50);
    --bs-pagination-focus-box-shadow: var(--ds-foco);
    --bs-pagination-active-bg: var(--ds-violeta-700);
    --bs-pagination-active-border-color: var(--ds-violeta-700);
    --bs-pagination-border-color: var(--ds-borde);
    --bs-pagination-disabled-color: var(--ds-texto-3);
}

.list-group {
    --bs-list-group-border-color: var(--ds-borde);
    --bs-list-group-action-hover-bg: var(--ds-violeta-50);
    --bs-list-group-active-bg: var(--ds-violeta-700);
    --bs-list-group-active-border-color: var(--ds-violeta-700);
}

.modal-content {
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
}

.modal-header, .modal-footer { border-color: var(--ds-borde); }

/* Formularios de alta y edición del panel: entran por la derecha, a alto completo (igual que
   `dialog.dialogo-lateral`). Las alertas y confirmaciones siguen centradas. El encabezado y el pie quedan
   fijos y sólo el cuerpo se desplaza; el <form> puede envolver todo o sólo cuerpo y pie. */
.modal-dialog.modal-lateral {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(32rem, 100vw);
    max-width: 100vw;
    height: 100%;
    margin: 0;
}
.modal-dialog.modal-lateral .modal-content { height: 100%; border-radius: 0; border-width: 0 0 0 1px; }
.modal-dialog.modal-lateral .modal-content > form { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.modal-dialog.modal-lateral .modal-header,
.modal-dialog.modal-lateral .modal-footer { flex: 0 0 auto; }
.modal-dialog.modal-lateral .modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.modal.fade .modal-dialog.modal-lateral { transform: translateX(100%); }
.modal.show .modal-dialog.modal-lateral { transform: none; animation: lateral-entra var(--ds-dur-panel) var(--ds-ease); }

.spinner-border.text-primary, .spinner-grow.text-primary { color: var(--ds-violeta-700) !important; }

/* ==========================================================================
   2. Armazón de la aplicación
   ========================================================================== */

/* --- Barra superior --- */
/* Delgada y clara: lleva el contexto (a la izquierda) y la cuenta (a la derecha). La marca vive en la barra
   lateral desde que ésta ocupa todo el alto; en el celular, donde la barra lateral se esconde, la marca
   vuelve acá. */
.app-topbar {
    background: var(--ds-superficie);
    border-bottom: 1px solid var(--ds-borde);
    min-height: 62px;
}

.app-marca {
    font-weight: 700;
    color: var(--ds-tinta);
    letter-spacing: -.01em;
}

.app-marca .app-marca-acento { color: var(--ds-violeta-700); }
.app-marca .app-marca-icono { color: var(--ds-violeta-700); }

/* --- Menú lateral: indigo del logo, de arriba abajo --- */
.app-sidebar {
    background: var(--ds-barra);
    color: var(--ds-barra-texto);
    width: var(--ds-barra-ancho);
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
}

/* La marca: el corazón del logo sobre una ficha blanca (el violeta solo no se lee sobre el indigo). */
.app-sidebar .app-sidebar-marca {
    display: flex;
    align-items: center;
    gap: .7rem;
    height: 72px;
    padding: 0 1.1rem;
    flex: 0 0 auto;
    color: var(--ds-barra-texto);
    text-decoration: none;
    overflow: hidden;
}

.app-sidebar .app-marca-ficha {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: var(--ds-radio);
    background: #fff;
    color: var(--ds-violeta-700);
    font-size: 1.3rem;
}

.app-sidebar .app-marca-nombre {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
    white-space: nowrap;
}

.app-sidebar .app-marca-nombre strong { font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em; }
.app-sidebar .app-marca-nombre small { font-size: .72rem; color: var(--ds-barra-texto-2); }

.app-sidebar > .app-sidebar-interior {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: .5rem;
    scrollbar-width: thin;
    scrollbar-color: var(--ds-barra-borde) transparent;
}

.app-sidebar .app-sidebar-titulo {
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ds-barra-texto-2);
    padding: 1rem .75rem .4rem;
}

.app-sidebar .nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: .75rem;
    color: var(--ds-barra-texto-2);
    font-weight: 500;
    font-size: .875rem;
    line-height: 1.25rem;
    border-radius: var(--ds-radio);
    padding: .5rem .75rem;
    margin-bottom: 2px;
    transition: background-color var(--ds-dur-base) var(--ds-ease), color var(--ds-dur-base) var(--ds-ease);
}

.app-sidebar .nav-link i {
    font-size: 1.05rem;
    width: 1.25rem;
    text-align: center;
    flex: 0 0 auto;
    color: inherit;
}

.app-sidebar .nav-link:hover,
.app-sidebar .nav-link:focus-visible {
    background: var(--ds-barra-2);
    color: var(--ds-barra-texto);
}

/* El ítem activo: fondo más claro y un hilo de cian a la izquierda (decorativo: el estado también se lee
   por el contraste del texto y por `aria-current`). */
.app-sidebar .nav-link.active {
    background: var(--ds-barra-2);
    color: var(--ds-barra-texto);
}

.app-sidebar .nav-link.active::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 1.25rem;
    border-radius: 999px;
    background: var(--ds-barra-hilo);
    transform: translateY(-50%);
}

/* El número de pendientes de una bandeja (pagos, solicitudes, comentarios): una píldora celeste a la derecha
   del ítem. Plegada la barra, se sube a la esquina del icono. */
.app-sidebar .app-sidebar-aviso {
    margin-left: auto;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 .375rem;
    border-radius: 999px;
    background: var(--ds-celeste-200);
    color: var(--ds-barra);
    font-size: .6875rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.app-sidebar.minimizado .app-sidebar-aviso {
    position: absolute;
    top: 2px;
    right: 4px;
    min-width: 1rem;
    height: 1rem;
    padding: 0 .25rem;
    font-size: .625rem;
}

.app-sidebar .nav-link.disabled {
    color: var(--ds-barra-texto-2);
    opacity: .55;
}

.app-sidebar :focus-visible { outline-color: var(--ds-celeste-200); }

/* Pie: separador, y a la derecha el botón de plegar. */
.app-sidebar .app-sidebar-pie {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: .25rem;
    padding: .5rem;
    border-top: 1px solid var(--ds-barra-borde);
    color: var(--ds-barra-texto-2);
    font-size: .75rem;
}

.app-sidebar .app-sidebar-pie .nav-link { margin: 0; flex: 1 1 auto; }

/* La versión de la aplicación (config('app.version')), a la izquierda del pie. */
.app-sidebar .app-sidebar-version {
    flex: 1 1 auto;
    padding: 0 .5rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.app-sidebar .app-sidebar-plegar {
    flex: 0 0 auto;
    display: none;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: 0;
    border-radius: var(--ds-radio);
    background: transparent;
    color: var(--ds-barra-texto-2);
    transition: background-color var(--ds-dur-base) var(--ds-ease), color var(--ds-dur-base) var(--ds-ease);
}

.app-sidebar .app-sidebar-plegar:hover { background: var(--ds-barra-2); color: var(--ds-barra-texto); }

/* El logo de la especialidad del consultorio: va **sobre el pie**, encima de la barra del botón de plegar. La
   imagen es la del escritorio de esa especialidad y se adapta al ancho de la barra sin deformarse. */
.app-sidebar .app-sidebar-logo {
    flex: 0 0 auto;
    padding: 0 .5rem .5rem;
}

.app-sidebar .app-sidebar-logo img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--ds-radio-sm);
}

/* Plegado: sólo quedan los iconos, la ficha de la marca y el botón de desplegar. */
.app-sidebar.minimizado .link-text,
.app-sidebar.minimizado .app-sidebar-titulo,
.app-sidebar.minimizado .app-sidebar-logo,
.app-sidebar.minimizado .app-marca-nombre { display: none; }

.app-sidebar.minimizado .app-sidebar-marca { justify-content: center; padding: 0; }
.app-sidebar.minimizado .nav-link { justify-content: center; padding-left: .5rem; padding-right: .5rem; }
.app-sidebar.minimizado .app-sidebar-pie { flex-direction: column; }
.app-sidebar.minimizado .app-sidebar-pie .nav-link { flex: 0 0 auto; width: 100%; }
.app-sidebar.minimizado .app-sidebar-version { flex: 0 0 auto; padding: 0; font-size: .6875rem; }

/* Grupo plegable del menú lateral (Catálogos): un `<details>` cuyo `<summary>` es el ítem padre y cuyos hijos son
   enlaces con su icono. Nace abierto dentro de uno de sus hijos. Plegada la barra, los hijos siguen siendo
   iconos con su `title`, como cualquier ítem. */
.app-sidebar .nav-grupo > summary { list-style: none; cursor: pointer; }
.app-sidebar .nav-grupo > summary::-webkit-details-marker { display: none; }
.app-sidebar .nav-grupo > summary .nav-grupo-flecha {
    margin-left: auto;
    font-size: .75rem;
    transition: transform var(--ds-dur-base) var(--ds-ease);
}

.app-sidebar .nav-grupo[open] > summary .nav-grupo-flecha { transform: rotate(180deg); }
.app-sidebar .nav-grupo > summary.activo-padre { color: var(--ds-barra-texto); }

.app-sidebar .nav-submenu {
    list-style: none;
    margin: 0 0 2px;
    padding: 0 0 0 1.1rem;
}

.app-sidebar .nav-submenu .nav-link { font-size: .84rem; padding-top: .4rem; padding-bottom: .4rem; }

.app-sidebar.minimizado .nav-grupo-flecha { display: none; }
.app-sidebar.minimizado .nav-submenu { padding-left: 0; }

@media (min-width: 992px) {
    /* De altura completa y fija: la página se desplaza, el menú no. La columna de contenido (y la barra
       superior del panel) le dejan su ancho a la izquierda y siguen el pliegue con `:has()`. */
    .app-sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 1030;
        transition: width var(--ds-dur-panel) var(--ds-ease);
    }

    .app-sidebar.minimizado { width: var(--ds-barra-ancho-plegada); }
    .app-sidebar .app-sidebar-plegar { display: inline-flex; }

    body.panel .main-content,
    .app-columna {
        margin-left: var(--ds-barra-ancho);
        transition: margin-left var(--ds-dur-panel) var(--ds-ease);
    }

    body.panel .app-topbar {
        left: var(--ds-barra-ancho);
        transition: left var(--ds-dur-panel) var(--ds-ease);
    }

    /* La marca está en la barra lateral: la barra superior del panel no la repite. */
    body.panel .app-topbar .app-marca { display: none; }

    body:has(.app-sidebar.minimizado) .main-content,
    body:has(.app-sidebar.minimizado) .app-columna { margin-left: var(--ds-barra-ancho-plegada); }

    body:has(.app-sidebar.minimizado) .app-topbar { left: var(--ds-barra-ancho-plegada); }
}

/* --- Encabezado de página --- */
.page-head {
    display: flex;
    flex-wrap: wrap;
    /* Título y acciones nacen en el mismo borde superior, también cuando las acciones envuelven (trampa 63). */
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: 1rem;
}

.page-head h1 {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -.01em;
    color: var(--ds-tinta);
    margin: 0;
}

.page-head .page-head-sub {
    color: var(--ds-texto-3);
    font-size: .875rem;
    margin: .25rem 0 0;
}

/* La barra de acento: marca dónde empieza la pantalla (decorativa, no lleva significado propio). */
.page-head .page-head-texto {
    position: relative;
    padding-left: .85rem;
    min-width: 0;
}

.page-head .page-head-texto::before {
    content: '';
    position: absolute;
    left: 0;
    top: .25rem;
    bottom: .25rem;
    width: 3px;
    border-radius: 999px;
    background: var(--ds-violeta-700);
}

/* --- Fichas de contexto (médico, especialidad, sede) --- */
.chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    background: var(--ds-superficie-2);
    border: 1px solid var(--ds-borde);
    color: var(--ds-texto-2);
    border-radius: 999px;
    padding: .15rem .65rem;
    font-size: .8rem;
    white-space: nowrap;
}

.chip i { color: var(--ds-texto-3); }

/* --- Tarjetas de indicador (dashboards) --- */
.stat-card {
    background: var(--ds-superficie);
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
    box-shadow: var(--ds-sombra-1);
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.stat-card .stat-card-cuerpo {
    padding: 1rem 1.1rem;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    flex: 1;
}

.stat-card .stat-etiqueta {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--ds-texto-2);
}

.stat-card .stat-valor {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--ds-tinta);
    margin: .3rem 0 0;
}

/* Círculo de icono, reutilizable fuera de las tarjetas de indicador (avatares, módulos del consultorio). */
.stat-icono {
    width: 42px;
    height: 42px;
    border-radius: var(--ds-radio);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    flex: 0 0 auto;
}

.stat-card .stat-pie {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .5rem 1.1rem;
    font-size: .8rem;
    color: var(--ds-texto-2);
    background: var(--ds-superficie-2);
    border-top: 1px solid var(--ds-borde);
    text-decoration: none;
}

.stat-card .stat-pie:hover { background: var(--ds-violeta-50); color: var(--ds-violeta-900); }

/* Acentos de las tarjetas: sólo el icono y el borde lateral llevan color. */
.stat-card.stat-violeta { border-left: 4px solid var(--ds-violeta-700); }
.stat-card.stat-violeta .stat-icono { background: var(--ds-violeta-100); color: var(--ds-violeta-700); }

.stat-card.stat-celeste { border-left: 4px solid var(--ds-celeste-500); }
.stat-card.stat-celeste .stat-icono { background: var(--ds-celeste-50); color: var(--ds-celeste-700); }

.stat-card.stat-exito { border-left: 4px solid var(--ds-exito); }
.stat-card.stat-exito .stat-icono { background: var(--ds-exito-bg); color: var(--ds-exito); }

.stat-card.stat-aviso { border-left: 4px solid #d99b00; }
.stat-card.stat-aviso .stat-icono { background: var(--ds-aviso-bg); color: var(--ds-aviso); }

.stat-card.stat-tinta { border-left: 4px solid var(--ds-tinta); }
.stat-card.stat-tinta .stat-icono { background: var(--ds-superficie-2); color: var(--ds-tinta); }

/* --- Estado vacío --- */
.empty-state {
    text-align: center;
    color: var(--ds-texto-3);
    padding: 2.25rem 1rem;
}

/* El icono del estado vacío va en bloque y grande. El selector apunta sólo al icono **propio** del
   componente: con `.empty-state i` también alcanzaba a los iconos de los botones del slot `acciones`
   (la historia del paciente tiene uno: "Ir a la ficha a asignarla"), que quedaban uno arriba del otro. */
.empty-state > i {
    font-size: 1.6rem;
    display: block;
    margin-bottom: .5rem;
    color: var(--ds-borde-2);
}

.empty-state p { margin-bottom: 0; }

/* --- Utilidades propias --- */
.sombra-1 { box-shadow: var(--ds-sombra-1); }
.texto-tenue { color: var(--ds-texto-3); }
.texto-2 { color: var(--ds-texto-2); }
.fondo-app { background: var(--ds-fondo); }

/* ==========================================================================
   3. Adaptación a pantallas chicas
   ========================================================================== */

/* En el panel el contenido llevaba hasta el borde de la ventana (las tablas se pegaban al menú). Se le
   da aire lateral; arriba no, porque cada pantalla ya trae su propio margen. */
body.panel .main-content {
    padding: 1.5rem 1.5rem 2rem;
}

@media (max-width: 767.98px) {
    body.panel .main-content { padding: 1rem .85rem 1.5rem; }
}

/* El menú lateral se pliega en un panel deslizable: en el celular ocupa el ancho completo y el
   contenido deja de quedar debajo (era el caso de `/clinica`, con el menú empujando la agenda). */
@media (max-width: 991.98px) {
    .app-sidebar {
        position: fixed;
        top: 0;
        left: -100%;
        bottom: 0;
        z-index: 1045;
        width: min(280px, 84vw);
        overflow-y: auto;
        transition: left var(--ds-dur-panel) var(--ds-ease);
        box-shadow: var(--ds-sombra-3);
    }

    .app-sidebar.abierto { left: 0; }

    .app-sidebar-fondo {
        position: fixed;
        inset: 0;
        background: rgba(31, 17, 70, .6);
        z-index: 1040;
    }
}

@media (min-width: 992px) {
    .app-sidebar-fondo { display: none; }
}

/* La barra de filtros y las tablas anchas se desplazan en horizontal, no rompen el layout. */
@media (max-width: 767.98px) {
    .page-head h1 { font-size: 1.15rem; }
    .app-contenido { padding: 1rem .85rem; }
}

/* ==========================================================================
   4. Web clínica — componentes de pantalla (`<x-ui.*>`, ver Docs/Web/guia-ui.md)
   ========================================================================== */

/* --- Encabezado de página: enlace de regreso y acciones --- */
.page-head .page-head-volver {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .85rem;
    font-weight: 600;
    text-decoration: none;
    margin-bottom: .25rem;
}

.page-head .page-head-acciones {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

/* --- Título de tarjeta --- */
.card-titulo {
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
    display: flex;
    align-items: center;
    gap: .5rem;
}

.card-titulo i { color: var(--ds-violeta-700); }

/* --- Pie de una tarjeta (resumen + acción principal) --- */
.tarjeta-pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .75rem 1rem;
    background: var(--ds-superficie-2);
    border-top: 1px solid var(--ds-borde);
}

/* --- Etiqueta de campo (mayúsculas pequeñas) --- */
.etiqueta {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ds-texto-3);
}

/* --- Estado: pastilla con color + icono + texto --- */
.estado {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .55rem;
    border-radius: var(--ds-radio-sm);
    border: 1px solid transparent;
    font-size: .78rem;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}

.estado-exito   { background: var(--ds-exito-bg);     border-color: var(--ds-exito-borde);   color: var(--ds-exito); }
.estado-aviso   { background: var(--ds-aviso-bg);     border-color: var(--ds-aviso-borde);   color: var(--ds-aviso); }
.estado-peligro { background: var(--ds-peligro-bg);   border-color: var(--ds-peligro-borde); color: var(--ds-peligro); }
.estado-info    { background: var(--ds-info-bg);      border-color: var(--ds-info-borde);    color: var(--ds-info); }
.estado-marca   { background: var(--ds-violeta-100);  border-color: var(--ds-violeta-200);   color: var(--ds-violeta-800); }
.estado-neutro  { background: var(--ds-superficie-2); border-color: var(--ds-borde-2);       color: var(--ds-texto-2); }

/* --- Avatar con iniciales y bloque de identidad --- */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: 50%;
    font-weight: 700;
    letter-spacing: .02em;
    user-select: none;
}

.avatar-sm { width: 28px; height: 28px; font-size: .68rem; }
.avatar-md { width: 38px; height: 38px; font-size: .82rem; }
.avatar-lg { width: 64px; height: 64px; font-size: 1.35rem; }

/* Texto oscuro sobre fondo suave: todos cumplen AA. */
.avatar-tono-violeta { background: var(--ds-violeta-100);  color: var(--ds-violeta-800); }
.avatar-tono-celeste { background: var(--ds-celeste-50);   color: var(--ds-celeste-700); }
.avatar-tono-exito   { background: var(--ds-exito-bg);     color: var(--ds-exito); }
.avatar-tono-aviso   { background: var(--ds-aviso-bg);     color: var(--ds-aviso); }
.avatar-tono-tinta   { background: var(--ds-superficie-2); color: var(--ds-tinta); }

.identidad {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-width: 0;
}

.identidad-texto {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}

.identidad-nombre {
    font-weight: 600;
    color: var(--ds-tinta);
    text-decoration: none;
    overflow-wrap: anywhere;
}

a.identidad-nombre:hover { color: var(--ds-violeta-700); text-decoration: underline; }

.identidad-detalle {
    font-size: .82rem;
    color: var(--ds-texto-3);
}

/* --- Ficha: pares etiqueta/valor --- */
.dato { margin: 0; }
.dato dd { margin: .1rem 0 0; color: var(--ds-texto); overflow-wrap: anywhere; }
.dato-vacio { color: var(--ds-texto-3); }

.datos-rejilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 1rem 1.25rem;
    margin: 0;
}

/* --- Estado vacío (amplía el de la sección 2) --- */
.empty-state .empty-state-titulo {
    font-weight: 600;
    color: var(--ds-texto-2);
    margin-bottom: .15rem;
}

.empty-state .empty-state-texto { font-size: .9rem; margin-bottom: 0; }
.empty-state .empty-state-acciones { margin-top: .85rem; }

/* --- Buscador --- */
.buscador {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.buscador-campo {
    position: relative;
    flex: 1 1 16rem;
    min-width: 0;
}

.buscador-campo i {
    position: absolute;
    left: .8rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ds-texto-3);
    pointer-events: none;
}

.buscador-campo .form-control { padding-left: 2.3rem; }

/* El botón que va al final del buscador («+» del alta de paciente en la cita): el campo le deja el lugar. */
.buscador-campo .form-control.buscador-con-accion { padding-right: 2.6rem; }
.buscador-accion {
    position: absolute;
    top: 50%;
    right: .35rem;
    transform: translateY(-50%);
}
.buscador-accion .btn {
    --bs-btn-padding-y: 0;
    --bs-btn-padding-x: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    line-height: 1;
    font-weight: 700;
}
.buscador-accion .signo-mas {
    font-size: 1.15rem;
    line-height: 1;
}

/* --- Barra de herramientas: el buscador y los filtros de una pantalla, debajo del encabezado ---
   El encabezado (`.page-head`) lleva sólo título, subtítulo y botones. Todo lo que filtra la lista va acá:
   el buscador ocupa el ancho útil y los filtros (segmentados, selects) quedan a su derecha; en el celular
   cada grupo baja a su propia línea. Es la hermana de `.agenda-barra`, para las pantallas sin calendario. */
.barra-herramientas {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 1rem;
    margin-bottom: 1rem;
}

.barra-herramientas .buscador { flex: 1 1 24rem; min-width: 0; }
.barra-herramientas .buscador-campo { flex: 1 1 14rem; min-width: 10rem; }

.barra-herramientas-filtros {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .6rem;
}

/* En el celular el campo y los dos botones ("Buscar" y "Limpiar", que aparece con una búsqueda activa) no
   entran en una línea: el campo se queda con el espacio que sobra y "Limpiar" baja a otra línea. Sin esto la página gana 3 px de
   scroll horizontal a 375 px (medido). */
@media (max-width: 575.98px) {
    .barra-herramientas .buscador { flex-basis: 100%; }
    .barra-herramientas .buscador-campo { flex: 1 1 8rem; min-width: 0; }
    .barra-herramientas-filtros { width: 100%; }
}

/* --- La tabla que no entra se desplaza **dentro de su tarjeta** (A-16, 2026-10-17) ---
   La página nunca scrollea en horizontal: es el contenedor de la tabla el que lo hace, así el encabezado, la barra
   lateral y la paginación siguen quietos. En el celular la tabla se apila en tarjetas y no desborda, así que esto no
   le cambia nada al modo tarjeta. El foco con el teclado y el `role="region"` los pone `shell.js` **sólo cuando hay
   desborde** (un `tabindex` de más en una tabla que entra es una parada de tabulación inútil). */
.tabla-envoltura {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.tabla-envoltura:focus-visible { outline: 2px solid var(--ds-violeta-700); outline-offset: -2px; }

/* --- Tabla que se apila en tarjetas en el celular --- */
@media (max-width: 767.98px) {
    .tabla-tarjetas thead { display: none; }

    .tabla-tarjetas,
    .tabla-tarjetas tbody,
    .tabla-tarjetas tr,
    .tabla-tarjetas td { display: block; width: 100%; }

    .tabla-tarjetas tr {
        padding: .6rem 0;
        border-bottom: 1px solid var(--ds-borde);
    }

    .tabla-tarjetas tr:last-child { border-bottom: 0; }

    .tabla-tarjetas > :not(caption) > * > * { padding: .25rem 1rem; border: 0; }

    .tabla-tarjetas td[data-etiqueta] {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 1rem;
        text-align: right;
    }

    .tabla-tarjetas td[data-etiqueta]::before {
        content: attr(data-etiqueta);
        flex: 0 0 auto;
        font-size: .72rem;
        font-weight: 700;
        letter-spacing: .05em;
        text-transform: uppercase;
        color: var(--ds-texto-3);
        text-align: left;
    }

    /* Una celda sin dato no ocupa renglón en la tarjeta. */
    .tabla-tarjetas td.celda-vacia { display: none; }

    /* La primera celda (la identidad) abre la tarjeta y ocupa todo el ancho. */
    .tabla-tarjetas td.celda-principal { text-align: left; padding-top: .35rem; }
    .tabla-tarjetas td.celda-acciones { display: flex; justify-content: flex-end; padding-bottom: .35rem; }

    /* Una celda con un valor largo (un correo) se apila: la etiqueta arriba y el valor con todo el ancho.
       En la fila de siempre (etiqueta a la izquierda, valor a la derecha) el correo se partía a mitad de
       palabra ("fuenmayoryy@gm / ail.com"). */
    .tabla-tarjetas td.celda-apilada[data-etiqueta] {
        flex-direction: column;
        align-items: flex-start;
        gap: .15rem;
        text-align: left;
    }
}

/* --- Pie de un listado: rango + paginación --- */
.lista-pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-top: .85rem;
}

.lista-pie .pagination { margin-bottom: 0; flex-wrap: wrap; }

@media (max-width: 575.98px) {
    .lista-pie { justify-content: center; }
}

/* --- Cabecera de una ficha --- */
.ficha-cabecera {
    display: flex;
    align-items: center;
    gap: 1.1rem;
}

.ficha-cabecera-texto {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    min-width: 0;
}

.ficha-cabecera-contacto {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.25rem;
    color: var(--ds-texto-2);
    font-size: .92rem;
}

/* Representante de un adulto: acción compacta a la derecha de la cabecera (se parte debajo en pantallas chicas). */
.ficha-cabecera-representante {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem .9rem;
    color: var(--ds-texto-2);
}

@media (max-width: 767.98px) {
    .ficha-cabecera { flex-wrap: wrap; }
    .ficha-cabecera-representante { margin-left: 0; justify-content: flex-start; width: 100%; }
}

.ficha-cabecera-contacto i { color: var(--ds-texto-3); margin-right: .2rem; }

/* --- Línea de tiempo (consultas, antecedentes…) --- */
.linea-tiempo {
    list-style: none;
    margin: 0;
    padding: .5rem 1rem .5rem 1.5rem;
}

.linea-tiempo > li {
    position: relative;
    padding: .7rem 0 .7rem 1.1rem;
    border-left: 2px solid var(--ds-violeta-200);
}

.linea-tiempo > li::before {
    content: "";
    position: absolute;
    left: -6px;
    top: 1.05rem;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--ds-superficie);
    border: 2px solid var(--ds-violeta-700);
}

.linea-tiempo-cabeza {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
}

.linea-tiempo-texto {
    margin: .2rem 0 0;
    font-size: .9rem;
    color: var(--ds-texto-2);
    overflow-wrap: anywhere;
}

@media (max-width: 575.98px) {
    .ficha-cabecera { align-items: flex-start; }
    .avatar-lg { width: 52px; height: 52px; font-size: 1.1rem; }
}

/* --- Representante del paciente en la ficha (WEB-3.4) --- */
.representante-datos {
    display: flex;
    flex-direction: column;
    gap: .9rem;
}

.representante-cabeza {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.representante-nombre {
    font-weight: 600;
    color: var(--ds-texto);
    overflow-wrap: anywhere;
}

/* --- Historia del paciente (WEB-3.5): los antecedentes agrupados por tipo --- */
.antecedentes-grupo + .antecedentes-grupo { margin-top: 1rem; }

.antecedentes-titulo {
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--ds-texto-3);
    margin: 0 0 .35rem;
}

.lista-antecedentes {
    list-style: none;
    margin: 0;
    padding: 0;
}

.lista-antecedentes > li {
    padding: .45rem 0;
    border-bottom: 1px solid var(--ds-borde);
    overflow-wrap: anywhere;
}

.lista-antecedentes > li:last-child { border-bottom: 0; }

/* --- Ancho de columnas y controles (reemplazan los `style=""` de las vistas) --- */
.col-estrecha { width: 2rem; }
.col-numero   { width: 3rem; }
.col-hora     { width: 4.5rem; }
.control-sede   { min-width: 15rem; }
.control-razon  { min-width: 12.5rem; }
.control-buscar { min-width: 16rem; }

/* ==========================================================================
   5. Web clínica — armazón y agenda (antes un `<style>` dentro de clinica/layout)
   ========================================================================== */

/* La fila que se arrastra (el diálogo de cobro es un <dialog>: ver sección 6). */
.lista-cola tr[draggable="true"] { cursor: grab; }
.lista-cola tr.arrastrando { opacity: .5; }
.calendario-mes td { width: 14.28%; }

/* La columna de contenido (barra superior + pantalla) ocupa lo que deja la barra lateral, que es fija. */
.app-columna { min-height: 100vh; display: flex; flex-direction: column; min-width: 0; }
.app-columna > .app-topbar { position: sticky; top: 0; z-index: 1020; }
.app-contenido { flex: 1; min-width: 0; }

/* ==========================================================================
   6. Web clínica — agenda y piezas compartidas (menú, diálogo, resultados en vivo)
   ========================================================================== */

/* --- Menú de acciones (<details class="menu-acciones">, ver `<x-ui.menu>` y shell.js) --- */
.menu-acciones { position: relative; display: inline-block; }
.menu-acciones > summary { list-style: none; cursor: pointer; }
.menu-acciones > summary::-webkit-details-marker { display: none; }
.menu-acciones[open] > summary { background: var(--ds-superficie-2); border-color: var(--ds-texto-3); }

.menu-lista {
    position: absolute;
    right: 0;
    top: calc(100% + 4px);
    z-index: 1060;
    min-width: 14rem;
    padding: .35rem;
    background: var(--ds-superficie);
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    box-shadow: var(--ds-sombra-2);
    text-align: left;
}

.menu-lista form { margin: 0; }

/* El menú de una fila que vive en una tabla con desplazamiento horizontal: el contenedor recorta también en
   vertical (`overflow-x: auto` implica `overflow-y: auto`), así que el menú se posiciona contra la ventana
   (`shell.js` le pone el `left` y el `top` del botón que lo abre, y lo abre hacia arriba si no entra abajo) y no
   queda cortado. Con `max-height` un menú largo se desplaza adentro en vez de salirse de la pantalla. */
.menu-lista-flotante {
    position: fixed;
    right: auto;
    max-height: calc(100vh - 16px);
    overflow-y: auto;
    z-index: 1070;
}

.menu-item {
    display: flex;
    align-items: center;
    gap: .55rem;
    width: 100%;
    padding: .5rem .7rem;
    border: 0;
    border-radius: var(--ds-radio-sm);
    background: transparent;
    color: var(--ds-texto);
    font-size: .92rem;
    text-align: left;
    text-decoration: none;
    white-space: nowrap;
}

.menu-item i { color: var(--ds-texto-3); }
.menu-item:hover { background: var(--ds-violeta-50); color: var(--ds-violeta-900); }
.menu-item:hover i { color: var(--ds-violeta-700); }
.menu-item:disabled { opacity: .55; cursor: not-allowed; }
.menu-item-peligro, .menu-item-peligro i { color: var(--ds-peligro); }
.menu-item-peligro:hover { background: var(--ds-peligro-bg); color: var(--ds-peligro); }

/* --- Diálogo nativo (<dialog>, ver `<x-ui.dialogo>`) --- */
dialog.dialogo {
    width: min(26rem, 92vw);
    padding: 0;
    border: 0;
    border-radius: var(--ds-radio-card);
    color: var(--ds-texto);
    box-shadow: var(--ds-sombra-3);
}

dialog.dialogo::backdrop { background: rgba(31, 17, 70, .6); }

dialog.dialogo[open]::backdrop { animation: velo-entra var(--ds-dur-base) var(--ds-ease); }
dialog.dialogo[open] { animation: dialogo-entra var(--ds-dur-base) var(--ds-ease); }

@keyframes velo-entra { from { opacity: 0; } to { opacity: 1; } }
@keyframes dialogo-entra { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes lateral-entra { from { transform: translateX(100%); } to { transform: none; } }

/* Variante lateral (`<x-ui.dialogo lateral>`): un formulario que entra por la derecha a alto completo y
   deja ver la pantalla de fondo. Para confirmaciones cortas sigue el diálogo centrado. */
dialog.dialogo-lateral {
    /* Cajón: ~416 px de ancho (el rango pedido es 380–420) y, en una pantalla más angosta, todo el ancho. */
    width: min(26rem, 100vw);
    max-width: 100vw;
    height: 100%;
    max-height: none;
    margin: 0 0 0 auto;
    border-radius: 0;
    border-left: 1px solid var(--ds-borde);
    overflow-y: auto;
}

dialog.dialogo-lateral[open] { animation: lateral-entra var(--ds-dur-panel) var(--ds-ease); }

dialog.dialogo-lateral .dialogo-caja { min-height: 100%; display: flex; flex-direction: column; padding: 1.5rem; }
dialog.dialogo-lateral .dialogo-caja > form { flex: 1 1 auto; display: flex; flex-direction: column; }
dialog.dialogo-lateral .dialogo-cuerpo { flex: 1 1 auto; }
dialog.dialogo-lateral .dialogo-pie {
    position: sticky;
    bottom: 0;
    margin-top: 1.25rem;
    padding-top: 1rem;
    background: var(--ds-superficie);
    border-top: 1px solid var(--ds-borde);
}

.dialogo-caja { padding: 1.25rem; }
.dialogo-titulo { font-size: 1.1rem; font-weight: 700; margin: 0 0 .9rem; }
.dialogo-pie { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1.1rem; }

/* --- Alta y edición de paciente (WEB-3.2) --- */
/* La nacionalidad es una letra (`V`/`E`): dentro del grupo de la cédula ocupa lo mínimo y deja el resto
   al número, que es lo que se escribe de verdad. */
.campo-nacionalidad { max-width: 8.5rem; }

/* --- Resultados en vivo (<x-ui.buscador-vivo>) --- */
.resultados-flotantes {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 1030;
    max-height: 16rem;
    overflow-y: auto;
    border-radius: var(--ds-radio);
    box-shadow: var(--ds-sombra-2);
}

.resultado-paciente {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .5rem .85rem;
    background: var(--ds-superficie);
    border-bottom: 1px solid var(--ds-borde);
}

.resultado-paciente:last-child { border-bottom: 0; }
.resultado-paciente-datos { font-size: .9rem; min-width: 0; overflow-wrap: anywhere; }

/* --- Barra de la agenda: navegación, vista y filtros --- */
.agenda-barra {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 1rem;
    margin-bottom: 1rem;
}

.agenda-navegacion, .agenda-controles, .agenda-filtros {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .6rem;
}

.agenda-titulo { font-size: 1.1rem; font-weight: 700; margin: 0 .25rem; }

.agenda-filtros .form-select { width: auto; flex: 1 1 12rem; max-width: 18rem; }

@media (max-width: 575.98px) {
    .agenda-filtros { width: 100%; }
    .agenda-filtros .form-select { width: 100%; min-width: 0; max-width: none; flex-basis: 100%; }
}

/* --- Jornada: cabecera con el cupo --- */
/* Sin `overflow: hidden`: recortaría el menú de acciones de la fila cuando hay pocas citas (queda detrás).
   Las esquinas se redondean a mano. */
.jornada { overflow: visible; }
.jornada-cabecera { border-radius: calc(var(--ds-radio-card) - 1px) calc(var(--ds-radio-card) - 1px) 0 0; }

.jornada-cabecera {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .6rem 1.25rem;
    padding: .85rem 1rem;
    background: var(--ds-violeta-50);
    border-bottom: 1px solid var(--ds-borde);
}

.jornada-titulo { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .75rem; }
.jornada-sede i { color: var(--ds-violeta-700); margin-right: .15rem; }

.jornada-resumen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem 1rem;
    font-size: .88rem;
    color: var(--ds-texto-2);
}

.jornada-cupo { display: inline-flex; align-items: center; gap: .45rem; }

progress.cupo-barra {
    width: 4.5rem;
    height: .5rem;
    border: 0;
    border-radius: 999px;
    background: var(--ds-borde);
    appearance: none;
    -webkit-appearance: none;
}

progress.cupo-barra::-webkit-progress-bar { background: var(--ds-borde); border-radius: 999px; }
progress.cupo-barra::-webkit-progress-value { background: var(--ds-violeta-700); border-radius: 999px; }
progress.cupo-barra::-moz-progress-bar { background: var(--ds-violeta-700); border-radius: 999px; }
progress.cupo-lleno::-webkit-progress-value { background: #d99b00; }
progress.cupo-lleno::-moz-progress-bar { background: #d99b00; }

/* --- Citas de la jornada --- */
.turno {
    display: inline-block;
    min-width: 2.2rem;
    padding: .15rem .55rem;
    border-radius: 999px;
    background: var(--ds-tinta);
    color: #fff;
    font-size: .8rem;
    font-weight: 700;
    text-align: center;
}

.turno-vacio { background: var(--ds-superficie-2); color: var(--ds-texto-3); border: 1px solid var(--ds-borde-2); }

.table > tbody > tr.fila-atendida,
.table > tbody > tr.fila-atendida > * { --bs-table-bg: var(--ds-exito-bg); --bs-table-color: var(--ds-texto); }

.table > tbody > tr.fila-movida > * { color: var(--ds-texto-3); }

.celda-arrastre { width: 2rem; color: var(--ds-texto-3); cursor: grab; }
.celda-hora { white-space: nowrap; font-variant-numeric: tabular-nums; }

.estados-fila { display: flex; flex-wrap: wrap; gap: .35rem; }

.acciones-fila {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .4rem;
}

.acciones-fila form { margin: 0; }

/* Un botón de acción nunca parte su rótulo en dos líneas: la fila crecería y la pauta es una línea por fila. */
.acciones-fila .btn { white-space: nowrap; }

/* En una celda de tabla las acciones van en **una línea**: sin `flex-wrap` el ancho mínimo de la celda es la suma de
   sus botones y la fila no se parte (pauta de Alexander, 2026-10-17: hasta dos acciones directas, alineadas). El
   `<form>` no dibuja caja (`display: contents`), así el botón queda como un ítem más del flex y se alinea con su
   vecino en lugar de quedar unos píxeles más abajo por la línea base. */
.celda-acciones .acciones-fila { flex-wrap: nowrap; }
.celda-acciones .acciones-fila form { display: contents; }

/* Un renglón por fila (el catálogo de medicamentos): el texto largo se recorta con puntos suspensivos en una sola línea
   y el completo queda en el `title`. `min-width: 0` deja que el texto ceda dentro de un flex. */
.texto-una-linea { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; min-width: 0; }

/* El catálogo de medicamentos es una tabla de **un renglón por fila**: con el ancho de las columnas fijo, el texto se
   recorta en lugar de empujar la tabla fuera de la pantalla. La columna de acciones mide lo que miden sus dos botones
   (Editar + papelera, con su separación): en una celda más angosta «Editar» se partiría en dos líneas y la fila
   crecería, que es justo lo que la pauta evita. */
.tabla-medicamentos { table-layout: fixed; }
.tabla-medicamentos th:nth-child(1) { width: 30%; }
.tabla-medicamentos th:nth-child(2) { width: 22%; }
.tabla-medicamentos th:nth-child(3) { width: 28%; }
.tabla-medicamentos th:nth-child(4) { width: 140px; white-space: nowrap; }

/* --- Tablas barridas con la pauta de una línea por fila (A-16, 2026-10-17) ---
   Las mismas reglas que la tabla de medicamentos, para los catálogos, sedes, consultorios y usuarios: el ancho de las
   columnas no depende del contenido, así que la fila mide una línea y el texto que no entra se recorta con puntos
   suspensivos (el completo queda en el `title`). La última columna —las acciones— mide lo que miden sus botones, que
   es lo único que no se puede recortar. */
.tabla-catalogo-simple,
.tabla-catalogo-tratamientos,
.tabla-catalogo-examenes,
.tabla-catalogo-doctores,
.tabla-catalogo-plantillas,
.tabla-catalogo-motivos,
.tabla-sedes { table-layout: fixed; }

.tabla-catalogo-simple th:last-child,
.tabla-catalogo-tratamientos th:last-child,
.tabla-catalogo-examenes th:last-child,
.tabla-catalogo-doctores th:last-child,
.tabla-catalogo-plantillas th:last-child { width: 150px; white-space: nowrap; }

.tabla-catalogo-motivos th:last-child { width: 160px; white-space: nowrap; }
.tabla-sedes th:last-child { width: 22%; white-space: nowrap; }

/* El diálogo del catálogo inicial (2026-11-03): la lista de lo que falta, con su propio scroll para que el botón
   «Agregar» quede siempre a la vista, aunque el catálogo inicial traiga cientos de filas. */
.catalogo-inicial-lista { max-height: 55vh; overflow-y: auto; margin-right: -0.5rem; padding-right: 0.5rem; }
.catalogo-inicial-lista .form-check { margin-bottom: 0.25rem; }
.catalogo-inicial-lista .form-check-label { overflow-wrap: anywhere; }

.tabla-catalogo-tratamientos th:nth-child(1) { width: 38%; }
.tabla-catalogo-examenes th:nth-child(1) { width: 55%; }
.tabla-catalogo-doctores th:nth-child(1) { width: 30%; }
.tabla-catalogo-doctores th:nth-child(3) { width: 24%; }
.tabla-catalogo-plantillas th:nth-child(1) { width: 50%; }
.tabla-catalogo-motivos th:nth-child(1) { width: 26%; }
.tabla-sedes th:nth-child(1) { width: 20%; }
.tabla-sedes th:nth-child(2) { width: 19%; }
.tabla-sedes th:nth-child(3) { width: 12%; }
.tabla-sedes th:nth-child(4) { width: 14%; }
.tabla-sedes th:nth-child(5) { width: 13%; }

/* Con seis columnas y una barra lateral de 264 px el relleno de 12 px por celda se come el ancho útil: en pantallas
   angostas las tablas barridas lo achican (no se toca el de todas). */
@media (max-width: 1199.98px) {
    .tabla-catalogo-simple > :not(caption) > * > *,
    .tabla-catalogo-tratamientos > :not(caption) > * > *,
    .tabla-catalogo-examenes > :not(caption) > * > *,
    .tabla-catalogo-doctores > :not(caption) > * > *,
    .tabla-catalogo-plantillas > :not(caption) > * > *,
    .tabla-catalogo-motivos > :not(caption) > * > *,
    .tabla-sedes > :not(caption) > * > * { padding-left: .45rem; padding-right: .45rem; }
}

/* En el celular cada cita es una tarjeta compacta: turno y hora arriba, el paciente, los estados y las
   acciones debajo (sin etiquetas por celda). */
@media (max-width: 767.98px) {
    .tabla-agenda > :not(caption) > * > * { padding: 0; }

    .tabla-agenda tbody tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: .4rem .75rem;
        padding: .8rem 1rem;
    }

    .tabla-agenda td { display: block; width: auto; }
    .tabla-agenda td.celda-arrastre { display: none; }
    .tabla-agenda td.celda-turno { order: 1; }
    .tabla-agenda td.celda-hora { order: 2; margin-right: auto; font-weight: 600; }
    .tabla-agenda td.celda-principal { order: 3; width: 100%; }
    .tabla-agenda td.celda-estado { order: 4; width: 100%; }
    .tabla-agenda td.celda-acciones { order: 5; width: 100%; text-align: left !important; justify-content: flex-start; }
    /* Las acciones de la fila se envuelven dentro de la tarjeta: con «Editar consulta» + «Imprimir documentos» +
       «Cobrar» + el menú, una sola línea se sale de la pantalla (medido: 7 px de scroll horizontal a 375 px). */
    .tabla-agenda .acciones-fila { justify-content: flex-start; flex-wrap: wrap; }
}

/* En la tableta (768 a 991 px, la barra lateral es un panel) la celda de acciones no entra en una línea con las
   cuatro acciones de una cita atendida: se envuelven ahí en vez de empujar la tabla —y la página— 144 px a la
   derecha (medido a 768 px). De 992 px para arriba siguen en una línea, que es la pauta de la tabla. */
@media (min-width: 768px) and (max-width: 991.98px) {
    .tabla-agenda .celda-acciones .acciones-fila { flex-wrap: wrap; }
}

/* En la tabla (escritorio y tableta) las acciones de una cita van **en una sola línea**: la columna se ajusta a
   su contenido y es la de estados la que envuelve. Con `flex-wrap` suelto, el navegador repartía el ancho
   entre columnas y partía "Confirmar / Cobrar / ⋯" en dos renglones en cada fila. */
@media (min-width: 768px) {
    .tabla-agenda td.celda-acciones { width: 1%; white-space: nowrap; }
    .tabla-agenda .acciones-fila { flex-wrap: nowrap; }
    /* Los dos estados de la cita (atendida/confirmada y pagada/pendiente) van **en la misma línea**: envueltos, la
       fila medía dos renglones y la pauta es una línea por fila. La columna toma el ancho que necesita y es la del
       paciente la que cede (su nombre se recorta con puntos suspensivos). */
    .tabla-agenda .estados-fila { flex-wrap: nowrap; }
    .tabla-agenda .celda-principal .identidad-nombre { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* Entre 768 y 1199 px la tabla de la agenda no entra con los rótulos de las acciones: «Confirmar», «Imprimir
   documentos» y «Cobrar» con su texto son ~250 px que, sumados al paciente y a los estados, la empujaban fuera
   de la pantalla (medido: 205 px a 992 y 97 px a 1100). Ahí el rótulo pasa a `title` + `aria-label` y el botón
   queda con su icono; sigue siendo una sola línea, que es la pauta. En el celular (modo tarjeta) los rótulos
   vuelven, porque ahí la acción va debajo del paciente y hay lugar. */
@media (min-width: 768px) and (max-width: 1199.98px) {
    .tabla-agenda .accion-texto { display: none; }
    /* Ídem con el relleno de las celdas: con la barra lateral desplegada a 1024-1100 px son ~70 px de tabla que
       hacen que no entre. Se ajusta el de esta tabla, no el de todas. */
    .tabla-agenda > :not(caption) > * > * { padding-left: .45rem; padding-right: .45rem; }
}

/* --- Semana --- */
.agenda-dia { margin-top: 1.25rem; }
.agenda-dia-cabecera { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; margin-bottom: .6rem; }
.agenda-dia-titulo { font-size: 1rem; font-weight: 700; margin: 0; }
.agenda-dia-titulo a { color: inherit; text-decoration: none; }
.agenda-dia-titulo a:hover { text-decoration: underline; }
.agenda-dia-titulo.es-hoy { color: var(--ds-violeta-700); }

/* --- Mes --- */
.calendario-mes th { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; }
.calendario-celda { height: 5.75rem; vertical-align: top; padding: .4rem !important; }
.calendario-celda.fuera-del-mes { background: var(--ds-superficie-2); }
.calendario-celda.fuera-del-mes .calendario-numero { color: var(--ds-texto-3); }

.calendario-dia {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .25rem;
    color: var(--ds-texto);
    text-decoration: none;
}

.calendario-numero {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    font-weight: 600;
}

.calendario-dia:hover .calendario-numero { background: var(--ds-violeta-100); }
.calendario-dia.es-hoy .calendario-numero { background: var(--ds-violeta-700); color: #fff; }

.calendario-conteo {
    padding: .05rem .5rem;
    border-radius: 999px;
    background: var(--ds-violeta-100);
    color: var(--ds-violeta-800);
    font-size: .78rem;
    font-weight: 700;
}

.calendario-marca { margin-top: .3rem; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }

@media (max-width: 575.98px) {
    /* El mes tiene que caber en el celular (a 390 px la columna del domingo quedaba fuera de la pantalla):
       columnas de igual ancho que no crecen con el texto y encabezados más compactos. */
    .calendario-mes { table-layout: fixed; width: 100%; }
    .calendario-mes th { padding: .4rem 0 !important; font-size: .66rem; letter-spacing: 0; }
    .calendario-celda { height: 4.2rem; padding: .25rem !important; }
    .calendario-celda.no-laborable { background: var(--ds-aviso-bg); }
    .calendario-marca { display: none; }
    .calendario-conteo { font-size: .7rem; padding: 0 .35rem; }
}

/* --- Formulario por pasos (cita) --- */
.paso { padding: 1.1rem 1.25rem; border-bottom: 1px solid var(--ds-borde); }
.paso-aviso { background: var(--ds-aviso-bg); }

.paso-titulo {
    display: flex;
    align-items: center;
    gap: .6rem;
    font-size: 1rem;
    font-weight: 700;
    margin: 0 0 .9rem;
}

.paso-numero {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    background: var(--ds-violeta-700);
    color: #fff;
    font-size: .8rem;
}

.jornada-resumen-inline { padding: .6rem .8rem; background: var(--ds-violeta-50); border-radius: var(--ds-radio-sm); }

/* --- Accesos a módulos (inicio) y errores de campo --- */
.modulo-icono { background: var(--ds-violeta-100); color: var(--ds-violeta-700); }
.modulo-nombre { font-size: 1rem; font-weight: 700; margin: 0 0 .15rem; }
.modulo-acceso { transition: box-shadow .15s ease, border-color .15s ease; }
.modulo-acceso:hover { border-color: var(--ds-violeta-200); box-shadow: var(--ds-sombra-2); }
.campo-error { color: var(--ds-peligro); font-size: .85rem; margin-top: .2rem; }

/* ==========================================================================
   7. Web clínica — la consulta (WEB-4.1): el panel de secciones del legado
   ========================================================================== */

.consulta-panel-grupo + .consulta-panel-grupo { margin-top: .9rem; }

.consulta-panel-titulo {
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--ds-texto-3);
    margin: 0 0 .35rem;
}

.consulta-panel { list-style: none; margin: 0; padding: 0; }

/* El ítem es una fila de dos piezas: el icono y el texto. El estado ("Próximamente") va **dentro** del texto,
   en la fila del título, así la descripción de abajo usa todo el ancho del ítem. */
.consulta-panel-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem 0;
    border-bottom: 1px solid var(--ds-borde);
}

.consulta-panel-item:last-child { border-bottom: 0; }

.consulta-panel-item-pendiente .consulta-panel-nombre { color: var(--ds-texto-2); }

.consulta-panel-icono {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--ds-radio);
    background: var(--ds-violeta-50);
    color: var(--ds-violeta-700);
}

.consulta-panel-item-pendiente .consulta-panel-icono {
    background: var(--ds-fondo);
    color: var(--ds-texto-3);
}

.consulta-panel-texto { flex: 1 1 auto; min-width: 0; }

/* La fila del título: el nombre a la izquierda y la pastilla a la derecha, **siempre en la misma fila**. Si
   no caben (una columna angosta), el que cede es el nombre, que se parte en dos renglones por palabras
   ("Estudio / ecográfico"); la pastilla no se achica ni baja, y queda alineada con el primer renglón. */
.consulta-panel-cabecera {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
}

.consulta-panel-cabecera > .consulta-panel-nombre { flex: 1 1 auto; min-width: 0; }
.consulta-panel-cabecera > .estado { flex: 0 0 auto; margin-left: auto; margin-top: .05rem; }

@media (min-width: 768px) {
    .consulta-panel-item { align-items: flex-start; max-width: 28rem; }
}

.consulta-panel-nombre {
    display: block;
    font-weight: 600;
    color: var(--ds-texto);
    text-decoration: none;
    overflow-wrap: anywhere;
}

a.consulta-panel-nombre:hover { color: var(--ds-violeta-700); text-decoration: underline; }

.consulta-panel-detalle {
    display: block;
    font-size: .85rem;
    color: var(--ds-texto-3);
    overflow-wrap: anywhere;
}

/* La sección que se está mirando: el ítem del panel se marca con el fondo de marca suave y una barra a
   la izquierda, para que se vea **cuál** de los trece está abierto (guía de UI §3: el ítem activo). */
.consulta-panel-item-activo {
    background: var(--ds-violeta-50);
    border-radius: var(--ds-radio);
    box-shadow: inset 3px 0 0 var(--ds-violeta-700);
    padding-left: .5rem;
    padding-right: .5rem;
}

/* ==========================================================================
   8. Web clínica — las secciones de la consulta (WEB-4.2): motivos y enfermedad actual
   ========================================================================== */

/* Los motivos que la consulta ya tiene: una fila por motivo, con su quitar a la derecha. Es una lista y
   no una tabla porque son pocos renglones cortos y en celular la tabla se volvería tarjetas. */
.motivos-lista { list-style: none; margin: 0; padding: 0; }

.motivos-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .55rem 0;
    border-bottom: 1px solid var(--ds-borde);
}

.motivos-item:last-child { border-bottom: 0; }

.motivos-item-texto { min-width: 0; }

.motivos-item-nombre {
    display: block;
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* La fila del buscador: el resultado y su acción. Es el mismo `.resultado-paciente` de los buscadores en
   vivo, con el botón de crear como `<button>` (abre el diálogo) y no como enlace. */
.resultado-motivo { width: 100%; text-align: left; border: 0; }

button.resultado-motivo-crear:hover .resultado-paciente-datos { color: var(--ds-violeta-700); }

/* El campo de la enfermedad actual: el texto clínico se lee cómodo y crece con el contenido hasta un
   tope, para que no empuje el botón de guardar fuera de la pantalla. */
#enfermedadactual { min-height: 14rem; resize: vertical; }

/* ==========================================================================
   9. Web clínica — la evaluación física (WEB-4.3)
   ========================================================================== */

/* La rejilla de la antropometría y los signos: campos numéricos cortos, tantos como entren (a 1280 px son
   cuatro por fila). `auto-fill` con un mínimo de 9rem evita el `col-*` de Bootstrap, que a 375 px deja los
   campos de a uno y alarga la pantalla sin necesidad. */
.examen-rejilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: .75rem;
    margin-bottom: 1rem;
}

/* La unidad de un campo numérico (`kg`, `cm`, `x min`): va al lado del control, no dentro de la etiqueta,
   para que la etiqueta siga siendo el nombre del dato. */
.examen-unidad {
    display: flex;
    align-items: center;
    gap: .35rem;
}

.examen-unidad > .form-control { min-width: 0; }

.examen-unidad > span {
    color: var(--ds-texto-3);
    font-size: .85rem;
    white-space: nowrap;
}

/* Los hallazgos por aparatos y el ginecológico: un área de texto por sistema, en dos columnas a 1280 px. */
.examen-hallazgos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: .75rem;
}

.examen-hallazgos textarea { min-height: 5.5rem; resize: vertical; }

/* El bloque de los resúmenes que escribe el escritorio con su botón "Actualizar": texto de lectura, así
   que va sin controles y con el aire de una nota. */
.examen-resumen {
    border-left: 3px solid var(--ds-borde-2);
    padding-left: .75rem;
    margin-bottom: .75rem;
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.examen-resumen:last-child { margin-bottom: 0; }

.examen-resumen-titulo {
    display: block;
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--ds-texto-3);
    margin-bottom: .15rem;
}

/* ==========================================================================
   9b. Web clínica — los bloques de horario dentro del listado de consultorios (A-10)
   ========================================================================== */

/* Cada consultorio muestra sus bloques en su fila y los edita ahí mismo: la celda de los horarios es la que
   se lleva el ancho que sobra. Sin `min-width` a propósito: con la barra lateral desplegada a 1024 px la
   tabla tendría que pedir scroll horizontal, y lo que se prefiere es que el alta de un bloque **envuelva**
   (los controles tienen `min-width: 0`). A 375 px la tabla ya se apila en tarjetas. */
@media (min-width: 768px) {
    .consultorios-tabla .celda-bloques { width: 38%; }
}

@media (min-width: 1200px) {
    .consultorios-tabla .celda-bloques { width: 46%; }
}

.bloques-lista { list-style: none; margin: 0 0 .4rem; padding: 0; }

.bloques-item {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: .5rem;
    padding: .15rem 0;
}

/* El texto no se estira: la papelera de cada bloque va al lado del bloque, no al otro extremo de la celda. */
.bloques-item-texto { flex: 0 1 auto; min-width: 0; overflow-wrap: anywhere; }
.bloques-item .btn { flex: 0 0 auto; }

/* El alta en línea: día · desde · hasta · cupo · Agregar, en una línea si entra y envuelto si no. Los
   controles no se estiran más de lo que necesitan: los de hora y cupo son angostos. */
.bloques-alta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .3rem;
}

.bloques-alta select { flex: 1 1 7rem; min-width: 0; }
.bloques-alta .dias-semana { flex: 1 1 100%; }
.bloques-alta input.hora-ampm { flex: 0 1 7rem; min-width: 0; }
.bloques-alta input[type="number"] { flex: 0 1 4.5rem; min-width: 0; }
.bloques-alta .btn { flex: 0 0 auto; white-space: nowrap; }

/* Los siete días como botones de dos letras que se encienden (`<x-ui.dias-semana>`): el horario de «Lu a Vi» se carga de
   una vez. Cuadrados de tamaño parejo; el encendido es el relleno del primario de `.btn-check:checked`. */
.dias-semana { display: flex; flex-wrap: wrap; gap: .3rem; }
.dias-semana-boton { min-width: 2.5rem; text-align: center; font-weight: 600; }
.dias-semana-compactos .dias-semana-boton { min-width: 2rem; padding-left: .35rem; padding-right: .35rem; }

/* En el celular la tabla es una tarjeta por fila: la celda deja de ser «etiqueta a la izquierda, valor a la
   derecha» y su rótulo pasa arriba, porque adentro va una lista y un formulario. */
@media (max-width: 767.98px) {
    .tabla-tarjetas td.celda-bloques { display: block; text-align: left; }
    .tabla-tarjetas td.celda-bloques::before { display: block; margin-bottom: .25rem; }
    .bloques-alta select,
    .bloques-alta input.hora-ampm,
    .bloques-alta input[type="number"] { flex: 1 1 5rem; }
}

/* Con seis columnas y una barra lateral de 264 px, 12 px de relleno por celda son ~70 px de tabla que a 1024 no
   entran: se ajusta el relleno de esta tabla, no el de todas. Las acciones de la fila van en el menú «…» (A-16). */
@media (max-width: 1199.98px) {
    .consultorios-tabla > :not(caption) > * > * { padding-left: .45rem; padding-right: .45rem; }
}

/* ==========================================================================
   10. Web clínica — los antecedentes del paciente (WEB-4.4)
   ========================================================================== */

/* Los **chips de tipo** de la sección de antecedentes (A-06): el filtro de las dos columnas. Siempre hay uno
   elegido (no hay «todos»), así que son enlaces con su `aria-current`. Cuando no entran **desbordan en
   horizontal** —no se envuelven a varias líneas, que fue un pedido explícito— y la fila se puede deslizar. */
.chips-filtro {
    display: flex;
    flex-wrap: nowrap;
    gap: .4rem;
    overflow-x: auto;
    padding-bottom: .35rem;
    margin-bottom: .75rem;
    -webkit-overflow-scrolling: touch;
}

.chip-filtro {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: .25rem .75rem;
    border: 1px solid var(--ds-borde-control);
    border-radius: 999px;
    background: var(--ds-superficie);
    color: var(--ds-texto-2);
    font-size: .85rem;
    font-weight: 500;
    line-height: 1.3;
    text-decoration: none;
    white-space: nowrap;
}

.chip-filtro:hover { background: var(--ds-violeta-50); border-color: var(--ds-violeta-200); color: var(--ds-violeta-800); }

/* El elegido: fondo de marca y texto blanco (AA sobre `--ds-violeta-700`), y no depende sólo del color —
   lleva `aria-current` y el borde más grueso. */
.chip-filtro.activo {
    background: var(--ds-violeta-700);
    border-color: var(--ds-violeta-700);
    color: #fff;
    font-weight: 600;
}

.chip-filtro.activo:hover { background: var(--ds-violeta-800); border-color: var(--ds-violeta-800); color: #fff; }

/* En el celular los chips miden 40 px de alto: son objetivos táctiles (guía de UI §7). */
@media (max-width: 575.98px) {
    .chip-filtro { min-height: 40px; padding: .4rem .8rem; }
}

/* La fila de cada antecedente del paciente (el `.antecedentes-grupo` de los tipos se fue con los chips: la
   columna muestra **un** tipo, el del chip elegido). */

.antecedentes-lista { list-style: none; margin: 0; padding: 0; }

.antecedentes-item {
    padding: .55rem 0;
    border-bottom: 1px solid var(--ds-borde);
}

.antecedentes-item:last-child { border-bottom: 0; }

/* La fila con la casilla de Alerta: fondo ámbar suave y barra a la izquierda. El color no es la única
   señal —la casilla está tildada y la pastilla del encabezado lo cuenta—, como pide la guía de UI §1. */
.antecedentes-item-alerta {
    background: var(--ds-aviso-bg);
    border-left: 3px solid var(--ds-aviso-borde);
    border-radius: var(--ds-radio);
    padding-left: .6rem;
    padding-right: .6rem;
}

.antecedentes-item-texto {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
}

.antecedentes-item-datos { flex: 1 1 auto; min-width: 0; }

.antecedentes-nombre {
    display: block;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.antecedentes-item-datos .form-control { margin-top: .25rem; }

/* La casilla de Alerta, a la derecha del nombre: `flex: 0 0 auto` para que no se estire con el texto. */
.antecedentes-alerta {
    flex: 0 0 auto;
    margin-top: .1rem;
    white-space: nowrap;
}

.antecedentes-acciones {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex: 0 0 auto;
}

/* Una fila marcada para quitar: se atenúa y el nombre se tacha **sólo acá**, porque el borrado todavía no
   pasó (la guía de UI prohíbe tachar como estado de un dato terminado; esto es una acción pendiente). */
.antecedentes-item-quitado { opacity: .55; }

.antecedentes-item-quitado .antecedentes-nombre,
.antecedentes-item-quitado .antecedentes-item-datos .form-control { text-decoration: line-through; }

@media (max-width: 575.98px) {
    .antecedentes-item-texto { flex-wrap: wrap; }
    .antecedentes-item-datos { flex-basis: 100%; }
    .antecedentes-alerta,
    .antecedentes-acciones { order: 2; }
}

/* ---------------------------------------------------------------------------
   Sección de diagnósticos de la consulta (WEB-4.5, ítem 8)
   Misma forma que los antecedentes: una fila con su nombre, el detalle editable y el botón de quitar.
   ========================================================================== */

.diagnosticos-lista { list-style: none; margin: 0; padding: 0; }

.diagnosticos-item {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .55rem 0;
    border-bottom: 1px solid var(--ds-borde);
}

.diagnosticos-item:last-child { border-bottom: 0; }

.diagnosticos-item-datos { flex: 1 1 auto; min-width: 0; }

.diagnosticos-nombre {
    display: block;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.diagnosticos-item-datos .form-control { margin-top: .25rem; }

.diagnosticos-acciones {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex: 0 0 auto;
}

/* Una fila marcada para quitar: se atenúa y el nombre se tacha **sólo acá**, porque el borrado todavía no
   pasó (la guía de UI prohíbe tachar como estado de un dato terminado; esto es una acción pendiente). */
.diagnosticos-item-quitado { opacity: .55; }

.diagnosticos-item-quitado .diagnosticos-nombre,
.diagnosticos-item-quitado .diagnosticos-item-datos .form-control { text-decoration: line-through; }

@media (max-width: 575.98px) {
    .diagnosticos-item { flex-wrap: wrap; }
    .diagnosticos-item-datos { flex-basis: 100%; }
    .diagnosticos-acciones { order: 2; }
}

/* ---------------------------------------------------------------------------
   Sección de evolución de la consulta (WEB-4.6, ítem 9)
   El campo de texto (el mismo patrón de la enfermedad actual) y, al lado, la lista de las plantillas del
   escritorio: cada una es un botón que copia su texto en el campo, como el doble clic del `dw_84`.
   ========================================================================== */

/* Fichas en una fila que se parte: no le quitan ancho al campo de texto. */
.evolucion-plantillas { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }

.evolucion-plantilla {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    max-width: 100%;
    text-align: left;
    padding: .35rem .7rem;
    border: 1px solid var(--ds-borde-2);
    border-radius: 999px;
    background: var(--ds-superficie);
    color: var(--ds-texto);
    cursor: pointer;
}

.evolucion-plantilla:hover { border-color: var(--ds-violeta-700); }

.evolucion-plantilla-titulo {
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* A 375 px cada control tiene que seguir siendo un objetivo táctil cómodo (guía de UI §7). */
@media (max-width: 575.98px) {
    .evolucion-plantilla { padding: .6rem .7rem; }
}

/* ---------------------------------------------------------------------------
   Sección de exámenes e imágenes de la consulta (WEB-4.7, ítem 7)
   La lista de las imágenes cargadas: cada fila dice qué es, de dónde salió el archivo —del servidor o del
   disco de la PC donde lo cargó el escritorio— y ofrece verlo o quitarlo. El icono es el mismo de la
   tarjeta (`bi-image`): la imagen no se incrusta en la lista (una ecografía entera desarmaría la pantalla
   y el archivo se sirve por su ruta autorizada, que se abre en una pestaña).
   ========================================================================== */

.examen-imagen {
    padding: .7rem 0;
    border-top: 1px solid var(--ds-borde);
}

.examen-imagen:first-child { border-top: 0; }

.examen-imagen-icono {
    flex: 0 0 auto;
    width: 2.4rem;
    height: 2.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ds-radio);
    background: var(--ds-violeta-50);
    color: var(--ds-violeta-700);
}

/* A 375 px las acciones de la fila bajan debajo del texto y ocupan el ancho: dos botones apretados al
   lado de un párrafo no se tocan con el dedo (guía de UI §7). */
@media (max-width: 575.98px) {
    .examen-imagen .acciones-fila { display: flex; gap: .5rem; width: 100%; }
    .examen-imagen .acciones-fila .btn { flex: 1 1 auto; }
}

/* El bloque de texto de una imagen se encoge: sin `min-width: 0` su ancho mínimo (el del contenido) empuja la
   fila y la lista desborda a lo ancho en el celular (medido a 375 px: 9 px de scroll horizontal). */
.examen-imagen > .flex-grow-1 { min-width: 0; }

/* --- Enlace "Saltar al contenido" (teclado y lector de pantalla): fuera de pantalla hasta recibir el foco --- */
.saltar-al-contenido {
    position: absolute;
    left: .75rem;
    top: -4rem;
    z-index: 2000;
    padding: .55rem 1rem;
    background: var(--ds-violeta-700);
    color: #fff;
    font-weight: 600;
    border-radius: var(--ds-radio);
    text-decoration: none;
    transition: top .1s ease-out;
}
.saltar-al-contenido:focus { top: .75rem; outline: 3px solid var(--ds-celeste-700); outline-offset: 2px; }
/* El destino del salto recibe el foco por código (`tabindex="-1"`): sin contorno, no es un control. */
.app-contenido:focus { outline: none; }

/* --- Objetivos táctiles en el celular ---
   Los botones y campos `-sm` miden ~31 px: demasiado chicos para el pulgar (la guía de accesibilidad de Apple
   pide 44 px y WCAG 2.5.8 un mínimo de 24). En pantallas angostas se suben a 40 px; en escritorio se
   quedan compactos, que es donde se usa el mouse. */
@media (max-width: 767.98px) {
    .btn-sm,
    .form-control-sm,
    .form-select-sm,
    .pagination .page-link { min-height: 2.5rem; }

    .btn-sm,
    .pagination .page-link { display: inline-flex; align-items: center; justify-content: center; }

    .pagination .page-link { min-width: 2.5rem; }
}


/* ==========================================================================
   8. Autenticación (login) — panel de marca + formulario
   ========================================================================== */

/* Dos columnas en escritorio: a la izquierda la marca con su trama y el lema, a la derecha el formulario.
   En el celular la marca queda como franja arriba y el formulario ocupa el resto. */
body.auth-pagina {
    min-height: 100vh;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    background: var(--ds-fondo);
}

.auth-marca {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2rem;
    padding: 1.25rem 1.5rem;
    background-color: var(--ds-barra);
    color: var(--ds-barra-texto);
    overflow: hidden;
    /* La trama: líneas de pulso muy tenues, el latido del logo repetido. Decorativa. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='140' viewBox='0 0 180 140'%3E%3Cg fill='none' stroke='%23ffffff' stroke-opacity='.07' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M0 35h46l8-18 12 36 10-18h104'/%3E%3Cpath d='M-40 105h46l8-18 12 36 10-18h104'/%3E%3C/g%3E%3C/svg%3E");
    background-size: 180px 140px;
}

.auth-marca-logo {
    display: inline-flex;
    align-items: center;
    gap: .75rem;
    color: var(--ds-barra-texto);
    text-decoration: none;
    align-self: flex-start;
}

.auth-marca-logo .app-marca-ficha {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--ds-radio);
    background: #fff;
    color: var(--ds-violeta-700);
    font-size: 1.4rem;
}

.auth-marca-nombre { font-size: 1.25rem; font-weight: 700; letter-spacing: -.01em; }
.auth-marca-nombre span { color: var(--ds-celeste-200); }

/* El lema sólo aparece cuando hay lugar: en el celular el formulario es lo importante. */
.auth-marca-lema { display: none; }

.auth-lema-titulo {
    margin: 0 0 .75rem;
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -.02em;
}

.auth-lema-texto { margin: 0; max-width: 26rem; color: var(--ds-barra-texto-2); font-size: .95rem; }

.auth-formulario {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem 2rem;
}

.login-card {
    width: 100%;
    max-width: 26rem;
    padding: 1.5rem;
    box-shadow: var(--ds-sombra-2);
}

.auth-titulo {
    margin: 0 0 .35rem;
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--ds-tinta);
}

.auth-links a {
    color: var(--ds-celeste-700);
    text-decoration: none;
    font-weight: 500;
    font-size: .875rem;
}

.auth-links a:hover { text-decoration: underline; }

/* «¿Dónde quieres entrar?»: una tarjeta-enlace por área (sólo aparece si la cuenta tiene más de una). */
.auth-panel-opciones { display: grid; gap: .75rem; }

.auth-panel-opcion {
    display: flex;
    align-items: center;
    gap: .9rem;
    padding: .9rem 1rem;
    border: 1px solid var(--ds-borde-control);
    border-radius: var(--ds-radio);
    background: var(--ds-superficie);
    color: var(--ds-tinta);
    text-decoration: none;
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}

.auth-panel-opcion:hover,
.auth-panel-opcion:focus-visible {
    border-color: var(--ds-violeta-700);
    background: var(--ds-violeta-50);
    color: var(--ds-tinta);
    text-decoration: none;
}

.auth-panel-opcion:focus-visible { outline: 2px solid var(--ds-violeta-700); outline-offset: 2px; }

.auth-panel-opcion-icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--ds-radio);
    background: var(--ds-violeta-50);
    color: var(--ds-violeta-700);
    font-size: 1.3rem;
}

.auth-panel-opcion-texto { display: flex; flex-direction: column; min-width: 0; }
.auth-panel-opcion-titulo { font-weight: 700; }
.auth-panel-opcion-descripcion { color: var(--ds-texto-2); font-size: .85rem; }

.auth-panel-opcion-flecha { margin-left: auto; color: var(--ds-texto-2); flex: none; }

/* Selector del tipo de usuario */
.user-type-selector .btn { border-color: var(--ds-borde-control); color: var(--ds-texto-2); }
.user-type-selector .btn:hover { background: var(--ds-violeta-50); color: var(--ds-violeta-800); }
.user-type-selector .btn-check:checked + .btn {
    background-color: var(--ds-violeta-700);
    border-color: var(--ds-violeta-700);
    color: #fff;
}

.disabled-group { opacity: .55; pointer-events: none; }

.acceso-sistema {
    background: var(--ds-superficie-2);
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    padding: .6rem .85rem;
}

@media (min-width: 992px) {
    body.auth-pagina {
        grid-template-columns: minmax(22rem, 5fr) 7fr;
        grid-template-rows: 1fr;
    }

    .auth-marca { padding: 2.5rem 3rem; min-height: 100vh; }
    .auth-marca-lema { display: block; }
    .auth-formulario { padding: 2rem; }
    .login-card { padding: 2rem; }
}


/* ==========================================================================
   9. Indicador de carga (`<x-ui.cargando>`)
   ========================================================================== */

.cargando {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: .15rem;           /* el texto casi toca el icono: el SVG ya está recortado a su contenido */
    color: var(--ds-violeta-700);
}

.cargando-icono { height: 7rem; width: auto; overflow: visible; }  /* el latido de la campana no se recorta */
.cargando-sm .cargando-icono { height: 2.75rem; }
.cargando-lg .cargando-icono { height: 10rem; }

.cargando-campana { fill: var(--ds-superficie); }
.cargando-latido { fill: var(--ds-celeste-500); }   /* el latido del logo; decorativo */

.cargando-texto {
    color: var(--ds-texto-3);
    font-size: .75rem;
    font-weight: 500;
    letter-spacing: .2em;
    text-transform: uppercase;
    animation: cargando-parpadeo 1.5s ease-in-out infinite;
}

.cargando-sm .cargando-texto { font-size: .6875rem; letter-spacing: .15em; }
.cargando-lg .cargando-texto { font-size: .8125rem; }

@keyframes cargando-parpadeo {
    0%, 100% { opacity: .55; }
    50%      { opacity: 1; }
}

/* Velo: tapa el contenedor mientras algo carga. El contenedor se vuelve la referencia de la posición. */
.cargando-cubre {
    position: absolute;
    inset: 0;
    z-index: 5;
    justify-content: center;
    background: rgba(246, 245, 249, .85);
    border-radius: inherit;
}

:has(> .cargando-cubre) { position: relative; }

/* Cuando el velo pasa de oculto a visible (Livewire lo muestra con `display: flex`) entra con un fundido. */
.cargando-cubre { animation: velo-entra var(--ds-dur-base) var(--ds-ease); }

@media (prefers-reduced-motion: reduce) {
    .cargando-texto { animation: none; }
}

/* ==========================================================================
   Web clínica — los récipes de la consulta (WEB-5.1 y WEB-5.1b, ítem 10 del panel)
   La lista de los récipes de la consulta (un bloque por récipe, con sus medicamentos) y el editor de uno (una
   fila por medicamento con su cantidad e indicaciones). Mismos tokens y misma forma que las otras secciones.
   ========================================================================== */

.recipe-lista { display: grid; gap: .85rem; }

/* Las dos pestañas de la sección (WEB-5.1b: «Récipes del paciente» / «Récipe de la pareja») y, a su derecha, el
   menú de lo destructivo. En el celular los dos botones se reparten el ancho y, si no caben, el texto se parte
   en lugar de empujar la página. */
.recipe-pestanas-barra {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem .75rem;
}
/* En la columna izquierda de las dos listas (A-04) la barra de la pareja tiene los chips y las acciones en el mismo
   renglón: los chips se quedan con el ancho que sobra y, si no alcanza, las acciones bajan a su renglón. */
.recipe-pestanas-barra .chips { flex: 1 1 12rem; min-width: 0; margin-bottom: 0; }
.recipe-pestanas-barra .recipe-acciones { flex-wrap: wrap; }
.recipe-pestanas { max-width: 100%; }
.recipe-pestanas .btn { white-space: normal; }

/* Las pestañas de las solicitudes de la consulta (WEB-5.3b: seis, y «Dieta / Recomendaciones» es larga): ya no caben en una sola fila del
   grupo de botones ni a 1280 px (la columna de la consulta es angosta) ni a 375 px. Pasan a botones sueltos que **se parten en filas**
   en lugar de empujar la página. Se pide con la clase «pestanas-en-fila»; las dos pestañas de los récipes siguen siendo el grupo unido. */
.btn-group.pestanas-en-fila { display: flex; flex-wrap: wrap; gap: .25rem; }
.btn-group.pestanas-en-fila > .btn.btn { flex: 0 1 auto; margin-left: 0; border-radius: var(--ds-radio); }

.recipe-bloque {
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
    padding: .85rem 1rem;
    background: var(--ds-superficie);
}

.recipe-cabecera {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .6rem;
}

.recipe-cabecera-texto { min-width: 0; }

.recipe-titulo {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 .1rem;
}

.recipe-acciones {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex: 0 0 auto;
}

.recipe-medicamentos { list-style: none; margin: 0; padding: 0; }

.recipe-medicamento {
    display: flex;
    align-items: baseline;
    gap: .65rem;
    padding: .4rem 0;
    border-top: 1px solid var(--ds-borde);
}

.recipe-medicamento:first-child { border-top: 0; }

/* La cantidad en una ficha fija: se lee de un vistazo antes que el nombre. */
.recipe-medicamento-cantidad {
    flex: 0 0 auto;
    min-width: 2rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--ds-violeta-800);
    background: var(--ds-violeta-100);
    border-radius: var(--ds-radio-sm);
    padding: .05rem .4rem;
}

.recipe-medicamento-texto { min-width: 0; }

.recipe-nombre {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.recipe-indicaciones-texto {
    display: block;
    color: var(--ds-texto-2);
    font-size: .875rem;
    white-space: pre-line;
    overflow-wrap: anywhere;
}

/* El editor: una fila por medicamento, con el quitar a la derecha. */
.recipe-editor { list-style: none; margin: 0; padding: 0; }

.recipe-fila {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .65rem 0;
    border-bottom: 1px solid var(--ds-borde);
}

.recipe-fila:first-child { border-top: 1px solid var(--ds-borde); }

.recipe-fila-datos { flex: 1 1 auto; min-width: 0; }

.recipe-generico { margin-left: .25rem; }

.recipe-fila-campos {
    display: flex;
    gap: .75rem;
    margin-top: .35rem;
}

.recipe-cantidad-campo { flex: 0 0 5.5rem; }
.recipe-indicaciones-campo { flex: 1 1 auto; min-width: 0; }

/* El editor de récipes vive en la columna izquierda de `<x-ui.dos-listas>` (A-04): con la sección muy angosta —menos
   de 40rem, o sea dos columnas de menos de ~310 px— la cantidad y las indicaciones ya no entran en la misma línea y se
   apilan. La medida es la de la **sección**, no la de la pantalla (`container-type: inline-size` en `.consulta-seccion`). */
@container (max-width: 40rem) {
    .recipe-fila-campos { flex-wrap: wrap; gap: .4rem; }
    .recipe-indicaciones-campo { flex: 1 1 100%; }
}

.recipe-fila .form-label {
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--ds-texto-3);
    margin-bottom: .15rem;
}

.recipe-quitar { flex: 0 0 auto; }

/* La fila de resultado del buscador (medicamento o tratamiento): el mismo `.resultado-paciente` de los
   otros buscadores en vivo, como `<button>` (agregar al récipe) y no como formulario. */
.resultado-recipe { width: 100%; text-align: left; border: 0; }
/* Lo que ya está en el récipe: el texto se apaga, **no** la fila (con `opacity` el fondo se vuelve translúcido y
   deja ver lo que hay debajo de la lista flotante). */
.resultado-recipe:disabled { cursor: default; }
.resultado-recipe:disabled .resultado-paciente-datos { color: var(--ds-texto-3); }
.resultado-recipe:not(:disabled):hover .resultado-paciente-datos strong { color: var(--ds-violeta-700); }

@media (max-width: 575.98px) {
    .recipe-pestanas { width: 100%; }
    .recipe-pestanas .btn { flex: 1 1 0; min-width: 0; }
    .recipe-pestanas-barra .recipe-pestanas { flex: 1 1 auto; width: auto; }
    .recipe-cabecera { flex-wrap: wrap; }
    .recipe-fila { flex-wrap: wrap; }
    .recipe-fila-datos { flex-basis: 100%; }
    .recipe-quitar { order: 2; margin-left: auto; }
    .recipe-fila-campos { flex-wrap: wrap; }
    .recipe-cantidad-campo { flex-basis: 100%; }
    /* Las acciones de un récipe de la lista (Imprimir, Visualizar, el QR, Editar y el menú) no entran en una línea de
       un teléfono: ocupan su renglón y envuelven, en vez de empujar la página a lo ancho. */
    .recipe-acciones { flex: 1 1 100%; flex-wrap: wrap; justify-content: flex-start; }
}

/* ---------------------------------------------------------------------------------------------------------
   Imprimir el récipe (WEB-5.2)
   --------------------------------------------------------------------------------------------------------- */

/* El diálogo "Imprimir récipe": qué se imprime y con qué nombre sale el medicamento. Dos grupos de opciones
   (botones de radio con su explicación). La vista previa, que no carga esta hoja, tiene un gemelo en
   `clinica-impresion.css`. */
.opciones-impresion .opciones-grupo { margin: 0 0 1rem; padding: 0; border: 0; min-width: 0; }
.opciones-impresion .opciones-grupo .etiqueta { padding: 0; margin-bottom: .4rem; }

.opcion-de-impresion {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .55rem .7rem;
    margin-bottom: .4rem;
    border: 1px solid var(--ds-borde-control);
    border-radius: var(--ds-radio);
    background: var(--ds-superficie);
    cursor: pointer;
}

.opcion-de-impresion:has(input:checked) { border-color: var(--ds-violeta-700); background: var(--ds-violeta-50); }
.opcion-de-impresion input { margin-top: .25rem; accent-color: var(--ds-violeta-700); }
.opcion-de-impresion-texto { display: flex; flex-direction: column; }
.opcion-de-impresion-texto small { color: var(--ds-texto-3); }
.opciones-nota { margin: 0; color: var(--ds-texto-3); font-size: .875rem; }

/* La franja de la sección de récipes con lo que sale al pie de la hoja: la próxima cita ya agendada (o la falta de
   ella) y el atajo para hacer una. */
.recipe-proxima-cita-franja {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem .75rem;
    margin-bottom: 1rem;
    padding: .55rem .75rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    background: var(--ds-fondo);
}

.recipe-proxima-cita-texto { display: flex; align-items: center; gap: .5rem; min-width: 0; }

/* Agendar la próxima cita en el lugar (2026-10-28): el `<details>` de la franja, sin JavaScript. El resumen se ve
   como un botón y el formulario abre debajo, a todo el ancho de la franja. */
.recipe-proxima-cita-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }

.recipe-agendar { position: relative; }

.recipe-agendar > summary {
    list-style: none;
    cursor: pointer;
}

/* Sin el triángulo del navegador: el botón ya dice lo que hace. */
.recipe-agendar > summary::-webkit-details-marker { display: none; }
.recipe-agendar > summary::marker { content: ''; }

.recipe-agendar[open] {
    flex-basis: 100%;
}

.recipe-agendar-form {
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px solid var(--ds-borde);
}

/* Solicitudes de la consulta (WEB-5.3a): el texto base de la constancia y las fechas calculadas del reposo. */
.solicitud-texto-base {
    margin: 0 0 1rem;
    padding: .75rem 1rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    background: var(--ds-fondo);
    color: var(--ds-texto-2);
}

.solicitud-calculo { font-size: 1rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------------------------------------
   Catálogos del médico (WEB-8.1a): medicamentos y tratamientos
   --------------------------------------------------------------------------------------------------------- */

/* Subir y bajar un medicamento del tratamiento (el editor de récipes lo apaga: allí el orden no importa). */
.recipe-orden { display: flex; flex-direction: column; gap: .25rem; flex: 0 0 auto; }

/* Las otras marcas del medicamento, en el diálogo: tres campos de una línea cada uno. */
.catalogo-marcas { display: grid; gap: .5rem; }

@media (max-width: 575.98px) {
    .recipe-orden { order: 2; flex-direction: row; }
    .recipe-orden .btn { min-width: 2.5rem; min-height: 2.5rem; }
}

/* El filtro por tipo de examen, junto al buscador. */
.buscador .catalogo-filtro { width: auto; min-width: 10rem; max-width: 100%; }

/* ---------------------------------------------------------------------------------------------------------
   Formato de impresión del médico (WEB-8.2)
   --------------------------------------------------------------------------------------------------------- */

/* La vista previa se queda a la vista mientras se editan las secciones (en pantallas anchas). */
@media (min-width: 1200px) {
    .formato-previa { position: sticky; top: 1rem; }
}

/* El marco con la hoja de ejemplo: A4 horizontal (297 × 210 mm) más un poco de aire del fondo de la vista. */
.formato-previa-marco {
    display: block;
    width: 100%;
    aspect-ratio: 297 / 218;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    background: var(--ds-fondo);
}

/* La imagen actual (logo, firma o sello) junto al control para reemplazarla. */
.formato-imagen { display: flex; align-items: flex-start; gap: 1rem; }
.formato-imagen-controles { flex: 1 1 auto; min-width: 0; }

/* Los formatos en blanco (WEB-5.5b): una fila por documento, con su botón de imprimir a la derecha. */
.lista-en-blanco-fila { padding: .55rem 0; border-top: 1px solid var(--ds-borde); }
.lista-en-blanco-fila:first-child { border-top: 0; padding-top: 0; }
.lista-en-blanco-fila > div { min-width: 0; }
.lista-en-blanco-fila .btn { flex: none; min-height: 40px; display: inline-flex; align-items: center; gap: .35rem; }

.formato-miniatura {
    flex: none;
    width: 7rem;
    height: 5rem;
    object-fit: contain;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    background: var(--ds-superficie);
}

.formato-miniatura-vacia { display: flex; align-items: center; justify-content: center; color: var(--ds-texto-3); font-size: 1.5rem; }

/* Un bloque de texto del membrete con sus opciones. */
.formato-bloque { min-width: 0; margin: 0 0 1rem; padding: .75rem 1rem 1rem; border: 1px solid var(--ds-borde); border-radius: var(--ds-radio); }
.formato-bloque-titulo { float: none; width: auto; margin: 0; padding: 0 .25rem; font-size: 1rem; font-weight: 600; }

/* Los nueve colores de la línea: la muestra es el color de la hoja impresa (no un token de la aplicación). */
.formato-colores { display: flex; flex-wrap: wrap; gap: .4rem; }
.formato-color-muestra { display: inline-block; width: .9rem; height: .9rem; border: 1px solid var(--ds-borde-control); border-radius: 50%; vertical-align: -.1rem; }
.formato-color-negro { background: #000000; }
.formato-color-blanco { background: #ffffff; }
.formato-color-rojo { background: #c62828; }
.formato-color-marron { background: #6d4c41; }
.formato-color-fucsia { background: #d81b60; }
.formato-color-verde { background: #2e7d32; }
.formato-color-gris { background: #757575; }
.formato-color-amarillo { background: #f9a825; }
.formato-color-azul { background: #1565c0; }

.formato-alineacion .btn { min-width: 2.75rem; }

@media (max-width: 575.98px) {
    .formato-imagen { flex-direction: column; }
    .formato-alineacion .btn, .formato-colores .btn { min-height: 2.5rem; }
}

/* --- Órdenes de la consulta: laboratorio y estudios (WEB-5.4) ---
   La lista de lo que lleva la orden (una fila por examen o estudio, con su «Quitar»), el buscador del catálogo con su filtro por tipo
   y las rutinas (un botón por tipo de examen). Los estudios van numerados con un contador de CSS, así que una fila que el script agrega
   toma su número sin tocar nada. */
.orden-lista {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: .5rem;
}

.orden-fila {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem .5rem .4rem .75rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    background: var(--ds-superficie);
}

.orden-fila-datos { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; font-size: .9rem; }
.orden-nombre { font-weight: 500; }
.orden-quitar { flex: 0 0 auto; }

.orden-lista-numerada { grid-template-columns: 1fr; counter-reset: orden; }
.orden-lista-numerada .orden-fila::before {
    counter-increment: orden;
    content: counter(orden) ".";
    flex: 0 0 auto;
    min-width: 1.5rem;
    font-variant-numeric: tabular-nums;
    color: var(--ds-texto-3);
}

.orden-buscador { display: flex; flex-wrap: wrap; gap: .5rem; }
.orden-buscador .buscador-campo { flex: 1 1 14rem; }
.orden-buscador .form-select { flex: 0 1 14rem; }

.orden-subtitulo {
    margin: 0 0 .25rem;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ds-texto-3);
}

.orden-rutinas { display: flex; flex-wrap: wrap; gap: .4rem; }

/* La columna derecha de una orden (A-04) es el catálogo con su buscador a la vista. Los resultados van **en línea**
   debajo del buscador (no son un desplegable flotante) y cada fila mide **una sola línea**: el nombre se trunca con
   puntos suspensivos (el completo va en el `title`), el tipo va como chip y «Agregar» queda a la derecha. La fila
   usa `.dos-listas-fila`, así que hereda el renglón y el modo compacto de las otras dos listas. */
.orden-resultados {
    margin-top: .5rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    max-height: 18rem;
    overflow-y: auto;
}

.orden-resultado { width: 100%; text-align: left; }
.orden-resultado-datos { display: flex; align-items: center; gap: .4rem; flex: 1 1 auto; min-width: 0; overflow: hidden; }
.orden-resultado-datos strong { font-size: .9rem; }
.orden-resultado-datos [data-resultado-detalle] { flex: 0 1 auto; min-width: 0; max-width: 45%; }
.orden-resultado-datos [data-resultado-detalle]:empty { display: none; }
/* El dato secundario (el tipo del examen, el principio activo del medicamento) no empuja el nombre fuera de la fila: se
   recorta con puntos suspensivos y el texto completo queda en su `title`. */
.orden-resultado-datos .chip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.orden-resultado [data-resultado-accion] { flex: 0 0 auto; white-space: nowrap; }

/* En una sección angosta el tipo del examen es lo secundario: se va de la fila —el nombre se queda con el ancho y el
   tipo sigue en el `title`—. Con la sección ancha (1366) el tipo va como chip al lado del nombre. */
@container (max-width: 46rem) {
    .dos-listas .orden-resultado [data-resultado-detalle] { display: none; }
}

@media (max-width: 575.98px) {
    .orden-quitar { min-width: 40px; min-height: 40px; }
    .orden-rutinas .btn { min-height: 40px; }
}

/* ---------------------------------------------------------------------------------------------------------
   Mensajes a pacientes (WEB-8.4)
   --------------------------------------------------------------------------------------------------------- */

/* Los botones de etiquetas del editor: se parten en varias líneas si no caben. */
.plantilla-etiquetas { display: flex; flex-wrap: wrap; gap: .4rem; }

/* El mensaje de ejemplo: una burbuja de texto plano, con los saltos de línea que escribió el médico. */
.plantilla-previa {
    padding: .75rem 1rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
    background: var(--ds-violeta-50);
    color: var(--ds-texto);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    min-height: 4rem;
}

/* Contadores de caracteres y de SMS, y los avisos de la plantilla (una etiqueta que no existe, falta de {paciente}…). */
.plantilla-contadores { font-variant-numeric: tabular-nums; }
.plantilla-avisos { display: grid; gap: .35rem; }
.plantilla-aviso {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    padding: .4rem .65rem;
    border: 1px solid transparent;
    border-radius: var(--ds-radio-sm);
    font-size: .875rem;
}
.plantilla-aviso > span { min-width: 0; overflow-wrap: anywhere; }
.plantilla-aviso-aviso { background: var(--ds-aviso-bg); border-color: var(--ds-aviso-borde); color: var(--ds-aviso); }
.plantilla-aviso-info { background: var(--ds-info-bg); border-color: var(--ds-info-borde); color: var(--ds-info); }

@media (max-width: 575.98px) {
    .plantilla-etiquetas .btn { min-height: 40px; }
}

/* Los filtros de la bitácora (WEB-8.5): fechas, quién, tipo de dato y paciente en una rejilla que baja a una columna en el celular. */
.bitacora-filtros {
    flex: 1 1 100%;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    align-items: end;
    gap: .6rem .9rem;
}
.bitacora-filtros .campo { min-width: 0; }
.bitacora-filtros .form-label { margin-bottom: .2rem; font-size: .8125rem; color: var(--ds-texto-2); }
.bitacora-filtro-paciente { grid-column: span 2; }
.bitacora-filtros-botones { display: flex; flex-wrap: wrap; gap: .5rem; }
.bitacora-filtros-ayuda { grid-column: 1 / -1; margin: 0; }
.bitacora-paginas { display: flex; flex-wrap: wrap; gap: .5rem; }

@media (max-width: 575.98px) {
    .bitacora-filtros { grid-template-columns: 1fr; }
    .bitacora-filtro-paciente { grid-column: auto; }
}

/* La clave temporal de una cuenta nueva o restablecida (WEB-8.5): grande, de ancho fijo y que se selecciona de un clic. */
.clave-temporal-tarjeta { border-color: var(--ds-aviso-borde); background: var(--ds-aviso-bg); }
.clave-temporal {
    display: inline-block;
    padding: .2rem .6rem;
    border: 1px solid var(--ds-borde-control);
    border-radius: var(--ds-radio-sm);
    background: var(--ds-superficie);
    color: var(--ds-texto);
    font-size: 1.15rem;
    letter-spacing: .08em;
    user-select: all;
    overflow-wrap: anywhere;
}

/* Los filtros de un listado entre fechas (WEB-6.8): rango, edades y el modo por semanas en una rejilla que se
   apila en el celular. Misma forma que la de la bitácora, con nombre propio para que las dos pantallas no
   queden atadas la una a la otra. */
.listados-filtros {
    flex: 1 1 100%;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    align-items: end;
    gap: .6rem .9rem;
}
.listados-filtros .campo { min-width: 0; }
.listados-filtros .form-label { margin-bottom: .2rem; font-size: .8125rem; color: var(--ds-texto-2); }
.listados-filtro-semanas .form-check { min-height: 2.25rem; display: flex; align-items: center; gap: .4rem; }
.listados-filtros-botones { display: flex; flex-wrap: wrap; gap: .5rem; }
.listados-filtros-ayuda { grid-column: 1 / -1; margin: 0; }

@media (max-width: 575.98px) {
    .listados-filtros { grid-template-columns: 1fr; }
}

/* El listado de consultas por rango tiene siete columnas con listas dentro de la celda: entre el celular (donde la
   tabla ya se apila en tarjetas) y el escritorio no entra a lo ancho, así que desplaza **su propio** contenedor en
   vez de la página y la identidad del paciente no se aplasta hasta una letra por renglón. */
.listados-tabla-ancha { overflow-x: auto; }
.listados-tabla-ancha td.celda-principal { min-width: 12rem; }
@media (max-width: 767.98px) {
    .listados-tabla-ancha { overflow-x: visible; }
    .listados-tabla-ancha td.celda-principal { min-width: 0; }
}

/* ---------------------------------------------------------------------------------------------------------
   Chips de navegación (WEB-11.1): reemplazan las pestañas que se envolvían. Una sola fila que se desplaza
   en horizontal cuando no entran; el elegido resaltado. Sin barra de desplazamiento visible pero usable con
   rueda, dedo y teclado (cada chip es un enlace enfocable).
   --------------------------------------------------------------------------------------------------------- */
.chips {
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;
    padding-bottom: .25rem;
}
.chips-lista {
    display: flex;
    flex-wrap: nowrap;
    gap: .4rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
.chip-opcion {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    padding: 0 .9rem;
    border: 1px solid var(--ds-borde-control);
    border-radius: 999px;
    background: var(--ds-superficie);
    color: var(--ds-texto-2);
    font-size: .875rem;
    white-space: nowrap;
    text-decoration: none;
}
.chip-opcion:hover { background: var(--ds-violeta-50); color: var(--ds-violeta-700); }
.chip-opcion.activo {
    background: var(--ds-violeta-700);
    border-color: var(--ds-violeta-700);
    color: #fff;
    font-weight: 600;
}
@media (max-width: 575.98px) {
    .chip-opcion { min-height: 40px; }
}

/* ---------------------------------------------------------------------------------------------------------
   Plantillas: botón que abre el cajón (revisión de Alexander, 2026-10-17)
   ---------------------------------------------------------------------------------------------------------
   El panel de plantillas ya no ocupa una franja arriba del campo: arriba va **sólo el botón** (con el conteo
   de plantillas) y el buscador, la lista y «Guardar como plantilla» viven en un cajón lateral
   (`<x-ui.dialogo lateral>`), así el campo queda visible desde el principio. */
.plantillas-disparador { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.plantillas-cajon { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.plantillas-cajon .plantillas-lista { flex: 1 1 auto; max-height: none; }

.plantillas-lista {
    list-style: none;
    margin: 0 0 .75rem;
    padding: 0;
    max-height: 22rem;
    overflow-y: auto;
}
.plantillas-lista [hidden] { display: none; }
.plantillas-item {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    width: 100%;
    padding: .45rem .5rem;
    border: 0;
    border-radius: var(--ds-radio-sm);
    background: transparent;
    color: var(--ds-texto);
    text-align: left;
    overflow-wrap: anywhere;
}
.plantillas-item:hover { background: var(--ds-violeta-50); color: var(--ds-violeta-700); }
.plantillas-guardar > summary { list-style: none; cursor: pointer; }
.plantillas-guardar > summary::-webkit-details-marker { display: none; }
@media (max-width: 575.98px) {
    .plantillas-item { padding: .7rem .5rem; }
}

/* ---------------------------------------------------------------------------------------------------------
   «Dos listas con Pasar / Eliminar / Agregar» (WEB-11.3)
   ---------------------------------------------------------------------------------------------------------
   El ancho que decide es el del **área de la sección**, no el de la pantalla (revisión de Alexander,
   2026-10-17). Antes había un `@media (max-width: 1399.98px)` que apilaba las dos columnas y a 1366 px —la
   pantalla del consultorio— el catálogo se iba abajo; **plegar el menú lateral no lo arreglaba** porque el
   viewport sigue midiendo 1366. Por eso `.consulta-seccion` es un *contenedor de consulta*
   (`container-type: inline-size`) y el modo compacto y el apilado se preguntan por SU ancho. */
.consulta-seccion { container-type: inline-size; }

.dos-listas {
    display: grid;
    /* Las dos listas, siempre lado a lado: el catálogo a la derecha es el punto de la pantalla. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}
.dos-listas-columna {
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
    background: var(--ds-superficie);
    padding: .85rem 1rem;
}
.dos-listas-cabecera {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .75rem;
}
.dos-listas-titulo { margin: 0; font-size: 1rem; font-weight: 600; }
.dos-listas-acciones { display: inline-flex; align-items: center; gap: .35rem; flex-shrink: 0; }
.dos-listas-buscar { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-bottom: .75rem; }
.dos-listas-buscar .form-control { flex: 1 1 10rem; min-width: 0; }
.dos-listas-catalogo { list-style: none; margin: 0; padding: 0; }
/* Las páginas del catálogo a la vista envuelven **siempre**: con un catálogo largo (once páginas) la fila de enlaces no
   entra en la columna derecha y empujaba el ancho de la página (scroll horizontal a 768 px). */
.dos-listas .pagination { flex-wrap: wrap; margin-bottom: 0; }
.dos-listas-fila {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .4rem .25rem;
    border-bottom: 1px solid var(--ds-borde);
}
.dos-listas-fila[data-pasar] { cursor: pointer; }
.dos-listas-fila[data-pasar]:hover { background: var(--ds-violeta-50); }
.dos-listas-fila-texto { overflow-wrap: anywhere; }
.dos-listas-fila .btn { flex-shrink: 0; white-space: nowrap; }

/* Modo compacto (por el ancho de la sección, no de la pantalla): letra y relleno más chicos y las acciones
   de cada fila —«Pasar», «Eliminar»— en **sólo icono**, con su `title` y su `aria-label` (el rótulo vive en
   `.dos-listas-boton-texto`). El objetivo táctil no baja de 40 px de alto. */
@container (max-width: 45rem) {
    .dos-listas { gap: .5rem; font-size: .8rem; }
    .dos-listas-columna { padding: .5rem .6rem; }
    .dos-listas-cabecera { gap: .35rem; margin-bottom: .5rem; }
    .dos-listas-titulo { font-size: .85rem; }
    .dos-listas-buscar { gap: .25rem; margin-bottom: .5rem; }
    .dos-listas-buscar .form-control,
    .dos-listas-buscar .btn { font-size: .8rem; }
    .dos-listas-fila { gap: .35rem; padding: .3rem .15rem; }
    .dos-listas .chip { padding: .05rem .4rem; font-size: .65rem; }
    .dos-listas-fila .btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: .3rem;
        min-width: 40px;
        min-height: 40px;
        padding: .25rem .4rem;
        font-size: .8rem;
    }
    .dos-listas-boton-texto { display: none; }
    /* Las filas de Bootstrap (`.row g-2`) sangran a los costados con márgenes negativos: en una columna de
       200 px eso es scroll horizontal de la página. */
    .dos-listas .row { margin-left: 0; margin-right: 0; }
    /* Y sus 9/12 + 3/12 no dejan lugar para el botón «Buscar»: el campo y el botón van uno debajo del otro. */
    .dos-listas .row > [class*="col-md-"] { flex: 0 0 100%; max-width: 100%; }
    /* Las páginas del catálogo no entran en una columna angosta: envuelven en vez de desbordar. */
    .dos-listas .pagination { flex-wrap: wrap; gap: .15rem; margin-bottom: 0; font-size: .8rem; }
    .dos-listas .page-link { padding: .2rem .45rem; }
}

/* Piso: las dos listas se apilan **sólo** cuando la sección mide 352 px o menos —en un teléfono la columna
   de trabajo queda en ~335 px—, porque ahí cada columna baja de ~160 px y el texto clínico ya no se lee. Con
   el menú desplegado a 1024 px la sección mide ~413 px y sigue lado a lado (dos columnas de ~198 px con la
   letra del modo compacto): es lo que pidió Alexander. A 600 px de ventana la sección mide ~568 px. */
@container (max-width: 22rem) {
    .dos-listas { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------------------------------------------------
   La fila del encabezado de la consulta (A-11): volver + identidad del paciente + navegador 1…N + acciones
   ---------------------------------------------------------------------------------------------------------
   Una sola fila de ~48 px. Antes la consulta tenía tres bloques arriba (la barra de contexto del armazón, el
   encabezado del paciente y la barra de la consulta) que ocupaban ~185 px en una pantalla de 768. El nombre ya no
   es un título: tipografía normal y una línea que se recorta con puntos suspensivos (el texto completo va en el
   `title`). En el celular la fila envuelve —identidad, navegador y acciones, cada uno en su renglón— y nunca
   produce scroll horizontal: el navegador se desplaza dentro de su propio ancho. */
.consulta-encabezado {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    margin-bottom: 1rem;
    padding: .35rem .5rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
    background: var(--ds-superficie);
}
.consulta-volver {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border: 1px solid transparent;
    border-radius: var(--ds-radio);
    color: var(--ds-texto-2);
    text-decoration: none;
}
.consulta-volver:hover { background: var(--ds-violeta-50); color: var(--ds-violeta-700); }
.consulta-identidad {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    flex: 1 1 12rem;
    min-width: 0;
    margin: 0;
    font-size: .875rem;
    color: var(--ds-texto-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.consulta-paciente { font-weight: 600; color: var(--ds-tinta); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* La edad no se recorta: en una pantalla angosta se recortan el nombre y el resto de la línea (Alexander, 2026-10-29). */
.consulta-edad { flex: 0 0 auto; white-space: nowrap; }
.consulta-datos { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.consulta-barra-navegador { display: flex; align-items: center; gap: .5rem; flex: 0 1 auto; min-width: 0; max-width: 100%; }
.consulta-encabezado .consulta-barra-navegador .chips { padding-bottom: 0; }
.consulta-encabezado .consulta-barra-navegador .chip-opcion {
    min-height: 30px;
    padding: 0 .55rem;
    border-radius: var(--ds-radio-sm);
    font-size: .8125rem;
}
.consulta-barra-acciones { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: .5rem; margin-left: auto; }
.consulta-barra-estado { min-width: 5rem; text-align: right; }
.consulta-barra-estado.es-error { color: var(--ds-peligro); font-weight: 600; }

@media (max-width: 575.98px) {
    /* En el celular los objetivos táctiles siguen midiendo 40 px; el navegador va en su propio renglón y se
       desplaza dentro de su ancho (los chips ya lo hacen: `.chips { overflow-x: auto }`). */
    .consulta-encabezado .consulta-barra-navegador .chip-opcion { min-height: 40px; }
    .consulta-barra-acciones { margin-left: 0; gap: 0; }
    .consulta-barra-estado { min-width: 0; text-align: left; }
    /* **La ayuda entra en la fila de acciones también en el teléfono** (O-31): con los botones a su ancho
       normal, Guardar + Terminar + «?» no entran en los ~343 px del encabezado y la ayuda caía a un tercer
       renglón. Se aprieta sólo la fila de acciones (menos separación y menos relleno lateral); el alto táctil
       no cambia. **Con el botón del resumen** (O-30) son cuatro controles: se aprieta un poco más —2 px de
       separación y 1,6 px de relleno por lado— para que sigan entrando en **una** fila. */
    .consulta-barra-acciones .btn { padding-left: .4rem; padding-right: .4rem; font-size: .8125rem; }
    /* El «?» es un control táctil: en el celular mide lo mismo que los demás botones de la fila (40 px). */
    .consulta-encabezado .tour-reabrir-redondo { width: 40px; height: 40px; }
    /* El botón del resumen (O-30) mide lo mismo: es el cuarto control táctil de la fila. */
    .consulta-encabezado .consulta-resumen-boton { width: 40px; height: 40px; }
}

/* ---------------------------------------------------------------------------------------------------------
   Alertas del paciente en la consulta (WEB-11.6): aviso de seguridad clínica, fijo en todas las secciones
   --------------------------------------------------------------------------------------------------------- */
.consulta-alertas {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    margin-bottom: 1rem;
    padding: .75rem 1rem;
    border: 1px solid var(--ds-peligro-borde);
    border-radius: var(--ds-radio-card);
    background: var(--ds-peligro-bg);
    color: var(--ds-peligro);
}
.consulta-alertas > i { font-size: 1.25rem; line-height: 1.4; }
.consulta-alertas-lista { margin: .25rem 0 0; padding-left: 1.1rem; }

/* «Imprimir la ficha» (WEB-11.25): al imprimir desde la sección de datos sólo sale la ficha, sin el armazón ni el panel. */
@media print {
    body.imprimiendo-ficha * { visibility: hidden; }
    body.imprimiendo-ficha #consulta-datos,
    body.imprimiendo-ficha #consulta-datos * { visibility: visible; }
    body.imprimiendo-ficha #consulta-datos { position: absolute; left: 0; top: 0; width: 100%; }
    body.imprimiendo-ficha [data-imprimir-ficha],
    body.imprimiendo-ficha #consulta-datos button { display: none; }
}

/* El orden del flujo de las gestas (WEB-11.15): los tres pasos del «¿Cómo funciona?» del control prenatal
   (O-23), que antes eran la lista de apertura de la pestaña. */
.pasos-gesta {
    margin: 0 0 1rem;
    padding: .6rem 1rem .6rem 2rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
    background: var(--ds-fondo);
    font-size: .875rem;
    color: var(--ds-texto-2);
}
.pasos-gesta li + li { margin-top: .25rem; }

/* El estado del embarazo (O-21): los tres controles que el escritorio tiene en su barra lateral —Embarazo
   múltiple, Cantidad y Final de embarazo— juntos y discretos al pie de la ficha, no como una fila de campos
   anchos de la misma jerarquía que los datos clínicos. */
.estado-embarazo {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1.5rem;
    margin-top: 1rem;
    padding-top: .75rem;
    border-top: 1px solid var(--ds-borde);
}
.estado-embarazo .form-check { min-height: 0; }
.estado-embarazo-numero { display: flex; align-items: center; gap: .5rem; }
.estado-embarazo-numero .form-control { width: 4.5rem; }

/* Resumen de una consulta anterior (WEB-11.9): respeta los saltos de línea que dejó el escritorio. */
.resumen-anterior-texto { white-space: pre-line; }

/* Lienzos de dibujo clínico (A-13): el marco y las herramientas que comparten las imágenes de mamas (WEB-11.10) y el
   cuello uterino de la colposcopía. Las clases `.mama-*` y `.mamas-*` quedan como alias de las de mamas para no tocar
   su vista ni su aspecto. */
.lienzo-marco, .mama-lienzo-marco { position: relative; width: 100%; max-width: 520px; aspect-ratio: 520 / 400; border: 1px solid var(--ds-borde, #dee2e6); border-radius: .5rem; overflow: hidden; background: #fff; }
.lienzo-base, .lienzo, .mama-lienzo-base, .mama-lienzo { position: absolute; inset: 0; width: 100%; height: 100%; }
.lienzo, .mama-lienzo { touch-action: none; cursor: crosshair; }
.lienzo-muestra, .mamas-muestra { width: 1.5rem; height: 1.5rem; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1px #6c757d; background: var(--muestra, #000); padding: 0; }
.lienzo-muestra:hover, .lienzo-muestra:focus-visible, .mamas-muestra:hover, .mamas-muestra:focus-visible { box-shadow: 0 0 0 2px #0d6efd; }
.lienzos-herramientas .form-control-color { width: 2.5rem; }
/* La **foto real** del estudio (O-09): el marco lo pone la foto —no el 520×400 del esquema— y el lienzo la cubre exacto,
   así la marca cae donde el médico la hizo y la foto se ve a su tamaño. */
.lienzo-marco-foto { position: relative; display: inline-block; width: auto; max-width: min(100%, 620px); aspect-ratio: auto; }
.lienzo-marco-foto .lienzo-base { position: static; display: block; width: auto; max-width: 100%; max-height: 460px; height: auto; }
.lienzo-marco-foto .lienzo { position: absolute; inset: 0; width: 100%; height: 100%; }

/* «Visualizar» (WEB-11.24): la vista previa de un documento en un diálogo grande, con «Modificar» e «Imprimir». */
.dialogo-visualizar { width: min(1100px, 96vw); height: 92vh; max-width: none; padding: 0; border: 0; border-radius: .75rem; box-shadow: 0 1rem 3rem rgba(0, 0, 0, .35); }
.dialogo-visualizar::backdrop { background: rgba(20, 10, 40, .55); }
.dialogo-visualizar-caja { display: flex; flex-direction: column; height: 100%; }
.dialogo-visualizar-cabecera { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; padding: .75rem 1rem; border-bottom: 1px solid var(--ds-borde, #dee2e6); }
.dialogo-visualizar-marco { flex: 1 1 auto; width: 100%; border: 0; background: #f1f1f4; }

/* Tour guiado de la pantalla (A-15): el botón de reabrir, el globo que señala cada elemento y el resalte del
   elemento señalado. El globo es `position: fixed` y lo ubica `public/js/clinica/tour.js` (arriba o abajo del
   elemento, siempre dentro de la ventana); acá sólo se define cómo se ve. Se apoya en los tokens: no hay
   colores ni sombras inventadas. */
.tour-reabrir-fila { display: flex; justify-content: flex-end; margin-bottom: .5rem; }
.tour-reabrir {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .15rem .25rem; border: 0; border-radius: var(--ds-radio-sm);
    background: transparent; color: var(--ds-texto-3);
    font-size: .8125rem; line-height: 1.2;
}
.tour-reabrir:hover { color: var(--ds-violeta-700); text-decoration: underline; }
.tour-reabrir:focus-visible { outline: 2px solid var(--ds-violeta-700); outline-offset: 2px; }
.tour-reabrir .bi { font-size: .95rem; }
/* En el celular el texto no entra al lado del título: queda el «?» con su `aria-label` y su `title`. */
@media (max-width: 575.98px) {
    .tour-reabrir-texto { display: none; }
}

/* **El botón redondo de la consulta** (O-31): la ayuda no ocupa un renglón propio. Vive dentro de la fila del
   encabezado, después de Guardar y Terminar, y mide lo mismo que la flecha de «Volver a la agenda» (36 px),
   que es el alto que la fila ya tenía: no la hace crecer ni la parte en dos. Sin texto, el nombre lo dan el
   `aria-label` y el `title`; el foco visible es el global. */
.tour-reabrir-redondo {
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 auto; width: 36px; height: 36px; padding: 0;
    border: 1px solid var(--ds-borde); border-radius: 50%;
    background: transparent; color: var(--ds-texto-3);
    font-size: 1rem; line-height: 1;
}
.tour-reabrir-redondo:hover { border-color: var(--ds-violeta-700); background: var(--ds-violeta-50); color: var(--ds-violeta-700); }
.tour-reabrir-redondo:focus-visible { outline: 2px solid var(--ds-violeta-700); outline-offset: 2px; }

/* **El botón redondo del cajón de la historia** (O-30): el mismo molde que el «?» de la ayuda —36 px, sin
   texto, con `aria-label` y `title`—, porque vive en la misma fila de ~49 px del encabezado de la consulta y no
   puede hacerla crecer. Abre el panel lateral con el resumen del paciente donde se redacta un documento. */
.consulta-resumen-boton {
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 auto; width: 36px; height: 36px; padding: 0;
    border: 1px solid var(--ds-borde); border-radius: 50%;
    background: transparent; color: var(--ds-texto-3);
    font-size: 1rem; line-height: 1;
}
.consulta-resumen-boton:hover { border-color: var(--ds-violeta-700); background: var(--ds-violeta-50); color: var(--ds-violeta-700); }
.consulta-resumen-boton:focus-visible { outline: 2px solid var(--ds-violeta-700); outline-offset: 2px; }

/* El resumen del paciente dentro del cajón (O-30): el mismo contenido de la pantalla de la historia, con la
   identidad del paciente arriba. En un cajón de ~416 px las tarjetas van sin márgenes de más. */
.resumen-cajon .resumen-panel-identidad {
    display: flex; flex-direction: column; gap: .1rem;
    margin: 0 0 .75rem; padding-bottom: .6rem;
    border-bottom: 1px solid var(--ds-borde);
    font-size: .95rem;
}
.resumen-cajon .resumen-panel .card:last-child { margin-bottom: 0; }
.resumen-cajon .es-error { color: var(--ds-peligro); }

/* El elemento señalado: el JS le pone esta clase para encontrarlo y el borde lo dibuja el anillo del
   `.tour-foco` (que sí queda por encima del velo). */
.tour-resaltado { scroll-margin: 5rem; }

/* El velo del tour (2026-10-20): cubre toda la ventana, transparente, y se come los clics de la pantalla; el
   gris lo pinta la sombra del `.tour-foco`, que deja un hueco claro sobre el elemento señalado. El scroll se
   bloquea en `html.tour-activo`. Va por encima de todo (barra lateral, cajones, menús) y debajo del globo. */
.tour-velo {
    position: fixed;
    inset: 0;
    z-index: 2070;
    background: transparent;
    cursor: default;
}
.tour-foco {
    position: fixed;
    z-index: 2071;
    pointer-events: none;
    border-radius: var(--ds-radio-sm);
    box-shadow: 0 0 0 200vmax rgba(33, 37, 41, .62);
    transition: left .15s ease, top .15s ease, width .15s ease, height .15s ease;
}
/* **El borde que late** (2026-10-29): el contorno del hueco respira para que se distinga de un vistazo qué
   elemento está señalado. Es el único borde del resalte —el `.tour-resaltado` ya no pinta contorno— y su
   opacidad va y viene entre una intensidad baja y la alta; el resplandor violeta acompaña porque la sombra
   se escala con la misma opacidad. Animar sólo `opacity` no obliga a repintar la sombra de 200vmax del
   velo, que es la que cuesta. */
.tour-foco::after {
    content: '';
    position: absolute;
    inset: 0;
    border: 2px solid var(--ds-violeta-700);
    border-radius: inherit;
    box-shadow: 0 0 0 1px rgba(120, 48, 128, .35), 0 0 16px 2px rgba(120, 48, 128, .5),
                inset 0 0 12px rgba(120, 48, 128, .22);
    animation: tour-latido 2.4s ease-in-out infinite;
}
@keyframes tour-latido {
    0%, 100% { opacity: .4; }
    50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .tour-foco { transition: none; }
    /* Sin latido queda encendido y fijo (la regla global lo dejaría en el extremo tenue). */
    .tour-foco::after { animation: none; opacity: .9; }
}
.tour-velo[hidden], .tour-foco[hidden] { display: none; }
html.tour-activo, html.tour-activo body { overflow: hidden; overscroll-behavior: none; }

/* El globo: no tapa el elemento (el JS lo pone arriba o abajo) y a 375 px entra igual. Es modal: el velo de
   arriba bloquea el resto de la pantalla. */
.tour-globo {
    position: fixed;
    z-index: 2080;
    width: min(21rem, calc(100vw - 1rem));
    padding: .75rem .875rem;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio-card);
    background: var(--ds-superficie);
    box-shadow: var(--ds-sombra-3);
    font-size: .875rem;
    color: var(--ds-texto);
}
.tour-globo[hidden] { display: none; }
.tour-globo:focus { outline: none; }
.tour-globo-cuenta { margin: 0 0 .15rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .02em; color: var(--ds-texto-3); }
.tour-globo-titulo { margin: 0 0 .25rem; font-size: 1rem; font-weight: 600; line-height: 1.3; }
.tour-globo-texto { margin: 0 0 .75rem; font-size: .875rem; line-height: 1.45; color: var(--ds-texto-2); }
.tour-globo-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.tour-globo-acciones .btn-link { padding-left: 0; padding-right: 0; color: var(--ds-texto-3); }
.tour-globo-botones { display: flex; gap: .5rem; margin-left: auto; }

/* Los pasos son la fuente del texto: el JS los lee y los pinta en el globo. Nunca se ven. */
.tour-pasos { display: none; }

/* ---------------------------------------------------------------------------------------------
   Las capturas adjuntas de «Ayúdanos a mejorar» (O-25).

   La lista de miniaturas es la misma en el formulario (lo que se va a mandar), en «Mis comentarios»
   (lo ya mandado) y en la bandeja del panel (lo que recibimos). En el celular las miniaturas se
   achican y el «quitar» mantiene los 40 px de objetivo táctil (guia-ui.md §7).
   --------------------------------------------------------------------------------------------- */
.adjuntos-lista {
    display: flex; flex-wrap: wrap; gap: .75rem;
    list-style: none; padding: 0; margin: 1rem 0 0;
}
.adjuntos-lista-chica { gap: .5rem; margin-top: .35rem; }
.adjunto {
    position: relative;
    padding: 0;
    margin: 0;
    border: 1px solid var(--ds-borde);
    border-radius: var(--ds-radio);
    background: var(--ds-superficie);
    overflow: hidden;
}
.adjunto a { display: block; line-height: 0; }
.adjunto-miniatura {
    display: block;
    width: 112px; height: 84px;
    object-fit: cover;
    background: var(--ds-fondo);
}
.adjuntos-lista-chica .adjunto-miniatura { width: 64px; height: 48px; }
.adjunto-nombre {
    display: block;
    max-width: 112px;
    padding: .15rem .35rem;
    font-size: .72rem;
    line-height: 1.2;
    color: var(--ds-texto-3);
}
.adjunto-quitar {
    position: absolute;
    top: .2rem; right: .2rem;
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px;
    padding: 0;
    border: 1px solid var(--ds-borde);
    border-radius: 50%;
    background: var(--ds-superficie);
    color: var(--ds-peligro);
    line-height: 1;
    box-shadow: var(--ds-sombra-1);
}
.adjunto-quitar:hover { background: var(--ds-peligro); color: #fff; border-color: transparent; }
.adjunto-quitar:focus-visible { outline: 2px solid var(--ds-violeta-700); outline-offset: 2px; }

@media (max-width: 575.98px) {
    .adjunto-miniatura { width: 92px; height: 70px; }
    .adjunto-nombre { max-width: 92px; }
}

/* ==========================================================================
   Formularios condensados (2026-10-20)
   Pedido del usuario: los formularios desperdiciaban pantalla (tres campos y había que bajar para ver el
   último). Se compacta el espaciado vertical de toda la web, sin tocar el alto de los controles (36 px, §2 de
   la guía), y se ponen en dos columnas la cita (paciente | cita) y el editor de tratamientos (editor | vademécum).
   ========================================================================== */
body.panel .main-content { padding: 1rem 1.25rem 1.25rem; }
.page-head { margin-bottom: .65rem; }
.page-head .page-head-sub { margin-top: .1rem; }
.main-content .card-body { padding: .85rem 1rem; }
.main-content .card-header { padding: .5rem 1rem; }
.main-content .card.mb-3 { margin-bottom: .75rem !important; }
.main-content .row.g-3 { --bs-gutter-y: .6rem; --bs-gutter-x: .85rem; }
.main-content .form-label { margin-bottom: .15rem; font-size: .8125rem; }
.main-content .form-text { margin-top: .15rem; font-size: .78rem; }
.empty-state { padding: 1.1rem 1rem; }
.empty-state > i { font-size: 1.3rem; margin-bottom: .25rem; }

/* Cita: paciente | cita lado a lado. */
.paso { padding: .8rem 1rem; }
.paso-titulo { margin-bottom: .6rem; font-size: .95rem; }
.paso-numero { width: 1.4rem; height: 1.4rem; font-size: .75rem; }
.pasos-columnas { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 992px) {
    .pasos-columnas { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
    .pasos-columnas > .paso { border-bottom: 0; }
    .pasos-columnas > .paso + .paso { border-left: 1px solid var(--ds-borde); }
}
.pasos-columnas + .tarjeta-pie { border-top: 1px solid var(--ds-borde); }

/* Editor de tratamientos: el editor a la izquierda y el vademécum siempre a la vista a la derecha. */
.editor-dos-columnas { display: grid; grid-template-columns: minmax(0, 1fr); gap: .75rem; align-items: start; }
.editor-dos-columnas > * { grid-column: 1 / -1; }
@media (min-width: 1100px) {
    .editor-dos-columnas { grid-template-columns: minmax(0, 1.4fr) minmax(18rem, 1fr); }
    .editor-dos-columnas > form { grid-column: 1; grid-row: 1; }
    .editor-dos-columnas > #recipe-herramientas {
        grid-column: 2; grid-row: 1; margin-top: 0 !important;
        position: sticky; top: 4.5rem;
    }
}

/* Ficha del paciente: «Quién es» a todo el ancho y las otras dos tarjetas lado a lado (si la sección mide >= 60rem). */
.campos-paciente { container-type: inline-size; }
.campos-paciente-rejilla { display: grid; grid-template-columns: minmax(0, 1fr); gap: .75rem; margin-bottom: .75rem; align-items: start; }
.campos-paciente-rejilla > .card { margin-bottom: 0 !important; }
@container (min-width: 60rem) {
    .campos-paciente-rejilla { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .campos-paciente-rejilla > .campos-paciente-ancha { grid-column: 1 / -1; }
}

/* Barra superior condensada: dos fichas (especialidad y sede) y la cuenta con el nombre completo; lo demás, en su menú. */
.chip-barra { max-width: 22rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-topbar .menu-cuenta > summary { max-width: 18rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 575.98px) { .app-topbar .menu-cuenta > summary > span { display: none; } }
.menu-cuenta-cabecera { display: flex; flex-direction: column; gap: .1rem; padding: .4rem .6rem .5rem; margin-bottom: .25rem; border-bottom: 1px solid var(--ds-borde); }

/* Encabezado y barra más bajos: el título y su subtítulo comparten renglón (el subtítulo pasa abajo si no cabe). */
.app-topbar { min-height: 48px; }
.app-topbar.py-2 { padding-top: .3rem !important; padding-bottom: .3rem !important; }
.app-contenido.p-lg-4 { padding: .85rem 1.25rem 1.25rem !important; }
.page-head .page-head-texto { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: .75rem; row-gap: 0; }
.page-head .page-head-volver { flex: 0 0 100%; margin-bottom: 0; }
.page-head .page-head-sub { margin: 0; }
.jornada-resumen-inline { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .75rem; font-size: .8125rem; padding: .35rem .6rem; }

/* El «i» de <x-ui.info>: un botón chico pegado a la etiqueta y un cuadro flotante bajo ella (contraste AA). */
.info-pista { position: relative; display: inline-block; vertical-align: baseline; }
.info-boton {
    border: 0; background: transparent; padding: 0 .2rem; line-height: 1; cursor: pointer;
    color: var(--ds-info); font-size: .95em;
}
.info-boton:hover, .info-boton[aria-expanded="true"] { color: var(--ds-violeta-700); }
.info-texto {
    position: absolute; top: calc(100% + .3rem); left: 0; z-index: 1080;
    width: max-content; max-width: min(16rem, 80vw); padding: .4rem .6rem;
    background: var(--ds-superficie); color: var(--ds-texto); border: 1px solid var(--ds-borde-2);
    border-radius: 8px; box-shadow: 0 4px 14px rgba(32, 16, 72, .18);
    font-size: .85rem; font-weight: 400; line-height: 1.35; text-align: left; white-space: normal;
}
.info-texto[hidden] { display: none; }


/* ==========================================================================
   Web clínica — Sedes y consultorios (`/clinica/sedes`, 2026-10-20)
   ========================================================================== */

/* Una tarjeta por sede con sus consultorios adentro. La grilla decide por el ancho del contenido (`auto-fill`), no por
   la ventana: plegar el menú lateral suma columnas (trampa 125). A 375 px queda una sola columna. */
.sedes-grilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr));
    gap: 1rem;
    align-items: start;
    margin-bottom: 1rem;
}

.sede-tarjeta .card-titulo { min-width: 0; overflow-wrap: anywhere; }
.sede-tarjeta .card-body { padding-top: .75rem; }

.sede-datos {
    display: flex; flex-wrap: wrap; gap: .1rem .9rem;
    margin: 0 0 .5rem; font-size: .875rem; color: var(--ds-texto-3);
}

.sede-sin-consultorios { margin: 0; font-size: .875rem; color: var(--ds-texto-3); }

.sede-consultorios { list-style: none; margin: 0; padding: 0; }
.sede-consultorio { padding: .6rem 0; border-top: 1px solid var(--ds-borde); }
.sede-consultorio:last-child { padding-bottom: 0; }

/* El menú «…» se queda a la derecha del renglón: lo que envuelve es la identidad (nombre, modalidad, duración). */
.sede-consultorio-cabeza { display: flex; align-items: flex-start; gap: .5rem; }
.sede-consultorio-identidad { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .4rem; flex: 1 1 auto; min-width: 0; padding-top: .2rem; }
.sede-consultorio-identidad > .bi-door-closed { color: var(--ds-violeta-700); }
.sede-consultorio-nombre { overflow-wrap: anywhere; }
.sede-consultorio-cabeza .menu-acciones { flex: 0 0 auto; }

.sede-consultorio-bloques { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; margin-top: .45rem; }

/* Un bloque de horario como pastilla, con su «x» para quitarlo (el `<form>` no ocupa caja). */
.bloque-chip {
    display: inline-flex; align-items: center; gap: .2rem;
    padding: .1rem .15rem .1rem .55rem;
    font-size: .8125rem; line-height: 1.3;
    background: var(--ds-fondo); border: 1px solid var(--ds-borde); border-radius: var(--ds-radio-sm);
}
.bloque-chip abbr { font-weight: 600; text-decoration: none; }
.bloque-chip form { display: contents; }
.bloque-chip-quitar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.75rem; height: 1.75rem; padding: 0;
    border: 0; border-radius: var(--ds-radio-sm); background: transparent; color: var(--ds-texto-3);
}
.bloque-chip-quitar:hover { background: var(--ds-peligro-bg); color: var(--ds-peligro); }

.sede-pie { margin-top: .75rem; }

/* El resto del catálogo de la clínica, plegado. */
.sedes-otras > summary {
    display: inline-flex; align-items: center; gap: .4rem;
    margin-bottom: .75rem; font-weight: 600; color: var(--ds-texto-2); cursor: pointer;
}
.sedes-otras > summary::-webkit-details-marker { display: none; }
.sedes-otras > summary .bi-chevron-right { transition: transform var(--ds-dur-base) var(--ds-ease); }
.sedes-otras[open] > summary .bi-chevron-right { transform: rotate(90deg); }

/* El error que escribe `sedes.js` en la sede rápida (llega por `fetch`, no por `<x-ui.campo>`). */
.campo-error[data-error-de] { display: block; }

/* «Sede creada. ¿Agregar un consultorio?» */
.sede-creada { text-align: center; padding: 1rem 0; }
.sede-creada-icono { display: block; font-size: 2.25rem; color: var(--ds-exito); margin-bottom: .5rem; }
.sede-creada-pregunta { margin: 0; font-size: 1rem; }

@media (max-width: 767.98px) {
    /* Objetivo táctil de 40 px en el celular. */
    .bloque-chip-quitar { width: 2.5rem; height: 2.5rem; }
}

/* ==========================================================================
   Dosis por kilo del medicamento (catálogo del médico y catálogo inicial del admin, 2026-10-21)
   La casilla «La dosis es por kilo» despliega el panel con la fórmula del récipe: sin JS, con `:has()`.
   ========================================================================== */
.dosis-por-kilo:not(:has(.dosis-por-kilo__casilla:checked)) .dosis-por-kilo__panel { display: none; }

/* --- Selector con búsqueda (<x-ui.selector-buscable>) --- */
.selector-buscable { position: relative; }
.selector-buscable .selector-control { position: relative; }
.selector-buscable .selector-entrada { padding-right: 2.5rem; }
.selector-buscable .selector-limpiar {
    position: absolute; top: 0; right: 0; width: 2.75rem; height: 100%; min-height: 2.5rem;
    display: flex; align-items: center; justify-content: center;
    border: 0; background: transparent; color: var(--ds-texto-suave, #6c757d); cursor: pointer;
}
.selector-buscable .selector-limpiar[hidden] { display: none; }
.selector-buscable .selector-popup { background: var(--ds-superficie); border: 1px solid var(--ds-borde); max-height: 18rem; }
.selector-buscable .selector-popup[hidden] { display: none; }
.selector-buscable .selector-opcion { min-height: 2.75rem; display: flex; align-items: center; flex-wrap: wrap; cursor: pointer; overflow-wrap: anywhere; }
.selector-buscable .selector-crear { font-weight: 600; }
.selector-buscable .selector-estado { padding: .6rem .85rem; color: var(--ds-texto-suave, #6c757d); font-size: .9rem; }
.selector-buscable .selector-estado[hidden] { display: none; }
.selector-buscable.tiene-error .selector-entrada { border-color: var(--ds-peligro); }

/* Un campo cuyo rótulo repite el título del grupo (2026-10-23): el rótulo queda sólo para lectores de pantalla. */
.campo.etiqueta-oculta > .form-label { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; padding: 0; margin: -1px; }

/* El análisis evolutivo del internista (MI-4): una línea por valor, dibujada en un SVG del tamaño de la celda. */
.grafica-evolucion { width: 160px; height: 44px; display: block; }
.grafica-evolucion polyline { fill: none; stroke: var(--ds-info); stroke-width: 2; }
.grafica-evolucion circle { fill: var(--ds-info); }
.tabla-evolucion th[scope="row"] { white-space: nowrap; }
