/* V3 subtle motion (John, Oct 2026). Opacity and transform only (no layout shift); no looping or attention-grabbing motion.
   Existing palette and existing button shapes/radii only. Everything is static under prefers-reduced-motion: reduce. */
@media (prefers-reduced-motion:no-preference){
  /* scroll reveal: items are hidden only after js/motion.js has marked them (below the fold) and set .rv-on */
  .rv-on .rv{opacity:0;transform:translate3d(0,14px,0);transition:opacity .5s cubic-bezier(.2,.7,.2,1) var(--rv-delay,0ms),transform .5s cubic-bezier(.2,.7,.2,1) var(--rv-delay,0ms)}
  .rv-on .rv.is-in{opacity:1;transform:none}

  /* page load: hero text (homepage) and the page head band (inner pages) fade and rise once. Pure CSS, ends visible. */
  @keyframes v3-rise{from{opacity:0;transform:translate3d(0,12px,0)}to{opacity:1;transform:none}}
  .js .hv2-hero__text > *,.js .v3-head .wrap > *{animation:v3-rise .6s cubic-bezier(.2,.7,.2,1) both}
  .js .hv2-hero__text > :nth-child(2),.js .v3-head .wrap > :nth-child(2){animation-delay:80ms}
  .js .hv2-hero__text > :nth-child(3){animation-delay:160ms}
  .js .hv2-hero__text > :nth-child(4){animation-delay:240ms}

  /* hover and focus: smooth colour, shadow and a slight lift; shapes and radii untouched */
  .home-v2 a{transition:color .2s ease-out,text-decoration-color .2s ease-out}
  .btn,.home-v2 .hv2-btn,.home-v2 .hv2-btn--outline{transition:background-color .2s ease-out,color .2s ease-out,border-color .2s ease-out,box-shadow .2s ease-out,transform .2s ease-out}
  .home-v2 .hv2-btn--outline:hover,.home-v2 .hv2-btn--outline:focus-visible{transform:translateY(-1px)}
  .home-v2 .hv2-arrow{transition:background-color .2s ease-out,color .2s ease-out,border-color .2s ease-out,box-shadow .2s ease-out}
  .home-v2 .hv2-arrow:hover:not(:disabled){box-shadow:var(--shadow-soft)}
  .home-v2 .site-header{transition:border-color .25s ease-out,box-shadow .25s ease-out}
  .home-v2 .hv2-case,.home-v2 .hv2-faq details,.v3-inner .service-list > li{transition:transform .2s ease-out,box-shadow .2s ease-out,border-color .2s ease-out}
  .home-v2 .hv2-faq summary::after{transition:transform .2s ease-out}
}
@media (prefers-reduced-motion:no-preference) and (hover:hover){
  .home-v2 .hv2-case:hover,.home-v2 .hv2-faq details:hover{transform:translateY(-2px);box-shadow:var(--shadow-lift)}
  .v3-inner .service-list > li:hover{transform:translateY(-2px)}
}
/* keyboard focus on a case card lifts it too (focus ring stays as before) */
@media (prefers-reduced-motion:no-preference){
  .home-v2 .hv2-case:focus-visible{transform:translateY(-2px);box-shadow:var(--shadow-lift)}
}
@media (prefers-reduced-motion:reduce){
  .rv,.rv-on .rv{opacity:1!important;transform:none!important}
  .js .hv2-hero__text > *,.js .v3-head .wrap > *{animation:none!important}
  .js .hv2-cheetah,.hv2-cta__cheetah,.js .hv2-speed,.js .hv2-speed i{animation:none!important;opacity:1}
  .js .hv2-speed i{opacity:0}
}
/* How it works connectors draw in after their step has revealed (only when the step was marked for reveal). */
@media (prefers-reduced-motion:no-preference){
  .rv-on .hv2-steps li.rv::after{transform:scaleX(0);transition:transform .6s cubic-bezier(.2,.7,.2,1) calc(var(--rv-delay,0ms) + 250ms)}
  .rv-on .hv2-steps li.rv.is-in::after{transform:none}
}
@media (prefers-reduced-motion:no-preference) and (max-width:760px){
  .rv-on .hv2-steps li.rv::after{transform:scaleY(0)}
  .rv-on .hv2-steps li.rv.is-in::after{transform:none}
}
/* Cheetah slide-in (John, Oct 2026): the hero cheetah (homepage) and the closing-CTA cheetah (every page) share
   these rules. js/motion.js waits until the image is loaded and decoded, then sets on the band (.hv2-hero or .hv2-cta)
   --dash-x (start just beyond the band's edge, so it enters from off-screen and is clipped by the band), --ch-dir
   (1 = from the right, -1 = from the left), --dash-dur, and adds .ch-run. The speed lines layer runs the same translate,
   so it travels with the cheetah and trails behind it, fading in once on screen and out as it settles.
   --ch-flip keeps the CTA cheetah's existing mirror (scaleX(-1)) through and after the move.
   Safety: the hero cheetah is held at opacity 0 only inside no-preference + html.js, and a CSS failsafe reveals it
   after 2.5s even if motion.js never runs. The CTA cheetah is only hidden by the script itself (.ch-wait).
   .ch-static = image slow or decode failed: a quick fade, no slide. */
@media (prefers-reduced-motion:no-preference){
  @keyframes v3-ch-show{from{opacity:0}to{opacity:1}}
  @keyframes v3-ch-slide{
    0%{transform:translate3d(var(--dash-x,60vw),0,0) skewX(calc(var(--dash-skew,8deg) * var(--ch-dir,1))) var(--ch-flip,scaleX(1));filter:blur(var(--dash-blur,3px))}
    55%{filter:blur(calc(var(--dash-blur,3px) * .4))}
    82%{transform:translate3d(calc(-6px * var(--ch-dir,1)),0,0) skewX(calc(-1.5deg * var(--ch-dir,1))) var(--ch-flip,scaleX(1));filter:blur(0)}
    100%{transform:var(--ch-flip,scaleX(1));filter:none}}
  @keyframes v3-ch-lines-move{from{transform:translate3d(var(--dash-x,60vw),0,0)}82%{transform:translate3d(calc(-6px * var(--ch-dir,1)),0,0)}to{transform:none}}
  @keyframes v3-ch-lines{0%{opacity:0;transform:scaleX(.6)}15%{opacity:1;transform:scaleX(1)}55%{opacity:.85}85%,100%{opacity:0;transform:scaleX(.4)}}
  .js .hv2-cheetah{opacity:0;animation:v3-ch-show .3s ease-out 2.5s forwards}
  .ch-wait .hv2-cta__cheetah{opacity:0}
  .js .ch-run .hv2-cheetah,.js .ch-run .hv2-cta__cheetah{opacity:1;transform-origin:50% 100%;animation:v3-ch-slide var(--dash-dur,1s) cubic-bezier(.33,1,.68,1) both}
  .js .ch-run .hv2-speed{animation:v3-ch-lines-move var(--dash-dur,1s) cubic-bezier(.33,1,.68,1) both}
  .js .ch-run .hv2-speed i{animation:v3-ch-lines var(--dash-dur,1s) linear both}
  .js .ch-run .hv2-speed i:nth-child(2){animation-delay:40ms}
  .js .ch-run .hv2-speed i:nth-child(3){animation-delay:80ms}
  .js .ch-run .hv2-speed i:nth-child(4){animation-delay:120ms}
  .js .ch-static .hv2-cheetah,.js .ch-static .hv2-cta__cheetah{opacity:1;animation:v3-ch-show .25s ease-out both}
}
.hv2-cta__cheetah{--ch-flip:scaleX(-1)}
@media (prefers-reduced-motion:no-preference) and (max-width:760px){
  .hv2-cheetah,.hv2-cta__cheetah{--dash-skew:5deg;--dash-blur:2px}
}
@media print{.hv2-cheetah,.hv2-cta__cheetah{opacity:1!important;animation:none!important}}

/* V3 mobile menu (John, 21 Oct 2026): the panel unrolls from under the header (clip-path + a 6px drop + fade,
   280ms open with cubic-bezier(.2,.8,.2,1)), the links fade and rise in with a 35ms stagger, the burger morphs into
   an X, and a light dim covers the page. Closing reverses in 200ms (no stagger). Opacity, transform and clip-path
   only: no height animation, no layout shift. Reduced motion: instant, nothing moves. */
@media (prefers-reduced-motion:no-preference) and (max-width:960px){
  .js .nav{transition:clip-path .2s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1),visibility 0s linear .2s}
  .js .nav.open{transition:clip-path .28s cubic-bezier(.2,.8,.2,1),opacity .2s cubic-bezier(.2,.8,.2,1),transform .28s cubic-bezier(.2,.8,.2,1),visibility 0s}
  @keyframes v3-menu-item{from{opacity:0;transform:translate3d(0,8px,0)}to{opacity:1;transform:none}}
  .js .nav.open>ul>li{animation:v3-menu-item .28s cubic-bezier(.2,.8,.2,1) both}
  .js .nav.open>ul>li:nth-child(2){animation-delay:35ms}
  .js .nav.open>ul>li:nth-child(3){animation-delay:70ms}
  .js .nav.open>ul>li:nth-child(4){animation-delay:105ms}
  .js .nav.open>ul>li:nth-child(5){animation-delay:140ms}
  .nav-burger i{transition:transform .25s cubic-bezier(.2,.8,.2,1),opacity .2s ease-out}
  .js .nav-backdrop{transition:opacity .2s cubic-bezier(.4,0,.2,1),visibility 0s linear .2s}
  .js .nav-backdrop.is-on{transition:opacity .28s cubic-bezier(.2,.8,.2,1),visibility 0s}
}
/* Reduced motion: styles.css already sets *{transition:none!important}, so the menu, burger and dim switch instantly;
   nothing clips, drops or staggers. */
@media (prefers-reduced-motion:reduce) and (max-width:960px){
  .js .nav,.js .nav.open{clip-path:none;transform:none}
}

/* Hero "Apply online" pulse (John, 21 Oct 2026), homepage hero button only. A soft ring in the button's own green
   (#017752 at low alpha) radiates out and fades, drawn with box-shadow on a pseudo-element, so the button's shape,
   radius, size, colours and text are untouched and nothing affects layout or scroll width. It starts after the hero
   text has risen in (about 0.85s), runs twice (2.4s each, with a rest), then stops, which keeps it calm and inside the
   5 second limit of WCAG 2.2.2. Hover or focus removes it so the normal hover state takes over. Reduced motion: none. */
@media (prefers-reduced-motion:no-preference){
  @keyframes v3-apply-pulse{
    0%{box-shadow:0 0 0 0 rgba(1,119,82,.9)}
    35%{box-shadow:0 0 0 9px rgba(1,119,82,.45)}
    65%,100%{box-shadow:0 0 0 16px rgba(1,119,82,0)}}
  .js .hv2-hero .hv2-actions > .btn.hv2-btn{position:relative}
  .js .hv2-hero .hv2-actions > .btn.hv2-btn::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
    animation:v3-apply-pulse 2.4s cubic-bezier(.2,.8,.2,1) 1.2s 2 both}
  .js .hv2-hero .hv2-actions > .btn.hv2-btn:hover::after,.js .hv2-hero .hv2-actions > .btn.hv2-btn:focus-visible::after{animation:none;box-shadow:none}
}
/* V4 case studies (John, 21 Oct 2026). Tab switch: the new story's content fades and rises 8px, the flow steps
   staggered and their sky line drawing in (only after a user switch, never on load). Accordion rows ease open
   and the chevron turns. Opacity and transform only, apart from the accordion's user-initiated height ease. */
@keyframes v4-story{from{opacity:0;transform:translate3d(0,8px,0)}to{opacity:1;transform:none}}
@keyframes v4-line-y{from{transform:scaleY(0)}to{transform:none}}
@media (prefers-reduced-motion:no-preference){
  .home-v2 .hv2-stories__tab{transition:background-color .2s ease-out,color .2s ease-out}
  .home-v2 .hv2-stories__tab::before{transition:transform .25s cubic-bezier(.2,.7,.2,1)}
  .home-v2 .hv2-stories__tab .hv2-story__ico{transition:background-color .2s ease-out,color .2s ease-out}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__in > *,
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__h{animation:v4-story .4s cubic-bezier(.2,.7,.2,1) both}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__fig{animation-delay:50ms}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__flow{animation:none}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__flow li{animation:v4-story .4s cubic-bezier(.2,.7,.2,1) both}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__flow li:nth-child(1){animation-delay:100ms}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__flow li:nth-child(2){animation-delay:160ms}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__flow li:nth-child(3){animation-delay:220ms}
  .home-v2 .is-tabs .hv2-story.is-swap .hv2-story__flow li:not(:last-child)::after{animation:v4-line-y .5s cubic-bezier(.2,.7,.2,1) 250ms both}
  .home-v2 .hv2-story__chev{transition:transform .25s cubic-bezier(.2,.7,.2,1)}
  .home-v2 .is-acc .hv2-story__body{transition:grid-template-rows .35s cubic-bezier(.2,.7,.2,1),visibility 0s linear 0s}
  .home-v2 .is-acc .hv2-story:not(.is-open) .hv2-story__body{transition:grid-template-rows .35s cubic-bezier(.2,.7,.2,1),visibility 0s linear .35s}
  .home-v2 .is-acc.no-anim .hv2-story__body,.home-v2 .is-acc .no-anim .hv2-story__body{transition:none!important}
}
