/* ==========================================================================
   PROYECTOS Y REFORMAS A+B — Hoja compartida
   --------------------------------------------------------------------------
   Contiene solo lo que usa todo el sitio: tokens, tipografías locales, capa
   base, cabecera, pie y los componentes que aparecen en más de una página.

   Regla de oro (§12.2 del contrato de marcado): ningún selector de componente
   se escribe suelto. Cada uno arranca por el `#id` de las secciones donde
   aparece, agrupadas con `:is()` para no duplicar declaraciones.

   El lenguaje visual es el de un plano acotado: monocromo, trazo de 1,5 px con
   remates rectos y una línea de cota como antetítulo. De ahí que no exista un
   color de acento y que el estado se lea siempre por la forma.
   ========================================================================== */

/* ==========================================================
   1. TIPOGRAFÍAS LOCALES
   ========================================================== */

@font-face {
    font-family: "Montserrat";
    src: url("../fonts/montserrat-variable.woff2") format("woff2");
    font-style: normal;
    font-weight: 700 800;
    font-display: swap;
}

@font-face {
    font-family: "Inter";
    src: url("../fonts/inter-variable.woff2") format("woff2");
    font-style: normal;
    font-weight: 400 500;
    font-display: swap;
}

@font-face {
    font-family: "IBM Plex Mono";
    src: url("../fonts/ibm-plex-mono-400.woff2") format("woff2");
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "IBM Plex Mono";
    src: url("../fonts/ibm-plex-mono-500.woff2") format("woff2");
    font-style: normal;
    font-weight: 500;
    font-display: swap;
}

/* ==========================================================
   2. TOKENS
   Nombrados por rol, nunca por valor. Los tonos «inverse» son
   los que se usan sobre fondo negro.
   ========================================================== */

:root {
    /* Color de acción. El diseño es monocromo: el acento es el propio negro. */
    --primary-color:            #0A0A0A;
    --primary-hover-color:      #2E2E2E;

    /* Texto sobre fondo claro */
    --title-color:              #0A0A0A;
    --text-color:               #0A0A0A;
    --muted-color:              #6B6B6B; /* 5,33:1 sobre blanco · 4,84:1 sobre el alterno */
    --legal-color:              #3A3A3A;

    /* Texto sobre fondo oscuro */
    --inverse-color:            #FFFFFF;
    --inverse-muted-color:      #B5B5B5; /* 9,66:1 sobre el fondo oscuro */
    --inverse-soft-color:       #9E9E9E; /* 7,39:1 sobre el fondo oscuro */
    --inverse-faint-color:      #8A8A8A; /* 5,74:1 sobre el fondo oscuro */

    /* Fondos */
    --body-color:               #FFFFFF;
    --alt-color:                #F4F4F4;
    --dark-color:               #0A0A0A;
    --dark-surface-color:       #171717;

    /* Líneas */
    --border-color:             #DEDEDE;
    --dark-border-color:        #2E2E2E;

    /* Estado de los formularios. Sin color de acento, el error se señala con
       una banda en el canto del campo, no con rojo. */
    --error-color:              #0A0A0A;

    /* Velo de legibilidad sobre fotografía. Va opaco bajo el texto y solo se
       desvanece por encima: con un degradado que se aclara ya a la altura de
       las líneas, el pie de foto queda por debajo del contraste AA. */
    --photo-veil: linear-gradient(to top,
                                  rgba(10, 10, 10, 0.88)   0%,
                                  rgba(10, 10, 10, 0.88)  50%,
                                  rgba(10, 10, 10, 0.62)  68%,
                                  rgba(10, 10, 10, 0.3)   84%,
                                  rgba(10, 10, 10, 0)    100%);

    /* Tipografía */
    --display-font: "Montserrat", "Segoe UI", Arial, sans-serif;
    --body-font:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --mono-font:    "IBM Plex Mono", "Consolas", monospace;

    /* Escala de espaciado */
    --space-1:  0.25rem;
    --space-2:  0.5rem;
    --space-3:  0.75rem;
    --space-4:  1rem;
    --space-5:  1.5rem;
    --space-6:  2rem;
    --space-7:  3rem;
    --space-8:  4rem;
    --space-9:  6rem;
    --space-10: 8rem;

    /* Medidas */
    /* Las tres del contrato §12.7, con estos nombres exactos y en píxeles: son
       las que el cliente ajusta desde la pantalla «Layout» del plugin sin abrir
       Elementor ni tocar CSS. Equivalen a lo que el diseño ya usaba —24px es
       var(--space-5) y 128px es var(--space-10)—, así que nombrarlas así no
       cambia nada de lo que se ve.

       El ancho del contenido va ya descontado el margen lateral. De él depende
       que la rejilla de servicios entre a tres columnas y no a cuatro, que
       dejaría dos celdas vacías en la segunda fila.

       El respiro vertical es el techo, no la medida fija: las secciones lo
       envuelven en un `clamp()` para que en pantallas estrechas no se coman
       media página. Cambiar este valor mueve el sitio entero en proporción,
       que es lo que la pantalla del panel promete. */
    --container-width:   1192px;
    --section-padding-x: 24px;
    --section-padding-y: 128px;

    --header-height:    72px;

    /* Movimiento */
    --ease-curve:      cubic-bezier(0.2, 0.7, 0.3, 1);
    --transition-base: 0.3s var(--ease-curve);
}

/* ==========================================================
   3. CAPA BASE
   Sin márgenes por defecto: todo el ritmo vertical se
   construye con `gap` dentro de flex o grid.
   ========================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background-color: var(--body-color);
    color: var(--text-color);
    font-family: var(--body-font);
    font-size: 1.0625rem;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
}

img,
svg,
video {
    display: block;
    max-width: 100%;
    height: auto;
}

a {
    color: inherit;
    cursor: pointer;
}

h1,
h2,
h3,
h4 {
    margin: 0;
    font-family: var(--display-font);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -0.03em;
    text-wrap: balance;
}

p {
    margin: 0;
}

ul,
ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
}

/* ==========================================================
   4. UTILIDADES TRANSVERSALES
   Las únicas reglas sin ancla de sección, porque por
   definición no pertenecen a ninguna.
   ========================================================== */

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip-link {
    position: absolute;
    top: 0;
    left: -9999px;
    z-index: 200;
    padding: var(--space-3) var(--space-5);
    background-color: var(--dark-color);
    color: var(--inverse-color);
    font-family: var(--mono-font);
    font-size: 0.75rem;
    text-decoration: none;
}

.skip-link:focus {
    left: 0;
}

/* ==========================================================
   4.1. CAPA DE MOVIMIENTO
   Las únicas reglas por atributo del proyecto, y van aquí por
   el mismo motivo que `.skip-link`: el movimiento atraviesa
   todas las secciones y no pertenece a ninguna.

   El contenido es visible por defecto. El estado oculto lo
   arma `animations.js` justo antes de observar (§18 del
   contrato), para que una animación que no llegue nunca no
   deje la página en blanco —ni dentro del editor de
   Elementor, que es donde más veces pasa—.
   ========================================================== */

[data-motion] {
    transition:
        opacity 0.7s var(--ease-curve),
        transform 0.7s var(--ease-curve),
        clip-path 0.9s var(--ease-curve);
    transition-delay: var(--motion-delay, 0ms);
}

/* Estado armado: lo escribe el JavaScript, nunca el CSS. */
[data-motion][data-motion-armed="true"] {
    opacity: 0;
}

[data-motion="rise"][data-motion-armed="true"] {
    transform: translateY(28px);
}

[data-motion="rise-sm"][data-motion-armed="true"] {
    transform: translateY(14px);
}

/* Barrido de la fotografía.

   El recorte va en la imagen de dentro y nunca en el elemento observado: un
   nodo con `clip-path` deja de intersecar y el observador no dispara jamás, así
   que la fotografía se quedaría tapada para siempre. El contenedor se queda
   entero —se ve su fondo, que hace de plancha— y la imagen entra sobre él.

   El barrido tampoco se acompaña de desvanecido: con los dos a la vez, la
   imagen termina de aparecer antes de que el corte llegue al otro lado y el
   barrido no llega a verse. Aquí el recorte es toda la animación. */
:is([data-motion="wipe"], [data-motion="wipe-up"])[data-motion-armed="true"] {
    opacity: 1;
}

:is([data-motion="wipe"], [data-motion="wipe-up"]) > img {
    transition: clip-path 0.9s var(--ease-curve), transform 0.9s var(--ease-curve);
    transition-delay: var(--motion-delay, 0ms);
}

[data-motion="wipe"][data-motion-armed="true"] > img {
    clip-path: inset(0 100% 0 0);
}

[data-motion="wipe-up"][data-motion-armed="true"] > img {
    clip-path: inset(100% 0 0 0);
}

:is([data-motion="wipe"], [data-motion="wipe-up"])[data-motion-revealed="true"] > img {
    clip-path: inset(0 0 0 0);
}

[data-motion][data-motion-revealed="true"] {
    opacity: 1;
    transform: none;
}

/* La cota se dibuja como se acota un plano: el texto entra deprisa y los dos
   trazos se extienden después, cada uno desde su extremo. */
[data-motion="cota"] {
    transition: opacity 0.45s var(--ease-curve);
    transition-delay: var(--motion-delay, 0ms);
}

[data-motion="cota"]::before,
[data-motion="cota"]::after {
    transition: transform 0.9s var(--ease-curve);
    transition-delay: var(--motion-delay, 0ms);
}

[data-motion="cota"]::before {
    transform-origin: left;
}

[data-motion="cota"]::after {
    transform-origin: right;
}

[data-motion="cota"][data-motion-armed="true"]::before,
[data-motion="cota"][data-motion-armed="true"]::after {
    transform: scaleX(0);
}

/* ==========================================================
   5. CABECERA — #site_header
   Ocupa todo el ancho; el contenido va en un contenedor
   propio de ancho limitado.
   ========================================================== */

#site_header {
    position: sticky;
    top: 0;
    z-index: 100;
    width: 100%;
    background-color: var(--body-color);
    border-bottom: 1px solid var(--border-color);
    transition: box-shadow var(--transition-base);
}

/* En cuanto la página deja de estar arriba del todo, la barra se despega del
   contenido que le pasa por debajo. Lo marca `animations.js`. */
#site_header[data-scrolled="true"] {
    box-shadow: 0 10px 30px rgba(10, 10, 10, 0.07);
}

#site_header .site-header__container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    height: var(--header-height);
    margin-inline: auto;
}

/* Logotipo. La marca A+B va en PNG con transparencia, en dos versiones: negra
   para la cabecera clara y blanca para el pie oscuro. */
#site_header .site-header__logo {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-shrink: 0;
    text-decoration: none;
}

#site_header .site-header__logo-image {
    width: auto;
    height: 38px;
    flex-shrink: 0;
}

#site_header .site-header__logo-text {
    display: flex;
    flex-direction: column;
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    line-height: 1.4;
    text-transform: uppercase;
}

#site_header .site-header__logo-place {
    color: var(--muted-color);
}

/* Navegación principal */
#site_header .site-header__nav-list {
    display: flex;
    align-items: center;
    gap: var(--space-6);
}

#site_header .site-header__nav-link {
    position: relative;
    display: block;
    padding: var(--space-2) 0;
    font-family: var(--mono-font);
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
}

/* El subrayado se traza de izquierda a derecha, como la cota de las secciones,
   en lugar de encenderse de golpe. */
#site_header .site-header__nav-link::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 1px;
    background-color: var(--text-color);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--transition-base);
}

#site_header .site-header__nav-link:hover::after,
#site_header .site-header__nav-link--active::after,
#site_header .site-header__nav-link[aria-current="page"]::after {
    transform: scaleX(1);
}

#site_header .site-header__actions {
    display: flex;
    align-items: center;
    gap: var(--space-5);
}

/* Botón diferencial de la cabecera: tiene forma de botón y no de enlace de
   menú, porque es la acción que el negocio quiere que ocurra. */
#site_header .site-header__cta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0.875rem 1.5rem;
    border: 1px solid var(--primary-color);
    background-color: var(--primary-color);
    color: var(--inverse-color);
    font-family: var(--mono-font);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
    transition: background-color var(--transition-base), color var(--transition-base);
}

#site_header .site-header__cta:hover {
    background-color: var(--body-color);
    color: var(--primary-color);
}

/* Botón hamburguesa */
#site_header .site-header__menu-btn {
    display: none;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--border-color);
    background: none;
    color: var(--text-color);
    cursor: pointer;
}

#site_header .site-header__menu-bar {
    display: block;
    width: 18px;
    height: 1px;
    margin: 4px auto;
    background-color: currentColor;
    transition: transform var(--transition-base), opacity 0.2s var(--ease-curve);
}

#site_header .site-header__menu-btn[aria-expanded="true"] .site-header__menu-bar:nth-child(1) {
    transform: translateY(5px) rotate(45deg);
}

#site_header .site-header__menu-btn[aria-expanded="true"] .site-header__menu-bar:nth-child(2) {
    opacity: 0;
}

#site_header .site-header__menu-btn[aria-expanded="true"] .site-header__menu-bar:nth-child(3) {
    transform: translateY(-5px) rotate(-45deg);
}

/* Panel del menú móvil. Existe siempre en el HTML con `hidden`: no lo genera
   el JavaScript. */
#site_header .site-header__panel {
    position: fixed;
    inset: var(--header-height) 0 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    padding: var(--space-7) var(--space-5);
    background-color: var(--dark-color);
    color: var(--inverse-color);
    overflow-y: auto;
}

#site_header .site-header__panel[hidden] {
    display: none;
}

#site_header .site-header__panel-list {
    display: flex;
    flex-direction: column;
}

#site_header .site-header__panel-link {
    display: block;
    padding: var(--space-5) 0;
    border-bottom: 1px solid var(--dark-border-color);
    color: var(--inverse-color);
    font-family: var(--mono-font);
    font-size: 0.875rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
}

#site_header .site-header__panel-link:hover,
#site_header .site-header__panel-link--active {
    border-bottom-color: var(--inverse-color);
}

#site_header .site-header__panel-cta {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: var(--space-3);
    padding: 1rem 1.75rem;
    border: 1px solid var(--inverse-color);
    color: var(--inverse-color);
    font-family: var(--mono-font);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
    transition: background-color var(--transition-base), color var(--transition-base);
}

#site_header .site-header__panel-cta:hover {
    background-color: var(--inverse-color);
    color: var(--text-color);
}

/* La barra completa —logotipo, cinco entradas y botón— deja de caber por
   debajo del portátil, así que a partir de ahí manda el menú desplegable. */
@media (min-width: 1025px) {
    #site_header .site-header__panel {
        display: none;
    }
}

@media (max-width: 1024px) {
    #site_header .site-header__nav {
        display: none;
    }

    #site_header .site-header__cta {
        display: none;
    }

    #site_header .site-header__menu-btn {
        display: block;
    }
}

@media (max-width: 767px) {
    #site_header .site-header__logo-text {
        display: none;
    }
}

/* ==========================================================
   6. PIE — #site_footer
   ========================================================== */

#site_footer {
    width: 100%;
    padding-block: var(--space-8) var(--space-6);
    background-color: var(--dark-color);
    color: var(--inverse-color);
}

#site_footer .site-footer__container {
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    margin-inline: auto;
}

#site_footer .site-footer__columns {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
    gap: var(--space-6);
    padding-bottom: var(--space-7);
    border-bottom: 1px solid var(--dark-border-color);
}

#site_footer .site-footer__column {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

#site_footer .site-footer__brand {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    text-decoration: none;
}

#site_footer .site-footer__logo {
    width: auto;
    height: 44px;
    flex-shrink: 0;
}

#site_footer .site-footer__brand-text {
    display: flex;
    flex-direction: column;
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    line-height: 1.4;
    text-transform: uppercase;
}

#site_footer .site-footer__brand-place {
    color: var(--inverse-faint-color);
}

#site_footer .site-footer__tagline {
    max-width: 32ch;
    font-size: 0.9375rem;
    color: var(--inverse-soft-color);
}

#site_footer .site-footer__title {
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--inverse-faint-color);
}

#site_footer .site-footer__list,
#site_footer .site-footer__nav-list {
    display: grid;
    gap: var(--space-3);
    font-size: 0.9375rem;
}

#site_footer .site-footer__link,
#site_footer .site-footer__nav-link {
    display: inline-block;
    color: var(--inverse-muted-color);
    text-decoration: none;
    transition: color var(--transition-base), transform var(--transition-base);
}

#site_footer .site-footer__link:hover,
#site_footer .site-footer__nav-link:hover {
    transform: translateX(4px);
}

#site_footer .site-footer__link:hover,
#site_footer .site-footer__nav-link:hover,
#site_footer .site-footer__nav-link--active {
    color: var(--inverse-color);
}

#site_footer .site-footer__bottom {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding-top: var(--space-5);
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--inverse-faint-color);
}

#site_footer .site-footer__legal-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

#site_footer .site-footer__legal-link {
    color: var(--inverse-faint-color);
    text-decoration: none;
    transition: color var(--transition-base);
}

#site_footer .site-footer__legal-link:hover,
#site_footer .site-footer__legal-link--active {
    color: var(--inverse-color);
}

/* Botón flotante de WhatsApp. Vive dentro del pie para que viaje con él como
   un elemento más de la plantilla global. */
#site_footer .site-footer__whatsapp {
    position: fixed;
    right: var(--space-5);
    bottom: var(--space-5);
    z-index: 90;
    display: grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background-color: var(--dark-color);
    color: var(--inverse-color);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.22);
    transition: transform var(--transition-base);
}

#site_footer .site-footer__whatsapp:hover {
    transform: scale(1.08);
}

#site_footer .site-footer__whatsapp-icon {
    width: 26px;
    height: 26px;
    fill: currentColor;
}

@media (max-width: 1024px) {
    #site_footer .site-footer__columns {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-7) var(--space-6);
    }
}

@media (max-width: 520px) {
    #site_footer .site-footer__columns {
        grid-template-columns: 1fr;
    }

    #site_footer .site-footer__whatsapp {
        right: var(--space-4);
        bottom: var(--space-4);
    }
}

/* ==========================================================
   7. ANTETÍTULO DE COTA — .site-eyebrow
   Elemento firma del proyecto: la línea de acotación de un
   plano, ├──── ETIQUETA ────┤. Sustituye a los antetítulos
   y a las numeraciones decorativas 01/02/03.
   ========================================================== */

:is(#home_hero, #home_services, #home_process, #home_about, #home_works, #home_cta,
    #about_hero, #about_values, #about_process, #about_location, #about_cta,
    #services_hero, #services_list, #services_cta,
    #gallery_hero, #gallery_works, #gallery_cta,
    #contact_hero, #contact_channels, #contact_quote) .site-eyebrow {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted-color);
    white-space: nowrap;
}

:is(#home_hero, #home_services, #home_process, #home_about, #home_works, #home_cta,
    #about_hero, #about_values, #about_process, #about_location, #about_cta,
    #services_hero, #services_list, #services_cta,
    #gallery_hero, #gallery_works, #gallery_cta,
    #contact_hero, #contact_channels, #contact_quote) .site-eyebrow::before,
:is(#home_hero, #home_services, #home_process, #home_about, #home_works, #home_cta,
    #about_hero, #about_values, #about_process, #about_location, #about_cta,
    #services_hero, #services_list, #services_cta,
    #gallery_hero, #gallery_works, #gallery_cta,
    #contact_hero, #contact_channels, #contact_quote) .site-eyebrow::after {
    content: "";
    flex: 1 1 auto;
    height: 8px;
    border-bottom: 1px solid currentColor;
}

/* Arranca pegada al texto: el trazo solo se extiende hacia la derecha. */
:is(#home_hero, #home_services, #home_process, #home_about, #home_works, #home_cta,
    #about_hero, #about_values, #about_process, #about_location, #about_cta,
    #services_hero, #services_list, #services_cta,
    #gallery_hero, #gallery_works, #gallery_cta,
    #contact_hero, #contact_channels, #contact_quote) .site-eyebrow::before {
    flex: 0 0 28px;
    border-left: 1px solid currentColor;
}

:is(#home_hero, #home_services, #home_process, #home_about, #home_works, #home_cta,
    #about_hero, #about_values, #about_process, #about_location, #about_cta,
    #services_hero, #services_list, #services_cta,
    #gallery_hero, #gallery_works, #gallery_cta,
    #contact_hero, #contact_channels, #contact_quote) .site-eyebrow::after {
    border-right: 1px solid currentColor;
}

/* Sobre fondo oscuro */
:is(#home_hero, #home_process, #home_cta,
    #about_hero, #about_process, #about_cta,
    #services_hero, #services_cta,
    #gallery_hero, #gallery_cta,
    #contact_hero) .site-eyebrow--inverse {
    color: var(--inverse-faint-color);
}

/* ==========================================================
   8. BOTONES — .site-button
   ========================================================== */

:is(#home_hero, #home_cta, #about_cta, #services_cta, #gallery_cta, #contact_quote) .site-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    padding: 1rem 1.75rem;
    border: 1px solid var(--primary-color);
    background: none;
    color: var(--text-color);
    font-family: var(--mono-font);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--transition-base), color var(--transition-base), transform var(--transition-base);
}

:is(#home_hero, #home_cta, #about_cta, #services_cta, #gallery_cta, #contact_quote) .site-button:hover {
    background-color: var(--primary-color);
    color: var(--inverse-color);
    transform: translateY(-2px);
}

:is(#home_hero, #home_cta, #about_cta, #services_cta, #gallery_cta, #contact_quote) .site-button:active {
    transform: translateY(0);
}

/* Relleno negro sobre fondo claro */
:is(#contact_quote) .site-button--solid {
    background-color: var(--primary-color);
    color: var(--inverse-color);
}

:is(#contact_quote) .site-button--solid:hover {
    background-color: var(--primary-hover-color);
    color: var(--inverse-color);
}

/* Relleno blanco sobre fondo oscuro */
:is(#home_hero, #home_cta, #about_cta, #services_cta, #gallery_cta) .site-button--inverse-solid {
    border-color: var(--inverse-color);
    background-color: var(--inverse-color);
    color: var(--text-color);
}

:is(#home_hero, #home_cta, #about_cta, #services_cta, #gallery_cta) .site-button--inverse-solid:hover {
    background-color: transparent;
    color: var(--inverse-color);
}

/* Contorno blanco sobre fondo oscuro */
:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .site-button--inverse-outline {
    border-color: var(--inverse-color);
    color: var(--inverse-color);
}

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .site-button--inverse-outline:hover {
    background-color: var(--inverse-color);
    color: var(--text-color);
}

/* Grupo de botones */
:is(#home_hero, #home_cta, #about_cta, #services_cta, #gallery_cta) .site-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-5);
}

@media (max-width: 520px) {
    :is(#home_hero, #home_cta, #about_cta, #services_cta, #gallery_cta) .site-actions {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ==========================================================
   9. ENLACE DE ACCIÓN — .action-link
   Enlace subrayado con flecha, para acciones secundarias.
   ========================================================== */

:is(#home_hero, #home_services, #home_about, #home_works) .action-link {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    gap: var(--space-2);
    padding-bottom: 3px;
    border-bottom: 1px solid currentColor;
    font-family: var(--mono-font);
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
}

:is(#home_hero, #home_services, #home_about, #home_works) .action-link__arrow {
    transition: transform var(--transition-base);
}

:is(#home_hero, #home_services, #home_about, #home_works) .action-link:hover .action-link__arrow {
    transform: translateX(5px);
}

/* ==========================================================
   10. HÉROE DE PÁGINA INTERIOR — .page-hero
   ========================================================== */

:is(#about_hero, #services_hero, #gallery_hero, #contact_hero,
    #legal_hero, #privacy_hero, #cookies_hero, #dataprotection_hero, #accessibility_hero) {
    padding-block: clamp(var(--space-8), 8vw, calc(var(--section-padding-y) * 0.75));
    background-color: var(--dark-color);
    color: var(--inverse-color);
}

:is(#about_hero, #services_hero, #gallery_hero, #contact_hero,
    #legal_hero, #privacy_hero, #cookies_hero, #dataprotection_hero, #accessibility_hero) .page-hero__container {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    margin-inline: auto;
}

:is(#about_hero, #services_hero, #gallery_hero, #contact_hero,
    #legal_hero, #privacy_hero, #cookies_hero, #dataprotection_hero, #accessibility_hero) .page-hero__title {
    font-size: clamp(2.5rem, 5.5vw, 4.25rem);
}

:is(#about_hero, #services_hero, #gallery_hero, #contact_hero) .page-hero__description {
    max-width: 58ch;
    font-size: 1.125rem;
    color: var(--inverse-soft-color);
}

/* El titular de las páginas legales es una frase larga, no un rótulo: pide una
   caja tipográfica más contenida para no partirse en cinco líneas. */
:is(#legal_hero, #privacy_hero, #cookies_hero, #dataprotection_hero, #accessibility_hero) .page-hero__title {
    max-width: 24ch;
    font-size: clamp(1.75rem, 3.6vw, 2.75rem);
    /* El titular de la declaración de accesibilidad lleva el dominio dentro, y
       un dominio largo no tiene por dónde partirse en un móvil estrecho. */
    overflow-wrap: anywhere;
}

/* ==========================================================
   11. ENCABEZADO DE SECCIÓN — .section-header
   ========================================================== */

:is(#home_services, #home_process, #home_works,
    #about_values, #about_process,
    #contact_channels, #contact_quote, #gallery_works) .section-header {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    max-width: 780px;
}

:is(#home_services, #home_process, #home_works,
    #about_values, #about_process,
    #contact_channels, #contact_quote, #gallery_works) .section-header__title {
    font-size: clamp(2rem, 4vw, 3.25rem);
}

/* Encabezado que acompaña a otro principal y no debe competir con él */
:is(#contact_quote) .section-header--secondary .section-header__title {
    font-size: clamp(1.5rem, 2.5vw, 2rem);
}

:is(#home_services, #home_process, #home_works,
    #about_values, #about_process,
    #contact_channels, #contact_quote, #gallery_works) .section-header__description {
    max-width: 60ch;
    font-size: 1.0625rem;
    color: var(--muted-color);
}

:is(#home_process, #about_process) .section-header__description {
    color: var(--inverse-soft-color);
}

/* ==========================================================
   12. REJILLA DE TARJETAS — .cards-grid / .site-card
   La rejilla se dibuja con el propio hueco: el fondo de la
   rejilla asoma por el `gap` de 1 px y hace de retícula.
   ========================================================== */

:is(#home_services, #about_values, #contact_channels) .cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1px;
    background-color: var(--border-color);
    border: 1px solid var(--border-color);
}

:is(#contact_channels) .cards-grid--compact {
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

:is(#home_services, #about_values, #contact_channels) .site-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-7) var(--space-6);
    background-color: var(--body-color);
    text-decoration: none;
}

:is(#home_services, #about_values, #contact_channels) .site-card__reference {
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    letter-spacing: 0.16em;
    color: var(--muted-color);
    transition: color 0.35s var(--ease-curve);
}

:is(#home_services, #about_values, #contact_channels) .site-card__title {
    font-size: 1.375rem;
    letter-spacing: -0.02em;
}

:is(#home_services, #about_values, #contact_channels) .site-card__text {
    font-size: 0.9375rem;
    line-height: 1.65;
    color: var(--muted-color);
    transition: color 0.35s var(--ease-curve);
}

/* Solo las tarjetas que son enlace reaccionan al puntero. */
:is(#home_services, #contact_channels) .site-card--link {
    transition: background-color 0.35s var(--ease-curve), color 0.35s var(--ease-curve);
}

:is(#home_services, #contact_channels) .site-card--link:hover {
    background-color: var(--dark-color);
    color: var(--inverse-color);
}

:is(#home_services, #contact_channels) .site-card--link:hover .site-card__text,
:is(#home_services, #contact_channels) .site-card--link:hover .site-card__reference {
    color: var(--inverse-soft-color);
}

/* ==========================================================
   13. PROCESO DE TRABAJO — .process
   Aquí la numeración sí es información: el orden importa.
   ========================================================== */

:is(#home_process, #about_process) {
    padding-block: clamp(4.5rem, 9vw, var(--section-padding-y));
    background-color: var(--dark-color);
    color: var(--inverse-color);
}

:is(#home_process, #about_process) .process__container {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    margin-inline: auto;
}

:is(#home_process, #about_process) .process__list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: var(--space-6);
}

:is(#home_process, #about_process) .process__step {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-top: var(--space-5);
    border-top: 1px solid var(--dark-border-color);
}

:is(#home_process, #about_process) .process__order {
    padding-bottom: var(--space-2);
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    letter-spacing: 0.2em;
    color: var(--inverse-faint-color);
}

:is(#home_process, #about_process) .process__title {
    font-size: 1.25rem;
    letter-spacing: -0.02em;
}

:is(#home_process, #about_process) .process__text {
    font-size: 0.9375rem;
    line-height: 1.65;
    color: var(--inverse-soft-color);
}

/* ==========================================================
   14. BLOQUE DE TEXTO E IMAGEN — .text-media
   ========================================================== */

:is(#home_about, #about_story, #about_location) {
    padding-block: clamp(4.5rem, 9vw, var(--section-padding-y));
}

:is(#home_about, #about_story, #about_location) .text-media {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(var(--space-6), 6vw, var(--space-9));
    align-items: center;
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    margin-inline: auto;
}

:is(#home_about, #about_story, #about_location) .text-media__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-7);
}

:is(#home_about, #about_story, #about_location) .text-media__intro {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

:is(#home_about, #about_story, #about_location) .text-media__title {
    font-size: clamp(1.75rem, 3.5vw, 2.75rem);
}

:is(#home_about, #about_story, #about_location) .text-media__paragraph {
    color: var(--text-color);
}

:is(#home_about, #about_story, #about_location) .text-media__media {
    background-color: var(--alt-color);
}

:is(#about_location) .text-media--reversed .text-media__media {
    order: -1;
}

/* Lista de argumentos con filete superior */
:is(#home_about, #about_location) .facts {
    display: grid;
    gap: var(--space-5);
}

:is(#home_about, #about_location) .facts__item {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-color);
}

:is(#home_about, #about_location) .facts__title {
    font-family: var(--mono-font);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

:is(#home_about, #about_location) .facts__text {
    font-size: 0.9375rem;
    color: var(--muted-color);
}

@media (max-width: 1024px) {
    :is(#home_about, #about_story, #about_location) .text-media {
        grid-template-columns: 1fr;
    }

    :is(#about_location) .text-media--reversed .text-media__media {
        order: 0;
    }
}

/* ==========================================================
   15. GALERÍA DE TRABAJOS — .works
   ========================================================== */

:is(#home_works, #gallery_works) .works {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-5);
}

:is(#home_works, #gallery_works) .works__item {
    position: relative;
    overflow: hidden;
    background-color: var(--alt-color);
}

:is(#home_works, #gallery_works) .works__item[hidden] {
    display: none;
}

/* Retrato: casi todas las fotos de obra vienen en vertical desde el móvil, así
   que se recorta lo mínimo imprescindible. */
:is(#home_works, #gallery_works) .works__image {
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    transition: transform 0.6s var(--ease-curve);
}

:is(#home_works, #gallery_works) .works__item:hover .works__image {
    transform: scale(1.04);
}

:is(#home_works, #gallery_works) .works__caption {
    position: absolute;
    inset: auto 0 0 0;
    display: flex;
    flex-direction: column;
    /* El relleno superior es la carrerilla que necesita el velo para
       desvanecerse por encima del texto en lugar de hacerlo sobre él. */
    padding: var(--space-8) var(--space-4) var(--space-4);
    background: var(--photo-veil);
    color: var(--inverse-color);
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    transition: transform 0.6s var(--ease-curve);
}

/* El rótulo sube un poco mientras la fotografía se acerca: los dos se mueven
   a la vez y en la misma dirección, así que la tarjeta parece una sola pieza. */
:is(#home_works, #gallery_works) .works__item:hover .works__caption {
    transform: translateY(-4px);
}

:is(#home_works, #gallery_works) .works__place {
    color: var(--inverse-muted-color);
    letter-spacing: 0.1em;
}

/* ==========================================================
   16. FRANJA DESTACADA — .highlight-band
   Una sola fila para una idea que merece salirse del ritmo de
   las secciones. Usa la superficie oscura, que no gasta
   ninguna otra franja: así no quedan dos negros seguidos.
   ========================================================== */

:is(#home_architect, #services_architect) {
    padding-block: clamp(var(--space-7), 6vw, calc(var(--section-padding-y) * 0.5));
    background-color: var(--dark-surface-color);
    color: var(--inverse-color);
}

:is(#home_architect, #services_architect) .highlight-band__container {
    display: grid;
    /* El texto pide algo más de sitio que el titular, que va en dos líneas. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: clamp(var(--space-5), 5vw, var(--space-8));
    align-items: start;
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    margin-inline: auto;
}

:is(#home_architect, #services_architect) .highlight-band__title {
    font-size: clamp(1.5rem, 3vw, 2.25rem);
}

:is(#home_architect, #services_architect) .highlight-band__text {
    max-width: 56ch;
    font-size: 1.0625rem;
    color: var(--inverse-soft-color); /* 6,69:1 sobre la superficie oscura */
}

@media (max-width: 1024px) {
    :is(#home_architect, #services_architect) .highlight-band__container {
        grid-template-columns: 1fr;
    }
}

/* ==========================================================
   17. LLAMADA A LA ACCIÓN — .cta-band
   ========================================================== */

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) {
    padding-block: clamp(4.5rem, 9vw, var(--section-padding-y));
    background-color: var(--dark-color);
    color: var(--inverse-color);
}

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .cta-band__container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-7);
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    margin-inline: auto;
    text-align: center;
}

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .cta-band__intro {
    display: flex;
    flex-direction: column;
    align-items: center;
    align-self: stretch;
    gap: var(--space-5);
}

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .cta-band__intro .site-eyebrow {
    justify-content: center;
    align-self: stretch;
}

/* En el CTA del home, el antetítulo se centra entre dos líneas simétricas
   para que el texto quede visualmente alineado con el título. */
#home_cta .cta-band__intro .site-eyebrow::before,
#home_cta .cta-band__intro .site-eyebrow::after {
    flex: 1 1 0;
}

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .cta-band__title {
    font-size: clamp(2rem, 4.5vw, 3.5rem);
}

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .cta-band__text {
    max-width: 52ch;
    color: var(--inverse-soft-color);
}

:is(#home_cta, #about_cta, #services_cta, #gallery_cta) .cta-band__actions {
    justify-content: center;
}

/* ==========================================================
   18. DOCUMENTO LEGAL — .site-legal
   Componente compartido por las cinco páginas legales.
   ========================================================== */

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) {
    padding-block: clamp(3.5rem, 7vw, calc(var(--section-padding-y) * 0.75));
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__container {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-7);
    width: min(100% - (var(--section-padding-x) * 2), var(--container-width));
    margin-inline: auto;
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__index {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-color);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__index-title {
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--muted-color);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__index-list {
    display: grid;
    gap: var(--space-2);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__index-link {
    font-family: var(--mono-font);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    color: var(--muted-color);
    text-decoration: none;
    transition: color var(--transition-base);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__index-link:hover {
    color: var(--text-color);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__document {
    display: flex;
    flex-direction: column;
    gap: var(--space-7);
    /* Sin esto, un hijo ancho —las tablas de cookies— estira la columna en vez
       de rodar dentro de su propio contenedor, y la página se va de ancho. */
    min-width: 0;
    max-width: 76ch;
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__block {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    scroll-margin-top: calc(var(--header-height) + var(--space-5));
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__block-number {
    font-family: var(--mono-font);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    color: var(--muted-color);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__block-title {
    font-size: 1.5rem;
    text-transform: none;
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__subtitle {
    margin-top: var(--space-2);
    font-size: 1.125rem;
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__paragraph {
    font-size: 1rem;
    color: var(--legal-color);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__list {
    display: grid;
    gap: var(--space-2);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__list-item {
    position: relative;
    padding-left: var(--space-5);
    font-size: 1rem;
    color: var(--legal-color);
}

:is(#legal_content, #privacy_content, #cookies_content,
    #dataprotection_content, #accessibility_content) .site-legal__list-item::before {
    content: "—";
    position: absolute;
    left: 0;
    color: var(--muted-color);
}

/* La ficha de datos identificativos y las tablas de cookies son de una sola
   página cada una, así que viven en su hoja: `aviso-legal.css` y
   `politica-cookies.css`. */

/* A partir del portátil, el índice se queda fijo a la izquierda del texto. */
@media (min-width: 1025px) {
    :is(#legal_content, #privacy_content, #cookies_content,
        #dataprotection_content, #accessibility_content) .site-legal__container {
        grid-template-columns: 260px minmax(0, 1fr);
        gap: var(--space-8);
        align-items: start;
    }

    :is(#legal_content, #privacy_content, #cookies_content,
        #dataprotection_content, #accessibility_content) .site-legal__index {
        position: sticky;
        top: calc(var(--header-height) + var(--space-5));
    }
}

/* ==========================================================
   19. MOVIMIENTO REDUCIDO
   ========================================================== */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    [data-motion],
    [data-motion][data-motion-armed="true"],
    [data-motion][data-motion-armed="true"] > img {
        opacity: 1;
        transform: none;
        clip-path: none;
    }

    [data-motion="cota"][data-motion-armed="true"]::before,
    [data-motion="cota"][data-motion-armed="true"]::after {
        transform: none;
    }

    *,
    *::before,
    *::after {
        scroll-behavior: auto !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}
