/* Two real cuts, so a heading can out-weigh the text under it instead of
   having to out-size it. 600 resolves to the bold file, which is what the
   headings across this stylesheet ask for. */
@font-face{
  font-family:'Sahar';
  src:url('/fonts/sahar-regular.woff2') format('woff2');
  font-weight:400;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:'Sahar';
  src:url('/fonts/sahar-bold.woff2') format('woff2');
  font-weight:700;
  font-style:normal;
  font-display:swap;
}

:root{
  --page:#EFEEEB;
  --ink:#ffffff;
  --lime:#D9E968;
  /* kept as its own name so the bar can diverge again if it ever needs to */
  --ticker-lime:var(--lime);
  --grey-100:rgba(255,255,255,.88);
  --grey-200:rgba(255,255,255,.66);
  --grey-300:rgba(255,255,255,.46);
  --hairline:rgba(255,255,255,.12);
  --star:#FFC02E;
  --overlay:38,38,44;
  --scrim:8,8,10;
  --brand-purple:26,15,58;
  --purple-wash:.02;
  --purple-grad:.26;
  --ink-veil:0;
  --overlay-alpha:.86;
  --surface:#18181B;
  --picker-bg:#141416;
  --purple-accent:96,64,180;
  /* deliberately between #fff and --page, so the white .pick cards
     that sit on it read as cards rather than white on white */
  --paper:#F5F4F1;
  --ink-dark:#121212;
  --panel:rgba(38,31,56,.97);
  --radius-main:1.5rem;
  --radius-full:9999px;
  --shell:1.25rem;
  --max:96rem;
  --gutter:2.25rem;
  --edge:max(var(--gutter), calc((100% - var(--max)) / 2));
  /* the studio photograph is used by two sections and the Google mark by
     thirteen elements, so both live here rather than being inlined again
     at every use */
  --photo-desk:url("/img/photo-desk-v2.webp");
  --photo-focus:url("/img/photo-focus-v2.webp");
  --photo-studio:url("/img/photo-studio-v2.webp");
  --mark-google:url("/img/mark-google.svg");
  --font-body:'Manrope',system-ui,-apple-system,sans-serif;
  /* Sahar is the display face and ships from /fonts as a single bold cut.
     Plus Jakarta Sans sits behind it as a same-genre fallback for the moment
     before it loads. Instrument Serif is the accent face, wired and unused. */
  --font-head:'Sahar','Plus Jakarta Sans',system-ui,-apple-system,sans-serif;
  --font-style:'Instrument Serif',Georgia,'Times New Roman',serif;
}

*{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;
  background:var(--page);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:1rem;
  line-height:1.5;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none;}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;}
:focus-visible{outline:2px solid var(--lime);outline-offset:3px;border-radius:4px;}

/* ---------- shell ---------- */
.shell{padding:var(--shell);}
.hero{
  position:relative;
  isolation:isolate;
  margin:calc(var(--shell) * -1) calc(var(--shell) * -1) 0;
  border-radius:0;
  overflow:hidden;
  min-height:100svh;
  display:flex;
  flex-direction:column;
}
.hero__media{
  position:absolute;
  inset:0;
  z-index:-2;
  background-image:url("/img/hero-home-v2.webp");
  background-size:cover;
  background-position:56% 38%;
  transform:scale(1.04);
  animation:driftIn 2.4s cubic-bezier(.16,1,.3,1) both;
}
.hero__scrim{
  position:absolute;
  inset:0;
  z-index:-1;
  background:
    /* dark from the bottom, clears above the eyebrow */
    linear-gradient(0deg,
      rgba(var(--scrim),.95) 0%,
      rgba(var(--scrim),.92) 18%,
      rgba(var(--scrim),.8) 34%,
      rgba(var(--scrim),.58) 48%,
      rgba(var(--scrim),.28) 62%,
      rgba(var(--scrim),0) 78%),
    /* sharp band behind the nav */
    linear-gradient(180deg,
      rgba(var(--scrim),.85) 0%,
      rgba(var(--scrim),.62) 5%,
      rgba(var(--scrim),.28) 10%,
      rgba(var(--scrim),0) 15%);
}
@keyframes driftIn{from{transform:scale(1.12);opacity:.4;}to{transform:scale(1.04);opacity:1;}}

/* ---------- nav ---------- */
.nav{
  position:relative;
  z-index:40;
  display:flex;
  align-items:center;
  gap:2rem;
  padding:1.5rem var(--edge);
}
.nav__logo{display:flex;align-items:center;flex:0 0 auto;}
.nav__logo > svg{height:2.1rem;width:auto;display:block;}
.nav__menu{
  display:flex;
  align-items:center;
  gap:.4rem;
  /* auto on the left only: the menu is pushed across to sit next to the
     call-us block rather than centred in the bar */
  margin-left:auto;
}
.nav__item{position:relative;}
.nav__link{
  display:flex;
  align-items:center;
  gap:.4rem;
  padding:.6rem 1.1rem;
  border:1px solid rgba(255,255,255,.10);
  background:rgba(255,255,255,.06);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  font-size:1rem;
  font-weight:400;
  color:var(--grey-100);
  border-radius:var(--radius-full);
  transition:color .18s ease, background-color .18s ease, border-color .18s ease;
  white-space:nowrap;
}
.nav__link:hover{background:rgba(255,255,255,.13);border-color:rgba(255,255,255,.22);color:#fff;}
.nav__item.is-open .nav__link{
  background:var(--lime);color:var(--ink-dark);
  border-color:transparent;
  box-shadow:0 0 0 4px rgba(217,233,104,.15);
}
.nav__item.is-open .nav__link svg{opacity:1;}
.nav__link svg{width:.7rem;height:.7rem;transition:transform .2s ease;opacity:.7;}
.nav__item.is-open .nav__link svg{transform:rotate(180deg);}

.nav__right{display:flex;align-items:center;gap:1.5rem;flex:0 0 auto;}
.callus{display:flex;flex-direction:column;line-height:1.2;}
.callus__label{
  font-size:.6875rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  /* --grey-300 is .46 white, which was not readable over the photograph */
  color:rgba(255,255,255,.78);
}
.callus__dot{
  width:.4rem;height:.4rem;border-radius:50%;background:var(--lime);
  box-shadow:0 0 0 0 rgba(217,233,104,.6);
  animation:pulse 2.4s infinite;
}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(217,233,104,.55);}
  70%{box-shadow:0 0 0 .45rem rgba(217,233,104,0);}
  100%{box-shadow:0 0 0 0 rgba(217,233,104,0);}
}
.callus__number{
  display:flex;align-items:center;gap:.45rem;
  margin-top:.15rem;
  font-family:var(--font-head);
  font-size:1rem;font-weight:600;letter-spacing:-.01em;color:#fff;
  transition:color .18s ease;
}
.nav__right::before{
  content:"";
  order:1;
  width:1px;height:2rem;
  background:var(--hairline);
}
.callus{order:0;}
.nav__right .btn--white{order:2;}
.burger{order:3;}
.callus:hover .callus__number{color:var(--lime);}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  border-radius:var(--radius-full);
  font-family:var(--font-body);
  font-size:.95rem;font-weight:500;
  white-space:nowrap;
  padding:.85rem 1.6rem;
  transition:transform .18s ease, background-color .18s ease, color .18s ease, border-color .18s ease;
}
.btn:hover{transform:translateY(-1px);}
.btn--white{background:#fff;color:#101010;box-shadow:0 6px 18px rgba(0,0,0,.28);}
.btn--white:hover{background:var(--lime);}
.btn--lime{background:var(--lime);color:#101010;font-weight:600;padding:.75rem .75rem .75rem 1.75rem;font-size:1rem;}
.btn__arrow{
  display:inline-flex;align-items:center;justify-content:center;
  width:2.1rem;height:2.1rem;
  border-radius:50%;
  background:var(--ink-dark);
  color:var(--lime);
  font-size:.9rem;
  transition:transform .2s ease;
}
.btn--lime:hover .btn__arrow{transform:rotate(45deg);}
.btn--lime:hover{background:#fff;}
/* the lime button's shape in the purple that already runs through the
   campaign icons and the pricing tiers, for a section on paper where a second
   lime moment would compete with the hero's */
.btn--purple{
  background:#5B31C4;color:#fff;font-weight:600;
  padding:.75rem .75rem .75rem 1.75rem;font-size:1rem;
}
.btn--purple .btn__arrow{background:#fff;color:#5B31C4;}
.btn--purple:hover{background:#4A26A8;}
.btn--purple:hover .btn__arrow{transform:rotate(45deg);}
.btn--ink{background:var(--ink-dark);color:#fff;}
.btn--ink:hover{background:#2b2b33;}
.btn--ghost{
  background:rgba(20,20,20,.55);color:#fff;
  border:1px solid var(--hairline);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  padding:1.05rem 2rem;font-size:1rem;
}
.btn--ghost:hover{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.28);}

.stars{color:var(--star);letter-spacing:.06em;line-height:1;}
.hero__rating{
  display:inline-flex;align-items:center;gap:.85rem;
  margin:1.75rem 0 0;
  font-size:.875rem;
  color:var(--grey-100);
}
.hero__rating .stars{font-size:.875rem;letter-spacing:.08em;}
.hero__rating-text{display:flex;flex-direction:column;gap:.1rem;line-height:1.25;}
.hero__rating-text span:last-child{font-size:.875rem;color:var(--grey-200);}
.hero__rating-text strong{color:#fff;font-weight:600;}
.faces{display:flex;flex:0 0 auto;}
.face{
  width:2.5rem;height:2.5rem;
  border-radius:50%;
  overflow:hidden;
  margin-right:-.65rem;
  border:2px solid rgba(255,255,255,.9);
  box-shadow:0 2px 8px rgba(0,0,0,.4);
}
.face:last-child{margin-right:0;}
.face img{width:100%;height:100%;object-fit:cover;display:block;}

/* ---------- dropdowns ---------- */
.drop{
  position:absolute;
  top:calc(100% + .7rem);
  left:50%;
  transform:translate(-50%,.5rem);
  width:26rem;
  padding:.6rem;
  background:var(--panel);
  border:1px solid var(--hairline);
  border-radius:1.25rem;
  backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px);
  box-shadow:0 24px 60px rgba(0,0,0,.55);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .2s ease, transform .2s ease, visibility .2s;
}
.nav__item.is-open .drop{opacity:1;visibility:visible;pointer-events:auto;transform:translate(-50%,0);}
/* The panel opens .7rem below the pill, and mouseleave fires on .nav__item the
   moment the pointer crosses that gap — so the menu closed on the way to it.
   This bridges the gap with a transparent strip that is still inside the item,
   so the pointer never actually leaves. */
.nav__item.is-open::after{
  content:"";
  position:absolute;left:0;right:0;top:100%;
  height:.9rem;
}
/* a notch pointing back at the pill that opened it */
.drop::before{
  content:"";
  position:absolute;top:-.4rem;left:50%;
  width:.8rem;height:.8rem;
  transform:translateX(-50%) rotate(45deg);
  background:var(--panel);
  border-left:1px solid var(--hairline);
  border-top:1px solid var(--hairline);
  border-radius:.15rem 0 0 0;
}
.drop__link{
  display:block;
  padding:.85rem .95rem;
  border-radius:.85rem;
  transition:background-color .16s ease;
}
.drop__link{position:relative;}
.drop__link::before{
  content:"";
  position:absolute;left:.3rem;top:.6rem;bottom:.6rem;
  width:2px;border-radius:2px;background:var(--lime);
  opacity:0;transform:scaleY(.35);
  transition:opacity .16s ease, transform .16s ease;
}
.drop__link:hover{background:rgba(255,255,255,.07);}
.drop__link:hover::before{opacity:1;transform:scaleY(1);}
.drop__title{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  font-family:var(--font-head);
  font-size:1rem;font-weight:600;color:#fff;letter-spacing:-.01em;
}
.drop__title span:last-child{color:var(--lime);opacity:0;transform:translateX(-.25rem);transition:opacity .16s ease,transform .16s ease;}
.drop__link:hover .drop__title span:last-child{opacity:1;transform:translateX(0);}
.drop__desc{margin-top:.15rem;font-size:.875rem;color:var(--grey-200);line-height:1.4;}
.drop__foot{
  margin-top:.4rem;padding:.85rem .95rem;
  border-top:1px solid var(--hairline);
  display:flex;align-items:center;gap:.45rem;
  font-size:.875rem;color:var(--lime);font-weight:500;
}
.drop__foot:hover{text-decoration:underline;text-underline-offset:3px;}

/* ---------- mobile nav ---------- */
.burger{
  display:none;
  width:2.75rem;height:2.75rem;
  align-items:center;justify-content:center;
  border-radius:var(--radius-full);
  border:1px solid var(--hairline);
  background:rgba(20,20,20,.5);
}
.burger span{display:block;width:1.05rem;height:1.5px;background:#fff;position:relative;transition:transform .2s ease;}
.burger span::before,.burger span::after{
  content:"";position:absolute;left:0;width:1.05rem;height:1.5px;background:#fff;transition:transform .2s ease,opacity .2s ease;
}
.burger span::before{top:-.35rem;} .burger span::after{top:.35rem;}
.burger[aria-expanded="true"] span{transform:rotate(45deg);}
.burger[aria-expanded="true"] span::before{transform:rotate(-90deg) translateX(.35rem);}
.burger[aria-expanded="true"] span::after{opacity:0;}

/* ---------- hero content ---------- */
.hero__body{
  flex:1;
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:3rem;
  padding:2.25rem var(--edge) 2.75rem;
}
.hero__copy{max-width:48rem;animation:riseIn .9s .15s cubic-bezier(.16,1,.3,1) both;}
@keyframes riseIn{from{opacity:0;transform:translateY(1.25rem);}to{opacity:1;transform:none;}}

.eyebrow{
  display:flex;align-items:center;gap:.6rem;
  font-size:.8125rem;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--grey-100);
  margin-bottom:1.5rem;
}
.eyebrow::before{content:"";width:.4rem;height:.4rem;background:var(--lime);display:block;}

h1{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(2.25rem,4.1vw,4rem);
  line-height:1.04;
  letter-spacing:-.032em;
  font-weight:600;
  color:#fff;
}
.hero__lede{
  margin:0;
  max-width:34rem;
  font-size:1.0625rem;
  line-height:1.6;
  color:var(--grey-200);
}
.hero__actions{display:flex;flex-wrap:wrap;align-items:center;gap:1.25rem;margin-top:2.75rem;}
.hero__aside{
  max-width:24rem;
  flex:0 0 auto;
  animation:riseIn .9s .3s cubic-bezier(.16,1,.3,1) both;
}
.hero__proof{display:flex;align-items:center;gap:.85rem;margin-top:1.75rem;}
.hero__proof-label{
  margin:0;
  font-size:.75rem;
  font-weight:700;
  letter-spacing:.1em;
  line-height:1.4;
  text-transform:uppercase;
  color:#fff;
}
.hero__aside .hero__lede{max-width:none;font-size:1rem;}
.hero__call{
  font-size:.9375rem;
  color:var(--grey-200);
  text-decoration:underline;
  text-underline-offset:4px;
  text-decoration-color:rgba(255,255,255,.3);
  transition:color .18s ease, text-decoration-color .18s ease;
}
.hero__call:hover{color:#fff;text-decoration-color:rgba(255,255,255,.7);}


/* ---------- intro: statement + logos ---------- */
.approach{
  position:relative;
  /* isolate so the photo layer's negative z-index is clamped inside this
     section: it then paints above the section's own background and below
     its content, instead of dropping behind the ground entirely */
  isolation:isolate;
  /* butts against the lime ticker rather than floating below it, and runs to
     the viewport edge like the hero and the ticker do: the three read as one
     edge-to-edge block, and the rounded stack starts at .picker below it */
  margin:0 calc(var(--shell) * -1);
  /* deliberately neutral, not the plum the other dark sections use, and
     the top bloom is a plain white lift rather than a purple one */
  background:
    radial-gradient(ellipse 80% 70% at 50% 0%, rgba(255,255,255,.055) 0%, rgba(255,255,255,0) 64%),
    var(--surface);
  border-radius:0;
  padding:6.5rem 0 5.5rem;
  text-align:center;
  color:#fff;
  overflow:hidden;
}
.approach::before{
  content:"";
  position:absolute;inset:0;z-index:-1;
  pointer-events:none;
  /* Texture rather than a photograph. The photo that was here competed with
     the client logos sitting on it and with the tilted row of photographs
     below, which is three photographic layers in one section. This is four
     wide colour fields on the section's own dark ground, drawn in gradients
     so there is nothing to download, held well under half opacity and faded
     out at the edges. */
  opacity:.4;
  background:
    radial-gradient(ellipse 60% 55% at 16% 12%, rgba(124,58,237,.34) 0%, rgba(124,58,237,0) 70%),
    radial-gradient(ellipse 55% 50% at 86% 18%, rgba(56,132,255,.26) 0%, rgba(56,132,255,0) 68%),
    radial-gradient(ellipse 70% 60% at 70% 92%, rgba(236,72,153,.2) 0%, rgba(236,72,153,0) 72%),
    radial-gradient(ellipse 50% 45% at 22% 96%, rgba(217,233,104,.14) 0%, rgba(217,233,104,0) 70%);
  -webkit-mask-image:radial-gradient(ellipse 95% 88% at 50% 42%, #000 12%, rgba(0,0,0,.5) 58%, transparent 88%);
  mask-image:radial-gradient(ellipse 95% 88% at 50% 42%, #000 12%, rgba(0,0,0,.5) 58%, transparent 88%);
}
/* a fine diagonal grain over the fields, so the ground has a surface to it
   rather than reading as three flat washes */
.approach::after{
  content:"";
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  opacity:.5;
  background-image:repeating-linear-gradient(115deg,
    rgba(255,255,255,.028) 0 1px,
    rgba(255,255,255,0) 1px 7px);
}
.approach__statement strong{font-weight:700;}
/* .logo hardcodes a near-black, which would vanish on this ground */
.approach .logo{color:rgba(255,255,255,.74);}
.approach .logo:hover{color:#fff;}
.pill{
  display:inline-block;
  padding:.5rem 1.15rem .55rem;
  border:1.5px solid rgba(16,16,16,.3);
  border-radius:var(--radius-full);
  font-size:.75rem;
  font-weight:600;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-dark);
}
.approach__statement{
  margin:0 auto;
  /* --edge resolves 100% against this element's containing block, not the
     viewport. Combined with max-width + border-box that lets the padding
     eat the whole column past ~1600px, so use the plain gutter: the box is
     already capped and centred and needs no viewport-edge maths. */
  padding:0 var(--gutter);
  max-width:74rem;
  font-family:var(--font-head);
  font-size:clamp(1.5rem,2.2vw,2.25rem);
  line-height:1.34;
  letter-spacing:-.024em;
  font-weight:600;
  color:#fff;
  text-wrap:pretty;
}
.approach .marquee{max-width:74rem;margin:4rem auto 0;}

/* ---------- logo marquee ---------- */
.marquee{
  position:relative;
  overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 1.5rem,#000 calc(100% - 1.5rem),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 1.5rem,#000 calc(100% - 1.5rem),transparent 100%);
}
.marquee__track{
  display:flex;
  width:max-content;
  animation:marquee 46s linear infinite;
}
.marquee:hover .marquee__track{animation-play-state:paused;}
@keyframes marquee{to{transform:translateX(-50%);}}
.marquee__set{display:flex;align-items:center;gap:8rem;padding-right:8rem;}
.logo{display:flex;align-items:center;flex:0 0 auto;}
/* every supplied logo flattened to white: four of them are black artwork
   and would otherwise vanish on this ground, and normalising the lot is
   what makes a mixed set read as one wall */
.logo img{
  display:block;
  /* fitted to a box, not sized by height: the wordmarks run as wide as
     12:1 and would otherwise tower over the square marks */
  max-height:2.5rem;max-width:10rem;
  width:auto;height:auto;
  object-fit:contain;
  filter:brightness(0) invert(1);
  opacity:.78;
  transition:opacity .2s ease;
}
.logo:hover img{opacity:1;}

/* ---------- channel picker ---------- */
.picker{
  position:relative;
  margin-top:var(--shell);
  padding:6rem var(--edge) 6.5rem;
  background:var(--paper);
  border-radius:var(--radius-main);
  overflow:hidden;
}
.picker__head{max-width:56rem;margin:0 auto;text-align:center;}
.picker h2{text-wrap:balance;
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(1.875rem,3.2vw,3rem);
  line-height:1.08;
  letter-spacing:-.03em;
  font-weight:600;
  color:var(--ink-dark);
}
.picker__lede{
  margin:1.15rem auto 0;
  max-width:34rem;
  font-size:1.0625rem;
  line-height:1.6;
  color:#54545a;
}
.picker__grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:1rem;
  margin-top:3.5rem;
}
.pick{
  position:relative;
  display:flex;
  flex-direction:column;
  justify-content:flex-end;
  min-height:0;
  padding:0;
  border:1px solid rgba(0,0,0,.09);
  border-radius:1.25rem;
  overflow:hidden;
  background:#fff;
  box-shadow:0 8px 24px rgba(0,0,0,.07);
  transition:border-color .2s ease, transform .2s ease, background-color .2s ease, box-shadow .2s ease;
}
.pick:hover{border-color:rgba(0,0,0,.16);background:#fff;transform:translateY(-4px);box-shadow:0 16px 36px rgba(0,0,0,.12);}
/* a span with a background rather than an <img>: the same three
   photographs front the services carousel, and held as tokens they are
   inlined once instead of twice */
/* The whole frame, not a crop of one. The band takes the source's own 3:2, so
   the photograph fills it edge to edge with nothing cut off and no letterbox
   bars - which is what every previous attempt at this slot got wrong, because
   the slot was portrait and every photograph we have is landscape. */
.pick__shot{
  display:block;
  aspect-ratio:3 / 2;
  overflow:hidden;
  background:#E7E6E2;
}
.pick__shot img{
  width:100%;height:100%;display:block;
  object-fit:cover;
  transition:transform .6s cubic-bezier(.16,1,.3,1);
}
.pick:hover .pick__shot img{transform:scale(1.04);}
.pick__hover{
  position:absolute;inset:0;z-index:3;
  display:flex;align-items:center;justify-content:center;
  padding:1.5rem;
  background:rgba(250,250,249,.88);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  opacity:0;
  pointer-events:none;
  transition:opacity .25s ease;
}
.pick__hover-btn{
  display:inline-flex;align-items:center;gap:.6rem;
  padding:1.05rem 1.65rem;
  border-radius:var(--radius-full);
  background:var(--lime);
  color:var(--ink-dark);
  font-family:var(--font-head);
  font-size:1rem;
  font-weight:600;
  letter-spacing:-.015em;
  text-align:center;
  transform:translateY(.5rem);
  transition:transform .25s ease;
}
.pick__hover-arrow{font-size:.95rem;}
@media (hover:hover){
  .pick:hover .pick__hover,.pick:focus-visible .pick__hover{opacity:1;}
  .pick:hover .pick__hover-btn,.pick:focus-visible .pick__hover-btn{transform:translateY(0);}
}
.pick__panel{
  position:relative;
  z-index:2;
  background:#fff;
  padding:1.5rem 1.5rem 1.6rem;
  color:var(--ink-dark);
}
.pick__num{
  position:absolute;
  top:1rem;left:1rem;
  z-index:2;
  display:inline-flex;align-items:center;
  height:2.1rem;
  padding:0 .85rem;
  gap:.4rem;
  border-radius:var(--radius-full);
  background:var(--lime);
  color:var(--ink-dark);
  font-family:var(--font-body);
  font-size:.6875rem;
  font-weight:700;
  letter-spacing:.1em;
  text-transform:uppercase;
  white-space:nowrap;
}
.pick__num i{font-style:normal;opacity:.45;}
.pick__title{
  margin:0;
  min-height:2.4em;
  font-family:var(--font-head);
  font-size:1.75rem;
  line-height:1.2;
  letter-spacing:-.022em;
  font-weight:700;
  text-wrap:balance;
  color:var(--ink-dark);
}
.pick__desc{
  margin:.5rem 0 0;
  text-wrap:pretty;
  font-size:1rem;
  line-height:1.45;
  color:#4f4f4f;
}
.pick__chips{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.9rem;}
.pick__chips span{
  display:inline-flex;align-items:center;
  padding:.4rem .7rem;
  border-radius:var(--radius-full);
  background:var(--chip-bg);
  color:var(--chip-ink);
  font-size:.75rem;
  font-weight:600;
  letter-spacing:-.005em;
  white-space:nowrap;
}
.pick--leads{--chip-bg:#E8FCA6;--chip-ink:#2F3D00;}
.pick--aware{--chip-bg:#E6E1FA;--chip-ink:#2A1D63;}
.pick--organic{--chip-bg:#DCEEF6;--chip-ink:#123A4C;}

/* ---------- faq ---------- */
.faq{
  margin-top:var(--shell);
  background:
    radial-gradient(52% 62% at 100% 100%, rgba(var(--purple-accent),.06) 0%, rgba(var(--purple-accent),0) 68%),
    var(--paper);
  /* no rounding: it sat as a card inside the page with its corners cut into
     the sections either side of it */
  border-radius:0;
  margin-left:calc(var(--shell) * -1);
  margin-right:calc(var(--shell) * -1);
  padding:clamp(3.5rem,6vw,5.5rem) var(--edge);
}
.faq__inner{
  display:grid;
  grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  grid-template-rows:auto 1fr;
  gap:0 4rem;
  align-items:start;
  max-width:var(--max);margin:0 auto;
}
/* Three children in a two-column grid, so they are placed rather than left to
   flow: adding the photograph put it in column two and bumped the list to a
   new row in column one.
   The heading and its CTA follow the list rather than scrolling away from it:
   the answer you are reading is often the one that decides the click. */
.faq__side{position:sticky;top:2.5rem;grid-column:1;grid-row:2;}
.faq__list{grid-column:2;grid-row:1 / 3;}
.faq__side p{margin:1.15rem 0 0;max-width:26rem;font-size:1rem;line-height:1.6;color:#54545a;}
.faq h2{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(1.75rem,2.9vw,2.75rem);
  line-height:1.1;
  letter-spacing:-.03em;
  font-weight:600;
  color:var(--ink-dark);
}
.faq__side .btn{margin-top:2rem;}
.faq__tel{
  display:block;margin-top:1.15rem;
  font-size:.9375rem;color:#54545a;
  transition:color .16s ease;
}
.faq__tel:hover{color:var(--ink-dark);}
/* over the heading column only, not across both */
.faq__shot{
  grid-column:1;grid-row:1;
  margin:0 0 1.75rem;
  border-radius:1.25rem;overflow:hidden;
  background:#E7E6E2;
  box-shadow:0 1px 2px rgba(0,0,0,.05), 0 14px 34px rgba(0,0,0,.08);
}
.faq__shot img{aspect-ratio:21/9;}
.faq__shot img{width:100%;height:auto;display:block;aspect-ratio:16/9;object-fit:cover;}
.faq__list{display:flex;flex-direction:column;gap:.75rem;}
.qa{
  background:#fff;
  border:1px solid rgba(18,18,18,.1);
  border-radius:1rem;
  transition:border-color .2s ease,background-color .2s ease,box-shadow .2s ease;
}
.qa:hover{border-color:rgba(18,18,18,.22);}
.qa[open]{
  border-color:rgba(18,18,18,.14);
  box-shadow:0 1px 2px rgba(0,0,0,.05), 0 12px 30px rgba(0,0,0,.07);
}
.qa summary{
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  padding:1.35rem 1.5rem;
  cursor:pointer;
  list-style:none;
  font-family:var(--font-head);
  font-size:clamp(1.125rem,1.45vw,1.3125rem);
  font-weight:700;
  letter-spacing:-.022em;
  color:var(--ink-dark);
}
.qa summary::-webkit-details-marker{display:none;}
/* the focus ring belongs on the row, not on the text node inside it */
.qa summary:focus-visible{outline:2px solid var(--lime);outline-offset:2px;border-radius:1rem;}
.qa[open] summary{padding-bottom:1rem;}
.qa__icon{position:relative;width:1rem;height:1rem;flex:0 0 auto;}
.qa__icon::before,.qa__icon::after{
  content:"";position:absolute;left:0;top:50%;
  width:1rem;height:1.5px;background:var(--ink-dark);
  transition:transform .25s ease;
}
.qa__icon::after{transform:rotate(90deg);}
.qa[open] .qa__icon::after{transform:rotate(0deg);}
.qa[open] .qa__icon::before,.qa[open] .qa__icon::after{background:var(--lime);}
.qa__body{
  padding:0 1.5rem 1.5rem;
  max-width:46rem;
  font-size:1rem;
  line-height:1.7;
  color:#54545a;
}
.qa__body p{margin:0;}
.qa__body p + p{margin-top:.75rem;}

@media (max-width:1280px){
  .pick__title{font-size:1.35rem;min-height:2.4em;}
  .pick__desc{font-size:.9375rem;}
  .pick__chips span{font-size:.6875rem;padding:.35rem .6rem;}
}
@media (max-width:1024px){
  .approach{padding:4.5rem 0 3.5rem;}
  .approach .marquee{margin:3rem auto 0;}
  .picker{padding:5rem var(--edge) 5.5rem;}
  .picker__grid{grid-template-columns:1fr;gap:.75rem;margin-top:2.75rem;}
  .pick{min-height:30rem;}
  .pick__title{min-height:0;}
  .faq{padding:4rem var(--edge) 4.5rem;}
  /* stacked, so the explicit placements have to be released or every child
     fights for the same cell */
  .faq__inner{grid-template-columns:1fr;grid-template-rows:none;gap:2rem;}
  .faq__shot,.faq__side,.faq__list{grid-column:auto;grid-row:auto;}
  .faq__side{position:static;}
  /* the heading sticks beside the list on desktop. In one column there is
     nothing to sit beside, and sticky left it riding over the questions */
  .faq__side{position:static;}
  .faq__side .btn{margin-top:1.5rem;}
  .marquee{
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 1rem,#000 calc(100% - 1rem),transparent 100%);
    mask-image:linear-gradient(90deg,transparent 0,#000 1rem,#000 calc(100% - 1rem),transparent 100%);
  }
}
@media (max-width:640px){
  .approach{padding:3.25rem 0 2.75rem;}
  .approach__statement{font-size:1.375rem;line-height:1.4;}
  .approach .marquee{margin:2.25rem auto 0;}
  .marquee__set{gap:4rem;padding-right:4rem;}
    .picker{padding:3.5rem var(--edge) 4rem;}

  .pick{min-height:30rem;}
  .pick__panel{padding:1.25rem 1.25rem 1.35rem;}
  .pick__num{height:1.9rem;font-size:.625rem;padding:0 .7rem;top:.75rem;left:.75rem;}
  .faq{padding:3rem var(--edge) 3.5rem;}
  .qa summary{padding:1.15rem 1.15rem;font-size:1rem;gap:1rem;}
  .qa__body{padding:0 1.15rem 1.25rem;}
  .faq__side .btn{width:100%;}
}

/* ---------- mobile ---------- */
.mobile{display:none;}

@media (max-width:1180px){
  .nav{gap:1rem;padding:1.25rem var(--edge);}
  .nav__link{padding:.6rem .7rem;font-size:.9375rem;}
}
@media (max-width:1024px){
  .nav__menu,.callus,.nav__right .btn{display:none;}
  .burger{display:flex;}
  .nav__right{margin-left:auto;}
  .hero__body{flex-direction:column;align-items:flex-start;justify-content:flex-end;padding:2rem var(--edge) 2rem;}
  .hero__aside{max-width:34rem;}
}
@media (max-width:640px){
  .hero__scrim{
    background:
      linear-gradient(0deg,
        rgba(var(--scrim),.95) 0%,
        rgba(var(--scrim),.9) 20%,
        rgba(var(--scrim),.82) 42%,
        rgba(var(--scrim),.5) 62%,
        rgba(var(--scrim),.18) 78%,
        rgba(var(--scrim),0) 92%),
      linear-gradient(180deg,
        rgba(var(--scrim),.9) 0%,
        rgba(var(--scrim),.65) 5%,
        rgba(var(--scrim),.3) 10%,
        rgba(var(--scrim),0) 16%);
  }
  .hero__rating{font-size:.875rem;margin-top:1.25rem;}
  :root{--shell:.65rem;--radius-main:1.25rem;}
  .hero__body{padding:1.75rem var(--edge) 1.75rem;gap:1.5rem;}
  .hero__actions{margin-top:1.75rem;gap:.6rem;}
  .hero__actions{gap:1rem;}
  .hero__actions .btn{width:100%;}
  .hero__call{width:100%;text-align:center;}
  h1{font-size:2.375rem;line-height:1.04;}
  .hero__lede{margin-top:1.15rem;}
  .eyebrow{font-size:.6875rem;letter-spacing:.12em;margin-bottom:1.1rem;}
  .hero__lede{font-size:1rem;}
}

.mobile{
  position:fixed;inset:0;z-index:90;
  background:rgba(10,10,10,.97);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  padding:1.25rem;
  overflow-y:auto;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .22s ease,visibility .22s;
}
.mobile.is-open{display:block;opacity:1;visibility:visible;pointer-events:auto;}
@media (max-width:1024px){.mobile{display:block;}}
.mobile > *{max-width:var(--max);margin-inline:auto;}
.mobile__head{display:flex;align-items:center;justify-content:space-between;padding:.25rem .25rem 1.5rem;}
.mobile__head svg{height:1.6rem;width:auto;}
.mobile__close{width:2.75rem;height:2.75rem;border-radius:50%;border:1px solid var(--hairline);display:flex;align-items:center;justify-content:center;font-size:1.35rem;line-height:1;}
.mobile__group{border-top:1px solid var(--hairline);padding:1.25rem .25rem;}
.mobile__label{font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;color:var(--grey-300);margin-bottom:.85rem;}
.mobile__link{display:block;padding:.65rem 0;}
.mobile__link .drop__title{font-size:1.0625rem;}
.mobile__solo{
  display:block;padding:1rem .25rem;
  font-family:var(--font-head);font-size:1.25rem;font-weight:600;
  border-top:1px solid var(--hairline);
}
.mobile__foot{display:flex;flex-direction:column;gap:.75rem;padding:1.5rem .25rem 2rem;border-top:1px solid var(--hairline);}
.mobile__foot .btn{width:100%;padding:1rem;}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;}
  .marquee__track{animation:none!important;}
  .ticker__track{animation:none!important;}
  .hero__media{transform:none;}
}

/* ---------- split hero ---------- */
.hero{
  position:relative;
  /* full bleed: the shell padding is cancelled on the top and both sides so the
     hero runs to the viewport edge with no rounding, the way a classic hero
     does. The rounded stack starts below the ticker instead. */
  margin:calc(var(--shell) * -1) calc(var(--shell) * -1) 0;
  border-radius:0;
  background:
    radial-gradient(ellipse 105% 95% at -5% 105%, #3A1C74 0%, #2A1458 30%, rgba(28,23,41,0) 68%),
    #1C1729;
  min-height:0;
  overflow:hidden;
}
.hero::after{
  content:"";
  position:absolute;
  inset:0;
  opacity:.5;
  pointer-events:none;
  background-image:radial-gradient(rgba(255,255,255,.14) 1px, transparent 1px);
  background-size:26px 26px;
  -webkit-mask-image:radial-gradient(ellipse 130% 130% at 0% 100%, #000 22%, rgba(0,0,0,.75) 62%, rgba(0,0,0,.6) 100%);
  mask-image:radial-gradient(ellipse 130% 130% at 0% 100%, #000 22%, rgba(0,0,0,.75) 62%, rgba(0,0,0,.6) 100%);
}
.hero > *{position:relative;z-index:1;}
.hero > .nav{z-index:40;}
/* the hero is the purple gradient alone; these two belong to the full-bleed
   hero variant this page does not use */
.hero__media,.hero__scrim{display:none;}
.hero__body{
  display:grid;
  grid-template-columns:minmax(0,.88fr) minmax(0,1.22fr);
  align-items:center;
  gap:4rem;
  padding:3.5rem var(--edge) 4.5rem;
}
.hero__copy{max-width:38rem;}
.hero__rating{
  display:inline-flex;align-items:center;gap:.7rem;
  margin:0 0 1.75rem;
  padding:.4rem 1rem .4rem .45rem;
  border:1px solid var(--hairline);
  border-radius:var(--radius-full);
  background:rgba(255,255,255,.06);
  font-size:.875rem;
  color:var(--grey-100);
}
.hero__rating .faces{display:flex;margin-right:.35rem;}
.hero__rating .face{width:1.7rem;height:1.7rem;border-width:2px;margin-right:-.5rem;}
.hero__rating .face:last-child{margin-right:0;}
.hero__rating .stars{font-size:.8125rem;}
.hero h1{font-size:clamp(2.25rem,3.6vw,3.6rem);line-height:1.05;}
.hl{color:var(--lime);}
.hero__lede{margin:1.5rem 0 0;max-width:30rem;}
.hero__actions{margin-top:2.25rem;}

.hero__media-card{
  position:relative;
  border-radius:1.5rem;
  overflow:visible;
}
.hero__media-card img,
.hero__media-card .hero__video{
  width:100%;
  height:auto;
  /* 15% taller than the 16/10 it was, which is what makes the whole hero
     section grow with it */
  aspect-ratio:16 / 11.5;
  object-fit:cover;
  border-radius:1.5rem;
  display:block;
  background:var(--ink-dark);
}
/* the reel is a 16/9 master in a 16/11.5 frame, so cover trims the sides
   rather than the heads */
.hero__media-card .hero__video{object-position:50% 45%;}

@media (max-width:1024px){
  .hero__body{
    grid-template-columns:1fr;
    gap:2.5rem;
    padding:2.5rem var(--edge) 3rem;
  }
  .hero__copy{max-width:none;}
  }
@media (max-width:640px){
  .hero__body{padding:2rem var(--edge) 2.5rem;}
  .hero__rating{font-size:.8125rem;}
  }

/* ---------- services overview carousel ----------
   A sticky copy column against a horizontally scrolling rail of photo
   cards, which bleeds off the right edge so it reads as a rail rather than
   a row that happens to fit. The four photographs are the tokens the
   channel picker already carries, so this section adds no image weight.
   Real photographs rather than the invented platform tiles: those still do
   their job one section down, where there is room to read them. */
.svc{
  margin-top:var(--shell);
  /* symmetric edges: the old left-only padding with the inset carried on the
     inner box centred the grid inside an off-centre content box, which read
     as fine at 1440 and drifted right by nearly 90px on a 1920 screen */
  padding:clamp(3.5rem,6vw,6rem) var(--edge);
  border-radius:var(--radius-main);
  background:var(--paper);
  color:var(--ink-dark);
  overflow:hidden;
}
/* one centred column: the head sits over the panels rather than beside them,
   which puts the whole section on one axis and gives the four mockups the
   width they need to be legible */
.svc__inner{
  display:block;
  max-width:74rem;
  margin:0 auto;
}
.svc__aside{
  position:static;
  display:flex;flex-direction:column;align-items:center;
  text-align:center;
  margin:0 auto clamp(2.5rem,4vw,3.5rem);
  /* the one column every centred section head uses */
  max-width:56rem;
}
.svc__aside h2{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(1.875rem,3.2vw,2.875rem);
  line-height:1.05;letter-spacing:-.035em;font-weight:600;
  text-wrap:balance;
}
.svc__lede{margin:1.25rem auto 0;max-width:46rem;font-size:1.0625rem;line-height:1.6;color:#54545a;text-wrap:balance;}
.svc__aside .btn{margin-top:2rem;}
.svc__aside .btn svg{width:1rem;height:1rem;transition:transform .18s ease;}
.svc__aside .btn:hover svg{transform:translateX(.2rem);}

/* ---- the four services, as a static 2x2 grid ----
   This used to be a horizontal rail that the page scroll dragged sideways
   while the section was pinned. It read as a scroller you had to fight, and
   a card could only carry a title. A grid shows all four at once and leaves
   room for what each one is actually used for. The pin CSS, the rail, the
   thumbnail controls and the scroll script that drove them are all gone. */
/* Two shared tracks - the mock band, then the card body - and each card spans
   both with grid-template-rows:subgrid. That is what makes the four bands one
   height: they share a single row sized to the tallest mock, instead of each
   card sizing its own band and the row coming out ragged. */
/* The row tracks have to match the number of card ROWS, not the number of
   cards: each card spans two of them. Four cards in two columns is two card
   rows, so four tracks. Declaring two left the second pair with no tracks to
   subgrid onto and the section blew out to 1369px tall. */
.svc__grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  grid-template-rows:repeat(4,auto);
  gap:1.15rem;
}
.sgrid{
  display:grid;
  grid-row:span 2;
  grid-template-rows:subgrid;
  overflow:hidden;
  border-radius:1.1rem;
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.05), 0 10px 28px rgba(0,0,0,.06);
  color:var(--ink-dark);
  transition:transform .2s ease, box-shadow .2s ease;
}
.sgrid:hover,.sgrid:focus-visible{
  transform:translateY(-3px);
  box-shadow:0 2px 4px rgba(0,0,0,.07), 0 18px 44px rgba(0,0,0,.12);
}
/* ---- the platform mockups ----
   Each card's photograph stays as ground, and a mock of the surface that
   service actually works on floats on top of it: a sponsored search result,
   a feed ad, an organic listing at position one, an earned press mention.

   The advertiser in every one is "Your Business" on yourbusiness.com.au.
   These are demonstrations on an agency's own site, so they must not read as
   a real company's ad - the layout is the point, not the name in it. */
/* The ground behind each mock. It was a stock photograph of somebody at a
   laptop, which competed with the mock in front of it and said nothing.
   It is a dark aura now: four soft colour fields on near-black, rotated per
   card so the row reads as a set without repeating. Drawn in gradients, so
   there is nothing to download and nothing to go out of date. */
.sgrid__ph{
  position:relative;
  /* No fixed ratio. At four across the column is ~340px and the search ad and
     the creative fan both outgrow any ratio that suits the others, and the
     band clips silently because it hides its overflow. It takes the mock's
     own height instead, with a floor so a short one still has presence. */
  min-height:13rem;
  display:flex;align-items:center;justify-content:center;
  padding:1.6rem 1.1rem;
  overflow:hidden;
  background:#120F1C;
}
/* The aura lives entirely on this layer, and so does the hue rotation. Put
   the filter on .sgrid__ph itself and it applies to every descendant too -
   it turned the search result's link purple and the masthead olive. */
.sgrid__ph::before{
  content:"";position:absolute;inset:-14%;
  background:
    radial-gradient(ellipse 58% 62% at 14% 16%, rgba(124,58,237,.78) 0%, rgba(124,58,237,0) 68%),
    radial-gradient(ellipse 52% 56% at 86% 22%, rgba(236,72,153,.5) 0%, rgba(236,72,153,0) 66%),
    radial-gradient(ellipse 64% 58% at 74% 92%, rgba(56,132,255,.54) 0%, rgba(56,132,255,0) 70%),
    radial-gradient(ellipse 44% 44% at 18% 96%, rgba(217,233,104,.26) 0%, rgba(217,233,104,0) 66%);
  filter:blur(34px) saturate(1.3);
}
.sgrid__ph::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg, rgba(10,8,16,.34) 0%, rgba(10,8,16,.54) 100%);
}
/* each card turns the aura, so the four are one family and no two the same */
.srow:nth-of-type(2) .sgrid__ph::before{filter:blur(34px) saturate(1.3) hue-rotate(-42deg);}
.srow:nth-of-type(3) .sgrid__ph::before{filter:blur(34px) saturate(1.3) hue-rotate(58deg);}
.srow:nth-of-type(4) .sgrid__ph::before{filter:blur(34px) saturate(1.3) hue-rotate(160deg);}
.viz{
  position:relative;z-index:1;
  /* inset from the band's own padding as well, so a margin of the
     photograph shows down both sides of every mock, not just the Meta one */
  display:block;width:86%;margin:0 auto;
  font-family:var(--font-body);
}
.viz span,.viz em,.viz b,.viz i{display:block;}

/* the search box the sponsored and organic mocks sit under */
.viz__omni{
  display:flex!important;align-items:center;gap:.5rem;
  margin-bottom:.5rem;
  padding:.45rem .7rem;
  border-radius:99px;
  background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.18);
}
.viz__gm{flex:0 0 auto;display:flex!important;}
.viz__gm img{width:.9rem;height:.9rem;display:block;}
.viz__q{
  min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
  font-size:.75rem;color:#3c4043;
}

/* the result itself */
.viz__card{
  position:relative;
  padding:.85rem .9rem;
  border-radius:.7rem;
  background:#fff;
  box-shadow:0 2px 6px rgba(0,0,0,.14), 0 18px 40px rgba(0,0,0,.24);
  text-align:left;
}
.viz__badge{
  display:inline-block!important;
  margin-bottom:.5rem;
  padding:.16rem .5rem;
  border-radius:.25rem;
  background:#202124;color:#fff;
  font-size:.6875rem;font-weight:700;letter-spacing:.02em;
}
.viz__brand{display:flex!important;align-items:center;gap:.45rem;}
.viz__fav{
  width:1.35rem;height:1.35rem;flex:0 0 auto;border-radius:50%;
  display:flex!important;align-items:center;justify-content:center;
  background:#202124;color:#fff;
  font-size:.6875rem;font-weight:700;line-height:1;
}
.viz__fav--r{border-radius:50%;background:linear-gradient(140deg,#6E33E8,#B15CFF);}
.viz__site{min-width:0;}
.viz__site b{font-size:.75rem;font-weight:600;color:#202124;line-height:1.25;}
.viz__site i{
  font-style:normal;font-size:.6875rem;color:#5f6368;line-height:1.25;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
.viz__hl{
  margin-top:.5rem;
  font-size:.9375rem;line-height:1.25;letter-spacing:-.008em;
  color:#1a0dab;
  text-wrap:balance;
}
.viz__hl--org{color:#1a0dab;}
.viz__desc{
  margin-top:.3rem;
  font-size:.75rem;line-height:1.45;color:#4d5156;
}
.viz__links{
  display:flex!important;flex-wrap:wrap;gap:.25rem .9rem;
  margin-top:.55rem;
}
.viz__links em{
  font-style:normal;font-size:.75rem;color:#1a0dab;
}

/* Google Advertising: two ad formats, layered.
   A single search result did not read as advertising at a glance, so the
   Sponsored label is now the loudest thing on the card and a Shopping ad sits
   behind it on an angle - the same treatment the Meta card uses, and the two
   formats together say what the service is without a word of copy. */
/* In flow, not absolutely placed. Placed absolutely the shopping card sat on
   top of the search box and the two collided the moment the column narrowed
   and the search ad grew taller. Stacked with a negative margin they overlap
   by a fixed amount at every width. */
.gfan{position:relative;display:flex;flex-direction:column;}
.gshop{
  position:relative;z-index:1;align-self:stretch;
  margin:0 4% -.2rem 6%;
  padding:.7rem .75rem;
  border-radius:.6rem;background:#fff;
  box-shadow:0 2px 6px rgba(0,0,0,.16), 0 14px 32px rgba(0,0,0,.22);
  transform:rotate(2.4deg);
  text-align:left;
}
.gshop__row{display:flex!important;gap:.45rem;margin-top:.45rem;}
.gshop__p{flex:1 1 0;min-width:0;}
/* the tiles read as product photography rather than as images that failed
   to load: a tint, a soft inner edge and a highlight, which is as far as a
   mock should go without putting a real product in it */
.gshop__im{
  height:3rem;border-radius:.35rem;
  background:
    radial-gradient(ellipse 70% 55% at 30% 22%, rgba(255,255,255,.75), rgba(255,255,255,0) 62%),
    linear-gradient(150deg,#E4E7EC,#C9CFD9);
  box-shadow:inset 0 0 0 1px rgba(32,33,36,.08);
}
.gshop__im--2{background:radial-gradient(ellipse 70% 55% at 30% 22%, rgba(255,255,255,.75), rgba(255,255,255,0) 62%),linear-gradient(150deg,#DFE8F2,#B9C8DC);}
.gshop__im--3{background:radial-gradient(ellipse 70% 55% at 30% 22%, rgba(255,255,255,.75), rgba(255,255,255,0) 62%),linear-gradient(150deg,#EAE4D6,#CFC6AE);}
.gshop__p b{margin-top:.3rem;font-size:.6875rem;font-weight:700;color:#202124;}
.gshop__p i{
  font-style:normal;font-size:.625rem;color:#5f6368;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
.gsearch{
  position:relative;z-index:2;
  transform:rotate(-1.2deg);
  margin:0 6% 0 0;
}

/* Meta: three of the real creatives, fanned.
   Not a mock of the Instagram frame - the chrome said nothing the card does
   not, and three pieces of actual work say more about the service than one
   piece inside a borrowed interface. The middle one sits upright and in
   front; the outer two are rotated behind it and scaled back.

   The files are screenshots of the posts rather than the original exports,
   so the two on the right are trimmed of the carousel chevron and the dot
   indicators. Their right edge was already clipped by the screenshot itself. */
/* the box takes the band's own ratio, and the three sit inside it by
   percentage, so the fan scales with the card and never outgrows the band */
.fan{
  position:relative;display:block;
  width:100%;
  aspect-ratio:16 / 11;
}
.fan img{
  position:absolute;
  width:40%;height:auto;
  border-radius:.4rem;
  /* the hairline is load-bearing: one of the three is a near-white creative
     and without an edge it disappeared into the photograph behind it */
  box-shadow:
    0 0 0 1px rgba(255,255,255,.18),
    0 2px 6px rgba(0,0,0,.24),
    0 14px 30px rgba(0,0,0,.34);
  transform-origin:50% 50%;
}
.fan__a{left:2%;top:13%;transform:rotate(-8deg);}
.fan__c{left:59%;top:13%;transform:rotate(8deg);}
.fan__b{
  z-index:2;
  left:29.5%;top:1%;width:41%;
  transform:rotate(-1.5deg);
  box-shadow:
    0 0 0 1px rgba(255,255,255,.22),
    0 3px 8px rgba(0,0,0,.28),
    0 20px 42px rgba(0,0,0,.4);
}

/* SEO: position one, and what it moved */
.viz__pos{
  position:absolute;top:-.55rem;left:-.55rem;
  width:1.6rem;height:1.6rem;border-radius:50%;
  display:flex!important;align-items:center;justify-content:center;
  background:var(--lime);color:var(--ink-dark);
  font-size:.8125rem;font-weight:700;line-height:1;
  box-shadow:0 2px 6px rgba(0,0,0,.2);
}
.viz__moved{
  margin-top:.55rem;padding-top:.5rem;
  border-top:1px solid rgba(0,0,0,.08);
  font-size:.6875rem;color:#5f6368;
}
.viz__moved b{display:inline!important;color:#1E8E3E;font-weight:700;}

/* Link building: an earned mention with the anchor lit up */
.viz__masthead{
  font-family:var(--font-head);
  font-size:.6875rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:#6E33E8;
}
.viz__hl--press{
  margin-top:.4rem;
  font-family:var(--font-head);
  font-size:1rem;font-weight:700;line-height:1.2;letter-spacing:-.022em;
  color:#202124;
}
.viz__anchor{
  display:inline!important;font-style:normal;
  color:#1a0dab;text-decoration:underline;text-underline-offset:.15em;
  background:rgba(217,233,104,.45);
  border-radius:.15rem;
  padding:0 .1rem;
}
.viz__tags{display:flex!important;flex-wrap:wrap;gap:.35rem;margin-top:.6rem;}
.viz__tags em{
  font-style:normal;
  padding:.16rem .45rem;border-radius:99px;
  background:rgba(18,18,18,.06);
  font-size:.625rem;font-weight:700;letter-spacing:.04em;color:#5f6368;
}


.sgrid__body{display:flex;flex-direction:column;flex:1 1 auto;padding:1.35rem 1.5rem 1.5rem;}
.sgrid h3{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(1.25rem,1.6vw,1.5rem);
  line-height:1.15;letter-spacing:-.028em;font-weight:700;
  text-wrap:balance;
}
.sgrid__list{
  margin:.9rem 0 0;padding:0;list-style:none;
  display:grid;gap:.6rem;
}
.sgrid__list li{
  position:relative;
  padding-left:1.35rem;
  font-size:.9375rem;line-height:1.5;color:#54545a;
}
.sgrid__list li::before{
  content:"";
  position:absolute;left:0;top:.52em;
  width:.45rem;height:.45rem;border-radius:50%;
  background:var(--lime);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
}
.sgrid__go{
  display:inline-flex;align-items:center;gap:.4rem;
  margin-top:auto;padding-top:1.25rem;
  font-size:.9375rem;font-weight:600;color:var(--ink-dark);
}
.sgrid__go svg{width:.95rem;height:.95rem;transition:transform .18s ease;}
.sgrid:hover .sgrid__go svg{transform:translateX(.2rem);}

@media (max-width:620px){
  .svc__grid{grid-template-columns:minmax(0,1fr);grid-template-rows:repeat(8,auto);}
}


/* Below this the card is too narrow for the mock to fit a 16/11 box, and the
   band clips it - overflow:hidden stops the content forcing the box taller,
   so nothing complains, it just cuts the ad in half. Measured card by card:
   the first overflow appears at 900px. The band gives up its ratio there and
   takes the mock's own height instead. */
@media (max-width:640px){
  .svc{padding:2.75rem 1.35rem 3rem;}
}

/* ---------- strategy call ----------
   The panel used to be a white card inside the plum card, with a third
   bordered card inside that. Three nested containers to say one thing.
   Now the copy sits straight on the plum and the booking card is the only
   card in the section, so there is exactly one object to look at. */
.call{
  position:relative;isolation:isolate;
  margin-top:var(--shell);
  padding:clamp(2.75rem,5.5vw,5.5rem) var(--edge);
  border-radius:var(--radius-main);
  background:
    radial-gradient(ellipse 62% 70% at 8% 0%, rgba(var(--purple-accent),.30) 0%, rgba(var(--purple-accent),0) 62%),
    radial-gradient(ellipse 50% 60% at 100% 100%, rgba(255,111,196,.10) 0%, rgba(255,111,196,0) 60%),
    #1C1729;
  color:#fff;
  overflow:hidden;
}
/* the brand pixel motif as ground texture rather than a corner sticker:
   masked out before it reaches the copy so it never competes with it */
.call__pips{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  color:var(--lime);opacity:.14;
  background-image:
    radial-gradient(currentColor 1.5px, transparent 1.5px),
    radial-gradient(currentColor 1.5px, transparent 1.5px);
  background-size:22px 22px, 22px 22px;
  background-position:0 0, 11px 11px;
  -webkit-mask-image:radial-gradient(ellipse 60% 90% at 100% 8%, #000 0%, rgba(0,0,0,.35) 45%, transparent 72%);
  mask-image:radial-gradient(ellipse 60% 90% at 100% 8%, #000 0%, rgba(0,0,0,.35) 45%, transparent 72%);
}
.call__panel{
  position:relative;z-index:1;
  max-width:var(--max);margin-inline:auto;
  /* the copy column is capped rather than fluid: left to fill 1.1fr it ran
     out of words long before the card, leaving a void down the middle */
  display:grid;grid-template-columns:minmax(0,34rem) minmax(0,25rem);
  justify-content:center;
  gap:clamp(2.5rem,4vw,3.5rem);
  align-items:center;
}
.call__panel h2{
  margin:0;max-width:22ch;
  font-family:var(--font-head);
  font-size:clamp(1.875rem,3.4vw,3rem);
  line-height:1.06;letter-spacing:-.035em;font-weight:600;
  text-wrap:balance;
}
.call__lede{margin:1.35rem 0 0;max-width:36rem;font-size:1.0625rem;line-height:1.62;color:var(--grey-100);}
.call__lede b{color:#fff;font-weight:600;}

.call__points{list-style:none;margin:2rem 0 0;padding:0;display:grid;gap:.9rem;}
.call__points li{
  display:flex;align-items:flex-start;gap:.75rem;
  font-size:1rem;line-height:1.5;color:var(--grey-100);
}
.call__points svg{
  flex:0 0 auto;width:1.25rem;height:1.25rem;margin-top:.1rem;
  color:var(--lime);
}
.call__actions{display:flex;flex-wrap:wrap;align-items:center;gap:1.25rem;margin-top:2.25rem;}
.call__tel{font-size:.9375rem;color:var(--grey-200);transition:color .16s ease;}
.call__tel:hover{color:#fff;}

/* ---- the booking card ---- */
.call__card{
  padding:1.5rem;
  border-radius:1.5rem;
  background:#fff;
  color:var(--ink-dark);
  box-shadow:0 2px 4px rgba(0,0,0,.16), 0 28px 64px rgba(0,0,0,.42);
}
.call__host{display:flex;align-items:center;gap:.9rem;}
.call__avatar{
  position:relative;flex:0 0 auto;
  width:3.5rem;height:3.5rem;border-radius:50%;
  overflow:hidden;
  box-shadow:0 0 0 1px rgba(0,0,0,.08);
}
.call__avatar img{width:100%;height:100%;object-fit:cover;display:block;}
.call__id{display:flex;flex-direction:column;gap:.15rem;min-width:0;}
.call__who{
  margin:0;
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:600;letter-spacing:-.018em;
}
.call__role{margin:0;font-size:.8125rem;color:#6b6b73;}
/* the live pip moves out of the avatar and onto its own labelled chip: as a
   dot on a photograph it was decoration, as a chip it says something */
.call__live{
  display:inline-flex;align-items:center;gap:.4rem;
  margin-left:auto;flex:0 0 auto;
  padding:.3rem .6rem .3rem .5rem;
  border-radius:var(--radius-full);
  background:#F1F8D6;
  font-size:.6875rem;font-weight:700;letter-spacing:.02em;color:#3F5200;
  white-space:nowrap;
}
.call__live i{
  width:.45rem;height:.45rem;border-radius:50%;background:#8CA800;
  box-shadow:0 0 0 0 rgba(140,168,0,.55);
  animation:pulse 2.4s infinite;
}

.call__rows{margin:1.35rem 0 0;padding:1.15rem 0 0;border-top:1px solid rgba(0,0,0,.09);display:grid;gap:.85rem;}
.call__rows > div{display:flex;align-items:center;gap:.75rem;}
.call__rows dt{
  display:flex;align-items:center;gap:.55rem;
  font-size:.875rem;color:#6b6b73;
}
.call__rows dt svg{width:1.05rem;height:1.05rem;flex:0 0 auto;color:#9a9aa2;}
.call__rows dd{
  margin:0 0 0 auto;text-align:right;
  font-family:var(--font-head);
  font-size:.875rem;font-weight:600;letter-spacing:-.012em;
}

.call__avail{margin-top:1.35rem;padding-top:1.15rem;border-top:1px solid rgba(0,0,0,.09);}
.call__avail-h{
  margin:0 0 .8rem;
  font-size:.6875rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#6b6b73;
}
.call__days{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:.3rem;}
.call__days span{
  display:flex;align-items:center;justify-content:center;
  height:2.1rem;border-radius:.55rem;
  background:#EFF6D3;color:#3F5200;
  font-size:.6875rem;font-weight:700;
}
.call__days span.is-off{background:#F4F4F1;color:#adadb4;font-weight:500;}
.call__window{
  display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;
  margin:.9rem 0 0;
  font-size:.875rem;font-weight:600;
}
.call__window svg{width:1.05rem;height:1.05rem;flex:0 0 auto;color:#9a9aa2;}
.call__window i{font-style:normal;margin-left:auto;font-size:.75rem;font-weight:500;color:#6b6b73;}
.call__go{width:100%;justify-content:center;margin-top:1.35rem;padding:.95rem 1.25rem;}

@media (max-width:1024px){
  .call__panel{grid-template-columns:minmax(0,1fr);gap:2.5rem;justify-items:stretch;}
  .call__card{max-width:26rem;}
}
@media (max-width:640px){
  .call{padding:2.25rem 1.25rem;}
  .call__actions .btn{width:100%;}
  .call__tel{width:100%;text-align:center;}
}

/* ---------- case studies ----------
   Was three white cards each fronted by a big empty logo plate and a bare
   percentage. The number is the same; what changed is that it now sits in
   a sentence, the client leads instead of a floating logo, and each tile
   carries one of the three brand hues so the set reads as a set. */
.cases{
  margin-top:var(--shell);
  padding:clamp(4rem,6vw,6.5rem) var(--edge);
  border-radius:var(--radius-main);
  background:var(--paper);
  color:var(--ink-dark);
}
.cases__head{
  display:flex;flex-direction:column;align-items:center;
  text-align:center;
  gap:1rem;
  max-width:56rem;
  margin:0 auto clamp(2rem,3.2vw,2.75rem);
}
.cases__head h2{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(2rem,3.8vw,3.25rem);
  line-height:1.06;letter-spacing:-.035em;font-weight:600;
  text-wrap:balance;
}
.cases__lede{
  margin:0;max-width:46rem;
  font-size:1.0625rem;line-height:1.6;color:#54545a;
  text-wrap:balance;
}
/* the rating sits with the heading as a reminder, not as its own band */
.rate{
  display:inline-flex;align-items:center;gap:.5rem;
  margin:.35rem 0 0;
  padding:.45rem .9rem;
  border-radius:var(--radius-full);
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.06), inset 0 0 0 1px rgba(0,0,0,.07);
  font-size:.9375rem;color:#54545a;
  white-space:nowrap;
}
.rate__g{width:1.05rem;height:1.05rem;display:block;flex:0 0 auto;}
.rate .stars{font-size:.875rem;letter-spacing:.04em;}
.rate strong{color:var(--ink-dark);font-weight:700;}

/* ---- industry filter ----
   The point of the section is that a reader recognises their own trade in
   it, so the categories are the way in. They are the industries we actually
   have work in - there is no empty bucket sitting there implying otherwise. */
/* ---- the case studies, as a rail rather than a grid ----
   Nine tiles in a 3x3 grid made the section the tallest on the page and gave
   every tile the same weight whichever industry you came for. As a rail, six
   are within reach of one drag, the filter narrows what is in it, and the
   section is a third of the height. The rail fades into the ground at both
   ends so it reads as continuing rather than stopping at the gutter. */
.crail{
  position:relative;
  margin:0 calc(var(--edge) * -1);
  /* The fade is per end rather than fixed on both, because a fade only means
     "there is more this way". At rest the rail is at nought and there is
     nothing to the left, so the left fade was washing out the front of the
     first card and the section opened on a card that looked half cut off.
     Left starts at zero and the script turns it on the moment the rail has
     been scrolled, which is also the state without JavaScript: no fade, no
     false promise. */
  --crail-fade:clamp(2rem,4vw,5rem);
  --crail-l:0px;
  --crail-r:var(--crail-fade);
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 var(--crail-l), #000 calc(100% - var(--crail-r)), transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, #000 var(--crail-l), #000 calc(100% - var(--crail-r)), transparent 100%);
}
.crail.has-prev{--crail-l:var(--crail-fade);}
.crail.at-end{--crail-r:0px;}
.cases__grid{
  display:flex;
  gap:1.5rem;
  overflow-x:auto;
  padding:.25rem var(--edge) 1.5rem;
  scroll-snap-type:x proximity;
  scroll-padding-left:var(--edge);
  overscroll-behavior-x:contain;
  /* the native bar is hidden because the rail has its own below, outside the
     mask: an overlay scrollbar is invisible until you are already scrolling,
     which is no use as the thing that tells you there is more to see */
  scrollbar-width:none;
}
.cases__grid::-webkit-scrollbar{display:none;}
.cases__grid .ccard{
  flex:0 0 clamp(18rem,26vw,23rem);
  scroll-snap-align:start;
}
@media (max-width:640px){
  .cases__grid .ccard{flex-basis:min(78vw,20rem);}
}

/* ---------- why dunk ---------- */
.whyus{
  margin-top:var(--shell);
  padding:6rem var(--edge) 6.5rem;
  border-radius:var(--radius-main);
  background:
    radial-gradient(ellipse 80% 65% at 50% 0%, rgba(var(--purple-accent),.20) 0%, rgba(var(--purple-accent),0) 62%),
    #1C1729;
  color:#fff;
}
.whyus__head{
  max-width:56rem;
  margin:0 auto clamp(3rem,4.6vw,4rem);
  text-align:center;
}
.whyus__head h2{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(2rem,3.6vw,3.25rem);
  line-height:1.06;letter-spacing:-.035em;font-weight:600;
  text-wrap:balance;
}
.whyus__lede{
  margin:1.35rem auto 0;max-width:38rem;
  font-size:1.1875rem;line-height:1.55;color:var(--grey-100);
}
.why{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(2.75rem,5vw,4rem) clamp(1.75rem,3vw,3.25rem);
}
.why__item{text-align:center;}
.why__ico{display:block;width:2.875rem;height:2.875rem;margin:0 auto 1.1rem;}
.why__item h3{
  margin:0 0 .7rem;
  font-family:var(--font-head);
  font-size:clamp(1.375rem,1.9vw,1.75rem);
  line-height:1.15;font-weight:600;letter-spacing:-.02em;
  color:#fff;
}
.why__item p{
  margin:0 auto;max-width:24rem;
  font-size:1.0625rem;line-height:1.6;color:var(--grey-100);
}

@media (max-width:1000px){
  .whyus{padding:4.5rem var(--edge) 5rem;}
  .why{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:640px){
  .why{grid-template-columns:minmax(0,1fr);}
}

/* ---------- client reviews ----------
   Three vertical rails on the same duplicated-set trick as the logo
   marquee: each .vrail__set carries a padding-bottom equal to its own
   card gap, so one set is exactly half the track and translateY(-50%)
   loops with no seam. A set must also be taller than the rail or a bald
   patch scrolls through, which is what sets the 4-cards-per-rail count.
   The middle rail runs in reverse so the three do not move as one slab. */
.voices{
  margin-top:var(--shell);
  padding:clamp(4rem,6vw,6.5rem) var(--edge) clamp(3rem,5vw,4.5rem);
  border-radius:var(--radius-main);
  background:var(--paper);
  color:var(--ink-dark);
}
.voices__head{max-width:56rem;margin:0 auto;text-align:center;}
.voices__head h2{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(2rem,3.8vw,3.25rem);
  line-height:1.06;letter-spacing:-.035em;font-weight:600;
  text-wrap:balance;
}
.voices__lede{
  margin:1.25rem auto 0;max-width:46rem;
  font-size:1.0625rem;line-height:1.6;color:#54545a;
}

/* the three figures used to float on the section ground with hairlines
   between them, reading as three separate things. On their own panel they
   read as one proof line. */
.voices__stats{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;
  width:fit-content;
  margin:clamp(2.5rem,4vw,3.5rem) auto clamp(4rem,6vw,5.5rem);
  padding:.5rem;
  border:1px solid rgba(0,0,0,.08);
  border-radius:1.25rem;
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 12px 32px rgba(0,0,0,.06);
}
.vstat{padding:1rem clamp(1.25rem,2.6vw,2.5rem);text-align:center;}
.vstat + .vstat{border-left:1px solid rgba(0,0,0,.09);}
.vstat__n{
  display:flex;align-items:center;justify-content:center;gap:.5rem;
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(1.75rem,3vw,2.5rem);
  line-height:1.1;letter-spacing:-.035em;font-weight:700;
}
.vstat__n .stars{font-size:.6em;}
.vstat__l{margin:.5rem 0 0;font-size:.9375rem;color:#54545a;}

.voices__rails{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:1.25rem;
  align-items:start;
}
.vrail{
  position:relative;overflow:hidden;
  height:42rem;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 5rem,#000 calc(100% - 5rem),transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 5rem,#000 calc(100% - 5rem),transparent 100%);
}
/* the middle rail is a third of a cycle ahead so the three columns do not
   line up on load. This used to be a -3.5rem margin, which staggered them
   by pulling the rail up into the proof bar above it; a negative delay
   staggers the content instead and leaves the box where it belongs. */
.vrail--mid .vrail__track{animation-delay:-20s;}
.vrail__track{display:flex;flex-direction:column;animation:vscroll 60s linear infinite;}
.vrail--rev .vrail__track{animation-direction:reverse;}
.vrail:hover .vrail__track{animation-play-state:paused;}
@keyframes vscroll{to{transform:translateY(-50%);}}
.vrail__set{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:1.25rem;}

.vcard{
  padding:1.75rem;
  border:1px solid rgba(0,0,0,.09);
  border-radius:1.25rem;
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.06);
  transition:box-shadow .2s ease, border-color .2s ease;
}
/* hovering a rail pauses it, so the card under the cursor says so */
.vrail:hover .vcard:hover{
  border-color:rgba(0,0,0,.16);
  box-shadow:0 2px 4px rgba(0,0,0,.06), 0 16px 40px rgba(0,0,0,.12);
}
.vcard__who{display:flex;align-items:center;gap:.85rem;}
/* monograms rather than photographs: these are real people who left real
   reviews, and putting a stock face on a named person invents them */
.vcard__av{
  flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  width:2.75rem;height:2.75rem;
  border-radius:50%;
  font-family:var(--font-head);
  font-size:.875rem;font-weight:700;letter-spacing:.01em;
  color:#1A1030;
}
.vcard__av--a{background:#EDE7FB;}
.vcard__av--b{background:#E8FCA6;}
.vcard__av--c{background:#E3E6FF;}
.vcard__av--d{background:#F2EBE1;}
.vcard__name{
  margin:0;
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:600;letter-spacing:-.015em;
}
.vcard__role{
  display:flex;align-items:center;gap:.4rem;
  margin:.15rem 0 0;font-size:.8125rem;color:#6b6b73;
}
.vcard__role i{
  flex:0 0 auto;width:.875rem;height:.875rem;
  background:var(--mark-google) center/contain no-repeat;
}
.vcard__quote{
  margin:1.4rem 0 0;
  font-family:var(--font-head);
  font-size:1rem;line-height:1.55;font-weight:500;letter-spacing:-.01em;
  color:var(--ink-dark);
}

@media (max-width:1024px){
  .voices__rails{grid-template-columns:repeat(2,minmax(0,1fr));}
  /* the third rail's cards are still in the DOM, they just scroll on
     whichever of the two columns they land in */
  .vrail{height:38rem;}
}
@media (max-width:700px){
  /* three stacked auto-scrolling rails on a phone is unreadable, so the
     rails become one plain column and the duplicate sets drop out */
  .voices__rails{grid-template-columns:minmax(0,1fr);gap:1rem;}
  .vrail{height:auto;overflow:visible;-webkit-mask-image:none;mask-image:none;}
  .vrail__track{animation:none;}
  .vrail__set[aria-hidden="true"]{display:none;}
  .vstat + .vstat{border-left:0;}
  .voices__stats{gap:1.75rem 0;}
}

/* ---------- lead form ---------- */
.lead{
  max-width:none;margin:0;
  padding:clamp(1.5rem,3vw,2.5rem);
  border:1px solid rgba(255,255,255,.12);
  border-radius:1.5rem;
  background:linear-gradient(180deg, rgba(255,255,255,.055) 0%, rgba(255,255,255,.022) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07), 0 24px 60px rgba(0,0,0,.35);
  text-align:left;
}
.lead__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem 1.1rem;}
.lead__field{display:flex;flex-direction:column;gap:.55rem;min-width:0;}
.lead__field--wide{grid-column:1 / -1;}
.lead__field label{
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:600;line-height:1.3;letter-spacing:-.015em;
  color:#fff;
}
.lead__field label i{font-style:normal;color:var(--lime);}
.lead__field input,
.lead__field select,
.lead__field textarea{
  width:100%;
  padding:.8rem .9rem;
  border:1px solid rgba(255,255,255,.16);
  border-radius:.7rem;
  background:rgba(0,0,0,.28);
  font:inherit;font-size:.9375rem;color:#fff;
  transition:border-color .16s ease, box-shadow .16s ease, background-color .16s ease;
}
.lead__field textarea{min-height:6.5rem;resize:vertical;}
.lead__field input::placeholder,.lead__field textarea::placeholder{color:rgba(255,255,255,.35);}
.lead__field input:focus,
.lead__field select:focus,
.lead__field textarea:focus{
  outline:none;
  border-color:var(--lime);
  background:rgba(0,0,0,.4);
  box-shadow:0 0 0 3px rgba(217,233,104,.18);
}
/* native selects render their own arrow in the OS colour, so draw one */
.lead__select{position:relative;}
.lead__select select{appearance:none;-webkit-appearance:none;padding-right:2.4rem;cursor:pointer;}
.lead__select select option{color:#111;}
.lead__select::after{
  content:"";
  position:absolute;right:1rem;bottom:1.15rem;
  width:.42rem;height:.42rem;
  border-right:2px solid var(--grey-200);
  border-bottom:2px solid var(--grey-200);
  transform:rotate(45deg);
  pointer-events:none;
}
.lead__submit{
  width:100%;justify-content:center;
  margin-top:1.5rem;
  padding:1.05rem 1.5rem;
  border-radius:.85rem;
  font-size:.875rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
}
.lead__note{
  margin:1.1rem 0 0;
  font-size:.75rem;line-height:1.6;color:var(--grey-300);
}
.lead__note b{color:var(--grey-200);font-weight:600;}
/* One column from 900px down. The two-column grid was holding to 640, and by
   700 each field was 108px wide — a phone number does not fit in that, and
   neither does an email. Measured across 13 widths before moving it. */
@media (max-width:900px){
  .lead__grid{grid-template-columns:minmax(0,1fr);}
}

/* ---------- footer ---------- */
.foot{
  position:relative;isolation:isolate;
  margin:0 calc(var(--shell) * -1) calc(var(--shell) * -1);
  padding:clamp(3rem,5vw,4.5rem) var(--edge) 2.5rem;
  border-radius:0;
  /* one step off the CTA's #0D0A14 so the two dark blocks read as two
     bands rather than one flat wall, with no rule needed between them */
  background:#15131C;
  color:#fff;
  overflow:hidden;
}
/* the three brand hues as a wash across the top of the footer. Masked to
   fade out well before the legal bar, so every line of text keeps its
   contrast against a value close to the flat ground. */
.foot::before{
  content:"";
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(ellipse 55% 70% at 4% 0%, rgba(138,92,255,.42) 0%, rgba(138,92,255,0) 62%),
    radial-gradient(ellipse 45% 60% at 52% -6%, rgba(255,111,196,.24) 0%, rgba(255,111,196,0) 60%),
    radial-gradient(ellipse 60% 75% at 100% 4%, rgba(75,75,232,.34) 0%, rgba(75,75,232,0) 62%);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.55) 38%,transparent 72%);
  mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.55) 38%,transparent 72%);
}
.foot__top{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);
  gap:clamp(2.5rem,5vw,5rem);
}
.foot__logo svg{height:2.6rem;width:auto;display:block;color:#fff;}
.foot__block{margin-top:2.5rem;}
.foot__label{
  margin:0 0 .7rem;
  font-size:.6875rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  /* grey-300 against the colour wash fell under 4.5:1 */
  color:var(--grey-200);
}
.foot__addr{margin:0;font-size:.9375rem;line-height:1.65;color:var(--grey-100);}
.foot__addr a{color:var(--grey-100);}
.foot__addr a:hover{color:var(--lime);}
.foot__social{display:flex;gap:.6rem;margin-top:2.25rem;}
.foot__social a{
  display:inline-flex;align-items:center;justify-content:center;
  width:2.25rem;height:2.25rem;
  border:1px solid var(--hairline);border-radius:50%;
  color:var(--grey-200);
  transition:color .18s ease, border-color .18s ease, background-color .18s ease;
}
.foot__social a:hover{color:var(--ink-dark);background:var(--lime);border-color:transparent;}
.foot__social svg{width:1rem;height:1rem;display:block;}

/* the rule between the halves, drawn on the right column so it stretches */
.foot__right{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(1.5rem,3vw,2.5rem) clamp(1.25rem,2.5vw,2rem);
  padding-left:clamp(1.5rem,4vw,4rem);
  border-left:1px solid var(--hairline);
}
.foot__col a{
  display:block;margin-top:.5rem;
  font-size:.9375rem;color:var(--grey-100);
  transition:color .16s ease;
}
.foot__col a:first-of-type{margin-top:0;}
.foot__col a:hover{color:var(--lime);}
.foot__news{grid-column:1 / -1;margin-top:1.5rem;}
.foot__news h3{
  margin:0;
  font-family:var(--font-head);
  font-size:1.25rem;font-weight:600;letter-spacing:-.02em;
}
.foot__news p{margin:.5rem 0 0;max-width:28rem;font-size:.875rem;line-height:1.55;color:var(--grey-200);}
.foot__form{
  display:flex;align-items:center;gap:.75rem;
  margin-top:1.25rem;max-width:28rem;
  padding-bottom:.6rem;
  border-bottom:1px solid rgba(255,255,255,.22);
}
.foot__form input{
  flex:1 1 auto;min-width:0;
  background:none;border:0;outline:none;
  font:inherit;font-size:.9375rem;color:#fff;
}
.foot__form input::placeholder{color:var(--grey-200);}
.foot__form button{
  flex:0 0 auto;
  width:2.1rem;height:2.1rem;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--lime);color:var(--ink-dark);
  font-size:.9rem;
  transition:transform .18s ease;
}
.foot__form button:hover{transform:translateX(.15rem);}

.foot__bar{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  margin-top:clamp(3rem,5vw,4.5rem);
  padding-top:1.5rem;
  border-top:1px solid var(--hairline);
  font-size:.8125rem;color:var(--grey-300);
}
.foot__bar p{margin:0;}
.foot__bar a{color:var(--grey-200);}
.foot__bar a:hover{color:var(--lime);}

@media (max-width:1024px){
  .foot__top{grid-template-columns:minmax(0,1fr);}
  .foot__right{padding-left:0;border-left:0;padding-top:2.5rem;border-top:1px solid var(--hairline);}
}
@media (max-width:640px){
  .foot__right{grid-template-columns:repeat(2,minmax(0,1fr));}
}

/* ---------- section placeholders ----------
   Deliberately unfinished-looking: dashed rule and an amber tag so none of
   these can be mistaken for real content in a review. Delete the .ph
   classes as each one gets built. */
.ph{
  margin-top:var(--shell);
  padding:clamp(2.5rem,5vw,3.75rem) var(--edge);
  border:2px dashed rgba(0,0,0,.18);
  border-radius:var(--radius-main);
  background:rgba(255,255,255,.45);
  color:var(--ink-dark);
}
.ph__tag{
  display:inline-flex;align-items:center;margin:0;
  padding:.3rem .7rem;
  border-radius:var(--radius-full);
  background:#FFE9A8;color:#5A4300;
  font-size:.6875rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
}
.ph__title{
  margin:1.1rem 0 0;
  font-family:var(--font-head);
  font-size:clamp(1.5rem,2.4vw,2.125rem);
  line-height:1.1;letter-spacing:-.03em;font-weight:600;
}
.ph__what{margin:.4rem 0 0;font-size:1.0625rem;color:#54545a;}
.ph__need{margin:1.15rem 0 0;max-width:46rem;font-size:.9375rem;line-height:1.65;color:#6b6b73;}
.ph__need b{color:var(--ink-dark);font-weight:600;}

/* ---------- footer CTA ---------- */
/* full bleed, and the colour band dissolves downward into the same value
   the footer starts on, so the two read as one block rather than two
   rounded cards with a gap */
.cta{
  position:relative;isolation:isolate;
  margin:var(--shell) calc(var(--shell) * -1) 0;
  padding:clamp(2.5rem,4.5vw,4rem) calc(var(--edge) + var(--shell)) clamp(2.5rem,4.5vw,4rem);
  border-radius:0;
  background:#0D0A14;
  overflow:hidden;
}
/* ---------- the contact section, on paper ----------
   Only the contact page uses this. Every other page's .cta stays dark, so the
   whole thing is scoped to .cta--light rather than reworked in global.css.
   The tokens the dark version leans on (--grey-100/200/300, --hairline) are all
   white at some alpha, so each one needs a dark counterpart here, not a tweak. */
/* white, not paper: the FAQ directly above is paper and the two ran together */
.cta--light{background:#fff;}
/* the photograph and its scrim were there to keep white type readable; on
   paper they only muddy it */
.cta--light::before,
.cta--light::after{display:none;}
.cta--light .eyebrow{color:rgba(18,18,18,.6);}
.cta--light .cta__panel h2{color:var(--ink-dark);}
.cta--light .cta__lede{color:rgba(18,18,18,.7);}

.cta--light .cta__proof{border-top-color:rgba(18,18,18,.12);}
.cta--light .cta__id b{color:var(--ink-dark);}
.cta--light .cta__id span{color:rgba(18,18,18,.62);}
.cta--light .cta__stars{color:rgba(18,18,18,.72);}
.cta--light .cta__stars strong{color:var(--ink-dark);}
.cta--light .cta__ticks{color:rgba(18,18,18,.74);}
/* lime on white fails at this size; the tick takes the accent purple instead */
.cta--light .cta__ticks svg{color:rgb(var(--purple-accent));}

.cta--light .lead{
  border-color:rgba(18,18,18,.10);
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 22px 55px rgba(0,0,0,.10);
}
.cta--light .lead__field label{color:var(--ink-dark);}
/* the required marker was lime on near-black; on white it needs the purple */
.cta--light .lead__field label i{color:rgb(var(--purple-accent));}
.cta--light .lead__field input,
.cta--light .lead__field select,
.cta--light .lead__field textarea{
  border-color:rgba(18,18,18,.16);
  background:#FBFBFA;
  color:var(--ink-dark);
}
.cta--light .lead__field input::placeholder,
.cta--light .lead__field textarea::placeholder{color:rgba(18,18,18,.38);}
.cta--light .lead__field input:focus,
.cta--light .lead__field select:focus,
.cta--light .lead__field textarea:focus{
  border-color:rgb(var(--purple-accent));
  background:#fff;
  box-shadow:0 0 0 3px rgba(var(--purple-accent),.16);
}
.cta--light .lead__select::after{
  border-right-color:rgba(18,18,18,.5);
  border-bottom-color:rgba(18,18,18,.5);
}
.cta--light .lead__note{color:rgba(18,18,18,.55);}
.cta--light .lead__note b{color:rgba(18,18,18,.72);}

/* ---------- the Pipedrive embed in the CTA block ----------
   The enquiry form is a Pipedrive web form now, so leads land in the CRM
   rather than in an inbox. It renders as an iframe carrying its own light
   styling, so it gets a light card to sit in on this dark panel.

   The Netlify form stays in the markup underneath as a fallback and hides
   itself the moment the embed actually renders. If the loader is ever blocked
   or Pipedrive is down, the page still captures the lead instead of showing a
   blank space - which matters, because this is the only enquiry path on the
   site. Remove the fallback only once the embed has been trusted for a while. */
.lead__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem 1.1rem;}
.lead__field{display:flex;flex-direction:column;gap:.55rem;min-width:0;}
.lead__field--wide{grid-column:1 / -1;}
.lead__field label{
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:600;line-height:1.3;letter-spacing:-.015em;
  color:#fff;
}
.lead__field label i{font-style:normal;color:var(--lime);}
.lead__field input,
.lead__field select,
.lead__field textarea{
  width:100%;
  padding:.8rem .9rem;
  border:1px solid rgba(255,255,255,.16);
  border-radius:.7rem;
  background:rgba(0,0,0,.28);
  font:inherit;font-size:.9375rem;color:#fff;
  transition:border-color .16s ease, box-shadow .16s ease, background-color .16s ease;
}
.lead__field textarea{min-height:6.5rem;resize:vertical;}
.lead__field input::placeholder,.lead__field textarea::placeholder{color:rgba(255,255,255,.35);}
.lead__field input:focus,
.lead__field select:focus,
.lead__field textarea:focus{
  outline:none;
  border-color:var(--lime);
  background:rgba(0,0,0,.4);
  box-shadow:0 0 0 3px rgba(217,233,104,.18);
}
/* native selects render their own arrow in the OS colour, so draw one */
.lead__select{position:relative;}
.lead__select select{appearance:none;-webkit-appearance:none;padding-right:2.4rem;cursor:pointer;}
.lead__select select option{color:#111;}
.lead__select::after{
  content:"";
  position:absolute;right:1rem;bottom:1.15rem;
  width:.42rem;height:.42rem;
  border-right:2px solid var(--grey-200);
  border-bottom:2px solid var(--grey-200);
  transform:rotate(45deg);
  pointer-events:none;
}
.lead__submit{
  width:100%;justify-content:center;
  margin-top:1.5rem;
  padding:1.05rem 1.5rem;
  border-radius:.85rem;
  font-size:.875rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
}
.lead__note{
  margin:1.1rem 0 0;
  font-size:.75rem;line-height:1.6;color:var(--grey-300);
}
.lead__note b{color:var(--grey-200);font-weight:600;}
/* One column from 900px down. The two-column grid was holding to 640, and by
   700 each field was 108px wide — a phone number does not fit in that, and
   neither does an email. Measured across 13 widths before moving it. */
@media (max-width:900px){
  .lead__grid{grid-template-columns:minmax(0,1fr);}
}

/* ---------- footer ---------- */
.foot{
  position:relative;isolation:isolate;
  margin:0 calc(var(--shell) * -1) calc(var(--shell) * -1);
  padding:clamp(3rem,5vw,4.5rem) var(--edge) 2.5rem;
  border-radius:0;
  /* one step off the CTA's #0D0A14 so the two dark blocks read as two
     bands rather than one flat wall, with no rule needed between them */
  background:#15131C;
  color:#fff;
  overflow:hidden;
}
/* the three brand hues as a wash across the top of the footer. Masked to
   fade out well before the legal bar, so every line of text keeps its
   contrast against a value close to the flat ground. */
.foot::before{
  content:"";
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(ellipse 55% 70% at 4% 0%, rgba(138,92,255,.42) 0%, rgba(138,92,255,0) 62%),
    radial-gradient(ellipse 45% 60% at 52% -6%, rgba(255,111,196,.24) 0%, rgba(255,111,196,0) 60%),
    radial-gradient(ellipse 60% 75% at 100% 4%, rgba(75,75,232,.34) 0%, rgba(75,75,232,0) 62%);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.55) 38%,transparent 72%);
  mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.55) 38%,transparent 72%);
}
.foot__top{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);
  gap:clamp(2.5rem,5vw,5rem);
}
.foot__logo svg{height:2.6rem;width:auto;display:block;color:#fff;}
.foot__block{margin-top:2.5rem;}
.foot__label{
  margin:0 0 .7rem;
  font-size:.6875rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  /* grey-300 against the colour wash fell under 4.5:1 */
  color:var(--grey-200);
}
.foot__addr{margin:0;font-size:.9375rem;line-height:1.65;color:var(--grey-100);}
.foot__addr a{color:var(--grey-100);}
.foot__addr a:hover{color:var(--lime);}
.foot__social{display:flex;gap:.6rem;margin-top:2.25rem;}
.foot__social a{
  display:inline-flex;align-items:center;justify-content:center;
  width:2.25rem;height:2.25rem;
  border:1px solid var(--hairline);border-radius:50%;
  color:var(--grey-200);
  transition:color .18s ease, border-color .18s ease, background-color .18s ease;
}
.foot__social a:hover{color:var(--ink-dark);background:var(--lime);border-color:transparent;}
.foot__social svg{width:1rem;height:1rem;display:block;}

/* the rule between the halves, drawn on the right column so it stretches */
.foot__right{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(1.5rem,3vw,2.5rem) clamp(1.25rem,2.5vw,2rem);
  padding-left:clamp(1.5rem,4vw,4rem);
  border-left:1px solid var(--hairline);
}
.foot__col a{
  display:block;margin-top:.5rem;
  font-size:.9375rem;color:var(--grey-100);
  transition:color .16s ease;
}
.foot__col a:first-of-type{margin-top:0;}
.foot__col a:hover{color:var(--lime);}
.foot__news{grid-column:1 / -1;margin-top:1.5rem;}
.foot__news h3{
  margin:0;
  font-family:var(--font-head);
  font-size:1.25rem;font-weight:600;letter-spacing:-.02em;
}
.foot__news p{margin:.5rem 0 0;max-width:28rem;font-size:.875rem;line-height:1.55;color:var(--grey-200);}
.foot__form{
  display:flex;align-items:center;gap:.75rem;
  margin-top:1.25rem;max-width:28rem;
  padding-bottom:.6rem;
  border-bottom:1px solid rgba(255,255,255,.22);
}
.foot__form input{
  flex:1 1 auto;min-width:0;
  background:none;border:0;outline:none;
  font:inherit;font-size:.9375rem;color:#fff;
}
.foot__form input::placeholder{color:var(--grey-200);}
.foot__form button{
  flex:0 0 auto;
  width:2.1rem;height:2.1rem;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--lime);color:var(--ink-dark);
  font-size:.9rem;
  transition:transform .18s ease;
}
.foot__form button:hover{transform:translateX(.15rem);}

.foot__bar{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  margin-top:clamp(3rem,5vw,4.5rem);
  padding-top:1.5rem;
  border-top:1px solid var(--hairline);
  font-size:.8125rem;color:var(--grey-300);
}
.foot__bar p{margin:0;}
.foot__bar a{color:var(--grey-200);}
.foot__bar a:hover{color:var(--lime);}

@media (max-width:1024px){
  .foot__top{grid-template-columns:minmax(0,1fr);}
  .foot__right{padding-left:0;border-left:0;padding-top:2.5rem;border-top:1px solid var(--hairline);}
}
@media (max-width:640px){
  .foot__right{grid-template-columns:repeat(2,minmax(0,1fr));}
}

/* ---------- section placeholders ----------
   Deliberately unfinished-looking: dashed rule and an amber tag so none of
   these can be mistaken for real content in a review. Delete the .ph
   classes as each one gets built. */
.ph{
  margin-top:var(--shell);
  padding:clamp(2.5rem,5vw,3.75rem) var(--edge);
  border:2px dashed rgba(0,0,0,.18);
  border-radius:var(--radius-main);
  background:rgba(255,255,255,.45);
  color:var(--ink-dark);
}
.ph__tag{
  display:inline-flex;align-items:center;margin:0;
  padding:.3rem .7rem;
  border-radius:var(--radius-full);
  background:#FFE9A8;color:#5A4300;
  font-size:.6875rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
}
.ph__title{
  margin:1.1rem 0 0;
  font-family:var(--font-head);
  font-size:clamp(1.5rem,2.4vw,2.125rem);
  line-height:1.1;letter-spacing:-.03em;font-weight:600;
}
.ph__what{margin:.4rem 0 0;font-size:1.0625rem;color:#54545a;}
.ph__need{margin:1.15rem 0 0;max-width:46rem;font-size:.9375rem;line-height:1.65;color:#6b6b73;}
.ph__need b{color:var(--ink-dark);font-weight:600;}

/* ---------- footer CTA ---------- */
/* full bleed, and the colour band dissolves downward into the same value
   the footer starts on, so the two read as one block rather than two
   rounded cards with a gap */
.cta{
  position:relative;isolation:isolate;
  margin:var(--shell) calc(var(--shell) * -1) 0;
  padding:clamp(2.5rem,4.5vw,4rem) calc(var(--edge) + var(--shell)) clamp(2.5rem,4.5vw,4rem);
  border-radius:0;
  background:#0D0A14;
  overflow:hidden;
}
/* ---------- the contact section, on paper ----------
   Only the contact page uses this. Every other page's .cta stays dark, so the
   whole thing is scoped to .cta--light rather than reworked in global.css.
   The tokens the dark version leans on (--grey-100/200/300, --hairline) are all
   white at some alpha, so each one needs a dark counterpart here, not a tweak. */
/* white, not paper: the FAQ directly above is paper and the two ran together */
.cta--light{background:#fff;}
/* the photograph and its scrim were there to keep white type readable; on
   paper they only muddy it */
.cta--light::before,
.cta--light::after{display:none;}
.cta--light .eyebrow{color:rgba(18,18,18,.6);}
.cta--light .cta__panel h2{color:var(--ink-dark);}
.cta--light .cta__lede{color:rgba(18,18,18,.7);}

.cta--light .cta__proof{border-top-color:rgba(18,18,18,.12);}
.cta--light .cta__id b{color:var(--ink-dark);}
.cta--light .cta__id span{color:rgba(18,18,18,.62);}
.cta--light .cta__stars{color:rgba(18,18,18,.72);}
.cta--light .cta__stars strong{color:var(--ink-dark);}
.cta--light .cta__ticks{color:rgba(18,18,18,.74);}
/* lime on white fails at this size; the tick takes the accent purple instead */
.cta--light .cta__ticks svg{color:rgb(var(--purple-accent));}

.cta--light .lead{
  border-color:rgba(18,18,18,.10);
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 22px 55px rgba(0,0,0,.10);
}
.cta--light .lead__field label{color:var(--ink-dark);}
/* the required marker was lime on near-black; on white it needs the purple */
.cta--light .lead__field label i{color:rgb(var(--purple-accent));}
.cta--light .lead__field input,
.cta--light .lead__field select,
.cta--light .lead__field textarea{
  border-color:rgba(18,18,18,.16);
  background:#FBFBFA;
  color:var(--ink-dark);
}
.cta--light .lead__field input::placeholder,
.cta--light .lead__field textarea::placeholder{color:rgba(18,18,18,.38);}
.cta--light .lead__field input:focus,
.cta--light .lead__field select:focus,
.cta--light .lead__field textarea:focus{
  border-color:rgb(var(--purple-accent));
  background:#fff;
  box-shadow:0 0 0 3px rgba(var(--purple-accent),.16);
}
.cta--light .lead__select::after{
  border-right-color:rgba(18,18,18,.5);
  border-bottom-color:rgba(18,18,18,.5);
}
.cta--light .lead__note{color:rgba(18,18,18,.55);}
.cta--light .lead__note b{color:rgba(18,18,18,.72);}

/* ---------- the Pipedrive embed in the CTA block ----------
   The enquiry form is a Pipedrive web form now, so leads land in the CRM
   rather than in an inbox. It renders as an iframe carrying its own light
   styling, so it gets a light card to sit in on this dark panel.

   The Netlify form stays in the markup underneath as a fallback and hides
   itself the moment the embed actually renders. If the loader is ever blocked
   or Pipedrive is down, the page still captures the lead instead of showing a
   blank space - which matters, because this is the only enquiry path on the
   site. Remove the fallback only once the embed has been trusted for a while. */
/* The Pipedrive embed IS the enquiry form now - the Netlify one is gone. It
   is always rendered: no conditional hiding, because hiding it is what made it
   invisible last time. The section is .cta--light, so the iframe's own light
   styling sits on a light ground rather than fighting a dark panel. */
/* No width cap. The embed is responsive and picks its layout off the width it
   is given, so capping the card at 40rem handed it a narrow column and it drew
   its phone layout on a desktop. It takes the grid column, and the column is
   what has to stay wide enough - see the stacking breakpoint below. */
/* The embed draws its form about 480px wide and centres it in whatever it is
   given. The card is capped a little above that, so it hugs the form with a
   small margin either side rather than a wide white field - but stays above
   the width the embed switches to its phone layout at. */
.lead__pd{
  min-height:34rem;
  max-width:36rem;margin:0 auto;
  border-radius:1.5rem;
  background:#fff;
  padding:clamp(1.5rem,3vw,2.25rem) clamp(.5rem,1vw,.85rem);
  box-shadow:inset 0 0 0 1px rgba(18,18,18,.08), 0 1px 2px rgba(0,0,0,.05), 0 18px 44px rgba(0,0,0,.08);
  overflow:hidden;
}

/* the studio photograph behind the panel, anchored to the copy side and
   masked out before it reaches the form: at this opacity it is a texture,
   and every field still sits on the flat ground its contrast was set
   against. It ends on #0D0A14, which is where the footer starts. */
.cta::before{
  content:"";
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--photo-studio);
  background-size:cover;
  background-position:22% 38%;
  opacity:.20;
  -webkit-mask-image:radial-gradient(ellipse 78% 105% at 6% 42%, #000 0%, rgba(0,0,0,.55) 42%, rgba(0,0,0,.18) 66%, transparent 84%);
  mask-image:radial-gradient(ellipse 78% 105% at 6% 42%, #000 0%, rgba(0,0,0,.55) 42%, rgba(0,0,0,.18) 66%, transparent 84%);
}
/* a scrim over the photograph only, so the eyebrow and lede keep their
   ratios wherever the crop lands a highlight */
.cta::after{
  content:"";
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(100deg, rgba(13,10,20,.72) 0%, rgba(13,10,20,.42) 34%, rgba(13,10,20,0) 62%);
}
.cta__panel{
  position:relative;z-index:1;
  max-width:var(--max);margin-inline:auto;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:clamp(2rem,5vw,4.5rem);
  /* the copy sits at the top beside the form rather than floating at the
     mid-point of a tall form, which made the section read as empty */
  align-items:start;
  padding:0;
  text-align:left;
}
/* the arc is excluded: a bare `> *` here would override its
   position:absolute and collapse it to a zero-width inline span */
.cta__panel h2{
  margin:0;max-width:34rem;
  font-family:var(--font-head);
  font-size:clamp(2rem,4vw,3.25rem);
  line-height:1.08;letter-spacing:-.035em;font-weight:600;
  color:#fff;text-wrap:balance;
}
.cta__lede{
  margin:1.5rem 0 0;max-width:32rem;
  font-size:1.0625rem;line-height:1.6;color:var(--grey-200);
}
.cta__panel .btn{margin-top:2.5rem;}
/* Declared after .cta__panel, not before it. On equal specificity the later
   rule wins, so while this sat above the base rule the panel never stacked and
   the form's two columns came out at 180px each — narrower than a phone number
   needs, on a tablet in portrait. */
/* Stacks at 1280, not 1100. Between the two the form column came out around
   500px, which is under the width the Pipedrive embed switches to its phone
   layout at - so the form rendered as a narrow strip on a wide screen. Stacked,
   it gets the whole panel. */
@media (max-width:1280px){
  .cta__panel{grid-template-columns:minmax(0,1fr);gap:2.5rem;}
}

/* ---------- the proof beside the contact form ----------
   The call has a person on the other end of it, a rating, and terms; all three
   sit under the lede rather than in the form, so the form stays a form. The
   avatar is .call__avatar reused — it is ground-agnostic — while the name and
   role need their own colours here, the booking card's being set for paper. */
.cta__proof{
  margin:2.25rem 0 0;padding-top:1.75rem;
  border-top:1px solid rgba(255,255,255,.14);
  display:flex;flex-direction:column;gap:1.35rem;
  max-width:32rem;
}
.cta__host{display:flex;align-items:center;gap:.9rem;}
.cta__id{display:flex;flex-direction:column;gap:.15rem;min-width:0;}
.cta__id b{
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:600;letter-spacing:-.018em;color:#fff;
}
.cta__id span{font-size:.8125rem;color:var(--grey-200);}
.cta__stars{
  display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;
  margin:0;font-size:.9375rem;color:var(--grey-100);
}
.cta__stars img{width:1.15rem;height:1.15rem;display:block;}
.cta__stars strong{color:#fff;font-weight:600;}
.cta__ticks{
  display:flex;flex-direction:column;gap:.55rem;
  margin:0;padding:0;list-style:none;
  font-size:.9375rem;color:var(--grey-100);
}
.cta__ticks li{display:flex;align-items:center;gap:.5rem;}
.cta__ticks svg{width:1.05rem;height:1.05rem;color:var(--lime);flex:0 0 auto;}

/* Netlify's honeypot field: present in the DOM for the bots that fill
   everything in, and out of the way of everyone else. Not display:none —
   some bots skip those — but clipped and unreachable by tab. */
.is-hidden{
  position:absolute!important;
  width:1px;height:1px;
  margin:-1px;padding:0;border:0;
  overflow:hidden;clip-path:inset(50%);
  white-space:nowrap;
}

/* ---------- case study cards ----------
   A photograph you read straight through. Pre-dimmed, a hairline, then the
   figure and what it means on one line, and the client with its channel pill
   along the bottom. The rest of the numbers are held back until hover, when
   the brand purple washes over the photograph. The pill carries the channel
   colour: lime for SEO, bright violet with the Google mark for Google Ads, so
   the mix reads at a glance without reading a word. */
/* ---------- case-study tiles ----------
   One dark ground for all nine, not a hue each - the per-card colours read as
   decoration rather than as anything about the client. The client's own
   photograph sits behind at low strength, and the card is a sentence: the
   result written out in context, with the figures lit in lime so they carry
   without being stripped out of the words around them. */
.cases__grid .ccard{
  position:relative;isolation:isolate;overflow:hidden;
  display:flex;flex-direction:column;
  min-height:25rem;
  padding:1.75rem;
  border:0;border-radius:1.35rem;
  /* Grey, not colour. Each card carries its own angle and its own light and
     dark ends, so the nine differ without any of them being tinted. */
  background:linear-gradient(var(--case-ang),
    hsl(250 6% var(--case-hi)) 0%,
    hsl(250 5% calc((var(--case-hi) + var(--case-lo)) / 2)) 58%,
    hsl(250 5% var(--case-lo)) 100%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.09);
  color:#fff;
  transition:transform .28s cubic-bezier(.16,1,.3,1), box-shadow .28s ease;
}
/* the photograph sits a layer below both overlays. At -1 it shared a layer
   with them and, being an element child, painted after ::before - so the
   charcoal gradient was underneath the photograph, not over it. */
.cc__ph{
  position:absolute;inset:0;z-index:-2;
  background-image:var(--case-photo);
  background-size:cover;background-position:50% 40%;
  /* barely visible at rest - the gradient is the tile and the photograph is
     a hint of one. Hover lifts it. */
  filter:grayscale(.15) brightness(.5) contrast(1.06) saturate(.85);
  opacity:1;
  transition:opacity .3s ease, transform .7s cubic-bezier(.16,1,.3,1);
}
/* A charcoal gradient laid over the photograph rather than a dark foot under
   the words: slightly lighter charcoal at the top, down through dark charcoal
   to almost black where the words sit. It runs on the card's own angle, so the
   nine still differ. */
.cases__grid .ccard::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(var(--case-ang),
    rgba(58,58,64,.3) 0%,
    rgba(34,34,39,.5) 44%,
    rgba(17,17,20,.74) 78%,
    rgba(9,9,11,.9) 100%);
}
/* and a second pass straight up the card, so the foot is the darkest part of
   it whatever angle the first one runs at */
.cases__grid .ccard::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(0deg,
    rgba(6,6,8,.86) 0%,
    rgba(6,6,8,.6) 34%,
    rgba(6,6,8,.3) 62%,
    rgba(6,6,8,.12) 100%);
}
/* the result is the heading of the card: one line, taken from the sentence
   under it, rather than a label and a heading fighting for the same place */
.cc__eyebrow{
  font-family:var(--font-head);
  font-size:clamp(1.5rem,2.05vw,1.875rem);
  font-weight:700;line-height:1.1;letter-spacing:-.03em;
  color:#fff;text-wrap:balance;
}
/* body copy, so Manrope - it was set in the heading face, which is for
   headings only */
.cc__line{
  margin:1.15rem 0 0;
  font-family:var(--font-body);
  font-size:clamp(1.0625rem,1.3vw,1.125rem);
  font-weight:400;line-height:1.5;letter-spacing:-.008em;
  color:rgba(255,255,255,.82);
  text-wrap:pretty;
}
/* the figures, inside the sentence rather than pulled out of it */
.cc__line b{font-weight:700;color:var(--lime);}
.cc__chips{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:1.15rem;}
.cc__chips span{
  padding:.32rem .7rem;
  border-radius:var(--radius-full);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.26);
  font-size:.75rem;font-weight:600;color:rgba(255,255,255,.88);
}
.cc__foot{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  margin-top:auto;padding-top:1.5rem;
}
.cc__name{
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:700;letter-spacing:-.02em;
  color:#fff;
}
.cc__view{
  display:inline-flex;align-items:center;gap:.35rem;
  font-size:.875rem;color:rgba(255,255,255,.66);
  transition:color .2s ease;
}
.cc__view svg{width:.85rem;height:.85rem;transition:transform .2s ease;}

@media (hover:hover){
  .cases__grid .ccard:hover,
  .cases__grid .ccard:focus-within{
    transform:translateY(-4px);
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.14), 0 4px 10px rgba(0,0,0,.2), 0 26px 56px rgba(0,0,0,.3);
  }
  .cases__grid .ccard:hover .cc__ph{opacity:.4;transform:scale(1.04);}
  .cases__grid .ccard:hover .cc__view{color:var(--lime);}
  .cases__grid .ccard:hover .cc__view svg{transform:translateX(.2rem);}
}
@media (prefers-reduced-motion:reduce){
  .cases__grid .ccard,.cc__ph,.cc__view,.cc__view svg{transition:none;}
}
/* The filter sets the hidden attribute, and [hidden] is one class worth of
   specificity against the two in ".cases__grid .ccard{display:flex}", so the
   card stayed on screen while the DOM reported it hidden. */
.cases__grid .ccard:focus-visible{outline:3px solid var(--lime);outline-offset:3px;}
/* one tile per row here, so the foot has ~260px to hold both the name and the
   pill: measured, "Cartridges Direct" plus a Google Ads pill wanted 279 and
   wrapped to two lines. Both come down enough to sit on one. */
@media (max-width:520px){
  .cc__body{padding:1.15rem;}
  .cc__stats{gap:.3rem 1.1rem;}
  .cc__name{font-size:1.0625rem;}
}

/* ---------- lime ticker, directly under the hero ----------
   Same mechanics as the logo marquee: two identical sets in one track, the
   track translated -50% so the loop is seamless. Full-bleed by cancelling the
   shell padding, and square-edged against the hero's rounded bottom so it
   reads as its own band. */
.ticker{
  /* the same full bleed as the hero directly above it, so the two read as one
     edge-to-edge block rather than a card sitting on the page */
  margin:0 calc(var(--shell) * -1);
  border-radius:0;
  background:var(--ticker-lime);
  color:var(--ink-dark);
  /* no edge mask: the logo marquee fades out because it sits on paper, but this
     bar is a solid band inside the stack, and the fade washed the lime to the
     page background for the first 200px on each side. The text hard-clips at
     the edges instead, which is what a ticker normally does. */
  overflow:hidden;
}
.ticker__track{
  display:flex;
  width:max-content;
  animation:ticker 44s linear infinite;
}
.ticker:hover .ticker__track{animation-play-state:paused;}
@keyframes ticker{to{transform:translateX(-50%);}}
.ticker__set{
  display:flex;align-items:center;
  gap:2.5rem;
  padding:.85rem 1.25rem .85rem 0;
}
.ticker__item{
  display:inline-flex;align-items:center;gap:.5rem;
  flex:0 0 auto;
  font-family:var(--font-head);
  font-size:.9375rem;font-weight:700;letter-spacing:-.01em;
  white-space:nowrap;
}
/* align-items:center centres the icon on the line box, but the cap-height band
   of the type sits above that centre, since the em box carries descender space
   the digits and caps here never use. Measured against the painted pixels of
   "300", the icon landed 2.17px low at 15px type: -.145em corrects it and
   scales with the font. */
.ticker__item svg{
  width:1.1rem;height:1.1rem;flex:0 0 auto;
  transform:translateY(-.145em);
}
@media (max-width:640px){
  .ticker__set{gap:1.75rem;padding:.75rem 1rem .75rem 0;}
  .ticker__item{font-size:.875rem;}
}

/* ---------- hero: team line above the title, rating on the photograph ----------
   The rating pill used to sit above the h1. The faces stay there carrying the
   team line, and the stars move onto the photograph where the number is next
   to a picture of the people rather than next to the headline. */
.hero__team{
  display:inline-flex;align-items:center;gap:.85rem;
  margin:0 0 1.6rem;
  font-family:var(--font-head);
  font-size:.9375rem;font-weight:600;letter-spacing:-.01em;
  color:#fff;
}
.hero__team .faces{display:flex;margin-right:.35rem;}
.hero__team .face{width:1.9rem;height:1.9rem;border-width:2px;margin-right:-.55rem;}
.hero__team .face:last-child{margin-right:0;}

/* a pill sitting inside the media card, inset off its bottom-left corner */
.hero__reviews{
  position:absolute;
  left:1.25rem;bottom:1.25rem;
  z-index:2;
  display:flex;align-items:center;gap:.55rem;
  margin:0;
  padding:.6rem 1rem;
  border-radius:var(--radius-full);
  background:rgba(20,17,28,.9);
  border:1px solid rgba(255,255,255,.14);
  box-shadow:0 10px 30px rgba(0,0,0,.35);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  font-size:.875rem;color:var(--grey-100);
  white-space:nowrap;
}
.hero__reviews .gmark{width:1.15rem;height:1.15rem;display:block;flex:0 0 auto;}
.hero__reviews .stars{font-size:.8125rem;letter-spacing:.04em;}
.hero__reviews strong{color:#fff;font-weight:600;}
@media (max-width:1024px){
  .hero__reviews{left:1rem;right:auto;bottom:1rem;}
}
@media (max-width:520px){
  /* tighter inset at phone width so the pill still clears the card edges */
  .hero__reviews{
    left:.6rem;right:auto;bottom:.6rem;
    font-size:.75rem;padding:.45rem .7rem;gap:.35rem;
  }
  .hero__reviews .stars{font-size:.75rem;}
  .hero__team{font-size:.875rem;gap:.6rem;}
  .hero__team .face{width:1.7rem;height:1.7rem;}
}

/* ---------- the sticky call bar ----------
   A floating pill rather than a full-width strip: centred, the width of the
   content column, and lifted clear of the bottom edge so it reads as an
   object on the page rather than browser furniture.

   Its ground is deliberately lighter than the strategy-call section it
   follows (#1C1729). Matched to it, the bar disappeared into the section it
   was meant to sit in front of.

   It hides itself again over the enquiry form at the foot of the page,
   because covering that form with a CTA for the same thing is the one place
   a bar like this actively costs a lead. */
.sbar{
  position:fixed;left:50%;bottom:2.25rem;z-index:60;
  width:min(calc(100% - 2.5rem), 64rem);
  padding:.7rem .7rem .7rem 1.1rem;
  border-radius:var(--radius-full);
  background:rgba(56,46,84,.92);
  -webkit-backdrop-filter:blur(20px) saturate(1.3);backdrop-filter:blur(20px) saturate(1.3);
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.14),
    0 2px 6px rgba(0,0,0,.2),
    0 22px 60px rgba(0,0,0,.45);
  color:#fff;
  transform:translate(-50%, calc(100% + 3rem));
  visibility:hidden;
  transition:transform .4s cubic-bezier(.16,1,.3,1), visibility .4s;
}
.sbar.is-on{transform:translate(-50%,0);visibility:visible;}
.sbar__in{display:flex;align-items:center;gap:1rem;}
.sbar__avatar{
  width:2.9rem;height:2.9rem;flex:0 0 auto;
  border-radius:50%;overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.24);
}
.sbar__avatar img{width:100%;height:100%;object-fit:cover;display:block;}
.sbar__copy{display:flex;flex-direction:column;min-width:0;flex:1 1 auto;}
.sbar__copy b{
  font-family:var(--font-head);
  font-size:1.375rem;font-weight:700;letter-spacing:-.026em;line-height:1.15;
}
.sbar__copy span{
  margin-top:.15rem;
  font-size:.875rem;color:rgba(255,255,255,.72);
}
.sbar__go{display:flex;align-items:center;gap:1.1rem;flex:0 0 auto;}
.sbar__tel{font-size:.9375rem;font-weight:600;color:#fff;white-space:nowrap;}
.sbar__tel:hover{color:var(--lime);}
.sbar__go .btn{padding:.72rem 1.2rem;font-size:.9375rem;}
.sbar__x{
  flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  width:2rem;height:2rem;border-radius:50%;
  background:rgba(255,255,255,.1);
  border:1px solid rgba(255,255,255,.16);
  color:rgba(255,255,255,.72);
  cursor:pointer;
  transition:background .18s ease, color .18s ease;
}
.sbar__x:hover{background:rgba(255,255,255,.2);color:#fff;}
.sbar__x svg{width:.85rem;height:.85rem;}

@media (max-width:760px){
  .sbar{
    bottom:1rem;
    width:calc(100% - 1.5rem);
    padding:.55rem .55rem .55rem .9rem;
  }
  .sbar__in{gap:.6rem;}
  .sbar__avatar,.sbar__copy span,.sbar__tel{display:none;}
  .sbar__copy b{font-size:1.0625rem;}
  .sbar__go .btn{padding:.65rem 1rem;font-size:.875rem;}
}
@media (prefers-reduced-motion:reduce){
  .sbar{transition:none;}
}

/* ---------- Inside DUNK: the photo gallery ----------
   Nine frames and nothing else - no heading, no copy. Six landscape and
   three cropped to portrait, laid out in columns rather than a grid. A grid with mixed ratios either leaves holes
   or forces every frame to one shape; columns let each keep its own and
   still pack tight. The order reads down each column, which is what a
   gallery wants anyway. */
/* Full bleed, like the hero and the ticker: the shell padding is cancelled on
   both sides and the rounding comes off, so the photographs run to the
   viewport edge rather than sitting in a card. */
.gal{
  margin:var(--shell) calc(var(--shell) * -1) 0;
  padding:clamp(2.5rem,4.5vw,4rem) var(--edge);
  border-radius:0;
  background:
    radial-gradient(ellipse 60% 62% at 12% 0%, rgba(var(--purple-accent),.26) 0%, rgba(var(--purple-accent),0) 62%),
    radial-gradient(ellipse 52% 58% at 96% 92%, rgba(255,111,196,.09) 0%, rgba(255,111,196,0) 60%),
    #1C1729;
  color:#fff;
}



/* A collage, not three equal columns. Twelve columns by three short rows, and
   the nine frames each take their own cells - one tall, the rest wide or
   square - so the section is a third of the height it was and reads as one
   arrangement rather than a stack of photographs. */
.gal__grid{
  max-width:var(--max);margin:0 auto;
  display:grid;
  grid-template-columns:repeat(12,minmax(0,1fr));
  grid-auto-rows:clamp(9rem,19vw,18rem);
  gap:.75rem;
}
/* twelve across three rows, widths varied so no two rows break in the same
   place. Every cell is placed, so a photograph can never reflow into a
   different shape when one is added or taken away. */
.gal__i--1{grid-column:1 / 4;grid-row:1;}
.gal__i--2{grid-column:4 / 7;grid-row:1;}
.gal__i--3{grid-column:7 / 11;grid-row:1;}
.gal__i--4{grid-column:11 / 13;grid-row:1;}
.gal__i--5{grid-column:1 / 3;grid-row:2;}
.gal__i--6{grid-column:3 / 7;grid-row:2;}
.gal__i--7{grid-column:7 / 10;grid-row:2;}
.gal__i--8{grid-column:10 / 13;grid-row:2;}
.gal__i--9{grid-column:1 / 4;grid-row:3;}
.gal__i--10{grid-column:4 / 8;grid-row:3;}
.gal__i--11{grid-column:8 / 11;grid-row:3;}
.gal__i--12{grid-column:11 / 13;grid-row:3;}
.gal__i{
  margin:0;
  border-radius:1rem;
  overflow:hidden;
  background:#251E36;
  box-shadow:0 2px 6px rgba(0,0,0,.24), 0 16px 36px rgba(0,0,0,.3);
}
.gal__i img{
  width:100%;height:100%;display:block;object-fit:cover;
  transition:transform .6s cubic-bezier(.16,1,.3,1);
}
@media (hover:hover){
  .gal__i:hover img{transform:scale(1.035);}
}
@media (prefers-reduced-motion:reduce){
  .gal__i img{transition:none;}
}
@media (max-width:900px){
  .gal__grid{grid-template-columns:repeat(6,minmax(0,1fr));grid-auto-rows:clamp(8rem,22vw,12rem);}
  .gal__i{grid-column:auto;grid-row:auto;}
  .gal__i--1{grid-column:1 / 4;} .gal__i--2{grid-column:4 / 7;}
  .gal__i--3{grid-column:1 / 3;} .gal__i--4{grid-column:3 / 7;}
  .gal__i--5{grid-column:1 / 4;} .gal__i--6{grid-column:4 / 7;}
  .gal__i--7{grid-column:1 / 3;} .gal__i--8{grid-column:3 / 7;}
  .gal__i--9{grid-column:1 / 4;} .gal__i--10{grid-column:4 / 7;}
  .gal__i--11{grid-column:1 / 3;} .gal__i--12{grid-column:3 / 7;}
}
@media (max-width:620px){
  .gal{padding:2.75rem 1.35rem 3rem;}
  .gal__grid{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:clamp(9rem,36vw,13rem);}
  .gal__i{grid-column:auto;grid-row:auto;}
  .gal__i--1{grid-column:1 / 3;}
}

/* ---------- the partner section ----------
   Full bleed and near-black, so it reads as a break in the page rather than
   another card in the stack. Centred column: the Google rating, a lime
   eyebrow, the claim, the detail, the button, then three photographs fanned
   below it and running off the bottom edge. */
.pt{
  position:relative;isolation:isolate;overflow:hidden;
  margin:var(--shell) calc(var(--shell) * -1) 0;
  padding:clamp(3.5rem,6vw,6rem) var(--edge) 0;
  border-radius:0;
  /* light, not dark: the page had too many dark sections in a row and this is
     the one that most wants to feel open */
  /* neutral: the lime and violet blooms read as decoration on a section
     whose job is the photographs and the certifications */
  background:
    radial-gradient(ellipse 60% 55% at 50% 0%, rgba(255,255,255,.9) 0%, rgba(255,255,255,0) 68%),
    var(--paper);
  color:var(--ink-dark);
  text-align:center;
}
.pt__in{max-width:72rem;margin:0 auto;}
.pt__eyebrow{
  margin:0;
  font-size:.875rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--lime);
}
.pt h2{
  margin:1rem 0 0;
  font-family:var(--font-head);
  /* the same size and weight as every other section heading, rather than a
     display size of its own */
  font-size:clamp(1.875rem,3.2vw,2.875rem);
  font-weight:600;line-height:1.05;letter-spacing:-.035em;
  color:var(--ink-dark);
  text-wrap:balance;
}
.pt__lede{
  margin:1.25rem auto 0;max-width:44rem;
  font-size:1rem;line-height:1.65;color:#54545a;
  text-wrap:balance;
}

/* the three photographs, fanned and running off the bottom of the section */
.pt__fan{
  position:relative;
  max-width:var(--max);
  margin:clamp(2.5rem,4.5vw,4rem) auto 0;
  max-width:none;
  width:124%;margin-left:-12%;
  aspect-ratio:16 / 5.6;
}
.pt__fan img{
  position:absolute;
  width:35%;height:auto;
  border-radius:.65rem;
  box-shadow:0 2px 6px rgba(0,0,0,.14), 0 20px 46px rgba(0,0,0,.18);
}
/* spread so the middle frame stops covering the people in the outer two: at
   41% each and a 45% centre they only meet at the edges */
.pt__a{left:0;top:8%;transform:rotate(-5deg);}
.pt__c{left:59%;top:8%;transform:rotate(5deg);}
.pt__b{z-index:2;left:30%;top:0;width:40%;transform:rotate(-1deg);}

@media (max-width:760px){
  .pt{padding:2.75rem 1.35rem 0;}
  .pt__fan{aspect-ratio:16 / 9;}
  .pt__fan img{width:44%;}
  .pt__a{left:1%;}
  .pt__c{left:55%;}
  .pt__b{left:28%;width:46%;}
}

/* ---------- the tilted photo band ----------
   A single row of frames at slight angles, the row wider than the window so
   the first and last run off both edges. It sits inside the approach panel
   rather than in a section of its own - on its own ground the photographs had
   a blank band behind them; here they share the panel with the statement and
   the client logos. */
.tilt__row{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(.75rem,1.6vw,1.5rem);
  /* wider than the panel on purpose: the end frames are meant to be cut */
  width:124%;margin:clamp(4rem,7vw,6.5rem) 0 0 -12%;
}
.tilt__i{
  flex:1 1 0;min-width:0;
  height:auto;
  border-radius:.5rem;
  transform:rotate(var(--rot));
  box-shadow:0 4px 12px rgba(0,0,0,.5), 0 18px 44px rgba(0,0,0,.55);
}
/* the middle frames sit a little proud, so the row has a centre */
.tilt__i:nth-child(3),.tilt__i:nth-child(4){transform:rotate(var(--rot)) scale(1.12);z-index:2;position:relative;}
.tilt__i:nth-child(2),.tilt__i:nth-child(5){transform:rotate(var(--rot)) scale(1.05);z-index:1;position:relative;}

@media (max-width:760px){
  .tilt__row{width:150%;margin-left:-25%;gap:.6rem;}
}


/* The certifications sit on their own white strip rather than on the section
   ground - every one of these logos is drawn for white - and the strip runs to
   the foot of the section so there is no band of paper between it and whatever
   comes next. */
.acc{
  list-style:none;
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(1.25rem,3vw,2.75rem);
  /* A real full bleed. Pulling back by --edge did not work: --edge is a max()
     against 100%, which resolves off this element's own width rather than the
     section's, so the negative margin never matched the section's padding and
     a band of paper stayed either side. */
  width:100vw;margin:clamp(2.5rem,4vw,3.5rem) 0 0 calc(50% - 50vw);
  padding:clamp(1.75rem,3vw,2.5rem) var(--gutter);
  background:#fff;
}
.acc li{
  /* one box for every logo, and each one fits inside it. Matching on height
     alone made the ahrefs wordmark enormous next to the round badges, because
     their artwork carries its own padding and its own proportions. */
  flex:0 0 auto;
  width:clamp(6rem,9vw,8.5rem);
  height:clamp(2.75rem,4vw,3.5rem);
  display:flex;align-items:center;justify-content:center;
}
.acc img{
  max-width:100%;max-height:100%;width:auto;height:auto;display:block;
  object-fit:contain;
}




/* The certifications row on the inner pages, matched to the homepage strip:
   white, edge to edge, logos in colour. It was a rounded white card inset in
   the page, which is a different answer to the same question. */
.badge:has(.badge__row){
  margin-left:calc(var(--shell) * -1);
  margin-right:calc(var(--shell) * -1);
  border-radius:0;
  background:#fff;
}
.badge:has(.badge__row) .badge__row{
  max-width:var(--max);margin:0 auto;
  gap:clamp(1.75rem,4vw,3.5rem);
}
.badge:has(.badge__row) img{filter:none;opacity:1;}

/* ---------- the contact section as a card ----------
   Declared last on purpose: the two earlier .cta blocks are equal
   specificity and the later declaration wins, so this is the one that
   paints. The structure is a white card on a brand-purple ground with the
   copy left and the form right, and the ground carries the embellishment
   (two soft blooms and a fine dot grid) so the card itself stays plain and
   the form on it reads as the point of the section. */
.cta--light{
  padding:clamp(3rem,5vw,4.75rem) var(--edge);
  background:
    radial-gradient(ellipse 48% 60% at 6% 0%, rgba(255,255,255,.22) 0%, rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 46% 58% at 100% 100%, rgba(217,233,104,.20) 0%, rgba(217,233,104,0) 66%),
    radial-gradient(ellipse 60% 60% at 60% 30%, rgba(122,84,220,1) 0%, rgba(122,84,220,0) 70%),
    #5B31C4;
}
.cta--light::before{
  content:"";display:block;
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:radial-gradient(rgba(255,255,255,.16) 1px, transparent 1.4px);
  background-size:22px 22px;
  -webkit-mask-image:linear-gradient(180deg, rgba(0,0,0,.9) 0%, rgba(0,0,0,.25) 55%, transparent 100%);
  mask-image:linear-gradient(180deg, rgba(0,0,0,.9) 0%, rgba(0,0,0,.25) 55%, transparent 100%);
  opacity:1;
}
.cta--light::after{display:none;}
.cta--light .cta__panel{
  max-width:80rem;
  grid-template-columns:minmax(0,1fr) minmax(0,36rem);
  gap:clamp(2rem,4vw,3.5rem);
  padding:clamp(2rem,3.5vw,3.25rem);
  border-radius:1.75rem;
  background:#fff;
  box-shadow:0 1px 0 rgba(255,255,255,.35) inset, 0 30px 80px rgba(20,8,50,.35), 0 8px 24px rgba(20,8,50,.18);
}
.cta--light .cta__panel h2{font-size:clamp(2rem,3.6vw,3rem);}
.cta--light .cta__lede{margin-top:1.25rem;}
/* proof block: the terms first, then the person and the rating in a tinted
   strip, so the eye lands on what you get before who you get */
.cta--light .cta__proof{
  margin-top:1.75rem;padding-top:1.5rem;
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:1.35rem .75rem;
  align-items:stretch;
}
.cta--light .cta__ticks{grid-column:1 / -1;}
.cta--light .cta__stars{align-content:center;}
@media (max-width:640px){
  .cta--light .cta__proof{grid-template-columns:minmax(0,1fr);}
}
.cta--light .cta__ticks{order:-1;gap:.8rem;font-size:1rem;color:var(--ink-dark);}
.cta--light .cta__ticks li{gap:.75rem;}
.cta--light .cta__ticks svg{
  width:1.5rem;height:1.5rem;padding:.3rem;
  border-radius:50%;
  background:rgb(var(--purple-accent));
  color:#fff;
}
.cta--light .cta__host,
.cta--light .cta__stars{
  margin:0;padding:.9rem 1.1rem;
  border-radius:1rem;
  background:rgba(var(--purple-accent),.07);
}
.cta--light .cta__stars{gap:.6rem;font-size:.9375rem;}
.cta--light .cta__stars img{width:1.25rem;height:1.25rem;}
/* the form sits straight on the card now, so the embed loses its own card */
.cta--light .lead__pd{
  max-width:none;margin:0;
  border-radius:0;padding:0;
  background:transparent;box-shadow:none;
  min-height:34rem;
}
.cta--light .lead{box-shadow:none;border-color:rgba(18,18,18,.1);}
@media (max-width:1280px){
  .cta--light .cta__panel{grid-template-columns:minmax(0,1fr);}
  .cta--light .lead__pd{max-width:36rem;margin:0 auto;width:100%;}
}
@media (max-width:640px){
  .cta--light{padding:2.5rem var(--gutter);}
  .cta--light .cta__panel{padding:1.5rem 1.15rem;border-radius:1.25rem;}
}

/* darker ground, and it runs into the footer: the lower third dissolves
   to the footer's own #15131C so the two are one dark block, no seam */
.cta--light{
  background:
    linear-gradient(180deg, rgba(21,19,28,0) 0%, rgba(21,19,28,0) 58%, rgba(21,19,28,.85) 88%, #15131C 100%),
    radial-gradient(ellipse 48% 60% at 6% 0%, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 46% 58% at 100% 40%, rgba(217,233,104,.12) 0%, rgba(217,233,104,0) 66%),
    radial-gradient(ellipse 60% 60% at 60% 20%, rgba(88,52,190,1) 0%, rgba(88,52,190,0) 70%),
    #34197F;
  padding-bottom:clamp(3.5rem,6vw,5.5rem);
}
.cta--light::before{
  background-image:radial-gradient(rgba(255,255,255,.12) 1px, transparent 1.4px);
}
/* the copy column ran out well before the form did, which left a white
   field under the proof. A real review and the ways to reach us fill it. */
.cta__quote{
  margin:1.5rem 0 0;padding:1.25rem 1.35rem 1.25rem 1.5rem;
  border-left:3px solid rgb(var(--purple-accent));
  border-radius:0 1rem 1rem 0;
  background:linear-gradient(90deg, rgba(var(--purple-accent),.08), rgba(var(--purple-accent),.02));
}
.cta__quote blockquote{
  margin:0;
  font-family:var(--font-head);
  font-size:1.0625rem;line-height:1.5;letter-spacing:-.012em;font-weight:500;
  color:var(--ink-dark);text-wrap:pretty;
}
.cta__quote figcaption{
  margin-top:.8rem;display:flex;flex-wrap:wrap;gap:.25rem .6rem;align-items:baseline;
  font-size:.8125rem;color:rgba(18,18,18,.62);
}
.cta__quote figcaption b{color:var(--ink-dark);font-weight:600;}
.cta__reach{margin:1.5rem 0 0;padding-top:1.35rem;border-top:1px solid rgba(18,18,18,.1);}
.cta__reach-l{
  margin:0 0 .85rem;
  font-family:var(--font-head);font-size:1rem;font-weight:600;letter-spacing:-.015em;
  color:var(--ink-dark);
}
.cta__reach ul{list-style:none;margin:0;padding:0;display:grid;gap:.6rem;}
.cta__reach li{display:flex;align-items:center;gap:.7rem;font-size:.9375rem;color:rgba(18,18,18,.74);min-width:0;}
.cta__reach svg{width:1.15rem;height:1.15rem;flex:0 0 auto;color:rgb(var(--purple-accent));}
.cta__reach a{color:var(--ink-dark);font-weight:600;text-decoration:none;}
.cta__reach a:hover{text-decoration:underline;text-underline-offset:.15em;}

/* the Google mock is the tallest of the four and its two cards are rotated
   in opposite directions, so it needs more room inside the band than the
   others before its corners reach the edge. Declared after .viz, which it
   ties with on specificity. */
.viz--gads{width:82%;}


/* ---- the four services, as alternating full-width rows ----
   This was a 2x2 grid of cards. Four detailed mockups do not survive being
   squeezed into a 430px column: the search ad and the creative fan both ran
   past their band and were clipped, and every fix traded one crop for
   another. A row gives each mock half of a 74rem container, which is the
   width it was drawn for, and gives the copy beside it room for a sentence
   rather than four bare bullets. The sides alternate so the eye zig-zags
   down the four rather than reading one column twice. */
.svc__rows{display:grid;}
.srow{
  display:grid;
  grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);
  gap:clamp(2rem,4vw,3.75rem);
  align-items:center;
}
/* the divider is padding on the row below rather than a gap, so the hairline
   sits exactly between the two and not floating in the middle of one */
.srow + .srow{
  margin-top:clamp(2.5rem,4.5vw,4rem);
  padding-top:clamp(2.5rem,4.5vw,4rem);
  border-top:1px solid rgba(18,18,18,.1);
}
/* placed by column rather than by order, so the mock always takes the wider
   of the two and the four bands come out the same width whichever side they
   are on. With order alone the even rows handed the mock the narrow column. */
.srow__media{grid-column:1;grid-row:1;}
.srow__body{grid-column:2;grid-row:1;}
.srow:nth-of-type(even){grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);}
.srow:nth-of-type(even) .srow__media{grid-column:2;}
.srow:nth-of-type(even) .srow__body{grid-column:1;}
.srow__media{min-width:0;}
.srow .sgrid__ph{
  border-radius:1.35rem;
  min-height:clamp(16rem,22vw,20rem);
  padding:clamp(1.75rem,2.6vw,2.5rem);
  box-shadow:0 2px 6px rgba(0,0,0,.1), 0 22px 50px rgba(0,0,0,.16);
}
.srow__body{min-width:0;}
.srow__n{
  display:flex;align-items:center;gap:.7rem;
  margin:0 0 .9rem;
  font-size:.75rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:#6b6b73;
}
.srow__n b{
  display:grid;place-items:center;
  width:2rem;height:2rem;border-radius:50%;
  background:var(--lime);
  font-size:.75rem;font-weight:700;letter-spacing:.02em;color:var(--ink-dark);
}
.srow h3{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(1.625rem,2.6vw,2.25rem);
  line-height:1.1;letter-spacing:-.032em;font-weight:600;
  color:var(--ink-dark);text-wrap:balance;
}
.srow__lede{
  margin:.9rem 0 0;max-width:34rem;
  font-size:1.0625rem;line-height:1.6;color:#54545a;
}
.srow__list{
  margin:1.35rem 0 0;padding:0;list-style:none;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem 1.5rem;
}
.srow__list li{
  position:relative;padding-left:1.4rem;
  font-size:.9375rem;line-height:1.5;color:var(--ink-dark);
}
.srow__list li::before{
  content:"";position:absolute;left:0;top:.5em;
  width:.5rem;height:.5rem;border-radius:50%;
  background:var(--lime);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
}
.srow__go{
  display:inline-flex;align-items:center;gap:.5rem;
  margin-top:1.6rem;padding:.7rem 1.15rem;
  border:1px solid rgba(18,18,18,.16);border-radius:99px;
  font-size:.9375rem;font-weight:600;color:var(--ink-dark);text-decoration:none;
  transition:background-color .18s ease, border-color .18s ease;
}
.srow__go svg{width:.95rem;height:.95rem;transition:transform .18s ease;}
.srow__go:hover{background:var(--ink-dark);border-color:var(--ink-dark);color:#fff;}
.srow__go:hover svg{transform:translateX(.2rem);}
/* side by side, every band takes the same ratio so the four read as a set.
   Stacked, it comes off: the column is full width there and a 7/5 band would
   be shorter than the mock inside it. */
@media (min-width:961px){
  .srow .sgrid__ph{aspect-ratio:5 / 4;min-height:0;}
  /* the Google mock is two rotated cards stacked and the tallest of the
     four, so it takes less of the band's width to come out the same height */
  .srow .viz--gads{width:76%;}
}
/* Between 961 and 1280 the band narrows but the mock does not: its type and
   its paddings are in rem, so a percentage width shrinks it sideways only
   and it grows past the band's fixed ratio. Scaling the whole mock keeps
   every proportion inside it and keeps it in the frame. There is no unitless
   way to derive a scale from the viewport, so these are steps. */
@media (min-width:1100px) and (max-width:1279px){
  .srow .viz--gads{transform:scale(.93);}
}
@media (min-width:961px) and (max-width:1099px){
  .srow .viz--gads{transform:scale(.76);}
}
@media (max-width:960px){
  .srow{grid-template-columns:minmax(0,1fr);gap:1.75rem;}
  /* the mock leads on every row once they stack, so the rhythm does not
     depend on which side it was on */
  .srow,.srow:nth-of-type(even){grid-template-columns:minmax(0,1fr);}
  .srow__media,.srow:nth-of-type(even) .srow__media{grid-column:1;grid-row:1;}
  .srow__body,.srow:nth-of-type(even) .srow__body{grid-column:1;grid-row:2;}
}
@media (max-width:560px){
  .srow__list{grid-template-columns:minmax(0,1fr);}
}


/* the collage runs the full width of the window rather than sitting inside
   the page gutter: nine photographs at gutter width read as a component,
   edge to edge they read as the room the section is describing */
.gal__grid{
  /* max-width is reset here on purpose: the rule above caps the grid at the
     96rem page measure, which left 400px of empty ground on either side of
     the collage on a 1940px screen */
  max-width:none;
  width:100vw;margin-left:calc(50% - 50vw);
  padding:0 .75rem;
}


/* the client and the industry it trades in, as one block in the foot */
.cc__id{display:flex;flex-direction:column;gap:.1rem;min-width:0;}
.cc__id b{
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:700;letter-spacing:-.02em;color:#fff;
}
.cc__id i{font-style:normal;font-size:.8125rem;color:rgba(255,255,255,.6);}

/* ---- the FAQ photograph, moved into the ground ----
   It was a framed picture in the left column, which made that column a
   picture with a heading under it. As the section's own background, held
   back by a near-opaque paper wash, it is texture rather than content and
   the two columns are both text again. */
.faq{
  background-image:
    linear-gradient(rgba(244,243,239,.95), rgba(244,243,239,.95)),
    url("/img/faq-shot-v1.webp");
  background-size:auto, cover;
  background-position:center, center;
  background-repeat:no-repeat, no-repeat;
}
.faq__shot{display:none;}
/* the photograph used to hold row one of the left column, so without it the
   two remaining blocks sit on one row. Kept inside the breakpoint the rest
   of the two-column layout lives in: unscoped, these placed the question
   list in a second column that does not exist on a phone, and it ran 130px
   off the side of the screen. */
@media (min-width:1025px){
  .faq__inner{grid-template-rows:auto;}
  .faq__side{grid-column:1;grid-row:1;}
  .faq__list{grid-column:2;grid-row:1;}
}

/* ---- one typographic scale for every section head ----
   The eight section headings had drifted to five different sizes: 41.8, 46,
   46.1, 48 and 52px at 1440, each set where its section was built. They are
   the same rank in the page, so they take the same type. Ledes were on two
   sizes for the same reason and take one. */
.picker h2,
.call__copy h2,
.pt h2,
.svc__aside h2,
.voices__head h2,
.cases__head h2,
.faq__side h2,
.cta__panel h2{
  font-family:var(--font-head);
  font-size:clamp(2rem,3.4vw,3rem);
  line-height:1.08;
  letter-spacing:-.035em;
  font-weight:600;
  text-wrap:balance;
}
.picker__lede,
.call__copy > p,
.pt__lede,
.svc__lede,
.voices__lede,
.cases__lede,
.faq__side p,
.cta__lede{
  font-size:1.0625rem;
  line-height:1.6;
}
/* and one size below that for the rank under a section head: the service
   name on each row, and the heading on a case tile */
.srow h3,
.cc__eyebrow{
  font-size:clamp(1.5rem,2.05vw,1.875rem);
  line-height:1.12;
  letter-spacing:-.03em;
}

/* ---- the Meta row: the creatives, and nothing behind them ----
   The other three mocks are interfaces and need a ground to sit on. This one
   is three pieces of real work, and the dark band was a frame around
   photographs that already have their own edges. Without it they can also be
   half as big again. */
.srow:nth-of-type(2) .sgrid__ph{
  background:transparent;
  box-shadow:none;
  overflow:visible;
  padding:0;
}
.srow:nth-of-type(2) .sgrid__ph::before,
.srow:nth-of-type(2) .sgrid__ph::after{display:none;}
.srow:nth-of-type(2) .viz--fan{width:100%;}


/* the rail's own scrollbar. It sits outside .crail so the mask does not fade
   its ends, it reports how far through the row you are, and it can be
   dragged, which is the only way through a rail for a mouse with no
   horizontal wheel. */
.crail__bar{
  position:relative;
  height:6px;
  margin:1.25rem auto 0;
  max-width:26rem;
  border-radius:99px;
  background:rgba(18,18,18,.1);
  cursor:pointer;
  touch-action:none;
}
.crail__thumb{
  position:absolute;top:0;left:0;height:100%;
  min-width:2.5rem;
  border-radius:99px;
  background:rgba(18,18,18,.42);
  transition:background-color .18s ease;
}
.crail__bar:hover .crail__thumb,
.crail__bar.is-drag .crail__thumb{background:var(--ink-dark);}
@media (prefers-reduced-motion:no-preference){
  .cases__grid{scroll-behavior:smooth;}
}


/* the certification strip is the last thing in the partner section and runs
   the full width of the window, so the page gutter below it showed as a grey
   line between a white bar and the paper section under it. The two sections
   butt together instead: section, bar, section. */
.pt + .svc{margin-top:0;}

/* ---- the mocks on the page's own ground ----
   The dark bands were doing the same job for four different things, and a
   Google result is white on white in real life, so a violet band around one
   made it read as an illustration of an ad rather than an ad. They sit on
   the paper now, with Google's own hairline and its own type colours. */
.srow .sgrid__ph{
  background:transparent;
  box-shadow:none;
  overflow:visible;
  padding:0;
  min-height:0;
}
.srow .sgrid__ph::before,
.srow .sgrid__ph::after{display:none;}
.srow .viz,
.srow .viz--gads{width:100%;}
@media (min-width:961px){
  .srow .sgrid__ph{aspect-ratio:auto;}
  .srow .viz--gads{width:100%;}
}
@media (min-width:1100px) and (max-width:1279px){ .srow .viz--gads{transform:none;} }
@media (min-width:961px) and (max-width:1099px){ .srow .viz--gads{transform:none;} }

/* Google's card: a hairline and a small shadow, not a floating panel */
.srow .viz__card,
.srow .gshop{
  border:1px solid #dadce0;
  border-radius:.75rem;
  box-shadow:0 1px 3px rgba(32,33,36,.1), 0 8px 24px rgba(32,33,36,.08);
}
.srow .viz__omni{
  border:1px solid #dadce0;
  box-shadow:0 1px 3px rgba(32,33,36,.12);
  padding:.6rem .9rem;
  margin-bottom:.75rem;
}
.srow .viz__q{font-size:.875rem;}
.srow .viz__gm img{width:1.1rem;height:1.1rem;}

/* "Sponsored" is bold black body text above the result, which is how Google
   has labelled paid results since 2023. The black pill it replaces was a
   thing this site invented. */
.viz__spon{
  display:block!important;
  margin-bottom:.55rem;
  font-size:.8125rem;font-weight:700;line-height:1.2;color:#202124;
}
.srow .viz__card{padding:1rem 1.1rem;}
.srow .viz__fav{width:1.6rem;height:1.6rem;font-size:.8125rem;}
.srow .viz__site b{font-size:.8125rem;}
.srow .viz__site i{font-size:.75rem;}
.srow .viz__hl{margin-top:.6rem;font-size:1.125rem;line-height:1.3;}
.srow .viz__desc{margin-top:.35rem;font-size:.8125rem;}
.srow .viz__links em{font-size:.8125rem;}

/* the Shopping unit: a product image, its title, the price, the merchant and
   the delivery line, which is the order Google puts them in */
.srow .gshop{padding:.9rem 1rem;}
.srow .gshop__row{gap:.75rem;margin-top:.6rem;}
.srow .gshop__im{height:5.5rem;}
.gshop__p em{
  font-style:normal;display:block!important;
  margin-top:.45rem;
  font-size:.75rem;line-height:1.35;color:#202124;
  display:-webkit-box!important;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.srow .gshop__p b{margin-top:.25rem;font-size:.875rem;}
.srow .gshop__p i{font-size:.6875rem;}
.gshop__p u{
  text-decoration:none;display:block!important;
  margin-top:.1rem;font-size:.6875rem;color:#188038;
}

/* the organic result carries no label at all, which is the whole difference
   between it and the one above */
.srow .viz__pos{top:-.7rem;left:-.7rem;}

/* the press mention keeps its card, on the same hairline as the rest */
.viz--press .viz__card{
  border:1px solid rgba(18,18,18,.12);
  border-radius:.75rem;
  background:#fff;
  box-shadow:0 1px 3px rgba(32,33,36,.1), 0 8px 24px rgba(32,33,36,.08);
}

/* ---- the row's points, as a checklist ---- */
.srow__list{gap:.85rem 1.75rem;margin-top:1.5rem;}
.srow__list li{
  display:flex;align-items:flex-start;gap:.6rem;
  padding-left:0;
  font-size:1rem;line-height:1.45;color:var(--ink-dark);
}
.srow__list li::before{display:none;}
.srow__list li svg{
  flex:0 0 auto;
  width:1.35rem;height:1.35rem;padding:.3rem;
  margin-top:.05rem;
  border-radius:50%;
  background:var(--lime);
  color:var(--ink-dark);
}


/* Straight, not tilted. The angles were there to separate two white cards on
   a dark band; on the page's own ground they only made a real interface look
   like a sticker. The order is a result page's order: the search box, the
   Shopping unit, then the text ad. */
.srow .gshop{transform:none;margin:0;}
.srow .gsearch{transform:none;margin:0;}
.srow .gfan{gap:.85rem;}
.srow .viz__omni{margin-bottom:0;}

/* ---- the challenge panels, without the photographs ----
   The picture at the top of each panel was the only thing separating three
   otherwise identical cards, and it was doing that job by being decorative
   rather than by saying anything. The card is the text now: the question,
   the answer and what it is you would actually be buying. */
.pick{justify-content:flex-start;}
.pick__body{padding:clamp(1.6rem,2.4vw,2.1rem);}

/* ---- the tilted strip, as a section of its own ----
   On the home page this row sits inside the approach block and takes that
   section's dark ground. On a service page it needs its own, so the section
   carries the same near-black and the same bleed to the window edge, and the
   row keeps its overhang: the end frames are meant to run off both sides. */
.tilt{
  position:relative;overflow:hidden;
  margin:var(--shell) calc(var(--shell) * -1) 0;
  padding:clamp(3rem,5vw,4.5rem) var(--edge);
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, rgba(255,255,255,.05) 0%, rgba(255,255,255,0) 66%),
    var(--surface);
}
.tilt__in{max-width:var(--max);margin-inline:auto;}
/* the row's top margin is for the copy above it on the home page; in a
   section of its own the section's own padding does that job */
.tilt .tilt__row{margin-top:0;}

/* ---- square sections butt together ----
   The page is a stack of rounded cards with a gutter between them, which is
   the design. A square, full-bleed section on either side of that gutter is
   not a card, so the gutter reads as a stripe of the page ground cutting
   through two blocks that should meet. These are the pairs that occur across
   the site, measured rather than guessed: in each one both sections are
   square and both run to the window edge. */
.faq + .cta,
.gal + .badge,
.badge + .tilt,
.tilt + .faq,
.badge + .badge,
.gal + .tilt,
.badge + .gal,
.cta + .gal{margin-top:0;}

/* ---- the FAQ ground ----
   A photograph under a 95% wash was still a photograph, and at that opacity
   all it did was put a soft grey shape behind the questions. It takes the
   same treatment as the approach section: wide colour fields on the paper,
   held low, with a fine grain over them. */
.faq{
  position:relative;isolation:isolate;
  background:
    radial-gradient(ellipse 62% 58% at 14% 6%, rgba(var(--purple-accent),.07) 0%, rgba(var(--purple-accent),0) 68%),
    radial-gradient(ellipse 58% 54% at 88% 92%, rgba(217,233,104,.16) 0%, rgba(217,233,104,0) 66%),
    var(--paper);
}
.faq::after{
  content:"";
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  opacity:.7;
  background-image:repeating-linear-gradient(115deg,
    rgba(18,18,18,.022) 0 1px,
    rgba(18,18,18,0) 1px 7px);
}

/* ---- one more turn of air between every section ----
   The page was tight enough that two sections with the same ground read as
   one long section. These roughly double what each was carrying, as one
   block rather than by editing thirty rules, so the ratio between a section
   and the one under it stays where it was. Sections that deliberately carry
   no padding (the heroes, the ticker) are not in the list. */
.picker,.call,.svc,.cases,.voices,.faq,.gal,.band,.tilt,.csdoc{
  padding-top:clamp(4rem,9vw,10rem);
  padding-bottom:clamp(4rem,9vw,10rem);
}
.approach{padding-top:clamp(5rem,11vw,12rem);padding-bottom:clamp(4.5rem,9.5vw,10.5rem);}
.pt{padding-top:clamp(4rem,9vw,10rem);}
.cta{padding-top:clamp(4rem,9vw,10rem);padding-bottom:clamp(4.5rem,9.5vw,10.5rem);}
.whyus{padding-top:clamp(4.5rem,10vw,11rem);padding-bottom:clamp(4.5rem,10vw,11rem);}
.badge{padding-top:clamp(2.25rem,4.5vw,5rem);padding-bottom:clamp(2.25rem,4.5vw,5rem);}
.trust{padding-top:clamp(2.5rem,5vw,5.5rem);padding-bottom:clamp(2.5rem,5vw,5.5rem);}
@media (max-width:640px){
  .picker,.call,.svc,.cases,.voices,.faq,.gal,.band,.tilt,.csdoc,
  .approach,.pt,.cta,.whyus{
    padding-top:clamp(3rem,10vw,4.5rem);
    padding-bottom:clamp(3rem,10vw,4.5rem);
  }
}

/* ---- the case tile, read from the top ----
   The client and the industry lead now, the result and the sentence sit at
   the foot, and the middle of the card is left to the photograph. That gap
   is the point: it is where you can actually see who the client is. */
.cases__grid .ccard{gap:1.5rem;}
.cc__foot{order:-1;margin-top:0;padding-top:0;}
.cc__eyebrow{margin-top:auto;}
/* the photograph in colour and twice as present, with the scrim pulled back
   to the two ends where the words are */
.cc__ph{filter:grayscale(.1) brightness(.72) contrast(1.04) saturate(.95);}
.cases__grid .ccard::before{
  background:linear-gradient(var(--case-ang),
    rgba(42,42,48,.4) 0%,
    rgba(26,26,30,.44) 55%,
    rgba(12,12,15,.5) 100%);
}
.cases__grid .ccard::after{
  background:linear-gradient(180deg,
    rgba(6,6,8,.82) 0%,
    rgba(6,6,8,.42) 22%,
    rgba(6,6,8,.28) 48%,
    rgba(6,6,8,.62) 76%,
    rgba(6,6,8,.9) 100%);
}
@media (hover:hover){
  .cases__grid .ccard:hover .cc__ph{opacity:1;transform:scale(1.05);}
}

/* ---- two sections, one ground ----
   Where a section follows one painted the same colour the two read as a
   single long section and the join disappears. The second takes a step up in
   light, which is enough to separate them without a rule between them. */
/* only paper follows paper: as ".band + .band" this also caught a dark band
   that happened to follow a paper one and painted it #FAF9F6, which put
   white type on near-white ground */
.pt + .svc,
.svc + .cases,
.voices + .faq,
.band--paper + .band--paper{background-color:#FAF9F6;}
.badge + .badge{background-color:#F7F6F3;}
.svc + .cases{
  background:
    radial-gradient(ellipse 62% 55% at 12% 4%, rgba(var(--purple-accent),.05) 0%, rgba(var(--purple-accent),0) 66%),
    #FAF9F6;
}
.voices + .faq{
  background:
    radial-gradient(ellipse 62% 58% at 14% 6%, rgba(var(--purple-accent),.06) 0%, rgba(var(--purple-accent),0) 68%),
    radial-gradient(ellipse 58% 54% at 88% 92%, rgba(217,233,104,.14) 0%, rgba(217,233,104,0) 66%),
    #FAF9F6;
}

/* ---- inside the studio: three rows, drifting ----
   The navy ground is gone and the photographs sit straight on the page. Each
   row moves at its own pace and the middle one runs the other way, which
   reads as movement without anything sliding past fast enough to chase. Two
   identical sets per row make the loop seamless: the track travels exactly
   one set's width and starts again, so there is no jump to see. Every
   photograph from the shoot is in here, fifty of them across the three. */
.gal{
  background:var(--paper);
  color:var(--ink-dark);
  padding-left:0;padding-right:0;
  overflow:hidden;
}
.grows{
  display:grid;gap:clamp(.5rem,1vw,.9rem);
  width:100vw;margin-left:calc(50% - 50vw);
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}
.grow{overflow:hidden;}
.grow__track{display:flex;width:max-content;gap:clamp(.5rem,1vw,.9rem);}
.grow__set{
  display:flex;flex:0 0 auto;
  gap:clamp(.5rem,1vw,.9rem);
}
.grow__set img{
  flex:0 0 auto;
  width:clamp(12rem,19vw,20rem);height:auto;
  aspect-ratio:3 / 2;object-fit:cover;
  border-radius:.9rem;
  background:#E7E6E2;
  box-shadow:0 1px 3px rgba(0,0,0,.08), 0 10px 26px rgba(0,0,0,.1);
}
@keyframes growLeft{ from{transform:translate3d(0,0,0);} to{transform:translate3d(calc(-50% - (clamp(.5rem,1vw,.9rem) / 2)),0,0);} }
@keyframes growRight{ from{transform:translate3d(calc(-50% - (clamp(.5rem,1vw,.9rem) / 2)),0,0);} to{transform:translate3d(0,0,0);} }
.grow--1 .grow__track{animation:growLeft 150s linear infinite;}
.grow--2 .grow__track{animation:growRight 170s linear infinite;}
.grow--3 .grow__track{animation:growLeft 190s linear infinite;}
@media (prefers-reduced-motion:reduce){
  .grow--1 .grow__track,.grow--2 .grow__track,.grow--3 .grow__track{animation:none;}
}

/* ---- square by default ----
   The rounded card was on nearly every section, which made the whole page a
   stack of cards and left the rounding saying nothing. It is square now
   except on the three kinds of block that are genuinely inset panels sitting
   on the page rather than bands of it: the strategy call, the dark
   "why we win" panels, and the packages panel. */
.picker,.svc,.cases,.voices,.faq,.gal,.cta,.approach,.pt,.tilt,
.trust,.badge,.band,.phero,.cshero,.csdoc,.ty{border-radius:0;}
/* declared after .band, which it has to beat on the dark panels */
.call,
.whyus,
.band.band--dark{border-radius:var(--radius-main);}

/* ---- the gutter goes where the panels are ----
   Now that a section is square by default, the 20px gutter between two of
   them is a stripe of the page ground cutting through blocks that should
   meet: it is the thing that has been reading as broken. The gutter stays
   only around the three kinds of block that kept their corners, so a panel
   still sits on the page with air around it, and every band butts. */
.picker,.svc,.cases,.voices,.faq,.gal,.cta,.approach,.pt,.tilt,
.trust,.badge,.band,.phero,.cshero,.csdoc,.ty{margin-top:0;}
.call,.whyus,.band.band--dark{margin-top:var(--shell);}
section.call + section,
section.whyus + section,
section.band--dark + section{margin-top:var(--shell);}

/* ---- a photograph back behind the statement, very dark ----
   The woven grain was texture for its own sake. This is the room the copy is
   describing, held at a fifth of its brightness under a scrim, so it reads
   as depth behind the words rather than as a picture competing with them. */
.approach::before{
  background:none;
  background-image:url("/img/photo-approach-v2.webp");
  background-size:cover;
  background-position:50% 42%;
  filter:grayscale(.35) brightness(.5) contrast(1.05);
  opacity:.3;
  -webkit-mask-image:radial-gradient(ellipse 100% 92% at 50% 46%, #000 10%, rgba(0,0,0,.55) 58%, transparent 92%);
  mask-image:radial-gradient(ellipse 100% 92% at 50% 46%, #000 10%, rgba(0,0,0,.55) 58%, transparent 92%);
}
/* the scrim that keeps the statement readable over whatever the crop lands on */
.approach::after{
  background-image:none;
  background:linear-gradient(180deg, rgba(14,12,20,.78) 0%, rgba(14,12,20,.5) 42%, rgba(14,12,20,.72) 100%);
  opacity:1;
}

/* ---- the certifications, flush under the strategy call ----
   They used to close the partner section, which put them a long way from the
   thing they are evidence for. As their own strip directly under the call
   panel they sit against its bottom edge with no gutter, so the panel and
   the proof under it read as one block. The list keeps its own white ground,
   so the strip needs no padding of its own. */
.accbar{margin-top:0;padding:0;background:transparent;}
section.call + .accbar{margin-top:0;}
.accbar .acc{margin-top:0;}

/* ---- the Google mocks inside a browser window ----
   A search result is something you see in a browser, so it is shown in one:
   a window bar with its three dots and the query in the address pill, the
   real result in the body, and the results that would sit under it blurred
   back, which is what makes the sharp one read as the one being talked
   about. */
.brow{
  display:block;
  border-radius:1rem;
  overflow:hidden;
  background:#fff;
  box-shadow:0 1px 3px rgba(32,33,36,.14), 0 18px 46px rgba(32,33,36,.16);
}
.brow__bar{
  display:flex!important;align-items:center;gap:.9rem;
  padding:.65rem .9rem;
  background:#F1F3F4;
  border-bottom:1px solid #dadce0;
}
.brow__dots{display:flex!important;gap:.35rem;flex:0 0 auto;}
.brow__dots i{width:.65rem;height:.65rem;border-radius:50%;background:#FF5F57;}
.brow__dots i:nth-child(2){background:#FEBC2E;}
.brow__dots i:nth-child(3){background:#28C840;}
.brow__url{
  display:flex!important;align-items:center;gap:.45rem;
  min-width:0;flex:1 1 auto;
  padding:.35rem .75rem;
  border-radius:99px;
  background:#fff;
  box-shadow:inset 0 0 0 1px #dadce0;
}
.brow__url svg{width:.8rem;height:.8rem;flex:0 0 auto;color:#5f6368;}
.brow__url em{
  font-style:normal;min-width:0;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
  font-size:.75rem;color:#5f6368;
}
.brow__body{display:block;padding:1.1rem 1.15rem 1.25rem;}
/* the mocks were drawn to float on a dark band; inside a window they are the
   window's content, so they lose their own shadows and their own frame */
.brow .viz__card,.brow .gshop{box-shadow:none;}
.brow .viz__omni{box-shadow:none;background:#F1F3F4;border-color:transparent;}
.brow .gfan{gap:1rem;}

/* the results underneath, out of focus */
.ghosts{display:grid;gap:1.1rem;margin-top:1.25rem;}
.ghost{display:grid;gap:.4rem;filter:blur(2.5px);opacity:.5;}
.ghost__u{height:.5rem;width:36%;border-radius:99px;background:#c9ced6;}
.ghost__h{height:.85rem;width:72%;border-radius:99px;background:#9aa8e0;}
.ghost__d{height:.5rem;width:100%;border-radius:99px;background:#d7dbe0;}
.ghost__d--s{width:64%;}

/* the organic result says where it ranks in words */
.viz__rank{
  display:inline-block!important;
  margin-bottom:.6rem;
  padding:.2rem .6rem;
  border-radius:99px;
  background:rgba(24,128,56,.1);
  font-size:.75rem;font-weight:700;letter-spacing:.01em;color:#188038;
}

/* ---- link building: a printed journal ----
   The service is coverage in a publication, so the mock is one: a cover
   behind, and the feature page in front carrying the headline, the columns
   and the link inside the copy, which is the thing being earned. */
.book{position:relative;display:block;padding:1.25rem 0 1.25rem 3.5rem;}
.book__cover{
  position:absolute;left:0;top:0;bottom:0;width:11rem;
  display:flex!important;flex-direction:column;
  padding:1.1rem .95rem;
  border-radius:.5rem .2rem .2rem .5rem;
  background:linear-gradient(145deg,#2A2440,#181428);
  box-shadow:0 2px 6px rgba(0,0,0,.24), 0 16px 34px rgba(0,0,0,.26);
  transform:rotate(-3deg);
  color:#fff;
}
.book__mast{
  font-family:var(--font-head);
  font-size:1rem;font-weight:700;line-height:1.1;letter-spacing:-.02em;
}
.book__issue{margin-top:.3rem;font-size:.625rem;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.55);}
.book__rule{height:1px;margin:.8rem 0;background:rgba(255,255,255,.22);}
.book__cvr{font-size:.75rem;line-height:1.4;color:rgba(255,255,255,.8);}
.book__page{
  position:relative;z-index:1;
  padding:1.35rem 1.5rem 1.4rem;
  border-radius:.3rem .6rem .6rem .3rem;
  background:#fff;
  box-shadow:-1px 0 0 rgba(18,18,18,.08) inset, 0 2px 6px rgba(0,0,0,.1), 0 18px 40px rgba(0,0,0,.14);
}
.book__kicker{
  font-size:.625rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:rgb(var(--purple-accent));
}
.book__hl{
  margin-top:.5rem;
  font-family:var(--font-head);
  font-size:1.1875rem;line-height:1.2;letter-spacing:-.025em;font-weight:700;
  color:var(--ink-dark);
}
.book__by{margin-top:.35rem;font-size:.6875rem;color:#6b6b73;}
.book__cols{display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr));gap:.9rem;margin-top:.9rem;}
.book__col{display:grid;gap:.4rem;}
.book__col i{height:.4rem;border-radius:99px;background:rgba(18,18,18,.12);}
.book__col i.is-short{width:62%;}
.book__anchor{
  display:inline-block!important;margin-top:1rem;
  padding-bottom:.1rem;
  border-bottom:1px solid rgba(var(--purple-accent),.5);
  background:linear-gradient(transparent 62%, rgba(217,233,104,.7) 0);
  font-size:.8125rem;color:rgb(var(--purple-accent));
}

/* ---- the studio rows ----
   No padding: the section is the photographs. They are half as big again and
   the drift is slower, so it reads as movement rather than as a carousel. */
.gal{padding-top:0;padding-bottom:0;}
.grow__set img{width:clamp(15rem,26vw,28rem);}
.grow--1 .grow__track{animation-duration:260s;}
.grow--2 .grow__track{animation-duration:290s;}
.grow--3 .grow__track{animation-duration:320s;}

/* the diagonal grain the FAQ picked up when the photograph came off it */
.faq::after{display:none;}

/* the statement had a full section's padding above it and the ticker
   directly over that, which read as a hole */
.approach{padding-top:clamp(3rem,6vw,6.5rem);}

/* the cover was almost entirely behind the page; it steps further out and
   turns further, and the column rules get room to read as lines of type */
.book{padding:1.75rem 0 1.75rem 6.5rem;}
.book__cover{width:12.5rem;transform:rotate(-6deg);padding:1.25rem 1.05rem;}
.book__page{transform:rotate(.8deg);}
.book__col{gap:.55rem;}
.book__col i{height:.45rem;background:rgba(18,18,18,.16);}

/* the square sections run to the window edge like the rest of them: they
   were still sitting inside the page gutter, which left a 20px rail of page
   ground down both sides of half the page */
.picker,.svc,.cases,.voices,.faq,.trust,.badge,.accbar{
  margin-left:calc(var(--shell) * -1);
  margin-right:calc(var(--shell) * -1);
}

/* ---- the case tile, as a photograph with the facts on it ----
   The client and what they do sit over the top of the picture, the result
   and its one line sit at the foot, and the link is a solid pill in the
   corner. The photograph is the card: the scrim only darkens the two ends
   where the words are, and the tile is tall enough for the middle of it to
   be worth looking at. */
.cases__grid .ccard{
  min-height:31rem;
  padding:1.6rem 1.6rem 1.5rem;
  gap:0;
}
.cc__ph{filter:grayscale(0) brightness(.86) contrast(1.02) saturate(1);}
.cases__grid .ccard::before{
  background:linear-gradient(var(--case-ang),
    rgba(30,30,36,.22) 0%,
    rgba(20,20,24,.24) 60%,
    rgba(10,10,13,.3) 100%);
}
.cases__grid .ccard::after{
  background:linear-gradient(180deg,
    rgba(6,6,8,.78) 0%,
    rgba(6,6,8,.3) 20%,
    rgba(6,6,8,.05) 42%,
    rgba(6,6,8,.55) 72%,
    rgba(6,6,8,.92) 100%);
}
.cc__foot{display:block;padding:0;}
.cc__id b{font-size:1.1875rem;letter-spacing:-.022em;}
.cc__id i{font-size:.8125rem;color:rgba(255,255,255,.7);}
.cc__eyebrow{
  margin-top:auto;
  font-size:clamp(1.5rem,2vw,1.8125rem);
  line-height:1.1;
}
.cc__line{
  margin-top:.6rem;max-width:22rem;
  font-size:.9375rem;line-height:1.5;color:rgba(255,255,255,.76);
}
.cc__chips{display:none;}
/* the link as a pill in the corner, over the photograph */
.cc__view{
  position:absolute;right:1.4rem;bottom:1.4rem;
  gap:.45rem;
  padding:.6rem .95rem;
  border-radius:99px;
  background:rgba(10,10,13,.82);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14);
  font-size:.8125rem;font-weight:600;color:#fff;
}
.cases__grid .ccard:hover .cc__view{background:#0A0A0D;color:#fff;}

/* a card with a link keeps the corner clear for it, so the sentence stops
   above the pill rather than running under it */
.cases__grid .ccard:has(.cc__view){padding-bottom:4.75rem;}

/* the foot of a case tile goes solid, so the sentence sits on a flat ground
   rather than on whatever the photograph is doing under it */
.cases__grid .ccard::after{
  background:linear-gradient(180deg,
    rgba(6,6,8,.8) 0%,
    rgba(6,6,8,.3) 18%,
    rgba(6,6,8,.06) 36%,
    rgba(6,6,8,.72) 62%,
    rgba(8,8,10,.95) 80%,
    rgba(8,8,10,1) 100%);
}
.cc__line{
  font-size:1rem;font-weight:500;line-height:1.5;
  color:rgba(255,255,255,.92);
}
.cc__line b{color:var(--lime);font-weight:700;}

/* ---- one ad, and a result page that looks like one ----
   Google does not draw a card around a result: it sits flat on white with
   space around it, the title is 20px on a 26px line in #1a0dab, the site
   name is 14px #202124 over a 12px #4d5156 URL beside a round favicon, and
   the snippet is 14px on a 22px line in #4d5156. The measurements come from
   the live page rather than from memory. */
.brow .viz__card{
  border:0;border-radius:0;box-shadow:none;background:transparent;
  padding:0;max-width:41rem;
}
.brow .viz__brand{gap:.75rem;}
.brow .viz__fav{width:1.75rem;height:1.75rem;font-size:.8125rem;}
.brow .viz__site b{font-size:.875rem;line-height:1.3;color:#202124;}
.brow .viz__site i{font-size:.75rem;line-height:1.3;color:#4d5156;}
.brow .viz__hl{
  margin-top:.35rem;
  font-size:1.25rem;line-height:1.625rem;letter-spacing:0;font-weight:400;
  color:#1a0dab;
}
.brow .viz__desc{margin-top:.2rem;font-size:.875rem;line-height:1.375rem;color:#4d5156;}
.brow .viz__links{margin-top:.5rem;gap:.25rem 1.25rem;}
.brow .viz__links em{font-size:.875rem;color:#1a0dab;}
.brow .viz__spon{font-size:.875rem;font-weight:700;color:#202124;margin-bottom:.4rem;}
.brow .viz__moved{margin-top:.75rem;padding-top:0;border-top:0;}
/* Google's search box: a pill with a hairline, not a grey block */
.brow .viz__omni{
  background:#fff;
  box-shadow:inset 0 0 0 1px #dfe1e5;
  padding:.7rem 1.1rem;
  max-width:41rem;
}
.brow .viz__q{font-size:.875rem;color:#202124;}
.brow__body{padding:1.35rem 1.4rem 1.5rem;}
.brow .gfan{gap:1.75rem;}
.ghosts{margin-top:1.75rem;gap:1.6rem;max-width:41rem;}

/* ---- the journal, rebuilt ----
   One printed page with a second behind it, rather than a cover the page was
   sitting on top of. The masthead runs across the top of the page it belongs
   to, the type below it is set in two real columns, and the earned link is
   inside the copy where it would be. */
.book{padding:1.5rem 1.25rem 1.5rem 1.5rem;}
.book__cover{
  left:auto;right:.75rem;top:1.9rem;bottom:1.9rem;width:auto;left:3.5rem;
  border-radius:.35rem;
  background:linear-gradient(160deg,#F4F3EF,#E4E2DB);
  box-shadow:0 2px 6px rgba(0,0,0,.14), 0 14px 30px rgba(0,0,0,.14);
  transform:rotate(2.5deg);
  padding:0;
}
.book__mast,.book__issue,.book__rule,.book__cvr{display:none!important;}
.book__page{
  transform:rotate(-1.2deg);
  padding:1.4rem 1.5rem 1.5rem;
  border-radius:.35rem;
  box-shadow:0 2px 6px rgba(0,0,0,.14), 0 18px 40px rgba(0,0,0,.16);
}
.book__kicker{
  display:flex!important;align-items:baseline;gap:.6rem;
  padding-bottom:.65rem;margin-bottom:.9rem;
  border-bottom:2px solid var(--ink-dark);
  font-family:var(--font-head);
  font-size:.875rem;font-weight:700;letter-spacing:-.01em;text-transform:none;
  color:var(--ink-dark);
}
.book__hl{margin-top:0;font-size:1.125rem;line-height:1.22;}
.book__by{margin-top:.4rem;font-size:.6875rem;letter-spacing:.06em;text-transform:uppercase;color:#8a8a92;}
.book__cols{gap:1.1rem;margin-top:1rem;}
.book__col{gap:.5rem;}
.book__col i{height:.375rem;background:rgba(18,18,18,.14);}
.book__anchor{margin-top:.9rem;font-size:.8125rem;}

/* the contact ground was reading as flat purple; it goes deeper and less
   saturated, closer to the ink the footer starts on */
.cta--light{
  background:
    linear-gradient(180deg, rgba(21,19,28,0) 0%, rgba(21,19,28,0) 56%, rgba(21,19,28,.88) 86%, #15131C 100%),
    radial-gradient(ellipse 48% 60% at 6% 0%, rgba(255,255,255,.1) 0%, rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 46% 58% at 100% 40%, rgba(217,233,104,.08) 0%, rgba(217,233,104,0) 66%),
    radial-gradient(ellipse 62% 62% at 62% 18%, rgba(56,34,112,1) 0%, rgba(56,34,112,0) 72%),
    #211540;
}

/* the doubling was too much: this lands between where it was and where that
   put it */
.picker,.svc,.cases,.voices,.faq,.band,.tilt,.csdoc{
  padding-top:clamp(3.25rem,6.5vw,7rem);
  padding-bottom:clamp(3.25rem,6.5vw,7rem);
}
.approach{padding-top:clamp(3rem,5.5vw,6rem);padding-bottom:clamp(3.25rem,6.5vw,7rem);}
.pt{padding-top:clamp(3.25rem,6.5vw,7rem);}
.cta{padding-top:clamp(3.25rem,6.5vw,7rem);padding-bottom:clamp(3.5rem,7vw,7.5rem);}
.whyus{padding-top:clamp(3.5rem,7vw,7.5rem);padding-bottom:clamp(3.5rem,7vw,7.5rem);}
.call{padding-top:clamp(3.25rem,6.5vw,7rem);padding-bottom:clamp(3.25rem,6.5vw,7rem);}

/* the heroes are panels, not bands: the inset hero on a service page and on
   a case study keeps its corners, which the square-by-default rule took */
.phero,.cshero{border-radius:var(--radius-main);}
/* room between the search box and the result under it */
.brow .gsearch,.brow .viz__card--org{margin-top:1.5rem;}
/* .viz span is (0,1,1) and was flattening the columns to blocks; this wins */
.book .book__cols{display:grid;}
.book .book__col{display:grid;gap:.5rem;}
.book .book__col i{display:block;height:.375rem;border-radius:99px;background:rgba(18,18,18,.14);}
.book{padding-right:2.25rem;}

/* ---- review pass ---- */
/* the challenge panels held a 30rem floor from when they carried a
   photograph; without one it left each card two thirds empty on a phone */
@media (max-width:1024px){ .pick{min-height:0;} }
/* every lede balances, so none leaves a single word on its last line */
.picker__lede,.call__copy > p,.pt__lede,.svc__lede,.voices__lede,.cases__lede,.faq__side p,.cta__lede{text-wrap:balance;}
/* footer links were 23px tall targets; the padding brings them to 32 without
   moving the visual rhythm, since the gap between them was margin */
/* block, not inline-block: side by side these two-word links sat on one
   line and the footer columns collapsed into running text */
.foot__col a{display:block;width:fit-content;padding:.25rem 0;margin-top:.15rem;}
.foot__col a:first-of-type{margin-top:-.25rem;}
.foot__touch a,.foot__hq a{display:block;width:fit-content;padding:.2rem 0;}

/* ---- what we do, as a rail of cards ----
   An eyebrow and a left-set heading with the rail's controls opposite, then
   wide cards that scroll sideways: the photograph on the left, the service
   and one line on the right, and the link as a disc in the corner. The rail
   starts on the content edge and runs off the right of the window, so the
   next card is always half in view, which is what says there are more. The
   ground is a shade warmer than the paper either side of it. */
.svc{
  --svc-bg:#ECEAE3;
  background:var(--svc-bg);
  overflow:hidden;
}
.svc__inner{max-width:var(--max);margin:0 auto;padding:0;}
.svc__head{
  display:flex;align-items:flex-end;justify-content:space-between;gap:2rem;
  margin:0 0 clamp(2rem,3.5vw,3rem);
}
.svc__lead{max-width:56rem;}
.svc__eyebrow{
  display:flex;align-items:center;gap:.6rem;
  margin:0 0 1rem;
  font-size:1rem;font-weight:500;color:var(--ink-dark);
}
.svc__eyebrow i{width:.5rem;height:.5rem;border-radius:50%;background:var(--lime);box-shadow:inset 0 0 0 1px rgba(0,0,0,.15);}
.svc__head h2{margin:0;text-align:left;}
.svc__nav{display:flex;gap:.5rem;flex:0 0 auto;padding-bottom:.35rem;}
.svc__arr{
  display:grid;place-items:center;
  width:3.25rem;height:3.25rem;
  border:1px solid rgba(18,18,18,.16);border-radius:.6rem;
  background:#fff;color:var(--ink-dark);cursor:pointer;
  transition:background-color .18s ease,color .18s ease,border-color .18s ease,opacity .18s ease;
}
.svc__arr svg{width:1.25rem;height:1.25rem;}
.svc__arr--next{background:var(--ink-dark);border-color:var(--ink-dark);color:#fff;}
.svc__arr:hover{background:var(--ink-dark);border-color:var(--ink-dark);color:#fff;}
.svc__arr--next:hover{background:#000;}
.svc__arr[disabled]{opacity:.35;cursor:default;}
.svc__arr[disabled]:hover{background:#fff;color:var(--ink-dark);border-color:rgba(18,18,18,.16);}
.svc__arr--next[disabled]:hover{background:var(--ink-dark);color:#fff;}
/* the rail: content edge on the left, window edge on the right */
.svcrail{
  margin:0 calc(var(--edge) * -1) 0 0;
}
.svc__track{
  display:flex;gap:1.5rem;
  overflow-x:auto;
  padding:.25rem var(--edge) 1rem 0;
  scroll-snap-type:x mandatory;
  scroll-behavior:smooth;
  scrollbar-width:none;
}
.svc__track::-webkit-scrollbar{display:none;}
.scard{
  flex:0 0 clamp(34rem,52vw,47rem);
  scroll-snap-align:start;
  display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1fr);gap:clamp(1.5rem,2.5vw,3rem);
  padding:1.25rem;
  border-radius:1.25rem;
  background:#F7F6F1;
  color:var(--ink-dark);text-decoration:none;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 12px 30px rgba(0,0,0,.05);
  transition:transform .25s cubic-bezier(.16,1,.3,1), box-shadow .25s ease;
}
.scard:hover{transform:translateY(-3px);box-shadow:0 2px 4px rgba(0,0,0,.05), 0 20px 44px rgba(0,0,0,.09);}
.scard__ph{display:block;aspect-ratio:9 / 11;border-radius:.75rem;overflow:hidden;background:#E3E1DA;}
.scard__ph img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s cubic-bezier(.16,1,.3,1);}
.scard:hover .scard__ph img{transform:scale(1.03);}
.scard__body{display:flex;flex-direction:column;min-width:0;padding:1.5rem .75rem 1.25rem 0;}
.scard__body h3{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(1.375rem,1.9vw,1.75rem);
  line-height:1.15;letter-spacing:-.028em;font-weight:600;
  text-wrap:balance;
}
.scard__body p{margin:1rem 0 0;font-size:1.0625rem;line-height:1.55;color:#54545a;max-width:22rem;}
.scard__go{
  margin-top:auto;align-self:flex-start;
  display:grid;place-items:center;
  width:3rem;height:3rem;border-radius:50%;
  background:#fff;color:var(--ink-dark);
  box-shadow:0 1px 2px rgba(0,0,0,.06), 0 6px 16px rgba(0,0,0,.08);
  transition:background-color .18s ease,color .18s ease,transform .18s ease;
}
.scard__go svg{width:1.1rem;height:1.1rem;}
.scard:hover .scard__go{background:var(--ink-dark);color:#fff;transform:translate(2px,-2px);}
/* the page's square-by-default rule squared these; the cards keep corners */
.scard,.scard__ph{border-radius:1.25rem;}
.scard__ph{border-radius:.75rem;}
@media (max-width:900px){
  .svc__head{flex-direction:column;align-items:flex-start;gap:1.25rem;}
  .scard{flex-basis:min(86vw,30rem);grid-template-columns:minmax(0,1fr);gap:1rem;padding:1rem;}
  .scard__ph{aspect-ratio:4 / 3;}
  .scard__body{padding:.25rem .25rem .25rem;}
  .scard__go{margin-top:1.25rem;}
}
@media (prefers-reduced-motion:reduce){
  .svc__track{scroll-behavior:auto;}
  .scard,.scard__ph img,.scard__go{transition:none;}
}
/* the head's h2 replaced .svc__aside h2, which is where the shared heading
   type was pinned; it takes the same scale as every other section head */
.svc__head h2{
  font-family:var(--font-head);
  font-size:clamp(2rem,3.4vw,3rem);
  line-height:1.08;letter-spacing:-.035em;font-weight:600;
  text-wrap:balance;color:var(--ink-dark);
}

/* ---- the studio, as a section with a head ----
   It was a bare strip of photographs; the partner section's heading and lede
   move onto it, so the rows have something to be a picture of, and the
   section takes a section's padding again. */
.gal{padding-top:clamp(3.25rem,6.5vw,7rem);padding-bottom:clamp(3.25rem,6.5vw,7rem);}
.gal__head{
  max-width:56rem;margin:0 auto clamp(2.25rem,4vw,3.5rem);
  padding:0 var(--gutter);
  text-align:center;
}
.gal__head h2{
  margin:0;
  font-family:var(--font-head);
  font-size:clamp(2rem,3.4vw,3rem);
  line-height:1.08;letter-spacing:-.035em;font-weight:600;
  color:var(--ink-dark);text-wrap:balance;
}
.gal__lede{
  margin:1.25rem auto 0;max-width:46rem;
  font-size:1.0625rem;line-height:1.6;color:#54545a;text-wrap:balance;
}
/* the strip that followed the partner section now follows the call directly,
   and the section that followed the studio is no longer preceded by paper */
.accbar + .svc{margin-top:0;}
/* the studio now sits on the FAQ, which is the same paper; the FAQ takes the
   step up in light the same-ground rule gives every second section */
.gal + .faq{
  background:
    radial-gradient(ellipse 62% 58% at 14% 6%, rgba(var(--purple-accent),.06) 0%, rgba(var(--purple-accent),0) 68%),
    radial-gradient(ellipse 58% 54% at 88% 92%, rgba(217,233,104,.14) 0%, rgba(217,233,104,0) 66%),
    #FAF9F6;
}

/* ---- the certifications as a card, and the challenges as a card ----
   Under the rounded call panel a square white strip read as a broken edge.
   The strip is its own rounded card on the page ground, with the gutter
   above and below, and the challenge section under it is a rounded card too,
   so the three stack the way the call panel already does. */
.accbar{
  margin:var(--shell) 0 0;
  padding:0;
  border-radius:var(--radius-main);
  background:#fff;
  overflow:hidden;
}
section.call + .accbar{margin-top:var(--shell);}
.accbar .acc{
  width:auto;margin:0;
  padding:clamp(1.75rem,3vw,2.5rem) var(--gutter);
  background:transparent;
}
.picker{
  margin-left:0;margin-right:0;margin-top:var(--shell);
  border-radius:var(--radius-main);
}
.accbar + .picker{margin-top:var(--shell);}
.accbar + .svc{margin-top:var(--shell);}

/* ---- the case rail: arrows, and a drift of its own ----
   The bar under it says where you are but cannot move you, so the rail takes
   the same two arrows the services rail uses. It also drifts on its own, one
   card every eight seconds, and stops the moment you touch it or hover it,
   so it shows there is more without taking the scroll away from you. */
.cases__nav{
  display:flex;justify-content:flex-end;gap:.5rem;
  max-width:var(--max);margin:0 auto clamp(1.25rem,2vw,1.75rem);
  padding:0 var(--edge);
}
.cs__arr{width:3rem;height:3rem;}
@media (max-width:640px){ .cases__nav{justify-content:center;} }

/* ---- what we actually do, under the studio heading ----
   The heading says what we help with; this says what that is made of. The
   line above the pills is the plain statement of it, and the pills are the
   six things, in the order we would rank them for ourselves. */
.gal__kicker{
  margin:clamp(1.75rem,3vw,2.5rem) auto 0;max-width:46rem;
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:600;letter-spacing:-.015em;
  color:var(--ink-dark);text-wrap:balance;
}
.gal__pills{
  list-style:none;
  display:flex;flex-wrap:wrap;justify-content:center;gap:.55rem;
  margin:1.1rem auto 0;padding:0;max-width:46rem;
}
.gal__pills li{
  padding:.5rem 1rem;
  border-radius:var(--radius-full);
  background:#fff;
  box-shadow:inset 0 0 0 1px rgba(18,18,18,.1);
  font-size:.9375rem;font-weight:600;color:var(--ink-dark);
}

/* ---- one button ----
   The primary button was 16px on most of the site and 15px inside the
   panels that were built later, with four different padding pairs behind it.
   Size and padding come from the base class now, so a button is the same
   button wherever it sits. */
.btn{font-size:1rem;font-weight:600;padding:.75rem 1.75rem;}
.btn--ghost,.btn--white,.btn--ink{font-weight:600;}
.approach{background-color:#1C1729;}

/* ---- the sticky call bar ----
   It was a washed violet on a page that has a dark of its own. It takes that
   dark, at full strength, with the accent bloom behind it so it reads as
   part of the site rather than as a browser chrome. The number carries a
   live dot and an "Available now" line under it, which is what the header
   does, and the button says what it does. */
.sbar{
  background:
    radial-gradient(ellipse 60% 140% at 12% 50%, rgba(var(--purple-accent),.5) 0%, rgba(var(--purple-accent),0) 70%),
    #1C1729;
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.12),
    0 2px 8px rgba(0,0,0,.3),
    0 26px 70px rgba(0,0,0,.55);
}
.sbar__tel{
  display:grid;
  grid-template-columns:auto auto;
  grid-template-rows:auto auto;
  align-items:center;
  column-gap:.5rem;row-gap:.05rem;
  text-decoration:none;color:#fff;
}
.sbar__live{
  grid-row:1 / 3;
  width:.5rem;height:.5rem;border-radius:50%;
  background:var(--lime);
  box-shadow:0 0 0 .25rem rgba(217,233,104,.2);
}
.sbar__num{
  font-family:var(--font-head);
  font-size:1.0625rem;font-weight:700;letter-spacing:-.015em;line-height:1.2;
  color:#fff;
}
.sbar__avail{
  font-size:.6875rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:rgba(255,255,255,.6);line-height:1.2;
}
.sbar__tel:hover .sbar__num{color:var(--lime);}
@media (max-width:760px){
  .sbar__avail{display:none;}
  .sbar__tel{grid-template-rows:auto;}
  .sbar__live{grid-row:1;}
}
/* the certification card keeps the gutter under it as well as over it: on
   the homepage the case studies were butting onto its bottom edge */
.accbar{margin-bottom:var(--shell);}
.accbar + section{margin-top:0;}

/* the studio section sits between the case rail and the FAQ, both on paper,
   so it takes the warmer ground the services rail uses and the three read as
   three sections rather than one long one */
.gal{
  background:var(--svc-bg, #ECEAE3);
  --svc-bg:#ECEAE3;
}
/* the pills run on one line: six of them wrapped to two, which put one pill
   on a line of its own. They scale down a step and the row is allowed the
   full page measure rather than the 46rem text column. */
/* one line, and the row gets the page measure rather than the 46rem text
   column: at the text column's width six of these wrapped and left one pill
   sitting on a line of its own */
.gal__pills{
  max-width:none;width:100vw;margin-left:calc(50% - 50vw);
  flex-wrap:nowrap;
  gap:.45rem;
  padding:0 var(--gutter);
  overflow-x:auto;
  scrollbar-width:none;
  justify-content:center;
}
.gal__pills::-webkit-scrollbar{display:none;}
.gal__pills li{
  flex:0 0 auto;
  padding:.42rem .75rem;
  font-size:.8125rem;
  white-space:nowrap;
}
@media (max-width:1100px){
  .gal__pills{justify-content:flex-start;}
}


/* ---- one hero shape ----
   The homepage hero runs to the window edge with square corners. The service
   and case study heroes were inset cards with 24px corners, which made the
   first thing on those pages a different component from the first thing on
   the homepage. They take the homepage's shape. The panels that are
   genuinely panels sitting on the page, the strategy call, the dark "why we
   win" blocks, the packages block and the two white strips, keep their
   corners: that is the distinction the corners are carrying. */
.phero,.cshero{
  margin-left:calc(var(--shell) * -1);
  margin-right:calc(var(--shell) * -1);
  margin-top:calc(var(--shell) * -1);
  border-radius:0;
}

/* ---- a rounded section always has air on both sides ----
   A corner only reads as a corner if the ground shows past it. These are the
   five that keep their corners, and each one takes the gutter above and
   below rather than relying on whatever follows it to leave a gap. The
   section after one zeroes its own top margin so the two do not stack into a
   double gutter. */
.call,.whyus,.band.band--dark,.accbar,.picker{
  margin-top:var(--shell);
  margin-bottom:var(--shell);
}
.call + *,
.whyus + *,
.band.band--dark + *,
.accbar + *,
.picker + *{margin-top:0;}

/* ---- the nav reads at a glance ----
   The links were 400 in a light grey on a dark bar, which at 16px is thinner
   than anything else on the site and the first thing a visitor has to read.
   They take a medium weight and a brighter grey, and the call-us number goes
   up with them. */
.nav__link{font-weight:500;color:rgba(255,255,255,.86);}
.nav__link:hover{color:#fff;}
.callus__label{font-weight:600;}
.callus__number{font-weight:700;}

/* ---- the platforms each panel runs on ----
   Small marks above the question, so the panel says which surfaces it means
   before the words do. Monochrome and all one size: in brand colours at this
   scale four logos become four competing accents on a card that already has
   chips. The files are the official marks from simple-icons, which publishes
   them as CC0 paths. */
.pick__logos{
  display:flex;align-items:center;gap:.7rem;
  margin:0 0 1rem;
}
.pick__logos img{
  width:1.15rem;height:1.15rem;display:block;
  opacity:.55;
}

/* ---------- the nav, once you have scrolled past it ----------
   The nav rides the hero photograph at rest, which only works while the
   photograph is behind it. Past that it comes back as its own surface: a
   light bar across the top, tighter than the resting one, with every child
   flipped off white. It is fixed rather than sticky because the hero is
   overflow:hidden and a sticky child cannot escape it; the spacer that
   site.js drops in behind it is what keeps the page from jumping the moment
   it leaves the flow. */
.nav__spacer{height:0;flex:0 0 auto;}

.nav.is-stuck{
  position:fixed;top:0;left:0;right:0;z-index:80;
  padding:.8rem max(calc(var(--shell) + var(--gutter)), calc((100% - var(--max)) / 2));
  background:rgba(255,255,255,.9);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid rgba(0,0,0,.08);
  box-shadow:0 10px 30px rgba(0,0,0,.06);
  color:var(--ink-dark);
  animation:navDrop .26s cubic-bezier(.22,.61,.36,1) both;
}
@keyframes navDrop{from{transform:translateY(-100%);}to{transform:translateY(0);}}

.nav.is-stuck .nav__logo{color:var(--ink-dark);}
.nav.is-stuck .nav__logo > svg{height:1.75rem;}
.nav.is-stuck .nav__link{
  border-color:transparent;background:transparent;box-shadow:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;
  color:#40404a;font-weight:500;
}
.nav.is-stuck .nav__link:hover{background:#F2F2EE;color:var(--ink-dark);}
.nav.is-stuck .nav__item.is-open .nav__link{
  background:var(--ink-dark);color:#fff;border-color:transparent;box-shadow:none;
}
.nav.is-stuck .callus__label{color:#6b6b73;}
.nav.is-stuck .callus__number{color:var(--ink-dark);}
.nav.is-stuck .callus:hover .callus__number{color:#5B7A00;}
.nav.is-stuck .callus__dot{background:#A8BE22;box-shadow:0 0 0 0 rgba(168,190,34,.6);}
.nav.is-stuck .nav__right::before{background:rgba(0,0,0,.13);}
.nav.is-stuck .burger{border-color:rgba(0,0,0,.14);background:#fff;}
.nav.is-stuck .burger span,
.nav.is-stuck .burger span::before,
.nav.is-stuck .burger span::after{background:var(--ink-dark);}
/* the white pill disappears on a white bar, so the call to action inverts */
.nav.is-stuck .btn--white{background:var(--ink-dark);color:#fff;}
.nav.is-stuck .btn--white:hover{background:#2b2b33;color:#fff;}
/* the panel is dark glass over a photograph; over the light bar it is a card */
.nav.is-stuck .drop{
  background:#fff;border-color:rgba(0,0,0,.08);
  box-shadow:0 26px 60px rgba(0,0,0,.16);
}
.nav.is-stuck .drop::before{background:#fff;border-left-color:rgba(0,0,0,.08);border-top-color:rgba(0,0,0,.08);}
.nav.is-stuck .drop__link:hover{background:#F3F3F0;}
/* lime on white is unreadable, so every accent in the panel shifts olive */
.nav.is-stuck .drop__link::before{background:#5B7A00;}
.nav.is-stuck .drop__title{color:var(--ink-dark);}
.nav.is-stuck .drop__title span:last-child{color:#5B7A00;}
.nav.is-stuck .drop__desc{color:#6b6b73;}
.nav.is-stuck .drop__foot{color:#5B7A00;border-top-color:rgba(0,0,0,.09);}

/* an anchored jump has to land below the bar rather than underneath it */
.shell > section[id],.shell > footer[id],.shell > header[id]{scroll-margin-top:6rem;}

@media (prefers-reduced-motion:reduce){
  .nav.is-stuck{animation:none;}
}

/* the live dot goes grey and stops pulsing outside office hours */
.callus__dot.is-off,.sbar__live.is-off{
  background:rgba(255,255,255,.45);
  box-shadow:none;
  animation:none;
}
/* the stuck bar restyles the dot at a higher specificity, so it needs the
   off state restating */
.nav.is-stuck .callus__dot.is-off{background:rgba(0,0,0,.28);box-shadow:none;animation:none;}
