/* =========================================================
   BuildZenvix — navbar + scroll-scrubbed hero
   Palette is locked to three values: white, black, logo blue.
   The page is authored STATIC-FIRST: with JavaScript off, or
   with the frames unavailable, the hero renders as a composed
   still with the headline already settled. The scrub is added
   on top of that, never assumed.
   ========================================================= */

/* ---------- tokens ---------- */
:root{
  --paper:#ffffff;
  --ink:#0b0b0c;
  --blue:#0653fb;              /* sampled from the supplied logo */

  --line:rgba(11,11,12,.12);
  --line-soft:rgba(11,11,12,.07);
  --muted:rgba(11,11,12,.70);

  --font-display:"Space Grotesk","Segoe UI",system-ui,sans-serif;
  --font-body:"Manrope","Segoe UI",system-ui,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,"Cascadia Mono",Consolas,monospace;

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-soft:cubic-bezier(.33,.02,.15,1);

  --nav-h:72px;
  --hero-scroll:500vh;         /* scroll distance AFTER the sticky viewport */
  --gutter:clamp(20px,4.6vw,64px);
}

@media (max-width:900px){ :root{ --nav-h:64px; --hero-scroll:420vh } }

/* ---------- reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html,body{
  margin:0;padding:0;
  overflow-x:hidden;          /* fallback first */
  overflow-x:clip;
}
/* No smooth scroll: programmatic and anchor jumps must not fight the scrub. */
html{-webkit-text-size-adjust:100%}

body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

img{max-width:100%;display:block}
button{font:inherit;color:inherit}

.u-sr{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

.skip{
  position:fixed;top:10px;left:10px;z-index:120;
  transform:translateY(-160%);
  background:var(--blue);color:var(--paper);
  padding:12px 18px;border-radius:10px;
  font-family:var(--font-mono);font-size:13px;letter-spacing:.02em;
  text-decoration:none;
  transition:transform .28s var(--ease);
}
.skip:focus-visible{transform:translateY(0)}

:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--blue);
  outline-offset:3px;
  border-radius:6px;
}

/* ---------- buttons ---------- */
.btn{
  --btn-bg:var(--blue);
  display:inline-flex;align-items:center;justify-content:center;
  gap:.5em;
  background:var(--btn-bg);
  color:var(--paper);
  border:0;border-radius:999px;
  font-family:var(--font-display);
  font-weight:600;
  letter-spacing:-.005em;
  text-decoration:none;
  cursor:pointer;
  padding:12px 22px;
  font-size:15px;
  white-space:nowrap;      /* a wrapped label breaks the bar's height */
  transition:background .34s var(--ease),transform .34s var(--ease),box-shadow .34s var(--ease);
  will-change:transform;
}
.btn:hover{ --btn-bg:var(--ink); transform:translateY(-2px); box-shadow:0 10px 30px rgba(11,11,12,.16) }
.btn:active{ transform:translateY(0) }

.btn--nav{padding:10px 20px;font-size:14px}
.btn--lg{padding:16px 34px;font-size:17px}

@media (pointer:coarse){
  .btn{min-height:44px;padding-top:0;padding-bottom:0}
  .btn:hover{transform:none;box-shadow:none;--btn-bg:var(--blue)}
}

/* ---------- navbar ---------- */
.nav{
  position:fixed;inset:0 0 auto 0;z-index:100;
  height:var(--nav-h);
  background:transparent;
  border-bottom:1px solid transparent;
  transition:background .4s var(--ease),border-color .4s var(--ease),backdrop-filter .4s var(--ease);
}
.nav.is-stuck{
  background:rgba(255,255,255,.82);
  border-bottom-color:var(--line-soft);
  backdrop-filter:blur(16px) saturate(1.4);
  -webkit-backdrop-filter:blur(16px) saturate(1.4);
}
.nav__inner{
  height:100%;
  max-width:1440px;margin:0 auto;
  padding:0 var(--gutter);
  display:flex;align-items:center;justify-content:space-between;gap:16px;
}

.brand{
  display:inline-flex;align-items:center;gap:12px;
  text-decoration:none;color:var(--ink);
  border-radius:10px;
}
/* The logo file ships exactly as supplied. Nothing here recolors,
   crops, masks or filters it; only its rendered size changes. */
.brand__mark{
  width:42px;height:42px;
  flex:0 0 auto;
  border-radius:50%;            /* the artwork is already a circle on white */
  transition:transform .5s var(--ease);
}
.brand:hover .brand__mark{transform:rotate(-6deg) scale(1.04)}
.brand__name{
  font-family:var(--font-display);
  font-weight:700;
  font-size:clamp(19px,2vw,22px);
  letter-spacing:-.028em;
  white-space:nowrap;
}
@media (max-width:400px){
  .settle__sub{letter-spacing:.10em}
  .brand__mark{width:36px;height:36px}
  .brand__name{font-size:18px}
  .btn--nav{padding:10px 14px;font-size:13px}
}
.nav__links{display:flex;align-items:center;gap:clamp(14px,2vw,26px)}
.nav__link{
  position:relative;
  font-family:var(--font-display);
  font-weight:600;
  font-size:15px;
  letter-spacing:-.01em;
  color:var(--ink);
  text-decoration:none;
  padding:6px 1px;
  transition:color .3s var(--ease);
}
.nav__link::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--blue);
  transform:scaleX(0);transform-origin:left;
  transition:transform .34s var(--ease);
}
.nav__link:hover{color:var(--blue)}
.nav__link:hover::after,.nav__link:focus-visible::after{transform:scaleX(1)}
@media (max-width:400px){ .nav__link{font-size:14px} }
@media (pointer:coarse){
  .nav__link{min-height:44px;display:inline-flex;align-items:center}
  .nav__link:hover{color:var(--ink)}
  .nav__link:hover::after{transform:scaleX(0)}
}
@media (pointer:coarse){ .brand:hover .brand__mark{transform:none} }

/* Below this the brand, the links and the button cannot share one line.
   Below it the desktop links move into the hamburger menu instead; the
   hero and every section below still carry their own call to action.
   This has to come AFTER .nav__links{display:flex} in the file: same
   specificity, so source order decides which one wins at a matching
   width, and the override needs to be the one written later.
   960px, not the tighter cutoff this once used: five links plus the
   button no longer fit a comfortable row below that, once Capabilities
   joined Services, Why Us, Process and Contact. */
@media (max-width:959px){
  .nav__links{display:none}
}
@media (min-width:960px){
  .nav__burger,.nav__menu{display:none!important}
}

/* ---------- hamburger + mobile menu ----------
   Only reachable below 960px (the min-width:960px rule above forces both
   off at every wider size, regardless of any JS state), so a resize past
   the breakpoint with the menu open can never leave a stray open panel. */
.nav__burger{
  position:relative;
  width:40px;height:40px;
  flex:0 0 auto;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:5px;
  background:none;border:0;border-radius:10px;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.nav__burger-bar{
  display:block;
  width:20px;height:2px;
  background:var(--ink);
  border-radius:2px;
  transition:transform .32s var(--ease),opacity .2s var(--ease),background .3s var(--ease);
}
/* the three bars fold into an X, driven purely by aria-expanded */
.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-child(2){opacity:0;transform:scaleX(0)}
.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media (pointer:coarse){ .nav__burger{width:44px;height:44px} }

/* the class carries the transition; the attribute is the hard off switch,
   so a menu that JS never touches (scripting disabled) stays truly gone
   instead of sitting transparent and clickable underneath the page */
.nav__menu[hidden]{display:none}
.nav__menu{
  position:fixed;left:0;right:0;top:var(--nav-h);z-index:99;
  display:flex;flex-direction:column;
  padding:8px var(--gutter) 22px;
  background:rgba(255,255,255,.97);
  backdrop-filter:blur(16px) saturate(1.4);
  -webkit-backdrop-filter:blur(16px) saturate(1.4);
  border-bottom:1px solid var(--line-soft);
  box-shadow:0 18px 40px rgba(11,11,12,.10);
  transform:translateY(-8px);
  opacity:0;
  pointer-events:none;
  transition:opacity .3s var(--ease),transform .3s var(--ease);
}
.nav__menu.is-open{
  transform:translateY(0);
  opacity:1;
  pointer-events:auto;
}
.nav__menu-link{
  padding:14px 2px;
  border-bottom:1px solid var(--line-soft);
  font-family:var(--font-display);font-weight:600;font-size:16px;
  color:var(--ink);text-decoration:none;
  min-height:44px;display:flex;align-items:center;
  transition:color .3s var(--ease);
}
.nav__menu-link:hover,.nav__menu-link:focus-visible{color:var(--blue)}
.nav__menu-cta{width:100%;margin-top:16px}

/* ---------- hero ---------- */
.hero{
  position:relative;
  height:calc(100vh + var(--hero-scroll));
  height:calc(100svh + var(--hero-scroll));
  background:var(--paper);
}
.hero__stage{
  position:sticky;top:0;
  height:100vh;height:100svh;
  overflow:hidden;
  background:var(--paper);
  --veil:0;                    /* written by JS, 0 to 1 */
}

.hero__canvas{
  position:absolute;inset:0;
  width:100%;height:100%;
  display:none;                /* the scrub opts IN; static is the default */
  opacity:0;
  transition:opacity .6s var(--ease);
  transform:translateZ(0);
  will-change:transform;
}
.hero.is-scrub .hero__canvas{display:block}
.hero.is-scrub.is-painted .hero__canvas{opacity:1}

.hero__still{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  object-position:center;
  transition:opacity .5s var(--ease);
}
.hero.is-scrub.is-painted .hero__still{opacity:0}

.hero__veil{
  position:absolute;inset:0;
  pointer-events:none;
  background:var(--paper);
  opacity:calc(var(--veil) * .88);
}

/* ---------- loading ring ---------- */
.hero__loader{
  position:absolute;left:50%;bottom:9vh;
  transform:translateX(-50%);
  color:var(--ink);
  opacity:0;
  pointer-events:none;
  transition:opacity .45s var(--ease);
}
.hero.is-loading .hero__loader{opacity:.55}
.ring{display:block;transform:rotate(-90deg)}
.ring__track{stroke:var(--line)}
.ring__arc{
  stroke:var(--blue);
  stroke-dashoffset:var(--ld,126);
  transition:stroke-dashoffset .18s linear;
}

/* ---------- the settle: headline, subline, call to action ---------- */
.settle{
  position:absolute;inset:0;
  z-index:3;
  display:flex;flex-direction:column;
  align-items:center;justify-content:center;
  text-align:center;
  padding:calc(var(--nav-h) + 24px) var(--gutter) 12vh;
  pointer-events:none;
  --k:1;                        /* assembly progress, written by JS */
  --band:1;                     /* band opacity, written by JS */
  opacity:var(--band);
}
.settle__cta,.settle a,.settle button{pointer-events:auto}

.settle__title{
  margin:0;
  font-family:var(--font-display);
  font-weight:700;
  font-size:clamp(38px,7.4vw,92px);
  line-height:1.03;
  letter-spacing:-.042em;
  max-width:15ch;
}
.settle__sub{
  margin:clamp(18px,2.4vh,26px) 0 0;
  font-family:var(--font-mono);
  font-weight:500;
  font-size:clamp(12px,1.45vw,16px);
  letter-spacing:.15em;
  text-transform:uppercase;
  color:var(--muted);
  /* letter spacing widens the line well past its character count, so the
     cap has to allow for it or the three services wrap mid list */
  max-width:min(100%,46ch);
  text-wrap:balance;
  /* staged arrival: the subline lands after the headline words */
  --ks:clamp(0,(var(--k) - .5) * 3.2,1);
  opacity:var(--ks);
  transform:translateY(calc((1 - var(--ks)) * 14px));
}
.settle__cta{
  margin-top:clamp(26px,3.6vh,40px);
  --kb:clamp(0,(var(--k) - .7) * 3.6,1);
  opacity:var(--kb);
  transform:translateY(calc((1 - var(--kb)) * 18px)) scale(calc(.94 + .06 * var(--kb)));
}

/* word-by-word rise, driven purely by --k so it reverses on scroll up */
.settle__title .w{
  display:inline-block;
  white-space:pre;
  --kc:clamp(0,(var(--k) - var(--th,0)) * 2.9,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * 26px));
}

/* portrait: the frames sit high, the words sit in the white below them */
@media (max-aspect-ratio:5/4){
  .settle{justify-content:flex-end;padding-bottom:clamp(56px,13vh,120px)}
  .settle__title{max-width:12ch}
}

/* ---------- scroll cue ---------- */
.cue{
  position:absolute;left:50%;bottom:26px;
  transform:translateX(-50%);
  z-index:4;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  pointer-events:none;
  opacity:var(--cue,1);
  transition:opacity .5s var(--ease);
}
.cue__label{
  font-family:var(--font-mono);font-size:10px;
  letter-spacing:.22em;text-transform:uppercase;color:var(--muted);
}
.cue__line{
  width:1px;height:34px;
  background:linear-gradient(to bottom,var(--line),transparent);
  position:relative;overflow:hidden;
}
.cue__line::after{
  content:"";position:absolute;inset:0 auto auto 0;
  width:1px;height:14px;background:var(--blue);
  animation:cueRun 2.6s var(--ease-soft) infinite;
  animation-delay:-.8s;
}
@keyframes cueRun{
  0%{transform:translateY(-16px);opacity:0}
  30%{opacity:1}
  100%{transform:translateY(36px);opacity:0}
}
/* no room for the cue on short screens */
@media (max-height:560px){ .cue,.hero__loader{display:none} }

/* ---------- the static fallback state ----------
   Reached three ways: JavaScript never runs, a gate turns the
   scrub off, or the frames fail to load. In all three the hero
   is a composed still with the words already settled. */
.hero:not(.is-scrub) .cue{display:none}
.hero:not(.is-scrub) .hero__veil{opacity:.88}
.hero:not(.is-scrub) .settle{--k:1;--band:1}
.hero:not(.is-scrub){height:100vh;height:100svh}
.hero:not(.is-scrub) .hero__stage{position:relative}

/* ---------- services ----------
   Deliberately a different skeleton from the hero: the hero is one centred
   stack, so this opens as an asymmetric two column header over a card row. */
.services{
  position:relative;
  background:var(--paper);
  border-top:1px solid var(--line-soft);
  padding:clamp(64px,9vh,112px) var(--gutter) clamp(76px,11vh,132px);
  scroll-margin-top:var(--nav-h);
}
.services__inner{max-width:1240px;margin:0 auto}

.services__head{
  display:grid;
  gap:clamp(18px,3vw,56px);
  margin:0 0 clamp(36px,5.5vh,64px);
}
@media (min-width:920px){
  .services__head{grid-template-columns:1.4fr 1fr;align-items:end}
}

.services__label{
  display:flex;align-items:center;gap:12px;
  margin:0 0 clamp(14px,1.8vh,20px);
  font-family:var(--font-mono);font-weight:500;
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--blue);
}
.services__label::before{
  content:"";flex:0 0 auto;width:28px;height:2px;background:var(--blue);
}
.services__title{
  margin:0;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(30px,4.4vw,54px);
  line-height:1.06;letter-spacing:-.035em;
  max-width:20ch;
}
.services__lede{
  margin:0;
  font-size:clamp(15px,1.25vw,17px);
  line-height:1.6;
  color:var(--muted);
  max-width:44ch;
}

.cards{
  display:grid;
  gap:clamp(14px,1.8vw,20px);
  grid-template-columns:1fr;
  max-width:560px;margin:0 auto;
}
/* three equal services read as one row or one column, never an orphan */
@media (min-width:760px){
  .cards{grid-template-columns:repeat(3,1fr);max-width:none;margin:0}
}

.card{
  position:relative;
  display:flex;flex-direction:column;
  padding:clamp(24px,2.4vw,34px);
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:16px;
  overflow:hidden;
  /* the entrance offset and the hover lift ride separate custom properties,
     so neither rule has to out-specify the other to move the card */
  transform:translateY(calc(var(--y,0px) + var(--lift,0px)));
  transition:opacity .6s var(--ease) var(--d,0s),
             transform .55s var(--ease) var(--d,0s),
             border-color .34s var(--ease),
             box-shadow .38s var(--ease);
}
.card__rule{
  position:absolute;left:0;right:0;top:0;height:2px;
  background:var(--blue);
  transform:scaleX(0);transform-origin:left;
  transition:transform .42s var(--ease);
}
.card__index{
  font-family:var(--font-mono);font-weight:500;
  font-size:12px;letter-spacing:.18em;
  color:rgba(6,83,251,.42);
  transition:color .34s var(--ease);
}
.card__title{
  margin:clamp(18px,2.2vh,26px) 0 0;
  font-family:var(--font-display);font-weight:600;
  font-size:clamp(19px,1.45vw,22px);
  line-height:1.2;letter-spacing:-.022em;
}
.card__text{
  margin:12px 0 0;
  font-size:15px;line-height:1.62;
  color:var(--muted);
  max-width:38ch;
}

.card:hover{
  --lift:-4px;
  border-color:rgba(6,83,251,.5);
  box-shadow:0 14px 40px rgba(6,83,251,.10);
}
.card:hover .card__rule{transform:scaleX(1)}
.card:hover .card__index{color:var(--blue)}
@media (pointer:coarse){
  .card:hover{--lift:0px;border-color:var(--line);box-shadow:none}
  .card:hover .card__rule{transform:scaleX(0)}
  .card:hover .card__index{color:rgba(6,83,251,.42)}
}

/* The fade up opts IN: JavaScript adds .anim, so with scripting off the
   cards are simply there rather than stuck at zero opacity. */
/* transition:none while it waits. The class lands after first paint, so
   without this the cards would visibly fade OUT before they fade up. */
.services.anim .card{--y:18px;opacity:0;transition:none}
.services.anim .card:nth-child(2){--d:.09s}
.services.anim .card:nth-child(3){--d:.18s}
.services.anim.in .card{
  --y:0px;opacity:1;
  transition:opacity .6s var(--ease) var(--d,0s),
             transform .55s var(--ease) var(--d,0s),
             border-color .34s var(--ease),
             box-shadow .38s var(--ease);
}
/* retire the stagger once it has played, or every later hover waits it out */
.services.anim.done .card{--d:0s}

/* ---------- why buildzenvix ----------
   Services opened as an asymmetric two column header over vertical numbered
   cards. This opens centred, over a horizontal icon-plus-text row, so the
   two sections never read as the same template repeated. */
.why{
  position:relative;
  background:var(--paper);
  border-top:1px solid var(--line-soft);
  padding:clamp(64px,9vh,112px) var(--gutter) clamp(76px,11vh,132px);
  scroll-margin-top:var(--nav-h);
}
.why__inner{max-width:1080px;margin:0 auto}

.why__head{
  text-align:center;
  max-width:46ch;margin:0 auto clamp(36px,5.5vh,60px);
}
.why__label{
  display:inline-flex;align-items:center;gap:12px;
  margin:0 0 clamp(14px,1.8vh,20px);
  font-family:var(--font-mono);font-weight:500;
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--blue);
}
.why__label::before,.why__label::after{
  content:"";flex:0 0 auto;width:20px;height:2px;background:var(--blue);
}
.why__title{
  margin:0;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(28px,4vw,46px);
  line-height:1.1;letter-spacing:-.032em;
}

.benefits{
  display:grid;
  gap:clamp(14px,1.8vw,20px);
  grid-template-columns:1fr;
}
@media (min-width:640px){
  .benefits{grid-template-columns:repeat(2,1fr)}
}

.benefit{
  display:flex;align-items:flex-start;gap:16px;
  padding:clamp(20px,2vw,26px);
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:16px;
  transform:translateY(calc(var(--y,0px) + var(--lift,0px)));
  transition:opacity .6s var(--ease) var(--d,0s),
             transform .55s var(--ease) var(--d,0s),
             border-color .34s var(--ease),
             box-shadow .38s var(--ease);
}
.benefit__icon{
  display:flex;align-items:center;justify-content:center;
  flex:0 0 auto;
  width:44px;height:44px;
  border-radius:12px;
  background:rgba(6,83,251,.08);
  color:var(--blue);
  transition:background .34s var(--ease),color .34s var(--ease),transform .34s var(--ease);
}
.benefit__icon svg{width:20px;height:20px}
.benefit__title{
  margin:0;
  font-family:var(--font-display);font-weight:600;
  font-size:17px;line-height:1.25;letter-spacing:-.018em;
}
.benefit__text{
  margin:8px 0 0;
  font-size:14.5px;line-height:1.6;
  color:var(--muted);
  max-width:34ch;
}

.benefit:hover{
  --lift:-4px;
  border-color:rgba(6,83,251,.5);
  box-shadow:0 14px 40px rgba(6,83,251,.10);
}
.benefit:hover .benefit__icon{
  background:var(--blue);
  color:var(--paper);
  transform:scale(1.06);
}
@media (pointer:coarse){
  .benefit:hover{--lift:0px;border-color:var(--line);box-shadow:none}
  .benefit:hover .benefit__icon{background:rgba(6,83,251,.08);color:var(--blue);transform:none}
}

/* the fade up opts in the same way the services cards do, see above */
.why.anim .benefit{--y:18px;opacity:0;transition:none}
.why.anim .benefit:nth-child(2){--d:.09s}
.why.anim .benefit:nth-child(3){--d:.18s}
.why.anim .benefit:nth-child(4){--d:.27s}
.why.anim.in .benefit{
  --y:0px;opacity:1;
  transition:opacity .6s var(--ease) var(--d,0s),
             transform .55s var(--ease) var(--d,0s),
             border-color .34s var(--ease),
             box-shadow .38s var(--ease);
}
.why.anim.done .benefit{--d:0s}

/* ---------- process ----------
   Services opened asymmetric two column, why opened centred over a card
   grid. This opens left aligned, over a row of numbered steps threaded by
   one line, so no two sections in a row ever share a skeleton. The line
   and the numeral box share one fixed geometry (a 64px square) so the
   connector's position is exact in both the stacked and the row layout,
   with no measurement needed. */
.process{
  position:relative;
  background:var(--paper);
  border-top:1px solid var(--line-soft);
  padding:clamp(64px,9vh,112px) var(--gutter) clamp(76px,11vh,132px);
  scroll-margin-top:var(--nav-h);
}
.process__inner{max-width:1080px;margin:0 auto}

.process__head{
  max-width:52ch;
  margin:0 0 clamp(40px,6vh,72px);
}
.process__label{
  display:inline-flex;align-items:center;gap:12px;
  margin:0 0 clamp(14px,1.8vh,20px);
  font-family:var(--font-mono);font-weight:500;
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--blue);
}
.process__label::before{
  content:"";flex:0 0 auto;width:28px;height:2px;background:var(--blue);
}
.process__title{
  margin:0;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(28px,4vw,46px);
  line-height:1.1;letter-spacing:-.032em;
  max-width:22ch;
}

.steps{
  --step-gap:clamp(20px,3.4vw,40px);
  list-style:none;margin:0;padding:0;
  position:relative;
  display:flex;flex-direction:column;
}

.step{
  position:relative;
  display:flex;flex-direction:column;align-items:flex-start;
  padding-left:calc(64px + 20px);
  margin-bottom:var(--step-gap);
  transform:translateY(var(--y,0px));
  transition:opacity .6s var(--ease) var(--d,0s),transform .55s var(--ease) var(--d,0s);
}
.step:last-child{margin-bottom:0}

/* the bridge to the NEXT step's numeral: a fixed length equal to the gap
   between steps, so it lands exactly on the following numeral regardless
   of how tall this step's own title and text happen to run */
.step::after{
  content:"";
  position:absolute;
  left:32px;top:64px;
  width:2px;height:var(--step-gap);
  background:var(--line);
}
.step:last-child::after{display:none}

.step__num{
  flex:0 0 auto;
  position:absolute;left:0;top:0;
  width:64px;height:64px;
  display:flex;align-items:center;justify-content:flex-start;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(30px,7vw,40px);
  line-height:1;letter-spacing:-.02em;
  color:var(--blue);
}
.step__title{
  margin:0;
  padding-top:14px;
  font-family:var(--font-display);font-weight:600;
  font-size:clamp(19px,1.6vw,23px);
  line-height:1.25;letter-spacing:-.02em;
}
.step__text{
  margin:8px 0 0;
  font-size:15px;line-height:1.62;
  color:var(--muted);
  max-width:38ch;
}

@media (min-width:760px){
  .steps{
    flex-direction:row;
    gap:var(--step-gap);
  }
  .step{
    flex:1 1 0;
    padding-left:0;
    margin-bottom:0;
    align-items:center;
    text-align:center;
  }
  .step::after{display:none}
  .step__num{
    position:static;
    justify-content:center;
    margin:0 auto;
  }
  .step__title{padding-top:18px}
  .step__text{max-width:32ch}
  /* one shared thread, centred on each numeral box regardless of the
     row's gap: the numeral sits centred in an equal share of the row,
     so its centre is exactly half a share in from each outer edge */
  .steps::before{
    content:"";
    position:absolute;
    top:32px;
    left:calc((100% - 2 * var(--step-gap)) / 6);
    right:calc((100% - 2 * var(--step-gap)) / 6);
    height:2px;
    background:var(--line);
    z-index:0;
  }
  .step__num,.step__title,.step__text{position:relative;z-index:1}
}

/* the fade up opts in the same way the services cards and the why
   benefits do, see above: JavaScript adds .anim, so with scripting off
   the steps are simply there rather than stuck at zero opacity */
.process.anim .step{--y:18px;opacity:0;transition:none}
.process.anim .step:nth-child(2){--d:.09s}
.process.anim .step:nth-child(3){--d:.18s}
.process.anim.in .step{
  --y:0px;opacity:1;
  transition:opacity .6s var(--ease) var(--d,0s),transform .55s var(--ease) var(--d,0s);
}
.process.anim.done .step{--d:0s}

/* ---------- contact / free audit ----------
   Every section so far has opened with its own header band. This one
   folds the header into the left half of a two column split instead,
   the form filling the right, so the skeleton is genuinely new rather
   than a fourth variation on "label, heading, content below". */
.contact{
  position:relative;
  background:var(--paper);
  border-top:1px solid var(--line-soft);
  padding:clamp(64px,9vh,112px) var(--gutter) clamp(76px,11vh,132px);
  scroll-margin-top:var(--nav-h);
}
.contact__inner{max-width:1160px;margin:0 auto}

.contact__grid{
  display:grid;
  gap:clamp(40px,6vw,80px);
  grid-template-columns:1fr;
}
@media (min-width:900px){
  .contact__grid{grid-template-columns:.92fr 1.08fr;align-items:start}
}

/* ---------- left: the pitch and the ways to reach us ---------- */
.contact__label{
  display:inline-flex;align-items:center;gap:12px;
  margin:0 0 clamp(14px,1.8vh,20px);
  font-family:var(--font-mono);font-weight:500;
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--blue);
}
.contact__label::before{
  content:"";flex:0 0 auto;width:28px;height:2px;background:var(--blue);
}
.contact__title{
  margin:0;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(28px,4vw,44px);
  line-height:1.1;letter-spacing:-.032em;
  max-width:18ch;
}
.contact__lede{
  margin:clamp(14px,2vh,20px) 0 0;
  font-size:clamp(15px,1.25vw,17px);
  line-height:1.6;
  color:var(--muted);
  max-width:46ch;
}

.contact-links{
  list-style:none;margin:clamp(28px,4vh,44px) 0 0;padding:0;
  display:flex;flex-direction:column;gap:6px;
}
.contact-links__item{
  display:flex;align-items:center;gap:8px;
}
.contact-links__link{
  flex:1 1 auto;min-width:0;
  display:flex;align-items:center;gap:14px;
  padding:10px 8px;
  border-radius:14px;
  text-decoration:none;color:var(--ink);
  transition:background .3s var(--ease);
}
.contact-links__link:hover{background:rgba(6,83,251,.06)}
.contact-links__icon{
  flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;
  border-radius:12px;
  background:rgba(6,83,251,.08);
  color:var(--blue);
  transition:background .34s var(--ease),color .34s var(--ease),transform .34s var(--ease);
}
.contact-links__icon svg{width:20px;height:20px}
.contact-links__link:hover .contact-links__icon{
  background:var(--blue);color:var(--paper);transform:scale(1.06);
}
.contact-links__text{display:flex;flex-direction:column;min-width:0}
.contact-links__label{
  font-family:var(--font-mono);font-weight:500;
  font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);
}
.contact-links__value{
  font-family:var(--font-display);font-weight:600;
  font-size:16px;letter-spacing:-.01em;
  word-break:break-word;
}
.contact-links__call{
  flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  width:40px;height:40px;
  border-radius:50%;
  border:1.5px solid var(--line);
  color:var(--ink);
  transition:border-color .3s var(--ease),color .3s var(--ease);
}
.contact-links__call svg{width:16px;height:16px}
.contact-links__call:hover{border-color:var(--blue);color:var(--blue)}
@media (pointer:coarse){
  .contact-links__link:hover{background:none}
  .contact-links__link:hover .contact-links__icon{background:rgba(6,83,251,.08);color:var(--blue);transform:none}
  .contact-links__call:hover{border-color:var(--line);color:var(--ink)}
}

/* ---------- right: the free audit form ---------- */
.contact__form-wrap{
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:20px;
  padding:clamp(24px,3vw,40px);
  box-shadow:0 30px 70px -32px rgba(11,11,12,.16);
}

.audit-form{display:flex;flex-direction:column;gap:16px}

.field{display:flex;flex-direction:column;gap:6px}
.field__label{
  font-family:var(--font-display);font-weight:600;
  font-size:13.5px;letter-spacing:-.005em;
  color:var(--ink);
}
.field__optional{
  font-family:var(--font-body);font-weight:400;
  color:var(--muted);
  text-transform:none;letter-spacing:0;
}
.field__input{
  width:100%;
  padding:12px 14px;
  font-family:var(--font-body);font-size:15px;
  color:var(--ink);
  background:var(--paper);
  border:1.5px solid var(--line);
  border-radius:10px;
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.field__input::placeholder{color:rgba(11,11,12,.38)}
.field__input:focus{border-color:var(--blue)}
.field__select{
  appearance:none;-webkit-appearance:none;
  padding-right:40px;
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%230B0B0C' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  cursor:pointer;
}
.field__textarea{resize:vertical;min-height:88px;font-family:var(--font-body)}

/* No red anywhere: an invalid field gets a heavier black border and a
   bold black message instead of the usual red, to stay inside the
   locked three colour palette. */
.field--invalid .field__input{border-color:var(--ink);border-width:2px}
.field__error{
  margin:2px 0 0;
  font-family:var(--font-body);font-weight:600;
  font-size:12.5px;line-height:1.4;
  color:var(--ink);
}
.field__error:empty{display:none;margin:0}

.audit-form__submit{width:100%;margin-top:4px}
.audit-form__note{
  margin:2px 0 0;
  font-family:var(--font-body);font-weight:600;
  font-size:13.5px;line-height:1.5;
  text-align:center;
}
.audit-form__note:empty{display:none;margin:0}
.audit-form__note--success{color:var(--blue)}
.audit-form__note--error{color:var(--ink)}

@media (pointer:coarse){ .field__select{min-height:44px} }

/* the fade up opts in the same way as the sections above: two items,
   the pitch and the form, arriving a beat apart */
.contact__info,.contact__form-wrap{transform:translateY(var(--y,0px))}
.contact.anim .contact__info,
.contact.anim .contact__form-wrap{--y:18px;opacity:0;transition:none}
.contact.anim .contact__form-wrap{--d:.12s}
.contact.anim.in .contact__info,
.contact.anim.in .contact__form-wrap{
  --y:0px;opacity:1;
  transition:opacity .6s var(--ease) var(--d,0s),transform .55s var(--ease) var(--d,0s);
}
.contact.anim.done .contact__info,.contact.anim.done .contact__form-wrap{--d:0s}

/* ---------- capabilities: what we can create ----------
   A loose scatter of nine photographs on plain white, the way a set of
   prints falls on a table. No card wrappers, no tinted tiles, no thick
   frames: just the pictures, a soft shadow for depth, and clean
   rectangular edges.

   Every piece is placed by the cascade alone. --fx/--fy are fractions of
   the stage's own half extent, and the left/top calc subtracts half the
   piece's own size before scaling, so a fraction of 1 lands the piece's
   EDGE on the stage edge, never past it. That is what keeps the collage
   inside its box at any width with no measurement and no script.

   Motion is two independent layers that never fight over one property:
     .piece      carries position + the pointer parallax (JS writes two
                 numbers on .collage; every piece reads them by cascade)
     .piece__img carries the idle drift keyframe, its own transform
   Both are transform-only, so neither costs layout. */
.capabilities{
  position:relative;
  background:var(--paper);
  border-top:1px solid var(--line-soft);
  padding:clamp(52px,7vh,84px) var(--gutter) clamp(40px,6vh,72px);
  scroll-margin-top:var(--nav-h);
}
.capabilities__inner{max-width:1180px;margin:0 auto}

/* compact on purpose: the collage is the content, the words introduce it */
.capabilities__head{
  text-align:center;
  max-width:46ch;
  margin:0 auto clamp(6px,1.4vh,16px);
}
.capabilities__label{
  display:inline-flex;align-items:center;gap:12px;
  margin:0 0 10px;
  font-family:var(--font-mono);font-weight:500;
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--blue);
}
.capabilities__label::before,.capabilities__label::after{
  content:"";flex:0 0 auto;width:20px;height:2px;background:var(--blue);
}
.capabilities__title{
  margin:0;
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(26px,3.6vw,42px);
  line-height:1.1;letter-spacing:-.032em;
}
.capabilities__hint{
  margin:10px 0 0;
  font-family:var(--font-mono);font-weight:500;
  font-size:11.5px;letter-spacing:.04em;
  color:var(--muted);
}

/* ---------- the stage ---------- */
.collage{
  position:relative;
  width:100%;
  max-width:960px;
  height:clamp(500px,58vw,660px);
  margin:0 auto;
  --parx:0px;
  --pary:0px;
}

/* ---------- one photograph ---------- */
.piece{
  position:absolute;
  left:calc(50% + var(--fx) * (50% - var(--w) / 2));
  top:calc(50% + var(--fy) * (50% - var(--h) / 2));
  width:var(--w);height:var(--h);
  padding:0;border:0;background:none;
  cursor:pointer;
  z-index:var(--z,1);
  -webkit-tap-highlight-color:transparent;
  transform:
    translate(-50%,-50%)
    translate(calc(var(--parx) * var(--depth)), calc(var(--pary) * var(--depth)))
    rotate(var(--rot));
  /* deliberately no transition on transform at rest: the parallax rewrites
     it every frame and is already smoothed by its own lerp, so a transition
     here would only ease an eased value and lag behind the pointer. The
     open/close flight switches one on for the duration of the trip. */
}
.piece.is-animating{
  transition:transform .42s var(--ease);
  z-index:120;
}
.piece__img{
  width:100%;height:100%;
  object-fit:cover;
  display:block;
  background:var(--line-soft);
  box-shadow:0 10px 26px -12px rgba(11,11,12,.34);
  /* the idle drift: slow, small, bounded, and given a negative delay so
     every piece is already mid-cycle at first paint rather than all
     starting together */
  animation:pieceDrift var(--dur,11s) ease-in-out var(--del,0s) infinite;
}
@keyframes pieceDrift{
  0%,100%{transform:translate(0,0) rotate(0deg)}
  50%{transform:translate(var(--dx,4px),var(--dy,-6px)) rotate(var(--dr,.5deg))}
}
/* offscreen or hidden tab: the drift stops rather than burning frames.
   (body.paused is the site-wide hidden-tab switch that already exists) */
.collage:not(.is-live) .piece__img{animation-play-state:paused}

@media (hover:hover){
  .piece:hover{z-index:40}
  .piece:hover .piece__img{box-shadow:0 18px 40px -14px rgba(11,11,12,.44)}
}
.piece:focus-visible{z-index:40}

/* the service name, only while a piece is open */
.piece__label{
  position:absolute;left:50%;bottom:-2.35em;
  transform:translateX(-50%);
  white-space:nowrap;
  font-family:var(--font-display);font-weight:600;
  font-size:15px;letter-spacing:-.01em;
  color:var(--ink);
  opacity:0;
  pointer-events:none;
  transition:opacity .3s var(--ease);
}

/* ---------- the nine resting positions ----------
   An oval scatter: three across the top, three through the middle, three
   along the bottom, one of them sitting near the centre so the ring is
   not a hollow circle. Sizes vary; the 3:4 ratio of every supplied file
   is preserved exactly in each --w / --h pair, so nothing is cropped by
   the layout itself. */
.piece--1{--fx:-.60;--fy:-.62;--rot:-4deg;  --w:150px;--h:201px;--depth:.9; --z:3;--dur:10s;  --del:-2.4s;--dx:5px; --dy:-7px;--dr:.5deg}
.piece--2{--fx: .02;--fy:-.84;--rot:3deg;   --w:132px;--h:177px;--depth:1.15;--z:2;--dur:12s; --del:-6.1s;--dx:-6px;--dy:5px; --dr:-.4deg}
.piece--3{--fx: .64;--fy:-.58;--rot:5deg;   --w:146px;--h:196px;--depth:.8; --z:3;--dur:9s;   --del:-1.2s;--dx:4px; --dy:6px; --dr:.6deg}
.piece--4{--fx:-.88;--fy: .04;--rot:-6deg;  --w:176px;--h:236px;--depth:1;  --z:5;--dur:13s;  --del:-8.3s;--dx:-5px;--dy:-6px;--dr:-.5deg}
.piece--5{--fx: .00;--fy:-.02;--rot:1.5deg; --w:190px;--h:254px;--depth:.55;--z:8;--dur:14s;  --del:-3.7s;--dx:3px; --dy:4px; --dr:.35deg}
.piece--6{--fx: .88;--fy: .10;--rot:4deg;   --w:168px;--h:225px;--depth:.95;--z:5;--dur:11s;  --del:-5.5s;--dx:6px; --dy:-4px;--dr:-.45deg}
.piece--7{--fx:-.62;--fy: .66;--rot:-5deg;  --w:138px;--h:185px;--depth:1.2;--z:4;--dur:10.5s;--del:-7.2s;--dx:-4px;--dy:6px; --dr:.5deg}
.piece--8{--fx: .06;--fy: .86;--rot:3.5deg; --w:178px;--h:238px;--depth:.85;--z:6;--dur:12.5s;--del:-.9s; --dx:5px; --dy:5px; --dr:-.4deg}
.piece--9{--fx: .62;--fy: .62;--rot:-3deg;  --w:142px;--h:190px;--depth:1.05;--z:4;--dur:9.5s; --del:-4.4s;--dx:-6px;--dy:-5px;--dr:.55deg}

/* ---------- phones ----------
   Deliberately re-placed and re-sized, not the desktop layout shrunk:
   the oval turns tall and narrow to suit a portrait screen, and the
   pieces stay large enough to read what is on each screen. */
@media (max-width:760px){
  .collage{
    max-width:none;
    height:clamp(540px,152vw,720px);
  }
  .piece--1{--fx:-.74;--fy:-.80;--w:100px;--h:134px}
  .piece--2{--fx: .54;--fy:-.88;--w:92px; --h:123px}
  .piece--3{--fx: .86;--fy:-.42;--w:96px; --h:129px}
  .piece--4{--fx:-.90;--fy:-.26;--w:112px;--h:150px}
  .piece--5{--fx: .04;--fy:-.10;--w:122px;--h:163px}
  .piece--6{--fx: .84;--fy: .24;--w:106px;--h:142px}
  .piece--7{--fx:-.80;--fy: .42;--w:96px; --h:129px}
  .piece--8{--fx:-.06;--fy: .74;--w:116px;--h:155px}
  .piece--9{--fx: .68;--fy: .82;--w:98px; --h:131px}
  .piece__label{font-size:13.5px;bottom:-2.1em}
}
@media (max-width:400px){
  .collage{height:clamp(500px,158vw,640px)}
  .piece--1{--w:88px; --h:118px}
  .piece--2{--w:80px; --h:107px}
  .piece--3{--w:84px; --h:112px}
  .piece--4{--w:98px; --h:131px}
  .piece--5{--w:106px;--h:142px}
  .piece--6{--w:92px; --h:123px}
  .piece--7{--w:84px; --h:112px}
  .piece--8{--w:100px;--h:134px}
  .piece--9{--w:86px; --h:115px}
}

/* ---------- the opened piece ----------
   position:fixed, so it is centred on the VIEWPORT rather than on the
   stage: that is what guarantees it stays fully on screen whatever the
   scroll position or the stage's own height. The centre is pushed down
   by half the navbar and the height capped against it, so it can never
   sit under the fixed bar. */
.collage__scrim{
  position:fixed;inset:0;z-index:110;
  background:rgba(255,255,255,.82);
  backdrop-filter:blur(7px);
  -webkit-backdrop-filter:blur(7px);
  opacity:0;
  transition:opacity .32s var(--ease);
}
.collage__scrim[hidden]{display:none}
.collage__scrim.is-open{opacity:1}

.piece.is-open{
  position:fixed;
  left:50%;
  top:calc(50% + var(--nav-h) / 2);
  /* the third term is the height budget converted back into a width by
     the images' own 3:4 ratio, so the box always matches the picture
     exactly: it is bounded by the viewport without ever letterboxing */
  --openh:calc(100vh - var(--nav-h) - 96px);
  --openh:calc(100svh - var(--nav-h) - 96px);
  width:min(78vw,380px,calc(var(--openh) * 0.7467));
  height:auto;
  z-index:120;
  transform:translate(-50%,-50%) rotate(0deg);
}
.piece.is-open .piece__img{
  width:100%;
  height:auto;
  object-fit:contain;
  animation:none;                 /* the drift stops while it is open */
  box-shadow:0 30px 70px -24px rgba(11,11,12,.5);
}
.piece.is-open .piece__label{opacity:1}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
    transition-delay:0ms!important;
  }
  .cue{display:none}
  .settle{--k:1;--band:1}
  .settle__title .w{opacity:1;transform:none}
  .settle__sub,.settle__cta{opacity:1;transform:none}
  .services.anim .card{--y:0px;--lift:0px;opacity:1}
  .card__rule{transform:scaleX(0)}
  .why.anim .benefit{--y:0px;--lift:0px;opacity:1}
  .process.anim .step{--y:0px;opacity:1}
  .contact.anim .contact__info,.contact.anim .contact__form-wrap{--y:0px;opacity:1}
  .nav__burger-bar{transition:none}
  .nav__menu{transition:none}
  /* the idle drift keyframe is already killed by the blanket rule at the
     top of this block; this only clears any parallax JS had in flight,
     so a piece can never rest off its plain resting position */
  .collage{--parx:0px!important;--pary:0px!important}
}

/* ---------- footer ----------
   The one deliberate inversion on the page: near black, white text, the
   same blue kept rare, doing only three jobs here, the top border, the
   tagline, and every hover. Reuses --ink and --paper in reverse rather
   than adding new colour tokens, so the palette stays the same three
   values it has been everywhere else. */
.site-footer{
  background:var(--ink);
  color:rgba(255,255,255,.82);
  border-top:3px solid var(--blue);
}
.site-footer__inner{
  max-width:1240px;margin:0 auto;
  padding:clamp(40px,6vh,64px) var(--gutter) clamp(24px,3.5vh,36px);
}

.site-footer__top{
  display:grid;
  gap:clamp(32px,5vw,64px);
  grid-template-columns:1fr;
  padding-bottom:clamp(28px,4vh,40px);
  border-bottom:1px solid rgba(255,255,255,.14);
}
@media (min-width:700px){
  .site-footer__top{grid-template-columns:1.3fr .8fr .9fr}
}

.site-footer__brand-link{
  display:inline-flex;align-items:center;gap:12px;
  text-decoration:none;color:var(--paper);
}
.site-footer__mark{
  width:40px;height:40px;
  border-radius:50%;
  flex:0 0 auto;
}
.site-footer__brand-name{
  font-family:var(--font-display);font-weight:700;
  font-size:20px;letter-spacing:-.026em;
}
.site-footer__tagline{
  margin:clamp(14px,2vh,18px) 0 0;
  font-family:var(--font-display);font-weight:700;
  font-size:15px;letter-spacing:-.01em;
  color:var(--blue);
}
.site-footer__lede{
  margin:8px 0 0;
  font-size:14px;line-height:1.6;
  color:rgba(255,255,255,.6);
  max-width:34ch;
}

.site-footer__col{display:flex;flex-direction:column;gap:12px}
.site-footer__heading{
  margin:0 0 2px;
  font-family:var(--font-mono);font-weight:500;
  font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.5);
}
.site-footer__link{
  color:rgba(255,255,255,.82);
  text-decoration:none;
  font-size:14.5px;
  width:fit-content;
  transition:color .3s var(--ease);
}
.site-footer__link:hover{color:var(--blue)}
.site-footer__link--icon{
  display:inline-flex;align-items:center;gap:10px;
}
.site-footer__link--icon svg{
  flex:0 0 auto;width:17px;height:17px;
  color:rgba(255,255,255,.5);
  transition:color .3s var(--ease);
}
.site-footer__link--icon:hover svg{color:var(--blue)}
@media (pointer:coarse){
  .site-footer__link{min-height:32px;display:inline-flex;align-items:center}
}

.site-footer__bottom{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:16px;
  padding-top:clamp(20px,3vh,28px);
}
.site-footer__copy{
  margin:0;
  font-size:13px;
  color:rgba(255,255,255,.5);
}
.site-footer__top-btn{
  display:flex;align-items:center;justify-content:center;
  flex:0 0 auto;
  width:40px;height:40px;
  border-radius:50%;
  border:1.5px solid rgba(255,255,255,.4);
  color:rgba(255,255,255,.82);
  transition:border-color .3s var(--ease),color .3s var(--ease),transform .3s var(--ease);
}
.site-footer__top-btn svg{width:17px;height:17px}
.site-footer__top-btn:hover{border-color:var(--blue);color:var(--blue);transform:translateY(-2px)}
@media (pointer:coarse){
  .site-footer__top-btn{width:44px;height:44px}
  .site-footer__top-btn:hover{transform:none}
}

/* ---------- pause everything on a hidden tab ---------- */
body.paused *,body.paused *::before,body.paused *::after{
  animation-play-state:paused!important;
}
