/* =====================================================================
   ZV CONSULTING — sections.css
   nav · hero · choreography · services · voices · process · contact · footer · wa
   ===================================================================== */

/* ============================ NAV ============================ */
.nav {
  position: fixed;
  top: clamp(0.7rem, 2vw, 1.4rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  width: min(1180px, calc(100% - 2 * clamp(0.9rem, 4vw, 2rem)));
}
.nav__pill {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 0.7rem 0.7rem 1.15rem;
  border-radius: 100px;
  /* Solidifies on scroll via --nav-solid. NO backdrop-filter: a fixed bar that
     blurs everything scrolling behind it recomputes that blur every frame — pure
     jank on mobile. A slightly-opaque background reads clean over the dark page. */
  background: rgba(16, 12, 8, calc(0.32 + 0.55 * var(--nav-solid)));
  border: 1px solid rgba(233, 205, 155, calc(0.05 + 0.16 * var(--nav-solid)));
  box-shadow: 0 18px 40px -24px rgba(0, 0, 0, calc(0.2 + 0.6 * var(--nav-solid)));
  transition: padding 0.5s var(--ease-out);
}
.nav.is-scrolled .nav__pill { padding-top: 0.5rem; padding-bottom: 0.5rem; }

.nav__brand { display: inline-flex; align-items: center; gap: 0.55rem; }
.nav__logo { width: 34px; height: 34px; object-fit: contain;
  filter: brightness(0) invert(1) drop-shadow(0 0 8px rgba(217,169,78,0.3)); }
.nav__brand-text {
  font-family: var(--font-display); font-size: 1.05rem; letter-spacing: 0.02em;
  color: var(--cream);
}
.nav__links { display: flex; align-items: center; gap: 0.35rem; }
.nav__link {
  padding: 0.55rem 0.95rem; border-radius: 100px;
  font-size: var(--step--1); font-weight: 500; letter-spacing: 0.01em;
  color: var(--cream-soft);
  transition: color 0.3s var(--ease-out), background 0.3s var(--ease-out);
}
.nav__link:hover { color: var(--cream); background: rgba(244,236,220,0.06); }
.nav__link--cta {
  background: linear-gradient(135deg, var(--gold-lit), var(--gold) 60%, var(--gold-deep));
  color: #241706; font-weight: 600;
  box-shadow: 0 8px 20px -10px rgba(217,169,78,0.6);
}
.nav__link--cta:hover { background: linear-gradient(135deg, var(--gold-lit), var(--gold)); color:#241706; }

.nav__burger {
  display: none;
  width: 44px; height: 44px; border-radius: 100px;
  border: 1px solid var(--line-strong);
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.nav__burger span {
  width: 18px; height: 1.5px; background: var(--cream); border-radius: 2px;
  transition: transform 0.4s var(--ease-out), opacity 0.3s;
}
.nav__burger.is-open span:nth-child(1) { transform: translateY(3.25px) rotate(45deg); }
.nav__burger.is-open span:nth-child(2) { transform: translateY(-3.25px) rotate(-45deg); }

/* Fullscreen mobile menu */
.mobile-menu {
  position: fixed; inset: 0; z-index: 90;
  background: linear-gradient(160deg, #120d09, var(--noir) 70%);
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 var(--pad-x);
  opacity: 0; visibility: hidden;
  clip-path: circle(0% at calc(100% - 40px) 40px);
  transition: clip-path 0.7s var(--ease-out), opacity 0.4s ease, visibility 0.4s;
}
.mobile-menu.is-open { opacity: 1; visibility: visible; clip-path: circle(150% at calc(100% - 40px) 40px); }
.mobile-menu__nav { display: flex; flex-direction: column; gap: 0.2rem; }
.mobile-menu__link {
  font-family: var(--font-display); font-size: clamp(2.4rem, 12vw, 4rem);
  line-height: 1.15; color: var(--cream); overflow: hidden;
}
.mobile-menu__link span {
  display: inline-block; transform: translateY(110%);
  transition: transform 0.6s var(--ease-out);
}
.mobile-menu.is-open .mobile-menu__link span { transform: translateY(0); }
.mobile-menu__link:active { color: var(--gold-lit); }
.mobile-menu__foot {
  margin-top: 3rem; display: flex; flex-direction: column; gap: 0.35rem;
  color: var(--cream-mute); font-size: var(--step--1); letter-spacing: 0.04em;
  opacity: 0; transition: opacity 0.5s ease 0.4s;
}
.mobile-menu.is-open .mobile-menu__foot { opacity: 1; }

/* ================= ACT: one pinned scroll sequence (hero + pain) =================
   Driven by JS scroll vars on .act__sticky:
     --hero-out  hero copy fades/lifts        --ignite   monogram lights
     --warm      background warms up           --text-y   pain title vertical (vh)
     --wipe      pain title left→right reveal   --mono-rise logo rises + shrinks
   ================================================================================ */
.act { position: relative; height: 480vh; background: #000; }  /* resolves to PURE black */
.act__sticky {
  position: sticky; top: 0;
  /* lvh (LARGE viewport = mobile bar collapsed), NOT dvh/svh:
     · dvh tracks the LIVE viewport, so when the URL bar hides and the viewport
       grows, the stage grew too and the bottom-anchored ZV jerked downward.
     · svh (small) was shorter than the screen once the bar hid → black gap.
     lvh sizes the stage to the bar-HIDDEN height from the start: with the bar
     visible the scene simply extends under it (bar overlays), and collapsing the
     bar just REVEALS the lower part of the ZV/plane — no reflow, no jump. */
  height: 100vh; height: 100lvh;
  overflow: hidden; isolation: isolate;
}

/* --- background that warms as you scroll; the WHOLE warm layer fades out with
       --dim so the act resolves to the pure-black .act behind it --- */
.act__bg { position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(125% 90% at 50% 122%, #150e08 0%, #0a0806 48%);
  opacity: calc(1 - var(--dim, 0)); will-change: opacity; }
.act__bg::before {   /* warm pool behind the logo, grows with --warm */
  content: ""; position: absolute; left: 50%; bottom: -16%; transform: translateX(-50%);
  width: 100vw; height: 92vh;
  background: radial-gradient(50% 50% at 50% 50%,
              rgba(217,169,78,0.34), rgba(198,122,46,0.14) 38%, transparent 70%);
  /* no blur filter: the radial gradient is already soft, and a 52px blur on a
     full-viewport layer is expensive to raster/composite on weak GPUs */
  opacity: calc(0.12 + 0.88 * var(--warm, 0));
  will-change: opacity;
}
.act__bg::after {    /* overall warm lift from black */
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(150% 105% at 50% 104%, rgba(120,68,24,0.30), transparent 62%);
  opacity: var(--warm, 0);
}
/* subtle warm light seeping in from the edges/corners — present from the
   very start (even with the ZV dark) and intensifying as --warm grows. */
.act__corners {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  /* fixed gradient alphas; the warm intensification is driven by OPACITY (a
     compositor-only property) instead of recomputing the gradient every frame */
  background:
    radial-gradient(38% 48% at 0% 100%,   rgba(198,122,46,0.34), transparent 62%),
    radial-gradient(40% 50% at 100% 100%, rgba(217,169,78,0.30), transparent 62%),
    radial-gradient(34% 42% at 100% 0%,   rgba(198,122,46,0.21), transparent 60%),
    radial-gradient(32% 40% at 0% 0%,     rgba(150,86,30,0.19),  transparent 60%);
  opacity: calc((0.28 + 0.72 * var(--warm, 0)) * (1 - var(--dim, 0)));
  will-change: opacity;
}
/* faint warm glows in the UPPER field (incl. behind the hero title) — present
   from the very start, gently intensifying with --warm and drifting with scroll
   so the top of the hero isn't dead-dark. */
.act__aura {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  /* fixed gradient alphas; warm intensification via OPACITY (no per-frame repaint
     of this big blurred full-viewport layer) */
  background:
    radial-gradient(46% 40% at 50% 27%, rgba(217,169,78,0.18), transparent 62%),
    radial-gradient(38% 34% at 17% 33%, rgba(198,122,46,0.14), transparent 60%),
    radial-gradient(40% 34% at 84% 30%, rgba(217,169,78,0.12), transparent 60%);
  opacity: calc((0.28 + 0.72 * var(--warm, 0)) * (1 - var(--dim, 0)));
  transform: translateY(calc(var(--aura-y, 0) * 1px));
  will-change: transform, opacity;
}

/* --- pain title: LOWER layer, seen through the ZV's negative space --- */
.act__paintext {
  position: absolute; inset: 0; z-index: 1;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 0 7vw;
  transform: translateY(calc(var(--text-y, 82) * 1vh));
  opacity: var(--paint-op, 1);
  /* blur is a fixed radius toggled by a CLASS (not a per-frame value), so it
     rasterises once and just transitions — no per-frame re-raster. The LONG
     duration makes focus→blur gradual/organic rather than a quick snap. */
  transition: filter 1s var(--ease-io);
  will-change: transform, opacity;
}
/* while the pain chips stream over the title, soft-blur it so the chips read */
.act__paintext.is-behind-pills { filter: blur(2.6px); }
.act__paintext span {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(2.3rem, 6.2vw, 5.4rem); line-height: 1.04; letter-spacing: -0.02em;
  color: var(--cream); max-width: 15ch;
  /* left→right reveal driven by --wipe (0 → 1): a wide soft edge sweeps
     across so each part fades in progressively rather than popping. */
  -webkit-mask: linear-gradient(90deg, #000 calc(var(--wipe,0) * 150% - 40%),
                rgba(0,0,0,0) calc(var(--wipe,0) * 150%));
  mask: linear-gradient(90deg, #000 calc(var(--wipe,0) * 150% - 40%),
                rgba(0,0,0,0) calc(var(--wipe,0) * 150%));
}

/* --- the ZV ignite: a scroll-scrubbed image sequence on one <canvas> ---
   Replaces the old multi-layer CSS 3D monogram (extrude/rims/glow/sheen/masks),
   whose per-frame blending of several full-screen ZV-masked layers was the
   structural fill-rate wall on phones. The gold render already carries all the
   3D/lighting, so here we just draw one frame per scroll position. */
.act__seq {
  position: absolute; left: 50%; bottom: 0; z-index: 2;
  /* square + alpha, framed exactly like the original ZV_logo.png → identical
     size/scale/travel as the old CSS monogram (peek 44% → rise to -4%, shrink 40%). */
  width: min(106vh, 134vw); aspect-ratio: 1 / 1;
  transform: translate(-50%, calc(44% - var(--mono-rise, 0) * 48%))
             scale(calc(1 - 0.4 * var(--mono-rise, 0)));
  opacity: 1;
  /* transparent frames → the logo composites directly over the warm bg lights,
     and the pain title shows through the ZV's gaps. No blend / mask / 3D layers. */
  pointer-events: none; will-change: transform, opacity;
}

/* --- hero copy: TOP layer, scrolls straight up with the page (no fade) --- */
.act__hero {
  position: absolute; left: 50%; top: 23%; z-index: 3;
  width: min(1000px, 92vw);
  transform: translate(-50%, calc(var(--hero-y, 0) * 1px));
  display: flex; flex-direction: column; align-items: center; gap: 1.5rem; text-align: center;
  will-change: transform;
}
.act__hero.is-hidden { pointer-events: none; }

.hero__title {
  font-size: var(--step-5);
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--cream);
  text-align: center;
}
/* The whole "Más + word" scales as ONE unit to a FIXED total width, so "Más"
   and the word are always the SAME size; the block's HEIGHT varies per word
   (a shorter word → scaled up → taller). --fit-w is the fixed layout width and
   .hero__scale is scaled by --fit-scale to fill it exactly. */
.hero__fit {
  display: block;
  width: var(--fit-w, auto);
  margin: 0 auto;
  white-space: nowrap;
  /* the fixed-width box is centred on the page (margin:auto); anchor the scaled
     block to its LEFT edge so "Más" always starts at the same x and only the
     right side (the word) grows/shrinks — every combo ends up centred. */
  text-align: left;
}
.hero__scale {
  display: inline-flex;
  align-items: baseline;
  transform-origin: left center;
  transform: scale(var(--fit-scale, 1));
  transition: transform 0.6s var(--ease-io);
  will-change: transform;
}
.hero__scale.is-instant { transition: none; }
.hero__mas { font-family: var(--font-display); }
/* the word "window" (mask): its width animates to the current word while the
   list rolls up like a mechanical counter, clipped by the window rails */
.ticker {
  display: inline-block;
  overflow: hidden;
  height: 1.05em;
  width: var(--mask-w, 6ch);
  vertical-align: baseline;
  transition: width 0.6s var(--ease-io);
}
.ticker.is-instant { transition: none; }
.ticker__list {
  transform: translateY(var(--list-y, 0));
  transition: transform 0.6s var(--ease-io);
}
.ticker__list.is-instant { transition: none; }
.ticker__list li {
  width: max-content;      /* shrink to the word so we can measure its true width */
  height: 1.05em;
  line-height: 1.05;
  font-style: italic;
  color: var(--gold);
  white-space: nowrap;
}

.hero__subtitle {
  font-size: var(--step-1); font-weight: 300;
  color: var(--cream-soft); max-width: 40ch; line-height: 1.5;
}
.hero__actions { display: flex; align-items: center; gap: 1.6rem; flex-wrap: wrap; justify-content: center; margin-top: 0.6rem; }
.hero__link {
  position: relative; font-size: var(--step-0); font-weight: 500; color: var(--cream-soft);
  padding-bottom: 3px;
  transition: color 0.3s var(--ease-out);
}
.hero__link::after {
  content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
  background: var(--gold); transform: scaleX(0.35); transform-origin: left;
  transition: transform 0.4s var(--ease-out);
}
.hero__link:hover { color: var(--gold-lit); }
.hero__link:hover::after { transform: scaleX(1); }

.act__cue {
  position: absolute; bottom: 1.6rem; left: 50%; z-index: 5;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
  font-size: 0.72rem; letter-spacing: 0.28em; text-transform: uppercase; color: var(--cream-mute);
  opacity: calc(1 - var(--cue-op, 0)); pointer-events: none;
}
.act__cue i {
  width: 1px; height: 34px;
  background: linear-gradient(var(--gold), transparent);
  animation: cueDrop 2s var(--ease-io) infinite;
  transform-origin: top;
}
@keyframes cueDrop { 0%{transform:scaleY(0);opacity:0} 40%{opacity:1} 100%{transform:scaleY(1);opacity:0} }

/* --- pain pills: a scattered stream that rises with scroll (driven per
       pill by JS: --py vh, --op opacity, --bl blur). --- */
.act__pains { position: absolute; inset: 0; z-index: 4; pointer-events: none; list-style: none; }
/* smoothly-animatable hover scale that composes with the per-frame transform */
@property --pain-scale { syntax: "<number>"; inherits: false; initial-value: 1; }
.pain {
  position: absolute; top: 50%; left: 50%;
  display: flex; align-items: center; gap: 1rem;
  width: min(27rem, 78vw); padding: 1.1rem 1.6rem;
  border-radius: 999px;                 /* fully rounded */
  /* Translucent panel that reads as glass over the dark ACT — WITHOUT
     backdrop-filter. Five glass pills each blurring the (also-animating)
     backdrop every frame was the single biggest source of scroll lag on
     phones/weak GPUs. A layered translucent gradient fakes the same depth. */
  background: linear-gradient(158deg, rgba(60, 44, 27, 0.66), rgba(24, 17, 10, 0.70));
  border: 1px solid var(--line-strong);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.10), 0 34px 60px -34px rgba(0,0,0,0.95);
  font-size: var(--step-0); font-weight: 400; color: var(--cream);
  /* centred column with a small alternating left/right deviation (--dx), plus a
     hover scale (--pain-scale) that eases via @property while the rAF keeps
     updating --py/--dx every frame */
  transform: translate(calc(-50% + var(--dx, 0)), calc(var(--py, 60) * 1vh))
             scale(var(--pain-scale, 1));
  opacity: var(--op, 0);
  pointer-events: auto;                  /* so the chips react to the cursor */
  transition: --pain-scale 0.4s var(--ease-out), border-color 0.4s var(--ease-out),
              background 0.4s var(--ease-out), box-shadow 0.4s var(--ease-out);
  will-change: transform, opacity;
}
@media (hover: hover) {
  .pain:hover {
    --pain-scale: 1.06;
    border-color: var(--gold);
    background: rgba(46, 33, 18, 0.5);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.16),
                0 26px 60px -30px rgba(0,0,0,0.95),
                0 0 34px -6px rgba(217,169,78,0.4);
  }
  .pain:hover .pain__ico { color: var(--gold-lit); }
}
.act__pains .pain:nth-child(1) { --dx: -6vw; }
.act__pains .pain:nth-child(2) { --dx:  6vw; }
.act__pains .pain:nth-child(3) { --dx: -4vw; }
.act__pains .pain:nth-child(4) { --dx:  5vw; }
.act__pains .pain:nth-child(5) { --dx: -5vw; }
/* thin-stroke line icon per pain point (in gold), replacing the number */
.pain__ico {
  flex: none;
  width: 1.55em; height: 1.55em;
  color: var(--gold);
  stroke: currentColor; fill: none;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  padding-right: 1rem; border-right: 1px solid var(--line-strong);
  box-sizing: content-box;
  transition: color 0.4s var(--ease-out);
}

/* --- solution: a LOOSE composition (no glass pill) that passes in FRONT of
       the ZV. Title, subtitle and button are positioned independently by JS
       (--sol-y in vh, --sol-op) so they can rise at different speeds and then
       converge during the handoff. --- */
.solution { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.solution__title, .solution__body {
  position: absolute; top: 0; left: 50%;
  width: min(64rem, 94vw);
  transform: translate(-50%, calc(var(--sol-y, 60) * 1vh));
  opacity: var(--sol-op, 0);
  text-align: center;
  will-change: transform, opacity;
}
/* same size + typography as the pain title "Tu negocio pierde dinero cada
   día por…" (.act__paintext span) so the two big statements feel like a pair */
.solution__title {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(2.3rem, 6.2vw, 5.4rem); line-height: 1.04; letter-spacing: -0.02em;
  color: #ffffff;
  /* lifted off the busy gold ZV behind it with a soft parallel drop shadow */
  text-shadow: 0 2px 26px rgba(0,0,0,0.9), 0 8px 18px rgba(0,0,0,0.55),
               0 1px 2px rgba(0,0,0,0.8);
  /* left→right reveal (same as the pain title), driven by --sol-wipe 0 → 1 */
  -webkit-mask: linear-gradient(90deg, #000 calc(var(--sol-wipe,1) * 150% - 40%),
                rgba(0,0,0,0) calc(var(--sol-wipe,1) * 150%));
  mask: linear-gradient(90deg, #000 calc(var(--sol-wipe,1) * 150% - 40%),
                rgba(0,0,0,0) calc(var(--sol-wipe,1) * 150%));
}
.solution__body { display: flex; flex-direction: column; align-items: center; gap: 1.3rem; }
.solution__sub {
  font-size: var(--step-1); font-weight: 300; color: var(--cream);
  max-width: 46ch; line-height: 1.5;
  text-shadow: 0 2px 18px rgba(0,0,0,0.85), 0 1px 2px rgba(0,0,0,0.7);
  /* the subtitle wipes in just after the title (inherits --sol-wipe from body) */
  -webkit-mask: linear-gradient(90deg, #000 calc(var(--sol-wipe,1) * 150% - 40%),
                rgba(0,0,0,0) calc(var(--sol-wipe,1) * 150%));
  mask: linear-gradient(90deg, #000 calc(var(--sol-wipe,1) * 150% - 40%),
                rgba(0,0,0,0) calc(var(--sol-wipe,1) * 150%));
}
.solution__btn { pointer-events: auto; }

@media (prefers-reduced-motion: reduce) {
  .pain { opacity: 1; --py: 0; }
}

/* ============================ SERVICES ============================
   The "Nuestros servicios" title pins under the nav for the whole section
   (position: sticky). Service texts scroll up and dissolve behind a soft
   black-gradient + blur banner attached to that title. Edge-fitted videos
   (3D renders on black) play scrubbed by scroll from a fixed layer. */
.services {
  position: relative; z-index: 5;
  /* transparent over the overlap (top 80vh) so the act's dimming ZV shows
     through the handoff, then PURE black for the rest of the section */
  background: linear-gradient(to bottom, transparent 0, transparent 80vh, #000 80vh, #000 100%);
  /* overlap the tail of the act: the first service is already rising and
     playing while the solution fuses into the "Nuestros servicios" title and
     the ZV / background fade to black. No separate curtain. */
  margin-top: -80vh;
  padding: 0 0 clamp(1.5rem, 3vh, 3rem);   /* trimmed: less black before the process */
}

/* --- fitted video layer: pinned to the viewport, videos anchored to edges.
       Videos are 3D renders on pure black, so they blend into the page. --- */
.services__videos { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
.svc-vid { position: absolute; display: none; object-fit: cover; }
/* 01 — full-height on the left edge */
.svc-vid--fill  { left: 0; top: 0; height: 100vh; width: auto; }
/* 02 / 04 — right-bottom corner */
.svc-vid--right { right: 0; bottom: 0; width: 35vw; max-width: 550px; height: auto; border-radius: 16px 0 0 0; }
/* 03 — left-bottom corner */
.svc-vid--left  { left: 0;  bottom: 0; width: 35vw; max-width: 550px; height: auto; border-radius: 0 16px 0 0; }
@media (min-width: 1600px) { .svc-vid--right, .svc-vid--left { width: 50vw; max-width: 850px; } }

/* --- pinned title + its dissolve banner ---
   Fixed at the dock so it appears at the EXACT spot the conclusion pill docks
   (a true crossfade/morph), then stays put while the section scrolls behind it.
   Opacity is a product: --svc-title-in (act.js, morph fade-in) × --svc-title-out
   (services.js, fade-out at the end of the section). */
.services__titlebar {
  position: fixed; top: clamp(78px, 11vh, 122px); left: 0; right: 0; z-index: 40;
  display: flex; justify-content: center;
  pointer-events: none;
  opacity: calc(var(--svc-title-in, 0) * var(--svc-title-out, 1));
  will-change: opacity;
}
.services__title {
  font-size: var(--step-4); text-align: center; line-height: 1.05;
  text-shadow: 0 8px 30px rgba(0,0,0,0.75);
  /* rides up from the bubble's height to the dock during the morph, then rests */
  transform: translateY(calc(var(--svc-title-y, 0) * 1vh));
  will-change: transform;
}
/* black-gradient + backdrop-blur band behind the title: rising text fades to
   black and softens as it passes into this zone before vanishing under the title */
.services__mask {
  position: absolute; top: -13vh; left: 50%; transform: translateX(-50%);
  width: 150vw; height: 36vh; z-index: -1; pointer-events: none;
  /* solid gradient only — a backdrop-filter here re-blurs the service text
     scrolling behind it on every frame. The opaque gradient hides it just as well. */
  background: linear-gradient(to bottom,
              rgba(10,8,6,0.97) 0%, rgba(10,8,6,0.86) 46%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 100%);
}

/* --- scrolling text column (spacing copied from the prototype) --- */
.services__text {
  position: relative; z-index: 2;
  max-width: 1200px; margin-inline: auto; padding-inline: 25px;
  /* dead zone: the title finishes docking before the first block rises */
  padding-top: 22vh;
}
.svc {
  margin-bottom: 60vh;     /* big gap so each video gets a full scroll to scrub */
  max-width: 45%;
}
/* the last block needs less trailing room (no more video to scrub after it),
   so we cut its gap to remove the dead black space before "La fórmula del éxito" */
.svc:last-child { margin-bottom: 30vh; }
.svc--right { margin-left: auto;  text-align: left; padding-right: 8vw; }  /* text right, video 01/03 left */
.svc--left  { margin-right: auto; text-align: left; padding-left: 8vw;  }  /* text left,  video 02/04 right */
.svc__index {
  font-family: var(--font-display); font-size: var(--step-2); color: var(--gold);
  display: block; margin-bottom: 0.4rem; opacity: 0.9;
}
.svc__title { font-size: clamp(2.6rem, 5vw, 5.2rem); line-height: 1.05; margin-bottom: 1.3rem; }
.svc__desc { color: var(--cream-soft); font-size: clamp(1.05rem, 1.5vw, 1.7rem); font-weight: 300; line-height: 1.5; }

/* ============================ VOICES (testimonials) ============================ */
.voices { padding: clamp(5rem, 12vh, 9rem) 0; overflow: hidden; }
.voices__head { max-width: var(--maxw); margin: 0 auto clamp(2.5rem,6vh,4rem); padding-inline: var(--pad-x); }
.voices__heading { font-size: var(--step-4); }

.voices__track-wrap {
  -webkit-mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.voices__track { display: flex; gap: 1.4rem; width: max-content; will-change: transform; }
.vcard {
  width: min(80vw, 380px);
  flex: none;
  padding: 1.8rem;
  border-radius: var(--radius);
  background: linear-gradient(165deg, rgba(33,24,18,0.9), rgba(16,11,8,0.9));
  border: 1px solid var(--line);
  box-shadow: 0 30px 60px -40px rgba(0,0,0,0.9), inset 0 1px 0 rgba(255,255,255,0.04);
  display: flex; flex-direction: column; gap: 1.1rem;
  transition: border-color 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}
.vcard:hover { border-color: var(--line-strong); transform: translateY(-4px); }
.vcard__head { display: flex; align-items: center; gap: 0.9rem; }
.vcard__avatar {
  width: 48px; height: 48px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  font-family: var(--font-display); font-size: 1.25rem; color: #241706;
  background: linear-gradient(135deg, var(--gold-lit), var(--gold-deep));
  box-shadow: 0 8px 18px -8px rgba(217,169,78,0.6);
}
.vcard__name { font-weight: 600; font-size: var(--step-0); }
.vcard__role { font-size: var(--step--1); color: var(--cream-mute); }
.vcard__stars { color: var(--gold); letter-spacing: 0.15em; font-size: 0.95rem; }
.vcard__text { color: var(--cream-soft); font-size: var(--step-0); line-height: 1.55; font-weight: 300; }

/* ============================ PROCESS ============================ */
/* position + z-index above the services' fixed video overlay so, now that the
   section is tighter, the (opaque) process paints OVER any video still on screen */
.process {
  position: relative; z-index: 6;
  padding: clamp(3rem, 6vh, 5rem) 0 clamp(5rem, 12vh, 9rem);
  background: var(--noir-2);
}
.process__head { max-width: var(--maxw); margin: 0 auto clamp(3rem,7vh,5rem); padding-inline: var(--pad-x); max-width: 720px; text-align: center; }
.process__heading { font-size: var(--step-4); margin: 0 0 1.2rem; }
.process__lead { color: var(--cream-soft); font-weight: 300; font-size: var(--step-1); }

.steps {
  max-width: var(--maxw); margin-inline: auto; padding-inline: var(--pad-x);
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.4rem;
}
/* Staged reveal (driven by .steps.is-in, set by process.js when the grid enters
   view): (1) the thin lines DRAW across the top like a schema branching out,
   (2) the numbers DROP in one-two-three-four in cascade, (3) each title + desc
   rises in just behind its number. --si (0..3) is the per-step index. */
.step {
  position: relative; padding: 2rem 1.6rem;
  border-top: none;                 /* the rule is now the animated ::before line */
}
/* the schema line, drawn left→right along the top of each column */
.step::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--line-strong);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 0.7s var(--ease-out);
  transition-delay: calc(0.1s + var(--si, 0) * 0.13s);
}
.steps.is-in .step::before { transform: scaleX(1); }

.step__num {
  font-family: var(--font-display); font-size: clamp(3rem, 6vw, 5rem);
  line-height: 1; color: transparent;
  -webkit-text-stroke: 1px var(--gold);
  display: block; margin-bottom: 1rem;
  opacity: 0; transform: translateY(-26px);
  transition: color 0.5s var(--ease-out), opacity 0.5s var(--ease-out),
              transform 0.7s cubic-bezier(0.34, 1.5, 0.64, 1);   /* drop with a soft bounce */
  transition-delay: calc(0.5s + var(--si, 0) * 0.16s);
}
.steps.is-in .step__num { opacity: 1; transform: none; }
.step:hover .step__num { color: var(--gold); }

.step__body {
  opacity: 0; transform: translateY(16px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  transition-delay: calc(0.72s + var(--si, 0) * 0.16s);
}
.steps.is-in .step__body { opacity: 1; transform: none; }

.step__title { font-size: var(--step-1); margin-bottom: 0.7rem; }
.step__desc { color: var(--cream-mute); font-size: var(--step-0); font-weight: 300; line-height: 1.5; }
@media (prefers-reduced-motion: reduce) {
  .step::before { transform: scaleX(1); transition: none; }
  .step__num, .step__body { opacity: 1; transform: none; transition: none; }
}

/* Closing statement where the client logos used to be — a centred phrase that
   "writes itself" left→right as it scrolls into view (same mask language as the
   solution title). --closer-wipe is driven 0→1 by process.js. */
.process__closer {
  max-width: 820px;             /* ~2 lines on desktop (more on phones) */
  margin: clamp(3.5rem, 8vh, 6rem) auto 0;
  padding-inline: 1.25rem;      /* small gutter only — the big --pad-x forced 3 lines */
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.15rem, 0.85rem + 1.15vw, 1.7rem);
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--cream);
  text-shadow: 0 10px 40px rgba(0,0,0,0.6);
  -webkit-mask: linear-gradient(90deg, #000 calc(var(--closer-wipe, 1) * 130% - 30%),
                rgba(0,0,0,0) calc(var(--closer-wipe, 1) * 130%));
  mask: linear-gradient(90deg, #000 calc(var(--closer-wipe, 1) * 130% - 30%),
                rgba(0,0,0,0) calc(var(--closer-wipe, 1) * 130%));
}
@media (prefers-reduced-motion: reduce) {
  .process__closer { -webkit-mask: none; mask: none; }
}

/* ============================ CONTACT ============================ */
.contact { position: relative; overflow: hidden; padding: clamp(5rem,12vh,9rem) 0; }
.contact__parallax {
  position: absolute; inset: -20% 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(60% 50% at 18% 20%, rgba(198,122,46,0.28), transparent 60%),
    radial-gradient(55% 45% at 85% 80%, rgba(217,169,78,0.20), transparent 60%);
  will-change: transform;
}
/* black→glow blend at the top edge: starts as solid noir (matching the process
   section above, so no hard horizontal cut) and fades out to reveal the warm
   radial lights. Sits above the parallax, below the content. No layout impact. */
.contact__fade {
  position: absolute; top: 0; left: 0; right: 0;
  height: clamp(130px, 24vh, 300px);
  z-index: 0; pointer-events: none;
  background: linear-gradient(to bottom,
              var(--noir-2) 0%, rgba(14, 11, 8, 0.65) 42%, transparent 100%);
}
.contact__inner {
  position: relative; z-index: 1;
  max-width: var(--maxw); margin-inline: auto; padding-inline: var(--pad-x);
}
/* "¿Te ayudamos?" heads the whole section */
.contact__head { text-align: center; max-width: 48ch; margin: 0 auto clamp(2.5rem, 6vh, 4rem); }
.contact__heading { font-size: var(--step-4); margin: 0 0 1.1rem; white-space: nowrap; }
.contact__lead { color: var(--cream-soft); font-weight: 300; font-size: var(--step-1); margin-inline: auto; }

/* two symmetric columns of equal height under the shared heading */
.contact__cols {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 3rem);
  align-items: stretch;
}
.contact__col {
  display: flex; flex-direction: column; gap: 1.1rem;
  /* opaque gradient instead of a translucent card + backdrop-filter (which
     re-blurs the page behind these large cards as they scroll past) */
  background: linear-gradient(165deg, rgba(37,27,19,0.96), rgba(15,10,7,0.97));
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: clamp(1.6rem, 3vw, 2.6rem);
  box-shadow: 0 40px 80px -50px rgba(0,0,0,0.95), inset 0 1px 0 rgba(255,255,255,0.05);
}
.contact__col-eyebrow { font-family: var(--font-display); font-size: var(--step-2); line-height: 1.1; }

.contact__details { margin: 0.4rem 0; display: flex; flex-direction: column; gap: 1.1rem; }
.contact__details li { display: flex; flex-direction: column; gap: 0.15rem; }
.contact__det-label { font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold); }
.contact__details a { color: var(--cream); font-size: var(--step-0); transition: color 0.3s; }
.contact__details a:hover { color: var(--gold-lit); }
.contact__map {
  border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line-strong);
  flex: 1 1 auto; min-height: 220px;     /* grows to match the form column's height */
  box-shadow: 0 30px 60px -40px rgba(0,0,0,0.9);
}
.contact__map iframe { width: 100%; height: 100%; border: 0; filter: grayscale(0.4) contrast(1.05) brightness(0.85); }

/* the form is just a styled column now (shares .contact__col) */
.field { display: flex; flex-direction: column; gap: 0.5rem; }
.field--grow { flex: 1 1 auto; }
.field--grow textarea { flex: 1 1 auto; min-height: 120px; }
.field__label { font-size: 0.75rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--cream-mute); }
.field input, .field textarea {
  background: rgba(10,8,6,0.6); border: 1px solid var(--line-strong);
  border-radius: 14px; padding: 0.85rem 1rem; color: var(--cream);
  font-size: var(--step-0); resize: vertical;
  transition: border-color 0.3s var(--ease-out), box-shadow 0.3s var(--ease-out);
}
.field input::placeholder, .field textarea::placeholder { color: var(--cream-faint); }
.field input:focus, .field textarea:focus {
  outline: none; border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(217,169,78,0.14);
}
.contact__form-note { font-size: var(--step--1); color: var(--gold-lit); min-height: 1.2em; }

/* ============================ FOOTER ============================ */
.footer {
  border-top: 1px solid var(--line);
  padding: clamp(2.5rem,6vh,4rem) var(--pad-x);
  max-width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  flex-wrap: wrap;
}
.footer__brand { display: flex; align-items: center; gap: 0.6rem; font-family: var(--font-display); font-size: 1.1rem; }
.footer__brand img { width: 30px; height: 30px; filter: brightness(0) invert(1) opacity(0.85); }
.footer__nav { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.footer__nav a { font-size: var(--step--1); color: var(--cream-mute); transition: color 0.3s; }
.footer__nav a:hover { color: var(--gold); }
.footer__legal { font-size: var(--step--1); color: var(--cream-faint); }

/* ============================ WHATSAPP FLOAT ============================ */
.wa {
  position: fixed; right: clamp(1rem, 3vw, 2rem); bottom: clamp(1rem, 3vw, 2rem);
  z-index: 80; display: flex; align-items: center; gap: 0.7rem;
  opacity: 0; transform: translateY(20px) scale(0.85); pointer-events: none;
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
}
.wa.is-visible { opacity: 1; transform: none; pointer-events: auto; }
.wa__bubble {
  max-width: 0; overflow: hidden; white-space: nowrap;
  padding: 0; opacity: 0;
  background: var(--cream); color: #1c140b;
  border-radius: 100px; font-size: var(--step--1); font-weight: 500;
  box-shadow: 0 14px 30px -14px rgba(0,0,0,0.6);
  transition: max-width 0.6s var(--ease-out), padding 0.6s var(--ease-out), opacity 0.4s ease;
}
.wa.is-open .wa__bubble { max-width: 260px; padding: 0.7rem 1.1rem; opacity: 1; }
.wa__btn {
  width: 60px; height: 60px; border-radius: 50%; flex: none;
  display: grid; place-items: center; color: var(--gold-lit);
  /* gold film + rim. No backdrop-filter: this button is FIXED and visible for the
     whole page, so a backdrop blur would re-blur everything scrolling behind it on
     every frame. A slightly more opaque gold gradient keeps the look. */
  background: linear-gradient(135deg, rgba(88,60,24,0.92), rgba(52,36,16,0.92));
  border: 1px solid rgba(217,169,78,0.55);
  box-shadow: 0 16px 34px -12px rgba(217,169,78,0.45), inset 0 1px 0 rgba(255,255,255,0.35);
}
.wa.is-bouncing .wa__btn { animation: waBounce 1.4s var(--ease-io) infinite; }
@keyframes waBounce { 0%,100%{transform:translateY(0)} 30%{transform:translateY(-8px)} 50%{transform:translateY(0)} 65%{transform:translateY(-4px)} 80%{transform:translateY(0)} }
@media (prefers-reduced-motion: reduce) { .wa.is-bouncing .wa__btn { animation: none; } }
