/* ═══════════════════════════════════════════════════════════
   TOKENS
   ═══════════════════════════════════════════════════════════ */
/* Los tonos van más claros que la paleta de origen a propósito: el texto flota
   sobre una escena viva, no sobre un fondo plano, y un crema apagado se pierde
   cada vez que un chevron iluminado pasa por detrás. */
:root{
  --cantera:      #F2EBDD;   /* texto principal, casi blanco cálido */
  --tinta:        #222831;   /* azul-negro: fondo base de toda la página */
  --buganvilia:   #A89A85;   /* acento único, aclarado para contrastar */
  --niebla:       #DCD3C4;   /* texto de apoyo sobre fondo oscuro */
  --brillo:       #D9C9A6;   /* acento claro: rótulos y estados de foco */
  --tenue:        #B8AD9B;   /* letra chica: avisos y pie */

  /* Playfair Display: serif de alto contraste, astas gruesas y remates de
     pelo. Se reserva para el texto grande — a tamaño chico los remates finos
     desaparecen sobre el canvas. Todo lo pequeño va en Inter. */
  --display: "Playfair Display", Georgia, "Times New Roman", serif;
  --cuerpo:  "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, monospace;

  --ancho: 1120px;
  --radio: 3px;

  /* Margen lateral único para encabezado, diapositivas y contenido: así los tres
     comparten la misma guía en cualquier ancho, en vez de que el escenario use
     60px fijos y el Acto II otra medida distinta. */
  --gutter: clamp(20px, 4.5vw, 60px);
}

/* ═══════════════════════════════════════════════════════════
   RESET Y BASE
   ═══════════════════════════════════════════════════════════ */
*{margin:0;padding:0;box-sizing:border-box;}

html,body{
  width:100%;
  background-color:var(--tinta);
  -ms-overflow-style:none;
  scrollbar-width:none;
}
/* El encabezado queda fijo también en el Acto II: los anclajes deben respetarlo. */
html{scroll-padding-top:96px;}
::-webkit-scrollbar{display:none;width:0;}

body{
  font-family:var(--cuerpo);
  color:var(--cantera);
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

/* El texto no se apoya en un fondo sólido sino en una escena que se mueve: un
   chevron iluminado puede cruzar por detrás de cualquier línea en cualquier
   momento. Esta sombra lo despega del canvas sin necesidad de opacar la escena,
   que es lo que le da carácter a la página. Se hereda a todo el texto de ambos
   actos; sobre los botones, que sí tienen fondo propio, se anula.
   .boton-contacto queda fuera de esa excepción: es de cristal, no tiene fondo
   sólido, y define su propia sombra más discreta. */
.capa-cine, #acto-dos{
  text-shadow:0 1px 2px rgba(8,10,14,.92), 0 0 16px rgba(8,10,14,.55);
}
/* Los botones ya no se excluyen: al ser de cristal no tienen fondo sólido y
   definen su propia sombra, más discreta, en la receta compartida. */

/* El interletrado cerrado que pedía la grotesca aquí sobra: en un Didone las
   astas gruesas ya llenan el renglón y apretarlas emborrona los remates. */
h1,h2{font-family:var(--display);line-height:1.06;margin:0;font-weight:400;letter-spacing:-.01em;}
h3{margin:0;}
p{margin:0 0 1.1em;}
a{color:inherit;}
img,svg{max-width:100%;display:block;}
/* También <ol>: la lista de pasos es un ol semántico (el orden es información),
   pero su numeración la dibuja .paso__num. Sin esto el navegador añadía la suya
   y salían dos numeraciones, «1. 01», «2. 02». */
ul,ol{margin:0;padding:0;list-style:none;}

/* Sin z-index propio a propósito: un z-index aquí crearía un contexto de
   apilamiento que encerraría a .reticula (31) y .capa-cine (40) por debajo de
   #acto-dos (30). Dejándolo en auto, esos hijos compiten en la raíz y pueden
   quedar por encima del Acto II. */
#acto-uno{height:420vh;position:relative;}
/* El cursor propio ya no se limita al escenario: lo gobierna body.cursor-propio
   para toda la página (ver sección CURSOR PERSONALIZADO). */

#webgl{
  position:fixed;top:0;left:0;
  width:100%;height:100%;
  z-index:1;outline:none;
}

/* El Acto II no tapa el escenario: lo vela. El fondo queda transparente y cada
   sección pone su propio velo oscuro, así la parvada y el shader siguen vivos
   detrás de toda la página y los dos actos se leen como un solo mundo. */
#acto-dos{
  position:relative;z-index:30;
  background:transparent;color:var(--cantera);
}

/* Puente visual: el escenario se ve limpio arriba y el velo entra por abajo,
   de modo que la cubierta se sienta como un fundido, no como un panel encimado. */
.transicion-acto{
  height:clamp(16vh,26vw,30vh);
 ;
}

@media(prefers-reduced-motion:reduce){
  *{transition-duration:.01ms !important;}
}

/* ═══════════════════════════════════════════════════════════
   CURSOR PERSONALIZADO
   ═══════════════════════════════════════════════════════════ */
/* Arrancan fuera de cuadro: hasta que el ratón se mueve por primera vez, el JS
   no les ha asignado posición, y en 0,0 asomarían por la esquina superior. */
.cursor-nucleo{
  position:fixed;top:-100px;left:-100px;
  width:6px;height:6px;
  background:var(--buganvilia);
  border-radius:50%;
  transform:translate(-50%,-50%);
  pointer-events:none;z-index:9999;
}
.cursor-halo{
  position:fixed;top:-100px;left:-100px;
  width:38px;height:38px;
  border:1.5px solid rgba(223,208,184,.55);
  border-radius:50%;
  transform:translate(-50%,-50%);
  pointer-events:none;z-index:9998;
  transition:width .3s,height .3s,border-color .3s;
}
/* Estado de enfoque: sobre cualquier cosa clicable el halo crece. */
.cursor-halo.halo-grande{width:64px;height:64px;border-color:var(--buganvilia);}

/* Sobre campos de texto el núcleo se convierte en una barra vertical y el halo
   se retira. Al ocultar el cursor del sistema en toda la página se pierde la
   viga en I, que es la que dice dónde vas a escribir; esto la sustituye en vez
   de dejar el formulario sin esa pista. */
.cursor-nucleo.nucleo-texto{
  width:2px;height:22px;border-radius:1px;
  background:var(--cantera);
}
.cursor-halo.halo-texto{opacity:0;}

/* La clase la pone el JS, y solo en dispositivos con puntero fino: en una
   pantalla táctil no hay cursor que sustituir y esconder el del sistema
   dejaría al usuario sin nada si conecta un ratón. Al depender de JS, si el
   script falla el cursor nativo sigue ahí: la degradación es la correcta.
   El `html` delante no es decorativo: sube la especificidad para ganarle a
   reglas como `.pregunta summary{cursor:pointer}`, que empataba con
   `body.cursor-propio *` y se imponía por ir después en el archivo. Con el
   empate deshecho, la manita del sistema ya no asoma sobre las preguntas. */
html body.cursor-propio,
html body.cursor-propio *{cursor:none;}

/* ═══════════════════════════════════════════════════════════
   CAPA CINEMATOGRÁFICA
   ═══════════════════════════════════════════════════════════ */
/* z-index por encima de #acto-dos (30) para que el encabezado sobreviva al
   Acto II. Las diapositivas inactivas son invisibles, así que solo persiste
   la cabecera; .capa-cine no captura el ratón salvo en .cabecera. */
.capa-cine{
  position:fixed;top:0;left:0;
  width:100%;height:100%;
  z-index:40;pointer-events:none;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:0 var(--gutter) clamp(24px,4vh,40px) var(--gutter);
}

/* Transparente de principio a fin: flota igual sobre el escenario que sobre
   el Acto II, sin velo ni desenfoque que la despeguen del resto. */
.cabecera{
  display:flex;justify-content:space-between;align-items:center;
  width:100%;z-index:20;pointer-events:auto;
  padding:20px 0;
}
.marca{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--cantera);}
/* La marca conserva algo más de peso que los títulos: es pequeña y necesita
   sostenerse sola en la esquina. Un poco más grande y sin el interletrado
   cerrado, porque el serif a 20px se lee más chico que la grotesca anterior. */
.marca-texto{font-family:var(--display);font-weight:600;font-size:23px;letter-spacing:0;}
.marca-texto b{color:var(--buganvilia);}

.nav-cabecera{display:flex;align-items:center;gap:24px;}
.nav-enlace{
  color:var(--cantera);text-decoration:none;
  font-family:var(--mono);font-size:11px;font-weight:500;
  text-transform:uppercase;letter-spacing:1.6px;
  padding-bottom:3px;border-bottom:1.5px solid transparent;
  transition:border-color .3s;
}
.nav-enlace:hover{border-bottom-color:var(--brillo);}
.nav-punto{width:3px;height:3px;background:rgba(223,208,184,.25);border-radius:50%;}

/* ═══════════════════════════════════════════════════════════
   CRISTAL LÍQUIDO — receta compartida por todos los botones
   ═══════════════════════════════════════════════════════════ */
/* Todos los botones de la página flotan sobre una escena que va del casi negro
   al dorado encendido. Un cristal solo claro dejaría el texto ilegible en la
   zona luminosa; la pieza que lo resuelve es el brightness(.55) dentro del
   backdrop-filter, que oscurece lo que hay detrás del botón sin dejar de
   transparentarlo, así que el contraste queda garantizado pase lo que pase en
   el canvas. El blur, además de dar el efecto, borra el detalle fino de los
   chevrones que cruzan por detrás.

   La receta vive en un solo lugar a propósito: son cuatro botones en tres
   secciones distintas y, repetida, se desincronizaría al primer ajuste. */
.boton-contacto,
.boton,
.dia-cta{
  position:relative;
  overflow:hidden;
  border-radius:999px;
  color:var(--cantera);
  text-decoration:none;
  font-family:var(--mono);
  text-transform:uppercase;letter-spacing:1px;font-weight:500;
  background:linear-gradient(180deg,
    rgba(255,255,255,.20) 0%,
    rgba(255,255,255,.06) 52%,
    rgba(255,255,255,.11) 100%);
  backdrop-filter:blur(16px) saturate(150%) brightness(.55);
  -webkit-backdrop-filter:blur(16px) saturate(150%) brightness(.55);
  border:1px solid rgba(223,208,184,.30);
  /* El filo superior iluminado es lo que lee como vidrio y no como panel. */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.40),
    inset 0 -1px 0 rgba(255,255,255,.08),
    0 6px 20px rgba(0,0,0,.34);
  text-shadow:0 1px 2px rgba(8,10,14,.65);
}

/* Reflejo que recorre el cristal al pasar el cursor: el matiz «líquido». */
.boton-contacto::before,
.boton::before,
.dia-cta::before{
  content:"";position:absolute;inset:0;border-radius:inherit;
  background:linear-gradient(115deg,
    transparent 32%, rgba(255,255,255,.26) 48%, transparent 64%);
  transform:translateX(-130%);
  transition:transform .85s cubic-bezier(.4,0,.2,1);
  pointer-events:none;
}
.boton-contacto:hover::before,
.boton:hover::before,
.dia-cta:hover::before{transform:translateX(130%);}

.boton-contacto:hover,
.boton:hover,
.dia-cta:hover{
  border-color:rgba(242,235,221,.55);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.55),
    inset 0 -1px 0 rgba(255,255,255,.10),
    0 10px 26px rgba(0,0,0,.42);
}

/* Variante de acento: el cristal se tiñe de cálido para que el botón principal
   siga leyéndose como principal. Sin esto, unificar el diseño aplanaría la
   jerarquía y el CTA más importante quedaría igual que los demás. */
.boton--principal,
.dia-cta{
  /* El tinte va oscuro, no claro. Con un cálido claro el contraste medido caía
     a 3.69:1, bajo el mínimo AA, y bajar el brightness del fondo no lo
     arreglaba: a esta opacidad el tinte tapa el fondo y es él quien manda.
     Un cálido oscuro conserva el acento y devuelve el margen de lectura. */
  background:
    linear-gradient(180deg,
      rgba(255,255,255,.16) 0%,
      rgba(255,255,255,.04) 55%,
      rgba(255,255,255,.09) 100%),
    linear-gradient(180deg,
      rgba(88,72,52,.72) 0%,
      rgba(62,52,40,.52) 100%);
  backdrop-filter:blur(16px) saturate(160%) brightness(.34);
  -webkit-backdrop-filter:blur(16px) saturate(160%) brightness(.34);
  border-color:rgba(223,208,184,.46);
}

/* Encima del reflejo, para que el barrido no lo atraviese por delante. */
.boton-contacto > *,
.boton > *,
.dia-cta > *{position:relative;z-index:1;}

.boton-punto{
  display:inline-block;width:6px;height:6px;border-radius:50%;
  border:1px solid rgba(242,235,221,.85);
}

/* Sin backdrop-filter no hay cristal, y un fondo al 10% de blanco dejaría los
   botones casi invisibles: se caen a un relleno sólido. */
@supports not ((backdrop-filter:blur(4px)) or (-webkit-backdrop-filter:blur(4px))){
  .boton-contacto,.boton{background:rgba(26,31,39,.92);}
  .boton--principal,.dia-cta{background:rgba(120,108,92,.95);}
}

/* ── Medidas propias de cada botón ─────────────────────────── */
.boton-contacto{
  display:inline-flex;align-items:center;gap:10px;
  padding:11px 24px;font-size:11px;
  transition:transform .3s, box-shadow .3s, border-color .3s;
}
.boton-contacto:hover{transform:scale(1.05);}

/* ═══════════════════════════════════════════════════════════
   DIAPOSITIVAS
   ═══════════════════════════════════════════════════════════ */
.dia{position:absolute;bottom:12%;pointer-events:none;}

#dia-1{left:0;width:100%;}
#dia-1 .dia-titulo{margin-left:var(--gutter);}
#dia-1 .fila-desc{position:relative;display:flex;width:100%;}
#dia-1 .col-1{margin-left:var(--gutter);width:calc(25vw - 60px);max-width:calc(25vw - 60px);}
#dia-1 .col-2{position:absolute;left:calc(25vw + 40px);width:calc(25vw - 60px);max-width:calc(25vw - 60px);}

#dia-2{left:0;width:100%;}
#dia-2 .dia-titulo{margin-left:calc(25vw + 40px);}
#dia-2 .dia-desc{margin-left:calc(50vw + 20px);width:calc(25vw - 60px);max-width:calc(25vw - 60px);}

#dia-3{left:calc(50vw + 20px);width:calc(25vw - 60px);max-width:calc(25vw - 60px);}
#dia-3 .dia-titulo{white-space:nowrap;}

#dia-4{left:calc(25% + 40px);max-width:620px;}

.dia-titulo{
  font-family:var(--display);
  font-size:clamp(52px,7.5vw,104px);
  line-height:1.06;font-weight:400;letter-spacing:-.01em;
  margin-bottom:26px;color:var(--cantera);
  text-wrap:balance;
}
.dia-desc{
  /* Inter ya viene bien espaciada; el tracking extra de la serif anterior aquí
     solo desarmaba las palabras. */
  font-size:17px;line-height:1.65;font-weight:400;
  color:var(--niebla);letter-spacing:.1px;
  opacity:0;transform:translateY(30px);
  transition:opacity .8s cubic-bezier(.25,1,.5,1),
             transform .8s cubic-bezier(.25,1,.5,1);
  transition-delay:.4s;
}
.dia.activa .dia-desc{opacity:1;transform:translateY(0);}

/* El fondo, el borde y el reflejo los pone la receta de cristal compartida;
   aquí solo van la medida y la animación de entrada de la diapositiva. */
.dia-cta{
  display:inline-flex;align-items:center;gap:10px;
  margin-top:26px;padding:14px 30px;
  font-size:12px;
  opacity:0;transform:translateY(20px);
  transition:opacity .8s, transform .8s, box-shadow .3s, border-color .3s;
  transition-delay:.7s;
}
.dia.activa .dia-cta{opacity:1;transform:translateY(0);}
/* El hover no puede usar transform: lo ocupa el revelado de la diapositiva y
   pisarlo devolvería el botón a su posición de entrada. */
.dia-cta:hover{filter:brightness(1.12);}

.dia-titulo .letra{
  display:inline-block;opacity:0;
  transform:translateY(50px);filter:blur(12px);
  transition:opacity .8s cubic-bezier(.25,1,.5,1),
             transform .8s cubic-bezier(.25,1,.5,1),
             filter .8s cubic-bezier(.25,1,.5,1);
}
.dia.activa .dia-titulo .letra{opacity:1;transform:translateY(0);filter:blur(0);}
.dia.activa{pointer-events:auto;}

/* ═══════════════════════════════════════════════════════════
   RETÍCULA Y PROGRESO
   ═══════════════════════════════════════════════════════════ */
/* z-index por encima de #acto-dos (30): la retícula es el pulso visual del
   Acto I y ahora recorre la página entera, no solo el escenario. */
.reticula-horizontal{
  position:fixed;top:70px;left:0;right:0;
  height:1px;background:rgba(223,208,184,.12);
  z-index:31;pointer-events:none;
}
.reticula{
  position:fixed;top:0;left:40px;right:40px;
  width:calc(100% - 80px);height:100vh;
  display:flex;justify-content:space-between;
  z-index:31;pointer-events:none;
  transition:opacity .6s;
}
/* En el Acto II la retícula se atenúa: marca el ritmo sin estorbar la lectura.
   La barra de progreso y la línea del encabezado se retiran porque ya no
   describen nada (el escenario terminó) y el encabezado trae su propio borde. */
body.fuera-de-escena .reticula{opacity:.4;}
body.fuera-de-escena .barras{opacity:0;}
body.fuera-de-escena .reticula-horizontal{opacity:0;}
.reticula-horizontal{transition:opacity .6s;}
.linea{position:relative;width:1px;height:100%;background:rgba(223,208,184,.12);}
.linea:nth-child(3){margin-top:70px;height:calc(100vh - 70px);}
.punto{
  position:absolute;left:50%;transform:translate(-50%,-50%);
  width:6px;height:6px;border-radius:50%;
  background:rgba(223,208,184,.35);
  box-shadow:0 0 4px rgba(223,208,184,.15);
}
.barras{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;gap:12px;
}
.barra{width:2px;height:40px;background:rgba(223,208,184,.15);border-radius:2px;}
.barra-relleno{width:100%;height:0%;background:var(--buganvilia);border-radius:2px;}

/* ═══════════════════════════════════════════════════════════
   ACTO DOS — la página de negocio
   ═══════════════════════════════════════════════════════════ */
.contenedor{width:100%;max-width:var(--ancho);margin-inline:auto;padding-inline:clamp(1.25rem,5vw,2.5rem);}

/* Sin velo: el escenario queda a la vista a través de todo el Acto II.
   La regla existe por el ritmo vertical — el padding es lo único que separa
   una sección de la siguiente, así que sin él todo se encima. */
.seccion{padding-block:clamp(5rem,10vw,9rem);}

/* Preguntas y contacto encadenan mucho texto seguido: respiran más que el
   resto para que el final de una no quede pegado al rótulo de la otra. */
#preguntas{padding-block:clamp(6rem,11vw,10rem);}
#contacto{padding-block:clamp(6.5rem,12vw,11rem);}

.seccion--tinta{background:rgba(24,28,35,.90);color:var(--cantera);}

:focus-visible{outline:2.5px solid var(--buganvilia);outline-offset:3px;}

.rotulo{
  font-family:var(--mono);font-size:.72rem;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:var(--brillo);
  display:flex;align-items:center;gap:.6rem;margin:0 0 1.4rem;
}
.rotulo::before{
  content:"";width:13px;height:8px;flex:none;
  background:currentColor;
  clip-path:polygon(0 100%,50% 0,100% 100%,100% 100%,50% 22%,0 100%);
}

/* Píldora en monoespaciada, igual que .boton-contacto y .dia-cta del Acto I. */
.boton{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  font-size:.78rem;
  padding:14px 30px;
  /* <button> trae estilos propios del sistema operativo que taparían el
     cristal; appearance:none los desactiva. */
  appearance:none;-webkit-appearance:none;
  cursor:pointer;
  transition:transform .3s, box-shadow .3s, border-color .3s;
}
.boton:hover{transform:scale(1.05);}

/* Misma voz tipográfica que las diapositivas del Acto I: display 800,
   interletrado cerrado y una escala grande, un escalón por debajo de la portada
   para que la jerarquía entre actos se sostenga. */
#acto-dos h2{
  font-size:clamp(2.1rem,1rem + 3.6vw,3.8rem);
  line-height:1.06;letter-spacing:-.01em;font-weight:400;
  /* La medida se fija en ch del propio h2, no del contenedor: así son ~18
     caracteres por renglón sin importar cuánto crezca la fuente. */
  max-width:18ch;
  text-wrap:balance;
}
/* Los subtítulos de tarjeta se quedan en Inter: a 20px los remates de pelo de
   un Didone se adelgazan hasta desaparecer sobre el canvas. */
h3{font-family:var(--cuerpo);font-size:clamp(1.15rem,1.05rem + .5vw,1.4rem);font-weight:600;letter-spacing:-.01em;line-height:1.3;}

/* Revelado letra por letra, el gesto de firma del Acto I. Las clases .letra las
   inyecta separarTitulos(); .revelado lo dispara ScrollTrigger al entrar en cuadro. */
#acto-dos h2 .letra{
  display:inline-block;opacity:0;
  transform:translateY(50px);filter:blur(12px);
  transition:opacity .8s cubic-bezier(.25,1,.5,1),
             transform .8s cubic-bezier(.25,1,.5,1),
             filter .8s cubic-bezier(.25,1,.5,1);
}
#acto-dos h2.revelado .letra{opacity:1;transform:translateY(0);filter:blur(0);}

/* Cada letra es una caja inline-block, y el navegador puede cortar el renglón
   entre dos cajas cualesquiera: sin esto, las palabras se parten a la mitad.
   La palabra necesita su propia caja indivisible. */
.palabra{display:inline-block;white-space:nowrap;}

/* Aire bajo cualquier h2 del Acto II, no solo los que van en .titulo-bloque:
   el de contacto es hijo directo de la sección y quedaba pegado a su párrafo. */
#acto-dos h2 + p{margin-top:1rem;}

.titulo-bloque{max-width:min(100%,46rem);margin-bottom:clamp(2.5rem,5vw,3.8rem);}
.titulo-bloque p{color:var(--niebla);margin-top:1rem;margin-bottom:0;max-width:52ch;}

.servicios{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem;}
.servicio{
  background:rgba(223,208,184,.04);border:1px solid rgba(223,208,184,.14);
  border-radius:var(--radio);padding:2rem 1.75rem 1.9rem;
  display:flex;flex-direction:column;
  transition:border-color .18s,transform .18s,background .18s;
}
.servicio:hover{border-color:var(--buganvilia);background:rgba(223,208,184,.07);transform:translateY(-3px);}
.servicio__ala{width:34px;height:20px;margin-bottom:1.5rem;}
.servicio h3{margin-bottom:.75rem;}
.servicio p{color:var(--niebla);font-size:.98rem;margin-bottom:1.3rem;}
.servicio ul{
  margin-top:auto;border-top:1px solid rgba(223,208,184,.14);padding-top:1.1rem;
  font-family:var(--mono);font-size:.75rem;color:var(--niebla);line-height:2;
}
/* Tres tarjetas no caben legibles por debajo de ~1024px: en tablet pasan a dos
   y la tercera ocupa el ancho completo, en vez de estrujarse las tres. */
@media(max-width:1024px){
  .servicios{grid-template-columns:repeat(2,1fr);}
  .servicio:last-child{grid-column:1 / -1;}
}
@media(max-width:700px){
  .servicios{grid-template-columns:1fr;}
  .servicio:last-child{grid-column:auto;}
}

.proceso{display:grid;grid-template-columns:repeat(4,1fr);gap:1.5rem;}
.paso{border-top:2px solid var(--buganvilia);padding-top:1.3rem;}
.paso__num{
  font-family:var(--mono);font-size:.75rem;color:var(--brillo);
  letter-spacing:.1em;display:block;margin-bottom:.7rem;
}
.paso h3{margin-bottom:.6rem;}
.paso p{color:var(--niebla);font-size:.96rem;margin-bottom:0;}
/* Cuatro pasos en fila se vuelven ilegibles pronto: 2x2 en tablet y en columna
   en móvil, donde además el orden numerado se lee mejor en vertical. */
@media(max-width:1024px){ .proceso{grid-template-columns:repeat(2,1fr);gap:2rem 1.5rem;} }
@media(max-width:640px){  .proceso{grid-template-columns:1fr;gap:2rem;} }

.proyectos{display:grid;grid-template-columns:repeat(2,1fr);gap:1.5rem;}
.proyecto{
  border:1px solid rgba(223,208,184,.14);border-radius:var(--radio);
  padding:1.9rem 1.75rem;background:rgba(223,208,184,.04);
  transition:border-color .18s,background .18s;
}
.proyecto:hover{border-color:var(--buganvilia);background:rgba(223,208,184,.07);}
.proyecto__meta{
  font-family:var(--mono);font-size:.72rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--brillo);margin-bottom:.9rem;
}
.proyecto h3{margin-bottom:.7rem;}
.proyecto p{color:var(--niebla);font-size:.96rem;margin-bottom:1.1rem;}
.proyecto__stack{font-family:var(--mono);font-size:.72rem;color:var(--niebla);}
@media(max-width:760px){ .proyectos{grid-template-columns:1fr;} }

/* ═══════════════════════════════════════════════════════════
   OPINIONES — cinta en desfile continuo
   ═══════════════════════════════════════════════════════════ */
/* La ventana por la que se asoma el desfile. overflow:hidden es lo que evita
   que la pista, que mide el doble del ancho del contenido, empuje la barra de
   scroll horizontal de la página. */
.cinta{
  position:relative;
  overflow:hidden;
  padding-block:.5rem;
  /* Desvanecido en los bordes: sin él las tarjetas aparecen y desaparecen de
     golpe contra el canto de la pantalla y se ve el truco. */
  mask-image:linear-gradient(90deg,
    transparent 0, #000 9%, #000 91%, transparent 100%);
  -webkit-mask-image:linear-gradient(90deg,
    transparent 0, #000 9%, #000 91%, transparent 100%);
}

/* La pista lleva DOS copias idénticas del grupo, una detrás de la otra. Al
   desplazarla un -50% recorre exactamente el ancho de una copia, de modo que
   el fotograma final es idéntico al inicial y el salto del bucle no se ve.
   Si alguna vez cambias el número de copias, este -50% cambia con él. */
.cinta__pista{
  display:flex;
  width:max-content;
  animation:desfile 46s linear infinite;
}
.cinta__grupo{
  display:flex;
  flex:none;
  gap:1.25rem;
  padding-inline:.625rem;   /* la mitad del gap, para que la costura respete el ritmo */
  margin:0;list-style:none;
}
@keyframes desfile{
  from{transform:translateX(0);}
  to{transform:translateX(-50%);}
}

/* Se detiene al pasar el cursor o al enfocar con teclado: si algo interesa,
   hay que poder leerlo sin perseguirlo. */
.cinta:hover .cinta__pista,
.cinta:focus-within .cinta__pista{animation-play-state:paused;}

.opinion{
  flex:none;
  width:min(78vw,340px);
  display:flex;flex-direction:column;justify-content:space-between;
  gap:1.1rem;
  padding:1.6rem 1.5rem;
  border-radius:calc(var(--radio) * 4);
  /* El color oscuro de abajo no es decorativo: es un suelo de opacidad que no
     depende de backdrop-filter. Con solo el filtro, medido a lo largo de todo
     el ciclo, la tarjeta que cruzaba el resplandor bajaba a 3.8:1. */
  background:
    linear-gradient(180deg,
      rgba(255,255,255,.10) 0%,
      rgba(255,255,255,.03) 100%),
    rgba(18,22,29,.55);
  border:1px solid rgba(223,208,184,.18);
  /* Mismo recurso que en los botones: el brightness oscurece el fondo que
     queda detrás de la tarjeta. Sin él, las que pasan por delante del
     resplandor dorado se leían lavadas, y como la cinta se mueve, cualquier
     opinión acaba tarde o temprano sobre esa zona. */
  backdrop-filter:blur(12px) saturate(130%) brightness(.42);
  -webkit-backdrop-filter:blur(12px) saturate(130%) brightness(.42);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16);
}
.opinion__texto{
  margin:0;
  font-size:.98rem;line-height:1.6;
  color:var(--niebla);
}

/* El sprite solo guarda las definiciones; no debe ocupar sitio ni aparecer. */
.sprite-iconos{position:absolute;width:0;height:0;overflow:hidden;}

.opinion__estrellas{display:flex;gap:3px;}
.estrella{
  width:14px;height:14px;flex:none;
  fill:var(--brillo);
}
/* La estrella que falta se apaga en vez de desaparecer: si no se ve el hueco,
   un 4 sobre 5 se lee igual que un 5 sobre 5. */
.estrella--vacia{fill:rgba(223,208,184,.20);}

.opinion__pie{display:flex;align-items:center;gap:.75rem;}
.opinion__avatar{
  flex:none;
  width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;
  background:rgba(223,208,184,.12);
  border:1px solid rgba(223,208,184,.24);
}
.opinion__avatar svg{width:21px;height:21px;fill:var(--brillo);}

.opinion__firma{
  margin:0;
  font-family:var(--mono);font-size:.72rem;
  letter-spacing:.08em;text-transform:uppercase;
  color:var(--brillo);
  line-height:1.5;
}
.opinion__firma span{color:var(--tenue);}

/* Con movimiento reducido no se desfila: la cinta se vuelve una fila que el
   usuario recorre a mano. Detener la animación sin más dejaría la mitad de las
   opiniones fuera de la pantalla y sin manera de alcanzarlas. */
@media(prefers-reduced-motion:reduce){
  .cinta{overflow-x:auto;-webkit-overflow-scrolling:touch;}
  .cinta__pista{animation:none;width:auto;}
  .cinta__grupo[aria-hidden="true"]{display:none;}
}

.preguntas{max-width:760px;}
.pregunta{border-bottom:1px solid rgba(223,208,184,.18);}
.pregunta summary{
  cursor:pointer;list-style:none;padding:1.75rem 2.5rem 1.75rem 0;
  font-family:var(--cuerpo);font-weight:600;font-size:1.06rem;
  position:relative;
}
.pregunta summary::-webkit-details-marker{display:none;}
.pregunta summary::after{
  content:"";position:absolute;right:.4rem;top:2.15rem;
  width:13px;height:8px;background:var(--buganvilia);
  clip-path:polygon(0 0,50% 100%,100% 0);
  transition:transform .2s;
}
.pregunta[open] summary::after{transform:rotate(180deg);}
.pregunta p{color:var(--niebla);font-size:.98rem;padding-right:2.5rem;margin-bottom:1.4rem;}

.contacto__reja{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(2.5rem,6vw,5rem);}
.vias{margin-top:2rem;}
.via{
  display:flex;align-items:center;gap:.9rem;text-decoration:none;
  padding:1rem 0;border-bottom:1px solid rgba(223,208,184,.18);
  font-family:var(--mono);font-size:.88rem;
}
.via:hover{color:var(--brillo);}
.via span:first-child{color:#C9BBA5;font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;min-width:88px;}

.campo{margin-bottom:1.15rem;}
.campo label{
  display:block;font-family:var(--mono);font-size:.73rem;letter-spacing:.09em;
  text-transform:uppercase;color:#C9BBA5;margin-bottom:.5rem;
}
.campo input,.campo select,.campo textarea{
  width:100%;background:rgba(223,208,184,.06);
  border:1px solid rgba(223,208,184,.22);border-radius:var(--radio);
  padding:.85rem 1rem;color:var(--cantera);
  font-family:var(--cuerpo);font-size:1rem;
}
.campo textarea{resize:vertical;min-height:130px;}
.campo input:focus,.campo select:focus,.campo textarea:focus{border-color:var(--brillo);}
.campo select option{background:var(--tinta);}
.aviso{font-family:var(--mono);font-size:.74rem;color:var(--tenue);margin:.9rem 0 0;}
/* El formulario necesita ancho para respirar: se apila antes que otras rejillas. */
@media(max-width:1024px){ .contacto__reja{grid-template-columns:1fr;gap:3rem;} }

/* ═══════════════════════════════════════════════════════════
   CIERRE — llamada a la acción final
   ═══════════════════════════════════════════════════════════ */
/* Botón secundario de contorno: acompaña al principal sin competir con él. */
/* Variante secundaria: el mismo cristal pero sin el tinte cálido del principal,
   para que acompañe sin competir. Hoy no la usa ningún botón — quedó libre al
   quitarse la sección de cierre — pero se conserva por si vuelve a hacer falta.
   No pone background:transparent: eso anularía el cristal de la receta. */
.boton--linea{border-color:rgba(223,208,184,.24);}
.boton--linea:hover{border-color:rgba(242,235,221,.50);}

.cierre{text-align:center;}
/* Panel propio, a diferencia del resto de secciones que dejan ver el canvas
   sin filtro. Esta cae sobre la zona más brillante del escenario y es la que
   tiene que convertir: aquí la legibilidad pesa más que la transparencia.
   El velo se queda contenido en la caja, así que la escena sigue a la vista
   alrededor y no se pierde el efecto. */
.cierre__caja{
  max-width:62ch;
  background:rgba(18,22,29,.78);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border:1px solid rgba(223,208,184,.16);
  border-radius:calc(var(--radio) * 4);
  padding:clamp(2.5rem,6vw,4rem) clamp(1.5rem,5vw,3.5rem);
}
/* #acto-dos h2 limita la medida a 18ch; aquí además hay que centrarla. */
.cierre h2{margin-inline:auto;}
.cierre .rotulo{justify-content:center;}
.cierre__bajada{
  color:var(--niebla);margin:1.1rem auto 0;max-width:52ch;
}
.cierre__acciones{
  display:flex;flex-wrap:wrap;gap:.9rem;justify-content:center;
  margin-top:2.4rem;
}
.cierre__redes{
  display:flex;flex-wrap:wrap;gap:.6rem 1.8rem;justify-content:center;
  margin-top:2.4rem;
  font-family:var(--mono);font-size:.78rem;
  letter-spacing:.1em;text-transform:uppercase;
}
.cierre__redes a{
  color:var(--brillo);text-decoration:none;
  padding-bottom:3px;border-bottom:1.5px solid transparent;
  transition:border-color .25s,color .25s;
}
.cierre__redes a:hover{border-bottom-color:var(--brillo);color:var(--cantera);}
.cierre__nota{
  margin:2rem 0 0;font-family:var(--mono);font-size:.72rem;
  letter-spacing:.06em;color:var(--tenue);
}

/* ═══════════════════════════════════════════════════════════
   BOTÓN FLOTANTE DE WHATSAPP
   ═══════════════════════════════════════════════════════════ */
/* Verde oficial de WhatsApp a propósito, aunque no sea de la paleta: este
   botón se reconoce por su color antes que por su forma, y perder eso a
   cambio de armonía cromática le costaría clics. */
.wa-flotante{
  position:fixed;
  right:clamp(16px,2.2vw,24px);
  bottom:clamp(16px,2.2vw,24px);
  /* Por encima de .capa-cine (40) y de #acto-dos (30), y por debajo del
     cursor personalizado (9998), que de todos modos no captura el puntero. */
  z-index:60;
  /* Círculo, no píldora: al quedarse sin etiqueta de texto, una píldora de
     66x54 se veía como un recorte accidental en vez de una decisión. */
  display:inline-flex;align-items:center;justify-content:center;
  width:56px;height:56px;padding:0;border-radius:50%;
  /* Verde oficial de WhatsApp, deliberadamente fuera de la paleta y sin el
     cristal del resto de botones: este se reconoce por su color antes que por
     su forma, y siendo solo un icono ese color es la única pista que da. */
  background:#25D366;color:#0B141A;
  text-decoration:none;
  box-shadow:0 6px 22px rgba(0,0,0,.42), 0 0 0 1px rgba(255,255,255,.10) inset;
  text-shadow:none;
  transition:transform .25s, box-shadow .25s, opacity .3s, visibility .3s;
}
.wa-flotante:hover{transform:translateY(-3px);box-shadow:0 10px 28px rgba(0,0,0,.5);}
.wa-flotante__icono{width:26px;height:26px;flex:none;display:block;}

/* Se retira cuando las secciones de contacto o de cierre están en pantalla:
   ahí el visitante ya tiene botones de WhatsApp a la vista, y el flotante
   solo estorbaría encima del formulario. La clase la pone script.js. */
.wa-flotante--oculto{
  opacity:0;visibility:hidden;pointer-events:none;transform:scale(.85);
}

/* El pie deja hueco para que el botón no se apoye sobre sus enlaces. */
.pie{background:rgba(20,23,28,.94);color:var(--tenue);border-top:1px solid rgba(223,208,184,.14);padding-block:2.2rem;}
.pie__fila{
  display:flex;flex-wrap:wrap;gap:1rem 2rem;
  align-items:center;justify-content:space-between;
  font-family:var(--mono);font-size:.74rem;
}
.pie a{text-decoration:none;}
.pie a:hover{color:var(--cantera);}

.revelar{will-change:transform,opacity;}

/* ═══════════════════════════════════════════════════════════
   RESPALDO SIN WEBGL
   ═══════════════════════════════════════════════════════════ */
.sin-webgl #webgl{display:none;}
/* El cursor propio ya no depende del bucle de la escena —tiene el suyo—, así
   que sigue funcionando también en el respaldo sin WebGL. */
.sin-webgl #acto-uno{
  height:auto;min-height:140vh;
  background:linear-gradient(180deg,var(--tinta),#241F1B);
}
.sin-webgl .capa-cine{position:absolute;inset:0;height:auto;min-height:140vh;}
.sin-webgl .cabecera{position:sticky;top:0;background:rgba(34,40,49,.85);backdrop-filter:blur(8px);}
.sin-webgl .reticula,.sin-webgl .reticula-horizontal{display:none;}
.sin-webgl .dia{
  position:relative;bottom:auto;left:0 !important;width:100% !important;max-width:720px !important;
  margin:0 auto;display:flex;flex-direction:column;justify-content:center;
  min-height:44vh;padding:40px 24px;
}
.sin-webgl #dia-1 .fila-desc{flex-direction:column;gap:1rem;position:static;}
.sin-webgl #dia-1 .col-1,.sin-webgl #dia-1 .col-2{position:static;width:100% !important;max-width:100% !important;margin-left:0 !important;left:auto !important;}
.sin-webgl #dia-2 .dia-titulo,.sin-webgl #dia-2 .dia-desc,.sin-webgl #dia-3,.sin-webgl #dia-3 .dia-titulo{
  margin-left:0 !important;width:100% !important;max-width:100% !important;position:static !important;left:auto !important;
}
.sin-webgl .dia-desc,.sin-webgl .dia-titulo .letra,.sin-webgl .dia-cta{opacity:1 !important;transform:none !important;filter:none !important;}

/* ═══════════════════════════════════════════════════════════
   TABLET — el escenario suelta la retícula de cuartos
   ═══════════════════════════════════════════════════════════ */
/* La composición del Acto I reparte las diapositivas sobre una retícula de
   cuartos de viewport. Por debajo de ~1180px un cuarto deja columnas de texto
   de unos 165px, ilegibles. Aquí se abandona esa retícula y cada diapositiva
   pasa a una sola columna ancha, conservando el escalonado izquierda/derecha
   para que no se pierda el ritmo de la secuencia. */
@media(max-width:1180px){
  .dia{
    left:0 !important;right:0;width:auto !important;max-width:none !important;
    padding-inline:var(--gutter);
  }
  .dia-titulo{max-width:15ch;}

  #dia-1 .dia-titulo{margin-left:0;}
  #dia-1 .fila-desc{gap:clamp(1rem,3vw,2.25rem);}
  #dia-1 .col-1,#dia-1 .col-2{
    position:static;left:auto;margin-left:0;
    width:auto;max-width:34ch;flex:1 1 0;
  }

  /* Las dos de en medio se recuestan a la derecha: mantienen el vaivén de la
     composición original sin depender de medidas en vw. */
  #dia-2 .dia-titulo,#dia-2 .dia-desc,
  #dia-3 .dia-titulo,#dia-3 .dia-desc{
    margin-left:auto;margin-right:0;width:auto;max-width:42ch;
  }
  #dia-3 .dia-titulo{white-space:normal;}
  #dia-4 .dia-desc{max-width:46ch;}
}

/* Entre tablet y móvil el escalonado ya no aporta: todo a la izquierda. */
@media(max-width:900px){
  #dia-2 .dia-titulo,#dia-2 .dia-desc,
  #dia-3 .dia-titulo,#dia-3 .dia-desc{margin-left:0;}
  #dia-1 .fila-desc{flex-direction:column;}
  #dia-1 .col-1,#dia-1 .col-2{max-width:52ch;}
}

/* ═══════════════════════════════════════════════════════════
   MÓVIL
   ═══════════════════════════════════════════════════════════ */
@media(max-width:860px){
  #acto-uno{height:220vh;}
  .nav-cabecera{display:none;}
  .reticula,.reticula-horizontal{display:none;}
  /* El cursor propio no se decide por ancho de pantalla sino por tipo de
     puntero: un portátil de 800px con ratón sí debe tenerlo, y una tableta
     táctil de 1024px no. De eso se encarga la comprobación en el JS. */
  #dia-2,#dia-3{display:none;}

  /* El tamaño del flotante ya es el mismo en todas las pantallas (56px, sobre
     el mínimo táctil de 44px), así que aquí no hace falta redefinirlo.
     Hueco bajo el pie para que el botón nunca se apoye sobre sus enlaces. */
  .pie{padding-bottom:calc(2.2rem + 68px);}
  /* El encabezado encoge, así que los anclajes no necesitan tanto respiro. */
  html{scroll-padding-top:74px;}
  .cabecera{padding:14px 0;}
  .marca-texto{font-size:20px;}
  .dia{
    position:absolute;top:50%;bottom:auto;transform:translateY(-50%);
    left:0 !important;right:0;width:auto !important;max-width:none !important;
    padding-inline:var(--gutter);
  }
  #dia-1 .fila-desc{flex-direction:column;gap:1.2rem;position:static;}
  #dia-1 .col-1,#dia-1 .col-2,#dia-1 .dia-titulo,#dia-4 .dia-titulo,#dia-4{
    margin-left:0 !important;width:auto !important;max-width:none !important;
    position:static !important;left:auto !important;
  }
  .dia-titulo{font-size:clamp(38px,10vw,58px);max-width:none;}
  .dia-desc{font-size:16px;}
  .titulo-bloque{max-width:none;}
  #acto-dos h2{max-width:none;}
  .servicio,.proyecto{padding:1.6rem 1.35rem;}
  .pregunta summary{padding-right:2rem;}
}

/* ── Teléfono angosto ───────────────────────────────────────── */
@media(max-width:480px){
  /* El botón del encabezado y la marca ya no caben juntos con holgura:
     el botón se reduce a lo indispensable. */
  .boton-contacto{padding:9px 16px;font-size:10px;gap:7px;}
  .boton-contacto .boton-punto{display:none;}
  .boton{width:100%;justify-content:center;}
  .via{flex-wrap:wrap;gap:.2rem .9rem;}
  .via span:first-child{min-width:0;flex:1 0 100%;}
  .pie__fila{flex-direction:column;align-items:flex-start;gap:.6rem;}
  .proyecto__stack,.servicio ul{font-size:.72rem;}
}

/* ── Teléfono en horizontal ─────────────────────────────────── */
/* Poca altura y mucho ancho: el título a tamaño de escritorio se come la
   pantalla y la descripción queda fuera de cuadro. */
@media(max-height:520px) and (orientation:landscape){
  #acto-uno{height:260vh;}
  .dia-titulo{font-size:clamp(30px,6.5vh,44px);margin-bottom:12px;}
  .dia-desc{font-size:14px;line-height:1.5;}
  .dia-cta{margin-top:14px;padding:10px 22px;}
  .capa-cine{padding-bottom:16px;}
  .cabecera{padding:10px 0;}
  .seccion{padding-block:clamp(3rem,8vh,5rem);}
}

/* ── Dispositivos sin puntero fino (táctiles) ───────────────── */
/* En una pantalla táctil el :hover se queda "pegado" tras tocar: el elemento
   permanece en su estado de hover hasta que tocas otra cosa. Se anulan los
   efectos de desplazamiento y se garantiza área de toque suficiente. */
@media(hover:none){
  .servicio:hover,.proyecto:hover,.boton:hover,
  .boton--principal:hover,.boton-contacto:hover,.dia-cta:hover{transform:none;}
  .cursor-nucleo,.cursor-halo{display:none;}
  .nav-enlace,.via{min-height:44px;display:flex;align-items:center;}
  .pregunta summary{min-height:44px;display:flex;align-items:center;}
  .pregunta summary::after{top:50%;transform:translateY(-50%);}
  .pregunta[open] summary::after{transform:translateY(-50%) rotate(180deg);}
}
