/* =============================================================================
   TectSoft — motion.css
   -----------------------------------------------------------------------------
   The pointer-reactive and scroll-reactive motion layer, kept in its own file
   so it can be dropped onto any page with one <link> and pulled back out just
   as easily if it ever fights the base design.

   Everything here animates `transform`, `opacity` or a custom property — never
   width/height/top/left — so each effect stays on the compositor and off the
   layout path. Anything driven by the pointer reads CSS variables that
   motion.js writes (--mx/--my), so JS never touches style properties that
   would force a reflow.

   Works on both grounds: dark sections get a cyan bloom, `.sec-light` gets a
   deeper tint, since a white highlight on white is nothing at all.
   ========================================================================== */

/* ── 1. Pointer spotlight ───────────────────────────────────────────────────
   A soft radial highlight that tracks the cursor across a card. --mx/--my are
   percentages written by motion.js; --spot fades the whole thing in and out so
   the highlight doesn't snap off when the pointer leaves. */
/* `isolation` pins the highlight's stacking context to the card, so the
   z-index:-1 below places it above the card's own background but beneath its
   content. The alternative — forcing position:relative onto every child —
   would silently override rules like .disc-glow{position:absolute} and
   collapse those decorations, since both selectors weigh the same and this
   file loads last. */
.spot{position:relative;isolation:isolate}
.spot::after{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  z-index:-1;opacity:var(--spot,0);transition:opacity .45s var(--ease);
  background:radial-gradient(
    380px circle at var(--mx,50%) var(--my,50%),
    color-mix(in srgb,var(--hue,var(--cyan)) 22%,transparent) 0%,
    transparent 62%);
}
.sec-light .spot::after{
  background:radial-gradient(
    380px circle at var(--mx,50%) var(--my,50%),
    color-mix(in srgb,var(--hue,var(--deep)) 13%,transparent) 0%,
    transparent 62%);
}

/* ── 2. Glare ───────────────────────────────────────────────────────────────
   Pairs with the tilt that script.js already applies: a narrow band of light
   sweeping across the card face sells the "solid pane catching a light source"
   read that tilt alone doesn't. */
.glare{overflow:hidden}
.glare::before{
  content:'';position:absolute;inset:-40%;pointer-events:none;z-index:2;
  opacity:var(--spot,0);transition:opacity .4s var(--ease);
  background:linear-gradient(
    115deg,transparent 42%,rgba(255,255,255,.10) 50%,transparent 58%);
  transform:translateX(calc((var(--mxr,0) - .5) * 60%));
}
.sec-light .glare::before{
  background:linear-gradient(
    115deg,transparent 42%,rgba(8,18,28,.045) 50%,transparent 58%);
}

/* ── 3-5. Button hover motion — removed ─────────────────────────────────────
   The magnetic pull, the shine sweep and the press-scale all used to live
   here. Buttons now change colour on hover and nothing moves. Kept as a note
   so the gap between 2 and 6 doesn't read as something lost by accident. */

/* ── 6. Scroll progress ─────────────────────────────────────────────────── */
.scroll-prog{
  position:fixed;left:0;top:0;height:2px;width:100%;z-index:500;
  transform:scaleX(var(--p,0));transform-origin:0 50%;
  background-image:var(--ramp);pointer-events:none;
  will-change:transform;
}

/* ── 7. Staggered entrance ──────────────────────────────────────────────────
   .reveal already fades a whole block in. .stagger walks its direct children
   in one after another instead, which reads as deliberate rather than as a
   single slab arriving. --si is the child's index, set by motion.js. */
.stagger > *{
  opacity:0;translate:0 22px;
  transition:opacity .6s var(--ease),translate .6s var(--ease);
  transition-delay:calc(var(--si,0) * 70ms);
}
/* Uses the standalone `translate` property, not `transform`:
   `.cmp-card-us:hover{transform:translateY(-4px)}` and `.stagger.in > *` weigh
   the same and this file loads last, so a transform here would cancel every
   card hover in a staggered grid. */
.stagger.in > *{opacity:1;translate:none}

/* ── 8. Heading word reveal ─────────────────────────────────────────────────
   Each word rides up out of its own clipping box. Words are wrapped by
   motion.js; the mask is per-word so the gradient fill on .fat is untouched. */
.word-rise .w{display:inline-block;overflow:hidden;vertical-align:bottom}
.word-rise .w > i{
  display:inline-block;font-style:inherit;
  transform:translate3d(0,105%,0);
  transition:transform .7s var(--ease);
  transition-delay:calc(var(--wi,0) * 45ms);
}
.word-rise.in .w > i{transform:none}

/* ── 9. Link underline sweep (non-nav) ──────────────────────────────────── */
.article-body a:not(.btn),.form-note a,.cta-note a{
  position:relative;background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1px;background-repeat:no-repeat;background-position:0 100%;
  transition:background-size .35s var(--ease);
}
.article-body a:not(.btn):hover,.form-note a:hover,.cta-note a:hover{background-size:100% 1px}

/* ── 10. Form field lift ────────────────────────────────────────────────── */
.form-row{transition:transform .3s var(--ease)}
.form-row:focus-within{transform:translateY(-2px)}
.form-row label{transition:color .25s}
.form-row:focus-within label{color:#066675}

/* ── Reduced motion ─────────────────────────────────────────────────────────
   Every effect above is decorative, so under a reduced-motion preference they
   are switched off outright rather than merely shortened — and the elements
   they animate are restored to their resting, visible state. */
@media (prefers-reduced-motion:reduce){
  .spot::after,.scroll-prog{display:none}
  .stagger > *{opacity:1;translate:none;transition:none}
  .word-rise .w > i{transform:none;transition:none}
}
