/* ==============================================================
   MOTION & INTERACTION
   Decoration only: transforms and opacity. Content is hidden for
   a reveal only once the script has added .js-reveal, so a failed
   script never leaves the page blank. Everything rests still for
   visitors who ask for reduced motion (end of file).
   ============================================================== */
@layer motion{
  /* ---------- entrances ---------- */
  .hero-copy > *,.hero-visual{animation:rise .6s var(--ease-out) both}
  .hero-copy > :nth-child(2){animation-delay:.05s}
  .hero-copy > :nth-child(3){animation-delay:.1s}
  .hero-copy > :nth-child(4){animation-delay:.15s}
  @keyframes rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

  /* headline: words rise into place one after another */
  .hero h1.split{animation:none}
  .w{display:inline-block;overflow:hidden;vertical-align:top;padding:0 .06em .14em;margin:0 -.06em -.14em}
  .w > span{display:inline-block;transform:translateY(110%);animation:word .9s var(--ease-out) forwards;
    animation-delay:calc(80ms + var(--i) * 40ms)}
  @keyframes word{to{transform:none}}

  /* sections reveal on scroll; siblings arrive one after another (--d) */
  .js-reveal .reveal{opacity:0;transform:translateY(8px);transition:opacity .5s var(--ease-out),transform .5s var(--ease-out);
    transition-delay:var(--d,0ms)}
  .js-reveal .reveal.in{opacity:1;transform:none}
  .js-reveal .reveal.done{transition-delay:0ms}
  .js-reveal .row.reveal.done{transition:opacity .2s ease-out,transform .5s var(--ease-out)}

  /* hovering a row quiets the others */
  @media (hover:hover) and (pointer:fine){
    .rows:hover .row,.js-reveal .rows:hover .row.done{opacity:.4}
    .rows .row:hover,.js-reveal .rows .row.done:hover{opacity:1}
  }

  .step-panel:not([hidden]) > *{animation:rise .45s var(--ease-out) both}
  .step-panel:not([hidden]) > :nth-child(2){animation-delay:.04s}
  .step-panel:not([hidden]) > :nth-child(3){animation-delay:.08s}
  .step-panel:not([hidden]) > :nth-child(4){animation-delay:.12s}

  /* ---------- living network (js/network.js) ---------- */
  .hero,.contact{--net-node:var(--ink-3);--net-agent:var(--accent)}
  .net-layer{position:absolute;inset:0;z-index:-1;pointer-events:none}
  .net-layer canvas{width:100%;height:100%}
  .hero-net{
    -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,.14) 0%,rgba(0,0,0,.22) 45%,#000 70%),linear-gradient(180deg,#000 70%,transparent);
    -webkit-mask-composite:source-in;
            mask-image:linear-gradient(90deg,rgba(0,0,0,.14) 0%,rgba(0,0,0,.22) 45%,#000 70%),linear-gradient(180deg,#000 70%,transparent);
            mask-composite:intersect}
  .band-net{opacity:.55;
    -webkit-mask-image:radial-gradient(ellipse 80% 70% at 70% 40%,#000 20%,transparent 75%);
            mask-image:radial-gradient(ellipse 80% 70% at 70% 40%,#000 20%,transparent 75%)}
  @media (max-width:899px){
    .hero-net{-webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,.2) 0%,rgba(0,0,0,.3) 40%,#000 60%,#000 80%,transparent);
                      mask-image:linear-gradient(180deg,rgba(0,0,0,.2) 0%,rgba(0,0,0,.3) 40%,#000 60%,#000 80%,transparent);
              -webkit-mask-composite:source-over;mask-composite:add}
  }

  /* ---------- portrait assembled from the network (js/portrait.js) ---------- */
  .portrait-ph{position:absolute;inset:0;display:grid;place-items:center;font-size:clamp(4rem,8vw,6rem);font-weight:var(--weight-display);
    letter-spacing:-.04em;color:var(--ink);opacity:.1}
  .portrait.has-photo .portrait-ph{display:none}
  .portrait-canvas{position:absolute;inset:0;z-index:1;width:100%;height:100%;touch-action:manipulation}
  .assemble-pill{position:absolute;z-index:2;top:var(--s-3);left:var(--s-3);display:flex;align-items:center;gap:var(--s-2);
    max-width:calc(100% - 24px);padding:6px 10px;border:1px solid var(--line-2);border-radius:999px;
    background:color-mix(in srgb,var(--surface) 80%,transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
    font-family:var(--font-mono);font-size:var(--text-2xs);line-height:1.2;color:var(--ink);font-variant-numeric:tabular-nums;
    white-space:nowrap;pointer-events:none;opacity:0;transform:translateY(-4px);
    transition:opacity .4s ease-out,transform .4s var(--ease-out)}
  .assemble-pill.on{opacity:1;transform:none}
  .assemble-pill span:last-child{overflow:hidden;text-overflow:ellipsis}
  .assemble-dot{width:6px;height:6px;flex:none;border-radius:50%;background:var(--accent);animation:blink 1.4s ease-in-out infinite}
  .assemble-pill.done .assemble-dot{animation:none}
  @keyframes blink{50%{opacity:.3}}

  /* hero depth: the portrait and its card follow the pointer (--mx, --my set by the script) */
  .hero-visual{--mx:0;--my:0;perspective:1200px}
  .portrait{transform:translate3d(calc(var(--mx) * -6px),calc(var(--my) * -6px),0) rotateY(calc(var(--mx) * 5deg)) rotateX(calc(var(--my) * -5deg))}
  .float-card{transform:translate3d(calc(var(--mx) * 18px),calc(var(--my) * 14px),0)}

  /* ---------- pointer effects ---------- */
  /* spotlight: a soft accent glow that follows the pointer */
  .spot{position:relative;isolation:isolate}
  .spot::after{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:0;
    background:radial-gradient(380px circle at var(--x,50%) var(--y,50%),var(--accent-soft),transparent 65%);
    transition:opacity var(--t-med) ease-out}
  .spot:hover::after{opacity:1}
  .spot:hover .chip{transform:translateY(-2px) rotate(-6deg);background:var(--accent);border-color:var(--accent);color:var(--on-accent)}

  /* blueprint: a fine grid that lights up around the pointer */
  .bg-grid{position:relative;isolation:isolate;--gx:50%;--gy:30%}
  .bg-grid::before{content:"";position:absolute;inset:0;z-index:-2;pointer-events:none;opacity:0;transition:opacity .4s ease-out;
    background-image:linear-gradient(var(--accent-line) 1px,transparent 1px),linear-gradient(90deg,var(--accent-line) 1px,transparent 1px);
    background-size:48px 48px;background-position:-1px -1px;
    -webkit-mask-image:radial-gradient(240px circle at var(--gx) var(--gy),rgba(0,0,0,.55),transparent 75%);
            mask-image:radial-gradient(240px circle at var(--gx) var(--gy),rgba(0,0,0,.55),transparent 75%)}
  .bg-grid.lit::before{opacity:1}

  /* ---------- approach: steps advance on their own until someone picks one ---------- */
  .step-bar{position:absolute;left:0;top:-1px;bottom:-1px;z-index:1;width:2px;background:var(--accent);
    transform:scaleY(0);transform-origin:50% 0;pointer-events:none}
  .steps.auto .step-tab[aria-selected="true"]::before{background:var(--line-2)}
  .steps.auto .step-tab[aria-selected="true"] .step-bar{animation:fillY 6.5s linear forwards}
  .steps:hover .step-bar,.steps:focus-within .step-bar,.steps.paused .step-bar{animation-play-state:paused!important}
  @keyframes fillY{to{transform:scaleY(1)}}
  @keyframes fillX{to{transform:scaleX(1)}}
  @media (max-width:899px){
    .step-bar{left:0;right:0;top:auto;bottom:-1px;width:auto;height:2px;transform:scaleX(0);transform-origin:0 50%}
    .steps.auto .step-tab[aria-selected="true"] .step-bar{animation-name:fillX}
  }

  /* approach drawing: steps cross-fade, the item in focus stands out */
  .m-step{transition:opacity .35s var(--ease-out),visibility 0s linear .35s}
  .m-step.cur{transition-delay:0s}
  .m-svg [data-k]{transition:opacity .3s var(--ease-out)}
  .checks li{transition:color var(--t-med) ease-out}
  .checks .i{transition:transform var(--t-med) var(--ease-out)}
  .checks li.on .i{transform:scale(1.2)}
  .m-trace{animation:dash9 1.2s linear infinite}
  .m-tool{animation:dash5 .8s linear infinite}
  .m-ring{animation:ring 1.8s var(--ease-io) infinite}
  .m-drill{animation:drill 2.4s var(--ease-io) infinite}
  @keyframes dash9{to{stroke-dashoffset:-9}}
  @keyframes dash5{to{stroke-dashoffset:-5}}
  @keyframes ring{50%{opacity:.3}}
  @keyframes drill{0%,20%{stroke:var(--bad)}50%,100%{stroke:var(--ok)}}

  /* ---------- reduced motion and print ---------- */
  @media (prefers-reduced-motion:reduce){
    html{scroll-behavior:auto}
    *,*::before,*::after{animation:none!important;transition-duration:.01ms!important}
    .js-reveal .reveal{opacity:1;transform:none}
    .w > span{transform:none}
    .portrait,.float-card{transform:none}
  }
  @media print{
    .nav,.form-card,.ops,.palette,.net-layer{display:none!important}
    .reveal{opacity:1!important;transform:none!important}
    .step-panel[hidden]{display:block!important}
  }
}
