/* ==========================================================================
   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;
    background: var(--gm-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). */
:root {
    --gm-t-ok: light-dark(#1b8f5a, #5fd49a);
    --gm-t-error: light-dark(#cc2f4e, #ff7d92);
    --gm-t-aviso: light-dark(#b87c04, #f2c14e);
    --gm-t-info: light-dark(#13809e, #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;
}
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); }

/* 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: por debajo del botón "Menú" y a todo el ancho */
@media (width <= 950px) {
    html.gm-js #notificacion,
    html.gm-js .notificacion-fija {
        top: calc(3.6rem + env(safe-area-inset-top, 0px) + var(--gm-toast-n, 0) * 4.2rem);
        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; }
.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;
    }
    .gm-js #calendario > .linea:first-of-type > .c-nombre:nth-last-child(-n+2) { color: color-mix(in srgb, var(--gm-t-error) 70%, var(--gm-suave)); }

    /* 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 ya lo marca en rojo) */
    .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-incidencia {
        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);
    }
}

/* Aviso de incidencia en el día: pastilla roja tintada (escritorio y móvil) */
.gm-js #calendario .c-incidencia-dia svg {
    box-sizing: border-box;
    padding: .4rem;
    border-radius: .6rem;
    background-color: color-mix(in srgb, var(--gm-t-error) 14%, light-dark(rgb(255 255 255 / .7), transparent));
    fill: var(--gm-t-error);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gm-t-error) 35%, transparent);
    transition: background-color .2s ease, fill .2s ease;
}
.gm-js #calendario .c-incidencia-dia svg:hover { background-color: var(--gm-t-error); fill: #fff; }
/* 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 sin incidencias): pastilla roja "Sin fichar" en el centro del día; solo
   informa (no abre nada como una incidencia) */
#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 {
    background: #fff;
    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;
    gap: .4rem;
    margin: 0;
    padding: .4rem .8rem;
    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.15em; height: 1.15em; fill: currentColor; }
.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);
}

/* El panel sale sobre la tarjeta, anclado a la esquina del botón */
.ayuda-panel {
    position: absolute;
    top: 3.4rem;
    right: 1rem;
    z-index: 4;
    width: min(26rem, calc(100vw - 2rem));
    box-sizing: border-box;
    max-height: min(32rem, 70vh);
    overflow-y: auto;
    padding: 1.1rem 1.2rem 1.2rem;
    border-radius: 1.2rem;
    text-align: left;
    background: light-dark(rgb(255 255 255 / .97), rgb(16 26 42 / .97));
    color: light-dark(#10233a, #e4eef9);
    box-shadow: 0 18px 50px rgb(8 18 32 / .3);
    backdrop-filter: blur(14px);
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity .2s ease, transform .2s ease;
}
.ayuda-panel.abierto { opacity: 1; transform: none; }
.ayuda-panel-cab { display: flex; align-items: center; gap: .5rem; }
.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; justify-content: flex-end; margin-top: 1.1rem; }
.ayuda-pie .btn-p { margin: 0; }

/* La tarjeta de la página tiene que ser el marco del botón */
.cristal:has(> .ayuda-btn) { position: relative; }

@media (width <= 600px) {
    .ayuda-btn { position: static; margin: 0 auto .6rem; }
    .ayuda-panel { position: fixed; top: auto; bottom: 0; right: 0; left: 0; width: 100%;
        max-height: 80vh; border-radius: 1.2rem 1.2rem 0 0; }
}

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