/* =========================================================================
   ESPECTRO PRO — hoja de estilos única
   Negro y blanco puro. Tipografía y movimiento hacen todo el trabajo.
   Orden: tokens · base · utilidades · layout · header · hero · ticker ·
          manifiesto · servicios (invertido) · nosotros · proyectos ·
          contacto · footer · página de proyectos · responsive
   ========================================================================= */

/* ---------- 1. Tokens ----------
   Hay dos temas. El oscuro es el de casa y vive en :root; el claro es el mismo
   diseño con los valores cambiados, en [data-theme="light"]. Ninguna regla de
   más abajo escribe un color literal: todas leen de aquí. Por eso el tema
   entero cambia con un atributo en el <html> y nada más.
   --bg-inv / --fg-inv son el bloque que va al revés que la página (la cinta de
   servicios y la sección Servicios). Se invierten solos con el tema.        */
:root{
  --bg:#000;
  --fg:#fff;
  --mut:#8f8f8f;          /* texto secundario */
  --line:rgba(255,255,255,.16);
  --line-soft:rgba(255,255,255,.08);
  --surface:#0b0b0b;      /* fondo de las portadas de proyecto */
  --bg-glass:rgba(0,0,0,.72);
  --grain:.035;

  /* bloque invertido (cinta + sección Servicios) */
  --bg-inv:#fff;
  --fg-inv:#000;
  --mut-inv:#6b6b6b;
  --line-inv:rgba(0,0,0,.16);

  /* EL NARANJA DE LA MARCA
     --accent es el color exacto (#F9A621) y sólo se usa como SUPERFICIE:
     relleno de botón, chip activo, el botón de WhatsApp. Sobre él va --on-accent.
     Como TEXTO no vale en todas partes: #F9A621 sobre blanco da 1.98:1 de
     contraste, muy por debajo del mínimo legible. Por eso hay una segunda
     variante, --accent-ink, que es el naranja que sí se lee encima del fondo
     que toque. La versión "-inv" es la del bloque que va al revés (la cinta y
     la sección Servicios), y por eso las dos se cruzan al cambiar de tema. */
  --accent:#F9A621;
  --on-accent:#141414;
  --accent-ink:#F9A621;      /* texto naranja sobre el fondo de página (negro) */
  --accent-ink-inv:#A66400;  /* texto naranja sobre el bloque invertido (blanco) */

  /* El logo es arte negro sobre transparente, así que en tema oscuro se
     invierte a blanco. Si algún día lo exportas ya en blanco, pon "none". */
  --logo-filter:invert(1);
}

:root[data-theme="light"]{
  --bg:#fff;
  --fg:#0b0b0b;
  --mut:#6b6b6b;
  --line:rgba(0,0,0,.16);
  --line-soft:rgba(0,0,0,.08);
  --surface:#f1efec;
  --bg-glass:rgba(255,255,255,.78);
  --grain:.022;           /* sobre blanco el grano se nota el doble */

  --bg-inv:#0b0b0b;
  --fg-inv:#fff;
  --mut-inv:#8f8f8f;
  --line-inv:rgba(255,255,255,.16);

  /* aquí el cruce: la página es blanca y el bloque invertido es negro */
  --accent-ink:#A66400;
  --accent-ink-inv:#F9A621;

  --logo-filter:none;        /* sobre blanco el logo va tal cual */
}

/* lo que no cambia entre temas */
:root{
  --font-sans:"Archivo","Helvetica Neue",Helvetica,Arial,sans-serif;
  --font-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* escala tipográfica fluida */
  /* el mínimo es deliberadamente bajo: los titulares van dentro de cajas con
     overflow:hidden (la animación de línea), así que si no caben se cortan */
  --fs-display:clamp(2.25rem,8.6vw,9rem);
  /* el titular del hero es más largo que el resto, así que va un punto por
     debajo del display general para que quepa sin cortarse */
  --fs-hero:clamp(1.75rem,6vw,5.6rem);
  --fs-h2:clamp(1.8rem,5.4vw,4.6rem);
  --fs-h3:clamp(1.35rem,2.4vw,2.1rem);
  --fs-lead:clamp(1.05rem,1.55vw,1.4rem);
  --fs-body:clamp(.95rem,1.05vw,1.05rem);
  --fs-micro:clamp(.66rem,.78vw,.75rem);

  --pad:clamp(20px,5vw,72px);      /* margen lateral del grid */
  --maxw:1560px;

  --ease:cubic-bezier(.16,1,.3,1); /* expo out — todo el movimiento usa esta */
  --ease-soft:cubic-bezier(.22,.61,.36,1);
}

/* ---------- 2. Base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;color-scheme:dark}
:root[data-theme="light"]{color-scheme:light}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* Al cambiar de tema se funde en lugar de saltar. La clase la pone y la quita
   el JS sólo durante el cambio: dejarla fija pelearía con el resto de
   transiciones de la página. */
:root.theme-anim,:root.theme-anim *{
  transition:background-color .4s linear,color .4s linear,
             border-color .4s linear,fill .4s linear,stroke .4s linear!important;
}
@media (prefers-reduced-motion:reduce){
  :root.theme-anim,:root.theme-anim *{transition:none!important}
}

body{
  margin:0;
  background:var(--bg);
  color:var(--fg);
  font-family:var(--font-sans);
  font-size:var(--fs-body);
  font-weight:400;
  line-height:1.6;
  letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
/* el cursor propio sólo se activa en punteros finos; ver js */
body.has-cursor,body.has-cursor a,body.has-cursor button{cursor:none}

img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0}
h1,h2,h3,h4,p,figure,blockquote{margin:0}
ul,ol{margin:0;padding:0;list-style:none}

::selection{background:var(--accent);color:var(--on-accent)}

:focus-visible{outline:2px solid currentColor;outline-offset:4px;border-radius:2px}

/* grano: rompe el plano y evita el look "degradado plano" */
body::after{
  content:"";position:fixed;inset:-50%;z-index:9998;pointer-events:none;
  opacity:var(--grain);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- 3. Utilidades tipográficas ---------- */
.micro{
  font-family:var(--font-mono);
  font-size:var(--fs-micro);
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--mut);
}
.inv .micro{color:var(--mut-inv)}

.display{
  font-size:var(--fs-display);
  font-weight:800;
  line-height:.92;
  letter-spacing:-.035em;
  text-transform:uppercase;
}
.h2{
  font-size:var(--fs-h2);
  font-weight:700;
  line-height:1.0;
  letter-spacing:-.03em;
  text-transform:uppercase;
}
.h3{font-size:var(--fs-h3);font-weight:600;line-height:1.14;letter-spacing:-.022em}
.lead{font-size:var(--fs-lead);line-height:1.5;letter-spacing:-.015em;font-weight:400}
.dim{color:var(--mut)}
.inv .dim{color:var(--mut-inv)}
.nowrap{white-space:nowrap}
.acc{color:var(--accent-ink)}           /* el naranja, para numeración y detalles */

/* ---------- 4. Layout ---------- */
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--pad)}
.section{padding-block:clamp(84px,11vh,168px);position:relative}
/* el header es fijo: los anclajes se detienen por debajo de él */
section[id]{scroll-margin-top:clamp(70px,9vh,104px)}
.rule{height:1px;background:var(--line);border:0;margin:0}
.inv .rule{background:var(--line-inv)}

/* cabecera de sección: etiqueta mono a la izquierda, contenido a la derecha */
.shead{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:clamp(24px,3.4vw,56px);
  padding-top:22px;
  border-top:1px solid var(--line);
}
.inv .shead{border-top-color:var(--line-inv)}
@media (min-width:900px){
  .shead{grid-template-columns:200px minmax(0,1fr)}
}

/* ---------- 5. Movimiento (reveal) ----------
   Los estados escondidos cuelgan de .js, una clase que el script del <head>
   pone en el <html> antes de pintar nada. Si el JavaScript no llega a correr
   —bloqueado, caído, un navegador raro— esa clase no existe y TODO el texto
   se ve de entrada. Sin esto, un fallo de JS dejaba la página en blanco con
   el contenido invisible pero ocupando su sitio.                            */
.rl{display:block;overflow:hidden;padding-bottom:.06em}
.rl > span{display:block}
.js .rl > span{
  transform:translateY(106%);
  transition:transform 1s var(--ease);
  transition-delay:var(--d,0ms);
}
.js .is-in .rl > span{transform:translateY(0)}

.js [data-fade]{
  opacity:0;transform:translateY(20px);
  transition:opacity .9s var(--ease-soft),transform .9s var(--ease);
  transition-delay:var(--d,0ms);
}
.is-in[data-fade],.is-in [data-fade]{opacity:1;transform:none}

/* línea que se dibuja de izquierda a derecha */
[data-draw]{transform:scaleX(0);transform-origin:left center;transition:transform 1.1s var(--ease);transition-delay:var(--d,0ms)}
.is-in[data-draw],.is-in [data-draw]{transform:scaleX(1)}

@media (prefers-reduced-motion:reduce){
  .rl > span,[data-fade],[data-draw]{transform:none!important;opacity:1!important;transition:none!important}
}

/* ---------- 6. Cursor propio ---------- */
.cursor{
  position:fixed;top:0;left:0;z-index:9999;pointer-events:none;
  width:12px;height:12px;border-radius:50%;
  border:1px solid #fff;
  mix-blend-mode:difference;   /* funciona igual sobre negro y sobre blanco */
  transform:translate3d(-100px,-100px,0);
  transition:width .3s var(--ease),height .3s var(--ease),background .3s var(--ease);
  display:none;
}
body.has-cursor .cursor{display:block}
.cursor.is-big{width:52px;height:52px;background:#fff}
.cursor.is-text{width:3px;height:26px;border-radius:2px;background:#fff}

/* ---------- 7. Header ---------- */
.header{
  position:fixed;inset:0 0 auto 0;z-index:900;
  transition:transform .5s var(--ease),background .4s linear,border-color .4s linear;
  border-bottom:1px solid transparent;
}
.header.is-stuck{
  background:var(--bg-glass);
  -webkit-backdrop-filter:blur(14px) saturate(120%);
  backdrop-filter:blur(14px) saturate(120%);
  border-bottom-color:var(--line-soft);
}
.header.is-hidden{transform:translateY(-102%)}
/* el logo empuja al resto a la derecha; así da igual cuántos controles haya */
.header .wrap{display:flex;align-items:center;justify-content:flex-end;
  gap:clamp(10px,1.4vw,20px);height:clamp(64px,7.4vh,86px)}

.brand{display:flex;align-items:center;gap:11px;letter-spacing:-.03em;margin-right:auto}
.brand__mark{width:24px;height:24px;flex:none}
.brand__mark rect,.brand__mark path{transition:transform .6s var(--ease)}
.brand:hover .brand__mark{animation:markPulse .7s var(--ease)}
@keyframes markPulse{50%{transform:rotate(-90deg)}100%{transform:rotate(0)}}
.brand__name{font-weight:700;font-size:1.02rem;text-transform:uppercase;letter-spacing:-.01em}
.brand__name b{font-weight:400;color:var(--mut)}

/* El logo de verdad. Mientras el archivo no exista se ve el lockup dibujado
   arriba; en cuanto se sube, el JS marca .has-logo y cambia uno por otro.
   Mismo truco que con las fotos de proyecto: nunca se ve nada roto. */
/* El lockup es vertical (marca arriba, palabra debajo), así que necesita más
   alto que un logo horizontal: a 26px la palabra ESPECTRO no se leería. */
.brand__logo{display:none;height:46px;width:auto;filter:var(--logo-filter)}
@media (max-width:480px){.brand__logo{height:40px}}
.brand.has-logo .brand__logo{display:block}
.brand.has-logo .brand__mark,.brand.has-logo .brand__name{display:none}

.nav{display:none;align-items:center;gap:clamp(18px,2vw,34px)}
@media (min-width:1000px){.nav{display:flex}}
.nav a{
  font-family:var(--font-mono);font-size:.74rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--mut);
  position:relative;padding-block:6px;transition:color .3s var(--ease-soft);
}
.nav a::after{
  content:"";position:absolute;left:0;bottom:0;width:100%;height:1px;background:var(--accent-ink);
  transform:scaleX(0);transform-origin:right center;transition:transform .45s var(--ease);
}
.nav a:hover,.nav a[aria-current="page"]{color:var(--fg)}
.nav a:hover::after,.nav a[aria-current="page"]::after{transform:scaleX(1);transform-origin:left center}

/* botón principal */
.btn{
  display:inline-flex;align-items:center;gap:12px;position:relative;overflow:hidden;
  height:46px;padding:0 22px;border-radius:999px;
  border:1px solid var(--line);
  font-family:var(--font-mono);font-size:.74rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;
  transition:color .4s var(--ease-soft),border-color .4s var(--ease-soft);
  will-change:transform;
}
.btn span{position:relative;z-index:1}
.btn::before{ /* relleno que sube desde abajo */
  content:"";position:absolute;inset:0;background:var(--fg);z-index:0;
  transform:translateY(101%);transition:transform .5s var(--ease);
}
.btn:hover{color:var(--bg);border-color:var(--fg)}
.btn:hover::before{transform:translateY(0)}
.btn .arw{position:relative;z-index:1;width:9px;height:9px;transition:transform .45s var(--ease)}
.btn:hover .arw{transform:translate(3px,-3px)}
/* el botón principal es el único sitio donde el naranja ocupa superficie */
.btn--solid{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.btn--solid::before{background:var(--fg)}
.btn--solid:hover{color:var(--bg);border-color:var(--fg)}
.btn--lg{height:58px;padding:0 30px;font-size:.78rem}
.inv .btn{border-color:var(--line-inv);color:var(--fg-inv)}
.inv .btn::before{background:var(--fg-inv)}
.inv .btn:hover{color:var(--bg-inv);border-color:var(--fg-inv)}
@media (prefers-reduced-motion:reduce){
  .btn::before{display:none}
  .btn:hover{background:var(--fg);color:var(--bg)}
  .btn--solid:hover{background:var(--fg);color:var(--bg)}
}

.header .btn{display:none}
@media (min-width:1000px){.header .btn{display:inline-flex}}

/* conmutador de tema — el icono es un círculo medio relleno que gira al pulsar */
.tgl{
  display:grid;place-content:center;width:40px;height:40px;flex:none;
  border:1px solid var(--line);border-radius:50%;cursor:pointer;
  color:var(--fg);-webkit-tap-highlight-color:transparent;
  transition:border-color .35s var(--ease-soft),color .35s var(--ease-soft);
}
.tgl svg{width:17px;height:17px;transition:transform .55s var(--ease)}
.tgl:hover{border-color:var(--accent-ink);color:var(--accent-ink)}
:root[data-theme="light"] .tgl svg{transform:rotate(180deg)}
@media (prefers-reduced-motion:reduce){.tgl svg{transition:none}}

/* conmutador de idioma — muestra el idioma al que se puede cambiar */
.lang{
  display:grid;place-content:center;height:40px;min-width:40px;padding:0 11px;flex:none;
  border:1px solid var(--line);border-radius:999px;cursor:pointer;color:var(--fg);
  font-family:var(--font-mono);font-size:.7rem;font-weight:500;letter-spacing:.1em;
  -webkit-tap-highlight-color:transparent;
  transition:border-color .35s var(--ease-soft),color .35s var(--ease-soft);
}
.lang:hover{border-color:var(--accent);color:var(--accent-ink)}

/* hamburguesa */
.burger{
  display:grid;place-content:center;gap:5px;width:44px;height:44px;margin-right:-10px;
  border-radius:50%;-webkit-tap-highlight-color:transparent;
}
@media (min-width:1000px){.burger{display:none}}
.burger i{display:block;width:20px;height:1.5px;background:var(--fg);border-radius:2px;
  transition:transform .4s var(--ease),opacity .2s linear}
body.menu-open .burger i:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
body.menu-open .burger i:nth-child(2){opacity:0}
body.menu-open .burger i:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

/* panel móvil a pantalla completa */
.menu{
  position:fixed;inset:0;z-index:880;background:var(--bg);
  display:flex;flex-direction:column;justify-content:center;
  padding:calc(var(--pad) + 60px) var(--pad) var(--pad);
  clip-path:inset(0 0 100% 0);
  transition:clip-path .7s var(--ease);
  visibility:hidden;
}
body.menu-open .menu{clip-path:inset(0 0 0 0);visibility:visible}
.menu__list li{overflow:hidden;border-bottom:1px solid var(--line-soft)}
.menu__list a{
  display:flex;align-items:baseline;gap:16px;padding:clamp(12px,2.4vh,22px) 0;
  font-size:clamp(2rem,9vw,3.4rem);font-weight:700;letter-spacing:-.035em;
  text-transform:uppercase;line-height:1;
  transform:translateY(105%);transition:transform .8s var(--ease);
}
body.menu-open .menu__list a{transform:none}
.menu__list li:nth-child(1) a{transition-delay:.10s}
.menu__list li:nth-child(2) a{transition-delay:.16s}
.menu__list li:nth-child(3) a{transition-delay:.22s}
.menu__list li:nth-child(4) a{transition-delay:.28s}
.menu__list li:nth-child(5) a{transition-delay:.34s}
.menu__list a em{font-style:normal;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.14em;color:var(--mut)}
.menu__foot{margin-top:clamp(28px,5vh,56px);display:flex;flex-wrap:wrap;gap:10px 26px}
@media (prefers-reduced-motion:reduce){
  .menu{transition:none}.menu__list a{transition:none}
}

/* ---------- 8. Hero ---------- */
.hero{
  position:relative;min-height:100vh;min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end;
  padding-top:clamp(120px,18vh,200px);padding-bottom:clamp(28px,5vh,56px);
  overflow:hidden;
}
/* "espectro": barras de luz detrás del titular */
.spectrum{position:absolute;inset:0;z-index:0;display:flex;gap:0;pointer-events:none;
  mask-image:linear-gradient(180deg,transparent,#000 22%,#000 62%,transparent 96%);
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 22%,#000 62%,transparent 96%)}
.spectrum i{flex:1 1 0;background:var(--fg);opacity:.05;transform-origin:50% 100%;
  animation:bar 7.5s ease-in-out infinite;animation-delay:var(--dl,0s)}
@keyframes bar{
  0%,100%{opacity:.035;transform:scaleY(.72)}
  50%{opacity:.14;transform:scaleY(1)}
}
@media (prefers-reduced-motion:reduce){.spectrum i{animation:none;opacity:.06}}
/* cuando el vídeo consigue arrancar, las barras se apagan: ya no aportan y
   dejan de gastar pintura en cada fotograma */
.hero.has-video .spectrum{opacity:0;transition:opacity .8s linear}
/* Y además se les para la animación. Con opacity:0 seguían animándose las 48,
   invisibles, consumiendo trabajo en cada fotograma de toda la página; parte
   del tirón que se notaba más abajo salía de aquí. */
.hero.has-video .spectrum i{animation:none}
/* fuera de pantalla tampoco tiene sentido que sigan */
.hero.fuera-de-vista .spectrum i{animation-play-state:paused}

/* --- vídeo de fondo del hero --- */
.herovid{
  position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none;
  opacity:0;transition:opacity 1.1s var(--ease-soft);
  /* la misma máscara que las barras: el vídeo se disuelve por arriba y por
     abajo en vez de cortarse en seco contra el resto de la página */
  mask-image:linear-gradient(180deg,transparent,#000 20%,#000 64%,transparent 97%);
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 20%,#000 64%,transparent 97%);
}
.herovid.is-on{opacity:1}
/* El metraje está grabado en vertical (608x1080) y el hero es apaisado, así que
   sólo cabe una franja. Midiendo el contraste del vídeo por bandas, la parte
   con más detalle —la cabecera de la láser sobre el material— está entre el 33%
   y el 56% de la altura; el resto es techo y mesa planos. De ahí este 44%, que
   centra la franja visible justo en esa zona en vez de en el medio geométrico. */
.herovid video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center 44%}
/* Velo del color de la página: es lo que mantiene legible el titular encima
   del vídeo, y funciona igual en tema oscuro que en claro.
   --veil es el número a tocar si el vídeo se ve muy apagado (bájalo) o si el
   titular cuesta de leer (súbelo). 0 = vídeo a plena luz, 1 = vídeo invisible. */
.herovid{--veil:.58}
.herovid__veil{position:absolute;inset:0;background:var(--bg);opacity:var(--veil)}
/* en móvil el titular ocupa casi todo el ancho, así que necesita más velo */
@media (max-width:700px){.herovid{--veil:.68}}
@media (prefers-reduced-motion:reduce){.herovid{display:none}}

.hero__top{position:relative;z-index:1;display:flex;flex-wrap:wrap;gap:12px 28px;
  justify-content:space-between;align-items:flex-end;margin-bottom:clamp(26px,4vh,54px)}
.hero__top p{max-width:34ch}

.hero__title{position:relative;z-index:1}
.hero__title .display{margin-left:-.012em;font-size:var(--fs-hero);line-height:.96}

/* "primera impresión" va perfilada en hueco y se rellena de naranja al pasar
   por encima. En táctil no hay hover, así que allí se muestra ya rellena. */
.hero__title em{font-style:normal}
@media (hover:hover){
  .hero__title em{
    -webkit-text-stroke:1.5px var(--fg);color:transparent;
    transition:color .55s var(--ease),-webkit-text-stroke-color .55s var(--ease);
  }
  .hero__title em:hover{color:var(--accent-ink);-webkit-text-stroke-color:var(--accent-ink)}
}
@media (hover:none){
  .hero__title em{color:var(--accent-ink)}
}
@media (prefers-reduced-motion:reduce){.hero__title em{transition:none}}

.hero__foot{
  position:relative;z-index:1;margin-top:clamp(30px,5vh,60px);
  display:grid;gap:clamp(20px,3vw,44px);align-items:end;
  grid-template-columns:minmax(0,1fr);
  border-top:1px solid var(--line);padding-top:22px;
}
@media (min-width:900px){.hero__foot{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) auto}}
.hero__cta{display:flex;flex-wrap:wrap;gap:12px}

.scrollcue{display:flex;align-items:center;gap:10px}
.scrollcue i{display:block;width:1px;height:34px;background:linear-gradient(var(--accent-ink),transparent);
  animation:cue 2.1s var(--ease-soft) infinite}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top}45%{transform:scaleY(1);transform-origin:top}
  55%{transform:scaleY(1);transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}
@media (prefers-reduced-motion:reduce){.scrollcue i{animation:none}}

/* ---------- 9. Ticker ---------- */
.ticker{background:var(--bg-inv);color:var(--fg-inv);overflow:hidden;
  padding-block:clamp(14px,1.8vw,22px);user-select:none}
.ticker__track{display:flex;width:max-content;animation:marquee 44s linear infinite}
.ticker:hover .ticker__track{animation-play-state:paused}
.ticker__track > span{display:flex;align-items:center;gap:clamp(22px,3vw,48px);padding-right:clamp(22px,3vw,48px);
  font-size:clamp(1.05rem,2.3vw,1.9rem);font-weight:700;text-transform:uppercase;letter-spacing:-.02em;white-space:nowrap}
.ticker__track svg{width:.62em;height:.62em;flex:none;color:var(--accent-ink-inv)}
@keyframes marquee{to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
  .ticker__track{animation:none;flex-wrap:wrap;width:100%}
  .ticker__track > span:nth-child(2){display:none}   /* sin bucle, la copia sobra */
}

/* ---------- 10. Manifiesto / qué hacemos ---------- */
.manifesto p + p{margin-top:1.15em}
.manifesto__claim{max-width:22ch}

.pillars{display:grid;gap:1px;background:var(--line);margin-top:clamp(48px,7vh,96px);border-top:1px solid var(--line)}
@media (min-width:860px){.pillars{grid-template-columns:repeat(3,1fr)}}
.pillar{background:var(--bg);padding:clamp(26px,3vw,40px) 0;position:relative}
@media (min-width:860px){.pillar{padding:clamp(26px,3vw,40px) clamp(20px,2.4vw,34px)}
  .pillar:first-child{padding-left:0}.pillar:last-child{padding-right:0}}
.pillar__n{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.16em;color:var(--accent-ink);display:block;margin-bottom:clamp(30px,5vw,64px)}
.pillar h3{margin-bottom:10px}
.pillar p{color:var(--mut);max-width:34ch}
/* la línea superior se dibuja al entrar */
.pillar::before{content:"";position:absolute;top:-1px;left:0;right:0;height:1px;background:var(--accent-ink);
  transform:scaleX(0);transform-origin:left;transition:transform .9s var(--ease);transition-delay:var(--d,0ms)}
.is-in .pillar::before{transform:scaleX(1)}

/* ---------- 11. Servicios: galería de fichas ---------- */
.inv{background:var(--bg-inv);color:var(--fg-inv)}
.inv .rule{background:var(--line-inv)}

.svcgrid{display:grid;gap:clamp(10px,1.1vw,16px);grid-template-columns:1fr;
  margin-top:clamp(40px,6vh,80px)}
@media (min-width:860px){
  .svcgrid{grid-template-columns:repeat(2,1fr)}
  /* Si el número de fichas es IMPAR, la última se queda sin pareja: en vez de
     dejarla coja ocupa el ancho entero y cierra la galería como una banda.
     Con un número par no se aplica y quedan dos columnas limpias. El
     :nth-child(odd) es lo que hace que esto se ajuste solo al añadir o quitar
     un servicio, sin tener que volver aquí. */
  .svcgrid > .stile:last-child:nth-child(odd){grid-column:1 / -1;aspect-ratio:21/9}
}

.stile{position:relative;overflow:hidden;isolation:isolate;aspect-ratio:4/3;
  background:#0d0d10}
/* Las fichas van oscuras SIEMPRE, con tema claro y con tema oscuro: llevan una
   foto debajo y el texto tiene que leerse encima de cualquier imagen. Por eso
   estos colores son fijos y no leen de los tokens de tema. */
.stile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;
  opacity:0;transition:opacity .7s var(--ease-soft),transform 1.2s var(--ease)}
.stile img.is-ok{opacity:1}
.stile:hover img{transform:scale(1.045)}
.stile__art{position:absolute;inset:0;width:100%;height:100%;color:#fff;z-index:0}

.stile__scrim{position:absolute;inset:0;z-index:1;background:linear-gradient(
  180deg,rgba(8,8,10,.22) 0%,rgba(8,8,10,.52) 42%,rgba(8,8,10,.93) 100%)}

/* Marco naranja al pasar por encima. Se eligió esto y no aclarar u oscurecer la
   foto porque un marco se ve igual de bien sobre cualquier imagen, mientras que
   tocar el brillo puede dejar el texto ilegible según lo que haya debajo. */
.stile::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  box-shadow:inset 0 0 0 0 var(--accent);transition:box-shadow .45s var(--ease)}
.stile:hover::after{box-shadow:inset 0 0 0 3px var(--accent)}

.stile__body{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;
  justify-content:flex-end;padding:clamp(18px,2.1vw,34px);color:#fff}
.stile__n{font-family:var(--font-mono);font-size:.7rem;font-weight:500;letter-spacing:.16em;
  color:var(--accent);margin-bottom:auto}
.stile__t{font-size:clamp(1.2rem,2.2vw,1.95rem);font-weight:700;line-height:1.02;
  letter-spacing:-.03em;text-transform:uppercase;max-width:18ch}
.stile__d{margin-top:10px;max-width:48ch;font-size:clamp(.9rem,.98vw,1rem);line-height:1.5;
  color:rgba(255,255,255,.84)}
.stile__tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:14px}
.stile__tags li{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.1em;
  text-transform:uppercase;color:rgba(255,255,255,.82);
  border:1px solid rgba(255,255,255,.28);border-radius:999px;padding:4px 10px}

@media (max-width:520px){
  /* en pantalla estrecha manda el texto: la ficha crece lo que haga falta en
     vez de recortar la descripción contra una proporción fija */
  .stile,.svcgrid > .stile:last-child{aspect-ratio:auto;min-height:340px}
}
@media (prefers-reduced-motion:reduce){
  .stile img,.stile::after{transition:none}
  .stile:hover img{transform:none}
}

/* ---------- 11b. Franja de logos de clientes ----------
   Va SIEMPRE sobre blanco, en los dos temas. No es un descuido: los logos de
   cliente casi siempre son oscuros sobre transparente, y sobre negro
   desaparecerían. Por eso aquí los colores tampoco leen de los tokens.        */
/* La etiqueta va FUERA de la banda, sobre el fondo de la página: así sigue el
   color del tema y la banda blanca queda limpia, solo con los logos. */
.clients{padding-top:clamp(14px,2vh,26px)}
.clients__lead{display:block;text-align:center;color:var(--fg);opacity:.78;
  font-size:clamp(.72rem,.86vw,.82rem);letter-spacing:.26em;
  margin-bottom:clamp(12px,1.6vh,18px)}
/* La banda tiene alto propio y centra su contenido, en vez de depender del
   relleno: así su grosor es una decisión y no una consecuencia del tamaño
   que acaben teniendo los logos. */
.clients__band{background:#fff;overflow:hidden;user-select:none;
  height:100px;display:flex;align-items:center;
  border-block:1px solid rgba(0,0,0,.08)}
/* La cinta NO se detiene al pasar el ratón: sólo reacciona el logo que se
   señala. El ciclo dura lo mismo siempre; el padding-right del grupo tiene que
   ser igual que el gap para que, al empalmar las dos copias, la separación
   entre el último logo y el primero sea idéntica a la de todos los demás.
   Es lo que hace que el salto del bucle no se note. */
/* El tirón periódico venía de aquí. La pista mide más de 4.000 px y, sin pedir
   capa propia, el navegador la rasteriza por trozos y va generando los que
   entran en cuadro: de ahí el enganchón cada pocos segundos. Con will-change
   y una transformación en 3D la capa se compone una vez y el desplazamiento
   pasa a la GPU, donde ya no hay nada que repintar. */
.clients__track{display:flex;width:max-content;
  animation:marquee-logos 58s linear infinite;
  will-change:transform;backface-visibility:hidden}
@keyframes marquee-logos{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(-50%,0,0)}
}
.clients__group{display:flex;align-items:center;gap:76px;padding-right:76px}
/* El alto vive en una variable porque lo necesitan el hueco y la imagen, y
   tienen que ir a la par. */
.clients{--logo-h:52px}
.clients__item{display:grid;place-items:center;flex:none;
  height:var(--logo-h);position:relative}
/* El logo entra en gris y se destapa al pasar por encima.
   Va con height:100% y no con max-height en porcentaje: dentro de una rejilla,
   el max-height porcentual no siempre se resuelve contra la fila y los logos
   se pintaban a su alto natural, desbordando la banda. También hace falta
   max-width:none, porque la regla global de imágenes las limita al 100%. */
/* Alto explícito y no 100%: el ancho del hueco depende de la imagen y la
   imagen dependería del alto del hueco. Ante esa circularidad el navegador
   se queda con el tamaño natural del archivo (200 px) y los logos desbordaban
   la banda. Con una medida concreta no hay nada que resolver. */
/* A COLOR, sin filtros. Cada marca con sus colores. El alto es el mismo para
   todos y el ancho sale de la proporción de cada archivo, así ninguno se
   deforma; los muy apaisados salen más anchos, que es lo correcto. */
.clients__item img{display:none;height:var(--logo-h);width:auto;max-width:none;
  object-fit:contain;
  transition:transform .3s var(--ease-soft)}
.clients__item.has-logo img{display:block}
.clients__item:hover img{transform:scale(1.05)}
/* mientras no haya archivo de logo, el nombre compuesto en tipografía */
.clients__name{font-weight:700;font-size:clamp(.9rem,1.35vw,1.15rem);letter-spacing:-.02em;
  text-transform:uppercase;color:rgba(0,0,0,.38);white-space:nowrap;
  transition:color .4s var(--ease-soft)}
.clients__item:hover .clients__name{color:#0b0b0b}
.clients__item.has-logo .clients__name{display:none}
/* Tablet y móvil: baja el logo, baja la banda y se juntan un poco, para que
   siga cabiendo el mismo número de marcas en pantalla sin agobiar. */
@media (max-width:1024px){
  .clients{--logo-h:42px}
  .clients__band{height:84px}
  .clients__group{gap:58px;padding-right:58px}
}
@media (max-width:640px){
  .clients{--logo-h:35px}
  .clients__band{height:70px}
  .clients__group{gap:44px;padding-right:44px}
}
@media (prefers-reduced-motion:reduce){
  .clients__track{animation:none;flex-wrap:wrap;width:100%;justify-content:center}
  .clients__group:nth-child(2){display:none}
  .clients__item:hover img{transform:none}
}

/* ---------- 11c. Reseñas ---------- */
/* Las fichas se apilan todas en la MISMA celda de una retícula de 1x1. Así la
   caja mide siempre lo que la reseña más larga y no pega un salto de altura al
   cambiar de una a otra, que es el defecto clásico de estos carruseles. */
.rvbox{display:grid;margin-top:clamp(30px,4.5vh,56px)}
.rv{grid-area:1 / 1;opacity:0;scale:.95;pointer-events:none;
  border:1px solid var(--line);background:var(--bg);
  padding:clamp(24px,3.6vw,52px);
  /* la caja mide lo que la reseña más larga, así que las cortas se centran
     en vertical en vez de dejar un hueco muerto debajo */
  display:flex;flex-direction:column;justify-content:center;
  transition:opacity .45s var(--ease-soft),scale .6s var(--ease)}
.rv.is-on{opacity:1;scale:1;pointer-events:auto}
.rv__stars{display:flex;gap:5px;margin-bottom:clamp(16px,2vw,24px)}
.rv__stars svg{width:17px;height:17px;color:var(--accent-ink)}
.rv__q{font-size:clamp(1.1rem,2vw,1.7rem);line-height:1.4;letter-spacing:-.02em;
  max-width:44ch;font-weight:400}
.rv__who{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;
  margin-top:clamp(20px,2.8vw,34px);padding-top:18px;border-top:1px solid var(--line)}
.rv__who b{font-weight:600}
.rv__who span{color:var(--mut)}
.rv__src{margin-left:auto;font-family:var(--font-mono);font-size:.64rem;
  letter-spacing:.13em;text-transform:uppercase;color:var(--mut)}

.rvnav{display:flex;align-items:center;gap:10px;margin-top:clamp(20px,2.6vh,30px)}
.rvbtn{width:46px;height:46px;flex:none;border:1px solid var(--line);border-radius:50%;
  display:grid;place-items:center;cursor:pointer;color:var(--fg);
  transition:border-color .35s var(--ease-soft),color .35s var(--ease-soft),
             background .35s var(--ease-soft)}
.rvbtn svg{width:15px;height:15px}
.rvbtn:hover{border-color:var(--accent);color:var(--accent-ink)}
.rvdots{display:flex;align-items:center;gap:7px;margin-left:auto}
.rvdots button{width:8px;height:8px;border-radius:999px;background:var(--line);
  cursor:pointer;padding:0;transition:width .4s var(--ease),background .35s var(--ease-soft)}
.rvdots button[aria-current="true"]{width:24px;background:var(--accent)}
@media (prefers-reduced-motion:reduce){
  .rv{transition:opacity .2s linear}
  .rv,.rv.is-on{scale:1}
  .rvdots button{transition:none}
}

/* etiquetas sueltas, fuera de las fichas oscuras */
.tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:clamp(20px,3vh,30px)}
.tags li{font-family:var(--font-mono);font-size:.64rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--mut);border:1px solid var(--line);
  border-radius:999px;padding:5px 11px}

/* ---------- 11d. Galería de una página de servicio ---------- */
/* Mosaico por columnas, no retícula. Las fotos de obra vienen del móvil y
   mezclan vertical con horizontal; una retícula de proporción fija recortaría
   justo la parte alta de un aviso vertical. Así cada foto se ve entera y la
   columna se acomoda a lo que haya. */
.gal{columns:1;column-gap:clamp(10px,1.1vw,16px);margin-top:clamp(30px,4.5vh,56px)}
@media (min-width:700px){.gal{columns:2}}
@media (min-width:1150px){.gal{columns:3}}
.gal__item{position:relative;overflow:hidden;isolation:isolate;display:block;
  width:100%;background:var(--surface);border:0;padding:0;cursor:zoom-in;
  break-inside:avoid;margin:0 0 clamp(10px,1.1vw,16px)}
.gal__item img{display:block;width:100%;height:auto;
  opacity:0;transition:opacity .6s var(--ease-soft),transform 1.1s var(--ease)}
.gal__item img.is-ok{opacity:1}
.gal__item:hover img{transform:scale(1.045)}
.gal__item::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  box-shadow:inset 0 0 0 0 var(--accent);transition:box-shadow .4s var(--ease)}
.gal__item:hover::after,.gal__item:focus-visible::after{box-shadow:inset 0 0 0 3px var(--accent)}
@media (prefers-reduced-motion:reduce){
  .gal__item img{transition:opacity .2s linear}
  .gal__item:hover img{transform:none}
}

/* visor a pantalla completa */
.lb{position:fixed;inset:0;z-index:9500;display:none;place-items:center;
  background:rgba(4,4,6,.94);padding:clamp(44px,5vw,72px)}
.lb.is-open{display:grid}
.lb__img{max-width:100%;max-height:82vh;width:auto;height:auto;object-fit:contain}
.lb__btn{position:absolute;display:grid;place-items:center;width:52px;height:52px;
  border-radius:50%;border:1px solid rgba(255,255,255,.26);color:#fff;cursor:pointer;
  background:rgba(0,0,0,.4);transition:border-color .3s var(--ease-soft),color .3s var(--ease-soft)}
.lb__btn:hover{border-color:var(--accent);color:var(--accent)}
.lb__btn svg{width:17px;height:17px}
.lb__close{top:clamp(14px,2.4vw,26px);right:clamp(14px,2.4vw,26px)}
.lb__prev{left:clamp(10px,2vw,26px);top:50%;transform:translateY(-50%)}
.lb__next{right:clamp(10px,2vw,26px);top:50%;transform:translateY(-50%)}
.lb__count{position:absolute;left:50%;transform:translateX(-50%);
  bottom:clamp(14px,2.4vw,26px);font-family:var(--font-mono);font-size:.68rem;
  letter-spacing:.14em;color:rgba(255,255,255,.62)}
body.lb-open{overflow:hidden}

/* paso al servicio siguiente, al pie de cada página de servicio */
.svcnav{display:grid;gap:1px;background:var(--line);border-block:1px solid var(--line);
  margin-top:clamp(60px,9vh,110px)}
@media (min-width:760px){.svcnav{grid-template-columns:1fr 1fr}}
.svcnav a{background:var(--bg);padding:clamp(22px,3vw,38px) clamp(18px,2.4vw,32px);
  display:block;transition:background .35s var(--ease-soft)}
.svcnav a:hover{background:var(--surface)}
.svcnav a:last-child{text-align:right}
.svcnav b{display:block;margin-top:8px;font-size:clamp(1.05rem,1.8vw,1.5rem);
  font-weight:700;letter-spacing:-.025em;text-transform:uppercase}
.svcnav a:hover b{color:var(--accent-ink)}

/* ---------- 12. Nosotros ---------- */
.about{display:grid;gap:clamp(34px,5vw,80px);grid-template-columns:minmax(0,1fr);align-items:start}
@media (min-width:980px){.about{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr)}}
.about__copy p + p{margin-top:1.1em}
/* Antes esto era sticky, cuando el lateral sólo tenía cuatro cifras pequeñas.
   Con la foto dentro el bloque pasa a ser más alto que la ventana, y un sticky
   más alto que el viewport se queda con el pie cortado. Mejor que fluya. */
.about__aside{position:relative}

/* foto del fundador: si el archivo no existe, el JS borra el bloque entero,
   así que nunca queda un hueco esperando una imagen */
/* Horizontal 3:2 a propósito: la foto tiene el aviso a un lado y el vinilo de
   la puerta al otro, y en vertical se perdía uno de los dos. */
.founder{position:relative;overflow:hidden;aspect-ratio:3/2;
  background:var(--surface);border:1px solid var(--line-soft);
  margin-bottom:clamp(22px,3.4vh,38px)}
.founder img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .6s var(--ease-soft)}
.founder img.is-ok{opacity:1}
.founder figcaption{position:absolute;left:0;right:0;bottom:0;padding:14px 16px;
  background:linear-gradient(transparent,rgba(0,0,0,.72));color:#fff}

/* cifras: número grande en naranja y etiqueta al lado, en filas */
.stats{display:grid;grid-template-columns:1fr;border-top:1px solid var(--line)}
.stat{display:flex;align-items:baseline;gap:clamp(14px,2vw,26px);
  padding:clamp(15px,2vw,22px) 0;border-bottom:1px solid var(--line)}
.stat b{flex:none;min-width:2.8em;font-size:clamp(1.9rem,4.2vw,2.9rem);font-weight:800;
  letter-spacing:-.045em;line-height:.9;color:var(--accent-ink)}
.stat span{font-family:var(--font-mono);font-size:.66rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--mut);line-height:1.5}

.quote{margin-top:clamp(28px,4vh,48px);border-left:2px solid var(--accent);padding-left:clamp(18px,2vw,28px)}
.quote p{font-size:var(--fs-lead);letter-spacing:-.018em;line-height:1.42}
.quote footer{margin-top:14px}

/* ---------- 13. Proyectos ---------- */
.projects{display:grid;gap:clamp(26px,3.4vw,56px);grid-template-columns:minmax(0,1fr);margin-top:clamp(40px,6vh,80px)}
@media (min-width:760px){.projects{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1200px){.projects--3{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* Ritmo desfasado: la segunda columna baja un poco. Evita la retícula plana.
   Se hace con margin y no con transform a propósito: transform ya lo usa la
   animación de entrada [data-fade] y las dos reglas se pisarían. */
@media (min-width:760px){.projects--stagger > *:nth-child(even){margin-top:clamp(20px,4vw,64px)}}

.pcard{display:block;position:relative;isolation:isolate}
.pcard__media{
  position:relative;overflow:hidden;background:var(--surface);border:1px solid var(--line-soft);
  aspect-ratio:4/3;
}
.pcard--tall .pcard__media{aspect-ratio:3/4}
/* La foto se monta encima de la pieza gráfica y aparece sólo cuando ha cargado
   bien (el JS le pone .is-ok). Si el archivo no existe todavía, no se ve ningún
   icono roto: simplemente queda el SVG de abajo. Así se pueden ir añadiendo
   fotos una a una sin tocar el HTML. */
.pcard__media img{
  position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .5s var(--ease-soft),transform 1.1s var(--ease);
}
.pcard__media img.is-ok{opacity:1}
.pcard__veil,.pcard__go{z-index:2}
.pcard__art{position:absolute;inset:0;width:100%;height:100%;color:var(--fg);
  transition:transform 1.1s var(--ease),opacity .6s linear}
.pcard:hover .pcard__art,.pcard:hover .pcard__media img{transform:scale(1.045)}
.pcard__veil{position:absolute;inset:0;background:var(--surface);opacity:0;
  transition:opacity .5s var(--ease-soft)}
.pcard:hover .pcard__veil{opacity:.62}
.pcard__go{
  position:absolute;left:50%;top:50%;translate:-50% -50%;
  display:grid;place-content:center;width:84px;height:84px;border-radius:50%;
  background:var(--accent);color:var(--on-accent);font-family:var(--font-mono);font-size:.64rem;letter-spacing:.12em;
  text-transform:uppercase;opacity:0;scale:.72;
  transition:opacity .45s var(--ease),scale .55s var(--ease);
}
.pcard:hover .pcard__go{opacity:1;scale:1}
.pcard__meta{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
.pcard__meta h3{font-size:clamp(1.05rem,1.6vw,1.35rem);font-weight:600;letter-spacing:-.02em}
.pcard__meta p{margin-top:4px}
@media (prefers-reduced-motion:reduce){
  .pcard__art,.pcard__go,.pcard__veil{transition:none}
}

.more{display:flex;justify-content:center;margin-top:clamp(52px,8vh,104px)}
@media (min-width:760px){.projects--stagger + .more{margin-top:clamp(72px,10vh,124px)}}

/* ---------- 14. Contacto ---------- */
.contact{position:relative}
.contact__grid{display:grid;gap:clamp(36px,5vw,80px);grid-template-columns:minmax(0,1fr);margin-top:clamp(34px,5vh,64px)}
@media (min-width:980px){.contact__grid{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)}}

.direct{display:grid;gap:clamp(18px,2.4vw,28px)}
.direct__row{display:grid;gap:4px;padding-bottom:clamp(16px,2vw,22px);border-bottom:1px solid var(--line)}
.direct__row a{font-size:clamp(1.15rem,2.2vw,1.7rem);font-weight:600;letter-spacing:-.025em;
  display:inline-flex;align-items:center;gap:10px;width:fit-content;position:relative}
.direct__row a::after{content:"";position:absolute;left:0;bottom:-2px;height:1px;width:100%;background:var(--accent-ink);
  transform:scaleX(0);transform-origin:right;transition:transform .45s var(--ease)}
.direct__row a:hover::after{transform:scaleX(1);transform-origin:left}

.form{display:grid;gap:clamp(16px,2vw,22px)}
.field{position:relative;display:grid;gap:8px}
.field label{font-family:var(--font-mono);font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:var(--mut)}
.field input,.field textarea,.field select{
  width:100%;background:transparent;border:0;border-bottom:1px solid var(--line);
  color:var(--fg);font-family:inherit;font-size:clamp(1rem,1.5vw,1.15rem);padding:10px 0;
  border-radius:0;transition:border-color .35s var(--ease-soft);
}
.field select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='%238f8f8f' stroke-width='1.6'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 2px center;padding-right:24px}
.field select option{background:var(--bg);color:var(--fg)}
.field textarea{resize:vertical;min-height:104px;line-height:1.5}
.field input::placeholder,.field textarea::placeholder{color:var(--mut);opacity:.7}
/* el foco se marca en naranja: es la única señal de color del formulario */
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-bottom-color:var(--accent-ink)}
.field:focus-within label{color:var(--accent-ink)}
.field--2{display:grid;gap:clamp(16px,2vw,22px);grid-template-columns:minmax(0,1fr)}
@media (min-width:640px){.field--2{grid-template-columns:repeat(2,minmax(0,1fr))}}

.form__foot{display:flex;flex-wrap:wrap;align-items:center;gap:16px 22px;margin-top:6px}
.form__note{max-width:38ch}
.form__msg{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--mut)}
.form__msg[data-state="ok"]{color:var(--accent-ink)}

/* ---------- 15. Footer ---------- */
.footer{border-top:1px solid var(--line);padding-block:clamp(40px,6vh,72px) clamp(24px,3vh,36px)}
.footer__big{overflow:hidden;margin-bottom:clamp(36px,6vh,72px)}
.footer__big a{display:block;font-size:clamp(2.6rem,12vw,11rem);font-weight:800;line-height:.86;
  letter-spacing:-.045em;text-transform:uppercase;transition:opacity .4s var(--ease-soft)}
.footer__big a{transition:color .45s var(--ease-soft)}
.footer__big a:hover{color:var(--accent-ink);opacity:1}
.footer__big a i{font-style:normal;color:var(--accent-ink)}
.footer__cols{display:grid;gap:clamp(22px,3vw,40px);grid-template-columns:minmax(0,1fr)}
@media (min-width:760px){.footer__cols{grid-template-columns:repeat(4,minmax(0,1fr))}}
.footer__cols h4{font-family:var(--font-mono);font-size:.66rem;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mut);margin-bottom:14px}
.footerlogo{display:none;height:84px;width:auto;margin-bottom:18px;filter:var(--logo-filter)}
.footerlogo.is-ok{display:block}
.footer__cols li + li{margin-top:7px}
.footer__cols a:hover{text-decoration:underline;text-underline-offset:4px}
/* Resumen de la ficha de Google, sobre las reseñas del carrusel. */
.gscore{display:inline-flex;align-items:center;gap:10px;margin-top:clamp(18px,2.6vh,28px);
  padding:9px 16px 9px 14px;border:1px solid var(--line);border-radius:999px;
  transition:border-color .35s var(--ease-soft),transform .35s var(--ease-soft)}
.gscore:hover{border-color:var(--accent);transform:translateY(-2px)}
.gscore__stars{display:inline-flex;gap:2px;color:var(--accent)}
.gscore__stars svg{width:15px;height:15px}
.gscore__n{font-size:1.02rem;font-weight:700;line-height:1}
.gscore__t{font-family:var(--font-mono);font-size:.68rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--mut)}
.gscore__a{color:var(--accent-ink);font-size:.85rem}
@media (max-width:520px){
  .gscore{gap:8px;padding:8px 13px}
  .gscore__t{font-size:.6rem;letter-spacing:.06em}
}

/* Zona de servicio: texto discreto, pero visible y seleccionable (Google no
   cuenta lo que esta oculto). Mismo tono que el resto del pie. */
.footer__area{margin-top:clamp(28px,4vh,44px);padding-top:18px;border-top:1px solid var(--line);
  max-width:92ch;line-height:1.7;color:var(--mut);
  /* .micro va en versalitas; en un parrafo largo cuesta leerlo y parece un
     bloque de palabras clave, asi que aqui se deja en caja normal */
  text-transform:none;letter-spacing:.015em;font-size:.76rem}
.footer__base{display:flex;flex-wrap:wrap;justify-content:space-between;gap:10px 24px;
  margin-top:clamp(36px,5vh,64px);padding-top:20px;border-top:1px solid var(--line-soft)}

/* botón flotante de whatsapp */
.wa{
  position:fixed;right:clamp(14px,2vw,26px);bottom:clamp(14px,2vw,26px);z-index:850;
  display:grid;place-content:center;width:54px;height:54px;border-radius:50%;
  background:var(--accent);color:var(--on-accent);box-shadow:0 10px 30px rgba(0,0,0,.35);
  transition:transform .45s var(--ease);
}
.wa:hover{transform:scale(1.08)}
.wa svg{width:26px;height:26px}
body.menu-open .wa{transform:scale(0);pointer-events:none}

/* ---------- 16. Página de proyectos ---------- */
.phero{padding-top:clamp(130px,20vh,220px);padding-bottom:clamp(40px,6vh,72px)}
.filters{display:flex;flex-wrap:wrap;gap:8px;margin-top:clamp(26px,4vh,44px)}
.filters button{
  font-family:var(--font-mono);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  border:1px solid var(--line);border-radius:999px;padding:9px 16px;color:var(--mut);cursor:pointer;
  transition:color .3s var(--ease-soft),border-color .3s var(--ease-soft),background .3s var(--ease-soft);
}
.filters button:hover{color:var(--fg);border-color:var(--fg)}
.filters button[aria-pressed="true"]{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.pcard.is-hidden{display:none}

.cta-strip{border-top:1px solid var(--line);padding-block:clamp(60px,9vh,120px);text-align:center}
.cta-strip .h2{max-width:16ch;margin-inline:auto}

/* ---------- 17. Ajustes finos ---------- */
@media (max-width:560px){
  .stats{grid-template-columns:1fr}
  .hero{min-height:92svh}
}
