/* ==========================================================================
   glass.css — Renovación de interfaz en cristal (v2.7)
   Se carga el ÚLTIMO, después de base.css, y solo pisa lo que cambia.
   REVERTIR: quitar el <link> de glass.css y el <script> de glass-menu.js en functions.php.
   Copia del diseño anterior en _backup_ui_original/.

   1. Tokens
   2. Menú lateral: rail de departamentos + panel de páginas
   3. Menú plegado: solo el rail, con submenú flotante al pasar el ratón
   4. Móvil y tablet: el menú completo como cajón
   5. Bandeja de notificaciones: panel flotante de cristal
   6. Avisos emergentes: tarjeta de cristal con el color de su tipo
   7. Campos de formulario
   8. Selector de fechas (glass-fecha.js)
   9. Botones
   10. Tablas
   11. Contenido de las tablas
   12. Botones de acciones
   13. Botón de borrar/limpiar filtros
   14. Calendarios
   15. Pestañas de vista
   16. Desplegables (glass-select.js)
   17. Acordeones
   18. Grupos de opciones como pestañas
   19. Listado de empleados
   25. Entrada (iniciar sesión)
   26. Fichador (pantalla de fichar)
   27. Modo tutorial (visita guiada)
   28. Ayuda de cada pantalla
   ========================================================================== */

/* ── 1. Tokens ───────────────────────────────────────────────────────────── */
:root {
    /* Hover: un tinte del azul de marca, no blanco (blanco sobre cristal claro no se distinguía) */
    --gm-hover: light-dark(rgb(3 94 177 / .11), rgb(140 200 255 / .14));
    /* Fondo de la aplicación: lavados de color difusos sobre un suelo azulado */
    --gm-suelo: light-dark(#dce8f4, #0a1422);
    --gm-lavado-1: light-dark(rgb(3 94 177 / .34), rgb(40 120 220 / .42));
    --gm-lavado-2: light-dark(rgb(46 180 196 / .26), rgb(30 150 170 / .28));
    --gm-lavado-3: light-dark(rgb(150 128 228 / .24), rgb(120 90 210 / .30));
    --gm-veta: light-dark(rgb(255 255 255 / .72), rgb(140 190 255 / .08));
    /* Opacidad del cristal (0 transparente – 1 opaco). Cada usuario la ajusta en Mi perfil; el valor
       se inyecta en el <head> y todo el cristal se deriva de aquí. */
    --gm-opacidad: .42;
    --gm-bg: light-dark(rgb(255 255 255 / var(--gm-opacidad)), rgb(18 30 46 / min(1, calc(var(--gm-opacidad) + .1))));
    --gm-bg-2: light-dark(rgb(255 255 255 / min(1, calc(var(--gm-opacidad) + .14))), rgb(30 46 68 / min(1, calc(var(--gm-opacidad) + .18))));
    --gm-borde: light-dark(rgb(255 255 255 / .72), rgb(255 255 255 / .10));
    --gm-luz: light-dark(rgb(255 255 255 / .88), rgb(255 255 255 / .14));
    --gm-sombra: 0 18px 42px light-dark(rgb(18 52 92 / .18), rgb(0 0 0 / .50));
    --gm-texto: light-dark(#10233a, #e4eef9);
    --gm-suave: light-dark(#4a6078, #93a8bf);
    --gm-acento: light-dark(rgb(3 94 177), rgb(140 200 255));
    --gm-pildora: linear-gradient(135deg, light-dark(rgb(3 94 177 / .96), rgb(96 166 245 / .66)), light-dark(rgb(42 132 222 / .88), rgb(62 118 214 / .56)));
    --gm-brillo: 0 8px 20px light-dark(rgb(3 94 177 / .34), rgb(60 140 240 / .30));
    --gm-blur: blur(22px) saturate(165%);

    --gm-margen: .75rem;      /* del menú al borde de la pantalla */
    --gm-hueco: var(--gm-margen); /* del menú al contenido: el mismo, para que todo cuadre */
    --gm-rail-w: 4.6rem;
    --gm-panel-w: 14.5rem;
    --gm-radio: 1.4rem;
}

/* El menú antiguo solo se oculta cuando el nuevo está montado (html.gm-js lo pone el script) */
html.gm-js #encabezado-lateral,
html.gm-js #btn-lateral { display: none !important; }

/* ── 2. Menú lateral ─────────────────────────────────────────────────────── */
#gm {
    position: fixed;
    top: var(--gm-margen);
    left: var(--gm-margen);
    bottom: var(--gm-margen);
    z-index: 30;
    display: flex;
    color: var(--gm-texto);
    font-family: var(--letra);
    /* Sin fondo ni backdrop propio: lo llevan el rail y el panel. Un backdrop-filter aquí haría que
       el submenú flotante (hijo) solo pudiera desenfocar lo que hay DENTRO del menú, no la página. */
}

/* Las dos piezas de cristal. border-box: miden exactamente --gm-rail-w y --gm-panel-w (antes el
   relleno y el borde se sumaban y el panel acababa 22 px más a la derecha, pisando el contenido). */
#gm .gm-rail,
#gm .gm-panel {
    box-sizing: border-box;
    position: relative;
    background: var(--gm-bg);
    border: 1px solid var(--gm-borde);
    box-shadow: inset 0 1px 0 var(--gm-luz), var(--gm-sombra);
    backdrop-filter: var(--gm-blur);
    -webkit-backdrop-filter: var(--gm-blur);
}
/* Reflejo: luz diagonal que se apaga hacia abajo */
#gm .gm-rail::before,
#gm .gm-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(160deg, var(--gm-luz) 0%, transparent 30%);
    opacity: .5;
}

/* Rail de departamentos */
#gm .gm-rail {
    width: var(--gm-rail-w);
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .15rem;
    padding: .75rem 0 .7rem;
    border-radius: var(--gm-radio) 0 0 var(--gm-radio);
    /* El borde derecho siempre está: desplegado es transparente (se une al panel) y plegado toma el
       color del cristal. Así esquinas y borde cambian con transición en vez de saltar. */
    border-right: 1px solid transparent;
    background: color-mix(in srgb, var(--gm-acento) 11%, var(--gm-bg));
    transition: border-radius .32s cubic-bezier(.22, .8, .3, 1), border-right-color .32s ease;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: none;
}
#gm .gm-rail::-webkit-scrollbar { display: none; }
/* Unión rail-panel sin raya: desplegado, el rail no lleva borde derecho (su franja transparente de 1px
   quedaba sin reflejo ni desenfoque y se veía como una raya en la junta) y rail y panel pintan
   trozos de UN mismo degradado calculado sobre las dos piezas juntas, en vez de empezar cada uno el
   suyo en la junta. Plegado, el rail vuelve a su reflejo propio. */
#gm:not([data-plegado="1"]):not(.gm-plegando) .gm-rail { border-right-width: 0; }
#gm:not([data-plegado="1"]) .gm-rail::before {
    background-size: calc(var(--gm-rail-w) + var(--gm-panel-w)) 100%;
    background-position: left top;
    background-repeat: no-repeat;
}
#gm:not([data-plegado="1"]) .gm-panel::before {
    background-size: calc(var(--gm-rail-w) + var(--gm-panel-w)) 100%;
    background-position: right top;
    background-repeat: no-repeat;
}
#gm[data-plegado="1"] .gm-rail,
#gm.gm-plegando .gm-rail { border-radius: var(--gm-radio); border-right-color: var(--gm-borde); }
/* gm-plegando: mientras el panel se va, la columna ya toma su forma de plegado, a la vez */

#gm .gm-logo {
    position: relative;
    z-index: 1;
    width: 2.7rem;
    height: 2.7rem;
    margin: 0 0 .55rem;
    padding: 0;
    border-radius: .95rem;
    display: grid;
    place-items: center;
    background: var(--gm-bg-2);
    border: 1px solid var(--gm-borde);
    box-shadow: inset 0 1px 0 var(--gm-luz);
    cursor: pointer;
    transition: transform .15s ease, box-shadow .2s ease;
}
#gm .gm-logo:hover { transform: translateY(-1px); box-shadow: inset 0 1px 0 var(--gm-luz), var(--gm-brillo); }
#gm .gm-logo img { width: 1.7rem; height: 1.7rem; object-fit: contain; }

#gm .gm-rb {
    position: relative;
    z-index: 1;
    width: 3.8rem;
    min-height: 3.05rem;
    margin: 0;
    padding: .45rem 0 .35rem;
    border: 0;
    border-radius: .95rem;
    background: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .18rem;
    color: var(--gm-suave);
    font: inherit;
    font-size: .66rem;
    line-height: 1.1;
    text-decoration: none;
    cursor: pointer;
    transition: color .2s ease;
}
#gm .gm-rb svg { width: 1.3rem; height: 1.3rem; fill: currentColor; flex: none; }
#gm .gm-rb > span:not(.bandeja-badge):not([id$="-count"]) {
    max-width: 3.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
#gm .gm-rb:hover { color: var(--gm-acento); background: var(--gm-hover); }
#gm .gm-rb.gm-on:hover { background: none; }
#gm .gm-rb.gm-on { color: var(--gm-acento); }
/* Página en la que estás (Inicio): se marca aunque la lengüeta esté en otro departamento */
#gm .gm-rb.activo { color: var(--gm-acento); font-weight: 700; }
#gm .gm-rb .bandeja-badge,
#gm .gm-rb [id$="-count"] { position: absolute; top: .1rem; right: .35rem; }

/* Lengüeta: se desliza detrás del departamento abierto y se funde con el panel */
#gm .gm-tab {
    position: absolute;
    top: 0;
    left: .4rem;
    right: 0;
    height: 3rem;
    z-index: 0;
    border-radius: .95rem 0 0 .95rem;
    /* Mismo cristal que el panel: la lengüeta parece una prolongación suya */
    background: var(--gm-bg-2);
    box-shadow: inset 0 1px 0 var(--gm-luz);
    transition: transform .38s cubic-bezier(.3, 1.2, .5, 1), height .2s ease, opacity .2s ease,
        right .32s cubic-bezier(.22, .8, .3, 1), border-radius .32s cubic-bezier(.22, .8, .3, 1), box-shadow .32s ease;
    pointer-events: none;
}
#gm .gm-espacio { flex: 1 1 auto; min-height: .5rem; }

/* Panel de páginas del departamento */
#gm .gm-panel {
    width: var(--gm-panel-w);
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    padding: .85rem .65rem .7rem;
    border-radius: 0 var(--gm-radio) var(--gm-radio) 0;
    border-left: 0;
    background: var(--gm-bg-2);
}
#gm .gm-panel-h { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .1rem .1rem 0 .45rem; }
#gm .gm-titulo { margin: 0; font-size: 1.02rem; font-weight: 700; color: var(--gm-texto); letter-spacing: -.005em; }
#gm .gm-plegar {
    width: 2rem;
    height: 2rem;
    flex: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: .65rem;
    display: grid;
    place-items: center;
    background: none;
    color: var(--gm-suave);
    cursor: pointer;
}
#gm .gm-plegar:hover { background: var(--gm-hover); color: var(--gm-acento); }
#gm .gm-plegar svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Buscador: halo que orbita detrás del cristal mientras se escribe */
#gm .gm-buscar { position: relative; z-index: 1; display: block; border-radius: 999px; overflow: hidden; isolation: isolate; margin: 0; }
#gm .gm-buscar::before {
    content: "";
    position: absolute;
    left: -20%;
    top: -180%;
    width: 140%;
    aspect-ratio: 1;
    z-index: -1;
    background: conic-gradient(from 0deg, transparent, rgb(3 94 177 / .38), rgb(46 180 196 / .34), transparent 60%);
    opacity: 0;
    transition: opacity .3s ease;
    animation: gm-halo 7s linear infinite;
}
#gm .gm-buscar:focus-within::before { opacity: 1; }
@keyframes gm-halo { to { transform: rotate(360deg); } }
#gm .gm-buscar svg { position: absolute; left: .8rem; top: 50%; transform: translateY(-50%); width: .95rem; height: .95rem; fill: none; stroke: var(--gm-suave); stroke-width: 2; stroke-linecap: round; pointer-events: none; }
#gm .gm-buscar input[type="search"] {
    width: 100%;
    height: auto;
    box-sizing: border-box;
    margin: 0;
    padding: .5rem .8rem .5rem 2.15rem;
    border: 1px solid var(--gm-borde);
    border-radius: 999px;
    /* Fondo de campo, no el del cristal: con la opacidad baja el buscador casi desaparecía */
    background: var(--gm-campo-bg);
    color: var(--gm-texto);
    font: inherit;
    font-size: .84rem;
    box-shadow: none;
    outline: none;
}
#gm .gm-buscar input[type="search"]::placeholder { color: var(--gm-suave); }

/* Listas de enlaces. [hidden] tiene que ganar al display:flex de abajo: solo se ve un departamento. */
#gm [hidden] { display: none !important; }
#gm .gm-dept,
#gm .gm-resultados {
    position: relative;
    z-index: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: .12rem;
    overflow-y: auto;
    overflow-x: hidden;
    /* base.css pinta las barras de scroll casi negras: aquí, discretas y del color del cristal */
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--gm-suave) 45%, transparent) transparent;
    padding-right: .1rem;
}
#gm .gm-link {
    position: relative;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: .65rem;
    width: 100%;
    min-height: 2.35rem;
    height: auto;
    margin: 0;
    padding: .35rem .75rem;
    box-sizing: border-box;
    border: 0;
    border-radius: .75rem;
    background: none;
    color: var(--gm-texto);
    fill: currentColor;
    font: inherit;
    font-size: .9rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .2s ease, color .2s ease;
}
#gm .gm-link svg { width: 1.1rem; height: 1.1rem; flex: none; fill: currentColor; opacity: .85; }
/* Subtítulo de apartado dentro de un departamento (Tiempo: Horas / Vacaciones y festivos) */
#gm .gm-apartado {
    margin: .55rem .75rem .15rem;
    color: var(--gm-suave);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
}
#gm .gm-apartado:first-child { margin-top: .1rem; }
/* Nombres completos: si no caben parten en dos líneas en vez de cortarse con puntos suspensivos */
#gm .gm-link > span:first-of-type {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-height: 1.2;
    white-space: normal;
}
#gm .gm-link:hover:not(.activo) { background: var(--gm-hover); color: var(--gm-acento); }
#gm .gm-link.activo {
    background: var(--gm-pildora);
    color: #fff;
    box-shadow: var(--gm-brillo), inset 0 1px 0 rgb(255 255 255 / .3);
}
#gm .gm-link.activo svg { opacity: 1; }
#gm .gm-link .gm-de { margin-left: auto; font-size: .7rem; color: var(--gm-suave); white-space: nowrap; }
#gm .gm-link.activo .gm-de { color: rgb(255 255 255 / .8); }
/* Enlaces con estilo propio por id en base.css: dentro del menú nuevo van como los demás.
   #claro-oscuro lleva color y fondo con !important en base.css, así que aquí también. */
#gm #abrir-bandeja.gm-rb { background: none; }
#gm #claro-oscuro.gm-link { background: none !important; color: var(--gm-texto) !important; }
#gm #claro-oscuro.gm-link svg { fill: currentColor !important; }
#gm #claro-oscuro.gm-link:hover { background: var(--gm-hover) !important; color: var(--gm-acento) !important; }
#gm #cerrar_sesion.gm-link { color: var(--rojo); margin-top: .35rem; background: none; }
#gm #cerrar_sesion.gm-link:hover { background: color-mix(in srgb, var(--rojo) 12%, transparent); }
#gm .gm-vacio { margin: 0; padding: .4rem .75rem; font-size: .84rem; color: var(--gm-suave); }

#gm .gm-rb:focus-visible,
#gm .gm-link:focus-visible,
#gm .gm-logo:focus-visible,
#gm .gm-plegar:focus-visible { outline: 2px solid var(--gm-acento); outline-offset: 2px; }

/* El contenido deja sitio al menú */
html.gm-js #gm ~ main {
    /* border-box: con width:100% MÁS el relleno del menú, main medía más que la pantalla y, al
       centrarlo el body, se salía por la izquierda y quedaba debajo del panel */
    box-sizing: border-box;
    padding-left: calc(var(--gm-margen) + var(--gm-rail-w) + var(--gm-panel-w) + var(--gm-hueco)) !important;
    transition: padding-left .3s ease;
}
html.gm-js #gm[data-plegado="1"] ~ main {
    padding-left: calc(var(--gm-margen) + var(--gm-rail-w) + var(--gm-hueco)) !important;
}

/* Fondo de la aplicación: lavados difusos en lugar de la imagen de formas (solo con el menú nuevo) */
html.gm-js body:not(.fichador) {
    background-color: var(--gm-suelo);
    background-image: none;
}
html.gm-js body:not(.fichador)::before,
html.gm-js[data-theme="dark"] body:not(.fichador)::before {
    background-color: var(--gm-suelo);
    background-image:
        radial-gradient(40rem 36rem at 6% 4%, var(--gm-lavado-1), transparent 70%),
        radial-gradient(38rem 30rem at 30% 104%, var(--gm-lavado-2), transparent 70%),
        radial-gradient(44rem 34rem at 98% 14%, var(--gm-lavado-3), transparent 70%),
        radial-gradient(24rem 9rem at 58% 52%, var(--gm-veta), transparent 72%),
        radial-gradient(20rem 8rem at 86% 90%, var(--gm-veta), transparent 72%);
    background-size: cover;
    opacity: 1;
    filter: none;
}

/* <aside id="notificaciones"> va el primero dentro de main y casi siempre vacío: aun así contaba
   como elemento y el hueco entre elementos (1rem) bajaba la tarjeta 16 px respecto al menú. Las
   notificaciones que recibe se pintan fijas, así que sacarlo del flujo no cambia dónde aparecen. */
html.gm-js #gm ~ main > #notificaciones { position: absolute; }

/* Contenido alineado a la izquierda, junto al menú (por defecto). Cada tarjeta ocupa lo que necesite su
   página, no todo el ancho. Cada usuario puede volver al centrado en Mi perfil → Apariencia
   (html[data-contenido="centro"]). */
@media (width > 950px) {
    html.gm-js:not([data-contenido="centro"]) #gm ~ main {
        align-items: flex-start;
        padding-top: var(--gm-margen);
        padding-right: var(--gm-margen);
    }
    /* Con el contenido centrado la tarjeta también empieza a la altura del menú (antes 32 px) */
    html.gm-js #gm ~ main { padding-top: var(--gm-margen); }
    html.gm-js:not([data-contenido="centro"]) #gm ~ main > .cristal {
        align-self: flex-start;
        max-width: 100%;
        margin-left: 0;
        margin-right: 0;
        box-sizing: border-box;
    }
    html.gm-js:not([data-contenido="centro"]) #gm ~ main > .cristal > h1 { text-align: left; }
}

/* Entrada en cascada: solo la primera vez de la sesión, nunca al navegar */
#gm.gm-entrada .gm-rb,
#gm.gm-entrada .gm-link {
    animation: gm-entra .42s cubic-bezier(.2, .8, .2, 1) backwards;
    animation-delay: calc(var(--gm-i, 0) * 32ms);
}
@keyframes gm-entra { from { opacity: 0; transform: translateX(-8px); } }

/* Desplegar y plegar el menú: el panel grande entra deslizándose de izquierda a derecha ganando
   opacidad, y al plegarlo sale con el movimiento contrario antes de ocultarse */
#gm .gm-panel.gm-abriendo { animation: gm-flota .34s cubic-bezier(.22, .8, .3, 1); }
#gm .gm-panel.gm-plegando {
    animation: gm-flota-sale .22s cubic-bezier(.5, 0, .75, .3) forwards;
    pointer-events: none;
}

/* ── 3. Menú plegado: submenú flotante ───────────────────────────────────── */
#gm[data-plegado="1"] .gm-panel { display: none; }
#gm[data-plegado="1"] .gm-tab {
    right: .4rem;
    border-radius: .95rem;
    background: var(--gm-pildora);
    box-shadow: var(--gm-brillo);
}
#gm[data-plegado="1"] .gm-rb.gm-on { color: #fff; }
#gm[data-plegado="1"] .gm-panel.gm-flotante {
    display: flex;
    position: fixed;
    left: calc(var(--gm-margen) + var(--gm-rail-w) + .55rem);
    top: var(--gm-flot-top, 1rem);
    max-height: calc(100dvh - 2 * var(--gm-margen));
    border-left: 1px solid var(--gm-borde);
    border-radius: 1.2rem;
    background: var(--gm-bg);
    transform-origin: left center;
    /* Sale del rail deslizándose hacia la derecha; al pasar a otro departamento no vuelve a
       entrar, se desplaza hasta su nueva altura */
    animation: gm-flota .3s cubic-bezier(.22, .8, .3, 1);
    transition: top .28s cubic-bezier(.2, .8, .2, 1);
}
/* Al irse no desaparece de golpe: se funde hacia el rail */
#gm[data-plegado="1"] .gm-panel.gm-flotante.gm-cerrando {
    animation: gm-flota-sale .22s cubic-bezier(.5, 0, .75, .3) forwards;
    pointer-events: none;
}
#gm[data-plegado="1"] .gm-flotante .gm-buscar { display: none; }
/* En el flotante ese botón DESPLIEGA el menú: la flecha mira hacia fuera */
#gm[data-plegado="1"] .gm-flotante .gm-plegar svg { transform: scaleX(-1); }
/* Se desliza de izquierda a derecha ganando opacidad; al ocultarse, lo mismo al revés */
@keyframes gm-flota { from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: translateX(0); } }
@keyframes gm-flota-sale { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(-18px); } }

/* Al cambiar de departamento (plegado o desplegado), el bloque de páginas entra deslizándose de
   izquierda a derecha y ganando opacidad, con cada página ligeramente escalonada */
#gm .gm-dept.gm-anim {
    animation: gm-flota .34s cubic-bezier(.22, .8, .3, 1) backwards;
}
#gm .gm-dept.gm-anim > .gm-link {
    animation: gm-link-entra .34s cubic-bezier(.22, .8, .3, 1) backwards;
    animation-delay: calc(var(--gm-j, 0) * 35ms);
}
@keyframes gm-link-entra { from { opacity: 0; transform: translateX(-14px); } to { opacity: 1; transform: translateX(0); } }
#gm .gm-titulo.gm-anim { animation: gm-titulo-entra .25s ease; }
@keyframes gm-titulo-entra { from { opacity: 0; transform: translateY(-3px); } }

/* ── 3b. Menú anclado a la pared (Mi perfil → Apariencia, html[data-menu="pared"]) ── */
/* Como el menú original: pegado al borde izquierdo y a toda la altura, sin esquinas ni margen. Solo
   en escritorio (en móvil el cajón ya va pegado al borde). Mismo cristal, rail, panel y animaciones;
   al cambiar la opción el menú se desliza a su sitio y las esquinas se transforman a la vez. */
@media (width > 950px) {
    html.gm-js #gm { transition: top .3s ease, left .3s ease, bottom .3s ease; }
    html.gm-js #gm .gm-panel { transition: border-radius .32s cubic-bezier(.22, .8, .3, 1); }

    html.gm-js[data-menu="pared"] #gm { top: 0; left: 0; bottom: 0; }
    html.gm-js[data-menu="pared"] #gm .gm-rail,
    html.gm-js[data-menu="pared"] #gm.gm-plegando .gm-rail,
    html.gm-js[data-menu="pared"] #gm[data-plegado="1"] .gm-rail {
        border-radius: 0;
        border-top: 0;
        border-bottom: 0;
        border-left: 0;
        box-shadow: none;
    }
    /* La sombra la echa solo la pieza que da al contenido: el panel, o el rail si está plegado */
    html.gm-js[data-menu="pared"] #gm .gm-panel {
        border-radius: 0;
        border-top: 0;
        border-bottom: 0;
        box-shadow: inset 0 1px 0 var(--gm-luz), var(--gm-sombra);
    }
    html.gm-js[data-menu="pared"] #gm[data-plegado="1"] .gm-rail { box-shadow: var(--gm-sombra); }
    html.gm-js[data-menu="pared"] #gm .gm-rail { padding-top: calc(.75rem + var(--gm-margen)); }
    html.gm-js[data-menu="pared"] #gm .gm-panel { padding-top: calc(.85rem + var(--gm-margen)); }
    /* El flotante sale pegado al rail, que ahora empieza en el borde */
    html.gm-js[data-menu="pared"] #gm[data-plegado="1"] .gm-panel.gm-flotante { left: calc(var(--gm-rail-w) + .55rem); }

    html.gm-js[data-menu="pared"] #gm ~ main {
        padding-left: calc(var(--gm-rail-w) + var(--gm-panel-w) + var(--gm-hueco)) !important;
    }
    html.gm-js[data-menu="pared"] #gm[data-plegado="1"] ~ main {
        padding-left: calc(var(--gm-rail-w) + var(--gm-hueco)) !important;
    }
}

@media (prefers-reduced-motion: reduce) {
    #gm *, #gm *::before { transition: none !important; animation: none !important; }
    html.gm-js #gm ~ main { transition: none; }
}

/* ── 4. Móvil y tablet: menú completo como cajón ─────────────────────────── */
@media (width <= 950px) {
    html.gm-js #gm {
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 119;
        padding: calc(3.8rem + env(safe-area-inset-top, 0px)) .5rem calc(.75rem + env(safe-area-inset-bottom, 0px));
        transform: translateX(-105%);
        transition: transform .25s ease;
    }
    html.gm-js body.menu-movil-abierto #gm { transform: none; }
    /* En el cajón siempre desplegado, aunque en escritorio se prefiera plegado */
    html.gm-js #gm .gm-panel,
    html.gm-js #gm[data-plegado="1"] .gm-panel {
        display: flex;
        position: relative;
        top: auto;
        left: auto;
        width: min(var(--gm-panel-w), calc(100vw - var(--gm-rail-w) - 2rem));
        border-left: 0;
        border-radius: 0 var(--gm-radio) var(--gm-radio) 0;
        background: var(--gm-bg-2);
        animation: none;
    }
    html.gm-js #gm[data-plegado="1"] .gm-rail { border-radius: var(--gm-radio) 0 0 var(--gm-radio); border-right-color: transparent; }
    html.gm-js #gm[data-plegado="1"] .gm-tab { right: 0; border-radius: .95rem 0 0 .95rem; background: color-mix(in srgb, var(--gm-bg-2) 70%, transparent); box-shadow: none; }
    html.gm-js #gm[data-plegado="1"] .gm-rb.gm-on { color: var(--gm-acento); }
    html.gm-js #gm .gm-plegar,
    html.gm-js #gm .gm-logo { display: none; }
    html.gm-js #gm .gm-buscar { display: block !important; }
    html.gm-js #gm ~ main,
    html.gm-js #gm[data-plegado="1"] ~ main { padding-left: 0 !important; }

    /* Botón "Menú"/"Cerrar": píldora de cristal como el resto; abierto, en azul como lo seleccionado */
    html.gm-js #btn-menu-movil {
        top: var(--gm-margen);
        left: var(--gm-margen);
        gap: .45rem;
        padding: 0 .95rem 0 .8rem;
        border: 1px solid var(--gm-borde);
        border-radius: 999px;
        background: var(--gm-bg-2);
        color: var(--gm-texto);
        font-family: var(--letra);
        box-shadow: inset 0 1px 0 var(--gm-luz), 0 8px 22px light-dark(rgb(18 52 92 / .16), rgb(0 0 0 / .45));
        backdrop-filter: var(--gm-blur);
        -webkit-backdrop-filter: var(--gm-blur);
        transition: background-color .25s ease, color .25s ease, box-shadow .25s ease, transform .15s ease;
    }
    html.gm-js #btn-menu-movil:hover { background: color-mix(in srgb, var(--gm-acento) 10%, var(--gm-bg-2)); color: var(--gm-acento); }
    html.gm-js #btn-menu-movil:active { transform: scale(.96); }
    html.gm-js #btn-menu-movil[aria-expanded="true"] {
        background: var(--gm-pildora);
        border-color: transparent;
        color: #fff;
        box-shadow: var(--gm-brillo), inset 0 1px 0 rgb(255 255 255 / .3);
    }
    html.gm-js #btn-menu-movil:focus-visible { outline: 2px solid var(--gm-acento); outline-offset: 2px; }
    /* Fondo del cajón: velo suave en vez del oscuro de antes, como el del panel de avisos */
    html.gm-js #menu-movil-fondo {
        background: light-dark(rgb(16 35 58 / .18), rgb(0 0 0 / .45));
        backdrop-filter: none;
    }
}

/* ── 5. Bandeja de notificaciones: panel flotante de cristal ─────────────── */
/* Mismo lenguaje que el menú: pieza de cristal separada del borde, esquinas redondeadas y entrada
   deslizándose (aquí desde la derecha, que es donde vive) ganando opacidad; al cerrar, al revés.
   Colores por tipo compartidos con los avisos emergentes (sección 6). En claro, todos llegan a 4,5:1
   (AA para texto pequeño) incluso sobre el tono más oscuro del cristal (#d2e2f2); los anteriores se
   quedaban en 2,7–4,3:1 en las pastillas del calendario, los horarios de Empleados y Ajustes. */
:root {
    --gm-t-ok: light-dark(#116b42, #5fd49a);
    --gm-t-error: light-dark(#b3213f, #ff7d92);
    --gm-t-aviso: light-dark(#865500, #f2c14e);
    --gm-t-info: light-dark(#0e6a83, #6fd0e8);
    --gm-bandeja-w: 25rem;
}
html.gm-js .bandeja-overlay {
    background: light-dark(rgb(16 35 58 / .16), rgb(0 0 0 / .42));
    transition: opacity .35s ease, visibility 0s .35s;
}
html.gm-js .bandeja-overlay.abierto { transition: opacity .35s ease; }

html.gm-js .bandeja-panel {
    box-sizing: border-box;
    top: var(--gm-margen);
    right: var(--gm-margen);
    bottom: var(--gm-margen);
    height: auto;
    width: min(var(--gm-bandeja-w), calc(100vw - 2 * var(--gm-margen)));
    overflow: hidden;
    color: var(--gm-texto);
    font-family: var(--letra);
    background: var(--gm-bg-2);
    border: 1px solid var(--gm-borde);
    border-radius: var(--gm-radio);
    box-shadow: inset 0 1px 0 var(--gm-luz), var(--gm-sombra);
    backdrop-filter: var(--gm-blur);
    -webkit-backdrop-filter: var(--gm-blur);
    opacity: 0;
    transform: translateX(calc(100% + 2 * var(--gm-margen)));
    transition: transform .42s cubic-bezier(.22, .8, .3, 1), opacity .3s ease, visibility 0s .42s;
}
html.gm-js .bandeja-panel.abierto {
    opacity: 1;
    transform: none;
    transition: transform .42s cubic-bezier(.22, .8, .3, 1), opacity .3s ease;
}
/* Reflejo, igual que el rail y el panel del menú */
html.gm-js .bandeja-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(160deg, var(--gm-luz) 0%, transparent 30%);
    opacity: .5;
}
html.gm-js .bandeja-panel > * { position: relative; }

/* Cabecera */
html.gm-js .bandeja-cab {
    padding: 1.05rem .8rem .55rem 1.25rem;
    border-bottom: 0;
}
html.gm-js .bandeja-cab b { font-size: 1.15rem; font-weight: 700; letter-spacing: -.01em; }
html.gm-js .bandeja-btn {
    border: 1px solid var(--gm-borde);
    background: light-dark(rgb(255 255 255 / .45), rgb(255 255 255 / .05));
    color: var(--gm-texto);
    border-radius: 999px;
    padding: .28rem .75rem;
    font-size: .76rem;
    font-weight: 600;
    font-family: inherit;
    transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}
html.gm-js .bandeja-btn:hover { background: var(--gm-hover); }
html.gm-js .bandeja-btn-rojo { color: var(--gm-t-error); border-color: color-mix(in srgb, var(--gm-t-error) 30%, transparent); }
html.gm-js .bandeja-btn-rojo:hover { background: color-mix(in srgb, var(--gm-t-error) 13%, transparent); }
html.gm-js .bandeja-cerrar {
    display: grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    padding: 0;
    border-radius: 50%;
    color: var(--gm-suave);
    font-size: 1.45rem;
    transition: background-color .2s ease, color .2s ease;
}
html.gm-js .bandeja-cerrar:hover { background: var(--gm-hover); color: var(--gm-texto); }

/* Lista */
html.gm-js .bandeja-lista {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: .15rem .7rem 1rem;
    scrollbar-width: thin;
    scrollbar-color: light-dark(rgb(16 35 58 / .22), rgb(255 255 255 / .18)) transparent;
}
/* Filtro por año del historial de la campana */
html.gm-js .bandeja-anios {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    padding: 0 .8rem .55rem 1.25rem;
}
html.gm-js .bandeja-anios[hidden] { display: none; }
html.gm-js .bandeja-anios .bandeja-btn.activo {
    background: var(--gm-acento);
    border-color: var(--gm-acento);
    color: light-dark(white, rgb(10 20 35));
}
html.gm-js .bandeja-grupo {
    margin: .75rem .55rem .1rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--gm-suave);
}
html.gm-js .bandeja-grupo:first-child { margin-top: .25rem; }

html.gm-js .bandeja-item {
    position: relative;
    align-items: flex-start;
    gap: .7rem;
    padding: .7rem .5rem .7rem .7rem;
    border: 1px solid transparent;
    border-radius: 1rem;
    background: light-dark(rgb(255 255 255 / .36), rgb(255 255 255 / .035));
    transition: background-color .2s ease, border-color .2s ease;
}
html.gm-js .bandeja-item:hover { background: var(--gm-hover); }
html.gm-js .bandeja-item.no-leida {
    background: light-dark(rgb(3 94 177 / .08), rgb(140 200 255 / .09));
    border-color: light-dark(rgb(3 94 177 / .16), rgb(140 200 255 / .15));
}
/* Punto de "sin leer" delante de la fecha */
html.gm-js .bandeja-item.no-leida .bandeja-fecha::before {
    content: "";
    display: inline-block;
    width: .42rem;
    height: .42rem;
    margin-right: .35rem;
    border-radius: 50%;
    background: var(--gm-acento);
    vertical-align: .06rem;
}

/* Icono del tipo: cuadrado redondeado teñido con su color */
html.gm-js .bandeja-ico {
    --t: var(--gm-t-info);
    display: grid;
    place-items: center;
    width: 2.15rem;
    height: 2.15rem;
    margin-top: 0;
    border-radius: .8rem;
    background: color-mix(in srgb, var(--t) 15%, transparent);
}
html.gm-js .bandeja-ico svg { width: 1.05rem; height: 1.05rem; fill: var(--t); }
html.gm-js .bandeja-ico.noti-correcto { --t: var(--gm-t-ok); }
html.gm-js .bandeja-ico.noti-error { --t: var(--gm-t-error); }
html.gm-js .bandeja-ico.noti-advertencia { --t: var(--gm-t-aviso); }

html.gm-js .bandeja-cont { gap: .2rem; padding-top: .05rem; }
html.gm-js .bandeja-msg { font-size: .86rem; line-height: 1.42; color: var(--gm-texto); }
html.gm-js .bandeja-msg a { color: var(--gm-acento) !important; font-weight: 600; text-underline-offset: 2px; }
html.gm-js .bandeja-fecha { font-size: .72rem; color: var(--gm-suave); }
html.gm-js .bandeja-veces {
    margin-left: .4rem;
    padding: 0 .4rem;
    border-radius: 999px;
    font-weight: 700;
    background: var(--gm-hover);
    color: var(--gm-acento);
}

/* Acciones de cada aviso: silenciar y borrar */
html.gm-js .bandeja-item-omitir,
html.gm-js .bandeja-item-del {
    display: grid;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    border-radius: .6rem;
    color: var(--gm-suave);
    transition: background-color .2s ease, color .2s ease, opacity .2s ease;
}
html.gm-js .bandeja-item-del { font-size: 1.3rem; }
html.gm-js .bandeja-item-omitir:hover { background: var(--gm-hover); color: var(--gm-acento); }
html.gm-js .bandeja-item-del:hover { background: color-mix(in srgb, var(--gm-t-error) 14%, transparent); color: var(--gm-t-error); }
/* Con ratón solo aparecen al pasar por el aviso; en pantallas táctiles están siempre */
@media (hover: hover) {
    html.gm-js .bandeja-item-omitir,
    html.gm-js .bandeja-item-del { opacity: 0; }
    html.gm-js .bandeja-item:hover .bandeja-item-omitir,
    html.gm-js .bandeja-item:hover .bandeja-item-del,
    html.gm-js .bandeja-item:focus-within .bandeja-item-omitir,
    html.gm-js .bandeja-item:focus-within .bandeja-item-del { opacity: 1; }
}
html.gm-js .bandeja-omitir-titulo { color: var(--gm-suave); }

html.gm-js .bandeja-pie {
    margin-top: .45rem;
    padding: .55rem .6rem .55rem .9rem;
    border: 0;
    border-radius: .9rem;
    background: var(--gm-hover);
    color: var(--gm-suave);
}

/* Sin notificaciones */
html.gm-js .bandeja-vacia {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .3rem;
    margin: auto 0;
    padding: 2.5rem 1rem 3.5rem;
    color: var(--gm-suave);
    font-size: .85rem;
}
html.gm-js .bandeja-vacia b { color: var(--gm-texto); font-size: 1rem; }
/* Sin nada que borrar, fuera el botón */
html.gm-js .bandeja-panel:has(.bandeja-vacia) .bandeja-btn-rojo { visibility: hidden; }
html.gm-js .bandeja-vacia-ico {
    display: grid;
    place-items: center;
    width: 3.4rem;
    height: 3.4rem;
    margin-bottom: .5rem;
    border-radius: 1.1rem;
    background: var(--gm-hover);
    color: var(--gm-acento);
}
html.gm-js .bandeja-vacia-ico svg { width: 1.6rem; height: 1.6rem; }

/* Al abrir, los avisos entran en cascada deslizándose hacia la izquierda */
html.gm-js .bandeja-panel.entrando .bandeja-item,
html.gm-js .bandeja-panel.entrando .bandeja-grupo,
html.gm-js .bandeja-panel.entrando .bandeja-vacia {
    animation: gm-bandeja-entra .42s cubic-bezier(.22, .8, .3, 1) backwards;
    animation-delay: calc(.1s + var(--i, 0) * 35ms);
}
@keyframes gm-bandeja-entra { from { opacity: 0; transform: translateX(16px); } }

/* ── 6. Avisos emergentes: tarjeta de cristal con el color de su tipo ────── */
/* #notificacion (crear_notificacion en PHP y JS) y .notificacion-fija (crear_notificacion_inline,
   con nivel-1..4). Se apilan arriba a la derecha sin pisarse: glass-menu.js coloca cada uno bajo el
   anterior según su altura real (el top de CSS es solo el respaldo). Entran desde la derecha ganando
   opacidad y salen igual; la barra inferior marca el tiempo que queda y se para al pasar el ratón.
   Un clic en el aviso (fuera de sus enlaces) lo cierra. */
html.gm-js #notificacion,
html.gm-js .notificacion-fija {
    --t: var(--gm-t-aviso);
    box-sizing: border-box;
    top: calc(var(--gm-margen) + var(--gm-toast-n, 0) * 4.2rem);
    right: var(--gm-margen);
    width: max-content;
    max-width: min(24rem, calc(100vw - 2 * var(--gm-margen)));
    align-items: flex-start;
    gap: .7rem;
    padding: .65rem 1rem .75rem .65rem;
    overflow: hidden;
    color: var(--gm-texto);
    font-family: var(--letra);
    font-size: .88rem;
    line-height: 1.4;
    background:
        linear-gradient(100deg, color-mix(in srgb, var(--t) 13%, transparent), transparent 55%),
        light-dark(rgb(255 255 255 / .84), rgb(24 38 58 / .88));
    border: 1px solid var(--gm-borde);
    border-radius: 1.05rem;
    box-shadow: inset 0 1px 0 var(--gm-luz), 0 14px 34px light-dark(rgb(18 52 92 / .2), rgb(0 0 0 / .5));
    backdrop-filter: var(--gm-blur);
    -webkit-backdrop-filter: var(--gm-blur);
    cursor: default;
    transition: top .35s cubic-bezier(.22, .8, .3, 1);
    animation: gm-toast 8s both;
}
html.gm-js .notificacion-fija.nivel-2 { --gm-toast-n: 1; animation-delay: .2s; }
html.gm-js .notificacion-fija.nivel-3 { --gm-toast-n: 2; animation-delay: .4s; }
html.gm-js .notificacion-fija.nivel-4 { --gm-toast-n: 3; animation-delay: .6s; }
html.gm-js #notificacion:has(.noti-correcto, .noti-ok),
html.gm-js .notificacion-fija.noti-correcto { --t: var(--gm-t-ok); }
html.gm-js #notificacion:has(.noti-error),
html.gm-js .notificacion-fija.noti-error { --t: var(--gm-t-error); }
html.gm-js #notificacion:has(.noti-info),
html.gm-js .notificacion-fija.noti-info { --t: var(--gm-t-info); }

html.gm-js #notificacion #noti-ico,
html.gm-js .notificacion-fija #noti-ico {
    flex: none;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: .72rem;
    line-height: 0;
    background: color-mix(in srgb, var(--t) 16%, transparent);
}
html.gm-js #notificacion #noti-ico svg,
html.gm-js .notificacion-fija #noti-ico svg {
    width: 1.05rem;
    height: 1.05rem;
    padding: 0;
    border-radius: 0;
    fill: var(--t);
}
html.gm-js #notificacion #noti-mensaje,
html.gm-js .notificacion-fija #noti-mensaje { flex: 1 1 auto; min-width: 0; align-self: center; }
html.gm-js #notificacion #noti-mensaje a,
html.gm-js .notificacion-fija #noti-mensaje a { color: var(--gm-acento) !important; font-weight: 600; text-underline-offset: 2px; }

/* Barra del tiempo restante */
html.gm-js #notificacion::after,
html.gm-js .notificacion-fija::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    background: var(--t);
    opacity: .7;
    transform-origin: left;
    animation: gm-toast-barra 8s linear both;
    animation-delay: inherit;
}
html.gm-js #notificacion:hover,
html.gm-js .notificacion-fija:hover,
html.gm-js #notificacion:hover::after,
html.gm-js .notificacion-fija:hover::after { animation-play-state: paused; }

/* Cerrado con un clic: sale ya, deslizándose a la derecha */
html.gm-js #notificacion.gm-toast-fuera,
html.gm-js .notificacion-fija.gm-toast-fuera {
    animation: gm-toast-sale .3s ease-in both !important;
    pointer-events: none;
}
html.gm-js .gm-toast-fuera::after { animation-play-state: paused !important; }

/* Sin light-dark() dentro de @keyframes (cuelga Chrome): solo opacidad, transform y visibilidad */
@keyframes gm-toast {
    0% { opacity: 0; transform: translateX(calc(100% + 2rem)); visibility: visible; animation-timing-function: cubic-bezier(.22, .8, .3, 1); }
    6% { opacity: 1; transform: none; }
    90% { opacity: 1; transform: none; animation-timing-function: ease-in; }
    100% { opacity: 0; transform: translateX(calc(100% + 2rem)); visibility: hidden; }
}
@keyframes gm-toast-barra {
    0%, 6% { transform: scaleX(1); }
    90%, 100% { transform: scaleX(0); }
}
@keyframes gm-toast-sale {
    from { opacity: 1; transform: none; }
    to { opacity: 0; transform: translateX(calc(100% + 2rem)); visibility: hidden; }
}
@keyframes gm-toast-quieto {
    0% { opacity: 0; visibility: visible; }
    4%, 94% { opacity: 1; }
    100% { opacity: 0; visibility: hidden; }
}

/* Móvil y tablet: abajo y a todo el ancho (arriba tapaban el título y las pestañas; abajo quedan
   además a mano del pulgar). glass-menu.js los apila desde abajo con su altura real. */
@media (width <= 950px) {
    html.gm-js #notificacion,
    html.gm-js .notificacion-fija {
        top: auto;
        bottom: calc(var(--gm-margen) + env(safe-area-inset-bottom, 0px) + var(--gm-toast-n, 0) * 4.2rem);
        transition: bottom .35s cubic-bezier(.22, .8, .3, 1);
        left: var(--gm-margen);
        right: var(--gm-margen);
        width: auto;
        max-width: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    html.gm-js .bandeja-panel { transform: none; transition: opacity .2s ease, visibility 0s .2s; }
    html.gm-js .bandeja-panel.abierto { transition: opacity .2s ease; }
    html.gm-js .bandeja-panel.entrando * { animation: none !important; }
    html.gm-js #notificacion,
    html.gm-js .notificacion-fija { animation-name: gm-toast-quieto; transition: none; }
}

/* ── 7. Campos de formulario ─────────────────────────────────────────────── */
/* Texto, número, correo, contraseña, búsqueda, fecha, hora, mes, desplegables, textarea, casillas
   (.chk), opciones segmentadas (radios .label-radio), deslizadores, ficheros y el desplegable
   buscable (combobox). Cristal claro con borde fino, esquinas suaves y anillo azul al enfocar.
   REGLAS PARA NO ROMPER NADA:
   - El borde es una sombra interior, no un border: el campo mide lo mismo que antes (hay rejillas de
     horas muy ajustadas). No se tocan tamaños, rellenos ni fuentes.
   - Especificidad (0,1,1): gana a input/select/textarea e input:valid de base.css, y pierde con las
     reglas de componentes más concretas (.hora-cell input.hora-afectada, .input-error !important).
   - Fuera: .ia-input y .na-combo-input (estilo propio), el interruptor claro/oscuro y los tipos que
     no son campos (checkbox, radio, range, file, hidden, botones). */
:root {
    --gm-campo-bg: light-dark(rgb(255 255 255 / .62), rgb(8 18 32 / .42));
    --gm-campo-bg-hover: light-dark(rgb(255 255 255 / .8), rgb(8 18 32 / .56));
    --gm-campo-bg-foco: light-dark(rgb(255 255 255 / .94), rgb(8 18 32 / .7));
    --gm-campo-linea: light-dark(rgb(16 35 58 / .15), rgb(255 255 255 / .13));
    --gm-campo-linea-hover: light-dark(rgb(3 94 177 / .38), rgb(140 200 255 / .38));
    --gm-campo-anillo: light-dark(rgb(3 94 177 / .16), rgb(140 200 255 / .18));
    --gm-campo-hundido: inset 0 1px 2px light-dark(rgb(16 35 58 / .07), rgb(0 0 0 / .32));
    --gm-campo-radio: .7rem;
}

.gm-js :is(input:where(:not([type=checkbox], [type=radio], [type=range], [type=file], [type=hidden], [type=button], [type=submit], [type=reset], [type=color], [type=image], .ia-input, .na-combo-input, .toggle-checkbox)), select, textarea:where(:not(.ia-input))) {
    border: none;
    outline: none;
    border-radius: var(--gm-campo-radio);
    background-color: var(--gm-campo-bg);
    color: var(--gm-texto);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), var(--gm-campo-hundido);
    accent-color: var(--gm-acento);
    transition: background-color .2s ease, box-shadow .2s ease, opacity .2s ease;
}
.gm-js :is(input:where(:not([type=checkbox], [type=radio], [type=range], [type=file], [type=hidden], [type=button], [type=submit], [type=reset], [type=color], [type=image], .ia-input, .na-combo-input, .toggle-checkbox)), select, textarea:where(:not(.ia-input))):hover {
    outline: none;
    background-color: var(--gm-campo-bg-hover);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover), var(--gm-campo-hundido);
}
.gm-js :is(input:where(:not([type=checkbox], [type=radio], [type=range], [type=file], [type=hidden], [type=button], [type=submit], [type=reset], [type=color], [type=image], .ia-input, .na-combo-input, .toggle-checkbox)), select, textarea:where(:not(.ia-input))):focus {
    outline: none;
    background-color: var(--gm-campo-bg-foco);
    box-shadow: inset 0 0 0 1.5px var(--gm-acento), 0 0 0 4px var(--gm-campo-anillo);
}
/* CAMPO MAL RELLENO — un solo aspecto venga de donde venga:
   • :user-invalid → lo dice el navegador y SOLO después de tocar el campo (si no, un obligatorio
     vacío salía en rojo nada más abrir la página, y los válidos teñidos de verde);
   • .input-error / aria-invalid → lo dice el JS del formulario al intentar enviar.
   Se ve con línea roja, un tinte rojo muy leve en el fondo y halo rojo; al enfocarlo el halo sube
   para saber cuál se está corrigiendo. No cambia tamaños: la línea sigue siendo sombra interior. */
:root {
    --gm-campo-error-bg: light-dark(rgb(204 47 78 / .07), rgb(255 125 146 / .1));
    --gm-campo-error-anillo: color-mix(in srgb, var(--gm-t-error) 16%, transparent);
    --gm-campo-error-anillo-foco: color-mix(in srgb, var(--gm-t-error) 30%, transparent);
}
.gm-js :is(input:where(:not([type=checkbox], [type=radio], [type=range], [type=file], [type=hidden], [type=button], [type=submit], [type=reset], [type=color], [type=image], .ia-input, .na-combo-input, .toggle-checkbox)), select, textarea:where(:not(.ia-input))):is(:user-invalid, .input-error, [aria-invalid="true"]) {
    background-color: var(--gm-campo-error-bg);
    box-shadow: inset 0 0 0 1.5px var(--gm-t-error), 0 0 0 4px var(--gm-campo-error-anillo);
}
.gm-js :is(input:where(:not([type=checkbox], [type=radio], [type=range], [type=file], [type=hidden], [type=button], [type=submit], [type=reset], [type=color], [type=image], .ia-input, .na-combo-input, .toggle-checkbox)), select, textarea:where(:not(.ia-input))):is(:user-invalid, .input-error, [aria-invalid="true"]):focus {
    /* también el fondo: la regla general de :focus lo ponía blanco y el campo con foco perdía el
       tinte rojo mientras se corrige */
    background-color: var(--gm-campo-error-bg);
    box-shadow: inset 0 0 0 1.5px var(--gm-t-error), 0 0 0 4px var(--gm-campo-error-anillo-foco);
}
/* Al marcarlos (el envío añade la clase de golpe a varios) una sacudida corta dice cuáles son sin
   tener que buscarlos. Sin light-dark() dentro del @keyframes (cuelga Chrome): solo transform. */
.gm-js :is(input, select, textarea):is(.input-error, [aria-invalid="true"]) {
    animation: gm-campo-error .32s ease;
}
@keyframes gm-campo-error {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-3px); }
    50% { transform: translateX(3px); }
    75% { transform: translateX(-2px); }
}
@media (prefers-reduced-motion: reduce) {
    .gm-js :is(input, select, textarea):is(.input-error, [aria-invalid="true"]) { animation: none; }
}
.gm-js :is(input, select, textarea):disabled { opacity: .55; cursor: not-allowed; }
.gm-js :is(input, textarea)::placeholder { color: var(--gm-suave); opacity: .85; }
/* Autorrelleno del navegador: sin el fondo amarillo/azul que rompe el cristal */
.gm-js input:-webkit-autofill {
    -webkit-text-fill-color: var(--gm-texto);
    transition: background-color 600000s 0s, box-shadow .2s ease;
}

/* Fecha, hora y mes: el icono del calendario/reloj, discreto y con respuesta al pasar el ratón */
.gm-js input::-webkit-calendar-picker-indicator {
    padding: .15rem;
    border-radius: .4rem;
    opacity: .55;
    cursor: pointer;
    transition: opacity .2s ease, background-color .2s ease;
}
.gm-js input::-webkit-calendar-picker-indicator:hover { opacity: 1; background-color: var(--gm-hover); }
/* Búsqueda: la X de borrar, igual de discreta */
.gm-js input[type=search]::-webkit-search-cancel-button { opacity: .55; cursor: pointer; }
.gm-js input[type=search]::-webkit-search-cancel-button:hover { opacity: 1; }

/* Desplegables: flecha propia (base.css quita la del navegador y no ponía ninguna) */
.gm-js select {
    padding-right: 2.1rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237088a0' stroke-width='2.2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .7rem center;
    background-size: .8rem;
}
.gm-js select option { background-color: light-dark(#fff, #16243a); color: var(--gm-texto); }

/* Casillas (label.chk con la marca animada en SVG) */
.gm-js label.chk {
    background-color: light-dark(rgb(255 255 255 / .45), rgb(255 255 255 / .04));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
    border-radius: .85rem;
    transition: background-color .2s ease, box-shadow .2s ease;
}
.gm-js label.chk:hover {
    background-color: var(--gm-hover);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover);
}
.gm-js label.chk:has(> input[type=checkbox]:checked) {
    background-color: light-dark(rgb(3 94 177 / .09), rgb(140 200 255 / .09));
    box-shadow: inset 0 0 0 1px light-dark(rgb(3 94 177 / .28), rgb(140 200 255 / .26));
}
.gm-js .chk .path { stroke: var(--gm-suave); }
.gm-js .chk input:checked ~ svg .path { stroke: var(--gm-acento); stroke-width: 7; }

/* Casillas sueltas (sin label.chk): cuadro de cristal que se llena de azul con la marca blanca.
   Las de .chk van ocultas; el interruptor claro/oscuro y el consentimiento de IA tienen el suyo. */
.gm-js input[type=checkbox]:where(:not(.toggle-checkbox, .chk input, .ia-consent-check input)) {
    -webkit-appearance: none;
    appearance: none;
    display: inline-grid;
    place-content: center;
    flex: none;
    width: 1.1rem;
    height: 1.1rem;
    margin: 0 .15rem;
    padding: 0;
    border: none;
    outline: none;
    border-radius: .35rem;
    vertical-align: -.2rem;
    background: var(--gm-campo-bg-foco);
    box-shadow: inset 0 0 0 1.5px light-dark(rgb(16 35 58 / .3), rgb(255 255 255 / .3));
    cursor: pointer;
    transition: background-color .2s ease, box-shadow .2s ease;
}
.gm-js input[type=checkbox]:where(:not(.toggle-checkbox, .chk input, .ia-consent-check input))::before {
    content: "";
    width: .62rem;
    height: .62rem;
    background: #fff;
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
    transform: scale(0);
    transition: transform .15s cubic-bezier(.3, 1.4, .5, 1);
}
.gm-js input[type=checkbox]:where(:not(.toggle-checkbox, .chk input, .ia-consent-check input)):hover {
    box-shadow: inset 0 0 0 1.5px var(--gm-acento);
}
.gm-js input[type=checkbox]:where(:not(.toggle-checkbox, .chk input, .ia-consent-check input)):checked {
    background: var(--gm-pildora);
    box-shadow: 0 2px 6px light-dark(rgb(3 94 177 / .3), rgb(60 140 240 / .3));
}
.gm-js input[type=checkbox]:where(:not(.toggle-checkbox, .chk input, .ia-consent-check input)):checked::before { transform: scale(1); }
.gm-js input[type=checkbox]:where(:not(.toggle-checkbox, .chk input, .ia-consent-check input)):focus-visible {
    box-shadow: inset 0 0 0 1.5px var(--gm-acento), 0 0 0 4px var(--gm-campo-anillo);
}

/* Opciones segmentadas: los radios van ocultos y se pulsa su etiqueta */
.gm-js :is(#label-empleado, #label-fechas, #label-grupo, .label-radio) {
    padding: .5rem 1rem;
    border-radius: .85rem;
    background-color: light-dark(rgb(255 255 255 / .45), rgb(255 255 255 / .04));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
    color: var(--gm-texto);
    transition: background-color .2s ease, box-shadow .2s ease, color .2s ease, transform .15s ease;
}
.gm-js :is(#label-empleado, #label-fechas, #label-grupo, .label-radio):hover {
    background-color: var(--gm-hover);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover);
    color: var(--gm-acento);
}
.gm-js :is(#iempleado:checked ~ #label-empleado, #ifechas:checked ~ #label-fechas, #igrupo:checked ~ #label-grupo, .radio:checked ~ .label-radio:not(.pendiente, .aprobado, .desaprobado)) {
    background: var(--gm-pildora);
    color: #fff;
    box-shadow: var(--gm-brillo), inset 0 1px 0 rgb(255 255 255 / .3);
}
/* Estados de aprobación: conservan su color, con la misma forma */
.gm-js .radio:checked ~ .label-radio:is(.pendiente, .aprobado, .desaprobado) {
    box-shadow: 0 6px 16px rgb(16 35 58 / .18), inset 0 1px 0 rgb(255 255 255 / .3);
}
.gm-js :is(#label-empleado, #label-fechas, #label-grupo, .label-radio):active { transform: scale(.97); }

/* Deslizadores: pista con la parte recorrida en azul (--gm-rango lo pone glass-menu.js) */
.gm-js input[type=range] {
    -webkit-appearance: none;
    appearance: none;
    height: 1.5rem;
    padding: 0;
    border: none;
    outline: none;
    background: transparent;
    box-shadow: none;
    cursor: pointer;
    accent-color: var(--gm-acento);
}
.gm-js input[type=range]::-webkit-slider-runnable-track {
    height: .42rem;
    border-radius: 999px;
    background: linear-gradient(to right, var(--gm-acento) var(--gm-rango, 0%), light-dark(rgb(16 35 58 / .13), rgb(255 255 255 / .14)) var(--gm-rango, 0%));
    box-shadow: var(--gm-campo-hundido);
}
.gm-js input[type=range]::-moz-range-track {
    height: .42rem;
    border-radius: 999px;
    background: light-dark(rgb(16 35 58 / .13), rgb(255 255 255 / .14));
}
.gm-js input[type=range]::-moz-range-progress { height: .42rem; border-radius: 999px; background: var(--gm-acento); }
.gm-js input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 1.2rem;
    height: 1.2rem;
    margin-top: calc((.42rem - 1.2rem) / 2);
    border-radius: 50%;
    background: #fff;
    border: none;
    box-shadow: 0 0 0 1px light-dark(rgb(3 94 177 / .35), rgb(140 200 255 / .45)), 0 2px 6px rgb(16 35 58 / .25);
    transition: transform .15s ease, box-shadow .2s ease;
}
.gm-js input[type=range]::-moz-range-thumb {
    width: 1.2rem;
    height: 1.2rem;
    border-radius: 50%;
    background: #fff;
    border: none;
    box-shadow: 0 0 0 1px light-dark(rgb(3 94 177 / .35), rgb(140 200 255 / .45)), 0 2px 6px rgb(16 35 58 / .25);
}
.gm-js input[type=range]:hover::-webkit-slider-thumb { transform: scale(1.1); }
.gm-js input[type=range]:active::-webkit-slider-thumb { transform: scale(1.15); }
.gm-js input[type=range]:focus-visible::-webkit-slider-thumb {
    box-shadow: 0 0 0 1px var(--gm-acento), 0 0 0 5px var(--gm-campo-anillo), 0 2px 6px rgb(16 35 58 / .25);
}

/* Ficheros: campo de cristal con el botón "Seleccionar archivo" como píldora */
.gm-js input[type=file] {
    max-width: 100%;
    padding: .3rem .6rem .3rem .3rem;
    border: none;
    outline: none;
    border-radius: var(--gm-campo-radio);
    background-color: var(--gm-campo-bg);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), var(--gm-campo-hundido);
    color: var(--gm-suave);
    font-size: .9rem;
    cursor: pointer;
}
.gm-js input[type=file]::file-selector-button {
    margin-right: .7rem;
    padding: .45rem .9rem;
    border: none;
    border-radius: .55rem;
    background: var(--gm-hover);
    color: var(--gm-acento);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .2s ease;
}
.gm-js input[type=file]:hover::file-selector-button { background: light-dark(rgb(3 94 177 / .18), rgb(140 200 255 / .22)); }
.gm-js input[type=file]:focus-visible { box-shadow: inset 0 0 0 1.5px var(--gm-acento), 0 0 0 4px var(--gm-campo-anillo); }

/* Desplegable buscable (combobox de base.js): mismo cristal que los paneles */
.gm-js .combo-panel {
    padding: .35rem;
    border-radius: .95rem;
    outline: none;
    background: light-dark(rgb(255 255 255 / .9), rgb(20 33 52 / .94));
    color: var(--gm-texto);
    box-shadow: inset 0 0 0 1px var(--gm-borde), var(--gm-sombra);
    backdrop-filter: var(--gm-blur);
    -webkit-backdrop-filter: var(--gm-blur);
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--gm-suave) 45%, transparent) transparent;
}
.gm-js .combo-opt { border-radius: .6rem; transition: background-color .15s ease; }
.gm-js .combo-opt:hover { background: var(--gm-hover); color: var(--gm-acento); }
.gm-js .combo-opt.active { background: var(--gm-pildora); color: #fff; }
.gm-js .combo-opt mark { color: inherit; }
.gm-js .combo-empty { color: var(--gm-suave); }

/* ── 8. Selector de fechas (glass-fecha.js) ──────────────────────────────── */
/* Calendario propio en cristal para los input[type=date] (como el de HOPE). La fecha única conserva
   su input; las parejas desde/hasta se ven como UN campo (.gm-dp-campo) y sus dos inputs quedan
   ocultos (.gm-dp-oculto). El icono nativo se cambia por uno propio. */
.gm-js .gm-dp-oculto { display: none !important; }
.gm-js input.gm-dp-input,
.gm-js input.gm-dp-campo {
    cursor: pointer;
    padding-right: 2.3rem !important; /* algunas vistas traen padding en línea */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237088a0' stroke-width='1.6'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 7.5v11.25m-18 0A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75m-18 0v-7.5A2.25 2.25 0 0 1 5.25 9h13.5A2.25 2.25 0 0 1 21 11.25v7.5m-9-6h.008v.008H12v-.008ZM12 15h.008v.008H12V15Zm0 2.25h.008v.008H12v-.008ZM9.75 15h.008v.008H9.75V15Zm0 2.25h.008v.008H9.75v-.008ZM7.5 15h.008v.008H7.5V15Zm0 2.25h.008v.008H7.5v-.008Zm6.75-4.5h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008V15Zm0 2.25h.008v.008h-.008v-.008Zm2.25-4.5h.008v.008H16.5v-.008Zm0 2.25h.008v.008H16.5V15Z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .7rem center;
    background-size: 1.05rem;
}
.gm-js input.gm-dp-input::-webkit-calendar-picker-indicator { display: none; }
.gm-js input.gm-dp-campo { min-width: 14.5rem; text-align: left; cursor: text; } /* se puede escribir */
.gm-js input.gm-dp-campo::placeholder { color: var(--gm-suave); }
.gm-js input.gm-dp-campo.gm-dp-error { box-shadow: inset 0 0 0 1.5px var(--gm-t-error), 0 0 0 4px color-mix(in srgb, var(--gm-t-error) 16%, transparent); }
.gm-js input:is(.gm-dp-input, .gm-dp-campo)[aria-expanded="true"] {
    background-color: var(--gm-campo-bg-foco);
    box-shadow: inset 0 0 0 1.5px var(--gm-acento), 0 0 0 4px var(--gm-campo-anillo);
}

.gm-dp {
    position: fixed;
    inset: auto;
    z-index: 10000;
    box-sizing: border-box;
    width: 18.5rem;
    margin: 0;
    padding: .75rem;
    overflow: visible;
    border: 0;
    border-radius: 1.2rem;
    color: var(--gm-texto);
    font-family: var(--letra);
    font-size: 1rem;
    /* Casi opaco: se abre encima de tablas con colores fuertes y tiene que leerse */
    background: light-dark(rgb(255 255 255 / .95), rgb(20 33 52 / .96));
    box-shadow: inset 0 0 0 1px var(--gm-borde), inset 0 1px 0 var(--gm-luz), var(--gm-sombra);
    backdrop-filter: var(--gm-blur);
    -webkit-backdrop-filter: var(--gm-blur);
    user-select: none;
}
.gm-dp:not(.abierto) { display: none; }
/* Aparece deslizándose un poco hacia abajo (o hacia arriba si se abre encima) ganando opacidad */
.gm-dp.abierto { animation: gm-dp-entra .2s cubic-bezier(.22, .8, .3, 1); }
.gm-dp.abierto.arriba { animation-name: gm-dp-entra-arriba; }
@keyframes gm-dp-entra { from { opacity: 0; transform: translateY(-6px); } }
@keyframes gm-dp-entra-arriba { from { opacity: 0; transform: translateY(6px); } }
.gm-dp button { font-family: inherit; }

.gm-dp__cab { display: flex; align-items: center; gap: .25rem; margin-bottom: .55rem; }
.gm-dp__titulos { flex: 1; display: flex; justify-content: center; gap: .15rem; }
.gm-dp__titulo {
    padding: .2rem .45rem;
    border: 0;
    border-radius: .6rem;
    background: transparent;
    color: var(--gm-texto);
    font-size: .95rem;
    font-weight: 700;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}
.gm-dp__titulo:hover { background: var(--gm-hover); color: var(--gm-acento); }
.gm-dp__nav {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 0;
    border-radius: .7rem;
    background: light-dark(rgb(255 255 255 / .6), rgb(255 255 255 / .06));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
    color: var(--gm-suave);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, transform .1s ease;
}
.gm-dp__nav svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.gm-dp__nav:hover { background: var(--gm-hover); color: var(--gm-acento); }
.gm-dp__nav:active { transform: scale(.93); }

.gm-dp__guia {
    margin: -.1rem 0 .4rem;
    text-align: center;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--gm-acento);
}
.gm-dp__semana { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: .25rem; }
.gm-dp__semana span { text-align: center; font-size: .68rem; font-weight: 700; color: var(--gm-suave); }
.gm-dp__semana span:nth-child(n+6) { color: color-mix(in srgb, var(--gm-t-error) 70%, var(--gm-suave)); }

.gm-dp__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.gm-dp__grid--meses { grid-template-columns: repeat(3, 1fr); gap: .35rem; }
.gm-dp__dia {
    height: 2.1rem;
    padding: 0;
    border: 0;
    border-radius: .65rem;
    background: transparent;
    color: var(--gm-texto);
    font-size: .82rem;
    cursor: pointer;
    transition: background-color .12s ease, transform .1s ease;
}
.gm-dp__dia:hover:not(:disabled) { background: var(--gm-hover); color: var(--gm-acento); }
.gm-dp__dia:active:not(:disabled) { transform: scale(.9); }
.gm-dp__dia--finde:not(.gm-dp__dia--sel, .gm-dp__dia--rango) { background: light-dark(rgb(204 47 78 / .05), rgb(255 125 146 / .06)); }
.gm-dp__dia--otro { color: color-mix(in srgb, var(--gm-suave) 55%, transparent); }
.gm-dp__dia--hoy { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--gm-acento) 55%, transparent); font-weight: 700; }
.gm-dp__dia--rango { background: light-dark(rgb(3 94 177 / .12), rgb(140 200 255 / .14)); border-radius: 0; }
.gm-dp__dia--sel,
.gm-dp__dia--sel:hover:not(:disabled) {
    background: var(--gm-pildora);
    color: #fff;
    font-weight: 700;
    box-shadow: var(--gm-brillo), inset 0 1px 0 rgb(255 255 255 / .3);
}
.gm-dp__dia:disabled { opacity: .3; cursor: not-allowed; text-decoration: line-through; }
.gm-dp__mes { height: 2.7rem; font-size: .85rem; }

.gm-dp__atajos {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .6rem;
    padding-top: .6rem;
    border-top: 1px solid var(--gm-campo-linea);
}
.gm-dp__atajos button {
    flex: 1 1 auto;
    padding: .32rem .5rem;
    border: 0;
    border-radius: 999px;
    background: light-dark(rgb(255 255 255 / .6), rgb(255 255 255 / .06));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
    color: var(--gm-texto);
    font-size: .72rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, transform .1s ease;
}
.gm-dp__atajos button:hover { background: var(--gm-hover); color: var(--gm-acento); }
.gm-dp__atajos button:active { transform: scale(.95); }
.gm-dp__atajos [data-atajo="borrar"] { color: var(--gm-t-error); }
.gm-dp__atajos [data-atajo="borrar"]:hover { background: color-mix(in srgb, var(--gm-t-error) 12%, transparent); color: var(--gm-t-error); }

@media (prefers-reduced-motion: reduce) {
    .gm-dp.abierto { animation: none; }
}

/* ── 9. Botones ──────────────────────────────────────────────────────────── */
/* .btn-p principal (píldora azul con brillo), .btn-s secundario (cristal), .btn-t de texto,
   .btn-d peligro (rojo) y .btn-circle-glass (iconos de las tablas: editar, eliminar, descargar).
   No se tocan tamaños, rellenos ni fuentes: solo aspecto. base.css pone !important en el hover
   de .btn-p (se volvía blanco) y en el fondo/borde de .btn-circle-glass, por eso aquí también. */
:root {
    --gm-btn-radio: .85rem;
    --gm-rojo-pildora: linear-gradient(135deg, light-dark(rgb(214 48 80), rgb(236 92 120)), light-dark(rgb(186 30 62), rgb(200 60 92)));
    --gm-rojo-brillo: 0 8px 20px light-dark(rgb(204 47 78 / .32), rgb(236 92 120 / .28));
}
.gm-js :is(.btn-p, .btn-s, .btn-t, .btn-d) {
    border: none;
    outline: none;
    border-radius: var(--gm-btn-radio);
    font-family: var(--letra);
    transition: background-color .2s ease, color .2s ease, box-shadow .2s ease, transform .15s ease, filter .2s ease;
}
.gm-js :is(.btn-p, .btn-s, .btn-t, .btn-d):active:not(:disabled) { transform: scale(.97); }
.gm-js :is(.btn-p, .btn-s, .btn-t, .btn-d):focus-visible {
    outline: 2px solid var(--gm-acento);
    outline-offset: 2px;
}
.gm-js :is(.btn-p, .btn-s, .btn-t, .btn-d, .btn-circle-glass):disabled {
    opacity: .5;
    cursor: not-allowed;
    transform: none;
    filter: none;
}

/* Principal */
.gm-js .btn-p {
    background: var(--gm-pildora);
    color: #fff;
    box-shadow: var(--gm-brillo), inset 0 1px 0 rgb(255 255 255 / .28);
}
.gm-js .btn-p svg,
.gm-js .btn-p:where(:hover, :focus) svg { fill: currentColor; }
.gm-js .btn-p:where(:hover, :focus-visible):not(:disabled) {
    background: var(--gm-pildora);
    color: #fff !important;
    filter: brightness(1.08) saturate(1.05);
    transform: translateY(-1px);
    box-shadow: 0 12px 26px light-dark(rgb(3 94 177 / .38), rgb(60 140 240 / .34)), inset 0 1px 0 rgb(255 255 255 / .34);
}
/* Tras pulsarlo con el ratón no se queda "encendido" (base.css lo dejaba invertido con :focus) */
.gm-js .btn-p:focus:not(:focus-visible):not(:hover) {
    background: var(--gm-pildora);
    color: #fff !important;
}

/* Secundario */
.gm-js .btn-s {
    background: light-dark(rgb(255 255 255 / .55), rgb(255 255 255 / .06));
    color: var(--gm-texto);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), 0 2px 6px light-dark(rgb(16 35 58 / .06), rgb(0 0 0 / .2));
}
.gm-js .btn-s svg { fill: currentColor; }
.gm-js .btn-s:where(:hover, :focus-visible):not(:disabled) {
    background: color-mix(in srgb, var(--gm-acento) 9%, light-dark(rgb(255 255 255 / .7), rgb(255 255 255 / .06)));
    color: var(--gm-acento);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover), 0 4px 12px light-dark(rgb(3 94 177 / .12), rgb(0 0 0 / .25));
}
.gm-js .btn-s:focus:not(:focus-visible):not(:hover) { color: var(--gm-texto); }

/* De texto */
.gm-js .btn-t {
    background: transparent;
    color: var(--gm-suave);
    box-shadow: none;
}
.gm-js .btn-t svg { fill: currentColor; }
.gm-js .btn-t:where(:hover, :focus-visible):not(:disabled) {
    background: var(--gm-hover);
    color: var(--gm-acento);
}

/* Peligro */
.gm-js .btn-d {
    background: var(--gm-rojo-pildora);
    color: #fff;
    box-shadow: var(--gm-rojo-brillo), inset 0 1px 0 rgb(255 255 255 / .25);
}
.gm-js .btn-d svg { fill: currentColor; }
.gm-js .btn-d:where(:hover, :focus-visible):not(:disabled) {
    filter: brightness(1.07);
    transform: translateY(-1px);
    box-shadow: 0 12px 26px light-dark(rgb(204 47 78 / .4), rgb(236 92 120 / .34)), inset 0 1px 0 rgb(255 255 255 / .3);
}

/* Iconos de las tablas: cuadrados de cristal que se tiñen del color de su acción */
.gm-js .btn-circle-glass {
    background: light-dark(rgb(255 255 255 / .7), rgb(255 255 255 / .07)) !important;
    border: none !important;
    border-radius: .7rem;
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), 0 2px 6px light-dark(rgb(16 35 58 / .08), rgb(0 0 0 / .25));
    backdrop-filter: none;
    transition: background-color .2s ease, box-shadow .2s ease, transform .15s ease;
}
.gm-js .btn-circle-glass:where(:hover, :focus-visible):not(:disabled) {
    background: light-dark(rgb(3 94 177 / .12), rgb(140 200 255 / .16)) !important;
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover), 0 4px 12px light-dark(rgb(3 94 177 / .16), rgb(0 0 0 / .3));
    transform: translateY(-1px);
}
.gm-js .btn-circle-glass:is(.rojo, .eliminar):where(:hover, :focus-visible):not(:disabled) {
    background: color-mix(in srgb, var(--gm-t-error) 14%, transparent) !important;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-error) 40%, transparent), 0 4px 12px color-mix(in srgb, var(--gm-t-error) 20%, transparent);
}
.gm-js .btn-circle-glass:active:not(:disabled) { transform: scale(.93); }
.gm-js .btn-circle-glass:focus-visible { outline: 2px solid var(--gm-acento); outline-offset: 2px; }

/* Mostrar/ocultar contraseña: botón pegado a la derecha del campo, formando una sola pieza */
.gm-js input:has(+ :is(#perfil-toggle-contra, #toggle-contraseña, #mostrarcontra)) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.gm-js :is(#perfil-toggle-contra, #toggle-contraseña, #mostrarcontra) {
    border: none !important;
    border-radius: 0 var(--gm-campo-radio) var(--gm-campo-radio) 0 !important;
    background: var(--gm-pildora) !important;
    fill: #fff !important;
    color: #fff;
    box-shadow: none !important;
    transition: filter .2s ease;
}
.gm-js :is(#perfil-toggle-contra, #toggle-contraseña, #mostrarcontra):hover { filter: brightness(1.1); }

@media (prefers-reduced-motion: reduce) {
    .gm-js :is(.btn-p, .btn-s, .btn-t, .btn-d, .btn-circle-glass) { transform: none !important; }
}

/* ── 10. Tablas ──────────────────────────────────────────────────────────── */
/* Todas las <table> (salvo la del asistente de IA) y la rejilla de Registros (.grid-registros, que
   trae su propio <style> al cargarse por ajax: por eso sus reglas aquí llevan una clase más).
   Cristal claro, esquinas grandes, cabecera suave, filas separadas por una línea fina, cebra muy
   ligera y la fila entera se tiñe al pasar el ratón. Se conservan los colores con significado
   (horas no puntuales en rojo, etiquetas, fondos puestos en la propia celda). Mismos tamaños: las
   líneas son sombras interiores, no bordes. */
:root {
    --gm-tabla-bg: light-dark(rgb(255 255 255 / .5), rgb(255 255 255 / .03));
    --gm-tabla-cab: light-dark(rgb(16 35 58 / .055), rgb(255 255 255 / .06));
    --gm-tabla-linea: light-dark(rgb(16 35 58 / .08), rgb(255 255 255 / .07));
    --gm-tabla-cebra: light-dark(rgb(3 94 177 / .045), rgb(140 200 255 / .035));
    --gm-tabla-fila-hover: light-dark(rgb(3 94 177 / .08), rgb(140 200 255 / .08));
    --gm-tabla-celda-hover: light-dark(rgb(3 94 177 / .15), rgb(140 200 255 / .15));
    --gm-tabla-radio: 1rem;
    --gm-tabla-sombra: 0 6px 18px light-dark(rgb(16 35 58 / .07), rgb(0 0 0 / .25));
}

@media (width > 950px) {
    /* Tablas normales */
    .gm-js table:not(.ia-tabla) {
        border: 1px solid var(--gm-campo-linea);
        border-radius: var(--gm-tabla-radio);
        background: var(--gm-tabla-bg);
        box-shadow: var(--gm-tabla-sombra);
    }
    .gm-js table:not(.ia-tabla) thead tr {
        background-color: var(--gm-tabla-cab) !important;
    }
    .gm-js table:not(.ia-tabla) thead :is(td, th) {
        color: var(--gm-texto);
        font-weight: 700;
        box-shadow: inset 0 -1px 0 var(--gm-campo-linea);
    }
    .gm-js table:not(.ia-tabla) thead :is(td, th):hover { background-color: transparent; }
    .gm-js table:not(.ia-tabla) tbody tr:nth-child(odd) { background-color: transparent; }
    .gm-js table:not(.ia-tabla) tbody tr:nth-child(even) { background-color: var(--gm-tabla-cebra); }
    .gm-js table:not(.ia-tabla) tbody tr:not(:last-child) > td { box-shadow: inset 0 -1px 0 var(--gm-tabla-linea); }
    .gm-js table:not(.ia-tabla) tbody tr:not(.fila-notas-emp):hover > td { background-color: var(--gm-tabla-fila-hover); }
    .gm-js table:not(.ia-tabla) tbody tr:not(.fila-notas-emp) > td:hover { background-color: var(--gm-tabla-celda-hover); }
    .gm-js table:not(.ia-tabla) td { transition: background-color .15s ease; }
    /* Más aire dentro de las celdas (estaban muy apretadas) y cifras de ancho fijo: las columnas de
       horas y días quedan alineadas */
    .gm-js table:not(.ia-tabla) :is(td, th) { padding: .55rem .85rem; font-variant-numeric: tabular-nums; }
    .gm-js table:not(.ia-tabla) thead :is(td, th) { padding-block: .65rem; }
    /* Esquinas de las celdas al radio de la tabla (si no, su fondo asoma por la curva) */
    .gm-js table:not(.ia-tabla) thead tr:first-child > :is(td, th):first-child { border-top-left-radius: calc(var(--gm-tabla-radio) - 1px); }
    .gm-js table:not(.ia-tabla) thead tr:first-child > :is(td, th):last-child { border-top-right-radius: calc(var(--gm-tabla-radio) - 1px); }
    .gm-js table:not(.ia-tabla) tbody tr:last-child > td:first-child { border-bottom-left-radius: calc(var(--gm-tabla-radio) - 1px); }
    .gm-js table:not(.ia-tabla) tbody tr:last-child > td:last-child { border-bottom-right-radius: calc(var(--gm-tabla-radio) - 1px); }

    /* Rejilla de Registros */
    .gm-js .grid-registros {
        border: 1px solid var(--gm-campo-linea);
        border-radius: var(--gm-tabla-radio);
        background: var(--gm-tabla-bg);
        box-shadow: var(--gm-tabla-sombra);
    }
    .gm-js .grid-registros .fila:nth-child(odd) .celda { background-color: transparent; }
    .gm-js .grid-registros .fila:nth-child(even) .celda { background-color: var(--gm-tabla-cebra); }
    .gm-js .grid-registros .fila:not(:last-child) .celda { box-shadow: inset 0 -1px 0 var(--gm-tabla-linea); }
    .gm-js .grid-registros .fila:hover .celda { background-color: var(--gm-tabla-fila-hover); }
    .gm-js .grid-registros .fila .celda:hover { background-color: var(--gm-tabla-celda-hover); }
    .gm-js .grid-registros .celda { font-variant-numeric: tabular-nums; }
    .gm-js .grid-registros .cabecera .celda-header {
        background-color: var(--gm-tabla-cab);
        color: var(--gm-texto);
        box-shadow: inset 0 -1px 0 var(--gm-campo-linea);
    }
    .gm-js .grid-registros .cabecera .celda-header:hover { background-color: var(--gm-tabla-cab); }
    .gm-js .grid-registros .cabecera .celda-header:first-child { border-top-left-radius: calc(var(--gm-tabla-radio) - 1px); }
    .gm-js .grid-registros .cabecera .celda-header:last-child { border-top-right-radius: calc(var(--gm-tabla-radio) - 1px); }
    .gm-js .grid-registros .fila:last-child .celda:first-child { border-bottom-left-radius: calc(var(--gm-tabla-radio) - 1px); }
    .gm-js .grid-registros .fila:last-child .celda:last-child { border-bottom-right-radius: calc(var(--gm-tabla-radio) - 1px); }
}

/* Móvil y tablet: cada fila es una tarjeta de cristal (base.css ya las convierte en tarjetas) */
@media (width <= 950px) {
    .gm-js table:not(.ia-tabla) tbody tr,
    .gm-js table:not(.ia-tabla) tbody tr:nth-child(n) {
        border-radius: var(--gm-tabla-radio);
        background-color: var(--gm-tabla-bg);
        box-shadow: inset 0 0 0 1px var(--gm-campo-linea), var(--gm-tabla-sombra);
    }
    .gm-js table:not(.ia-tabla) td:hover { background-color: transparent; }
    .gm-js table:not(.ia-tabla) td[data-label]:not([data-label=""])::before { color: var(--gm-suave); font-weight: 600; }
    /* En la tarjeta la celda es flex y se come el espacio antes de un <small>: "30(generales)" */
    .gm-js table:not(.ia-tabla) td > small { margin-left: .3rem; }

    .gm-js .grid-registros .fila:nth-child(n) {
        border-radius: var(--gm-tabla-radio);
        background-color: var(--gm-tabla-bg);
        box-shadow: inset 0 0 0 1px var(--gm-campo-linea), var(--gm-tabla-sombra);
    }
    .gm-js .grid-registros .horas-wrapper .celda { background-color: var(--gm-tabla-cebra); }
}

/* Esqueleto de carga con la misma forma */
.gm-js .skeleton-tabla {
    border: 1px solid var(--gm-campo-linea);
    border-radius: var(--gm-tabla-radio);
    background: var(--gm-tabla-bg);
}
.gm-js .skeleton-tabla-head-cell { background: var(--gm-tabla-cab); }
/* Filas del esqueleto con la misma cebra suave que las tablas (antes franjas verde/azul), línea fina
   entre filas y barras redondeadas de anchos variados con un brillo teñido de azul */
.gm-js .skeleton-tabla-cell[data-row="0"] { background-color: transparent; }
.gm-js .skeleton-tabla-cell[data-row="1"] { background-color: var(--gm-tabla-cebra); }
.gm-js .skeleton-tabla-cell:not(.skeleton-tabla-head-cell) { box-shadow: inset 0 -1px 0 var(--gm-tabla-linea); }
.gm-js .skeleton-tabla-head-cell { box-shadow: inset 0 -1px 0 var(--gm-campo-linea); }
.gm-js :is(.skeleton-bar, .skeleton-row, .skeleton-card) {
    background: linear-gradient(90deg,
        light-dark(rgb(16 35 58 / .07), rgb(255 255 255 / .06)) 0%,
        light-dark(rgb(3 94 177 / .16), rgb(140 200 255 / .16)) 50%,
        light-dark(rgb(16 35 58 / .07), rgb(255 255 255 / .06)) 100%);
    background-size: 200% 100%;
}
.gm-js .skeleton-bar { height: .75rem; border-radius: 999px; }
.gm-js .skeleton-tabla-cell:nth-child(3n) .skeleton-bar { width: 48%; }
.gm-js .skeleton-tabla-cell:nth-child(4n+1) .skeleton-bar { width: 62%; }
.gm-js .skeleton-tabla-cell:nth-child(5n+2) .skeleton-bar { width: 78%; }
.gm-js .skeleton-tabla-head-cell .skeleton-bar { width: 55%; height: .7rem; }
.gm-js :is(.skeleton-row, .skeleton-card) { border-radius: var(--gm-tabla-radio); }

/* ── 11. Contenido de las tablas ─────────────────────────────────────────── */
/* Lo que va dentro: horas no puntuales, etiquetas (horas de más/menos, Impar, fin de semana…),
   marcas de hora modificada y de localización, motivo del registro y tooltips. */

/* Campos dentro de tablas con fondo blanco puesto en línea (horas acumuladas): cristal como el resto */
.gm-js :is(td, .celda) input[style*="background-color:light-dark(white"] { background-color: var(--gm-campo-bg) !important; }
.gm-js :is(td, .celda) input[style*="background-color:light-dark(white"]:focus { background-color: var(--gm-campo-bg-foco) !important; }

/* Hora NO puntual (:nth-child(n) para ganar al <style> de la rejilla, que llega después): tinte rojo suave que late y la hora en rojo (antes, celda rojo intenso con
   texto blanco). Sin light-dark() en el @keyframes (cuelga Chrome): los colores van en variables. */
:root {
    --gm-vivo-a: light-dark(rgb(204 47 78 / .09), rgb(255 110 135 / .10));
    --gm-vivo-b: light-dark(rgb(204 47 78 / .20), rgb(255 110 135 / .22));
}
@keyframes gm-vivo {
    0%, 100% { background-color: var(--gm-vivo-a); }
    50% { background-color: var(--gm-vivo-b); }
}
.gm-js :is(td.nopuntual, .celda.nopuntual),
.gm-js .grid-registros .fila:nth-child(n) .celda.nopuntual {
    color: var(--gm-t-error);
    font-weight: 700;
    animation: gm-vivo 4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .gm-js :is(td.nopuntual, .celda.nopuntual),
    .gm-js .grid-registros .fila:nth-child(n) .celda.nopuntual { animation: none; background-color: var(--gm-vivo-b); }
}

/* Etiquetas: píldora con el color de su tipo en tinte y el texto en ese color */
.gm-js .men-incidencia {
    --t: var(--gm-suave);
    display: inline-block;
    padding: .18rem .6rem;
    border-radius: 999px;
    background-color: color-mix(in srgb, var(--t) 15%, transparent);
    color: var(--t);
    font-weight: 700;
    line-height: 1.25;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t) 26%, transparent);
}
.gm-js .men-incidencia.incidencia-impar { --t: var(--gm-t-aviso); }
.gm-js .men-incidencia.incidencia-ocho- { --t: var(--gm-t-error); }
.gm-js .men-incidencia.incidencia-ocho-mas { --t: var(--gm-t-ok); }
.gm-js .men-incidencia.incidencia-finde { --t: light-dark(#5b6b7d, #a9b8c8); }
.gm-js .men-incidencia.incidencia-no-trabajo { --t: light-dark(#7b3fd6, #b99bf5); }
/* Fichó un día de vacaciones: aviso en rojo, bajo la fecha (tabla) o en el día (calendario) */
.gm-js .men-incidencia.incidencia-vacaciones { --t: var(--gm-t-error); margin-top: .15rem; font-size: .72rem; white-space: nowrap; }
/* La pequeña de horas de más/menos junto a las teóricas: mismo posicionamiento de base.css */
.gm-js sup.men-incidencia {
    display: inline;
    padding: .1rem .38rem;
    font-size: .62rem;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t) 30%, transparent);
}

/* Marcas bajo cada hora: modificada (M), localización y fuera de zona, más el origen del fichaje
   junto a la hora. Pastillas cuadradas del mismo tamaño, cada una con el color de lo que indica:
   M ámbar (aviso), pin turquesa, fuera de zona rojo con un halo que late, origen azul. */
:root {
    --gm-halo-a: 0 0 0 0 rgb(204 47 78 / .45);
    --gm-halo-b: 0 0 0 5px rgb(204 47 78 / 0);
}
@keyframes gm-halo-zona {
    0% { box-shadow: inset 0 0 0 1px rgb(204 47 78 / .45), var(--gm-halo-a); }
    70%, 100% { box-shadow: inset 0 0 0 1px rgb(204 47 78 / .45), var(--gm-halo-b); }
}
/* Altura fija, como en base.css: el tooltip de la M va dentro y ocupa sitio en la maqueta */
.gm-js .selectores-hora { height: 1.05rem; margin-top: 0; gap: .2rem; }
.gm-js .selectores-hora > span { gap: .2rem; }
.gm-js :is(.localiza, .t-hora-modificada) {
    --t: var(--gm-t-info);
    box-sizing: border-box;
    display: grid;
    place-items: center;
    width: 1.05rem;
    height: 1.05rem;
    padding: 0;
    border-radius: .38rem;
    background-color: color-mix(in srgb, var(--t) 14%, light-dark(rgb(255 255 255 / .7), transparent));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t) 32%, transparent);
    cursor: pointer;
    transition: transform .15s ease, background-color .2s ease;
}
.gm-js .t-hora-modificada { --t: var(--gm-t-aviso); cursor: help; }
.gm-js :is(.localiza, .t-hora-modificada) svg,
.gm-js .localiza svg.dorado { width: .62rem; height: .62rem; fill: var(--t); color: var(--t); }
.gm-js .localiza a { display: grid; place-items: center; width: 100%; height: 100%; }
.gm-js :is(.localiza, .t-hora-modificada):hover {
    transform: scale(1.12);
    background-color: color-mix(in srgb, var(--t) 24%, light-dark(rgb(255 255 255 / .7), transparent));
}
/* Fichaje fuera de sus zonas: pin en pastilla roja con halo */
.gm-js .localiza:has(svg.rojo) {
    --t: var(--gm-t-error);
    animation: gm-halo-zona 2.2s ease-out infinite;
}
.gm-js .localiza svg.rojo { fill: var(--gm-t-error) !important; }
/* …y la hora, con marco rojo suave en vez del recuadro discontinuo */
.gm-js .grid-registros .hora.fuera-zona {
    outline: none;
    padding: 0 .35rem;
    border-radius: .4rem;
    background-color: color-mix(in srgb, var(--gm-t-error) 10%, transparent);
    box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--gm-t-error) 70%, transparent);
}
/* Origen del fichaje (tablet, sesión, huella) junto a la hora: misma pastilla, en azul */
.gm-js .celda abbr.btn-circle-glass[title^="Fichado desde"] {
    box-sizing: border-box;
    width: 1.2rem !important;
    height: 1.2rem !important;
    padding: .18rem !important;
    border-radius: .4rem;
    background: color-mix(in srgb, var(--gm-acento) 13%, light-dark(rgb(255 255 255 / .7), transparent)) !important;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-acento) 30%, transparent);
    color: var(--gm-acento) !important;
    text-decoration: none;
    cursor: help;
    transform: none;
}
@media (prefers-reduced-motion: reduce) {
    .gm-js .localiza:has(svg.rojo) { animation: none; box-shadow: inset 0 0 0 1.5px rgb(204 47 78 / .6); }
    .gm-js :is(.localiza, .t-hora-modificada):hover { transform: none; }
}

/* Tooltip de la M (hora modificada / agregada) en Registros. base.css lo colocaba con desplazamientos
   fijos (left: 20rem; margin-left: -14.8rem) y salía corrido abajo a la derecha, tapado por la celda
   de la fila siguiente y con medio segundo de espera. Ahora va anclado justo DEBAJO de la marca (así
   no tapa la hora), con flechita, por encima de las demás celdas y aparece al momento. */
.gm-js .grid-registros .selectores-hora > span { position: relative; }
.gm-js .grid-registros .celda:has(.trigger-tooltip:hover, .trigger-tooltip:focus) { position: relative; z-index: 20; }
.gm-js .grid-registros .selectores-hora .tooltip {
    position: absolute;
    top: calc(100% + 8px);
    bottom: auto;
    left: 50%;
    right: auto;
    width: max-content;
    min-width: 0;
    max-width: 15rem;
    margin: 0;
    padding: .45rem .7rem;
    z-index: 30;
    font-size: .8rem;
    font-weight: 600;
    line-height: 1.3;
    text-align: center;
    white-space: normal;
    pointer-events: none;
    transform: translate(-50%, -4px);
    transition: opacity .15s ease, transform .15s ease, visibility 0s linear .15s;
}
.gm-js .grid-registros .selectores-hora .tooltip::after {
    content: "";
    position: absolute;
    bottom: 100%;
    left: 50%;
    width: 10px;
    height: 10px;
    margin-left: -5px;
    margin-bottom: -5px;
    background: inherit;
    box-shadow: -1px -1px 0 var(--gm-borde);
    transform: rotate(45deg);
    border-radius: 3px 0 0 0;
}
.gm-js .grid-registros .selectores-hora .trigger-tooltip:where(:hover, :focus) + .tooltip {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition: opacity .15s ease, transform .15s ease, visibility 0s;
}

/* Motivo del registro bajo la fecha (CORREGIDO, AUSENCIA…) */
.gm-js .grid-registros .celda small.azul {
    margin-top: .1rem;
    font-size: .7rem;
    letter-spacing: .04em;
    opacity: .9;
}

/* Tooltips: cristal en vez de amarillo sólido; los de nota conservan un tinte ámbar */
.gm-js :is(.tooltip, .tooltip-nota) {
    border-radius: .8rem;
    background: light-dark(rgb(255 255 255 / .96), rgb(22 36 56 / .97));
    color: var(--gm-texto);
    font-style: normal;
    box-shadow: inset 0 0 0 1px var(--gm-borde), var(--gm-sombra);
    backdrop-filter: var(--gm-blur);
    -webkit-backdrop-filter: var(--gm-blur);
}
.gm-js .tooltip-nota {
    background:
        linear-gradient(color-mix(in srgb, var(--gm-t-aviso) 14%, transparent), color-mix(in srgb, var(--gm-t-aviso) 14%, transparent)),
        light-dark(rgb(255 255 255 / .97), rgb(22 36 56 / .97));
    box-shadow: inset 3px 0 0 var(--gm-t-aviso), inset 0 0 0 1px var(--gm-borde), var(--gm-sombra);
}

/* ── 12. Botones de acciones (editar, eliminar, crear) ───────────────────── */
/* Cada botón de acción lleva ya en reposo el tinte de lo que hace (azul editar, rojo eliminar, verde
   crear) y al pasar el ratón se rellena de su color con el icono en blanco. En Registros, editar y
   eliminar forman un único control segmentado: una píldora de cristal con los dos iconos y una línea
   fina entre ellos. .azul/.rojo de base.css ponen color y fill con !important: por eso el icono
   blanco también lo lleva. */
:root {
    --gm-verde-pildora: linear-gradient(135deg, light-dark(rgb(34 160 104), rgb(90 210 150)), light-dark(rgb(20 128 80), rgb(56 170 116)));
}
.gm-js .btn-circle-glass:is(.azul, :has(> .azul)):not(.trabajando) {
    background: color-mix(in srgb, var(--gm-acento) 12%, light-dark(rgb(255 255 255 / .75), transparent)) !important;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-acento) 28%, transparent), 0 2px 6px light-dark(rgb(16 35 58 / .06), rgb(0 0 0 / .2));
}
.gm-js .btn-circle-glass:is(.rojo, .eliminar, :has(> .eliminar, > .rojo)) {
    background: color-mix(in srgb, var(--gm-t-error) 11%, light-dark(rgb(255 255 255 / .75), transparent)) !important;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-error) 28%, transparent), 0 2px 6px light-dark(rgb(16 35 58 / .06), rgb(0 0 0 / .2));
}
.gm-js .btn-circle-glass:is(.verde, :has(> .verde)) {
    background: color-mix(in srgb, var(--gm-t-ok) 12%, light-dark(rgb(255 255 255 / .75), transparent)) !important;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-ok) 28%, transparent), 0 2px 6px light-dark(rgb(16 35 58 / .06), rgb(0 0 0 / .2));
}
/* Al pasar el ratón: relleno del color de la acción e icono blanco */
.gm-js .btn-circle-glass:is(.azul, :has(> .azul)):not(.trabajando):where(:hover, :focus-within):not(:disabled) {
    background: var(--gm-pildora) !important;
    box-shadow: var(--gm-brillo);
}
.gm-js .btn-circle-glass:is(.rojo, .eliminar, :has(> .eliminar, > .rojo)):where(:hover, :focus-within):not(:disabled) {
    background: var(--gm-rojo-pildora) !important;
    box-shadow: var(--gm-rojo-brillo);
}
.gm-js .btn-circle-glass:is(.verde, :has(> .verde)):where(:hover, :focus-within):not(:disabled) {
    background: var(--gm-verde-pildora) !important;
    box-shadow: 0 8px 20px light-dark(rgb(27 143 90 / .3), rgb(90 210 150 / .25));
}
.gm-js .btn-circle-glass:is(.azul, .rojo, .eliminar, .verde, :has(> .azul, > .eliminar, > .rojo, > .verde)):not(.trabajando):where(:hover, :focus-within) :is(svg, button, path) {
    color: #fff !important;
    fill: #fff !important;
}
.gm-js .btn-circle-glass:is(.azul, .rojo, .eliminar, .verde):where(:hover, :focus-within) {
    color: #fff !important;
    fill: #fff !important;
}

/* Registros: control segmentado editar | eliminar */
.gm-js .grid-registros .acciones-fila {
    gap: 0;
    width: fit-content;
    margin: 0 auto;
    padding: 3px;
    border-radius: .8rem;
    background: light-dark(rgb(255 255 255 / .6), rgb(255 255 255 / .05));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), 0 2px 6px light-dark(rgb(16 35 58 / .06), rgb(0 0 0 / .2));
}
.gm-js .grid-registros .acciones-fila > .btn-circle-glass {
    position: relative;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 1.8rem;
    margin: 0;
    padding: 0;
    border-radius: .6rem;
    background: transparent !important;
    box-shadow: none;
    transform: none;
}
.gm-js .grid-registros .acciones-fila > .btn-circle-glass + .btn-circle-glass { margin-left: 3px; }
.gm-js .grid-registros .acciones-fila > .btn-circle-glass + .btn-circle-glass::before {
    content: "";
    position: absolute;
    left: -2px;
    top: 22%;
    bottom: 22%;
    width: 1px;
    background: var(--gm-campo-linea);
    transition: opacity .15s ease;
}
/* La línea se esconde cuando uno de los dos está resaltado */
.gm-js .grid-registros .acciones-fila:has(> .btn-circle-glass:hover) > .btn-circle-glass + .btn-circle-glass::before { opacity: 0; }
.gm-js .grid-registros .acciones-fila > .btn-circle-glass > button {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: inherit;
    background: transparent !important;
    cursor: pointer;
}
.gm-js .grid-registros .acciones-fila svg { width: .95rem; height: .95rem; }
.gm-js .grid-registros .acciones-fila > .btn-circle-glass:active { transform: scale(.92); }
.gm-js .grid-registros .acciones-fila > .btn-circle-glass:has(> button:focus-visible) { outline: 2px solid var(--gm-acento); outline-offset: 1px; }
/* Hover dentro del segmentado (el fondo transparente de arriba empataría con el de la acción) */
.gm-js .grid-registros .acciones-fila > .btn-circle-glass:has(> .azul, > button:not(.eliminar)):where(:hover, :focus-within) {
    background: var(--gm-pildora) !important;
    box-shadow: var(--gm-brillo);
}
.gm-js .grid-registros .acciones-fila > .btn-circle-glass:has(> .eliminar):where(:hover, :focus-within) {
    background: var(--gm-rojo-pildora) !important;
    box-shadow: var(--gm-rojo-brillo);
}
.gm-js .grid-registros .acciones-fila > .btn-circle-glass:where(:hover, :focus-within) :is(button, svg, path) {
    color: #fff !important;
    fill: #fff !important;
}

/* ── 13. Botón de borrar/limpiar filtros (.btn-filtros) ──────────────────── */
/* Píldora compacta de cristal con un embudo tachado, a la altura de los campos de al lado. Limpiar no destruye nada: en reposo discreto y al pasar el ratón
   se tiñe de azul. */
.gm-js .btn-filtros {
    gap: .45rem;
    min-width: 0;
    height: auto;
    padding: .5rem .95rem .5rem .8rem;
    border-radius: 999px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--gm-suave) !important;
    white-space: nowrap;
}
.gm-js .btn-filtros::before {
    content: "";
    flex: none;
    width: 1.05rem;
    height: 1.05rem;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .25s cubic-bezier(.3, 1.4, .5, 1);
}
.gm-js .btn-filtros:where(:hover, :focus-visible):not(:disabled) {
    color: var(--gm-acento) !important;
}
.gm-js .btn-filtros:where(:hover, :focus-visible):not(:disabled)::before { transform: rotate(-12deg) scale(1.08); }
/* Donde va en su propia columna con un espaciador (Registros, Aprobaciones), la columna se alinea por
   abajo con los campos y sin espaciador; y el botón mide lo mismo que un campo */
.gm-js .btn-filtros { min-height: 2.25rem; }
@media (width > 950px) {
    .gm-js :is(section, div).flex.column:has(> .btn-filtros) { align-self: flex-end; gap: 0; }
    .gm-js :is(section, div).flex.column:has(> .btn-filtros) > span:empty { display: none; }
}

/* ── 14. Calendarios ─────────────────────────────────────────────────────── */
/* Mensual (registros) y de festivos: #calendario > .linea > .c-nombre / .c-dia. El anual: .cal-anual.
   Sus <style> llegan por ajax después de glass.css: aquí todo va con #calendario o una clase más.
   Mismas medidas de las celdas (los bordes cambian de color, no de grosor). En móvil el calendario
   tiene su propio diseño (.cal-movil) y solo se toca el color. */
@media (width > 950px) {
    .gm-js #calendario {
        border-radius: var(--gm-tabla-radio);
        background: var(--gm-tabla-bg);
        box-shadow: inset 0 0 0 1px var(--gm-campo-linea), var(--gm-tabla-sombra);
    }
    /* Esquinas redondeadas en las celdas de las esquinas (el calendario no recorta: hay tooltips) */
    .gm-js #calendario > .linea:first-of-type > :first-child { border-top-left-radius: var(--gm-tabla-radio); }
    .gm-js #calendario > .linea:first-of-type > :last-child { border-top-right-radius: var(--gm-tabla-radio); }
    .gm-js #calendario > .linea:last-of-type > :first-child { border-bottom-left-radius: var(--gm-tabla-radio); }
    .gm-js #calendario > .linea:last-of-type > :last-child { border-bottom-right-radius: var(--gm-tabla-radio); }

    /* Cabecera: días de la semana */
    .gm-js #calendario .c-nombre {
        border-color: var(--gm-tabla-linea);
        background-color: var(--gm-tabla-cab);
        color: var(--gm-suave);
        font-size: .78rem;
        font-weight: 700;
        letter-spacing: .06em;
        text-transform: uppercase;
    }

    /* Días */
    .gm-js #calendario .c-dia {
        border-color: var(--gm-tabla-linea);
        background-color: light-dark(rgb(255 255 255 / .38), rgb(255 255 255 / .02));
        transition: background-color .15s ease;
    }
    .gm-js #calendario .c-dia:hover { background-color: var(--gm-tabla-fila-hover); }
    /* Fin de semana: gris azulado muy tenue (la cabecera va en gris como el resto: el rojo es de los errores) */
    .gm-js #calendario .c-dia.c-fds { background-color: light-dark(rgb(16 35 58 / .045), rgb(255 255 255 / .035)); }
    .gm-js #calendario .c-dia.c-fds:hover { background-color: var(--gm-tabla-fila-hover); }
    .gm-js #calendario .c-dia.c-hoy {
        background-color: light-dark(rgb(3 94 177 / .09), rgb(140 200 255 / .08));
        box-shadow: inset 0 3px 0 var(--gm-acento);
    }
    .gm-js #calendario .c-dia.c-hoy .c-num-dia { color: var(--gm-acento); font-weight: 800; }
    .gm-js #calendario .c-dia.c-vacio {
        background: repeating-linear-gradient(135deg,
            light-dark(rgb(16 35 58 / .035), rgb(255 255 255 / .025)) 0 8px, transparent 8px 16px);
    }
    .gm-js #calendario .c-dia.c-otro-mes { background-color: transparent; }
    .gm-js #calendario .c-dia.c-marcado {
        border-color: var(--gm-tabla-linea) !important;
        box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--gm-t-error) 55%, transparent);
    }

    /* Número del día: más fino, en la esquina, sin descolocar lo de debajo */
    .gm-js #calendario .c-num-dia {
        box-sizing: border-box;
        min-height: 2.2rem;
        align-items: center;
        right: 0;
        padding: .15rem .6rem 0 0;
        font-size: 1.15rem;
        font-weight: 600;
        color: var(--gm-texto);
        font-variant-numeric: tabular-nums;
    }

    /* Crear (+) y editar registro: pastillas tintadas en la esquina; al pasar el ratón, rellenas */
    .gm-js #calendario :is(.c-crear-registro, .c-editar-registro) { left: .35rem; top: .35rem; }
    .gm-js #calendario :is(.c-crear-registro, .c-editar-registro) svg {
        box-sizing: border-box;
        width: 1.85rem;
        height: 1.85rem;
        padding: .45rem;
        border-radius: .6rem;
        box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t) 30%, transparent);
        background-color: color-mix(in srgb, var(--t) 13%, light-dark(rgb(255 255 255 / .7), transparent));
        fill: var(--t);
        transition: background-color .2s ease, fill .2s ease, transform .15s ease, box-shadow .2s ease;
    }
    .gm-js #calendario .c-crear-registro { --t: var(--gm-t-ok); }
    .gm-js #calendario .c-editar-registro { --t: var(--gm-acento); }
    .gm-js #calendario :is(.c-crear-registro, .c-editar-registro):hover svg {
        background-color: var(--t);
        fill: #fff;
        transform: translateY(-1px);
        box-shadow: 0 6px 14px color-mix(in srgb, var(--t) 35%, transparent);
    }
    /* Crear en un día vacío: discreto hasta pasar por el día */
    .gm-js #calendario .c-dia:not(:hover) .c-crear-registro svg { opacity: .55; }

    /* Contenido del día */
    .gm-js #calendario .c-horas-totales {
        align-items: center;
        gap: .25rem;
        margin: 0 .4rem .35rem;
        font-size: .82rem;
        color: var(--gm-suave);
        font-variant-numeric: tabular-nums;
    }
    .gm-js #calendario .c-horas-totales b { color: var(--gm-texto); font-weight: 700; }
    .gm-js #calendario .c-horas-totales .eliminar { margin-left: auto; }
    .gm-js #calendario .c-horas { font-size: .9rem; font-variant-numeric: tabular-nums; }
    .gm-js #calendario .c-linea-horas { gap: .3rem; color: var(--gm-texto); }
    .gm-js #calendario .c-linea-horas > span:nth-child(2) { color: var(--gm-suave); }

    /* Columna de horas por semana */
    .gm-js #calendario .c-semana {
        border-color: var(--gm-tabla-linea);
        background-color: var(--gm-tabla-cab);
    }
    .gm-js #calendario .c-semana-label { color: var(--gm-suave); }
}

/* Calendario de festivos: cada vacación/festivo del día como pastilla legible con su color */
.gm-js #calendario .cal-fest-wrapper { gap: .25rem; padding: 0 .35rem .35rem; }
.gm-js #calendario .cal-fest-entry {
    --t: var(--gm-acento);
    max-width: 100%;
    box-sizing: border-box;
    padding: .18rem .55rem;
    border-radius: 999px;
    font-size: .76rem;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--t);
    background-color: color-mix(in srgb, var(--t) 13%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t) 26%, transparent);
    transition: background-color .15s ease;
}
.gm-js #calendario .cal-fest-entry.cal-fest-entry-festivo { --t: var(--gm-t-error); }
.gm-js #calendario .cal-fest-entry:hover { background-color: color-mix(in srgb, var(--t) 22%, transparent); }

/* Calendario en móvil (.cal-movil): mismo diseño propio, con los colores de la renovación: días de
   cristal, hoy en píldora azul (antes negra) y el día elegido con aro azul (antes gris) */
@media (width <= 950px) {
    .gm-js #calendario.cal-movil .linea .c-dia {
        background: light-dark(rgb(255 255 255 / .5), rgb(255 255 255 / .05));
        box-shadow: inset 0 0 0 1px var(--gm-tabla-linea);
        border-radius: .7rem;
    }
    .gm-js #calendario.cal-movil .linea .c-dia.c-fds { background: light-dark(rgb(16 35 58 / .045), rgb(255 255 255 / .03)); }
    .gm-js #calendario.cal-movil .c-dia.c-hoy:not(.c-otro-mes) .c-num-dia {
        background: var(--gm-pildora);
        color: #fff;
        box-shadow: var(--gm-brillo);
        border-radius: .5rem;
    }
    .gm-js #calendario.cal-movil .linea .c-dia.cal-sel {
        border-color: var(--gm-acento);
        background: light-dark(rgb(255 255 255 / .9), rgb(255 255 255 / .1));
        box-shadow: 0 0 0 3px var(--gm-campo-anillo);
    }
}

/* Calendario de festivos: el "+" de cada día abre la ventana de añadir; en el detalle móvil dice lo que añade */
#calendario .c-crear-festivo { cursor: pointer; }
.cal-detalle-cuerpo .c-crear-festivo::after { content: "Añadir festivo"; }

/* Día no trabajado (ajuste de Ajustes): pastilla roja "Sin fichar" en el centro del día; solo
   informa (no abre nada) */
#calendario .c-no-trabajado {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    width: 100%;
}
#calendario .c-no-trabajado > span {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .15rem .55rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--gm-t-error, #e54b3c) 13%, transparent);
    color: var(--gm-t-error, #e54b3c);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-error, #e54b3c) 30%, transparent);
    font-size: .75rem;
    font-weight: 700;
    white-space: nowrap;
    cursor: help;
}
#calendario .c-no-trabajado svg { width: .9rem; height: .9rem; flex: none; fill: currentColor; }

/* Calendario anual */
/* La tarjeta tomaba el ancho mínimo del contenido y los meses quedaban estrechos, con los números
   pegados: en escritorio ocupa un ancho cómodo */
@media (width > 950px) {
    .gm-js .cal-anual { min-width: min(62rem, calc(100vw - 22rem)); gap: 1.5rem; }
}
.gm-js .cal-anual .cal-mes-grid { gap: 4px; }
.gm-js .cal-anual .cal-mes { aspect-ratio: auto; }
.gm-js .cal-anual .cal-mes-grid { padding: .5rem .6rem .75rem; }
.gm-js .cal-anual .cal-mes {
    border: 1px solid var(--gm-campo-linea);
    border-radius: var(--gm-tabla-radio);
    background: var(--gm-tabla-bg);
    box-shadow: var(--gm-tabla-sombra);
}
.gm-js .cal-anual .cal-mes-titulo {
    background: var(--gm-tabla-cab);
    color: var(--gm-texto);
    font-size: .95rem;
    letter-spacing: .08em;
    box-shadow: inset 0 -1px 0 var(--gm-campo-linea);
}
.gm-js .cal-anual .cal-dia-header { color: var(--gm-suave); font-size: .78rem; }
.gm-js .cal-anual .cal-dia { border-radius: .55rem; font-size: 1rem; font-variant-numeric: tabular-nums; }
.gm-js .cal-anual .cal-dia-fds { color: color-mix(in srgb, var(--gm-t-error) 55%, var(--gm-suave)); }
.gm-js .cal-anual .cal-dia-hoy { outline: none; box-shadow: inset 0 0 0 2px var(--gm-acento); color: var(--gm-acento); }
.gm-js .cal-anual .cal-dia-festivo { background-color: color-mix(in srgb, var(--gm-t-error) 15%, transparent); color: var(--gm-t-error); }
.gm-js .cal-anual .cal-dia-vacacion { background-color: color-mix(in srgb, var(--gm-acento) 15%, transparent); color: var(--gm-acento); }
.gm-js .cal-anual .cal-dia-vacacion-otro { background-color: light-dark(rgb(123 63 214 / .14), rgb(185 155 245 / .16)); color: light-dark(#7b3fd6, #b99bf5); }
.gm-js .cal-anual .cal-dia-doble { background: linear-gradient(135deg, color-mix(in srgb, var(--gm-acento) 15%, transparent) 50%, light-dark(rgb(123 63 214 / .14), rgb(185 155 245 / .16)) 50%); color: var(--gm-acento); }
.gm-js .cal-anual .cal-dia:is([onclick], [title]):hover { box-shadow: 0 4px 12px light-dark(rgb(16 35 58 / .15), rgb(0 0 0 / .35)); }
.gm-js .cal-leyenda-color { border-radius: .35rem; }

/* ── 15. Pestañas de vista (.gm-pestanas) ────────────────────────────────── */
/* Como las pestañas píldora de HOPE/FacturaO, en cristal: contenedor hundido y una píldora de
   cristal claro que se desliza hasta la pestaña activa y "amaga" hacia la que apunta el ratón
   (glass-menu.js). Las pestañas llevan btn-p para verse como antes sin la interfaz nueva: aquí se
   anula ese aspecto. Van las primeras de su fila de botones. */
.gm-js .gm-pestanas {
    position: relative;
    order: -1;
    display: inline-flex;
    flex-wrap: nowrap;
    gap: .2rem;
    width: fit-content;
    max-width: 100%;
    padding: .3rem;
    border-radius: 999px;
    background: light-dark(rgb(16 35 58 / .07), rgb(0 0 0 / .22));
    box-shadow: inset 0 2px 5px light-dark(rgb(16 35 58 / .12), rgb(0 0 0 / .35)), inset 0 -1px 0 light-dark(rgb(255 255 255 / .7), rgb(255 255 255 / .06));
    overflow-x: auto;
    scrollbar-width: none;
}
.gm-js .gm-pestanas::-webkit-scrollbar { display: none; }
.gm-js .gm-pestanas .gm-pestana.btn-p {
    position: relative;
    z-index: 1;
    gap: .45rem;
    min-width: 0;
    padding: .5rem 1.05rem;
    border-radius: 999px;
    background: transparent !important;
    box-shadow: none !important;
    color: var(--gm-suave) !important;
    font-size: 1.1rem;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
    filter: none !important;
    transform: none !important;
    transition: color .2s ease;
}
.gm-js .gm-pestanas .gm-pestana.btn-p svg { width: 1.35rem; height: 1.35rem; fill: none; stroke: currentColor; }
.gm-js .gm-pestanas .gm-pestana.btn-p:hover { color: var(--gm-texto) !important; }
.gm-js .gm-pestanas .gm-pestana.btn-p.active { color: var(--gm-acento) !important; font-weight: 700; }
.gm-js .gm-pestanas .gm-pestana.btn-p:focus-visible { outline: 2px solid var(--gm-acento); outline-offset: -2px; }
/* Sin la píldora (antes de que cargue el script) la activa se marca con su propio fondo */
.gm-js .gm-pestanas:not(.con-pildora) .gm-pestana.btn-p.active {
    background: light-dark(rgb(255 255 255 / .92), rgb(255 255 255 / .12)) !important;
    box-shadow: 0 3px 10px light-dark(rgb(16 35 58 / .12), rgb(0 0 0 / .3)) !important;
}
.gm-js .gm-pestanas-pildora {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 0;
    border-radius: 999px;
    background: light-dark(rgb(255 255 255 / .92), rgb(255 255 255 / .13));
    box-shadow: 0 3px 10px light-dark(rgb(16 35 58 / .13), rgb(0 0 0 / .3)), inset 0 1px 0 var(--gm-luz);
    opacity: 0;
    pointer-events: none;
    transition: left .3s cubic-bezier(.25, 1.2, .35, 1), width .3s cubic-bezier(.25, 1.2, .35, 1), top .3s ease, height .3s ease, transform .18s ease, opacity .15s ease;
}
/* Amago al pasar por otra pestaña: se estira hacia ella */
.gm-js .gm-pestanas-pildora.amago {
    transform: scaleY(.92);
    transition: left .18s ease, width .18s ease, top .18s ease, height .18s ease, transform .18s ease, opacity .15s ease;
}
@media (prefers-reduced-motion: reduce) {
    .gm-js .gm-pestanas-pildora { transition: opacity .15s ease; }
}

/* ── 16. Desplegables (glass-select.js) ──────────────────────────────────── */
/* Lista propia de los <select>: panel de cristal en la capa superior con la opción elegida marcada,
   grupos, desactivadas y buscador si hay muchas opciones. El <select> sigue siendo el campo (§7). */
.gm-js select[aria-expanded="true"] {
    background-color: var(--gm-campo-bg-foco);
    box-shadow: inset 0 0 0 1.5px var(--gm-acento), 0 0 0 4px var(--gm-campo-anillo);
}
.gm-sel {
    position: fixed;
    inset: auto;
    z-index: 10000;
    box-sizing: border-box;
    max-width: min(26rem, calc(100vw - 16px));
    max-height: min(22rem, calc(100vh - 16px));
    margin: 0;
    padding: .35rem;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: .3rem;
    border: 0;
    border-radius: 1rem;
    color: var(--gm-texto);
    font-family: var(--letra);
    font-size: .95rem;
    background: light-dark(rgb(255 255 255 / .95), rgb(20 33 52 / .96));
    box-shadow: inset 0 0 0 1px var(--gm-borde), inset 0 1px 0 var(--gm-luz), var(--gm-sombra);
    backdrop-filter: var(--gm-blur);
    -webkit-backdrop-filter: var(--gm-blur);
}
.gm-sel:not(.abierto) { display: none; }
.gm-sel.abierto { animation: gm-dp-entra .18s cubic-bezier(.22, .8, .3, 1); }
.gm-sel.abierto.arriba { animation-name: gm-dp-entra-arriba; }

.gm-sel__buscar { position: relative; display: none; flex: none; }
.gm-sel.con-buscador .gm-sel__buscar { display: block; }
.gm-sel__buscar svg { position: absolute; left: .7rem; top: 50%; width: 1rem; height: 1rem; transform: translateY(-50%); color: var(--gm-suave); pointer-events: none; }
.gm-sel__buscar input {
    box-sizing: border-box;
    width: 100%;
    margin: 0;
    padding: .5rem .7rem .5rem 2.1rem;
    border: 0;
    outline: 0;
    border-radius: .7rem;
    background: light-dark(rgb(16 35 58 / .05), rgb(255 255 255 / .06));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
    color: var(--gm-texto);
    font: inherit;
    font-size: .9rem;
}
.gm-sel__buscar input:focus { box-shadow: inset 0 0 0 1.5px var(--gm-acento), 0 0 0 3px var(--gm-campo-anillo); }

.gm-sel__lista {
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--gm-suave) 45%, transparent) transparent;
}
.gm-sel__grupo {
    padding: .55rem .7rem .2rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--gm-suave);
}
.gm-sel__op {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-height: 2.2rem;
    padding: .35rem .7rem;
    border-radius: .65rem;
    cursor: pointer;
    user-select: none;
}
.gm-sel__texto { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gm-sel__op svg { flex: none; width: 1rem; height: 1rem; color: var(--gm-acento); }
.gm-sel__op.activa { background: var(--gm-hover); color: var(--gm-acento); }
.gm-sel__op.elegida { font-weight: 700; color: var(--gm-acento); }
.gm-sel__op.elegida.activa { background: light-dark(rgb(3 94 177 / .15), rgb(140 200 255 / .18)); }
.gm-sel__op.desactivada { opacity: .4; cursor: not-allowed; }
.gm-sel__vacio { padding: .8rem; text-align: center; color: var(--gm-suave); font-size: .88rem; }
@media (prefers-reduced-motion: reduce) {
    .gm-sel.abierto { animation: none; }
}

/* ── 17. Acordeones (<details>) ──────────────────────────────────────────── */
/* Grupos, usuarios, motivos y la ficha de empleado (Horario, Historial de horarios). Mismo diseño que las
   fichas de Empleados (§19): tarjeta de cristal que se eleva al pasar el ratón, título a sangre centrado
   en vertical, flecha de Heroicons (chevron-down) que gira al abrir; abierto, el título en azul con una
   línea fina debajo y el contenido con margen. Fuera: .empleado-card (§19) y .ia-tool-log.
   TRAMPAS de base.css: cerrado lleva max-height 2.5em (recorta títulos con botones y descentra), abierto
   gana padding (el título salta) y la primera sección del título tiene margin-top:-1.6rem para
   compensar el triángulo nativo. Las tres se anulan. */
.gm-js details:not(.empleado-card, .ia-tool-log) {
    padding: 0;
    border: 1px solid var(--gm-campo-linea);
    border-radius: var(--gm-tabla-radio);
    background: var(--gm-tabla-bg);
    box-shadow: var(--gm-tabla-sombra);
    backdrop-filter: none;
    overflow: hidden;
    transition: box-shadow .2s ease, border-color .2s ease, transform .2s ease, background-color .2s ease;
}
.gm-js details:not(.empleado-card, .ia-tool-log):not([open]) { max-height: none; }
.gm-js details:not(.empleado-card, .ia-tool-log):not([open]):hover {
    border-color: var(--gm-campo-linea-hover);
    box-shadow: 0 10px 24px light-dark(rgb(16 35 58 / .12), rgb(0 0 0 / .35));
    transform: translateY(-1px);
}
.gm-js details:not(.empleado-card, .ia-tool-log)[open] {
    padding: 0;
    background: light-dark(rgb(255 255 255 / .62), rgb(255 255 255 / .05));
}
/* Listas: las tarjetas ocupan todo el ancho de su columna (en Usuarios quedaban estrechas) */
.gm-js :is(#usuarios, #grupos, #motivos) { width: 100%; align-self: stretch; box-sizing: border-box; }
.gm-js :is(#usuarios, #grupos, #motivos) > details { width: 100%; max-width: 100%; margin-inline: 0; }

.gm-js details:not(.empleado-card, .ia-tool-log) > summary {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 3.4rem;
    box-sizing: border-box;
    list-style: none;
    margin: 0;
    padding: .55rem 2.9rem .55rem 1rem;
    border-radius: 0;
    background: transparent;
    color: var(--gm-texto);
    font-size: 1.2rem;
    font-weight: 700;
    transition: background-color .2s ease, color .2s ease;
}
.gm-js details:not(.empleado-card, .ia-tool-log) > summary::-webkit-details-marker { display: none; }
.gm-js details:not(.empleado-card, .ia-tool-log) > summary::after {
    content: "";
    position: absolute;
    right: 1rem;
    top: 50%;
    width: 1.05rem;
    height: 1.05rem;
    margin-top: -.525rem;
    background: var(--gm-suave);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .3s cubic-bezier(.22, .8, .3, 1), background-color .2s ease;
}
.gm-js details:not(.empleado-card, .ia-tool-log) > summary:hover { background: var(--gm-hover); color: var(--gm-acento); }
.gm-js details:not(.empleado-card, .ia-tool-log) > summary:focus-visible { outline: 2px solid var(--gm-acento); outline-offset: -2px; }
.gm-js details:not(.empleado-card, .ia-tool-log)[open] > summary {
    margin: 0 0 .8rem;
    background: transparent;
    color: var(--gm-acento);
    border-radius: 0;
    box-shadow: inset 0 -1px 0 var(--gm-campo-linea);
}
.gm-js details:not(.empleado-card, .ia-tool-log)[open] > summary:hover { background: var(--gm-hover); }
.gm-js details:not(.empleado-card, .ia-tool-log)[open] > summary::after { transform: rotate(180deg); background: var(--gm-acento); }

/* Contenido del título: fila a lo ancho, centrada, nombre a la izquierda y botones a la derecha */
.gm-js details:not(.empleado-card, .ia-tool-log) > summary > section:first-child {
    flex: 1;
    min-width: 0;
    align-items: center;
    justify-content: space-between;
    margin: 0;
    padding: 0;
}
.gm-js details:not(.empleado-card, .ia-tool-log) > summary :is(.modificadoresficha, .titulo-summary) { margin-block: 0; padding-block: 0; }
.gm-js details:not(.empleado-card, .ia-tool-log) > summary > section:first-child > span[style] { margin-top: 0 !important; padding-bottom: 0 !important; }
.gm-js details:not(.empleado-card, .ia-tool-log) > summary .titulo-summary { align-items: flex-start; text-align: left; }
.gm-js details:not(.empleado-card, .ia-tool-log)[open] > summary .titulo-summary { color: var(--gm-acento); }

/* Contenido desplegado: margen a los lados y abajo; los paneles azules en línea pasan a cristal tintado */
.gm-js details:not(.empleado-card, .ia-tool-log)[open] > :not(summary) { margin-inline: 1rem; }
.gm-js details:not(.empleado-card, .ia-tool-log)[open] > :not(summary):last-child { margin-bottom: 1rem; }
.gm-js details:not(.empleado-card, .ia-tool-log) [style*="#82bbfc9d"] {
    padding: .8rem 1rem;
    border-radius: .85rem !important;
    background-color: light-dark(rgb(3 94 177 / .06), rgb(140 200 255 / .06)) !important;
    box-shadow: inset 0 0 0 1px light-dark(rgb(3 94 177 / .12), rgb(140 200 255 / .12));
}
/* Grupos: el tipo (FIJO, ROTATIVO...) venía como caja blanca de cristal; pasa a pastilla */
.gm-js details:not(.empleado-card, .ia-tool-log)[open] span.cristal {
    display: inline-flex;
    width: auto;
    margin: 0;
    padding: .2rem .8rem;
    border: 0;
    border-radius: 999px;
    background: color-mix(in srgb, var(--gm-acento) 12%, transparent);
    color: var(--gm-acento);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-acento) 25%, transparent);
    backdrop-filter: none;
    font-size: .85rem;
    font-weight: 700;
    letter-spacing: .04em;
    /* .cristal de base.css trae transition: 1s y la animación de aparición de las tarjetas: al abrir, la
       pastilla encogía desde el tamaño de tarjeta (20px de relleno) hasta el suyo */
    transition: none;
    animation: none;
}
@media (prefers-reduced-motion: reduce) {
    .gm-js details > summary::after { transition: none; }
    .gm-js details:not(.empleado-card, .ia-tool-log) { transition: none; transform: none !important; }
}

/* Exportar: botones PDF y CSV como botones de cristal con un solo icono de su color. base.css les
   superponía una flechita (segundo svg con márgenes negativos) que con los iconos nuevos quedaba suelta. */
.gm-js :is(#convertirpdf, #convertircsv) {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .55rem 1.1rem .55rem .85rem;
    border-radius: var(--gm-btn-radio);
    background: light-dark(rgb(255 255 255 / .6), rgb(255 255 255 / .06));
    color: var(--gm-texto);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), 0 2px 6px light-dark(rgb(16 35 58 / .06), rgb(0 0 0 / .2));
    font-family: var(--letra);
    font-size: 1.05rem;
    transition: background-color .2s ease, box-shadow .2s ease, transform .15s ease;
}
.gm-js :is(#convertirpdf, #convertircsv) svg:nth-of-type(2) { display: none; }
.gm-js :is(#convertirpdf, #convertircsv) svg:nth-of-type(1) { margin: 0; width: 1.35rem; height: 1.35rem; transform: none; }
.gm-js #convertirpdf svg:nth-of-type(1) { fill: var(--gm-t-error); }
.gm-js #convertircsv svg:nth-of-type(1) { fill: var(--gm-t-ok); }
.gm-js :is(#convertirpdf, #convertircsv):where(:hover, :focus-visible) {
    background: light-dark(rgb(255 255 255 / .85), rgb(255 255 255 / .1));
    color: var(--gm-texto);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover), 0 6px 14px light-dark(rgb(16 35 58 / .12), rgb(0 0 0 / .3));
    transform: translateY(-1px);
}
.gm-js :is(#convertirpdf, #convertircsv):where(:hover, :focus-visible) svg:nth-of-type(1) { transform: none; }

/* ── 18. Grupos de opciones como pestañas (.gm-segmentado) ───────────────── */
/* Exportar (Empleado · Grupo · Fechas), festivo, grupos, aprobaciones y solicitudes de notas: los
   radios ocultos con sus etiquetas, con el mismo aspecto que las pestañas de vista (§15): contenedor
   hundido y píldora clara deslizante bajo la opción marcada (glass-menu.js). En aprobaciones y notas
   la marcada conserva el color de su estado en el texto. Anula §7 (botones segmentados) con una
   especificidad mayor por los ids de base.css. */
.gm-js .gm-segmentado {
    position: relative;
    display: inline-flex;
    flex-direction: row !important;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: .2rem;
    width: fit-content;
    max-width: 100%;
    margin-inline: auto;
    padding: .3rem;
    border-radius: 999px;
    background: light-dark(rgb(16 35 58 / .07), rgb(0 0 0 / .22));
    box-shadow: inset 0 2px 5px light-dark(rgb(16 35 58 / .12), rgb(0 0 0 / .35)), inset 0 -1px 0 light-dark(rgb(255 255 255 / .7), rgb(255 255 255 / .06));
    overflow-x: auto;
    scrollbar-width: none;
}
.gm-js .gm-segmentado::-webkit-scrollbar { display: none; }
.gm-js .gm-segmentado > section { display: contents; }
.gm-js .gm-segmentado :is(#label-empleado, #label-fechas, #label-grupo, .label-radio, label) {
    position: relative;
    z-index: 1;
    padding: .5rem 1.1rem;
    border-radius: 999px;
    background: transparent;
    box-shadow: none;
    color: var(--gm-suave);
    font-size: 1.05rem !important; /* algunas vistas les dan un tamaño propio más pequeño */
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    pointer-events: auto;
    transform: none;
    transition: color .2s ease;
}
.gm-js .gm-segmentado :is(#label-empleado, #label-fechas, #label-grupo, .label-radio, label):hover { background: transparent; color: var(--gm-texto); }
.gm-js .gm-segmentado :is(#iempleado:checked ~ #label-empleado, #ifechas:checked ~ #label-fechas, #igrupo:checked ~ #label-grupo, #radio_grupo:checked ~ #label-grupo, #radio_empleado:checked ~ #label-empleado, .radio:checked ~ .label-radio) {
    background: transparent;
    box-shadow: none;
    color: var(--gm-acento);
    font-weight: 700;
    pointer-events: none;
}
/* Color del estado: el selector imposible dentro de :is() solo sube la especificidad por encima de la regla general, que lleva dos ids */
.gm-js .gm-segmentado :is(#gm-sin-id#gm-sin-id2.gm-x.gm-y, .radio:checked ~ .label-radio.pendiente) { color: var(--gm-t-aviso); }
.gm-js .gm-segmentado :is(#gm-sin-id#gm-sin-id2.gm-x.gm-y, .radio:checked ~ .label-radio.aprobado) { color: var(--gm-t-ok); }
.gm-js .gm-segmentado :is(#gm-sin-id#gm-sin-id2.gm-x.gm-y, .radio:checked ~ .label-radio.desaprobado) { color: var(--gm-t-error); }
/* Antes de que el script ponga la píldora, la marcada lleva su propio fondo */
.gm-js .gm-segmentado:not(.con-pildora) :is(#iempleado:checked ~ #label-empleado, #ifechas:checked ~ #label-fechas, #igrupo:checked ~ #label-grupo, #radio_grupo:checked ~ #label-grupo, #radio_empleado:checked ~ #label-empleado, .radio:checked ~ .label-radio) {
    background: light-dark(rgb(255 255 255 / .92), rgb(255 255 255 / .12));
    box-shadow: 0 3px 10px light-dark(rgb(16 35 58 / .12), rgb(0 0 0 / .3));
}

/* ── 19. Listado de empleados (.empleado-card) ───────────────────────────── */
/* Tarjetas de cristal. Sus estilos llegan con la tabla por ajax (después de glass.css) y base.css pinta
   el título de un <details> abierto en azul sólido: por eso aquí todo va con #empleados delante. */
.gm-js #empleados .empleado-card {
    border: 1px solid var(--gm-campo-linea);
    border-radius: var(--gm-tabla-radio);
    background: var(--gm-tabla-bg);
    box-shadow: var(--gm-tabla-sombra);
    backdrop-filter: none;
    overflow: hidden;
    transition: box-shadow .2s ease, border-color .2s ease, transform .2s ease;
}
.gm-js #empleados .empleado-card:not([open]):hover {
    border-color: var(--gm-campo-linea-hover);
    box-shadow: 0 10px 24px light-dark(rgb(16 35 58 / .12), rgb(0 0 0 / .35));
    transform: translateY(-1px);
}
.gm-js #empleados .empleado-card.fichando { border-left: 1px solid var(--gm-campo-linea); }
.gm-js #empleados .empleado-card[open] { background: light-dark(rgb(255 255 255 / .62), rgb(255 255 255 / .05)); }

/* Título de la tarjeta (cerrada y abierta) */
.gm-js #empleados .empleado-card > summary {
    gap: .6rem;
    margin: 0;
    padding: .8rem 1rem;
    border-radius: 0;
    background: transparent;
    color: var(--gm-texto);
    transition: background-color .2s ease;
}
.gm-js #empleados .empleado-card > summary:hover { background: var(--gm-hover); }
.gm-js #empleados .empleado-card[open] > summary {
    margin: 0;
    background: transparent;
    color: var(--gm-texto);
    border-bottom: 0;
    box-shadow: inset 0 -1px 0 var(--gm-campo-linea);
}
.gm-js #empleados .empleado-card[open] > summary:hover { background: var(--gm-hover); }
.gm-js #empleados .empleado-card > summary::after {
    content: "";
    flex: none;
    width: 1.05rem;
    height: 1.05rem;
    background: var(--gm-suave);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .3s cubic-bezier(.22, .8, .3, 1);
}
.gm-js #empleados .empleado-card[open] > summary::after { transform: rotate(180deg); background: var(--gm-acento); }
.gm-js #empleados .empleado-card > summary section:first-child { margin-top: 0; }
/* base.css deja un margen negativo abajo en .emp-summary y un relleno arriba en los botones: todo descentrado */
.gm-js #empleados .empleado-card > summary :is(.emp-summary, .modificadoresficha) { margin-block: 0; padding-block: 0; }
/* La tarjeta cerrada venía recortada a 3.5em (56px) con un título más alto: el contenido quedaba bajo.
   Sin tope, la tarjeta mide lo que su título, que se compacta un poco. */
.gm-js #empleados .empleado-card, .gm-js #empleados .empleado-card[open] { max-height: none; padding: 0; } /* abierta traía 8px de relleno: el título saltaba */
.gm-js #empleados .empleado-card > summary { padding-block: .55rem; }

/* Avatar, nombre y datos cortos */
.gm-js #empleados .emp-avatar {
    width: 2.5rem;
    height: 2.5rem;
    font-size: .95rem;
    box-shadow: inset 0 -2px 4px rgb(0 0 0 / .15), 0 0 0 2px light-dark(rgb(255 255 255 / .9), rgb(255 255 255 / .12));
}
.gm-js #empleados .empleado-card.fichando .emp-avatar {
    box-shadow: inset 0 -2px 4px rgb(0 0 0 / .15), 0 0 0 2px light-dark(#fff, rgb(20 33 52)), 0 0 0 4px var(--gm-t-ok);
}
.gm-js #empleados .emp-nombre-linea .titulo-summary { font-size: 1.05rem; font-weight: 700; color: var(--gm-texto); }
.gm-js #empleados .empleado-card[open] .emp-nombre-linea .titulo-summary { color: var(--gm-acento); }
.gm-js #empleados .emp-sub,
.gm-js #empleados .empleado-card[open] > summary .emp-sub { color: var(--gm-suave); opacity: 1; font-size: .82rem; }
.gm-js #empleados .emp-dot-fichando,
.gm-js #empleados .empleado-card[open] > summary .emp-dot-fichando { color: var(--gm-t-ok); text-shadow: 0 0 6px color-mix(in srgb, var(--gm-t-ok) 60%, transparent); }
.gm-js #empleados .emp-badge.sub,
.gm-js #empleados .empleado-card[open] > summary .emp-badge.sub {
    background: color-mix(in srgb, var(--gm-t-aviso) 15%, transparent);
    color: var(--gm-t-aviso);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-aviso) 28%, transparent);
}

/* Horas de hoy y de la semana: pastillas */
.gm-js #empleados .emp-horas { gap: .15rem; }
.gm-js #empleados .emp-horas > span {
    display: inline-flex;
    align-items: baseline;
    gap: .3rem;
    padding: 0 .5rem;
    line-height: 1.25; /* las dos pastillas caben en el alto del avatar: todas las tarjetas miden igual */
    border-radius: 999px;
    font-size: .78rem;
}
.gm-js #empleados .emp-horas .lbl { margin: 0; opacity: 1; color: var(--gm-suave); font-size: .68rem; }
.gm-js #empleados .emp-horas .horas-hoy { background: color-mix(in srgb, var(--gm-t-ok) 12%, transparent); }
.gm-js #empleados .emp-horas .horas-semana { background: color-mix(in srgb, var(--gm-acento) 11%, transparent); }
.gm-js #empleados .emp-horas .horas-hoy b,
.gm-js #empleados .empleado-card[open] .emp-horas .horas-hoy b { color: var(--gm-t-ok); }
.gm-js #empleados .emp-horas .horas-semana b,
.gm-js #empleados .empleado-card[open] .emp-horas .horas-semana b { color: var(--gm-acento); }

/* Contenido desplegado: datos y horario en paneles de cristal */
.gm-js #empleados .empleado-card[open] > section { padding: .8rem 1rem 1rem; gap: .7rem; }
.gm-js #empleados .empleado-datos[style] {
    padding: .8rem 1rem;
    border-radius: .85rem !important;
    background-color: light-dark(rgb(3 94 177 / .06), rgb(140 200 255 / .06)) !important;
    box-shadow: inset 0 0 0 1px light-dark(rgb(3 94 177 / .12), rgb(140 200 255 / .12));
}
.gm-js #empleados .empleado-datos .dato .label { color: var(--gm-suave); opacity: 1; font-size: .82rem; }
.gm-js #empleados .empleado-datos .dato b { color: var(--gm-texto); font-weight: 600; }
.gm-js #empleados .horario-compacto {
    margin-top: 0;
    padding: .7rem 1rem;
    border-radius: .85rem;
    background: light-dark(rgb(16 35 58 / .035), rgb(255 255 255 / .04));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
}
.gm-js #empleados .horario-dia-nombre { color: var(--gm-acento); font-weight: 600; }
.gm-js #empleados .horario-rango {
    background: color-mix(in srgb, var(--gm-t-ok) 13%, transparent);
    color: var(--gm-t-ok);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-ok) 22%, transparent);
    font-weight: 600;
}
@media (prefers-reduced-motion: reduce) {
    .gm-js #empleados .empleado-card { transition: none; transform: none !important; }
}

/* ── 20. Horario por días (formularios de empleado y grupo) ──────────────── */
/* OJO: .horario-dia también la usa el horario compacto de la lista de Empleados (impr_tabla_mostrar_horas):
   por eso todo va con .horario-dias > delante. Cada día es una tarjeta con su nombre y sus horas; se colocan varias por fila si caben. Con las horas
   progresivas (base.js: horas_progresivas) casi siempre hay 1-2 tramos, así que lunes y martes (o más)
   comparten fila y hay mucho menos scroll. base.css daba a .horas márgenes negativos pensados para un
   día por fila: se anulan dentro de la tarjeta. */
.gm-js .horario-dias {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr)); /* columnas iguales: el último día no se estira */
    gap: .8rem;
    width: 100%;
}
/* Su contenedor (#horario_horas, columna centrada) encogía al contenido y la rejilla quedaba de una columna */
.gm-js :has(> .horario-dias) { align-self: stretch; width: 100%; box-sizing: border-box; }
.gm-js .horario-dias > .horario-dia {
    display: flex;
    box-sizing: border-box;
    flex-direction: column;
    gap: .35rem;
    min-width: 0;
    padding: .7rem .9rem .8rem;
    border-radius: .9rem;
    background: light-dark(rgb(255 255 255 / .5), rgb(255 255 255 / .04));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
}
.gm-js .horario-dias > .horario-dia > h3 {
    margin: 0;
    color: var(--gm-acento);
    font-size: 1rem;
    text-align: left;
}
/* Dentro, un tramo por fila: entrada | salida. Así la tarjeta es estrecha (caben 3 por fila) y crece
   hacia abajo con los tramos que se van abriendo, en vez de desbordar a lo ancho. */
.gm-js .horario-dias > .horario-dia > .horas {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .4rem .6rem;
    width: 100%;
    margin: 0;
}
.gm-js .horario-dias > .horario-dia > .horas > .opcioneshoras {
    flex-direction: column !important;
    align-items: stretch;
    margin: 0;
    gap: .15rem;
}
.gm-js .horario-dias > .horario-dia > .horas > .opcioneshoras > label { display: flex; align-items: center; gap: .1rem; font-size: .85rem; }
.gm-js .horario-dias > .horario-dia > .horas > .opcioneshoras > label svg { width: .85em; height: .85em; }
.gm-js .horario-dias > .horario-dia > .horas > .opcioneshoras input {
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
    padding-inline: .4rem;
    font-size: 1rem;
}

/* ── 21. Rejilla de campos en diálogos (.gm-rejilla) ─────────────────────── */
/* Crear y editar usuario: campos en dos columnas iguales (una si no caben), todos a la misma altura y
   alineados a la izquierda; los botones abajo a la derecha (.gm-acciones-dialogo). */
.gm-js dialog:has(.gm-rejilla) { width: min(36rem, calc(100vw - 2rem)); box-sizing: border-box; }
.gm-js dialog:has(.gm-rejilla) > h2 { margin: 0 0 .9rem; text-align: left; }
.gm-js .gm-rejilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr));
    align-items: end;
    gap: .9rem 1rem;
    width: 100%;
    text-align: left;
}
.gm-js .gm-rejilla > label { min-width: 0; margin: 0; }
.gm-js .gm-rejilla > label :is(input:not([type=checkbox], [type=radio], [type=hidden]), select) {
    width: 100%;
    max-width: none;
    height: 2.4rem;
    box-sizing: border-box;
}
.gm-js .gm-rejilla > label select { font-size: 1.4rem; text-align: left; text-align-last: left; } /* mismo tamaño de letra que los campos */
.gm-js .gm-acciones-dialogo {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .6rem;
    width: 100%;
    margin-top: 1.2rem;
}

/* ── 22. Estado vacío ("No hay datos", "no tienes empleados") ────────────── */
/* Antes una etiqueta roja con sombra dura, como si fuera un error. Ahora un aviso tranquilo: tarjeta de
   cristal con borde discontinuo, la lupa arriba dentro de un círculo tintado y el texto en gris. El
   enlace ("Añadir empleado") pasa a botón azul suave debajo. Mismo marcado (no_hay_nada() y las vistas). */
.gm-js #no-hay-datos {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: center;
    gap: .6rem;
    width: fit-content;
    min-width: min(16rem, 100%);
    max-width: 100%;
    box-sizing: border-box;
    margin-inline: auto;
    padding: 1.3rem 1.8rem 1.4rem;
    border: 1.5px dashed var(--gm-campo-linea);
    border-radius: var(--gm-tabla-radio);
    background: light-dark(rgb(255 255 255 / .45), rgb(255 255 255 / .03));
    box-shadow: none;
    color: var(--gm-suave);
    fill: var(--gm-acento);
    text-align: center;
    animation: gm-vacio-entra .35s ease-out both;
}
.gm-js #no-hay-datos > svg {
    order: -1;
    width: 2.9rem;
    height: 2.9rem;
    padding: .7rem;
    box-sizing: border-box;
    border-radius: 50%;
    background: color-mix(in srgb, var(--gm-acento) 12%, transparent);
    fill: var(--gm-acento);
}
.gm-js #no-hay-datos h3 {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .7rem;
    margin: 0;
    color: var(--gm-suave);
    font-size: 1.05rem;
    font-weight: 600;
    text-wrap: balance;
}
.gm-js #no-hay-datos a.enlace {
    padding: .4rem 1rem;
    border-radius: var(--gm-btn-radio);
    background: color-mix(in srgb, var(--gm-acento) 12%, transparent);
    color: var(--gm-acento) !important; /* .blanco de base.css lleva !important */
    font-size: .95rem;
    font-weight: 700;
    text-decoration: none;
    transition: background-color .2s ease;
}
.gm-js #no-hay-datos a.enlace:hover { background: color-mix(in srgb, var(--gm-acento) 20%, transparent); }
@keyframes gm-vacio-entra {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .gm-js #no-hay-datos { animation: none; }
}

/* ── 23. Cambio de tema claro/oscuro con transición ──────────────────────── */
/* cambiar_modo_claro_oscuro() (functions.php) usa View Transitions: la foto del tema anterior se queda y
   el nuevo se revela en un círculo que crece desde el clic (clip-path animado por JS). Aquí solo se
   quitan el fundido por defecto y la mezcla, para que el borde del círculo sea limpio. */
html.gm-cambio-tema::view-transition-old(root),
html.gm-cambio-tema::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
}
/* Mientras dura el cambio, nada con transición CSS: muchos elementos llevan transition (base.css:
   .cristal 1s, enlaces .5s...) y sus colores de texto y fondo llegaban tarde al tema nuevo */
html.gm-cambio-tema *,
html.gm-cambio-tema *::before,
html.gm-cambio-tema *::after {
    transition: none !important;
}
html.gm-cambio-tema::view-transition-new(root) { z-index: 2; }
html.gm-cambio-tema::view-transition-old(root) { z-index: 1; }

/* ── 24. Cambio de menú y de contenido con transición ────────────────────── */
/* Mi perfil > Apariencia (Menú flotante/pared, Contenido izquierda/centro): animar_cambio_diseno() usa
   View Transitions. El menú (#gm, gm-menu) y la tarjeta de la página (cristal) se deslizan y cambian de
   tamaño hasta su sitio nuevo; el resto funde. Algo más rápido que la navegación entre páginas. */
html.gm-cambio-diseno::view-transition-group(*) {
    animation-duration: .5s;
    animation-timing-function: cubic-bezier(.22, .8, .3, 1);
}
html.gm-cambio-diseno::view-transition-old(*),
html.gm-cambio-diseno::view-transition-new(*) {
    animation-duration: .3s;
}


/* ── 25. Entrada (iniciar sesión) ──────────────────────────────── */
/* La entrada no tiene menú, así que la interfaz nueva se enciende en crear_head() con las clases
   gm-js + gm-login (functions.php). Así hereda fondo, campos y botones de cristal; aquí se arregla
   lo que era propio de esta página: la barra azul del logo, la tarjeta suelta arriba y el botón de
   claro/oscuro, que se metía dentro de la tarjeta encima del botón de entrar. */

/* El logo deja de ir en una barra azul de lado a lado: flota sobre el fondo, centrado */
html.gm-login #menu,
html.gm-fichador #menu {
    background-color: transparent;
    backdrop-filter: none;
    border: none;
    height: auto;
    padding: 1.8rem 1rem 0;
    overflow: visible;
}
/* El logo de la aplicación es blanco (iba sobre la barra azul): en claro se invierte para que se lea
   sobre el fondo claro y en oscuro se deja tal cual. Por [data-theme], que la entrada escribe siempre
   (light-dark() solo vale para colores: en filter o en opacity el navegador descarta la regla). */
html.gm-login #logo,
html.gm-fichador #logo {
    height: 3.4rem;
    filter: drop-shadow(0 2px 10px rgb(16 35 58 / .18)) invert(1);
}
html.gm-login[data-theme="dark"] #logo,
html.gm-fichador[data-theme="dark"] #logo { filter: drop-shadow(0 6px 18px rgb(0 0 0 / .45)); }

/* La tarjeta, centrada en la pantalla y con el aire del resto de la aplicación */
html.gm-login main {
    /* Arriba, justo debajo del logo: centrada en la pantalla quedaba demasiado baja y en pantallas
       altas obligaba a bajar la vista para escribir. */
    box-sizing: border-box;
    justify-content: flex-start;
    padding: 1rem 1rem 3rem;
}
html.gm-login main > .cristal {
    width: min(26rem, 100%);
    margin: 0 auto;
    padding: 2.2rem 2rem 2.4rem;
    border-radius: 1.6rem;
    position: relative;
}
html.gm-login main > .cristal > h1 {
    margin: 0 0 .3rem;
    text-align: center;
    font-size: 1.9rem;
}
/* El "* Para acceder al área privada..." como subtítulo, no como aviso */
html.gm-login main > .cristal > p {
    text-align: center;
    color: var(--gm-suave);
    font-size: .95rem;
    margin: 0 0 1.6rem;
}
html.gm-login main > .cristal > p .rojo { display: none; }

html.gm-login #login { gap: 1.1rem; width: 100%; }
html.gm-login #login label { width: 100%; gap: .35rem; }
html.gm-login #login input { width: 100%; height: 2.6rem; box-sizing: border-box; }
html.gm-login #login #contraseña { width: 100%; }
/* Contraseña + botón del ojo: el campo manda y el ojo es la píldora azul de siempre (§9) */
html.gm-login #campocontra section { width: 100%; }
html.gm-login #login #contraseña { flex: 1; width: auto; }

/* El botón de entrar ocupa el ancho de la tarjeta */
html.gm-login #login > section:has(#iniciarsesion) { width: 100%; }
html.gm-login #iniciarsesion { width: 100%; height: 2.7rem; font-size: 1.05rem; }

/* Error de acceso: tarjeta roja de cristal bajo el botón (antes, una caja plana) */
html.gm-login #notificar {
    width: 100%;
    align-self: stretch;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    padding: .7rem .9rem;
    border-radius: 1rem;
    background: color-mix(in srgb, var(--gm-t-error) 12%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-error) 32%, transparent);
    color: var(--gm-t-error);
}
html.gm-login #notificar span { display: flex; align-items: center; gap: .5rem; text-align: left; }
html.gm-login #notificar svg { fill: var(--gm-t-error); flex-shrink: 0; }

/* Claro/oscuro: botón redondo de cristal en la esquina, fuera de la tarjeta */
html.gm-login #claro-oscuro,
html.gm-fichador #claro-oscuro {
    /* !important también en la posición: la regla de base.css para esta página lleva :has(#login)
       y suma más especificidad que esta */
    position: fixed !important;
    top: 1rem !important;
    left: 1rem !important;      /* a la izquierda: los avisos salen por la esquina derecha y lo tapaban */
    right: auto !important;
    bottom: auto !important;
    width: 2.6rem;
    height: 2.6rem;
    padding: 0 !important;
    border-radius: 50% !important;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--gm-campo-bg) !important;
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), 0 6px 18px rgb(16 35 58 / .12);
    backdrop-filter: blur(var(--gm-blur, 12px));
    cursor: pointer;
    transition: background-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
html.gm-login #claro-oscuro:hover,
html.gm-fichador #claro-oscuro:hover { background-color: var(--gm-campo-bg-hover) !important; transform: translateY(-1px); }
html.gm-login #claro-oscuro svg,
html.gm-fichador #claro-oscuro svg { width: 1.2rem; height: 1.2rem; fill: var(--gm-texto) !important; }

@media (width <= 480px) {
    html.gm-login main > .cristal { padding: 1.8rem 1.2rem 2rem; border-radius: 1.3rem; }
    html.gm-login #logo { height: 2.8rem; }
}


/* ── 26. Fichador (pantalla de fichar) ───────────────────────────────────── */
/* La otra página sin menú. Mismo encendido que la entrada (gm-js + gm-fichador en crear_head()).
   Vale para los dos modos: la lista de nombres y el MASIVO (un buscador con el desplegable de
   base.js, que aquí también sale en cristal). Es una pantalla táctil: nada se hace más pequeño. */

/* El fondo de la aplicación estaba excluido para .fichador (tenía su imagen propia) */
html.gm-fichador body.fichador {
    background-color: var(--gm-suelo);
    background-image: none;
}
html.gm-fichador body.fichador::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background-color: var(--gm-suelo);
    background-image:
        radial-gradient(40rem 36rem at 6% 4%, var(--gm-lavado-1), transparent 70%),
        radial-gradient(38rem 30rem at 30% 104%, var(--gm-lavado-2), transparent 70%),
        radial-gradient(44rem 34rem at 98% 14%, var(--gm-lavado-3), transparent 70%);
    background-size: cover;
}

html.gm-fichador main {
    box-sizing: border-box;
    justify-content: flex-start;    /* arriba, como la entrada */
    padding: 1rem 1rem 3rem;
}
html.gm-fichador main > .cristal {
    width: min(64rem, 100%);
    margin: 0 auto;
    padding: 2rem 1.6rem 2.2rem;
    border-radius: 1.6rem;
}
html.gm-fichador main > .cristal > h1 { text-align: center; margin: 0 0 1.4rem; }

/* Nombres: píldoras de cristal grandes (se pulsan con el dedo); la elegida, en azul */
html.gm-fichador #fichaje {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .8rem;
    margin-top: .5rem;
}
html.gm-fichador .label-empleado {
    position: relative;
    gap: .5rem;
    padding: .85rem 1.3rem;
    font-size: 1.35rem;
    border: none;
    border-radius: 1rem;
    background-color: var(--gm-campo-bg);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), var(--gm-campo-hundido);
    backdrop-filter: blur(var(--gm-blur, 12px));
    color: var(--gm-texto);
    cursor: pointer;
    transition: background-color .2s ease, box-shadow .2s ease, transform .2s ease, color .2s ease;
}
html.gm-fichador .label-empleado:hover {
    background-color: var(--gm-campo-bg-hover);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover), var(--gm-campo-hundido);
    transform: translateY(-1px);
}
html.gm-fichador .label-empleado:active { transform: translateY(0); }
html.gm-fichador .iempleado:checked ~ .label-empleado {
    background: var(--gm-pildora);
    color: #fff;
    box-shadow: 0 8px 22px color-mix(in srgb, var(--gm-acento) 35%, transparent);
    /* fichar.css se lo quitaba: el nombre ya elegido no se podía volver a pulsar y, si se había
       tocado fuera, no había forma de recuperar el foco del PIN sin elegir a otra persona */
    pointer-events: auto;
    cursor: pointer;
}
/* La hora del último fichaje: chapa sobre la esquina de la píldora, no con márgenes negativos */
html.gm-fichador .horafichador {
    position: absolute;
    top: -.6rem;
    right: -.4rem;
    margin: 0;
    padding: .1rem .45rem;
    font-size: .85rem;
    font-style: normal;
    border-radius: .6rem;
    background: var(--gm-campo-bg-foco);
    color: var(--gm-suave);
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
}
html.gm-fichador .iempleado:checked ~ .label-empleado .horafichador {
    /* En oscuro el acento es azul claro: sobre #fff no se leía. Chapa oscura en ese tema */
    background: light-dark(#fff, rgb(8 18 32 / .9));
    color: var(--gm-acento);
}

/* Modo masivo: el buscador manda, así que es más grande (su desplegable ya sale en cristal) */
html.gm-fichador #buscador_fichaje {
    width: min(26rem, 100%);
    height: 3rem;
    font-size: 1.2rem;
    text-align: center;
}

/* PIN + ojo: una pieza centrada y con el tamaño de una pantalla táctil */
html.gm-fichador #contraseña {
    /* border-box: el campo trae relleno propio de base.css y con content-box medía 58 px mientras
       el botón del ojo medía 48, y se veían desalineados */
    box-sizing: border-box;
    width: 7rem !important;
    height: 3rem;
    font-size: 1.4rem;
    text-align: center;
    letter-spacing: .3em;
    border-radius: var(--gm-campo-radio) 0 0 var(--gm-campo-radio) !important;
}
html.gm-fichador #mostrarcontra {
    box-sizing: border-box;
    height: 3rem;
    align-self: stretch;     /* misma altura que el campo pase lo que pase */
    margin-left: 0;
    margin-top: 0;
}

/* Botón de fichar: la acción principal de la pantalla */
html.gm-fichador #fichar {
    min-width: 12rem;
    height: 3.2rem;
    font-size: 1.25rem;
    margin-top: .3rem;
}

@media (width <= 600px) {
    html.gm-fichador main > .cristal { padding: 1.4rem 1rem 1.8rem; border-radius: 1.3rem; }
    html.gm-fichador .label-empleado { font-size: 1.15rem; padding: .7rem 1rem; }
}

/* ── 27. Modo tutorial (visita guiada, tour.js) ──────────────────────────── */
/* Oscurece la pantalla, deja iluminado lo que se está explicando y saca una tarjeta
   de cristal al lado. Funciona con y sin la interfaz nueva (no lleva prefijo .gm-js). */
.tour-capa {
    position: fixed;
    inset: 0;
    /* Por encima de TODO: el menú y las tarjetas crean sus propios contextos de apilamiento */
    z-index: 2147483000;
    pointer-events: auto;
}
.tour-capa.tour-sin-foco { background: rgb(8 18 32 / .55); }
.tour-foco {
    position: fixed;
    border-radius: 1rem;
    /* El "agujero": todo lo de fuera queda oscurecido por la sombra */
    box-shadow: 0 0 0 9999px rgb(8 18 32 / .55), 0 0 0 2px var(--gm-acento, #035db1), 0 0 26px 4px rgb(3 94 177 / .45);
    transition: top .25s ease, left .25s ease, width .25s ease, height .25s ease;
}
.tour-capa.tour-sin-foco .tour-foco { display: none; }

.tour-tarjeta {
    position: fixed;
    z-index: 2147483001;
    width: min(24rem, calc(100vw - 2rem));
    box-sizing: border-box;
    padding: 1.1rem 1.2rem 1rem;
    border-radius: 1.2rem;
    background: light-dark(rgb(255 255 255 / .96), rgb(16 26 42 / .96));
    color: light-dark(#10233a, #e4eef9);
    box-shadow: 0 18px 50px rgb(8 18 32 / .35);
    backdrop-filter: blur(14px);
}
.tour-tarjeta.tour-centrada {
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(30rem, calc(100vw - 2rem));
}
.tour-contador {
    font-size: .78rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    opacity: .65;
}
.tour-tarjeta h3 { margin: .25rem 0 .5rem; font-size: 1.25rem; }
.tour-tarjeta p { margin: 0 0 1rem; line-height: 1.45; }
/* Una sola fila: Salir a la izquierda, Atrás y Siguiente juntos a la derecha. Los botones del
   proyecto son grandes y en una tarjeta estrecha se partían en varias líneas. */
.tour-botones { display: flex; gap: .5rem; align-items: center; justify-content: flex-end; flex-wrap: nowrap; }
.tour-botones .tour-salir { margin-right: auto; }
.tour-botones button {
    flex: 0 0 auto;
    margin: 0;
    padding: .45rem .9rem;
    font-size: .95rem;
    min-width: 0;
    white-space: nowrap;
}
body.tour-activo { overflow: hidden; }

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

/* ── 28. Ayuda de cada pantalla (botón arriba a la derecha + panel) ──────── */
/* Lo pinta ayuda_contextual() (functions.php) con los textos de app/ayudas.php. Cuenta qué es la
   pantalla y para qué sirve cada cosa, y desde ahí se lanza la visita guiada. */
.ayuda-btn {
    position: absolute;
    top: 1rem;
    right: 1rem;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 0;
    width: 2.3rem;
    height: 2.3rem;
    font-size: .95rem;
    border: none;
    border-radius: 999px;
    cursor: pointer;
    color: var(--gm-texto, inherit);
    background-color: var(--gm-campo-bg, rgb(255 255 255 / .6));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea, rgb(16 35 58 / .12));
    backdrop-filter: blur(var(--gm-blur, 12px));
    transition: background-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.ayuda-btn svg { width: 1.5rem; height: 1.5rem; fill: currentColor; }
/* El texto sigue ahí para quien usa lector de pantalla, pero se ve solo el interrogante */
.ayuda-btn-txt {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.ayuda-btn:hover {
    background-color: var(--gm-campo-bg-hover, rgb(255 255 255 / .8));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover, rgb(3 94 177 / .35));
    transform: translateY(-1px);
}

/* Panel lateral: entra desde el borde derecho de la pantalla, a toda la altura */
.ayuda-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    width: min(26rem, 100vw);
    box-sizing: border-box;
    max-height: none;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 1.4rem 1.4rem 2rem;
    border-radius: 1.4rem 0 0 1.4rem;
    text-align: left;
    background: light-dark(rgb(255 255 255 / .97), rgb(16 26 42 / .97));
    color: light-dark(#10233a, #e4eef9);
    box-shadow: -18px 0 50px rgb(8 18 32 / .28);
    backdrop-filter: blur(14px);
    opacity: 0;
    transform: translateX(100%);
    transition: opacity .25s ease, transform .25s ease;
}
.ayuda-panel.abierto { opacity: 1; transform: none; }
/* Velo: atenúa la página mientras el panel está abierto y se cierra al pulsarlo */
.ayuda-velo {
    position: fixed;
    inset: 0;
    z-index: 59;
    border: none;
    padding: 0;
    background: rgb(8 18 32 / .28);
    opacity: 0;
    transition: opacity .25s ease;
}
.ayuda-velo.abierto { opacity: 1; }
.ayuda-panel-cab {
    display: flex;
    align-items: center;
    gap: .5rem;
    position: sticky;
    top: -1.4rem;
    margin: -1.4rem -1.4rem .2rem;
    padding: 1.4rem 1.4rem .6rem;
    background: inherit;
}
.ayuda-panel-cab h2 { margin: 0; font-size: 1.2rem; flex: 1; }
.ayuda-cerrar {
    margin: 0;
    padding: 0 .3rem;
    font-size: 1.5rem;
    line-height: 1;
    border: none;
    background: transparent;
    color: inherit;
    cursor: pointer;
    opacity: .6;
}
.ayuda-cerrar:hover { opacity: 1; }
.ayuda-intro { margin: .4rem 0 .9rem; line-height: 1.45; }
.ayuda-lista { margin: 0; }
.ayuda-lista dt { font-weight: bold; margin-top: .7rem; }
.ayuda-lista dd { margin: .15rem 0 0; line-height: 1.4; opacity: .88; }
.ayuda-pie { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; justify-content: space-between; margin-top: 1.1rem; }
.ayuda-pie .btn-p, .ayuda-pie .btn-t { margin: 0; }
.ayuda-pie .btn-t { text-decoration: none; }

/* La tarjeta de la página tiene que ser el marco del botón */
.cristal:has(> .ayuda-btn) { position: relative; }
/* Hueco del botón a los dos lados del título: en tarjetas estrechas lo tapaba, y así un título
   centrado sigue centrado */
.cristal:has(> .ayuda-btn) > h1 { padding-inline: 2.8rem; }

@media (width <= 600px) {
    .ayuda-btn { position: absolute; top: .6rem; right: .6rem; }
    /* En móvil el panel lateral ocupa toda la pantalla: no cabe media */
    .ayuda-panel { width: 100%; border-radius: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .ayuda-panel, .ayuda-velo { transition: none; }
}

/* ── 29. Horas acumuladas: marca de notas junto al nombre ────────────────── */
/* Con notas escritas: icono dorado + contador. Solo canjes sin nota: icono gris, sin número. */
/* El número va pequeño y flotando en la esquina del icono, como el contador de Avisos */
.gm-js .marca-notas { position: relative; display: inline-flex; align-items: center; margin-right: .35rem; }
.gm-js .icono-notas.con-notas { fill: #d19a00; }
.gm-js .icono-notas.sin-notas { fill: var(--gm-suave); opacity: .7; }
.gm-js .contador-notas {
    position: absolute;
    top: -.45rem;
    right: -.55rem;
    min-width: .8rem;
    height: .8rem;
    padding: 0 .18rem;
    box-sizing: border-box;
    border-radius: 999px;
    background: #d19a00;
    color: #fff;
    font-size: .55rem;
    font-weight: 700;
    line-height: .8rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
    box-shadow: 0 0 0 1.5px light-dark(#fff, #1b2430);
    pointer-events: none;
}
.gm-js .celda-nombre-notas.notas-abierto .icono-notas.con-notas { fill: #a87c00; }
.gm-js .celda-nombre-notas.notas-abierto .contador-notas { background: #a87c00; }

/* ── 30. Calendario: la nota va junto a editar, con su mismo estilo ──────── */
/* Antes el icono iba abajo, al lado del Total. Ahora es una pastilla más en la esquina superior
   izquierda: tras el botón de editar/crear si lo hay, o en su sitio si no (empleado, días futuros).
   Colores: verde para añadir nota, ámbar si ya hay nota o una solicitud pendiente. */
@media (width > 950px) {
    /* Absoluta respecto al día (.c-dia es relative): así cae exactamente a la altura del lápiz,
       sin depender del hueco del flex ni de la línea del botón de editar */
    .gm-js #calendario .c-nota-registro {
        position: absolute;
        left: .35rem;
        top: .35rem;
        z-index: 2;
        display: flex;
        width: fit-content;
    }
    .gm-js #calendario :is(.c-crear-registro, .c-editar-registro) + .c-nota-registro { left: calc(.35rem + 1.85rem + .3rem); }
    .gm-js #calendario .c-nota-registro:where(:hover, :focus-within) { z-index: 1000; }
    /* Editar y crear ocupaban TODO el ancho del día (bloque estirado) aunque solo se viera el icono,
       y al pasar el ratón suben a z-index 1000 (base.css): tapaban la nota, que no se iluminaba, y
       el clic abría el formulario de editar. Ahora solo ocupan su icono. */
    .gm-js #calendario :is(.c-crear-registro, .c-editar-registro) { width: fit-content; align-self: flex-start; }
    .gm-js #calendario .c-nota-registro .btn-nota {
        --t: var(--gm-t-ok);
        display: flex;
        padding: 0;
        margin: 0;
        border: 0;
        background: none;
        cursor: pointer;
    }
    .gm-js #calendario .c-nota-registro .btn-nota.nota-tooltip,
    .gm-js #calendario .c-nota-registro.nota-pendiente .btn-nota { --t: var(--gm-t-aviso); }
    .gm-js #calendario .c-nota-registro .btn-nota svg {
        box-sizing: border-box;
        width: 1.85rem;
        height: 1.85rem;
        padding: .45rem;
        border-radius: .6rem;
        box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--t) 30%, transparent);
        background-color: color-mix(in srgb, var(--t) 13%, light-dark(rgb(255 255 255 / .7), transparent));
        fill: var(--t);
        transition: background-color .2s ease, fill .2s ease, transform .15s ease, box-shadow .2s ease;
    }
    .gm-js #calendario .c-nota-registro .btn-nota:hover svg {
        background-color: var(--t);
        fill: #fff;
        transform: translateY(-1px);
        box-shadow: 0 6px 14px color-mix(in srgb, var(--t) 35%, transparent);
    }
    /* Añadir nota: discreto hasta pasar por el día, como el "+" de crear */
    .gm-js #calendario .c-dia:not(:hover) .c-nota-registro .nota-agregar svg { opacity: .55; }
    /* El texto de la nota se despliega debajo de la pastilla */
    .gm-js #calendario .c-nota-registro .tooltip-nota {
        position: absolute;
        top: calc(100% + .35rem);
        left: 0;
        transform: translateY(6px);
    }
    .gm-js #calendario .c-nota-registro .nota-tooltip:hover + .tooltip-nota,
    .gm-js #calendario .c-nota-registro .tooltip-nota:where(:hover, :focus, :focus-within) { transform: none; }
}

/* ── 31. Enlaces legales (aviso legal y privacidad) ───────────────────────── */
/* Discretos, abajo a la derecha junto a la píldora de versión; en móvil, al final de la página. */
#enlaces-legales {
    position: fixed;
    bottom: .55rem;
    right: 4.9rem;
    z-index: 5;
    display: flex;
    gap: .7rem;
    padding: .15rem .6rem;
    border-radius: 999px;
    font-size: .72rem;
    background: light-dark(rgb(255 255 255 / .6), rgb(29 35 39 / .6));
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}
#enlaces-legales a { color: var(--gm-suave, #4a6078); text-decoration: none; }
#enlaces-legales a:hover { text-decoration: underline; }
@media (width <= 950px) {
    #enlaces-legales { position: static; justify-content: center; margin: 1rem auto 1.5rem; width: fit-content; }
}

/* ── 32. Ajustes: configuración del asistente de IA solo con la opción activada ── */
/* .flex (display:flex) gana a [hidden] del navegador: sin esto el bloque se veía siempre. */
#ia-config[hidden] { display: none !important; }

/* ── 33. Ajustes: buscador, índice y secciones ────────────────────────────── */
.aj-barra {
    position: sticky;
    top: .5rem;
    z-index: 20;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    padding: .8rem 1rem;
    align-items: stretch;
}
.aj-buscar {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: 0 .8rem;
    border-radius: 999px;
    background: var(--gm-campo-bg, light-dark(rgb(255 255 255 / .8), rgb(255 255 255 / .06)));
    box-shadow: inset 0 0 0 1px var(--gm-borde, rgb(0 0 0 / .1));
}
.aj-buscar svg { width: 1.1rem; height: 1.1rem; flex-shrink: 0; color: var(--gm-suave, #4a6078); }
.aj-buscar input { flex: 1; min-width: 0; border: 0 !important; box-shadow: none !important; background: transparent !important; padding: .55rem 0 !important; font-size: 1rem; }
.aj-indice { display: flex; flex-wrap: wrap; gap: .35rem; }
.aj-chip {
    border: 0;
    cursor: pointer;
    padding: .3rem .75rem;
    border-radius: 999px;
    font-size: .82rem;
    color: var(--gm-texto, inherit);
    background: color-mix(in srgb, var(--gm-acento, #2563eb) 10%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-acento, #2563eb) 22%, transparent);
    transition: background-color .15s ease, color .15s ease;
}
.aj-chip:hover { background: var(--gm-acento, #2563eb); color: #fff; }
.aj-desc { margin: -.3rem 0 .4rem; font-size: .85rem; color: var(--gm-suave, #4a6078); }
.aj-sub { margin: 1rem 0 .2rem; font-size: 1.05rem; }
.aj-seccion { scroll-margin-top: 9rem; }
.aj-vacio { text-align: center; color: var(--gm-suave, #4a6078); }
/* .flex / display propios ganan a [hidden]: se fuerza */
.aj-seccion[hidden], .aj-seccion article[hidden], .aj-chip[hidden], .aj-vacio[hidden] { display: none !important; }
/* Buscando: fuera las descripciones y los subtítulos, solo los ajustes que coinciden */
.aj-seccion.aj-filtrando :is(.aj-desc, .aj-sub) { display: none; }
/* Ancho de lectura: con el ancho "natural" las tarjetas se quedaban en ~250 px y la vista previa del
   logo se salía por la derecha */
.aj-barra, .aj-seccion { width: min(46rem, 100%); box-sizing: border-box; }
.aj-seccion img { max-width: 100%; }
/* La tarjeta que envuelve la página lleva overflow:hidden, que la convierte en contenedor de scroll y
   el sticky de la barra se quedaba pegado dentro de ella (desaparecía al bajar). clip recorta igual
   pero no crea contenedor de scroll. */
.cristal:has(> section > .aj-barra) { overflow: clip; }
/* Fija arriba, el contenido pasa por debajo: casi opaca para que no se transparente */
.cristal.aj-barra { background: light-dark(rgb(246 249 253 / .94), rgb(22 32 46 / .94)); top: .6rem; }
/* Las tarjetas (barra y secciones) centradas dentro del recuadro de la página */
.cristal:has(> section > .aj-barra) > section:has(> .aj-barra) { align-items: center; }
.aj-vacio { align-self: center; }

/* ── 34. Pulido tras la revisión de diseño (26w42d) ──────────────────────── */
/* Restos del estilo antiguo dentro del cristal, jerarquía de botones, contraste y móvil. */

/* Colores de texto .verde / .rojo (base.css, con !important): los mismos tonos de estado del cristal,
   que llegan a AA. Antes el verde era #02814a en claro y en oscuro (4,2:1 en Ajustes). */
html.gm-js {
    --verde: light-dark(#116b42, #5fd49a);
    --rojo: light-dark(#b3213f, #ff7d92);
}

/* Un botón principal por cabecera. En una fila con pestañas de vista, todos los .btn-p menos el
   último pasan a secundarios (p. ej. «Compr. incidencias» del módulo junto a «Añadir festivo»).
   El módulo trae un background-color en línea (naranja) que en oscuro asomaba bajo la píldora. */
.gm-js .btn-p[style*="background-color"] { background-color: transparent !important; }
.gm-js section:has(> .gm-pestanas) > .btn-p:has(~ .btn-p) {
    background: light-dark(rgb(255 255 255 / .55), rgb(255 255 255 / .06)) !important;
    color: var(--gm-texto) !important;
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), 0 2px 6px light-dark(rgb(16 35 58 / .06), rgb(0 0 0 / .2));
    filter: none;
}
.gm-js section:has(> .gm-pestanas) > .btn-p:has(~ .btn-p):where(:hover, :focus-visible) {
    background: color-mix(in srgb, var(--gm-acento) 9%, light-dark(rgb(255 255 255 / .7), rgb(255 255 255 / .06))) !important;
    color: var(--gm-acento) !important;
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover), 0 4px 12px light-dark(rgb(3 94 177 / .12), rgb(0 0 0 / .25));
    filter: none;
}

/* Calendarios: mes anterior/siguiente como flechas redondas a los lados del título (como ya era en
   móvil), en vez de dos píldoras azules que competían con la acción principal. El texto del botón
   («Anterior», «Siguiente») se queda para lectores de pantalla. */
.gm-js .cristal section:has(> #cont-cal-nombre) {
    display: grid !important;
    grid-template-columns: 2.5rem auto 2.5rem;
    justify-content: center;
    align-items: start;
    column-gap: .75rem;
}
.gm-js #cont-cal-anterior { grid-column: 1; grid-row: 1; justify-content: flex-start !important; }
.gm-js #cont-cal-nombre { grid-column: 2; grid-row: 1; }
.gm-js #cont-cal-siguiente { grid-column: 3; grid-row: 1; justify-content: flex-start !important; }
.gm-js :is(#cont-cal-anterior, #cont-cal-siguiente) > :is(#anterior, #siguiente) {
    box-sizing: border-box;
    width: 2.5rem;
    height: 2.5rem;
    min-width: 0;
    padding: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0;
    background: light-dark(rgb(255 255 255 / .6), rgb(255 255 255 / .07));
    color: var(--gm-texto) !important;
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea), 0 2px 6px light-dark(rgb(16 35 58 / .08), rgb(0 0 0 / .25));
}
.gm-js :is(#cont-cal-anterior, #cont-cal-siguiente) > :is(#anterior, #siguiente):where(:hover, :focus-visible):not(:disabled) {
    background: color-mix(in srgb, var(--gm-acento) 12%, light-dark(rgb(255 255 255 / .75), rgb(255 255 255 / .07)));
    color: var(--gm-acento) !important;
    filter: none;
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea-hover), 0 4px 12px light-dark(rgb(3 94 177 / .14), rgb(0 0 0 / .3));
}
.gm-js :is(#cont-cal-anterior, #cont-cal-siguiente) > :is(#anterior, #siguiente):focus:not(:focus-visible):not(:hover) {
    background: light-dark(rgb(255 255 255 / .6), rgb(255 255 255 / .07));
    color: var(--gm-texto) !important;
}
/* Chevrons de Heroicons (mini, sólido) como máscara: toman el color del botón */
.gm-js :is(#anterior, #siguiente)::before {
    content: "";
    width: 1.15rem;
    height: 1.15rem;
    margin: 0;
    background-color: currentColor;
    -webkit-mask: var(--gm-chevron) center / contain no-repeat;
    mask: var(--gm-chevron) center / contain no-repeat;
}
.gm-js #anterior { --gm-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill-rule='evenodd' d='M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z' clip-rule='evenodd'/%3E%3C/svg%3E"); }
.gm-js #siguiente { --gm-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill-rule='evenodd' d='M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z' clip-rule='evenodd'/%3E%3C/svg%3E"); }
/* Título del mes/año: marino, no el carmesí de los errores; centrado con las flechas */
.gm-js :is(#mostrarmes, #mostrar_año) {
    margin: 0;
    line-height: 2.5rem;
    color: var(--gm-texto) !important;
    font-weight: 700;
    letter-spacing: -.01em;
}

/* Días del calendario: el «+» de crear y la nota vacía solo al pasar por el día (o con el foco
   dentro). Eran ~70 controles iguales en pantalla. En pantallas táctiles siguen visibles. */
@media (width > 950px) and (hover: hover) {
    .gm-js #calendario .c-crear-registro svg,
    .gm-js #calendario .c-nota-registro .nota-agregar svg { transition: opacity .15s ease, background-color .2s ease, fill .2s ease, transform .15s ease, box-shadow .2s ease; }
    .gm-js #calendario .c-dia:not(:hover, :focus-within) .c-crear-registro svg,
    .gm-js #calendario .c-dia:not(:hover, :focus-within) .c-nota-registro .nota-agregar svg { opacity: 0; }
}

/* Etiquetas de campo: pequeñas y en gris, encima del dato (venían a 24 px en casi negro desde
   base.css y pesaban más que el propio valor). Campos y desplegables de esas etiquetas, a la misma
   altura y letra (el input venía a 22,4 px y el select a 16). */
.gm-js label.flex.column { font-size: .95rem; color: var(--gm-suave); }
.gm-js label.flex.column > b:first-child {
    font-size: .85rem;
    font-weight: 600;
    color: var(--gm-suave);
    letter-spacing: .01em;
}
.gm-js label.flex.column > :is(input:not([type=checkbox], [type=radio], [type=range], [type=file], [type=color]), select) {
    box-sizing: border-box;
    height: 2.4rem;
    font-size: 1rem;
    color: var(--gm-texto);
}
.gm-js label.flex.column > textarea { font-size: 1rem; color: var(--gm-texto); }

/* Entrada: «Contraseña» va en un label sin .flex.column (campo + ojo dentro) y salía más grande
   que «Nombre»: los dos con la misma etiqueta y la misma letra en el campo */
html.gm-login #login label { font-size: .95rem; color: var(--gm-suave); }
html.gm-login #login label input { font-size: 1rem; color: var(--gm-texto); }

/* Campos de solo lectura (Restante en Horas acumuladas): se leen como dato, no como un campo
   que se pueda editar */
.gm-js input.sololeer[readonly] {
    background: transparent !important;
    box-shadow: none !important;
    font-weight: 600;
    cursor: default;
    /* En negrita, "-103,30" ya no cabía en los 4rem en línea del campo */
    min-width: 5.5rem;
}
/* Saldos negativos en rojo (Horas acumuladas: la clase la pone la vista) */
.gm-js input.negativo { color: var(--gm-t-error) !important; }
.gm-js :is(td, input) { font-variant-numeric: tabular-nums; }

/* Acciones masivas (Horas acumuladas): aparte de los filtros, en un recuadro con su nombre */
.gm-js fieldset.acciones-masivas {
    margin-inline: auto;
    padding: .55rem 1rem .8rem;
    border: 0;
    border-radius: 1rem;
    background: light-dark(rgb(16 35 58 / .035), rgb(255 255 255 / .04));
    box-shadow: inset 0 0 0 1px var(--gm-campo-linea);
}
.gm-js fieldset.acciones-masivas > legend {
    float: left;
    width: 100%;
    margin-bottom: .2rem;
    padding: 0;
    font-size: .78rem;
    font-weight: 600;
    color: var(--gm-suave);
}
/* «Aplicar» de la fila: apagado hasta que la fila cambia; la fila cambiada se marca */
.gm-js .btn-aplicar:disabled { opacity: .45; }
.gm-js tr.fila-cambiada > td { background-color: light-dark(rgb(3 94 177 / .07), rgb(140 200 255 / .07)) !important; }

/* Foco visible donde faltaba: buscador de Ajustes y botón del ojo de la contraseña */
.gm-js .aj-buscar:focus-within { box-shadow: inset 0 0 0 1px var(--gm-acento), 0 0 0 3px var(--gm-campo-anillo); }
.gm-js :is(#perfil-toggle-contra, #toggle-contraseña, #mostrarcontra):focus-visible {
    outline: 2px solid var(--gm-acento) !important;
    outline-offset: 2px;
}

/* Pantallas táctiles: objetivos de al menos 44 px en los botones pequeños más usados */
@media (pointer: coarse) {
    .gm-js .btn-circle-glass { min-width: 2.75rem; min-height: 2.75rem; }
    .gm-js .aj-chip { min-height: 2.5rem; padding-inline: .9rem; }
    .gm-js #gm .gm-plegar { min-width: 2.75rem; min-height: 2.75rem; }
}

/* Móvil: el botón del asistente, más pequeño y pegado a la esquina; se aparta al bajar por la
   página (glass-menu.js pone .gm-fab-oculto) y el contenido deja sitio al final para no quedar
   debajo de él */
@media (width <= 950px) {
    .gm-js .ia-fab {
        width: 3rem;
        height: 3rem;
        right: var(--gm-margen);
        bottom: calc(var(--gm-margen) + env(safe-area-inset-bottom, 0px));
        transition: transform .3s cubic-bezier(.22, .8, .3, 1), opacity .25s ease, box-shadow .2s ease;
    }
    .gm-js.gm-fab-oculto .ia-fab {
        transform: translateY(calc(100% + 1.5rem));
        opacity: 0;
        pointer-events: none;
    }
    .gm-js main { padding-bottom: 4.5rem; }
}
@media (prefers-reduced-motion: reduce) {
    .gm-js .ia-fab { transition: opacity .2s ease; }
    .gm-js.gm-fab-oculto .ia-fab { transform: none; }
}
