/* ============================================================
   Tercero Analytics — landing
   hero.css · loads AFTER styles.css.
   PART 1 — the rich PARTICLE WAVE hero (3D projected mesh).
   PART 2 — the "See what we build" object that opens into two paths.
   ============================================================ */

/* ============================================================
   PART 1 — PARTICLE WAVE HERO
   - DARK throughout (deep charcoal, no white base this time).
   - The CANVAS (#heroField) paints a dense field of particles laid
     out on a 3D grid whose surface undulates like a travelling wave
     (several sine layers over a perspective-projected mesh). Depth
     + height drive size and brightness: white in the body, CYAN on
     the crests / near peaks, luminous and dense. Painter back-to-front.
   - Headline is REAL DOM TEXT, white on the dark, sitting in the
     upper third clear of the wave's busiest band.
   - A solid cyan/blue luminous cursor dot lerp-follows the pointer
     and gently disturbs the wave near it. Fine-pointer only.
   Layer order: dark bg (.hero-wave) -> canvas wave (z2) -> .wrap text (z3).
   ============================================================ */

.hero-wave{
  background:
    radial-gradient(130% 80% at 50% 4%, rgba(0,184,148,.12), transparent 60%),
    linear-gradient(180deg,
      var(--deep)   0%,
      var(--deep)   30%,
      var(--deep-2) 64%,
      #0b151d       100%);
  color:var(--snow);
  text-align:center;
  align-items:flex-start;
  border-bottom:1px solid rgba(0,184,148,.22);
}
/* neutralise the dark styles.css .hero::after veil; keep a faint teal lift up top */
.hero-wave::after{
  background:
    radial-gradient(120% 56% at 50% 4%, rgba(0,184,148,.10), transparent 62%) !important;
}

#heroField{position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none;}

/* over the hero, hide the OS arrow — JS draws a solid cyan dot instead.
   pointer-fine + JS only; touch / no-pointer keeps the native cursor. */
.js .hero-wave.cursor-hidden{cursor:none;}
.js .hero-wave.cursor-hidden a,
.js .hero-wave.cursor-hidden .btn{cursor:none;}

/* --- hero layout — headline in the DARK upper third -------------- */
.hero-wave .wrap{
  position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;
  padding-top:clamp(7rem,18vh,12rem);padding-bottom:0;
}
/* the glowing logo mark — central dot + connections to 3 outer dots */
.hero-brand{display:inline-flex;margin-bottom:1.8rem;}
.hero-brand::before,.hero-brand::after{content:none;}
.hero-mark{width:clamp(64px,8vw,100px);height:auto;overflow:visible;
  transform-origin:50% 50%;will-change:transform,filter;
  animation:hmBreath 2.8s var(--e-out) infinite alternate;}
.hero-mark .hm-legs path{stroke:rgba(0,184,148,.7);stroke-width:5;stroke-linecap:round;fill:none;}
.hero-mark .hm-outer circle{fill:#3ff0cf;}
.hero-mark .hm-core{fill:#d6fff4;}
.hero-mark .hm-outer circle,.hero-mark .hm-core{animation:hmPulse 2.6s var(--e-out) infinite alternate;}
.hero-mark .hm-outer circle:nth-child(2){animation-delay:.3s;}
.hero-mark .hm-outer circle:nth-child(3){animation-delay:.6s;}
@keyframes hmPulse{from{opacity:.62;}to{opacity:1;}}
/* the whole mark visibly breathes: scale + glow swell together */
@keyframes hmBreath{
  from{transform:scale(.94);filter:drop-shadow(0 0 6px rgba(0,184,148,.45));}
  to  {transform:scale(1.05);filter:drop-shadow(0 0 18px rgba(0,184,148,.9));}
}
@media (prefers-reduced-motion:reduce){
  .hero-mark{animation:none;filter:drop-shadow(0 0 9px rgba(0,184,148,.6));}
  .hero-mark .hm-outer circle,.hero-mark .hm-core{animation:none;}
}

/* gentle scroll-snap on the landing: scrolling out of the hero pulls the
   next section into place so it is obvious there is more to do. Proximity
   (not mandatory) so it never traps the scroll. (hero.css loads on home only.) */
@media (min-width:821px) and (prefers-reduced-motion:no-preference){
  html{scroll-snap-type:y proximity;scroll-padding-top:72px;}
  .hero,#choose,.contact{scroll-snap-align:start;}
}

/* --- the headline: REAL DOM TEXT, white on the dark -------------- */
.hero-headline{
  font-family:var(--exp);font-weight:900;letter-spacing:-.03em;line-height:1.04;
  font-size:clamp(2.3rem,1.4rem + 4.6vw,4.6rem);color:var(--snow);
  margin:0;position:relative;width:100%;max-width:20ch;
  text-shadow:0 1px 30px rgba(8,16,22,.55);
}
.hl-stage{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:.12em;}
.hl-fixed{display:block;color:#fff;}

/* the rotor reserves a fixed line for the changing word; words stack
   inside and the live one rises into place. */
.hl-rotor{
  position:relative;display:block;
  height:1.18em;width:100%;overflow:hidden;
}
.hl-word{
  position:absolute;left:0;right:0;top:0;
  display:block;line-height:1.18;
  color:#3ff0cf;                       /* bright cyan, echoes the crests */
  opacity:0;transform:translateY(.62em);
  filter:blur(2px);
  transition:opacity .5s var(--e-out),transform .62s var(--e-out),filter .5s var(--e-out);
  will-change:transform,opacity;
}
.hl-word.is-on{ opacity:1;transform:translateY(0);filter:blur(0); }
.hl-word.is-out{
  opacity:0;transform:translateY(-.5em);filter:blur(2px);
  transition:opacity .42s var(--e-out),transform .5s var(--e-out),filter .42s var(--e-out);
}

/* (scrollcue removed — readers just scroll) */

/* "Signal from Noise" — hidden in the open space, revealed under the cursor.
   Sits in the lower band below the headline; hero.js drives a radial mask
   centred on the cursor so only the slice under the aura lights up. */
.hero-signal{position:absolute;left:0;right:0;bottom:10%;z-index:2;display:flex;justify-content:center;pointer-events:none;}
.hero-signal-text{
  font-family:var(--exp);font-weight:800;letter-spacing:.05em;white-space:nowrap;text-transform:uppercase;
  font-size:clamp(1.8rem,1rem + 3.2vw,3.6rem);line-height:1;color:#cfeee6;
  /* invisible at rest (no persistent block). A flicker hints it is there;
     the cursor's radial mask (set inline by JS) reveals it cleanly. */
  opacity:0;
  animation:signalFlicker 3s ease-in-out infinite;
}
/* the "signal trying to break through the noise" flicker — more frequent,
   a touch more visible so people notice it. */
@keyframes signalFlicker{
  0%,68%,100%{opacity:0;}
  74%{opacity:.10;} 78%{opacity:.32;} 82%{opacity:.08;} 88%{opacity:.24;} 93%{opacity:.05;}
}
/* cursor reveal wins: full opacity + glow, mask applied to container by JS */
.hero-signal-text.is-reveal{opacity:1;animation:none;text-shadow:0 0 20px rgba(0,184,148,.7),0 0 6px rgba(63,240,207,.55);}
/* burst particles sweeping through: flash in sync with the particle wave */
.hero-signal-text.is-signal-hit{opacity:.85!important;animation:none!important;text-shadow:0 0 28px rgba(0,184,148,1),0 0 60px rgba(0,184,148,.5),0 0 6px rgba(63,240,207,.9);transition:opacity .05s,text-shadow .05s;}
/* touch / reduced-motion: show it faintly-but-readable, no flicker */
.hero-wave.touch .hero-signal-text{opacity:.45;animation:none;}

/* --- DEGRADATION ------------------------------------------------ */
/* reduced-motion: static dark hero, legible first word, native cursor, no wave. */
@media (prefers-reduced-motion:reduce){
  .hero-wave.cursor-hidden,
  .hero-wave.cursor-hidden a,
  .hero-wave.cursor-hidden .btn{cursor:auto;}
  .hl-rotor{height:auto;overflow:visible;}
  .hl-word{position:static;opacity:0;transform:none;filter:none;display:none;}
  .hl-word.is-on{opacity:1;display:block;}
}
/* JS bailed (no canvas / reduced) -> show first word plainly */
.no-particles .hl-word{position:static;display:none;opacity:0;}
.no-particles .hl-word.is-on{display:block;opacity:1;transform:none;filter:none;}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}

/* ============================================================
   PART 2 — TWO WORLDS DIPTYCH
   Two full-height, edge-to-edge panels, always visible, each a real
   <a>. LEFT is the DARK world (real estate / institutional), RIGHT is
   the LIGHT world (SMEs / clean). The light-vs-dark contrast IS the
   design: one charcoal-deep with cyan circuitry, one paper-white with
   ink type and a quiet teal flow. Pure-CSS hover, keyboard accessible,
   reduced-motion safe. No state machine, nothing to click open.
   ============================================================ */
.choose{
  position:relative;
  border-top:1px solid var(--rule-d);
  border-bottom:1px solid var(--rule-d);
}
/* the two-up grid; a hairline cyan seam divides the worlds */
.diptych{
  position:relative;
  display:grid;grid-template-columns:1fr 1fr;
  min-height:clamp(580px,80vh,900px);
  isolation:isolate;
}
/* the dividing seam between the worlds */
.diptych::after{
  content:"";position:absolute;top:0;bottom:0;left:50%;width:1px;
  transform:translateX(-.5px);z-index:3;pointer-events:none;
  background:linear-gradient(180deg,transparent,rgba(0,184,148,.55),transparent);
}

/* ---- a panel (shared) ------------------------------------------ */
.panel{
  position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(2rem,4.5vw,4rem) clamp(1.8rem,4vw,3.4rem) clamp(2.4rem,5vw,4rem);
  text-decoration:none;overflow:hidden;isolation:isolate;
  transition:flex-grow .6s var(--e-out);
  will-change:transform;
}
.panel:focus-visible{outline:none;}
.panel:focus-visible::before{
  content:"";position:absolute;inset:10px;z-index:5;pointer-events:none;
  border:2px solid var(--teal);box-shadow:0 0 0 1px rgba(0,184,148,.4);
}

/* the line-art layer (circuit/flow), painted behind the veil */
.panel-art{position:absolute;inset:0;z-index:0;pointer-events:none;
  transition:opacity .55s var(--e-out),transform .9s var(--e-out);}
.panel-art svg{position:absolute;inset:0;width:100%;height:100%;}
.panel-art .ln{fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset 1.1s var(--e-out);}
.panel-art .nds circle{opacity:0;transition:opacity .4s var(--e-out) .35s;}

.panel-veil{position:absolute;inset:0;z-index:1;pointer-events:none;
  transition:opacity .55s var(--e-out);}

.panel-inner{position:relative;z-index:2;max-width:30ch;}
.panel-label{font-family:var(--mono);font-size:.74rem;letter-spacing:.24em;
  text-transform:uppercase;display:block;}
.panel-h{font-family:var(--exp);font-weight:800;letter-spacing:-.025em;line-height:1.07;
  display:block;font-size:clamp(1.7rem,1.1rem + 2vw,2.7rem);margin:.85rem 0 .7rem;max-width:16ch;}
.panel-h em{font-style:normal;}
.panel-sub{display:block;font-size:clamp(.95rem,.92rem + .2vw,1.06rem);line-height:1.55;
  max-width:34ch;margin-bottom:1.3rem;}
.panel-cta{display:inline-flex;align-items:center;gap:.55em;font-weight:600;font-size:1.02rem;}
.panel-cta .arw{transition:transform .35s var(--e-out);}

/* ============================================================
   DARK WORLD — real estate (institutional charcoal + cyan)
   ============================================================ */
.panel-dark{
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(0,184,148,.14), transparent 60%),
    linear-gradient(160deg,#13242f 0%,var(--deep) 56%,#0a1218 100%);
  color:var(--snow);
}
.panel-dark .panel-art{opacity:.55;}
.panel-dark .panel-art .gr line{stroke:rgba(0,184,148,.10);stroke-width:1;}
.panel-dark .panel-art .ln{stroke:#3ff0cf;filter:drop-shadow(0 0 6px rgba(0,184,148,.55));}
.panel-dark .panel-art .nds circle{fill:#3ff0cf;filter:drop-shadow(0 0 5px rgba(0,184,148,.7));}
.panel-dark .panel-veil{
  background:linear-gradient(180deg,rgba(8,14,20,.10) 30%,rgba(8,14,20,.74) 100%);
}
.panel-dark .panel-label{color:var(--teal);}
.panel-dark .panel-h{color:var(--snow);}
.panel-dark .panel-h em{background:linear-gradient(100deg,#3ff0cf,var(--teal));
  -webkit-background-clip:text;background-clip:text;color:transparent;}
.panel-dark .panel-sub{color:var(--snow-soft);}
.panel-dark .panel-cta{color:var(--teal);}

/* ============================================================
   LIGHT WORLD — SMEs (clean paper + ink + quiet teal)
   ============================================================ */
.panel-light{
  background:
    radial-gradient(120% 90% at 82% 0%, rgba(0,134,106,.10), transparent 58%),
    linear-gradient(160deg,var(--cloud) 0%,var(--paper) 60%,#e9f1f3 100%);
  color:var(--ink);
}
.panel-light .panel-art{opacity:.7;}
.panel-light .panel-art .gr line{stroke:rgba(14,26,36,.07);stroke-width:1;}
.panel-light .panel-art .ln{stroke:var(--teal-deep);filter:none;opacity:.6;}
.panel-light .panel-art .nds circle{fill:var(--teal-deep);}
.panel-light .panel-veil{
  background:linear-gradient(180deg,rgba(247,250,251,.04) 30%,rgba(233,241,243,.62) 100%);
}
.panel-light .panel-label{color:var(--teal-deep);}
.panel-light .panel-h{color:var(--ink);}
.panel-light .panel-h em{color:var(--teal-deep);}
.panel-light .panel-sub{color:var(--ink-soft);}
.panel-light .panel-cta{color:var(--teal-deep);}

/* ---- entrance: draw the line + light the nodes once in view ---- */
.diptych.is-in .panel-art .ln{stroke-dashoffset:0;}
.diptych.is-in .panel-art .nds circle{opacity:1;}
.diptych.is-in .panel-dark .panel-art .ln{transition-delay:.15s;}
.diptych.is-in .panel-light .panel-art .ln{transition-delay:.3s;}

/* ---- HOVER / FOCUS — each world energises in its own register --- */
@media (hover:hover) and (prefers-reduced-motion:no-preference){
  /* the hovered panel grows a touch, the other yields */
  .diptych:hover .panel{flex-grow:.92;}
  .diptych .panel:hover{flex-grow:1.16;}
}
.panel:hover .panel-art,.panel:focus-visible .panel-art{transform:scale(1.04);}
.panel:hover .panel-veil,.panel:focus-visible .panel-veil{opacity:.78;}
.panel:hover .panel-cta .arw,.panel:focus-visible .panel-cta .arw{transform:translateX(7px);}

/* dark world: cyan glow swells, art brightens */
.panel-dark:hover,.panel-dark:focus-visible{
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(0,184,148,.22), transparent 62%),
    linear-gradient(160deg,#16303d 0%,var(--deep) 54%,#0a1218 100%);
}
.panel-dark:hover .panel-art,.panel-dark:focus-visible .panel-art{opacity:.95;}
.panel-dark:hover .panel-h,.panel-dark:focus-visible .panel-h{text-shadow:0 0 28px rgba(63,240,207,.4);}

/* light world: paper lifts, teal warms */
.panel-light:hover,.panel-light:focus-visible{
  background:
    radial-gradient(120% 90% at 82% 0%, rgba(0,134,106,.18), transparent 60%),
    linear-gradient(160deg,#ffffff 0%,var(--cloud) 58%,#e3eef0 100%);
}
.panel-light:hover .panel-art,.panel-light:focus-visible .panel-art{opacity:1;}
.panel-light:hover .panel-art .ln,.panel-light:focus-visible .panel-art .ln{opacity:.9;}

/* ---- responsive: stack the two worlds top/bottom --------------- */
@media (max-width:760px){
  .diptych{grid-template-columns:1fr;min-height:0;}
  .diptych::after{top:50%;bottom:auto;left:0;right:0;width:auto;height:1px;
    transform:translateY(-.5px);
    background:linear-gradient(90deg,transparent,rgba(0,184,148,.55),transparent);}
  .panel{min-height:clamp(360px,52vh,440px);}
  /* no flex-grow reflow when stacked */
  .diptych:hover .panel,.diptych .panel:hover{flex-grow:0;}
}

/* ============================================================
   HOVER ANIMATIONS — traveling dot + line re-trace + node pulse
   ============================================================ */

/* --- traveling data dot (shared base) --- */
.panel-art .ln-travel{
  fill:none;
  stroke-dasharray:0.06 0.94;
  stroke-dashoffset:1;
  stroke-width:4;
  stroke-linecap:round;
  opacity:0;
  transition:opacity .4s var(--e-out);
}
.panel-dark .panel-art .ln-travel{
  stroke:#3ff0cf;
  filter:drop-shadow(0 0 8px rgba(0,184,148,.9));
}
.panel-light .panel-art .ln-travel{
  stroke:var(--teal-deep);
  filter:drop-shadow(0 0 5px rgba(0,125,99,.65));
}

/* --- keyframes --- */
@keyframes dotTravel{
  from{stroke-dashoffset:1;}
  to  {stroke-dashoffset:0;}
}
@keyframes lineTrace{
  from{stroke-dashoffset:1;}
  to  {stroke-dashoffset:0;}
}
@keyframes nodePulse{
  from{opacity:.65;transform:scale(1);}
  to  {opacity:1;  transform:scale(1.5);}
}

/* --- on hover: activate everything --- */
@media (hover:hover) and (prefers-reduced-motion:no-preference){
  /* traveling dot appears and loops */
  .panel:hover .panel-art .ln-travel,
  .panel:focus-visible .panel-art .ln-travel{
    opacity:1;
    animation:dotTravel 2.2s linear infinite;
  }

  /* re-trace the main line continuously on hover */
  .panel:hover .panel-art .ln,
  .panel:focus-visible .panel-art .ln{
    animation:lineTrace 2.8s var(--e-out) infinite alternate;
  }

  /* node circles pulse */
  .panel:hover .panel-art .nds circle,
  .panel:focus-visible .panel-art .nds circle{
    transform-origin:center;
    animation:nodePulse 1.6s ease-in-out infinite alternate;
  }

  /* dark panel: grid lines warm up on hover */
  .panel-dark:hover .panel-art .gr line,
  .panel-dark:focus-visible .panel-art .gr line{
    stroke:rgba(0,184,148,.22);
    transition:stroke .6s;
  }

  /* dark panel node pulse gets a glow */
  .panel-dark:hover .panel-art .nds circle,
  .panel-dark:focus-visible .panel-art .nds circle{
    filter:drop-shadow(0 0 7px rgba(0,184,148,.8));
  }
}

/* ---- reduced-motion: no line-draw, no reflow, art shown static -- */
@media (prefers-reduced-motion:reduce){
  .panel,.panel-art,.panel-art .ln,.panel-art .nds circle,
  .panel-veil,.panel-cta .arw{transition:none !important;}
  .panel-art .ln{stroke-dashoffset:0;}
  .panel-art .nds circle{opacity:1;}
  .diptych:hover .panel,.diptych .panel:hover{flex-grow:0;}
}
/* JS-off / not-yet-observed: still show the art (progressive enhancement) */
html:not(.js) .panel-art .ln{stroke-dashoffset:0;}
html:not(.js) .panel-art .nds circle{opacity:1;}
