/* ============================================================================
   McCLURE'S COMFORT ZONE — "DISPATCH" motion layer                  (2026-09-15)
   Canvas instruments live in dispatch.js (thermostat, dispatch). Here: headlines
   come in fast and stop hard, like a truck pulling up; a dispatch light blinks
   once on the accent phrase; content lands; the phone icon actually rings.
   ========================================================================== */

.thermostat{position:relative;width:100%;aspect-ratio:1/1;max-width:26rem;justify-self:center;border:1px solid var(--line-w);border-radius:50%;overflow:hidden;box-shadow:0 30px 60px -36px rgba(0,0,0,.9),inset 0 0 0 10px rgba(0,0,0,.2)}
.thermostat canvas{position:absolute;inset:0;width:100%;height:100%}
.dispatch__stage{position:relative;width:100%;aspect-ratio:16/10;max-width:34rem;justify-self:center;border:1px solid var(--line-w);border-radius:10px;overflow:hidden;box-shadow:0 30px 60px -36px rgba(0,0,0,.9)}
.dispatch__stage canvas{position:absolute;inset:0;width:100%;height:100%}

/* 1. fast in, hard stop */
.js .pull{opacity:0}
.js .pull.in{animation:pullup .38s cubic-bezier(.2,.9,.3,1) forwards}
@keyframes pullup{0%{opacity:0;transform:translateX(-28px)}100%{opacity:1;transform:none}}

/* 2. the dispatch light on the accent */
.js .pull .y{position:relative}   /* inline, so the light follows the last word wherever the heading wraps */
.js .pull .y::after{content:none}   /* the 'acknowledge' dot read as a stray mark beside the headline */
.js .pull.in .y::after{animation:ack .9s ease-out .35s forwards}
@keyframes ack{0%{opacity:0;box-shadow:0 0 0 0 rgba(255,140,116,.6)}30%{opacity:1}100%{opacity:1;box-shadow:0 0 0 .6em rgba(255,140,116,0)}}

/* 3. land */
.js .fx{opacity:0;transform:translateY(12px)}
.js .fx.in{animation:land .4s cubic-bezier(.2,.9,.3,1) forwards}
.js .fx.d1.in{animation-delay:.06s}.js .fx.d2.in{animation-delay:.12s}.js .fx.d3.in{animation-delay:.18s}.js .fx.d4.in{animation-delay:.24s}
@keyframes land{to{opacity:1;transform:none}}

/* 4. the phone rings */
.hd__phone svg,.callout__ic svg{transform-origin:50% 60%}
.hd__phone:hover svg,.callout:hover .callout__ic svg{animation:ring .5s ease-in-out 2}
@keyframes ring{0%,100%{transform:rotate(0)}20%{transform:rotate(-14deg)}40%{transform:rotate(12deg)}60%{transform:rotate(-8deg)}80%{transform:rotate(6deg)}}

/* 5. the pinned stage */
.dispatch.is-pinned .dispatch__pin{position:sticky;top:0;height:100vh;display:grid;align-items:center}
.dispatch.is-pinned .stage{opacity:.3;transition:opacity .35s ease,transform .35s cubic-bezier(.25,.85,.2,1);transform:translateX(-8px)}
.dispatch.is-pinned .stage.is-on{opacity:1;transform:none}
.dispatch.is-pinned .stage.is-done{opacity:.6;transform:none}
.dispatch.is-flat .stage{opacity:1}

/* 6. cards */
.job,.rev,.chapter{transition:transform .25s cubic-bezier(.2,.9,.3,1),box-shadow .25s,border-color .25s}
.job:hover,.rev:hover{border-color:var(--red)}
.btn{transition:transform .2s cubic-bezier(.2,.9,.3,1),box-shadow .2s,background .2s,color .2s}
.btn--ink:hover{}

@media (prefers-reduced-motion:reduce){
  .js .pull,.js .pull.in{opacity:1;transform:none;animation:none}
  .js .pull.in .y::after{animation:none;opacity:1}
  .js .fx,.js .fx.in{opacity:1;transform:none;animation:none}
  .hd__phone:hover svg,.callout:hover .callout__ic svg{animation:none}
  .job:hover,.rev:hover,.btn--ink:hover{transform:none}
}
