/* =========================================================================
   Herrería Artística — Javier Perea · Rivadavia, Mendoza
   Los tokens de abajo están documentados en DESIGN-SYSTEM.md
   ========================================================================= */

:root{
  /* ---------- espaciado (base 8) ---------- */
  --sp-1:.25rem;  --sp-2:.5rem;   --sp-3:.75rem;  --sp-4:1rem;
  --sp-5:1.5rem;  --sp-6:2rem;    --sp-7:3rem;    --sp-8:4rem;
  --sp-9:6rem;    --sp-10:8rem;   --sp-11:11rem;  --sp-12:15rem;

  --section-y:clamp(6rem, 11vw, 13rem);

  /* ---------- grilla ---------- */
  --shell:1560px;
  --gutter:clamp(1.25rem, 4vw, 4rem);
  --col-gap:clamp(1rem, 2vw, 2rem);

  /* ---------- tipografía ---------- */
  --f-display:"Fraunces", Georgia, "Times New Roman", serif;
  --f-text:"Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --f-mono:"IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --t-meta:.6875rem;
  --t-xs:.8125rem;
  --t-sm:.9375rem;
  --t-base:1.0625rem;
  --t-lg:clamp(1.125rem, 1rem + .55vw, 1.375rem);
  --t-xl:clamp(1.5rem, 1.15rem + 1.5vw, 2.25rem);
  --t-2xl:clamp(2rem, 1.35rem + 3vw, 3.5rem);
  --t-3xl:clamp(2.75rem, 1.5rem + 5.6vw, 6rem);
  --t-4xl:clamp(3.25rem, 1.2rem + 9.4vw, 8.75rem);
  --t-marquee:clamp(4rem, 13vw, 13rem);

  /* ---------- color ---------- */
  --paper:#EDE8E0;
  --paper-2:#E4DDD3;
  --paper-3:#D9D0C3;
  --ink:#0D0E10;
  --ink-2:#16181C;
  --ink-3:#212429;

  --tx:#121417;
  --tx-soft:#55595F;
  --tx-mute:#63676E;   /* 4.7:1 sobre --paper: cumple AA en 11px */
  --tx-inv:#EDE8E0;
  --tx-inv-soft:#9BA1A9;

  --red:#B3242B;
  --red-lift:#D9464D;
  --blue:#1B3A8C;
  --blue-lift:#7E9BE8;

  --hair:rgba(13,14,16,.14);
  --hair-inv:rgba(237,232,224,.15);

  /* ---------- movimiento ---------- */
  --dur-1:.3s; --dur-2:.6s; --dur-3:.9s;
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-io:cubic-bezier(.65,.05,.36,1);

  --header-h:76px;
}

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

html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--header-h) + var(--sp-4));
}
@media (pointer:fine){ html{ scrollbar-gutter:stable; } }

body{
  margin:0;
  background:var(--paper);
  color:var(--tx);
  font-family:var(--f-text);
  font-size:var(--t-base);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

/* grano: saca al papel de ser un color plano. Va incrustado, no pesa nada. */
body::before{
  content:"";
  position:fixed; inset:0; z-index:1;
  pointer-events:none;
  opacity:.035;
  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='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
}

img{ max-width:100%; height:auto; display:block; }
a{ color:inherit; }
button{ font:inherit; color:inherit; }

h1,h2,h3,h4{ margin:0; font-weight:400; }

::selection{ background:var(--ink); color:var(--paper); }

.skip{
  position:absolute; left:-9999px; top:0; z-index:300;
  background:var(--ink); color:var(--paper); padding:var(--sp-3) var(--sp-5);
}
.skip:focus{ left:0; }

:focus-visible{ outline:2px solid var(--red); outline-offset:3px; }

/* =========================================================================
   PRIMITIVAS
   ========================================================================= */
.wrap{
  width:100%; max-width:var(--shell);
  margin-inline:auto; padding-inline:var(--gutter);
  position:relative; z-index:2;
}

.grid{
  display:grid;
  grid-template-columns:repeat(12,minmax(0,1fr));
  gap:var(--col-gap);
}

.section{ padding-block:var(--section-y); position:relative; }
.section--ink{ background:var(--ink); color:var(--tx-inv); }
.section--paper2{ background:var(--paper-2); }

/* ---------- ritmo entre bloques ----------
   Cada bloque aporta --section-y arriba y abajo. Cuando el de abajo tiene
   otro fondo, su padding se ve pintado como parte del bloque y la suma no
   molesta. Pero si dos bloques comparten fondo, ese aire se duplica y queda
   un hueco que no coincide con el resto de la página: ahí el de abajo no
   aporta su padding superior. El aire entre bloques es siempre uno solo. */
.manifiesto + .section:not(.section--ink),
.section:not(.section--ink) + .section:not(.section--ink),
.section--ink + .section--ink{ padding-top:0; }
/* el pie no es hermano de la última sección (está fuera de <main>), así que
   se lo alcanza por el main: si el último bloque ya es oscuro, el aire lo
   pone él y el pie no suma el suyo */
main:has(> .section--ink:last-child) + .site-footer{ padding-top:0; }

/* ---------- tipografía ---------- */
.display{
  font-family:var(--f-display);
  font-variation-settings:"opsz" 144;
  line-height:1;
  letter-spacing:-.028em;
  text-wrap:balance;
}
.display--xl{
  font-size:var(--t-4xl);
  line-height:.92;
  letter-spacing:-.035em;
  text-wrap:none;
}
.display--lg{ font-size:var(--t-3xl); line-height:.98; }
.display--md{ font-size:var(--t-2xl); line-height:1.02; }
.display--sm{ font-size:var(--t-xl); line-height:1.1; letter-spacing:-.02em; }

.meta{
  font-family:var(--f-mono);
  font-size:var(--t-meta);
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--tx-mute);
}
/* el pie es oscuro pero no lleva .section--ink, así que se nombra aparte */
.section--ink .meta, .site-footer .meta{ color:var(--tx-inv-soft); }

.eyebrow{
  display:flex; align-items:center; gap:var(--sp-3);
  margin:0 0 var(--sp-6);
  font-family:var(--f-mono); font-size:var(--t-meta);
  letter-spacing:.18em; text-transform:uppercase;
  color:var(--tx-soft);
}
.eyebrow::before{
  content:""; width:32px; height:1px; background:var(--red); flex:none;
}
.section--ink .eyebrow{ color:var(--tx-inv-soft); }

.lead{
  font-size:var(--t-lg);
  color:var(--tx-soft);
  max-width:46ch;
  margin:0;
}
.section--ink .lead{ color:var(--tx-inv-soft); }

.rule{ border:0; border-top:1px solid var(--hair); margin:0; }
.section--ink .rule{ border-color:var(--hair-inv); }

/* ---------- botones ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  padding:var(--sp-4) var(--sp-6);
  background:var(--ink); color:var(--paper);
  border:1px solid var(--ink); border-radius:2px;
  font-family:var(--f-mono); font-size:var(--t-meta);
  letter-spacing:.16em; text-transform:uppercase;
  text-decoration:none; cursor:pointer;
  transition:background var(--dur-1) var(--ease-out),
             color var(--dur-1) var(--ease-out) .12s,
             border-color var(--dur-1) var(--ease-out);
}
.btn:hover{ background:var(--red); border-color:var(--red); color:#fff; }
.btn--ghost{ background:transparent; color:var(--tx); border-color:var(--hair); }
.btn--ghost:hover{ background:var(--ink); border-color:var(--ink); color:var(--paper); }
.btn--inv{ background:var(--paper); color:var(--ink); border-color:var(--paper); }
.btn--inv:hover{ background:var(--red); border-color:var(--red); color:#fff; }
.btn--sm{ padding:var(--sp-3) var(--sp-4); }
.btn--block{ width:100%; }

/* =========================================================================
   HEADER
   ========================================================================= */
.site-header{
  position:fixed; inset:0 0 auto 0; z-index:100;
  height:var(--header-h);
  display:flex; align-items:center;
  border-bottom:1px solid transparent;
  transition:background var(--dur-2) var(--ease-out),
             border-color var(--dur-2) var(--ease-out),
             opacity var(--dur-1) var(--ease-out);
}
.site-header.is-scrolled{
  background:rgba(237,232,224,.82);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  border-bottom-color:var(--hair);
}
.header-inner{
  width:100%; max-width:var(--shell); margin-inline:auto;
  padding-inline:var(--gutter);
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-5);
}

.brand{ display:flex; align-items:center; gap:var(--sp-3); text-decoration:none; }
.brand-logo{ width:40px; height:40px; flex:none; }
.lg-ring{ stroke:var(--blue); }
.lg-mark{ stroke:var(--red); }
.brand-text{ display:flex; flex-direction:column; line-height:1.2; }
.brand-name{ font-family:var(--f-display); font-size:1.05rem; letter-spacing:-.015em; }
.brand-sub{
  font-family:var(--f-mono); font-size:.6rem;
  letter-spacing:.2em; text-transform:uppercase; color:var(--tx-soft);
}

.nav{ display:flex; align-items:center; gap:var(--sp-7); }
.nav a{ text-decoration:none; font-size:var(--t-sm); position:relative; padding:var(--sp-1) 0; }
.nav a .n{
  font-family:var(--f-mono); font-size:.6rem; color:var(--tx-mute);
  margin-right:var(--sp-2); vertical-align:.25em;
}
.nav a:not(.btn)::after{
  content:""; position:absolute; left:0; bottom:0; width:100%; height:1px;
  background:currentColor; transform:scaleX(0); transform-origin:right;
  transition:transform var(--dur-2) var(--ease-out);
}
.nav a:not(.btn):hover::after{ transform:scaleX(1); transform-origin:left; }

.burger{
  display:none; width:44px; height:44px; margin-right:-10px;
  background:none; border:0; cursor:pointer;
  flex-direction:column; align-items:center; justify-content:center; gap:6px;
}
.burger span{
  width:24px; height:1.5px; background:var(--tx);
  transition:transform var(--dur-1) var(--ease-out);
}
.burger[aria-expanded="true"] span:first-child{ transform:translateY(3.75px) rotate(45deg); }
.burger[aria-expanded="true"] span:last-child{ transform:translateY(-3.75px) rotate(-45deg); }

/* =========================================================================
   HERO
   ========================================================================= */
.hero{
  min-height:100svh;
  padding-top:calc(var(--header-h) + var(--sp-7));
  padding-bottom:var(--sp-6);
  display:flex; flex-direction:column; justify-content:space-between;
  position:relative;
}
.hero-grid{ align-items:center; flex:1; }

.hero-copy{ grid-column:1 / span 7; }
.hero h1{ margin:0 0 var(--sp-6); }
.hero h1 .em{ font-style:italic; font-weight:300; color:var(--red); }

/* revelado por líneas */
.line{ display:block; overflow:hidden; padding-bottom:.14em; margin-bottom:-.14em; }
.js .line > span{
  display:block;
  transform:translateY(105%);
  transition:transform var(--dur-3) var(--ease-out);
}
.is-in .line > span{ transform:none; }
.is-in .line:nth-child(2) > span{ transition-delay:.09s; }
.is-in .line:nth-child(3) > span{ transition-delay:.18s; }

.hero-actions{
  display:flex; flex-wrap:wrap; gap:var(--sp-3);
  margin-top:var(--sp-6);
}

/* la imagen sale hasta el borde derecho de la ventana */
.hero-media{
  grid-column:9 / span 4;
  margin:0 calc(-1 * var(--gutter)) 0 0; position:relative;
  align-self:stretch;
  display:flex; align-items:center;
}
.hero-media .frame{
  display:block;
  position:relative; width:100%; overflow:hidden;
  background:var(--paper-3);
  aspect-ratio:10/13;
}
.hero-media img{
  width:100%; height:100%; object-fit:cover;
  transform:scale(1.06);
}
.hero-media figcaption{
  position:absolute; left:0; bottom:calc(-1 * var(--sp-6));
  display:flex; gap:var(--sp-3); align-items:baseline;
}

.hero-foot{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:var(--sp-5);
  padding-top:var(--sp-5);
  border-top:1px solid var(--hair);
  margin-top:var(--sp-6);
}
.hero-foot ul{
  list-style:none; margin:0; padding:0;
  display:flex; flex-wrap:wrap; gap:var(--sp-6);
}
.scroll-cue{ display:flex; align-items:center; gap:var(--sp-2); }
.scroll-cue .bar{
  display:block; width:1px; height:26px; background:var(--hair);
  position:relative; overflow:hidden;
}
.scroll-cue .bar::after{
  content:""; position:absolute; inset:0; background:var(--red);
  animation:cue 2.4s var(--ease-io) infinite;
}
@keyframes cue{
  0%{ transform:translateY(-100%); }
  55%,100%{ transform:translateY(100%); }
}

/* =========================================================================
   CINTA
   ========================================================================= */
.marquee{
  border-block:1px solid var(--hair);
  overflow:hidden;
  position:relative; z-index:2;
  user-select:none;
}
.marquee-track{
  display:flex; width:max-content;
  font-size:var(--t-marquee);
  line-height:1;
  /* El aire va acá y en em, no en el contenedor y en px: con line-height 1
     la tinta de Fraunces sobresale ~0.115em de la caja de línea, y la cola
     de la "j" se la comía el overflow. Siendo proporcional, el margen
     acompaña al tamaño de la fuente en todos los anchos. */
  padding-block:.16em;
  animation:slide 42s linear infinite;
}
.marquee-track > *{
  font-family:var(--f-display);
  font-variation-settings:"opsz" 144;
  font-size:var(--t-marquee);
  line-height:1; letter-spacing:-.03em;
  margin-right:.35em; flex:none;
}
.marquee-track .sep{ color:var(--red); font-size:.5em; align-self:center; }

/* Palabras en contorno.
   El trazo se dibuja centrado sobre el borde del glifo, así que donde la
   letra es más fina que el trazo los dos bordes se cruzan y el contorno se
   ve cortado. Fraunces en "opsz" 144 es la versión de display: remates
   finísimos, justo el peor caso. Bajando el eje óptico a 40 los trazos se
   emparejan y el contorno queda continuo, sin perder el aire de serif. */
/* Palabras en contorno — NO usar -webkit-text-stroke.
   Fraunces, como casi toda fuente variable, tiene contornos superpuestos: el
   remate y el asta son formas distintas que se solapan. Con relleno se ven
   como una sola pieza, pero text-stroke dibuja el borde de CADA subforma,
   incluidas las uniones internas, y la letra aparece cruzada por líneas.
   No se arregla con más peso ni más grosor: hay que cambiar de técnica.

   Acá el contorno se arma con el texto repetido en 8 posiciones alrededor
   (radio 1.5px: las diagonales van a 1.5/√2 para que el borde sea parejo) y
   el relleno del color del fondo tapando el centro. Son formas sólidas
   desplazadas, no contornos, así que no aparece ninguna línea interna. */
.marquee-track .out{
  color:var(--paper);
  text-shadow:
     1.5px 0 0 var(--tx-mute),  1.06px  1.06px 0 var(--tx-mute),
     0  1.5px 0 var(--tx-mute), -1.06px  1.06px 0 var(--tx-mute),
    -1.5px 0 0 var(--tx-mute), -1.06px -1.06px 0 var(--tx-mute),
     0 -1.5px 0 var(--tx-mute),  1.06px -1.06px 0 var(--tx-mute);
}
@keyframes slide{ to{ transform:translateX(-50%); } }

/* =========================================================================
   MANIFIESTO
   ========================================================================= */
.manifiesto{ padding-block:var(--section-y); }
.manifiesto-in{ grid-column:2 / span 9; }
.manifiesto p{
  font-family:var(--f-display);
  font-variation-settings:"opsz" 120;
  font-size:var(--t-2xl);
  line-height:1.16; letter-spacing:-.022em;
  margin:0; text-wrap:balance;
}
.manifiesto p .soft{ color:var(--tx-mute); }
.manifiesto-foot{
  grid-column:2 / span 9;
  margin-top:var(--sp-8); padding-top:var(--sp-5);
  border-top:1px solid var(--hair);
  display:flex; flex-wrap:wrap; gap:var(--sp-6); justify-content:space-between;
}

/* =========================================================================
   SERVICIOS
   ========================================================================= */
.section-head{ margin-bottom:var(--sp-9); }
.section-head .col-a{ grid-column:1 / span 6; }
.section-head .col-b{ grid-column:8 / span 4; align-self:end; }

.services{ list-style:none; margin:0; padding:0; border-top:1px solid var(--hair); }
.service{
  position:relative;
  display:grid;
  grid-template-columns:6rem minmax(14rem,26rem) minmax(0,1fr);
  gap:var(--col-gap);
  align-items:start;
  padding-block:var(--sp-7);
  border-bottom:1px solid var(--hair);
  transition:padding-inline-start var(--dur-2) var(--ease-out);
}
/* filete que se dibuja al pasar el mouse */
.service::after{
  content:""; position:absolute; left:0; bottom:-1px; height:1px; width:100%;
  background:var(--red); transform:scaleX(0); transform-origin:left;
  transition:transform var(--dur-2) var(--ease-out);
}
.service-num{ font-family:var(--f-mono); font-size:var(--t-meta); letter-spacing:.16em; color:var(--red); padding-top:.55rem; }
.service h3{ font-family:var(--f-display); font-variation-settings:"opsz" 144; font-size:var(--t-xl); line-height:1.05; letter-spacing:-.02em; }
.service p{ margin:0; color:var(--tx-soft); font-size:var(--t-sm); max-width:44ch; }

@media (hover:hover) and (pointer:fine){
  .service:hover{ padding-inline-start:var(--sp-5); }
  .service:hover::after{ transform:scaleX(1); }
  .service:hover h3{ color:var(--red); }
}


/* =========================================================================
   BANDA A SANGRE
   ========================================================================= */
.banda{
  position:relative; overflow:hidden;
  height:clamp(15rem,34vw,30rem);
  background:var(--ink);
}
.banda img{
  position:absolute; inset:-12% 0; width:100%; height:124%;
  object-fit:cover;
  will-change:transform;
}
.banda-cap{
  position:absolute; inset:auto 0 0 0; z-index:2;
  padding:var(--sp-5) var(--gutter);
  display:flex; justify-content:space-between; gap:var(--sp-5); flex-wrap:wrap;
  background:linear-gradient(to top, rgba(13,14,16,.6), transparent);
  color:var(--tx-inv);
}
.banda-cap .meta{ color:rgba(237,232,224,.8); }

/* =========================================================================
   GALERÍA
   ========================================================================= */
.filters{ display:flex; flex-wrap:wrap; gap:var(--sp-2); margin-bottom:var(--sp-8); }
.filter{
  padding:var(--sp-2) var(--sp-4);
  background:transparent; border:1px solid var(--hair-inv); border-radius:2px;
  font-family:var(--f-mono); font-size:var(--t-meta);
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--tx-inv-soft); cursor:pointer;
  transition:background var(--dur-1) var(--ease-out),
             color var(--dur-1) var(--ease-out),
             border-color var(--dur-1) var(--ease-out);
}
.filter:hover{ color:var(--tx-inv); border-color:var(--tx-inv-soft); }
.filter.is-active{ background:var(--paper); border-color:var(--paper); color:var(--ink); }

.gallery{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--sp-8) var(--col-gap);
}

/* Hoja de catálogo: todas las piezas con el mismo encuadre y las filas
   alineadas. Con fotos de tono y estilo parecidos, el orden es el diseño;
   la variedad de tamaños sólo se leía como desorden. */
.tile{ margin:0; cursor:pointer; }

.tile .frame{
  display:block; position:relative; overflow:hidden;
  aspect-ratio:4/3;
  background:var(--ink-2);
}
.tile .frame img{
  width:100%; height:100%; object-fit:cover;
  transition:transform var(--dur-3) var(--ease-out);
}
.tile:hover .frame img,
.tile:focus-visible .frame img{ transform:scale(1.035); }

/* el signo + reemplaza al cursor propio: no persigue al puntero
   y también se ve en pantallas táctiles */
.tile-mas{
  position:absolute; top:var(--sp-4); right:var(--sp-4); z-index:2;
  width:34px; height:34px; border-radius:50%;
  background:var(--paper);
  opacity:0; transform:scale(.7);
  transition:opacity var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out);
}
.tile-mas::before, .tile-mas::after{
  content:""; position:absolute; top:50%; left:50%;
  background:var(--ink); transform:translate(-50%,-50%);
}
.tile-mas::before{ width:12px; height:1.5px; }
.tile-mas::after{ width:1.5px; height:12px; }
.tile:hover .tile-mas,
.tile:focus-visible .tile-mas{ opacity:1; transform:scale(1); }

.tile figcaption{
  display:grid;
  grid-template-columns:2.5rem 1fr auto;
  align-items:baseline; gap:var(--sp-3);
  margin-top:var(--sp-4); padding-top:var(--sp-3);
  border-top:1px solid var(--hair-inv);
  transition:border-color var(--dur-1) var(--ease-out);
}
.tile:hover figcaption{ border-top-color:var(--red-lift); }
.tile .t-num{ font-family:var(--f-mono); font-size:var(--t-meta); letter-spacing:.14em; color:var(--red-lift); }
.tile .t-title{ font-family:var(--f-display); font-size:1.02rem; letter-spacing:-.01em; }
.tile .t-meta{ text-align:right; }

.tile.is-hidden{ display:none; }

/* cierra el hueco que dejan 10 piezas en una grilla de 3, y aprovecha
   el momento: el visitante acaba de ver la obra */
.tile-cta{
  grid-column:span 2;
  display:flex; flex-direction:column; justify-content:center; align-items:flex-start;
  gap:var(--sp-5);
  padding:var(--sp-6) 0;
  border-top:1px solid var(--hair-inv);
}
.tile-cta p{ margin:0; color:var(--tx-inv); }

/* =========================================================================
   TALLER
   ========================================================================= */
.taller-media{
  grid-column:1 / span 6; margin:0;
  position:relative; overflow:hidden;
  background:var(--paper-3);
  aspect-ratio:4/5;
}
.taller-media img{
  position:absolute; inset:-8% 0; width:100%; height:116%;
  object-fit:cover; will-change:transform;
}
.taller-copy{ grid-column:8 / span 5; }
.taller-copy h2{ margin-bottom:var(--sp-6); }
.taller-copy > p{ color:var(--tx-soft); margin:0 0 var(--sp-5); max-width:48ch; }

.steps{ list-style:none; margin:var(--sp-8) 0 0; padding:0; border-top:1px solid var(--hair); counter-reset:s; }
.steps li{
  display:grid; grid-template-columns:3.5rem 1fr; gap:var(--sp-4);
  padding-block:var(--sp-5);
  border-bottom:1px solid var(--hair);
}
.steps .p-num{ font-family:var(--f-mono); font-size:var(--t-meta); letter-spacing:.16em; color:var(--red); padding-top:.3rem; }
.steps h3{ font-size:var(--t-base); font-weight:500; margin-bottom:var(--sp-1); }
.steps p{ margin:0; color:var(--tx-soft); font-size:var(--t-sm); }

/* =========================================================================
   CONTACTO
   ========================================================================= */
.contacto-copy{ grid-column:1 / span 6; }
.contacto-form{ grid-column:8 / span 5; }

.datos{ margin:var(--sp-8) 0 0; border-top:1px solid var(--hair-inv); }
.datos > div{
  display:grid; grid-template-columns:9rem 1fr; gap:var(--sp-4);
  padding-block:var(--sp-5); border-bottom:1px solid var(--hair-inv);
}
.datos dt{ font-family:var(--f-mono); font-size:var(--t-meta); letter-spacing:.16em; text-transform:uppercase; color:var(--tx-inv-soft); }
.datos dd{ margin:0; font-size:var(--t-lg); }
.datos a{ text-decoration:none; border-bottom:1px solid transparent; transition:border-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
.datos a:hover{ border-bottom-color:currentColor; color:var(--red-lift); }

.form-intro{
  margin:0 0 var(--sp-6); padding-bottom:var(--sp-5);
  border-bottom:1px solid var(--hair-inv);
  color:var(--tx-inv-soft); font-size:var(--t-sm);
}
.field{ margin-bottom:var(--sp-5); }
.field label{
  display:block; margin-bottom:var(--sp-2);
  font-family:var(--f-mono); font-size:var(--t-meta);
  letter-spacing:.16em; text-transform:uppercase; color:var(--tx-inv-soft);
}
.opt{ text-transform:none; letter-spacing:0; opacity:.65; }
.field input, .field select, .field textarea{
  width:100%; padding:var(--sp-4);
  background:transparent; color:var(--tx-inv);
  border:0; border-bottom:1px solid var(--hair-inv); border-radius:0;
  font-family:inherit; font-size:var(--t-base);
  transition:border-color var(--dur-1) var(--ease-out);
}
.field textarea{ resize:vertical; min-height:120px; }
.field input::placeholder, .field textarea::placeholder{ color:#5A5F66; }
.field input:focus, .field select:focus, .field textarea:focus{ outline:none; border-bottom-color:var(--paper); }
.field select{
  appearance:none; cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,var(--tx-inv-soft) 50%),
                   linear-gradient(135deg,var(--tx-inv-soft) 50%,transparent 50%);
  background-position:calc(100% - 15px) 55%, calc(100% - 10px) 55%;
  background-size:5px 5px,5px 5px; background-repeat:no-repeat;
}
.field select option{ background:var(--ink-2); color:var(--tx-inv); }
.field.has-error input, .field.has-error select, .field.has-error textarea{ border-bottom-color:var(--red-lift); }
.err{ display:block; min-height:1.15rem; margin-top:var(--sp-1); font-size:var(--t-xs); color:var(--red-lift); }

/* =========================================================================
   FOOTER
   ========================================================================= */
.site-footer{ background:var(--ink); color:var(--tx-inv); padding-top:var(--sp-9); position:relative; z-index:2; }
.footer-top{ padding-bottom:var(--sp-9); }
.footer-brand{ grid-column:1 / span 5; display:flex; align-items:center; gap:var(--sp-4); }
.footer-brand .lg-ring{ stroke:var(--blue-lift); }
.footer-brand .lg-mark{ stroke:var(--red-lift); }
.footer-brand .brand-logo{ width:52px; height:52px; }
.footer-name{ margin:0; font-family:var(--f-display); font-size:1.2rem; }
.footer-sub{ margin:var(--sp-1) 0 0; font-size:var(--t-xs); color:var(--tx-inv-soft); }
.footer-nav{ grid-column:8 / span 5; display:flex; flex-wrap:wrap; gap:var(--sp-5) var(--sp-6); align-items:center; }
.footer-nav a{ text-decoration:none; font-size:var(--t-sm); color:var(--tx-inv-soft); transition:color var(--dur-1) var(--ease-out); }
.footer-nav a:hover{ color:var(--tx-inv); }

.footer-legal{
  border-top:1px solid var(--hair-inv); padding-block:var(--sp-5) var(--sp-6);
  display:flex; flex-wrap:wrap; gap:var(--sp-2) var(--sp-6); justify-content:space-between;
}

/* =========================================================================
   WHATSAPP FLOTANTE
   ========================================================================= */
.wa-float{
  position:fixed; right:clamp(1rem,3vw,2rem); bottom:clamp(1rem,3vw,2rem);
  z-index:80; width:54px; height:54px; border-radius:50%;
  display:grid; place-items:center;
  background:#1FA855; color:#fff;
  transition:transform var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out), opacity var(--dur-1) var(--ease-out);
}
.wa-float svg{ width:27px; height:27px; }
.wa-float:hover{ transform:scale(1.08); background:#17914A; }

/* =========================================================================
   LIGHTBOX
   ========================================================================= */
.lightbox{
  position:fixed; inset:0; z-index:150;
  background:rgba(9,10,11,.96);
  display:grid; place-items:center;
  padding:clamp(1rem,4vw,3rem);
  opacity:0; pointer-events:none;
  transition:opacity var(--dur-1) var(--ease-out);
}
/* sin esto, .lightbox{display:grid} le gana al [hidden] del navegador
   y el overlay invisible se come todos los clics de la página */
.lightbox[hidden]{ display:none; }
.lightbox.is-open{ opacity:1; pointer-events:auto; }

.lb-figure{ margin:0; max-width:min(1300px,100%); display:flex; flex-direction:column; gap:var(--sp-4); }
.lb-figure img{
  max-width:100%; max-height:calc(100vh - 10rem);
  width:auto; margin-inline:auto; object-fit:contain;
}
.lb-figure figcaption{
  display:flex; justify-content:center; gap:var(--sp-4);
  color:rgba(237,232,224,.75);
}
.lb-close,.lb-nav{
  position:absolute; z-index:2;
  background:transparent; border:1px solid rgba(237,232,224,.22); color:#fff;
  cursor:pointer; border-radius:50%; display:grid; place-items:center;
  transition:background var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.lb-close:hover,.lb-nav:hover{ background:rgba(237,232,224,.14); border-color:rgba(237,232,224,.5); }
.lb-close{ top:var(--sp-5); right:var(--sp-5); width:46px; height:46px; font-size:1.6rem; line-height:1; padding-bottom:4px; }
.lb-nav{ top:50%; transform:translateY(-50%); width:50px; height:50px; font-size:1.9rem; line-height:1; padding-bottom:5px; }
.lb-prev{ left:clamp(.5rem,2vw,2rem); }
.lb-next{ right:clamp(.5rem,2vw,2rem); }

body.lb-lock{ overflow:hidden; }
body.lb-lock .site-header, body.lb-lock .wa-float{ opacity:0; pointer-events:none; }

/* =========================================================================
   REVELADOS
   ========================================================================= */
.js .reveal{ opacity:0; transform:translateY(28px); transition:opacity var(--dur-3) var(--ease-out), transform var(--dur-3) var(--ease-out); }
.reveal.is-in{ opacity:1; transform:none; }

/* La imagen se descubre con una cortina que se retrae hacia abajo.
   Ojo: NO usar clip-path para esto. IntersectionObserver descuenta el recorte,
   así que un elemento con inset(100%) nunca "entra en pantalla", nunca recibe
   .is-in y el revelado queda trabado para siempre. */
.mask{ position:relative; overflow:hidden; --mask-bg:var(--paper); }
.section--ink .mask, .tile .mask{ --mask-bg:var(--ink); }
.js .mask::after{
  content:""; position:absolute; inset:0; z-index:1;
  background:var(--mask-bg);
  transform-origin:bottom; transform:scaleY(1);
  transition:transform 1.05s var(--ease-out);
}
.mask.is-in::after{ transform:scaleY(0); }
.js .mask img{ transform:scale(1.1); transition:transform 1.5s var(--ease-out); }
.mask.is-in img{ transform:scale(1); }

/* las piezas de una misma fila entran escalonadas */
.gallery .reveal:nth-child(3n+2){ transition-delay:.07s; }
.gallery .reveal:nth-child(3n){ transition-delay:.14s; }

.services .reveal:nth-child(2){ transition-delay:.05s; }
.services .reveal:nth-child(3){ transition-delay:.1s; }
.services .reveal:nth-child(4){ transition-delay:.15s; }
.services .reveal:nth-child(5){ transition-delay:.2s; }
.services .reveal:nth-child(6){ transition-delay:.25s; }

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media (max-width:1180px){
  .hero-copy{ grid-column:1 / span 12; }
  /* en una columna deja de ser flex: si no, el epígrafe se acomoda
     al lado de la imagen en vez de debajo y la achica */
  .hero-media{
    grid-column:1 / span 12;
    display:block;
    margin-top:var(--sp-8);
  }
  .hero-media .frame{ aspect-ratio:16/10; }
  .hero-media figcaption{ position:static; margin-top:var(--sp-3); }
  .hero{ min-height:0; }

  .manifiesto-in, .manifiesto-foot{ grid-column:1 / span 12; }
  .section-head .col-a{ grid-column:1 / span 12; }
  .section-head .col-b{ grid-column:1 / span 12; margin-top:var(--sp-5); }

  .service{ grid-template-columns:4rem 1fr; }
  .service p{ grid-column:2; margin-top:var(--sp-2); }

  .taller-media{ grid-column:1 / span 12; aspect-ratio:16/10; }
  .taller-copy{ grid-column:1 / span 12; margin-top:var(--sp-8); }

  .contacto-copy, .contacto-form{ grid-column:1 / span 12; }
  .contacto-form{ margin-top:var(--sp-8); }

  .footer-brand, .footer-nav{ grid-column:1 / span 12; }
  .footer-nav{ margin-top:var(--sp-6); }

  .gallery{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}

@media (max-width:860px){
  .burger{ display:flex; }
  .nav{
    position:fixed; inset:var(--header-h) 0 auto 0;
    flex-direction:column; align-items:stretch; gap:0;
    background:var(--paper); border-bottom:1px solid var(--hair);
    padding:var(--sp-2) var(--gutter) var(--sp-6);
    transform:translateY(-12px); opacity:0; visibility:hidden;
    transition:opacity var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out), visibility var(--dur-1);
    max-height:calc(100dvh - var(--header-h)); overflow-y:auto;
  }
  .nav.is-open{ opacity:1; visibility:visible; transform:none; }
  .nav a{ padding:var(--sp-4) 0; border-bottom:1px solid var(--hair); font-size:var(--t-lg); }
  .nav a:not(.btn)::after{ display:none; }
  .nav .btn{ margin-top:var(--sp-5); border-bottom:0; }
  .site-header.is-nav-open{ background:var(--paper); border-bottom-color:transparent; }
}

@media (max-width:640px){
  :root{ --header-h:64px; }
  .brand-logo{ width:34px; height:34px; }
  .brand-name{ font-size:.95rem; }

  .hero-actions .btn{ flex:1 1 auto; }
  .hero-foot ul{ gap:var(--sp-4); }

  .service{ grid-template-columns:1fr; gap:var(--sp-2); }
  .service p{ grid-column:1; }
  .service-num{ padding-top:0; }

  .gallery{ grid-template-columns:1fr; }
  .tile-cta{ grid-column:span 1; }

  .datos > div{ grid-template-columns:1fr; gap:var(--sp-1); }
  .steps li{ grid-template-columns:2.75rem 1fr; }
  .lb-nav{ width:42px; height:42px; font-size:1.6rem; }
  .lb-close{ width:42px; height:42px; }
}

/* =========================================================================
   PREFERENCIAS
   ========================================================================= */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  .js .reveal{ opacity:1; transform:none; }
  .js .line > span{ transform:none; }
  .js .mask::after{ transform:scaleY(0); }
  .js .mask img{ transform:none; }
  .marquee-track{ animation:none; }
}

@media print{
  .site-header,.wa-float,.lightbox,.filters,.marquee,.tile-mas{ display:none !important; }
  body{ background:#fff; }
  body::before{ display:none; }
  .section--ink,.site-footer{ background:#fff; color:#000; }
}

/* =========================================================================
   MICROANIMACIONES
   Criterio: una sola entrada orquestada al cargar, y después movimiento
   sólo como respuesta a algo que hace la persona. Donde el navegador
   soporta animaciones ligadas al scroll se usan las nativas, que corren
   fuera del hilo principal; si no, no pasa nada y todo queda visible.
   ========================================================================= */

/* ---------- barra de lectura ---------- */
.progress{
  position:fixed; top:0; left:0; z-index:120;
  height:2px; width:100%;
  background:var(--red);
  transform:scaleX(0); transform-origin:0 50%;
}
@supports (animation-timeline: scroll()){
  .progress{
    animation:barra linear both;
    animation-timeline:scroll(root block);
  }
}
@keyframes barra{ to{ transform:scaleX(1); } }

/* ---------- entrada orquestada ---------- */
/* el hero no espera al scroll: entra apenas carga la página */
.hero .reveal{ transition-delay:.05s; }
.hero-foot.reveal{ transition-delay:.45s; }

.js body:not(.is-ready) .site-header{ opacity:0; transform:translateY(-100%); }
.site-header{ transition:background var(--dur-2) var(--ease-out),
                         border-color var(--dur-2) var(--ease-out),
                         opacity var(--dur-2) var(--ease-out),
                         transform var(--dur-2) var(--ease-out); }

.js .hero-copy .eyebrow,
.js .hero-copy .lead,
.js .hero-copy .hero-actions{
  opacity:0; transform:translateY(14px);
  transition:opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.is-ready .hero-copy .eyebrow{ opacity:1; transform:none; transition-delay:.1s; }
.is-ready .hero-copy .lead{ opacity:1; transform:none; transition-delay:.42s; }
.is-ready .hero-copy .hero-actions{ opacity:1; transform:none; transition-delay:.5s; }
.is-ready .hero h1 .line > span{ transform:none; }
.hero h1 .line:nth-child(1) > span{ transition-delay:.16s; }
.hero h1 .line:nth-child(2) > span{ transition-delay:.24s; }
.hero h1 .line:nth-child(3) > span{ transition-delay:.32s; }
.is-ready .hero-media .js .mask::after{ transform:scaleY(0); transition-delay:.2s; }
.is-ready .hero-media .mask img{ transform:scale(1); transition-delay:.2s; }

/* ---------- manifiesto: se aclara palabra por palabra al scrollear ---------- */
.palabras .w{
  display:inline-block;
  color:var(--tx-mute);
  transition:color var(--dur-2) var(--ease-out);
}
.palabras.is-in .w{ color:var(--tx); }
@supports (animation-timeline: view()){
  .palabras .w{
    color:var(--tx-mute);
    animation:tinta linear both;
    animation-timeline:view();
    /* cada palabra se enciende un poco después que la anterior */
    animation-range:cover calc(18% + (var(--i) / var(--n)) * 34%)
                    cover calc(30% + (var(--i) / var(--n)) * 34%);
  }
  .palabras.is-in .w{ color:var(--tx-mute); }
}
@keyframes tinta{ to{ color:var(--tx); } }

/* ---------- botones: el relleno sube desde abajo ---------- */
.btn{ position:relative; overflow:hidden; isolation:isolate; }
.btn::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:var(--red);
  transform:scaleY(0); transform-origin:bottom;
  transition:transform var(--dur-2) var(--ease-out);
}
.btn:hover::before, .btn:focus-visible::before{ transform:scaleY(1); }
.btn:hover, .btn:focus-visible{ background:var(--ink); color:#fff; border-color:var(--red); }
.btn--ghost:hover, .btn--ghost:focus-visible{ background:transparent; }
.btn--inv:hover, .btn--inv:focus-visible{ background:var(--paper); }

/* ---------- filtros: la pastilla se desliza ---------- */
.filters{ position:relative; }
.filter-pill{
  position:absolute; top:0; left:0; z-index:0;
  height:100%; border-radius:2px;
  background:var(--paper);
  transform:translateX(var(--x,0)) ;
  width:var(--w,0);
  opacity:0;
  transition:transform var(--dur-2) var(--ease-out),
             width var(--dur-2) var(--ease-out),
             opacity var(--dur-1) var(--ease-out);
}
.filter-pill.is-ready{ opacity:1; }
.filter{ position:relative; z-index:1; }
/* sólo cuando el JS ya colocó la pastilla; si no, el botón activo
   conserva su fondo y sigue siendo legible */
.filters.con-pill .filter.is-active{
  background:transparent; border-color:transparent; color:var(--ink);
}

/* ---------- servicios: la flecha entra al pasar el mouse ---------- */
.service{ position:relative; }
.service-flecha{
  position:absolute; top:50%; right:0; margin-top:-6px;
  width:26px; height:12px;
  opacity:0; transform:translateX(-14px);
  transition:opacity var(--dur-1) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.service-flecha::before{
  content:""; position:absolute; top:50%; left:0; width:100%; height:1px;
  background:var(--red);
}
.service-flecha::after{
  content:""; position:absolute; top:50%; right:0;
  width:7px; height:7px;
  border-top:1px solid var(--red); border-right:1px solid var(--red);
  transform:translateY(-50%) rotate(45deg);
}
@media (hover:hover) and (pointer:fine){
  .service:hover .service-flecha{ opacity:1; transform:none; }
}
@media (max-width:1180px){ .service-flecha{ display:none; } }

/* ---------- campos: la línea se dibuja al enfocar ---------- */
/* con un degradado propio del control, para que quede sobre el borde real
   sin agregar elementos ni depender de la altura del campo */
.field input, .field textarea{
  background-image:linear-gradient(var(--paper), var(--paper));
  background-repeat:no-repeat;
  background-position:0 100%;
  background-size:0% 1px;
  transition:border-color var(--dur-1) var(--ease-out),
             background-size var(--dur-2) var(--ease-out);
}
.field input:focus, .field textarea:focus{ background-size:100% 1px; }

/* ---------- banda: acercamiento muy lento ---------- */
.banda img{ animation:acercar 24s ease-in-out infinite alternate; }
@keyframes acercar{ from{ scale:1; } to{ scale:1.07; } }

/* ---------- el botón de WhatsApp aparece al bajar ---------- */
.js .wa-float{ opacity:0; transform:scale(.7); pointer-events:none; }
.wa-float.is-on{ opacity:1; transform:none; pointer-events:auto; }
.wa-float.is-on:hover{ transform:scale(1.08); }

/* ---------- lightbox: la imagen entra con una escala mínima ---------- */
.js .lb-figure img{ transform:scale(.97); opacity:0; transition:transform var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out); }
.lightbox.is-open .lb-figure img{ transform:none; opacity:1; }

/* ---------- subrayado que se dibuja en los datos de contacto ---------- */
.datos a{ position:relative; border-bottom:0; }
.datos a::after{
  content:""; position:absolute; left:0; bottom:-2px; width:100%; height:1px;
  background:currentColor; transform:scaleX(0); transform-origin:right;
  transition:transform var(--dur-2) var(--ease-out);
}
.datos a:hover::after{ transform:scaleX(1); transform-origin:left; }

/* ---------- respeto por quien pide menos movimiento ---------- */
@media (prefers-reduced-motion:reduce){
  .progress{ display:none; }
  .js .hero-copy .eyebrow, .js .hero-copy .lead, .js .hero-copy .hero-actions{ opacity:1; transform:none; }
  .js body:not(.is-ready) .site-header{ opacity:1; transform:none; }
  .palabras .w{ color:var(--tx); animation:none; }
  .banda img{ animation:none; }
  .js .lb-figure img{ opacity:1; transform:none; }
  .js .wa-float{ opacity:1; transform:none; pointer-events:auto; }
}
