﻿
/* ============================================================================
   Poppins, del repositorio
   ----------------------------------------------------------------------------
   Estaba declarada sólo en la hoja del sitio público, así que el panel —que no
   la carga— se quedaba sin ella y tiraba de Mada, que se bajaba de Google en
   cada pantalla. Aquí la ven las dos plantillas.

   Los archivos son los mismos de siempre, en assets/fonts. Declararla dos veces
   no descarga nada dos veces: el navegador la trae una vez y la reutiliza.
   ========================================================================== */
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 300;
    font-display: swap;
    src: url('../assets/fonts/poppins-v24-latin-300.woff2') format('woff2');
}

@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../assets/fonts/poppins-v24-latin-regular.woff2') format('woff2');
}

@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../assets/fonts/poppins-v24-latin-500.woff2') format('woff2');
}

@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../assets/fonts/poppins-v24-latin-700.woff2') format('woff2');
}

@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 900;
    font-display: swap;
    src: url('../assets/fonts/poppins-v24-latin-900.woff2') format('woff2');
}

/* ============================================================================
   Lenguaje visual común
   ----------------------------------------------------------------------------
   Cada pantalla nueva venía declarando sus propios colores: dashboard.css tenía
   --cm-navy, consultation.css --cm-ink y coupon.css los escribía a mano, todos
   para el mismo gris. Tres nombres para un color es garantía de que un día
   dejan de ser el mismo.

   Aquí están los valores una sola vez, y con ellos las piezas que se repiten
   pantalla tras pantalla: etiquetas de estado, tablas que en el móvil se leen
   como fichas, estados vacíos y el selector deslizante.

   No pisa la plantilla comprada. Se carga después de style.css y sólo define
   clases con prefijo cm-, así que lo que ya funcionaba sigue igual.
   ============================================================================ */

:root {
    /* --- Marca ------------------------------------------------------------ */
    --cm-cyan: #20c0f3;
    --cm-cyan-dark: #0f9fce;
    --cm-cyan-soft: #eaf7fd;
    --cm-mint: #09e5ab;
    --cm-mint-dark: #06b98a;

    /* --- Texto y superficies ---------------------------------------------- */
    --cm-ink: #272b41;          /* titulares y texto principal */
    --cm-gray: #6b7385;           /* texto secundario */
    --cm-gray-light: #9aa4ae;     /* texto terciario, marcas de agua */
    --cm-rule: #e3e8ef;
    --cm-bg: #f7fafc;
    --cm-white: #ffffff;

    /* --- Estado ------------------------------------------------------------
       Semánticos, separados del cian de marca: un aviso no debe depender de
       que mañana no se cambie el color corporativo. */
    --cm-green: #1a9a5f;
    --cm-green-bg: #e6f7ef;
    --cm-amber: #b7791f;
    --cm-amber-bg: #fdf3e2;
    --cm-red: #d64545;
    --cm-red-bg: #fdecec;
    --cm-neutral: #6b7280;
    --cm-neutral-bg: #f1f3f5;

    /* --- Forma ------------------------------------------------------------- */
    --cm-radius-sm: 8px;
    --cm-radius: 12px;
    --cm-radius-lg: 16px;
    --cm-shadow: 0 2px 10px rgba(39, 43, 65, .06);
    --cm-shadow-high: 0 8px 26px rgba(39, 43, 65, .12);

    /* Para códigos e importes: en una proporcional, O y 0 se confunden. */
    --cm-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* ============================================================================
   Etiquetas de estado
   ----------------------------------------------------------------------------
   Un estado se mira de reojo, así que va con color de fondo y no sólo de
   texto: sobre una tabla larga el color es lo primero que se distingue.
   ============================================================================ */

.cm-pill {
    display: inline-block;
    padding: .2rem .6rem;
    border-radius: 999px;
    font-size: .74rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

.cm-pill-on   { background: var(--cm-green-bg);  color: var(--cm-green); }
.cm-pill-end  { background: var(--cm-amber-bg);  color: var(--cm-amber); }
.cm-pill-off  { background: var(--cm-neutral-bg); color: var(--cm-neutral); }
.cm-pill-height { background: var(--cm-red-bg);   color: var(--cm-red); }
.cm-pill-info { background: var(--cm-cyan-soft);   color: var(--cm-cyan-dark); }

/* ============================================================================
   Estado vacío
   ----------------------------------------------------------------------------
   Una tabla sin filas y sin explicación parece rota. Aquí se dice qué falta y
   cómo llenarlo.
   ============================================================================ */

.cm-empty {
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--cm-gray-light);
}

.cm-empty i {
    display: block;
    margin-bottom: .6rem;
    font-size: 2rem;
}

.cm-empty p {
    margin: 0 auto;
    max-width: 42ch;
    font-size: .9rem;
    line-height: 1.5;
}

.cm-empty .btn {
    margin-top: 1rem;
}

/* ============================================================================
   Tablas que en el móvil se leen como fichas
   ----------------------------------------------------------------------------
   Una tabla de seis columnas en un teléfono obliga a arrastrar la pantalla de
   lado, y lo que se busca —el estado, la hora— suele quedar en la columna que
   no se ve. Debajo de 768px cada fila pasa a ser una ficha y cada celda toma
   su rótulo de data-label, sin duplicar marcado.

   Requiere data-label en las celdas. Una celda sin él sale sin rótulo, que es
   lo correcto para la de acciones.
   ============================================================================ */

@media (max-width: 767.98px) {
    .cm-records thead {
        display: none;
    }

    .cm-records,
    .cm-records tbody,
    .cm-records tr,
    .cm-records td {
        display: block;
        width: 100%;
    }

    .cm-records tr {
        margin-bottom: .85rem;
        padding: .5rem .85rem;
        border: 1px solid var(--cm-rule);
        border-radius: var(--cm-radius);
        background: var(--cm-white);
        box-shadow: var(--cm-shadow);
    }

    .cm-records td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        padding: .4rem 0;
        border: 0;
        text-align: right;
    }

    .cm-records td.cm-cell-empty {
        display: none;
    }

    .cm-records td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: .76rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--cm-gray-light);
        text-align: left;
    }

    /* El valor de la ficha tiene que poder encogerse y partirse.

       Un elemento flex no baja de lo que ocupa su contenido, y el tema le pone
       white-space:nowrap a .table-avatar. En la tabla ancha de escritorio eso no
       molesta; aquí dejaba la celda del doctor en 232px con 306px dentro, así
       que el nombre salía cortado —se leía "Dr. J"— y no se sabía de quién era
       el comprobante. El selector lleva table delante para empatar en
       especificidad con la regla del tema; esta hoja carga después. */
    .cm-records td > * {
        min-width: 0;
    }

    /* Un correo largo no tiene por dónde partirse: no lleva espacios, así que se
       quedaba cortado contra el borde de la ficha —"javier.moncayo@demo.citas-m"— y
       no se podía leer entero. Aquí se permite partir dentro de la palabra, que para
       un correo o una dirección es lo correcto. La hora se quedaba igual, sin el
       punto final de "p.m.". */
    .cm-records td {
        overflow-wrap: anywhere;
    }

    /* El valor puede ocupar todo el ancho que le deje el rótulo. Sin esto, un nombre
       de dos palabras se apelotonaba en una columna estrecha mientras quedaba sitio
       libre a su lado. */
    .cm-records td[data-label]::before {
        max-width: 45%;
    }

    table.cm-records td h2.table-avatar {
        white-space: normal;
        align-items: center;
    }

    /* La foto no se encoge; lo que se parte es el nombre. */
    table.cm-records td h2.table-avatar > .avatar {
        flex: 0 0 auto;
    }

    /* La celda de acciones ocupa la ficha entera: dos botones apretados contra
       el borde derecho son difíciles de acertar con el pulgar. */
    .cm-records td:last-child {
        justify-content: flex-end;
        flex-wrap: wrap;
        padding-top: .6rem;
        margin-top: .3rem;
        border-top: 1px dashed var(--cm-rule);
    }
}

/* ============================================================================
   Selector deslizante
   ----------------------------------------------------------------------------
   Las pestañas apiladas de Bootstrap ocupan cuatro líneas en un teléfono. Esto
   es lo que hacen las apps: una fila que se desliza, con la opción activa
   subrayada. Por debajo siguen siendo pestañas de Bootstrap.
   ============================================================================ */

.cm-security {
    position: relative;
    margin-bottom: 1.25rem;
    border-bottom: 1px solid var(--cm-rule);
}

.cm-security__list {
    display: flex;
    /* Bootstrap pone flex-wrap:wrap en .nav y las opciones se partían en dos
       líneas justo en el móvil, que es donde esto tenía que deslizarse. */
    flex-wrap: nowrap;
    gap: .25rem;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
}

.cm-security__list::-webkit-scrollbar {
    display: none;
}

.cm-security__item {
    flex: 0 0 auto;
    scroll-snap-align: start;
}

.cm-security__link {
    display: block;
    padding: .7rem 1rem;
    border-bottom: 2px solid transparent;
    color: var(--cm-gray);
    font-size: .9rem;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
    transition: color .15s ease, border-color .15s ease;
}

.cm-security__link:hover,
.cm-security__link:focus-visible {
    color: var(--cm-ink);
    text-decoration: none;
}

.cm-security__link.active {
    color: var(--cm-cyan-dark);
    border-bottom-color: var(--cm-cyan);
}

/* ── Flechas de la fila de pestañas ────────────────────────────────────────
   La fila se desliza sola con el dedo, pero en un teléfono no se ve que haya
   más opciones a la derecha: "Certificados" quedaba cortada y parecía que las
   pestañas eran tres. Las flechas sólo se ven cuando queda algo por ese lado,
   igual que en el calendario de reserva.

   Sólo desplazan. El contenido de cada pestaña sigue en su propio contenedor y
   no se mueve: esto no cambia de pestaña, sólo enseña las que no caben. */
.cm-security__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;

    display: none;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;

    border: 1px solid var(--cm-rule);
    border-radius: 50%;
    background: rgba(255, 255, 255, .9);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    box-shadow: 0 1px 6px rgba(39, 43, 65, .12);

    color: var(--cm-ink);
    font-size: .8rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color .12s ease, box-shadow .12s ease;
}

/* Sólo aparece la del lado por el que queda algo. */
.cm-security__arrow.cm-security__arrow--visible {
    display: flex;
}

.cm-security__arrow:hover {
    background: var(--cm-white);
    box-shadow: 0 2px 10px rgba(39, 43, 65, .18);
}

.cm-security__arrow--left { left: 0; }
.cm-security__arrow--right { right: 0; }

/* El hueco de la flecha se le quita a la caja, no a la lista: si el relleno va en la
   lista se desplaza con ella y acaba al final del recorrido, así que la flecha seguía
   tapando la última opción que se ve. En la caja, que no se mueve, el hueco se queda
   donde tiene que estar. La línea de abajo sigue de lado a lado. */
.cm-security:has(.cm-security__arrow--left.cm-security__arrow--visible) { padding-left: 2.6rem; }
.cm-security:has(.cm-security__arrow--right.cm-security__arrow--visible) { padding-right: 2.6rem; }

@media (prefers-reduced-motion: reduce) {
    .cm-security__list { scroll-behavior: auto; }
}

/* Contador junto al nombre: dice si vale la pena entrar antes de entrar. */
.cm-security__n {
    display: inline-block;
    margin-left: .35rem;
    padding: .05rem .4rem;
    border-radius: 999px;
    background: var(--cm-neutral-bg);
    color: var(--cm-gray);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
}

.cm-security__link.active .cm-security__n {
    background: var(--cm-cyan-soft);
    color: var(--cm-cyan-dark);
}

/* En pantallas anchas caben todas, así que se reparten y se pierde el aire de
   "hay más a la derecha" que en el móvil sí hace falta. */
@media (min-width: 992px) {
    .cm-security__list {
        overflow-x: visible;
    }
}

/* El mecanismo sigue siendo el de las pestañas de Bootstrap, así que hay que
   apagar su presentación: bordes de caja, esquinas y fondo del elemento activo
   dibujaban un recuadro alrededor de la fila. Se necesita esta especificidad
   porque .nav-tabs .nav-link gana a una sola clase. */
.cm-security .nav-tabs,
.cm-security .nav-tabs .nav-link,
.cm-security .nav-tabs .nav-link.active {
    border: 0;
    border-radius: 0;
    background: transparent;
}

.cm-security .nav-tabs .nav-link.active {
    border-bottom: 2px solid var(--cm-cyan);
    color: var(--cm-cyan-dark);
}

/* ============================================================================
   Detalles transversales
   ============================================================================ */

/* Cifras que se comparan en columna: sin esto los dígitos bailan y cuesta ver
   cuál es mayor. */
.cm-figure {
    font-variant-numeric: tabular-nums;
}

.cm-code {
    padding: .15rem .45rem;
    border: 1px solid var(--cm-rule);
    border-radius: 6px;
    background: var(--cm-cyan-soft);
    font-family: var(--cm-mono);
    font-size: .85rem;
    font-weight: 600;
    letter-spacing: .03em;
}

/* El foco de teclado de la plantilla es un contorno del navegador que en
   algunos fondos no se ve. */
.cm-security__link:focus-visible,
.cm-records a:focus-visible,
.cm-empty .btn:focus-visible {
    outline: 2px solid var(--cm-cyan-dark);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .cm-security__link {
        transition: none;
    }
}

/* ============================================================================
   Barra lateral de perfil en el móvil
   ----------------------------------------------------------------------------
   Los paneles de paciente y de doctor abrían en el teléfono con la foto de
   perfil a pantalla completa y el menú debajo: había que pasar de largo la
   propia cara para llegar a la agenda, que es a lo que se entra.

   Se resuelve con el orden del flex, sin tocar las dieciséis vistas que montan
   esa columna. Un navegador sin :has() se queda como estaba, que era lo de
   antes: nada se rompe.
   ============================================================================ */

@media (max-width: 767.98px) {
    .row > [class*="col-"]:has(.profile-sidebar) {
        order: 2;
        margin-top: 1.25rem;
    }

    /* Y de paso deja de ocupar una pantalla entera: la foto al lado del nombre
       en vez de encima, que es como se lee una ficha. */
    .profile-sidebar .widget-profile.pro-widget-content {
        padding: 1rem;
    }

    .profile-sidebar .profile-info-widget {
        display: flex;
        align-items: center;
        gap: .9rem;
        text-align: left;
    }

    .profile-sidebar .profile-info-widget .booking-doc-img {
        flex: 0 0 auto;
        margin: 0;
    }

    .profile-sidebar .profile-info-widget .booking-doc-img img {
        width: 64px;
        height: 64px;
        border-radius: 50%;
        object-fit: cover;
    }

    .profile-sidebar .profile-det-info {
        flex: 1 1 auto;
        min-width: 0;
        margin: 0;
    }

    .profile-sidebar .profile-det-info h3 {
        margin-bottom: .15rem;
        font-size: 1.05rem;
    }
}

/* ============================================================================
   Aviso de zona horaria
   ----------------------------------------------------------------------------
   Los horarios se guardan en la zona en la que el doctor arma su agenda. Hay
   que decir en cuál se están mostrando: sin decirlo, quien reserva desde otro
   país no sabe si el número que ve es el suyo o el del doctor, y la conversión
   no sirve de nada.

   Vivía en booking.css, que sólo carga la pantalla de reserva. Al necesitarlo
   también la ficha del doctor, pasa aquí.
   ============================================================================ */

.cm-notice-zone {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: .75rem 1.25rem 0;
    padding: .6rem .9rem;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius-sm);
    background: var(--cm-cyan-soft);
    font-size: .82rem;
    line-height: 1.4;
}

.cm-notice-zone i {
    flex: 0 0 auto;
    color: var(--cm-cyan);
    font-size: .95rem;
}

@media (max-width: 767.98px) {
    .cm-notice-zone {
        margin: .75rem .75rem 0;
        align-items: flex-start;   /* con dos líneas, el icono se queda arriba */
    }

    .cm-notice-zone i {
        margin-top: .15rem;
    }
}

/* ============================================================================
   El campo de archivo que se esconde tras "Cargar foto"
   ----------------------------------------------------------------------------
   El botón es un <span> con estilo y detrás va el <input type="file"> real,
   invisible y estirado sobre él para que al pulsar se abra el selector.

   La hoja de la plantilla pública lo coloca en posición absoluta, pero la del
   panel de administración no trae esa regla: allí el campo se dibujaba como un
   control normal de 310px al lado de un botón de 150, y la página se
   desplazaba de lado en el teléfono. Se define aquí, que es la hoja que cargan
   las dos.
   ============================================================================ */

.change-photo-btn {
    position: relative;
}

.change-photo-btn input.upload {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    opacity: 0;
    cursor: pointer;
}

/* ============================================================================
   Homologación de la plantilla
   ----------------------------------------------------------------------------
   Ciento veintiuna vistas, y noventa y ocho siguen tal como venían en la
   plantilla comprada: campos de 38px de alto, tarjetas con esquinas de 4px,
   títulos de tamaños distintos según la pantalla. Rediseñarlas una a una es
   inviable y, sobre todo, no arregla la siguiente que se añada.

   Aquí se ajustan las piezas que la plantilla usa en todas partes —tarjeta,
   campo, botón, cabecera de página— a los mismos valores que ya usan las
   pantallas rehechas. Así lo viejo se parece a lo nuevo sin tocar el marcado,
   y lo que venga después nace homologado.

   Sólo se tocan medidas, color y forma. Nada de posición ni de disposición:
   ahí es donde una regla global rompe pantallas que no se han mirado.

   Las clases cm- ya definidas ganan: van en hojas que se cargan después.
   ============================================================================ */

/* ------------------------------------------------------------------ Tarjetas */

.card {
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    box-shadow: var(--cm-shadow);
}

.card-header {
    border-bottom: 1px solid var(--cm-rule);
    background: transparent;
}

.card-title,
.card-header h4,
.card-header h5 {
    color: var(--cm-ink);
    font-weight: 700;
}

/* ------------------------------------------------- Cabecera de cada pantalla */

.page-header .page-title {
    color: var(--cm-ink);
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -.015em;
}

.page-header .breadcrumb {
    background: transparent;
    padding-left: 0;
    font-size: .82rem;
}

.page-header .breadcrumb-item.active {
    color: var(--cm-gray);
}

/* -------------------------------------------------------------------- Campos */

/* 48px de alto y 16px de letra. Lo segundo no es estético: por debajo de 16px,
   iOS hace zoom al enfocar un campo y descoloca la página entera. */
.form-control,
.form-select,
.custom-select {
    min-height: 46px;
    padding: .55rem .85rem;
    border: 1px solid #cfd7e3;
    border-radius: var(--cm-radius-sm);
    color: var(--cm-ink);
    font-size: 16px;
    transition: border-color .15s ease, box-shadow .15s ease;
}

textarea.form-control {
    min-height: 96px;
}

.form-control:focus,
.form-select:focus,
.custom-select:focus {
    border-color: var(--cm-cyan);
    box-shadow: 0 0 0 3px rgba(32, 192, 243, .18);
}

.form-control::placeholder {
    color: #a2abba;
}

.form-control:disabled,
.form-control[readonly] {
    background: var(--cm-bg);
    color: var(--cm-gray);
}

.form-group > label,
.form-label {
    margin-bottom: .4rem;
    color: var(--cm-ink);
    font-size: .88rem;
    font-weight: 600;
}

/* El asterisco de campo obligatorio. Vivía en forms.css y en onboarding.css, que no
   se cargan en todas las páginas, así que en PreCheckout salía en negro, como parte
   del texto. Usa el rojo de estado, no un rojo propio: ya había dos. */
.cm-req { color: var(--cm-red); font-weight: 600; }

/* ------------------------------------------------------------------- Botones */

.btn {
    border-radius: var(--cm-radius-sm);
    font-weight: 600;
    /* 44px es el mínimo cómodo para el pulgar; la plantilla los dejaba en 38. */
    min-height: 44px;
    padding: .5rem 1.1rem;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn-sm {
    min-height: 34px;
    padding: .3rem .7rem;
    font-size: .82rem;
}

.btn-primary {
    background-color: var(--cm-cyan);
    border-color: var(--cm-cyan);
}

.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--cm-cyan-dark);
    border-color: var(--cm-cyan-dark);
}

.btn-outline-primary {
    color: var(--cm-cyan-dark);
    border-color: var(--cm-cyan);
}

.btn-outline-primary:hover,
.btn-outline-primary:focus {
    background-color: var(--cm-cyan);
    border-color: var(--cm-cyan);
    color: #fff;
}

/* El foco de teclado tiene que verse: la plantilla lo dejaba en el contorno del
   navegador, que sobre fondo cian no se distingue. */
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible {
    outline: 2px solid var(--cm-cyan-dark);
    outline-offset: 2px;
}

/* ------------------------------------------------------------------- Avisos */

.alert {
    border-radius: var(--cm-radius-sm);
    border-width: 1px;
    font-size: .88rem;
}

/* --------------------------------------------------------- Errores de campo */

.text-danger,
.field-validation-error,
.validation-summary-errors {
    color: var(--cm-red);
    font-size: .82rem;
}

.validation-summary-errors ul {
    margin: 0;
    padding-left: 1.1rem;
}

/* ------------------------------------------------------------------- Tablas */

.table thead th {
    border-bottom: 1px solid var(--cm-rule);
    color: var(--cm-gray);
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.table td {
    color: var(--cm-ink);
    vertical-align: middle;
}

/* ── Barra de avance ──────────────────────────────────────────────────────
   Cuánto se ha consumido o completado. La usan los cupones y los idiomas: la
   cifra sola obliga a dividir mentalmente para saber si va por la mitad. */
.cm-use {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 120px;
}

.cm-use > span {
    color: var(--cm-gray);
    font-size: .8rem;
    font-variant-numeric: tabular-nums;
}

.cm-use-bar {
    height: 5px;
    border-radius: 3px;
    background: var(--cm-neutral-bg);
    overflow: hidden;
}

.cm-use-bar > span {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: var(--cm-cyan);
}


@media (max-width: 767.98px) {
    /* Dentro de una ficha la barra se alinea a la derecha, con el resto de
       valores de la fila. */
    .cm-use {
        align-items: flex-end;
        min-width: 140px;
    }

    .cm-use-bar {
        width: 100%;
    }
}

/* ── Selector de idioma ───────────────────────────────────────────────────
   Vive en la barra superior, donde se espera encontrarlo. Muestra el código y
   no la bandera: una bandera es un país, no una lengua, y el español de la
   bandera de España no es el de quien entra desde Quito. */
.cm-language__button {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 40px;
    padding: .35rem .6rem;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius-sm);
    background: var(--cm-white);
    color: var(--cm-ink);
    font-size: .82rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
}

.cm-language__button:hover,
.cm-language__button:focus-visible {
    border-color: var(--cm-cyan);
    color: var(--cm-cyan-dark);
}

.cm-language__button > i {
    font-size: .95rem;
    color: var(--cm-gray);
}

.cm-language__code {
    letter-spacing: .04em;
}

/* La posición del panel se escribe aquí a propósito.

   Con `data-bs-display="static"` en el botón, Popper no interviene y la posición es
   sólo esto: pegado abajo y alineado por la derecha, que es donde vive el botón.

   El selector lleva tres clases a propósito, y ninguna sobra. Dos hojas anteriores
   pisan este panel con más peso del que tendría una sola clase:

   - Bootstrap le pone `data-bs-popper` al abrirlo, y su hoja trae
     `.dropdown-menu[data-bs-popper] { left: 0 }`. Eso alineaba el panel por la
     izquierda: 200 px colgando de un botón de 58, metido debajo del botón de entrar
     y saliéndose de la ventana. Y no se veía al abrir sino un instante después,
     cuando Bootstrap ponía el atributo, así que parecía que el panel «saltaba».
   - La plantilla, dentro de una consulta de medios, trae
     `.header-navbar-rht li .dropdown-menu`, que son tres, y le quita el relleno y le
     impone 200 px de ancho.

   Con tres clases se empata a la más pesada, y esta hoja se carga después que las
   dos. Escrito con una sola clase, esto no se aplicaba y no había forma de saberlo
   leyendo el archivo. */
.cm-language {
    position: relative;
}

.cm-language .cm-language__list.dropdown-menu {
    position: absolute;
    top: 100%;
    right: 0;
    left: auto;
    float: none;
    margin: 0;
    min-width: 190px;
    padding: .3rem;
}

/* Cada opción es un formulario para que el cambio funcione sin JavaScript; el
   botón tiene que parecer y comportarse como el resto de opciones del menú. */
.cm-language__list form { margin: 0; }

.cm-language__list .dropdown-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    width: 100%;
    border: 0;
    border-radius: var(--cm-radius-sm);
    background: transparent;
    text-align: left;
    font-size: .87rem;
    cursor: pointer;
}

.cm-language__list .dropdown-item.active {
    background: var(--cm-cyan-soft);
    color: var(--cm-cyan-dark);
    font-weight: 600;
}

.cm-language__suffix {
    color: var(--cm-gray-light);
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.cm-language__list .dropdown-item.active .cm-language__suffix {
    color: var(--cm-cyan-dark);
}

@media (max-width: 767.98px) {
    /* En el móvil la barra va justa: se queda el globo y el código, sin más. */
    .cm-language__button {
        padding: .3rem .45rem;
        font-size: .78rem;
    }

    .cm-language__button::after { display: none; }
}

/* ── Campana de avisos ────────────────────────────────────────────────────
   Estaba en chrome.css, que sólo carga el sitio público. El panel de
   administración usa la misma campana y no cargaba ese archivo, así que allí
   salía sin ningún estilo: una lista pelada encima de la cabecera. Vive aquí
   porque la comparten los dos. */

/*
  Campana de avisos
  ------------------------------------------------------------------
  Vive en la cabecera del panel. El contador sólo aparece si hay algo sin leer: un cero
  permanente enseña a la gente a ignorar la campana.
*/

.cm-campaign { position: relative; display: inline-block; }

.cm-campaign__btn {
    position: relative;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border: 1px solid #e3e8ef;
    border-radius: 50%;
    background: #fff;
    color: #272b41;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.cm-campaign__btn:hover { border-color: #20c0f3; color: #20c0f3; }
.cm-campaign__btn:focus-visible { outline: 3px solid rgba(32, 192, 243, .45); outline-offset: 2px; }

.cm-campaign__counter {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 19px;
    height: 19px;
    padding: 0 5px;
    border-radius: 999px;
    background: #c62828;
    color: #fff;
    font-size: .68rem;
    font-weight: 700;
    line-height: 19px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.cm-campaign__dashboard {
    position: absolute;
    right: 0;
    top: calc(100% + 10px);
    width: min(360px, calc(100vw - 32px));
    background: #fff;
    border: 1px solid #e3e8ef;
    border-radius: 14px;
    box-shadow: 0 4px 8px rgba(39, 43, 65, .06), 0 24px 48px rgba(39, 43, 65, .16);
    z-index: 1050;
    overflow: hidden;
}

.cm-campaign__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    border-bottom: 1px solid #e3e8ef;
}

.cm-campaign__header strong { font-size: .95rem; }

.cm-campaign__read-all {
    border: 0;
    background: none;
    color: #0f9fce;
    font-size: .8rem;
    cursor: pointer;
    padding: 0;
}

.cm-campaign__read-all:hover { text-decoration: underline; }

.cm-campaign__list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 380px;
    overflow-y: auto;
}

.cm-campaign__item { border-bottom: 1px solid #f0f3f7; }
.cm-campaign__item:last-child { border-bottom: 0; }

.cm-campaign__item > a,
.cm-campaign__item {
    display: block;
    padding: 13px 16px;
    color: #272b41;
    text-decoration: none;
}

.cm-campaign__item > a { padding: 0; }
.cm-campaign__item:has(> a) { padding: 0; }
.cm-campaign__item > a { padding: 13px 16px; }

.cm-campaign__item:hover { background: #f7fafc; }

/* Punto y fondo tenue para lo no leído: se distingue sin depender sólo del color. */
.cm-campaign__item--new { background: rgba(32, 192, 243, .06); }

.cm-campaign__item--new strong::before {
    content: "";
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #20c0f3;
    margin-right: 7px;
    vertical-align: middle;
}

.cm-campaign__item strong { display: block; font-size: .9rem; font-weight: 600; margin-bottom: 2px; }
.cm-campaign__body { display: block; font-size: .82rem; color: #6b7385; line-height: 1.45; }
.cm-campaign__item time { display: block; font-size: .74rem; color: #9aa3b2; margin-top: 5px; }

.cm-campaign__empty,
.cm-campaign__loading { padding: 26px 16px; text-align: center; font-size: .87rem; color: #6b7385; }

/* ── Barra lateral del panel ───────────────────────────────────────────────
   La plantilla la traía en azul medio con el activo en cian eléctrico, los
   títulos de sección en naranja y los enlaces subrayados: cuatro colores
   fuertes compitiendo con el contenido, que es lo que hay que mirar.

   Pasa a ser clara, como el resto de la plataforma. Sobre blanco el contenido
   manda, y la navegación se lee por jerarquía —tamaño, peso y espacio— en vez
   de por color. El único color vivo se reserva para dónde estás. */

.sidebar {
    background-color: var(--cm-white);
    border-right: 1px solid var(--cm-rule);
}

.sidebar-menu {
    padding: 1rem .75rem 2rem;
}

.sidebar-menu ul {
    font-size: .92rem;
}

/* Rótulo de sección: presente pero callado. Ordena la lista sin pedir turno. */
.sidebar-menu li.menu-title,
.sidebar-menu .menu-title {
    color: var(--cm-gray-light);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    padding: 1.15rem .85rem .4rem;
}

.sidebar-menu li.menu-title a {
    color: var(--cm-cyan-dark);
}

/* Se repite el selector de la plantilla, ".sidebar-menu > ul > li > a", porque el
   suyo tiene más peso: con ".sidebar-menu li a" el texto se quedaba en el gris
   casi blanco que ella usaba sobre azul, y sobre blanco no se leía. */
.sidebar-menu li a,
.sidebar-menu > ul > li > a {
    display: flex;
    align-items: center;
    gap: .7rem;
    min-height: 42px;
    padding: 0 .85rem;
    margin-bottom: 2px;
    border-radius: var(--cm-radius-sm);
    color: var(--cm-gray);
    font-size: .92rem;
    font-weight: 500;
    line-height: 1.3;
    transition: background-color .12s ease, color .12s ease;
}

.sidebar-menu li a i,
.sidebar-menu ul li a i {
    width: 20px;
    flex: 0 0 20px;
    text-align: center;
    font-size: 1rem;
    color: var(--cm-gray-light);
    transition: color .12s ease;
}

/* Los del submenú, igual que los de arriba. La plantilla los pinta con
   `.sidebar-menu ul ul a { display: block }`, que pesa más que la regla de
   arriba: el icono se salía de la caja flexible y se quedaba pegado al borde
   superior mientras el texto —que en varios ocupa dos líneas— caía al centro.
   Se repite el mismo peso de selector para ganarle. */
.sidebar-menu ul ul a {
    display: flex;
    align-items: center;
    gap: .7rem;
    min-height: 36px;
    padding-top: 6px;
    padding-bottom: 6px;
    line-height: 1.35;
}

/* El sangrado de la plantilla lo hace con padding-left, y con flex el icono
   quedaría dentro de ese hueco: se pasa al margen del icono. */
.sidebar-menu ul ul a i {
    margin-left: 0;
}

.sidebar-menu li a:hover,
.sidebar-menu > ul > li > a:hover {
    background-color: var(--cm-bg);
    color: var(--cm-ink);
}

.sidebar-menu li a:hover i {
    color: var(--cm-gray);
}

/* Dónde estás. Con un fondo suave apenas se distinguía del resto, y saber en qué
   pantalla se está es lo primero que se le pide a una barra de navegación. Ahora
   la pestaña activa se rellena con el azul de la marca: no hay forma de
   confundirla, y el color sólo aparece ahí. */
.sidebar-menu li.active > a,
.sidebar-menu > ul > li.active > a,
.sidebar-menu > ul > li.active > a:hover,
.sidebar-menu li.active > a:hover,
.sidebar-menu ul ul a.active {
    background-color: #147fbd;
    color: var(--cm-white);
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 2px 8px rgba(20, 127, 189, .28);
}

.sidebar-menu li.active > a i,
.sidebar-menu ul ul a.active i {
    color: var(--cm-white);
}

/* Dentro de un submenú, el padre queda marcado en suave: dice dónde estás sin
   competir con la pestaña concreta, que es la que lleva el relleno. */
.sidebar-menu li.submenu.subdrop > a,
.sidebar-menu li.submenu:has(a.active) > a {
    background-color: var(--cm-cyan-soft);
    color: var(--cm-cyan-dark);
    font-weight: 600;
}

.sidebar-menu li.submenu.subdrop > a i,
.sidebar-menu li.submenu:has(a.active) > a i {
    color: var(--cm-cyan-dark);
}

/* Los hermanos de la pestaña abierta no se rellenan.

   La plantilla trae `.sidebar-menu li.active a`, sin `>`, así que pinta de cian
   fuerte TODOS los enlaces que cuelgan del menú abierto y no sólo el que estás
   viendo. Salían tres pastillas encendidas donde sólo una es la pantalla actual,
   y encima con el icono en gris claro sobre el cian: el texto pasaba a blanco por
   esa misma regla, pero el icono lo seguía pintando la regla de arriba y se
   quedaba en un plomo que no contrasta con nada.

   Aquí se les devuelve el aspecto normal —sin relleno, texto secundario, icono
   gris sobre blanco— y el relleno se queda para la que de verdad está abierta,
   que es lo que hace que se distinga. */
.sidebar-menu li.active ul li:not(.active) > a {
    background-color: transparent;
    color: var(--cm-gray);
    font-weight: 400;
    box-shadow: none;
}

.sidebar-menu li.active ul li:not(.active) > a i {
    color: var(--cm-gray-light);
}

.sidebar-menu li.active ul li:not(.active) > a:hover {
    background-color: var(--cm-bg);
    color: var(--cm-ink);
}

.sidebar-menu li.active ul li:not(.active) > a:hover i {
    color: var(--cm-gray);
}

/* Submenú: colgado de una guía, para que se vea de quién depende. */
.sidebar-menu ul ul {
    position: relative;
    margin: 2px 0 .35rem 1.6rem;
    padding-left: .75rem;
    border-left: 1px solid var(--cm-rule);
}

.sidebar-menu ul ul a {
    min-height: 36px;
    padding: 0 .7rem;
    font-size: .87rem;
    font-weight: 400;
}

.sidebar-menu .menu-arrow {
    margin-left: auto;
    font-size: .8rem;
    color: var(--cm-gray-light);
    transition: transform .18s ease;
}

.sidebar-menu li.subdrop > a .menu-arrow {
    transform: rotate(90deg);
}

/* La barra de desplazamiento propia de la plantilla era oscura sobre azul. */
.sidebar .slimScrollBar {
    background: var(--cm-rule) !important;
}

@media (prefers-reduced-motion: reduce) {
    .sidebar-menu li a,
    .sidebar-menu .menu-arrow {
        transition: none;
    }
}

/* ── Cabecera del panel en pantallas estrechas ─────────────────────────────
   La plantilla estira el bloque del logo a todo el ancho y lo centra, con lo
   que el logo acababa justo debajo del menú de usuario, que tiene más z-index:
   se veía asomar el estetoscopio por detrás de la campana.

   Aquí la cabecera es una fila: botón de menú, logo, y los controles al final.

   Va con la clase del panel y no con ".header" a secas: el sitio público usa
   ese mismo nombre para una cabecera con otra estructura, y convertirla en fila
   le desmontaba el logo. */

@media (max-width: 991.98px) {
    .header.cm-header-dashboard {
        display: flex;
        align-items: center;
        gap: .5rem;
        padding-right: .75rem;
    }

    .cm-header-dashboard .mobile_btn {
        position: static;
        /* En el marcado el logo va antes que el botón; en pantalla se espera al
           revés, el botón primero y pegado al borde. */
        order: -1;
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        margin-left: .25rem;
    }

    .cm-header-dashboard .header-left {
        position: static;
        display: flex;
        align-items: center;
        flex: 0 0 auto;
        width: auto;
        height: 100%;
        padding: 0;
        margin-left: .15rem;
        text-align: left;
        line-height: 1;
    }

    .cm-header-dashboard .header-left .logo.logo-small {
        display: flex;
        align-items: center;
        height: auto;
        padding: 0;
    }

    .cm-header-dashboard .header-left .logo.logo-small img {
        display: block;
    }

    /* Los controles se van al final y empujan el resto a su sitio. */
    .cm-header-dashboard .user-menu {
        margin-left: auto;
        flex: 0 1 auto;
    }
}

/* ── Gráficos ─────────────────────────────────────────────────────────────
   Se dibujan como SVG en el servidor: llegan hechos, sin salto al cargar, y
   salen igual al imprimir. Lo único que hace falta aquí es cómo se ven. */

.cm-chart {
    width: 100%;
    margin-top: .35rem;
}

.cm-chart svg {
    width: 100%;
    height: auto;
    display: block;
    overflow: visible;
}

/* Rejilla discreta: sirve para situar el valor, no para mirarla. */
.cm-chart__guide {
    stroke: var(--cm-rule);
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.cm-chart__scale,
.cm-chart__axis {
    fill: var(--cm-gray-light);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.cm-chart__line {
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* El punto crece al acercarse; el círculo transparente de debajo agranda la
   zona sensible para que no haya que apuntar al píxel exacto. */
.cm-chart__mark {
    transition: r .12s ease;
}

.cm-chart__point:hover .cm-chart__mark {
    r: 6;
}

.cm-chart__legend {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .5rem .75rem;
    margin-top: .5rem;
}

.cm-chart__series {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .82rem;
    color: var(--cm-gray);
}

.cm-chart__series::before {
    content: "";
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--cm-cyan);
}

.cm-chart__series--mint::before { background: var(--cm-mint); }

.cm-chart__figure {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--cm-ink);
    font-variant-numeric: tabular-nums;
}

.cm-chart__note {
    margin-left: auto;
    font-size: .78rem;
    color: var(--cm-gray-light);
}

.cm-card__sub {
    margin: 1.25rem 0 0;
    font-size: .82rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--cm-gray-light);
}

/* ── Anillo de reparto ──────────────────────────────────────────────────── */

.cm-spread-chart {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
    margin-top: .5rem;
}

.cm-ring {
    width: 150px;
    height: 150px;
    flex: 0 0 auto;
}

.cm-ring__part {
    transition: opacity .15s ease;
}

.cm-ring:hover .cm-ring__part {
    opacity: .45;
}

.cm-ring:hover .cm-ring__part:hover {
    opacity: 1;
}

.cm-ring__total {
    fill: var(--cm-ink);
    font-size: 26px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.cm-ring__footer {
    fill: var(--cm-gray-light);
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.cm-legend {
    flex: 1 1 180px;
    min-width: 0;
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .55rem;
}

.cm-legend li {
    display: grid;
    grid-template-columns: 10px 1fr auto auto;
    align-items: center;
    gap: .5rem;
    font-size: .86rem;
}

.cm-legend__point {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--cm-neutral);
}

/* Mismo orden que las porciones del anillo, o la leyenda no sirve de nada. */
.cm-legend__point--0 { background: var(--cm-cyan); }
.cm-legend__point--1 { background: var(--cm-mint); }
.cm-legend__point--2 { background: var(--cm-amber); }
.cm-legend__point--3 { background: var(--cm-red); }
.cm-legend__point--4 { background: var(--cm-neutral); }

.cm-legend__text {
    color: var(--cm-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cm-legend__value {
    font-weight: 600;
    color: var(--cm-ink);
    font-variant-numeric: tabular-nums;
}

.cm-legend__pct {
    color: var(--cm-gray-light);
    font-size: .8rem;
    font-variant-numeric: tabular-nums;
    min-width: 3.2em;
    text-align: right;
}

/* Tendencia junto al indicador. */
.cm-spark {
    width: 100%;
    height: 32px;
    display: block;
    margin-top: .5rem;
}

@media (max-width: 575.98px) {
    /* En un teléfono el anillo y su leyenda no caben al lado: se apilan. */
    .cm-spread-chart {
        flex-direction: column;
        align-items: stretch;
    }

    .cm-ring {
        align-self: center;
    }

    .cm-chart__note {
        margin-left: 0;
        width: 100%;
    }
}

/* ── Avisos ───────────────────────────────────────────────────────────────
   Estaban escritos en cada elemento, con los colores a mano y repetidos en
   ocho pantallas. Cada copia se fue separando un poco de las demás. */

.cm-notice {
    display: flex;
    align-items: flex-start;
    gap: .8rem;
    padding: 1.1rem 1.2rem;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-bg);
    color: var(--cm-gray);
    font-size: .9rem;
    line-height: 1.5;
}

.cm-notice > i {
    flex: 0 0 auto;
    margin-top: .1rem;
    font-size: 1.15rem;
    color: var(--cm-gray-light);
}

.cm-notice strong {
    color: var(--cm-ink);
}

/* Atención: algo que conviene leer antes de seguir. */
.cm-notice--eye {
    background: var(--cm-amber-bg);
    border-color: #f0d9a8;
    color: #7a5b12;
}

.cm-notice--eye > i,
.cm-notice--eye strong {
    color: var(--cm-amber);
}

/* Informativo: contexto que ayuda, sin urgencia. */
.cm-notice--data {
    background: var(--cm-cyan-soft);
    border-color: #bde7f7;
    color: #0c6a8c;
}

.cm-notice--data > i,
.cm-notice--data strong {
    color: var(--cm-cyan-dark);
}

/* Una lista dentro del aviso, para enumerar lo que se está contando. */
.cm-notice__list {
    margin: .45rem 0 0;
    padding-left: 1.1rem;
}

.cm-notice__list li {
    margin-bottom: .2rem;
    font-variant-numeric: tabular-nums;
}

.cm-notice p {
    margin: .15rem 0 0;
}

/* Botón esperando respuesta del servidor. El puntero deja de ofrecerse y la opacidad
   baja lo justo para que se note que está ocupado sin que deje de leerse. */
.cm-button--processing {
    cursor: progress;
    opacity: .8;
}

.cm-button--processing .spinner-border {
    vertical-align: -.125em;
}

/* Botón de envío de los formularios de la plantilla.
   Venía como píldora de 50 px de radio, letra de 18 y ancho mínimo de 200: al
   lado de los botones homologados parecía de otra aplicación. */
.submit-btn {
    min-width: 0;
    padding: 0 1.4rem;
    border-radius: var(--cm-radius-sm);
    font-size: .95rem;
    font-weight: 600;
    min-height: 44px;
}

/* La plantilla separa los botones con `margin-left: 15px` en el segundo. En una fila
   funciona, pero al apilarse en el teléfono ese margen lo empuja a la derecha y lo saca
   del formulario. Con una caja flexible la separación no depende de la dirección. */
.submit-section {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    align-items: center;
}

/* Con text-center la plantilla pide que el botón vaya centrado, pero esto es un
   contenedor flexible y ahí el text-align no coloca a los hijos: el botón se
   quedaba pegado a la izquierda en las seis pantallas de confirmación. */
.submit-section.text-center { justify-content: center; }

.submit-section .submit-btn + .submit-btn,
.submit-section .btn + .btn {
    margin-left: 0;
}

@media (max-width: 575.98px) {
    /* En el teléfono cada botón ocupa la fila: son las acciones de la pantalla. */
    .submit-section {
        flex-direction: column;
        align-items: stretch;
    }

    .submit-btn,
    .submit-section .btn {
        width: 100%;
    }
}

/* Texto secundario dentro de una tarjeta o una ficha. */
.cm-text-minor {
    font-size: .88rem;
    line-height: 1.45;
}

.cm-pending__icon {
    font-size: 1.35rem;
}

/* Contacto directo en la página de Contáctenos.
   El correo se lee y se pulsa: quien entra buscando cómo escribir no debería
   tener que rellenar un formulario ni bajar hasta el pie. */
.cm-contact-direct {
    display: flex;
    align-items: center;
    gap: .8rem;
    margin-bottom: 1.25rem;
    padding: .9rem 1.1rem;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-bg);
    text-decoration: none;
    transition: border-color .12s ease, background-color .12s ease;
}

.cm-contact-direct:hover,
.cm-contact-direct:focus-visible {
    border-color: var(--cm-cyan);
    background: var(--cm-cyan-soft);
}

.cm-contact-direct > i {
    font-size: 1.25rem;
    color: var(--cm-cyan-dark);
}

.cm-contact-direct span {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.cm-contact-direct strong {
    color: var(--cm-ink);
    font-size: .95rem;
    overflow-wrap: anywhere;
}

.cm-contact-direct small {
    color: var(--cm-gray);
    font-size: .8rem;
}

/* ── Campos de fecha y hora ───────────────────────────────────────────────
   En iOS estos campos traen un ancho propio, calculado sobre el formato que
   muestran, y no lo sueltan aunque el contenedor sea más estrecho: se salían
   del marco por la derecha. Quitarles la apariencia nativa y dejarles el ancho
   en cero mínimo los obliga a caber. */

input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

/* El icono del calendario se pega al borde derecho y no empuja al texto. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
    margin-left: auto;
}

/* Safari centra el texto dentro del campo; el resto de campos lo alinean a la
   izquierda y así quedaban descolgados de la columna. */
input[type="date"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value,
input[type="datetime-local"]::-webkit-date-and-time-value {
    text-align: left;
}

/* El contenedor tampoco puede dejarles desbordar. */
.cm-field,
.form-group,
.cm-filters__group {
    min-width: 0;
}

/* ── Pago con PayPal ───────────────────────────────────────────────────────
   Botón con los colores de PayPal, para que el paciente reconozca el método
   antes de pulsar. La marca se escribe, no se copia el logotipo. */
.cm-paypal__note {
    margin-bottom: .75rem;
    color: var(--cm-text-soft, #6b7280);
    font-size: .875rem;
    text-align: center;
}

.cm-paypal__button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    width: 100%;
    padding: .8rem 1rem;
    border-radius: 24px;
    background: #ffc439;
    color: #003087;
    font-weight: 700;
    text-decoration: none;
}

.cm-paypal__button:hover { background: #f0b429; color: #003087; }
.cm-paypal__button:focus-visible { outline: 3px solid #009cde; outline-offset: 2px; }

.cm-paypal__mark { font-style: italic; font-weight: 800; }
.cm-paypal__mark span:first-child { color: #003087; }
.cm-paypal__mark span:last-child { color: #009cde; }

/* ── Logotipo de la marca ─────────────────────────────────────────────────
   El lockup viene rasterizado a 3x del paquete de marca, así que se le fija el
   alto y se deja que el ancho salga solo: sin esto, un PNG de 1000px de ancho
   entra en la cabecera a tamaño natural. */
.cm-mark {
    height: 42px;
    width: auto;
    max-width: 100%;
}

/* La plantilla le fija 160px de ancho al enlace de la cabecera. El logotipo nuevo es
   más ancho que el anterior, así que con ese tope salía aplastado: se deja que el
   ancho lo marque el propio archivo.

   Sólo de 768px para arriba. En el teléfono la plantilla centra el logo con
   `width: 100%` y deja la hamburguesa flotando encima a la izquierda; quitarle ese
   ancho lo mandaba al borde, justo debajo del botón del menú. */
@media (min-width: 768px) {
    .navbar-brand.logo,
    .menu-logo {
        width: auto;
        max-width: 220px;
    }
}

@media (max-width: 575.98px) {
    /* Aquí el <picture> ya ha cambiado al icono suelto, que es cuadrado. */
    .cm-mark {
        height: 38px;
    }
}

/* ── Dos gráficos en paralelo ─────────────────────────────────────────────
   Apilados obligaban a bajar media pantalla para ver el segundo, que es
   justamente con el que hay que comparar el primero. En pantalla estrecha
   vuelven a apilarse: dos series de doce meses en media pantalla de móvil no
   se leen. */
.cm-charts-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 22px;
    align-items: start;
}

@media (max-width: 991.98px) {
    .cm-charts-pair {
        grid-template-columns: 1fr;
    }
}

/* ── Resumen de la reserva ─────────────────────────────────────────────────
   Dos cosas de la plantilla que estropean el resumen de la cita:

   1. ".booking-date li" lleva text-transform: capitalize. Los textos ya vienen
      escritos como toca desde el catálogo, así que lo único que hacía era poner
      mayúscula donde no va: "Tipo De Consulta", "En Línea Fin De Semana" y, peor,
      "03:40 P.m." en la hora.

   2. ".booking-date li span" flota a la derecha, y como es un selector de
      descendencia también atrapaba el <span> de la zona horaria que va dentro de
      la hora: se salía de su sitio y quedaba pegado, "03:40 p.m.GMT-5". Sólo debe
      flotar el valor de la fila. */
.booking-date li,
.booking-fee li {
    text-transform: none;
}

.booking-date li span span,
.booking-fee li span span {
    float: none;
    font-size: inherit;
}

/* ── Diálogo de confirmación ───────────────────────────────────────────────
   Sustituye al confirm() del navegador, que cada sistema pinta a su manera y
   siempre sale en el idioma del sistema, no en el de la página. */
.cm-confirm {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.cm-confirm[hidden] { display: none; }

.cm-confirm__background {
    position: absolute;
    inset: 0;
    background: rgba(39, 43, 65, .45);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}

.cm-confirm__box {
    position: relative;
    width: 100%;
    max-width: 420px;
    padding: 26px 26px 22px;
    border-radius: var(--cm-radius-lg);
    background: var(--cm-white);
    box-shadow: var(--cm-shadow-high);
    animation: cm-confirmar-entra .16s ease-out;
}

@keyframes cm-confirmar-entra {
    from { opacity: 0; transform: translateY(8px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

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

.cm-confirm__title {
    margin: 0 0 .5rem;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--cm-ink);
}

.cm-confirm__message {
    margin: 0 0 1.4rem;
    font-size: .93rem;
    line-height: 1.55;
    color: var(--cm-gray);
}

.cm-confirm__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    justify-content: flex-end;
}

.cm-confirm__actions button {
    min-height: 42px;
    padding: 0 1.2rem;
    border-radius: var(--cm-radius-sm);
    font-size: .93rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .12s ease, border-color .12s ease;
}

.cm-confirm__no {
    border: 1px solid var(--cm-rule);
    background: var(--cm-white);
    color: var(--cm-ink);
}

.cm-confirm__no:hover { background: var(--cm-bg); }

.cm-confirm__yes {
    border: 1px solid var(--cm-cyan);
    background: var(--cm-cyan);
    color: var(--cm-white);
}

.cm-confirm__yes:hover {
    background: var(--cm-cyan-dark);
    border-color: var(--cm-cyan-dark);
}

/* Para lo que se borra y no vuelve. */
.cm-confirm__box--danger .cm-confirm__yes {
    border-color: var(--cm-red);
    background: var(--cm-red);
}

.cm-confirm__box--danger .cm-confirm__yes:hover {
    background: #b93a3a;
    border-color: #b93a3a;
}

.cm-confirm__actions button:focus-visible {
    outline: 3px solid var(--cm-cyan-soft);
    outline-offset: 1px;
}

/* En el teléfono, uno debajo de otro y a todo el ancho. */
@media (max-width: 420px) {
    .cm-confirm__actions { flex-direction: column-reverse; }
    .cm-confirm__actions button { width: 100%; }
}

/* ============================================================================
   Los desplegables del menú, también con el teclado
   ----------------------------------------------------------------------------
   "Pacientes" y "Doctores" abren su lista al pasar el ratón por encima y de
   ninguna otra manera. Quien navega con el tabulador llegaba al enlace, lo
   pulsaba —lleva href="#"— y no pasaba nada: la lista no se abría nunca, así
   que Buscar un doctor y las guías de correo quedaban fuera de su alcance.

   Con :focus-within la lista se abre en cuanto el foco entra en el grupo, y se
   cierra al salir. Va aquí y no en la hoja de la plantilla porque aquélla es de
   terceros y se sustituye entera al actualizarla.
   ========================================================================== */
@media (min-width: 1150px) {
    .main-nav li.has-submenu:focus-within > .submenu {
        visibility: visible;
        opacity: 1;
        margin-top: 0;
        transform: translateY(0);
    }

    .main-nav > li.has-submenu:focus-within > .submenu > li.has-submenu:focus-within > .submenu {
        visibility: visible;
        opacity: 1;
        margin-top: -1px;
        margin-right: 0;
    }
}

/* ============================================================================
   Cosas que hay que poder acertar con el dedo
   ----------------------------------------------------------------------------
   El barrido midió los controles a 375 px de ancho. Salieron tres que no se
   aciertan: las flechas de cambiar de semana en el horario del doctor, que son
   un icono de 10x23; la casilla de aceptar los términos, de 13x13 en el resumen
   antes de pagar; y las casillas de los filtros del buscador, de 20x20.

   La referencia es la de las pautas de accesibilidad: 24 px de lado como
   mínimo, y mejor cerca de 44, que es lo que ocupa la yema de un dedo. Se
   agranda lo que responde al toque, no el dibujo, que ya está bien.
   ========================================================================== */

/* Las flechas de semana del horario. */
.booking-schedule .day-slot .left-arrow a.cm-week,
.booking-schedule .day-slot .right-arrow a.cm-week {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
}

/* Las casillas de aceptar los términos: en registrarse y en el registro de
   doctores la etiqueta envuelve a la casilla; en el resumen antes de pagar van
   sueltas dentro de .form-check. */
.cm-field--check > label,
.terms-accept .form-check {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
}

.cm-field--check input[type="checkbox"],
.terms-accept input[type="checkbox"] {
    width: 22px;
    height: 22px;
    min-width: 22px;
    margin: 0;
    accent-color: #20c0f3;
}

/* Las casillas de los filtros del buscador. */
.cm-filters__option {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 40px;
}

.cm-filters__option input[type="checkbox"],
.cm-filters__option input[type="radio"] {
    width: 22px;
    height: 22px;
    min-width: 22px;
    accent-color: #20c0f3;
}

/* ----------------------------------------------------------------------------
   La lupa del menú y la equis de cerrarlo
   ----------------------------------------------------------------------------
   Medían 61x29 y 12x27, por debajo de lo que se acierta con el dedo. Lo que
   falta es área sensible, no tamaño de dibujo, así que se añade con un
   pseudoelemento centrado en vez de tocar el tamaño o la caja.

   `display` no se toca a propósito. Cada plantilla enseña estos botones a un
   ancho distinto —el sitio público por debajo de 1149, el panel por debajo de
   992— y cualquier regla de display puesta aquí, aunque sea dentro de un
   @media, acaba enseñándolos donde la otra plantilla los esconde: en el panel
   salían la lupa y el botón de plegar la barra, uno al lado del otro.

   Con el pseudoelemento no hay nada que decidir: si el botón está oculto, el
   pseudoelemento tampoco se pinta.
   -------------------------------------------------------------------------- */
#mobile_btn,
.mobile_btn,
.menu-close {
    position: relative;
}

#mobile_btn::after,
.mobile_btn::after,
.menu-close::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
}

/* La etiqueta de aceptar los términos en el resumen antes de pagar es hermana de
   la casilla, no la envuelve: la altura hay que dársela a ella. */
.terms-accept .form-check-label {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}

/* El campo de "escriba ELIMINAR" del diálogo, para lo que no tiene vuelta atrás. */
.cm-confirm__type {
    display: block;
    margin: 0 0 18px 0;
    font-size: .875rem;
    color: var(--cm-ink-soft, #6b7385);
}

.cm-confirm__type-text {
    display: block;
    margin-bottom: 6px;
}

.cm-confirm__type-field {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--cm-rule, #e3e8ef);
    border-radius: 8px;
    font: inherit;
    color: var(--cm-ink, #272b41);
    background: var(--cm-bg, #fff);
}

.cm-confirm__type-field:focus {
    outline: none;
    border-color: #20c0f3;
    box-shadow: 0 0 0 3px rgba(32, 192, 243, .18);
}

/* El motivo: lo mismo que «teclear», pero para escribir una explicación en vez de
   repetir una palabra. Lo usa el rechazo de una especialidad, donde el motivo es lo
   único que le dice al profesional qué tiene que arreglar. */
.cm-confirm__reason {
    display: block;
    margin: 0 0 18px 0;
    font-size: .875rem;
    color: var(--cm-ink-soft, #6b7385);
    text-align: left;
}

.cm-confirm__reason-text {
    display: block;
    margin-bottom: 6px;
}

.cm-confirm__reason-field {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--cm-rule, #e3e8ef);
    border-radius: 8px;
    font: inherit;
    color: var(--cm-ink, #272b41);
    background: var(--cm-bg, #fff);
    resize: vertical;
}

.cm-confirm__reason-field:focus {
    outline: none;
    border-color: #20c0f3;
    box-shadow: 0 0 0 3px rgba(32, 192, 243, .18);
}

.cm-confirm__reason-help {
    display: block;
    margin-top: 6px;
    font-size: .78rem;
    color: var(--cm-ink-soft, #6b7385);
}

.cm-confirm__yes[disabled] {
    opacity: .5;
    cursor: not-allowed;
}

/* ============================================================================
   Los desplegables tienen que parecer desplegables
   ----------------------------------------------------------------------------
   La hoja de la plantilla del panel pone appearance:none en todos los <select>
   y no pone nada en su lugar. El resultado es una caja idéntica a la de escribir
   texto: País, Ciudad, Especialidad, el "ver N filas" de las tablas y los
   filtros de estado se veían como campos de texto, y no había forma de saber que
   se despliegan sin pulsarlos.

   La flecha ya existía bien hecha en forms.css, pero sólo dentro de .cm-form, y
   esa hoja no la carga el panel. Se trae aquí, que la ven las dos plantillas.
   Va en un data: URI y no en un archivo aparte para no añadir una petición por
   una flecha de doce píxeles.
   ========================================================================== */
.custom-select,
select.form-control,
select.form-select,
.dataTables_length select,
.dataTables_wrapper select {
    -webkit-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236b7385' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 38px;
}

/* Los que se dejan pequeños —el de cuántas filas— no necesitan tanto hueco. */
.dataTables_length select,
.custom-select-sm,
select.form-control-sm {
    background-position: right 10px center;
    padding-right: 30px;
}

/* Desactivado, la flecha también se apaga: si no, invita a pulsar. */
.custom-select:disabled,
select.form-control:disabled,
select.form-select:disabled {
    opacity: .6;
    background-image: none;
}

/* ============================================================================
   Le falta firmar el contrato
   ----------------------------------------------------------------------------
   El aviso iba sólo por correo, y un correo se pierde, se va a spam o llega
   cuando la persona no está. El contrato es una tarea pendiente del doctor, así
   que se le dice en su panel, en todas sus pantallas, hasta que lo firme.
   ========================================================================== */
.cm-pending-contract {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 16px;
    padding: 14px 16px;
    background: var(--cm-white);
    border: 1px solid var(--cm-rule);
    border-left: 4px solid var(--cm-amber);
    border-radius: 12px;
    color: var(--cm-ink);
    text-decoration: none;
    transition: box-shadow .15s ease, transform .15s ease;
}

.cm-pending-contract:hover {
    color: var(--cm-ink);
    text-decoration: none;
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(39, 43, 65, .09);
}

.cm-pending-contract i {
    color: var(--cm-amber);
    font-size: 1.1rem;
    margin-top: 2px;
    flex: none;
}

.cm-pending-contract strong {
    display: block;
    font-size: .95rem;
    margin-bottom: 2px;
}

.cm-pending-contract span {
    font-size: .86rem;
    line-height: 1.4;
    color: var(--cm-gray);
}

/* ============================================================================
   El menú de la foto de perfil, igual en el sitio y en el panel
   ----------------------------------------------------------------------------
   El marcado de _LoginPartial y _AdminLoginPartial ya era el mismo; lo que no
   lo era es el CSS, porque cada layout carga la hoja de una plantilla distinta
   —assets/css/style.css el sitio, adminAssets/css/style.css el panel— y las dos
   traen sus propias reglas para este menú.

   Se veía en la foto: la hoja del sitio lleva `.user-img > img` con alto, ancho
   y object-fit; la del panel no la trae. Sin alto, una foto de 512x384 se
   queda en 31x23, y el border-radius del 50% sobre una caja que no es cuadrada
   dibuja un óvalo. No es que la foto estuviera mal recortada: es que en el
   panel nadie le puso el alto.

   Esto va aquí, en la hoja que cargan los dos layouts y después de las de las
   plantillas, para que la apariencia salga de un solo sitio y no pueda volver
   a separarse. Si alguna plantilla cambia, esto sigue mandando.
   ========================================================================== */

/* La foto de la barra. Cuadrada y recortada, no encogida: así el círculo es un
   círculo con cualquier proporción de foto. */
.user-img > img,
.user-img img.rounded-circle {
    width: 31px;
    height: 31px;
    object-fit: cover;
}

/* La cabecera del desplegable, con la foto y el nombre. */
.user-header {
    display: flex;
    align-items: center;
    padding: 10px 15px;
    background-color: transparent;
}

.user-header .user-text {
    margin-left: 10px;
    min-width: 0;
}

.user-header .user-text h6 {
    font-size: 15px;
    margin-bottom: 2px;
    /* Un nombre largo no tiene por qué caber: antes de estirar el menú, corta. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Y la foto de dentro del desplegable, por lo mismo que la de la barra. */
.user-header .avatar-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.user-header .avatar.avatar-sm {
    width: 31px;
    height: 31px;
    flex: none;
}

/* ==========================================================================
   El panel lateral del doctor y del paciente, fijo al desplazar
   --------------------------------------------------------------------------
   Las vistas llevan la clase theiaStickySidebar, heredada de un complemento de
   la plantilla. El complemento se cargaba en catorce pantallas y no en el
   resto, así que el panel se quedaba arriba mientras el contenido bajaba en
   todas las demás, y en una pantalla larga —los documentos, la agenda— el menú
   desaparecía de la vista.

   Ahora esto es lo único que lo hace: el complemento se quitó, porque tener dos
   mecanismos para lo mismo significaba que el panel se comportaba de dos formas
   según la pantalla. position: sticky lo hace el navegador solo, sin JavaScript
   que pueda fallar ni un sensor de redimensionado escuchando.

   La clase se conserva porque es de lo que se agarra esta regla y está puesta
   en todas las vistas que lo necesitan.

   Se pega la columna entera y no su primer hijo. Antes era el hijo, y sólo si
   era una .card o un .profile-sidebar: el panel de filtros del buscador lleva
   otra cosa dentro, así que ahí no aplicaba y el panel se quedaba arriba. Con
   la columna no hay que ir enumerando qué puede haber dentro.

   El tope deja hueco para la barra superior, que también es fija. Y el alto
   máximo con desplazamiento propio es para el menú largo del doctor: sin él,
   en una pantalla de portátil los últimos elementos quedan fuera y no hay
   forma de llegar a ellos.
   ========================================================================== */
@media (min-width: 768px) {
    .theiaStickySidebar {
        position: sticky;
        top: 96px;
        max-height: calc(100vh - 120px);
        overflow-y: auto;
        overscroll-behavior: contain;

        /* Sin esto no se pega nada. La columna vive dentro de una fila de Bootstrap, que
           es flex, y por omisión se estira hasta el alto de la fila: un elemento tan alto
           como su contenedor no tiene margen por el que desplazarse, y sticky no hace
           nada. Se lo dice el navegador a nadie. */
        align-self: flex-start;
    }
}

/* ==========================================================================
   El menú de la foto de perfil: el mismo en el sitio y en el panel
   --------------------------------------------------------------------------
   El marcado ya era el mismo. Lo que no lo era es el CSS, porque cada layout
   carga la hoja de una plantilla distinta y cada una estiliza este menú a su
   manera: la del panel le pone líneas entre las opciones, otro color al pasar
   por encima y otro ancho; la del sitio, una sombra suave y una flecha que
   apunta al avatar.

   Aquí se fija uno solo. Va después de las dos hojas de plantilla, así que
   manda sobre ambas y no puede volver a separarse.
   ========================================================================== */

/* El disparador es un botón: hay que quitarle lo que Bootstrap le pone a los
   botones para que se vea como lo que es, un avatar en la barra. */
.logged-item > .dropdown-toggle.btn,
.logged-item > .dropdown-toggle.btn:hover,
.logged-item > .dropdown-toggle.btn:focus {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0 .25rem;
    text-decoration: none;
    line-height: 1;
}

.logged-item .dropdown-menu {
    border: 0;
    border-radius: .5rem;
    box-shadow: 0 4px 24px rgba(39, 43, 65, .14);
    min-width: 220px;
    padding: 0;
    overflow: hidden;
}

/* La flechita que apunta al avatar. La tenía el sitio y el panel no. */
.logged-item .dropdown-menu::before {
    content: "";
    position: absolute;
    top: -6px;
    right: 14px;
    width: 12px;
    height: 12px;
    background: #fff;
    transform: rotate(45deg);
}

.logged-item .dropdown-menu .dropdown-item {
    display: flex;
    align-items: center;
    padding: .6rem 1rem;
    /* El panel separaba las opciones con una línea cada una. Con la cabecera
       arriba ya se entiende la agrupación, y las líneas sólo hacen ruido. */
    border-top: 0;
    font-size: .9rem;
}

.logged-item .dropdown-menu .dropdown-item:hover,
.logged-item .dropdown-menu .dropdown-item:focus {
    background: var(--cm-bg, #f4f6fb);
    color: inherit;
}

/* La cabecera, separada de las opciones por una sola línea. */
.logged-item .user-header {
    border-bottom: 1px solid var(--cm-rule, #eceff4);
    padding: .9rem 1rem;
}

/* ==========================================================================
   Los menús laterales no crecen ni desbordan
   --------------------------------------------------------------------------
   Las etiquetas se acortaron, pero eso resuelve las de hoy y no las de mañana:
   la próxima pantalla que alguien añada volverá a salirse, y en alemán casi
   todas las palabras son más largas que en español.

   Así que se corta con puntos suspensivos. El panel mantiene su ancho y el
   texto que no cabe se recorta en vez de derramarse sobre el contenido.
   ========================================================================== */
.sidebar-menu li a span:not(.menu-arrow):not(.badge),
.dashboard-menu ul li a span {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}

.sidebar-menu li a,
.dashboard-menu ul li a {
    /* Sin esto el enlace crece con su contenido y arrastra al panel entero. */
    min-width: 0;
    overflow: hidden;
}

/* ===========================================================================
   Confirmar el pago a un profesional
   ---------------------------------------------------------------------------
   El modal anterior venía del flujo de marcar citas a mano: una tarjeta con el
   nombre centrado, otra con un número y un aviso azul. Decía cuántas citas
   eran pero no cuáles, y una vez pagado no dejaba rastro de la transferencia.

   Ahora son tres bloques que responden tres preguntas en el orden en que se
   hacen: a dónde va el dinero, qué cubre, y con qué queda constancia.
   ========================================================================= */

.cm-payment {
    border: 0;
    border-radius: 14px;
    overflow: hidden;
}

.cm-payment__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 24px 16px;
    border-bottom: 1px solid #eceff3;
}

.cm-payment__label {
    margin: 0 0 2px;
    font-size: .7rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #9aa4ae;
    font-weight: 600;
}

.cm-payment__doctor {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 600;
    color: #272b41;
}

.cm-payment__close {
    background: none;
    border: 0;
    font-size: 1.6rem;
    line-height: 1;
    color: #9aa4ae;
    cursor: pointer;
    padding: 0 4px;
}

.cm-payment__close:hover { color: #272b41; }

.cm-payment__body {
    padding: 4px 24px 8px;
    max-height: 66vh;
    overflow-y: auto;
}

.cm-payment__block { padding: 18px 0; border-bottom: 1px solid #f1f3f6; }
.cm-payment__block:last-child { border-bottom: 0; }

.cm-payment__title {
    margin: 0 0 12px;
    font-size: .72rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #9aa4ae;
    font-weight: 600;
}

.cm-payment__title-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.cm-payment__total {
    font-size: 1.35rem;
    font-weight: 700;
    color: #1c8a4d;
    font-variant-numeric: tabular-nums;
}

/* --- A dónde va --- */

.cm-payment__data {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 10px 20px;
    margin: 0;
}

.cm-payment__data > div { min-width: 0; }

.cm-payment__data dt {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #9aa4ae;
    font-weight: 600;
    margin: 0 0 2px;
}

.cm-payment__data dd {
    margin: 0;
    color: #272b41;
    font-weight: 500;
    word-break: break-word;
}

/* --- Qué se paga --- */

.cm-payment__appointments {
    max-height: 220px;
    overflow-y: auto;
    border: 1px solid #eceff3;
    border-radius: 8px;
}

.cm-payment__appointments table { width: 100%; margin: 0; border-collapse: collapse; }

.cm-payment__appointments thead th {
    position: sticky;
    top: 0;
    background: #f7f9fb;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #9aa4ae;
    font-weight: 600;
    padding: 8px 12px;
    border-bottom: 1px solid #eceff3;
}

.cm-payment__appointments td {
    padding: 8px 12px;
    border-bottom: 1px solid #f4f6f8;
    color: #272b41;
}

.cm-payment__appointments tr:last-child td { border-bottom: 0; }

.cm-payment__num { text-align: right; font-variant-numeric: tabular-nums; }

.cm-payment__footer {
    margin: 10px 0 0;
    font-size: .875rem;
    color: #6b7385;
}

/* --- Constancia --- */

.cm-payment__fields {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 14px;
}

.cm-payment__fields label { display: block; margin: 0; }

.cm-payment__fields span {
    display: block;
    font-size: .8rem;
    color: #6b7385;
    margin-bottom: 5px;
}

.cm-payment__fields em { color: #c0392b; font-style: normal; }

.cm-payment__fields input {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid #dfe3ea;
    border-radius: 8px;
    font: inherit;
    color: #272b41;
}

.cm-payment__fields input:focus {
    outline: 0;
    border-color: #20c0f3;
    box-shadow: 0 0 0 3px rgba(32, 192, 243, .15);
}

.cm-payment__fields input.is-invalid {
    border-color: #c0392b;
    box-shadow: 0 0 0 3px rgba(192, 57, 43, .12);
}

.cm-payment__notice {
    margin: 12px 0 0;
    font-size: .875rem;
    color: #6b7385;
}

.cm-payment__notice--bad { color: #c0392b; font-weight: 500; }

.cm-payment__actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 16px 24px;
    border-top: 1px solid #eceff3;
    background: #fbfcfd;
}

@media (max-width: 600px) {
    .cm-payment__fields { grid-template-columns: 1fr; }
    .cm-payment__body { padding: 4px 16px 8px; }
    .cm-payment__header, .cm-payment__actions { padding-left: 16px; padding-right: 16px; }
}

/* ===========================================================================
   Procesos automáticos
   ---------------------------------------------------------------------------
   Las colas primero, en tarjetas que se leen de un vistazo, y los trabajos
   después en tabla. El orden no es casual: cuando algo va mal, lo que se nota
   es la cola —correos que no salen, documentos que no llegan— y el trabajo es
   la causa que se busca después.
   ========================================================================= */

.cm-process-notice {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    background: #fdf5e6;
    border-left: 3px solid #d99518;
    border-radius: 0 8px 8px 0;
    padding: 14px 18px;
    margin-bottom: 24px;
    color: #5c4a2c;
}

.cm-process-notice i { color: #d99518; margin-top: 3px; }
.cm-process-notice strong { color: #7a5410; }
.cm-process-notice p { margin: 4px 0 0; font-size: .9rem; }

.cm-process-section {
    margin: 28px 0 14px;
    font-size: .75rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #9aa4ae;
    font-weight: 600;
}

.cm-process-queues {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 16px;
}

.cm-process-queue {
    background: #fff;
    border: 1px solid #eceff3;
    border-top: 3px solid #1c8a4d;
    border-radius: 10px;
    padding: 16px 18px;
}

.cm-process-queue--eye { border-top-color: #d99518; }
.cm-process-queue--bad { border-top-color: #c0392b; }

.cm-process-queue h6 {
    margin: 0 0 2px;
    font-size: 1rem;
    font-weight: 600;
    color: #272b41;
}

.cm-process-queue__that {
    margin: 0 0 14px;
    font-size: .85rem;
    color: #6b7385;
}

.cm-process-figures {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin: 0 0 12px;
    padding: 12px 0;
    border-top: 1px solid #f1f3f6;
    border-bottom: 1px solid #f1f3f6;
}

.cm-process-figures dt {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #9aa4ae;
    font-weight: 600;
    margin: 0 0 2px;
}

.cm-process-figures dd {
    margin: 0;
    font-size: 1.4rem;
    font-weight: 700;
    color: #272b41;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.cm-process-figure--bad dd { color: #c0392b; }

.cm-process-queue__footer { margin: 0; font-size: .85rem; color: #4d5c6b; }
.cm-process-queue__footer span { margin-left: 6px; font-size: .8rem; }

.cm-process-queue__error {
    margin: 10px 0 0;
    font-size: .8rem;
    color: #c0392b;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.cm-process-chip {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 8px;
    border-radius: 20px;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    font-weight: 600;
    vertical-align: middle;
}

.cm-process-chip--active { background: #e6f4ec; color: #14663a; }
.cm-process-chip--pause { background: #f1f3f6; color: #6b7385; }

/* --- La constancia y sus correcciones, en la tabla de pagos hechos --- */

.cm-payment-missing {
    color: #c0392b;
    font-size: .85rem;
    font-style: italic;
}

.cm-payment-correction {
    margin-top: 4px;
    font-size: .78rem;
    color: #8a5a12;
    cursor: help;
}

.cm-payment-correction i { margin-right: 4px; }

.cm-payment__reason textarea {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid #dfe3ea;
    border-radius: 8px;
    font: inherit;
    color: #272b41;
    resize: vertical;
}

.cm-payment__reason textarea:focus {
    outline: 0;
    border-color: #20c0f3;
    box-shadow: 0 0 0 3px rgba(32, 192, 243, .15);
}

.cm-payment__reason textarea.is-invalid {
    border-color: #c0392b;
    box-shadow: 0 0 0 3px rgba(192, 57, 43, .12);
}

/* --- Lo que hizo un trabajo la última vez --- */

.cm-process-done {
    margin-top: 4px;
    font-size: .8rem;
    display: flex;
    align-items: baseline;
    gap: 5px;
}

.cm-process-done--good { color: #14663a; }
.cm-process-done--eye { color: #8a5a12; }
.cm-process-done--bad { color: #c0392b; }
.cm-process-done span { font-size: .75rem; }

/* De qué consultas se compone un retiro.
   El importe llevaba debajo un "de 6 consultas cobradas" que no se podía abrir: para saber
   cuáles eran había que ir a los pagos del doctor y cruzar fechas a mano. Ahora es un botón,
   y parece un botón: sin fondo hasta que se pasa por encima, para no competir con el importe
   que está justo arriba. */

.cm-payment-show {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 2px 0 0 -6px;
    padding: 2px 6px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: #6c757d;
    font-size: 12px;
    line-height: 1.4;
    text-align: left;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

.cm-payment-show:hover,
.cm-payment-show:focus-visible {
    background: #eaf4fd;
    color: #2f8fe0;
}

.cm-payment-show i {
    font-size: 9px;
    opacity: .7;
}

/* ----------------------------------------------------------------------------
   El ahorro de la videoconsulta
   ----------------------------------------------------------------------------
   Va dentro de la opción, debajo de su descripción, y sólo aparece cuando hay
   ahorro de verdad. Verde y discreto: es un dato que ayuda a decidir, no una
   oferta que grita.
   -------------------------------------------------------------------------- */
.cm-modality__savings {
    display: inline-block;
    margin-top: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    background-color: #e8f7ee;
    color: #1b7f4d;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
}

/* El aviso de una tarifa baja, junto al campo mientras se escribe. */
.cm-fee__notice {
    font-size: 13px;
    line-height: 1.5;
    padding: 10px 12px;
    margin-bottom: 0;
}

/* ----------------------------------------------------------------------------
   Lo que falta para ser visible, en el panel del profesional
   ----------------------------------------------------------------------------
   Ámbar y no rojo: no ha hecho nada mal, le falta terminar. El rojo es para lo
   que está roto, y esto es una lista de tareas con final feliz.
   -------------------------------------------------------------------------- */
.cm-pending {
    background: #fffaf0;
    border: 1px solid #f5d9a8;
    border-left: 4px solid #e8a33d;
    border-radius: 12px;
    padding: 20px 22px;
    margin-bottom: 22px;
}

.cm-pending__header {
    display: flex;
    gap: 14px;
    align-items: flex-start;
}

.cm-pending__icon {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: #f7e2bf;
    color: #a4671a;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
}

.cm-pending__title {
    margin: 0 0 3px 0;
    font-size: 16px;
    font-weight: 600;
    color: #6b4410;
    line-height: 1.35;
}

.cm-pending__note {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.55;
    color: #8a6636;
}

.cm-pending__list {
    margin: 14px 0 0 54px;
    padding: 0;
    list-style: none;
    font-size: 14px;
    line-height: 1.6;
    color: #6b4410;
}

.cm-pending__list li {
    position: relative;
    padding-left: 22px;
    margin-bottom: 5px;
}

/* El círculo vacío dice «queda por hacer» sin necesidad de leerlo. */
.cm-pending__list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 6px;
    width: 11px;
    height: 11px;
    border: 2px solid #d9a55e;
    border-radius: 50%;
}

.cm-pending__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 18px 0 0 54px;
}

.cm-pending__actions .btn i {
    margin-right: 7px;
}

/* En pantalla estrecha la sangría del icono se come el ancho útil. */
@media (max-width: 575.98px) {
    .cm-pending__list,
    .cm-pending__actions {
        margin-left: 0;
    }

    .cm-pending__actions .btn {
        width: 100%;
        justify-content: center;
    }
}

/* Lo tiene todo y espera revisión: azul, que no es una tarea suya. */
.cm-pending--waiting {
    background: #f2f9fd;
    border-color: #c5e2f2;
    border-left-color: #20c0f3;
}

.cm-pending--waiting .cm-pending__icon {
    background: #d8eefa;
    color: #0c6a8c;
}

.cm-pending--waiting .cm-pending__title { color: #0c5c7a; }
.cm-pending--waiting .cm-pending__note { color: #3a7f9c; }

/* Las especialidades por acreditar: gris, deliberadamente. No le impiden salir en el
   portal —el que ya está publicado sigue publicado— así que no puede tener el mismo peso
   visual que la lista de lo que sí se lo impide. Es un recordatorio, no una alarma. */
.cm-pending--soft {
    background: #f7f9fb;
    border-color: #e0e6ec;
    border-left-color: #9aa7b4;
}

.cm-pending--soft .cm-pending__icon {
    background: #e8edf2;
    color: #5b6b7a;
}

.cm-pending--soft .cm-pending__title { color: #3d4a57; }
.cm-pending--soft .cm-pending__note { color: #6b7385; }

/* Publicado y sin agenda: verde, no ámbar.

   No ha hecho nada mal y no le falta ningún requisito —su perfil está entero y ya se
   ve—; lo que le queda es lo que hace que empiece a atender. Pintarlo de alarma sería
   decirle que hay un problema cuando lo que hay es el siguiente paso. */
.cm-pending--schedule {
    background: #f1faf4;
    border-color: #c6e6d3;
    border-left-color: #2fae66;
}

.cm-pending--schedule .cm-pending__icon {
    background: #dcf1e5;
    color: #14663a;
}

.cm-pending--schedule .cm-pending__title { color: #14663a; }
.cm-pending--schedule .cm-pending__note { color: #3f7a58; }

/* El motivo del rechazo, en su propia línea: leído a continuación del nombre de la
   especialidad se confunde con ella. */
.cm-pending__reason {
    display: block;
    margin-top: 3px;
    font-size: .84rem;
    font-style: italic;
    color: #6b7385;
}

/* Se lo devolvieron: ámbar, porque sí hay algo que hacer, pero no es un fallo suyo
   ni una lista de campos vacíos —es lo que alguien le pidió que reescribiera—. */
.cm-pending--returned {
    background: #fdf7ee;
    border-color: #f0dcbc;
    border-left-color: #e0a355;
}

.cm-pending--returned .cm-pending__icon {
    background: #f8e9d2;
    color: #96601c;
}

.cm-pending--returned .cm-pending__title { color: #8a5715; }
.cm-pending--returned .cm-pending__note { color: #a4783c; }

/* Lo que dijo quien lo revisó, con sus palabras. Va citado y no como un párrafo más
   para que se vea que es de otra persona y no un texto de la aplicación. */
.cm-pending__notes {
    margin: 14px 0 0 0;
    padding: 12px 16px;
    border-left: 3px solid #e0a355;
    background: #fffdf9;
    border-radius: 0 8px 8px 0;
    color: #5c4423;
    font-size: 14px;
    line-height: 1.6;
    white-space: pre-line;
}

/* El hueco donde la plantilla pone el aviso: sin margen propio cuando no hay nada
   que pintar, para que no deje un espacio en las pantallas de quien no es doctor. */
.cm-pending__gap:empty {
    display: none;
}

.cm-pending__gap > .cm-pending {
    margin-top: 22px;
}

/* ----------------------------------------------------------------------------
   El mapa donde el profesional marca su consultorio
   -------------------------------------------------------------------------- */
/* La fila del buscador se parte.
   
   Eran tres controles en un flex que no se partía: el campo de búsqueda, la lupa
   y «Usar mi ubicación». Un flex no encoge a sus hijos por debajo de su contenido
   —min-width vale auto— así que en un teléfono la suma de los tres medía más que
   la pantalla: el botón se salía treinta y dos píxeles y arrastraba la página
   entera de lado. Medido a 375: el documento salía a 393. */
.cm-map__search {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 10px;
}

.cm-map__search input[type="search"] {
    flex: 1 1 10rem;
    min-width: 0;
}

.cm-map__search .cm-btn {
    flex: 0 0 auto;
}

.cm-map__canvas {
    height: 320px;
    border-radius: 10px;
    border: 1px solid #dee2e7;
    z-index: 0;   /* Leaflet sube sus capas; sin esto tapa los menús de encima. */
}

.cm-map__chosen {
    margin: 8px 0 0 0;
    font-size: 13px;
    color: #6b7385;
}

@media (max-width: 575.98px) {
    .cm-map__canvas { height: 260px; }

    /* «Usar mi ubicación» se lleva su propia línea: al lado del buscador no cabe
       en ningún teléfono, y es la acción que más se usa de las tres. */
    .cm-map__search .cm-btn--ghost {
        flex: 1 1 100%;
        justify-content: center;
    }
}

/* ----------------------------------------------------------------------------
   Bloques de lista del perfil: formación, experiencia, premios
   ----------------------------------------------------------------------------
   Filas que se añaden y se quitan. La papelera va al final de la fila y no
   dentro de los campos: quitar una fila entera es una acción sobre la fila, no
   sobre ninguno de sus datos.
   -------------------------------------------------------------------------- */
.cm-block {
    background: #ffffff;
    border: 1px solid #e6eaee;
    border-radius: 12px;
    padding: 22px 24px;
    margin-bottom: 22px;
}

.cm-block__header { margin-bottom: 16px; }

.cm-block__title {
    margin: 0 0 4px 0;
    font-size: 17px;
    font-weight: 600;
    color: #272b41;
}

.cm-block__note {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.55;
    color: #6b7385;
}

.cm-list { display: grid; gap: 14px; }

.cm-list__row {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 16px;
    border: 1px solid #eef1f4;
    border-radius: 10px;
    background: #fbfcfd;
}

.cm-list__fields {
    flex: 1 1 auto;
    display: grid;
    gap: 14px;
    min-width: 0;   /* Sin esto, un select largo estira la rejilla y desborda. */
}

.cm-list__fields--2 { grid-template-columns: 1fr 1fr; }
.cm-list__fields--4 { grid-template-columns: 2fr 2fr 1fr 1fr; }

.cm-list__row .cm-field { margin-bottom: 0; }

/* La papelera se alinea con los campos, no con la etiqueta de encima. */
.cm-list__remove {
    flex: 0 0 auto;
    margin-top: 26px;
    width: 38px;
    height: 38px;
    border-radius: 9px;
    border: 1px solid #f0d3d3;
    background: #fdf3f3;
    color: #c0392b;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.cm-list__remove:hover { background: #fbe6e6; }

.cm-list__add {
    margin-top: 14px;
    padding: 9px 16px;
    border-radius: 9px;
    border: 1px dashed #b9c6d1;
    background: transparent;
    color: #20c0f3;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.cm-list__add:hover { background: #f2fafd; border-color: #20c0f3; }

.cm-list__add i { margin-right: 6px; }

/* ----------------------------------------------------------------------------
   El perfil: lo que impide guardar, y la modalidad con su precio
   -------------------------------------------------------------------------- */

/* Todo lo que impidió guardar, arriba y junto. Un aviso colgado de un campo que
   no se está pintando no lo ve nadie, y eso dejaba al profesional pulsando
   «Guardar» sin que pasara nada visible. */
.cm-errors {
    background: #fdf0f0;
    border: 1px solid #f2cfcf;
    border-left: 4px solid #c0392b;
    border-radius: 12px;
    padding: 16px 20px;
    margin-bottom: 22px;
}

.cm-errors__title {
    margin: 0 0 8px 0;
    font-size: 15px;
    font-weight: 600;
    color: #93302f;
}

.cm-errors ul { margin: 0; padding-left: 22px; color: #6b2f2f; font-size: 14px; line-height: 1.6; }
.cm-errors li { margin-bottom: 3px; }

/* Las dos marcas de un campo, que no son lo mismo:
   el asterisco rojo dice «sin esto no se guarda»; estas dicen otra cosa —que no
   se puede tocar, o que hace falta para aparecer en el portal pero no para
   guardar—. Mezclarlas en un solo símbolo es lo que hace que nadie se fíe de
   ninguno. */
.cm-field__mark {
    margin-left: 7px;
    padding: 1px 8px;
    border-radius: 999px;
    background: #eef1f4;
    color: #6b7385;
    font-size: 11.5px;
    font-weight: 500;
    vertical-align: middle;
    text-transform: none;
    letter-spacing: 0;
}

.cm-field__mark--publish { background: #e6f4fb; color: #0c6a8c; }
.cm-field__mark--ok { background: #eaf6ef; color: #14663a; }

/* ----------------------------------------------------------------------------
   El estado de una especialidad declarada
   ----------------------------------------------------------------------------
   Una especialidad no vale porque se escriba: hay que subir el documento que la
   acredita y un administrador lo comprueba. Mientras tanto no sale en la ficha
   pública ni se puede elegir al registrar una consulta.

   Cada estado tiene su color y, cuando hay algo que hacer, su enlace. El rechazo
   lleva siempre el motivo: es lo único que le dice al profesional qué arreglar.
   ---------------------------------------------------------------------------- */
.cm-specialty__status {
    grid-column: 1 / -1;
    margin: 8px 0 0 0;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--cm-rule, #e3e8ef);
    background: #f7fafc;
    font-size: .84rem;
    line-height: 1.5;
}

.cm-specialty__line {
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: 7px;
    color: var(--cm-ink-soft, #6b7385);
}

.cm-specialty__line i { flex: none; }

.cm-specialty__status--missing-document {
    background: #fdf6e7;
    border-color: #f2e2bd;
}

.cm-specialty__status--missing-document .cm-specialty__line { color: #7a5b12; }

.cm-specialty__status--under-review {
    background: #eef4fb;
    border-color: #d6e3f2;
}

.cm-specialty__status--under-review .cm-specialty__line { color: #2c5580; }

.cm-specialty__status--rejected {
    background: #fdf1f1;
    border-color: #f3d2d2;
}

.cm-specialty__status--rejected .cm-specialty__line { color: #a02020; }

.cm-specialty__reason {
    margin: 6px 0 0 0;
    color: var(--cm-ink, #272b41);
}

.cm-specialty__that-do {
    margin: 6px 0 0 0;
    color: var(--cm-ink-soft, #6b7385);
}

.cm-specialty__link {
    display: inline-block;
    margin-top: 6px;
    font-weight: 600;
    color: #0c6a8c;
    text-decoration: underline;
}

/* El aviso que explica qué pasa al añadir una especialidad. Va debajo del botón
   de añadir, donde lo lee quien está a punto de hacerlo. */
.cm-block__notice {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 12px 0 0 0;
    padding: 11px 13px;
    border-radius: 8px;
    background: #eef4fb;
    border: 1px solid #d6e3f2;
    color: #2c5580;
    font-size: .84rem;
    line-height: 1.55;
}

.cm-block__notice i { flex: none; }

/* ----------------------------------------------------------------------------
   El selector de servicios
   ----------------------------------------------------------------------------
   Era un <select multiple> con Ctrl. En el móvil no hay Ctrl, y un descuido
   borraba toda la selección.

   Sobre las columnas: la referencia de patrones de formulario recomienda lista
   vertical con buscador, no rejilla — leer en columnas rompe el orden natural
   de arriba abajo. Aquí se usan dos dentro de cada grupo sólo en pantallas
   anchas, donde una sola columna dejaría media pantalla vacía y obligaría a
   desplazarse por ciento veintitrés opciones; en cuanto la pantalla estrecha,
   vuelve a una.
   -------------------------------------------------------------------------- */
.cm-selector {
    border: 1px solid var(--cm-border, #cfd7e3);
    border-radius: 12px;
    background: #fff;
    overflow: hidden;
}

/* Lo elegido, arriba y siempre a la vista: para repasarlo sin abrir nada. */
.cm-selector__records {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid #eef1f4;
    background: #f7fafc;
    min-height: 54px;
}

.cm-selector__records--empty::before {
    content: attr(data-empty);
    color: #a2abba;
    font-size: 14px;
    align-self: center;
}

.cm-record {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* 44px de alto: es el mínimo para un objetivo táctil que se acierte. */
    min-height: 36px;
    padding: 6px 8px 6px 14px;
    border: 1px solid #bfe6f7;
    border-radius: 999px;
    background: #e6f4fb;
    color: #0c5c7a;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
}

.cm-record i {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(12, 92, 122, .12);
    font-size: 11px;
}

.cm-record:hover { background: #d3ecf8; }
.cm-record:hover i { background: rgba(12, 92, 122, .22); }

.cm-selector__search {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 14px;
    border-bottom: 1px solid #eef1f4;
}

.cm-selector__search i { color: #a2abba; }

.cm-selector__search input {
    flex: 1;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding-left: 0 !important;
}

.cm-selector__list { max-height: 420px; overflow-y: auto; }

.cm-selector__header {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 11px 14px;
    border: 0;
    border-top: 1px solid #f2f4f7;
    background: #fff;
    font-size: 14px;
    font-weight: 600;
    color: #272b41;
    cursor: pointer;
    text-align: left;
}

.cm-selector__header:hover { background: #f7fafc; }
.cm-selector__header > span { flex: 1; }

.cm-selector__header > i {
    color: #a2abba;
    font-size: 12px;
    transition: transform .15s ease;
}

.cm-selector__header[aria-expanded="true"] > i { transform: rotate(90deg); }

.cm-selector__header > small {
    padding: 1px 9px;
    border-radius: 999px;
    background: #eef1f4;
    color: #6b7385;
    font-size: 11.5px;
    font-weight: 500;
}

/* La especialidad del propio profesional viene abierta y marcada: es donde va a
   encontrar lo suyo, y lo demás es ruido hasta que lo busque. */
.cm-selector__group[data-theirs="yes"] > .cm-selector__header { background: #f2f9fd; color: #0c5c7a; }
.cm-selector__group[data-theirs="yes"] > .cm-selector__header > small { background: #d3ecf8; color: #0c5c7a; }

.cm-selector__options { padding: 6px 14px 12px; }

.cm-selector__option {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    /* Alto de objetivo táctil: en el móvil se acierta o no se acierta. */
    min-height: 44px;
    padding: 8px 10px;
    border-radius: 8px;
    margin: 0;
    cursor: pointer;
    break-inside: avoid;
}

.cm-selector__option:hover { background: #f7fafc; }

.cm-selector__option input {
    width: 19px;
    height: 19px;
    margin-top: 2px;
    accent-color: #20c0f3;
    flex: 0 0 auto;
}

.cm-selector__option strong { display: block; font-size: 14px; font-weight: 500; color: #272b41; }
.cm-selector__option small { display: block; font-size: 12.5px; line-height: 1.45; color: #6b7385; }

.cm-selector__empty { margin: 0; padding: 18px 16px; color: #6b7385; font-size: 14px; }

/* Dos columnas sólo donde sobra ancho. Por debajo, una: leer en columnas en una
   pantalla estrecha es peor que desplazarse. */
@media (min-width: 992px) {
    .cm-selector__options { columns: 2; column-gap: 18px; }
}

/* Cuánto le falta. Un formulario largo sin saber cuánto queda es lo que lo hace
   abrumador: no se ve el final. */
.cm-progress {
    background: #fff;
    border: 1px solid #e6eaee;
    border-radius: 12px;
    padding: 16px 20px;
    margin-bottom: 22px;
}

.cm-progress__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
    font-size: 15px;
    color: #272b41;
}

.cm-progress__header span { font-size: 13.5px; color: #6b7385; }

.cm-progress__bar {
    height: 8px;
    border-radius: 999px;
    background: #eef1f4;
    overflow: hidden;
}

.cm-progress__bar > span {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, #20c0f3, #09e5ab);
    transition: width .3s ease;
}

.cm-progress--ready .cm-progress__bar > span { background: #1c8a4d; }
.cm-progress--ready .cm-progress__header strong { color: #14663a; }

/* La cabecera de un grupo de bloques: separa «lo que hay que poner» de «lo que
   suma pero no bloquea», que es la diferencia que más se agradece en un
   formulario largo. */
.cm-block__group { margin: 30px 0 14px; }

.cm-group__title {
    margin: 0 0 4px 0;
    font-size: 19px;
    font-weight: 600;
    color: #272b41;
}

.cm-group__title small {
    margin-left: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    background: #eef1f4;
    color: #6b7385;
    font-size: 12px;
    font-weight: 500;
    vertical-align: middle;
}

.cm-group__note { margin: 0; font-size: 13.5px; line-height: 1.55; color: #6b7385; }

/* El interruptor del precio de fin de semana: pequeño y pegado a su modalidad,
   que es un matiz y no una decisión del mismo peso. */
.cm-fee__weekend { margin: 2px 0 10px; }

.cm-fee__switch {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 13.5px;
    color: #6b7385;
    cursor: pointer;
    margin: 0;
}

.cm-fee__switch input { width: 18px; height: 18px; accent-color: #20c0f3; }

/* Cada modalidad, con lo suyo dentro: se lee que el precio pertenece a la
   casilla de arriba y no al bloque entero. */
.cm-modality {
    padding: 14px 16px;
    border: 1px solid #eef1f4;
    border-radius: 10px;
    margin-bottom: 12px;
    background: #fbfcfd;
}

.cm-modality__note { margin-top: 18px; padding-top: 16px; border-top: 1px solid #eef1f4; }

.cm-modality__notice {
    margin: 0 0 14px 0;
    padding: 11px 14px;
    border-radius: 8px;
    background: #fdf0f0;
    color: #93302f;
    font-size: 14px;
    font-weight: 600;
}

.cm-fees { display: grid; gap: 14px; margin-top: 4px; }

.cm-fee__box {
    padding: 14px 16px;
    border: 1px dashed #cfd7e3;
    border-radius: 10px;
    background: #fff;
}

/* El importe con su símbolo pegado, para que se lea que es dinero. */
.cm-fee__amount { display: flex; align-items: stretch; }

.cm-fee__currency {
    display: flex;
    align-items: center;
    padding: 0 13px;
    border: 1px solid #cfd7e3;
    border-right: 0;
    border-radius: 10px 0 0 10px;
    background: #f7fafc;
    color: #6b7385;
    font-weight: 600;
}

.cm-fee__amount input { border-radius: 0 10px 10px 0 !important; }

/* El consultorio cuelga de «presencial»: metido hacia dentro para que se lea
   que es suyo y no del bloque entero. */
.cm-office {
    margin-top: 18px;
    padding: 16px 18px;
    border: 1px solid #e3e8ef;
    border-radius: 10px;
    background: #f7fafc;
}

.cm-office__title { margin: 0 0 14px 0; font-size: 15px; font-weight: 600; color: #272b41; }

@media (max-width: 575.98px) {
    .cm-office { padding: 14px; }
}

/* El botón que guarda la pantalla entera. Va solo y al final, para que se lea como
   lo que es: uno para todo, y no uno por bloque. */
.cm-save {
    display: flex;
    justify-content: flex-end;
    margin: 4px 0 28px;
}

.cm-save .cm-btn { min-width: 190px; }

@media (max-width: 575.98px) {
    .cm-save .cm-btn { width: 100%; }
}

/* Cuando no hay ninguna fila, el botón es lo único que queda: que no parezca perdido. */
.cm-list:empty + .cm-list__add { margin-top: 0; }

@media (max-width: 991.98px) {
    .cm-list__fields--4 { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 575.98px) {
    .cm-list__fields--2,
    .cm-list__fields--4 { grid-template-columns: 1fr; }

    .cm-list__row { flex-direction: column; }

    .cm-list__remove { margin-top: 0; width: 100%; }
}

/* El diálogo de confirmar, cuando sólo avisa: un botón y nada que decidir. */
.cm-confirm__actions button[hidden] { display: none; }

/* Aviso de que el profesional atiende en otro país. No bloquea la reserva: informa
   antes de pagar, que es cuando todavía se puede elegir videoconsulta. */
.cm-other-country {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    margin: .75rem 0 0;
    padding: .7rem .9rem;
    border-left: 3px solid var(--cm-amber, #b7791f);
    border-radius: 0 var(--cm-radius-sm) var(--cm-radius-sm) 0;
    background: var(--cm-amber-soft, #fdf3e2);
    color: var(--cm-amber-dark, #7a5b12);
    font-size: .86rem;
    line-height: 1.5;
}

.cm-other-country > i { margin-top: .15rem; flex: none; }

/* ── Lo que el paciente manda durante la consulta ──────────────────────────
   Va en la columna del profesional, junto al vídeo. Que llegue algo mientras
   se habla merece un aviso: él está mirando al paciente, no a esta columna. */
.cm-attachments-doctor { margin-bottom: 1rem; }

.cm-attachments-doctor__title {
    display: flex;
    align-items: center;
    gap: .45rem;
    font-size: .92rem;
    font-weight: 600;
    margin: 0 0 .6rem;
}

.cm-attachments-doctor__title > i { color: var(--cm-cyan-dark); }

.cm-attachments-doctor__count {
    margin-left: auto;
    background: var(--cm-cyan-soft);
    color: var(--cm-cyan-dark);
    border-radius: 999px;
    padding: 0 .5rem;
    font-size: .78rem;
    font-variant-numeric: tabular-nums;
}

.cm-attachments-doctor__count[hidden] { display: none; }

.cm-attachments-doctor__empty { font-size: .82rem; color: var(--cm-gray); margin: 0; }
.cm-attachments-doctor__empty[hidden] { display: none; }

.cm-attachments-doctor__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; }

.cm-attachments-doctor__list a {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .84rem;
    color: var(--cm-ink);
    text-decoration: none;
    padding: .35rem .5rem;
    border-radius: var(--cm-radius-sm);
}

.cm-attachments-doctor__list a:hover { background: var(--cm-bg); }
.cm-attachments-doctor__list span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-attachments-doctor__list small { color: var(--cm-gray); margin-left: auto; flex: none; }

/* El resultado de un examen que él mismo pidió, que puede venir de otra consulta. */
.cm-attachments-doctor__list .cm-attachments-doctor__mark {
    display: block;
    margin: -.15rem 0 .25rem 2rem;
    font-size: .72rem;
    color: var(--cm-cyan-dark);
}

@media (prefers-reduced-motion: no-preference) {
    .cm-attachments-doctor--new { animation: cm-llego 1.2s ease-in-out 2; }

    @keyframes cm-llego {
        0%, 100% { box-shadow: none; }
        50% { box-shadow: 0 0 0 3px var(--cm-cyan-soft); }
    }
}

/* ---------------------------------------------------------------------------
   Los resultados del examen, en la ficha de la cita del paciente.
   Donde el paciente sube lo que el laboratorio le entregó, contra el pedido
   que le hicieron. Se apoya en la tarjeta que ya está, sin repetir su marco.
   --------------------------------------------------------------------------- */
.cm-results {
    margin-top: 1rem;
    padding: 1rem;
    border: 1px dashed var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-bg);
}

.cm-results__title {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin: 0 0 .35rem;
    font-size: .95rem;
    font-weight: 600;
    color: var(--cm-ink);
}

.cm-results__note { margin: 0 0 .75rem; font-size: .82rem; color: var(--cm-gray); }
.cm-results__empty { margin: 0 0 .75rem; font-size: .82rem; color: var(--cm-gray); }
.cm-results__empty[hidden] { display: none; }

.cm-results__list { list-style: none; margin: 0 0 .5rem; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.cm-results__list:empty { margin: 0; }

.cm-results__list a {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .84rem;
    color: var(--cm-ink);
    text-decoration: none;
    padding: .4rem .55rem;
    border-radius: var(--cm-radius-sm);
    background: var(--cm-white);
    border: 1px solid var(--cm-rule);
}

.cm-results__list a:hover { border-color: var(--cm-cyan); }
.cm-results__list span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-results__list small { color: var(--cm-gray); margin-left: auto; flex: none; }

.cm-results__button { display: inline-flex; align-items: center; gap: .4rem; }

/* Lo que espera a que el profesional lo registre, bajo su saldo. */
.cm-balance__waiting {
    display: flex;
    align-items: baseline;
    gap: .45rem;
    margin: .6rem 0 0;
    font-size: .85rem;
    line-height: 1.5;
    color: var(--cm-amber);
}

/* ---------------------------------------------------------------------------
   Los precios del perfil, agrupados por modalidad.

   Los cuatro iban seguidos y con los de fin de semana apagados quedaba un
   interruptor suelto justo encima del precio de la otra modalidad: se leía como
   su rótulo. Cada bloque lleva ahora el nombre de su modalidad y todo lo suyo
   dentro, para que no haya duda de a qué precio pertenece cada casilla.
   --------------------------------------------------------------------------- */
.cm-fee__group {
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-bg);
    padding: 1rem 1.1rem;
    margin: 0 0 .85rem;
}

.cm-fee__group[hidden] { display: none; }

.cm-fee__group-title {
    margin: 0 0 .75rem;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--cm-gray);
}

/* El interruptor cuelga del precio de arriba, no flota entre los dos. */
.cm-fee__group .cm-fee__weekend { margin: .75rem 0 0; }
.cm-fee__group .cm-fee__box[data-weekend="yes"] { margin-top: .75rem; }
.cm-fee__group .cm-fee__box[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   Las consultas que quedaron a medio escribir.
   No se borran —un registro clínico no se borra— pero tienen que verse: en la
   agenda, una a medio escribir y una sin tocar se veían exactamente igual. Vive
   aquí y no en schedule.css porque sale en dos pantallas con hojas distintas.
   --------------------------------------------------------------------------- */
.cm-schedule__unclosed {
    margin: 0 0 1.25rem;
    padding: .9rem 1.1rem;
    border-left: 3px solid var(--cm-amber, #b7791f);
    border-radius: var(--cm-radius, 12px);
    background: var(--cm-amber-bg, #fdf3e2);
}

.cm-schedule__unclosedTitle {
    display: flex;
    align-items: baseline;
    gap: .45rem;
    margin: 0 0 .2rem;
    font-size: .95rem;
    color: #7a5210;
}

.cm-schedule__unclosedNote { margin: 0 0 .6rem; font-size: .82rem; color: #8a6420; }

.cm-schedule__unclosedList { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }

.cm-schedule__unclosedList a {
    display: inline-flex;
    align-items: baseline;
    gap: .35rem;
    padding: .3rem .65rem;
    border-radius: 999px;
    background: var(--cm-white, #fff);
    border: 1px solid #e6d3b0;
    font-size: .82rem;
    color: #7a5210;
    text-decoration: none;
}

.cm-schedule__unclosedList a:hover { border-color: var(--cm-amber, #b7791f); }
.cm-schedule__unclosedList span { color: #a08a5e; }

.cm-appointment__started { color: var(--cm-amber, #b7791f); }

/* ============================================================================
   Los modales se colocaban en mitad del documento, no en la pantalla
   ----------------------------------------------------------------------------
   La plantilla difumina la página mientras hay un modal abierto:

       .modal-open .main-wrapper { filter: blur(1px); }

   Y `filter` sobre un elemento lo convierte en el bloque contenedor de todos
   sus descendientes con `position: fixed`. El modal vive dentro de
   `.main-wrapper` —ahí es donde el diseño mete el cuerpo de cada vista—, así que
   al abrirse dejaba de estar anclado a la pantalla y pasaba a estarlo al
   documento: arriba del todo, con la altura de la página entera, y centrado
   respecto a esa altura. En una página larga eso lo manda a cientos de píxeles
   de donde está mirando quien lo abrió.

   En el escritorio se disimulaba, porque las páginas son cortas y el modal caía
   cerca. En el teléfono, donde la pantalla de la consulta se apila y mide varias
   veces la ventana, sólo asomaba la cabecera por el borde de abajo: el doctor
   veía «Triaje de la consulta» y una equis, sin nada donde escribir. Y borroso,
   porque el modal también es descendiente de lo que se difumina.

   Le pasaba a todos los modales de la aplicación, no sólo al del triaje.

   Se quita el difuminado entero. El fondo oscuro que Bootstrap pone ya separa
   el modal de la página; el desenfoque no añadía nada y rompía la única cosa
   que un modal necesita, que es saber dónde está la pantalla.
   ========================================================================== */
.modal-open .main-wrapper {
    -webkit-filter: none;
    filter: none;
}


/* ============================================================================
   El estado de una factura
   ----------------------------------------------------------------------------
   En el panel del doctor había un checkbox desactivado que decía sí o no.
   Emitir no es una cosa de dos estados ni la decide el doctor: la factura la
   emite la plataforma y puede estar pendiente, en proceso, emitida, con error o
   anulada. Un interruptor apagado no distingue «todavía no» de «falló», que es
   justo lo que hay que saber.

   No se reutiliza .cm-status de dashboard.css porque esa hoja no la carga esta
   pantalla, y una clase que no llega no es un estilo: es un texto suelto.
   ========================================================================== */
.cm-status-invoice {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
    background: rgba(39, 43, 65, .07);
    color: var(--cm-gray);
}

/* Emitida. */
.cm-status-invoice--sent { background: rgba(15, 143, 104, .12); color: #0f8f68; }

/* Camino normal, todavía sin terminar. */
.cm-status-invoice--pending,
.cm-status-invoice--draft { background: rgba(39, 43, 65, .07); color: var(--cm-gray); }

.cm-status-invoice--processing { background: rgba(32, 192, 243, .14); color: var(--cm-cyan-dark); }

/* Lo que hay que mirar. */
.cm-status-invoice--failed,
.cm-status-invoice--cancelled { background: rgba(176, 48, 48, .1); color: #b03030; }

/* ============================================================================
   Mis Pagos: las cifras y las citas de cada pago
   ----------------------------------------------------------------------------
   Una tarjeta por pago recibido (con las clases de Mis documentos, .cm-file)
   y, arriba a la derecha, el total recibido y la comisión vigente. Las citas que
   cubre cada pago van plegadas en un <details>.
   ========================================================================== */
.cm-payments__figures {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 28px;
    flex: 0 0 auto;
}

.cm-payments__appointments {
    margin-top: 8px;
    font-size: .84rem;
}

.cm-payments__appointments summary {
    cursor: pointer;
    color: var(--cm-cyan-dark);
    font-weight: 600;
    list-style: none;
}

.cm-payments__appointments summary::-webkit-details-marker { display: none; }

.cm-payments__appointments summary::before {
    content: '\25B8';
    display: inline-block;
    margin-right: 6px;
    transition: transform .15s ease;
}

.cm-payments__appointments[open] summary::before { transform: rotate(90deg); }

.cm-payments__appointments ul {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.cm-payments__appointments li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 12px;
    align-items: baseline;
    padding: 4px 0;
    border-top: 1px dashed var(--cm-rule);
}

.cm-payments__appointments li a { font-variant-numeric: tabular-nums; }

.cm-payments__appointments li span { color: var(--cm-gray); overflow-wrap: anywhere; }

.cm-payments__appointments li strong { font-variant-numeric: tabular-nums; }

.cm-payments__figure {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.cm-payments__label {
    font-size: .78rem;
    color: var(--cm-gray);
    line-height: 1.3;
}

.cm-payments__value {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.2;
}

/* ============================================================================
   Los mandos de las tablas, en el teléfono
   ----------------------------------------------------------------------------
   DataTables saca «Ver N filas» y «Buscar:» flotados a los lados. En un móvil no
   caben en la misma línea: la caja de búsqueda se salía por la derecha y
   arrastraba la página entera de lado. Debajo de 768px se apilan y ocupan todo
   el ancho, que es lo que hace falta para escribir dentro.
   ========================================================================== */
@media (max-width: 767.98px) {

    .dataTables_wrapper .dataTables_length,
    .dataTables_wrapper .dataTables_filter,
    .dataTables_wrapper .dataTables_info,
    .dataTables_wrapper .dataTables_paginate {
        float: none;
        width: 100%;
        text-align: left;
        margin-bottom: .5rem;
    }

    .dataTables_wrapper .dataTables_filter label,
    .dataTables_wrapper .dataTables_length label {
        display: flex;
        align-items: center;
        gap: .5rem;
        width: 100%;
        margin: 0;
    }

    .dataTables_wrapper .dataTables_filter input {
        flex: 1 1 auto;
        min-width: 0;
        width: auto;
        margin: 0;
    }

    .dataTables_wrapper .dataTables_length select {
        flex: 0 0 auto;
        width: auto;
    }

    /* La paginación se centra: con la fila entera para ella, pegada a la
       izquierda parecía cortada. */
    .dataTables_wrapper .dataTables_paginate {
        text-align: center;
    }

    /* Y el envoltorio no desplaza nada de lado por su cuenta. */
    .dataTables_wrapper {
        overflow-x: hidden;
    }
}

/* ============================================================================
   Los documentos de la consulta
   ----------------------------------------------------------------------------
   La cita guarda cuatro documentos —receta, laboratorio, certificado de reposo e
   informe de atención— y ninguna pantalla los enseñaba los cuatro. La del
   paciente listaba los medicamentos y los exámenes como texto, sin un enlace al
   PDF: si borraba el correo, había perdido su receta. La del doctor ofrecía dos,
   escondidas detrás de un icono repetido en cada línea.

   Una tarjeta por documento, con lo que hace falta para usarlo: qué es, qué
   lleva dentro, cuándo se firmó, el código con el que se comprueba y el PDF.
   ========================================================================== */
.cm-docs {
    margin-bottom: 1.25rem;
}

.cm-docs__title {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: 1rem;
    font-weight: 700;
    color: var(--cm-ink);
    margin: 0 0 .75rem;
}

.cm-docs__title i { color: var(--cm-cyan-dark); }

.cm-docs__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 12px;
}

.cm-doc {
    display: grid;
    grid-template-columns: 44px 1fr;
    gap: 0 14px;
    align-items: start;
    padding: 16px;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-white);
    box-shadow: var(--cm-shadow);
    min-width: 0;
}

.cm-doc__icon {
    grid-row: 1 / span 2;
    width: 44px;
    height: 44px;
    border-radius: 11px;
    display: grid;
    place-items: center;
    background: rgba(32, 192, 243, .12);
    color: var(--cm-cyan-dark);
    font-size: 1.05rem;
}

.cm-doc__body { min-width: 0; }

.cm-doc__name {
    font-size: .98rem;
    font-weight: 700;
    color: var(--cm-ink);
    margin: 0 0 2px;
}

.cm-doc__detail,
.cm-doc__signature,
.cm-doc__code {
    margin: 0;
    font-size: .82rem;
    line-height: 1.5;
}

.cm-doc__detail { color: var(--cm-gray); }

.cm-doc__signed { color: #0f8f68; font-weight: 600; }
.cm-doc__pending { color: var(--cm-gray-light); }

.cm-doc__code {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    margin-top: 2px;
    color: var(--cm-gray-light);
}

.cm-doc__code code {
    font-size: .84rem;
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--cm-ink);
    background: #f3f6f9;
    padding: 1px 7px;
    border-radius: 5px;
    overflow-wrap: anywhere;
}

/* Los botones, debajo de todo y a lo ancho de la tarjeta: en una columna de
   280px no caben al lado del texto sin partirse por la mitad. */
.cm-doc__actions {
    grid-column: 2;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

.cm-doc__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex: 1 1 auto;
    min-height: 36px;
    padding: 6px 14px;
    border-radius: 8px;
    border: 1px solid var(--cm-border);
    background: transparent;
    color: var(--cm-ink);
    font-size: .84rem;
    font-weight: 600;
    text-decoration: none;
    transition: background .15s ease, border-color .15s ease;
}

.cm-doc__btn:hover {
    background: #f3f6f9;
    color: var(--cm-ink);
    border-color: var(--cm-gray-light);
}

.cm-doc__btn--main {
    background: var(--cm-cyan);
    border-color: var(--cm-cyan);
    color: #fff;
}

.cm-doc__btn--main:hover {
    background: var(--cm-cyan-dark);
    border-color: var(--cm-cyan-dark);
    color: #fff;
}

@media (max-width: 400px) {
    .cm-doc { grid-template-columns: 36px 1fr; gap: 0 11px; padding: 14px; }
    .cm-doc__icon { width: 36px; height: 36px; font-size: .95rem; }
}

/* ==========================================================================
   Compartir el perfil
   --------------------------------------------------------------------------
   Va debajo del nombre en la barra lateral, que sale en todas las pantallas
   del profesional: compartir su página no es algo que se haga desde una
   pantalla concreta, es algo que se hace cuando surge.

   Ancho completo y sin color fuerte: es una acción secundaria y no debe
   competir con el menú que tiene justo debajo.
   ========================================================================== */
.cm-share {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin-top: 14px;
    padding: 10px 14px;
    background: var(--cm-white);
    border: 1px solid var(--cm-rule);
    border-radius: 10px;
    color: var(--cm-ink);
    font-size: .9rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.cm-share:hover {
    border-color: var(--cm-ink);
}

.cm-share:disabled {
    opacity: .6;
    cursor: default;
}

/* Mientras dice «Copiado». Se marca con color, no con un icono nuevo: cambiar
   el icono a la vez que el texto hace que el botón parezca otro botón. */
.cm-share--done,
.cm-share--done:hover {
    border-color: var(--cm-green);
    color: var(--cm-green);
}

/* En la ficha, compartir va en la MISMA fila que «Agendar» y no debajo.

   Debajo ocupaba una fila entera y estiraba la columna de la derecha unos
   cincuenta puntos. Como la columna de la izquierda no crece con ella —tiene lo
   que tiene: foto, nombre, servicios y la próxima hora— ese estirón se veía como
   un vacío a la izquierda de los botones, y era mío.

   Con contorno y no relleno, porque sigue siendo la secundaria: quien llega a la
   ficha viene a reservar. Las medidas son las de `.clinic-booking a.apt-btn` de
   la plantilla, copiadas aquí porque esa hoja no se toca. */
.clinic-booking {
    display: flex;
    align-items: stretch;
    gap: 8px;
}

.clinic-booking a.apt-btn {
    flex: 1 1 auto;
    /* La plantilla se lo pone al 100% y aquí manda el reparto del flex. */
    width: auto;
    margin: 0;
}

.cm-share--record {
    flex: 0 0 auto;
    /* La clase base lo pone al 100% —allí es un botón de barra lateral, solo en su
       fila— y aquí comparte fila con «Agendar»: sin esto se lo come entero. */
    width: auto;
    margin: 0;
    /* Más apretado que «Agendar» y con menos espaciado entre letras: comparten fila y
       el principal tiene que seguir siendo el más ancho de los dos. */
    padding: 10px 12px;
    border-radius: 4px;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: .4px;
    text-transform: uppercase;
    border: 2px solid var(--cm-rule);
    color: var(--cm-ink);
}

.cm-share--record:hover {
    border-color: var(--cm-ink);
}

/* Sitio justo: por debajo de esto, «COMPARTIR» y «AGENDAR» en la misma fila
   dejan los dos textos partidos. Se queda el icono, que es lo que se reconoce, y
   la palabra pasa al lector de pantalla. */
@media (max-width: 1399.98px) {
    .cm-share--record .cm-share__text {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    .cm-share--record {
        padding: 10px 14px;
    }
}

/* Los dos dibujos del icono de compartir: el de Apple y el de los tres nodos.
   Se enseña el que toca según el teléfono de quien mira, y lo decide
   cm-share.js. Al tamaño del texto del botón, como si fuera una letra.

   Cuál se ve lo dice esta clase y no el atributo «hidden»: en un <svg> ese
   atributo no se refleja al asignarlo desde JavaScript, así que el icono no se
   movía nunca. */
.cm-icon-share {
    display: none;
    width: 1.15em;
    height: 1.15em;
    flex: none;
    vertical-align: -.2em;
}

.cm-icon-share--active {
    display: inline-block;
}

/* ==========================================================================
   Que lo fijo se quede fijo en el iPhone
   --------------------------------------------------------------------------
   La barra de reservar del móvil se despegaba del fondo y quedaba flotando a
   media pantalla al hacer scroll en Safari. No era de la barra: la plantilla
   pone `overflow-x: hidden` en el `body`, y un eje en `hidden` obliga al otro
   a `auto`, con lo que el body pasa a ser el contenedor del desplazamiento.
   A partir de ahí, `position: fixed` deja de medirse contra la ventana y se
   mide contra el body, que al desplazarse se lleva la barra con él.

   `clip` recorta exactamente igual —para eso estaba el `hidden`— pero no
   crea contenedor de desplazamiento, así que el scroll vuelve al documento y
   lo fijo vuelve a anclarse a la ventana.

   Va aquí y no en la hoja de la plantilla, que no se toca, y como
   declaración aparte: un navegador que no entienda `clip` la ignora y se
   queda con el `hidden` de siempre, que es el comportamiento de hoy.

   No pisa el bloqueo del scroll con el menú abierto: esa regla es
   `html.menu-opened body`, con más peso que ésta.
   ========================================================================== */
body {
    overflow-x: clip;
}

/* Qué le falta a cada consulta sin cerrar: si ya se empezó a escribir o ni se abrió. */
.cm-schedule__unclosedLabel {
    display: inline-block;
    margin-left: .4rem;
    padding: .1rem .5rem;
    border-radius: 999px;
    background: var(--cm-amber-bg, #fdf3e2);
    color: var(--cm-amber, #b7791f);
    font-size: .72rem;
    font-style: normal;
    font-weight: 600;
    vertical-align: middle;
}

/* «Enviando al SRI…» en el lugar del botón de facturar, mientras la cola trabaja. */
.cm-invoice__waiting {
    display: inline-block;
    font-size: .82rem;
    color: var(--cm-cyan-dark);
    white-space: nowrap;
}

.cm-status-invoice i { margin-right: .3rem; }

/* ============================================================================
   Barra de herramientas de una lista: buscar, filtrar, contar
   ----------------------------------------------------------------------------
   Encima de una tabla o de una lista de tarjetas: un campo de búsqueda con su
   lupa, uno o dos selectores y, a la derecha, cuántas cosas hay. Nelson, 16 de
   septiembre de 2026: «sin filtros ni búsqueda, ¿cómo llego a un dato en
   específico?… sin dañar el look & feel». Va con los mismos bordes, radios y
   grises que el resto; en el teléfono los controles se apilan.
   ============================================================================ */

.cm-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    margin-bottom: 1rem;
}

.cm-search {
    position: relative;
    flex: 1 1 220px;
    max-width: 380px;
    min-width: 0;
    margin: 0;
}

.cm-search i {
    position: absolute;
    left: .8rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--cm-gray-light);
    font-size: .85rem;
    pointer-events: none;
}

.cm-search input {
    width: 100%;
    min-height: 40px;
    padding: .45rem .9rem .45rem 2.2rem;
    border: 1px solid #cfd7e3;
    border-radius: var(--cm-radius-sm);
    background: var(--cm-white);
    color: var(--cm-ink);
    font-size: .9rem;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.cm-search input::placeholder {
    color: var(--cm-gray-light);
}

.cm-search input:focus {
    outline: none;
    border-color: var(--cm-cyan);
    box-shadow: 0 0 0 3px rgba(32, 192, 243, .18);
}

/* El aspa que el navegador pinta en un type=search, del mismo gris. */
.cm-search input::-webkit-search-cancel-button {
    cursor: pointer;
}

.cm-tools__filter {
    flex: 0 1 220px;
    min-width: 0;
    margin: 0;
}

.cm-tools__filter--short {
    flex: 0 1 170px;
}

.cm-tools .form-select {
    min-height: 40px;
    padding-top: .35rem;
    padding-bottom: .35rem;
    font-size: .9rem;
}

.cm-tools__account {
    margin-left: auto;
    color: var(--cm-gray);
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

@media (max-width: 575.98px) {
    .cm-search,
    .cm-tools__filter,
    .cm-tools__filter--short {
        flex: 1 1 100%;
        max-width: none;
    }

    .cm-tools__account {
        margin-left: 0;
    }
}

/* ============================================================================
   Datos de acceso (correo e identificación) en el perfil
   ----------------------------------------------------------------------------
   Dos filas en un recuadro: el dato, y a la derecha el botón para cambiarlo.
   Antes eran dos campos bloqueados con «no se puede cambiar»; ahora se cambian
   con sus reglas (LosDatosDeAcceso) y se ve si hay un correo nuevo esperando
   confirmación. Se usa en el perfil del doctor y en el del paciente, que tienen
   hojas distintas: por eso no depende de ninguna de las dos.
   ============================================================================ */

.cm-access {
    margin: 0 0 1.25rem;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-bg);
}

.cm-access__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    padding: .8rem 1rem;
}

.cm-access__row + .cm-access__row {
    border-top: 1px solid var(--cm-rule);
}

.cm-access__data {
    flex: 1 1 240px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .1rem;
}

.cm-access__label {
    color: var(--cm-gray-light);
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
}

.cm-access__value {
    color: var(--cm-ink);
    font-size: .95rem;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.cm-access__pending {
    margin-top: .2rem;
    color: #7a5b12;
    font-size: .82rem;
}

.cm-access__pending i {
    margin-right: .25rem;
}

.cm-access__link {
    padding: 0;
    border: 0;
    background: none;
    color: var(--cm-cyan-dark);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    cursor: pointer;
}

.cm-access__button {
    flex: 0 0 auto;
    white-space: nowrap;
}

.cm-access__button i {
    margin-right: .3rem;
}

/* ============================================================================
   La cabecera y la barra lateral del panel, con las medidas del sitio
   ----------------------------------------------------------------------------
   Las dos plantillas traían cabeceras distintas: la del sitio mide 85px con
   el logotipo a 42 y los controles de la derecha separados 20px con aire
   antes del borde; la del panel medía 60, el logotipo salía a 40, los
   controles iban a 8px y el desplegable del usuario tocaba el borde. Nelson,
   16 de septiembre de 2026: «necesito que las barras tengan dimensiones
   iguales, el tamaño del logo igual y por supuesto armonía en los espacios».

   Aquí se fija una sola medida para las dos, en variables, y la barra lateral
   se ensancha: a 240px los rótulos largos («Procesos automáticos»,
   «Verificación en dos pasos») salían cortados con puntos suspensivos.

   Sólo de 992px para arriba: en el teléfono la cabecera del panel es la fila
   compacta de más arriba (.header.cm-header-dashboard en el bloque de móvil).
   ============================================================================ */

:root {
    --cm-header-height: 85px;            /* .header-nav del sitio */
    --cm-brand-height: 42px;          /* .cm-mark */
    --cm-sidebar-width: 280px;
    --cm-sidebar-collapsed: 78px;     /* lo que la plantilla usa con .mini-sidebar */
    --cm-band-height: 20px;         /* la banda «AMBIENTE DE PRUEBAS» */
}

@media (min-width: 992px) {
    .header.cm-header-dashboard {
        display: flex;
        align-items: center;
        height: var(--cm-header-height);
        padding-right: 30px;
    }

    .cm-header-dashboard .header-left {
        float: none;
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        width: var(--cm-sidebar-width);
        height: var(--cm-header-height);
        padding: 0 30px;
        text-align: left;
    }

    .cm-header-dashboard .header-left .logo {
        display: flex;
        align-items: center;
        line-height: 1;
    }

    /* El icono suelto sólo con la barra plegada; la regla de arriba, al pesar lo
       mismo que la de la plantilla que lo esconde, lo dejaba ver junto al logotipo. */
    .cm-header-dashboard .header-left .logo.logo-small { display: none; }
    .mini-sidebar .cm-header-dashboard .header-left .logo.logo-small { display: flex; }

    /* El mismo alto que en el sitio: la plantilla lo dejaba en 40. */
    .cm-header-dashboard .header-left .logo img.cm-mark {
        height: var(--cm-brand-height);
        max-height: none;
        width: auto;
    }

    .cm-header-dashboard #toggle_btn {
        float: none;
        height: auto;
        margin-left: 0;
        padding: 0 .5rem;
        font-size: 26px;
        color: var(--cm-gray);
    }

    /* Los controles de la derecha, separados como en el sitio
       (.header-navbar-rht li: 20px entre ellos, nada tras el último). */
    .cm-header-dashboard .user-menu {
        float: none;
        display: flex;
        align-items: center;
        margin-left: auto;
    }

    .cm-header-dashboard .user-menu > li {
        display: inline-flex;
        align-items: center;
        padding-right: 20px;
    }

    .cm-header-dashboard .user-menu > li:last-child {
        padding-right: 0;
    }

    .cm-header-dashboard .user-menu.nav > li > a {
        height: auto;
        line-height: 1;
        padding: 0;
    }

    .sidebar {
        top: var(--cm-header-height);
        width: var(--cm-sidebar-width);
    }

    .page-wrapper {
        margin-left: var(--cm-sidebar-width);
        padding-top: var(--cm-header-height);
    }

    .mini-sidebar .cm-header-dashboard .header-left {
        width: var(--cm-sidebar-collapsed);
        padding: 0 5px;
        justify-content: center;
    }

    .mini-sidebar .sidebar { width: var(--cm-sidebar-collapsed); }
    .mini-sidebar.expand-menu .sidebar { width: var(--cm-sidebar-width); }
    .mini-sidebar .page-wrapper { margin-left: var(--cm-sidebar-collapsed); }

    /* Con la banda de pruebas todo baja lo que mide la banda. La plantilla lo
       tenía fijado con !important sobre sus 60px; hay que pesar lo mismo. */
    body.has-test-banner .sidebar {
        top: calc(var(--cm-header-height) + var(--cm-band-height)) !important;
    }

    body.has-test-banner .page-wrapper {
        padding-top: var(--cm-header-height) !important;
    }

    body.has-test-banner .slimScrollDiv,
    body.has-test-banner .sidebar-inner {
        height: calc(100vh - var(--cm-header-height) - var(--cm-band-height)) !important;
    }
}

/* La flecha del menú del usuario, igual en las dos cabeceras: la del sitio la
   separa 10px del avatar y la pinta gris; la del panel la pegaba y la ponía negra. */
.header .has-arrow .dropdown-toggle:after {
    margin-left: 10px;
    border-color: var(--cm-gray);
}

/* ============================================================================
   Mis documentos del profesional
   ----------------------------------------------------------------------------
   La lista primero, con búsqueda y filtros; subir es un botón que abre una
   ventana. Antes el formulario ocupaba la pantalla entera y los documentos
   quedaban debajo, fuera de la vista; y la lista usaba «.cm-doc», que es la
   tarjeta de los documentos de la consulta, así que salía con esa rejilla:
   el estado y el botón pegados al borde y sin aire entre uno y otro (Nelson,
   16 de septiembre de 2026). Estas clases son sólo de aquí.
   ============================================================================ */

/* Título, frase y el botón de subir, en una fila que se parte en el teléfono. */
.cm-docs-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem 1rem;
    margin-bottom: 1rem;
}

.cm-docs-header > div { flex: 1 1 320px; min-width: 0; }

.cm-docs-header__upload { flex: 0 0 auto; white-space: nowrap; }

/* Las especialidades que esperan su documento: un aviso corto con su icono. */
.cm-notice-specialty {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 14px 16px;
    margin-bottom: 1rem;
    border: 1px solid #cfeaf5;
    border-radius: var(--cm-radius);
    background: var(--cm-cyan-soft);
    color: var(--cm-ink);
}

.cm-notice-specialty__icon {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    background: rgba(32, 192, 243, .18);
    color: var(--cm-cyan-dark);
}

.cm-notice-specialty__text { min-width: 0; font-size: .9rem; }

.cm-notice-specialty__list {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 4px 0 8px;
    vertical-align: middle;
}

.cm-notice-specialty__list .cm-pill { white-space: normal; }

/* La firma electrónica, en una línea con su estado y el enlace. */
.cm-signature-status {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
    padding: 12px 16px;
    margin-bottom: 1rem;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-white);
    box-shadow: var(--cm-shadow);
    font-size: .9rem;
}

.cm-signature-status > i { color: var(--cm-cyan-dark); }

.cm-signature-status .cm-pill { white-space: normal; }

.cm-signature-status__link {
    margin-left: auto;
    font-weight: 600;
    white-space: nowrap;
}

/* La lista: una tarjeta por documento, con aire entre ellas. */
.cm-files {
    display: grid;
    gap: 12px;
}

.cm-file {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) auto;
    gap: 2px 14px;
    align-items: start;
    padding: 14px 16px;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-white);
    box-shadow: var(--cm-shadow);
    min-width: 0;
}

.cm-file__icon {
    grid-column: 1;
    grid-row: 1 / span 2;
    width: 44px;
    height: 44px;
    border-radius: 11px;
    display: grid;
    place-items: center;
    background: rgba(32, 192, 243, .12);
    color: var(--cm-cyan-dark);
    font-size: 1.05rem;
}

.cm-file__body { grid-column: 2; min-width: 0; }

.cm-file__name {
    font-size: .98rem;
    font-weight: 700;
    color: var(--cm-ink);
    margin: 0 0 2px;
    overflow-wrap: anywhere;
}

.cm-file__goal {
    margin: 0;
    font-size: .82rem;
    line-height: 1.5;
    color: var(--cm-gray);
}

.cm-file__note {
    margin: 4px 0 0;
    font-size: .82rem;
    line-height: 1.5;
    color: var(--cm-amber);
}

/* El estado y el botón, a la derecha y alineados entre sí. */
.cm-file__side {
    grid-column: 3;
    grid-row: 1 / span 2;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
}

/* Señalar la especialidad: debajo del texto, a lo ancho. */
.cm-file__accredit {
    grid-column: 2 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
    padding-top: 10px;
    border-top: 1px dashed var(--cm-rule);
}

.cm-file__accredit .form-select {
    flex: 1 1 220px;
    max-width: 320px;
}

@media (max-width: 575.98px) {
    .cm-file { grid-template-columns: 36px minmax(0, 1fr); gap: 2px 11px; padding: 14px; }
    .cm-file__icon { width: 36px; height: 36px; font-size: .95rem; }
    .cm-file__side {
        grid-row: auto;
        grid-column: 2;
        flex-direction: row;
        align-items: center;
        margin-top: 8px;
    }
    .cm-signature-status__link { margin-left: 0; }
}

/* Zona de arrastre. El botón de archivo del navegador es una caja gris que no
   dice nada; esto le da un sitio grande donde soltar y un estado visible cuando
   el archivo está encima. */
.cm-release {
    border: 2px dashed #d7dce5;
    border-radius: .75rem;
    padding: 2rem 1rem;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s, background-color .15s;
}

.cm-release:hover,
.cm-release:focus-within { border-color: var(--cm-cyan); }

.cm-release--over {
    border-color: var(--cm-cyan);
    background-color: rgba(32, 192, 243, .06);
}

.cm-release__icon {
    font-size: 1.75rem;
    opacity: .55;
    margin-bottom: .5rem;
}

/* El nombre del archivo elegido puede ser larguísimo y sin espacios: sin esto
   empuja la ventana entera a lo ancho. */
.cm-release__chosen {
    overflow-wrap: anywhere;
    font-weight: 600;
}

.cm-declaration {
    background-color: rgba(0, 0, 0, .025);
    border-radius: .5rem;
    padding: .9rem 1rem;
    font-size: .875rem;
}

/* ============================================================================
   El pie de página
   ----------------------------------------------------------------------------
   Una franja azul con la marca, los enlaces que sirven y lo legal. Sustituye
   al pie de cuatro columnas de la plantilla (.footer), que se comía media
   pantalla, repetía el menú y la lista de especialidades, y en el teléfono
   dejaba el «Powered by» suelto. Del mismo azul, para que el sitio siga
   siendo el mismo.
   ============================================================================ */
.cm-footer {
    flex-shrink: 0;
    background: #15558d;
    color: rgba(255, 255, 255, .82);
    font-size: .9rem;
}

.cm-footer a {
    color: rgba(255, 255, 255, .82);
    text-decoration: none;
    transition: color .15s ease;
}

.cm-footer a:hover,
.cm-footer a:focus-visible { color: #fff; text-decoration: underline; text-underline-offset: 3px; }

.cm-footer__up {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px 32px;
    padding: 26px 0 22px;
}

.cm-footer__mark { min-width: 0; }

.cm-footer__logo {
    display: inline-block;
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: #fff;
    line-height: 1.2;
}

.cm-footer__logo span { color: var(--cm-cyan); }

.cm-footer a.cm-footer__logo:hover { text-decoration: none; }

.cm-footer__tagline {
    margin: 2px 0 0;
    font-size: .88rem;
    color: rgba(255, 255, 255, .7);
}

.cm-footer__links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 24px;
    font-weight: 600;
}

.cm-footer__down {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 24px;
    padding: 14px 0 18px;
    border-top: 1px solid rgba(255, 255, 255, .14);
    font-size: .82rem;
    color: rgba(255, 255, 255, .62);
}

.cm-footer__legal { margin: 0; }

.cm-footer__legal strong { color: rgba(255, 255, 255, .85); font-weight: 700; }

.cm-footer__point { margin: 0 4px; }

.cm-footer__legal-links {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
}

.cm-footer__legal-links a { color: rgba(255, 255, 255, .62); }

@media (max-width: 575.98px) {
    .cm-footer__up { padding: 22px 0 18px; }
    .cm-footer__links { gap: 6px 18px; }
    .cm-footer__down { flex-direction: column; align-items: flex-start; gap: 8px; }
}

/* ============================================================================
   Facturas y comprobantes: una tarjeta por cita
   ----------------------------------------------------------------------------
   Nació en patient.css para Facturas y Comprobantes del paciente; el doctor
   tiene la misma pantalla (sus facturas, por cita y paciente), así que las
   clases viven aquí, que cargan los dos paneles.
   ============================================================================ */

/* Una tarjeta por cita, y dentro sus dos facturas: la del especialista y la
   de la plataforma. Antes era una tabla plana en la que las dos salían como
   filas sueltas con la misma fecha, y el paciente no sabía por qué tenía dos.
   El porqué se dice una vez, arriba, y luego cada tarjeta lo muestra. */
.cm-invoices__why {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    margin: 0 0 1rem;
    color: var(--cm-gray);
    font-size: .88rem;
    line-height: 1.5;
}

.cm-invoices__why i {
    margin-top: .2rem;
    color: var(--cm-cyan-dark);
}

.cm-invoices {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.cm-invoice-appointment {
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius-lg);
    background: var(--cm-white);
    box-shadow: var(--cm-shadow);
    overflow: hidden;
}

.cm-invoice-appointment--cancelled {
    background: var(--cm-bg);
}

/* La cabecera: quién atendió y cuándo. La fecha va a la derecha y grande
   porque es por lo que el paciente busca: «la factura de la cita de tal día». */
.cm-invoice-appointment__header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem 1rem;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--cm-rule);
}

.cm-invoice-appointment__photo {
    width: 48px;
    height: 48px;
    flex: 0 0 auto;
    border-radius: 50%;
    border: 2px solid var(--cm-white);
    box-shadow: var(--cm-shadow);
    object-fit: cover;
}

.cm-invoice-appointment__doctor {
    flex: 1 1 200px;
    min-width: 0;
}

.cm-invoice-appointment__name {
    display: block;
    color: var(--cm-ink);
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.25;
    text-decoration: none;
    overflow-wrap: anywhere;
}

.cm-invoice-appointment__name:hover {
    color: var(--cm-cyan-dark);
}

.cm-invoice-appointment__specialty {
    display: block;
    color: var(--cm-gray);
    font-size: .82rem;
}

.cm-invoice-appointment__when {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem .6rem;
    margin-left: auto;
    text-align: right;
}

/* «domingo 13 de septiembre» con la primera en mayúscula y nada más: capitalize
   ponía «Domingo 13 De Septiembre». */
.cm-invoice-appointment__date {
    display: inline-block;
    color: var(--cm-ink);
    font-weight: 700;
    font-size: .95rem;
}

.cm-invoice-appointment__date::first-letter {
    text-transform: uppercase;
}

.cm-invoice-appointment__time {
    color: var(--cm-cyan-dark);
    font-size: .88rem;
    font-variant-numeric: tabular-nums;
}

/* Las dos líneas: icono, qué es (con su pastilla), monto y botón. En rejilla
   para que los montos y los botones queden alineados entre tarjetas. */
.cm-invoice-appointment__lines {
    margin: 0;
    padding: .35rem 1.25rem .6rem;
    list-style: none;
}

.cm-invoice-appointment__line {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: .5rem .9rem;
    padding: .65rem 0;
}

.cm-invoice-appointment__line + .cm-invoice-appointment__line {
    border-top: 1px dashed var(--cm-rule);
}

.cm-invoice-appointment__icon {
    width: 1.4rem;
    text-align: center;
    color: var(--cm-cyan-dark);
    font-size: 1rem;
}

.cm-invoice-appointment__line--without .cm-invoice-appointment__icon {
    color: var(--cm-gray-light);
}

.cm-invoice-appointment__that {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .3rem .5rem;
    min-width: 0;
}

.cm-invoice-appointment__label {
    color: var(--cm-ink);
    font-size: .92rem;
    font-weight: 600;
}

.cm-invoice-appointment__line--without .cm-invoice-appointment__label {
    color: var(--cm-gray);
    font-weight: 500;
}

.cm-invoice-appointment__amount {
    color: var(--cm-ink);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* El monto sin botón al lado (la factura del doctor que está en la cola, o la
   consulta que aún no se registra) se corre hasta el borde derecho. */
.cm-invoice-appointment__amount--only {
    grid-column: 3 / span 2;
    justify-self: end;
}

.cm-invoice-appointment__download {
    white-space: nowrap;
}

.cm-invoice-appointment__download i {
    margin-right: .3rem;
}

/* Lo que todavía no se puede descargar ocupa el sitio del monto y del botón,
   en gris: se ve que falta y por qué, sin parecer un error. */
.cm-invoice-appointment__status {
    grid-column: 3 / span 2;
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .3rem .7rem;
    border-radius: 999px;
    background: var(--cm-neutral-bg);
    color: var(--cm-neutral);
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
}

/* En una pantalla estrecha el monto y el botón bajan a su propia línea, a la
   derecha, para que el nombre de la factura no se parta en tres. */
@media (max-width: 575.98px) {
    .cm-invoice-appointment__line {
        grid-template-columns: auto minmax(0, 1fr) auto;
    }

    .cm-invoice-appointment__that { grid-column: 2 / span 2; }
    .cm-invoice-appointment__amount { grid-column: 2; }
    .cm-invoice-appointment__amount--only { grid-column: 2 / span 2; justify-self: end; }
    .cm-invoice-appointment__download { grid-column: 3; }
    .cm-invoice-appointment__status { grid-column: 2 / span 2; justify-self: start; }

    .cm-invoice-appointment__when {
        margin-left: 0;
        text-align: left;
        width: 100%;
    }
}

/* El mes y las tandas: para no recorrer veinte tarjetas para dar con una. La
   barra de búsqueda y filtros es la de cm-base (.cm-tools). */
.cm-invoices__month {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.cm-invoices__month-title {
    display: inline-block;
    margin: .25rem 0 -.25rem;
    color: var(--cm-gray);
    font-size: .76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .07em;
}

.cm-invoices__month + .cm-invoices__month {
    margin-top: .5rem;
}

.cm-invoices__nothing {
    margin-top: .5rem;
}

.cm-invoices__more {
    display: flex;
    justify-content: center;
    margin-top: 1.25rem;
}

/* Comprobantes: la misma tarjeta, con las líneas sólo informativas (sin botón,
   sin pastilla) y un pie con el número, cuándo y con qué se pagó, el total y
   el único botón: ver el comprobante. */
.cm-invoice-appointment__line--soft {
    grid-template-columns: auto minmax(0, 1fr) auto;
    padding: .45rem 0;
}

.cm-invoice-appointment__line--soft .cm-invoice-appointment__label {
    font-weight: 500;
    color: var(--cm-gray);
}

.cm-invoice-appointment__line--soft .cm-invoice-appointment__amount {
    font-weight: 600;
    color: var(--cm-gray);
}

.cm-invoice-appointment__footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    padding: .85rem 1.25rem;
    border-top: 1px solid var(--cm-rule);
    background: var(--cm-bg);
}

.cm-invoice-appointment__payment {
    flex: 1 1 220px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .1rem;
}

.cm-invoice-appointment__number {
    color: var(--cm-ink);
    font-size: .9rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.cm-invoice-appointment__paid {
    color: var(--cm-gray);
    font-size: .8rem;
}

.cm-invoice-appointment__total {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    color: var(--cm-ink);
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.cm-invoice-appointment__total small {
    color: var(--cm-gray-light);
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
}

@media (max-width: 575.98px) {
    .cm-invoice-appointment__line--soft .cm-invoice-appointment__that { grid-column: 2; }
    .cm-invoice-appointment__line--soft .cm-invoice-appointment__amount { grid-column: 3; grid-row: 1; }
}


/* ============================================================================
   La baja de los correos de novedades
   ----------------------------------------------------------------------------
   Una tarjeta en el centro: icono, una frase, y la puerta abierta por si se
   arrepiente. Nada de «¿está seguro?»: el clic del correo ya fue la decisión.
   ============================================================================ */
.cm-unsubscribe {
    max-width: 560px;
    margin: 2.5rem auto 3.5rem;
    padding: 2.4rem 2rem;
    text-align: center;
    background: var(--cm-white);
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius-lg);
    box-shadow: var(--cm-shadow);
}

.cm-unsubscribe__icon {
    width: 72px;
    height: 72px;
    margin: 0 auto 1.1rem;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--cm-cyan-soft);
    color: var(--cm-cyan-dark);
    font-size: 1.8rem;
}

.cm-unsubscribe__icon--good { background: var(--cm-green-bg); color: var(--cm-green); }
.cm-unsubscribe__icon--bad { background: var(--cm-amber-bg); color: var(--cm-amber); }

.cm-unsubscribe__title {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--cm-ink);
    margin: 0 0 .75rem;
    text-wrap: balance;
}

.cm-unsubscribe__text {
    color: var(--cm-gray);
    font-size: 1rem;
    line-height: 1.6;
    margin: 0 auto .5rem;
    max-width: 44ch;
}

.cm-unsubscribe__note {
    color: var(--cm-gray-light);
    font-size: .88rem;
    margin: 0 auto 1.4rem;
    max-width: 44ch;
}

.cm-unsubscribe__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: .5rem 1rem;
}

/* ============================================================================
   Campañas de correo (panel de administración)
   ----------------------------------------------------------------------------
   El formulario a la izquierda y el correo tal como llega a la derecha; en una
   pantalla estrecha, uno debajo del otro.
   ============================================================================ */
.cma-campaign {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
}

.cma-campaign__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--cm-rule);
}

.cma-campaign__preview { position: sticky; top: 96px; }

.cma-campaign__iframe {
    display: block;
    width: 100%;
    height: min(78vh, 900px);
    border: 0;
    background: #f7fafc;
}

@media (max-width: 1199.98px) {
    .cma-campaign { grid-template-columns: minmax(0, 1fr); }
    .cma-campaign__preview { position: static; }
    .cma-campaign__iframe { height: 640px; }
}

/* La casilla de novedades en el perfil del paciente: en su recuadro, para que
   no parezca un dato de salud más. */
.cm-news {
    margin: .25rem 0 1rem;
    padding: .9rem 1rem .9rem 2.4rem;
    border: 1px solid var(--cm-rule);
    border-radius: var(--cm-radius);
    background: var(--cm-bg);
}

.cm-news .form-check-input { margin-left: -1.6rem; margin-top: .3rem; }
