/* =====================================================================
   llave-en-mano.css — el servicio integral de proyectos desde cero

   Cuatro piezas, en este orden:

     1. La entrada destacada de la barra de navegación
     2. La sección de la portada, con la misma estructura en las dos
        marcas y la piel de cada una
     3. El botón flotante de WhatsApp, abajo a la derecha
     4. El cuestionario previo, en <dialog> nativo

   Se apoya en sistema.css y en portada.css: los colores, la escala
   tipográfica, la escala de espacio, el carril (--m-carril) y los
   componentes con prefijo m- salen de allí y aquí no se vuelven a
   declarar. Ni un !important, y ni una regla que toque una etiqueta.

   Nada de esto puede escribirse en línea: el CSP del sitio es
   style-src 'self', así que no hay ni un atributo style= ni un bloque
   <style> en el HTML. Lo que cambia en caliente lo cambia el JS por
   element.style, que el CSP no restringe.
   ===================================================================== */


/* =====================================================================
   1. LA ENTRADA DESTACADA DE LA BARRA

   Medido antes de escribirla, en las dos marcas y a cinco anchos: la
   barra estaba llena. El contenido de la cabecera se detiene en el
   carril —1.208 px a partir de 1.432 de ventana— y ahí dentro caben el
   logotipo (264), la navegación (599 en CNC, 667 en medieval), el
   conmutador (194) y las dos separaciones (38). En medieval eso deja
   42 px libres, y el enlace más corto que se puede escribir cuesta 74.

   O sea: un octavo enlace con su rótulo no cabe en la barra medieval a
   ningún ancho, porque el carril deja de crecer. Se probaron seis
   combinaciones —rótulo en mayúsculas, en minúsculas, con icono y sin
   él, apretando el hueco de la barra, el tracking, el conmutador y hasta
   el logotipo— y ninguna con rótulo entra: la más barata se pasaba de 16
   a 110 px según el ancho.

   Lo que sí entra, con 60 px de sobra, es la pastilla con el icono solo.
   Así que la entrada es una llave: en la barra se ve el icono, y el
   rótulo «Llave en mano» aparece entero en el panel desplegable, que es
   donde hay sitio. El nombre accesible lo lleva siempre el enlace en
   aria-label, de modo que el lector de pantalla lee lo mismo arriba que
   abajo, y el título nativo lo enseña al posar el puntero.

   La pastilla es el único elemento relleno de la barra además del
   conmutador: eso es lo que la destaca, no un color distinto.
   ===================================================================== */
/* Todas las reglas de la pastilla van acotadas con `.cabecera__nav`, y no
   por gusto: portada.css estiliza sus enlaces con `.cabecera__nav a`, que
   pesa (0,1,1). Una clase suelta pesa (0,1,0) y pierde. Medido antes de
   corregirlo: la llave salía del color del humo —rgb(163,169,180)— en vez
   del oro, y con el tracking y el peso de un enlace de sección. Acotarla
   la sube a (0,2,0) y gana sin necesitar un !important. */
.cabecera .cabecera__llave {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--m-esp-3xs);
    /* Objetivo táctil completo aunque solo lleve el icono. */
    min-width: 2.75rem;
    min-height: 2.75rem;
    padding-inline: var(--m-esp-2xs);
    /* La pastilla vive en la barra, y la barra tiene su propia paleta:
       en la marca industrial es blanca aunque la página sea marino. Con
       --m-acento la llave salía en el azul de la página y desaparecía
       sobre el papel. */
    border: var(--m-hilo) solid var(--m-barra-azul);
    /* El mismo radio que la pastilla de sesión, que es la otra pieza
       rellena de la barra. Con una redonda y otra cuadrada parecían de
       dos sitios distintos. */
    border-radius: var(--m-radio-sm);
    /* El relleno era el mismo azul al 10 %, y sobre él el rótulo se
       quedaba en 4,37:1: el tinte aclara el fondo justo lo suficiente
       para bajar del mínimo. Se baja al 6 % y el rótulo se cierra un
       punto; da 5,3:1 y la pastilla sigue viéndose rellena. */
    background: color-mix(in srgb, var(--m-barra-azul) 6%, transparent);
    color: color-mix(in srgb, var(--m-barra-azul) 88%, #000000);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    transition:
        background var(--m-medio) var(--m-salida),
        color var(--m-rapido) var(--m-entrada),
        box-shadow var(--m-medio) var(--m-salida);
}

.cabecera .cabecera__llave:hover,
.cabecera .cabecera__llave:focus-visible {
    background: var(--m-barra-azul);
    color: var(--m-barra-fondo);
    box-shadow: 0 0 18px color-mix(in srgb, var(--m-barra-azul) 35%, transparent);
}

/* La barra no tiene sitio para el rótulo; el panel sí. Se enciende en la
   media query del final, la misma que pliega la navegación. */
.cabecera .cabecera__llave-texto {
    display: none;
}

/* El subrayado que crece desde la izquierda es de los enlaces de sección.
   Esta entrada es una pastilla rellena: el subrayado le sale por debajo
   del borde redondeado y se ve como un defecto. */
.cabecera .cabecera__llave::after {
    content: none;
}

.cabecera .cabecera__llave .m-icono {
    width: 1.25rem;
    height: 1.25rem;
}


/* La pastilla de la barra sustituye a la de la navegación mientras esta
   está plegada. El tramo tiene dos topes medidos, uno por arriba y otro
   por abajo:

     · Por arriba, 1.519 px: a partir de 1.520 la navegación vuelve a la
       barra y se lleva su propia pastilla.
     · Por abajo, 880 px: con el rótulo entero la pastilla cuesta unos
       160 px, y por debajo de ese ancho la fila —logotipo, sesión,
       conmutador y botón de menú— ya no los tiene. Ahí la entrada vive
       solo en el panel, con su rótulo.
   ─────────────────────────────────────────────────────────────────── */
.cabecera__acciones .cabecera__llave {
    display: none;
}

@media (min-width: 880px) and (max-width: 1519px) {
    .cabecera__acciones .cabecera__llave {
        display: inline-flex;
    }

    .cabecera__acciones .cabecera__llave-texto {
        display: inline;
    }

    .cabecera__nav .cabecera__llave {
        display: none;
    }
}


/* =====================================================================
   2. LA SECCIÓN

   La misma estructura en las dos marcas —cinta, titular, entrada, cinco
   pasos y llamada— y dos pieles. Los cinco pasos son los reales: se
   conversa la idea, se levanta el plano o el boceto, se cotiza, se
   fabrica y se entrega. Ni plazos ni precios: no los tenemos.

   La banda respeta el contrato del carril de portada.css: canal a los
   lados, contenido hasta --m-carril, y el alto lo pone el contenido.
   ===================================================================== */
.llave {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding-block: var(--m-esp-xl);
    padding-inline: var(--m-canal);
    /* La banda más honda de la portada, y encima dos focos. El cliente la
       quiere oscura y con luz: el fondo baja al abismo del ritmo y la luz
       la ponen dos degradados radiales, uno frío arriba a la izquierda y
       otro más cerrado abajo a la derecha, que es de donde vendría la luz
       de un taller. */
    background:
        radial-gradient(38rem 26rem at 12% 0%, color-mix(in srgb, var(--m-acento) 16%, transparent) 0%, transparent 62%),
        radial-gradient(44rem 30rem at 92% 108%, color-mix(in srgb, var(--m-acento-hondo) 40%, transparent) 0%, transparent 60%),
        var(--m-banda-6, var(--m-negro-0));
}

/* La rejilla de plano, muy tenue: da textura al fondo sin dibujar nada
   que compita con la línea de tiempo. */
.llave::after {
    content: '';
    position: absolute;
    z-index: -1;
    inset: 0;
    pointer-events: none;
    opacity: 0.5;
    background-image:
        linear-gradient(color-mix(in srgb, var(--m-acento) 7%, transparent) 1px, transparent 1px),
        linear-gradient(90deg, color-mix(in srgb, var(--m-acento) 7%, transparent) 1px, transparent 1px);
    background-size: 72px 72px;
    mask-image: radial-gradient(70% 60% at 50% 45%, #000 0%, transparent 78%);
}

.llave__inner {
    position: relative;
    width: 100%;
    max-width: var(--m-carril);
    margin-inline: auto;
}

.llave__cabecera {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--m-esp-sm);
    margin-block-end: var(--m-esp-xl);
    text-align: center;
}

.llave__titulo {
    font-size: var(--m-txt-2xl);
}

.llave__titulo span {
    color: var(--m-acento);
}

/* El párrafo de entrada va centrado bajo el titular: .m-parrafo lo corta
   a 68 caracteres, y sin margen automático se pega a la izquierda. */
.llave__entrada {
    margin-inline: auto;
    text-align: center;
}

/* ── Los cinco pasos ────────────────────────────────────────────────
   De 1.024 px arriba son cinco columnas iguales con el riel pasando por
   detrás de los números. Por debajo, una sola columna con el riel en
   vertical, que es como se lee un proceso en un teléfono.

   Las pistas van con minmax(0, 1fr) y no con 1fr: 1fr es minmax(auto,
   1fr) y no baja del contenido mínimo, que es lo que descuadraba la fila
   de carteles de la portada. */
.llave__pasos {
    position: relative;
    display: grid;
    gap: var(--m-esp-md);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* ── El riel ─────────────────────────────────────────────────────────
   En el móvil los cinco pasos se apilan y el riel es lo que siempre fue:
   una vertical de un píxel a la izquierda de los números, dibujada con un
   ::before. La curva no cabe en una columna.

   De 1.024 px en adelante el ::before se apaga y manda el SVG: una onda
   que sube y baja pasando por los cinco números, que van alternando
   altura. Ahí es donde la línea deja de ser recta.
   ─────────────────────────────────────────────────────────────────── */
.llave__pasos::before {
    content: '';
    position: absolute;
    z-index: 0;
    background: linear-gradient(180deg,
        transparent 0%,
        color-mix(in srgb, var(--m-acento) 45%, transparent) 12%,
        color-mix(in srgb, var(--m-acento) 45%, transparent) 88%,
        transparent 100%);
    /* Vertical por defecto: el móvil manda. */
    inset-block: 1.4rem;
    inset-inline-start: 1.35rem;
    width: 1px;
}

/* El envoltorio existe para que el riel tenga contra qué posicionarse: el
   SVG va absoluto y necesita una caja que empiece donde empieza la lista,
   no donde empieza la banda. */
.llave__linea {
    position: relative;
}

/* El riel en SVG está apagado hasta que la banda pasa a cinco columnas. */
.llave__riel {
    display: none;
}

.llave__paso {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: 2.75rem minmax(0, 1fr);
    grid-template-areas:
        'numero titulo'
        '.      texto';
    align-items: center;
    gap: var(--m-esp-2xs) var(--m-esp-sm);
}

.llave__numero {
    grid-area: numero;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 55%, transparent);
    /* El fondo de la banda, para que el riel no cruce por encima. */
    background: var(--m-negro-1);
    color: var(--m-acento);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    font-weight: 700;
    letter-spacing: 0.08em;
}

.llave__paso-titulo {
    grid-area: titulo;
    display: flex;
    align-items: center;
    gap: var(--m-esp-2xs);
    margin: 0;
    font-family: var(--m-titular);
    font-size: var(--m-txt-md);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: var(--m-titular-ajuste, 0.01em);
    color: var(--m-texto);
    text-wrap: balance;
}

.llave__paso-titulo .m-icono {
    color: var(--m-acento);
}

.llave__paso-texto {
    grid-area: texto;
    margin: 0;
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    line-height: 1.6;
    color: var(--m-humo);
    text-wrap: pretty;
}

/* ── La llamada ──────────────────────────────────────────────────── */
.llave__acciones {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--m-esp-xs);
    margin-block-start: var(--m-esp-xl);
    text-align: center;
}

.llave__nota {
    margin: 0;
    max-width: 52ch;
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    line-height: 1.6;
    color: var(--m-humo-tenue);
    text-wrap: pretty;
}

/* La piel medieval de esta banda —la trama de buril, las escuadras de
   cartela y los titulares grabados— se retiró con la sección: el cliente
   dejó «Llave en mano» solo en la marca industrial. Lo que queda de este
   archivo lo usan las dos marcas: el botón flotante de WhatsApp y el
   cuestionario previo viven fuera de las secciones maestras a propósito,
   porque cambiar de marca esconde una sección entera y un canal de
   contacto no puede irse con ella. */

/* =====================================================================
   3. EL BOTÓN FLOTANTE DE WHATSAPP

   Abajo a la derecha. El módulo de accesibilidad ocupa la esquina de
   abajo a la izquierda con el mismo margen —clamp(0.75rem, 3vw,
   1.25rem)—, así que los dos discos no se pisan en ningún ancho: el
   valor se repite aquí a propósito, porque accesibilidad.css no está
   cargado en la portada y no se puede leer su variable.

   La capa va por debajo de la del módulo de accesibilidad (100050) para
   que, si un día coinciden, el control de accesibilidad quede encima:
   un ajuste de contraste enterrado bajo un botón de contacto no sirve.
   Los <dialog> abiertos con showModal() viven en la capa superior del
   navegador y quedan por encima de esto pase lo que pase.

   El color es el del taller, no el de la marca de WhatsApp: lo identifica
   el icono. Es el mismo criterio con el que el botón de Instagram dejó de
   llevar el degradado de Instagram.
   ===================================================================== */
.wa-flotante {
    --wa-margen: clamp(0.75rem, 3vw, 1.25rem);

    position: fixed;
    z-index: 100040;
    inset-block-end: calc(var(--wa-margen) + env(safe-area-inset-bottom, 0px));
    inset-inline-end: calc(var(--wa-margen) + env(safe-area-inset-right, 0px));
    display: inline-flex;
    align-items: center;
    gap: var(--m-esp-2xs);
    min-height: 3rem;
    padding-inline: var(--m-esp-sm);
    border: var(--m-hilo) solid var(--m-acento);
    border-radius: 999px;
    background: linear-gradient(180deg, var(--m-negro-2) 0%, var(--m-negro-0) 100%);
    box-shadow: var(--m-sombra-media);
    color: var(--m-acento-claro);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-decoration: none;
    transition:
        background var(--m-medio) var(--m-salida),
        color var(--m-rapido) var(--m-entrada),
        box-shadow var(--m-medio) var(--m-salida);
}

.wa-flotante:hover,
.wa-flotante:focus-visible {
    background: linear-gradient(180deg, var(--m-acento) 0%, var(--m-acento-hondo) 100%);
    color: var(--m-negro-0);
    box-shadow: 0 0 26px color-mix(in srgb, var(--m-acento) 40%, transparent);
}

.wa-flotante .m-icono {
    width: 1.4rem;
    height: 1.4rem;
}

/* El botón es fijo, así que al final de la página se posa encima del
   último renglón del pie. Medido con la página abajo del todo, en las dos
   marcas y a 390 y 1.440: tapaba el enlace «Administración», que es el
   único acceso al panel. Un botón flotante puede cruzarse con el
   contenido mientras se pasa, pero no puede quedarse encima de un enlace
   cuando la página se detiene.

   El pie de cada marca reserva el alto del botón más sus dos márgenes.
   Va aquí y no con el resto del pie porque el motivo es este botón: si
   algún día se retira, la reserva se retira con él.

   La regla gana por orden de carga —esta hoja va después de portada.css—
   y no por peso: las dos declaran (0,1,0). */
.main-footer-cnc,
.footer-medieval {
    padding-block-end: calc(var(--m-esp-md) + 3rem + 2 * clamp(0.75rem, 3vw, 1.25rem));
}

/* Al imprimir no pinta nada: es un control, no contenido. Y sin botón no
   hace falta reservarle sitio. */
@media print {
    .wa-flotante {
        display: none;
    }

    .main-footer-cnc,
    .footer-medieval {
        padding-block-end: var(--m-esp-md);
    }
}


/* =====================================================================
   4. EL CUESTIONARIO

   <dialog> nativo abierto con showModal(). De ahí salen, sin escribir ni
   una línea: la capa superior, role="dialog" y aria-modal implícitos, el
   foco dentro mientras está abierto y devuelto al botón que lo abrió al
   cerrar, el resto de la página inerte y Escape.

   Cuatro preguntas, una por pantalla, y una quinta pantalla de resumen
   con las dos salidas. No pide nombre, correo ni teléfono: eso lo hace el
   cotizador y no se duplica la recogida de datos.
   ===================================================================== */
.llave-dlg {
    /* Apagar la hoja del navegador para <dialog>, igual que modal.css. */
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: 0;
    border: 0;
    color: inherit;

    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background: transparent;
    opacity: 0;
    transition:
        opacity var(--m-medio) ease,
        display var(--m-medio) allow-discrete,
        overlay var(--m-medio) allow-discrete;
}

.llave-dlg[open] {
    display: flex;
    opacity: 1;
}

@starting-style {
    .llave-dlg[open] {
        opacity: 0;
    }
}

.llave-dlg::backdrop {
    background: rgb(3 3 4 / 0.82);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

.llave-dlg__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(38rem, calc(100% - 2 * var(--m-esp-sm)));
    max-height: min(90vh, 46rem);
    overflow: hidden;
    border: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 32%, transparent);
    border-radius: var(--m-radio-md);
    background: linear-gradient(160deg,
        color-mix(in srgb, var(--m-negro-3) 92%, var(--m-acento)) 0%,
        var(--m-negro-2) 45%,
        var(--m-negro-1) 100%);
    box-shadow: var(--m-sombra-alta);
}

/* El reflejo del canto superior, como .m-superficie. */
.llave-dlg__panel::before {
    content: '';
    position: absolute;
    inset-inline: 12%;
    inset-block-start: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--m-acento-claro) 55%, transparent),
        transparent);
    pointer-events: none;
}

.llave-dlg__cabecera {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 2.75rem;
    align-items: start;
    gap: var(--m-esp-2xs);
    padding: var(--m-esp-md) var(--m-esp-md) var(--m-esp-sm);
}

.llave-dlg__contador {
    margin: 0 0 var(--m-esp-3xs);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-xs);
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--m-acento);
}

.llave-dlg__titulo {
    margin: 0;
    font-family: var(--m-titular);
    font-size: var(--m-txt-lg);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: var(--m-titular-ajuste, 0.01em);
    color: var(--m-texto);
    text-wrap: balance;
}

.llave-dlg__cerrar {
    width: 2.75rem;
    height: 2.75rem;
    border: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 25%, transparent);
    border-radius: var(--m-radio-sm);
    background: transparent;
    color: var(--m-humo);
    font-size: var(--m-txt-base);
    line-height: 1;
    cursor: pointer;
    transition: color var(--m-rapido) var(--m-entrada),
                border-color var(--m-rapido) var(--m-entrada);
}

.llave-dlg__cerrar:hover,
.llave-dlg__cerrar:focus-visible {
    color: var(--m-acento-claro);
    border-color: var(--m-acento);
}

/* La barra de avance. Es decoración: lo que se anuncia es el contador,
   que va en aria-live. */
.llave-dlg__barra {
    height: 2px;
    margin-inline: var(--m-esp-md);
    background: color-mix(in srgb, var(--m-acento) 14%, transparent);
}

.llave-dlg__avance {
    height: 100%;
    width: 0;
    background: linear-gradient(90deg, var(--m-acento-hondo), var(--m-acento));
    box-shadow: 0 0 8px color-mix(in srgb, var(--m-acento) 55%, transparent);
    transition: width var(--m-medio) var(--m-salida);
}

.llave-dlg__cuerpo {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: var(--m-esp-md);
}

/* El cuerpo recibe el foco al cambiar de paso para que el lector de
   pantalla lea la pregunta nueva; el anillo del navegador sobre una caja
   que ocupa toda la ventana no dice nada útil. */
.llave-dlg__cuerpo:focus {
    outline: none;
}

.llave-dlg__pregunta {
    margin: 0 0 var(--m-esp-2xs);
    font-family: var(--m-titular);
    font-size: var(--m-txt-md);
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: var(--m-titular-ajuste, 0.01em);
    color: var(--m-texto);
}

.llave-dlg__ayuda {
    margin: 0 0 var(--m-esp-sm);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    line-height: 1.6;
    color: var(--m-humo);
}

/* ── Las opciones rápidas ───────────────────────────────────────── */
.llave-opciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--m-esp-2xs);
    margin-block-end: var(--m-esp-sm);
}

.llave-opcion {
    min-height: 2.75rem;
    padding-inline: var(--m-esp-sm);
    border: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 30%, transparent);
    border-radius: 999px;
    background: transparent;
    color: var(--m-humo);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    font-weight: 600;
    cursor: pointer;
    transition:
        border-color var(--m-rapido) var(--m-entrada),
        background var(--m-rapido) var(--m-entrada),
        color var(--m-rapido) var(--m-entrada);
}

.llave-opcion:hover,
.llave-opcion:focus-visible {
    border-color: var(--m-acento);
    color: var(--m-acento-claro);
}

.llave-opcion[aria-pressed='true'] {
    border-color: var(--m-acento);
    background: linear-gradient(180deg, var(--m-acento) 0%, var(--m-acento-hondo) 100%);
    color: var(--m-negro-0);
}

/* ── El campo libre ─────────────────────────────────────────────── */
.llave-campo {
    display: block;
    margin-block-end: var(--m-esp-3xs);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-xs);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--m-humo-tenue);
}

.llave-entrada {
    width: 100%;
    min-height: 2.75rem;
    padding: var(--m-esp-2xs) var(--m-esp-xs);
    border: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 22%, transparent);
    border-radius: var(--m-radio-sm);
    background: color-mix(in srgb, var(--m-negro-0) 70%, transparent);
    color: var(--m-texto);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-base);
}

.llave-entrada:focus-visible {
    outline: 2px solid var(--m-acento);
    outline-offset: 1px;
}

.llave-entrada::placeholder {
    color: var(--m-humo-tenue);
}

/* ── El resumen ─────────────────────────────────────────────────── */
.llave-resumen {
    margin: 0 0 var(--m-esp-md);
    border-block-start: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 22%, transparent);
}

.llave-resumen__fila {
    display: grid;
    grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
    gap: var(--m-esp-2xs) var(--m-esp-sm);
    padding-block: var(--m-esp-xs);
    border-block-end: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 12%, transparent);
}

.llave-resumen__etiqueta {
    margin: 0;
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-xs);
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--m-humo-tenue);
}

.llave-resumen__valor {
    margin: 0;
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-base);
    line-height: 1.5;
    color: var(--m-texto);
    overflow-wrap: anywhere;
}

.llave-resumen__valor[data-vacio='si'] {
    color: var(--m-humo-tenue);
    font-style: italic;
}

/* ── Las dos salidas ────────────────────────────────────────────── */
/* ── El formulario ──────────────────────────────────────────────────
   Una sola pantalla con todos los campos. En ancho de escritorio los pares
   cortos —medidas, correo, teléfono— comparten línea; el nombre de lo que
   se fabrica y el texto libre ocupan la suya. */
.llave-form {
    display: grid;
    gap: var(--m-esp-2xs);
}

.llave-form__campo {
    display: block;
}

.llave-form__archivos {
    margin-block-start: var(--m-esp-3xs);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-xs);
    line-height: 1.5;
    color: var(--m-humo-tenue);
    overflow-wrap: anywhere;
}

.llave-form__archivos:empty {
    display: none;
}

.llave-form__enviar {
    width: 100%;
    margin-block-start: var(--m-esp-2xs);
}

@media (min-width: 34rem) {
    .llave-form {
        grid-template-columns: 1fr 1fr;
    }

    /* Los que necesitan la línea entera: lo que se fabrica, el texto libre,
       los adjuntos y todo lo que no es un campo corto. */
    .llave-form > .llave-form__campo:nth-child(1),
    .llave-form > .llave-form__campo:nth-child(3),
    .llave-form > .llave-form__campo:nth-child(7),
    .llave-form > .llave-dlg__ayuda,
    .llave-form > .llave-dlg__aviso,
    .llave-form > .llave-form__enviar {
        grid-column: 1 / -1;
    }
}

/* ── Los datos de contacto del resumen ──────────────────────────────
   Tres campos cortos. En pantalla ancha caben correo y teléfono en la
   misma línea; el nombre ocupa la suya porque es el único obligatorio y
   conviene que no compita. */
.llave-contacto {
    display: grid;
    gap: var(--m-esp-2xs);
    margin-block: var(--m-esp-sm);
}

@media (min-width: 30rem) {
    .llave-contacto {
        grid-template-columns: 1fr 1fr;
    }

    .llave-contacto__campo:first-child {
        grid-column: 1 / -1;
    }
}

/* Lo que responde el envío: el número de seguimiento, o el motivo por el
   que no salió. Vacío no ocupa sitio. */
.llave-dlg__aviso {
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    line-height: 1.5;
    color: var(--m-acento-claro, var(--m-acento));
}

.llave-dlg__aviso:empty {
    display: none;
}

.llave-salidas {
    display: grid;
    gap: var(--m-esp-2xs);
}

.llave-salidas .m-boton {
    width: 100%;
}

/* ── El pie de la navegación entre pasos ────────────────────────── */
.llave-dlg__pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--m-esp-2xs);
    padding: var(--m-esp-sm) var(--m-esp-md);
    border-block-start: var(--m-hilo) solid color-mix(in srgb, var(--m-acento) 18%, transparent);
    background: color-mix(in srgb, var(--m-negro-0) 55%, transparent);
}

/* «Saltar» empuja a «Siguiente» al canto derecho y se queda en el medio;
   con el botón de volver oculto, ocupa él la izquierda. */
.llave-dlg__hueco {
    flex: 1 1 auto;
}

.llave-dlg__pie .m-boton {
    flex: 0 0 auto;
}

.llave-dlg__enlace {
    border: 0;
    background: transparent;
    padding: var(--m-esp-2xs);
    min-height: 2.75rem;
    color: var(--m-humo);
    font-family: var(--m-cuerpo);
    font-size: var(--m-txt-sm);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
    transition: color var(--m-rapido) var(--m-entrada);
}

.llave-dlg__enlace:hover,
.llave-dlg__enlace:focus-visible {
    color: var(--m-acento-claro);
}

/* Mientras el diálogo está abierto la página de detrás no se desplaza.
   Lo pone y lo quita el JS con una clase, nunca con un atributo style. */
.llave-sin-scroll {
    overflow: hidden;
}


/* =====================================================================
   5. LAS MEDIA QUERIES, AL FINAL

   Es el único sitio donde ganan sin necesitar un !important, que es la
   regla que ya sigue portada.css.
   ===================================================================== */

/* Cinco columnas y riel horizontal en cuanto hay sitio. El riel arranca
   y termina en el centro del primer número y del último: con cinco
   pistas iguales y cuatro huecos, ese centro cae a (100 % − 4 huecos) / 10
   del canto. No es un 10 % redondo —eso ignora los huecos y deja el riel
   siete píxeles corrido—, y aunque el número lo taparía igual, el número
   es opaco por otra razón y no conviene apoyarse en eso. */
@media (min-width: 1024px) {
    .llave__pasos {
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: var(--m-esp-sm);
        /* Sitio para que la onda suba y baje por detrás. */
        padding-block-start: 5.5rem;
    }

    /* Manda el SVG: la recta se apaga. */
    .llave__pasos::before {
        display: none;
    }

    /* Las tres medidas de esta banda salen todas de la misma cuenta y por
       eso cuadran solas cuando el widget de accesibilidad sube la letra:

         · El número mide 2,75 rem de alto.
         · La lista se separa 5,5 rem por arriba, que es lo que baja el
           paso par respecto del impar. La onda sube y baja exactamente
           esa distancia.
         · El SVG mide 11 rem de alto con un viewBox de 200 unidades, así
           que la cresta (y=50) cae al 25 % —2,75 rem— y el valle (y=150)
           al 75 %. Entre los dos hay 5,5 rem, que es el zigzag.
         · Y arranca 4,125 rem antes que la lista para que la cresta caiga
           justo en el centro del número impar: 4,125 + 2,75 = 6,875, que
           es 5,5 de separación más 1,375 de medio número. */
    .llave__riel {
        display: block;
        position: absolute;
        z-index: 0;
        inset-inline: calc((100% - 4 * var(--m-esp-sm)) / 10);
        inset-block-start: 4.125rem;
        height: 11rem;
        pointer-events: none;
    }

    .llave__riel svg {
        display: block;
        width: 100%;
        height: 100%;
        overflow: visible;
    }

    /* El trazo. Se dibuja solo al entrar en pantalla: la línea empieza
       recogida en su propio largo y lo va soltando. 1.400 unidades es el
       largo del camino redondeado hacia arriba; con dasharray y offset
       iguales, el trazo no se ve hasta que el offset baja. */
    .llave__riel-trazo {
        fill: none;
        stroke: color-mix(in srgb, var(--m-acento) 55%, transparent);
        stroke-width: 2;
        stroke-linecap: round;
        vector-effect: non-scaling-stroke;
        stroke-dasharray: 1400;
        stroke-dashoffset: 1400;
    }

    .llave.en-pantalla .llave__riel-trazo {
        animation: llaveTrazo 1.8s var(--m-salida) forwards;
    }

    /* El destello que recorre la línea: un trozo corto de trazo que viaja
       por el mismo camino. Es un dasharray de 26 encendidos y 1.374
       apagados, y lo único que se anima es el desplazamiento del patrón.
       Solo corre mientras la banda está en pantalla —lo enciende
       portada.js—, para no pedir fotogramas a una sección que nadie ve. */
    .llave__riel-chispa {
        fill: none;
        stroke: var(--m-acento-claro);
        stroke-width: 3;
        stroke-linecap: round;
        vector-effect: non-scaling-stroke;
        filter: drop-shadow(0 0 6px var(--m-acento-claro));
        stroke-dasharray: 26 1374;
        stroke-dashoffset: 1400;
        opacity: 0;
    }

    .llave.en-pantalla .llave__riel-chispa {
        animation: llaveChispa 5s linear 1.6s infinite;
    }

    .llave__paso {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            'numero'
            'titulo'
            'texto';
        justify-items: center;
        align-items: start;
        /* Los cinco pasos miden lo mismo de alto porque la rejilla madre
           los estira, y el sobrante se repartía entre las tres filas de
           cada uno —que es lo que hace `align-content` por defecto en una
           rejilla—: con textos de distinto largo, el icono y el titular
           de cada paso caían a una altura distinta. Medido: 368, 368,
           360, 368 y 376 px. Con las filas apiladas arriba, los cinco
           titulares quedan a la misma altura y el sobrante se va abajo,
           que es donde no se ve. */
        align-content: start;
        gap: var(--m-esp-2xs);
        text-align: center;
    }

    /* El zigzag. Los pasos impares se sientan en la cresta de la onda y
       los pares en el valle: 5,5 rem de diferencia, que es el alto que la
       curva sube y baja en el SVG. De ahí que la línea deje de ser recta
       sin que ningún número quede colgando en el aire. */
    .llave__paso:nth-child(odd) {
        margin-block-start: 0;
    }

    .llave__paso:nth-child(even) {
        margin-block-start: 5.5rem;
    }

    /* Cada paso entra detrás del anterior, siguiendo el trazo. El retardo
       lo lleva cada uno escrito: son cinco, no hace falta una variable. */
    .llave.en-pantalla .llave__paso {
        animation: llavePaso 0.7s var(--m-salida) backwards;
    }

    .llave.en-pantalla .llave__paso:nth-child(1) { animation-delay: 0.25s; }
    .llave.en-pantalla .llave__paso:nth-child(2) { animation-delay: 0.50s; }
    .llave.en-pantalla .llave__paso:nth-child(3) { animation-delay: 0.75s; }
    .llave.en-pantalla .llave__paso:nth-child(4) { animation-delay: 1.00s; }
    .llave.en-pantalla .llave__paso:nth-child(5) { animation-delay: 1.25s; }

    .llave__paso-titulo {
        flex-direction: column;
        gap: var(--m-esp-3xs);
    }
}

@keyframes llaveTrazo {
    to { stroke-dashoffset: 0; }
}

@keyframes llaveChispa {
    0%        { opacity: 0; stroke-dashoffset: 1400; }
    6%        { opacity: 1; }
    88%       { opacity: 1; }
    100%      { opacity: 0; stroke-dashoffset: 0; }
}

@keyframes llavePaso {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}

/* Menos movimiento: el trazo aparece entero, los pasos también, y el
   destello no corre. El estado final es el mismo. */
@media (prefers-reduced-motion: reduce) {
    .llave__riel-trazo {
        stroke-dashoffset: 0;
    }

    .llave.en-pantalla .llave__riel-trazo,
    .llave.en-pantalla .llave__paso {
        animation: none;
    }

    .llave__riel-chispa {
        display: none;
    }
}

/* El punto de corte de la barra de navegación.

   Estaba en 1.140 px y sube a 1.280. No es un capricho del módulo: a
   1.141 px la cabecera medieval ya se desbordaba 51 px por la derecha
   —el conmutador se salía del canal— con sus siete enlaces y sin tocar
   nada, porque entre 1.140 y 1.432 el contenido de la cabecera es más
   estrecho que el carril. Medido: a 1.141 el contenido son 1.035 px y la
   barra medieval necesita 1.086.

   A 1.280 entran las dos marcas con la pastilla puesta, comprobado a
   1.280, 1.366, 1.440 y 1.920. El JS no necesita saber este número:
   pregunta al CSS si el botón de menú se está pintando.

   Este bloque acompaña al de portada.css, que es el que pliega la
   navegación. Si uno se mueve, el otro también. */
@media (max-width: 1519px) {
    /* En el panel desplegable la entrada destacada enseña su rótulo: ahí
       sí hay sitio. Encabeza el panel porque es el primer hijo del <nav>,
       no porque se la suba con `order`: con `order` el tabulador seguiría
       llegando a ella después de Contacto, y el orden del foco dejaría de
       coincidir con lo que se ve. */
    .cabecera .cabecera__llave {
        justify-content: flex-start;
        gap: var(--m-esp-2xs);
        margin-block-end: var(--m-esp-2xs);
        padding-inline: var(--m-esp-sm);
        border-radius: var(--m-radio-sm);
    }

    .cabecera__nav .cabecera__llave-texto {
        display: inline;
    }
}

/* El rótulo del botón flotante deja sitio al pulgar en pantallas
   estrechas: el disco con el icono se queda, que es lo que hay que
   acertar con el dedo. */
@media (max-width: 480px) {
    .wa-flotante {
        gap: 0;
        min-width: 3rem;
        padding-inline: 0;
        justify-content: center;
    }

    .wa-flotante__texto {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }
}

/* Quien pidió menos movimiento no ve crecer la barra de avance ni las
   transiciones de apertura. */
@media (prefers-reduced-motion: reduce) {
    .llave-dlg,
    .llave-dlg__avance,
    .cabecera__llave,
    .wa-flotante,
    .llave-opcion {
        transition: none;
    }
}
