/* Brand fonts — self-hosted (was a Google Fonts @import). Self-hosting keeps
   the CSP tight (no fonts.googleapis.com / fonts.gstatic.com) and sends no
   visitor IP to Google. Both families are variable fonts: one .woff2 per
   subset covers every weight, so a single @font-face with a weight range is
   enough. Files in static/fonts/. Display = Montserrat (matches centro-ejemplo.example),
   body = Nunito Sans. */
@font-face {
    font-family: 'Montserrat';
    src: url('/fonts/montserrat-latin.woff2') format('woff2');
    font-weight: 100 900;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Montserrat';
    src: url('/fonts/montserrat-latin-ext.woff2') format('woff2');
    font-weight: 100 900;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Nunito Sans';
    src: url('/fonts/nunito-sans-latin.woff2') format('woff2');
    font-weight: 100 900;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Nunito Sans';
    src: url('/fonts/nunito-sans-latin-ext.woff2') format('woff2');
    font-weight: 100 900;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* Centro de Ejemplo palette — teal / blue-slate family, matching centro-ejemplo.example
       (accent ~#649cb0, dark ~#4389a2/#337e98, dark sections ~#0c121e,
       soft fills ~#dee7ea). Variable names are kept from the el proyecto original
       original to avoid a churn across the whole file; "mauve"/"mint" now
       hold teals. Button/link teals are nudged a shade darker than the
       site's for readable white-on-colour text. */
    --color-bg: #f4f7f8;
    --color-surface: #ffffff;
    --color-mint: #a9cdd9;
    --color-mint-dark: #8ab8c6;
    --color-lilac: #dfe8eb;
    /* Un punto más oscuro que el #47869a del logo: con texto blanco encima
       llega al contraste mínimo de WCAG AA (4,93:1 frente a 4,08:1;
       AccessibilitySeleniumTest, 01/10/2026). */
    --color-mauve: #3d788b;
    --color-mauve-dark: #356d80;
    --color-dark: #16232e;
    --color-primary: #3d788b;
    --color-primary-dark: #356d80;
    --color-text: #2b3138;
    --color-text-muted: #66727d;
    /* Acento vivo para realces finos (líneas, subrayados) sobre la paleta pastel y oscura. */
    --color-acento: #f08a24;
    /* Portada (landing-ondas.css): realce intenso para líneas y botones, su versión para letra sobre claro y sobre
       oscuro (contraste AA), y los dos tonos claros de las ondas. Cada paquete los cambia en su tema.css. */
    --color-realce: #ff6a00;
    --color-realce-texto: #c2410c;
    --color-realce-sobre-oscuro: #ffc9a0;
    --color-onda: #9fd3e0;
    --color-haz: #cfeaf1;
    --color-text-on-dark: #eef3f5;
    --color-border: #dbe3e7;
    --color-error-bg: #fbe4e1;
    --color-error-text: #a33a2f;
    --color-success-bg: #e3f0e6;
    --color-success-text: #2f6b3e;
    --radius: 14px;
    --radius-pill: 999px;
    --shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
    --shadow-lift: 0 8px 24px rgba(0, 0, 0, 0.1);
    --font: 'Nunito Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-display: 'Montserrat', 'Segoe UI', system-ui, -apple-system, sans-serif;

    /* Patrón estándar del front (docs/analisis-patron-estandar-front.md,
       Trello #161). Toda regla nueva usa estas medidas en lugar de valores
       sueltos; las antiguas se irán pasando fase a fase. La referencia
       visual está en /ayuda/estilos. */

    /* Estados: aviso e información (éxito y error ya existen arriba). */
    --color-warning-bg: #fef8ec;
    --color-warning-text: #7a5a12;
    --color-warning-border: #e3a92b;
    --color-info-bg: #e5eff2;
    --color-info-text: #2c5f70;

    /* Esquinas: pequeño (campos, iconos, menús), estándar (paneles y
       tarjetas) y pill (botones y etiquetas, siempre). */
    --radius-sm: 6px;

    /* Espaciado, escala de 4px. */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-6: 24px;
    --space-8: 32px;

    /* Tamaños de letra: seis en total. */
    --text-xs: 0.75rem;
    --text-sm: 0.85rem;
    --text-md: 1rem;
    --text-lg: 1.2rem;
    --text-xl: 1.6rem;
    --text-2xl: 2.1rem;

    /* Alturas de botones y campos: los del mismo tamaño encajan en línea. */
    --control-sm: 30px;
    --control-md: 38px;
    --control-lg: 46px;

    /* Iconos SVG (con currentColor). */
    --icon-sm: 16px;
    --icon-md: 20px;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: var(--font);
    line-height: 1.6;
    background: var(--color-bg);
    color: var(--color-text);
}

a {
    color: var(--color-mauve-dark);
}

/* --- Buttons shared --- */

.btn-primary,
.btn-primary-link {
    display: inline-block;
    padding: 12px 28px;
    background: var(--color-mauve);
    color: white;
    border: none;
    border-radius: var(--radius-pill);
    font-size: 1rem;
    font-weight: 600;
    font-family: var(--font);
    cursor: pointer;
    text-decoration: none;
    text-align: center;
    transition: background 0.15s ease, transform 0.15s ease;
}

.btn-primary:hover,
.btn-primary-link:hover {
    background: var(--color-mauve-dark);
    transform: translateY(-1px);
}

.btn-on-dark {
    background: var(--color-mint);
    color: var(--color-dark);
}

.btn-on-dark:hover {
    background: var(--color-mint-dark);
}

/* --- Auth (login) --- */

.auth-page {
    min-height: calc(100vh - 100px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: linear-gradient(160deg, var(--color-lilac) 0%, var(--color-bg) 45%);
}

.auth-card {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
    padding: 40px 36px;
    width: 100%;
    max-width: 380px;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 4px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.6rem;
    color: var(--color-mauve-dark);
    text-decoration: none;
}

.brand-mark {
    display: block;
    width: 50px;
    height: 50px;
    flex-shrink: 0;
}

.brand-name {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35em;
}

.brand-city {
    font-size: 0.6em;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    /* Línea fina de acento bajo el nombre de la ciudad (pedido del equipo 15/10/2026). */
    border-bottom: 1.5px solid var(--color-acento);
    padding-bottom: 2px;
}

.tagline {
    margin: 0 0 28px;
    color: var(--color-text-muted);
    font-size: 0.95rem;
}

.auth-form label {
    display: block;
    font-size: 0.9rem;
    margin-bottom: 6px;
    margin-top: 16px;
    color: var(--color-text-muted);
}

.auth-form input[type="text"],
.auth-form input[type="password"],
.auth-form input[type="email"],
.auth-form input[type="tel"],
.auth-form textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font-size: 1rem;
    font-family: inherit;
}

.auth-form input:focus {
    outline: none;
    border-color: var(--color-mauve);
}

.auth-form .btn-primary {
    margin-top: 24px;
    width: 100%;
}

/* "Mostrar contraseña" checkbox injected after every password field by
   /js/ui-behaviors.js. `label.password-toggle` (not just `.password-toggle`)
   so it outranks the generic `.auth-form label` block above on the auth
   pages — otherwise it would inherit `display:block` and `margin-top:16px`. */
label.password-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 8px 0 0;
    font-size: 0.85rem;
    color: var(--color-text-muted);
    cursor: pointer;
    user-select: none;
}

.password-toggle .password-toggle-checkbox {
    width: auto;
    margin: 0;
    cursor: pointer;
}

.alert {
    padding: 10px 14px;
    border-radius: 8px;
    font-size: 0.9rem;
    margin-bottom: 8px;
}

.alert-error {
    background: var(--color-error-bg);
    color: var(--color-error-text);
}

.alert-success {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

/* --- Topbar (app pages) --- */

.topbar {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    padding: 16px 32px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}

.topbar .brand {
    margin: 0;
    font-size: 1.2rem;
}

.topbar nav a {
    color: var(--color-mauve-dark);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
}

.topbar nav a:hover {
    text-decoration: underline;
}

/* Home / back bar — fragments/page-nav.html, included below the header on
   every page except landing.html. Icon-only (house + back arrow); the
   localized label is on title / aria-label. */
.page-nav {
    display: flex;
    gap: 8px;
    padding: 8px 32px;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.page-nav-link {
    color: var(--color-mauve-dark);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}

.page-nav-link:hover {
    text-decoration: underline;
}

.page-nav-icon {
    display: inline-flex;
    align-items: center;
    padding: 3px 5px;
    border-radius: 6px;
}

.page-nav-icon:hover {
    text-decoration: none;
    color: var(--color-mauve);
    background: var(--color-lilac);
}

/* Botones dentro de la barra («Colapsar», «Guardar»): sin el estilo por
   defecto del navegador, con la misma altura y el mismo radio para los dos
   (antes «Colapsar» salía gris y con esquinas rectas; #160/#161). */
.page-nav-btn {
    display: inline-flex;
    align-items: center;
    height: 30px;
    padding: 0 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-family: inherit;
    line-height: 1;
}

.page-nav-btn:hover {
    text-decoration: none;
    color: var(--color-mauve);
    background: var(--color-lilac);
}

.page-nav-btn:focus-visible {
    outline: 2px solid var(--color-mauve);
    outline-offset: 1px;
}

/* Live clock (clock.js), centred in whichever nav bar it sits in via the
   flex auto-margins — bigger than the icons around it, on purpose. */
.page-nav-clock {
    margin: 0 auto;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--color-mauve-dark);
    font-variant-numeric: tabular-nums;
}

/* Wraps the ficha-only controls (panel toggle + save) so they land
   together on the right edge of the bar, rather than each fighting over
   its own margin-left:auto — when embedded in the dashboard's iframe,
   home/back/clock are hidden and this is the only thing left in the bar,
   so it still needs to land on the right on its own. */
.page-nav-end {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 12px;
}

.logout-form {
    display: flex;
    align-items: center;
    gap: 16px;
}

.welcome {
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.welcome-code {
    font-family: monospace;
    letter-spacing: 0.03em;
}

.role-badge {
    display: inline-block;
    background: var(--color-lilac);
    color: var(--color-mauve-dark);
    border-radius: var(--radius-pill);
    padding: 3px 12px;
    margin-right: 8px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* SuperAdmin: same pill, filled accent so it's obvious the session has the
   full-access role rather than a plain admin's. */
.role-badge--super {
    background: var(--color-mauve);
    color: #fff;
}

.btn-link {
    background: none;
    border: none;
    color: var(--color-mauve-dark);
    cursor: pointer;
    font-size: 0.9rem;
    text-decoration: underline;
    padding: 0;
    font-family: inherit;
}

/* --- Dashboard --- */

.dashboard-grid {
    max-width: 900px;
    margin: 48px auto;
    padding: 0 24px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 20px;
}

.dashboard-banner {
    grid-column: 1 / -1;
}

.dashboard-card {
    background: var(--color-surface);
    border-radius: var(--radius);
    border-top: 4px solid var(--color-mint);
    box-shadow: var(--shadow);
    padding: 28px;
    text-decoration: none;
    color: var(--color-text);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    display: block;
}

.dashboard-card:nth-child(even) {
    border-top-color: var(--color-lilac);
}

.dashboard-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lift);
}

.dashboard-card h2 {
    margin: 0 0 8px;
    font-family: var(--font-display);
    color: var(--color-mauve-dark);
    font-size: 1.15rem;
}

.dashboard-card p {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.dashboard-card.disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* --- Dashboard workspace (agenda-first + section buttons) --- */

.dashboard-workspace {
    /* Near-full-width on large screens (this is a working tool, not a
       reading column); still fluid on smaller ones via the side padding. */
    max-width: 1760px;
    margin: 16px auto 32px;
    padding: 0 clamp(16px, 3vw, 40px);
}

.dashboard-banner + .dashboard-tabs {
    margin-top: 16px;
}

.dashboard-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.dashboard-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-mauve-dark);
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.dashboard-tab:hover {
    border-color: var(--color-mauve);
}

.dashboard-tab.is-active {
    background: var(--color-mauve);
    border-color: var(--color-mauve);
    color: #fff;
}

/* Los tabs/grupos ocultos por elección del usuario (dashboard-shortcuts.js)
   siguen en el DOM (hace falta para medir si entran en una línea) con el
   atributo [hidden] — sin esto, .dashboard-tab{display:inline-flex} de
   arriba pisa el display:none nativo del navegador, mismo problema que ya
   se dio con .dashboard-tab-group-menu. */
.dashboard-tab[hidden],
.dashboard-tab-group[hidden] {
    display: none;
}

.dashboard-shortcuts-menu .checkbox-label {
    display: flex;
}

.dashboard-shortcuts-limit {
    color: var(--color-error-text);
}

.dashboard-shortcuts-menu .btn-submit {
    align-self: flex-start;
    margin-top: 4px;
}

.dashboard-tab-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--color-mint-dark);
    color: #fff;
    font-size: 0.72rem;
    line-height: 1;
}

.dashboard-tab.is-active .dashboard-tab-badge {
    background: #fff;
    color: var(--color-mauve-dark);
}

/* Botones del cintillo agrupados bajo un desplegable (dashboard-panels.js),
   p. ej. "Doc. Clínica" = Códigos clínicos + Catálogo de ejercicios. */
.dashboard-tab-group {
    position: relative;
}

.dashboard-tab-group-trigger::after {
    content: "▾";
    font-size: 0.75em;
}

.dashboard-tab-group-menu {
    position: absolute;
    z-index: 5;
    top: calc(100% + 4px);
    left: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 200px;
    padding: 6px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 4px 12px rgba(22, 35, 46, 0.12);
}

/* El display:flex de arriba pisa el display:none del [hidden] nativo del
   navegador (misma especificidad, esta regla de clase va después) — sin
   esto, dashboard-panels.js togglea el atributo hidden pero el menú se ve
   abierto siempre, sin importar el clic. */
.dashboard-tab-group-menu[hidden] {
    display: none;
}

.dashboard-tab-group-menu .dashboard-tab {
    width: 100%;
    justify-content: flex-start;
    /* Un <button> centra el texto por defecto: sin esto, los nombres de dos líneas
       («Proveedores recurrentes») quedaban centrados y el resto a la izquierda. */
    text-align: left;
    border-radius: 6px;
}

/* La página del panel no deja hueco debajo: la agenda llega hasta el borde de la pantalla (el panel mide su altura
   en dashboard-panels.js y deja 8 px, que son este relleno). */
.page-content:has(> .dashboard-embed) {
    margin-bottom: 0;
    padding-bottom: 8px;
}

.dashboard-embed {
    width: 100%;
    /* Fill the viewport down to the fold — the section content scrolls
       inside the frame, not the dashboard shell. */
    height: calc(100vh - 168px);
    min-height: 520px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    box-shadow: var(--shadow);
}

@media (max-width: 600px) {
    .dashboard-embed {
        height: calc(100vh - 220px);
    }
}

/* Any page rendered inside the dashboard workspace iframe (ui-behaviors.js
   adds .is-embedded when window !== window.top). Normally the ?embedded=1
   fragments already omit these; this is the fallback for when that flag is
   lost on an internal redirect, so nothing stacks on the parent page.
   2026-09-14: this used to blanket-hide the whole .page-nav, which meant
   fragments/page-nav.html's own saveFormId-gated "Guardar" button could
   never actually show while embedded — the one context the ficha is
   ever really viewed in — no matter what its own th:if said: this
   !important fallback always won. Narrowed to the specific chrome that's
   genuinely duplicated by the outer dashboard shell (home/back icons,
   the clock), so a page-specific control riding along in the same
   <nav> — .page-nav-save is the only one so far — still gets through. */
html.is-embedded .topbar,
html.is-embedded .landing-header,
html.is-embedded .page-nav-icon:not(.page-nav-save),
html.is-embedded .page-nav-clock,
html.is-embedded .dashboard-tabs,
html.is-embedded #dashboard-embed,
html.is-embedded .whatsapp-float,
html.is-embedded #chat-widget {
    display: none !important;
}

/* Inside the iframe the shell chrome is gone, so the content shouldn't
   keep its full-page top margin or a narrow reading cap — let it use the
   frame. */
html.is-embedded .page-content {
    margin-top: 12px;
    max-width: none;
}

/* --- Cuadro de mandos --- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
    margin: 24px 0;
}

/* A stat-tile is a link now (2026-09-17: "clicar y ver una lista") — reset
   the anchor defaults so it still reads as the plain white card it always
   was, with just a hover lift to signal it's clickable. */
.stat-tile {
    display: block;
    background: var(--color-surface);
    border-radius: var(--radius);
    border-top: 4px solid var(--color-mint);
    box-shadow: var(--shadow);
    padding: 20px 24px;
    text-decoration: none;
    color: inherit;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.stat-tile:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lift);
}

.stat-tile:nth-child(even) {
    border-top-color: var(--color-lilac);
}

.stat-tile h3 {
    margin: 0 0 8px;
    font-family: var(--font-display);
    color: var(--color-mauve-dark);
    font-size: 0.95rem;
}

.stat-number {
    margin: 0;
    font-size: 2rem;
    font-weight: 700;
    color: var(--color-text);
}

/* --- Landing --- */

.landing-header {
    background: var(--color-surface);
    padding: 20px 32px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: relative;
}

.landing-header .brand {
    margin: 0;
    font-size: 1.5rem;
}

.landing-nav {
    display: flex;
    align-items: center;
    gap: 28px;
    margin-left: auto;
}

.landing-nav a:not(.btn-primary-link) {
    white-space: nowrap;
    color: var(--color-text);
    font-weight: 600;
    font-size: 0.92rem;
    text-decoration: none;
}

.landing-nav a:not(.btn-primary-link):hover {
    color: var(--color-mauve-dark);
}

/* Hamburger button for the public nav — hidden here, shown only under the
   980px breakpoint below, where .landing-nav becomes a collapsible dropdown
   instead of wrapping under the logo (card 147, 2026-09-21). Three plain
   <span> bars rather than an icon font/SVG import, styled entirely in CSS. */
.mobile-nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    flex-shrink: 0;
}

.mobile-nav-toggle span {
    display: block;
    width: 100%;
    height: 2px;
    background: var(--color-dark);
    border-radius: 1px;
    transition: transform 0.2s ease, opacity 0.2s ease;
}

.mobile-nav-toggle[aria-expanded="true"] span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
}

.mobile-nav-toggle[aria-expanded="true"] span:nth-child(2) {
    opacity: 0;
}

.mobile-nav-toggle[aria-expanded="true"] span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
}

/* Outside the nav, right after it: same place on a wide screen, and next to
   the hamburger (always visible) on a narrow one. */
.lang-switch {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-left: 28px;
}

.lang-switch a {
    display: inline-flex;
    line-height: 0;
    text-decoration: none;
    border-radius: 3px;
}

.lang-switch a .flag {
    display: block;
    border-radius: 3px;
    border: 1px solid var(--color-border);
    opacity: 0.5;
    transition: opacity 0.15s ease, outline-color 0.15s ease;
}

.lang-switch a:hover .flag {
    opacity: 0.85;
}

.lang-switch a.active .flag {
    opacity: 1;
    outline: 2px solid var(--color-mauve-dark);
    outline-offset: 1px;
}

/* Scroll-reveal utility (2026-09-17, scroll-reveal.js): any element gets
   [data-reveal], starts faded/offset, and the script flips .is-visible
   once it scrolls into view. Gated behind prefers-reduced-motion: someone
   who asked their OS for less motion gets the content fully visible from
   the start, never the fade — scroll-reveal.js also skips setting up the
   observer in that case, so [data-reveal] alone (no .is-visible) must
   already render at full opacity, which this media query guarantees. */
@media (prefers-reduced-motion: no-preference) {
    [data-reveal] {
        opacity: 0;
        transform: translateY(16px);
        transition: opacity 0.5s ease, transform 0.5s ease;
    }

    [data-reveal].is-visible {
        opacity: 1;
        transform: none;
    }
}

.landing-hero {
    position: relative;
    overflow: hidden;
    padding: 96px 24px 88px;
    text-align: center;
}

.hero-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 30%;
    z-index: 0;
}

.hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(250, 247, 242, 0.5) 0%, rgba(250, 247, 242, 0.87) 60%, rgba(250, 247, 242, 0.97) 100%);
    z-index: 1;
}

.hero-content {
    position: relative;
    z-index: 2;
    max-width: 720px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
}

.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 18px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-mauve-dark);
    box-shadow: var(--shadow);
}

.landing-hero h1 {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: -0.015em;
    color: var(--color-mauve);
    font-size: 2.75rem;
    line-height: 1.18;
}

.landing-hero p {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 1.1rem;
    line-height: 1.6;
}

.hero-cta {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 15px 34px;
    font-size: 1.02rem;
    box-shadow: var(--shadow-lift);
}

.service-hero {
    padding-bottom: 72px;
}

.service-hero h1 {
    margin-bottom: 0;
}

.landing-hero p.service-description {
    max-width: 640px;
    margin: 0 auto 20px;
    text-align: justify;
    color: var(--color-text-muted);
    font-size: 1.05rem;
    line-height: 1.6;
}

.landing-hero p.service-price {
    margin: 0 0 28px;
}

.landing-band {
    background: var(--color-mint);
    padding: 40px 24px;
    text-align: center;
}

.landing-band p {
    margin: 0 0 20px;
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 1.2rem;
    color: var(--color-dark);
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
}

.landing-band .btn-primary-link {
    background: var(--color-dark);
}

.landing-band .btn-primary-link:hover {
    background: #000;
}

.services-section {
    background: var(--color-lilac);
    padding: 64px 24px;
}

.services-section h2 {
    text-align: center;
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: -0.005em;
    color: var(--color-dark);
    font-size: 1.6rem;
    margin: 0 0 32px;
}

.services-grid {
    max-width: 960px;
    margin: 0 auto;
    display: grid;
    /* Auto-wraps: 5 equal columns on desktop, down to 2 on a phone —
       never a single squeezed nowrap row. */
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
}

/* Staggers the services-grid reveal so the cards fade in left-to-right
   instead of all at once — capped at 6 (the grid never has more today). */
.services-grid [data-reveal]:nth-child(1) { transition-delay: 0s; }
.services-grid [data-reveal]:nth-child(2) { transition-delay: 0.06s; }
.services-grid [data-reveal]:nth-child(3) { transition-delay: 0.12s; }
.services-grid [data-reveal]:nth-child(4) { transition-delay: 0.18s; }
.services-grid [data-reveal]:nth-child(5) { transition-delay: 0.24s; }
.services-grid [data-reveal]:nth-child(6) { transition-delay: 0.3s; }

.service-card {
    display: block;
    min-width: 0;
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 28px 14px;
    text-align: center;
    text-decoration: none;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.service-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lift);
}

.service-card:hover .service-icon {
    background: rgba(71, 134, 154, 0.22);
    transform: scale(1.06);
}

.service-card h3 {
    margin: 0;
    font-family: var(--font-display);
    color: var(--color-mauve-dark);
    font-size: 1rem;
    font-weight: 500;
}

.service-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    margin: 0 auto 16px;
    border-radius: 50%;
    background: rgba(71, 134, 154, 0.12);
    transition: background 0.15s ease, transform 0.15s ease;
}

.office-photo-frame {
    max-width: 1100px;
    margin: 0 auto;
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-lift);
}

.office-photo {
    width: 100%;
    height: 380px;
    object-fit: cover;
    display: block;
}

/* --- Publicidad obligatoria de la subvención NextGenerationEU --- */

/* "Conoce nuestro centro" photo carousel (landing.html only, between
   Tratamientos and the grant section) — real photos of the clinic and its
   equipment, not stock/decorative ones. The viewport is a native
   scroll-snapping row (see carousel.js's header comment for why); this is
   just its look. */
.landing-gallery {
    padding: 64px 24px;
    background: var(--color-bg);
    text-align: center;
}

.landing-gallery h2 {
    text-align: center;
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: -0.005em;
    color: var(--color-dark);
    font-size: 1.6rem;
    margin: 0 0 32px;
}

/* "Lo que dicen nuestros pacientes" — reviews carousel, styled identically
   to .landing-gallery above (same rhythm, alternating background so the
   two sections read as distinct on the page). */
.landing-reviews {
    padding: 64px 24px;
    background: var(--color-lilac);
    text-align: center;
}

.landing-reviews h2 {
    text-align: center;
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: -0.005em;
    color: var(--color-dark);
    font-size: 1.6rem;
    margin: 0 0 32px;
}

.photo-carousel {
    position: relative;
    max-width: 720px;
    margin: 0 auto;
}

.photo-carousel-viewport {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
    /* Native swipe/scroll is the whole point (see carousel.js) — the
       scrollbar itself is just visual noise on top of the dots below. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.photo-carousel-viewport::-webkit-scrollbar {
    display: none;
}

.photo-carousel-track {
    display: flex;
    width: 100%;
    margin: 0;
    padding: 0;
    list-style: none;
}

.photo-carousel-slide {
    flex: 0 0 100%;
    scroll-snap-align: center;
}

/* Direct child only — a review slide (below) also has an <img>, the
   reviewer's small avatar, which must NOT get this treatment. */
.photo-carousel-slide > img {
    display: block;
    width: 100%;
    height: 360px;
    object-fit: cover;
}

.photo-carousel-caption {
    margin: 0;
    padding: 14px 20px;
    background: var(--color-surface);
    font-family: var(--font-display);
    font-weight: 500;
    color: var(--color-dark);
}

/* Real Google reviews (GooglePlacesReviewService) reuse the same
   .photo-carousel shell as the photo gallery above — same nav/dots/
   auto-advance behaviour from carousel.js, different slide content. */
.review-card {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 20px;
    min-height: 220px;
    padding: 32px 28px;
    background: var(--color-surface);
    text-align: left;
}

.review-stars {
    display: flex;
    gap: 2px;
    color: var(--color-border);
    font-size: 1.1rem;
    line-height: 1;
}

.review-star--filled {
    color: #e3a92b;
}

.review-text {
    margin: 0;
    color: var(--color-text-muted);
    line-height: 1.6;
}

.review-author {
    display: flex;
    align-items: center;
    gap: 12px;
}

.review-author-photo {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
}

.review-author-info {
    display: flex;
    flex-direction: column;
}

.review-author-name {
    font-weight: 600;
    color: var(--color-dark);
}

.review-time {
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

.photo-carousel-arrow {
    position: absolute;
    top: 160px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: rgba(12, 18, 30, 0.55);
    color: white;
    cursor: pointer;
    transition: background 0.15s ease;
}

.photo-carousel-arrow:hover {
    background: rgba(12, 18, 30, 0.78);
}

.photo-carousel-arrow--prev {
    left: 12px;
}

.photo-carousel-arrow--next {
    right: 12px;
}

.photo-carousel-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 16px;
}

.photo-carousel-dot {
    width: 9px;
    height: 9px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--color-border);
    cursor: pointer;
    transition: background 0.15s ease, transform 0.15s ease;
}

.photo-carousel-dot.is-active {
    background: var(--color-mauve-dark);
    transform: scale(1.25);
}

.grant-section {
    padding: 48px 24px 56px;
    background: var(--color-bg);
    border-top: 1px solid var(--color-border);
    text-align: center;
}

.grant-title {
    margin: 0 0 18px;
    font-family: var(--font-display);
    font-size: 0.9rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--color-text-muted);
}

.grant-frame {
    max-width: 720px;
    margin: 0 auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
}

.grant-poster {
    display: block;
    width: 100%;
    height: auto;
}

.grant-caption {
    max-width: 720px;
    margin: 14px auto 0;
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--color-text-muted);
}

.landing-footer {
    background: var(--color-dark);
    color: var(--color-text-on-dark);
    padding: 32px;
    text-align: center;
}

.landing-footer p {
    margin: 0;
    color: #9aa7ae;
    font-size: 0.85rem;
}

.landing-footer a {
    color: var(--color-mint);
}

.footer-portal-links {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
}

.btn-footer-link {
    display: inline-block;
    padding: 6px 16px;
    border: 1px solid rgba(242, 240, 235, 0.3);
    border-radius: var(--radius-pill);
    color: var(--color-text-on-dark);
    font-size: 0.78rem;
    font-weight: 600;
    text-decoration: none;
}

.btn-footer-link:hover {
    border-color: var(--color-mint);
    color: var(--color-mint);
}

.map-frame {
    padding: 0;
    overflow: hidden;
}

.map-frame iframe {
    display: block;
    border: 0;
}

/* Placeholder de "clic para cargar" mostrado antes de que map-loader.js
   inyecte el iframe de Google Maps (docs/backlog.md, cookies/mapa). */
.map-placeholder-content {
    padding: 24px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
}

/* Tablet / narrow window: the public nav (four links and «Iniciar sesión») no
   longer fits next to a long centre name well before phone widths, so under
   980px it collapses behind the hamburger. The language flags stay outside,
   between the name and the hamburger. */
@media (max-width: 980px) {
    .landing-header {
        padding: 16px 22px;
    }

    .mobile-nav-toggle {
        display: flex;
    }

    .lang-switch {
        margin-left: auto;
        margin-right: 16px;
    }

    .landing-nav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
        padding: 12px 22px 20px;
        background: var(--color-surface);
        border-top: 1px solid var(--color-border);
        box-shadow: var(--shadow-lift);
        z-index: 900;
    }

    .landing-nav.is-open {
        display: flex;
    }

    .landing-nav a:not(.btn-primary-link) {
        padding: 8px 0;
        width: 100%;
    }
}

/* Tablet / large phone: the hero's desktop padding is too tall for a short
   viewport. */
@media (max-width: 760px) {
    .landing-hero {
        padding: 64px 24px 60px;
    }

    .landing-hero h1 {
        font-size: 2.1rem;
    }

    .grant-section {
        padding: 40px 20px 44px;
    }
}

@media (max-width: 480px) {
    .topbar {
        flex-direction: column;
        align-items: flex-start;
    }

    /* Phone: name, flags and hamburger on one line. the city goes under the
       name and the flags shrink a little. */
    .landing-header {
        padding: 12px 16px;
    }

    .landing-header .brand {
        font-size: 1.25rem;
        min-width: 0;
    }

    .landing-header .brand-mark {
        width: 40px;
        height: 40px;
    }

    .landing-header .brand-name {
        flex-direction: column;
        align-items: flex-start;
        gap: 2px;
    }

    .landing-header .lang-switch {
        gap: 8px;
        margin-right: 10px;
    }

    .landing-header .lang-switch .flag {
        width: 24px;
        height: 16px;
    }

    .landing-hero {
        padding: 56px 22px 52px;
    }

    .landing-hero h1 {
        font-size: 1.8rem;
    }

    .services-section {
        padding: 48px 16px;
    }

    .services-grid {
        /* Phones: a predictable 2-up grid (2 + 2 + 1) rather than letting
           auto-fit drop to a single column on the narrowest devices. */
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
    }

    .service-card {
        padding: 18px 10px;
    }

    .landing-gallery,
    .landing-reviews {
        padding: 48px 16px;
    }

    .photo-carousel-slide > img {
        height: 220px;
    }

    .review-card {
        padding: 22px 18px;
        min-height: 0;
    }

    .photo-carousel-arrow {
        top: 90px;
        width: 34px;
        height: 34px;
    }

    .service-icon {
        width: 40px;
        height: 40px;
        margin-bottom: 10px;
    }

    .service-icon svg {
        width: 18px;
        height: 18px;
    }

    .service-card h3 {
        font-size: 0.8rem;
    }

    .office-photo {
        height: 220px;
    }
}

/* --- App content pages (tasks, appointments) --- */

.page-content {
    max-width: 760px;
    margin: 40px auto;
    padding: 0 24px 48px;
}

/* Wider variant for pages built around a data table (patient records,
   appointments, admin listings): the 760px default is sized for forms
   and reads as cramped once a table with several columns sits inside
   it, even though the surrounding page has plenty of unused width to
   give. Still shrinks like any max-width container on narrower
   viewports — this only changes the ceiling on medium/large screens. */
.page-content--wide {
    max-width: 1440px;
}

/* Row of filter links (e.g. one per aseguradora + "Todos") above a table. */
.filter-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 16px 0;
}

.filter-pills a {
    padding: 6px 14px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: 0.9rem;
    text-decoration: none;
}

.filter-pills a:hover {
    border-color: var(--color-mauve-dark);
}

.filter-pills a.is-active {
    background: var(--color-mauve-dark);
    border-color: var(--color-mauve-dark);
    color: #fff;
}

.page-content h1 {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--color-mauve-dark);
    font-size: 1.8rem;
    margin-bottom: 24px;
}

.card-panel {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 24px;
    margin-top: 20px;
}

.card-panel h3 {
    margin-top: 0;
    font-family: var(--font-display);
    color: var(--color-mauve-dark);
    font-size: 1.1rem;
}

/* Ficha de paciente: cada apartado se colapsa clicando su título — ver
   ficha-collapsible.js. Solo se aplica a los .card-panel cuyo primer hijo
   es un <h3> (el panel de datos generales, arriba del todo, no lo tiene y
   se queda siempre visible a propósito). */
.card-panel.is-collapsible > h3:first-child {
    cursor: pointer;
    user-select: none;
}

/* El triángulo solo aparece si el panel se puede plegar de verdad: ficha-collapsible.js marca los paneles con .is-collapsible
   (antes salía en todas las pantallas aunque no hiciera nada: proveedores, contabilidad... — 14/10/2026). */
.card-panel.is-collapsible > h3:first-child::before {
    content: "▾";
    display: inline-block;
    width: 1em;
    margin-right: 4px;
    transition: transform 0.15s ease;
}

.card-panel.is-collapsible.is-collapsed > h3:first-child::before {
    transform: rotate(-90deg);
}

/* !important a propósito: un panel plegado no debe enseñar nada salvo su título, aunque un hijo tenga una regla con
   identificador (p. ej. #enviar-ejercicios-form { display: block }) que pesaría más. */
.card-panel.is-collapsed > :not(h3) {
    display: none !important;
}

/* "La clínica": lista de equipos y montaje de fotos al final de la página
   (tarjeta de Equipamiento). La lista es una enumeración corta a dos
   columnas cuando hay sitio; el montaje es una sola imagen que todavía
   no existe en /images/equipos/ — hasta que se suba, data-hide-on-error
   (ui-behaviors.js) esconde el <figure> entero para no dejar el icono de
   imagen rota. */
.equipment-list {
    margin: 12px 0 16px;
    padding-left: 20px;
    columns: 2;
    column-gap: 32px;
}

.equipment-list li {
    margin-bottom: 4px;
    break-inside: avoid;
}

@media (max-width: 520px) {
    .equipment-list {
        columns: 1;
    }
}

/* "Fisioterapeuta asignado" on the ficha: at most 2 rows, name (+ its
   collegiate number directly under it, tightly grouped so it's obvious
   which number belongs to which name) and the row's "Quitar" button on
   the right, kept small since it's just a per-row action, not a
   page-level one. */
.professional-list {
    list-style: decimal;
    margin: 12px 0 16px;
    padding-left: 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* "Fisioterapeuta asignado", the first section inside "Añadir consulta"
   (2026-09-14: used to live as a side column in a two-column grid next
   to the form — "si en vez de estar en un área separada lo metemos
   dentro de Añadir consulta no nos limita las cajas y se integra
   mejor" — that grid forced this box to stretch as tall as the whole
   form beside it for no reason; it's just a plain subsection now, like
   any other block in the card). Left-aligned throughout (2026-09-13,
   "el título debe ir alineado con los nombres") — it used to open as a
   leftward dropdown and needed text-align:right to hug the card's
   edge, but it's a plain always-visible block now, so the title should
   start at the same left edge as the names below it. */
.professional-panel {
    margin-bottom: 20px;
    text-align: left;
}
.professional-panel h4 {
    margin: 0 0 4px;
    font-family: var(--font-display);
    color: var(--color-mauve-dark);
    font-size: 1.1rem;
}
.professional-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.professional-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.professional-collegiate {
    margin: 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}
.btn-action--sm {
    padding: 3px 10px;
    font-size: 0.75rem;
}

/* Galería de fotos de equipos en "La clínica" — una foto por técnica, con
   pie de foto. Tarjetas de igual tamaño (misma proporción, object-fit:
   cover) para que las fotos de proveedores distintos guarden armonía entre
   sí, aunque su resolución original difiera. */
.equipment-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 20px;
    margin: 24px 0 0;
}

.equipment-gallery-item {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    overflow: hidden;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.equipment-gallery-item:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lift);
}

.equipment-gallery-item img {
    display: block;
    width: 100%;
    height: 200px;
    object-fit: contain;
    background: #fff;
}

/* Same left-to-right stagger as .services-grid above. */
.equipment-gallery [data-reveal]:nth-child(1) { transition-delay: 0s; }
.equipment-gallery [data-reveal]:nth-child(2) { transition-delay: 0.06s; }
.equipment-gallery [data-reveal]:nth-child(3) { transition-delay: 0.12s; }
.equipment-gallery [data-reveal]:nth-child(4) { transition-delay: 0.18s; }

.equipment-gallery-item figcaption {
    padding: 12px 16px 16px;
}

.equipment-gallery-item .equipment-gallery-title {
    font-weight: 600;
    margin: 0 0 4px;
}

.equipment-gallery-item .equipment-gallery-note {
    margin: 0;
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

.backup-codes-list {
    list-style: none;
    padding: 0;
    margin: 16px 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 8px;
}

.backup-codes-list code {
    display: block;
    padding: 8px 12px;
    background: var(--color-bg);
    border-radius: 6px;
    text-align: center;
}

.table-responsive {
    width: 100%;
    overflow-x: auto;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--color-surface);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
}

.data-table th,
.data-table td {
    text-align: left;
    padding: 16px 20px;
    font-size: 1rem;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

/* Columns that hold free-form text (descriptions, notes, reasons) should
   still wrap normally — only short, single-value columns (names, dates,
   statuses, action buttons) benefit from the nowrap default above, which
   exists to stop the browser's table layout from squeezing breakable
   text like "Juan Perez Gomez" onto multiple lines just because a
   neighboring unbreakable column (e.g. an email address) claimed more
   width. */
.data-table td.cell-wrap {
    white-space: normal;
}

.data-table th {
    background: var(--color-lilac);
    color: var(--color-dark);
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 0.95rem;
}

.data-table tr:last-child td {
    border-bottom: none;
}

.data-table .completada {
    text-decoration: line-through;
    color: var(--color-text-muted);
}

/* A row whose patient's ficha can be opened with a double-click on the
   name (see /js/agenda-patient-open.js) — same pattern as the agenda's
   .calendar-appointment-chip.is-openable. */
.data-table tr.is-openable td.is-openable-target {
    cursor: pointer;
}

.data-table tr.is-openable:hover td {
    background: var(--color-mint);
}

/* Precio original tachado junto al precio con descuento ya aplicado
   (patient-payments.html) — para que el staff vea de un vistazo por qué
   el monto no es el de siempre, antes de llegar a la factura. */
.strikethrough {
    text-decoration: line-through;
    color: var(--color-text-muted);
}

/* Un <input type="text"> o <select> normal es width:100% (regla global de
   arriba); dentro de una celda de tabla eso lo hace reclamar todo el ancho
   disponible en el cálculo de columnas, aplastando las columnas vecinas
   (Estado/Acciones en admin-insurers.html; el botón "Marcar como pagado"
   en patient-payments.html) hasta que su contenido se solapa o queda
   invisible. Ancho fijo y razonable en vez de 100% para cualquier
   input/select embebido en una fila de tabla. */
input.table-inline-input[type="text"],
select.table-inline-input {
    width: 220px;
    display: inline-block;
}

.chat-thread {
    max-height: 360px;
    overflow-y: auto;
    margin-bottom: 16px;
}

.chat-message {
    background: var(--color-lilac);
    border-radius: var(--radius);
    padding: 10px 16px;
    margin-bottom: 10px;
}

.chat-message p {
    margin: 4px 0;
}

.chat-message strong {
    font-family: var(--font-display);
    color: var(--color-mauve-dark);
}

.chat-message span {
    color: var(--color-text-muted);
    font-size: 0.85rem;
    margin-left: 8px;
}

.form-row {
    margin: 14px 0;
}

.form-row label {
    display: block;
    margin-bottom: 6px;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

/* Puts two short fields (e.g. selects) side by side instead of stacked,
   for pairs that read naturally as one line — falls back to stacked on
   narrow screens instead of squeezing both into half-width each. */
.form-row-pair {
    display: flex;
    gap: 16px;
}

/* Same gotcha as .dashboard-tab[hidden]/.chat-widget-panel[hidden] above:
   the explicit display:flex beats the native [hidden]{display:none} UA
   rule, so a form-row-pair (e.g. the insurer card number/version fields
   on "Nueva cita") stayed visible even after JS set hidden=true. */
.form-row-pair[hidden] {
    display: none;
}

.form-row-pair > .form-row {
    flex: 1;
    min-width: 0;
}

@media (max-width: 480px) {
    .form-row-pair {
        flex-direction: column;
        gap: 0;
    }
}

input[type="text"],
input[type="date"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="number"],
select,
textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font-size: 1rem;
    font-family: inherit;
    background: var(--color-surface);
    box-sizing: border-box;
}

input[type="text"]:focus,
input[type="date"]:focus,
input[type="email"]:focus,
input[type="tel"]:focus,
input[type="password"]:focus,
input[type="number"]:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--color-mauve);
}

/* Multi-select checkbox groups (e.g. zona tratada, técnicas aplicadas) —
   mirrors .form-row's spacing/legend styling so a fieldset reads like any
   other form field, not a foreign element. */
fieldset.form-row {
    border: none;
    padding: 0;
}

fieldset.form-row legend {
    margin-bottom: 6px;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--color-text-muted);
    padding: 0;
}

.checkbox-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0 16px 8px 0;
    font-weight: 400;
    font-size: 0.95rem;
}

.checkbox-label input[type="checkbox"] {
    width: auto;
}

/* min-height gives textareas a usable starting size instead of the
   browser's tiny ~2-row default; resize stays vertical-only so
   dragging bigger never breaks the form's width. */
textarea {
    min-height: 110px;
    resize: vertical;
}

/* Teal/white "primary" look, app-wide (2026-09-14, "todo lo que es
   común lo hacemos igual en todos lados") — this used to be the base
   gray/outline look, with the ficha's own action rows separately
   overridden to teal; every other page's .btn-action (admin tables
   included) stayed gray, so the same button read as two different
   button languages depending on which page you were on. One look now,
   everywhere; .btn-submit already was this same teal, so this also
   makes .btn-action/.btn-submit consistent with each other. */
.btn-action {
    display: inline-block;
    cursor: pointer;
    padding: 8px 16px;
    margin-right: 6px;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-mauve);
    color: white;
    text-decoration: none;
    font-weight: 600;
    font-family: inherit;
    font-size: 0.85rem;
    transition: background 0.15s ease;
}

.btn-action:hover {
    background: var(--color-mauve-dark);
}

.btn-action.danger {
    background: var(--color-error-text);
}

.btn-action.danger:hover {
    background: #7d2c23;
}

/* Proper wrap layout for the ficha's top action-button row — these were
   plain inline elements relying on text-wrapping, which left wrapped
   rows touching with no vertical gap (especially visible once they got
   a solid background). .ficha-actions keeps display:contents, so its
   buttons still participate directly in this flex box, same as
   .patient-actions' own direct children. */
.patient-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
}
.patient-actions .btn-action,
.patient-actions .inline-form {
    margin-right: 0;
}

/* The appointment table's action cell (Cancelar / Asistió / No se
   presentó / Canceló a tiempo / Mover) is a mix of plain <form>s and a
   <details>, each block-level by default, so with no layout of their own
   they stacked touching with zero gap. Same fix as .patient-actions above:
   a wrapping flex row with its own gap, buttons no longer need their
   individual margin-right. */
.row-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}
.row-actions .btn-action {
    margin-right: 0;
}

/* Always visible now, no click required (2026-09-13) — same reasoning as
   "Fisioterapeuta asignado": a click-to-reveal control is one more thing
   that can go wrong (and repeatedly seemed to, in ways that never showed
   up in a markup-only check), and this needs to just work every time. */
#enviar-ejercicios-form {
    display: block;
    margin-top: 16px;
}

/* A date picker doesn't need to stretch across the whole panel like a
   textarea does — the global input[type="date"] { width: 100% } rule
   made sense while Fecha shared a .form-row-pair with Hora (each ~half
   width); alone, it just needs to fit its own content. */
#input-fecha-consulta {
    width: auto;
    max-width: 190px;
}

/* Ficha "Reordenar botones" (ficha-actions.js): a plain wrapper for
   drag-and-drop bookkeeping, invisible to layout so it doesn't disturb the
   existing inline button flow. */
.ficha-actions {
    display: contents;
}
.ficha-actions.is-reordering [data-btn-key] {
    cursor: grab;
    outline: 1px dashed var(--color-border);
    outline-offset: 2px;
}
.ficha-actions [data-btn-key].is-dragging {
    opacity: 0.4;
}

.btn-submit {
    cursor: pointer;
    padding: 10px 24px;
    margin-top: 12px;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-mauve);
    color: white;
    font-family: inherit;
    font-weight: 600;
    font-size: 0.95rem;
    transition: background 0.15s ease;
}

.btn-submit:hover {
    background: var(--color-mauve-dark);
}

.btn-submit:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Action row for dropdown form panels (Nueva cita, Nuevo curso, Buscar
   huecos, Relación mensual, Mover, Renovar, and the agenda block menu):
   a "Cancelar" that closes the <details> next to the submit, both the
   same size — equal width, one height, one type scale, label clipped
   with an ellipsis if it ever doesn't fit. */
.panel-actions {
    display: flex;
    gap: 8px;
    margin-top: 12px;
}
.panel-btn {
    flex: 1 1 0;
    min-width: 0;
    height: 38px;
    padding: 0 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-mauve-dark);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 36px;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-sizing: border-box;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.panel-btn--primary {
    background: var(--color-mauve);
    border-color: var(--color-mauve);
    color: #fff;
}
.panel-btn--primary:hover {
    background: var(--color-mauve-dark);
    border-color: var(--color-mauve-dark);
}
.panel-btn--ghost {
    background: var(--color-bg);
}
.panel-btn--ghost:hover {
    background: var(--color-lilac);
}
.panel-btn--danger {
    color: var(--color-error-text);
    border-color: var(--color-error-text);
}
/* Same idea, tighter, inside the narrow agenda block menu. */
.agenda-block-menu-panel .panel-actions {
    margin-top: 4px;
}
.agenda-block-menu-panel .panel-btn {
    height: 30px;
    line-height: 28px;
    font-size: 0.72rem;
    padding: 0 8px;
}

.slots {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 10px;
}

.slot-option {
    display: flex;
    align-items: center;
    gap: 6px;
    font-weight: normal;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    padding: 8px 14px;
    font-size: 0.9rem;
}

.form-error {
    color: var(--color-error-text);
    display: block;
    font-size: 0.85rem;
    margin-top: 4px;
}

/* Clickable free-slot grid on the staff "nueva cita" form (populated by
   appointment-form.js from /admin/appointments/slots). */
.slot-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 6px;
}

.slot-chip {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    padding: 6px 12px;
    font-size: 0.9rem;
    cursor: pointer;
}

.slot-chip--active {
    background: var(--color-primary, #2b8a8a);
    border-color: var(--color-primary, #2b8a8a);
    color: #fff;
}

.slot-grid-empty {
    margin: 0;
    font-size: 0.85rem;
    color: var(--color-muted, #5b6b76);
}

.form-hint {
    display: block;
    font-size: 0.8rem;
    color: var(--color-muted, #5b6b76);
    margin-top: 4px;
}

/* Non-<label> caption inside a .form-row (e.g. above the slot grid), styled
   to read like the row's own label. */
.form-row .form-label {
    display: block;
    margin-bottom: 6px;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--color-text-muted);
}

/* Honeypot field for the /como-llegar contact form: invisible to a sighted
   visitor (off-screen, unreachable by Tab), but present in the DOM for a
   bot filling every field to fall into — see ContactRequest#getWebsite(). */
.contact-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.success-banner {
    background: var(--color-success-bg);
    color: var(--color-success-text);
    padding: 12px 16px;
    border-radius: 8px;
    margin-bottom: 15px;
}

.conflict-banner {
    background: var(--color-error-bg);
    color: var(--color-error-text);
    padding: 12px 16px;
    border-radius: 8px;
    margin-bottom: 15px;
}

.server-time-hint {
    color: var(--color-text-muted);
    font-size: 0.9em;
}

.server-time-hint time {
    font-family: monospace;
    font-weight: bold;
}

/* --- Month calendar (professional's own agenda, admin panel) --- */

.calendar-tabs {
    display: flex;
    gap: 8px;
    margin: 20px 0 12px;
}

.calendar-tab {
    padding: 8px 18px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text);
    text-decoration: none;
    font-size: 0.9rem;
}

.calendar-tab:hover {
    background: var(--color-lilac);
}

.calendar-tab--active {
    background: var(--color-mauve);
    border-color: var(--color-mauve);
    color: white;
}

/* Compact variant, used on the agenda so the whole control band is one
   tight header over the calendar. */
.calendar-tabs--compact {
    gap: 6px;
    margin: 0 0 8px;
    flex-wrap: wrap;
}

.calendar-tabs--compact .calendar-tab {
    padding: 5px 12px;
    font-size: 0.8rem;
}

/* Agenda date row: the calendar-icon view/range picker next to the
   ‹ Anterior — label — Siguiente › navigation (2026-09-08). */
.agenda-daterow {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 8px;
}

.agenda-daterow .calendar-header {
    flex: 1;
    min-width: 240px;
    margin: 0;
    order: 1;
}

/* The view picker (Mes / Semana / Día) sits at the right end, as in the usual calendars. */
.agenda-daterow .view-picker {
    order: 2;
}

/* «+ Crear»: the primary action of the agenda toolbar, always visible. */
.agenda-create-btn {
    background: var(--color-mauve);
    color: #fff;
    font-weight: 700;
}

.view-picker {
    position: relative;
}

.view-picker-btn {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-mauve-dark);
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
}

.view-picker-btn::-webkit-details-marker {
    display: none;
}

.view-picker-btn::after {
    content: "\25be";
    font-size: 0.8em;
    opacity: 0.55;
}

.view-picker-icon {
    font-size: 1rem;
    line-height: 1;
}

.view-picker[open] > .view-picker-btn {
    background: var(--color-lilac);
}

.view-picker-menu {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 6px;
    z-index: 30;
    min-width: 190px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
}

.view-picker-group {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

.view-picker-group + .view-picker-group {
    border-top: 1px solid var(--color-border);
    padding-top: 8px;
}

.view-picker-menu .calendar-tab {
    padding: 5px 10px;
    font-size: 0.8rem;
}

/* --- Agenda toolbar: create / search / report panels as small buttons in
   one header row, each dropping its form as an overlay when opened
   (2026-09-08). Pure CSS on native <details> — no inline handlers. --- */
.agenda-toolbar {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 0 0 8px;
}

.agenda-tool {
    position: static;
}

.agenda-tool-btn {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 170px;
    padding: 5px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-mauve-dark);
    font-size: 0.8rem;
    font-weight: 600;
    white-space: nowrap;
}

.agenda-tool-btn::-webkit-details-marker {
    display: none;
}

.agenda-tool-btn > span {
    overflow: hidden;
    text-overflow: ellipsis;
}

.agenda-tool-btn::after {
    content: "\25be";
    font-size: 0.7em;
    opacity: 0.55;
}

.agenda-tool-btn:hover {
    background: var(--color-lilac);
}

.agenda-tool[open] > .agenda-tool-btn {
    background: var(--color-mauve);
    border-color: var(--color-mauve);
    color: #fff;
}

.agenda-tool[open] > form {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 6px;
    z-index: 30;
    width: min(560px, 92vw);
    max-height: 72vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
    padding: 16px;
}

.agenda-tool-filter {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.8rem;
}

.agenda-tool-filter label {
    color: var(--color-text-muted);
}

.agenda-tool-filter select {
    height: var(--control-md);
    padding: 0 var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    font-size: var(--text-sm);
    font-family: inherit;
}

/* --- Agenda cintillo: the create/search/report actions live in the
   home/back nav bar on the Citas page (2026-09-08). --- */
.agenda-nav {
    position: relative;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
}

.agenda-nav-icon {
    display: inline-flex;
    align-items: center;
    padding: 2px 4px;
}

/* "Citas" — the only thing still using this class since Relación
   mensual/Ingresos moved to Contabilidad (2026-09-17): a bit bigger than
   .agenda-tool-btn (the panels inside it) and with the same pill
   background, so it reads as the entry point it is rather than a plain
   text link sitting among icon buttons. */
.agenda-nav-summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-mauve-dark);
    font-size: 0.9rem;
    font-weight: 600;
}

.agenda-nav-summary::-webkit-details-marker {
    display: none;
}

.agenda-nav-summary::after {
    content: "\25be";
    font-size: 0.75em;
    opacity: 0.55;
}

.agenda-nav-summary:hover {
    background: var(--color-lilac);
}

.agenda-nav-item {
    position: static;
}

.agenda-nav-item[open] > .agenda-nav-summary {
    background: var(--color-mauve);
    border-color: var(--color-mauve);
    color: #fff;
}

/* "Citas" dropdown: the three create/search panels, stacked and scrollable. */
.agenda-nav-panel {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 4px;
    z-index: 40;
    width: min(600px, 94vw);
    max-height: 78vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
}

/* Quick patient finder in the cintillo. */
.agenda-search {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 240px;
    max-width: 360px;
    padding: 4px 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
}

.agenda-search-icon {
    color: var(--color-text-muted);
    flex-shrink: 0;
}

.agenda-search-input {
    border: 0;
    outline: none;
    background: transparent;
    font-family: inherit;
    font-size: 0.82rem;
    width: 100%;
}

.agenda-search-datebtn {
    position: static;
    flex-shrink: 0;
}

.agenda-search-datesummary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    color: var(--color-text-muted);
    padding: 2px;
}

.agenda-search-datesummary::-webkit-details-marker {
    display: none;
}

.agenda-search-datebtn[open] > .agenda-search-datesummary {
    color: var(--color-mauve);
}

.agenda-search-daterange {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 4px;
    z-index: 45;
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 8px;
    padding: 12px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
}

.agenda-search-daterange label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 0.72rem;
    color: var(--color-text-muted);
}

.agenda-search-daterange input {
    padding: 4px 6px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: inherit;
    font-size: 0.8rem;
}

.agenda-search-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 4px;
    z-index: 45;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
}

.agenda-search-hit {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 7px 12px;
    text-decoration: none;
    color: var(--color-text);
    border-bottom: 1px solid var(--color-border);
}

.agenda-search-hit:last-child {
    border-bottom: 0;
}

.agenda-search-hit:hover,
.agenda-search-hit:focus {
    background: var(--color-lilac);
}

.agenda-search-hit-name {
    font-weight: 600;
    font-size: 0.82rem;
    color: var(--color-mauve-dark);
}

.agenda-search-hit-meta {
    font-size: 0.72rem;
    color: var(--color-text-muted);
}

.agenda-search-empty {
    padding: 10px 12px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* Inside that dropdown the forms open inline (not as their own overlay). */
.agenda-nav-panel .agenda-tool[open] > form {
    position: static;
    width: auto;
    max-height: none;
    margin-top: 8px;
    padding: 12px 2px 2px;
    border: 0;
    border-top: 1px solid var(--color-border);
    border-radius: 0;
    box-shadow: none;
}

.calendar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 16px 0;
}

.calendar-nav {
    text-decoration: none;
    white-space: nowrap;
}

/* Standard calendar header: [Hoy] [‹ ›] Título, all together on the left (Trello #174, bloque D). */
.calendar-header {
    justify-content: flex-start;
}

.calendar-today {
    text-decoration: none;
    white-space: nowrap;
}

.calendar-step {
    display: inline-flex;
    gap: 2px;
}

.calendar-step-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    color: var(--color-mauve-dark);
    font-size: 1.5rem;
    line-height: 1;
    text-decoration: none;
}

.calendar-step-btn:hover,
.calendar-step-btn:focus-visible {
    background: var(--color-lilac);
}

.calendar-month-label {
    display: flex;
    align-items: center;
    gap: 12px;
    font-family: var(--font-display);
    color: var(--color-mauve-dark);
    font-size: 1.2rem;
    text-transform: capitalize;
}

.calendar-scroll {
    width: 100%;
    overflow-x: auto;
}

.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(120px, 1fr));
    gap: 1px;
    background: var(--color-border);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.calendar-weekday {
    background: var(--color-lilac);
    color: var(--color-dark);
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 0.85rem;
    padding: 10px 12px;
    text-align: center;
}

.calendar-day {
    background: var(--color-surface);
    min-height: 110px;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.calendar-day--other-month {
    background: var(--color-bg);
    color: var(--color-text-muted);
}

/* Day view: a single wide cell needs more room to list a full day's appointments. */
.calendar-day--wide {
    min-height: 400px;
}

.calendar-day--today .calendar-day-number {
    background: var(--color-mauve);
    color: white;
    border-radius: 50%;
}

.calendar-day-number {
    align-self: flex-start;
    font-size: 0.85rem;
    font-weight: 600;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.calendar-appointment-chip {
    display: flex;
    align-items: center;
    gap: 4px;
    background: var(--color-lilac);
    border-radius: 6px;
    padding: 3px 6px;
    font-size: 0.78rem;
    line-height: 1.2;
}

/* Staff agenda: a chip whose patient's ficha can be opened with a
   double-click (see /js/agenda-patient-open.js). */
.calendar-appointment-chip.is-openable {
    cursor: pointer;
}

.calendar-appointment-chip.is-openable:hover {
    background: var(--color-mint);
}

.calendar-appointment-time {
    font-weight: 600;
    white-space: nowrap;
}

.calendar-appointment-who {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}

/* Flags a patient with a pending payment (see AdminAppointmentController)
   on the admin calendar/list — a small "€" badge rather than a plain dot,
   so it stays identifiable once other status icons (e.g. for sent
   messages) join it here later; each new one gets its own symbol/color
   rather than relying on a shape alone. */
.status-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    font-size: 0.65rem;
    font-weight: 700;
    color: var(--color-text-on-dark);
    flex-shrink: 0;
}

.payment-pending-icon {
    background: var(--color-error-text);
}

.calendar-appointment-cancel {
    cursor: pointer;
    border: none;
    background: none;
    color: var(--color-error-text);
    font-size: 1rem;
    line-height: 1;
    padding: 0 2px;
}

.calendar-appointment-cancel:hover {
    font-weight: 700;
}

/* --- Booking date-picker calendar (appointments.html) --- */
/* Compact on purpose, unlike .calendar-day above: a date picker only ever
   shows a day number, never appointment chips, so it doesn't need that
   layout's height. */

.booking-calendar-scroll {
    width: 100%;
    overflow-x: auto;
    margin-top: 10px;
}

.booking-calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(44px, 1fr));
    gap: 4px;
}

.booking-calendar-weekday {
    text-align: center;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--color-text-muted);
    padding: 4px 0;
}

.booking-calendar-day {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 40px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--color-text);
    font-size: 0.9rem;
    background: var(--color-bg);
}

.booking-calendar-day[href]:hover {
    background: var(--color-lilac);
}

.booking-calendar-day--other-month {
    color: var(--color-border);
}

.booking-calendar-day--unbookable {
    color: var(--color-text-muted);
    opacity: 0.45;
}

.booking-calendar-day--selected {
    background: var(--color-mauve);
    color: white;
    font-weight: 600;
}

/* --- Floating WhatsApp button (every page) --- */

.whatsapp-float {
    position: fixed;
    right: 24px;
    bottom: 24px;
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #25d366;
    color: white;
    border-radius: 50%;
    box-shadow: var(--shadow-lift);
    z-index: 1000;
    transition: transform 0.15s ease;
}

.whatsapp-float:hover {
    transform: scale(1.08);
}

@media (max-width: 480px) {
    .whatsapp-float {
        right: 16px;
        bottom: 16px;
        width: 48px;
        height: 48px;
    }
}

/* Landing page only, left side — WhatsApp/chat already own the bottom-right
   corner. scroll-to-bottom.js hides it (via the `hidden` attribute) once
   the page is already scrolled near the bottom. */
.scroll-to-bottom-float {
    position: fixed;
    left: 24px;
    bottom: 24px;
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-mauve);
    color: white;
    border: none;
    border-radius: 50%;
    box-shadow: var(--shadow-lift);
    z-index: 1000;
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease;
}

.scroll-to-bottom-float:hover {
    background: var(--color-mauve-dark);
    transform: scale(1.08);
}

/* Same gotcha as .form-row-pair[hidden]/.dashboard-tab[hidden] above: the
   explicit display:flex beats the native [hidden]{display:none} UA rule,
   so the button stayed visible and covered the footer's "Acceso
   fisioterapeuta" link even once scroll-to-bottom.js set hidden=true. */
.scroll-to-bottom-float[hidden] {
    display: none;
}

@media (max-width: 480px) {
    .scroll-to-bottom-float {
        left: 16px;
        bottom: 16px;
        width: 48px;
        height: 48px;
    }
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.chat-widget-toggle {
    position: fixed;
    right: 24px;
    bottom: 92px;
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-mauve);
    color: white;
    border: none;
    border-radius: 50%;
    box-shadow: var(--shadow-lift);
    z-index: 1000;
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease;
}

.chat-widget-toggle:hover {
    background: var(--color-mauve-dark);
    transform: scale(1.08);
}

.chat-widget-panel {
    position: fixed;
    right: 24px;
    bottom: 156px;
    width: 320px;
    max-width: calc(100vw - 32px);
    height: 420px;
    max-height: calc(100vh - 180px);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    box-shadow: var(--shadow-lift);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* `display: flex` above has the same specificity as the browser's own
   `[hidden] { display: none }` rule and comes later in the cascade, so it
   silently wins and the panel stays visible even with `hidden` set unless
   this higher-specificity override is here to close it back out. */
.chat-widget-panel[hidden] {
    display: none;
}

.chat-widget-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    background: var(--color-mauve);
    color: white;
    font-weight: 600;
}

.chat-widget-close {
    background: none;
    border: none;
    color: white;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
}

.chat-widget-messages {
    flex: 1;
    overflow-y: auto;
    padding: 12px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.chat-widget-message {
    max-width: 85%;
    padding: 8px 12px;
    border-radius: 10px;
    font-size: 0.9rem;
    line-height: 1.4;
    white-space: pre-wrap;
}

.chat-widget-message-user {
    align-self: flex-end;
    background: var(--color-mint);
    color: var(--color-dark);
}

.chat-widget-message-assistant {
    align-self: flex-start;
    background: var(--color-lilac);
    color: var(--color-dark);
}

/* "Escribiendo..." — misma burbuja que chat-widget-message-assistant, con
   tres puntos animados en vez de texto, mientras se espera la respuesta de
   /api/chat (puede tardar varios segundos si hay tool-use encadenado). */
.chat-widget-typing {
    align-self: flex-start;
    display: flex;
    gap: 4px;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--color-lilac);
}

.chat-widget-typing span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-dark);
    opacity: 0.4;
    animation: chat-widget-typing-bounce 1.2s infinite ease-in-out;
}

.chat-widget-typing span:nth-child(2) {
    animation-delay: 0.2s;
}

.chat-widget-typing span:nth-child(3) {
    animation-delay: 0.4s;
}

@keyframes chat-widget-typing-bounce {
    0%, 60%, 100% {
        opacity: 0.4;
        transform: translateY(0);
    }
    30% {
        opacity: 1;
        transform: translateY(-3px);
    }
}

/* Preguntas sugeridas al abrir el chat vacío — botones clicables que bajan
   la fricción de escribir el primer mensaje. Desaparecen en cuanto hay una
   primera pregunta real (ver chat-widget.js). */
.chat-widget-suggestions {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 4px 0;
}

.chat-widget-suggestion {
    align-self: flex-start;
    max-width: 90%;
    padding: 8px 12px;
    border-radius: 10px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-dark);
    font-size: 0.85rem;
    text-align: left;
    cursor: pointer;
}

.chat-widget-suggestion:hover {
    background: var(--color-mint);
}

.chat-widget-form {
    display: flex;
    gap: 8px;
    padding: 12px;
    border-top: 1px solid var(--color-border);
}

.chat-widget-form input {
    flex: 1;
    padding: 8px 10px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

.chat-widget-form .btn-primary {
    padding: 8px 14px;
}

@media (max-width: 480px) {
    .chat-widget-toggle {
        right: 16px;
        bottom: 72px;
        width: 48px;
        height: 48px;
    }

    .chat-widget-panel {
        right: 16px;
        bottom: 128px;
        width: calc(100vw - 32px);
    }
}

/* ---------------------------------------------------------------------------
   Helpers extraídos de atributos style="" en las plantillas, para poder
   servir la CSP con style-src 'self' (sin 'unsafe-inline'). Ver
   SecurityConfig#CONTENT_SECURITY_POLICY. No añadir style="" nuevos: crear
   una clase aquí.
   --------------------------------------------------------------------------- */

/* <form> en línea junto a otros botones de acción (listados de admin, ficha). */
.inline-form {
    display: inline;
}

/* Etiqueta "parcial" en el buscador de huecos de curso. */
.badge-inline {
    display: inline;
    padding: 2px 6px;
}

/* Aviso de "facturamos nosotros" en la ficha de aseguradora (admin-insurers.html) —
   destacado a propósito: es la excepción rara (autofactura es lo normal). */
.insurer-billing-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 0.78rem;
    font-weight: 600;
}

.insurer-billing-badge--direct {
    background: var(--color-danger, #c0392b);
    color: #fff;
}

.insurer-billing-badge--self-billed {
    color: var(--color-text-muted, #6b6b6b);
    font-weight: 400;
}

/* Antigüedad de un cobro pendiente en /admin/facturacion — mismo patrón de
   pastilla que insurer-billing-badge, para que un pago vencido salte a la
   vista en la cola de recobros. */
.payment-age-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 0.78rem;
    font-weight: 600;
}

.payment-age-badge--overdue {
    background: var(--color-danger, #c0392b);
    color: #fff;
}

.payment-age-badge--normal {
    color: var(--color-text-muted, #6b6b6b);
    font-weight: 400;
}

/* Separación entre promociones elegibles en la ficha del paciente. */
.promo-eligible-item {
    margin-bottom: 12px;
}

/* Lienzo de firma en /firmar-consentimiento. */
.signature-pad {
    border: 1px solid var(--color-border);
    touch-action: none;
    max-width: 100%;
}

/* Nº de columnas del calendario — antes un style="" dinámico; sólo hay tres
   valores posibles (7 mes/semana, 5 semana laboral, 1 día). */
.calendar-grid--cols-7 {
    grid-template-columns: repeat(7, minmax(120px, 1fr));
}

.calendar-grid--cols-5 {
    grid-template-columns: repeat(5, minmax(120px, 1fr));
}

.calendar-grid--cols-1 {
    grid-template-columns: repeat(1, minmax(120px, 1fr));
}

/* Card 147 (2026-09-21): on a ~390px phone, the month/week grid (7 or 5
   columns at 120px each) needs a long horizontal drag through
   .calendar-scroll to see the whole week — not broken, just uncomfortable.
   Narrower columns fit more of the week per screen; .calendar-appointment-who
   already truncates with an ellipsis, so shrinking the column never
   overflows or breaks a chip, it just shows less of the patient's name. */
@media (max-width: 480px) {
    .calendar-grid--cols-7 {
        grid-template-columns: repeat(7, minmax(72px, 1fr));
    }

    .calendar-grid--cols-5 {
        grid-template-columns: repeat(5, minmax(84px, 1fr));
    }

    .calendar-day {
        min-height: 88px;
        padding: 6px;
        gap: 3px;
    }

    .calendar-weekday {
        padding: 8px 4px;
        font-size: 0.75rem;
    }

    .calendar-appointment-chip {
        padding: 2px 4px;
        font-size: 0.7rem;
    }
}

/* ---------------------------------------------------------------------------
   Comunicaciones — bandeja del paciente + campana flotante + badges.
   (Feature "comunicaciones", fase 1.)
   --------------------------------------------------------------------------- */

/* Campana flotante, justo encima del botón de WhatsApp. */
.comm-bell-float {
    position: fixed;
    right: 24px;
    bottom: 92px;
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-primary);
    color: #fff;
    border-radius: 50%;
    box-shadow: var(--shadow-lift);
    z-index: 1000;
    transition: transform 0.15s ease;
}

.comm-bell-float:hover {
    transform: translateY(-2px);
}

.comm-bell-count {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    border-radius: 10px;
    background: var(--color-danger, #c0392b);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
}

@media (max-width: 480px) {
    .comm-bell-float {
        right: 16px;
        bottom: 128px;
        width: 46px;
        height: 46px;
    }
}

/* Contador junto al ítem "Comunicaciones" de la barra superior. */
.topbar-comms-count,
.dashboard-card-badge {
    display: inline-block;
    min-width: 18px;
    padding: 0 5px;
    margin-left: 6px;
    border-radius: 9px;
    background: var(--color-danger, #c0392b);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    vertical-align: middle;
}

/* Lista de la bandeja. */
.comm-list {
    list-style: none;
    padding: 0;
    margin: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.comm-item + .comm-item {
    border-top: 1px solid var(--color-border);
}

.comm-item-link {
    display: grid;
    grid-template-columns: auto auto 1fr auto;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    text-decoration: none;
    color: inherit;
}

.comm-item-link:hover {
    background: var(--color-lilac, #f2f5f7);
}

.comm-item--unread .comm-item-link {
    font-weight: 600;
}

.comm-item-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-primary);
}

.comm-item--unread .comm-item-type,
.comm-item .comm-item-type {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-primary);
}

.comm-item-date {
    font-size: 0.82rem;
    color: var(--color-muted, #5b6b76);
    white-space: nowrap;
}

/* Detalle de una comunicación. */
.comm-detail-meta {
    font-size: 0.85rem;
    color: var(--color-muted, #5b6b76);
    margin-top: -4px;
}

.comm-detail-body {
    white-space: pre-wrap;
    margin-top: 12px;
}

.comm-detail-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 16px;
}

/* Selector de fichas de ejercicios — en "Añadir consulta" y en el panel
   independiente "Enviar ejercicios" (exercise-picker.js, uno o más por
   página). */
.exercise-picker legend {
    font-weight: 600;
}

.exercise-picker-combo {
    position: relative;
}

.exercise-picker-combo .exercise-search {
    width: 100%;
}

.exercise-options {
    position: absolute;
    z-index: 5;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 220px;
    overflow-y: auto;
    margin: 0;
    padding: 4px 0;
    list-style: none;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(22, 35, 46, 0.12);
}

.exercise-options li {
    padding: 8px 12px;
    cursor: pointer;
    font-size: 0.9rem;
}

.exercise-options li:hover {
    background: var(--color-surface-alt, #eef3f5);
}

.exercise-picker-empty {
    color: var(--color-text-muted);
}

.exercise-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}

.exercise-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 14px;
    background: var(--color-surface-alt, #eef3f5);
    font-size: 0.85rem;
}

.exercise-chip-remove {
    border: none;
    background: transparent;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0 2px;
    color: var(--color-muted, #5b6b76);
}

/* "Botones desplegables" (field-disclosure.js): compact fields for
   "Añadir consulta" (zona tratada, técnicas, escalas de dolor, número de
   sesión) and the diagnóstico picker — a plain-button-looking <summary>
   collapsed by default, showing the field's current value once picked;
   opens into the real control on click. Native <details>/<summary> does
   the open/close; ui-behaviors.js's auto-close-on-mouse-leave already
   skips any <details> holding a form field, so these stay open until the
   user closes them — same as every other fillable panel on the site. */
.field-disclosure-group {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-start;
    margin-bottom: 12px;
}
.field-disclosure {
    position: relative;
    /* Sizes to its own content instead of stretching full-width — <details>
       is block-level by default. Harmless inside .field-disclosure-group:
       a flex item's own display is irrelevant to how the flex box sizes
       it, this only matters for one sitting on its own (e.g. "Enviar
       ejercicios", not part of any group). */
    display: inline-block;
}
.field-disclosure > summary {
    cursor: pointer;
    list-style: none;
    padding: 8px 16px;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-mauve);
    color: white;
    font-weight: 600;
    font-size: 0.85rem;
    white-space: nowrap;
    transition: background 0.15s ease;
}
.field-disclosure > summary::-webkit-details-marker {
    display: none;
}
.field-disclosure > summary:hover {
    background: var(--color-mauve-dark);
}

/* "Ver detalle" in Historial de consultas (2026-09-14, "en el verde que
   usamos así el usuario identifica que se pueden clicar") — a plain
   native <details> with the browser's default gray/black marker gave no
   hint it was clickable, unlike every other disclosure on the ficha. */
.consultation-detail > summary {
    color: var(--color-mauve);
    cursor: pointer;
    font-weight: 600;
    list-style: none;
}
.consultation-detail > summary::-webkit-details-marker {
    display: none;
}
.consultation-detail > summary::before {
    content: "\25b8";
    display: inline-block;
    margin-right: 4px;
    color: var(--color-mauve);
    transition: transform 0.15s ease;
}
.consultation-detail[open] > summary::before {
    transform: rotate(90deg);
}
/* Same white as the label (dark text on the button didn't reach the 4.5:1
   contrast); the bold weight is what sets the picked value apart. */
.field-disclosure-value {
    color: inherit;
    font-weight: 700;
}
.field-disclosure[open] > summary {
    border-radius: var(--radius-pill) var(--radius-pill) 0 0;
}
.field-disclosure-body {
    position: absolute;
    z-index: 5;
    top: calc(100% - 1px);
    left: 0;
    min-width: 260px;
    padding: 12px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 0 8px 8px 8px;
    box-shadow: 0 4px 12px rgba(22, 35, 46, 0.12);
}
.field-disclosure-body input[type="number"] {
    width: 100%;
}

/* A plain pick-from-a-list inside a field-disclosure (escalas de dolor,
   número de sesión) — field-disclosure.js wires the clicks. */
.option-list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 200px;
    overflow-y: auto;
    min-width: 100px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
}
.option-list li {
    padding: 8px 12px;
    cursor: pointer;
    font-size: 0.9rem;
}
.option-list li:hover {
    background: var(--color-surface-alt, #eef3f5);
}
.option-list li.is-selected {
    background: var(--color-lilac);
    font-weight: 600;
}

/* Zona tratada / Técnicas aplicadas: plain checkboxes in an .option-list,
   no search box — every option is short enough to just scan the list. */
.option-list--multi {
    max-height: 260px;
}
.option-list--multi li {
    cursor: default;
    padding: 4px 12px;
}
.option-list--multi .checkbox-label {
    margin: 0;
    width: 100%;
}
.option-list--multi li:has(input:checked) {
    background: var(--color-lilac);
    font-weight: 600;
}

/* Selector genérico de un Set<Enum> con th:field (zona tratada, técnicas
   aplicadas…) — checkbox-picker.js. Mismo look que el de ejercicios de
   arriba, generalizado en vez de duplicado por campo. */
.checkbox-picker {
    position: relative;
    margin-bottom: 12px;
}

.checkbox-picker .picker-search {
    width: 100%;
}

.picker-options {
    position: absolute;
    z-index: 5;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 220px;
    overflow-y: auto;
    margin: 0;
    padding: 4px 0;
    list-style: none;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(22, 35, 46, 0.12);
}

.picker-options li {
    padding: 8px 12px;
    cursor: pointer;
    font-size: 0.9rem;
}

.picker-options li:hover {
    background: var(--color-surface-alt, #eef3f5);
}

.picker-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}

.picker-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 14px;
    background: var(--color-surface-alt, #eef3f5);
    font-size: 0.85rem;
}

.picker-chip-remove {
    border: none;
    background: transparent;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0 2px;
    color: var(--color-muted, #5b6b76);
}

.form-inline-link {
    display: inline-block;
    margin-top: 4px;
    font-size: 0.85rem;
}

/* Day-view agenda timeline (fragments/calendar-month.html :: dayTimeline):
   the open day split into :00 / :30 blocks, free ones bookable. */
.day-timeline {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    overflow: hidden;
}

.day-slot {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 6px 10px;
    border-top: 1px solid var(--color-border);
    min-height: 34px;
}

.day-slot:first-child {
    border-top: none;
}

.day-slot--hour {
    border-top-color: var(--color-text-muted);
}

.day-slot-time {
    flex: 0 0 44px;
    font-variant-numeric: tabular-nums;
    font-size: 0.85rem;
    color: var(--color-text-muted);
    padding-top: 2px;
}

.day-slot--hour .day-slot-time {
    font-weight: 600;
    color: inherit;
}

.day-slot-body {
    flex: 1 1 auto;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

.day-slot--free {
    background: color-mix(in srgb, var(--color-primary) 6%, transparent);
}

.day-slot-free {
    font-size: 0.85rem;
    color: var(--color-primary);
    text-decoration: none;
}

.day-slot-free:hover {
    text-decoration: underline;
}

.day-slot-cont {
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

/* Arrastrar-y-soltar para mover una cita (vista de día, solo panel admin —
   ver calendar-drag-reschedule.js). */
.day-timeline--drag-enabled .calendar-appointment-chip[draggable="true"] {
    cursor: grab;
}

.day-timeline--drag-enabled .calendar-appointment-chip[draggable="true"]:active {
    cursor: grabbing;
}

.day-slot--drag-over {
    background: color-mix(in srgb, var(--color-primary) 18%, transparent);
    outline: 2px dashed var(--color-primary);
    outline-offset: -2px;
}

/* --- Staff agenda: week / work-week time grid (agenda redesign 2026-09-08) ---
   Layout the clinic's incumbent scheduler uses: day columns, 30-minute rows,
   each appointment a block placed by start time and sized by duration.
   All geometry rides on utility classes (s-N top, h-N height, lXofY lane) so
   the CSP can stay style-src 'self' — no inline styles. */

.agenda-week {
    --agenda-row-h: 40px;
    --agenda-cols: 5;
    --agenda-gutter: 52px;
    overflow-x: auto;
    margin-top: 8px;
}

.agenda-week--cols-7 {
    --agenda-cols: 7;
}

.agenda-week-head,
.agenda-week-body {
    display: grid;
    grid-template-columns: var(--agenda-gutter) repeat(var(--agenda-cols), minmax(120px, 1fr));
    min-width: 620px;
}

.agenda-week-dayname {
    padding: 6px 4px;
    text-align: center;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--color-mauve-dark);
    text-transform: capitalize;
    border-bottom: 2px solid var(--color-border);
    border-left: 1px solid var(--color-border);
}

.agenda-week-dayname.is-today {
    background: var(--color-lilac);
}

.agenda-times {
    display: grid;
    grid-auto-rows: var(--agenda-row-h);
}

.agenda-time {
    font-size: 0.68rem;
    color: var(--color-text-muted);
    text-align: right;
    padding-right: 6px;
    transform: translateY(-0.55em);
}

.agenda-day {
    position: relative;
    min-height: calc(24 * var(--agenda-row-h));
    border-left: 1px solid var(--color-border);
    background-image: repeating-linear-gradient(
        to bottom,
        var(--color-border) 0,
        var(--color-border) 1px,
        transparent 1px,
        transparent var(--agenda-row-h));
}

.agenda-day.is-today {
    background-color: color-mix(in srgb, var(--color-lilac) 45%, transparent);
}

.agenda-day-gap {
    position: absolute;
    left: 0;
    right: 0;
    background: repeating-linear-gradient(
        45deg,
        rgba(0, 0, 0, 0.04) 0,
        rgba(0, 0, 0, 0.04) 6px,
        rgba(0, 0, 0, 0.07) 6px,
        rgba(0, 0, 0, 0.07) 12px);
    z-index: 0;
}

.agenda-block {
    position: absolute;
    z-index: 1;
    overflow: hidden;
    box-sizing: border-box;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    /* Left accent + tint come from the patient's principal pathology
       (.zone-xxx sets --patho / --patho-bg); neutral when there is none. */
    border-left: 4px solid var(--patho, var(--color-mauve));
    background: var(--patho-bg, var(--color-surface));
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    padding: 2px 6px;
    font-size: 0.68rem;
    line-height: 1.2;
    color: var(--color-text);
    display: flex;
    flex-direction: column;
}

/* Zone colours — one fixed colour per body zone (BodyZone), the same legend as MN. */
.agenda-block.zone-cervical    { --patho: hsl(205 55% 48%); --patho-bg: hsl(205 66% 96%); }
.agenda-block.zone-dorsal      { --patho: hsl(265 45% 56%); --patho-bg: hsl(265 55% 96%); }
.agenda-block.zone-lumbar      { --patho: hsl(22 72% 50%);  --patho-bg: hsl(22 82% 95%); }
.agenda-block.zone-hombro      { --patho: hsl(350 60% 54%); --patho-bg: hsl(350 74% 96%); }
.agenda-block.zone-codo        { --patho: hsl(45 75% 44%);  --patho-bg: hsl(45 80% 94%); }
.agenda-block.zone-mano        { --patho: hsl(320 45% 52%); --patho-bg: hsl(320 55% 96%); }
.agenda-block.zone-cadera      { --patho: hsl(158 46% 40%); --patho-bg: hsl(158 45% 95%); }
.agenda-block.zone-rodilla     { --patho: hsl(95 42% 40%);  --patho-bg: hsl(95 45% 95%); }
.agenda-block.zone-tobillo-pie { --patho: hsl(178 40% 40%); --patho-bg: hsl(178 42% 94%); }
.agenda-block.zone-general     { --patho: hsl(228 20% 55%); --patho-bg: hsl(228 25% 96%); }

/* Legend of the zone colours, above the week grid. */
.agenda-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin: 0 0 6px;
    padding: 0;
    list-style: none;
    font-size: 0.72rem;
    color: var(--color-text-muted);
}

.agenda-legend li {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.agenda-legend .swatch {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    border-left: 4px solid var(--patho);
    background: var(--patho-bg);
}

.agenda-legend .swatch.zone-cervical    { --patho: hsl(205 55% 48%); --patho-bg: hsl(205 66% 96%); }
.agenda-legend .swatch.zone-dorsal      { --patho: hsl(265 45% 56%); --patho-bg: hsl(265 55% 96%); }
.agenda-legend .swatch.zone-lumbar      { --patho: hsl(22 72% 50%);  --patho-bg: hsl(22 82% 95%); }
.agenda-legend .swatch.zone-hombro      { --patho: hsl(350 60% 54%); --patho-bg: hsl(350 74% 96%); }
.agenda-legend .swatch.zone-codo        { --patho: hsl(45 75% 44%);  --patho-bg: hsl(45 80% 94%); }
.agenda-legend .swatch.zone-mano        { --patho: hsl(320 45% 52%); --patho-bg: hsl(320 55% 96%); }
.agenda-legend .swatch.zone-cadera      { --patho: hsl(158 46% 40%); --patho-bg: hsl(158 45% 95%); }
.agenda-legend .swatch.zone-rodilla     { --patho: hsl(95 42% 40%);  --patho-bg: hsl(95 45% 95%); }
.agenda-legend .swatch.zone-tobillo-pie { --patho: hsl(178 40% 40%); --patho-bg: hsl(178 42% 94%); }
.agenda-legend .swatch.zone-general     { --patho: hsl(228 20% 55%); --patho-bg: hsl(228 25% 96%); }

.agenda-block-tags {
    display: flex;
    gap: 4px;
    font-size: 0.6rem;
    color: var(--color-text-muted);
    white-space: nowrap;
    overflow: hidden;
}

.agenda-block-patho,
.agenda-block-service {
    overflow: hidden;
    text-overflow: ellipsis;
}

.agenda-block-patho {
    font-weight: 600;
    color: var(--patho, var(--color-text-muted));
    flex-shrink: 1;
    min-width: 0;
    max-width: none;   /* un % aquí se calculaba sobre un contenedor que se ajusta al contenido y la dejaba en «Ho…» */
}

.agenda-block-tags { max-width: 100%; }

.agenda-block-patho + .agenda-block-service::before {
    content: "· ";
}

/* Status-icon strip (agenda redesign slice 3). */
.agenda-block-flags {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 3px;
    margin-top: 1px;
    overflow: hidden;
}

.agenda-block-flags:empty {
    display: none;
}

.agenda-flag {
    font-size: 0.58rem;
    line-height: 1.3;
    font-weight: 700;
    white-space: nowrap;
}

.agenda-flag-session {
    border-radius: 999px;
    padding: 0 5px;
    background: var(--color-lilac);
    color: var(--color-mauve-dark);
}

/* Attendance/cancel marker, inline in front of the patient name. */
.agenda-status {
    font-size: 0.8rem;
    line-height: 1;
    margin-right: 2px;
}

.agenda-status:empty {
    display: none;
}

.agenda-status .ok { color: #2e7d32; }
.agenda-status .bad { color: var(--color-error-text, #b3261e); }
.agenda-status .muted { color: var(--color-text-muted); }

.agenda-flag-lopd {
    border-radius: 3px;
    padding: 0 4px;
    background: color-mix(in srgb, #2e7d32 12%, transparent);
    color: #2e7d32;
}

.agenda-flag-consent {
    border-radius: 3px;
    padding: 0 4px;
    background: color-mix(in srgb, #1565c0 12%, transparent);
    color: #1565c0;
}

.agenda-flag-warn {
    color: #b3261e;
    font-size: 0.72rem;
}

.agenda-flag-icon {
    display: inline-flex;
    align-items: center;
    color: var(--color-mauve-dark);
    cursor: help;
}

.agenda-flag-icon .icon {
    width: 0.85rem;
    height: 0.85rem;
}

.agenda-flag-pay {
    color: #b3261e;
    font-size: 0.68rem;
}

/* 30-minute blocks (SEGURO sessions): shrink to fit, drop the least-critical bits. */
.agenda-block.h-1 {
    padding: 1px 5px;
    font-size: 0.6rem;
    line-height: 1.12;
}

.agenda-block.h-1 .agenda-block-time { font-size: 0.56rem; }
.agenda-block.h-1 .agenda-block-who { font-size: 0.64rem; }
.agenda-block.h-1 .agenda-block-flags { font-size: 0.52rem; }
.agenda-block.h-1 .agenda-status { font-size: 0.66rem; }
/* No room in a 30-min block for the pathology/service/insurer lines or the
   pro name — they come back on hover (see the peek rule below). */
.agenda-block.h-1 .agenda-block-tags,
.agenda-block.h-1 .agenda-block-insurer,
.agenda-block.h-1 .agenda-block-prof { display: none; }

/* Non-scheduled outcomes read as done/void. */
.agenda-block.is-cancelada_a_tiempo,
.agenda-block.is-anulada_staff,
.agenda-block.is-movida_staff {
    opacity: 0.55;
}

.agenda-block.is-cancelada_a_tiempo .agenda-block-who,
.agenda-block.is-anulada_staff .agenda-block-who {
    text-decoration: line-through;
}

.agenda-block.is-openable {
    cursor: pointer;
}

.agenda-block.is-openable:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.16);
}

.agenda-block-head {
    display: flex;
    align-items: center;
    gap: 3px;
}

.agenda-block-time {
    font-size: 0.64rem;
    font-weight: 600;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.agenda-block-who {
    font-weight: 700;
    font-size: 0.72rem;
    color: var(--color-mauve-dark);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.agenda-block-prof,
.agenda-block-insurer {
    font-size: 0.62rem;
    color: var(--color-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.agenda-block-insurer {
    display: block;
    font-style: italic;
}

/* Peek: un clic en la cita la despliega (antes, al pasar el ratón: tapaba la cita de debajo sin querer); doble clic abre la ficha. Expande so nothing stays clipped (esp. the
   30-min SEGURO blocks — pathology, insurer and service all become visible). */
.agenda-day > .agenda-block.is-expanded {
    height: auto;
    min-height: calc(var(--agenda-row-h) * 2);
    overflow: visible;
    z-index: 25;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.22);
}

.agenda-block.h-1.is-expanded {
    font-size: 0.66rem;
    line-height: 1.25;
    padding: 3px 6px;
}

.agenda-block.h-1.is-expanded .agenda-block-time { font-size: 0.62rem; }
.agenda-block.h-1.is-expanded .agenda-block-who { font-size: 0.72rem; }
.agenda-block.h-1.is-expanded .agenda-block-tags { display: flex; }
.agenda-block.h-1.is-expanded .agenda-block-insurer,
.agenda-block.h-1.is-expanded .agenda-block-prof { display: block; }

.agenda-block-cancel {
    position: absolute;
    top: 1px;
    right: 3px;
    line-height: 1;
}

/* --- Slice 4: click an empty slot / an existing block to act on it --- */

/* Empty-slot layer (staff agenda only): one transparent <a> per 30-min row,
   full column width, sitting under the blocks (.agenda-block is z-index 1),
   so only free time reaches it. Click -> prefilled "Nueva cita" panel. */
.agenda-slot {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    text-decoration: none;
}
.agenda-slot:hover,
.agenda-slot:focus-visible {
    background: color-mix(in srgb, var(--color-mauve) 12%, transparent);
    outline: 1px dashed var(--color-mauve);
    outline-offset: -3px;
}
.agenda-slot-plus {
    font-size: 1rem;
    font-weight: 700;
    color: transparent;
}
.agenda-slot:hover .agenda-slot-plus,
.agenda-slot:focus-visible .agenda-slot-plus {
    color: var(--color-mauve);
}

/* Click-to-manage menu on an existing block. Native <details> (name=... so
   only one opens at a time) — stays open while you use it, unlike the
   hover-peek. The ⋮ sits just left of the × quick-cancel. */
.agenda-block-menu {
    position: absolute;
    top: 0;
    right: 15px;
    z-index: 3;
}
.agenda-block-menu > summary {
    list-style: none;
    cursor: pointer;
    font-size: 0.82rem;
    line-height: 1;
    padding: 1px 3px;
    color: var(--color-text-muted);
}
.agenda-block-menu > summary::-webkit-details-marker { display: none; }
.agenda-block-menu[open] > summary { color: var(--color-mauve); }
.agenda-block-menu-panel {
    position: absolute;
    top: calc(100% + 3px);
    right: 0;
    width: 210px;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 8px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
    font-size: 0.72rem;
    line-height: 1.3;
    text-align: left;
    white-space: normal;
}
/* Let the panel escape the (normally clipped) block while the menu is open. */
.agenda-block:has(> .agenda-block-menu[open]) {
    overflow: visible;
    z-index: 30;
}
.agenda-menu-form {
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.agenda-menu-form > label {
    font-weight: 600;
}
.agenda-menu-form input {
    font: inherit;
    font-size: 0.72rem;
    height: 28px;
    padding: 0 6px;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    box-sizing: border-box;
}
.agenda-menu-action {
    display: block;
    box-sizing: border-box;
    width: 100%;
    height: 30px;
    line-height: 28px;
    padding: 0 8px;
    border: 1px solid var(--color-border);
    border-radius: 5px;
    background: var(--color-bg);
    color: var(--color-text);
    font: inherit;
    font-size: 0.72rem;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}
.agenda-menu-action:hover {
    background: var(--color-lilac);
}
.agenda-menu-action--privada {
    border-color: var(--color-mauve);
    color: var(--color-mauve);
    font-weight: 600;
}
.agenda-menu-action--danger {
    color: var(--color-error-text);
}

/* --- Mini month calendars beside the agenda (scrolling months, left side) --- */

.agenda-layout--with-side {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}
.agenda-layout-main {
    flex: 1 1 auto;
    min-width: 0;
}

/* Side calendars on the LEFT of the grid, like the usual calendar apps (Trello #174, bloque D). */
.agenda-layout--with-side > .agenda-side {
    order: -1;
}

.agenda-side {
    flex: 0 0 236px;
    width: 236px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    box-sizing: border-box;
    overflow: hidden;
}
.agenda-side.is-collapsed {
    flex-basis: 40px;
    width: 40px;
}
.agenda-side-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg);
}
.agenda-side-title {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--color-mauve-dark);
    white-space: nowrap;
}
.agenda-side.is-collapsed .agenda-side-title {
    display: none;
}
.agenda-side-toggle {
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 2px 6px;
    font-size: 1rem;
    line-height: 1;
    color: var(--color-mauve-dark);
}
.agenda-side.is-collapsed .agenda-side-toggle-icon {
    display: inline-block;
    transform: rotate(180deg);
}
.agenda-side.is-collapsed .agenda-side-body {
    display: none;
}
.agenda-side-body {
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.mini-month-label {
    font-size: 0.78rem;
    font-weight: 700;
    text-align: center;
    margin-bottom: 4px;
    color: var(--color-text);
}
.mini-month-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
}
.mini-month-wd {
    font-size: 0.62rem;
    font-weight: 700;
    text-align: center;
    color: var(--color-text-muted);
    padding-bottom: 2px;
}
.mini-month-day {
    font-size: 0.68rem;
    text-align: center;
    padding: 3px 0;
    border-radius: 4px;
    color: var(--color-text);
}
/* Muted grey without the old 50% opacity (1.98:1, unreadable): still
   lighter than the month's own days, which use the body text colour. */
.mini-month-day.is-outside {
    color: var(--color-text-muted);
    font-weight: 400;
}
.mini-month-day.is-weekend {
    color: var(--color-mauve-dark);
}
.mini-month-day.is-holiday {
    background: var(--color-error-bg);
    color: var(--color-error-text);
    font-weight: 700;
}
.mini-month-day.is-today {
    outline: 2px solid var(--color-mauve);
    outline-offset: -2px;
    font-weight: 700;
}
/* Side calendars: month/year jumps, scrolling months, clickable days (Trello #174, bloque A). */
.mini-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}

.mini-nav-btn,
.mini-nav-today {
    color: var(--color-mauve-dark);
    text-decoration: none;
    font-weight: 700;
    font-size: 0.85rem;
    border-radius: 6px;
    padding: 2px 7px;
}

.mini-nav-today {
    flex: 1;
    text-align: center;
    font-size: 0.78rem;
}

.mini-nav-btn:hover,
.mini-nav-today:hover {
    background: var(--color-lilac);
}

.mini-months-scroll {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-height: 64vh;
    overflow-y: auto;
    padding-right: 4px;
}

.mini-month-label a {
    color: inherit;
    text-decoration: none;
}

.mini-month-label a:hover {
    text-decoration: underline;
}

a.mini-month-day {
    color: inherit;
    text-decoration: none;
}

a.mini-month-day:hover {
    background: var(--color-lilac);
    border-radius: 4px;
}

.mini-month-legend {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 2px 0 0;
    font-size: 0.66rem;
    color: var(--color-text-muted);
}
.mini-month-legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--color-error-bg);
    border: 1px solid var(--color-error-text);
    flex-shrink: 0;
}

/* Narrow screens: the mini calendars drop below the agenda instead of
   squeezing it. */
@media (max-width: 1080px) {
    .agenda-layout--with-side {
        flex-direction: column;
    }
    .agenda-side,
    .agenda-side.is-collapsed {
        flex-basis: auto;
        width: 100%;
    }
    .agenda-layout--with-side > .agenda-side {
        order: 0;
    }
    .agenda-side-body {
        flex-direction: row;
        flex-wrap: wrap;
    }
    .mini-month {
        flex: 1 1 180px;
    }
}

/* Ficha de paciente: contact data on the left, "Datos de seguro" on the
   right — that side of the page used to sit empty under a full-width
   contact panel. Each .card-panel keeps its own border/background, so
   this is a plain gap grid, not a bordered sidebar like .agenda-side.
   Deliberately NOT align-items:start (2026-09-14, "estos espacios
   desalineados no son aceptables"): the default stretch makes both
   columns the same height, so the two white .card-panel boxes end at
   the same line instead of leaving a jagged edge whichever side has
   less content — record-top-main/side are flex columns with a single
   .card-panel child that grows to fill (see .record-top-main
   .card-panel, .record-top-side .card-panel below). */
.record-top-layout {
    display: grid;
    /* 1.45fr: lo justo para que la barra de acciones de la ficha (con «Menor» y el icono de imágenes) quepa en una
       sola línea de más a ancho que antes (era 1.3fr). */
    grid-template-columns: 1.45fr 1fr;
    gap: 20px;
}
.record-top-main,
.record-top-side {
    display: flex;
    flex-direction: column;
    /* No gap: each .card-panel already carries its own margin-top, same
       spacing it uses everywhere else on the page. */
}
.record-top-main .card-panel:last-child,
.record-top-side .card-panel {
    flex: 1;
}
@media (max-width: 900px) {
    .record-top-layout {
        grid-template-columns: 1fr;
    }
}

/* Vertical geometry: s-N = top (row index 0..23), h-N = height in rows.
   Applied to both .agenda-block and .agenda-day-gap. */
.agenda-day > .s-0 { top: 0; }
.agenda-day > .s-1 { top: calc(1 * var(--agenda-row-h)); }
.agenda-day > .s-2 { top: calc(2 * var(--agenda-row-h)); }
.agenda-day > .s-3 { top: calc(3 * var(--agenda-row-h)); }
.agenda-day > .s-4 { top: calc(4 * var(--agenda-row-h)); }
.agenda-day > .s-5 { top: calc(5 * var(--agenda-row-h)); }
.agenda-day > .s-6 { top: calc(6 * var(--agenda-row-h)); }
.agenda-day > .s-7 { top: calc(7 * var(--agenda-row-h)); }
.agenda-day > .s-8 { top: calc(8 * var(--agenda-row-h)); }
.agenda-day > .s-9 { top: calc(9 * var(--agenda-row-h)); }
.agenda-day > .s-10 { top: calc(10 * var(--agenda-row-h)); }
.agenda-day > .s-11 { top: calc(11 * var(--agenda-row-h)); }
.agenda-day > .s-12 { top: calc(12 * var(--agenda-row-h)); }
.agenda-day > .s-13 { top: calc(13 * var(--agenda-row-h)); }
.agenda-day > .s-14 { top: calc(14 * var(--agenda-row-h)); }
.agenda-day > .s-15 { top: calc(15 * var(--agenda-row-h)); }
.agenda-day > .s-16 { top: calc(16 * var(--agenda-row-h)); }
.agenda-day > .s-17 { top: calc(17 * var(--agenda-row-h)); }
.agenda-day > .s-18 { top: calc(18 * var(--agenda-row-h)); }
.agenda-day > .s-19 { top: calc(19 * var(--agenda-row-h)); }
.agenda-day > .s-20 { top: calc(20 * var(--agenda-row-h)); }
.agenda-day > .s-21 { top: calc(21 * var(--agenda-row-h)); }
.agenda-day > .s-22 { top: calc(22 * var(--agenda-row-h)); }
.agenda-day > .s-23 { top: calc(23 * var(--agenda-row-h)); }

.agenda-day > .h-1 { height: calc(1 * var(--agenda-row-h)); }
.agenda-day > .h-2 { height: calc(2 * var(--agenda-row-h)); }
.agenda-day > .h-3 { height: calc(3 * var(--agenda-row-h)); }
.agenda-day > .h-4 { height: calc(4 * var(--agenda-row-h)); }
.agenda-day > .h-5 { height: calc(5 * var(--agenda-row-h)); }
.agenda-day > .h-6 { height: calc(6 * var(--agenda-row-h)); }
.agenda-day > .h-7 { height: calc(7 * var(--agenda-row-h)); }
.agenda-day > .h-8 { height: calc(8 * var(--agenda-row-h)); }

/* Horizontal geometry: lXofY = lane X of Y side-by-side lanes. */
.agenda-block.l1of1 { left: 1px; width: calc(100% - 3px); }

.agenda-block.l1of2 { left: 1px;              width: calc(50% - 2px); }
.agenda-block.l2of2 { left: calc(50% + 1px);  width: calc(50% - 2px); }

.agenda-block.l1of3 { left: 1px;                 width: calc(33.333% - 2px); }
.agenda-block.l2of3 { left: calc(33.333% + 1px); width: calc(33.333% - 2px); }
.agenda-block.l3of3 { left: calc(66.666% + 1px); width: calc(33.333% - 2px); }

.agenda-block.l1of4 { left: 1px;              width: calc(25% - 2px); }
.agenda-block.l2of4 { left: calc(25% + 1px);  width: calc(25% - 2px); }
.agenda-block.l3of4 { left: calc(50% + 1px);  width: calc(25% - 2px); }
.agenda-block.l4of4 { left: calc(75% + 1px);  width: calc(25% - 2px); }

.agenda-block.l1of5 { left: 1px;             width: calc(20% - 2px); }
.agenda-block.l2of5 { left: calc(20% + 1px); width: calc(20% - 2px); }
.agenda-block.l3of5 { left: calc(40% + 1px); width: calc(20% - 2px); }
.agenda-block.l4of5 { left: calc(60% + 1px); width: calc(20% - 2px); }
.agenda-block.l5of5 { left: calc(80% + 1px); width: calc(20% - 2px); }

.agenda-block.l1of6 { left: 1px;                 width: calc(16.666% - 2px); }
.agenda-block.l2of6 { left: calc(16.666% + 1px); width: calc(16.666% - 2px); }
.agenda-block.l3of6 { left: calc(33.333% + 1px); width: calc(16.666% - 2px); }
.agenda-block.l4of6 { left: calc(50% + 1px);     width: calc(16.666% - 2px); }
.agenda-block.l5of6 { left: calc(66.666% + 1px); width: calc(16.666% - 2px); }
.agenda-block.l6of6 { left: calc(83.333% + 1px); width: calc(16.666% - 2px); }

/* Galería de fotos/imágenes clínicas de seguimiento (patient-record-detail.html) —
   evidencia real del export de MN program: pacientes con fotos/ecografías
   fechadas para comparar evolución de una lesión. */
.clinical-photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 14px;
}

.clinical-photo-item { text-align: center; }

.clinical-photo-item img {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    display: block;
}

.clinical-photo-item .clinical-photo-date {
    display: block;
    margin-top: 4px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* Visor modal de documentos (patient-record-detail.html, document-viewer.js) —
   abre un PDF/documento en un <iframe> dentro de la propia página en vez de
   navegar a él, para no depender de cómo cada extensión del navegador (p.
   ej. Adobe Acrobat) intercepte una navegación directa a un PDF. Native
   <dialog>: centrado/backdrop/foco los da el navegador gratis. */
dialog.document-viewer-modal {
    width: min(900px, 92vw);
    height: min(85vh, 900px);
    padding: 0;
    border: none;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
}

dialog.document-viewer-modal::backdrop {
    background: rgba(0, 0, 0, 0.5);
}

.document-viewer-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border);
}

.document-viewer-modal-header span {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.document-viewer-modal-close {
    cursor: pointer;
    border: none;
    background: none;
    flex-shrink: 0;
    font-size: 1.4rem;
    line-height: 1;
    color: var(--color-text-muted);
    padding: 2px 8px;
}

.document-viewer-modal-close:hover {
    color: var(--color-dark);
}

#document-viewer-frame {
    display: block;
    width: 100%;
    height: calc(100% - 45px);
    border: none;
}

/* Shown instead of #document-viewer-frame for a file type the browser has
   no native renderer for (Word, mainly) — see document-viewer.js. */
.document-viewer-fallback {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    height: calc(100% - 45px);
    padding: 24px;
    text-align: center;
    color: var(--color-text-muted);
}

/* El atributo hidden lo pone document-viewer.js, pero los display de arriba le ganaban: salían a la vez el PDF y el aviso de
   «no se puede previsualizar» (16/10/2026). */
#document-viewer-frame[hidden],
.document-viewer-fallback[hidden] { display: none; }

/* ── Alertas de contraindicaciones e IA clínica (docs/plan-ia-clinica.md) ── */
.clinical-alert-list {
    list-style: none;
    margin: 0 0 12px;
    padding: 0;
    display: grid;
    gap: 10px;
}
.clinical-alert-list > li {
    border: 1px solid var(--color-border);
    border-left-width: 6px;
    border-radius: 10px;
    padding: 10px 14px;
    background: var(--color-surface);
}
.clinical-alert--contraindicada { border-left-color: #c0392b; background: #fdf0ee; }
.clinical-alert--precaucion { border-left-color: #d68910; background: #fef8ec; }
.clinical-alert--indicada { border-left-color: #2f6b3e; background: var(--color-success-bg); }
.clinical-alert-list--dismissed > li { border-left-color: var(--color-border); color: var(--color-text-muted); }
.clinical-alert-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.clinical-alert-level { font-size: 0.85rem; color: var(--color-text-muted); }
.clinical-alert-techniques { margin: 4px 0; }
.clinical-alert-reviewed { font-size: 0.85rem; color: var(--color-success-text); font-weight: 600; }
.clinical-alert-actions { margin-top: 6px; display: flex; gap: 8px; }
.clinical-alert-footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
.badge-ia {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 8px;
    border-radius: var(--radius-pill);
    background: var(--color-lilac);
    color: var(--color-mauve-dark);
    font-size: 0.75rem;
    font-weight: 700;
    vertical-align: middle;
}
.technique-warning { margin-left: 2px; }
.pre-line { white-space: pre-line; }
.ia-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.ia-suggestion {
    border-top: 1px solid var(--color-border);
    margin-top: 14px;
    padding-top: 10px;
}
.ia-review-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; }
.ia-review-form fieldset { flex-basis: 100%; }
.send-row--problem td { background: #fef8ec; }
.legal-doc-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.legal-doc-list > li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.legal-doc--pendiente_envio, .legal-doc--enlace_caducado, .legal-doc--version_anterior { font-weight: 600; }
.ia-draft { width: 100%; font-family: inherit; }
.ia-codes { list-style: none; padding: 0; display: grid; gap: 6px; }
.ia-text { white-space: pre-line; }

/* Manual de uso (manual.html) */
.manual h2 { margin-top: 0; }
.manual-toc ol { columns: 2; column-gap: 32px; margin: 0; }
@media (max-width: 640px) { .manual-toc ol { columns: 1; } }
.manual-dl dt { font-weight: 600; margin-top: 10px; }
.manual-dl dd { margin: 2px 0 0 0; }
.manual-table { margin-bottom: 12px; }
.manual-state { display: inline-block; font-size: 0.75rem; font-weight: 600; padding: 2px 8px; border-radius: 999px;
    vertical-align: middle; }
.manual-state.is-on { background: #e3f4e8; color: #1d6b35; }
.manual-state.is-off { background: #f3eee2; color: #7a5a12; }

/* «Citas bloqueadas»: candado junto al nombre (fragments/booking-lock.html).
   Discreto a propósito: solo el icono, sin texto ni colores llamativos. */
.record-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0.67em 0 24px; }
/* Sin márgenes propios: el margen superior del navegador en el h1 lo bajaba
   respecto al candado y los dos quedaban desalineados (#160). */
.record-title h1 { margin: 0; }
.booking-lock { position: relative; display: inline-flex; align-items: center; align-self: center; line-height: 0; }
.booking-lock-icon { list-style: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; border-radius: 6px; color: var(--color-text-muted); opacity: 0.7; user-select: none; }
.booking-lock-icon .icon { width: var(--icon-md); height: var(--icon-md); display: block; }
.booking-lock-icon:hover { background: var(--color-lilac); }
.booking-lock-icon::-webkit-details-marker { display: none; }
.booking-lock-icon:hover, .booking-lock[open] .booking-lock-icon { opacity: 1; }
.booking-lock-panel { position: absolute; z-index: 20; top: 130%; left: 0; width: min(340px, 90vw); padding: 12px;
    background: var(--color-surface, #fff); border: 1px solid var(--color-border, #ddd); border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); }
.booking-lock-reason { white-space: pre-line; font-style: italic; }
.booking-confirm-row { margin: 4px 0 8px; }
.chat-widget-disclosure { margin: 0; padding: 6px 12px; font-size: 0.75rem; color: var(--color-text-muted); border-bottom: 1px solid var(--color-border); }

/* Guía de estilos (/ayuda/estilos, style-guide.html). Solo para el personal;
   usa las medidas comunes de :root. Las clases sg-bg-*, sg-fs-*… existen
   porque el CSP no permite estilos en línea. */
.style-guide section { margin-bottom: var(--space-6); }
.style-guide h3 { margin: var(--space-6) 0 var(--space-3); font-size: var(--text-md); }
.sg-toc { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); margin-bottom: var(--space-6); font-size: var(--text-sm); }
.sg-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.sg-row--end { align-items: flex-end; }
.sg-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-3); }
.sg-swatch { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-xs); }
.sg-swatch span { height: 48px; border: 1px solid var(--color-border); border-radius: var(--radius-sm); }
.sg-states { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-3); }
.sg-state { margin: 0; padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); font-size: var(--text-sm); font-weight: 600; }
.sg-type p { margin: 0 0 var(--space-3); line-height: 1.3; }
.sg-type code, .sg-state code { font-size: var(--text-xs); font-weight: 400; color: var(--color-text-muted); }
.sg-box { width: 180px; padding: var(--space-4); border: 2px solid var(--color-primary); background: var(--color-bg); font-size: var(--text-xs); text-align: center; }
.sg-spaces div { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); font-size: var(--text-xs); }
.sg-spaces span { display: inline-block; height: 16px; background: var(--color-primary); border-radius: 2px; }
.sg-height { display: flex; align-items: center; gap: var(--space-1); padding: 0 var(--space-4); border: 1px dashed var(--color-primary); border-radius: var(--radius-sm); font-size: var(--text-xs); }
.style-guide .success-banner, .style-guide .alert, .style-guide .form-error { margin-bottom: var(--space-2); }
.sg-bg-bg { background: var(--color-bg); }
.sg-bg-border { background: var(--color-border); }
.sg-bg-dark { background: var(--color-dark); }
.sg-bg-error-bg { background: var(--color-error-bg); color: var(--color-error-text); }
.sg-bg-info-bg { background: var(--color-info-bg); color: var(--color-info-text); }
.sg-bg-lilac { background: var(--color-lilac); }
.sg-bg-mint { background: var(--color-mint); }
.sg-bg-primary { background: var(--color-primary); }
.sg-bg-primary-dark { background: var(--color-primary-dark); }
.sg-bg-success-bg { background: var(--color-success-bg); color: var(--color-success-text); }
.sg-bg-surface { background: var(--color-surface); }
.sg-bg-t-muted { background: var(--color-text-muted); }
.sg-bg-text { background: var(--color-text); }
.sg-bg-warning-bg { background: var(--color-warning-bg); color: var(--color-warning-text); }
.sg-fs-text-2xl-display { font-size: var(--text-2xl); font-family: var(--font-display); }
.sg-fs-text-lg-display { font-size: var(--text-lg); font-family: var(--font-display); }
.sg-fs-text-md { font-size: var(--text-md); }
.sg-fs-text-sm { font-size: var(--text-sm); }
.sg-fs-text-xl-display { font-size: var(--text-xl); font-family: var(--font-display); }
.sg-fs-text-xs { font-size: var(--text-xs); }
.sg-h-control-lg { height: var(--control-lg); }
.sg-h-control-md { height: var(--control-md); }
.sg-h-control-sm { height: var(--control-sm); }
.sg-r-radius { border-radius: var(--radius); }
.sg-r-radius-pill { border-radius: var(--radius-pill); }
.sg-r-radius-sm { border-radius: var(--radius-sm); }
.sg-w-space-1 { width: var(--space-1); }
.sg-w-space-2 { width: var(--space-2); }
.sg-w-space-3 { width: var(--space-3); }
.sg-w-space-4 { width: var(--space-4); }
.sg-w-space-6 { width: var(--space-6); }
.sg-w-space-8 { width: var(--space-8); }

/* ══════════════════════════════════════════════════════════════════════
   Botón estándar (fase 2 del patrón del front, Trello #161).
   Un solo botón con variantes: .btn + --primary | --secondary | --ghost |
   --danger | --link, tamaños --sm / (estándar) / --lg y --icon (solo el
   icono). Siempre pill, sin el estilo por defecto del navegador. Lo nuevo
   usa estas clases; las antiguas (btn-action, btn-submit, panel-btn…) se
   ven igual gracias a los alias de abajo hasta que se migren las
   plantillas. Referencia visual: /ayuda/estilos.
   ══════════════════════════════════════════════════════════════════════ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    height: var(--control-md);
    padding: 0 var(--space-4);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-primary-dark);
    font-family: inherit;
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.btn svg { width: var(--icon-sm); height: var(--icon-sm); flex: none; }
.btn--sm { height: var(--control-sm); padding: 0 var(--space-3); font-size: var(--text-xs); }
.btn--lg { height: var(--control-lg); padding: 0 var(--space-6); font-size: var(--text-md); }
.btn--icon { width: var(--control-md); padding: 0; }
.btn--icon.btn--sm { width: var(--control-sm); }
.btn--icon svg { width: var(--icon-md); height: var(--icon-md); }

.btn--primary { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.btn--primary:hover { background: var(--color-primary-dark); border-color: var(--color-primary-dark); color: #fff; }
.btn--secondary { background: var(--color-surface); border-color: var(--color-border); }
.btn--secondary:hover { background: var(--color-lilac); }
.btn--ghost:hover { background: var(--color-lilac); }
.btn--danger { background: var(--color-surface); border-color: var(--color-error-text); color: var(--color-error-text); }
.btn--danger:hover { background: var(--color-error-text); color: #fff; }
.btn--link { height: auto; padding: 0; border: 0; text-decoration: underline; }
.btn--link:hover { color: var(--color-primary); }

.btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }

/* ── Alias: las clases antiguas con el aspecto del botón estándar ────────
   Solo tocan el aspecto (altura, relleno, letra, colores, esquinas); la
   colocación de cada una (márgenes, flex, anchos) sigue en su regla
   original. Las reglas más específicas de un contexto concreto (p. ej. el
   menú compacto de la agenda) siguen mandando. Al migrar una plantilla a
   .btn, su alias se puede borrar. */

/* Principal, tamaño estándar */
.btn-action,
.btn-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    height: var(--control-md);
    padding: 0 var(--space-4);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-pill);
    background: var(--color-primary);
    color: #fff;
    font-size: var(--text-sm);
    font-weight: 600;
    line-height: 1;
    vertical-align: middle;
}
.btn-action:hover,
.btn-submit:hover { background: var(--color-primary-dark); border-color: var(--color-primary-dark); color: #fff; }

/* Principal, pequeño */
.btn-action.btn-action--sm { height: var(--control-sm); padding: 0 var(--space-3); font-size: var(--text-xs); }

/* Principal, grande (llamadas a la acción de la web y del acceso) */
.btn-primary-link,
.btn-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--control-lg);
    padding: 0 var(--space-6);
    border: 1px solid transparent;
    font-size: var(--text-md);
    line-height: 1;
}

/* Peligro */
.btn-action.danger,
.panel-btn.panel-btn--danger { background: var(--color-surface); border-color: var(--color-error-text); color: var(--color-error-text); }
.btn-action.danger:hover,
.panel-btn.panel-btn--danger:hover { background: var(--color-error-text); border-color: var(--color-error-text); color: #fff; }

/* Botones de panel: secundario, principal y discreto, tamaño estándar */
.panel-btn { height: var(--control-md); line-height: calc(var(--control-md) - 2px); font-size: var(--text-sm); }
.panel-btn:hover { background: var(--color-lilac); }
.panel-btn.panel-btn--primary:hover { background: var(--color-primary-dark); }
.panel-btn.panel-btn--ghost { background: transparent; border-color: transparent; }
.panel-btn.panel-btn--ghost:hover { background: var(--color-lilac); }

/* Desplegables de la agenda y selector de vista: secundario pequeño */
.agenda-tool-btn,
.view-picker-btn { height: var(--control-sm); padding: 0 var(--space-3); font-size: var(--text-xs); }

/* Menú «Citas» y buscador de la barra de la agenda: misma altura estándar */
.agenda-nav-summary { height: var(--control-md); padding: 0 var(--space-4); font-size: var(--text-sm); }
.agenda-search { height: var(--control-md); padding-top: 0; padding-bottom: 0; }

/* Enlace con aspecto de botón */
.btn-link { font-size: var(--text-sm); }

.btn-action:focus-visible, .btn-submit:focus-visible, .btn-primary-link:focus-visible, .btn-primary:focus-visible,
.panel-btn:focus-visible, .agenda-tool-btn:focus-visible, .view-picker-btn:focus-visible, .btn-link:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}
.btn-action:disabled, .panel-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ══════════════════════════════════════════════════════════════════════
   Fase 3 del patrón del front (Trello #161): iconos, avisos, etiquetas y
   campos. Referencia visual: /ayuda/estilos.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Iconos (fragments/icons.html) ───────────────────────────────────────
   Decisión del equipo (30/09/2026): todos iguales, simples, de línea y en
   gris; nada de emojis ni de colores («para no hacerlo un circo»). La
   forma distingue el significado. Dentro de un texto miden como la letra;
   en columnas, listas de estado y barras (.icon-slot), 20px. */
.icon {
    display: inline-block;
    width: 1.15em;
    height: 1.15em;
    vertical-align: -0.2em;
    flex: none;
}
.icon-slot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    vertical-align: middle;
}
.icon-slot .icon { width: var(--icon-md); height: var(--icon-md); vertical-align: 0; }
.btn .icon, .btn-action .icon, .btn-submit .icon, .panel-btn .icon { width: var(--icon-sm); height: var(--icon-sm); vertical-align: -0.15em; }

/* Antes, marcas de color (✓ verde, ✗ rojo, ⚠ rojo): ahora iconos grises. */
.agenda-status .icon { width: 0.95rem; height: 0.95rem; vertical-align: -0.15em; }
.agenda-status .ok, .agenda-status .bad, .agenda-status .muted { color: var(--color-text-muted); }
.agenda-flag-warn { color: var(--color-text-muted); }
.agenda-flag-warn .icon { width: 0.85rem; height: 0.85rem; }
.view-picker-icon { display: inline-flex; color: var(--color-text-muted); }
.view-picker-icon .icon { width: var(--icon-sm); height: var(--icon-sm); vertical-align: 0; }
.technique-warning.icon-slot { margin-left: var(--space-1); }
.technique-warning .icon { width: var(--icon-sm); height: var(--icon-sm); }
.clinical-alert-reviewed { color: var(--color-text-muted); }
.legal-doc-list .icon-slot, .clinical-alert-head .icon-slot { margin-right: var(--space-1); }

/* ── Avisos ──────────────────────────────────────────────────────────────
   Un aviso estándar: .alert + --success | --error | --warning | --info.
   success-banner, alert-success y alert-error (las clases antiguas) se ven
   igual. form-error (el error de un campo) es otra cosa y se queda. */
.alert,
.success-banner {
    padding: var(--space-3) var(--space-4);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    line-height: 1.45;
    margin-bottom: var(--space-3);
}
.alert--success, .alert-success, .success-banner {
    background: var(--color-success-bg);
    color: var(--color-success-text);
    border-color: color-mix(in srgb, var(--color-success-text) 18%, transparent);
}
.alert--error, .alert-error {
    background: var(--color-error-bg);
    color: var(--color-error-text);
    border-color: color-mix(in srgb, var(--color-error-text) 18%, transparent);
}
.alert--warning {
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    border-color: color-mix(in srgb, var(--color-warning-border) 45%, transparent);
}
.alert--info {
    background: var(--color-info-bg);
    color: var(--color-info-text);
    border-color: color-mix(in srgb, var(--color-info-text) 18%, transparent);
}
.form-error { font-size: var(--text-sm); margin-top: var(--space-1); }
.form-hint { font-size: var(--text-xs); color: var(--color-text-muted); margin-top: var(--space-1); }

/* ── Etiquetas ───────────────────────────────────────────────────────────
   Una etiqueta estándar: .badge + --primary | --success | --warning |
   --error | --muted. Las antiguas (role-badge, badge-ia,
   insurer-billing-badge, payment-age-badge) se ven igual; su colocación
   (márgenes) sigue en su regla original. */
.badge,
.role-badge,
.badge-ia,
.insurer-billing-badge,
.payment-age-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    height: 22px;
    padding: 0 var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--color-lilac);
    color: var(--color-primary-dark);
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0;
    text-transform: none;
    white-space: nowrap;
    vertical-align: middle;
}
.badge--primary, .role-badge--super { background: var(--color-primary); color: #fff; }
.badge--success { background: var(--color-success-bg); color: var(--color-success-text); }
.badge--warning { background: var(--color-warning-bg); color: var(--color-warning-text); }
.badge--error, .insurer-billing-badge--direct, .payment-age-badge--overdue {
    background: var(--color-error-bg);
    color: var(--color-error-text);
}
.badge--muted, .insurer-billing-badge--self-billed, .payment-age-badge--normal {
    background: transparent;
    color: var(--color-text-muted);
    font-weight: 400;
}

/* ── Campos ──────────────────────────────────────────────────────────────
   Misma altura que el botón estándar (--control-md) y esquina pequeña,
   para que campo y botón encajen en una línea. El área de texto conserva
   su altura mínima. Las reglas de un contexto concreto (tablas, agenda)
   siguen mandando. */
input[type="text"],
input[type="date"],
input[type="time"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="number"],
input[type="search"],
select {
    height: var(--control-md);
    padding: 0 var(--space-3);
    border-radius: var(--radius-sm);
    font-size: var(--text-md);
}
textarea {
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    font-size: var(--text-md);
}
input[type="text"]:focus-visible,
input[type="date"]:focus-visible,
input[type="time"]:focus-visible,
input[type="email"]:focus-visible,
input[type="tel"]:focus-visible,
input[type="password"]:focus-visible,
input[type="number"]:focus-visible,
input[type="search"]:focus-visible,
select:focus-visible,
textarea:focus-visible {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 22%, transparent);
}

/* ── Columna de avisos de la lista de pacientes ─────────────────────────
   (PatientListFlagsService). Iconos grises de 20px, uno junto a otro. */
.data-table .col-flags { width: 1%; padding-left: var(--space-2); padding-right: var(--space-2); white-space: nowrap; }
.patient-flags { display: inline-flex; align-items: center; vertical-align: middle; gap: var(--space-2); color: var(--color-text-muted); cursor: help; }
.patient-flags .icon { width: var(--icon-md); height: var(--icon-md); vertical-align: 0; }
.sg-icon-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--space-3); }
.sg-icon-cell { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); font-size: var(--text-xs); }
.sg-icon-cell small { color: var(--color-text-muted); }
.sg-inline-input { max-width: 320px; }

/* Datos del centro (admin-clinic-data.html): el fieldset solo sirve para
   desactivar el formulario a quien no es superadministrador. */
.clinic-data-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.clinic-data .card-panel { margin-bottom: var(--space-4); }

/* Autorizaciones de seguro en la ficha (Trello #164). */
.authorization { border-top: 1px solid var(--color-border); padding: var(--space-4) 0; }
.authorization:first-of-type { border-top: 0; }
.authorization-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap; }
.authorization-head .badge { margin-left: var(--space-2); }
.authorization-counter { text-align: right; }
.authorization-counter strong { font-size: var(--text-lg); color: var(--color-primary-dark); }
.authorization-counter .form-hint { display: block; }
.authorization-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: flex-start; margin-top: var(--space-3); }
.authorization .alert { margin: var(--space-3) 0 0; }
#nueva-autorizacion { margin-top: var(--space-4); }

/* Declaración responsable (declaracion-responsable.html). */
.declaration-list dt { font-weight: 700; margin-top: var(--space-4); }
.declaration-list dd { margin: var(--space-1) 0 0; }
.declaration-list dd p { margin: var(--space-2) 0; }
.declaration-signature { margin-top: var(--space-6); font-weight: 600; }

/* Quien pide al sistema menos movimiento no ve transiciones ni animaciones en
   ninguna parte (WCAG 2.3.3). AccessibilitySeleniumTest arranca Chrome con esa
   preferencia, así axe nunca mide un color a mitad de una transición. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Panel «Esta semana» del cuadro de mandos (fragments/weekly-insights.html). */
.weekly-insights-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-4);
}
.weekly-insights-head h2 {
    margin: 0;
}
.weekly-insights-range {
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}
.weekly-kpi-trend {
    margin: var(--space-1) 0 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}
.weekly-kpi-trend--good span:first-child {
    color: var(--color-success-text);
}
.weekly-kpi-trend--bad span:first-child {
    color: var(--color-error-text);
}
.weekly-opportunities {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
}
.weekly-opportunities li {
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--color-border, #e3e8ea);
}
.weekly-opportunities li:last-child {
    border-bottom: none;
}
.weekly-opportunities a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}
.weekly-opportunities p {
    margin: var(--space-1) 0 0;
    font-size: var(--text-sm);
}

/* Página /instalar (instalar.html). */
.install-steps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--space-4);
    margin: var(--space-4) 0;
}
.install-qr {
    text-align: center;
}
.install-qr img {
    display: block;
    margin: var(--space-2) auto;
    max-width: 100%;
    height: auto;
}

/* Dictado por voz (dictation.js). */
.dictation-btn {
    margin: var(--space-1) var(--space-2) 0 0;
}
.dictation-btn.is-recording {
    border-color: var(--color-error-text);
    color: var(--color-error-text);
}

/* Cita sin alta (Trello #169): «Pasó por la clínica» dentro del bloque de la agenda. */
.agenda-inline-form { display: inline; margin: 0; }
.agenda-inline-form button { border: 0; cursor: pointer; font: inherit; }

/* Voided expense: stays on the list, struck through, not counted. */
.data-table tr.is-voided td {
    color: var(--color-text-muted);
    text-decoration: line-through;
}

.data-table tr.is-voided td:last-child {
    text-decoration: none;
}

/* Confirmation window for moving private appointments (staff agenda). */
.rebook-dialog {
    position: fixed;
    inset: 0;
    margin: auto;
    max-width: 34rem;
    max-height: 90vh;
    overflow: auto;
    padding: 1.2rem 1.4rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25);
    z-index: 50;
}

.rebook-dialog ul {
    padding-left: 1.1rem;
}

.rebook-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.rebook-manual summary {
    cursor: pointer;
    color: var(--color-mauve-dark);
    font-weight: 600;
}


/* Number field with visible − / + buttons (data-stepper, wired in ui-behaviors.js). */
.stepper {
  display: inline-flex;
  align-items: stretch;
  gap: 0.25rem;
}
.stepper input[type="number"] {
  width: 4.5rem;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}
.stepper input[type="number"]::-webkit-inner-spin-button,
.stepper input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.stepper-btn {
  min-width: 2.25rem;
  padding: 0 0.6rem;
  border: 1px solid var(--color-border, #c9d6dc);
  border-radius: 8px;
  background: var(--color-surface, #fff);
  color: inherit;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}
.stepper-btn:hover,
.stepper-btn:focus-visible {
  background: var(--color-surface-alt, #e8f0f3);
}

/* Estado de cada módulo en Administración → Herramientas (admin-herramientas.html). */
.module-pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: 0.78rem;
    font-weight: 600;
}

.module-pill--on {
    background: var(--color-success-bg);
    color: var(--color-success-text);
}

.module-pill--off {
    background: var(--color-surface-alt, #eef3f5);
    color: var(--color-muted, #5b6b76);
}

.module-missing {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 6px;
    border-left: 3px solid var(--color-warning-border);
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    font-size: 0.85rem;
}

/* ── Revisión del front 08/10/2026 (docs/revision-front-2026-10-08.md) ───── */

/* Campo de búsqueda con su botón en la misma línea; en pantallas estrechas el botón baja. */
.search-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 8px 12px;
}

.search-row > .form-row {
    flex: 1 1 260px;
    margin: 0;
}

.search-row > .btn-action,
.search-row > .btn-submit {
    margin-right: 0;
    min-height: var(--control-md);
}

/* Fila de botones de un mismo grupo, con espacio entre ellos (sustituye a los <p> con botones pegados). */
.btn-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px;
}

.btn-row > .btn-action,
.btn-row > .btn-submit {
    margin-right: 0;
}

/* Botones de una celda de tabla, apilados con espacio. */
.cell-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
}

.cell-actions > details {
    margin: 0;
}

.cell-actions .inline-form {
    margin: 0;
}

/* Botón secundario (acción de menor peso o filtro): borde y fondo claro, para que el principal destaque. */
.btn-action--secondary {
    background: var(--color-surface);
    color: var(--color-primary);
    box-shadow: inset 0 0 0 1px var(--color-primary);
}

.btn-action--secondary:hover {
    background: var(--color-lilac);
    color: var(--color-primary);
}

/* «+ Crear» es la acción principal de la agenda: relleno. La regla `.agenda-nav-summary` (más abajo
   en esta hoja) le quitaba el fondo; con esta especificidad mayor se queda relleno. */
.agenda-nav-summary.agenda-create-btn {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.agenda-nav-summary.agenda-create-btn:hover {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
}

/* Pestañas del panel: todas centradas en la misma línea, y «Editar atajos» del mismo tamaño que ellas. */
.dashboard-tabs {
    align-items: center;
}

.dashboard-shortcuts-picker .view-picker-btn {
    padding: 8px 16px;
    font-size: 0.9rem;
}

/* Documentos del paciente: el botón cae siempre en la misma columna, tenga el texto el largo que tenga. */
.legal-doc-list > li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) 11rem;
    align-items: center;
    gap: 6px 12px;
}

.legal-doc-list > li > .inline-form {
    margin: 0;
    justify-self: start;
}

@media (max-width: 640px) {
    .legal-doc-list > li {
        grid-template-columns: auto minmax(0, 1fr);
    }

    .legal-doc-list > li > .inline-form {
        grid-column: 2;
    }
}

/* Un <details> dentro de una fila de botones ocupa toda la línea cuando se abre, para que su formulario no quede estrecho. */
.btn-row {
    align-items: flex-start;
}

.btn-row > details {
    margin: 0;
}

.btn-row > details[open] {
    flex-basis: 100%;
}

/* ── Cabecera de la agenda: [Hoy] a la izquierda, ‹ fecha › centrado en la página, selector de vista a la derecha ── */
.calendar-header {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    justify-content: normal;
    gap: 12px;
}

.calendar-header .calendar-today {
    grid-column: 1;
    justify-self: start;
}

.calendar-nav-center {
    grid-column: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
}

/* En la agenda del panel, la fila entera es la rejilla (Hoy | ‹ fecha › | vista) y la fecha queda en el centro de la página. */
.agenda-daterow {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 12px;
}

.agenda-daterow .calendar-header {
    display: contents;
}

.agenda-daterow .calendar-today {
    grid-column: 1;
    grid-row: 1;
}

.agenda-daterow .calendar-nav-center {
    grid-column: 2;
    grid-row: 1;
}

.agenda-daterow .view-picker {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
}

@media (max-width: 720px) {
    .calendar-header,
    .agenda-daterow {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
    }

    .agenda-daterow .calendar-header {
        display: contents;
    }

    .calendar-nav-center {
        order: 3;
        flex-basis: 100%;
    }
}

/* Las flechas ‹ › de la fecha, más grandes y con borde para que se vean como botones. */
.calendar-step-btn {
    width: 38px;
    height: 38px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-primary-dark);
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1;
}

.calendar-step-btn:hover,
.calendar-step-btn:focus-visible {
    border-color: var(--color-primary);
    background: var(--color-lilac);
}

/* La flechita ▾ de todos los desplegables: oscura y sin transparencia, para que se vea que se abre. */
.view-picker-btn::after,
.agenda-tool-btn::after {
    opacity: 1;
    color: var(--color-primary-dark);
    font-size: 0.9em;
    font-weight: 700;
}

/* En los botones que pueden ir rellenos («+ Crear», la pestaña activa) la flecha toma el color del texto. */
.agenda-nav-summary::after,
.dashboard-tab-group-trigger::after {
    opacity: 1;
    color: currentColor;
    font-size: 0.9em;
    font-weight: 700;
}

/* Arrastrar citas en la semana (agenda-week-drag.js). */
.agenda-week .agenda-block[draggable="true"] {
    cursor: grab;
}

.agenda-week .agenda-block.is-dragging {
    opacity: 0.45;
    cursor: grabbing;
}

.agenda-week .agenda-slot--drag-over {
    background: var(--color-lilac);
    outline: 2px dashed var(--color-primary);
    outline-offset: -2px;
}

/* Botón ⋮ de cada cita de la agenda: más grande, con zona de clic de verdad y separado de la ✕ de cancelar. */
.agenda-block-menu {
    top: 3px;
    right: 28px;
}

.agenda-block-menu > summary {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--color-primary-dark);
}

.agenda-block-menu > summary:hover,
.agenda-block-menu[open] > summary {
    background: var(--color-lilac);
}

.agenda-block-cancel {
    top: 5px;
    right: 6px;
}

.agenda-block-cancel .calendar-appointment-cancel {
    font-size: 1.15rem;
    padding: 0 4px;
}

/* Volantes y sesiones usadas en la ficha: cada elemento en una sola línea, sin saltos dentro de un volante. */
.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 6px;
}

.chip {
    display: inline-block;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-alt, #eef3f5);
    color: var(--color-text);
    font-size: 0.82rem;
    white-space: nowrap;
}

.usage-line {
    display: flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    padding: 2px 0;
}

/* Historial de citas en la columna lateral de la ficha: altura limitada con su propio scroll y cabecera fija. */
.history-scroll {
    max-height: 24rem;
    overflow-y: auto;
}

.history-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 1;
}

/* La columna lateral de la ficha lleva paneles pequeños (descuento de bienvenida, promociones): altura natural, sin estirarlos. */
.record-top-side .card-panel {
    flex: 0 0 auto;
}

/* Barra de acciones de la ficha (arriba de la tarjeta de datos): botones pequeños, con icono donde se entiende. */
.patient-actions {
    margin: 0 0 14px;
    gap: 6px;
}

.patient-actions .btn-action {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 11px;
    font-size: 0.78rem;
    line-height: 1.2;
}

.patient-actions .btn-action .icon {
    width: 15px;
    height: 15px;
    color: inherit;
    flex: none;
    vertical-align: baseline;
}

/* Acciones de la página del marco, en la fila de pestañas del panel (dashboard-panels.js). */
.dashboard-frame-actions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

.dashboard-frame-actions[hidden] {
    display: none;
}

.dashboard-frame-btn .icon {
    width: 18px;
    height: 18px;
    color: inherit;
}

/* La barra de la página (Expandir/Guardar) vive en el panel: dentro del marco se oculta. */
.actions-in-parent .page-nav {
    display: none;
}

/* Cerrar sesión: solo el símbolo de apagado, con su nombre en el tooltip. */
.logout-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    padding: 0;
    text-decoration: none;
}

.logout-btn:hover,
.logout-btn:focus-visible {
    background: var(--color-lilac);
}

.logout-btn .icon {
    width: 20px;
    height: 20px;
    color: var(--color-primary-dark);
}

/* «Paciente:» delante del nombre en la cabecera de la ficha. */
.record-title-label {
    font-size: 0.5em;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    vertical-align: middle;
}

/* Código de cliente en la ficha: al final de los datos, pequeño y en gris (sigue ahí para identificar al paciente sin nombre). */
.record-code {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* Apartado «Seguro» de la ficha: dos secciones (datos y autorizaciones) dentro de un mismo panel plegable. */
.subpanel + .subpanel {
    margin-top: 28px;
    padding-top: 20px;
    border-top: 1px solid var(--color-border);
}

.subpanel > h4:first-child {
    margin-top: 0;
    color: var(--color-primary-dark);
}

/* Botón de avisos de la ficha (campana con contador y desplegable). */
.alerts-menu {
    position: relative;
    margin-left: auto;
}

.alerts-menu-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    list-style: none;
    cursor: pointer;
    padding: 6px 12px;
}

.alerts-menu-btn::-webkit-details-marker {
    display: none;
}

.alerts-menu-btn .icon {
    width: 18px;
    height: 18px;
    color: inherit;
}

.alerts-count {
    min-width: 20px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--color-error-text);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
}

.alerts-menu-panel {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: 5;
    min-width: 280px;
    padding: 10px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 6px 20px rgba(22, 35, 46, 0.14);
}

.alerts-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 4px;
}

.alerts-list a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 8px;
    color: var(--color-text);
    text-decoration: none;
    font-size: 0.9rem;
}

.alerts-list a:hover {
    background: var(--color-lilac);
}

.alerts-list strong {
    min-width: 22px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--color-lilac);
    color: var(--color-primary-dark);
    text-align: center;
}

.alerts-empty {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

/* Botón de avisos: la línea «Nada pendiente» solo se ve cuando no queda nada. */
.alerts-empty.is-hidden,
.alerts-count[hidden] {
    display: none;
}

/* Ficha: datos principales compactos en tres líneas (pedido del equipo 09/10/2026). */
.ficha-datos { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.ficha-datos-linea { display: flex; flex-wrap: wrap; gap: 4px 18px; }
.ficha-datos-linea:empty { display: none; }
.ficha-dato b { font-weight: 600; color: var(--muted, #5b6770); margin-right: 4px; font-size: 0.85em; text-transform: uppercase; letter-spacing: 0.02em; }

/* Botones segmentados (sexo, estado civil) con radios reales: accesibles y sin JS. */
.segmented { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.segmented label { margin: 0; cursor: pointer; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span { display: inline-block; padding: 6px 12px; border: 1px solid var(--border, #c9d1d6); border-radius: 999px; font-size: 0.9rem; }
.segmented input:checked + span { background: var(--primary, #1f4d5c); border-color: var(--primary, #1f4d5c); color: #fff; }
.segmented input:focus-visible + span { outline: 2px solid var(--primary, #1f4d5c); outline-offset: 2px; }

/* Fisioterapeutas asignados como etiquetas con «x». */
.professional-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.professional-chip { display: inline-flex; align-items: center; gap: 8px; padding: 4px 6px 4px 12px; border: 1px solid var(--border, #c9d1d6); border-radius: 999px; }
.professional-chip .chip-x { border: 0; background: transparent; cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 2px 8px; border-radius: 999px; color: inherit; }
.professional-chip .chip-x:hover { background: rgba(180, 40, 40, 0.12); color: #a12626; }

.ex-sent-log { list-style: none; padding: 0; margin: 6px 0 0; }
.ex-sent-ok { color: #1c6b3a; }
.ex-sent-error { color: #a12626; }

/* Apartado agrupado (p. ej. «Bonos y promociones»): las sub-secciones van dentro, sin caja propia. */
.panel-group .card-panel { border: 0; box-shadow: none; background: transparent; padding: 10px 0 0; margin-top: 8px; border-top: 1px solid var(--border, #e1e6ea); border-radius: 0; }
.panel-group .card-panel > h3 { font-size: 1.05rem; }

/* Ficha responsive: las columnas pueden encogerse y cada sub-sección abre en su propio bloque, a todo el ancho de su
   apartado; las tablas anchas se desplazan dentro de su caja en vez de desbordar la página. */
.record-top-main,
.record-top-side { min-width: 0; }
.panel-group .card-panel { min-width: 0; display: block; width: 100%; box-sizing: border-box; }
.panel-group .card-panel:not(.is-collapsed) { overflow-x: auto; }
.panel-group .table-responsive { overflow-x: auto; max-width: 100%; }
@media (max-width: 900px) {
    .record-top-layout { grid-template-columns: minmax(0, 1fr); }
    .ficha-datos-linea { gap: 4px 12px; }
}

/* Cabecera de la historia clínica: fisioterapeuta a la izquierda y, a la derecha, los botones de tipo de consulta,
   asistencia y tipo de sesión (pedido del equipo 09/10/2026). */
.historia-cabecera { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: flex-start; justify-content: space-between; }
.historia-cabecera .professional-panel { flex: 1 1 280px; min-width: 0; }
.historia-cabecera .historia-botones { flex: 0 1 auto; justify-content: flex-end; }

/* Campana de avisos dentro de la barra superior de la ficha. */
.alerts-menu--nav { margin-left: 0; }
.alerts-menu--nav .alerts-menu-btn { padding: 4px 10px; }
.alerts-menu--nav .alerts-menu-panel { z-index: 20; }

/* Hojas de cálculo en pantalla (gastos, ingresos): cabecera fija, importes a la derecha y gastos anulados en gris. */
.data-sheet thead th { position: sticky; top: 0; background: var(--color-surface); z-index: 1; }
#gastos-hoja th:nth-child(n+7):nth-child(-n+10),
#gastos-hoja td:nth-child(n+7):nth-child(-n+10) { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.data-sheet tr.is-voided td { color: var(--color-muted, #7a858c); text-decoration: line-through; }
.data-sheet tr.is-voided td:last-child { text-decoration: none; }

/* Re-evaluación: ventana emergente y fila propia (otro color) en el historial. */
.reevaluacion-dialog { border: 1px solid var(--color-border); border-radius: var(--radius); padding: 16px; width: min(560px, 92vw); }
.reevaluacion-dialog::backdrop { background: rgba(22, 35, 46, 0.45); }
.reevaluacion-header { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.reevaluacion-header h4 { margin: 0; }
tr.history-reeval-row td { background: rgba(61, 120, 139, 0.10); }

/* Representante legal: solo se ve si se marca «Menor de edad». */
.representative-block { display: none; }
form:has(#input-minor:checked) .representative-block { display: block; }

/* Códigos CIE-10-ES elegidos, como etiquetas junto al Diagnóstico. */
.cie-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.cie-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 6px 3px 10px; border: 1px solid var(--color-border); border-radius: 999px; font-size: 0.85rem; }
.cie-chip .chip-x { border: 0; background: transparent; cursor: pointer; padding: 2px 6px; border-radius: 999px; color: inherit; }
.cie-chip .chip-x:hover { background: rgba(61, 120, 139, 0.15); }
.cie-chip.is-principal-code { border-color: var(--color-primary, #3d788b); }

/* Etiquetas de los grupos de botones de la historia clínica y botón de dolor doble. */
.btn-group-label { margin: 8px 0 4px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-muted, #5b6770); }
.historia-botones-bloque { flex: 0 1 auto; }
.historia-botones-bloque .btn-group-label { margin-top: 0; text-align: right; }
.disclosure-sub { margin-bottom: 8px; }
.disclosure-sub:last-child { margin-bottom: 0; }

/* Notas de la ficha: Urgente (rojo), Importante (amarillo), Informativa (azul), con el semáforo de siempre. */
.note-list { list-style: none; padding: 0; margin: 0 0 12px; display: flex; flex-direction: column; gap: 8px; }
.note { border-left: 4px solid var(--color-info, #3d788b); padding: 8px 12px; border-radius: var(--radius); background: rgba(61, 120, 139, 0.07); }
.note--urgente { border-left-color: #b42828; background: rgba(180, 40, 40, 0.09); }
.note--importante { border-left-color: #c79a00; background: rgba(199, 154, 0, 0.12); }
.note--unread { box-shadow: 0 0 0 1px currentColor inset; }
.note-head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.notes-banner { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
fieldset.note-block { border: 0; padding: 0; margin: 0; min-width: 0; }
fieldset.note-block:disabled { opacity: 0.45; }
.alert-globo { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 999px; color: #fff; font-size: 0.75rem; line-height: 20px; text-align: center; vertical-align: middle; }
.alert-globo--rojo { background: #b42828; animation: alert-pulso 1.6s ease-in-out 3; }
.alert-globo--azul { background: #3d788b; animation: alert-pulso 1.6s ease-in-out 3; }
@keyframes alert-pulso { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.18); } }
@media (prefers-reduced-motion: reduce) { .alert-globo--rojo, .alert-globo--azul { animation: none; } }

/* Ficha: la fila del nombre del paciente (con Nueva cita, Asistencia, Asistió y el candado) se queda fija arriba al bajar
   por la hoja, para ver siempre de quién es (pedido del equipo 11/10/2026). La cabecera común (hora, Agenda, Pacientes...) no
   se toca: es la misma para todas las pantallas. */
.page-content > .record-title {
    position: sticky;
    top: 0;
    z-index: 40;
    margin: 0 0 16px;
    padding: 10px 20px;
    background: var(--color-surface, #fff);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.page-content > .record-title h1 { font-size: 1.35rem; }

/* Iconos de la cita (WhatsApp, correo, recordatorio, LOPD…) en la MISMA LÍNEA que la hora, en el hueco libre de la
   izquierda (decisión del equipo 08/10 y 11/10/2026): ya no hay una fila debajo del nombre que lo empuje o lo corte. Con
   más de 3 se ven 2 y un «+»; al pasar el ratón la cita se despliega entera (ver «peek»). */
.agenda-block-head > .agenda-block-flags { margin: 0; overflow: visible; flex: 0 0 auto; gap: 2px; }
.agenda-block-head > .agenda-block-flags .agenda-flag { line-height: 1; }
.agenda-block-head > .agenda-block-flags .agenda-flag-icon .icon { width: 0.7rem; height: 0.7rem; }
.agenda-block-flags:has(> :nth-child(4)) > :nth-child(n+3) { display: none; }
.agenda-block-flags:has(> :nth-child(4))::after { content: "+"; font-size: 0.62rem; font-weight: 700; line-height: 1; }

/* Iconos de la línea de la hora alineados entre sí y con el texto (captura del equipo 11/10/2026: el euro bajaba y las
   campanas y triángulos subían). Misma altura de caja, centrado vertical y el SVG sin hueco de línea base. */
.agenda-block-head { align-items: center; }
.agenda-block-head > .agenda-block-flags { display: inline-flex; align-items: center; height: 0.9rem; }
.agenda-block-head .agenda-flag { display: inline-flex; align-items: center; justify-content: center; height: 0.9rem; line-height: 1; }
.agenda-block-head .agenda-flag .icon { display: block; }
.agenda-block-head .agenda-flag-pay { font-size: 0.7rem; }
.agenda-block-head .agenda-block-time { display: inline-flex; align-items: center; height: 0.9rem; line-height: 1; }

/* Aseguradora y profesional en una línea: la aseguradora nunca se recorta; el profesional sí, con «…». */
.agenda-block-meta { display: flex; align-items: baseline; gap: 3px; min-width: 0; white-space: nowrap; font-size: 0.62rem; color: var(--color-text-muted); }
.agenda-block-meta .agenda-block-insurer { flex: 0 0 auto; overflow: visible; }
.agenda-block-meta .agenda-block-prof { flex: 0 1 auto; min-width: 0; }
.agenda-block.h-1 .agenda-block-meta { display: none; }
.agenda-block.h-1.is-expanded .agenda-block-meta { display: flex; }

/* Citas a la misma hora (dos columnas estrechas): el menú ⋮ y la × se montaban sobre la hora y la sesión (captura de
   el equipo 11/10/2026). La línea de la hora reserva a la derecha el sitio de los dos botones y, si no cabe todo, la sesión
   («1/10») baja a otra línea en vez de quedar debajo de ellos. */
.agenda-block-head { padding-right: 3.1rem; flex-wrap: wrap; row-gap: 0; min-width: 0; }
.agenda-block-head .agenda-block-time { min-width: 0; }

/* Hojas: cabecera ordenable con un clic y barra de filtros. */
.data-sheet th.is-sortable { cursor: pointer; user-select: none; }
.data-sheet th.is-sortable:hover { text-decoration: underline; }
.data-sheet th[aria-sort="ascending"]::after { content: " ▲"; font-size: 0.7em; }
.data-sheet th[aria-sort="descending"]::after { content: " ▼"; font-size: 0.7em; }
.sheet-filters { margin: 0 0 10px; align-items: flex-end; gap: 12px; }
.sheet-filters label { display: flex; flex-direction: column; gap: 2px; font-size: 0.8rem; }

/* Cita desplegada (un clic): siempre opaca y por encima de las demás. Las anuladas o canceladas se ven atenuadas y, al
   desplegarse, dejaban ver la cita de debajo y las letras se montaban (captura del equipo 11/10/2026). */
.agenda-day > .agenda-block.is-expanded {
    opacity: 1;
    background: var(--color-surface, #fff);
    background-image: linear-gradient(var(--patho-bg, transparent), var(--patho-bg, transparent));
    z-index: 30;
}

/* Cita de la agenda (el equipo 11/10/2026): la × y el menú ⋮ más pegados al borde derecho, y el nombre en una sola línea que
   reduce la letra si es largo (agenda-fit-names.js) en vez de salirse o saltar de línea. La hora y los iconos se quedan
   como estaban. */
.agenda-block > .agenda-block-cancel { right: 1px; }
.agenda-block > .agenda-block-menu { right: 12px; }
.agenda-block-head { padding-right: 2.4rem; }
.agenda-block > .agenda-block-who { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Citas estrechas (dos a la misma hora): iconos, «1/10» y hora en UNA sola línea para que el nombre no se quede sin sitio;
   la hora baja un poco de tamaño solo aquí (captura del equipo 11/10/2026). El «1/10» va antes de la hora, con los iconos. */
.agenda-block { container-type: inline-size; }
@container (max-width: 170px) {
    .agenda-block-head { flex-wrap: nowrap; gap: 2px; padding-right: 2.1rem; }
    .agenda-block-head .agenda-block-time { font-size: 0.54rem; }
    .agenda-block-head .agenda-flag-session { font-size: 0.5rem; padding: 0 3px; }
}

/* Cita desplegada de las que se pisan (dos o más a la misma hora): se abre a todo el ancho de la columna, por encima de las
   demás, para que se lea entera (el equipo 11/10/2026). */
.agenda-day > .agenda-block.is-expanded { left: 1px; width: calc(100% - 3px); }

/* Cita desplegada: más aire entre los iconos, la hora y el «1/10» (el equipo 11/10/2026). */
.agenda-day > .agenda-block.is-expanded .agenda-block-head { gap: 9px; flex-wrap: wrap; padding-right: 3rem; }
.agenda-day > .agenda-block.is-expanded .agenda-block-head > .agenda-block-flags { gap: 8px; }
.agenda-day > .agenda-block.is-expanded .agenda-block-time { font-size: 0.7rem; }
.agenda-day > .agenda-block.is-expanded .agenda-flag-session { padding: 1px 6px; }

/* Glosario de iconos de la agenda (plegado). */
.agenda-glossary { margin: 0 0 8px; font-size: 0.8rem; }
.agenda-glossary > summary { cursor: pointer; color: var(--color-text-muted); width: fit-content; }

/* Menú «+ Crear» (nueva cita, nuevo curso, buscar huecos): panel más estrecho (sobraba mucho espacio a la derecha) y una X
   para cerrar el panel y otra para cerrar cada formulario, por si se abre por error (el equipo 11/10/2026). */
#citas-menu > .agenda-nav-panel { width: min(440px, 94vw); padding-right: 34px; }
.panel-close {
    position: absolute;
    top: 6px;
    right: 8px;
    z-index: 2;
    width: 1.7rem;
    height: 1.7rem;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--color-text-muted);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
}
.panel-close:hover { background: rgba(180, 40, 40, 0.12); color: #a12626; }
.panel-close:focus-visible { outline: 2px solid var(--color-primary, #3d788b); }
.agenda-nav-panel .agenda-tool[open] > form { position: relative; padding-right: 30px; }
.panel-close--menu { top: 4px; right: 6px; }

/* Engranaje: sección «Colores de la agenda» (un selector de color por zona). */
.agenda-colors-form { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--color-border); }
.agenda-colors-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 14px; margin: 8px 0; }
.agenda-color-row { display: flex; align-items: center; gap: 8px; font-size: 0.82rem; cursor: pointer; }
.agenda-color-row input[type="color"] { width: 1.9rem; height: 1.5rem; padding: 0; border: 1px solid var(--color-border); border-radius: 6px; background: none; cursor: pointer; }

/* Elegir la zona del cuerpo: fichas de color (en la cita desplegada y en «Zonas pendientes»). */
.zone-chip { display: inline-block; width: 0.95rem; height: 0.95rem; border-radius: 999px; background: var(--patho, #b9c2c8); border: 1px solid rgba(0, 0, 0, 0.18); flex: 0 0 auto; }
.agenda-day > .agenda-block.is-expanded .zone-chooser-row { display: flex; flex-wrap: wrap; gap: 6px; }
.zone-chip-label { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px 3px 6px; border: 1px solid var(--color-border); border-radius: 999px; background: var(--color-surface); cursor: pointer; font-size: 0.8rem; }
.zone-chip-label:hover { background: rgba(61, 120, 139, 0.1); }

.agenda-zones-link { margin: 0 0 6px; font-size: 0.8rem; }

/* Zona del cuerpo en la ficha: desplegable con el color de cada zona (selección única). */
.ficha-zona { margin: 8px 0 4px; }
.zone-picker { max-height: 17rem; overflow-y: auto; }
.zone-picker-option { display: flex; align-items: center; gap: 10px; width: 100%; padding: 6px 10px; border: 0; background: none; text-align: left; cursor: pointer; font: inherit; }
.zone-picker-option:hover, .zone-picker-option:focus-visible { background: rgba(61, 120, 139, 0.12); }
.zone-picker-option.is-current { background: rgba(61, 120, 139, 0.18); font-weight: 600; }
.zone-picker-none { color: var(--color-text-muted); }

/* Ficha en pantalla pequeña: la fila del nombre (con sus botones, que pasan a varias líneas) no se queda fija, porque
   taparía media pantalla; el nombre y los botones se reparten en el ancho y los datos no se salen de la caja. */
@media (max-width: 720px) {
    .ficha-fija { position: static; }
    .ficha-fija > .record-title {
        position: static;
        padding: 10px 12px;
        gap: 8px;
    }
    .ficha-fija > .record-title h1 { font-size: 1.15rem; flex: 1 1 100%; overflow-wrap: anywhere; }
    .ficha-dato { overflow-wrap: anywhere; min-width: 0; }
    .historia-cabecera .historia-botones { justify-content: flex-start; }
}

/* Escanear con la cámara: miniaturas de las páginas hechas, con su «×». */
.scan-pages { list-style: decimal inside; display: flex; flex-wrap: wrap; gap: 10px; padding: 0; margin: 8px 0; }
.scan-pages li { display: flex; align-items: flex-start; gap: 4px; }
.scan-thumb { width: 72px; height: 96px; object-fit: cover; border: 1px solid var(--border, #c9d1d6); border-radius: 6px; }
.scan-actions { margin: 6px 0 10px; }
.scan-form button[disabled] { opacity: 0.5; cursor: not-allowed; }

/* Resumen de seguros en la columna derecha de la ficha: una línea por autorización. */
.seguro-resumen { list-style: none; padding: 0; margin: 6px 0 0; display: flex; flex-direction: column; gap: 8px; }
.seguro-resumen li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.seguro-resumen a { color: inherit; text-decoration: none; display: inline-flex; flex-wrap: wrap; gap: 2px 8px; }
.seguro-resumen a:hover { text-decoration: underline; }
.seguro-resumen-uso { font-variant-numeric: tabular-nums; }

/* Línea de navegación del panel: casa + volver y, a su lado, los botones de sección. */
.dash-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 32px;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.dash-bar .page-nav {
    padding: 0;
    border: 0;
    background: none;
    flex: none;
}

.dash-bar .dashboard-tabs {
    flex: 1;
    margin: 0;
}

.topbar .page-nav-clock {
    font-size: 1.3rem;
}

/* Barra de acciones de la ficha: una sola línea arriba, con todos los botones (más pequeños); si la ventana es estrecha, se desplaza. */
.patient-actions--barra {
    flex-wrap: nowrap;
    align-items: center;
    gap: 5px;
    margin: 4px 0 12px;
    padding-bottom: 2px;
    overflow-x: auto;
}

.patient-actions--barra .btn-action {
    padding: 4px 9px;
    font-size: 0.72rem;
    white-space: nowrap;
}

.patient-actions--barra .inline-form {
    flex: none;
}

.patient-actions--barra .btn-action .icon {
    width: 13px;
    height: 13px;
}

/* Datos del paciente dentro de la banda del nombre: fluyen en líneas que se ajustan al ancho, con el mismo tamaño de letra. */
.ficha-resumen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 18px;
}

.ficha-resumen .ficha-datos,
.ficha-resumen .ficha-datos-linea {
    display: contents;
}

.ficha-resumen .ficha-zona,
.ficha-resumen .record-code {
    margin: 0;
}

/* Campos fijos de la ficha resaltados: etiqueta con fondo y en negrita, valor al lado (pedido del equipo 13/10/2026). */
.ficha-resumen .ficha-dato {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.ficha-resumen .ficha-dato b {
    margin: 0;
    padding: 2px 8px;
    border-radius: 6px;
    background: var(--color-lilac);
    color: var(--color-mauve-dark);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
}

/* El engranaje (reordenar) y su guardado van al final de la barra, pegados a la derecha. */
.patient-actions--barra #btn-reordenar-acciones {
    margin-left: auto;
}

/* Cabecera fija de la ficha (pedido del equipo 13/10/2026): barra de acciones, nombre y datos, cada uno en su banda, siempre a la vista. */
.ficha-fija {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 0 0 16px;
    padding: 6px 0;
    background: var(--color-bg);
}

.ficha-fija > .patient-actions--barra,
.ficha-fija > .record-title,
.ficha-fija > .ficha-resumen {
    margin: 0;
    padding: 8px 20px;
    background: var(--color-surface, #fff);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.ficha-fija > .record-title {
    position: static;
    padding: 6px 20px;
}

.ficha-fija > .record-title h1 { font-size: 1.35rem; }

/* Asignar fisioterapeuta: lista de opciones en la que se elige con doble clic. */
.professional-option {
    width: 100%;
    padding: 6px 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-family: inherit;
    font-size: 0.9rem;
    text-align: left;
    cursor: pointer;
}

.professional-option:hover,
.professional-option:focus-visible {
    background: rgba(61, 120, 139, 0.12);
}

.historia-cabecera .professional-panel { margin-bottom: 0; }

/* Botones de la cabecera de la historia alineados por abajo: «Asignar fisioterapeuta» a la misma altura que los de «Datos de la sesión». */
.historia-cabecera { align-items: flex-end; }
.historia-cabecera .historia-botones { margin-bottom: 0; }

/* Seguro en la columna derecha: campos pequeños y volantes como lista (pedido del equipo 13/10/2026). */
.seguro-form .form-row { margin-bottom: 8px; }
.seguro-form label { font-size: 0.78rem; margin-bottom: 2px; }
.seguro-form input[type="text"],
.seguro-form select {
    padding: 5px 8px;
    font-size: 0.85rem;
}
.seguro-form-campos {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 10px;
}
.volantes-lista {
    list-style: decimal inside;
    margin: 4px 0 8px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.volantes-lista li { display: flex; align-items: center; gap: 6px; font-size: 0.85rem; }
.volantes-lista li::marker { color: var(--color-mauve-dark); font-weight: 600; }
.volantes-lista .volante-input { flex: 1; min-width: 0; padding: 4px 8px; font-size: 0.85rem; }
.volantes-lista .chip-x { border: 0; background: transparent; cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 2px 8px; border-radius: 999px; color: inherit; }
.volantes-lista .chip-x:hover { background: rgba(180, 40, 40, 0.12); color: #a12626; }
.volantes-anadir { padding: 4px 11px; font-size: 0.78rem; }
.record-top-side #panel-seguro .data-table { font-size: 0.8rem; }

/* Pautas para casa: botón de enviar y registro de envíos debajo del cuadro. */
.pautas-acciones { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.pautas-registro { list-style: none; margin: 6px 0 0; padding: 0; font-size: 0.85rem; color: var(--color-text-muted, #5b6770); }
.pautas-registro li { padding: 2px 0; }
.pautas-registro li.send-row--problem { color: #a12626; }

/* Seguro: un bloque por aseguradora, con su etiqueta, el uso de sesiones y sus campos pequeños. */
.seguro-item { border: 1px solid var(--color-border); border-radius: var(--radius); padding: 8px 10px; margin: 8px 0; }
.seguro-item-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-bottom: 6px; }
.seguro-item-cab .usage-line { font-size: 0.8rem; }
.btn-guardar-seguro { padding: 4px 12px; font-size: 0.78rem; }
.seguro-form-campos { grid-template-columns: 1fr 1fr; }

/* Asistente IA: botones en una fila con aire, selector + botón juntos, y espacio antes de la caja de la nota. */
.ia-explicacion { margin: 4px 0 12px; line-height: 1.5; }
.ia-actions { gap: 10px; margin-bottom: 20px; align-items: center; }
.ia-actions .inline-form { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.ia-actions select { padding: 5px 8px; font-size: 0.82rem; width: auto; }
.ia-actions .btn-action { white-space: nowrap; }

/* «Dónde estamos»: recorrido bajo los botones de sección del panel («Agenda › Ficha de paciente › Ficha administrativa»). */
.topbar-where {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    padding: 5px 32px;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
    font-size: 0.9rem;
    color: var(--color-text-muted, #5b6770);
}

.topbar-where:empty { display: none; }
.topbar-where-sep { color: var(--color-border-strong, #9aa7ae); }
.topbar-where-current { font-weight: 700; color: var(--color-mauve-dark); }

/* Los tramos anteriores del recorrido son botones sin aspecto de botón: se pulsan para volver a esa pantalla. */
.topbar-where-step {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: var(--color-mauve-dark);
    cursor: pointer;
}

.topbar-where-step:hover { text-decoration: underline; }

/* Tipo de tratamiento: el elegido se marca en la lista. */
.professional-option.is-current { background: rgba(61, 120, 139, 0.18); font-weight: 600; }

/* Tratamientos indicados: marca ✓ en la lista de la historia y línea bajo la zona en la cita de la agenda. */
.tratamiento-marca { display: inline-block; width: 1.1em; }
.professional-option.is-current .tratamiento-marca::before { content: "✓"; }
.tratamiento-cabina { color: var(--color-text-muted); }

.agenda-block-treat { white-space: nowrap; flex-shrink: 0; }
.agenda-block-treat.is-cabin { font-weight: 700; color: var(--color-mauve-dark); }

/* Botón «Colores» de la agenda: su menú se abre hacia la izquierda (está al borde derecho) y lista los colores en una columna. */
.view-picker--right > .view-picker-menu { left: auto; right: 0; min-width: 230px; }
.agenda-legend--menu { flex-direction: column; flex-wrap: nowrap; gap: 5px; margin: 0; padding: 0; max-height: 60vh; overflow-y: auto; }
.agenda-colors-row { display: flex; justify-content: flex-end; margin: 0 0 6px; }
.agenda-daterow .agenda-colors { order: 3; }

/* Panel del candado: el candado usa line-height 0 para centrar el icono y el panel lo heredaba (las líneas se pisaban);
   «Cancelar» y «Bloquear» van en una fila, con «Bloquear» a la derecha. */
.booking-lock-panel { line-height: 1.4; text-align: left; }
.booking-lock-panel textarea { margin: 4px 0 10px; }
.booking-lock-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* Cita desplegada: lo que va debajo del nombre (zona, tratamiento, aseguradora y profesional) un punto más grande (pedido del equipo 13/10/2026). */
.agenda-day > .agenda-block.is-expanded .agenda-block-tags,
.agenda-day > .agenda-block.is-expanded .agenda-block-meta { font-size: calc(0.62rem + 1pt); }

/* Títulos con su explicación al lado, en una sola línea y en letra pequeña (pedido del equipo 13/10/2026). */
.titulo-con-explicacion { display: flex; align-items: baseline; gap: 10px; flex-wrap: nowrap; margin: 0 0 4px; }
.titulo-con-explicacion label { margin: 0; color: var(--color-mauve-dark); font-weight: 700; white-space: nowrap; }
.explicacion-corta { font-size: 0.72rem; color: var(--color-text-muted, #5b6770); line-height: 1.3; min-width: 0; }
.titulo-con-explicacion .explicacion-corta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* junto al botón «Ejercicios» */
.btn-row > .explicacion-corta { align-self: center; }

/* Botón de dictado como icono de micrófono: redondo y pequeño. */
.dictation-btn { width: 34px; height: 34px; padding: 0; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; }

/* «Datos de la sesión»: con cuatro botones el grupo baja a su propia línea y se quedaba a la izquierda con el rótulo a la derecha;
   se pega al borde derecho para que el rótulo y los botones queden alineados. */
.historia-cabecera .historia-botones-bloque { margin-left: auto; }

/* «Guardar historial» en la fila de los botones del cuadro de pautas: sin margen propio y del mismo tamaño que los demás. */
.pautas-acciones .btn-submit { margin: 0; width: auto; padding: 8px 16px; font-size: 0.85rem; }

/* Página de firma: «Limpiar» y «Confirmar y firmar» uno al lado del otro (pedido del equipo 13/10/2026). */
#btn-limpiar-firma, #btn-firmar { display: inline-block; width: auto; margin: 8px 8px 0 0; vertical-align: middle; }
#signing-form { display: inline; }

/* Cabecera de la historia clínica: «Fisioterapeuta» y «Datos de la sesión» en la misma línea y alineados por abajo (el panel del
   fisioterapeuta ya no pide un ancho mínimo, que era lo que empujaba los datos de la sesión a la línea siguiente). */
.historia-cabecera .professional-panel { flex: 0 0 auto; }

/* «Zona tratada» y «Técnicas aplicadas»: sin casilla visible (pedido del equipo 13/10/2026). Se marca con doble clic y lo elegido
   sale resaltado con ✓, como en las demás listas. La casilla sigue ahí (oculta) para el formulario y el teclado. */
#panel-anadir-consulta .option-list--multi input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    margin: 0;
}

#panel-anadir-consulta .option-list--multi li {
    border-radius: 6px;
    cursor: pointer;
    user-select: none;
}

#panel-anadir-consulta .option-list--multi li:hover,
#panel-anadir-consulta .option-list--multi li:has(input:focus-visible) { background: rgba(61, 120, 139, 0.12); }

#panel-anadir-consulta .option-list--multi li:has(input:checked) { background: rgba(61, 120, 139, 0.18); font-weight: 600; }

#panel-anadir-consulta .option-list--multi .checkbox-label::before {
    content: "";
    display: inline-block;
    width: 1.1em;
    flex: none;
}

#panel-anadir-consulta .option-list--multi li:has(input:checked) .checkbox-label::before { content: "✓"; }

/* Tratamiento de la cita, editable desde la cita desplegada. */
.agenda-treatment-form { display: none; margin: 4px 0 0; }
.agenda-day > .agenda-block.is-expanded .agenda-treatment-form { display: block; }
.agenda-treatment-form select { width: 100%; padding: 2px 6px; font-size: 0.7rem; }

/* Fisioterapeuta asignado en la cabecera de la historia: la etiqueta con su nombre tiene el estilo de «Catálogo» (borde verde azulado,
   texto del mismo color) y el mismo alto que el botón relleno de al lado; la «×» queda dentro (pedido del equipo 13/10/2026). */
.historia-cabecera .professional-chips { gap: 8px; align-items: center; }
.historia-cabecera .professional-chip {
    min-height: 36px;
    padding: 0 6px 0 16px;
    border: 2px solid var(--color-mauve);
    background: transparent;
    color: var(--color-mauve-dark);
    font-size: 0.88rem;
    font-weight: 600;
}
.historia-cabecera .professional-chip .professional-collegiate { color: var(--color-text-muted); }
.historia-cabecera .professional-chip .chip-x { color: var(--color-mauve-dark); font-size: 1.15rem; }
.historia-cabecera .professional-chip .chip-x:hover { background: rgba(180, 40, 40, 0.12); color: #a12626; }

/* El botón «Fisioterapeuta» (con su icono) va primero y el nombre del fisio a su lado; si son dos, el segundo pasa a la línea
   de abajo (pedido del equipo 14/10/2026). Con el botón desplegado ocupa todo el ancho y los nombres bajan. */
.historia-cabecera .professional-chips { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; }
.historia-cabecera .professional-chips > #asignar-fisioterapeuta { order: -1; }
.historia-cabecera .professional-chips > #asignar-fisioterapeuta[open] { flex-basis: 100%; }
#asignar-fisioterapeuta > summary { display: inline-flex; align-items: center; gap: 6px; }

/* El botón «Fisioterapeuta» queda a la altura de los botones de «Datos de la sesión» aunque debajo lleve el nombre del fisio:
   se alinean por arriba y el panel del fisio reserva el hueco del rótulo «DATOS DE LA SESIÓN» con un rótulo en blanco. */
.historia-cabecera { align-items: flex-start; }
.historia-cabecera .professional-panel::before {
    content: "\00a0";
    display: block;
    margin: 0 0 4px;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
}

/* Las explicaciones junto a los botones, en letra más pequeña que la de los botones (pedido del equipo 13/10/2026). */
.btn-row .explicacion-corta,
.titulo-con-explicacion .explicacion-corta,
.pautas-acciones .explicacion-corta,
.explicacion-corta { font-size: 0.66rem; line-height: 1.3; }

/* El fisio asignado como línea de lista: sin borde ni círculo, solo el nombre y su «×» (pedido del equipo 13/10/2026). */
.historia-cabecera .professional-chip {
    min-height: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    gap: 6px;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--color-mauve-dark);
}
.historia-cabecera .professional-chip .chip-x { padding: 0 6px; }

/* Asistente por voz: botón junto a las secciones y panel con la propuesta (pedido del equipo 13/10/2026). */
.asistente-btn { margin-left: auto; gap: 6px; }
.asistente-btn.is-recording { border-color: var(--color-error-text); color: var(--color-error-text); }
.asistente-panel {
    position: fixed;
    top: 120px;
    right: 24px;
    z-index: 60;
    width: min(420px, 92vw);
    padding: 14px 16px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
    font-size: 0.9rem;
    line-height: 1.4;
}
.asistente-oido { margin: 0 0 6px; color: var(--color-text-muted, #5b6770); font-size: 0.8rem; }
.asistente-mensaje { margin: 0 0 8px; font-weight: 600; color: var(--color-mauve-dark); }
/* Mientras graba: punto rojo que parpadea y barra que se mueve con la voz (si no se mueve, el micro no capta). */
.asistente-nivel { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.asistente-nivel[hidden] { display: none; }
.asistente-punto { width: 10px; height: 10px; border-radius: 50%; background: #d32f2f; flex: none;
    animation: asistente-latido 1s ease-in-out infinite; }
.asistente-barra { flex: 1; height: 8px; border-radius: 4px; background: var(--color-border, #ddd); overflow: hidden; }
.asistente-barra > span { display: block; height: 100%; width: 0; background: var(--color-primary, #2e7d32);
    transition: width 80ms linear; }
@keyframes asistente-latido { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .asistente-punto { animation: none; } }
.asistente-lineas { margin: 0 0 8px; padding-left: 18px; }
.asistente-opciones { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.asistente-texto { display: flex; gap: 8px; margin-top: 8px; }
.asistente-texto input { flex: 1; min-width: 0; padding: 5px 8px; font-size: 0.85rem; }

/* Fecha de registro de cada volante, al lado del número. */
.volante-fecha { color: var(--color-text-muted, #5b6770); font-size: 0.72rem; white-space: nowrap; }

/* La campana de avisos de la ficha, a la derecha de la banda del nombre (dentro del panel no hay barra donde llevarla). */
.record-title .alerts-menu { margin-left: auto; }
.record-title .alerts-menu-panel { z-index: 60; }

/* Campana de avisos en la barra del panel; la de dentro de la ficha se oculta cuando la lleva el panel. */
html.avisos-in-parent .record-title .alerts-menu { display: none; }
.dash-avisos { position: relative; }
.dash-avisos[hidden] { display: none; }
.dash-avisos-btn { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.dash-avisos-btn::-webkit-details-marker { display: none; }
.dash-avisos-panel { right: 0; left: auto; z-index: 70; min-width: 300px; }
.dash-avisos-panel .is-hidden { display: none; }
.dash-avisos { margin-left: 0; }

/* «Leído» junto a cada aviso de la campana. */
.alerts-list li { display: flex; align-items: center; gap: 8px; }
.alerts-list li > a { flex: 1; min-width: 0; }
.alerts-leido { flex: none; border: 1px solid var(--color-border); border-radius: var(--radius-pill); background: var(--color-surface); color: var(--color-mauve-dark); font: inherit; font-size: 0.72rem; font-weight: 600; padding: 2px 10px; cursor: pointer; }
.alerts-leido:hover { background: var(--color-lilac); }

/* Iconos de las citas en semáforo (pedido del equipo 13/10/2026): verde = en orden, amarillo = requiere atención, rojo = urgente. */
.agenda-flag--ok,
.agenda-flag-icon.agenda-flag--ok { color: #2e7d32; }
.agenda-flag--warn,
.agenda-flag-icon.agenda-flag--warn,
.agenda-flag-warn { color: #b26a00; }
.agenda-flag--bad,
.agenda-flag-icon.agenda-flag--bad,
.agenda-flag-pay { color: #b3261e; }
.agenda-flag-consent { background: color-mix(in srgb, #2e7d32 12%, transparent); color: #2e7d32; }

/* PRUEBA (el equipo 13/10/2026; si no gusta, se revierte este commit): el cartel de la subvención más pequeño y «Conoce nuestro centro» más
   ancho (ocupa más ancho de pantalla, la misma altura de foto). */
.grant-frame { max-width: 440px; }
.grant-caption { max-width: 560px; }
.landing-gallery .photo-carousel { max-width: 1100px; }

/* Valoración media y recuento de reseñas de Google, sobre las tarjetas. */
.reviews-summary { display: flex; align-items: baseline; justify-content: center; gap: 10px; margin: 0 0 22px; flex-wrap: wrap; }
.reviews-summary-score { font-family: var(--font-display); font-size: 2.6rem; font-weight: 700; line-height: 1; color: var(--color-dark); }
.reviews-summary-stars { color: #b8864b; letter-spacing: 2px; font-size: 1.1rem; }
.reviews-summary-count { color: var(--color-text-muted); font-size: 0.95rem; }
.reviews-link { text-align: center; margin: 22px 0 0; }

.badge-test {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.1rem 0.5rem;
    border: 1px solid currentColor;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    vertical-align: middle;
    color: #8a5a00;
}

/* Botón «Nota» de las ayudas para escribir: el micrófono con la palabra debajo (14/10/2026). */
.dictation-btn.dictation-btn--note {
    width: auto;
    height: auto;
    min-width: 48px;
    padding: 0.2rem 0.6rem;
    border-radius: 14px;
    flex-direction: column;
    gap: 0.1rem;
}
.dictation-btn__label {
    font-size: 0.7rem;
    line-height: 1;
}

/* Cuerpo humano para marcar la zona tratada (14/10/2026). Las zonas se marcan con doble clic (ficha-cuerpo.js). */
.body-map { margin-bottom: 0.75rem; }
.body-map-svg { width: min(100%, 340px); height: auto; display: block; }
.body-map .base { fill: #e8eef1; stroke: #b4c2c9; stroke-width: 1.2; }
.body-map .base .limb { stroke: #b4c2c9; fill: none; stroke-linecap: round; }
.body-map .base line.limb { stroke: #e8eef1; }
.body-map .zone { fill: rgba(61, 111, 128, 0.14); stroke: var(--color-mauve, #3d6f80); stroke-width: 1.3; cursor: pointer; }
.body-map .zone:hover { fill: rgba(61, 111, 128, 0.38); }
.body-map .zone:focus-visible { outline: 2px solid var(--color-mauve-dark, #2c5563); outline-offset: 2px; }
.body-map .zone.is-on { fill: var(--color-mauve, #3d6f80); }
.body-map-caption { font-size: 11px; fill: var(--color-text-muted, #66777f); }
.body-map-extra { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; justify-content: center; }
.body-map .zone--pill { padding: 4px 14px; border: 2px solid var(--color-mauve, #3d6f80); border-radius: 999px; background: transparent; color: var(--color-mauve-dark, #2c5563); font-weight: 600; font-size: 0.85rem; }
.body-map .zone--pill:hover { background: rgba(61, 111, 128, 0.18); }
.body-map .zone--pill.is-on { background: var(--color-mauve, #3d6f80); color: #fff; }

/* Diagnóstico + ayudas a la izquierda y los dos cuerpos a la derecha (prueba 14/10/2026). En pantallas estrechas se apilan. */
.diagnostico-cuerpo { display: grid; grid-template-columns: minmax(0, 1fr) 250px; gap: 20px; align-items: start; }
.diagnostico-cuerpo__texto { min-width: 0; }
.diagnostico-cuerpo__mapa { padding-top: 22px; }
.diagnostico-cuerpo__mapa .body-map { margin: 0; }
.diagnostico-cuerpo__mapa .body-map-svg { width: 100%; }
.diagnostico-cuerpo__mapa .body-map .zone--pill { padding: 3px 12px; font-size: 0.78rem; }
@media (max-width: 900px) {
    .diagnostico-cuerpo { grid-template-columns: 1fr; }
    .diagnostico-cuerpo__mapa { max-width: 260px; }
}

/* «Téc.»: con varias técnicas marcadas el botón enseña solo el principio de la lista (la completa, al abrirlo) para que
   el botón «Nota» quepa en la misma línea que los demás (14/10/2026). */
.field-disclosure > summary[data-truncate] .field-disclosure-value {
    display: inline-block;
    max-width: 14ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* Tratamiento: con varios, la etiqueta se corta con «…» y el tooltip lleva la lista completa, así la fila de arriba
   (fisioterapeuta, zona, tratamiento, tipo de sesión) no cambia de ancho ni sube o baja el fisioterapeuta. */
#tratamiento-resumen {
    display: inline-block;
    max-width: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* El nombre del fisioterapeuta se corta con «…» si es largo (el nombre completo, en el tooltip): la fila de arriba no se
   descuadra ni el fisioterapeuta sube o baja de línea. */
.historia-cabecera .professional-chip .professional-name {
    max-width: 20ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* «Ayudas para escribir»: «Nota» y el micrófono en una segunda línea fija, con «Nota» debajo de «CIE» (14/10/2026). */
#ayudas-escribir .ayudas-salto { flex-basis: 100%; height: 0; }

/* Datos del paciente en columnas fijas (pedido del equipo 14/10/2026): cada campo ocupa dos columnas de la cuadrícula (etiqueta y
   valor), así las etiquetas con fondo y los valores en negro quedan alineados de una fila a otra. Fila 1: estado, teléfono, DNI y
   código de cliente. Fila 2: código postal, localidad, provincia y dirección. Fila 3: sexo, nacimiento y correo. Un campo vacío deja
   su hueco, así nada se mueve. */
.ficha-resumen .ficha-datos {
    display: grid;
    grid-template-columns: repeat(9, max-content) minmax(0, 1fr);
    column-gap: 8px;
    row-gap: 6px;
    align-items: center;
    width: 100%;
}
.ficha-resumen .ficha-datos .ficha-dato { display: contents; }
.ficha-resumen .ficha-datos .ficha-dato > b { white-space: nowrap; justify-self: start; }
.ficha-resumen .ficha-datos .ficha-dato > span, .ficha-resumen .ficha-datos .ficha-dato > b + span { min-width: 0; }
/* Etiqueta en la columna indicada y valor en la siguiente; las columnas 2, 3 y 4 de campos llevan aire a la izquierda. */
.ficha-dato--estado > b { grid-area: 1 / 1; }
.ficha-dato--estado > span { grid-area: 1 / 2; }
.ficha-dato--telefono > b { grid-area: 1 / 3; margin-left: 18px !important; }
.ficha-dato--telefono > span { grid-area: 1 / 4; }
.ficha-dato--dni > b { grid-area: 1 / 5; margin-left: 18px !important; }
.ficha-dato--dni > span { grid-area: 1 / 6; }
.ficha-dato--codigo > b { grid-area: 1 / 7; margin-left: 18px !important; }
.ficha-dato--codigo > span { grid-area: 1 / 8; }
.ficha-dato--cp > b { grid-area: 2 / 1; }
.ficha-dato--cp > span { grid-area: 2 / 2; }
.ficha-dato--localidad > b { grid-area: 2 / 3; margin-left: 18px !important; }
.ficha-dato--localidad > span { grid-area: 2 / 4; }
.ficha-dato--provincia > b { grid-area: 2 / 5; margin-left: 18px !important; }
.ficha-dato--provincia > span { grid-area: 2 / 6; }
.ficha-dato--direccion > b { grid-area: 2 / 7; margin-left: 18px !important; }
.ficha-dato--direccion > span { grid-area: 2 / 8 / 3 / 11; }
.ficha-dato--sexo > b { grid-area: 3 / 1; }
.ficha-dato--sexo > span { grid-area: 3 / 2; }
.ficha-dato--nacimiento > b { grid-area: 3 / 3; margin-left: 18px !important; }
.ficha-dato--nacimiento > span { grid-area: 3 / 4; }
.ficha-dato--correo > b { grid-area: 1 / 9; margin-left: 18px !important; }
.ficha-dato--correo > span { grid-area: 1 / 10; }
.ficha-resumen #ficha-menor { display: flex; flex-wrap: wrap; gap: 4px 18px; grid-area: 4 / 1 / 5 / 11; }
.ficha-resumen .ficha-dato--codigo code { font-size: 0.85rem; }
/* Móvil (16/10/2026): la cuadrícula de 10 columnas es solo para pantallas anchas; en una estrecha se desbordaba (valores cortados,
   filas enormes). Aquí cada dato va en dos columnas, etiqueta y valor, uno debajo de otro y en el orden del HTML. */
@media (max-width: 720px) {
    .ficha-resumen .ficha-datos { grid-template-columns: max-content minmax(0, 1fr); }
    .ficha-resumen .ficha-datos .ficha-dato > b,
    .ficha-resumen .ficha-datos .ficha-dato > span { grid-area: auto !important; margin-left: 0 !important; }
    .ficha-resumen .ficha-datos .ficha-dato > span { overflow-wrap: anywhere; }
    .ficha-resumen #ficha-menor { grid-area: auto; grid-column: 1 / -1; }
}

/* Historial: «Ver diagnóstico», «Ver evolución» y «Ver detalle» abren una ventanita flotante junto al enlace, sin estirar la fila ni la
   columna; se cierra al sacar el ratón (ficha-popup-historial.js) (14/10/2026). */
.consultation-popup { position: relative; display: inline-block; }
.consultation-popup[open] > .consultation-popup-body {
    position: fixed;
    z-index: 60;
    width: 340px;
    max-width: 70vw;
    margin: 0;
    padding: 10px 14px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #c9d1d6);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    white-space: pre-line;
    overflow-wrap: anywhere;      /* un texto largo sin espacios se parte dentro de la ventana en vez de salirse */
    max-height: 50vh;
    overflow-y: auto;
    font-weight: 400;
    text-align: left;
}
.consultation-popup-body p { margin: 0 0 6px; }

/* Volantes del seguro: se ve el activo (el último) y «Ver todos» abre una ventanita con la lista completa; se cierra al salir con el
   ratón, con un clic fuera o con Escape (14/10/2026). */
.volantes-wrap { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.volantes-wrap .volante-activo { font-size: 0.95rem; }
.volantes-popup {
    position: absolute;
    z-index: 40;
    left: 0;
    top: 100%;
    width: min(100%, 520px);
    padding: 12px 14px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #c9d1d6);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.volantes-popup[hidden] { display: none; }
.volantes-popup .volantes-lista { margin: 0 0 8px; max-height: 260px; overflow-y: auto; }

/* Guardar historial (disquete) en la segunda línea de las ayudas, a ras de «CIE» (14/10/2026). */
#ayudas-escribir .ayudas-guardar { width: 34px; height: 34px; padding: 0; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; }
#ayudas-escribir .ayudas-guardar[disabled] { opacity: 0.5; cursor: not-allowed; }

/* Debajo de «Evolución»: disquete, micrófono y aviso del borrador en una línea (14/10/2026). */
.evolucion-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-top: 6px; }
.evolucion-acciones .dictation-btn { margin: 0; }
.evolucion-acciones .form-hint { margin: 0; }

/* Agenda: «Semana laboral» y «Colores» comparten la tercera columna de la fila de fecha; antes se pisaban (14/10/2026). */
.agenda-daterow .agenda-view-tools {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 8px;
}

.agenda-daterow .agenda-view-tools .view-picker {
    grid-column: auto;
    grid-row: auto;
    justify-self: auto;
}

/* Agenda: la barra de arriba (inicio, buscador, «+ Crear», fisioterapeuta) y la fila de la fecha se quedan fijas al bajar
   por la agenda (pedido del equipo 14/10/2026). La altura de la barra la mide agenda-sticky.js para que la fecha quede justo debajo. */
.agenda-nav {
    position: sticky;
    top: 0;
    z-index: 70;
    background: var(--color-bg);
}

.agenda-daterow {
    position: sticky;
    top: var(--agenda-nav-h, 56px);
    z-index: 65;
    background: var(--color-bg);
    padding-bottom: 6px;
}

/* Glosario de iconos de la agenda, en grupos: icono a la izquierda en una columna fija y la explicación a la derecha. */
.agenda-glossary-list {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px 28px;
    margin: 6px 0 0;
    padding: 12px 16px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md, 10px);
}

.agenda-gl-semaforo,
.agenda-gl-tip {
    grid-column: 1 / -1;
    margin: 0;
}

.agenda-gl-group h4 {
    margin: 0 0 6px;
    font-size: var(--text-xs, 0.75rem);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

.agenda-gl-group ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 8px;
}

.agenda-gl-group li {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    align-items: start;
    gap: 10px;
    line-height: 1.35;
}

.agenda-gl-ico {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 1.6rem;
}

@media (max-width: 1100px) {
    .agenda-glossary-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
    .agenda-glossary-list { grid-template-columns: minmax(0, 1fr); }
}

.agenda-gl-group .agenda-flag,
.agenda-gl-group .agenda-status { margin: 0; }
.agenda-gl-group em .agenda-flag { font-size: inherit; }

/* Relación mensual de ingresos y egresos: el selector de mes (← mes Ver mes →) va alineado y con la misma letra y altura que los botones
   (el campo de mes salía más arriba y con tipografía del navegador; 14/10/2026). */
#month-form {
    align-items: center;
}

#month-form input[type="month"] {
    font: inherit;
    height: var(--control-md, 38px);
    padding: 0 var(--space-4, 14px);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-text);
}

#month-form .btn-action {
    height: var(--control-md, 38px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0;
}

#month-form a.btn-action { min-width: 46px; color: var(--color-primary, #3f7a8c); }
#month-form a.btn-action svg { display: block; }

/* Relación mensual: el resumen (tabla estrecha) y, a su derecha, el gráfico de ingresos y egresos por semanas (14/10/2026). */
.resumen-grid {
    display: grid;
    grid-template-columns: minmax(280px, 400px) minmax(0, 1fr);
    gap: 24px;
    align-items: start;
}

.resumen-chart {
    margin: 0;
}

.resumen-chart-svg {
    width: 100%;
    height: auto;
    display: block;
}

.resumen-chart .bar-ingresos { fill: var(--color-primary, #3f7a8c); }
.resumen-chart .bar-egresos { fill: var(--color-mauve, #b3739a); }
.resumen-chart .chart-axis { stroke: var(--color-border); stroke-width: 1; }
.resumen-chart .chart-text { fill: var(--color-text-muted); font-size: 12px; font-family: inherit; }

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

/* Vista previa de un informe en ventana pequeña (botón «Ver»). */
.informe-vista-main { padding: 16px 20px 24px; }
.informe-vista-main h1 { font-size: 1.2rem; margin: 0 0 12px; }
.informe-vista-scroll { overflow: auto; max-height: calc(100vh - 150px); margin-top: 12px; }
.informe-vista .data-table { font-size: 0.85rem; }

/* Zoom de la agenda: lupa (ajustar) y + / − junto a «Colores» (pedido del equipo 14/10/2026). */
.agenda-zoom {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    overflow: hidden;
}

.agenda-zoom[hidden] { display: none; }

.agenda-zoom-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--control-sm, 30px);
    min-width: 32px;
    padding: 0 8px;
    border: 0;
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
}

.agenda-zoom-btn + .agenda-zoom-btn { border-left: 1px solid var(--color-border); }
.agenda-zoom-btn:hover { background: var(--color-lilac, #eef3f5); color: var(--color-text); }
.agenda-zoom-btn:focus-visible { outline: 2px solid var(--color-primary, #3f7a8c); outline-offset: -2px; }
.agenda-zoom-btn .icon { width: 16px; height: 16px; }
.agenda-zoom-pct { min-width: 3.9rem; font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ── Agenda más compacta en alto (pedido del equipo 14/10/2026): más sitio para las citas ───────────────────────────── */

/* Cabecera del panel (logo, hora, usuario) y pestañas de sección. */
body.dashboard-page .topbar { padding: 6px 32px; gap: 8px; }
body.dashboard-page .topbar .brand { font-size: 1.05rem; }
body.dashboard-page .dashboard-workspace { margin-top: 6px; }
body.dashboard-page .dashboard-tabs { margin-bottom: 6px; gap: 6px; }
body.dashboard-page .dashboard-tab { padding: 3px 12px; font-size: 0.82rem; }

/* La agenda (dentro del panel y suelta): barra de herramientas y fila de la fecha, con controles de 30 px. */
.agenda-nav,
.agenda-daterow {
    --control-md: 30px;
    --control-sm: 26px;
}

.agenda-nav { padding-top: 4px; padding-bottom: 4px; gap: 8px; }
.agenda-search { padding: 2px 10px; }
.agenda-daterow { gap: 8px; padding-bottom: 2px; }
.agenda-daterow .calendar-month-label { font-size: 1.05rem; }
.agenda-daterow .calendar-step-btn { width: 28px; height: 28px; font-size: 1rem; }
.agenda-daterow .calendar-today { padding: 3px 14px; font-size: 0.82rem; }
.page-content:has(.agenda-daterow) { margin-top: 6px; padding-bottom: 12px; }
.page-content:has(.agenda-daterow) .agenda-week { margin-top: 2px; }

/* Glosario de iconos como desplegable al lado de «Hoy». */
.agenda-daterow .agenda-glossary-pop { grid-column: 1; grid-row: 1; justify-self: start; margin-left: 76px; align-self: center; }
.agenda-glossary-menu { width: min(1080px, calc(100vw - 96px)); max-height: 70vh; overflow: auto; }
.agenda-glossary-menu .agenda-glossary-list { margin: 0; border: 0; padding: 4px; box-shadow: none; }

/* Citas de 30 minutos: nombre visible en una sola línea (iconos y nombre; la hora ya está en el eje y se ve al ampliar la cita). */
.agenda-day > .agenda-block.h-1:not(.is-expanded) {
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    gap: 6px;
    padding-right: 2.4rem;
}

.agenda-day > .agenda-block.h-1:not(.is-expanded) .agenda-block-head {
    flex: 0 0 auto;
    padding-right: 0;
    flex-wrap: nowrap;
}

.agenda-day > .agenda-block.h-1:not(.is-expanded) > .agenda-block-who {
    flex: 1 1 auto;
    min-width: 0;
    text-align: left;
}

/* Con la agenda muy reducida, la hora se esconde para que quepa el nombre. */
@container (max-width: 230px) {
    .agenda-day > .agenda-block.h-1:not(.is-expanded) .agenda-block-time { display: none; }
}

/* Zoom: la lupa se marca cuando la agenda está en su tamaño por defecto (ajustada al día completo). */
.agenda-zoom-btn.is-active { background: var(--color-primary, #3f7a8c); color: #fff; }
.agenda-zoom-btn.is-active:hover { background: var(--color-primary, #3f7a8c); color: #fff; }

/* Si la columna es muy estrecha, el nombre manda: se esconden también los iconos de la línea (siguen en la cita desplegada). */
@container (max-width: 170px) {
    .agenda-day > .agenda-block.h-1:not(.is-expanded) .agenda-block-flags { display: none; }
}

/* Citas de más de 30 minutos (privados): el nombre nunca se encoge hasta desaparecer; si falta altura, se esconden antes el
   fisioterapeuta y la zona/tratamiento (siguen en la cita desplegada). Antes el nombre quedaba a 0 de alto (14/10/2026). */
.agenda-day > .agenda-block > .agenda-block-head,
.agenda-day > .agenda-block > .agenda-block-who { flex: 0 0 auto; }

.agenda-week.is-dense .agenda-day > .agenda-block:not(.h-1):not(.is-expanded) .agenda-block-prof,
.agenda-week.is-dense .agenda-day > .agenda-block:not(.h-1):not(.is-expanded) .agenda-block-tags,
.agenda-week.is-dense .agenda-day > .agenda-block:not(.h-1):not(.is-expanded) .agenda-block-insurer { display: none; }

.ficha-dato--falta > span { color: #b42318; font-weight: 600; }

.ficha-pago-acciones { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
#datos-facturacion, #cobro-manual { margin: 14px 0; }
#datos-facturacion > summary, #cobro-manual > summary { cursor: pointer; font-weight: 600; margin-bottom: 8px; }
#datos-facturacion form, #cobro-manual form { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: flex-end; margin-top: 10px; }
#datos-facturacion label, #cobro-manual label { display: flex; flex-direction: column; gap: 4px; font-size: 0.9rem; }

.payment-row-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px 10px; }
.payment-row-actions .inline-details { margin: 0; }

.data-table td details { margin-top: 8px; }
/* inline-flex, como el resto de .btn-action: con inline-block el texto se quedaba arriba (la altura es fija). */
.data-table td details > summary.btn-action { display: inline-flex; }
/* En una columna de acciones el hueco lo pone .cell-actions (gap); el margen de arriba lo duplicaba. */
.data-table td .cell-actions > details { margin-top: 0; }

#cobro-rapido > summary { cursor: pointer; font-weight: 600; }
.cobro-rapido-form { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: flex-end; margin-top: 12px; }
.cobro-rapido-form label { display: flex; flex-direction: column; gap: 4px; font-size: 0.9rem; }

/* Webcam del PC para «Hacer foto» (camara-web.js, 16/10/2026): ventana centrada sobre un fondo oscuro. */
.camara-web { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
    background: rgba(15, 23, 28, 0.78); padding: 16px; }
.camara-web__caja { background: var(--color-surface, #fff); border-radius: 12px; padding: 14px; max-width: min(92vw, 880px);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35); }
/* Visor con marco guía A4: el recuadro se coloca desde camara-web.js; lo de fuera se oscurece con una sombra enorme. */
.camara-web__visor { position: relative; overflow: hidden; border-radius: 8px; background: #000; line-height: 0; }
.camara-web__video { display: block; width: 100%; max-height: 70vh; background: #000; }
.camara-web__marco { position: absolute; border: 2px solid #fff; box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.55); pointer-events: none; }
.camara-web__marco[hidden] { display: none; }
.camara-web__opciones { display: flex; gap: 14px; align-items: center; justify-content: center; margin-top: 10px; flex-wrap: wrap; }
.camara-web__completa { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
.camara-web__botones { display: flex; gap: 10px; justify-content: center; align-items: center; margin-top: 12px; }
.camara-web__botones button { margin: 0; }

/* Etiquetas con lo anotado al lado del título de cada apartado de antecedentes (se ven con el apartado plegado). */
.ficha-chips { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: 10px; vertical-align: middle; font-weight: 400; }
/* Más pequeñas que el título y de aspecto aparte: son los elementos anotados (alergias, fármacos…), no parte del título. */
.ficha-chips .cie-chip { font-family: var(--font-body, inherit); font-size: 0.74rem; line-height: 1.2; padding: 1px 3px 1px 8px;
  gap: 2px; color: var(--color-text, inherit); background: rgba(61, 120, 139, 0.07); }
.ficha-chips .chip-x { font-size: 0.8rem; padding: 0 5px; line-height: 1; }
.card-panel:not(.is-collapsed) > h3 > .ficha-chips { display: none; }
.btn-guardar-seccion { margin-top: 8px; }
