/* ============================================================
   DENTAL CLINIC CABARETE — Sistema de Gestión
   Diseño basado en Stitch UI: dark sidebar + clean white content
   ============================================================ */

/* ── Fuente Inter, servida desde el propio servidor ──
   Copia local de la entrada "inter" de app/Config/Librerias.php, donde está
   su versión. Es la fuente variable (grosores de 100 a 900) con dos
   subconjuntos: el navegador baja el latino extendido solo si la página
   tiene alguno de sus caracteres (unicode-range). La dirección del latino
   coincide con su precarga del parcial de librerías. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('../vendor/inter/inter-latin-ext-wght-normal.woff2') format('woff2');
    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: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('../vendor/inter/inter-latin-wght-normal.woff2') format('woff2');
    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;
}

/* ── CSS Variables ── */
:root {
    /* Color de la marca y sus tonos (F6-50; LAYO-21). Son los de
       marca_tonos() de app/Helpers/avatar_helper.php con el color de fábrica
       de clinica.color_primario: el layout los reemplaza con el de la
       clínica (bloque #marca-clinica), y las reglas solo usan las variables.
       --primary-dark es también el texto sobre --primary-xlight (4,5:1 o
       más); --primary-light, solo fondos y bordes. */
    --primary:           #1565C0;
    --primary-rgb:       21, 101, 192;
    --primary-dark:      #11519A;
    --primary-dark-rgb:  17, 81, 154;
    --primary-light:     #176FD2;
    --primary-xlight:    #E3EFFC;
    --accent:         #00838F;
    --accent-light:   #E0F7FA;
    --success:        #2E7D32;
    --warning:        #E65100;
    --danger:         #C62828;
    --info:           #0277BD;
    /* Texto sobre los fondos claros de insignias y avisos, con contraste de
       4,5:1 o más (LAYO-15). --warning e --info quedan para iconos y bordes:
       como texto sobre su fondo claro se quedan en 3,57:1 y 4,20:1.
       --warning-texto: 5,11:1 sobre #FFF8E1 y 5,43:1 sobre blanco (también
       como fondo con texto blanco); --info-texto: 6,48:1 sobre #E3F2FD;
       --neutro-texto: 6,92:1 sobre #F1F5F9. */
    --warning-texto:  #B54708;
    --info-texto:     #01579B;
    --neutro-texto:   #475569;

    /* Dibujo del diente de la marca (.icono-diente) */
    --icono-diente: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M5 1.25C3.2 1.25 2 2.6 2 4.45c0 1.2.35 2.1.7 3.25.4 1.35.5 2.75.8 4.15.25 1.2.6 2.9 1.6 2.9.9 0 1.05-1.2 1.25-2.3.2-1.15.5-2.2 1.65-2.2s1.45 1.05 1.65 2.2c.2 1.1.35 2.3 1.25 2.3 1 0 1.35-1.7 1.6-2.9.3-1.4.4-2.8.8-4.15.35-1.15.7-2.05.7-3.25C14 2.6 12.8 1.25 11 1.25c-1.2 0-1.8.6-3 .6s-1.8-.6-3-.6z'/%3E%3C/svg%3E");

    --sidebar-bg:     #1A1D21;
    --sidebar-w:      220px;
    --sidebar-w-iconos: 64px;   /* menú plegado a barra de iconos (tableta) */
    --sidebar-text:   #9CA3AF;
    --sidebar-hover:  rgba(255,255,255,0.08);
    --sidebar-active: rgba(var(--primary-rgb), 0.25);
    --sidebar-active-border: var(--primary);

    --bg:             #F4F6F9;
    --white:          #FFFFFF;
    --border:         #E2E8F0;
    --border-light:   #F1F5F9;
    --text-dark:      #111827;
    --text-mid:       #4B5563;
    /* Texto secundario (subtítulos, códigos, .text-muted). Contraste de
       5,43:1 sobre #FFFFFF, 5,01:1 sobre el fondo #F4F6F9 y 4,95:1 sobre
       #F1F5F9 (LAYO-15: el #9CA3AF anterior daba 2,54:1, y #6B7280 no basta,
       4,47:1 sobre #F4F6F9). */
    --text-light:     #5F6B7A;
    /* Anillo de foco: sobre fondo claro (el color de la marca) y sobre el menú oscuro */
    --foco:           var(--primary);
    --foco-oscuro:    #90CAF9;

    /* Bootstrap con el color de la marca (F6-50): sus utilidades
       (.bg-primary, .border-primary, .link-primary…) y sus enlaces */
    --bs-primary:              var(--primary);
    --bs-primary-rgb:          var(--primary-rgb);
    --bs-link-color:           var(--primary);
    --bs-link-color-rgb:       var(--primary-rgb);
    --bs-link-hover-color:     var(--primary-dark);
    --bs-link-hover-color-rgb: var(--primary-dark-rgb);

    /* Cabecera fija de la página (F4-30). --topbar-barra-h: alto de la barra
       superior. --aviso-conexion-h: alto de la franja roja de WhatsApp
       desconectado mientras va fija encima de la barra; 0 sin franja (lo
       anota el script que acompaña a la franja en el layout). --topbar-h es
       la suma, lo que la cabecera ocupa arriba de la ventana: con ella
       colocan las vistas lo que va pegado debajo de la cabecera. */
    --topbar-barra-h: 60px;
    --aviso-conexion-h: 0px;
    --topbar-h:       calc(var(--topbar-barra-h) + var(--aviso-conexion-h));
    --radius:         10px;
    --radius-sm:      6px;
    --shadow:         0 1px 4px rgba(0,0,0,0.08);
    --shadow-md:      0 4px 16px rgba(0,0,0,0.10);
    --shadow-lg:      0 8px 32px rgba(0,0,0,0.14);
    --transition:     all 0.2s ease;
}

/* ── Reset & Base ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Ventanas <dialog>: el navegador las centra con `margin: auto` y el reset de
   arriba se lo quitaba (se abrían pegadas a la esquina superior izquierda).
   Se repone para cualquier <dialog> de la aplicación; el ancho, el relleno y
   el borde los pone cada una. */
dialog { margin: auto; }
html { font-size: 14px; scroll-behavior: smooth; }
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    background: var(--bg);
    color: var(--text-dark);
    line-height: 1.5;
    min-height: 100vh;
}
a { text-decoration: none; color: var(--primary); transition: var(--transition); }
a:hover { color: var(--primary-dark); }
img { max-width: 100%; }

/* ── Layout ── */
.app-layout {
    display: flex;
    min-height: 100vh;
}

/* ── Sidebar ──
   Altura completa de la ventana visible (100dvh; 100vh donde no hay dvh):
   la marca y el pie quedan fijos y la lista de opciones se desplaza por
   dentro (LAYO-17). Si la ventana es tan baja que ni así cabe, se desplaza
   el menú entero. */
.sidebar {
    width: var(--sidebar-w);
    background: var(--sidebar-bg);
    height: 100vh;
    height: 100dvh;
    position: fixed;
    top: 0; left: 0;
    display: flex;
    flex-direction: column;
    z-index: 1000;
    transition: var(--transition);
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
}
.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 18px 16px;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    text-decoration: none;
}
.sidebar-brand-icon {
    width: 36px; height: 36px;
    background: var(--primary);
    border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    font-size: 18px; color: #fff;
    flex-shrink: 0;
}
/* Diente de la marca (menú lateral, inicio de sesión y odontograma).
   Bootstrap Icons no trae ninguno: se dibuja aquí con una máscara, sin cargar
   nada de fuera, y se comporta como un icono de la fuente: mide 1em y toma el
   color del texto, así que se ve igual con el menú plegado y desplegado. */
.icono-diente {
    display: inline-block;
    flex-shrink: 0;
    width: 1em; height: 1em;
    vertical-align: -.125em;
    background-color: currentColor;
    -webkit-mask: var(--icono-diente) center / contain no-repeat;
            mask: var(--icono-diente) center / contain no-repeat;
}
/* Logo de la clínica (F6-50), en lugar del diente: del mismo tamaño, sobre
   blanco para que se vea en el menú oscuro, y entero aunque no sea cuadrado */
.sidebar-brand-logo {
    width: 36px; height: 36px;
    padding: 3px;
    background: #fff;
    border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
}
.sidebar-brand-logo img { display: block; width: 100%; height: 100%; object-fit: contain; }
.sidebar-brand-text { flex: 1; min-width: 0; }
/* Nombre corto o comercial de la clínica (F6-50): hasta dos líneas, partiendo
   la palabra que no cabe; el nombre entero está en el title del enlace */
.sidebar-brand-name {
    font-size: 13px; font-weight: 700; line-height: 1.3;
    color: #fff;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}
.sidebar-nav {
    flex: 1 1 auto;
    min-height: 96px;
    padding: 4px 0 12px;
    overflow-y: auto;
    overscroll-behavior: contain;
}
.sidebar-nav::-webkit-scrollbar { width: 4px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; }
.sidebar-brand, .sidebar-footer { flex-shrink: 0; }

/* Secciones del menú (Clínica, Pacientes, Finanzas, Administración: app/Config/Menu.php) */
.nav-section-title {
    padding: 12px 19px 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--sidebar-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.nav-link-text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.nav-item { display: block; }
.nav-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    color: var(--sidebar-text);
    font-size: 13px;
    font-weight: 500;
    border-left: 3px solid transparent;
    transition: var(--transition);
    border-radius: 0;
    text-decoration: none;
    cursor: pointer;
}
.nav-link i { font-size: 16px; width: 18px; flex-shrink: 0; }
.nav-link:hover {
    background: var(--sidebar-hover);
    color: #fff;
    text-decoration: none;
}
.nav-link.active {
    background: var(--sidebar-active);
    color: #fff;
    border-left-color: var(--sidebar-active-border);
}
/* Foco con teclado en el menú oscuro (LAYO-15): anillo claro por dentro del
   enlace, que no se corta con el borde del menú */
.sidebar a:focus-visible,
.sidebar button:focus-visible,
.sidebar .nav-link:focus-visible {
    outline: 2px solid var(--foco-oscuro);
    outline-offset: -2px;
    box-shadow: none;
}
.sidebar .nav-link:focus-visible {
    background: var(--sidebar-hover);
    color: #fff;
}
.sidebar-footer {
    padding: 12px 16px;
    border-top: 1px solid rgba(255,255,255,0.08);
}
.sidebar-user {
    display: flex; align-items: center; gap: 10px;
}
.sidebar-user-avatar {
    width: 34px; height: 34px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: #fff;
    flex-shrink: 0;
}
/* El nombre del usuario se parte en varias líneas en lugar de cortarse con
   puntos suspensivos (F6-49): «Administrador Sistema» se leía a medias a
   1280 px. Una palabra que no cabe (un nombre largo sin espacios) se parte
   donde haga falta, sin empujar el botón de salir. */
.sidebar-user-name {
    font-size: 12px; font-weight: 600; color: #fff;
    line-height: 1.3; overflow-wrap: anywhere;
}
.sidebar-user-role {
    font-size: 11px; color: var(--sidebar-text);
}
.sidebar-user-texto { flex: 1 1 auto; min-width: 0; }
/* Botón de salir del pie del menú (su aspecto está en el layout): objetivo
   de 24 px como mínimo, 44 px con pantalla táctil (más abajo) */
.btn-salir { flex-shrink: 0; min-width: 24px; min-height: 24px; }

/* ── Main Content ── */
.main-content {
    margin-left: var(--sidebar-w);
    flex: 1;
    min-width: 0;          /* critical: prevents flex child from overflowing */
    /* Recorta lo que se salga a lo ancho antes de que llegue a la ventana.
       Con `clip` y no `hidden`: `hidden` convierte la caja en un contenedor
       con desplazamiento y anula `position: sticky` de lo que lleva dentro
       (la barra superior y el aviso de modo de la agenda dejaban de quedarse
       fijos al desplazar la página). Un navegador sin `clip` se queda con
       `hidden`, como antes. */
    overflow-x: hidden;
    overflow-x: clip;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* ── Topbar ──
   Fija arriba al desplazar la página; con la franja de WhatsApp
   desconectado, justo debajo de ella (--aviso-conexion-h, 0 sin franja). */
.topbar {
    height: var(--topbar-barra-h);
    background: var(--white);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    padding: 0 24px;
    gap: 12px;
    position: sticky;
    top: var(--aviso-conexion-h);
    z-index: 100;
    box-shadow: var(--shadow);
}

/* ── Aviso de WhatsApp desconectado (F4-30; EVOL-7, AUTO-2) ──
   canal/_aviso_conexion.php, que el layout pone el primero de
   .main-content: franja roja encima de la barra superior, en todas las
   pantallas, mientras la línea lleva caída alertas.desconexion_min o más.
   Ocupa su sitio en la página, así que no tapa nada, y se queda arriba al
   desplazarla: la barra superior se pega justo debajo y, con --topbar-h,
   también lo que las vistas colocan bajo la cabecera (el aviso de modo de
   la agenda, la cabecera fija del paciente, el alto de la bandeja de
   conversaciones y el panel de la campana en el teléfono). Si el alto no
   llega a anotarse, la franja queda detrás de la barra al desplazar.
   El icono, el texto y el enlace van seguidos, como una frase: en una línea
   si caben y en varias si no, sin desbordar a lo ancho.
   Texto blanco sobre --danger: contraste de 5,62:1. */
.aviso-conexion {
    position: sticky;
    top: 0;
    z-index: 99;
    flex-shrink: 0;
    padding: 8px 24px;
    background: var(--danger);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    text-align: center;
    overflow-wrap: anywhere;
}
.aviso-conexion-icono { margin-right: 4px; font-size: 14px; }

/* Franja de pacientes que esperan a una persona (app.js, campanaAvisos; 2026-10-28):
   sale arriba en todas las pantallas mientras haya una conversación derivada que nadie tomó */
.aviso-persona {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px 12px;
    padding: 10px 24px;
    background: var(--danger);
    color: #fff;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.4;
    text-align: center;
    animation: aviso-persona-pulso 1.6s ease-in-out 3;
}
.aviso-persona-icono { font-size: 18px; }
.aviso-persona-detalle { font-weight: 500; opacity: .95; }
.aviso-persona-enlace {
    padding: 4px 14px;
    border-radius: 999px;
    background: #fff;
    color: var(--danger);
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}
.aviso-persona-enlace:hover, .aviso-persona-enlace:focus-visible { background: #ffe9e9; color: var(--danger); }
@keyframes aviso-persona-pulso { 0%, 100% { filter: none; } 50% { filter: brightness(1.25); } }
@media (prefers-reduced-motion: reduce) { .aviso-persona { animation: none; } }
.aviso-conexion-enlace,
.aviso-conexion-nota { margin-left: 6px; }
.aviso-conexion-nota { font-weight: 500; }
.aviso-conexion-enlace {
    color: #fff;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 2px;
    white-space: nowrap;
}
.aviso-conexion-enlace:hover { color: #fff; text-decoration-thickness: 2px; }
/* Foco blanco: el anillo azul general no se distingue sobre el rojo */
.aviso-conexion-enlace:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
    border-radius: 2px;
}
/* Ventana baja (teléfono en horizontal): la franja fija dejaría muy poco
   sitio a la página. Pasa debajo de la barra superior y se va con el
   contenido al desplazar; la cabecera vuelve a ser solo la barra. */
@media (max-height: 599.98px) {
    :root { --aviso-conexion-h: 0px !important; }
    .aviso-conexion { position: static; }
    .aviso-conexion ~ .topbar { order: -1; }
}
/* ── Búsqueda global (F2-09, LAYO-16, LAYO-18) ──
   partials/busqueda_global.php. En tableta y escritorio, caja en el
   encabezado con la lista de resultados desplegada debajo. En el teléfono
   (bloque «Teléfono» de la búsqueda, más abajo), la caja no sale: la lupa
   .busqueda-abrir la abre a pantalla completa (.abierta).
   El campo va a 16 px en todos los anchos (PRUEBAS 4.2, letraPequena). */
/* La caja crece primero hasta 400 px y el hueco (.topbar-spacer, base 0)
   se queda con el resto: en tableta, con el nombre del usuario a la
   derecha, la caja no se reparte el sitio con el hueco. Si falta sitio,
   encoge solo la caja: los botones y las acciones mantienen su tamaño. */
.topbar-search {
    position: relative;
    flex: 1 1 400px;
    min-width: 0;
    max-width: 400px;
}
@media (min-width: 768px) {
    .topbar > .topbar-icon-btn,
    .topbar-actions { flex-shrink: 0; }
}
.busqueda-form {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
}
.topbar-search .input-group {
    flex: 1;
    flex-wrap: nowrap;
    min-width: 0;
    border-radius: 20px;
    overflow: hidden;
}
.topbar-search .form-control {
    min-width: 0;
    border-radius: 20px 0 0 20px;
    border-right: none;
    background: var(--bg);
    border-color: var(--border);
    font-size: 16px;
    padding: 5px 16px;
}
.topbar-search .form-control:focus {
    box-shadow: none;
    border-color: var(--primary);
    background: #fff;
    /* Por dentro: el grupo recorta lo que sale de sus bordes redondeados */
    outline: 2px solid var(--foco);
    outline-offset: -2px;
}
.topbar-search .btn {
    border-radius: 0 20px 20px 0;
    background: var(--bg);
    border-color: var(--border);
    border-left: none;
    color: var(--text-mid);
}
.topbar-search .btn:hover { color: var(--primary); background: var(--primary-xlight); }
/* El grupo recorta el anillo exterior: el de la lupa va por dentro */
.topbar-search .btn:focus-visible { outline-offset: -3px; }
/* Lupa del teléfono y flecha de volver: solo en el teléfono */
.topbar-icon-btn.busqueda-abrir,
.busqueda-cerrar { display: none; }

/* Lista de resultados, desplegada bajo la caja */
.busqueda-panel {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 1050;
    width: max(100%, 420px);
    max-width: calc(100vw - 32px);
    max-height: min(70vh, 480px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 6px;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}
.busqueda-mensaje {
    padding: 10px 12px;
    font-size: 13px;
    color: var(--text-mid);
    overflow-wrap: anywhere;
}
.busqueda-grupo + .busqueda-grupo {
    margin-top: 4px;
    padding-top: 4px;
    border-top: 1px solid var(--border-light);
}
/* Sin mayúsculas por CSS: el navegador las pasa al nombre del grupo y
   algunos lectores de pantalla deletrean las palabras en mayúsculas */
.busqueda-grupo-titulo {
    padding: 8px 10px 4px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .2px;
    color: var(--text-light);
}
.busqueda-opcion {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    color: var(--text-dark);
    cursor: pointer;
}
.busqueda-opcion:hover,
.busqueda-opcion.activa {
    background: var(--primary-xlight);
    color: var(--text-dark);
}
/* La opción elegida con las flechas: el foco sigue en la caja, el anillo
   marca la opción (aria-activedescendant) */
.busqueda-opcion.activa {
    outline: 2px solid var(--foco);
    outline-offset: -2px;
}
.busqueda-avatar {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--primary);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
}
.busqueda-datos {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
    overflow-wrap: anywhere;
}
.busqueda-nombre { font-size: 14px; font-weight: 600; line-height: 1.3; }
.busqueda-meta { font-size: 12px; color: var(--text-light); }
.busqueda-proxima { font-size: 12px; font-weight: 500; color: var(--primary); }
/* Paciente dado de baja (F2-36): atenuado, sin que el texto pierda contraste, y con su etiqueta */
.busqueda-inactivo .busqueda-avatar { filter: grayscale(1); opacity: .55; }
.busqueda-inactivo .busqueda-nombre { font-weight: 500; color: var(--text-mid); }
.busqueda-baja { font-weight: 600; color: var(--text-mid); }
.busqueda-cuando {
    display: flex;
    flex: 0 0 76px;
    flex-direction: column;
    align-items: center;
    padding: 4px 2px;
    border-radius: var(--radius-sm);
    background: var(--border-light);
    line-height: 1.2;
    text-align: center;
}
.busqueda-dia { font-size: 11px; font-weight: 600; color: var(--text-mid); }
.busqueda-hora { font-size: 14px; font-weight: 700; color: var(--text-dark); }
.busqueda-estado { flex: 0 0 auto; }
.busqueda-ver-lista { color: var(--primary); font-weight: 600; }
.busqueda-ver-lista:hover,
.busqueda-ver-lista.activa { color: var(--primary-dark); }
.busqueda-ver-lista .bi { flex: 0 0 34px; text-align: center; font-size: 16px; }

.topbar-spacer { flex: 1 1 0; }
.topbar-actions {
    display: flex; align-items: center; gap: 8px;
}
.topbar-icon-btn {
    width: 36px; height: 36px;
    border: none; background: none;
    border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    color: var(--text-mid);
    font-size: 18px;
    cursor: pointer;
    transition: var(--transition);
    position: relative;
}
.topbar-icon-btn:hover { background: var(--bg); color: var(--primary); }
/* Con texto (el selector de idioma) el botón crece en vez de desbordarse */
.topbar-icon-btn.dropdown-toggle { width: auto; min-width: 36px; padding: 0 8px; }
.topbar-icon-btn .badge-dot {
    position: absolute; top: 6px; right: 6px;
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--danger);
    border: 2px solid #fff;
}
/* Disparador del menú de usuario: es un <button> (LAYO-15) que se ve como antes */
.topbar-user {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 8px;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    text-align: inherit;
    border-radius: 8px;
    cursor: pointer;
    transition: var(--transition);
}
.topbar-user:hover { background: var(--bg); }
.topbar-user-avatar {
    width: 34px; height: 34px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: #fff;
}
/* Un nombre o un rol muy largos no le quitan el sitio a la búsqueda global
   (F6-51): se cortan con puntos suspensivos. El nombre entero está en el
   aria-label del botón y en el title, y en el menú lateral se parte en
   varias líneas (F6-49) */
.topbar-user-info { text-align: right; min-width: 0; max-width: 180px; }
.topbar-user-name { font-size: 13px; font-weight: 600; color: var(--text-dark); }
.topbar-user-role { font-size: 11px; color: var(--text-light); }
.topbar-user-name,
.topbar-user-role { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Page Content ── */
.page-content {
    flex: 1;
    padding: 24px;
}
.page-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 24px; flex-wrap: wrap; gap: 12px;
}
.page-title { font-size: 22px; font-weight: 700; color: var(--text-dark); }
.page-subtitle { font-size: 13px; color: var(--text-light); margin-top: 2px; }

/* ── Cards ── */
.card {
    background: var(--white);
    border-radius: var(--radius);
    border: 1px solid var(--border);
    box-shadow: var(--shadow);
    overflow: hidden;
}
.card-header {
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 8px 12px;   /* en anchos estrechos los botones bajan de línea en vez de cortarse */
    background: var(--white);
}
.card-title {
    font-size: 14px; font-weight: 600; color: var(--text-dark);
    margin: 0;
}
.card-body { padding: 20px; }
.card-footer {
    padding: 12px 20px;
    border-top: 1px solid var(--border);
    background: var(--border-light);
}

/* ── KPI Cards ── */
.kpi-card {
    background: var(--white);
    border-radius: var(--radius);
    border: 1px solid var(--border);
    padding: 20px;
    box-shadow: var(--shadow);
    transition: var(--transition);
}
.kpi-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.kpi-header { display: flex; align-items: flex-start; justify-content: space-between; }
.kpi-label { font-size: 12px; font-weight: 500; color: var(--text-light); text-transform: uppercase; letter-spacing: 0.5px; }
.kpi-icon {
    width: 40px; height: 40px; border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px;
}
.kpi-icon.blue   { background: var(--primary-xlight); color: var(--primary); }
.kpi-icon.teal   { background: var(--accent-light); color: var(--accent); }
.kpi-icon.green  { background: #E8F5E9; color: var(--success); }
.kpi-icon.orange { background: #FFF3E0; color: var(--warning); }
.kpi-icon.red    { background: #FFEBEE; color: var(--danger); }

.kpi-value { font-size: 26px; font-weight: 700; color: var(--text-dark); margin: 8px 0 4px; }
.kpi-delta { font-size: 12px; display: flex; align-items: center; gap: 4px; }
.kpi-delta.up { color: var(--success); }
.kpi-delta.down { color: var(--danger); }
.kpi-delta.neutral { color: var(--text-light); }
.kpi-alert { font-size: 12px; color: var(--danger); display: flex; align-items: center; gap: 4px; }

/* ── Tables ──
   La tabla ancha se desplaza en horizontal dentro de su contenedor en
   cualquier ancho (LAYO-7). El redondeo lo pone la tarjeta (.card, con
   overflow: hidden), no el contenedor de la tabla. */
.table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table { margin: 0; font-size: 13px; }
.table thead th {
    background: var(--border-light);
    font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.5px;
    color: var(--text-mid);
    border-bottom: 1px solid var(--border);
    padding: 10px 16px;
    white-space: nowrap;
}
.table tbody td {
    padding: 12px 16px;
    vertical-align: middle;
    border-bottom: 1px solid var(--border-light);
    color: var(--text-dark);
}
.table tbody tr:hover { background: var(--border-light); }
.table tbody tr:last-child td { border-bottom: none; }

/* ── Patient Avatar ── */
.patient-avatar {
    width: 36px; height: 36px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: #fff;
    flex-shrink: 0;
}
.patient-name { font-weight: 600; font-size: 13px; }
.patient-id { font-size: 11px; color: var(--text-light); }

/* ── Badges ──
   Texto con contraste de 4,5:1 o más sobre su fondo (LAYO-15): éxito 4,56,
   advertencia 5,11, peligro 4,92, información 6,48, neutra 6,92 y
   primaria 5,03. */
.badge {
    display: inline-flex; align-items: center;
    padding: 3px 8px; border-radius: 20px;
    font-size: 11px; font-weight: 600;
    line-height: 1.4;
}
.badge-success  { background: #E8F5E9; color: #2E7D32; }
.badge-warning  { background: #FFF8E1; color: var(--warning-texto); }
.badge-danger   { background: #FFEBEE; color: #C62828; }
.badge-info     { background: #E3F2FD; color: var(--info-texto); }
.badge-secondary{ background: #F1F5F9; color: var(--neutro-texto); }
/* Texto de la marca sobre su fondo muy claro: --primary-dark, que da 4,5:1 con cualquier color de la clínica (F6-50) */
.badge-primary  { background: var(--primary-xlight); color: var(--primary-dark); }

/* ── Buttons ── */
/* El borde es el de la variante de Bootstrap (--bs-btn-border-color): con
   `transparent` a secas, btn-outline-* y btn-light se quedaban sin borde.
   El grosor no cambia, así que ningún botón cambia de tamaño (F6-51) */
.btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 16px;
    font-size: 13px; font-weight: 500;
    border-radius: var(--radius-sm);
    border: 1px solid var(--bs-btn-border-color, transparent);
    cursor: pointer; transition: var(--transition);
    line-height: 1.4;
    white-space: nowrap;
}
/* Foco (LAYO-15): sin anillo al pulsar con el ratón o el dedo, y con anillo
   visible al llegar con el teclado (:focus-visible) */
.btn:focus:not(:focus-visible) { box-shadow: none; outline: none; }
.btn:focus-visible {
    outline: 2px solid var(--foco);
    outline-offset: 2px;
    box-shadow: none;
}
/* Botones de la marca (F6-50): también los estados que pinta Bootstrap con sus
   variables (pulsado, desactivado, marcado y su sombra de foco) */
.btn-primary {
    --bs-btn-bg: var(--primary); --bs-btn-border-color: var(--primary);
    --bs-btn-hover-bg: var(--primary-dark); --bs-btn-hover-border-color: var(--primary-dark);
    --bs-btn-active-bg: var(--primary-dark); --bs-btn-active-border-color: var(--primary-dark);
    --bs-btn-disabled-bg: var(--primary); --bs-btn-disabled-border-color: var(--primary);
    --bs-btn-focus-shadow-rgb: var(--primary-rgb);
    background: var(--primary); color: #fff; border-color: var(--primary);
}
.btn-primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); color: #fff; }
.btn-secondary{ background: #fff; color: var(--text-mid); border-color: var(--border); }
.btn-secondary:hover{ background: var(--bg); }
.btn-success  { background: var(--success); color: #fff; border-color: var(--success); }
.btn-danger   { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn-danger:hover { background: #B71C1C; color: #fff; }
.btn-outline-primary {
    --bs-btn-color: var(--primary); --bs-btn-border-color: var(--primary);
    --bs-btn-hover-bg: var(--primary); --bs-btn-hover-border-color: var(--primary);
    --bs-btn-active-bg: var(--primary); --bs-btn-active-border-color: var(--primary);
    --bs-btn-disabled-color: var(--primary); --bs-btn-disabled-border-color: var(--primary);
    --bs-btn-focus-shadow-rgb: var(--primary-rgb);
    background: transparent; color: var(--primary); border-color: var(--primary);
}
.btn-outline-primary:hover { background: var(--primary); color: #fff; }
.btn-icon { padding: 6px 8px; }
.btn-sm { padding: 4px 10px; font-size: 12px; }
.btn-lg { padding: 10px 24px; font-size: 15px; border-radius: 8px; }
.btn-block { width: 100%; justify-content: center; }
.btn-fab {
    position: fixed; bottom: 28px; right: 28px;
    width: 54px; height: 54px; border-radius: 50%;
    background: var(--primary); color: #fff;
    border: none; font-size: 24px;
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow-lg);
    cursor: pointer; transition: var(--transition);
    z-index: 200;
}
.btn-fab:hover { background: var(--primary-dark); transform: scale(1.05); }

/* ── Forms ── */
.form-label { font-size: 12px; font-weight: 600; color: var(--text-mid); margin-bottom: 4px; }

.form-control {
    font-size: 13px; border-radius: var(--radius-sm);
    border-color: var(--border); color: var(--text-dark);
    padding: 7px 12px;
    transition: var(--transition);
}

/* Select: needs extra right padding for the chevron arrow */
.form-select {
    font-size: 13px; border-radius: var(--radius-sm);
    border-color: var(--border); color: var(--text-dark);
    padding: 7px 2.25rem 7px 12px;   /* right=2.25rem leaves room for arrow */
    transition: var(--transition);
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%231565C0' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 12px 8px;
    cursor: pointer;
}

.form-control:focus, .form-select:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.12);
    outline: none;
}
/* Casillas, opciones e interruptores marcados con el color de la marca (F6-50) */
.form-check-input:checked { background-color: var(--primary); border-color: var(--primary); }
.form-check-input:focus { border-color: var(--primary); box-shadow: 0 0 0 .25rem rgba(var(--primary-rgb), 0.25); }
/* Lo activo de los componentes de Bootstrap (menús desplegables, paginación,
   pestañas en píldora, listas y barras de progreso), también de la marca */
.dropdown-menu { --bs-dropdown-link-active-bg: var(--primary); }
.pagination {
    --bs-pagination-active-bg: var(--primary); --bs-pagination-active-border-color: var(--primary);
    --bs-pagination-focus-box-shadow: 0 0 0 .25rem rgba(var(--primary-rgb), 0.25);
}
.nav-pills { --bs-nav-pills-link-active-bg: var(--primary); }
.list-group { --bs-list-group-active-bg: var(--primary); --bs-list-group-active-border-color: var(--primary); }
.progress, .progress-stacked { --bs-progress-bar-bg: var(--primary); }
.form-floating > .form-control { padding: 16px 12px 6px; }
.form-floating > label { font-size: 12px; color: var(--text-light); }

/* form-select-sm: Bootstrap overrides padding-top/bottom but we keep right padding for arrow */
.form-select-sm {
    padding-right: 2rem !important;
    background-position: right 0.6rem center !important;
    background-size: 11px 7px !important;
}

/* In-table estado select: ensure enough width to show full option text */
.estado-sel { min-width: 108px; }

/* Disabled selects */
.form-select:disabled { opacity: .6; cursor: not-allowed; }

/* ── Modals ── */
.modal-header {
    background: var(--white); border-bottom: 1px solid var(--border);
    padding: 16px 20px;
}
.modal-title { font-size: 15px; font-weight: 600; }
/* El título es un elemento flexible de la cabecera: sin `min-width: 0` no
   encoge por debajo de su palabra más larga, y un nombre con una palabra de
   más de 30 letras ensanchaba la cabecera y empujaba la X de cerrar fuera de
   la ventana en el teléfono. Ahora encoge y parte la palabra que no cabe; la
   X conserva su tamaño. Un título que cabe queda igual. */
.modal-title { min-width: 0; overflow-wrap: anywhere; }
.modal-header .btn-close { flex-shrink: 0; }
.modal-body { padding: 20px; }
.modal-footer { padding: 12px 20px; border-top: 1px solid var(--border); background: var(--border-light); }
.modal-content { border-radius: var(--radius); border: none; box-shadow: var(--shadow-lg); }
.modal-lg { max-width: 700px; }
.modal-xl { max-width: 900px; }

/* ── Alerts / Flash ── */
.alert {
    border-radius: var(--radius-sm);
    font-size: 13px;
    padding: 10px 14px;
    border: none;
    display: flex; align-items: center; gap: 8px;
}
.alert-success { background: #E8F5E9; color: #2E7D32; }
.alert-danger   { background: #FFEBEE; color: #C62828; }
.alert-warning  { background: #FFF8E1; color: var(--warning-texto); }
.alert-info     { background: var(--primary-xlight); color: var(--primary-dark); }

/* Las reglas del odontograma viven en odontograma.css desde F6-46 (F6-51) */

.leyenda-dot {
    width: 14px; height: 14px; border-radius: 3px; display: inline-block;
}

/* ── WhatsApp Bot ── */
.chat-bubble {
    max-width: 75%; padding: 10px 14px; border-radius: 12px;
    font-size: 13px; line-height: 1.5; margin-bottom: 8px;
}
.chat-bubble.bot { background: #F1F5F9; border-bottom-left-radius: 3px; }
.chat-bubble.user { background: var(--primary); color: #fff; margin-left: auto; border-bottom-right-radius: 3px; }
.chat-bubble.system { background: var(--accent-light); color: #00727D; /* 5,09:1 sobre --accent-light */ text-align: center; margin: 4px auto; font-size: 11px; border-radius: 20px; padding: 4px 12px; }
.chat-meta { font-size: 10px; color: var(--text-light); margin-top: 4px; }

/* ── Status badges (mismos contrastes que .badge-*) ── */
.status-activo    { background: #E8F5E9; color: #2E7D32; }
.status-inactivo  { background: #F1F5F9; color: var(--neutro-texto); }
.status-pendiente { background: #FFF8E1; color: var(--warning-texto); }
.status-confirmada{ background: var(--primary-xlight); color: var(--primary-dark); }
.status-atendida  { background: #E8F5E9; color: #2E7D32; }
.status-cancelada { background: #FFEBEE; color: #C62828; }
.status-pagada    { background: #E8F5E9; color: #2E7D32; }
.status-parcial   { background: #FFF8E1; color: var(--warning-texto); }
.status-anulada   { background: #FFEBEE; color: #C62828; }
.status-borrador  { background: #F1F5F9; color: var(--neutro-texto); }
.status-emitida   { background: var(--primary-xlight); color: var(--primary-dark); }

/* ── Utility ── */
.text-primary { color: var(--primary) !important; }
.text-muted   { color: var(--text-light) !important; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 12px; }
.fw-600 { font-weight: 600; }
.fw-700 { font-weight: 700; }
.fs-12  { font-size: 12px; }
.fs-13  { font-size: 13px; }
.fs-22  { font-size: 22px; }
.rounded-full { border-radius: 50%; }

/* ── Scrollbar ── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--border-light); }
::-webkit-scrollbar-thumb { background: #CBD5E1; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #94A3B8; }

/* ── Animations ── */
@keyframes fadeInUp {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
.fade-in-up { animation: fadeInUp 0.25s ease; }

@keyframes pulse-dot {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}
.pulse { animation: pulse-dot 1.5s ease infinite; }

/* ── Login Page ── */
.login-page {
    min-height: 100vh;
    background: linear-gradient(135deg, #0D47A1 0%, #0277BD 50%, #00838F 100%);
    display: flex; align-items: center; justify-content: center;
    position: relative;
    overflow: hidden;
}
.login-page::before {
    content: '';
    position: absolute; inset: 0;
    background-image: radial-gradient(circle, rgba(255,255,255,0.04) 1px, transparent 1px);
    background-size: 40px 40px;
}
.login-card {
    background: rgba(255,255,255,0.95);
    backdrop-filter: blur(20px);
    border-radius: 16px;
    padding: 40px 36px;
    width: 100%; max-width: 420px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.25);
    position: relative;
}
.login-logo {
    width: 56px; height: 56px; border-radius: 50%;
    background: var(--primary);
    display: flex; align-items: center; justify-content: center;
    font-size: 26px; color: #fff;
    margin: 0 auto 16px;
}
.login-title {
    font-size: 22px; font-weight: 700;
    color: var(--primary); text-align: center;
}
.login-subtitle { font-size: 13px; color: var(--text-light); text-align: center; margin-bottom: 28px; }
.login-lang {
    display: flex; justify-content: center; gap: 8px; margin-top: 20px;
}
.login-lang button {
    padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 600;
    border: 1px solid var(--border); background: #fff; cursor: pointer; transition: var(--transition);
}
.login-lang button.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.login-footer { text-align: center; font-size: 11px; color: var(--text-light); margin-top: 24px; }

/* ── Tabs ── */
.nav-tabs .nav-link {
    font-size: 13px; font-weight: 500;
    color: var(--text-mid); border: none; border-bottom: 2px solid transparent;
    padding: 10px 16px; border-radius: 0;
}
.nav-tabs .nav-link:hover { color: var(--primary); background: none; border-bottom-color: var(--primary-xlight); }
.nav-tabs .nav-link.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }
.nav-tabs { border-bottom: 1px solid var(--border); }

/* ── Dropdown actions ── */
.dropdown-menu {
    border-radius: var(--radius-sm);
    border-color: var(--border);
    box-shadow: var(--shadow-md);
    font-size: 13px;
    padding: 6px;
    min-width: 160px;
}
.dropdown-item {
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    display: flex; align-items: center; gap: 8px;
    color: var(--text-dark);
}
.dropdown-item:hover { background: var(--border-light); }
.dropdown-item.text-danger { color: var(--danger); }
.dropdown-item.text-danger:hover { background: #FFEBEE; }
.dropdown-item:focus-visible { outline: 2px solid var(--foco); outline-offset: -2px; }

/* ══════════════════════════════════════════
   ACCESIBILIDAD (F2-08, LAYO-15)
   ══════════════════════════════════════════ */

/* Foco visible con el teclado en todo lo que se puede activar. :where() no
   suma especificidad: cualquier estilo de foco propio de un componente
   (botones, menú oscuro, campos) manda sobre este. */
:where(a[href], button, summary, [role="button"], [tabindex]:not([tabindex="-1"])):focus-visible {
    outline: 2px solid var(--foco);
    outline-offset: 2px;
}

/* «Saltar al contenido»: primer elemento de la página; fuera de la vista
   hasta que recibe el foco con el teclado. Lleva a <main id="contenido">. */
.saltar-contenido {
    position: fixed;
    top: 8px;
    left: 8px;
    z-index: 2000;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 10px 16px;
    background: var(--primary-dark);
    color: #fff;
    font-weight: 600;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
    transform: translateY(-200%);
    transition: none;
}
.saltar-contenido:focus,
.saltar-contenido:focus-visible {
    transform: none;
    color: #fff;
    outline: 2px solid #fff;
    outline-offset: -5px;
}
/* El contenido recibe el foco desde el enlace anterior sin dibujar un marco */
.page-content:focus { outline: none; }

/* ══════════════════════════════════════════
   LISTAS EN TARJETAS Y COLUMNAS CON PRIORIDAD (F2-08, LAYO-16)
   ──────────────────────────────────────────
   Clases para las pantallas que en el teléfono enseñan cada fila como una
   tarjeta, sin desplazamiento lateral y con el estado siempre visible.

   1) Tabla que se vuelve tarjetas en teléfono: <table class="table
      tabla-tarjetas">. Desde 768 px es una tabla normal. En teléfono cada
      <tr> es una tarjeta y cada <td> una línea con su rótulo, que sale del
      atributo data-etiqueta (el texto de su columna):
        <td data-etiqueta="Estado">…</td>
      .celda-principal: la línea de cabecera de la tarjeta (nombre), sin rótulo.
      .celda-acciones:  los botones, abajo y alineados a la derecha.
      La cabecera de la tabla queda solo para lectores de pantalla.

   2) Lista de tarjetas con marcado propio (citas del día, tablero):
        <ul class="lista-tarjetas">
          <li class="tarjeta-fila">
            <div class="tarjeta-fila-principal">
              <div class="tarjeta-fila-titulo">…</div>
              <div class="tarjeta-fila-meta">…</div>
            </div>
            <div class="tarjeta-fila-lateral">estado, hora…</div>
            <div class="tarjeta-fila-acciones">botones</div>
          </li>
        </ul>

   3) Columnas con prioridad, en <th> y <td> de la misma columna (también
      en la tabla que se vuelve tarjetas):
        (sin clase)        prioridad 1: se ve siempre
        .col-prioridad-2   se ve desde la tableta (768 px)
        .col-prioridad-3   solo en escritorio (desde 1200 px)
        .col-oculta        la oculta quien elige columnas (selector de columnas)
   ══════════════════════════════════════════ */

/* 2) Lista de tarjetas */
.lista-tarjetas {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.tarjeta-fila {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    min-width: 0;
    padding: 12px 14px;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.tarjeta-fila-principal { flex: 1 1 12rem; min-width: 0; }
.tarjeta-fila-titulo {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-dark);
    overflow-wrap: anywhere;
}
.tarjeta-fila-meta {
    font-size: 12px;
    color: var(--text-light);
    overflow-wrap: anywhere;
}
.tarjeta-fila-lateral {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 6px;
}
.tarjeta-fila-acciones {
    display: flex;
    flex: 1 1 100%;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
}

/* 3) Columnas con prioridad */
.col-oculta { display: none !important; }
@media (max-width: 1199.98px) {
    .col-prioridad-3 { display: none !important; }
}
@media (max-width: 767.98px) {
    .col-prioridad-2 { display: none !important; }
}

/* 1) Tabla que se vuelve tarjetas en teléfono */
@media (max-width: 767.98px) {
    .tabla-tarjetas,
    .tabla-tarjetas tbody,
    .tabla-tarjetas tr,
    .tabla-tarjetas td {
        display: block;
        width: 100%;
    }
    .tabla-tarjetas thead {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }
    .tabla-tarjetas tbody { padding: 10px; }
    .table.tabla-tarjetas tbody tr {
        margin-bottom: 10px;
        padding: 10px 14px;
        background: var(--white);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        box-shadow: var(--shadow);
    }
    .table.tabla-tarjetas tbody tr:last-child { margin-bottom: 0; }
    .table.tabla-tarjetas tbody tr:hover { background: var(--white); }
    .table.tabla-tarjetas tbody td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        min-width: 0;
        padding: 6px 0;
        border: 0;
        text-align: right;
        overflow-wrap: anywhere;
    }
    .table.tabla-tarjetas tbody td[data-etiqueta]::before {
        content: attr(data-etiqueta);
        flex-shrink: 0;
        max-width: 45%;
        font-size: 12px;
        font-weight: 600;
        color: var(--text-mid);
        text-align: left;
    }
    .table.tabla-tarjetas tbody td.celda-principal {
        display: block;
        margin-bottom: 4px;
        padding-bottom: 8px;
        border-bottom: 1px solid var(--border-light);
        text-align: left;
    }
    .table.tabla-tarjetas tbody td.celda-principal::before { content: none; }
    .table.tabla-tarjetas tbody td.celda-acciones {
        flex-wrap: wrap;
        justify-content: flex-end;
        padding-top: 8px;
    }
}

/* ── Permissions Matrix ── */
.perms-table th, .perms-table td { text-align: center; vertical-align: middle; font-size: 12px; }
.perms-table th:first-child, .perms-table td:first-child { text-align: left; }
.perms-check { width: 16px; height: 16px; cursor: pointer; accent-color: var(--primary); }

/* ── Invoice ── */
.invoice-line-row:hover { background: var(--border-light); }
.invoice-total-row { background: var(--primary-xlight); }
.invoice-total-row td { font-weight: 700; color: var(--primary-dark); }

/* ── Print ── */
@media print {
    .sidebar, .topbar, .aviso-conexion, .btn, .no-print { display: none !important; }
    .main-content { margin-left: 0 !important; }
    .page-content { padding: 0 !important; }
    .card { box-shadow: none; border: 1px solid #ddd; }
}

/* ══════════════════════════════════════════
   RESPONSIVE — un solo juego de puntos de corte (F2-07, LAYO-5)
   ──────────────────────────────────────────
   Teléfono:   menos de 768 px   → @media (max-width: 767.98px)
   Tableta:    768 a 1199 px     → @media (min-width: 768px) and (max-width: 1199.98px)
   Escritorio: desde 1200 px     → sin media query (estilos base)
   Son los puntos md (768) y xl (1200) de Bootstrap: el botón del menú usa
   .d-xl-none y el script del layout, matchMedia('(min-width: 1200px)').
   «Tableta y teléfono» juntos: @media (max-width: 1199.98px).
   ══════════════════════════════════════════ */

/* Fondo oscuro detrás del menú abierto (teléfono y tableta) */
.sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.55);
    z-index: 999;
    transition: opacity .25s;
}
.sidebar-overlay.show { display: block; }

/* ── Tableta y teléfono (menos de 1200 px) ── */
@media (max-width: 1199.98px) {
    .page-content { padding: 16px; }
    .kpi-value { font-size: 20px; }
}

/* ── Tableta (768 a 1199 px): menú plegado a barra de iconos ──
   El contenido empieza después de la barra, nunca debajo. El botón del
   menú (.d-xl-none) abre el menú completo encima del contenido, con el
   fondo oscuro, sin moverlo. Plegado, los títulos de sección y los nombres
   de los módulos quedan solo para lectores de pantalla (y en el title). */
@media (min-width: 768px) and (max-width: 1199.98px) {
    .sidebar { width: var(--sidebar-w-iconos); }
    .sidebar.open {
        width: var(--sidebar-w);
        box-shadow: 4px 0 32px rgba(0,0,0,0.35);
    }
    .main-content { margin-left: var(--sidebar-w-iconos); }

    .sidebar:not(.open) .sidebar-brand { justify-content: center; padding: 18px 0; }
    .sidebar:not(.open) .sidebar-brand-text { display: none; }
    .sidebar:not(.open) .nav-link { justify-content: center; padding: 11px 0; }
    .sidebar:not(.open) .nav-link-text,
    .sidebar:not(.open) .nav-section-title span {
        position: absolute;
        width: 1px; height: 1px;
        margin: -1px; padding: 0;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }
    .sidebar:not(.open) .nav-section-title {
        height: 0;
        margin: 8px 14px;
        padding: 0;
        border-top: 1px solid rgba(255,255,255,0.12);
    }
    .sidebar:not(.open) .sidebar-footer { padding: 12px 0; }
    .sidebar:not(.open) .sidebar-user { flex-direction: column; gap: 8px; }
    .sidebar:not(.open) .sidebar-user-texto { display: none; }
}

/* ── Teléfono (menos de 768 px) ── */
@media (max-width: 767.98px) {
    /* El menú queda fuera de la pantalla; el botón lo abre encima. Cerrado
       está además oculto (visibility): con Tab no se entra en opciones que
       no se ven, y los lectores de pantalla no las leen (LAYO-15). Al
       cerrar, se oculta cuando termina de salir. */
    .sidebar {
        left: calc(-1 * var(--sidebar-w));
        z-index: 1001;
        visibility: hidden;
        transition: left .28s cubic-bezier(.4,0,.2,1), visibility 0s linear .28s;
    }
    .sidebar.open {
        left: 0;
        visibility: visible;
        box-shadow: 4px 0 32px rgba(0,0,0,0.35);
        transition: left .28s cubic-bezier(.4,0,.2,1), visibility 0s;
    }
    /* Las opciones toman la visibilidad del menú al momento (sin la
       transición general de los enlaces): reciben el foco nada más abrirlo */
    .sidebar a,
    .sidebar button { transition-property: color, background-color, border-color, box-shadow; }

    /* Main content occupies full width */
    .main-content { margin-left: 0; }

    /* Page content padding */
    .page-content { padding: 12px; }

    /* Page header stacks vertically */
    .page-header {
        flex-direction: column;
        align-items: flex-start !important;
        gap: 10px;
        margin-bottom: 16px;
    }
    .page-header > *:last-child { width: 100%; }
    .page-title { font-size: 18px; }

    /* KPI cards: 2 per row on phone */
    .kpi-card { margin-bottom: 12px; padding: 14px; }
    .kpi-value { font-size: 18px; }

    /* Cards */
    .card { border-radius: 8px; }
    .card-body { padding: 14px; }

    /* Topbar. Lo que no quepa a lo ancho se recorta, pero no lo que cuelga
       hacia abajo: con `hidden` en los dos ejes, los menús de idioma y de
       usuario se abrían recortados dentro de la barra y no se podían pulsar.
       `clip` recorta solo el eje que se le pide; un navegador sin `clip` se
       queda con `hidden`, como antes. */
    .topbar {
        padding: 0 12px;
        gap: 6px;
        overflow: hidden;
    }
    @supports (overflow: clip) {
        .topbar { overflow: visible; overflow-x: clip; }
    }
    /* Aviso de WhatsApp desconectado (F4-30): alineado a la izquierda, con
       el margen de la barra; el enlace o la nota, si pasan a otra línea,
       empiezan donde el texto. El enlace mide 44 px de alto para el dedo
       sin separar las líneas: su relleno vertical no cuenta en el alto de
       la línea. */
    .aviso-conexion { padding: 8px 12px; text-align: left; }
    .aviso-conexion-enlace,
    .aviso-conexion-nota { margin-left: 0; }
    .aviso-conexion-enlace { padding: 15px 0; }

    .topbar-spacer { display: none; }
    .topbar-actions { gap: 4px; margin-left: auto; }
    /* Hide notification badge text and user name text on mobile */
    .topbar-user-info { display: none !important; }

    /* Búsqueda global (F2-09, LAYO-16): en el encabezado solo la lupa; al
       pulsarla, la búsqueda ocupa la pantalla entera, con la flecha de
       volver, la caja y la lupa arriba y los resultados debajo. Mientras
       está abierta, el encabezado sube por encima del contenido (botones
       flotantes incluidos) y la página no se desplaza por detrás. */
    .topbar-icon-btn.busqueda-abrir { display: flex; }
    .topbar-search { display: none; }
    .topbar-search.abierta {
        position: fixed;
        inset: 0;
        z-index: 1100;
        display: flex;
        flex-direction: column;
        max-width: none;
        height: 100vh;
        height: 100dvh;
        background: var(--white);
    }
    body.busqueda-abierta { overflow: hidden; }
    body.busqueda-abierta .topbar { z-index: 1100; }
    .topbar-search.abierta .busqueda-form {
        flex: 0 0 auto;
        min-height: var(--topbar-barra-h);
        padding: 8px 12px 8px 4px;
        border-bottom: 1px solid var(--border);
        box-shadow: var(--shadow);
    }
    .busqueda-cerrar {
        display: inline-flex;
        flex: 0 0 auto;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        padding: 0;
        border: 0;
        border-radius: 8px;
        background: none;
        color: var(--text-mid);
        font-size: 20px;
        cursor: pointer;
    }
    .busqueda-cerrar:hover { background: var(--bg); color: var(--primary); }
    .topbar-search.abierta .form-control { min-height: 44px; }
    .topbar-search.abierta .btn { min-width: 44px; min-height: 44px; justify-content: center; }
    .topbar-search.abierta .busqueda-panel {
        position: static;
        flex: 1 1 auto;
        width: auto;
        max-width: none;
        max-height: none;
        padding: 8px 12px 24px;
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }
    .topbar-search.abierta .busqueda-opcion { min-height: 52px; }

    /* Facturación nueva page buttons stack */
    .btn-group-mobile { flex-direction: column; width: 100%; }
    .btn-group-mobile .btn { width: 100%; }

    /* Campos a 16 px: con menos, iOS amplía la página al escribir (LAYO-16).
       Incluye los campos pequeños (-sm) y los que no llevan clase. */
    input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=hidden]),
    select, textarea,
    .form-control, .form-select, .form-control-sm, .form-select-sm { font-size: 16px; }

    /* Modals: full width on small phones */
    .modal-dialog { margin: 8px; max-width: calc(100vw - 16px); }

    /* Tabs: scrollable */
    .nav-tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .nav-tabs .nav-link { white-space: nowrap; }

    /* Hide non-essential table columns on mobile via utility class */
    .col-hide-xs { display: none !important; }

    /* Show icon-only in page header buttons */
    .btn-label-hide { display: none; }

    /* Pantallas de entrada (inicio de sesión, elegir sucursal y 403): los
       enlaces de texto, las casillas y el botón de ver la contraseña miden
       44 px (PRUEBAS 4.2). Lo mismo en el bloque de pantalla táctil. */
    .login-enlace { display: inline-flex; align-items: center; min-width: 44px; min-height: 44px; }
    .login-casilla { display: flex; align-items: center; gap: 10px; min-height: 44px; margin: 0; padding-left: 0; }
    .login-casilla .form-check-input,
    .form-check-input.login-opcion { flex: 0 0 auto; float: none; width: 44px; height: 44px; margin: 0; }
    .login-ver-clave { min-width: 44px; justify-content: center; }
}

/* Ventanas a pantalla completa en el teléfono (.modal-fullscreen-sm-down).
   Bootstrap les da el alto entero de la pantalla por debajo de 576 px (su
   punto sm: de ahí este corte) y el bloque de teléfono de arriba les deja
   8 px de margen por cada lado. Sin descontar ese margen del alto, el pie
   de la ventana quedaba 8 px por debajo de la pantalla. */
@media (max-width: 575.98px) {
    .modal-dialog.modal-fullscreen-sm-down { height: calc(100% - 16px); }
}

/* ══════════════════════════════════════════
   PANTALLA TÁCTIL (F2-08, LAYO-16)
   ──────────────────────────────────────────
   Con un puntero grueso (dedo) como puntero principal, cada objetivo mide al
   menos 44×44 px: botones (también .btn-sm y .btn-icon), botones del
   encabezado, opciones del menú, de los desplegables y de la paginación,
   y campos. El aspecto con ratón no cambia.
   ══════════════════════════════════════════ */
@media (pointer: coarse) {
    .btn,
    .btn-sm,
    .btn-icon {
        min-width: 44px;
        min-height: 44px;
        justify-content: center;
    }
    .topbar-icon-btn {
        width: 44px;
        height: 44px;
    }
    .topbar-icon-btn.dropdown-toggle { width: auto; min-width: 44px; }
    .topbar-user { min-height: 44px; }
    .btn-salir,
    .btn-close {
        box-sizing: border-box;
        min-width: 44px;
        min-height: 44px;
    }
    .nav-link,
    .dropdown-item { min-height: 44px; }
    /* Enlace de la franja de WhatsApp desconectado: 44 px con su relleno */
    .aviso-conexion-enlace { padding: 15px 0; }
    .nav-tabs .nav-link {
        padding-top: 12px;
        padding-bottom: 12px;
    }
    .page-link {
        display: flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
    }
    .form-control,
    .form-select { min-height: 44px; }
    /* Pantallas de entrada: como en el bloque del teléfono */
    .login-enlace { display: inline-flex; align-items: center; min-width: 44px; min-height: 44px; }
    .login-casilla { display: flex; align-items: center; gap: 10px; min-height: 44px; margin: 0; padding-left: 0; }
    .login-casilla .form-check-input,
    .form-check-input.login-opcion { flex: 0 0 auto; float: none; width: 44px; height: 44px; margin: 0; }
    .login-ver-clave { min-width: 44px; justify-content: center; }
}

/* ══════════════════════════════════════════
   MENOS MOVIMIENTO (F2-08, LAYO-15)
   ──────────────────────────────────────────
   Si el sistema pide reducir el movimiento, no hay animaciones ni
   transiciones: la entrada de la página, el punto que late, los avisos y el
   menú lateral aparecen sin desplazarse. Bootstrap ejecuta al momento lo que
   espera a una transición cuando su duración es 0.
   ══════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *,
    *::before,
    *::after {
        animation: none !important;
        transition: none !important;
        scroll-behavior: auto !important;
    }
}

/* Diálogo de confirmación (window.confirmarDialogo, app.js; 2026-11-04) */
.dialogo-confirmar .modal-dialog { max-width: 30rem; }
.dialogo-confirmar .modal-content { border: 0; border-radius: 1rem; box-shadow: 0 1.25rem 3rem rgba(0, 0, 0, .2); }
.dialogo-confirmar .modal-body { padding: 2rem 1.75rem 1.5rem; text-align: center; }
.dialogo-confirmar-icono {
    width: 4.75rem; height: 4.75rem; margin: 0 auto 1.1rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 2.6rem; border: .25rem solid currentColor;
    animation: dialogo-confirmar-entrada .35s ease-out;
}
.dialogo-confirmar-warning { color: #f8bb86; }
.dialogo-confirmar-question { color: #87adbd; }
.dialogo-confirmar-success { color: #a5dc86; }
.dialogo-confirmar-titulo { font-size: 1.35rem; font-weight: 600; margin-bottom: .5rem; }
.dialogo-confirmar-texto { color: var(--bs-secondary-color, #6c757d); margin-bottom: 1.5rem; }
.dialogo-confirmar-botones { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }
.dialogo-confirmar-botones .btn { min-width: 8.5rem; border-radius: .6rem; padding: .6rem 1.25rem; font-weight: 500; }
@keyframes dialogo-confirmar-entrada { from { transform: scale(.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .dialogo-confirmar-icono { animation: none; } }
