/* =========================================================================
   Inventario bluumun — sistema de diseño
   =========================================================================
   Hoja única, sin framework. Se sirve tal cual: no pasa por ningún compilador,
   de modo que un despliegue solo tiene que copiarla.

   Orden del archivo:
     1. Tokens (claro y oscuro)
     2. Base y tipografía
     3. Disposición: barra lateral, cabecera, contenido
     4. Componentes
     5. Utilidades
   ========================================================================= */

/* -------------------------------------------------------- 0. Tipografía */

/*
 * Outfit, la tipografía de texto e interfaz de bluumun (brand.css). Fichero
 * variable autoalojado (subconjunto "latin", cubre el español) para no
 * depender de ningún CDN externo: la CSP de la aplicación cierra font-src a
 * 'self'. Licencia SIL OFL 1.1, ver fuentes/LICENSE-outfit.txt.
 */
@font-face {
    font-family: "Outfit Variable";
    font-style: normal;
    font-display: swap;
    font-weight: 100 900;
    src: url("../fuentes/outfit-variable.woff2") format("woff2-variations");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
        U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
        U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/*
 * BLUUMUN, la tipografía de display exclusiva de marca. Fuente propia, no
 * redistribuible: no lleva fichero de licencia porque no es de terceros.
 * Solo trae tres pesos estáticos (no es variable, a diferencia de Outfit),
 * que son exactamente los que documenta brand.css: Thin 300, Regular 400,
 * Medium 500. Nunca para texto corrido — ver dónde se aplica --fuente-display
 * más abajo, limitado a los dos rótulos de marca de la interfaz.
 */
@font-face {
    font-family: "BLUUMUN";
    font-style: normal;
    font-display: swap;
    font-weight: 300;
    src: url("../fuentes/bluumun-thin.woff2") format("woff2");
}
@font-face {
    font-family: "BLUUMUN";
    font-style: normal;
    font-display: swap;
    font-weight: 400;
    src: url("../fuentes/bluumun-regular.woff2") format("woff2");
}
@font-face {
    font-family: "BLUUMUN";
    font-style: normal;
    font-display: swap;
    font-weight: 500;
    src: url("../fuentes/bluumun-medium.woff2") format("woff2");
}

/* ------------------------------------------------------------- 1. Tokens */

:root {
    color-scheme: light;

    --fondo:            #f6f7f9;
    --fondo-alterno:    #eef0f4;
    --superficie:       #ffffff;
    --superficie-2:     #f9fafb;
    --superficie-3:     #f3f4f6;

    --borde:            #e3e6ea;
    --borde-fuerte:     #cdd2d9;

    --texto:            #14181d;
    --texto-suave:      #5c6672;
    --texto-tenue:      #8b95a1;

    /* Azul Órbita oficial de bluumun (brand.css v1.0). --acento es el tono
       base de marca (--bm-azul, 60% de uso oficial); --acento-fuerte es su
       derivado más oscuro (--bm-azul-900), reservado al hover de botones
       para no diluir el azul de marca en el resto de la interfaz, donde se
       usa --acento directamente en enlaces, foco, insignias e iconos.
       Contraste comprobado: azul/blanco 11,7:1 (manual: 11,8:1 AAA). */
    --acento:           #26346C;
    --acento-fuerte:    #1C2751;
    --acento-suave:     #DEE1E9;
    --acento-borde:     #9DA4BD;
    --sobre-acento:     #ffffff;

    --exito:            #17803d;
    --exito-suave:      #e7f6ec;
    --exito-borde:      #b7e3c5;

    --peligro:          #c62b2b;
    --peligro-suave:    #fdecec;
    --peligro-borde:    #f5c2c2;

    --aviso:            #a15c07;
    --aviso-suave:      #fdf3e3;
    --aviso-borde:      #f0d9ae;

    --info:             #0e6f8a;
    --info-suave:       #e6f5fa;
    --info-borde:       #b3dce8;

    --radio-sm:  6px;
    --radio:     10px;
    --radio-lg:  16px;
    --radio-max: 999px;

    --sombra-1: 0 1px 2px rgb(16 24 40 / .05);
    --sombra-2: 0 2px 8px rgb(16 24 40 / .07), 0 1px 2px rgb(16 24 40 / .04);
    --sombra-3: 0 12px 32px rgb(16 24 40 / .14), 0 2px 8px rgb(16 24 40 / .06);

    --rail:     68px;   /* barra lateral recogida */
    --lateral:  256px;  /* barra lateral desplegada */
    --cabecera: 60px;

    --transicion: 180ms cubic-bezier(.4, 0, .2, 1);

    /* Outfit: texto y sistema, tal como fija brand.css. Autoalojada arriba;
       la pila de sistema queda como alternativa si el .woff2 no cargase. */
    --fuente: "Outfit Variable", ui-sans-serif, system-ui, -apple-system,
              "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;

    /* BLUUMUN: display exclusivo de marca, nunca para texto corrido (ver
       nota en el @font-face de arriba). Reservada a los dos puntos donde la
       interfaz es de verdad un rótulo de marca: el título de la pantalla de
       acceso y el nombre de la aplicación en la cabecera. El resto de
       títulos (h1-h6 de tablas, fichas, diálogos) son texto de trabajo, no
       marca, y se quedan en --fuente. */
    --fuente-display: "BLUUMUN", Georgia, serif;

    --mono:   ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
              "Liberation Mono", monospace;
}

[data-tema="oscuro"] {
    color-scheme: dark;

    --fondo:            #0d1117;
    --fondo-alterno:    #10161f;
    --superficie:       #161b23;
    --superficie-2:     #1c222c;
    --superficie-3:     #232a36;

    --borde:            #272e3a;
    --borde-fuerte:     #3a4352;

    --texto:            #e8ebf0;
    --texto-suave:      #9aa5b4;
    --texto-tenue:      #6e7987;

    /* Sobre fondo oscuro el manual de marca invierte a Crema Lunar como
       acento (--bm-acento en brand.css), no a un azul aclarado: el azul
       sobre negro no llega al contraste mínimo (manual: 1,8:1, insuficiente).
       --sobre-acento usa el propio Azul Órbita sobre el relleno crema
       (manual: crema/azul 8,9:1 AAA). --acento-fuerte es la crema más clara
       para el hover; --acento-suave y --acento-borde son tonos oscuros del
       azul para fondos y bordes sutiles, como en el tema claro. */
    --acento:           #E7E1D9;
    --acento-fuerte:    #F3F0EC;
    --acento-suave:     #1C2751;
    --acento-borde:     #5C6791;
    --sobre-acento:     #26346C;

    --exito:            #56d68a;
    --exito-suave:      #10241a;
    --exito-borde:      #1f4030;

    --peligro:          #ff8080;
    --peligro-suave:    #2a1517;
    --peligro-borde:    #4d2427;

    --aviso:            #f0b866;
    --aviso-suave:      #271d10;
    --aviso-borde:      #45341c;

    --info:             #63c8e3;
    --info-suave:       #0f2229;
    --info-borde:       #1d3d47;

    --sombra-1: 0 1px 2px rgb(0 0 0 / .4);
    --sombra-2: 0 2px 8px rgb(0 0 0 / .45), 0 1px 2px rgb(0 0 0 / .3);
    --sombra-3: 0 12px 32px rgb(0 0 0 / .6), 0 2px 8px rgb(0 0 0 / .4);
}

/* --------------------------------------------------- 2. Base y tipografía */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--fondo);
    color: var(--texto);
    font-family: var(--fuente);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    margin: 0 0 .5rem;
    font-weight: 650;
    line-height: 1.25;
    letter-spacing: -.011em;
}
h1 { font-size: 1.6rem; }
h2 { font-size: 1.35rem; }
h3 { font-size: 1.15rem; }
h4 { font-size: 1.02rem; }
h5, h6 { font-size: .94rem; }

p { margin: 0 0 .85rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--acento); text-decoration: none; }
a:hover { text-decoration: underline; }

code, kbd, pre, samp { font-family: var(--mono); font-size: .88em; }

hr {
    border: 0;
    border-top: 1px solid var(--borde);
    margin: 1.25rem 0;
}

:focus-visible {
    outline: 2px solid var(--acento);
    outline-offset: 2px;
    border-radius: var(--radio-sm);
}

::selection { background: var(--acento); color: var(--sobre-acento); }

/* Barras de desplazamiento discretas */
* { scrollbar-width: thin; scrollbar-color: var(--borde-fuerte) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
    background: var(--borde-fuerte);
    border: 3px solid transparent;
    border-radius: var(--radio-max);
    background-clip: content-box;
}

/* ------------------------------------------------------- 3. Disposición */

.app {
    display: flex;
    min-height: 100vh;
    min-height: 100dvh;
}

/*
 * Barra lateral.
 *
 * En escritorio queda recogida a un carril de iconos y se despliega al pasar
 * el cursor. El botón de abajo la fija: mientras está fijada, el contenido se
 * desplaza para no quedar tapado. Sin fijar, el despliegue flota por encima,
 * que es lo que se espera de algo que aparece al pasar por delante.
 */
.lateral {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 40;
    width: var(--rail);
    display: flex;
    flex-direction: column;
    background: var(--superficie);
    border-right: 1px solid var(--borde);
    overflow: hidden;
    transition: width var(--transicion), box-shadow var(--transicion),
                transform var(--transicion);
}

.lateral:hover,
.lateral:focus-within,
.lateral.abierta {
    width: var(--lateral);
    box-shadow: var(--sombra-3);
}

.lateral.fijada {
    width: var(--lateral);
    box-shadow: none;
}

.lateral-marca {
    display: flex;
    align-items: center;
    gap: .7rem;
    height: var(--cabecera);
    padding: 0 calc((var(--rail) - 34px) / 2);
    flex: 0 0 auto;
    border-bottom: 1px solid var(--borde);
    color: var(--texto);
    text-decoration: none;
    white-space: nowrap;
}
.lateral-marca:hover { text-decoration: none; }

/* --- Logotipo --- */

.lateral-logo {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    color: var(--acento);
}

/*
 * El logotipo viene en dos ficheros, azul y blanco. Se colocan los dos y el
 * tema decide cual se ve. Se hace con CSS y no cambiando el `src` desde
 * JavaScript porque el tema se aplica antes de que arranque React: si
 * dependiera del JavaScript, al cargar en oscuro se veria un destello del
 * logotipo azul sobre fondo negro.
 */
.logotipo,
.marca {
    display: inline-flex;
    align-items: center;
    line-height: 0;   /* sin hueco fantasma bajo la imagen */
}
.logotipo img,
.marca img { width: auto; }

/*
 * Van DESPUES de `.logotipo img` y con su misma fuerza, o no se aplican:
 * `.logotipo img` pesa igual que `img.solo-oscuro` y, empatadas, gana la ultima
 * escrita. Con el orden al reves —como estaban— la regla del tamaño devolvia el
 * `display` a las dos imagenes y se veian los dos logotipos a la vez, el azul
 * y el blanco, uno junto al otro.
 */
img.solo-claro  { display: block; }
img.solo-oscuro { display: none; }

[data-tema="oscuro"] img.solo-claro  { display: none; }
[data-tema="oscuro"] img.solo-oscuro { display: block; }

.lateral-titulo {
    font-weight: 650;
    font-size: .96rem;
    letter-spacing: -.01em;
}

.lateral-nav {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding: .6rem 0 .4rem;
}

.lateral-grupo + .lateral-grupo { margin-top: .35rem; }

.lateral-grupo-titulo {
    height: 1.9rem;
    display: flex;
    align-items: center;
    padding: 0 1rem;
    margin: .35rem 0 .1rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--texto-tenue);
    white-space: nowrap;
}

/* El separador sustituye al rótulo cuando el carril está recogido. */
.lateral-grupo-linea {
    height: 1px;
    margin: .5rem .9rem;
    background: var(--borde);
}

.lateral-enlace {
    position: relative;
    display: flex;
    align-items: center;
    gap: .8rem;
    height: 42px;
    margin: 1px .5rem;
    padding: 0 calc((var(--rail) - 22px) / 2 - .5rem);
    border-radius: var(--radio-sm);
    color: var(--texto-suave);
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--transicion), color var(--transicion);
}
.lateral-enlace:hover {
    background: var(--superficie-3);
    color: var(--texto);
    text-decoration: none;
}
.lateral-enlace.activo {
    background: var(--acento-suave);
    color: var(--acento);
    font-weight: 600;
}
.lateral-enlace.activo::before {
    content: "";
    position: absolute;
    left: -.5rem;
    top: 50%;
    translate: 0 -50%;
    width: 3px;
    height: 22px;
    border-radius: 0 3px 3px 0;
    background: var(--acento);
}

.lateral-icono {
    flex: 0 0 22px;
    width: 22px;
    display: grid;
    place-items: center;
    font-size: 1.05rem;
    line-height: 1;
}

.lateral-texto {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lateral-pie {
    flex: 0 0 auto;
    border-top: 1px solid var(--borde);
    padding: .45rem 0;
}

/*
 * El rótulo de un enlace y el del pie solo aparecen cuando hay sitio. Se anima
 * la opacidad y no el ancho: así el texto no se reflowa a cada píxel.
 */
.lateral-titulo,
.lateral-texto,
.lateral-grupo-titulo,
.lateral-insignia,
.lateral-fijar-texto {
    opacity: 0;
    transition: opacity 120ms linear;
}
.lateral:hover  .lateral-titulo,
.lateral:hover  .lateral-texto,
.lateral:hover  .lateral-grupo-titulo,
.lateral:hover  .lateral-insignia,
.lateral:hover  .lateral-fijar-texto,
.lateral:focus-within .lateral-titulo,
.lateral:focus-within .lateral-texto,
.lateral:focus-within .lateral-grupo-titulo,
.lateral:focus-within .lateral-insignia,
.lateral:focus-within .lateral-fijar-texto,
.lateral.abierta .lateral-titulo,
.lateral.abierta .lateral-texto,
.lateral.abierta .lateral-grupo-titulo,
.lateral.abierta .lateral-insignia,
.lateral.abierta .lateral-fijar-texto,
.lateral.fijada  .lateral-titulo,
.lateral.fijada  .lateral-texto,
.lateral.fijada  .lateral-grupo-titulo,
.lateral.fijada  .lateral-insignia,
.lateral.fijada  .lateral-fijar-texto {
    opacity: 1;
    transition-delay: 40ms;
}

/* Contador del enlace. Recogido se convierte en un punto sobre el icono. */
.lateral-insignia {
    flex: 0 0 auto;
    min-width: 1.35rem;
    height: 1.35rem;
    padding: 0 .4rem;
    display: grid;
    place-items: center;
    border-radius: var(--radio-max);
    background: var(--peligro);
    color: #fff;
    font-size: .7rem;
    font-weight: 700;
}
.lateral-insignia.acento { background: var(--acento); color: var(--sobre-acento); }

.lateral-punto {
    position: absolute;
    top: 9px;
    left: calc((var(--rail) - 22px) / 2 - .5rem + 14px);
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--peligro);
    border: 2px solid var(--superficie);
    transition: opacity 120ms linear;
}
.lateral:hover .lateral-punto,
.lateral:focus-within .lateral-punto,
.lateral.abierta .lateral-punto,
.lateral.fijada .lateral-punto { opacity: 0; }

.lateral-fijar {
    display: flex;
    align-items: center;
    gap: .8rem;
    width: calc(100% - 1rem);
    height: 40px;
    margin: 0 .5rem;
    padding: 0 calc((var(--rail) - 22px) / 2 - .5rem);
    border: 0;
    border-radius: var(--radio-sm);
    background: transparent;
    color: var(--texto-suave);
    font: inherit;
    font-size: .87rem;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--transicion), color var(--transicion);
}
.lateral-fijar:hover { background: var(--superficie-3); color: var(--texto); }
.lateral-fijar[aria-pressed="true"] { color: var(--acento); }
.lateral-fijar .lateral-icono { transition: rotate var(--transicion); }
.lateral-fijar[aria-pressed="true"] .lateral-icono { rotate: -45deg; }

/* --- Contenido --- */

.principal {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: var(--rail);
    display: flex;
    flex-direction: column;
    transition: margin-left var(--transicion);
}
.app.fijada .principal { margin-left: var(--lateral); }

/*
 * Cabecera en tres zonas de igual peso a los lados, para que el buscador quede
 * ópticamente centrado en la pantalla y no se desplace según lo largo que sea
 * el nombre del usuario.
 */
.cabecera {
    position: sticky;
    top: 0;
    z-index: 30;
    height: var(--cabecera);
    flex: 0 0 auto;
    display: grid;
    grid-template-columns: 1fr minmax(0, 560px) 1fr;
    align-items: center;
    gap: 1rem;
    padding: 0 1.25rem;
    background: color-mix(in srgb, var(--fondo) 82%, transparent);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--borde);
}

.cabecera-izq { display: flex; align-items: center; gap: .6rem; min-width: 0; }

.cabecera-titulo {
    margin: 0;
    font-family: var(--fuente-display);
    font-size: 1.05rem;
    font-weight: 500;
    letter-spacing: .01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cabecera-acciones {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem;
    min-width: 0;
}

/* El contenido ocupa el ancho disponible; solo se frena en pantallas enormes. */
.contenido {
    flex: 1 1 auto;
    width: 100%;
    max-width: 1800px;
    margin-inline: auto;
    padding: 1.5rem 1.75rem 3rem;
}
@media (min-width: 1900px) { .contenido { padding-inline: 2.5rem; } }

/* Botón que abre la barra en móvil; en escritorio no existe. */
.abrir-lateral { display: none; }

.velo {
    position: fixed;
    inset: 0;
    z-index: 35;
    background: rgb(8 12 18 / .5);
    backdrop-filter: blur(2px);
    border: 0;
    padding: 0;
    animation: aparecer 160ms ease;
}

@keyframes aparecer { from { opacity: 0; } to { opacity: 1; } }

/* --- Buscador de la cabecera, con comandos rápidos --- */

.paleta { position: relative; }

.paleta-campo {
    position: relative;
    display: flex;
    align-items: center;
}
.paleta-campo .control {
    height: 36px;
    padding-left: 2.1rem;
    padding-right: 3.2rem;
    background: var(--superficie);
    font-size: .87rem;
}

.paleta-lupa {
    position: absolute;
    left: .7rem;
    color: var(--texto-tenue);
    font-size: .9rem;
    pointer-events: none;
}

.paleta-atajo {
    position: absolute;
    right: .45rem;
    display: flex;
    gap: .2rem;
    pointer-events: none;
}
.paleta-tecla {
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 .3rem;
    display: grid;
    place-items: center;
    border: 1px solid var(--borde-fuerte);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: var(--superficie-2);
    color: var(--texto-tenue);
    font-size: .66rem;
    font-weight: 700;
}

.paleta-panel {
    position: absolute;
    top: calc(100% + .45rem);
    left: 0;
    right: 0;
    z-index: 50;
    max-height: min(60vh, 460px);
    overflow-y: auto;
    padding: .35rem;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: var(--sombra-3);
    animation: bajar 140ms cubic-bezier(.4, 0, .2, 1);
}
@keyframes bajar {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

.paleta-grupo {
    padding: .5rem .6rem .25rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--texto-tenue);
}

.paleta-opcion {
    display: flex;
    align-items: center;
    gap: .65rem;
    width: 100%;
    padding: .5rem .6rem;
    border: 0;
    border-radius: var(--radio-sm);
    background: none;
    color: var(--texto);
    font: inherit;
    font-size: .87rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.paleta-opcion:hover,
.paleta-opcion.marcada {
    background: var(--acento-suave);
    color: var(--acento);
    text-decoration: none;
}

.paleta-icono {
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    display: grid;
    place-items: center;
    border-radius: var(--radio-sm);
    background: var(--superficie-3);
    font-size: .9rem;
}
.paleta-opcion.marcada .paleta-icono { background: var(--superficie); }

.paleta-texto { flex: 1 1 auto; min-width: 0; }
.paleta-titulo { display: block; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.paleta-sub    { display: block; font-size: .78rem; color: var(--texto-suave); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.paleta-opcion.marcada .paleta-sub { color: inherit; opacity: .75; }

.paleta-comando {
    flex: 0 0 auto;
    font-family: var(--mono);
    font-size: .74rem;
    color: var(--texto-tenue);
}
.paleta-opcion.marcada .paleta-comando { color: inherit; opacity: .8; }

.paleta-vacio { padding: 1.25rem .6rem; text-align: center; font-size: .85rem; color: var(--texto-suave); }

.paleta-pie {
    display: flex;
    gap: 1rem;
    padding: .5rem .6rem .2rem;
    margin-top: .3rem;
    border-top: 1px solid var(--borde);
    font-size: .72rem;
    color: var(--texto-tenue);
}

/* --- Tableta --- */
@media (max-width: 1100px) {
    .contenido { padding: 1.25rem 1rem 2.5rem; }
}

/* En pantallas estrechas el buscador ocupa el centro y se ocultan los rótulos. */
@media (max-width: 900px) {
    .cabecera { grid-template-columns: auto 1fr auto; gap: .5rem; }
    .cabecera-titulo { display: none; }
    .paleta-atajo { display: none; }
    .paleta-campo .control { padding-right: .7rem; }
}

/* --- Móvil y tableta pequeña: la barra pasa a ser un cajón --- */
@media (max-width: 820px) {
    .lateral {
        width: var(--lateral);
        transform: translateX(-100%);
        box-shadow: none;
    }
    /* El despliegue por cursor no aplica donde no hay cursor. */
    .lateral:hover, .lateral:focus-within { width: var(--lateral); box-shadow: none; }
    .lateral.abierta { transform: translateX(0); box-shadow: var(--sombra-3); }
    .lateral.fijada  { transform: translateX(-100%); }
    .lateral.fijada.abierta { transform: translateX(0); box-shadow: var(--sombra-3); }

    .lateral-titulo, .lateral-texto, .lateral-grupo-titulo,
    .lateral-insignia, .lateral-fijar-texto { opacity: 1; }
    .lateral-punto { opacity: 0; }

    /* Fijar no tiene sentido en un cajón. */
    .lateral-fijar { display: none; }

    .principal, .app.fijada .principal { margin-left: 0; }

    .abrir-lateral {
        display: inline-grid;
        place-items: center;
        width: 38px;
        height: 38px;
        flex: 0 0 auto;
        border: 1px solid var(--borde);
        border-radius: var(--radio-sm);
        background: var(--superficie);
        color: var(--texto);
        font-size: 1.1rem;
        cursor: pointer;
    }
    .abrir-lateral:hover { background: var(--superficie-3); }
}

@media (max-width: 520px) {
    .contenido { padding: 1rem .8rem 2.5rem; }
    .cabecera { padding: 0 .8rem; }
    :root { --lateral: min(280px, 84vw); }
}

/* ------------------------------------------------------- 4. Componentes */

/* --- Botones --- */

.btn {
    --btn-fondo: var(--superficie);
    --btn-borde: var(--borde-fuerte);
    --btn-texto: var(--texto);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    height: 38px;
    padding: 0 .95rem;
    border: 1px solid var(--btn-borde);
    border-radius: var(--radio-sm);
    background: var(--btn-fondo);
    color: var(--btn-texto);
    font: inherit;
    font-size: .89rem;
    font-weight: 550;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--transicion), border-color var(--transicion),
                color var(--transicion), box-shadow var(--transicion);
}
.btn:hover { text-decoration: none; background: var(--superficie-3); }
.btn:active { transform: translateY(.5px); }
.btn:disabled, .btn[aria-disabled="true"] {
    opacity: .55;
    cursor: not-allowed;
    transform: none;
}

.btn-primario {
    --btn-fondo: var(--acento);
    --btn-borde: var(--acento);
    --btn-texto: var(--sobre-acento);
}
.btn-primario:hover:not(:disabled) { background: var(--acento-fuerte); border-color: var(--acento-fuerte); }

.btn-peligro {
    --btn-fondo: var(--peligro);
    --btn-borde: var(--peligro);
    --btn-texto: #fff;
}
.btn-peligro:hover:not(:disabled) { filter: brightness(1.08); background: var(--peligro); }

.btn-sutil {
    --btn-fondo: transparent;
    --btn-borde: transparent;
    --btn-texto: var(--texto-suave);
}
.btn-sutil:hover:not(:disabled) { background: var(--superficie-3); color: var(--texto); }

.btn-peligro-sutil {
    --btn-fondo: transparent;
    --btn-borde: var(--peligro-borde);
    --btn-texto: var(--peligro);
}
.btn-peligro-sutil:hover:not(:disabled) { background: var(--peligro-suave); }

.btn-sm { height: 31px; padding: 0 .65rem; font-size: .82rem; gap: .3rem; }
.btn-lg { height: 44px; padding: 0 1.3rem; font-size: .95rem; }
.btn-bloque { width: 100%; }

.btn-icono { width: 38px; padding: 0; }
.btn-icono.btn-sm { width: 31px; }
.btn-redondo { border-radius: var(--radio-max); }

/* --- Tarjetas --- */

.tarjeta {
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: var(--sombra-1);
    overflow: hidden;
}

.tarjeta-cabecera {
    display: flex;
    align-items: center;
    flex-wrap: wrap;   /* con varias insignias y botones, antes se desbordaba */
    gap: .5rem .75rem;
    padding: .85rem 1.1rem;
    border-bottom: 1px solid var(--borde);
    background: var(--superficie-2);
}
.tarjeta-cabecera h2,
.tarjeta-cabecera h3,
.tarjeta-cabecera h4 { margin: 0; font-size: .97rem; }
.tarjeta-cabecera .acciones {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}
/* En una tarjeta estrecha los botones ocupan su propia linea, completa. */
@media (max-width: 480px) {
    .tarjeta-cabecera .acciones { margin-left: 0; width: 100%; }
}

/* Tarjeta que reclama atención: la vía excepcional de un formulario. */
.tarjeta.resaltada-aviso { border-color: var(--aviso-borde); border-left: 3px solid var(--aviso); }
.tarjeta.resaltada-acento { border-color: var(--acento-borde); border-left: 3px solid var(--acento); }

.tarjeta-cuerpo { padding: 1.1rem; }
.tarjeta-pie {
    padding: .8rem 1.1rem;
    border-top: 1px solid var(--borde);
    background: var(--superficie-2);
}

/* --- Rejilla --- */

.rejilla { display: grid; gap: 1rem; }
.rejilla-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.rejilla-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.rejilla-4 { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/*
 * Tarjetas con acciones al pie: necesitan mas ancho que una rejilla normal
 * porque llevan tres botones en fila, y se estiran a la misma altura para que
 * los pies queden alineados aunque las descripciones midan distinto.
 */
.rejilla-tarjetas {
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    align-items: stretch;
}
.rejilla-tarjetas > .tarjeta { display: flex; flex-direction: column; }
.rejilla-tarjetas > .tarjeta > .tarjeta-cuerpo { flex: 1 1 auto; }
.rejilla-tarjetas .tarjeta-pie .acciones { display: flex; flex-wrap: wrap; gap: .4rem; }

@media (max-width: 380px) {
    .rejilla-tarjetas { grid-template-columns: 1fr; }
    .rejilla-tarjetas .tarjeta-pie .acciones > .btn { flex: 1 1 auto; }
}

/* --- Indicadores --- */

.indicador {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    padding: 1rem 1.1rem;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: var(--sombra-1);
    text-decoration: none;
    color: inherit;
    transition: border-color var(--transicion), box-shadow var(--transicion),
                transform var(--transicion);
}
a.indicador:hover {
    text-decoration: none;
    border-color: var(--acento-borde);
    box-shadow: var(--sombra-2);
    transform: translateY(-1px);
}
.indicador-rotulo {
    font-size: .76rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--texto-tenue);
}
.indicador-cifra {
    font-size: 1.85rem;
    font-weight: 680;
    line-height: 1.1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}
.indicador-pie { font-size: .82rem; color: var(--texto-suave); }

.indicador.peligro .indicador-cifra { color: var(--peligro); }
.indicador.aviso   .indicador-cifra { color: var(--aviso); }
.indicador.exito   .indicador-cifra { color: var(--exito); }
.indicador.acento  .indicador-cifra { color: var(--acento); }

/* --- Formularios --- */

.campo { display: flex; flex-direction: column; gap: .35rem; margin-bottom: 1rem; }
.campo:last-child { margin-bottom: 0; }

.etiqueta {
    font-size: .84rem;
    font-weight: 600;
    color: var(--texto);
}
.etiqueta .opcional { font-weight: 400; color: var(--texto-tenue); }

.control {
    width: 100%;
    height: 38px;
    padding: 0 .7rem;
    border: 1px solid var(--borde-fuerte);
    border-radius: var(--radio-sm);
    background: var(--superficie);
    color: var(--texto);
    font: inherit;
    font-size: .9rem;
    transition: border-color var(--transicion), box-shadow var(--transicion);
}
textarea.control { height: auto; min-height: 84px; padding: .5rem .7rem; resize: vertical; }
select.control {
    appearance: none;
    padding-right: 2rem;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 1.05rem) 52%, calc(100% - .75rem) 52%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}
.control:hover { border-color: var(--texto-tenue); }
.control:focus {
    outline: none;
    border-color: var(--acento);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 18%, transparent);
}
.control::placeholder { color: var(--texto-tenue); }
.control:disabled { background: var(--superficie-3); color: var(--texto-tenue); cursor: not-allowed; }

.control.error { border-color: var(--peligro); }
.control.error:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--peligro) 18%, transparent); }

.ayuda { font-size: .8rem; color: var(--texto-suave); }
.mensaje-error { font-size: .8rem; color: var(--peligro); font-weight: 500; }

.casilla {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    cursor: pointer;
    padding: .35rem 0;
}
.casilla input[type="checkbox"],
.casilla input[type="radio"] {
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
    margin: .18rem 0 0;
    accent-color: var(--acento);
    cursor: pointer;
}
.casilla-texto { font-size: .89rem; }
.casilla-ayuda { display: block; font-size: .8rem; color: var(--texto-suave); }

/* Casilla presentada como tarjeta seleccionable, para los permisos de un rol */
.opcion {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    padding: .7rem .8rem;
    border: 1px solid var(--borde);
    border-radius: var(--radio-sm);
    background: var(--superficie);
    cursor: pointer;
    transition: border-color var(--transicion), background var(--transicion);
}
.opcion:hover { border-color: var(--borde-fuerte); background: var(--superficie-2); }
.opcion:has(input:checked) {
    border-color: var(--acento-borde);
    background: var(--acento-suave);
}
.opcion:has(input:disabled),
.opcion.deshabilitada { opacity: .6; cursor: not-allowed; }

/* Acceso al archivo: centrado y al final de la lista, sin llamar la atención. */
.pie-archivo {
    display: flex;
    justify-content: center;
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--borde);
}
.opcion input { flex: 0 0 auto; margin: .2rem 0 0; width: 17px; height: 17px; accent-color: var(--acento); }
.opcion-nombre { font-size: .88rem; font-weight: 600; }
.opcion-descripcion { font-size: .8rem; color: var(--texto-suave); }

/* --- Formulario por pasos --- */

.paso-numero {
    flex: 0 0 24px;
    width: 24px;
    height: 24px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--acento);
    color: var(--sobre-acento);
    font-size: .78rem;
    font-weight: 700;
}

/*
 * Una línea de material solicitado: tipo, cantidad, detalle y el botón de
 * quitar. En cuanto no cabe en una fila cada campo pasa a ocupar el ancho
 * completo, que es más legible que encogerlos hasta lo ilegible.
 */
.linea-peticion {
    display: grid;
    grid-template-columns: minmax(0, 2fr) 6.5rem minmax(0, 2fr) auto;
    gap: 0 .75rem;
    align-items: start;
}
.linea-peticion .campo { margin-bottom: 0; }
.linea-peticion > .btn { margin-top: 1.62rem; }

@media (max-width: 760px) {
    .linea-peticion {
        grid-template-columns: 1fr auto;
        gap: .5rem .75rem;
        padding: .85rem;
        border: 1px solid var(--borde);
        border-radius: var(--radio-sm);
        background: var(--superficie-2);
    }
    .linea-peticion .campo:first-child { grid-column: 1 / -1; }
    .linea-peticion > .btn { margin-top: 1.62rem; }
}

/* Elegir tipo, elegir unidad y añadir: tres controles en una fila. */
.selector-equipo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) auto;
    gap: 0 .75rem;
    align-items: start;
}
.selector-equipo .campo { margin-bottom: 0; }
.selector-equipo > .btn { margin-top: 1.62rem; }

@media (max-width: 760px) {
    .selector-equipo { grid-template-columns: 1fr; gap: .75rem; }
    .selector-equipo > .btn { margin-top: 0; width: 100%; }
}

/* Tarjeta de departamento: se marca la que filtra la lista de abajo. */
.departamento.elegido {
    border-color: var(--acento);
    box-shadow: 0 0 0 1px var(--acento);
}

/* --- Desplegable con búsqueda --- */

.selector { position: relative; }

.selector-campo { position: relative; display: flex; align-items: center; }
.selector-campo .control { padding-right: 3.6rem; }

/* Con algo elegido, el texto se ve como un valor y no como algo a medio
   escribir; abierto vuelve a ser un campo de búsqueda normal. */
.selector:not(.abierto) .selector-campo .control { cursor: pointer; }
.selector.abierto .selector-campo .control { cursor: text; }

.selector-flecha {
    position: absolute;
    right: .7rem;
    color: var(--texto-tenue);
    font-size: .8rem;
    pointer-events: none;
    transition: rotate var(--transicion);
}
.selector.abierto .selector-flecha { rotate: 180deg; }

.selector-limpiar {
    position: absolute;
    right: 1.8rem;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border: 0;
    border-radius: var(--radio-sm);
    background: transparent;
    color: var(--texto-tenue);
    font-size: .75rem;
    cursor: pointer;
}
.selector-limpiar:hover { background: var(--superficie-3); color: var(--texto); }

/*
 * La lista se dibuja al final del documento y se coloca sobre el campo desde
 * JavaScript. Colgada del campo la recortaba el `overflow` de la tarjeta que lo
 * contiene, y dentro de un diálogo la habría cortado su propio desplazamiento.
 *
 * De ahí el z-index por encima del diálogo (70): es lo último que se dibuja.
 */
.selector-lista {
    position: fixed;
    z-index: 80;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: .3rem;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: var(--sombra-3);
    animation: bajar 130ms cubic-bezier(.4, 0, .2, 1);
}

/* Desplegada hacia arriba, la animación tiene que venir del lado contrario. */
.selector-lista.arriba { animation-name: subir; }

@keyframes subir {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.selector-opcion {
    display: flex;
    align-items: center;
    gap: .6rem;
    width: 100%;
    padding: .5rem .6rem;
    border: 0;
    border-radius: var(--radio-sm);
    background: none;
    color: var(--texto);
    font: inherit;
    font-size: .89rem;
    text-align: left;
    cursor: pointer;
}
.selector-opcion.marcada { background: var(--acento-suave); color: var(--acento); }

/* La fila de «crear esto que estás escribiendo», separada de las de la lista. */
.selector-opcion.es-nuevo {
    color: var(--acento);
    border-bottom: 1px dashed var(--borde);
    border-radius: var(--radio-sm) var(--radio-sm) 0 0;
}
.selector-opcion.es-nuevo .selector-titulo { font-weight: 600; }

.selector-texto { flex: 1 1 auto; min-width: 0; }
.selector-titulo { display: block; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.selector-detalle {
    display: block;
    font-size: .78rem;
    color: var(--texto-suave);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.selector-opcion.marcada .selector-detalle { color: inherit; opacity: .8; }

.selector-marca { flex: 0 0 auto; font-size: .74rem; }

.selector-vacio,
.selector-cuenta {
    margin: 0;
    padding: .7rem .6rem;
    text-align: center;
    font-size: .8rem;
    color: var(--texto-tenue);
}
.selector-cuenta {
    padding: .45rem .6rem .2rem;
    margin-top: .25rem;
    border-top: 1px solid var(--borde);
    font-size: .74rem;
}

/* --- Identidad y tipos, en la configuración --- */

.vista-previa {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .6rem .8rem;
    border: 1px dashed var(--borde);
    border-radius: var(--radio);
    background: var(--superficie-2);
}
.vista-previa .etiqueta { margin: 0; }
.vista-previa strong { font-size: 1.02rem; }

.rejilla-marca { display: grid; gap: .8rem; }

@media (min-width: 46rem) {
    .rejilla-marca { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.ranura-marca {
    display: flex;
    gap: .8rem;
    padding: .8rem;
    border: 1px solid var(--borde);
    border-radius: var(--radio);
}

/*
 * El recuadro de la vista previa va en blanco siempre: casi todos los
 * logotipos vienen con fondo transparente y el que es azul oscuro
 * desaparecería sobre el fondo del tema oscuro.
 */
.ranura-marca-vista {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 88px;
    height: 64px;
    padding: .4rem;
    border-radius: var(--radio-sm);
    background: #fff;
    border: 1px solid var(--borde);
}
.ranura-marca-vista img { max-width: 100%; max-height: 100%; object-fit: contain; }

.ranura-marca-texto { flex: 1 1 auto; min-width: 0; }
.ranura-marca-texto .ayuda { margin: .15rem 0 .5rem; }

/* Un `label` haciendo de botón para el campo de fichero, que es feo de serie. */
.ranura-marca-texto label.btn { cursor: pointer; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }

.tipo-equipo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: .6rem;
    padding: .6rem;
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    background: var(--superficie-2);
}

@media (max-width: 46rem) {
    .tipo-equipo { grid-template-columns: minmax(0, 1fr) auto; }
    .tipo-equipo > .fila { grid-column: 1 / -1; }
}

/* --- Grupos de avisos en la configuración --- */

.grupo-avisos { margin-bottom: 1.1rem; }
.grupo-avisos:last-child { margin-bottom: 0; }
.grupo-avisos .etiqueta {
    margin-bottom: .5rem;
    padding-bottom: .3rem;
    border-bottom: 1px solid var(--borde);
}

/* --- Datos heredados de una ficha --- */

/*
 * Resumen de lo que la aplicación va a copiar de otro sitio —la ficha de
 * personal, al dar de alta una cuenta—. Se ve como un bloque aparte y no como
 * campos deshabilitados: un campo gris invita a intentar escribir en él.
 */
.ficha-elegida {
    margin-bottom: 1rem;
    padding: .8rem .9rem;
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    background: var(--superficie-2);
}
.ficha-elegida .etiqueta { margin-bottom: .5rem; }

.datos-linea { display: grid; gap: .55rem; margin: 0 0 .6rem; }
.datos-linea dt {
    font-size: .74rem;
    color: var(--texto-tenue);
    text-transform: uppercase;
    letter-spacing: .03em;
}
.datos-linea dd {
    margin: .1rem 0 0;
    font-size: .92rem;
    font-weight: 550;
    overflow-wrap: anywhere;
}

@media (min-width: 30rem) {
    .datos-linea { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Vincular el móvil como cámara --- */

.vinculo {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .85rem;
    text-align: center;
}

.vinculo-qr {
    padding: .8rem;
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    /* Blanco siempre, también en tema oscuro: un QR invertido no lo lee
       ninguna cámara de móvil. */
    background: #fff;
    line-height: 0;
    transition: opacity var(--transicion);
}
.vinculo-qr img { display: block; width: 200px; height: 200px; }

/* Leído el código, el QR ya no hace falta y estorba menos apagado. */
.vinculo-qr.vinculado { opacity: .25; }

.vinculo-estado {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin: 0;
    font-size: .88rem;
    font-weight: 550;
    color: var(--texto-suave);
}
.vinculo-estado .punto-estado { background: var(--texto-tenue); }
.vinculo-estado.activo { color: var(--exito); }
.vinculo-estado.activo .punto-estado {
    background: var(--exito);
    animation: latir 1.6s ease-in-out infinite;
}

@keyframes latir {
    0%, 100% { opacity: 1; }
    50%      { opacity: .35; }
}

.vinculo-pasos {
    margin: 0;
    padding-left: 1.2rem;
    text-align: left;
    font-size: .86rem;
    color: var(--texto-suave);
}
.vinculo-pasos li { margin-bottom: .25rem; }

.vinculo-enlace {
    display: flex;
    gap: .4rem;
    width: 100%;
}
.vinculo-enlace .control { font-size: .76rem; }

/* --- La pantalla del móvil que hace de lector --- */

/*
 * Ocupa la ventana entera y no lleva nada de la aplicación: se entra sin
 * identificarse y lo único que se puede hacer es apuntar la cámara.
 */
/*
 * Fija y pegada a los cuatro bordes, no `min-height: 100svh`.
 *
 * Con alto mínimo, el reparto entre barra, cámara y pie dependía de lo que
 * midiera el contenido, y la cámara se quedaba sin altura definida. Fija ocupa
 * exactamente la ventana, se ajusta sola cuando el navegador del móvil esconde
 * o enseña su barra de direcciones, y no hay página que se desplace por detrás.
 */
.movil {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #0b0d10;
    color: #f2f4f7;
}

.movil-barra {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: .55rem;
    /* El añadido de arriba esquiva la muesca de los móviles que la tienen. */
    padding: calc(.7rem + env(safe-area-inset-top)) .9rem .7rem;
    background: #14171c;
    border-bottom: 1px solid #23272e;
}
.movil-titulo { flex: 1 1 auto; font-size: .92rem; font-weight: 600; }
.movil-cuenta {
    min-width: 1.9rem;
    padding: .15rem .5rem;
    border-radius: 999px;
    background: #23272e;
    color: #8a939d;
    font-size: .82rem;
    font-weight: 700;
    text-align: center;
}
.movil-cuenta.activa { background: var(--exito); color: #fff; }

/*
 * `min-height: 0` no sobra: un hijo de flex no baja de su tamaño de contenido
 * salvo que se le diga, y sin esto la zona de la cámara no tenía altura
 * definida. El vídeo, con `height: 100%` sobre un alto automático, se quedaba
 * con su tamaño natural —4:3— dentro de un hueco más alto, y el marco de
 * puntería, que sí se centra en el hueco, aparecía por debajo del centro de la
 * imagen. De ahí que el cuadro no cuadrara con lo que se veía.
 */
.movil-camara {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    background: #000;
    /* Rejilla centrada: lo que se ponga encima queda en medio sin cálculos. */
    display: grid;
    place-items: center;
}
.movil-camara video {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/*
 * El marco y el aviso comparten celda: sin esto la rejilla los pondría en
 * filas distintas y ninguno de los dos quedaría en el centro.
 */
.movil-mira,
.movil-aviso { grid-area: 1 / 1; }

/*
 * Marco de puntería.
 *
 * En `vmin` y no en `vw`: así el cuadrado cabe también con el móvil tumbado,
 * donde el alto es la medida corta.
 */
.movil-mira {
    position: relative;
    width: min(66vmin, 300px);
    aspect-ratio: 1;
    border: 2px solid rgba(255, 255, 255, .85);
    border-radius: 14px;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .45);
}

/* Línea de barrido, igual que en el escáner de escritorio. */
.movil-mira::after {
    content: "";
    position: absolute;
    left: 6%;
    right: 6%;
    top: 50%;
    height: 2px;
    background: var(--acento);
    box-shadow: 0 0 8px var(--acento);
    animation: barrer 2.2s ease-in-out infinite;
}

.movil-aviso {
    position: relative;
    margin: 0;
    font-size: .9rem;
    color: #c9d1d9;
}

.movil-pie-panel {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    padding: 1rem .9rem calc(1rem + env(safe-area-inset-bottom));
    background: #14171c;
    border-top: 1px solid #23272e;
    text-align: center;
    min-height: 4.6rem;
}
.movil-instruccion { margin: 0; font-size: .86rem; color: #98a2ad; }
.movil-error { margin: 0; font-size: .86rem; color: #ff8f8f; }
.movil-hecho {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .2rem;
    margin: 0;
    font-size: .92rem;
    font-weight: 600;
    color: #6ee7a8;
}
.movil-codigo {
    font-family: var(--mono, ui-monospace, monospace);
    font-size: .78rem;
    font-weight: 400;
    color: #8a939d;
    overflow-wrap: anywhere;
}

.movil-centro {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .7rem;
    padding: 2rem 1.4rem;
    text-align: center;
}
.movil-centro h1 { margin: .4rem 0 0; font-size: 1.15rem; }
.movil-centro p { margin: 0; font-size: .9rem; color: #98a2ad; max-width: 24rem; }
.movil-pie { font-size: .82rem !important; color: #6b747f !important; }

/* --- Escáner de etiquetas --- */

.escaner {
    position: relative;
    aspect-ratio: 4 / 3;
    width: 100%;
    overflow: hidden;
    border-radius: var(--radio);
    background: #05070b;
    display: grid;
    place-items: center;
}

.escaner-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Recuadro de puntería: ayuda a encuadrar sin tapar la imagen. */
.escaner-mira {
    position: relative;
    width: min(62%, 240px);
    aspect-ratio: 1;
    border: 2px solid rgb(255 255 255 / .85);
    border-radius: var(--radio);
    box-shadow: 0 0 0 100vmax rgb(0 0 0 / .35);
}
.escaner-mira::after {
    content: "";
    position: absolute;
    left: 6%;
    right: 6%;
    top: 50%;
    height: 2px;
    background: var(--acento);
    box-shadow: 0 0 8px var(--acento);
    animation: barrer 2.2s ease-in-out infinite;
}
@keyframes barrer {
    0%, 100% { transform: translateY(-42%); }
    50%      { transform: translateY(42%); }
}

.escaner-aviso {
    position: relative;
    margin: 0;
    padding: .5rem .9rem;
    border-radius: var(--radio-max);
    background: rgb(0 0 0 / .6);
    color: #fff;
    font-size: .88rem;
}

@media (prefers-reduced-motion: reduce) {
    .escaner-mira::after { animation: none; }
}

/* --- Etiquetas imprimibles --- */

.hoja-etiquetas {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: .5rem;
}

.etiqueta-equipo {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem;
    border: 1px solid var(--borde);
    border-radius: var(--radio-sm);
    background: #fff;
    color: #14181d;
    break-inside: avoid;
}
.etiqueta-equipo img { width: 62px; height: 62px; flex: 0 0 62px; }
.etiqueta-equipo .datos { min-width: 0; }
.etiqueta-equipo .codigo {
    font-family: var(--mono);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
}
.etiqueta-equipo .que {
    font-size: .68rem;
    line-height: 1.25;
    color: #5c6672;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.etiqueta-equipo .numero { font-size: .62rem; color: #8a939d; }

@media print {
    .hoja-etiquetas { grid-template-columns: repeat(3, 1fr); gap: 3mm; }
    .etiqueta-equipo { border-color: #bbb; }
    @page { margin: 10mm; }
}

/* --- Dato personal enmascarado --- */

.dato-sensible {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}
.dato-sensible .mono { letter-spacing: .06em; }

.ojo-dato {
    display: inline-grid;
    place-items: center;
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
    border: 0;
    border-radius: var(--radio-sm);
    background: transparent;
    color: var(--texto-suave);
    font-size: .82rem;
    cursor: pointer;
    transition: background var(--transicion), color var(--transicion);
}
.ojo-dato:hover { background: var(--superficie-3); color: var(--texto); }

/* --- Tablas --- */

.tabla-caja {
    width: 100%;
    overflow-x: auto;
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    background: var(--superficie);
    box-shadow: var(--sombra-1);
}

.tabla {
    width: 100%;
    border-collapse: collapse;
    font-size: .89rem;
}
.tabla th, .tabla td {
    padding: .68rem .85rem;
    text-align: left;
    vertical-align: middle;
    border-bottom: 1px solid var(--borde);
}
.tabla thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--superficie-2);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--texto-suave);
    white-space: nowrap;
}
.tabla tbody tr:last-child td { border-bottom: 0; }
.tabla tbody tr:hover { background: var(--superficie-2); }
.tabla .numero { text-align: right; font-variant-numeric: tabular-nums; }
.tabla .acciones { display: flex; gap: .35rem; justify-content: flex-end; }
.tabla td.encoge { width: 1%; white-space: nowrap; }

/* --- Insignias --- */

.insignia {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .16rem .5rem;
    border-radius: var(--radio-max);
    border: 1px solid transparent;
    font-size: .75rem;
    font-weight: 650;
    line-height: 1.45;
    white-space: nowrap;
}
.insignia.neutra  { background: var(--superficie-3); color: var(--texto-suave); border-color: var(--borde); }
.insignia.acento  { background: var(--acento-suave);  color: var(--acento);  border-color: var(--acento-borde); }
.insignia.exito   { background: var(--exito-suave);   color: var(--exito);   border-color: var(--exito-borde); }
.insignia.peligro { background: var(--peligro-suave); color: var(--peligro); border-color: var(--peligro-borde); }
.insignia.aviso   { background: var(--aviso-suave);   color: var(--aviso);   border-color: var(--aviso-borde); }
.insignia.info    { background: var(--info-suave);    color: var(--info);    border-color: var(--info-borde); }

.punto-estado {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

/* --- Avisos --- */

.aviso-caja {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    padding: .8rem .95rem;
    border: 1px solid var(--borde);
    border-left-width: 3px;
    border-radius: var(--radio-sm);
    background: var(--superficie);
    font-size: .89rem;
    margin-bottom: 1rem;
}
.aviso-caja .icono { flex: 0 0 auto; font-size: 1rem; line-height: 1.35; }
.aviso-caja.exito   { background: var(--exito-suave);   border-color: var(--exito-borde);   border-left-color: var(--exito);   color: var(--exito); }
.aviso-caja.error   { background: var(--peligro-suave); border-color: var(--peligro-borde); border-left-color: var(--peligro); color: var(--peligro); }
.aviso-caja.aviso   { background: var(--aviso-suave);   border-color: var(--aviso-borde);   border-left-color: var(--aviso);   color: var(--aviso); }
.aviso-caja.info    { background: var(--info-suave);    border-color: var(--info-borde);    border-left-color: var(--info);    color: var(--info); }
.aviso-caja strong { font-weight: 700; }

/* Pila de avisos flotantes */
.avisos {
    position: fixed;
    top: calc(var(--cabecera) + .6rem);
    right: 1rem;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    width: min(380px, calc(100vw - 2rem));
}
.avisos .aviso-caja {
    margin: 0;
    box-shadow: var(--sombra-3);
    animation: entrar-derecha 200ms cubic-bezier(.4, 0, .2, 1);
}
@keyframes entrar-derecha {
    from { opacity: 0; transform: translateX(12px); }
    to   { opacity: 1; transform: none; }
}

/* --- Diálogos --- */

.dialogo-velo {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgb(8 12 18 / .55);
    backdrop-filter: blur(3px);
    animation: aparecer 140ms ease;
}

.dialogo {
    width: min(560px, 100%);
    max-height: calc(100dvh - 2rem);
    display: flex;
    flex-direction: column;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio-lg);
    box-shadow: var(--sombra-3);
    animation: subir 180ms cubic-bezier(.4, 0, .2, 1);
}
.dialogo.ancho { width: min(760px, 100%); }
@keyframes subir {
    from { opacity: 0; transform: translateY(10px) scale(.99); }
    to   { opacity: 1; transform: none; }
}

.dialogo-cabecera {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: 1rem 1.2rem;
    border-bottom: 1px solid var(--borde);
}
.dialogo-cabecera h3 { margin: 0; font-size: 1.02rem; }
.dialogo-cuerpo { padding: 1.2rem; overflow-y: auto; }
.dialogo-pie {
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
    padding: .9rem 1.2rem;
    border-top: 1px solid var(--borde);
    background: var(--superficie-2);
}

/* --- Estado vacío --- */

.vacio {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .4rem;
    padding: 3rem 1.5rem;
    text-align: center;
    color: var(--texto-suave);
}
.vacio-icono { font-size: 2rem; opacity: .5; }
.vacio-titulo { font-weight: 600; color: var(--texto); }
.vacio p { font-size: .89rem; max-width: 46ch; }

/* --- Pestañas --- */

.pestanas {
    display: flex;
    gap: .25rem;
    margin-bottom: 1.25rem;
    padding-bottom: 2px;
    overflow-x: auto;
    border-bottom: 1px solid var(--borde);
    scrollbar-width: none;
}
.pestanas::-webkit-scrollbar { display: none; }

.pestana {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .55rem .85rem;
    border: 0;
    background: none;
    color: var(--texto-suave);
    font: inherit;
    font-size: .89rem;
    font-weight: 550;
    white-space: nowrap;
    text-decoration: none;
    border-radius: var(--radio-sm) var(--radio-sm) 0 0;
    transition: color var(--transicion), background var(--transicion);
}
.pestana:hover { color: var(--texto); background: var(--superficie-2); text-decoration: none; }

.pestana.activa { color: var(--acento); }
.pestana.activa::after {
    content: "";
    position: absolute;
    left: .35rem;
    right: .35rem;
    bottom: -1px;
    height: 2px;
    border-radius: 2px 2px 0 0;
    background: var(--acento);
}

.pestana-cuenta {
    min-width: 1.4rem;
    padding: 0 .35rem;
    display: inline-grid;
    place-items: center;
    border-radius: var(--radio-max);
    background: var(--superficie-3);
    color: var(--texto-suave);
    font-size: .72rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.pestana.activa .pestana-cuenta { background: var(--acento-suave); color: var(--acento); }

/*
 * Pestañas en pastilla.
 *
 * La otra variante, la del subrayado, sirve para filtrar una misma lista. Esta
 * es para cambiar de apartado entero, donde conviene que se lea como un grupo
 * de botones y no como un filtro.
 */
.pestanas-cajas {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-bottom: 1.25rem;
}

.pestana-caja {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .5rem .9rem;
    border: 1px solid transparent;
    border-radius: var(--radio);
    background: var(--superficie-2);
    color: var(--texto-suave);
    font: inherit;
    font-size: .89rem;
    font-weight: 550;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--transicion), color var(--transicion);
}
.pestana-caja:hover { background: var(--superficie-3); color: var(--texto); }

.pestana-caja.activa {
    background: var(--texto);
    border-color: var(--texto);
    color: var(--fondo);
}
.pestana-caja.activa:hover { background: var(--texto); color: var(--fondo); }

/* Señal de que ese apartado está configurado y funcionando. */
.pestana-caja .punto-estado { width: 7px; height: 7px; }

@media (max-width: 34rem) {
    /* En pantalla estrecha, una rejilla en vez de una fila que se desborda. */
    .pestanas-cajas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .pestana-caja { justify-content: center; }
}

/* --- Barra de búsqueda y filtros --- */

.filtros {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .55rem;
    margin-bottom: 1rem;
}
.buscador { position: relative; flex: 1 1 240px; min-width: 0; }
.buscador .control { padding-left: 2.1rem; }
.buscador-icono {
    position: absolute;
    left: .7rem;
    top: 50%;
    translate: 0 -50%;
    color: var(--texto-tenue);
    font-size: .9rem;
    pointer-events: none;
}

/* --- Página de acceso: escena de cristal --- */

.acceso {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 1.5rem;
    overflow: hidden;
    background:
        radial-gradient(1200px 640px at 18% -8%,  #cfd9ff 0%, transparent 58%),
        radial-gradient(1000px 560px at 88% 12%,  #d9ccff 0%, transparent 56%),
        radial-gradient(900px 620px at 60% 108%,  #c7e9ff 0%, transparent 58%),
        #eef1f9;
}
[data-tema="oscuro"] .acceso {
    background:
        radial-gradient(1200px 640px at 18% -8%,  #1c2450 0%, transparent 58%),
        radial-gradient(1000px 560px at 88% 12%,  #2a1f4d 0%, transparent 56%),
        radial-gradient(900px 620px at 60% 108%,  #10314a 0%, transparent 58%),
        #080b12;
}

/* Manchas de color que se desplazan despacio por detrás del cristal. */
.acceso-fondo {
    position: absolute;
    inset: -20%;
    z-index: 0;
    pointer-events: none;
    filter: blur(60px);
}
.acceso-mancha {
    position: absolute;
    border-radius: 50%;
    opacity: .55;
    mix-blend-mode: multiply;
    animation: flotar 22s ease-in-out infinite;
}
/* En oscuro el modo «screen» aclara: hace falta más opacidad para que se vean. */
[data-tema="oscuro"] .acceso-mancha { mix-blend-mode: screen; opacity: .55; }

.acceso-mancha.a { width: 42vmax; height: 42vmax; left:  4%; top:  2%; background: #6d8bff; }
.acceso-mancha.b { width: 34vmax; height: 34vmax; right: 6%; top: 12%; background: #b98cff; animation-delay: -7s;  animation-duration: 26s; }
.acceso-mancha.c { width: 38vmax; height: 38vmax; left:  30%; bottom: -6%; background: #5fd0f0; animation-delay: -14s; animation-duration: 30s; }

@keyframes flotar {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33%      { transform: translate(6%, -5%) scale(1.08); }
    66%      { transform: translate(-5%, 4%) scale(.95); }
}

.acceso-caja {
    position: relative;
    z-index: 1;
    width: min(420px, 100%);
}

.acceso-marca {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
    margin: 1.75rem 0 1.5rem;   /* aire entre el robot y la marca */
    text-align: center;
}
.acceso-marca h1 {
    margin: 0;
    font-family: var(--fuente-display);
    font-size: 1.15rem;
    font-weight: 500;
    letter-spacing: .01em;
    color: var(--texto-suave);
}
.acceso-marca p {
    margin: 0;
    font-size: .86rem;
    color: var(--texto-tenue);
    min-height: 1.3em;          /* el texto cambia y no debe saltar el bloque */
}

/*
 * Cristal líquido: fondo translúcido con desenfoque de lo que hay detrás, un
 * filo claro arriba y sombra difusa. El borde se dibuja con un degradado
 * enmascarado para que el brillo recorra solo el canto superior.
 */
.cristal {
    position: relative;
    border-radius: 22px;
    background: linear-gradient(160deg,
                rgb(255 255 255 / .72),
                rgb(255 255 255 / .42));
    backdrop-filter: blur(22px) saturate(180%);
    -webkit-backdrop-filter: blur(22px) saturate(180%);
    box-shadow:
        0 20px 60px rgb(20 28 60 / .16),
        0 2px 10px  rgb(20 28 60 / .06),
        inset 0 1px 0 rgb(255 255 255 / .85);
    border: 1px solid rgb(255 255 255 / .6);
    overflow: hidden;
}
[data-tema="oscuro"] .cristal {
    background: linear-gradient(160deg,
                rgb(30 38 56 / .72),
                rgb(16 22 34 / .55));
    border-color: rgb(255 255 255 / .1);
    box-shadow:
        0 20px 60px rgb(0 0 0 / .55),
        inset 0 1px 0 rgb(255 255 255 / .12);
}

/* Reflejo que cruza el cristal en diagonal. */
.cristal::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(115deg,
                transparent 30%,
                rgb(255 255 255 / .28) 45%,
                transparent 58%);
}
[data-tema="oscuro"] .cristal::after {
    background: linear-gradient(115deg,
                transparent 32%,
                rgb(255 255 255 / .07) 46%,
                transparent 58%);
}

.cristal-cuerpo { position: relative; z-index: 1; padding: 1.5rem 1.4rem; }
.cristal-pie {
    position: relative;
    z-index: 1;
    padding: .9rem 1.4rem;
    text-align: center;
    border-top: 1px solid rgb(255 255 255 / .45);
    background: rgb(255 255 255 / .25);
}
[data-tema="oscuro"] .cristal-pie {
    border-top-color: rgb(255 255 255 / .08);
    background: rgb(255 255 255 / .04);
}

/* Los campos dentro del cristal también son translúcidos. */
.cristal .control {
    background: rgb(255 255 255 / .6);
    border-color: rgb(255 255 255 / .7);
    backdrop-filter: blur(6px);
}
.cristal .control:hover { border-color: rgb(255 255 255 / .95); }
.cristal .control:focus { background: rgb(255 255 255 / .85); border-color: var(--acento); }
[data-tema="oscuro"] .cristal .control {
    background: rgb(255 255 255 / .06);
    border-color: rgb(255 255 255 / .12);
}
[data-tema="oscuro"] .cristal .control:focus { background: rgb(255 255 255 / .1); }

/* --- Campo de contraseña con botón para mostrarla --- */

.campo-clave { position: relative; }
.campo-clave .control { padding-right: 2.9rem; }

.ojo {
    position: absolute;
    right: .35rem;
    top: 50%;
    translate: 0 -50%;
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: var(--radio-sm);
    background: transparent;
    color: var(--texto-suave);
    font-size: 1rem;
    cursor: pointer;
    transition: background var(--transicion), color var(--transicion);
}
.ojo:hover { background: rgb(0 0 0 / .06); color: var(--texto); }
[data-tema="oscuro"] .ojo:hover { background: rgb(255 255 255 / .1); }

/* --- Robot --- */

.robot {
    --robot-claro: #eef2ff;
    --robot-oscuro: #b9c4e8;

    display: block;
    width: min(210px, 56vw);
    height: auto;
    margin: 0 auto;
    filter: drop-shadow(0 14px 26px rgb(28 38 78 / .22));
}
[data-tema="oscuro"] .robot {
    --robot-claro: #47527a;
    --robot-oscuro: #2b3350;
    filter: drop-shadow(0 14px 26px rgb(0 0 0 / .5));
}

.robot-cabeza {
    transform: rotate(var(--giro, 0deg));
    transform-origin: 120px 150px;
    transition: transform 320ms cubic-bezier(.34, 1.3, .64, 1);
}

.robot-antena {
    fill: var(--acento);
    animation: latir 2.6s ease-in-out infinite;
}
@keyframes latir {
    0%, 100% { opacity: 1;   r: 7; }
    50%      { opacity: .55; r: 6; }
}

.robot-ojos {
    transform: translate(var(--ojo-x, 0), var(--ojo-y, 0));
    transition: transform 110ms ease-out;
}

/* Parpadeo: el ojo entero se aplasta un instante. */
.robot-ojo {
    transform-box: fill-box;
    transform-origin: center;
    animation: parpadear 6.5s infinite;
}
.robot-ojo:last-child { animation-delay: .06s; }
@keyframes parpadear {
    0%, 92%, 100% { transform: scaleY(1); }
    95%           { transform: scaleY(.08); }
}

.robot-moflete { fill: var(--acento); opacity: .22; }

.robot-boca { transition: d 260ms ease; }

.robot-mano {
    transition: transform 420ms cubic-bezier(.34, 1.28, .64, 1);
}

/* En reposo las manos descansan abajo, fuera de la cara. */
.robot-mano-izq { transform: translate(6px, 14px) rotate(-8deg); }
.robot-mano-der { transform: translate(-6px, 14px) rotate(8deg); }
.robot-mano { transform-box: fill-box; transform-origin: center; }

/* Al taparse suben a cubrir el visor. */
.robot.tapandose .robot-mano-izq { transform: translate(38px, -64px) rotate(-16deg); }
.robot.tapandose .robot-mano-der { transform: translate(-38px, -64px) rotate(16deg); }

/* Y la sonrisa se ensancha, que es lo que hace la cara al esconderse. */
.robot.tapandose .robot-boca { d: path("M104 128 Q120 141 136 128"); }

@media (prefers-reduced-motion: reduce) {
    .acceso-mancha, .robot-antena, .robot-ojo { animation: none; }
}

/* --- Barra de progreso --- */

.progreso {
    height: 7px;
    border-radius: var(--radio-max);
    background: var(--superficie-3);
    overflow: hidden;
}
.progreso-relleno {
    height: 100%;
    border-radius: inherit;
    background: var(--acento);
    transition: width var(--transicion);
}

/* --- Lista de descripción --- */

.datos { display: grid; gap: .7rem; }
.datos-fila { display: grid; grid-template-columns: minmax(120px, 34%) 1fr; gap: .75rem; }
.datos-clave { font-size: .82rem; color: var(--texto-suave); }
.datos-valor { font-size: .9rem; }
@media (max-width: 520px) {
    .datos-fila { grid-template-columns: 1fr; gap: .1rem; }
}

/* --- Página pública de firma --- */

/*
 * La abre el empleado desde el correo, casi siempre en el móvil y sin haber
 * iniciado sesión. Va sin barra lateral y con una columna estrecha.
 */
.firma-pagina {
    min-height: 100vh;
    min-height: 100dvh;
    padding: 1.5rem 1rem 3rem;
    background:
        radial-gradient(900px 420px at 50% -10%, var(--acento-suave), transparent 60%),
        var(--fondo);
}

.firma-caja { width: min(720px, 100%); margin-inline: auto; }

.firma-marca {
    display: flex;
    justify-content: center;
    margin-bottom: 1.5rem;
}

.lienzo-firma {
    display: block;
    width: 100%;
    border: 2px dashed var(--borde-fuerte);
    border-radius: var(--radio-sm);
    background: #ffffff;
    cursor: crosshair;
    touch-action: none;   /* el dedo dibuja, no desplaza la página */
}
.lienzo-firma.firmado { border-style: solid; border-color: var(--exito); }

@media (pointer: coarse) { .lienzo-firma { cursor: default; } }

/* --- Documento imprimible --- */

/*
 * El acta se pinta siempre sobre papel blanco con tinta negra, también en tema
 * oscuro: es un documento que se firma y se imprime, y debe salir igual en los
 * dos casos.
 */
.documento {
    position: relative;
    background: #fff;
    color: #14181d;
    padding: 2.5rem;
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: var(--sombra-2);
}
.documento h1 { font-size: 1.2rem; margin-bottom: .25rem; }
.documento h2 { font-size: .95rem; margin-bottom: .6rem; }
.documento a  { color: #14181d; }

/*
 * Membrete. Va dentro del documento para que salga también al imprimir: todo
 * lo que está fuera del `article` lleva `no-imprimir` y desaparece.
 *
 * El margen derecho deja libre la esquina donde va el sello de estado.
 */
.documento-membrete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin: 0 9rem 1.6rem 0;
    padding-bottom: .9rem;
    border-bottom: 2px solid #e5e7eb;
}
.documento-membrete img {
    display: block;
    height: 34px;
    width: auto;
    /* Que el navegador no lo aclare al imprimir: es la marca. */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
}
.documento-membrete-ref {
    font-family: var(--mono, ui-monospace, monospace);
    font-size: .8rem;
    color: #5c6672;
}

@media (max-width: 30rem) {
    /* En pantalla estrecha el sello se queda arriba del todo y el membrete
       puede ocupar el ancho completo. */
    .documento-membrete { margin-right: 0; }
    .documento-membrete img { height: 26px; }
}

.documento-sello {
    position: absolute;
    top: 1.6rem;
    right: 2rem;
    padding: .3rem .8rem;
    border: 3px solid currentColor;
    border-radius: var(--radio-sm);
    font-weight: 800;
    font-size: .82rem;
    letter-spacing: .04em;
    rotate: -8deg;
}
.documento-sello.firmada  { color: #17803d; }
.documento-sello.anulada  { color: #c62b2b; }
.documento-sello.pendiente{ color: #a15c07; }

.documento-datos { width: 100%; max-width: 520px; margin-bottom: 1.5rem; border-collapse: collapse; }
.documento-datos th,
.documento-datos td { padding: .3rem 0; text-align: left; font-size: .89rem; vertical-align: top; }
.documento-datos th { width: 38%; font-weight: 600; color: #5c6672; }

.documento-tabla { width: 100%; border-collapse: collapse; margin-bottom: 1.5rem; font-size: .87rem; }
.documento-tabla th,
.documento-tabla td { padding: .45rem .6rem; border: 1px solid #d6dae0; text-align: left; }
.documento-tabla thead th { background: #f3f4f6; font-weight: 650; }

.documento-firma { margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid #d6dae0; }
.documento-linea { height: 90px; max-width: 320px; border-bottom: 1px solid #999; }

@media (max-width: 600px) {
    .documento { padding: 1.4rem; }
    .documento-sello { position: static; display: inline-block; rotate: none; margin-bottom: 1rem; }
}

@media print {
    /* Fuera todo lo que es interfaz: solo se imprime el documento. */
    .lateral, .cabecera, .avisos, .velo, .no-imprimir { display: none !important; }
    .principal, .app.fijada .principal { margin-left: 0 !important; }
    .contenido { padding: 0 !important; max-width: none !important; }
    .documento { border: 0; box-shadow: none; padding: 0; }
    body { background: #fff; }
    a[href]::after { content: ""; }

    /* El logotipo y el sello de estado salen en color: sin esto muchos
       navegadores los imprimen en gris para ahorrar tinta. */
    .documento,
    .documento-membrete img,
    .documento-sello {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
}

/* --------------------------------------------------------- 5. Utilidades */

.pila     { display: flex; flex-direction: column; }
.fila     { display: flex; align-items: center; }
.fila-arriba { display: flex; align-items: flex-start; }
.entre    { justify-content: space-between; }
.centro   { justify-content: center; }
.derecha  { justify-content: flex-end; }
.envolver { flex-wrap: wrap; }
.crece    { flex: 1 1 auto; min-width: 0; }
.auto-izq { margin-left: auto; }

.g-1 { gap: .25rem; } .g-2 { gap: .5rem; } .g-3 { gap: .75rem; }
.g-4 { gap: 1rem; }   .g-5 { gap: 1.5rem; }

.mt-0{margin-top:0}    .mt-1{margin-top:.25rem} .mt-2{margin-top:.5rem}
.mt-3{margin-top:.75rem} .mt-4{margin-top:1rem} .mt-5{margin-top:1.5rem}
.mb-0{margin-bottom:0} .mb-1{margin-bottom:.25rem} .mb-2{margin-bottom:.5rem}
.mb-3{margin-bottom:.75rem} .mb-4{margin-bottom:1rem} .mb-5{margin-bottom:1.5rem}

.texto-suave { color: var(--texto-suave); }
.texto-tenue { color: var(--texto-tenue); }
.texto-peligro { color: var(--peligro); }
.texto-exito   { color: var(--exito); }
.texto-aviso   { color: var(--aviso); }
.texto-acento  { color: var(--acento); }
.sm  { font-size: .82rem; }
.xs  { font-size: .76rem; }
.fuerte { font-weight: 650; }
.mono { font-family: var(--mono); font-size: .85em; }
.cifra { font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }
.centrado { text-align: center; }
.truncar { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ancho-total { width: 100%; }

@media (max-width: 700px) { .ocultar-movil { display: none !important; } }

/* -------------------------------------------- Repaso final de responsive */

/*
 * Tablas: por debajo de cierto ancho no caben ni ocultando columnas, asi que
 * se dejan desplazar en horizontal dentro de su caja —nunca el documento— y se
 * reduce el relleno para ganar sitio real.
 */
@media (max-width: 700px) {
    .tabla th, .tabla td { padding: .55rem .6rem; }
    .tabla { font-size: .85rem; }

    /* Las acciones de una fila se apilan en vez de desbordar la celda. */
    .tabla .acciones { flex-wrap: wrap; justify-content: flex-start; }
    .tabla td.encoge { white-space: normal; }
}

/* La cabecera de pagina: titulo y botones dejan de competir por la linea. */
@media (max-width: 620px) {
    .contenido h1 { font-size: 1.32rem; }
    .contenido h2 { font-size: 1.12rem; }

    /* Los botones de una cabecera ocupan el ancho, que es mas facil de pulsar. */
    .cabecera-acciones .btn:not(.btn-icono) { padding-inline: .7rem; }
}

@media (max-width: 520px) {
    /* Filtros y buscadores, uno por linea. */
    .filtros { flex-direction: column; align-items: stretch; }
    .filtros > .btn, .filtros > .control { width: 100%; }
    .buscador { flex: 1 1 auto; width: 100%; }

    /* Los dialogos ocupan casi toda la pantalla, sin bordes redondeados
       enormes que roben espacio al contenido. */
    .dialogo-velo { padding: .5rem; }
    .dialogo { border-radius: var(--radio); max-height: calc(100dvh - 1rem); }
    .dialogo-cuerpo { padding: 1rem; }
    .dialogo-pie { padding: .8rem 1rem; flex-wrap: wrap; }
    .dialogo-pie > .btn { flex: 1 1 auto; }

    /* Dos columnas no caben: todo a una. */
    .rejilla-2, .rejilla-3, .rejilla-4, .rejilla-tarjetas { grid-template-columns: 1fr; }

    /* Los avisos flotantes, a lo ancho y sin tapar la cabecera. */
    .avisos { left: .5rem; right: .5rem; width: auto; }
}

/* Ninguna pantalla debe provocar desplazamiento horizontal del documento. */
body { overflow-x: hidden; }
.contenido, .tarjeta, .tarjeta-cuerpo { min-width: 0; }

/* Solo para lectores de pantalla */
.solo-lectores {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}
