/*
 * OneIoT se ve como lo que es: un tablero.
 *
 * La hoja se escribe entera desde el principio en vez de copiarse de OneAccount
 * o de GastroSquad. Es la misma decisión que se tomó allá y por el mismo motivo:
 * en GastroSquad ocho pantallas nacieron copiando el CSS de su vecina y
 * acabaron con cuatro anchos distintos para la misma tarjeta.
 *
 * Tres zonas con la misma piel y distinta densidad: el sitio público respira,
 * el panel del cliente aprovecha el ancho, y `/admin` es una tabla detrás de
 * otra. La clase va en el `body` (`zona-website`, `zona-dashboard`, `zona-admin`).
 */

:root {
    color-scheme: light dark;

    --tinta: #0f172a;
    --tinta-suave: #64748b;
    --fondo: #f8fafc;
    --papel: #ffffff;
    --borde: #e2e8f0;
    --acento: #0f766e;
    --acento-claro: #ccfbf1;
    /* El texto SOBRE el acento. Blanco en claro; en oscuro el acento es un turquesa
       luminoso y el blanco encima se lee a 1,9:1 — ahí va casi negro. */
    --sobre-acento: #ffffff;
    --bueno: #16a34a;
    --malo: #dc2626;
    --atencion: #d97706;
    --sombra: 0 1px 2px rgba(15, 23, 42, .04), 0 12px 32px rgba(15, 23, 42, .07);
    --radio: 14px;
    /* Los bloques de una automatización, con los colores de MacroDroid en versión
       fina (`_dev_docs/34` §6): Cuando, Solo si, Entonces, las ramas y Si algo falla. */
    --auto-cuando: #e11d48;
    --auto-solo-si: #059669;
    --auto-entonces: #2563eb;
    --auto-si: #7c3aed;
    --auto-falla: #d97706;
}

/*
 * EL TEMA TIENE TRES ESTADOS, NO DOS.
 *
 *   sin elegir  →  manda el sistema (`prefers-color-scheme`)
 *   claro       →  claro aunque el sistema esté en oscuro
 *   oscuro      →  oscuro aunque el sistema esté en claro
 *
 * Por eso el bloque del sistema lleva `:not([data-tema="claro"])` y hay uno
 * aparte para la elección explícita. Con solo la consulta de medios, el
 * interruptor no podría ganarle al sistema en una de las dos direcciones — y un
 * interruptor que a veces no hace nada es peor que no tenerlo.
 *
 * `data-tema` lo pone un guion en el `<head>` ANTES de pintar. Si se pusiera al
 * final, la pantalla daría un fogonazo blanco en cada carga para quien lo tiene
 * en oscuro.
 */
@media (prefers-color-scheme: dark) {
    :root:not([data-tema="claro"]) {
        --tinta: #e2e8f0;
        --tinta-suave: #94a3b8;
        --fondo: #0b1120;
        --papel: #111827;
        --borde: #1f2937;
        --acento: #2dd4bf;
        --acento-claro: #134e4a;
        --sobre-acento: #042f2e;
        --sombra: 0 1px 2px rgba(0, 0, 0, .3), 0 12px 32px rgba(0, 0, 0, .45);
        --auto-cuando: #fb7185;
        --auto-solo-si: #34d399;
        --auto-entonces: #60a5fa;
        --auto-si: #a78bfa;
        --auto-falla: #fbbf24;
    }
}

:root[data-tema="oscuro"] {
    color-scheme: dark;
    --tinta: #e2e8f0;
    --tinta-suave: #94a3b8;
    --fondo: #0b1120;
    --papel: #111827;
    --borde: #1f2937;
    --acento: #2dd4bf;
    --acento-claro: #134e4a;
    --sobre-acento: #042f2e;
    --sombra: 0 1px 2px rgba(0, 0, 0, .3), 0 12px 32px rgba(0, 0, 0, .45);
    --auto-cuando: #fb7185;
    --auto-solo-si: #34d399;
    --auto-entonces: #60a5fa;
    --auto-si: #a78bfa;
    --auto-falla: #fbbf24;
}

:root[data-tema="claro"] { color-scheme: light; }

/*
 * LO PRIMERO, Y NO ES ESTÉTICA: QUE `hidden` OCULTE.
 *
 * El navegador trae `[hidden] { display: none }`, pero es una regla de baja
 * especificidad: cualquier `.mi-caja { display: flex }` **la gana**, y el
 * elemento se queda a la vista con el atributo puesto.
 *
 * Esto ya rompió cuatro cosas en la app —el aviso rojo de «sin conexión»
 * permanente, el de versión nueva siempre encendido, el teclado del PIN abierto
 * sobre la pantalla de pared y la caja de foto vacía— y se arregló ahí. Y volvió
 * a morder en la tienda: la galería enseñaba **todas las fotos a la vez**, porque
 * la regla estaba en `app.css` y la zona pública **no carga `app.css`**.
 *
 * Por eso vive aquí, en la hoja que carga todo el mundo. Arreglar una regla
 * general en la hoja de una zona es arreglarla para esa zona y dejarla rota en
 * las otras tres.
 *
 * `!important` a conciencia: es la única forma de que una regla de un atributo
 * le gane a una de clase, y `hidden` significa oculto o no significa nada.
 */
[hidden] { display: none !important; }

* { box-sizing: border-box; }

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
    background: var(--fondo);
    color: var(--tinta);
    line-height: 1.6;
}

h1, h2, h3 { font-family: Outfit, Inter, system-ui, sans-serif; line-height: 1.2; margin: 0 0 .5rem; }
h1 { font-size: 1.9rem; }
h2 { font-size: 1.35rem; margin-top: 0; }
h3 { font-size: 1.05rem; }
/*
 * LOS ENLACES NO SE SUBRAYAN AL PASAR EL RATÓN.
 *
 * El subrayado del navegador es de 1970 y aquí hace daño de verdad: en este
 * producto casi todo lo que se toca es un `<a>` —la tarjeta de un sitio, el
 * botón «Añadir», una fila de equipo—, y verlos subrayarse uno a uno al pasar
 * por encima hace que una pantalla se vea improvisada por muy bien que funcione
 * lo de abajo.
 *
 * Lo que se pierde con esto es la señal de «esto es un enlace» para quien no
 * distingue el color. Se devuelve de otra forma: lo que se pulsa tiene forma de
 * botón, y lo que es enlace de texto cambia de color y de fondo al pasar — que
 * es una señal más, no una menos.
 */
a { color: var(--acento); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: none; }
code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .9em; }
pre { background: var(--fondo); border: 1px solid var(--borde); border-radius: 8px; padding: .75rem; overflow-x: auto; font-size: .8rem; }

/* ── La barra ─────────────────────────────────────────────────────────── */
.barra {
    display: flex; align-items: center; gap: 1.5rem;
    padding: .85rem 1.5rem;
    background: var(--papel);
    border-bottom: 1px solid var(--borde);
    position: sticky; top: 0; z-index: 20;
}
.marca { display: flex; align-items: center; gap: .5rem; font-family: Outfit, sans-serif; font-weight: 800; color: var(--tinta); }
.marca:hover { text-decoration: none; }
.marca-icono { font-size: 1.2rem; }
.barra-plegable { flex: 1; display: flex; align-items: center; gap: 1rem; min-width: 0; }
.barra-nav { display: flex; gap: .25rem .85rem; flex-wrap: wrap; font-size: .92rem; }
.barra-acciones { flex: none; }
.barra-nav a { color: var(--tinta-suave); padding: .2rem 0; border-bottom: 2px solid transparent; }
.barra-nav a:hover { color: var(--acento); text-decoration: none; }
/* Dónde se está, sin que haya que leer la dirección. */
.barra-nav a[aria-current="page"] { color: var(--tinta); border-bottom-color: var(--acento); }
.barra-acciones { margin-left: auto; display: flex; align-items: center; gap: .75rem; }
.barra .conexion { order: 3; }
.barra-menu { display: none; }

/*
 * EL «?» DE ESTA PANTALLA. Un círculo de 36 px que se toca como uno de 44: el
 * `::before` agranda el área de toque sin agrandar el dibujo. Va el último en la
 * barra del ordenador y junto al «Menú» en el teléfono.
 */
.boton-ayuda {
    order: 4; flex: none; position: relative;
    display: inline-grid; place-items: center;
    width: 2.25rem; height: 2.25rem; border-radius: 50%;
    border: 1px solid var(--borde); background: var(--papel); color: var(--tinta-suave);
    transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.boton-ayuda::before { content: ""; position: absolute; inset: -4px; border-radius: 50%; }
.boton-ayuda svg { width: 1.25rem; height: 1.25rem; }
.boton-ayuda:hover { color: var(--acento); border-color: var(--acento); background: color-mix(in srgb, var(--acento) 8%, var(--papel)); text-decoration: none; }
.boton-ayuda:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }

/*
 * El punto de la conexión. Está en la barra y no escondido en una esquina
 * porque es la única diferencia visible entre «no está pasando nada» y «esta
 * pantalla dejó de recibir hace diez minutos».
 */
.boton-barra { padding: .45rem .85rem; font-size: .85rem; white-space: nowrap; }
/* Donde ya estás no vuelve a pedir el clic: se apaga y deja de parecer una
   invitación. */
.boton-barra[aria-current="page"] { opacity: .55; pointer-events: none; }

.conexion { display: inline-flex; align-items: center; gap: .4rem; font-size: .78rem; color: var(--tinta-suave); }
.conexion .punto { width: .55rem; height: .55rem; border-radius: 50%; background: var(--tinta-suave); }
.conexion-conectado .punto { background: var(--bueno); box-shadow: 0 0 0 3px color-mix(in srgb, var(--bueno) 20%, transparent); }
.conexion-sospechoso .punto { background: var(--atencion); }
.conexion-caido .punto, .conexion-sin-sesion .punto { background: var(--malo); }

/* ── El marco ─────────────────────────────────────────────────────────── */
.marco { flex: 1; width: 100%; max-width: 78rem; margin: 0 auto; padding: 2rem 1.25rem 3rem; }
.zona-website .marco { max-width: 68rem; }
.marco-centrado { display: grid; place-items: center; min-height: 60vh; }
.marco-centrado .tarjeta { max-width: 32rem; }
.bloque { margin-top: 2.5rem; }
.centrado { text-align: center; }
.derecha { text-align: right; }
.apagado { color: var(--tinta-suave); }
/* EN LA HOJA COMÚN Y NO EN `app.css`, QUE ES DONDE ESTABA.
   Veinte vistas de `/admin` escriben `p.apagado.pequeno`, y `/admin` **no carga
   `app.css`** —solo lo hace el panel—. Así que en todo el panel del staff esa
   clase no hacía nada y esos textos salían del tamaño normal. Es el mismo caso
   que `[hidden]`: una regla en la hoja que no carga la zona que la usa. */
.pequeno { font-size: .78rem; }
.malo { color: var(--malo); font-weight: 600; }
.entrada { font-size: 1.05rem; color: var(--tinta-suave); max-width: 46rem; }
.antetitulo { text-transform: uppercase; letter-spacing: .08em; font-size: .75rem; color: var(--acento); font-weight: 600; margin: 0; }
.cabecera-pagina { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }

/* ── Piezas ───────────────────────────────────────────────────────────── */
.tarjeta { background: var(--papel); border: 1px solid var(--borde); border-radius: var(--radio); padding: 1.25rem; box-shadow: var(--sombra); }
.tarjeta-ancha { grid-column: 1 / -1; }
.tarjeta-enlace { display: block; color: inherit; }
.tarjeta-enlace:hover { text-decoration: none; border-color: var(--acento); }
.tarjeta-mala { border-color: var(--malo); }
.tarjeta-error { text-align: center; }
.codigo { font-family: Outfit, sans-serif; font-size: 3rem; font-weight: 800; color: var(--tinta-suave); margin: 0; }
.vacio { text-align: center; padding: 3rem 1rem; color: var(--tinta-suave); border: 1px dashed var(--borde); border-radius: var(--radio); }

.rejilla-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1.25rem; }
.rejilla-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1.25rem; }
.rejilla-pareja { align-items: stretch; }
.rejilla-cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.rejilla-metricas { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 1rem; }

.cifra { text-align: center; }
.cifra-numero { display: block; font-family: Outfit, sans-serif; font-size: 2rem; font-weight: 800; }
.cifra-etiqueta { font-size: .8rem; color: var(--tinta-suave); }
.cifra-mala .cifra-numero { color: var(--malo); }
.cifra-atencion .cifra-numero { color: var(--atencion); }

/* La tarjeta de un equipo se retiró el 15/10/2026: ahora es una fila (`_fila-equipo.pug`, al final de esta hoja). */

.metrica { display: flex; flex-direction: column; }
.metrica-valor { font-family: Outfit, sans-serif; font-size: 1.6rem; font-weight: 700; line-height: 1; }
.metrica-unidad { font-size: .8rem; color: var(--tinta-suave); }
.metrica-etiqueta { font-size: .72rem; color: var(--tinta-suave); }
.metrica-grande { text-align: center; }
.metrica-grande .metrica-valor { font-size: 2.2rem; display: block; margin: .25rem 0; }

.punto { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%; background: var(--tinta-suave); flex: none; }
.punto.en-linea {
    background: var(--bueno);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--bueno) 20%, transparent);
    animation: latido-vivo 2.6s ease-in-out infinite;
}
/* Late el halo, no el punto: agrandar el punto mueve el texto de al lado en las
   tarjetas donde comparte renglón, y un renglón que se mueve se lee como un
   fallo de dibujo. */
@keyframes latido-vivo {
    0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--bueno) 20%, transparent); }
    50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--bueno) 6%, transparent); }
}
.punto.callado { background: var(--tinta-suave); }

.grafica { width: 100%; height: 220px; background: var(--papel); border: 1px solid var(--borde); border-radius: var(--radio); }
.grafica[hidden] { display: none; }
/* Las pastillas que eligen qué medida enseña la gráfica: 44 px de toque. */
.pastillas { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 .6rem; }
.pastilla { min-height: 44px; padding: .4rem .9rem; border-radius: 999px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta-suave); font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer; }
.pastilla[aria-pressed="true"] { border-color: var(--acento); color: var(--acento); background: color-mix(in srgb, var(--acento) 10%, var(--papel)); }
.pastilla:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }

/* ── Formularios ──────────────────────────────────────────────────────── */
label { display: block; font-size: .85rem; color: var(--tinta-suave); margin-bottom: .75rem; }
input, select, textarea {
    width: 100%; margin-top: .25rem; padding: .55rem .7rem;
    border: 1px solid var(--borde); border-radius: 9px;
    background: var(--fondo); color: var(--tinta);
    font: inherit; font-size: .92rem;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--acento); outline-offset: 1px; }
textarea { font-family: ui-monospace, Menlo, monospace; font-size: .82rem; }
.campos { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0 1rem; }
.formulario-linea { display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap; margin-top: .75rem; }
.formulario-linea label { margin-bottom: 0; }
.linea-cantidad { display: flex; align-items: center; gap: .5rem; }
.linea-cantidad input[type="number"] { width: 4.5rem; }
.linea-check { display: flex; align-items: center; gap: .5rem; }
.linea-check input { width: auto; }

.boton {
    display: inline-block; padding: .6rem 1.1rem;
    background: var(--acento); color: var(--sobre-acento); border: 1px solid var(--acento);
    border-radius: 9px; font: inherit; font-weight: 600; font-size: .92rem;
    cursor: pointer; text-align: center;
}
/* `a.boton` y no solo `.boton`, y esto NO es un adorno de especificidad:
   `.boton` sola pierde contra cualquier regla de `<a>` que ponga un color —y
   había una—, así que el texto blanco se volvía tinta oscura sobre verde y el
   botón dejaba de leerse. Un botón que no se lee es un botón que no existe. */
a.boton, button.boton { color: var(--sobre-acento); }
a.boton-suave, button.boton-suave { color: var(--acento); }
a.boton-peligro, button.boton-peligro { color: #fff; }
.boton:hover { text-decoration: none; filter: brightness(1.08); }
.boton:disabled { opacity: .5; cursor: not-allowed; }
.boton-suave { background: transparent; color: var(--acento); }
.boton-peligro { background: var(--malo); border-color: var(--malo); color: #fff; }
.boton-grande { padding: .8rem 1.6rem; font-size: 1rem; }
/* El botón pequeño de una cabecera. Sigue midiendo 44 px de alto de verdad
   —el ancho se puede recortar, el área del pulgar no— y por eso el relleno
   vertical es menor pero el `min-height` no baja. */
/*
 * VOLVER — un control, no una frase con una flecha delante.
 *
 * Era `← Controles` en texto plano, y ahí hay tres cosas mal a la vez: se lee
 * como parte del contenido y no como algo que se pulsa, no tiene área de toque
 * —una línea de 20 px de alto en un teléfono se falla— y el `←` es un carácter,
 * así que cambia de forma según la fuente que tenga cada aparato.
 *
 * La flecha se dibuja con dos bordes girados: escala con el texto, es del color
 * que sea y se mueve al pasar por encima, que es la señal de «esto va a algún
 * sitio». Y va en las cuatro zonas: volver es lo mismo en todas.
 */
.volver {
    display: inline-flex; align-items: center; gap: .5rem;
    min-height: 44px; padding: .4rem .95rem .4rem .8rem;
    border: 1px solid var(--borde); border-radius: 999px;
    background: var(--papel); color: var(--tinta-suave);
    font: inherit; font-size: .88rem; font-weight: 600;
    text-decoration: none; cursor: pointer;
    transition: color .14s ease, border-color .14s ease, background-color .14s ease;
}
.volver::before {
    content: ''; flex: none; width: .42em; height: .42em;
    border-left: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform .14s ease;
}
.volver:hover, .volver:focus-visible {
    color: var(--acento); border-color: var(--acento); background: var(--acento-claro);
}
.volver:hover::before { transform: rotate(45deg) translate(2px, -2px); }
@media (prefers-reduced-motion: reduce) {
    .volver, .volver::before { transition: none; }
    .volver:hover::before { transform: rotate(45deg); }
}

/*
 * EL TERCER NIVEL: EL BOTÓN NEUTRO (clase `boton-fantasma`, por historia).
 *
 * En la barra había dos botones —uno lleno, uno de contorno— y al lado «Mi
 * panel» y «Salir». La jerarquía es correcta: **quien ya es cliente sabe dónde
 * entra, y el botón lleno es para quien todavía no lo es**.
 *
 * Pero se le dio forma SIN FONDO NI BORDE («la misma caja, transparente»), y
 * una caja transparente no se ve: en claro y en oscuro seguía pareciendo texto
 * pelado al lado de dos botones. El dueño lo pidió cuatro veces. Ahora tiene
 * cuerpo: un relleno gris y un borde que se ven en los dos temas —la tinta
 * mezclada con el papel, así que se adapta solo— y la tinta de verdad, no la
 * suave. Pesa menos que los de la marca porque es gris, no porque no se vea:
 *
 *     lleno (marca)  →  contorno (marca)  →  neutro (gris, con cuerpo)
 *
 * `los-botones-se-ven-botones` lo mide en el navegador, en claro y en oscuro.
 */
.boton-fantasma {
    background: color-mix(in srgb, var(--tinta) 7%, var(--papel));
    border-color: color-mix(in srgb, var(--tinta) 24%, var(--papel));
    color: var(--tinta);
}
a.boton-fantasma, button.boton-fantasma { color: var(--tinta); }
.boton-fantasma:hover, .boton-fantasma:focus-visible {
    background: color-mix(in srgb, var(--acento) 12%, var(--papel));
    border-color: var(--acento);
    color: var(--acento);
    filter: none;
}

.boton-chico {
    padding: .35rem .8rem; font-size: .85rem;
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
}
.boton.encendido { box-shadow: inset 0 0 0 2px #fff; }
/* Encendido en un botón suave: el color de la marca, no un borde blanco que en
   un fondo claro no se ve. */
.boton-suave.encendido { background: color-mix(in srgb, var(--acento) 14%, var(--papel)); border-color: var(--acento); color: var(--acento); box-shadow: none; }
.boton-estado { font-weight: 500; opacity: .8; }
.fila-botones { display: flex; gap: .6rem; flex-wrap: wrap; }
/* EL ENLACE DE TEXTO — el que de verdad es una acción escrita, no una tarjeta.
   Tiene área de toque (44 px de alto real) y responde con fondo, no con
   subrayado: lo mismo que hace un botón, que es lo que es. */
.enlace {
    background: none; border: 0; font: inherit; font-weight: 600;
    color: var(--acento); cursor: pointer; text-decoration: none;
    display: inline-flex; align-items: center; min-height: 44px;
    padding: .35rem .55rem; margin: 0 -.55rem; border-radius: 8px;
}
a.enlace, button.enlace { color: var(--acento); }
.enlace:hover, .enlace:focus-visible { text-decoration: none; background: var(--acento-claro); }
/* Dentro de un párrafo no puede medir 44 px de alto: ahí abriría un hueco en
   mitad del texto. Es una palabra dentro de una frase, no una acción suelta. */
p .enlace, li .enlace { min-height: 0; padding: 0; margin: 0; display: inline; }

/* ── LAS MODALES ─────────────────────────────────────────────────────────
 *
 * Un `<dialog>` de verdad: el foco no se escapa con el tabulador, Esc cierra y
 * se pinta en la capa superior, así que ningún `z-index` de ninguna pantalla lo
 * puede tapar. Lo único que hay que poner aquí es la ropa.
 *
 * Van en `oneiot.css` y no en la hoja de una zona: la regla es que no se usan
 * las del navegador en NINGUNA pantalla, y una modal que solo existe en el panel
 * es un `confirm()` esperando a aparecer en la app.
 */
.modal {
    border: 0; padding: 0; background: transparent;
    max-width: min(28rem, calc(100vw - 2rem));
    width: 100%;
    color: var(--tinta);
}
/* El fondo se oscurece pero NO se difumina: un `blur` sobre una pantalla llena
   de gráficas cuesta cuadros en un tablet de pared, que es donde más se usa. */
.modal::backdrop { background: rgba(2, 6, 23, .55); }
.modal-caja {
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: 14px; padding: 1.25rem;
    box-shadow: 0 24px 60px rgba(2, 6, 23, .28);
    display: flex; flex-direction: column; gap: .75rem;
}
.modal-titulo { font-size: 1.15rem; margin: 0; line-height: 1.25; }
.modal-texto { margin: 0; color: var(--tinta-suave); font-size: .95rem; }
.modal-campo { display: flex; flex-direction: column; gap: .35rem; }
.modal-etiqueta { font-size: .8rem; color: var(--tinta-suave); font-weight: 600; }
/* 16 px de verdad en el campo: por debajo, Safari en iPhone hace zoom al
   enfocarlo y deja la modal a medio salir de la pantalla. */
.modal-valor {
    font: inherit; font-size: 16px; padding: .6rem .7rem; min-height: 44px;
    border: 1px solid var(--borde); border-radius: 9px;
    background: var(--fondo); color: var(--tinta); width: 100%;
}
.modal-valor:focus-visible { outline: 2px solid var(--acento); outline-offset: 1px; }
.modal-error { margin: 0; color: var(--malo); font-size: .85rem; font-weight: 600; }
/* `row-reverse`: la acción va a la derecha, que es donde la busca el pulgar, y
   en una pantalla estrecha las dos se apilan con la principal ARRIBA. */
.modal-botones { display: flex; flex-direction: row-reverse; gap: .5rem; margin-top: .25rem; }
.modal-botones .boton { flex: 1; min-height: 44px; }

/* ── PAGINACIÓN ──────────────────────────────────────────────────────────
   La cuenta a la izquierda y los botones a la derecha, y la cuenta SIEMPRE
   visible: «137 de 137» es lo que distingue una lista completa de una cortada
   por la mitad sin avisar. */
.paginacion {
    display: flex; align-items: center; justify-content: space-between;
    gap: .75rem; flex-wrap: wrap; margin: .9rem 0;
    font-size: .85rem; color: var(--tinta-suave);
}
.paginacion-cuenta { font-weight: 600; }
.paginacion-botones { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.paginacion-donde { padding: 0 .2rem; }
/* Deshabilitado y no escondido: un botón que desaparece mueve el otro de sitio,
   y en la página 2 se pulsa «Siguiente» donde estaba «Anterior». */
.desactivado { opacity: .45; pointer-events: none; }

/* ── LO QUE DESHACE ALGO SE VE DISTINTO ──────────────────────────────────
   En una tabla, un botón rojo relleno por fila grita. Esto solo pinta el borde
   y la letra: se distingue de un vistazo de las acciones que solo informan, sin
   convertir la pantalla en una alarma. */
.boton-peligro-suave {
    background: transparent; color: var(--malo); border-color: var(--malo);
}
.boton-peligro-suave:hover { background: color-mix(in srgb, var(--malo) 12%, transparent); }
a.boton-peligro-suave, button.boton-peligro-suave { color: var(--malo); }

/* ── LA BARRA DE FILTROS DE UNA LISTA ───────────────────────────────────── */
.filtros {
    display: flex; gap: .5rem; align-items: flex-end; flex-wrap: wrap;
    margin-bottom: .9rem;
}
.filtros label { display: flex; flex-direction: column; gap: .25rem; font-size: .78rem; color: var(--tinta-suave); font-weight: 600; }
.filtros input, .filtros select { min-height: 44px; }
.filtros .boton { min-height: 44px; }

/* ══ EL CATÁLOGO ═════════════════════════════════════════════════════════
 *
 * Una ficha de producto es la pantalla que decide una venta. Aquí se gasta el
 * espacio: la galería a la izquierda ocupando lo que haga falta, y a la derecha
 * una columna donde el precio es lo más grande después del nombre.
 */
.ficha-producto {
    display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 2rem; align-items: start; margin-bottom: 2rem;
}
/* Por debajo de eso la galería se queda estrecha y las fotos dejan de enseñar
   nada: mejor una columna con la foto a lo ancho. */
@media (max-width: 62rem) {
    .ficha-producto { grid-template-columns: 1fr; gap: 1.25rem; }
}

.galeria { display: flex; flex-direction: column; gap: .6rem; }
.galeria:focus-visible { outline: 2px solid var(--acento); outline-offset: 4px; border-radius: 14px; }
/*
 * LA FOTO ENTERA, SIN RECORTAR.
 *
 * Estaba con relación fija 4/3 y `object-fit: cover`, que es **recortar**: una
 * foto apaisada perdía arriba y abajo. En un catálogo eso no es un detalle
 * estético — se corta justo lo que alguien está mirando para decidir si compra.
 *
 * Ahora la pieza activa va EN FLUJO —las otras están `hidden`, o sea
 * `display: none`— así que el alto de la caja es el alto de la foto. Se ve
 * entera, ocupa todo el ancho, y no hay bandas.
 *
 * Lo que se paga: al cambiar entre una foto apaisada y una vertical, la caja
 * cambia de alto. Es el precio de no recortar, y es el correcto: una foto
 * cortada engaña, una caja que cambia de alto solo se mueve.
 *
 * El `min-height` es para que un medio que todavía no ha cargado no deje la
 * caja plana de un píxel y la página dando un salto al llegar la imagen.
 */
.galeria-principal {
    position: relative; border-radius: 14px; overflow: hidden;
    background: var(--papel); border: 1px solid var(--borde);
    min-height: 12rem;
}
.galeria-pieza { display: block; width: 100%; height: auto; }
/* `contain` no hace nada con el alto automático de arriba, y está puesto a
   propósito: el día que alguien le ponga un alto a la caja, lo que pasará es que
   la foto se encoja — no que se recorte. */
img.galeria-pieza { object-fit: contain; }

/* La fachada de un vídeo: la miniatura, y encima el triángulo. */
.video-fachada { cursor: pointer; display: block; position: relative; }
.video-fachada img { width: 100%; height: auto; display: block; }
/* Solo al reproducir hace falta una caja: un `iframe` no trae alto propio. Antes
   de eso manda la miniatura, que sí lo trae. */
.video-fachada.reproduciendo { aspect-ratio: 16 / 9; }
.video-fachada iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-jugar {
    position: absolute; inset: 0; margin: auto;
    width: 74px; height: 74px; border-radius: 50%;
    border: 0; cursor: pointer;
    background: rgba(15, 118, 110, .92);
    display: grid; place-items: center;
    box-shadow: 0 8px 30px rgba(2, 6, 23, .35);
    transition: transform .16s ease, background-color .16s ease;
}
.video-fachada:hover .video-jugar { transform: scale(1.07); background: var(--acento); }
.video-triangulo {
    width: 0; height: 0; margin-left: 5px;
    border-left: 20px solid #fff;
    border-top: 13px solid transparent; border-bottom: 13px solid transparent;
}
/* Mientras se reproduce, fuera el botón y el sello: tapan el vídeo. */
.video-fachada.reproduciendo .video-jugar,
.video-fachada.reproduciendo .video-sello { display: none; }

/* LA PORTADA DIBUJADA — cuando no hay miniatura.
   Un `<img>` que apunta a nada no deja un hueco limpio: deja el texto
   alternativo desbordando la caja. Esto se ve intencionado, que es lo mínimo
   en la pantalla que decide una venta.

   Y lleva su propia relación: no hay imagen dentro que le dé alto. */
.video-sinportada, .medio-sinportada {
    display: grid; place-items: center; gap: .5rem;
    aspect-ratio: 16 / 9;
    background:
        radial-gradient(120% 100% at 50% 0%, color-mix(in srgb, var(--acento) 30%, transparent), transparent 70%),
        var(--fondo);
    color: var(--tinta-suave);
}
.video-sinportada-titulo {
    align-self: end; padding: 0 1.5rem 1.5rem;
    font-weight: 700; font-size: 1.05rem; color: var(--tinta); text-align: center;
}
.medio-sinportada { position: relative; aspect-ratio: 4 / 3; }
.medio-triangulo { font-size: 1.6rem; color: var(--acento); }
/* En la tira de miniaturas sí va estirada al hueco: ahí lo que importa es que
   todas midan lo mismo. */
.galeria-tira .video-sinportada { position: absolute; inset: 0; aspect-ratio: auto; }
/* Se dice de quién es el reproductor que se va a abrir. En YouTube importa:
   al acabar salen recomendaciones que no controlamos. */
.video-sello {
    position: absolute; right: .6rem; bottom: .6rem;
    background: rgba(2, 6, 23, .7); color: #fff;
    font-size: .7rem; font-weight: 600; padding: .2rem .5rem; border-radius: 999px;
}

.galeria-tiras { display: flex; gap: .5rem; flex-wrap: wrap; }
.galeria-tira {
    position: relative; width: 72px; height: 54px; padding: 0; cursor: pointer;
    border: 2px solid transparent; border-radius: 9px; overflow: hidden;
    background: var(--papel); opacity: .65;
    transition: opacity .14s ease, border-color .14s ease;
}
.galeria-tira img { width: 100%; height: 100%; object-fit: cover; display: block; }
.galeria-tira:hover { opacity: 1; }
.galeria-tira.activa { opacity: 1; border-color: var(--acento); }
.galeria-tira-video {
    position: absolute; inset: 0; display: grid; place-items: center;
    color: #fff; font-size: .9rem; text-shadow: 0 1px 6px rgba(0, 0, 0, .8);
}

.ficha-columna h1 { font-size: 2rem; margin-bottom: .35rem; }
.precio-caja { margin: 1rem 0 1.25rem; }
.precio-caja .precio { font-size: 2.1rem; font-weight: 800; margin: 0; color: var(--tinta); }
/* Tachado y en pequeño ARRIBA del bueno: debajo se lee como el precio final. */
.precio-tachado { margin: 0; text-decoration: line-through; color: var(--tinta-suave); font-size: 1rem; }
.precio-nota { margin: .3rem 0 0; font-size: .88rem; }
.precio-casa { color: var(--acento); font-weight: 700; }

/* Que existe un precio mejor se dice; cuál es, no — hasta que hay sesión. */
.precio-casa-aviso {
    margin-top: .9rem; padding: .9rem 1rem;
    border: 1px dashed var(--acento); border-radius: 12px;
    background: color-mix(in srgb, var(--acento) 7%, transparent);
    display: flex; flex-direction: column; gap: .5rem; align-items: flex-start;
}
.precio-casa-aviso strong { color: var(--acento); }
.aviso-casa { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 7%, transparent); }

.lista-caracteristicas { padding-left: 1.1rem; margin: 0 0 1.25rem; }
.lista-caracteristicas li { margin-bottom: .3rem; }
.texto-largo { max-width: 42rem; white-space: pre-line; }

/* La cinta del precio de casa en la rejilla del catálogo. */
/* La foto de portada dentro de la caja del dibujo: así una tarjeta con foto y
   otra sin ella miden lo mismo y la rejilla no se escalona. */
/* `contain` y no `cover`: en la rejilla las tarjetas tienen que medir lo mismo
   —si no, se escalonan— pero eso no obliga a recortar la foto. Se ve entera
   dentro de su hueco, con el fondo de la tarjeta alrededor. */
.foto-catalogo { width: 100%; height: 100%; object-fit: contain; border-radius: 10px; display: block; }

.cinta-casa {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: .72rem; font-weight: 700; color: var(--acento);
    background: color-mix(in srgb, var(--acento) 12%, transparent);
    border-radius: 999px; padding: .15rem .6rem;
}

/* ── El catálogo por dentro (staff) ──────────────────────────────────────── */
.medios-rejilla {
    display: grid; gap: .75rem; margin-bottom: 1.25rem;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}
.medio {
    position: relative; margin: 0; border: 1px solid var(--borde);
    border-radius: 12px; overflow: hidden; background: var(--papel);
}
.medio img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.medio-pie { padding: .5rem; display: flex; flex-direction: column; gap: .4rem; }
.medio-acciones { display: flex; gap: .3rem; flex-wrap: wrap; }
.medio-acciones .boton-chico { min-height: 36px; padding: .25rem .6rem; }
.medio-sello {
    position: absolute; top: .4rem; left: .4rem;
    background: rgba(2, 6, 23, .72); color: #fff;
    font-size: .68rem; font-weight: 600; padding: .12rem .45rem; border-radius: 999px;
}
/* El de Bunny en verde: es el que no trae recomendaciones ajenas detrás. */
.medio-sello.limpio { background: var(--acento); }
/* La que acaba de subir se señala sola. `widget-latido` vive en `app.css`, que
   la zona de administración no carga: una animación que se define en otra hoja
   es una que un día no está. */
.medio-recien { animation: medio-llega .5s ease-out; }
@keyframes medio-llega {
    from { opacity: 0; transform: scale(.94); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .medio-recien { animation: none; } }

.subir-fotos {
    display: flex; align-items: center; justify-content: center;
    min-height: 96px; padding: 1rem; cursor: pointer;
    border: 2px dashed var(--borde); border-radius: 12px;
    color: var(--tinta-suave); font-weight: 600;
    transition: border-color .14s ease, background-color .14s ease;
}
.subir-fotos:hover, .subir-fotos.encima { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 8%, transparent); }
.subir-fotos input[type="file"] { display: none; }

/* El interruptor de un canal, en la lista. Verde encendido, gris apagado: en
   una tabla de doce productos y tres columnas, un texto no se lee de un vistazo
   y el color sí. */
.interruptor-canal {
    font: inherit; font-size: .75rem; font-weight: 700; cursor: pointer;
    min-height: 34px; padding: .2rem .7rem; border-radius: 999px;
    border: 1px solid var(--borde); background: var(--fondo); color: var(--tinta-suave);
}
.interruptor-canal.si { background: var(--acento); border-color: var(--acento); color: var(--sobre-acento); }
.tabla-catalogo td { vertical-align: middle; }
.canales-eleccion { display: grid; gap: .75rem; margin-bottom: 1rem; }
.canales-eleccion .linea-check { align-items: flex-start; }

/* El sello de versión del pie. Discreto pero SIEMPRE visible: es lo que
   convierte «se ve raro» en una pregunta con respuesta. */
.sello-version {
    font-size: .74rem; color: var(--tinta-suave); letter-spacing: .01em;
    display: inline-flex; align-items: center; gap: .3rem;
}
.sello-version code { font-size: .95em; opacity: .8; }

.desplegable summary { cursor: pointer; list-style: none; }
/* Un desplegable cuyo tirador ES un botón: se ve que se puede abrir sin tener
   que descubrirlo pasando el ratón por encima de un texto. */
.invitar { margin-bottom: 1rem; }
.invitar > summary { display: inline-block; margin-bottom: .6rem; }
.desplegable summary::-webkit-details-marker { display: none; }

/* ── Avisos, etiquetas, tablas ────────────────────────────────────────── */
.aviso { padding: .85rem 1rem; border-radius: 10px; border: 1px solid var(--borde); background: var(--papel); margin-bottom: 1.25rem; }
.aviso-bueno { border-color: var(--bueno); }
.aviso-malo { border-color: var(--malo); }

.etiqueta { display: inline-block; padding: .1rem .5rem; border-radius: 999px; font-size: .72rem; font-weight: 600; border: 1px solid var(--borde); color: var(--tinta-suave); }
.etiqueta-activo, .etiqueta-activa, .etiqueta-publicado, .etiqueta-hecho, .etiqueta-pagado, .etiqueta-entregado, .etiqueta-publicado { border-color: var(--bueno); color: var(--bueno); }
.etiqueta-suspendido, .etiqueta-vencida, .etiqueta-fallido, .etiqueta-cancelado, .etiqueta-baja, .etiqueta-rechazado { border-color: var(--malo); color: var(--malo); }
.etiqueta-gracia, .etiqueta-pendiente, .etiqueta-recibido, .etiqueta-borrador, .etiqueta-agotado, .etiqueta-almacen, .etiqueta-en_pruebas { border-color: var(--atencion); color: var(--atencion); }

.tabla { width: 100%; border-collapse: collapse; margin-top: .75rem; font-size: .92rem; }
.tabla th, .tabla td { text-align: left; padding: .6rem .5rem; border-bottom: 1px solid var(--borde); vertical-align: top; }
.tabla th { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--tinta-suave); }
.tabla tbody tr:hover { background: color-mix(in srgb, var(--acento) 5%, transparent); }

.lista-alertas { list-style: none; padding: 0; margin: 0; }
.lista-alertas li { padding: .6rem .8rem; border-left: 3px solid var(--atencion); background: var(--papel); border-radius: 0 8px 8px 0; margin-bottom: .5rem; display: flex; gap: .5rem; align-items: center; }
.lista-alertas .gravedad-grave, .lista-alertas li.gravedad-grave { border-left-color: var(--malo); }
.lista-alertas button { margin-left: auto; }
/* En el teléfono, «· una vez» no se apila letra a letra: baja entero, con «Cerrar» a su derecha. */
.lista-alertas li { flex-wrap: wrap; row-gap: .15rem; }
.lista-alertas li > strong { flex: 1 1 auto; }
@media (max-width: 600px) { .lista-alertas li > strong { flex-basis: 100%; } }
.lista-alertas li > .apagado { white-space: nowrap; }

/* ── El sitio público ─────────────────────────────────────────────────── */
/*
 * El encabezado cabe en dos renglones y cede el sitio al diagrama.
 *
 * La versión anterior se comía la pantalla entera: titular a 3rem, párrafo,
 * botones y una tarjeta de muestra. El resultado era que lo único que explica
 * el producto —el flujo del dato— solo lo veía quien bajaba. Un encabezado que
 * hay que superar para llegar a la demostración está trabajando en contra.
 */
.heroe { padding: 1.5rem 0 1rem; }
/*
 * El titular puede ser grande porque los botones se fueron a la barra: esa fila
 * que ocupaban es exactamente la que necesitaba el titular para crecer sin
 * empujar el diagrama por debajo del pliegue. Sigue cabiendo en UN renglón a
 * partir de 1280 px de ancho.
 */
.heroe h1 { font-size: clamp(1.9rem, 4vw, 3.05rem); margin-bottom: .5rem; line-height: 1.08; }
.heroe-frase { color: var(--tinta-suave); margin: 0; max-width: 54rem; font-size: 1.02rem; }
.precio { font-family: Outfit, sans-serif; font-size: 1.5rem; font-weight: 700; margin: .25rem 0; }
.precio span { font-size: .8rem; font-weight: 400; color: var(--tinta-suave); }

/* ── El pie ───────────────────────────────────────────────────────────── */
.pie { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; padding: 1.25rem 1.5rem; border-top: 1px solid var(--borde); font-size: .82rem; color: var(--tinta-suave); }
.marca-pie { font-weight: 600; }
.pie-enlaces { display: flex; gap: 1rem; }
.pie-enlaces a { color: var(--tinta-suave); }
/* El entorno, a la vista. Una pantalla de desarrollo que parece la de
   producción es cómo alguien apaga un equipo donde no debía. */
.entorno { margin-left: auto; padding: .1rem .6rem; border: 1px solid var(--atencion); color: var(--atencion); border-radius: 999px; font-weight: 600; }

@media (max-width: 640px) {
    /* En el teléfono el diagrama se pone de pie y mide lo que mide: ocho
       tarjetas en columna no caben en una pantalla y no hay truco que lo
       arregle. Lo que sí se puede es que empiece pronto — con el sujeto y el
       primer sensor a la vista, se entiende que aquí pasa algo y se baja. */
    .heroe { padding: .75rem 0 .5rem; }
    .heroe h1 { font-size: 1.6rem; }
    .heroe-frase { font-size: .92rem; }
    .boton-barra { padding: .4rem .7rem; font-size: .8rem; }
    .barra-nav { font-size: .85rem; }
    .sector-panel { padding: 1.1rem 1rem 1rem; }
    .sector-cabecera { margin-bottom: 1rem; }
    .flujo { gap: .7rem; }
    .sujeto-dibujo { max-width: 6.5rem; }
    .flujo-pie { margin-top: 1rem; }

    .barra { gap: .75rem; }
    .marco { padding: 1.25rem 1rem 2rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
 * EL MOVIMIENTO
 *
 * Esta aplicación va de datos que se mueven, así que una portada quieta
 * cuenta lo contrario de lo que vende. Pero el movimiento aquí tiene una
 * regla: **se mueve lo que representa algo que de verdad se mueve.**
 *
 *   sí   un punto que recorre la línea del sensor a la nube — eso es un dato
 *   sí   una cifra que cambia — eso es una lectura nueva
 *   sí   una sección que aparece al llegar a ella — eso es atención
 *   no   un título que rebota, un icono que gira sin motivo, un fondo inquieto
 *
 * Lo segundo llama la atención una vez y estorba las demás. Y todo lo de
 * aquí se apaga con `prefers-reduced-motion`, que no es una concesión: para
 * quien tiene vértigo vestibular, una pantalla que no para es inutilizable.
 * ═══════════════════════════════════════════════════════════════════════ */

.hoja-de-simbolos { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Aparecer al llegar. El desplazamiento es corto —12px— a propósito: lo que
   guía la mirada es que algo entre, no cuánto viaja. */
.aparece { opacity: 0; transform: translateY(12px); transition: opacity .55s ease, transform .55s ease; }
.aparece.visible { opacity: 1; transform: none; }

/* ── Las pestañas de sector ──────────────────────────────────────────── */
.soluciones { margin-top: .5rem; }
.sector-pestanas { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; margin-bottom: .85rem; }
.pestanas-rotulo {
    text-transform: uppercase; letter-spacing: .08em; font-size: .72rem;
    font-weight: 600; color: var(--tinta-suave); margin-right: .35rem;
}
.sector-pestana {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .5rem .9rem;
    background: var(--papel); color: var(--tinta-suave);
    border: 1px solid var(--borde); border-radius: 10px;
    font: inherit; font-size: .92rem; font-weight: 500; cursor: pointer;
    transition: color .2s, border-color .2s, transform .2s;
}
.sector-pestana:hover { color: var(--tinta); border-color: var(--acento); transform: translateY(-1px); }
.sector-pestana.activa { color: var(--acento); border-color: var(--acento); font-weight: 600; }
.pestana-icono { width: 18px; height: 18px; flex: none; }

/* ── El panel ────────────────────────────────────────────────────────── */
.sector-panel {
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: 20px; padding: 1.5rem 1.5rem 1.25rem; box-shadow: var(--sombra);
    position: relative; overflow: hidden;
}
.sector-panel[hidden] { display: none; }
/* Al cambiar de pestaña, el panel entra. Es lo que hace que se lea como «otra
   cosa» y no como que el texto se corrigió solo. */
.sector-panel.entrando { animation: panel-entra .4s ease both; }
@keyframes panel-entra { from { opacity: 0; transform: translateY(10px); } }

/* Título y frase en el mismo renglón. Centrados y uno debajo del otro sumaban
   cuatro líneas entre las pestañas y el diagrama, que es justo el sitio donde
   no sobra ni una. */
.sector-cabecera {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: .4rem 2rem; flex-wrap: wrap; margin-bottom: 1.35rem;
}
.sector-titulo { font-size: clamp(1.25rem, 2.4vw, 1.65rem); margin: 0; }
.sector-entrada { color: var(--tinta-suave); margin: 0; max-width: 34rem; font-size: .92rem; }

/* ── El diagrama ─────────────────────────────────────────────────────── */
.flujo {
    position: relative;
    display: grid;
    /* `minmax(0, …)` y no `minmax(11rem, …)`: el mínimo por defecto de una
       columna de rejilla es su contenido, así que un detalle largo —«Puerta
       abierta · 2:14 p. m.»— empujaba la última columna fuera del panel y el
       `overflow: hidden` se la comía. Con 0, el texto envuelve en vez de
       desbordar. */
    grid-template-columns: minmax(5rem, .72fr) minmax(0, .82fr) auto minmax(0, 1.25fr);
    align-items: center;
    /* El hueco entre columnas ES el largo de la línea de flujo: no hay otro
       sitio donde estirarla. Las tarjetas de sensor se estrechan para pagarlo,
       que es donde menos cuesta — llevan una etiqueta y un número. */
    gap: 1rem 3.25rem;
}
/* La capa de las líneas va DEBAJO de las tarjetas y no recibe clics: es
   decoración que explica, no interfaz. */
.flujo-lineas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; overflow: visible; }
.flujo-linea { fill: none; stroke: var(--borde); stroke-width: 1.5; }
.flujo-linea.viva { stroke: var(--acento); opacity: .55; }
.flujo-punto { fill: var(--acento); filter: drop-shadow(0 0 7px var(--acento)) drop-shadow(0 0 2px var(--acento)); }

.flujo-columna { display: grid; gap: .85rem; position: relative; z-index: 1; min-width: 0; }
.flujo-sujeto { display: grid; justify-items: center; gap: .6rem; position: relative; z-index: 1; }
.sujeto-dibujo { width: 100%; max-width: 11rem; height: auto; color: var(--tinta); }
.sujeto-dibujo .acento { color: var(--acento); }
.sujeto-pie { font-weight: 600; text-align: center; font-size: .95rem; }

.nodo {
    background: var(--fondo); border: 1px solid var(--borde);
    border-radius: 12px; padding: .7rem .85rem;
    display: flex; align-items: center; gap: .65rem;
    position: relative; z-index: 1;
    transition: border-color .25s, transform .25s;
}
.nodo-sensor { padding: .6rem .7rem; gap: .5rem; }
.nodo-icono { width: 20px; height: 20px; flex: none; color: var(--tinta-suave); }
.nodo-texto { display: grid; min-width: 0; }
.nodo { min-width: 0; }
.nodo-nombre { font-size: .72rem; color: var(--tinta-suave); text-transform: uppercase; letter-spacing: .04em; line-height: 1.3; }
.nodo-valor { font-family: Outfit, sans-serif; font-weight: 700; font-size: 1.05rem; white-space: nowrap; }
.nodo-valor-texto { font-size: .92rem; font-weight: 600; }
.nodo-unidad { font-size: .78rem; font-weight: 500; color: var(--tinta-suave); margin-left: .15rem; }
.nodo-detalle { font-size: .8rem; color: var(--tinta-suave); line-height: 1.35; }

/* El destello de dato nuevo. Corto y sin repetición inmediata: una tarjeta que
   parpadea sin parar deja de significar «llegó algo». */
.nodo.latido { border-color: var(--acento); transform: translateY(-1px); }
.insignia {
    position: absolute; top: -.6rem; left: .7rem;
    background: var(--acento); color: var(--papel);
    font-size: .62rem; font-weight: 700; letter-spacing: .03em;
    padding: .1rem .45rem; border-radius: 999px;
    opacity: 0; transition: opacity .3s;
}
.nodo.latido .insignia { opacity: 1; }

.nodo-marca {
    justify-content: center; padding: .9rem 1.25rem;
    background: var(--papel); border-color: var(--acento);
    font-family: Outfit, sans-serif; font-weight: 800; font-size: 1.1rem;
    box-shadow: 0 0 0 6px color-mix(in srgb, var(--acento) 8%, transparent);
    transition: box-shadow .3s, transform .3s;
}
.marca-punto { color: var(--acento); }
.marca-texto { transition: opacity .14s; }

/* `inset: 0` + `margin: auto` para centrarlo de verdad. Sin offsets, un
   absoluto se queda en su «posición estática» —donde habría caído en la fila— y
   el aro salía corrido a la derecha del texto. Y la entrada es corta (.14s):
   el cuadro solo procesa 0,7 s, así que un desvanecido largo se come un tercio
   del momento que hay que enseñar. */
.marca-aro {
    position: absolute; inset: 0; margin: auto;
    width: 34px; height: 34px;
    opacity: 0; transition: opacity .14s; color: var(--acento);
}
.aro-fondo { stroke: currentColor; opacity: .18; }
.aro-giro { stroke: currentColor; stroke-dasharray: 20 62; transform-origin: 50% 50%; }

/* Mientras procesa: el texto se aparta y el aro gira. Que el cuadro se limite a
   iluminarse dejaría el mismo dibujo de antes con más brillo; lo que cuenta la
   historia es que aquí PASA algo antes de que salga el resultado. */
.nodo-marca.procesando { box-shadow: 0 0 0 10px color-mix(in srgb, var(--acento) 14%, transparent); }
.nodo-marca.procesando .marca-texto { opacity: .18; }
.nodo-marca.procesando .marca-aro { opacity: 1; animation: aro-gira .9s linear infinite; }
@keyframes aro-gira { to { transform: rotate(360deg); } }

/* Y un pulso corto al recibir, antes de ponerse a procesar. */
.nodo-marca.recibe { transform: scale(1.06); }

/* La tarjeta de salida acusa la llegada. Corto: es un acuse, no una alarma. */
.nodo-salida.recibido { border-color: var(--acento); }

/* ── Las salidas ─────────────────────────────────────────────────────── */
/* `min-width: 0` en cadena hasta el texto. El mínimo por defecto de un elemento
   de rejilla o de caja flexible es su contenido, así que un encabezado con el
   valor sin partir —«VELOCIDAD · ÚLTIMA HORA  62 km/h»— ensanchaba la tarjeta
   por encima de su columna y se salía del panel. */
.nodo-salida { flex-direction: column; align-items: stretch; gap: .5rem; min-width: 0; }
.salida-cabeza { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.salida-cabeza .nodo-nombre { min-width: 0; overflow-wrap: anywhere; }
.salida-valor { font-family: Outfit, sans-serif; font-size: .95rem; margin-left: auto; white-space: nowrap; }

/* `grafica-barra` y no `barra` a secas: `.barra` ya era la barra de navegación
   del sitio, con su `padding`, su `position: sticky` y su fondo. Cada columna
   de la gráfica heredaba 38 px de relleno y el conjunto se salía de la tarjeta.
   Un nombre genérico en una hoja de estilo compartida choca tarde o temprano, y
   el choque no da error: da un dibujo raro que parece un problema de rejilla. */
.grafica-barras { display: flex; align-items: flex-end; gap: .3rem; height: 3.2rem; }
.grafica-barra {
    flex: 1 1 0; min-width: 0; border-radius: 3px 3px 0 0;
    background: var(--acento); opacity: .85;
    height: var(--alto);
    transform-origin: bottom;
    transform: scaleY(0);
    transition: transform .5s cubic-bezier(.2, .8, .3, 1);
}
.sector-panel.activo .grafica-barra { transform: scaleY(1); }

.mapa { position: relative; height: 5.5rem; border-radius: 8px; overflow: hidden; background: color-mix(in srgb, var(--acento) 7%, var(--papel)); color: var(--tinta); }
.mapa svg { width: 100%; height: 100%; display: block; }
.mapa-ruta { stroke: var(--acento); stroke-dasharray: 5 5; }
.mapa-nucleo { fill: var(--acento); }
.mapa-halo { fill: var(--acento); opacity: .25; }

/* ── El fondo del panel: una aurora lenta ────────────────────────────── */
.sector-panel::before {
    content: ''; position: absolute; inset: -30%;
    background:
        radial-gradient(35% 45% at 22% 30%, color-mix(in srgb, var(--acento) 16%, transparent), transparent 70%),
        radial-gradient(30% 40% at 78% 70%, color-mix(in srgb, var(--acento) 11%, transparent), transparent 70%);
    z-index: 0; pointer-events: none;
    animation: aurora 26s ease-in-out infinite alternate;
}
/* 26 segundos: por debajo del umbral en el que el ojo lo sigue. Se nota que la
   pantalla está viva y no se nota que algo se mueve. */
@keyframes aurora {
    from { transform: translate3d(-2%, -1%, 0) scale(1); }
    to   { transform: translate3d(3%, 2%, 0) scale(1.08); }
}

.flujo-pie { text-align: center; margin-top: 1.5rem; font-size: .82rem; }

/* ── En pantallas pequeñas el diagrama se pone de pie ────────────────── */
@media (max-width: 900px) {
    .flujo { grid-template-columns: 1fr; gap: 1rem; }
    .flujo-sujeto { margin-bottom: .5rem; }
    .sujeto-dibujo { max-width: 8rem; }
    .flujo-centro { justify-self: center; }
    /* Las líneas se vuelven a trazar solas al cambiar el ancho: las dibuja el
       JavaScript midiendo dónde quedaron las tarjetas, no unas coordenadas
       escritas a mano que dejarían de ser ciertas justo aquí. */
}

@media (prefers-reduced-motion: reduce) {
    .aparece { opacity: 1; transform: none; transition: none; }
    .sector-panel::before,
    .sector-panel.entrando { animation: none; }
    .grafica-barra { transition: none; transform: scaleY(1); }
    .nodo, .sector-pestana { transition: none; }
    .punto.en-linea { animation: none; }
    .nodo-marca.procesando .marca-aro { animation: none; }
    .mapa-ruta { stroke-dasharray: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
 * LOS CUATRO CUADROS
 *
 * Rejilla de cinco columnas: 2+3 arriba, 3+2 abajo. Con `1fr 1.6fr` en dos
 * rejillas separadas quedaban dos filas que no se alineaban entre sí; con una
 * sola rejilla de cinco, las cuatro esquinas caen donde tienen que caer.
 * ═══════════════════════════════════════════════════════════════════════ */

.capacidades h2 { margin-bottom: 1.25rem; }

.bento { display: grid; grid-template-columns: repeat(5, 1fr); gap: 1.25rem; }
.bento-cuadro {
    grid-column: span 5;
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: 18px; box-shadow: var(--sombra);
    padding: 1.5rem; overflow: hidden;
    display: flex; flex-direction: column; gap: 1.25rem;
    position: relative;
}
.bento-texto h3 { font-size: 1.15rem; margin-bottom: .4rem; }
.bento-texto p { color: var(--tinta-suave); font-size: .92rem; margin: 0; }

@media (min-width: 900px) {
    .bento-equipos { grid-column: span 2; }
    .bento-protocolos { grid-column: span 3; flex-direction: row; align-items: center; }
    .bento-alertas { grid-column: span 3; flex-direction: row-reverse; align-items: center; }
    .bento-metricas { grid-column: span 2; }
    .bento-protocolos .bento-texto,
    .bento-alertas .bento-texto { flex: 1 1 0; min-width: 0; }
    .bento-alertas .bento-escena { flex: 1 1 0; min-width: 0; }
    .bento-protocolos .bento-escena { flex: 1.15 1 0; min-width: 0; }
}

/* Las escenas se salen del cuadro por abajo a propósito: se ve que aquello
   sigue, y un recorte limpio pesa menos que un borde más. */
.bento-escena { position: relative; }

/* ── 1 · El desfile de equipos ───────────────────────────────────────── */
.desfile { overflow: hidden; margin: auto -1.5rem -1.5rem; padding: 0 1.5rem 1.5rem; }
.desfile-cinta { display: flex; gap: .7rem; width: max-content; animation: desfilar 34s linear infinite; }
.desfile-ficha {
    width: 11rem; flex: none;
    background: var(--fondo); border: 1px solid var(--borde); border-radius: 11px;
    padding: .7rem .8rem; display: grid; gap: .15rem;
}
.ficha-serie { font-family: ui-monospace, Menlo, monospace; font-weight: 600; font-size: .88rem; }
.ficha-modelo { font-size: .72rem; color: var(--tinta-suave); }
.desfile-ficha .etiqueta { justify-self: start; margin-top: .2rem; }
/* -50 % y no -100 %: la cinta lleva la lista dos veces, así que a media vuelta
   la copia está justo donde estaba la original y el salto no se ve. */
@keyframes desfilar { to { transform: translateX(-50%); } }

/* ── 2 · La órbita ───────────────────────────────────────────────────── */
/* La escena es MÁS GRANDE que el anillo de fuera a propósito. Los satélites van
   centrados sobre el anillo, así que la mitad de cada uno cae por fuera: con la
   escena y el anillo del mismo tamaño, «TLS 8883» quedaba cortado contra el
   borde del cuadro cada vez que pasaba por los lados. */
.orbita-escena { aspect-ratio: 1; margin: 0 auto; width: 100%; max-width: 19rem; }
.orbita-centro {
    position: absolute; inset: 0; margin: auto; width: fit-content; height: fit-content;
    font-family: Outfit, sans-serif; font-weight: 800; font-size: 1.05rem; z-index: 2;
}
.orbita {
    position: absolute; inset: 0; margin: auto;
    border: 1px dashed color-mix(in srgb, var(--tinta-suave) 40%, transparent);
    border-radius: 50%;
    animation: girar-orbita var(--vuelta) linear infinite;
}
/* El anillo que lleva los seis satélites, y otro decorativo por dentro.
 *
 * Los radios están medidos, no elegidos a ojo: con la escena a 304 px, el
 * anillo de fuera al 72 % da un radio de 109, y entre dos satélites vecinos
 * —repartidos a 60°— caben esos mismos 109 px. El más ancho mide 50, así que
 * nunca se tocan. Y 109 + 25 de medio satélite = 134, dentro de los 152 de
 * media escena: tampoco se salen del cuadro. */
.orbita-dentro {
    width: 42%; height: 42%;
    animation-direction: reverse;
    border-style: dotted; opacity: .7;
}
.orbita-fuera { width: 72%; height: 72%; }
.orbita-posicion { position: absolute; inset: 0; transform: rotate(var(--angulo)); }
.satelite {
    position: absolute; top: 0; left: 50%;
    transform: translate(-50%, -50%);
    background: var(--fondo); border: 1px solid var(--borde); border-radius: 999px;
    padding: .25rem .55rem; font-size: .68rem; font-weight: 600; white-space: nowrap;
    /*
     * El satélite descuenta DOS giros: la vuelta de la órbita y su propio
     * ángulo de partida. Por eso el ángulo entra como variable y aparece
     * dentro de los fotogramas — si solo se descontara la vuelta, el texto
     * quedaría inclinado, y si solo se descontara el ángulo, daría volteretas.
     */
    animation: contragiro var(--vuelta) linear infinite;
}
.satelite-fuerte { border-color: var(--acento); color: var(--acento); }
@keyframes girar-orbita { to { transform: rotate(360deg); } }
@keyframes contragiro {
    from { transform: translate(-50%, -50%) rotate(calc(-1 * var(--angulo))); }
    to   { transform: translate(-50%, -50%) rotate(calc(-1 * var(--angulo) - 360deg)); }
}

/* ── 3 · La pila de alertas ──────────────────────────────────────────── */
/*
 * EL CUADRO NO CAMBIA DE ALTO. NUNCA.
 *
 * Durante la entrada hay cinco tarjetas en la lista, y con el alto libre eso
 * estiraba el cuadro y lo encogía 400 ms después: un tirón en cada ronda. Se ve
 * aunque no se sepa nombrar, y es de las cosas que hacen que una pantalla
 * parezca amateur sin que nadie sepa decir por qué.
 *
 * Así que el alto sale de una cuenta, no del contenido: cuatro tarjetas de alto
 * fijo más sus tres separaciones. La quinta se sale por abajo y el `overflow`
 * la recorta mientras se va.
 */
.pila {
    --alto-alerta: 3.35rem;
    --hueco-alerta: .55rem;
    height: calc(4 * var(--alto-alerta) + 3 * var(--hueco-alerta));
    overflow: hidden;
}
.pila-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--hueco-alerta); align-content: start; }
.pila-alerta {
    display: flex; align-items: center; gap: .6rem;
    height: var(--alto-alerta); flex: none;
    background: var(--fondo); border: 1px solid var(--borde);
    border-left: 3px solid var(--atencion);
    border-radius: 0 11px 11px 0; padding: 0 .75rem;
}
.pila-alerta.grave { border-left-color: var(--malo); }
.pila-texto { display: grid; min-width: 0; }
/* Una línea cada uno, con puntos suspensivos de red de seguridad: un texto que
   creciera a dos líneas no rompería el alto —está fijado— pero se vería
   cortado, y eso sí que no se entiende. */
.pila-titulo, .pila-detalle { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pila-titulo { font-size: .82rem; font-weight: 600; }
.pila-detalle { font-size: .75rem; color: var(--tinta-suave); }
.pila-icono { width: 17px; height: 17px; flex: none; color: var(--tinta-suave); }
/* La nueva entra desde arriba y empuja: es lo que se ve en un panel de verdad
   cuando algo pasa, y por eso se anima la entrada y no un simple aparecer. */
/* Casi un segundo, y con una curva que frena tarde (`ease-out` marcado).
 * Con 0,45 s la tarjeta ya estaba puesta antes de que la vista llegara a ella:
 * el movimiento existía y no se apreciaba, que es lo mismo que no tenerlo. Y
 * viene desde más arriba —18 px— porque una entrada lenta y corta se lee como
 * lentitud, no como entrada. */
.pila-alerta.entra { animation: alerta-entra .9s cubic-bezier(.16, 1, .3, 1) both; }
.pila-alerta.sale { animation: alerta-sale .6s cubic-bezier(.4, 0, .6, 1) both; }
@keyframes alerta-entra {
    from { opacity: 0; transform: translateY(-18px) scale(.96); }
}
/* Solo se desvanece y baja un poco. Antes encogía su propio alto, que era otra
   forma de mover a las de arriba: ahora nada de lo que hace la que se va afecta
   a las que se quedan. */
@keyframes alerta-sale {
    to { opacity: 0; transform: translateY(10px); }
}

/* ── 4 · La marquesina de métricas ───────────────────────────────────── */
.marquesina { display: grid; gap: .6rem; overflow: hidden; margin: auto -1.5rem -1.5rem; padding: 0 0 1.5rem; }
.marquesina-fila { overflow: hidden; }
.marquesina-cinta { display: flex; gap: .5rem; width: max-content; animation: desfilar 26s linear infinite; }
/* La segunda fila va al revés. Dos filas en el mismo sentido se leen como una
   sola cosa moviéndose; en sentidos contrarios se lee como un catálogo. */
.al-reves .marquesina-cinta { animation-direction: reverse; animation-duration: 32s; }
.chip {
    flex: none; background: var(--fondo); border: 1px solid var(--borde);
    border-radius: 999px; padding: .35rem .8rem; font-size: .8rem; white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .desfile-cinta, .marquesina-cinta, .orbita, .satelite { animation: none; }
    .pila-alerta.entra, .pila-alerta.sale { animation: none; }
}

/* ── Los dibujos del catálogo ────────────────────────────────────────── */
/*
 * El dibujo va sobre un fondo propio y no sobre el de la tarjeta: un módulo
 * dibujado a línea sobre el mismo color en el que flota se lee como un boceto;
 * con su recuadro se lee como un producto.
 */
.equipo-dibujo {
    display: block;
    background: color-mix(in srgb, var(--acento) 6%, var(--fondo));
    border: 1px solid var(--borde); border-radius: 12px;
    padding: .5rem; margin-bottom: .9rem;
    color: var(--tinta);
}
.equipo-dibujo svg { display: block; width: 100%; height: auto; }
/* La foto, en la misma caja que el dibujo (180 × 130): así una tarjeta con foto
   mide lo mismo que una con dibujo, en la portada y en el catálogo. */
.equipo-dibujo > .foto-catalogo { aspect-ratio: 180 / 130; height: auto; }
.equipo-dibujo .acento { color: var(--acento); }
.equipo-dibujo:hover { border-color: var(--acento); }
/* Todas las fichas del catálogo miden lo mismo y el precio queda abajo del todo.
   Con el alto libre, el botón de añadir caía a una altura distinta en cada
   tarjeta según lo largo que fuera el resumen, y una fila de precios en zigzag
   se lee como un catálogo mal montado. */
.tarjeta-equipo-tienda { display: flex; flex-direction: column; height: 100%; }
.tarjeta-equipo-tienda .equipo-dibujo { margin-bottom: 1rem; }
.tarjeta-equipo-tienda .precio { margin-top: auto; padding-top: .75rem; }

.ficha-cabecera {
    display: grid; grid-template-columns: minmax(14rem, 22rem) 1fr;
    gap: 1.5rem 2rem; align-items: center; margin-bottom: 2rem;
}
.ficha-cabecera h1 { margin-bottom: .25rem; }
.equipo-dibujo-grande { margin-bottom: 0; padding: 1rem; }

@media (max-width: 700px) {
    .ficha-cabecera { grid-template-columns: 1fr; }
}

/* El selector de cuenta de la barra. Solo aparece cuando hay más de una: un
   desplegable con una sola opción es ruido, y ocupa el sitio de algo que sí
   importa. */
.selector-cuenta { display: inline-flex; align-items: center; }
.selector-cuenta select {
    font: inherit; font-size: .85rem; padding: .25rem 1.6rem .25rem .5rem;
    border: 1px solid var(--borde, #d8dee9); border-radius: .4rem;
    background: transparent; color: inherit; max-width: 14rem;
}

/* El QR de emparejamiento. Se dibuja aquí, en SVG: pedirle la imagen a un
   servicio de fuera sería mandarle a un tercero el código con el que se
   emparejan los avisos de alguien. */
.qr { display: inline-block; padding: .75rem; background: #fff; border-radius: .6rem; }
.qr svg { display: block; width: 220px; height: 220px; }

/* Un aviso sin leer se distingue de uno leído. La bandeja existe para eso:
   para poder mirarla después de que el globo de la notificación ya se fue. */
.sin-leer { font-weight: 500; }
.sin-leer td:first-child::before { content: '● '; color: var(--acento, #0f766e); }


/* ── WIDGETS EN EL PANEL DEL NAVEGADOR ────────────────────────────────────
   El bloque del widget vive en `app.css` porque nació en la app. Aquí solo va
   lo que hace falta para que la misma pieza funcione fuera de ella: la rejilla
   y los estilos que `app.css` no trae a esta zona.

   Un archivo aparte solo para esto sería una tercera hoja que mantener; y
   copiar el bloque entero sería tener dos, y arreglar una. */
.zona-dashboard .widgets, .zona-admin .widgets {
    display: grid; gap: .75rem;
    /* Un poco más ancha que en el teléfono —aquí sobra sitio y se mira de más
       lejos— pero del mismo orden: si una dijera 9.5rem y la otra 15rem, el
       mismo tablero se vería con distinto número de columnas sin motivo. */
    grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
}

/* ══ EL BANCO DE PRUEBAS ═════════════════════════════════════════════════
 *
 * Esta pantalla se mira con las manos ocupadas: en una hay una placa y en la
 * otra un multímetro. Así que lo que se mira de reojo —qué falta— tiene que
 * distinguirse a un metro de distancia, y lo que se acaba de poner en verde
 * tiene que avisar solo, porque nadie está leyendo la pantalla en ese momento.
 */
.banco-cabeza {
    display: flex; justify-content: space-between; align-items: flex-start;
    gap: 1rem; flex-wrap: wrap; margin-bottom: 1.4rem;
}
.banco-cabeza h1 { margin-bottom: .3rem; }
.banco-cabeza h1 code { font-size: inherit; background: none; padding: 0; letter-spacing: .06em; }

.comprobaciones { list-style: none; padding: 0; margin: 0 0 2rem; display: grid; gap: .5rem; }

.comprobacion {
    display: grid; grid-template-columns: 1.6rem 1fr; gap: .7rem; align-items: start;
    padding: .7rem .9rem; border: 1px solid var(--borde); border-radius: .6rem;
    background: var(--papel);
    /* Sin transición en el color de fondo: el destello de abajo la usa, y dos
       animaciones sobre la misma propiedad se pisan. */
    transition: border-color .2s ease;
}
.comprobacion-marca {
    display: grid; place-items: center; width: 1.6rem; height: 1.6rem;
    border-radius: 50%; font-size: .85rem; font-weight: 700; line-height: 1;
    border: 1px solid var(--borde); color: var(--tinta-suave);
}
.comprobacion-ok { border-color: color-mix(in srgb, var(--bueno) 45%, var(--borde)); }
.comprobacion-ok .comprobacion-marca { border-color: var(--bueno); color: var(--bueno); }
.comprobacion-falta .comprobacion-marca { border-style: dashed; }

.comprobacion-que { font-weight: 600; margin: 0; }
.comprobacion-detalle { margin: .15rem 0 0; }
/* El porqué solo aparece cuando algo falla, y por eso puede permitirse ocupar:
   es la única línea de la pantalla que dice qué hacer con la placa en la mano. */
.comprobacion-porque {
    margin: .5rem 0 0; padding: .5rem .7rem; font-size: .82rem; line-height: 1.5;
    border-left: 2px solid var(--atencion);
    background: color-mix(in srgb, var(--atencion) 7%, transparent);
    border-radius: 0 .35rem .35rem 0;
}
.comprobacion-porque code { font-size: .95em; }

/* Lo que acaba de ponerse en verde, señalado un momento. Es la recompensa de
   haber soldado bien, y llega cuando quien probó está mirando la placa. */
@keyframes banco-recien {
    0%   { background: color-mix(in srgb, var(--bueno) 26%, var(--papel)); }
    100% { background: var(--papel); }
}
.comprobacion-recien { animation: banco-recien 1.6s ease-out; }
@media (prefers-reduced-motion: reduce) { .comprobacion-recien { animation: none; } }

.banco-botones { display: flex; gap: .5rem; flex-wrap: wrap; margin: .8rem 0; }
.banco-respuesta.malo { color: var(--malo); }

.banco-firma { display: grid; gap: .7rem; max-width: 42rem; margin-top: .8rem; }
.banco-requisitos { border: 1px solid var(--borde); border-radius: 12px; padding: .8rem 1rem; margin: 0; display: grid; gap: .5rem; }
.banco-requisitos legend { font-weight: 600; padding: 0 .3rem; }
.banco-requisitos .linea-check { display: flex; gap: .55rem; align-items: flex-start; font-size: .92rem; font-weight: 400; color: var(--tinta); }
.banco-requisitos .linea-check input { margin-top: .25rem; width: 1.1rem; height: 1.1rem; }
.banco-firma label { display: grid; gap: .3rem; font-size: .8rem; font-weight: 600; color: var(--tinta-suave); }
.banco-firma textarea { width: 100%; }
.banco-firma-botones { display: flex; gap: .6rem; flex-wrap: wrap; }

/* Los lotes de la fábrica: el avance de una tanda, de un vistazo. */
.lotes { margin-bottom: 1.6rem; }
.lote { border: 1px solid var(--borde); border-radius: .6rem; padding: .8rem .9rem; margin-bottom: .6rem; background: var(--papel); }
.lote-cabeza { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; align-items: baseline; }
.lote-barra { height: 6px; border-radius: 999px; background: var(--borde); overflow: hidden; margin: .6rem 0 .5rem; }
.lote-barra-hecha { height: 100%; background: var(--bueno); border-radius: inherit; transition: width .3s ease; }

/* El asistente de fábrica: una conversación, no un formulario de veinte campos. */
.asistente-form { display: grid; gap: .9rem; max-width: 48rem; margin-bottom: 2rem; }
.asistente-form label { display: grid; gap: .3rem; font-size: .8rem; font-weight: 600; color: var(--tinta-suave); }
.asistente-form textarea { width: 100%; }
.asistente-preguntas { display: grid; gap: 1rem; margin: .5rem 0; }
.pregunta { border-left: 2px solid var(--acento); padding-left: .8rem; }
/* El porqué debajo y no encima: primero la pregunta, y el motivo para quien dude. */
.pregunta-porque { margin: .35rem 0 0; line-height: 1.5; }
.propuesta h3 { margin-top: 1.6rem; }
.propuesta table th { text-align: left; white-space: nowrap; }
.propuesta-nota {
    margin-top: 1.2rem; padding: .8rem 1rem; border: 1px solid var(--borde);
    border-radius: .6rem; background: var(--papel);
}
.propuesta-nota h3 { margin: 0 0 .4rem; font-size: .95rem; }
.propuesta-nota p { margin: 0; line-height: 1.6; }

/* ══ EL ASISTENTE DE FÁBRICA ═════════════════════════════════════════════
 *
 * Diseñar un equipo es una conversación con un documento al lado que va
 * cambiando. Por eso son dos columnas y no una lista: a la izquierda lo que se
 * dijo, a la derecha cómo va quedando el aparato. Se lee cruzando.
 */
.disenar { display: grid; gap: .9rem; max-width: 48rem; margin-bottom: 2.5rem; }
.disenar label { display: grid; gap: .3rem; font-size: .8rem; font-weight: 600; color: var(--tinta-suave); }
.disenar textarea, .disenar input { width: 100%; }
.disenar-contexto { border: 1px solid var(--borde); border-radius: .6rem; padding: .7rem .9rem; background: var(--papel); }
.disenar-contexto summary { cursor: pointer; font-weight: 600; font-size: .85rem; }
.disenar-contexto[open] summary { margin-bottom: .5rem; }

.sesion-cabeza { margin-bottom: 1.2rem; }
.sesion-cuerpo { display: grid; grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); gap: 2rem; align-items: start; }
/* Por debajo de esto la columna del hilo se queda tan estrecha que una pregunta
   ocupa seis líneas: mejor una encima de otra. */
@media (max-width: 68rem) { .sesion-cuerpo { grid-template-columns: 1fr; } }

/* ── EL HILO ─────────────────────────────────────────────────────────── */
.turno { padding: .7rem .9rem; border-radius: .7rem; margin-bottom: .7rem; border: 1px solid var(--borde); }
.turno-persona { background: color-mix(in srgb, var(--acento) 6%, var(--papel)); border-color: color-mix(in srgb, var(--acento) 25%, var(--borde)); }
.turno-asistente { background: var(--papel); }
.turno-quien { font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--tinta-suave); margin-bottom: .3rem; }
.turno-texto { margin: 0; line-height: 1.6; white-space: pre-wrap; }
.turno-pregunta { margin-top: .6rem; padding-left: .7rem; border-left: 2px solid var(--borde); }
.turno-pregunta-q { margin: 0; font-weight: 600; font-size: .9rem; }
.turno-pregunta-porque { margin: .2rem 0 0; line-height: 1.5; }
.turno-respuesta { margin: .3rem 0 0; font-size: .9rem; }
.turno-respuesta-marca { color: var(--acento); font-weight: 700; margin-right: .35rem; }

.seguir { margin-top: 1.2rem; display: grid; gap: .8rem; }
.seguir h3 { margin: 0; font-size: .95rem; }
.seguir label { display: grid; gap: .3rem; font-size: .85rem; font-weight: 600; }
.seguir textarea, .seguir select { width: 100%; }

/* ── LOS TÉRMINOS QUE NO SE ENTIENDEN SOLOS ──────────────────────────── */
/* Con la explicación AL LADO y no en otra página: quien está decidiendo si
   fabricar un aparato no va a irse a buscar qué significa «porEntidad». */
.termino { position: relative; display: inline-flex; align-items: center; gap: .25rem; cursor: help; border-bottom: 1px dotted var(--tinta-suave); }
.termino-marca {
    display: inline-grid; place-items: center; width: 14px; height: 14px; border-radius: 50%;
    background: var(--tinta-suave); color: var(--papel); font-size: 9px; font-weight: 700; line-height: 1;
}
.termino-globo {
    position: absolute; bottom: calc(100% + .5rem); left: 0; z-index: 30;
    width: min(20rem, 70vw); padding: .7rem .8rem; border-radius: .6rem;
    background: var(--tinta); color: var(--papel); box-shadow: var(--sombra);
    font-size: .8rem; line-height: 1.55; font-weight: 400;
    display: none; text-align: left;
}
.termino-globo strong { display: block; margin-bottom: .25rem; }
.termino-globo em { display: block; margin-top: .4rem; font-style: normal; opacity: .85; }
/* Al pasar por encima y también al enfocar con el teclado: quien navega con
   teclado tiene el mismo derecho a saber qué significa. */
.termino:hover .termino-globo, .termino:focus .termino-globo, .termino:focus-within .termino-globo { display: block; }

/* ── LA PROPUESTA ────────────────────────────────────────────────────── */
.propuesta h3 { margin-top: 1.8rem; margin-bottom: .6rem; font-size: 1rem; }
.tabla-ficha th { text-align: left; white-space: nowrap; width: 9rem; }
.razonamiento { padding: .8rem 1rem; border-radius: .6rem; background: var(--papel); border: 1px solid var(--borde); margin-top: 1rem; }
.razonamiento h3 { margin-top: 0; }
.razonamiento p { margin: 0; line-height: 1.65; }

.canal { padding: .7rem .9rem; border: 1px solid var(--borde); border-radius: .6rem; margin-bottom: .55rem; background: var(--papel); }
.canal-cabeza { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.canal-clave { font-size: .78rem; }
.canal-porque { margin: .35rem 0 0; line-height: 1.6; font-size: .9rem; }

.bloque-sinred { padding: .9rem 1rem; border-radius: .6rem; border: 1px solid color-mix(in srgb, var(--atencion) 40%, var(--borde)); background: color-mix(in srgb, var(--atencion) 6%, transparent); margin-top: 1.4rem; }
.bloque-sinred h3 { margin-top: 0; }

.ajuste { padding: .6rem .9rem; border-left: 2px solid var(--acento); margin-bottom: .5rem; }
.ajuste-cabeza { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.avisos { padding-left: 1.1rem; }
.avisos li { margin-bottom: .4rem; line-height: 1.6; }
.avisos .aviso-critico { color: var(--malo); font-weight: 600; }
.avisos .aviso-importante { color: var(--atencion); }

.aprobar { margin-top: 2rem; }

/* ── LOS DIAGRAMAS ───────────────────────────────────────────────────── */
.figura { margin: 1.6rem 0; }
.figura figcaption { font-size: .8rem; font-weight: 600; color: var(--tinta-suave); margin-bottom: .5rem; }
/* Se desborda a lo ancho DENTRO de su caja, nunca la página: un diagrama que
   empuja el cuerpo entero rompe todas las demás pantallas del sitio. */
.figura { overflow-x: auto; }
.diagrama { display: block; width: 100%; min-width: 32rem; height: auto; }
.dg-equipo { fill: color-mix(in srgb, var(--acento) 8%, var(--papel)); stroke: color-mix(in srgb, var(--acento) 35%, var(--borde)); stroke-width: 1.5; }
.dg-caja { fill: var(--papel); stroke: var(--borde); stroke-width: 1.5; }
.dg-titulo { font-size: 13px; font-weight: 600; fill: var(--tinta); }
.dg-sub { font-size: 10.5px; fill: var(--tinta-suave); }
.dg-item { font-size: 11.5px; fill: var(--tinta); }
.dg-mando { fill: var(--acento); }
.dg-linea { stroke: var(--acento); stroke-width: 1.5; color: var(--acento); }
.dg-vuelta { stroke: var(--tinta-suave); color: var(--tinta-suave); stroke-dasharray: 4 3; }
.dg-etiqueta { font-size: 10.5px; fill: var(--tinta-suave); }
.dg-vuelta-texto { fill: var(--tinta-suave); }
.dg-paso { fill: var(--papel); stroke: var(--borde); }
.dg-paso-t { font-size: 11.5px; font-weight: 600; fill: var(--tinta); }
.dg-paso-d { font-size: 10px; fill: var(--tinta-suave); }
.dg-col-titulo { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; fill: var(--tinta-suave); }
.dg-col-arranque { stroke: color-mix(in srgb, var(--acento) 40%, var(--borde)); }
.dg-col-bucle { stroke: color-mix(in srgb, var(--bueno) 40%, var(--borde)); }
.dg-col-evento { stroke: color-mix(in srgb, var(--atencion) 45%, var(--borde)); }
.dg-col-fallo { stroke: color-mix(in srgb, var(--malo) 40%, var(--borde)); }

/* ── MIENTRAS PIENSA ─────────────────────────────────────────────────── */
.pensando {
    display: grid; grid-template-columns: auto 1fr; gap: 1rem 1.2rem; align-items: center;
    padding: 1.1rem 1.3rem; border-radius: .8rem; margin-bottom: 1.6rem;
    border: 1px solid color-mix(in srgb, var(--acento) 30%, var(--borde));
    background: color-mix(in srgb, var(--acento) 5%, var(--papel));
}
.pensando-nota { grid-column: 1 / -1; margin: 0; }
.pensando-titulo { margin: 0 0 .2rem; font-size: 1rem; }
.pensando-que { margin: 0 0 .5rem; color: var(--tinta-suave); font-size: .88rem; }
/* Tres puntos que laten por turnos. Dice «esto está vivo», que es lo único
   honesto que se puede decir sin saber cuánto falta. */
.pensando-luz { display: flex; gap: .3rem; }
.pensando-luz span { width: 8px; height: 8px; border-radius: 50%; background: var(--acento); animation: latir 1.4s ease-in-out infinite; }
.pensando-luz span:nth-child(2) { animation-delay: .2s; }
.pensando-luz span:nth-child(3) { animation-delay: .4s; }
@keyframes latir { 0%, 100% { opacity: .25; transform: scale(.8); } 50% { opacity: 1; transform: scale(1); } }
.pensando-barra { height: 4px; border-radius: 999px; background: color-mix(in srgb, var(--acento) 18%, transparent); overflow: hidden; margin-bottom: .4rem; }
/* Una franja que se desliza, NO un porcentaje: no sabemos cuánto falta, y
   fingirlo sería una mentira con mejor pinta que una ruedita. */
.pensando-barra-vive { width: 32%; height: 100%; border-radius: inherit; background: var(--acento); animation: deslizar 1.6s ease-in-out infinite; }
@keyframes deslizar { 0% { transform: translateX(-110%); } 100% { transform: translateX(320%); } }
@media (prefers-reduced-motion: reduce) {
    .pensando-luz span, .pensando-barra-vive { animation: none; }
    .pensando-barra-vive { width: 100%; opacity: .4; }
}

/* Las instrucciones del diseño: el bloque que se lleva al laboratorio. */
.instrucciones { margin-top: 2rem; padding: 1rem 1.2rem; border-radius: .7rem; border: 1px solid var(--borde); background: var(--papel); }
.instrucciones h3 { margin-top: 0; }
.instrucciones-botones { display: flex; flex-wrap: wrap; gap: .5rem; margin: .8rem 0; align-items: center; }

/* ══ LAS ÓRDENES DE TRABAJO ══════════════════════════════════════════════
 *
 * Una lista que se mira de pie, con la placa en la mesa. Lo que tiene que
 * leerse de un vistazo es **qué está parado y por qué**: eso decide a quién
 * llamar hoy, y por eso es lo único con color.
 */
.orden-fila { border: 1px solid var(--borde); border-radius: .7rem; padding: .85rem 1rem; margin-bottom: .6rem; background: var(--papel); }
.orden-cabeza { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; align-items: baseline; }
.orden-codigo { text-decoration: none; }
.orden-titulo { margin: .3rem 0 .6rem; font-weight: 600; }
.orden-titulo a { color: inherit; text-decoration: none; }
.orden-titulo a:hover, .orden-titulo a:focus-visible { color: var(--acento); }
/* Una barra parada no es una barra a medias: es una barra detenida, y se ve. */
.barra-parada { background: var(--atencion); }
.parada-texto { color: var(--atencion); }

.abrir-orden { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--borde); }
.clases-ayuda { margin-top: 1.2rem; display: grid; gap: .5rem; }
.clases-ayuda dt { font-weight: 600; font-size: .9rem; }
.clases-ayuda dd { margin: 0 0 .3rem; }

.orden-titulo-caja { display: flex; justify-content: space-between; align-items: flex-start; gap: 1.5rem; flex-wrap: wrap; }
.orden-titulo-caja h1 { margin-bottom: .3rem; }
.orden-progreso-num { font-size: 1.9rem; font-weight: 700; margin: 0; line-height: 1; text-align: right; }
.orden-h2 { margin: .4rem 0 1rem; font-size: 1.15rem; font-weight: 600; }

.pasos-trabajo { margin: 1.8rem 0; display: grid; gap: .6rem; }
.paso-trabajo { border: 1px solid var(--borde); border-radius: .7rem; padding: .85rem 1rem; background: var(--papel); }
.paso-trabajo .paso-cabeza { display: grid; grid-template-columns: 1.7rem 1fr; gap: .8rem; align-items: start; margin-bottom: 0; }
.paso-marca {
    display: grid; place-items: center; width: 1.7rem; height: 1.7rem; border-radius: 50%;
    border: 1px solid var(--borde); color: var(--tinta-suave); font-weight: 700; font-size: .85rem; line-height: 1;
}
.paso-hecho .paso-marca { border-color: var(--bueno); color: var(--bueno); }
.paso-detenido .paso-marca { border-color: var(--atencion); color: var(--atencion); }
.paso-en_curso .paso-marca { border-color: var(--acento); color: var(--acento); }
.paso-omitido .paso-marca { border-style: dashed; }
.paso-hecho { opacity: .72; }
.paso-detenido { border-color: color-mix(in srgb, var(--atencion) 45%, var(--borde)); }
.paso-titulo { margin: 0; font-weight: 600; display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.paso-ayuda { margin: .25rem 0 0; line-height: 1.55; }
.paso-motivo { margin: .4rem 0 0; color: var(--atencion); font-size: .9rem; }
.paso-nota { margin: .3rem 0 0; font-size: .9rem; }

.paso-form { margin-top: .7rem; padding-top: .7rem; border-top: 1px dashed var(--borde); display: grid; gap: .5rem; }
.paso-botones { display: flex; gap: .8rem; flex-wrap: wrap; }
.paso-form label { display: grid; gap: .2rem; font-size: .75rem; font-weight: 600; color: var(--tinta-suave); }
.paso-nota-campo input { width: 100%; }

.orden-acciones { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--borde); }
.orden-acciones textarea { width: 100%; max-width: 40rem; display: block; margin-bottom: .5rem; }
.descartar { display: flex; gap: .6rem; align-items: flex-end; flex-wrap: wrap; }
.descartar label { display: grid; gap: .2rem; font-size: .75rem; font-weight: 600; color: var(--tinta-suave); }

/* Las partes de un paso: la costura del almacén del laboratorio. */
.componentes { margin: .7rem 0 0; padding-top: .7rem; border-top: 1px dashed var(--borde); }
.componentes table { font-size: .88rem; }
.componente-form, .componente-anadir { display: flex; gap: .35rem; align-items: center; flex-wrap: wrap; }
.componente-anadir { margin-top: .6rem; }
.componente-anadir input[type="text"] { min-width: 7rem; }
.componente-anadir input[type="number"] { width: 4.5rem; }
.componente-form input, .componente-form select { min-height: 32px; font-size: .8rem; }

/* ── Para soporte: quién es quien mira ─────────────────────────────────── */
.identificacion { margin-top: 1.5rem; }
.identificacion-datos { display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1rem; margin: 1rem 0; }
.identificacion-datos dt { color: var(--tinta-suave); font-size: .9rem; }
.identificacion-datos dd { margin: 0; overflow-wrap: anywhere; }
.identificacion-texto { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .8rem; padding: .75rem; border: 1px solid var(--borde); border-radius: var(--radio); background: var(--fondo); margin: 0 0 .75rem; }
@media (max-width: 560px) { .identificacion-datos { grid-template-columns: 1fr; gap: .1rem; } .identificacion-datos dd { margin-bottom: .5rem; } }

/* Una tabla ancha se desplaza ella sola en el celular; la página no. Sin esto,
   la lista de equipos empujaba toda la pantalla de /admin/dispositivos hacia
   los lados a 390 px. */
@media (max-width: 760px) {
    table.tabla { display: block; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ── Lo que se fabrica y se enseña una vez ─────────────────────────────── */
.fabricado { display: grid; gap: .75rem; padding-top: 1rem; margin-top: 1rem; border-top: 1px solid var(--borde); min-width: 0; }
.fabricado h4 { margin: 0; font-family: ui-monospace, Menlo, Consolas, monospace; }
.fabricado-datos { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: .35rem 1rem; margin: 0; }
.fabricado-datos dt { color: var(--tinta-suave); font-size: .9rem; }
.fabricado-datos dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.fabricado-datos code { overflow-wrap: anywhere; word-break: break-all; }
.fabricado-bloque { display: grid; gap: .4rem; margin-top: .75rem; min-width: 0; }
.fabricado-codigo { max-width: 100%; overflow-x: auto; }
.fabricado-texto:not([hidden]) { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .8rem; }
.fabricado > .boton, .fabricado-bloque > .boton { justify-self: start; }
@media (max-width: 560px) { .fabricado-datos { grid-template-columns: minmax(0, 1fr); gap: .1rem; } .fabricado-datos dd { margin-bottom: .5rem; } }
.acciones-fila { display: flex; flex-wrap: wrap; gap: .5rem .9rem; align-items: center; }
.acciones-fila form { margin: 0; }

/* Un comando con valor, en el banco: el campo y su botón, juntos. */
.banco-con-valor { display: inline-flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.banco-con-valor input { width: 7rem; min-height: 36px; }
.visualmente-oculto { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }


/* ── La barra en el teléfono: un menú, no una nube de enlaces ──────────── */
@media (max-width: 760px) {
    .barra { flex-wrap: wrap; padding: .7rem 1rem; gap: .5rem .75rem; }
    .barra .conexion { order: 1; margin-left: auto; }
    .barra .conexion .texto { display: none; }
    .barra-menu {
        order: 2; display: inline-flex; align-items: center; gap: .45rem;
        min-height: 44px; padding: .4rem .85rem; border-radius: 9px;
        border: 1px solid var(--borde); background: var(--papel); color: var(--tinta);
        font: inherit; font-size: .9rem; font-weight: 600; cursor: pointer;
    }
    .barra-menu-icono, .barra-menu-icono::before, .barra-menu-icono::after {
        display: block; width: 16px; height: 2px; border-radius: 2px; background: currentColor; position: relative;
        transition: transform .15s ease, background .15s ease;
    }
    .barra-menu-icono::before, .barra-menu-icono::after { content: ""; position: absolute; left: 0; }
    .barra-menu-icono::before { top: -5px; }
    .barra-menu-icono::after { top: 5px; }
    .barra.abierta .barra-menu-icono { background: transparent; }
    .barra.abierta .barra-menu-icono::before { transform: translateY(5px) rotate(45deg); }
    .barra.abierta .barra-menu-icono::after { transform: translateY(-5px) rotate(-45deg); }

    .barra-plegable { display: none; order: 3; flex-basis: 100%; flex-direction: column; align-items: stretch; gap: .75rem; padding: .25rem 0 .5rem; }
    .barra.abierta .barra-plegable { display: flex; }
    .barra-nav { flex-direction: column; gap: 0; font-size: 1rem; }
    .barra-nav a { padding: .8rem .25rem; border-bottom: 1px solid var(--borde); color: var(--tinta); }
    .barra-nav a[aria-current="page"] { color: var(--acento); border-bottom-color: var(--borde); font-weight: 600; }
    .barra-nav .selector-cuenta { padding: .6rem 0; }
    .barra-acciones { margin-left: 0; flex-wrap: wrap; gap: .5rem; }
    .barra-acciones .boton-barra { flex: 1 1 auto; justify-content: center; text-align: center; padding: .6rem .8rem; font-size: .9rem; }
}
@media (max-width: 760px) and (prefers-reduced-motion: reduce) {
    .barra-menu-icono, .barra-menu-icono::before, .barra-menu-icono::after { transition: none; }
}

/* ── Casillas y etiquetas: en su sitio en toda la casa ─────────────────── */
/* `input` es ancho completo para los campos de texto, y eso estiraba también
   las casillas: quedaban lejos de su texto, en otra línea. */
input[type="checkbox"], input[type="radio"] {
    width: 1.15rem; height: 1.15rem; margin: 0; padding: 0; flex: none;
    accent-color: var(--acento); vertical-align: middle; cursor: pointer;
}
label:has(> input[type="checkbox"]), label:has(> input[type="radio"]) {
    display: flex; align-items: center; gap: .55rem; color: var(--tinta); font-size: .92rem; cursor: pointer;
}
/* Una cápsula junto a un título, con aire: no pegada a la última letra. */
:is(h1, h2, h3, h4) > .etiqueta { margin-left: .6rem; vertical-align: .2em; font-family: Inter, system-ui, sans-serif; }

/* ── Avisos: cada canal, una tarjeta con principio y fin ───────────────── */
.avisos-altas { margin-top: .75rem; align-items: start; }
.canal-cab { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .75rem; margin-bottom: .75rem; }
.canal-cab h2, .canal-cab h3 { margin: 0; }
.canal-cab > .etiqueta { margin-left: 0; }
.canal-cab .boton { margin-left: auto; }
.canal-ultimo { margin-left: auto; }
.canal-alta p { margin: 0 0 .6rem; }
.canal-qr { display: flex; gap: 1rem; align-items: flex-start; flex-wrap: wrap; }
.canal-qr .qr { flex: none; width: 150px; padding: .4rem; background: #fff; border-radius: 10px; border: 1px solid var(--borde); }
.canal-qr .qr svg { display: block; width: 100%; height: auto; }
.canal-qr > div { flex: 1 1 14rem; }
.canales-lista { display: grid; gap: 1rem; margin-top: .75rem; }
.canal-caido { border-color: color-mix(in srgb, var(--malo) 45%, var(--borde)); }
.canal-grupo { border: 0; padding: 0; margin: 0 0 1rem; min-width: 0; }
.canal-grupo legend { font-weight: 600; font-size: .92rem; color: var(--tinta); padding: 0; margin-bottom: .35rem; }
.canal-grupo > p { margin: 0 0 .6rem; }
.casillas { display: flex; flex-wrap: wrap; gap: .5rem; }
.casilla { margin: 0; padding: .5rem .8rem; border: 1px solid var(--borde); border-radius: 999px; background: var(--fondo); }
.casilla:has(input:checked) { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 8%, var(--papel)); }
.casilla:has(input:focus-visible) { outline: 2px solid var(--acento); outline-offset: 2px; }
.canal-reglas { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: .75rem 1rem; }
.canal-reglas label { margin: 0; }
.canal-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; padding-top: 1rem; border-top: 1px solid var(--borde); }
.canal-acciones form { margin: 0; }
.canal-acciones .canal-quitar { margin-left: auto; }
.bandeja { padding: 0; overflow: hidden; }
.bandeja .tabla { margin: 0; }
.bandeja .tabla th:first-child, .bandeja .tabla td:first-child { padding-left: 1rem; }
@media (max-width: 560px) {
    .canal-acciones { flex-direction: column; align-items: stretch; }
    .canal-acciones .boton, .canal-acciones form, .canal-acciones form .boton { width: 100%; }
    .canal-acciones .canal-quitar { margin-left: 0; }
    .canal-ultimo { margin-left: 0; flex-basis: 100%; }
}
@media (max-width: 760px) {
    /* El botón de menú, a la derecha aunque no haya punto de conexión. */
    .barra-menu { margin-left: auto; }
    .barra .conexion ~ .barra-menu, .barra .boton-ayuda ~ .barra-menu { margin-left: 0; }
    .barra .boton-ayuda { order: 2; width: 2.75rem; height: 2.75rem; }
    .barra .boton-ayuda::before { inset: 0; }
    /* En la parte pública no se pliega: son dos botones de acción y un enlace, y
       «Ver los equipos» escondido detrás de un menú es una venta que no se hace. */
    .zona-website .barra-menu { display: none; }
    .zona-website .barra-plegable { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; padding: 0; }
    .zona-website .barra-nav { flex-direction: row; font-size: .9rem; }
    .zona-website .barra-nav a { padding: .2rem 0; border-bottom: 0; color: var(--tinta-suave); }
    .zona-website .barra-acciones { width: 100%; }
}

/* ── La biblioteca de placas y la parte física de un modelo ────────────── */
.placas-lista { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); margin-top: 1rem; }
.placa-fila { display: grid; gap: .3rem; color: var(--tinta); }
.placa-fila:hover { border-color: var(--acento); text-decoration: none; }
.placa-fila-cab { display: flex; justify-content: space-between; align-items: flex-start; gap: .5rem; }
.placa-fila-cab .etiqueta { flex: none; margin-top: .15rem; }
.etiqueta-placa-probada { border-color: var(--bueno); color: var(--bueno); }
.etiqueta-placa-investigada { border-color: var(--acento); color: var(--acento); }
.etiqueta-placa-borrador { border-color: var(--atencion); color: var(--atencion); }
.placa-form textarea { font-size: .82rem; }
.hardware-rejilla { align-items: start; }
.hardware-texto { min-height: 28rem; font-size: .8rem; line-height: 1.5; tab-size: 2; }
.hardware-yaml { max-height: 40rem; overflow: auto; font-size: .75rem; margin: 0; }
.aviso-atencion { border-color: color-mix(in srgb, var(--atencion) 45%, var(--borde)); background: color-mix(in srgb, var(--atencion) 7%, var(--papel)); }
.aviso ul { margin: .4rem 0 0; padding-left: 1.1rem; }
.parte-fisica summary { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }
.pestanas-biblioteca { display: flex; flex-wrap: wrap; gap: .5rem; margin: .5rem 0 1rem; }
.filtros-biblioteca { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; }
.filtros-biblioteca label { margin: 0; flex: 1 1 12rem; }
.filtros-biblioteca .boton { flex: none; }
.esphome-plataforma { padding: .6rem 0; border-top: 1px solid var(--borde); }
.esphome-plataforma:first-of-type { border-top: 0; }
.esphome-plataforma p { margin: .25rem 0 0; }
.tabla-desplazable { max-width: 100%; overflow-x: auto; }

/* ── Investigar con IA (F090) ─────────────────────────────────────────── */
.investigar-nueva, .investigar-ficha { margin-bottom: 1.25rem; }
.investigar-ficha h3 { margin: 0 0 .35rem; }
.investigar-form { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; margin-top: .5rem; }
.investigar-form label { margin: 0; flex: 1 1 14rem; }
.investigar-form .boton { flex: none; }
.investigar-columna { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
.investigar-columna > .tarjeta { margin: 0; }
.investigar-pendientes { list-style: none; margin: .75rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.investigar-pendientes li { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.investigar-resumen p { line-height: 1.6; }
.investigar-rastro { margin-top: .5rem; }
.investigar-rastro ul { margin: .25rem 0 .5rem; padding-left: 1.1rem; }
.investigar-grupo { margin-bottom: 1.25rem; }
.investigar-todos { display: inline-flex; gap: .4rem; margin-left: auto; }
/* Más específico que `label:has(> input[type="checkbox"])`, que la haría flex. */
.investigar-grupo label.investigar-dato {
    display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .75rem; align-items: start;
    margin: 0; padding: .75rem 0; border-top: 1px solid var(--borde); cursor: pointer; font-weight: 400;
}
.investigar-grupo label.investigar-dato:first-of-type { border-top: 0; }
.investigar-dato > input { margin-top: .2rem; }
.investigar-grupo label.investigar-bloqueado { cursor: default; opacity: .65; }
.investigar-cuerpo { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.investigar-cabeza { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; }
.investigar-fuente { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .35rem; font-size: .82rem; }
.investigar-fuente .enlace { overflow-wrap: anywhere; }
.investigar-ahora { font-size: .85rem; color: var(--tinta-suave); overflow-wrap: anywhere; }
.investigar-ahora .investigar-valor { text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--tinta-suave) 60%, transparent); }
.investigar-propone { overflow-wrap: anywhere; line-height: 1.5; }
.investigar-largo {
    white-space: pre-wrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .8rem;
    background: var(--fondo); border: 1px solid var(--borde); border-radius: 8px; padding: .6rem .75rem;
    max-height: 18rem; overflow: auto;
}
.investigar-motivo { font-size: .8rem; color: var(--atencion); }
.investigar-acciones { position: sticky; bottom: 0; background: var(--fondo); padding: .75rem 0; flex-wrap: wrap; }
.investigar-descartar { margin-top: .5rem; }
/* Lo bloqueado se queda: su valor de ahora no se tacha. */
.investigar-grupo label.investigar-bloqueado .investigar-valor { text-decoration: none; }

/* La placa, al diseñar: se elige delante, no escondida en lo opcional. */
.disenar-placa { display: grid; gap: .3rem; font-size: .85rem; font-weight: 600; }
.disenar-placa select { width: 100%; }
.disenar-placa .apagado, .seguir-placa .apagado { font-weight: 400; margin: 0; }

/* ── Quién entra a esta cuenta (Mi cuenta) ─────────────────────────────── */
.personas { list-style: none; margin: 1rem 0 0; padding: 0; border-top: 1px solid var(--borde); }
.persona {
    display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto; gap: .5rem 1rem;
    align-items: center; padding: .75rem .5rem; border-bottom: 1px solid var(--borde);
}
@media (hover: hover) { .persona:hover { background: color-mix(in srgb, var(--acento) 5%, transparent); } }
.persona-quien, .persona-que { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.persona-quien strong, .persona-quien span { overflow-wrap: anywhere; }
.persona-que .etiqueta { align-self: flex-start; }
.persona-que .apagado, .persona-quien .apagado { font-size: .85rem; }
.persona-accion { justify-self: end; }
.persona-pendiente .persona-quien strong { font-weight: 600; }
.invitar input[type="email"] { min-width: min(18rem, 100%); }
.nota-personas { margin-top: .75rem; font-size: .88rem; max-width: 46rem; }
@media (max-width: 640px) {
    .persona { grid-template-columns: minmax(0, 1fr) auto; }
    .persona-que { grid-column: 1; grid-row: 2; flex-direction: row; flex-wrap: wrap; align-items: center; gap: .5rem; }
    .persona-accion { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
    .invitar, .invitar label, .invitar input, .invitar select, .invitar .boton { width: 100%; }
}
.nota-sin-boton { margin: 0 0 .4rem; font-size: .82rem; max-width: 26rem; }
.personas + h3 { margin-top: 1.75rem; }
.aviso-de-ficha p { margin: .35rem 0 .75rem; } .aviso-de-ficha form { margin: 0; }

/* ── Volver a la app (solo dentro de la app instalada) ─────────────────── */
.volver-a-la-app {
    position: fixed; left: 50%; transform: translateX(-50%);
    bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); z-index: 60;
    display: inline-flex; align-items: center; gap: .35rem; min-height: 44px;
    padding: .55rem 1.1rem; border-radius: 999px; font-weight: 600; font-size: .95rem;
    color: var(--sobre-acento, #fff); background: var(--acento);
    box-shadow: 0 6px 20px color-mix(in srgb, var(--tinta) 25%, transparent);
}
.volver-a-la-app:hover { text-decoration: none; filter: brightness(1.05); }
.volver-a-la-app[hidden] { display: none; }
body.con-volver-a-la-app { padding-bottom: 4.5rem; }
body.modo-pared .volver-a-la-app { display: none; }

/* ── El firmware de un equipo (Administración › ficha) ─────────────────── */
.firmware-compilador { display: flex; align-items: center; gap: .5rem; font-size: .9rem; margin: .5rem 0 1rem; }
.firmware-claves { margin: 1rem 0; padding: 1rem; border: 1px solid var(--borde); border-radius: 12px; background: color-mix(in srgb, var(--tinta) 2%, var(--papel)); }
.firmware-claves details { margin-top: .5rem; }
.firmware-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: .75rem; margin-top: .75rem; align-items: end; }
.firmware-preparar { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin: 1rem 0; }
.firmware-lista { list-style: none; margin: 1rem 0 .5rem; padding: 0; border-top: 1px solid var(--borde); }
.firmware-item {
    display: grid; grid-template-columns: minmax(10rem, 1fr) minmax(8rem, .8fr) minmax(12rem, 1.6fr) auto;
    gap: .5rem 1.25rem; align-items: start; padding: 1rem .25rem; border-bottom: 1px solid var(--borde);
}
.firmware-cuando, .firmware-version { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.firmware-estado p { margin: .4rem 0 0; }
.firmware-acciones { display: flex; flex-direction: column; gap: .45rem; align-items: flex-start; }
.firmware-acciones form, .firmware-acciones p { margin: 0; }
.firmware-aire { color: var(--tinta-suave); }
@media (max-width: 760px) {
    .firmware-item { grid-template-columns: 1fr 1fr; }
    .firmware-estado, .firmware-acciones { grid-column: 1 / -1; }
    .firmware-acciones { flex-direction: row; flex-wrap: wrap; align-items: center; }
}

/* ── LA LISTA DE EQUIPOS: filas, acordeón por sitio y la hoja (15/10/2026) ──
   Era una rejilla de tarjetas de 200–280 px: diez equipos medían 3.460 px en un
   teléfono. Ahora una fila de ~64 px por equipo, los sitios plegables y la hoja
   del equipo que sube desde abajo (a la derecha en lo ancho). `equipos.js`. */
.equipos-herramientas { display: grid; gap: .6rem; margin: .25rem 0 1rem; }
.equipos-buscar input { width: 100%; min-height: 44px; font-size: 1rem; padding-left: 2.4rem;
    background: var(--papel) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") no-repeat .8rem 50% / 1.1rem; }
.equipos-filtros { display: flex; flex-wrap: wrap; gap: .45rem; }
.equipos-filtros .pagina-pestana { cursor: pointer; font: inherit; font-weight: 600; font-size: .9rem; }
.pagina-pestana .contador, .alertas-plegables .contador {
    display: inline-grid; place-items: center; min-width: 1.5rem; height: 1.5rem; padding: 0 .4rem; border-radius: 999px;
    font-size: .78rem; background: color-mix(in srgb, currentColor 14%, transparent);
}
.equipos-nada { text-align: center; color: var(--tinta-suave); padding: 2rem 1rem; }
.grupos-ambito { margin-bottom: 1.25rem; }
.grupos-ambito-titulo { font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--tinta-suave); margin: 0 0 .5rem; }
.grupo-equipos, .lista-sola, .bloque-lista .lista-equipos {
    background: var(--papel); border: 1px solid var(--borde); border-radius: var(--radio); box-shadow: var(--sombra);
    overflow: hidden; margin-bottom: .7rem;
}
.grupo-equipos > summary {
    list-style: none; cursor: pointer; display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; gap: .5rem .6rem;
    align-items: center; min-height: 56px; padding: .7rem 1rem;
}
.grupo-equipos > summary::-webkit-details-marker { display: none; }
@media (hover: hover) { .grupo-equipos > summary:hover { background: color-mix(in srgb, var(--tinta) 3%, var(--papel)); } }
.grupo-equipos > summary:focus-visible { outline: 2px solid var(--acento); outline-offset: -2px; }
.grupo-titulo { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.grupo-titulo strong { font-size: 1.02rem; overflow-wrap: anywhere; }
.grupo-resumen { font-size: .82rem; color: var(--tinta-suave); text-align: right; }
.grupo-malo { color: var(--atencion); font-weight: 600; }
.grupo-flecha { width: 1.15rem; height: 1.15rem; color: var(--tinta-suave); transition: transform .18s; }
.grupo-equipos[open] .grupo-flecha { transform: rotate(180deg); }
.grupo-vacio { margin: 0; padding: .4rem 1rem 1rem; }
.grupo-ir { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; color: var(--acento); border: 1px solid var(--borde); background: var(--papel); }
.grupo-ir svg { width: 1.15rem; height: 1.15rem; }
@media (hover: hover) { .grupo-ir:hover { background: color-mix(in srgb, var(--acento) 10%, var(--papel)); } }
.grupo-nota { margin: .2rem 1rem .9rem; }
.lista-equipos { border-top: 1px solid var(--borde); }
.lista-sola, .bloque-lista .lista-equipos { border-top: 1px solid var(--borde); }
.fila-equipo {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: .8rem; align-items: center;
    min-height: 64px; padding: .6rem .9rem .6rem 1rem; color: var(--tinta); text-decoration: none;
    border-bottom: 1px solid var(--borde); transition: background-color .12s;
}
.fila-equipo:last-child { border-bottom: 0; }
.fila-equipo:hover { text-decoration: none; }
@media (hover: hover) { .fila-equipo:hover { background: color-mix(in srgb, var(--acento) 5%, var(--papel)); } }
.fila-equipo:focus-visible { outline: 2px solid var(--acento); outline-offset: -2px; }
.fila-equipo.latido { background: color-mix(in srgb, var(--acento) 8%, var(--papel)); }
.fila-dibujo { position: relative; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 50%;
    color: var(--acento); background: color-mix(in srgb, var(--acento) 11%, var(--papel)); }
.fila-dibujo .widget-icono { width: 1.35rem; height: 1.35rem; }
.fila-dibujo .punto { position: absolute; right: -1px; bottom: -1px; width: .8rem; height: .8rem; border-radius: 50%; border: 2px solid var(--papel); margin: 0; }
.fila-equipo.equipo-callado .fila-dibujo { color: var(--tinta-suave); background: color-mix(in srgb, var(--tinta) 7%, var(--papel)); }
.fila-texto { min-width: 0; display: grid; gap: .1rem; }
.fila-nombre { font-weight: 600; font-size: .98rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fila-sub, .fila-equipo .equipo-pie { font-size: .82rem; color: var(--tinta-suave); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fila-alerta { color: var(--malo); font-weight: 600; }
.fila-alerta::after { content: ' · '; color: var(--tinta-suave); font-weight: 400; }
.fila-equipo .equipo-pie { display: none; }
.fila-equipo.equipo-callado .equipo-pie { display: block; color: var(--atencion); font-weight: 600; }
.fila-equipo.equipo-callado .fila-sub { display: none; }
.fila-equipo.equipo-callado.con-alerta .fila-sub { display: block; }
.fila-valor { display: grid; justify-items: end; text-align: right; min-width: 0; }
.fila-cifra { display: flex; align-items: baseline; gap: .15rem; font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fila-cifra .metrica-valor { font-size: 1.3rem; }
.fila-cifra .metrica-unidad { font-size: .78rem; font-weight: 600; color: var(--tinta-suave); }
.fila-valor-que { font-size: .72rem; color: var(--tinta-suave); max-width: 6.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fila-equipo.equipo-callado .fila-cifra { color: var(--tinta-suave); }
.fila-oculto { display: none; }
.fila-flecha { width: 1.05rem; height: 1.05rem; color: var(--tinta-suave); }
.alertas-plegables > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .6rem; min-height: 44px; }
.alertas-plegables > summary::-webkit-details-marker { display: none; }
.alertas-plegables > summary h2 { margin: 0; }
.bloque-lista h2 { margin-bottom: .6rem; }

.hoja-velo { position: fixed; inset: 0; z-index: 70; background: color-mix(in srgb, #0f172a 45%, transparent); opacity: 0; transition: opacity .2s; }
.hoja-velo.abierto { opacity: 1; }
.hoja {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 71; max-height: 88vh; display: flex; flex-direction: column;
    background: var(--fondo); color: var(--tinta); border-radius: 20px 20px 0 0; box-shadow: 0 -18px 48px rgba(15, 23, 42, .22);
    transform: translateY(100%); transition: transform .24s ease;
}
.hoja.abierta { transform: none; }
.hoja-asa { width: 44px; height: 5px; border-radius: 999px; background: var(--borde); margin: .55rem auto .2rem; flex: none; }
.hoja-cerrar {
    position: absolute; top: .45rem; right: .6rem; width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--borde);
    background: var(--papel); color: var(--tinta-suave); font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.hoja-cerrar:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.hoja-cuerpo { overflow: auto; padding: .2rem 1rem calc(1.2rem + env(safe-area-inset-bottom, 0px)); -webkit-overflow-scrolling: touch; }
.hoja-cargando { padding: 2rem 0; text-align: center; }
.hoja-cabeza { padding-right: 3rem; margin-bottom: .6rem; }
.hoja-cabeza h2 { margin: .2rem 0 .15rem; font-size: 1.25rem; }
.hoja-cabeza h2:focus { outline: none; }
.hoja-cabeza p { margin: 0; }
.hoja-estado { display: flex; align-items: center; gap: .45rem; margin-top: .35rem !important; font-size: .9rem; font-weight: 600; }
.hoja-estado .punto { margin: 0; }
.hoja-alertas { list-style: none; margin: .5rem 0; padding: 0; display: grid; gap: .4rem; }
.hoja-alertas li { padding: .55rem .75rem; border-radius: 10px; font-size: .88rem; border: 1px solid color-mix(in srgb, var(--malo) 35%, var(--borde)); background: color-mix(in srgb, var(--malo) 6%, var(--papel)); }
.hoja-bloque { margin-top: 1rem; }
.hoja-bloque h3 { margin: 0 0 .5rem; font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; color: var(--tinta-suave); }
.hoja-pie { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.2rem; }
.hoja-pie .boton { min-height: 44px; display: inline-flex; align-items: center; }
@media (min-width: 900px) {
    .hoja { left: auto; top: 0; width: min(32rem, 100%); max-height: none; border-radius: 0; transform: translateX(100%); box-shadow: -18px 0 48px rgba(15, 23, 42, .18); border-left: 1px solid var(--borde); }
    .hoja-asa { display: none; }
    .hoja-cuerpo { padding-top: 1rem; }
}
@media (prefers-reduced-motion: reduce) { .hoja, .hoja-velo, .grupo-flecha { transition: none; } }
/* Dentro de la hoja ya se sabe de qué equipo es cada control. */
.hoja .widget-donde { display: none; }
/* El nombre en dos renglones antes que cortado: «Bomba del tanque de…» no dice cuál. */
.fila-nombre { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.25; overflow-wrap: anywhere; }
@media (max-width: 420px) { .fila-equipo { gap: .65rem; padding-left: .8rem; padding-right: .7rem; } .fila-valor-que { max-width: 5.5rem; } }
/* En lo ancho, dos columnas de filas: una fila de 1.200 px se lee mal. */
@media (min-width: 900px) {
    .lista-equipos { display: grid; grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr)); }
    .lista-equipos .fila-equipo:last-child { border-bottom: 1px solid var(--borde); }
}

/* ── LA HOJA DE UN CONTROL (15/10/2026, `_dev_docs/35`) ─────────────────────
   Tocar una tarjeta del Tablero o de Controles (fuera de su mando) abre su hoja:
   cómo está, lo que pide atención, cómo ha ido, lo que ha pasado y sus funciones. */
.widget[data-abre] { cursor: pointer; }
.widget[data-abre]:focus-visible { outline: 2px solid var(--acento); outline-offset: 3px; }
@media (hover: hover) { .widget[data-abre]:not([draggable="true"]):hover { box-shadow: 0 10px 28px rgba(15, 23, 42, .12); border-color: color-mix(in srgb, var(--acento) 35%, var(--borde)); } }
.widget[draggable="true"] { cursor: grab; }
/* Mantener pulsado: la tarjeta se llena de abajo arriba mientras el dedo sigue. */
.widget[data-mantener] [data-mandar] { -webkit-touch-callout: none; user-select: none; touch-action: manipulation; }
.widget.manteniendo { position: relative; }
.widget.manteniendo::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 100%; border-radius: inherit; pointer-events: none;
    background: color-mix(in srgb, var(--acento) 16%, transparent); transform-origin: bottom; animation: mantener var(--mantener, 1s) linear forwards;
}
@keyframes mantener { from { transform: scaleY(0); } to { transform: scaleY(1); } }
.widget-cuenta { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-top: .5rem; padding: .4rem .6rem; border-radius: 10px; font-weight: 600; font-size: .88rem;
    background: color-mix(in srgb, var(--atencion) 12%, var(--papel)); color: var(--tinta); }

@media (min-width: 900px) { .hoja.hoja-control-de { width: min(38rem, 100%); } }
.control-ahora { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .3rem 1rem; padding: .8rem 1rem; margin: .2rem 0 .4rem;
    border: 1px solid var(--borde); border-radius: 14px; background: var(--papel); }
.control-ahora.con-alerta { border-color: color-mix(in srgb, var(--malo) 45%, var(--borde)); background: color-mix(in srgb, var(--malo) 5%, var(--papel)); }
.control-valor { margin: 0; display: flex; align-items: baseline; gap: .3rem; }
.control-cifra { font-family: 'Outfit', 'Inter', sans-serif; font-weight: 800; font-size: 2.3rem; line-height: 1; letter-spacing: -.02em; }
.control-palabra { font-size: 1.6rem; }
.control-ahora.con-alerta .control-cifra { color: var(--malo); }
.control-unidad { color: var(--tinta-suave); font-weight: 600; }
.control-rango { margin: 0; font-size: .88rem; }
.control-atencion .control-alerta { display: grid; gap: .3rem; padding: .7rem .85rem; border-radius: 12px; margin-bottom: .5rem;
    border: 1px solid color-mix(in srgb, var(--malo) 35%, var(--borde)); background: color-mix(in srgb, var(--malo) 7%, var(--papel)); }
.control-alerta.gravedad-aviso { border-color: color-mix(in srgb, var(--atencion) 40%, var(--borde)); background: color-mix(in srgb, var(--atencion) 8%, var(--papel)); }
.control-alerta .boton { justify-self: start; margin-top: .2rem; }
.control-historia-cabeza { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .5rem; }
.control-historia-cabeza h3 { margin: 0 !important; }
.control-periodos { display: flex; gap: .35rem; }
.control-periodos .pagina-pestana { min-height: 36px; padding: .3rem .7rem; font-size: .82rem; }
#control-grafica { transition: opacity .15s; }
#control-grafica.cargando { opacity: .45; }
.control-grafica { margin: 0; }
.control-grafica-lienzo { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .4rem; align-items: stretch; }
.control-grafica-eje { display: flex; flex-direction: column; justify-content: space-between; font-size: .72rem; color: var(--tinta-suave); text-align: right; padding: .1rem 0; font-variant-numeric: tabular-nums; }
.control-grafica svg, .control-franja svg { width: 100%; height: 170px; display: block; border-radius: 10px; background: color-mix(in srgb, var(--tinta) 3%, var(--papel)); border: 1px solid var(--borde); }
.control-franja svg { height: 34px; }
.control-banda { fill: color-mix(in srgb, var(--bien, #16a34a) 12%, transparent); }
.control-sombra { fill: color-mix(in srgb, var(--acento) 16%, transparent); stroke: none; }
.control-linea { fill: none; stroke: var(--acento); stroke-width: 2.2; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.control-rojos { fill: none; stroke: var(--malo); stroke-width: 7; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.control-franja-fondo { fill: color-mix(in srgb, var(--tinta) 6%, var(--papel)); }
.control-franja-si { fill: var(--acento); }
.control-grafica-marcas { display: flex; justify-content: space-between; font-size: .72rem; color: var(--tinta-suave); margin: .3rem 0 0; padding-left: 2.2rem; }
.control-franja .control-grafica-marcas { padding-left: 0; }
.control-cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(8.5rem, 45%), 1fr)); gap: .5rem; margin: .7rem 0 0; }
.control-cifras div { padding: .5rem .65rem; border-radius: 10px; border: 1px solid var(--borde); background: var(--papel); }
.control-cifras dt { font-size: .72rem; color: var(--tinta-suave); text-transform: uppercase; letter-spacing: .06em; }
.control-cifras dd { margin: .1rem 0 0; font-weight: 700; font-variant-numeric: tabular-nums; }
.control-cifras .malo dd { color: var(--malo); }
.control-sin-historia { padding: 1rem 0; }
.control-pasado h4 { margin: .8rem 0 .3rem; font-size: .85rem; }
.control-lista { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--borde); }
.control-lista li { display: grid; gap: .1rem; padding: .5rem 0; border-bottom: 1px solid var(--borde); font-size: .9rem; }
.control-lista li.fallo .control-lista-que strong { color: var(--malo); }
.control-lista-cuando { font-size: .8rem; color: var(--tinta-suave); }
a.control-lista-que { text-decoration: none; color: var(--tinta); }
@media (hover: hover) { a.control-lista-que:hover strong { color: var(--acento); } }
.control-funcion { border-top: 1px solid var(--borde); }
.control-funcion:last-of-type { border-bottom: 1px solid var(--borde); }
.control-funcion > summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: .6rem; padding: .8rem 0; min-height: 56px; }
.control-funcion > summary::-webkit-details-marker { display: none; }
.control-funcion > summary:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; border-radius: 8px; }
.control-funcion[open] > summary .grupo-flecha { transform: rotate(180deg); }
.control-funcion-texto { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.control-funcion-texto strong { font-size: .98rem; }
.control-funcion-marca { font-size: .74rem; font-weight: 700; color: var(--acento); white-space: nowrap; padding: .15rem .5rem; border-radius: 999px;
    background: color-mix(in srgb, var(--acento) 12%, var(--papel)); border: 1px solid color-mix(in srgb, var(--acento) 35%, var(--borde)); }
.control-funcion-cuerpo { padding: 0 0 1rem; display: grid; gap: .7rem; }
.control-form { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); align-items: end; }
.control-form label { display: grid; gap: .25rem; margin: 0; font-size: .82rem; font-weight: 600; }
.control-form input, .control-form select { min-height: 44px; }
.control-form > .boton, .control-form-botones, .control-form .control-respuesta, .control-form > p, .control-atajos, .control-dias { grid-column: 1 / -1; }
.control-form > .boton { justify-self: start; min-height: 44px; }
.control-form-botones { display: flex; flex-wrap: wrap; gap: .5rem; }
.control-form-botones .boton { min-height: 44px; }
.control-quitar { color: var(--malo) !important; border-color: color-mix(in srgb, var(--malo) 40%, var(--borde)) !important; }
.control-check { display: flex !important; grid-template-columns: none; align-items: center; gap: .55rem !important; font-size: .95rem !important; min-height: 44px; }
.control-check input { min-height: 0; width: 1.25rem; height: 1.25rem; }
.control-atajos { display: flex; flex-wrap: wrap; gap: .4rem; }
.control-atajo { min-height: 36px; padding: .25rem .7rem; border-radius: 999px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta); font: inherit; font-size: .85rem; cursor: pointer; }
.control-atajo.activa { border-color: var(--acento); color: var(--acento); font-weight: 700; }
.control-temporizador { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem; padding: .6rem .8rem; border-radius: 12px;
    border: 1px solid color-mix(in srgb, var(--acento) 35%, var(--borde)); background: color-mix(in srgb, var(--acento) 7%, var(--papel)); }
.control-dias { border: 0; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.control-dias legend { font-size: .82rem; font-weight: 600; margin-bottom: .3rem; width: 100%; }
.control-dia { display: inline-flex !important; align-items: center; justify-content: center; min-width: 3rem; min-height: 40px; padding: 0 .5rem; border-radius: 999px; border: 1px solid var(--borde); background: var(--papel); cursor: pointer; }
.control-dia input { position: absolute; opacity: 0; pointer-events: none; }
.control-dia:has(input:checked) { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 14%, var(--papel)); color: var(--acento); }
.control-dia:has(input:focus-visible) { outline: 2px solid var(--acento); outline-offset: 2px; }
.control-respuesta { margin: 0; font-size: .85rem; color: var(--malo); }
.control-respuesta.bien { color: var(--acento); }
.control-respuesta:empty { display: none; }
@media (prefers-reduced-motion: reduce) { .widget.manteniendo::after { animation-duration: .01s; } }

/* Un temporizador esperando en este control (15/10/2026): el borde late y la
   cuenta atrás va en una píldora, encima del pie. Que se vea que algo va a pasar. */
.widget.con-temporizador { border-color: color-mix(in srgb, var(--acento) 60%, var(--borde)) !important; animation: temporizador-late 2.4s ease-in-out infinite; }
@keyframes temporizador-late {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--acento) 0%, transparent), 0 6px 18px rgba(15, 23, 42, .06); }
    50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--acento) 22%, transparent), 0 6px 18px rgba(15, 23, 42, .06); }
}
.widget-temporizador {
    display: inline-flex; align-items: center; gap: .4rem; align-self: flex-start; margin: .55rem 0 0; padding: .3rem .7rem .3rem .55rem; border-radius: 999px;
    font-size: .82rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--acento);
    background: color-mix(in srgb, var(--acento) 12%, var(--papel)); border: 1px solid color-mix(in srgb, var(--acento) 40%, var(--borde));
}
.widget-temporizador[hidden] { display: none; }
.widget-temporizador svg { flex: none; }
@media (prefers-reduced-motion: reduce) { .widget.con-temporizador { animation: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 22%, transparent); } }
/* Los ajustes se guardan solos: se dice una vez, en pequeño, y la respuesta («✓ Guardado») va justo debajo. */
.control-autoguardado { grid-column: 1 / -1; margin: -.1rem 0 0; font-size: .8rem; color: var(--tinta-suave); }

/* ── ADMINISTRACIÓN: LAS PESTAÑAS DE CADA SECCIÓN Y EL PROYECTO ABIERTO ──────
   (15/10/2026, `_dev_docs/36`). La barra tiene seis secciones; las pestañas de
   la sección van aquí, encima del contenido. */
.admin-pestanas { display: flex; gap: .35rem; flex-wrap: nowrap; overflow-x: auto; margin: -.25rem 0 1.4rem; padding: .3rem; border-radius: 14px;
    background: color-mix(in srgb, var(--tinta) 4%, var(--papel)); border: 1px solid var(--borde); scrollbar-width: none; }
.admin-pestanas::-webkit-scrollbar { display: none; }
.admin-pestana { flex: none; padding: .45rem .9rem; border-radius: 10px; color: var(--tinta-suave); font-weight: 600; font-size: .9rem; white-space: nowrap; min-height: 40px; display: inline-flex; align-items: center; }
.admin-pestana:hover { text-decoration: none; color: var(--tinta); background: var(--papel); }
.admin-pestana[aria-current="page"] { background: var(--papel); color: var(--acento); box-shadow: 0 1px 3px rgba(15, 23, 42, .1); }
.proyecto-franja { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem 1rem; padding: .7rem 1rem; margin: 0 0 1.4rem;
    border-radius: 14px; border: 1px dashed color-mix(in srgb, var(--acento) 55%, var(--borde)); background: color-mix(in srgb, var(--acento) 7%, var(--papel)); }
.proyecto-franja-botones { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.proyecto-franja-botones form { margin: 0; }

/* ── EL DIAGRAMA DE TRES COLUMNAS ── */
.recorrido { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: start; gap: 1.25rem; margin: 1.2rem 0 1.5rem; position: relative; }
.recorrido-columna { position: relative; padding: .9rem; border-radius: 18px; border: 1px solid var(--borde);
    background: radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--tinta-suave) 16%, transparent) 1px, transparent 0) 0 0 / 16px 16px, color-mix(in srgb, var(--tinta) 2%, var(--fondo)); }
/* La flecha entre columnas: el recorrido va de izquierda a derecha. */
.recorrido-columna:not(:last-child)::after { content: ''; position: absolute; top: 1.6rem; right: -1.05rem; width: .85rem; height: .85rem; border-top: 2px solid var(--acento); border-right: 2px solid var(--acento); transform: rotate(45deg); opacity: .7; }
.recorrido-columna.columna-no-aplica { opacity: .55; }
.recorrido-columna-cabeza { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: .2rem .6rem; margin-bottom: .8rem; }
.recorrido-columna-numero { width: 2rem; height: 2rem; border-radius: 50%; display: grid; place-items: center; font-weight: 800; font-size: .9rem; color: var(--acento);
    background: color-mix(in srgb, var(--acento) 13%, var(--papel)); border: 1px solid color-mix(in srgb, var(--acento) 35%, var(--borde)); }
.recorrido-columna-texto { display: flex; flex-direction: column; min-width: 0; }
.recorrido-columna-texto strong { font-size: .8rem; letter-spacing: .12em; text-transform: uppercase; }
.recorrido-columna-texto span { font-size: .8rem; color: var(--tinta-suave); }
.recorrido-columna-barra { grid-column: 1 / -1; height: 5px; border-radius: 999px; background: color-mix(in srgb, var(--tinta) 8%, var(--papel)); overflow: hidden; }
.recorrido-columna-barra span { display: block; height: 100%; background: var(--bueno); border-radius: inherit; }
.recorrido-pasos { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
/* La línea que une un paso con el siguiente. */
.recorrido-li { position: relative; }
.recorrido-li:not(:last-child)::after { content: ''; position: absolute; left: 1.95rem; bottom: -.72rem; height: .72rem; width: 2px; background: var(--borde); }
.recorrido-li.estado-hecho:not(:last-child)::after, .recorrido-li.estado-omitido:not(:last-child)::after { background: color-mix(in srgb, var(--bueno) 60%, var(--borde)); }
.recorrido-paso { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: .7rem; padding: .7rem .8rem; min-height: 64px;
    border-radius: 14px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta); box-shadow: 0 1px 2px rgba(15, 23, 42, .04); transition: border-color .15s, box-shadow .15s, transform .15s; }
.recorrido-paso:hover { text-decoration: none; }
@media (hover: hover) { .recorrido-paso:not(.sin-pantalla):hover { border-color: color-mix(in srgb, var(--acento) 45%, var(--borde)); box-shadow: 0 8px 22px rgba(15, 23, 42, .1); transform: translateY(-1px); } }
.recorrido-paso:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.recorrido-paso.sin-pantalla { cursor: default; border-style: dashed; }
.recorrido-paso-dibujo { position: relative; width: 2.6rem; height: 2.6rem; border-radius: 12px; display: grid; place-items: center; color: var(--acento);
    background: color-mix(in srgb, var(--acento) 11%, var(--papel)); }
.recorrido-paso-check { position: absolute; right: -.35rem; bottom: -.35rem; width: 1.25rem; height: 1.25rem; border-radius: 50%; display: grid; place-items: center; background: var(--bueno); color: #fff; border: 2px solid var(--papel); }
.recorrido-paso-check .paso-icono { width: .8rem; height: .8rem; stroke-width: 3; }
.recorrido-paso-texto { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.recorrido-paso-texto strong { font-size: .95rem; line-height: 1.25; }
.recorrido-paso-estado { font-size: .8rem; color: var(--tinta-suave); }
.recorrido-etiquetas { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .2rem; }
.recorrido-etiqueta { font-size: .68rem; font-weight: 700; padding: .05rem .45rem; border-radius: 999px; border: 1px solid var(--borde); color: var(--tinta-suave); }
.recorrido-sigue { position: absolute; top: -.6rem; right: .7rem; font-size: .7rem; font-weight: 800; letter-spacing: .04em; padding: .12rem .55rem; border-radius: 999px; background: var(--acento); color: var(--papel); }
/* Los estados. */
.recorrido-paso.estado-hecho .recorrido-paso-dibujo { color: var(--bueno); background: color-mix(in srgb, var(--bueno) 12%, var(--papel)); }
.recorrido-paso.estado-hecho .recorrido-paso-estado { color: var(--bueno); font-weight: 600; }
.recorrido-paso.estado-en_curso { border-color: color-mix(in srgb, var(--acento) 45%, var(--borde)); }
.recorrido-paso.estado-en_curso .recorrido-paso-estado { color: var(--acento); font-weight: 600; }
.recorrido-paso.estado-detenido { border-color: color-mix(in srgb, var(--atencion) 60%, var(--borde)); background: color-mix(in srgb, var(--atencion) 7%, var(--papel)); }
.recorrido-paso.estado-detenido .recorrido-paso-dibujo { color: var(--atencion); background: color-mix(in srgb, var(--atencion) 14%, var(--papel)); }
.recorrido-paso.estado-detenido .recorrido-paso-estado { color: var(--atencion); font-weight: 700; }
.recorrido-paso.estado-omitido, .recorrido-paso.estado-no_aplica { border-style: dashed; background: transparent; box-shadow: none; }
.recorrido-paso.estado-omitido .recorrido-paso-texto strong, .recorrido-paso.estado-no_aplica .recorrido-paso-texto strong { color: var(--tinta-suave); font-weight: 600; }
.recorrido-paso.estado-no_aplica .recorrido-paso-dibujo, .recorrido-paso.estado-omitido .recorrido-paso-dibujo { color: var(--tinta-suave); background: color-mix(in srgb, var(--tinta) 5%, transparent); }
.recorrido-paso.estado-bloqueado .recorrido-paso-dibujo { color: var(--tinta-suave); background: color-mix(in srgb, var(--tinta) 6%, var(--papel)); }
.recorrido-paso.es-actual { border-color: var(--acento); box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 20%, transparent), 0 8px 22px rgba(15, 23, 42, .1); }
.recorrido-paso.es-actual.estado-detenido { border-color: var(--atencion); box-shadow: 0 0 0 3px color-mix(in srgb, var(--atencion) 22%, transparent); }
.recorrido-paso.es-actual.estado-detenido .recorrido-sigue { background: var(--atencion); }
@media (max-width: 899px) {
    /* En el teléfono, una línea de tiempo: las columnas una debajo de otra, la flecha hacia abajo. */
    .recorrido { grid-template-columns: 1fr; gap: 1.6rem; }
    .recorrido-columna:not(:last-child)::after { top: auto; bottom: -1.2rem; right: 50%; transform: translateX(50%) rotate(135deg); }
}

/* ── EL PASO QUE SIGUE, Y LA HOJA DE UN PASO ── */
.proyecto-cabeza { margin-bottom: 1rem; }
.proyecto-cabeza h1 { margin: .3rem 0 .3rem; }
.proyecto-codigo { display: flex; align-items: center; gap: .5rem; margin: 0; }
.etiqueta.proyecto-activo { color: var(--acento); border-color: color-mix(in srgb, var(--acento) 40%, var(--borde)); }
.etiqueta.proyecto-detenido { color: var(--atencion); border-color: color-mix(in srgb, var(--atencion) 50%, var(--borde)); }
.etiqueta.proyecto-terminado { color: var(--bueno); border-color: color-mix(in srgb, var(--bueno) 45%, var(--borde)); }
.proyecto-sigue { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .8rem 1.2rem; padding: 1rem 1.2rem; border-radius: 16px;
    border: 1px solid color-mix(in srgb, var(--acento) 40%, var(--borde)); background: linear-gradient(120deg, color-mix(in srgb, var(--acento) 9%, var(--papel)), var(--papel)); }
.proyecto-sigue.estado-detenido { border-color: color-mix(in srgb, var(--atencion) 50%, var(--borde)); background: linear-gradient(120deg, color-mix(in srgb, var(--atencion) 10%, var(--papel)), var(--papel)); }
.proyecto-sigue-texto { display: flex; flex-direction: column; gap: .15rem; min-width: 0; flex: 1 1 18rem; }
.proyecto-sigue-etiqueta { font-size: .72rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--acento); }
.proyecto-sigue.estado-detenido .proyecto-sigue-etiqueta { color: var(--atencion); }
.proyecto-sigue-texto strong { font-size: 1.15rem; }
.proyecto-sigue-botones { display: flex; flex-wrap: wrap; gap: .5rem; }
.proyecto-sigue-botones .boton { min-height: 44px; display: inline-flex; align-items: center; }
.recorrido-panel-columna { margin: 0; font-size: .72rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--acento); }
.recorrido-estado { margin: .2rem 0 0; font-weight: 700; font-size: .9rem; }
.recorrido-estado.estado-hecho { color: var(--bueno); }
.recorrido-estado.estado-detenido { color: var(--atencion); }
.recorrido-estado.estado-en_curso { color: var(--acento); }
.recorrido-estado.estado-pendiente, .recorrido-estado.estado-bloqueado, .recorrido-estado.estado-omitido, .recorrido-estado.estado-no_aplica { color: var(--tinta-suave); }
.recorrido-ayuda { color: var(--tinta); line-height: 1.55; }
.recorrido-sabe { display: grid; gap: .2rem; padding: .7rem .85rem; margin: .8rem 0; border-radius: 12px; border: 1px solid var(--borde); background: var(--papel); }
.recorrido-sabe strong { font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--tinta-suave); }
.recorrido-sabe.por-el-sistema { border-color: color-mix(in srgb, var(--bueno) 40%, var(--borde)); background: color-mix(in srgb, var(--bueno) 6%, var(--papel)); }
.recorrido-sabe.por-el-sistema strong { color: var(--bueno); }
.recorrido-unidades { list-style: none; margin: 0 0 .9rem; padding: 0; border-top: 1px solid var(--borde); }
.recorrido-unidades li { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .3rem 1rem; padding: .5rem 0; border-bottom: 1px solid var(--borde); font-size: .9rem; }
.recorrido-unidades li span { color: var(--tinta-suave); }
.recorrido-unidades li.hecha span { color: var(--bueno); font-weight: 600; }
.recorrido-unidades li.hecha span::before { content: '✓ '; }
.recorrido-marca { font-size: .88rem; padding: .55rem .75rem; border-radius: 10px; background: color-mix(in srgb, var(--tinta) 4%, var(--papel)); }
.recorrido-acciones { display: flex; flex-wrap: wrap; gap: .5rem; margin: .9rem 0 .4rem; }
.recorrido-acciones form { margin: 0; }
.recorrido-acciones .boton { min-height: 44px; }
.recorrido-mas { border-top: 1px solid var(--borde); }
.recorrido-mas summary { cursor: pointer; min-height: 48px; display: flex; align-items: center; font-weight: 600; color: var(--acento); }
.recorrido-form { display: grid; gap: .6rem; padding: 0 0 .9rem; }
.recorrido-form label { display: grid; gap: .25rem; margin: 0; font-size: .85rem; font-weight: 600; }
.recorrido-form .boton { justify-self: start; min-height: 44px; }
@media (min-width: 900px) { .hoja.hoja-paso { width: min(36rem, 100%); } }

/* ── LOS AJUSTES DEL PROYECTO Y EL NUEVO ── */
.proyecto-ajustes > summary, .proyecto-nuevo > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .8rem; }
.proyecto-ajustes > summary::-webkit-details-marker, .proyecto-nuevo > summary::-webkit-details-marker { display: none; }
.proyecto-ajustes > summary h2, .proyecto-nuevo > summary h2 { margin: 0; }
.proyecto-ajustes > summary h2::after, .proyecto-nuevo > summary h2::after { content: ' ▾'; font-size: .8em; color: var(--tinta-suave); }
.proyecto-ajustes[open] > summary h2::after, .proyecto-nuevo[open] > summary h2::after { content: ' ▴'; }
.proyecto-nuevo { padding: 1rem 1.2rem; border-radius: 16px; border: 1px solid var(--borde); background: var(--papel); margin-top: 1rem; }
.proyecto-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); gap: .9rem 1rem; margin-top: 1rem; align-items: start; }
.proyecto-form label { display: grid; gap: .3rem; margin: 0; font-weight: 600; font-size: .9rem; }
.proyecto-form input, .proyecto-form select, .proyecto-form textarea { min-height: 44px; width: 100%; }
.proyecto-form .ancho { grid-column: 1 / -1; }
.proyecto-form [hidden] { display: none !important; }
.proyecto-form fieldset { border: 0; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.proyecto-form legend { font-weight: 600; font-size: .9rem; margin-bottom: .35rem; width: 100%; }
.proyecto-radio { display: inline-flex !important; grid-template-columns: none; align-items: center; gap: .5rem !important; padding: .55rem .9rem; min-height: 44px; border-radius: 12px; border: 1px solid var(--borde); background: var(--papel); cursor: pointer; font-weight: 600; }
.proyecto-radio input { width: auto; min-height: 0; accent-color: var(--acento); }
.proyecto-radio:has(input:checked) { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 9%, var(--papel)); color: var(--acento); }

/* ── LA LISTA ── */
.proyectos-vistas { display: flex; gap: .4rem; flex-wrap: wrap; margin: 1.6rem 0 .8rem; }
.chip-vista { display: inline-flex; align-items: center; gap: .45rem; min-height: 40px; padding: .35rem .85rem; border-radius: 999px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta-suave); font-weight: 600; font-size: .9rem; }
.chip-vista:hover { text-decoration: none; color: var(--tinta); }
.chip-vista[aria-current="page"] { background: var(--acento); border-color: var(--acento); color: var(--papel); }
.chip-vista .contador { min-width: 1.4rem; height: 1.4rem; padding: 0 .35rem; border-radius: 999px; display: inline-grid; place-items: center; font-size: .75rem; background: color-mix(in srgb, var(--tinta) 8%, transparent); }
.chip-vista[aria-current="page"] .contador { background: color-mix(in srgb, var(--papel) 25%, transparent); }
.proyectos-buscar { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; }
.proyectos-buscar label { margin: 0; flex: 1 1 14rem; }
.proyectos-buscar input, .proyectos-buscar select { min-height: 44px; width: 100%; }
.proyectos-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
@media (min-width: 900px) { .proyectos-lista { grid-template-columns: repeat(auto-fill, minmax(26rem, 1fr)); } }
.proyecto-fila { display: grid; gap: .45rem; padding: 1rem 1.1rem; border-radius: 16px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta); height: 100%; transition: border-color .15s, box-shadow .15s; }
.proyecto-fila:hover { text-decoration: none; }
@media (hover: hover) { .proyecto-fila:hover { border-color: color-mix(in srgb, var(--acento) 45%, var(--borde)); box-shadow: 0 8px 22px rgba(15, 23, 42, .08); } }
.proyecto-fila.proyecto-detenido { border-color: color-mix(in srgb, var(--atencion) 45%, var(--borde)); }
.proyecto-fila-cabeza { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.proyecto-fila-cabeza .apagado { margin-left: auto; }
.proyecto-fila-titulo { font-size: 1.05rem; }
.proyecto-fila-para { font-size: .85rem; }
.proyecto-fases { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; margin-top: .2rem; }
.proyecto-fase { display: grid; gap: .25rem; }
.proyecto-fase-nombre { font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-suave); }
.proyecto-fase-riel { height: 6px; border-radius: 999px; background: color-mix(in srgb, var(--tinta) 8%, var(--papel)); overflow: hidden; }
.proyecto-fase-riel span { display: block; height: 100%; background: var(--bueno); border-radius: inherit; }
.proyecto-fase.no-aplica .proyecto-fase-riel { background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--tinta) 6%, transparent) 0 4px, transparent 4px 8px); }
.proyecto-fila-sigue { font-size: .88rem; color: var(--tinta-suave); }
.proyecto-fila-sigue strong { color: var(--tinta); }
.proyecto-fila-sigue .malo { color: var(--atencion); font-weight: 700; }
.mapa-leyenda { display: grid; gap: .5rem; padding: 1rem 1.2rem; border-radius: 14px; border: 1px solid var(--borde); background: var(--papel); font-size: .92rem; }
.mapa-leyenda p { margin: 0; }
@media (prefers-reduced-motion: reduce) { .recorrido-paso { transition: none; } }

/* ── LA PANTALLA DE UN PASO («el taller», `_dev_docs/36`) ─────────────────────
   Una cosa por pantalla, los botones grandes y en orden, y al terminar
   «Siguiente paso». Para quien no ha usado nunca la plataforma. */
.paso-migas { margin-bottom: .6rem; }
.paso-cabeza { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1rem; align-items: start; margin-bottom: 1rem; }
.paso-cabeza h1 { margin: .1rem 0 .4rem; }
.paso-dibujo { width: 3.6rem; height: 3.6rem; border-radius: 16px; display: grid; place-items: center; color: var(--acento); background: color-mix(in srgb, var(--acento) 12%, var(--papel)); }
.paso-dibujo .paso-icono { width: 1.8rem; height: 1.8rem; }
.paso-dibujo.estado-hecho { color: var(--bueno); background: color-mix(in srgb, var(--bueno) 12%, var(--papel)); }
.paso-numero { margin: 0; font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--acento); }
.paso-que { margin: 0; font-size: 1.05rem; line-height: 1.55; color: var(--tinta); max-width: 46rem; }
.paso-recorrido { list-style: none; display: flex; gap: 4px; padding: 0; margin: 0 0 1.4rem; }
.paso-recorrido li { flex: 1; }
.paso-recorrido a { display: block; height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--tinta) 10%, var(--papel)); }
.paso-recorrido li.estado-hecho a, .paso-recorrido li.estado-omitido a { background: var(--bueno); }
.paso-recorrido li.estado-detenido a { background: var(--atencion); }
.paso-recorrido li.aqui a { background: var(--acento); box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 25%, transparent); }
.paso-listo { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1rem; padding: 1rem 1.2rem; border-radius: 16px; margin-bottom: 1.2rem;
    border: 1px solid color-mix(in srgb, var(--bueno) 45%, var(--borde)); background: color-mix(in srgb, var(--bueno) 8%, var(--papel)); }
.paso-listo > div { flex: 1 1 16rem; display: flex; flex-direction: column; gap: .15rem; }
.paso-listo-check { width: 2.4rem; height: 2.4rem; border-radius: 50%; display: grid; place-items: center; background: var(--bueno); color: #fff; }
.paso-listo-check .paso-icono { stroke-width: 3; }
.paso-siguiente { min-height: 48px; display: inline-flex; align-items: center; font-size: 1rem; }
.paso-espera { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem; padding: .9rem 1.1rem; border-radius: 14px; margin-bottom: 1.2rem;
    border: 1px solid color-mix(in srgb, var(--atencion) 45%, var(--borde)); background: color-mix(in srgb, var(--atencion) 8%, var(--papel)); }
.paso-espera span { flex: 1 1 14rem; }
.paso-taller { display: grid; gap: 1rem; max-width: 52rem; }
.paso-taller > p { margin: 0; font-size: 1.02rem; line-height: 1.55; }
.paso-sub { font-size: 1.05rem; margin: .6rem 0 0; }
.paso-form { display: grid; gap: .8rem; }
.paso-form label { display: grid; gap: .3rem; margin: 0; }
.paso-form input:not([type="radio"]):not([type="checkbox"]), .paso-form textarea, .paso-form select { min-height: 48px; width: 100%; font-size: 1rem; }
.paso-etiqueta { font-weight: 700; font-size: .98rem; }
.paso-pista { font-size: .9rem; color: var(--tinta-suave); line-height: 1.5; margin: 0; }
.boton.boton-grande { min-height: 52px; padding: .75rem 1.4rem; font-size: 1.05rem; justify-self: start; display: inline-flex; align-items: center; }
.paso-cuantas { max-width: 12rem; }
.paso-opciones { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr)); }
.paso-opcion { display: flex !important; align-items: center; gap: .7rem !important; padding: .8rem .9rem; min-height: 60px; border-radius: 14px; border: 1px solid var(--borde); background: var(--papel); cursor: pointer; }
.paso-opcion input { width: 1.2rem; height: 1.2rem; accent-color: var(--acento); flex: none; }
.paso-opcion:has(input:checked) { border-color: var(--acento); background: color-mix(in srgb, var(--acento) 8%, var(--papel)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 18%, transparent); }
.paso-opcion-texto { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.paso-opcion-texto span { font-size: .82rem; color: var(--tinta-suave); }
.paso-elegida, .paso-tarjeta { display: flex; gap: .8rem; align-items: center; padding: .9rem 1rem; border-radius: 14px; border: 1px solid var(--borde); background: var(--papel); }
.paso-tarjeta { flex-direction: column; align-items: flex-start; gap: .3rem; }
.paso-tarjeta ul { margin: .3rem 0; padding-left: 1.2rem; }
.paso-elegida > div { display: flex; flex-direction: column; gap: .1rem; }
.paso-elegida > div span { color: var(--tinta-suave); font-size: .9rem; }
.paso-elegida .paso-icono { color: var(--acento); flex: none; }
.paso-mas { border-top: 1px solid var(--borde); }
.paso-mas summary { cursor: pointer; min-height: 48px; display: flex; align-items: center; font-weight: 600; color: var(--acento); }
.paso-mas > .paso-form { padding-bottom: 1rem; }
.paso-lista, .paso-unidades { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--borde); }
.paso-lista li, .paso-unidades li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .4rem 1rem; padding: .7rem 0; border-bottom: 1px solid var(--borde); }
.paso-unidades li > span { flex: 1 1 12rem; color: var(--tinta-suave); }
.paso-unidades li.hecha > span { color: var(--bueno); font-weight: 600; }
.paso-unidades li.hecha > span::before { content: '✓ '; }
.paso-serie { font-size: 1rem; font-weight: 700; }
.paso-trabajando { display: flex; align-items: center; gap: .8rem; padding: .8rem 1rem; border-radius: 12px; background: color-mix(in srgb, var(--acento) 8%, var(--papel)); border: 1px solid color-mix(in srgb, var(--acento) 30%, var(--borde)); }
.paso-trabajando div { display: flex; flex-direction: column; gap: .1rem; }
.paso-girando { width: 1.4rem; height: 1.4rem; border-radius: 50%; border: 3px solid color-mix(in srgb, var(--acento) 25%, transparent); border-top-color: var(--acento); animation: girar 1s linear infinite; flex: none; }
@keyframes girar { to { transform: rotate(360deg); } }
.paso-error { white-space: pre-wrap; font-size: .8rem; max-height: 10rem; overflow: auto; background: color-mix(in srgb, var(--tinta) 5%, var(--papel)); padding: .6rem; border-radius: 8px; }
.paso-unidad { border: 1px solid var(--borde); border-radius: 16px; background: var(--papel); padding: 1rem 1.1rem; }
.paso-unidad > header { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin-bottom: .6rem; }
.paso-numerado { list-style: none; counter-reset: paso; margin: 0; padding: 0; display: grid; gap: .8rem; }
.paso-numerado > li { counter-increment: paso; position: relative; padding: .2rem 0 .2rem 2.6rem; display: grid; gap: .45rem; justify-items: start; }
.paso-numerado > li::before { content: counter(paso); position: absolute; left: 0; top: 0; width: 1.9rem; height: 1.9rem; border-radius: 50%; display: grid; place-items: center; font-weight: 800; font-size: .9rem;
    color: var(--tinta-suave); background: color-mix(in srgb, var(--tinta) 7%, var(--papel)); border: 1px solid var(--borde); }
.paso-numerado > li.ahora::before { color: var(--papel); background: var(--acento); border-color: var(--acento); }
.paso-numerado > li.hecho::before { content: '✓'; color: #fff; background: var(--bueno); border-color: var(--bueno); }
.paso-numerado > li.hecho > strong { color: var(--tinta-suave); }
.paso-numerado .malo { color: var(--malo); margin: 0; }
.paso-etiquetas { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr)); }
.paso-etiqueta-caja { display: flex; flex-direction: column; gap: .1rem; padding: 1rem; border-radius: 12px; border: 2px dashed var(--borde); background: var(--papel); }
.paso-etiqueta-caja span { font-size: .78rem; color: var(--tinta-suave); }
.paso-etiqueta-marca { font-weight: 700; color: var(--acento) !important; margin-bottom: .3rem; }
.paso-etiqueta-grande { font-family: ui-monospace, monospace; font-size: 1.5rem; letter-spacing: .08em; margin-bottom: .3rem; }
.paso-etiqueta-pie { margin-top: .3rem; }
.paso-mensaje { padding: 1rem; border-radius: 14px; border: 1px solid var(--borde); background: var(--papel); display: grid; gap: .8rem; }
.paso-mensaje p { margin: 0; line-height: 1.55; }
.paso-mensaje-botones { display: flex; flex-wrap: wrap; gap: .5rem; }
.paso-mensaje-botones .boton { min-height: 44px; display: inline-flex; align-items: center; }
.paso-cierre { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: 1.4rem 0 0; max-width: 52rem; }
.paso-cierre form { margin: 0; }
.paso-cierre .paso-mas { flex-basis: 100%; }
.paso-pie { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem; margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--borde); }
.paso-pie .boton { min-height: 44px; display: inline-flex; align-items: center; }
.paso-pie-diagrama { font-weight: 600; }
@media (max-width: 599px) { .paso-pie { flex-direction: column; align-items: stretch; text-align: center; } .paso-pie .boton { justify-content: center; } }
@media (prefers-reduced-motion: reduce) { .paso-girando { animation-duration: 3s; } }
/* Imprimir las etiquetas: solo las etiquetas. */
@media print {
    body:has(.paso-etiquetas) * { visibility: hidden; }
    .paso-etiquetas, .paso-etiquetas * { visibility: visible; }
    .paso-etiquetas { position: absolute; left: 0; top: 0; width: 100%; }
    .paso-etiqueta-caja { break-inside: avoid; border-color: #000; }
}
.paso-taller[hidden] { display: none; }
.paso-anterior::before { content: '←'; margin-right: .45rem; }
.paso-proximo::after { content: '→'; margin-left: .45rem; }

/* ── EL JSON, BIEN VISTO Y BIEN ESCRITO (16/10/2026, norma de la casa) ───────
   El visor (`parciales/_json.pug`) y el editor (`publico/js/json.js`). Colores
   por tipo que funcionan en claro y en oscuro. */
:root {
    --json-clave: #7c3aed; --json-texto: #0f7b55; --json-numero: #1d4ed8; --json-booleano: #b45309; --json-nulo: #94a3b8; --json-puntuacion: #64748b;
    --json-fondo: color-mix(in srgb, var(--tinta) 3%, var(--papel));
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --json-clave: #c4b5fd; --json-texto: #6ee7b7; --json-numero: #93c5fd; --json-booleano: #fcd34d; --json-nulo: #64748b; --json-puntuacion: #94a3b8; } }
:root[data-theme="dark"] { --json-clave: #c4b5fd; --json-texto: #6ee7b7; --json-numero: #93c5fd; --json-booleano: #fcd34d; --json-nulo: #64748b; --json-puntuacion: #94a3b8; }
.json-visor, .json-editor { border: 1px solid var(--borde); border-radius: 14px; background: var(--json-fondo); overflow: hidden; }
.json-barra { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .8rem; padding: .5rem .7rem; border-bottom: 1px solid var(--borde); background: var(--papel); }
.json-titulo { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .85rem; }
.json-tamano, .json-estado { font-size: .8rem; color: var(--tinta-suave); }
.json-estado.bien { color: var(--bueno); font-weight: 600; }
.json-estado.mal { color: var(--malo); font-weight: 700; }
.json-botones { display: flex; flex-wrap: wrap; gap: .3rem; margin-left: auto; }
.json-boton { min-height: 34px; padding: .2rem .7rem; border-radius: 8px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta); font: inherit; font-size: .8rem; font-weight: 600; cursor: pointer; }
.json-boton:hover { border-color: var(--acento); color: var(--acento); }
.json-boton[aria-pressed="true"] { background: color-mix(in srgb, var(--acento) 12%, var(--papel)); border-color: var(--acento); color: var(--acento); }
.json-arbol { padding: .6rem .8rem .8rem; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .84rem; line-height: 1.7; overflow-x: auto; max-height: 36rem; overflow-y: auto; }
.json-arbol details.json-nodo > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: baseline; gap: .3rem; border-radius: 6px; padding: 0 .3rem 0 0; }
.json-arbol details.json-nodo > summary::-webkit-details-marker { display: none; }
.json-arbol details.json-nodo > summary::before { content: '▸'; display: inline-block; width: 1rem; color: var(--tinta-suave); transition: transform .12s; }
.json-arbol details.json-nodo[open] > summary::before { transform: rotate(90deg); }
.json-arbol details.json-nodo > summary:hover { background: color-mix(in srgb, var(--acento) 8%, transparent); }
.json-arbol details.json-nodo[open] > summary .json-resumen, .json-arbol details.json-nodo[open] > summary .json-llave-cierre { display: none; }
.json-hijos { list-style: none; margin: 0 0 0 .45rem; padding: 0 0 0 .9rem; border-left: 1px dashed color-mix(in srgb, var(--tinta-suave) 35%, transparent); }
.json-hoja { padding-left: 1rem; }
.json-clave { color: var(--json-clave); }
.json-indice { color: var(--json-puntuacion); }
.json-dos { color: var(--json-puntuacion); margin-right: .35rem; }
.json-texto { color: var(--json-texto); word-break: break-word; }
.json-numero { color: var(--json-numero); }
.json-booleano { color: var(--json-booleano); font-weight: 600; }
.json-nulo { color: var(--json-nulo); font-style: italic; }
.json-llave, .json-llave-cierre, .json-puntuacion { color: var(--json-puntuacion); }
.json-resumen { color: var(--tinta-suave); font-family: Inter, system-ui, sans-serif; font-size: .78rem; padding: 0 .35rem; border-radius: 999px; background: color-mix(in srgb, var(--tinta) 6%, transparent); }
/* El editor: el texto se escribe en un textarea transparente encima del texto pintado. */
.json-lienzo { position: relative; }
.json-lienzo[hidden] { display: none; }
.json-color, .json-lienzo textarea.json-escribir { margin: 0; padding: .75rem .9rem; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .84rem; line-height: 1.6; white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere; tab-size: 2; letter-spacing: normal; }
.json-color { position: absolute; inset: 0; overflow: hidden; pointer-events: none; color: var(--tinta); }
.json-lienzo textarea.json-escribir { position: relative; display: block; width: 100%; min-height: 6rem; resize: vertical; border: 0; border-radius: 0; background: transparent; color: transparent; caret-color: var(--tinta); outline: none; overflow: hidden; }
.json-lienzo textarea.json-escribir::selection { background: color-mix(in srgb, var(--acento) 30%, transparent); color: transparent; }
.json-editor:focus-within { border-color: var(--acento); box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 18%, transparent); }
.json-editor.con-error { border-color: var(--malo); }
.json-editor[hidden] { display: none; }

/* ── LOS MODELOS: la lista, su página y su editor (16/10/2026) ── */
.modelos-buscar { display: block; margin: .4rem 0 1rem; max-width: 34rem; }
.modelos-buscar input { min-height: 46px; width: 100%; }
.modelos-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; grid-template-columns: repeat(auto-fill, minmax(min(24rem, 100%), 1fr)); }
.modelos-lista li[hidden] { display: none; }
.modelo-fila { display: grid; gap: .35rem; height: 100%; padding: 1rem 1.1rem; border-radius: 16px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta); transition: border-color .15s, box-shadow .15s; }
.modelo-fila:hover { text-decoration: none; }
@media (hover: hover) { .modelo-fila:hover { border-color: color-mix(in srgb, var(--acento) 45%, var(--borde)); box-shadow: 0 8px 22px rgba(15, 23, 42, .08); background: color-mix(in srgb, var(--acento) 3%, var(--papel)); } }
.modelo-fila.descontinuado { opacity: .7; }
.modelo-fila-cabeza { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.modelo-fila-cabeza strong { font-size: 1.05rem; }
.modelo-fila-clave { color: var(--tinta-suave); font-size: .82rem; }
.modelo-fila-desc { font-size: .88rem; color: var(--tinta-suave); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.modelo-fila-datos { display: flex; flex-wrap: wrap; gap: .2rem .9rem; font-size: .84rem; color: var(--tinta-suave); }
.modelo-fila-marcas { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .2rem; }
.marca-estado { display: inline-flex; align-items: center; gap: .3rem; padding: .12rem .55rem; border-radius: 999px; font-size: .75rem; font-weight: 700; border: 1px solid var(--borde); color: var(--tinta-suave); background: var(--papel); }
.marca-estado::before { content: ''; width: .45rem; height: .45rem; border-radius: 50%; background: currentColor; }
.marca-estado.bien { color: var(--bueno); border-color: color-mix(in srgb, var(--bueno) 40%, var(--borde)); }
.marca-estado.atencion { color: var(--atencion); border-color: color-mix(in srgb, var(--atencion) 45%, var(--borde)); }
.marca-estado.mal { color: var(--malo); border-color: color-mix(in srgb, var(--malo) 45%, var(--borde)); }
.modelo-sub { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin: .1rem 0 .4rem; }
.modelo-acciones { display: flex; flex-wrap: wrap; gap: .5rem; }
.modelo-acciones .boton { min-height: 44px; display: inline-flex; align-items: center; }
.modelo-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr)); gap: .6rem; margin: 1rem 0 0; }
.modelo-datos div { padding: .7rem .85rem; border-radius: 12px; border: 1px solid var(--borde); background: var(--papel); }
.modelo-datos dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .07em; color: var(--tinta-suave); }
.modelo-datos dd { margin: .15rem 0 0; font-weight: 600; }
h2 > .contador { display: inline-grid; place-items: center; min-width: 1.6rem; height: 1.6rem; padding: 0 .4rem; margin-left: .4rem; border-radius: 999px; font-size: .8rem; vertical-align: .15em; background: color-mix(in srgb, var(--tinta) 8%, transparent); color: var(--tinta-suave); font-family: Inter, system-ui, sans-serif; }
.modelo-requisitos { margin: .4rem 0 0; padding-left: 1.2rem; line-height: 1.7; }
.tabla-apilable td .marca-estado { margin: 0 .25rem .2rem 0; }
@media (hover: hover) { .tabla-apilable tbody tr:hover { background: color-mix(in srgb, var(--acento) 5%, transparent); } }
/* En el teléfono, cada fila de la tabla es una tarjeta con el nombre de cada dato. */
@media (max-width: 699px) {
    .tabla-apilable thead { display: none; }
    .tabla-apilable, .tabla-apilable tbody, .tabla-apilable tr, .tabla-apilable td { display: block; width: 100%; }
    .tabla-apilable tr { border: 1px solid var(--borde); border-radius: 12px; padding: .5rem .7rem; margin-bottom: .6rem; background: var(--papel); }
    .tabla-apilable td { border: 0; padding: .25rem 0; display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: .5rem; }
    .tabla-apilable td::before { content: attr(data-titulo); font-size: .75rem; font-weight: 700; color: var(--tinta-suave); text-transform: uppercase; letter-spacing: .05em; }
}
.modelo-form { display: grid; gap: 1.4rem; }
.modelo-seccion { padding: 1.1rem 1.2rem; border-radius: 16px; border: 1px solid var(--borde); background: var(--papel); display: grid; gap: .7rem; }
.modelo-seccion > h2 { margin: 0; }
.modelo-seccion > p { margin: 0; }
.modelo-rejilla { display: grid; gap: .8rem 1rem; grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr)); }
.modelo-rejilla label { display: grid; gap: .3rem; margin: 0; font-weight: 600; font-size: .9rem; }
.modelo-rejilla .ancho { grid-column: 1 / -1; }
.modelo-rejilla input, .modelo-rejilla select, .modelo-rejilla textarea { min-height: 44px; width: 100%; }
.modelo-rejilla textarea { font-family: inherit; font-size: .95rem; }
.modelo-rejilla input[readonly] { background: color-mix(in srgb, var(--tinta) 4%, var(--papel)); color: var(--tinta-suave); }
.modelo-pista { font-weight: 400; font-size: .8rem; color: var(--tinta-suave); }
.filas-lista { display: grid; gap: .7rem; }
.filas-lista[hidden] { display: none; }
.filas-vacio { margin: 0; padding: 1rem; text-align: center; border: 1px dashed var(--borde); border-radius: 12px; }
.fila-modelo { border: 1px solid var(--borde); border-radius: 14px; padding: .8rem .9rem; background: var(--json-fondo); }
.fila-modelo > header { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; margin-bottom: .6rem; }
.fila-num { width: 1.6rem; height: 1.6rem; border-radius: 50%; display: grid; place-items: center; font-size: .78rem; font-weight: 800; color: var(--acento); background: color-mix(in srgb, var(--acento) 12%, var(--papel)); }
.fila-titulo { font-size: .98rem; }
.fila-clave { color: var(--tinta-suave); font-size: .8rem; }
.fila-botones { margin-left: auto; display: flex; gap: .3rem; }
.fila-boton { min-width: 36px; min-height: 36px; padding: .2rem .6rem; border-radius: 9px; border: 1px solid var(--borde); background: var(--papel); color: var(--tinta); font: inherit; font-weight: 700; cursor: pointer; }
.fila-boton:disabled { opacity: .35; cursor: default; }
.fila-boton.fila-quitar { color: var(--malo); font-weight: 600; font-size: .85rem; }
.fila-campos { display: grid; gap: .6rem .8rem; grid-template-columns: repeat(auto-fill, minmax(min(11rem, 100%), 1fr)); }
.fila-campo { display: grid; gap: .25rem; margin: 0; font-size: .8rem; font-weight: 600; color: var(--tinta-suave); }
.fila-campo[hidden], .fila-casilla[hidden] { display: none; }
.fila-campo input, .fila-campo select { min-height: 42px; width: 100%; font-size: .92rem; color: var(--tinta); }
.fila-casilla { grid-column: 1 / -1; display: flex; align-items: center; gap: .55rem; margin: 0; font-size: .9rem; min-height: 40px; }
.fila-casilla input { width: 1.15rem; height: 1.15rem; accent-color: var(--acento); }
.fila-mas { margin-top: .6rem; }
.fila-mas > summary { cursor: pointer; font-size: .85rem; font-weight: 600; color: var(--acento); min-height: 36px; display: flex; align-items: center; }
.filas-barra { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .8rem; }
.filas-barra .boton { min-height: 44px; }
.filas-modo { min-height: 40px; padding: .3rem .8rem; border-radius: 10px; border: 1px dashed color-mix(in srgb, var(--acento) 45%, var(--borde)); background: transparent; color: var(--acento); font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer; }
.filas-modo:hover { background: color-mix(in srgb, var(--acento) 8%, transparent); }
.filas-deshacer { font-size: .88rem; color: var(--tinta-suave); }
.modelo-guardar { display: flex; flex-wrap: wrap; gap: .6rem; position: sticky; bottom: 0; padding: .8rem 0; background: linear-gradient(to top, var(--fondo) 70%, transparent); z-index: 5; }
.modelo-guardar .boton { min-height: 48px; display: inline-flex; align-items: center; }

/* ── CÓMO SE CONECTA (`admin/_conexionado.pug`, `_dev_docs/38`) ─────────── */
.montaje { margin-top: 2.5rem; padding: 1.25rem; border: 1px solid var(--borde); border-radius: var(--radio); background: var(--papel); box-shadow: var(--sombra); }
.montaje-cabeza { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: .75rem 1rem; }
.montaje-cabeza h2 { margin: 0; }
.montaje-estado { margin: .35rem 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.montaje-acciones, .montaje-pie { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.montaje-pie { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--borde); }
.montaje-pie form { margin: 0; }
.montaje-pie p { flex-basis: 100%; margin: .25rem 0 0; }
.montaje-explica { color: var(--tinta-suave); margin: .75rem 0 1rem; max-width: 70ch; }
.montaje-dibujo { overflow-x: auto; border-radius: 12px; border: 1px solid var(--borde); background: color-mix(in srgb, var(--fondo) 70%, var(--papel)); padding: .5rem; -webkit-overflow-scrolling: touch; }
.montaje-dibujo:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.montaje-svg { display: block; width: 100%; min-width: 760px; height: auto; font-family: inherit; }
.montaje-svg .cx-placa { fill: #0f3b2e; stroke: #0a2a21; stroke-width: 1.5; }
.montaje-svg .cx-placa-nombre { fill: #fff; font-weight: 700; font-size: 14px; }
.montaje-svg .cx-placa-sub { fill: #a7f3d0; font-size: 12px; }
.montaje-svg .cx-pata { fill: #e2e8f0; stroke: #94a3b8; }
.montaje-svg .cx-pata-texto { font-size: 11px; font-weight: 700; fill: #0f172a; }
.montaje-svg .cx-gpio { font-size: 11px; fill: #ecfdf5; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.montaje-svg .cx-caja { fill: var(--papel); stroke: var(--borde); stroke-width: 1.5; }
.montaje-svg .cx-nombre { fill: var(--tinta); font-weight: 700; font-size: 13px; }
.montaje-svg .cx-pin { fill: var(--tinta-suave); font-size: 12px; }
.montaje-svg .cx-riel { font-size: 11px; font-weight: 700; }
.montaje-svg .cx-extra-caja { fill: var(--papel); stroke-width: 1.6; }
.montaje-svg .cx-extra-texto { fill: var(--tinta); font-size: 11px; font-weight: 700; }
.montaje-leyenda { list-style: none; display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; padding: 0; margin: .65rem 0 0; font-size: .85rem; color: var(--tinta-suave); }
.montaje-leyenda li { display: inline-flex; align-items: center; gap: .4rem; }
.montaje-color { width: 18px; height: 4px; border-radius: 2px; display: inline-block; }
.montaje-color-senal { background: linear-gradient(90deg, #2563eb 0 33%, #16a34a 33% 66%, #9333ea 66%); }
.montaje-alimentar { margin-top: 1rem; padding: .75rem 1rem; border-radius: 10px; border-left: 3px solid #f97316; background: color-mix(in srgb, #f97316 7%, var(--papel)); }
.montaje-alimentar p { margin: .25rem 0 0; }
.montaje-columnas { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 1.5rem 2rem; margin-top: 1.25rem; }
.montaje-columnas h3 { margin: 0 0 .6rem; font-size: 1rem; display: flex; align-items: center; gap: .4rem; }
.montaje-columnas h3 + * { margin-top: 0; }
.montaje-columnas > div > h3:not(:first-child) { margin-top: 1.25rem; }
@media (max-width: 820px) { .montaje-columnas { grid-template-columns: minmax(0, 1fr); } }
.montaje-cables { list-style: none; counter-reset: cable; padding: 0; margin: 0; border-top: 1px solid var(--borde); }
.montaje-cables > li { counter-increment: cable; border-bottom: 1px solid var(--borde); }
.montaje-cables > li > .montaje-cable-texto, .montaje-tachar { display: flex; align-items: center; gap: .65rem; padding: .55rem .35rem; }
.montaje-cables:not(.montaje-cables-tachar) > li > .montaje-cable-texto::before { content: counter(cable); min-width: 1.6rem; height: 1.6rem; border-radius: 999px; display: inline-grid; place-items: center; font-size: .75rem; font-weight: 700; background: var(--fondo); color: var(--tinta-suave); flex: none; }
.montaje-cable-texto { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.montaje-cable-texto > span:last-child { min-width: 0; overflow-wrap: anywhere; }
.montaje-hilo { width: 22px; height: 5px; border-radius: 3px; flex: none; }
.montaje-cables form { margin: 0; }
.montaje-tachar { width: 100%; text-align: left; background: none; border: 0; color: inherit; font: inherit; cursor: pointer; border-radius: 8px; }
@media (hover: hover) { .montaje-cables > li:hover { background: color-mix(in srgb, var(--acento) 6%, transparent); } }
.montaje-tachar:focus-visible { outline: 2px solid var(--acento); outline-offset: -2px; }
.montaje-casilla { width: 1.35rem; height: 1.35rem; border-radius: 6px; border: 2px solid var(--borde); flex: none; display: inline-grid; place-items: center; transition: background .15s, border-color .15s; }
.montaje-cables > li.hecho .montaje-casilla { background: var(--bueno); border-color: var(--bueno); }
.montaje-cables > li.hecho .montaje-casilla::after { content: ''; width: .35rem; height: .65rem; border: solid #fff; border-width: 0 2.5px 2.5px 0; transform: translateY(-1px) rotate(45deg); }
.montaje-cables > li.hecho .montaje-cable-texto > span:last-child { text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--tinta) 45%, transparent); color: var(--tinta-suave); }
.montaje-progreso { margin: 0 0 .35rem; }
.montaje-barra { display: block; height: 6px; border-radius: 3px; background: var(--fondo); border: 1px solid var(--borde); overflow: hidden; margin-bottom: .75rem; }
.montaje-barra > span { display: block; height: 100%; background: var(--bueno); transition: width .2s; }
.montaje-completa .montaje-progreso::after { content: ' · ¡Todos conectados!'; color: var(--bueno); font-weight: 700; }
.montaje-materiales, .montaje-avisos { list-style: none; padding: 0; margin: 0; }
.montaje-materiales li { display: flex; gap: .6rem; padding: .45rem 0; border-bottom: 1px solid var(--borde); }
.montaje-cuantos { min-width: 2.4rem; font-weight: 700; color: var(--acento); font-variant-numeric: tabular-nums; }
.montaje-porque { display: block; font-size: .85rem; color: var(--tinta-suave); font-weight: 400; margin-top: .1rem; }
.montaje-avisos li { position: relative; padding: .4rem 0 .4rem 1.2rem; font-size: .92rem; }
.montaje-avisos li::before { content: ''; position: absolute; left: 0; top: .85rem; width: .5rem; height: .5rem; border-radius: 999px; background: var(--atencion); }
.montaje-notas li::before { background: var(--acento); }
.pensando-aviso { flex-basis: 100%; margin: .35rem 0 0; color: var(--tinta-suave); font-size: .9rem; }
.boton.pensando { opacity: .75; cursor: progress; }
@media (max-width: 600px) { .montaje { padding: 1rem .85rem; } }
@media print {
    html.imprimiendo-montaje body * { visibility: hidden; }
    html.imprimiendo-montaje .montaje, html.imprimiendo-montaje .montaje * { visibility: visible; }
    html.imprimiendo-montaje .montaje { position: absolute; left: 0; top: 0; width: 100%; box-shadow: none; border: 0; }
    html.imprimiendo-montaje .no-imprimir { display: none !important; }
    html.imprimiendo-montaje .montaje-dibujo { overflow: visible; }
    html.imprimiendo-montaje .montaje-svg { min-width: 0; }
}
/* En el taller, el montaje ocupa todo el ancho; y la columna no crece con el dibujo (sin `minmax(0, …)`, el SVG de 760 px la ensanchaba y la pantalla se salía de lado en el teléfono). */
.paso-taller { grid-template-columns: minmax(0, 1fr); }
.paso-taller:has(.montaje) { max-width: none; }
.montaje { min-width: 0; }
.montaje-deslizar { display: none; margin: .4rem 0 0; font-size: .82rem; color: var(--tinta-suave); }
@media (max-width: 820px) { .montaje-deslizar { display: block; } }

/* ── LA IDEA, EN LA PÁGINA DEL PROYECTO (`admin/proyecto.pug`, `_dev_docs/40`) ── */
.idea-seccion-cabeza { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: .75rem 1.5rem; }
.idea-seccion-cabeza h2 { margin: 0 0 .25rem; }
.idea-seccion-cabeza p { margin: 0; max-width: 62ch; }
.idea-seccion-botones { display: flex; flex-wrap: wrap; gap: .5rem; }
.idea-seccion-botones form { margin: 0; }
.idea-tarjetas { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr)); gap: .9rem; }
.idea-tarjeta-enlace { display: grid; border: 1px solid var(--borde); border-radius: var(--radio); background: var(--papel); overflow: hidden; color: inherit; text-decoration: none; transition: border-color .15s, box-shadow .15s; }
@media (hover: hover) { .idea-tarjeta-enlace:hover { border-color: var(--acento); box-shadow: var(--sombra); } }
.idea-tarjeta-enlace:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.idea-miniatura { display: block; aspect-ratio: 16 / 9; background: var(--fondo); border-bottom: 1px solid var(--borde); }
.idea-miniatura img { width: 100%; height: 100%; object-fit: contain; display: block; }
.idea-tarjeta-texto { display: grid; gap: .25rem; padding: .75rem .9rem .9rem; }
.idea-tarjeta-texto .marca-estado { justify-self: start; }

/* ── EL MONTAJE REALISTA (`ficha/montaje.js`, `_dev_docs/41`) ─────────── */
.montaje-vistas { display: inline-flex; gap: 4px; padding: 4px; margin-bottom: .6rem; border-radius: 999px; background: var(--fondo); border: 1px solid var(--borde); }
.montaje-vista { font: inherit; font-weight: 700; font-size: .9rem; min-height: 40px; padding: 0 18px; border-radius: 999px; border: 0; background: transparent; color: var(--tinta-suave); cursor: pointer; }
.montaje-vista[aria-selected="true"] { background: var(--acento); color: var(--sobre-acento); }
.montaje-vista:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.montaje-dibujo[hidden] { display: none; }
.montaje-real { --mt-tinta: var(--tinta); color: var(--tinta); }
.montaje-real .mt-svg { display: block; width: 100%; min-width: 720px; height: auto; }
.montaje-sin-forma { margin: .6rem 0 0; font-size: .9rem; color: var(--tinta-suave); }
.montaje-svg.resaltando .cx-cable:not(.resaltado) { opacity: .15; }
.montaje-svg.resaltando .cx-cable.resaltado { stroke-width: 4.5; }
.montaje-cables > li[data-cable] { cursor: pointer; }
@media print { html.imprimiendo-montaje .montaje-real .mt-svg { min-width: 0; } }

/* ── EL ESQUEMA ELECTRÓNICO (`ficha/esquemaElectrico.js`, `_dev_docs/42`) ── */
.montaje-electrico .el-svg { display: block; width: 100%; min-width: 760px; height: auto; }
.montaje-descargas { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; padding: .75rem .25rem .25rem; }
.el-svg.resaltando .el-cable:not(.resaltado) { opacity: .25; }

/* ── LOS DATOS TÉCNICOS DE UN EQUIPO (`_dev_docs/44`) ───────────────────────
   En la ficha y en la hoja: una lista de dos columnas que en el celular pasa a
   una, y debajo «Si no responde», con sus pasos. */
.datos-tecnicos { display: grid; gap: .9rem; min-width: 0; }
.dt-titulo { margin: 0; }
.dt-lista { margin: 0; display: grid; border: 1px solid var(--borde); border-radius: 14px; background: var(--papel); overflow: hidden; }
.dt-fila { display: grid; grid-template-columns: minmax(150px, 220px) 1fr; gap: .25rem 1rem; padding: .75rem 1rem; border-top: 1px solid var(--borde); align-items: baseline; }
.dt-fila:first-child { border-top: 0; }
.dt-fila dt { margin: 0; font-size: .85rem; font-weight: 600; color: var(--tinta-suave); }
.dt-fila dd { margin: 0; display: grid; gap: .2rem; min-width: 0; }
.dt-valor { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; font-weight: 700; overflow-wrap: anywhere; }
.dt-detalle { font-size: .85rem; line-height: 1.45; color: var(--tinta-suave); }
.dt-bien .dt-valor { color: var(--bueno); }
.dt-atencion .dt-valor { color: var(--atencion); }
.dt-malo .dt-valor { color: var(--malo); }
.dt-staff { background: color-mix(in srgb, var(--acento) 5%, var(--papel)); }
.dt-nota-staff { font-style: italic; }
.dt-copiar { font: inherit; font-size: .75rem; font-weight: 600; padding: .2rem .6rem; border-radius: 999px; border: 1px solid var(--borde); background: var(--papel); color: var(--acento); cursor: pointer; min-height: 28px; }
.dt-copiar.dt-copiado { border-color: var(--bueno); color: var(--bueno); }
@media (hover: hover) { .dt-copiar:hover { border-color: var(--acento); } }
.dt-barras { display: inline-flex; align-items: flex-end; gap: 2px; height: 14px; }
.dt-barras i { width: 4px; border-radius: 1px; background: color-mix(in srgb, currentColor 25%, transparent); }
.dt-barras i:nth-child(1) { height: 25%; } .dt-barras i:nth-child(2) { height: 50%; } .dt-barras i:nth-child(3) { height: 75%; } .dt-barras i:nth-child(4) { height: 100%; }
.dt-barras[data-barras="1"] i:nth-child(-n+1), .dt-barras[data-barras="2"] i:nth-child(-n+2), .dt-barras[data-barras="3"] i:nth-child(-n+3), .dt-barras[data-barras="4"] i { background: currentColor; }
.dt-rescate { border: 1px solid var(--borde); border-left: 4px solid var(--atencion); border-radius: 14px; background: var(--papel); }
.dt-rescate summary { display: grid; gap: .15rem; padding: .85rem 1rem; cursor: pointer; list-style-position: inside; }
.dt-rescate-titulo { font-weight: 800; }
.dt-rescate-sub { font-size: .85rem; color: var(--tinta-suave); }
.dt-pasos { margin: 0; padding: 0 1.25rem 1rem 2.4rem; display: grid; gap: .7rem; line-height: 1.5; }
.dt-red { display: inline-flex; align-items: center; gap: .5rem; margin: .1rem .25rem; padding: .15rem .25rem .15rem .6rem; border-radius: 8px; background: color-mix(in srgb, var(--atencion) 12%, var(--papel)); font-weight: 800; }
@media (max-width: 560px) {
    .dt-fila { grid-template-columns: 1fr; }
}
