/* ==========================================================================
   Ripple Media
   Bold. Unapologetic. Black, red, and a bandsaw.
   Palette and type straight off the Branding & Identity Guide.
   ========================================================================== */

/* ---------- Fonts ---------- */
@font-face{
  font-family:"Eurostile Ext";
  /* the supplied .ttf ships a truncated cmap that browsers reject outright,
     so this is the same face rebuilt with a valid Unicode cmap */
  src:url("../fonts/eurostile-ext-black.woff2") format("woff2"),
      url("../fonts/eurostile-ext-black.ttf") format("truetype");
  font-weight:900; font-style:normal; font-display:swap;
}
@font-face{ font-family:"Metropolis"; src:url("../fonts/metropolis-300.woff2") format("woff2"); font-weight:300; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("../fonts/metropolis-400.woff2") format("woff2"); font-weight:400; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("../fonts/metropolis-500.woff2") format("woff2"); font-weight:500; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("../fonts/metropolis-600.woff2") format("woff2"); font-weight:600; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("../fonts/metropolis-700.woff2") format("woff2"); font-weight:700; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("../fonts/metropolis-800.woff2") format("woff2"); font-weight:800; font-display:swap; }

/* ---------- Tokens ---------- */
:root{
  --red:#EC1C24;
  --red-dk:#B4141B;
  --black:#000000;
  --ink:#0A0A0A;
  --ink-2:#111111;
  --line:rgba(255,255,255,.12);
  --white:#FFFFFF;
  --grey:#9B9B9B;
  --silver:linear-gradient(180deg,#FFFFFF 0%,#D6D6D6 42%,#8E8E8E 62%,#F2F2F2 100%);
  /* brighter chrome for the hero headline, where legibility beats the dip */
  --silver-lit:linear-gradient(180deg,#FFFFFF 0%,#EDEDED 44%,#BFBFBF 64%,#FFFFFF 100%);

  --display:"Eurostile Ext","Arial Black",system-ui,sans-serif;
  --body:"Metropolis",system-ui,-apple-system,"Segoe UI",sans-serif;

  --wrap:1240px;
  --pad:clamp(20px,5vw,64px);
  --sec-y:clamp(72px,10vw,150px);

  /* the angular cut used across buttons, cards and bands */
  --cut:14px;

  /* Motion. Everything interactive runs on these two so the whole site eases
     the same way. The curve settles rather than stopping dead, which is what
     stops a hover feeling snappy. */
  --ease:cubic-bezier(.2,.65,.3,1);
  --t-fast:.28s;
  --t:.42s;
  --t-slow:.7s;
  /* scroll-reveal: gentle, even ease-out (easeOutQuad) over a long duration so
     each element glides in rather than snapping. Kept as a variable because any
     element with its own `transition` shorthand (eg .svc) would otherwise drop
     the reveal timing — those rules must reference this too. */
  --reveal:.95s cubic-bezier(.25,.46,.45,.94);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth}
body{
  margin:0; background:var(--black); color:var(--white);
  font-family:var(--body); font-weight:300; font-size:clamp(15.5px,1.05vw,17px);
  line-height:1.65; -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
img,video{max-width:100%; display:block}
a{color:inherit; text-decoration:none}
h1,h2,h3,h4,.navlbl{margin:0; font-weight:900; line-height:.95}
p{margin:0}
ul,ol{margin:0; padding:0; list-style:none}
::selection{background:var(--red); color:#fff}

.wrap{width:min(var(--wrap),100% - var(--pad)*2); margin-inline:auto}
.skip{position:absolute; left:-9999px}
.skip:focus{left:12px; top:12px; z-index:200; background:var(--red); padding:10px 16px}
:focus-visible{outline:2px solid var(--red); outline-offset:3px}

/* ---------- Shared type ---------- */
.eyebrow{
  font-family:var(--body); font-weight:700; font-size:.66rem;
  letter-spacing:.34em; text-transform:uppercase; color:var(--grey); margin:0;
}
.eyebrow--red{color:var(--red); display:inline-flex; align-items:center; gap:.7em}
.eyebrow--red::before{
  content:""; width:26px; height:2px; background:var(--red); display:inline-block;
}
.h2{
  font-family:var(--display); text-transform:uppercase;
  font-size:clamp(1.9rem,4.6vw,3.5rem); letter-spacing:-.005em;
}
.red{color:var(--red)}

/* ---------- Buttons: angular, not pills ---------- */
.btn{
  --bg:var(--red); --fg:#fff;
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  gap:.6em; padding:14px 26px; background:var(--bg); color:var(--fg);
  font-family:var(--body); font-weight:800; font-size:.74rem;
  letter-spacing:.16em; text-transform:uppercase; white-space:nowrap;
  clip-path:polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition:transform var(--t) var(--ease), background var(--t-fast) var(--ease),
             color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
/* inline-flex would otherwise beat the [hidden] attribute */
.btn[hidden]{display:none}
.btn:hover{transform:translate(2px,-2px)}
.btn:active{transform:translate(0,0); transition-duration:.09s}
.btn--lg{padding:17px 32px; font-size:.78rem}
.btn--red{--bg:var(--red); --fg:#fff}
.btn--red:hover{--bg:#ff2b34}
.btn--black{--bg:var(--black); --fg:#fff}
/* primary CTA on dark, video-backed panels: white reads as the main action
   where red competes with the brand furniture around it */
.btn--white{--bg:#fff; --fg:#000}
.btn--white:hover{--bg:#fff; --fg:#000; box-shadow:0 0 0 2px rgba(236,28,36,.9)}
.btn--ghost{
  --bg:transparent; --fg:#fff;
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.42);
}
.btn--ghost:hover{--bg:#fff; --fg:#000; box-shadow:inset 0 0 0 1.5px #fff}
/* a primary and its alternative sitting side by side */
.btnrow{display:flex; flex-wrap:wrap; gap:14px; margin-top:clamp(24px,3vw,32px)}
.btnrow--center{justify-content:center}
@media (max-width:460px){ .btnrow{flex-direction:column; align-items:stretch} }

/* ---------- Nav ---------- */
.nav{
  position:fixed; inset:0 0 auto 0; z-index:100;
  transition:background .3s ease, backdrop-filter .3s ease, border-color .3s ease;
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  background:rgba(0,0,0,.86); backdrop-filter:blur(14px);
  border-bottom-color:var(--line);
}
.nav__in{
  width:min(var(--wrap),100% - var(--pad)*2); margin-inline:auto;
  display:flex; align-items:center; gap:clamp(14px,3vw,42px);
  height:clamp(68px,7vw,88px);
}
.nav__logo img{height:clamp(38px,4vw,50px); width:auto}
.nav__links{display:flex; align-items:center; gap:clamp(16px,2.2vw,32px); margin-left:auto}
.nav__links a,.nav__top{
  font-family:var(--body); font-weight:600; font-size:.72rem; letter-spacing:.2em;
  text-transform:uppercase; color:rgba(255,255,255,.72);
  padding:6px 0; position:relative; transition:color var(--t-fast) var(--ease);
  background:none; border:0; cursor:pointer; line-height:inherit;
}
.nav__links a::after,.nav__top::after{
  content:""; position:absolute; left:0; bottom:0; height:2px; width:0;
  background:var(--red); transition:width var(--t) var(--ease);
}
.nav__links a:hover,.nav__links a.is-current,
.nav__top:hover,.nav__top.is-current{color:#fff}
.nav__links a:hover::after,.nav__links a.is-current::after,
.nav__top:hover::after,.nav__top.is-current::after{width:100%}

/* ---------- Nav dropdowns ----------
   Hover opens them on pointer devices, the button's aria-expanded opens them
   on keyboard and touch. Both routes drive the same .is-open class so there is
   only ever one visual state to reason about. */
.nav__has{position:relative; display:flex; align-items:center}
.nav__top{display:inline-flex; align-items:center; gap:.5em; white-space:nowrap}
.nav__caret{
  width:0; height:0; border-inline:4px solid transparent; border-top:5px solid currentColor;
  translate:0 1px; transition:rotate var(--t) var(--ease), color var(--t-fast) var(--ease);
}
.nav__has.is-open .nav__caret{rotate:180deg}
.nav__sub{
  position:absolute; left:-18px; top:100%; margin-top:14px; z-index:5;
  min-width:230px; padding:8px; display:grid; gap:2px;
  background:rgba(8,8,8,.97); backdrop-filter:blur(14px);
  border:1px solid var(--line); border-top:2px solid var(--red);
  clip-path:polygon(0 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%);
  opacity:0; visibility:hidden; translate:0 -8px; pointer-events:none;
  transition:opacity var(--t-fast) var(--ease), translate var(--t-fast) var(--ease), visibility var(--t-fast);
}
/* a transparent bridge over the gap so the menu survives the trip down to it */
.nav__sub::before{content:""; position:absolute; inset:-16px 0 auto 0; height:16px}
.nav__has.is-open .nav__sub{opacity:1; visibility:visible; translate:0; pointer-events:auto}
.nav__links .nav__sub a{
  padding:11px 14px; letter-spacing:.1em; font-size:.68rem;
  color:rgba(255,255,255,.78); transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.nav__links .nav__sub a::after{display:none}
.nav__links .nav__sub a:hover,.nav__links .nav__sub a.is-current{background:rgba(236,28,36,.14); color:#fff}
/* Bars are absolutely placed rather than flex-spaced so the open state is
   exact: 11 / 17 / 23 puts the outer two 6px either side of the middle, and
   the same 6px translate lands them both dead on the centre line. */
.nav__burger{
  display:none; margin-left:auto; width:44px; height:36px; background:none;
  border:0; padding:0; cursor:pointer; position:relative;
}
.nav__burger span{
  position:absolute; left:50%; margin-left:-13px; width:26px; height:2px;
  background:#fff; border-radius:2px;
  transition:transform var(--t) var(--ease), opacity var(--t-fast) var(--ease);
}
.nav__burger span:nth-child(1){top:11px}
.nav__burger span:nth-child(2){top:17px}
.nav__burger span:nth-child(3){top:23px}
.nav__burger[aria-expanded="true"] span:nth-child(1){transform:translateY(6px) rotate(45deg)}
.nav__burger[aria-expanded="true"] span:nth-child(2){opacity:0; transform:scaleX(.3)}
.nav__burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

/* full-screen overlay for mobile nav */
.drawer{
  position:fixed; inset:0; z-index:98; overflow-y:auto; overscroll-behavior:contain;
  display:flex; flex-direction:column; justify-content:center;
  /* clear the fixed header, and never let the panel sit tighter than this
     against the top and bottom of a short screen */
  padding:calc(var(--pad) + clamp(56px,14vw,76px)) var(--pad) var(--pad);
  background:rgba(4,0,1,.97); backdrop-filter:blur(16px);
  transform-origin:top center; animation:drawerDrop .34s cubic-bezier(.22,1,.36,1) both;
}
.drawer[hidden]{display:none}
@keyframes drawerDrop{from{opacity:0; transform:scale(.98)} to{opacity:1; transform:none}}
/* The whole panel scales off one unitless number, so a short phone gets the
   same layout at a smaller size rather than a cramped version of the tall one.
   The steps live in the height queries at the end of this block. */
.drawer nav{
  --dw:1;
  display:grid; gap:calc(10px * var(--dw)); position:relative; z-index:2;
  width:min(100%,420px); margin-inline:auto;
}
.drawer nav a{
  display:block;
  font-family:var(--display); text-transform:uppercase; letter-spacing:.02em;
  font-size:calc(1.08rem * var(--dw));
  padding:calc(14px * var(--dw)) 20px; position:relative; text-align:center;
  border:1.5px solid rgba(236,28,36,.4); background:transparent; color:#fff;
  clip-path:polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition:border-color var(--t) var(--ease), background var(--t) var(--ease), color var(--t) var(--ease), transform var(--t) var(--ease);
}
.drawer nav a:hover{background:rgba(236,28,36,.1); border-color:var(--red); transform:translateY(-2px)}
/* stagger the top-level children, so a labelled group animates in as one block
   rather than each of its links arriving on its own beat */
.drawer nav > *{opacity:0; transform:translateY(10px); animation:drawerLink .38s ease forwards}
.drawer nav > *:nth-child(1){animation-delay:.04s}
.drawer nav > *:nth-child(2){animation-delay:.08s}
.drawer nav > *:nth-child(3){animation-delay:.12s}
.drawer nav > *:nth-child(4){animation-delay:.16s}
.drawer nav > *:nth-child(5){animation-delay:.20s}
.drawer nav > *:nth-child(6){animation-delay:.24s}
.drawer nav > *:nth-child(7){animation-delay:.28s}
@keyframes drawerLink{to{opacity:1; transform:none}}

/* a labelled cluster in the drawer, mirroring a desktop dropdown */
.drawer__grp{
  display:grid; gap:calc(8px * var(--dw)); padding:calc(12px * var(--dw)) 14px;
  border:1.5px solid rgba(236,28,36,.22);
}
.drawer__grp .navlbl{
  font-family:var(--body); font-weight:700; font-size:calc(.6rem * var(--dw)); letter-spacing:.24em;
  text-transform:uppercase; color:var(--red); text-align:center; margin:0;
}
.drawer__grp a{font-size:calc(.92rem * var(--dw)); padding:calc(11px * var(--dw)) 16px}

.drawer nav a.btn{
  font-family:var(--display); font-size:calc(.82rem * var(--dw));
  margin-top:calc(6px * var(--dw)); justify-content:center;
  background:var(--red); border-color:var(--red); color:#fff;
}

/* Short screens: step the whole panel down instead of letting it overflow or
   crush the gaps. 740px covers most phones in landscape and the small ones
   (SE, mini) in portrait once the browser chrome is counted. */
@media (max-height:740px){ .drawer nav{--dw:.86} }
@media (max-height:640px){ .drawer nav{--dw:.8} }
@media (max-height:560px){
  .drawer nav{--dw:.72}
  /* below this it stops being a centred panel and just becomes a scrollable list */
  .drawer{justify-content:flex-start}
}
.drawer nav a.btn:hover{background:#ff2b34; border-color:#ff2b34; transform:translateY(-2px)}
.drawer__ring{
  position:absolute; right:-16%; top:-30%; width:min(70vw,420px); max-width:none;
  opacity:.10; pointer-events:none; animation:spin 60s linear infinite;
}

/* ---------- Hero ---------- */
.hero{
  position:relative; min-height:100svh; display:grid; align-items:center;
  padding:clamp(104px,12vw,140px) 0 clamp(84px,9vw,104px); overflow:hidden;
  isolation:isolate;
}
.hero__media{position:absolute; inset:0; z-index:-3}
.hero__video{width:100%; height:100%; object-fit:cover}
.hero__grade{
  position:absolute; inset:0; z-index:-2;
  background:
    /* red wash on the left (behind the branding), fading out by the middle */
    linear-gradient(90deg, rgba(236,28,36,.32) 0%, rgba(236,28,36,.08) 30%, rgba(236,28,36,0) 52%),
    /* dark under the text (left) and behind the ring (right); clearest video in the middle */
    linear-gradient(90deg, rgba(0,0,0,.80) 0%, rgba(0,0,0,.50) 46%, rgba(0,0,0,.78) 100%),
    /* keep the bottom dark for the ticker, lift the middle so the video reads */
    linear-gradient(180deg, rgba(0,0,0,.5) 0%, rgba(0,0,0,.18) 38%, rgba(0,0,0,.92) 100%);
}
/* Eases the hero video into the pure-black section below so the bottom edge
   blends out instead of meeting a hard seam. Sits above the video/grade but
   below the rings and text, so no positioning changes. */
.hero::after{
  content:""; position:absolute; left:0; right:0; bottom:0; z-index:-1;
  height:clamp(180px,32vh,340px); pointer-events:none;
  background:linear-gradient(180deg,
    rgba(0,0,0,0) 0%,
    rgba(0,0,0,.35) 42%,
    rgba(0,0,0,.72) 70%,
    rgba(0,0,0,.93) 88%,
    #000 100%);
}
.hero__halftone{
  position:absolute; inset:0; z-index:-1; opacity:.5; mix-blend-mode:overlay;
  background-image:radial-gradient(rgba(255,255,255,.55) 1px, transparent 1.2px);
  background-size:5px 5px;
  -webkit-mask-image:linear-gradient(115deg, transparent 45%, #000 100%);
  mask-image:linear-gradient(115deg, transparent 45%, #000 100%);
}
.hero__ring{
  position:absolute; z-index:-1; pointer-events:none; max-width:none;
}
.hero__ring--a{
  width:min(70vw,860px); right:-15vw; top:68%; transform:translateY(-50%);
  opacity:.5; animation:spin 44s linear infinite;
}
.hero__ring--b{
  width:min(34vw,340px); left:-7vw; bottom:6%;
  opacity:.22; animation:spin 34s linear infinite reverse;
}
@keyframes spin{to{transform:rotate(360deg)}}
.hero__ring--a{animation-name:spinY}
@keyframes spinY{from{transform:translateY(-50%) rotate(0)} to{transform:translateY(-50%) rotate(360deg)}}

.hero__in{width:min(var(--wrap),100% - var(--pad)*2); margin-inline:auto; max-width:min(var(--wrap),100%)}
.hero__h1{
  font-family:var(--display); text-transform:uppercase; margin:18px 0 0;
  font-size:clamp(2.1rem,7.4vw,5.6rem); line-height:.92; letter-spacing:-.005em;
}
.hero__h1 span{display:block}
.hero__h1 .l2{padding-left:.09em}
.hero__h1 .l3{
  padding-left:.18em;
  background:var(--silver); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.hero__h1 em{color:var(--red); -webkit-text-fill-color:var(--red); font-style:normal}

/* The market-ownership headline breaks over three lines. "How Much Of The" is
   the longest of them and Eurostile Extended is wide, so that line is what
   sets the ceiling on this scale. */
.hero__h1--own{font-size:clamp(1.42rem,5.4vw,3.85rem)}
.hero__h1--own .l2{padding-left:.06em}
/* Same chrome sweep, held to a brighter range so the third line stays as
   readable as the two above it. */
.hero__h1--own .l3{
  padding-left:.12em;
  background:var(--silver-lit); -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* The sub reads as one long line then a stub of three words if it is left to
   wrap on its own, so cap the measure and let the browser balance the rest. */
.hero__sub{
  margin-top:clamp(16px,2vw,24px); max-width:min(54ch,39rem);
  font-size:clamp(.98rem,1.25vw,1.12rem); color:rgba(255,255,255,.82);
  text-wrap:balance;
}
/* Both sentences run on every size now. */
.hero__sub2{display:inline}
.hero__cta{display:flex; flex-wrap:wrap; gap:14px; margin-top:clamp(22px,2.8vw,32px)}

/* tagline ticker along the bottom of the hero */
@keyframes slide{to{transform:translateX(-50%)}}

/* ---------- Clients ---------- */
.clients{padding:clamp(44px,6vw,70px) 0 clamp(34px,4vw,48px); border-bottom:1px solid var(--line)}
.clients__label{text-align:center; margin-bottom:clamp(24px,3vw,36px)}
.marquee{overflow:hidden; -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent); mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.marquee__track{display:flex; align-items:center; gap:clamp(34px,5vw,72px); width:max-content; animation:slide var(--dur,45s) linear infinite}
.marquee--rev .marquee__track{animation-direction:reverse}
.clients .marquee__track img{
  height:clamp(34px,4vw,50px); width:auto; object-fit:contain;
  filter:grayscale(1) brightness(1.7); opacity:.55; transition:filter var(--t) var(--ease), opacity var(--t) var(--ease);
}
.clients .marquee__track a:hover img{filter:none; opacity:1}

/* ---------- Section frame ---------- */
.sec{position:relative; padding:var(--sec-y) 0; overflow:hidden}
.sec--services{background:var(--ink)}
/* Two sections running back to back on the same background read as one long
   block, which is what makes a service page feel like it never changes
   subject. A hairline is enough to mark where one ends. */
.sec + .sec{border-top:1px solid var(--line)}
.sec--services + .sec--services{border-top-color:rgba(255,255,255,.07)}
/* For a section that opens on a hard-edged block (the case study meta bar)
   rather than a heading. The full pad leaves it floating. */
.sec--tighttop{padding-top:clamp(26px,3.4vw,44px)}
.watermark{
  position:absolute; max-width:none; pointer-events:none; opacity:.055; z-index:0;
}
.watermark--left{width:min(70vw,760px); left:-22vw; top:8%}
.watermark--right{width:min(60vw,660px); right:-18vw; bottom:4%}
.sec > .wrap{position:relative; z-index:1}

.sechead{max-width:44rem; margin-bottom:clamp(38px,5vw,66px)}
.sechead .h2{margin-top:16px}
.sechead__lead{margin-top:18px; color:var(--grey); max-width:52ch}
.sechead__lead a{color:var(--red); font-weight:600}
/* For headings whose written line breaks are wider than the 44rem default and
   would otherwise pick up a third line of their own. */
.sechead--wide{max-width:54rem}
@media (min-width:900px){ .sechead--wide .h2{white-space:nowrap} }
.sechead--center{margin-inline:auto; text-align:center}
.sechead--center .eyebrow--red{justify-content:center}

/* ---------- Pillars ---------- */
.pillars{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
  gap:1px; background:var(--line); border:1px solid var(--line);
  margin-bottom:clamp(44px,6vw,80px);
}
.pillar{background:var(--ink); padding:clamp(26px,3vw,40px); position:relative; transition:background var(--t) var(--ease), opacity var(--reveal), transform var(--reveal)}
.pillar:hover{background:#161616}
.pillar__no{
  font-family:var(--display); color:var(--red); font-size:.8rem; letter-spacing:.1em;
}
.pillar h3{
  font-family:var(--display); text-transform:uppercase; font-size:clamp(1rem,1.5vw,1.2rem);
  margin:14px 0 12px; line-height:1.15;
}
.pillar p{color:var(--grey); font-size:.95rem}

/* ---------- Service cards ---------- */
.cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:clamp(14px,1.8vw,22px)}
.card{
  position:relative; display:block; background:#141414; overflow:hidden;
  clip-path:polygon(0 0, 100% 0, 100% calc(100% - 26px), calc(100% - 26px) 100%, 0 100%);
  transition:transform var(--t) var(--ease);
}
.card:hover{transform:translateY(-6px)}
.card__img{aspect-ratio:4/5; overflow:hidden; position:relative}
.card__img img{width:100%; height:100%; object-fit:cover; transition:transform var(--t-slow) var(--ease)}
.card__img::after{content:""; position:absolute; inset:0; background:rgba(0,0,0,.38); opacity:0; transition:opacity var(--t) var(--ease); pointer-events:none; z-index:1}
.card:hover .card__img img{transform:scale(1.05)}
.card:hover .card__img::after{opacity:1}
.card__body{padding:20px 22px 26px; position:relative}
.card__body::before{
  content:""; position:absolute; left:0; top:0; width:0; height:3px; background:var(--red);
  transition:width var(--t-slow) var(--ease);
}
.card:hover .card__body::before{width:100%}
.card__no{font-family:var(--display); color:var(--red); font-size:.72rem; letter-spacing:.1em}
.card h3{
  font-family:var(--display); text-transform:uppercase; font-size:clamp(.95rem,1.3vw,1.08rem);
  margin:10px 0 14px; line-height:1.15;
}
.card__go{
  font-size:.66rem; font-weight:700; letter-spacing:.22em; text-transform:uppercase; color:var(--grey);
  display:inline-flex; align-items:center; gap:.5em; transition:color var(--t) var(--ease), gap var(--t) var(--ease);
}
.card__go::after{content:"\2192"}
.card:hover .card__go{color:var(--red); gap:.9em}

/* ---------- Handshake band ---------- */
.band{position:relative; background:var(--red); padding:clamp(58px,8vw,104px) 0; overflow:hidden}
/* The band used to carry a Ripple-liveried race car behind it. It now runs the
   same slow ripple ring the CTA band uses, so the two red bands on a page read
   as one family instead of two unrelated backgrounds. */
.band__tex{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:min(150vw,1400px); aspect-ratio:1;
  background:url("../img/brand/ring-full.png") center/contain no-repeat;
  opacity:.15; mix-blend-mode:multiply; pointer-events:none;
  animation:spin 82s linear infinite;
}
@media (prefers-reduced-motion:reduce){ .band__tex{animation:none} }
.band__in{position:relative; z-index:1; text-align:center}
.band__quote{
  font-family:var(--display); text-transform:uppercase; line-height:1.12;
  font-size:clamp(1.35rem,3.9vw,3rem); max-width:26ch; margin-inline:auto;
}
.band__quote .band__white{display:block}
.band__quote em{font-style:normal; color:var(--black); display:block; margin-top:.28em}

/* ---------- Why ---------- */
.why{display:grid; grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr); gap:clamp(32px,5vw,72px); align-items:center}
.why__left .h2{margin:16px 0 20px}
.why__lead{color:var(--grey); margin-bottom:30px; max-width:36ch}
/* The two owners, sitting between the heading and the paragraph. Jack's frame
   is dropped a little so the pair reads as a composition rather than a row of
   two identical boxes. */
.owners{display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(10px,1.2vw,18px); margin:0; max-width:none}
.owner{margin:0; position:relative; overflow:hidden; background:#141414; border:1px solid var(--line)}
/* middle photo dropped a touch so three faces read as a composition, not a row
   of identical boxes */
.owner:nth-child(2){margin-top:clamp(14px,2.4vw,34px)}
/* Full colour, no hover-to-reveal. The greyscale version read as a memorial on
   touch devices, where there is no hover to bring them back. */
.owner img{
  display:block; width:100%; aspect-ratio:4/5; object-fit:cover; object-position:50% 30%;
  transition:transform 1s var(--ease);
}
.owner:hover img{transform:scale(1.05)}
.owner figcaption{
  position:absolute; left:0; right:0; bottom:0; padding:30px 14px 12px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.92));
}
.owner figcaption b{display:block; font-family:var(--display); text-transform:uppercase; font-size:.92rem}
.owner figcaption span{display:block; margin-top:5px; font-size:.56rem; letter-spacing:.22em; text-transform:uppercase; color:var(--red); font-weight:700}
@media (max-width:420px){ .owner figcaption span{letter-spacing:.14em} }
/* Four written lines, two white then two red, so "Every Week" never splits.
   Sits a touch under the global .h2 scale because it runs one line longer. */
.why__h{font-size:clamp(1.5rem,3.5vw,2.7rem)}
.why__h span{display:block}

/* Right column. Numbered panels with a red edge that fills on hover, closed
   off by a row of facts so the column ends on something solid. */
.whyx{display:grid; gap:clamp(12px,1.4vw,16px); align-content:start}
.whyx__card{
  position:relative; display:grid; grid-template-columns:auto minmax(0,1fr);
  gap:clamp(16px,2vw,24px); align-items:start;
  padding:clamp(20px,2.4vw,30px) clamp(20px,2.4vw,28px);
  background:linear-gradient(180deg,#121212,#0B0B0B);
  border:1px solid var(--line); overflow:hidden;
  transition:border-color var(--t) var(--ease), transform var(--t) var(--ease), background var(--t) var(--ease),
             opacity var(--reveal);
}
/* transform here drives the hover nudge, so this card reveals as a pure fade
   (no rise) to keep that transform slot free */
.whyx__card.reveal{transform:none}
/* the red edge that grows down the left on hover */
.whyx__card::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:var(--red); scale:1 0; transform-origin:top;
  transition:scale var(--t-slow) var(--ease);
}
.whyx__card:hover{border-color:rgba(236,28,36,.45); transform:translateX(4px); background:linear-gradient(180deg,#161616,#0B0B0B)}
.whyx__card:hover::before{scale:1 1}
.whyx__no{
  font-family:var(--display); font-size:clamp(1.6rem,3vw,2.4rem); line-height:1;
  color:transparent; -webkit-text-stroke:1px rgba(255,255,255,.28);
  transition:-webkit-text-stroke-color var(--t) var(--ease);
}
.whyx__card:hover .whyx__no{-webkit-text-stroke-color:var(--red)}
.whyx__body h3{
  font-family:var(--display); text-transform:uppercase; font-size:clamp(.98rem,1.5vw,1.2rem);
  line-height:1.18; margin-bottom:10px;
}
.whyx__body p{color:var(--grey); font-size:.95rem}
.whyx__facts{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1px;
  background:var(--line); border:1px solid var(--line); margin-top:clamp(6px,1vw,10px);
}
.whyx__facts div{background:var(--black); padding:clamp(18px,2.2vw,26px) clamp(12px,1.6vw,20px)}
.whyx__facts b{
  display:block; font-family:var(--display); color:var(--red);
  font-size:clamp(1.4rem,2.6vw,2.1rem); line-height:1;
}
.whyx__facts span{
  display:block; margin-top:10px; font-size:.6rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--grey); font-weight:700; line-height:1.5;
}
@media (max-width:520px){
  .whyx__facts{grid-template-columns:1fr}
}

/* ---------- Process ---------- */
.steps{display:grid; gap:clamp(18px,2.4vw,30px)}
.step{
  display:grid; grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(20px,3vw,48px); align-items:center;
  background:var(--ink); border:1px solid var(--line);
  clip-path:polygon(0 0, 100% 0, 100% calc(100% - 30px), calc(100% - 30px) 100%, 0 100%);
}
.step__media{aspect-ratio:16/11; overflow:hidden; align-self:stretch; position:relative}
.step__media img{width:100%; height:100%; object-fit:cover; transition:transform 1s var(--ease)}
.step__media::after{content:""; position:absolute; inset:0; background:rgba(0,0,0,.38); opacity:0; transition:opacity var(--t) var(--ease); pointer-events:none}
.step:hover .step__media img{transform:scale(1.04)}
.step:hover .step__media::after{opacity:1}
.step__body{padding:clamp(22px,3vw,44px) clamp(22px,3vw,50px) clamp(30px,3.4vw,50px) 0}
.step__no{
  font-family:var(--display); font-size:clamp(2.2rem,5vw,3.6rem); line-height:1;
  color:transparent; -webkit-text-stroke:1.5px var(--red); display:block; margin-bottom:14px;
}
.step__body h3{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.1rem,2vw,1.6rem); margin-bottom:14px}
.step__body p{color:var(--grey); max-width:52ch}

/* ---------- Results ---------- */
.sec--results{background:var(--ink)}
.cases{display:grid; gap:clamp(16px,2vw,26px); margin-bottom:clamp(40px,5vw,70px)}
.case{
  display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(22px,3vw,54px); align-items:center;
  background:#0C0C0C; border:1px solid var(--line); padding:clamp(24px,3vw,48px);
  position:relative; overflow:hidden;
}
.case::after{
  content:""; position:absolute; right:-60px; top:-60px; width:200px; height:200px;
  background:var(--red); opacity:.10; transform:rotate(45deg);
}
.case--flip .case__media{order:-1}
.case__year{
  font-family:var(--display); font-size:.7rem; letter-spacing:.24em; color:var(--red);
}
.case h3{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.2rem,2.3vw,1.9rem); margin:14px 0 16px}
.case p{color:var(--grey); max-width:48ch}
.case__media img{width:100%; border:1px solid var(--line)}
.stats{display:flex; gap:clamp(24px,4vw,54px); margin-top:clamp(24px,3vw,36px)}
.stat b{
  display:block; font-family:var(--display); color:var(--red);
  font-size:clamp(1.8rem,4.4vw,3.1rem); line-height:1;
}
.stat span{
  display:block; margin-top:10px; font-size:.62rem; font-weight:700;
  letter-spacing:.24em; text-transform:uppercase; color:var(--grey);
}
.marquee--proof .marquee__track{gap:18px}
.marquee--proof img{height:clamp(200px,26vw,320px); width:auto; border:1px solid var(--line)}

/* ---------- Video testimonials ---------- */
/* the testimonial rail is the last block in the results section, so pull the
   section's own bottom padding in a bit, otherwise the gap to the next
   section reads as dead space */
.sec--results{padding-bottom:clamp(48px,6vw,84px)}
.vtestis{margin-top:clamp(30px,4vw,56px)}
.vtestis__label{
  text-align:center; margin-bottom:clamp(22px,3vw,34px);
  font-size:.62rem; font-weight:700; letter-spacing:.26em; text-transform:uppercase; color:var(--grey);
}
.vrail{
  display:grid; grid-auto-flow:column; grid-auto-columns:clamp(180px,22vw,220px);
  gap:clamp(12px,1.6vw,20px); overflow-x:auto; padding-bottom:14px;
  scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch;
}
.vrail::-webkit-scrollbar{height:6px}
.vrail::-webkit-scrollbar-thumb{background:rgba(236,28,36,.5); border-radius:6px}
.vcard{
  position:relative; scroll-snap-align:start; cursor:pointer; padding:0; border:0;
  aspect-ratio:9/13; overflow:hidden; background:#141414; isolation:isolate;
  border-radius:16px; box-shadow:inset 0 0 0 1.5px rgba(236,28,36,.55);
  transition:transform .35s ease, box-shadow .3s ease;
  /* keep the rounded clip crisp while the inner image scales on hover
     (overflow:hidden + border-radius otherwise drops clipping during a
     child transform, so the corners flash square) */
  clip-path:inset(0 round 16px);
}
.vcard img{width:100%; height:100%; object-fit:cover; border-radius:inherit; transition:transform var(--t-slow) var(--ease)}
.vcard::after{content:""; position:absolute; inset:0; border-radius:inherit; background:linear-gradient(180deg,rgba(0,0,0,.15),rgba(0,0,0,.55)); pointer-events:none}
.vcard:hover{transform:translateY(-6px); box-shadow:inset 0 0 0 2px var(--red)}
.vcard:hover img{transform:scale(1.05)}
.vcard__play{
  position:absolute; left:50%; top:50%; translate:-50% -50%; z-index:2;
  width:clamp(46px,5vw,62px); height:clamp(46px,5vw,62px); border-radius:50%;
  background:var(--red); box-shadow:0 8px 30px -8px rgba(236,28,36,.9);
  transition:scale .25s ease, background .25s ease;
}
.vcard__play::before{
  content:""; position:absolute; left:54%; top:50%; translate:-50% -50%;
  border-style:solid; border-width:9px 0 9px 15px; border-color:transparent transparent transparent #fff;
}
.vcard:hover .vcard__play{scale:1.12}
.vcard__cap{
  position:absolute; left:0; right:0; bottom:0; z-index:2; padding:14px 14px 16px;
  font-size:.6rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:#fff; text-align:center;
}

/* ---------- Testimonial lightbox ---------- */
.vbox{position:fixed; inset:0; z-index:200; display:grid; place-items:center; padding:24px}
.vbox[hidden]{display:none}
.vbox__scrim{position:absolute; inset:0; background:rgba(0,0,0,.86); backdrop-filter:blur(6px); animation:vfade .3s ease both}
.vbox__panel{
  position:relative; z-index:1; width:min(420px,92vw); animation:vpop .4s cubic-bezier(.22,1,.36,1) both;
}
.vbox__stage{
  position:relative; aspect-ratio:9/16; background:#000; overflow:hidden;
  border-radius:18px; box-shadow:0 0 0 2px var(--red), 0 30px 80px -20px rgba(0,0,0,.9);
}
.vbox__stage video,.vbox__stage iframe{position:absolute; inset:0; width:100%; height:100%; border:0; object-fit:cover}
.vbox__x{
  position:absolute; right:0; top:-46px; width:38px; height:38px; z-index:2; cursor:pointer;
  background:none; border:0; color:#fff; font-size:2rem; line-height:1; transition:color .2s, transform .2s;
}
.vbox__x:hover{color:var(--red); transform:scale(1.1)}
.vbox__name{
  position:absolute; left:0; top:-42px; font-family:var(--display); text-transform:uppercase;
  font-size:.9rem; letter-spacing:.04em; color:#fff;
}
@keyframes vfade{from{opacity:0} to{opacity:1}}
@keyframes vpop{from{opacity:0; transform:translateY(20px) scale(.96)} to{opacity:1; transform:none}}

/* ---------- FAQ ---------- */
.faq{display:grid; grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); gap:clamp(30px,5vw,80px); align-items:start}
.faq .sechead{margin-bottom:0}
/* Stack the heading above the questions before the two columns get tight on a
   part-width window (Jack was not fullscreen). Full desktop (>1150px) keeps the
   two-column layout unchanged. */
@media (max-width:1300px){
  .faq{grid-template-columns:1fr; gap:clamp(26px,4vw,44px)}
  .faq .sechead{margin-bottom:8px}
}
.qa{border-bottom:1px solid var(--line)}
.qa:first-child{border-top:1px solid var(--line)}
.qa summary{
  list-style:none; cursor:pointer; padding:clamp(20px,2.4vw,28px) 46px clamp(20px,2.4vw,28px) 0;
  font-family:var(--display); text-transform:uppercase; font-size:clamp(.86rem,1.25vw,1.02rem);
  line-height:1.3; position:relative; transition:color .2s;
}
.qa summary::-webkit-details-marker{display:none}
.qa summary:hover{color:var(--red)}
.qa summary::before,.qa summary::after{
  content:""; position:absolute; right:6px; top:50%; background:var(--red);
  transition:transform .3s ease, opacity .3s ease;
}
.qa summary::before{width:16px; height:2px; margin-top:-1px}
.qa summary::after{width:2px; height:16px; margin-top:-8px; right:13px}
.qa[open] summary::after{transform:rotate(90deg); opacity:0}
.qa p{padding:0 46px clamp(22px,2.6vw,30px) 0; color:var(--grey); max-width:58ch}

/* Smooth open/close instead of the native snap. ::details-content lands the
   height animation on the browser's own wrapper, so the markup stays plain
   <details>; browsers without it simply keep the old instant toggle. */
.qa summary::before,.qa summary::after{transition:transform .45s var(--ease), opacity .3s var(--ease)}
@supports selector(::details-content){
  :root{ interpolate-size:allow-keywords }
  .qa::details-content{
    block-size:0; overflow:hidden; opacity:0;
    transition:
      block-size .45s var(--ease),
      opacity .32s var(--ease),
      content-visibility .45s allow-discrete;
  }
  .qa[open]::details-content{ block-size:auto; opacity:1 }
}
@media (prefers-reduced-motion:reduce){
  .qa::details-content{transition:none}
}

/* ---------- Photo reel ---------- */
.reel{display:grid; gap:clamp(10px,1.2vw,16px); padding:clamp(20px,3vw,40px) 0 0}
.reel .marquee__track{gap:clamp(10px,1.2vw,16px)}
.reel img{
  height:clamp(150px,20vw,270px); width:auto; object-fit:cover;
  border-radius:16px; border:1.5px solid rgba(236,28,36,.55);
  box-shadow:0 0 0 1px rgba(0,0,0,.4), 0 14px 30px -18px rgba(0,0,0,.9);
}

/* ---------- CTA ---------- */
.cta{position:relative; background:var(--red); padding:clamp(70px,10vw,130px) 0; overflow:hidden; text-align:center}
.cta__ring{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:min(120vw,1100px); max-width:none; opacity:.16; mix-blend-mode:multiply;
  animation:spin 70s linear infinite; pointer-events:none;
}
.cta__in{position:relative; z-index:1}
.cta__h{
  font-family:var(--display); text-transform:uppercase; line-height:.94;
  font-size:clamp(2rem,6.4vw,4.6rem);
}
.cta__in p{margin:22px auto 34px; max-width:46ch; color:rgba(0,0,0,.75); font-weight:400}

/* ---------- Footer ---------- */
.foot{background:var(--black); padding:clamp(56px,7vw,90px) 0 0; border-top:1px solid var(--line)}
.foot__in{display:grid; grid-template-columns:1.5fr repeat(3,1fr); gap:clamp(28px,4vw,50px)}
.foot__brand img{height:56px; width:auto; margin-bottom:18px}
.foot__brand p{color:var(--grey); max-width:26ch; font-size:.92rem}
.foot__col .navlbl{
  font-family:var(--display); text-transform:uppercase; font-size:.72rem;
  letter-spacing:.14em; margin-bottom:18px; color:var(--red);
}
.foot__col a,.foot__col span{display:block; color:var(--grey); font-size:.92rem; padding:5px 0; transition:color var(--t-fast) var(--ease)}
.foot__col a:hover{color:#fff}
.foot__bar{
  margin-top:clamp(44px,6vw,70px); border-top:1px solid var(--line); padding:22px 0;
  display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap;
  width:min(var(--wrap),100% - var(--pad)*2); margin-inline:auto;
  font-size:.66rem; letter-spacing:.2em; text-transform:uppercase; color:var(--grey);
}
.foot__tag{color:var(--red); font-weight:700}
.foot__bar-link{color:var(--grey); text-decoration:none}
.foot__bar-link:hover{color:var(--white)}

/* ---------- Reveal ---------- */
.reveal{
  opacity:0; transform:translateY(30px);
  transition:opacity var(--reveal), transform var(--reveal);
}
.reveal.in{opacity:1; transform:none}

/* ---------- Responsive ---------- */
@media (max-width:1000px){
  .why,.faq{grid-template-columns:1fr}
  .step,.case{grid-template-columns:1fr}
  .case--flip .case__media{order:0}
  .step__body{padding:0 clamp(22px,4vw,32px) clamp(30px,5vw,40px)}
  .step__media{aspect-ratio:16/9}
}
@media (max-width:760px){
  .nav__links,.nav__cta{display:none}
  .nav__burger{display:flex}
  /* tighten the hero on phones: less dead space up top, content lifted
     off dead-centre and given a little more breathing room between lines */
  .hero{
    min-height:84svh; align-items:center;
    padding:clamp(96px,24vw,120px) 0 clamp(118px,32vw,150px);
  }
  /* The desktop clamp on the market-ownership headline is set by how wide
     Eurostile Extended runs at large sizes. On a phone that same clamp leaves
     the H1 sitting in the middle of the column, so drive it off the viewport
     here instead and let it run the full measure. */
  /* 6.55vw is the largest size at which "How Much Of The" still holds one
     line at 320, 375, 390 and 430 wide (measured, not guessed), so the
     headline runs edge to edge on a phone and keeps its three written lines. */
  .hero__h1--own{font-size:clamp(1.2rem,6.55vw,2.6rem)}
  /* Phones get the full sub, running the width of the column. Capping the
     measure here only bought a ragged extra line, and the second sentence is
     the one that says the work is ongoing, so it earns its place on mobile. */
  .hero__sub{margin-top:18px; font-size:.92rem; max-width:none; text-wrap:pretty}
  .hero__cta{margin-top:28px; gap:12px}
  /* eyebrow: single line on mobile, hide the red bar prefix only */
  .hero__eyebrow::before{display:none}
  .hero__eyebrow{font-size:.56rem; gap:.4em; letter-spacing:.14em}
  .hero__ring--a{right:-34vw; opacity:.34}
  /* On phones the desktop fade finished around the hero's midpoint, leaving a
     flat black band above the clients line. Compress it to a shorter strip so
     the video and ring stay visible much lower and the blend to black only
     happens right at the seam. */
  .hero::after{
    height:clamp(90px,17vh,150px);
    background:linear-gradient(180deg,
      rgba(0,0,0,0) 0%,
      rgba(0,0,0,.45) 55%,
      rgba(0,0,0,.9) 84%,
      #000 100%);
  }
  .foot__in{grid-template-columns:1fr 1fr}
  .foot__brand{grid-column:1 / -1}
  .stats{gap:32px}
  /* bigger, more tappable testimonial cards on phones */
  .vrail{grid-auto-columns:clamp(232px,66vw,300px); gap:14px}
}
@media (max-width:460px){
  .foot__in{grid-template-columns:1fr}
  .btn{width:100%}
  .hero__cta{flex-direction:column; align-items:stretch}
}

/* ---------- Motion preferences ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important}
  html{scroll-behavior:auto}
  .reveal{opacity:1; transform:none}
}

/* ==========================================================================
   Inner pages: page hero, about, service detail, contact wizard
   ========================================================================== */

/* ---------- Page hero ---------- */
.phero{
  position:relative; overflow:hidden; background:var(--black);
  /* fixed height across every inner page so the title baseline and the
     top-right ring always land in the same spot, regardless of copy length */
  min-height:clamp(320px,46vh,480px);
  display:flex; align-items:flex-end;
  padding:clamp(120px,15vw,180px) 0 clamp(44px,5.5vw,66px);
  border-bottom:1px solid var(--line);
}
.phero__ring{
  position:absolute; right:-14vw; top:50%; translate:0 -50%;
  width:min(64vw,620px); max-width:none; opacity:.13; pointer-events:none;
  animation:spinY 90s linear infinite;
}
.phero__tex{
  position:absolute; inset:0; pointer-events:none; opacity:.35;
  background:
    radial-gradient(120% 90% at 12% 0%, rgba(236,28,36,.20), transparent 62%),
    radial-gradient(80% 70% at 100% 100%, rgba(236,28,36,.10), transparent 60%);
}
.phero__in{position:relative; z-index:1; max-width:60rem}
.phero__h1{
  font-family:var(--display); text-transform:uppercase; line-height:.96;
  font-size:clamp(2.05rem,5.4vw,3.9rem); margin:16px 0 0; max-width:17ch;
}
.phero__h1 em{font-style:normal; color:var(--red)}
.phero__sub{margin-top:20px; color:var(--grey); max-width:54ch; font-size:1rem}
.phero__sub a{color:var(--red); font-weight:600}
.phero__cta{display:flex; flex-wrap:wrap; gap:14px; margin-top:clamp(26px,3vw,36px)}
/* thin red rule under the eyebrow keeps every inner-page header on the same beat */
.phero .eyebrow--red{margin-bottom:2px}
.phero--sm{min-height:clamp(200px,28vh,320px); padding-bottom:clamp(36px,4vw,52px)}

/* ---------- Legal prose ---------- */
.legal{max-width:70ch}
.legal p,.legal li{color:var(--grey); line-height:1.8; margin-bottom:1em}
.legal h2{font-family:var(--display); text-transform:uppercase; font-size:clamp(.9rem,1.4vw,1.05rem); letter-spacing:.08em; color:var(--white); margin:2.5em 0 .6em}
.legal ul{padding-left:1.4em; margin-bottom:1em}
.legal a{color:var(--red)}

/* ---------- Split: copy beside a photo ---------- */
.split{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(30px,5vw,80px); align-items:center;
}
.split--flip .split__media{order:-1}
.split__media{position:relative}
.split__media img{width:100%; aspect-ratio:4/3; object-fit:cover; border:1px solid var(--line)}
.split--wide .split__media img{aspect-ratio:16/10}
.split__media::before{
  content:""; position:absolute; inset:auto -14px -14px auto; width:58%; height:58%;
  border:2px solid var(--red); z-index:-1;
}
.split__body .h2{margin:16px 0 20px}
.split__body p{color:var(--grey); max-width:50ch}
.split__body p + p{margin-top:18px}
.split__body .ticks{margin-top:26px}
.split__body .btn{margin-top:30px}

/* About "Our Journey": a wider copy column beside a single tall portrait, so
   the four paragraphs read comfortably and the photo fills the column height. */
.split--about{grid-template-columns:minmax(0,1.42fr) minmax(0,.78fr); align-items:stretch}
.split--about .split__body{align-self:center}
.split--about .split__body p{max-width:64ch}
.split--about .split__media img{aspect-ratio:auto; height:100%; min-height:clamp(420px,42vw,620px); object-position:50% 35%}

/* ---------- Mission / values ---------- */
.tiles{display:grid; grid-template-columns:repeat(auto-fit,minmax(300px,1fr)); gap:1px; background:var(--line); border:1px solid var(--line)}
.tile{background:var(--ink); padding:clamp(28px,3.4vw,46px)}
.tile img{width:44px; height:auto; margin-bottom:22px}
.tile h3{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.1rem,2vw,1.5rem); margin-bottom:16px}
.tile > p{color:var(--grey); margin-bottom:26px}
/* plan tiles carry a volume label above the name, so the eyebrow has to win
   back the colour and spacing that .tile > p takes off it */
.tile > p.eyebrow{margin-bottom:14px}
.tile > p.eyebrow--red{color:var(--red)}
.ticks{display:grid; gap:14px}
.ticks li{position:relative; padding-left:30px; font-size:.94rem; color:#DCDCDC}
.ticks li::before{
  content:""; position:absolute; left:0; top:.52em; width:12px; height:12px;
  background:var(--red);
  clip-path:polygon(0 0, 100% 0, 100% 62%, 62% 100%, 0 100%);
}

/* ---------- Team ---------- */
/* wide behind-the-scenes shot that sits under the team portraits */
.bts{margin:clamp(24px,3vw,40px) 0 0; border:1px solid var(--line); overflow:hidden; position:relative}
.bts img{display:block; width:100%; aspect-ratio:16/9; object-fit:cover}
.bts figcaption{
  position:absolute; left:0; right:0; bottom:0; padding:clamp(16px,2vw,26px) clamp(18px,2.2vw,30px);
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.88));
  font-size:.72rem; letter-spacing:.16em; text-transform:uppercase; font-weight:700; color:#fff;
}
@media (max-width:700px){ .bts img{aspect-ratio:4/3} }
.team{display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:clamp(16px,2vw,26px)}
.member{position:relative; overflow:hidden; background:#141414}
.member img{width:100%; aspect-ratio:3/4; object-fit:cover; transition:transform 1s var(--ease)}
.member:hover img{transform:scale(1.04)}
.member__tag{
  position:absolute; left:0; bottom:0; right:0; padding:26px 24px 22px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.88) 62%);
}
.member__tag h3{font-family:var(--display); text-transform:uppercase; font-size:1.3rem}
.member__tag span{display:block; margin-top:8px; font-size:.64rem; letter-spacing:.24em; text-transform:uppercase; color:var(--red); font-weight:700}

/* ---------- Service index rows ---------- */
.srows{display:grid; gap:1px; background:var(--line); border-block:1px solid var(--line)}
.srow{
  background:var(--black); display:grid; grid-template-columns:auto minmax(0,1fr) auto;
  gap:clamp(20px,4vw,54px); align-items:center; padding:clamp(26px,3.4vw,46px) 0;
  transition:background var(--t) var(--ease);
}
.srow:hover{background:var(--ink-2)}
.srow__no{font-family:var(--display); color:var(--red); font-size:clamp(1.4rem,3vw,2.4rem)}
.srow h3{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.2rem,2.8vw,2rem); margin-bottom:12px}
.srow p{color:var(--grey); max-width:56ch; font-size:.96rem}
.srow__go{
  flex:none; width:56px; height:56px; display:grid; place-items:center;
  background:var(--red); color:#fff; font-size:1.1rem;
  clip-path:polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition:transform var(--t) var(--ease);
}
.srow:hover .srow__go{transform:translate(4px,-4px)}

/* ---------- Services page: showcase rows ----------
   Editorial alternating blocks. Big image, stroked number, what's included
   and a clear call to the detail page. Replaces the flat text list. */
.svcs{display:grid; gap:clamp(18px,2.4vw,30px)}
.svc{
  display:grid; grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);
  gap:clamp(24px,4vw,58px); align-items:stretch;
  background:#0C0C0C; border:1px solid var(--line); overflow:hidden;
  clip-path:polygon(0 0, 100% 0, 100% calc(100% - 30px), calc(100% - 30px) 100%, 0 100%);
  transition:border-color var(--t) var(--ease), background var(--t) var(--ease),
             opacity var(--reveal), transform var(--reveal);
}
.svc:hover{border-color:rgba(236,28,36,.5); background:#101010}
/* Whole card is the click target, not just the CTA: the cta anchor is stretched
   over the card, so hovering anywhere shows a pointer and clicking opens the
   service page. Both existing anchors point at the same page, so no conflict. */
.svc{position:relative}
.svc__cta::after{content:""; position:absolute; inset:0; z-index:1}
.svc__no{pointer-events:none}
.svc:nth-child(even) .svc__media{order:1}
/* the image is absolutely filled so it never drives the card height. The
   body content sets the height and every card lines up the same */
.svc__media{position:relative; align-self:stretch; overflow:hidden; min-height:300px; display:block}
.svc__media img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform 1s var(--ease)}
.svc__media::after{content:""; position:absolute; inset:0; background:linear-gradient(90deg,rgba(0,0,0,.55),rgba(0,0,0,0) 62%); pointer-events:none}
.svc:nth-child(even) .svc__media::after{background:linear-gradient(270deg,rgba(0,0,0,.55),rgba(0,0,0,0) 62%)}
.svc:hover .svc__media img{transform:scale(1.05)}
.svc__no{
  position:absolute; left:clamp(16px,2vw,26px); top:clamp(10px,1.4vw,18px); z-index:2;
  font-family:var(--display); font-size:clamp(2.6rem,6vw,4.6rem); line-height:1;
  color:transparent; -webkit-text-stroke:1.6px rgba(255,255,255,.75);
}
.svc__body{padding:clamp(26px,3.2vw,50px)}
.svc__body h3{
  font-family:var(--display); text-transform:uppercase; line-height:1.04;
  font-size:clamp(1.35rem,2.7vw,2.2rem); margin-bottom:16px;
}
.svc__body > p{color:var(--grey); max-width:46ch; margin-bottom:24px}
/* each service leads with the one line that separates it from the other three */
.svc__body > p b{color:#fff; font-weight:700}
.svc__list{display:grid; gap:11px; margin-bottom:30px}
.svc__list li{position:relative; padding-left:26px; color:#DCDCDC; font-size:.94rem}
.svc__list li::before{
  content:""; position:absolute; left:0; top:.5em; width:11px; height:11px; background:var(--red);
  clip-path:polygon(0 0,100% 0,100% 62%,62% 100%,0 100%);
}
.svc__cta{
  display:inline-flex; align-items:center; gap:.6em;
  min-height:24px;   /* WCAG 2.5.8 target size, these are standalone CTAs */
  font-family:var(--body); font-weight:800; font-size:.74rem; letter-spacing:.16em;
  text-transform:uppercase; color:#fff; transition:gap var(--t) var(--ease), color var(--t) var(--ease);
}
.svc__cta span{color:var(--red); font-size:1.1em; transition:transform var(--t) var(--ease)}
.svc__cta:hover{color:var(--red); gap:1em}
.svc__cta:hover span{transform:translateX(4px)}
/* Homepage variant. Same editorial row, but no bullet list and a shorter
   image, so five of them read as an index rather than repeating the services
   page beat for beat. */
.svcs--tight{gap:clamp(14px,1.8vw,20px)}
.svcs--tight .svc{grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr)}
.svcs--tight .svc__media{min-height:250px}
.svcs--tight .svc__body{padding:clamp(24px,2.8vw,40px)}
.svcs--tight .svc__body h3{font-size:clamp(1.25rem,2.3vw,1.9rem); margin-bottom:14px}
.svcs--tight .svc__body > p{max-width:52ch; margin-bottom:22px}

@media (max-width:1000px){
  /* stacked, and with no column gap left over, so the banner sits flush
     against the copy instead of floating above it */
  .svc{grid-template-columns:1fr; gap:0}
  .svcs--tight .svc{grid-template-columns:1fr; gap:0}
  .svc:nth-child(even) .svc__media{order:0}
  /* Keep the photography on phones, but as a banner across the top of the card
     rather than a half-screen block. Five stacked cards otherwise turn the
     section into a scroll. A fixed height rather than a ratio, so the image
     always spans the full card width and only its height is capped. */
  .svc__media,.svcs--tight .svc__media{
    min-height:0; aspect-ratio:auto; width:100%; height:clamp(160px,42vw,230px);
  }
  .svc:nth-child(even) .svc__media::after{background:linear-gradient(90deg,rgba(0,0,0,.55),rgba(0,0,0,0) 62%)}
  /* the gradient reads better bottom-up once the image sits above the copy */
  .svc__media::after{background:linear-gradient(180deg,rgba(0,0,0,.15),rgba(0,0,0,.55))}
  .svc:nth-child(even) .svc__media::after{background:linear-gradient(180deg,rgba(0,0,0,.15),rgba(0,0,0,.55))}
  .svc__no{font-size:clamp(2.2rem,9vw,3.2rem)}
}

/* ---------- Service detail: what we offer ---------- */
.offer{display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); gap:clamp(30px,5vw,74px); align-items:start}
.offer__body p{color:var(--grey); margin:20px 0 30px; max-width:52ch}
.offer__media img{width:100%; aspect-ratio:3/4; object-fit:cover; border:1px solid var(--line)}
/* some service pages only have landscape photography, so the portrait frame
   would crop the subject out of it */
.offer--wide .offer__media img{aspect-ratio:4/3}
.phases{display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:1px; background:var(--line); border:1px solid var(--line)}
.phase{background:var(--ink); padding:clamp(26px,3vw,42px); position:relative}

/* Same trap the follow band hit. These grids draw their hairlines with the
   container background showing through a 1px gap, so the moment a row wraps
   short the unfilled cells read as a grey slab. Here the cells carry the line
   themselves as an outline, which meets in the gap and looks identical, but
   leaves nothing behind an empty cell. Use on any grid whose item count does
   not divide evenly at every breakpoint. */
.pillars--edged,.tiles--edged,.figure--edged{background:none; border:0}
.pillars--edged .pillar,
.tiles--edged .tile,
.figure--edged > div{outline:1px solid var(--line)}
.phase::before{content:""; position:absolute; left:0; top:0; width:0; height:3px; background:var(--red); transition:width var(--t-slow) var(--ease)}
.phase:hover::before{width:100%}
.phase h3{font-family:var(--display); text-transform:uppercase; font-size:clamp(1rem,1.6vw,1.3rem); margin-bottom:16px}
.phase h3 span{color:var(--red); margin-right:.5em}
.phase p{color:var(--grey); font-size:.94rem}

/* ---------- Social: platform strip ---------- */
.sgrid{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:1px; background:var(--line); border:1px solid var(--line);
}
.splat{
  background:var(--ink); padding:clamp(24px,3vw,38px); position:relative;
  display:flex; flex-direction:column; gap:8px; transition:background var(--t) var(--ease);
}
.splat::before{content:""; position:absolute; left:0; top:0; width:0; height:3px; background:var(--red); transition:width var(--t-slow) var(--ease)}
.splat:hover{background:#161616}
.splat:hover::before{width:100%}
.splat b{font-family:var(--display); text-transform:uppercase; font-size:clamp(1rem,1.5vw,1.25rem)}
.splat span{color:var(--grey); font-size:.86rem}
.splat i{
  font-style:normal; margin-top:8px; font-size:.62rem; font-weight:700; letter-spacing:.22em;
  text-transform:uppercase; color:var(--red); display:inline-flex; align-items:center; gap:.5em;
}
.splat i::after{content:"\2192"; transition:transform var(--t) var(--ease)}
.splat:hover i::after{transform:translateX(4px)}

/* ---------- Social: instagram feed ---------- */
.feedhead{
  display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap;
  margin-bottom:clamp(26px,3vw,40px);
}
.feedhead__h{display:flex; align-items:center; gap:14px}
.feedhead__h b{font-family:var(--display); text-transform:uppercase; font-size:clamp(1rem,1.6vw,1.35rem)}
.feedhead__h span{color:var(--grey); font-size:.82rem}
.feed{display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:clamp(12px,1.6vw,18px)}
/* On a phone the 190px floor collapses these to one enormous post per row.
   Force the two-up grid instead so it reads like a feed. */
@media (max-width:640px){
  .feed,.feed--big{grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px}
  .feed .post__cap,.feed--big .post__cap{font-size:.72rem; padding:14px 12px 12px; line-height:1.35; -webkit-line-clamp:2}
  .feed .post__likes,.feed--big .post__likes{font-size:.68rem; padding:6px 9px}
}

/* "From The Feed" heading: keep it on the two lines it is written as, and let
   the lead break where the <br class="brwide"> says on wide screens only. */
.sec--feed .sechead{max-width:52rem}
@media (min-width:900px){
  .sec--feed .sechead .h2{font-size:clamp(1.9rem,3.6vw,2.95rem); white-space:nowrap}
}
@media (max-width:760px){ br.brwide{display:none} }
/* larger, taller curated grid on the social page */
.feed--big{grid-template-columns:repeat(auto-fit,minmax(clamp(230px,26vw,300px),1fr)); gap:clamp(16px,2vw,26px)}
.feed--big .post:hover{transform:translateY(-8px) scale(1.015) rotate(-.6deg)}
.feed--big .post__cap{font-size:.86rem; padding:20px 18px 18px}
.feed--big .post__likes{font-size:.76rem; padding:8px 12px}
.post{
  position:relative; display:block; aspect-ratio:9/13; overflow:hidden; isolation:isolate;
  background:#141414; border-radius:16px; box-shadow:inset 0 0 0 1.5px rgba(236,28,36,.5);
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.post img{width:100%; height:100%; object-fit:cover; border-radius:inherit; transition:transform .6s ease}
.post::after{content:""; position:absolute; inset:0; border-radius:inherit; background:linear-gradient(180deg,rgba(0,0,0,.05) 40%,rgba(0,0,0,.82)); pointer-events:none}
.post:hover{transform:translateY(-5px); box-shadow:inset 0 0 0 2px var(--red)}
.post:hover img{transform:scale(1.05)}
.post__likes{
  position:absolute; left:12px; top:12px; z-index:2; display:inline-flex; align-items:center; gap:6px;
  padding:6px 10px; background:rgba(0,0,0,.55); backdrop-filter:blur(4px); border-radius:100px;
  font-size:.7rem; font-weight:700; color:#fff;
}
.post__likes svg{width:13px; height:13px; fill:var(--red)}
.post__cap{
  position:absolute; left:0; right:0; bottom:0; z-index:2; padding:16px 14px 16px;
  font-size:.78rem; line-height:1.4; color:#EDEDED;
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}
.feednote{margin-top:clamp(26px,3vw,40px); color:#8A8A8A; font-size:.82rem; text-align:center}
.feednote a{color:var(--red); font-weight:600}

/* ---------- Other services strip ---------- */
.more{display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:clamp(12px,1.6vw,18px)}
.more a{
  background:var(--ink-2); padding:24px 22px; border:1px solid var(--line);
  font-family:var(--display); text-transform:uppercase; font-size:.92rem; line-height:1.2;
  display:flex; justify-content:space-between; align-items:center; gap:16px;
  transition:border-color var(--t) var(--ease), background var(--t) var(--ease), transform var(--t) var(--ease);
}
.more a::after{content:"\2192"; color:var(--red)}
.more a:hover{border-color:var(--red); background:#161616; transform:translateY(-4px)}

/* ---------- Contact ---------- */
/* Both columns run to the same height, so the contact-detail box bottoms out
   level with the wizard card beside it instead of hanging below it. The strip
   is pushed down the column rather than stretched, so the cells keep their
   own proportions. */
.contact{
  display:grid; grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
  gap:clamp(28px,4vw,64px); align-items:stretch;
}
.contact__aside{position:relative; display:flex; flex-direction:column}
.contact__aside .h2{margin:14px 0 18px}
.contact__aside .contact__lead{color:var(--grey); max-width:38ch; margin-bottom:clamp(24px,3vw,34px)}
/* .cstrip is a <dl>, which carries a 1em UA bottom margin. Without this the
   box lands 15px short of the wizard it is meant to line up with. */
.contact__aside .cstrip{margin-top:auto; margin-bottom:0}
/* contact-method strip, now stacked down the left column */
.cstrip{
  display:grid; grid-template-columns:1fr 1fr;
  gap:1px; background:var(--line); border:1px solid var(--line);
}
.cstrip div{background:var(--ink); padding:18px 22px}
.cstrip dt{font-size:.58rem; letter-spacing:.26em; text-transform:uppercase; color:var(--red); font-weight:700; margin-bottom:8px}
.cstrip dd{margin:0; font-size:.96rem}
.cstrip dd a:hover{color:var(--red)}

/* ---------- Wizard ---------- */
.wizard{background:var(--ink); border:1px solid var(--line); padding:clamp(24px,3.4vw,48px)}
.wiz__bar{height:3px; background:rgba(255,255,255,.1); margin-bottom:26px}
.wiz__fill{display:block; height:100%; width:25%; background:var(--red); transition:width .45s cubic-bezier(.22,1,.36,1)}
.wiz__meta{display:flex; justify-content:space-between; align-items:baseline; gap:16px; margin-bottom:28px}
.wiz__count{font-size:.6rem; letter-spacing:.26em; text-transform:uppercase; color:var(--grey); font-weight:700}
.wiz__now{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.1rem,2.2vw,1.5rem); color:var(--red)}
/* fieldsets carry a default border, margin and padding that would show through */
.wiz__step{border:0; margin:0; padding:0; min-inline-size:0; animation:wizIn .4s ease both}
.wiz__step[hidden]{display:none}
@keyframes wizIn{from{opacity:0; transform:translateY(14px)} to{opacity:1; transform:none}}
.wiz__grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:clamp(16px,2vw,24px)}
.field{display:grid; gap:9px}
.field--wide{grid-column:1 / -1}
.field label{font-size:.62rem; letter-spacing:.24em; text-transform:uppercase; font-weight:700; color:#CFCFCF}
.field label b{color:var(--red); font-weight:700}
.field input,.field textarea,.field select{
  width:100%; background:#0F0F0F; border:1px solid var(--line); color:#fff;
  font-family:var(--body); font-size:1rem; font-weight:300; padding:17px 18px;
  border-radius:0; cursor:text;
  transition:border-color .2s ease, background .2s ease, box-shadow .2s ease;
}
.field input:hover,.field textarea:hover{border-color:rgba(236,28,36,.45)}
.field textarea{resize:vertical; min-height:118px; line-height:1.6}
.field input::placeholder,.field textarea::placeholder{color:#5E5E5E}
.field input:focus,.field textarea:focus,.field select:focus{outline:none; border-color:var(--red); background:#131313}
/* the rule above kills the global focus ring, so put it back for keyboard users */
.field input:focus-visible,.field textarea:focus-visible,.field select:focus-visible{outline:2px solid var(--red); outline-offset:2px}
.field .err{font-size:.72rem; color:var(--red); letter-spacing:.04em; text-transform:none; font-weight:600}
.field.is-bad input,.field.is-bad textarea{border-color:var(--red)}

.chips{display:flex; flex-wrap:wrap; gap:10px}
.chip input{position:absolute; opacity:0; pointer-events:none}
.chip span{
  display:block; padding:12px 18px; border:1px solid var(--line); background:#0F0F0F;
  font-size:.72rem; letter-spacing:.12em; text-transform:uppercase; font-weight:700;
  cursor:pointer; transition:all .2s ease;
}
.chip span:hover{border-color:rgba(255,255,255,.35)}
.chip input:checked + span{background:var(--red); border-color:var(--red); color:#fff}
.chip input:focus-visible + span{outline:2px solid var(--red); outline-offset:3px}

.wiz__nav{display:flex; gap:12px; margin-top:34px; flex-wrap:wrap}
.wiz__nav .btn--ghost{margin-right:auto}
/* the forward action is the obvious tap target on every step */
.wiz__nav #wizNext,.wiz__nav #wizSend{padding:18px 40px; font-size:.82rem}
.wiz__note{margin-top:18px; font-size:.78rem; color:#8A8A8A}
.wiz__hint{margin-top:14px; font-size:.8rem; color:#7A7A7A; letter-spacing:.02em}

.wiz__done{text-align:center; padding:clamp(20px,4vw,50px) 0}
.wiz__done img{width:74px; margin:0 auto 26px; animation:spin 24s linear infinite}
.wiz__done h3{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.5rem,3.4vw,2.4rem); margin-bottom:18px}
.wiz__done p{color:var(--grey); max-width:44ch; margin:0 auto 30px}

/* the access code handed over after a mastery lead capture. Sits between the
   message and the button, and has to be the loudest thing in the panel. */
.codeout{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:8px 18px;
  max-width:30rem; margin:0 auto 30px; padding:22px 26px;
  background:#0B0B0B; border:1px solid rgba(236,28,36,.5);
}
.codeout__lab{
  flex-basis:100%; font-size:.6rem; letter-spacing:.26em; text-transform:uppercase;
  font-weight:700; color:var(--grey);
}
.codeout__val{
  font-family:var(--display); font-size:clamp(1.05rem,2.6vw,1.5rem); letter-spacing:.06em;
  text-transform:uppercase; color:#fff; user-select:all;
}
.codeout__copy{
  font-size:.6rem; letter-spacing:.2em; text-transform:uppercase; font-weight:700;
  color:var(--red); background:none; border:1px solid rgba(236,28,36,.5);
  padding:9px 14px; cursor:pointer; transition:background .2s ease, color .2s ease;
}
.codeout__copy:hover{background:var(--red); color:#fff}
.codeout__copy.is-done{background:var(--red); color:#fff}

/* ---------- Inner-page responsive ---------- */
@media (max-width:1000px){
  .split,.offer,.contact{grid-template-columns:1fr}
  .split--flip .split__media{order:0}
  /* on mobile the wizard is the primary action, so lift it above the
     direct contact strip */
  .contact .wizard{order:-1}
  .srow{grid-template-columns:auto minmax(0,1fr); row-gap:18px}
  .srow__go{grid-column:2; justify-self:start}
}
@media (max-width:560px){
  .wiz__nav .btn{width:100%}
  .wiz__nav .btn--ghost{margin-right:0}
  .split__media::before{display:none}
}

/* ==========================================================================
   First-visit intro. The mark lands on black and the brand's own ripple runs
   out of it: clean red rings that thin as they widen, plus one pulse of the
   brush ring from the kit. The black then splits on a red seam and clears the
   hero. Armed only on the first load of a session (guard in HTML).
   ========================================================================== */
html.is-intro, html.is-intro body{overflow:hidden}

#ripple-intro{
  position:fixed; inset:0; z-index:9999;
  overflow:hidden; background:transparent;
}

/* ---------- the black, in two halves so it can split on the way out ---------- */
.ri__panel{
  position:absolute; left:0; width:100%; height:calc(50% + 1px);
  background:#000; z-index:1; will-change:transform;
}
.ri__panel--t{top:0}
.ri__panel--b{bottom:0}

/* the red seam. Hidden until the split, then it leads the two halves apart */
.ri__panel::after{
  content:""; position:absolute; left:0; right:0; height:2px;
  background:var(--red); opacity:0;
  box-shadow:0 0 22px 3px rgba(236,28,36,.6);
}
.ri__panel--t::after{bottom:0}
.ri__panel--b::after{top:0}

/* ---------- the ripple ---------- */
.ri__field{
  position:absolute; inset:0; z-index:2;
  display:grid; place-items:center; pointer-events:none;
}

/* Every ring is the same brush artwork from the kit (ring-red is the only one
   of the three exported clean, the others carry a white matte that fringes
   grey on black). Start angle, end angle, mirroring, peak opacity and speed
   are set per layer, so three pulses out of one file never read as the same
   picture repeating. */
.ri__ring{
  position:absolute; left:50%; top:50%;
  width:min(64vmax,620px); height:auto;
  --fx:1; --o:.95; --r0:0deg; --r1:0deg;
  opacity:0; will-change:transform, opacity;
  transform:translate(-50%,-50%) scaleX(var(--fx)) scale(.28) rotate(var(--r0));
  /* linear: a wavefront travels at a steady speed. Easing it made the ring
     blow past readable size while it was still at full strength */
  animation:ri-pulse 1.12s linear both;
}
/* staggered so one ring owns the frame at a time and the next is only just
   leaving the mark as it goes. Overlapping bright rings turn into a red wall */
.ri__ring--1{--r0:-16deg; --r1:16deg;  --o:1;   animation-delay:.05s}
.ri__ring--2{--r0:126deg; --r1:96deg;  --o:.92; --fx:-1; animation-delay:.44s; animation-duration:1.18s}
.ri__ring--3{--r0:242deg; --r1:278deg; --o:1;   animation-delay:.82s; animation-duration:1.08s}

/* holds the centre and lets the rings die out toward the corners */
.ri__vig{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  background:radial-gradient(circle at 50% 50%,
              transparent 42%, rgba(0,0,0,.3) 76%, rgba(0,0,0,.62));
}

.ri__logo{
  position:relative; z-index:3;
  width:clamp(172px,25vw,300px); height:auto;
  opacity:0; transform:scale(.9);
  /* the first shadow is a tight black halo. It knocks the ripple back just
     enough behind the mark to keep it readable at full density */
  filter:drop-shadow(0 0 26px rgba(0,0,0,.92)) drop-shadow(0 10px 34px rgba(0,0,0,.6));
  animation:ri-logo .42s cubic-bezier(.16,.84,.28,1) .05s both;
}

/* ---------- exit: mark clears, black splits on the seam ---------- */
/* the mark is gone before the seam opens, so nothing ghosts over the hero */
#ripple-intro.is-out .ri__field{animation:ri-clear .14s ease-in forwards}
#ripple-intro.is-out .ri__panel::after{animation:ri-seam .44s ease-out .07s forwards}
#ripple-intro.is-out .ri__panel--t{animation:ri-split-t .44s cubic-bezier(.72,0,.16,1) .07s forwards}
#ripple-intro.is-out .ri__panel--b{animation:ri-split-b .44s cubic-bezier(.72,0,.16,1) .07s forwards}

/* the red never dims on screen. By the time the fade starts the ring is wider
   than the viewport diagonal, so it is already gone when it goes. Fading brand
   red down over black is what turned it to mud */
@keyframes ri-pulse{
  0%  {opacity:0;        transform:translate(-50%,-50%) scaleX(var(--fx)) scale(.28) rotate(var(--r0))}
  5%  {opacity:var(--o)}
  62% {opacity:var(--o)}
  74% {opacity:0}
  100%{opacity:0;        transform:translate(-50%,-50%) scaleX(var(--fx)) scale(3.8) rotate(var(--r1))}
}
@keyframes ri-logo{
  0%  {opacity:0; transform:scale(.9)}
  30% {opacity:1}
  100%{opacity:1; transform:scale(1)}
}
@keyframes ri-clear{
  0%  {opacity:1; transform:scale(1)}
  100%{opacity:0; transform:scale(.97)}
}
@keyframes ri-seam{
  0%{opacity:0} 12%{opacity:1} 100%{opacity:0}
}
@keyframes ri-split-t{
  0%{transform:translateY(0)} 100%{transform:translateY(-101%)}
}
@keyframes ri-split-b{
  0%{transform:translateY(0)} 100%{transform:translateY(101%)}
}

/* never animate for reduced-motion users (the guard also skips arming) */
@media (prefers-reduced-motion:reduce){ #ripple-intro{display:none} }

/* ==========================================================================
   2026 repositioning pass. New shared components
   ========================================================================== */

/* ---------- Follow band ----------
   The old /social page's "Everywhere You Look" grid, now site furniture that
   sits between the CTA and the footer on every page. Kept deliberately quiet
   so it reads as a footer lead-in rather than another full section. */
.follow{background:var(--ink); border-top:1px solid var(--line); padding:clamp(40px,5vw,64px) 0}
.follow__in{display:grid; grid-template-columns:minmax(0,.55fr) minmax(0,1.45fr); gap:clamp(24px,3vw,48px); align-items:center}
.follow__h{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.2rem,2.4vw,1.8rem); line-height:1.02; margin:14px 0 0}
.follow__p{color:var(--grey); font-size:.9rem; margin-top:12px; max-width:32ch}
/* Five platforms across a narrower column than the old /social page had, so
   the platform name gets its own smaller scale. Eurostile Extended is wide
   enough that "Instagram" is what sets the minimum cell here.
   The shared .sgrid draws its hairlines with a container background showing
   through a 1px gap, which leaves a grey slab behind any unfilled cell when
   the row wraps. Here the tiles carry their own border instead, so a short
   last row just shows fewer boxes. */
.follow .sgrid{
  grid-template-columns:repeat(auto-fit,minmax(156px,1fr));
  gap:8px; background:none; border:0;
}
.follow .splat{padding:18px 16px; border:1px solid var(--line)}
.follow .splat b{font-size:clamp(.86rem,1.05vw,1rem)}
.follow .splat span{font-size:.78rem}
/* Stack early: once the platform row can no longer hold all five side by side
   it looks better giving it the full width than wrapping one tile onto its own
   line beside the heading. */
@media (max-width:1150px){ .follow__in{grid-template-columns:1fr} }

/* ---------- Homepage service intro ----------
   Replaces the "All-Round Digital Solutions" pillars. Four literal service
   names, one line of separation each, so Long-Form Video and Video Production
   are never confused for one another. */
.slist{display:grid; gap:1px; background:var(--line); border:1px solid var(--line)}
.sitem{
  background:var(--black); display:grid; grid-template-columns:auto minmax(0,1fr) auto;
  gap:clamp(18px,3vw,44px); align-items:center; padding:clamp(24px,3vw,40px) clamp(20px,3vw,38px);
  transition:background var(--t) var(--ease);
}
.sitem:hover{background:var(--ink-2)}
.sitem__no{font-family:var(--display); color:var(--red); font-size:clamp(1.2rem,2.4vw,1.9rem); line-height:1}
.sitem h3{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.1rem,2.3vw,1.7rem); margin-bottom:10px}
.sitem p{color:var(--grey); font-size:.94rem; max-width:58ch}
.sitem__go{
  flex:none; width:50px; height:50px; display:grid; place-items:center;
  background:var(--red); color:#fff; font-size:1rem;
  clip-path:polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition:transform var(--t) var(--ease);
}
.sitem:hover .sitem__go{transform:translate(4px,-4px)}
.sfoot{
  margin-top:clamp(22px,2.6vw,32px); color:var(--grey); font-size:.9rem;
  border-left:2px solid var(--red); padding-left:18px; max-width:64ch;
}
.sfoot a{color:#fff; font-weight:600; border-bottom:1px solid var(--red)}
.sfoot a:hover{color:var(--red)}
@media (max-width:760px){
  .sitem{grid-template-columns:auto minmax(0,1fr); row-gap:14px}
  .sitem__go{grid-column:2; justify-self:start; width:44px; height:44px}
}

/* ---------- Marks ----------
   The "What Drives Us" idea in a different structure: line icon, heading and
   a couple of lines, led by a red hairline instead of a box. Gives a section
   shape without another bordered grid. */
.marks{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:clamp(26px,3.2vw,48px);
}
.mark{
  position:relative; padding-top:clamp(20px,2.2vw,28px);
  border-top:2px solid rgba(236,28,36,.3);
  transition:border-color var(--t) var(--ease), opacity var(--reveal), transform var(--reveal);
}
.mark:hover{border-top-color:var(--red)}
.mark__ico{
  display:block; width:clamp(36px,3.2vw,44px); aspect-ratio:1; color:var(--red);
  margin-bottom:clamp(16px,1.8vw,22px); transition:transform var(--t) var(--ease);
}
.mark:hover .mark__ico{transform:translateY(-4px)}
.mark__ico svg{
  width:100%; height:100%; fill:none; stroke:currentColor;
  stroke-width:1.7; stroke-linecap:square; stroke-linejoin:miter;
}
.mark h3{
  font-family:var(--display); text-transform:uppercase;
  font-size:clamp(1rem,1.5vw,1.24rem); line-height:1.16; margin-bottom:12px;
}
.mark p{color:var(--grey); font-size:.94rem}
.mark .ticks{margin-top:18px}
.mark .ticks a{color:var(--red); font-weight:600}
/* two wider columns, for a pair of longer points rather than a four-up */
.marks--two{grid-template-columns:repeat(auto-fit,minmax(320px,1fr)); gap:clamp(30px,4vw,64px)}
.marks--two .mark h3{font-size:clamp(1.1rem,1.9vw,1.45rem)}
/* the literal service name, so the abstract heading always resolves to one */
.mark__svc{
  display:block; font-size:.62rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--red); font-weight:700; margin-bottom:14px; line-height:1.5;
}

/* ---------- Flow ----------
   Replaces the boxed pillar grids on the service pages. Same information, but
   it reads as a set of steps rather than six identical slabs: an outlined
   number and a line icon on a rule that draws itself in red as each item
   comes up the page. Works for a sequence (planning, filming, editing) and for
   a flat set (the six numbers we report on) without changing shape. */
/* Column count is set per section rather than left to auto-fit, because
   auto-fit was splitting six items 4 + 2 and four items 3 + 1. Six wants
   three across, four wants four. */
.flow{
  display:grid; grid-template-columns:repeat(var(--cols,3),minmax(0,1fr));
  gap:clamp(30px,3.6vw,54px) clamp(24px,3vw,46px);
}
.flow--4{--cols:4}
@media (max-width:1100px){ .flow{--cols:2 !important} }
@media (max-width:620px){ .flow{--cols:1 !important} }
.flow__i{position:relative; padding-top:clamp(22px,2.4vw,30px)}
/* the unlit rule, always there so the row never looks unfinished */
.flow__i::before{
  content:""; position:absolute; inset:0 0 auto; height:2px; background:rgba(255,255,255,.13);
}
/* and the red one that wipes across it on reveal */
.flow__i::after{
  content:""; position:absolute; inset:0 0 auto; height:2px; background:var(--red);
  transform:scaleX(0); transform-origin:left center;
  transition:transform .75s var(--ease);
}
.flow__i.in::after{transform:scaleX(1)}
.flow__i:nth-child(2)::after{transition-delay:.08s}
.flow__i:nth-child(3)::after{transition-delay:.16s}
.flow__i:nth-child(4)::after{transition-delay:.24s}
.flow__i:nth-child(5)::after{transition-delay:.32s}
.flow__i:nth-child(6)::after{transition-delay:.4s}
.flow__top{
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; margin-bottom:clamp(18px,2vw,26px);
}
/* outlined rather than filled: the number is a marker, not a headline */
.flow__n{
  font-family:var(--display); font-size:clamp(1.55rem,2.9vw,2.2rem); line-height:1;
  color:transparent; -webkit-text-stroke:1px rgba(255,255,255,.34);
  transition:-webkit-text-stroke-color .6s var(--ease);
}
.flow__i.in .flow__n{-webkit-text-stroke-color:rgba(236,28,36,.85)}
.flow__ico{display:block; width:clamp(34px,3vw,42px); aspect-ratio:1; color:var(--red); flex:none; transition:transform var(--t) var(--ease)}
.flow__i:hover .flow__ico{transform:translateY(-4px)}
.flow__ico svg{
  width:100%; height:100%; fill:none; stroke:currentColor;
  stroke-width:1.7; stroke-linecap:square; stroke-linejoin:miter;
}
.flow__i h3{
  font-family:var(--display); text-transform:uppercase;
  font-size:clamp(1rem,1.5vw,1.2rem); line-height:1.16; margin-bottom:12px;
}
.flow__i p{color:var(--grey); font-size:.94rem}
.flow__i .ticks{margin-top:16px}
/* the grid used to carry the bottom margin the pillars had */
.flow--gap{margin-bottom:clamp(44px,6vw,80px)}

/* ---------- Featured client experience ----------
   The long-form testimonial treatment: who they are, what they said, and the
   full video one tap away. Used on the homepage and the testimonials page. */
.exps{display:grid; gap:clamp(18px,2.4vw,28px)}
.exp{
  display:grid; grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  gap:clamp(22px,3.4vw,50px); align-items:stretch;
  background:#0C0C0C; border:1px solid var(--line); overflow:hidden;
  clip-path:polygon(0 0, 100% 0, 100% calc(100% - 30px), calc(100% - 30px) 100%, 0 100%);
  transition:border-color var(--t) var(--ease), background var(--t) var(--ease),
             opacity var(--reveal), transform var(--reveal);
}
.exp:hover{border-color:rgba(236,28,36,.5); background:#101010}
.exp:nth-child(even) .exp__media{order:1}
.exp__media{position:relative; align-self:stretch; min-height:290px; overflow:hidden; border:0; padding:0; background:none; cursor:pointer; display:block; width:100%}
.exp__media img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform 1s var(--ease)}
.exp__media::after{content:""; position:absolute; inset:0; background:linear-gradient(180deg,rgba(0,0,0,.12),rgba(0,0,0,.6)); pointer-events:none}
.exp:hover .exp__media img{transform:scale(1.05)}
.exp__play{
  position:absolute; left:50%; top:50%; translate:-50% -50%; z-index:2;
  width:clamp(54px,6vw,72px); aspect-ratio:1; border-radius:50%;
  background:var(--red); display:grid; place-items:center;
  box-shadow:0 0 0 8px rgba(236,28,36,.18); transition:scale var(--t) var(--ease);
}
.exp__play::before{content:""; width:0; height:0; margin-left:5px; border-block:11px solid transparent; border-left:18px solid #fff}
.exp__media:hover .exp__play{scale:1.1}
.exp__body{padding:clamp(26px,3.2vw,48px); display:flex; flex-direction:column; justify-content:center}
.exp__who{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.2rem,2.4vw,1.85rem); line-height:1.04}
.exp__biz{display:block; margin-top:10px; font-size:.62rem; letter-spacing:.24em; text-transform:uppercase; color:var(--red); font-weight:700}
.exp__quote{
  margin:clamp(20px,2.4vw,30px) 0 0; font-size:clamp(1.02rem,1.7vw,1.28rem);
  line-height:1.5; color:#fff; font-weight:300; position:relative; padding-left:20px;
  border-left:2px solid var(--red);
}
.exp__cta{
  margin-top:clamp(22px,2.6vw,32px); align-self:flex-start;
  min-height:24px;   /* WCAG 2.5.8 target size */
  display:inline-flex; align-items:center; gap:.6em;
  font-weight:800; font-size:.72rem; letter-spacing:.16em; text-transform:uppercase;
  color:#fff; background:none; border:0; cursor:pointer; padding:0;
  transition:gap var(--t) var(--ease), color var(--t) var(--ease);
}
.exp__cta span{color:var(--red); font-size:1.1em; transition:transform var(--t) var(--ease)}
.exp__cta:hover{color:var(--red); gap:1em}
.exp__cta:hover span{transform:translateX(4px)}
@media (max-width:900px){
  .exp{grid-template-columns:1fr}
  .exp:nth-child(even) .exp__media{order:0}
  .exp__media{min-height:0; aspect-ratio:16/10}
}

/* ---------- Case study feature block ----------
   The homepage lead-in to the full ITow page. Dark red wash, the headline
   number, and three proof stats. */
.csf{position:relative; overflow:hidden; background:#0B0405; border:1px solid rgba(236,28,36,.34); padding:clamp(30px,4.2vw,62px)}
.csf::before{
  content:""; position:absolute; inset:0; pointer-events:none; opacity:.9;
  background:radial-gradient(90% 120% at 100% 0%, rgba(236,28,36,.22), transparent 62%);
}
.csf__in{position:relative; z-index:1; display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr); gap:clamp(26px,4vw,60px); align-items:center}
.csf__side{display:grid; gap:clamp(16px,2vw,22px)}

/* The iTow testimonial video, folded into this block so the client is not
   presented twice on the homepage. */
.csf__media{
  position:relative; display:block; width:100%; aspect-ratio:16/10; overflow:hidden;
  border:1px solid rgba(255,255,255,.16); padding:0; background:#0A0304; cursor:pointer;
}
.csf__media img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform 1s var(--ease)}
.csf__media::after{content:""; position:absolute; inset:0; background:linear-gradient(180deg,rgba(0,0,0,.1) 35%,rgba(0,0,0,.78)); pointer-events:none}
.csf__media:hover{border-color:rgba(236,28,36,.6)}
.csf__media:hover img{transform:scale(1.05)}
.csf__play{
  position:absolute; z-index:2; top:50%; left:50%; translate:-50% -50%;
  width:64px; height:64px; border-radius:50%; background:var(--red);
  display:grid; place-items:center; transition:scale var(--t) var(--ease);
}
.csf__play::before{content:""; width:0; height:0; margin-left:5px; border-block:11px solid transparent; border-left:18px solid #fff}
.csf__media:hover .csf__play{scale:1.1}
.csf__mlabel{
  position:absolute; z-index:2; left:clamp(14px,2vw,20px); bottom:clamp(12px,1.8vw,18px); right:14px;
  text-align:left; font-size:.62rem; letter-spacing:.22em; text-transform:uppercase;
  font-weight:700; color:#fff;
}
/* Same card. It opens the case study page rather than a lightbox, but it keeps
   the play badge because the card reads as a piece of footage either way. */
.csf__media--link{display:block}
.csf__media--link:hover .csf__play{scale:1.1}

/* Photo panel used where the block has no video or stats to sit on the right. */
.csf__shot{margin:0; position:relative; border:1px solid rgba(255,255,255,.16); overflow:hidden; background:#0A0304}
.csf__shot img{display:block; width:100%; aspect-ratio:4/5; object-fit:cover; object-position:50% 35%}
.csf__shot figcaption{
  position:absolute; left:0; right:0; bottom:0; padding:44px 18px 16px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.9));
  font-size:.62rem; letter-spacing:.2em; text-transform:uppercase; font-weight:700; color:#fff;
  line-height:1.6;
}
@media (max-width:1000px){ .csf__shot img{aspect-ratio:16/10} }

.csf__quote{
  margin:clamp(22px,2.8vw,30px) 0 0; padding-left:clamp(16px,2vw,22px);
  border-left:2px solid var(--red);
}
.csf__quote p{color:#fff; font-size:clamp(1rem,1.55vw,1.18rem); line-height:1.5; margin:0; max-width:46ch}
.csf__quote cite{
  display:block; margin-top:14px; font-style:normal; font-family:var(--display);
  text-transform:uppercase; font-size:.9rem; letter-spacing:.02em;
}
.csf__quote cite span{
  display:block; margin-top:6px; font-family:var(--body);
  font-size:.62rem; letter-spacing:.24em; color:var(--red); font-weight:700;
}
.csf__h{font-family:var(--display); text-transform:uppercase; line-height:.98; font-size:clamp(1.7rem,4.2vw,3.1rem); margin:14px 0 0}
.csf__h em{font-style:normal; color:var(--red)}
.csf__p{color:var(--grey); margin-top:20px; max-width:52ch}
.csf__cta{display:flex; flex-wrap:wrap; gap:14px; margin-top:clamp(24px,3vw,34px)}
.csf__stats{display:grid; gap:1px; background:rgba(255,255,255,.14); border:1px solid rgba(255,255,255,.14)}
.csf__stat{background:#0A0304; padding:clamp(18px,2.2vw,26px)}
.csf__stat b{display:block; font-family:var(--display); font-size:clamp(1.5rem,3.4vw,2.4rem); line-height:1; color:#fff}
.csf__stat span{display:block; margin-top:10px; font-size:.78rem; color:var(--grey); line-height:1.5}
@media (max-width:900px){ .csf__in{grid-template-columns:1fr} }

/* ---------- Case study page ---------- */
.cs__lede{font-size:clamp(1.05rem,1.9vw,1.35rem); color:#DCDCDC; max-width:62ch; line-height:1.62; font-weight:300}
.cs__source{margin-top:clamp(22px,2.6vw,32px); font-size:.8rem; color:#8A8A8A; max-width:62ch}
/* the headline investment figure, given its own beat */
.figure{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:1px;
  background:var(--line); border:1px solid var(--line);
}
.figure div{background:var(--ink); padding:clamp(22px,2.4vw,32px)}
/* Eurostile Extended is wide, so this caps well below the section headings.
   "$30,984" is the longest figure and it is what sets the ceiling. */
.figure b{display:block; font-family:var(--display); font-size:clamp(1.45rem,2.8vw,2.3rem); line-height:1.04; color:var(--red)}
.figure span{display:block; margin-top:12px; font-size:.68rem; letter-spacing:.2em; text-transform:uppercase; color:var(--grey); font-weight:700}
/* ---- report furniture ----
   The page reads as a written report rather than a story, so it carries the
   same scaffolding one would: a scope line at the top, numbered findings, and
   the evidence for each one sitting beside the finding instead of stacked up
   as a wall of quotations. */

/* scope strip: who, over what period, on what */
.rmeta{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:1px; background:var(--line); border:1px solid var(--line);
  margin-bottom:clamp(30px,4vw,52px);
}
.rmeta div{background:var(--ink); padding:16px 20px}
.rmeta dt{font-size:.56rem; letter-spacing:.26em; text-transform:uppercase; color:var(--red); font-weight:700; margin-bottom:9px}
.rmeta dd{margin:0; font-size:.92rem; line-height:1.45}

/* a numbered finding */
.finds{display:grid}
.find{
  display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(22px,3.6vw,56px); align-items:start;
  padding:clamp(30px,4vw,52px) 0; border-top:1px solid var(--line);
}
.find:first-child{border-top:0; padding-top:0}
.find__lab{
  display:flex; align-items:center; gap:14px; margin-bottom:clamp(16px,2vw,22px);
}
.find__no{
  font-family:var(--display); font-size:.66rem; letter-spacing:.22em;
  color:var(--red); font-weight:700;
}
.find__rule{flex:1; height:1px; background:var(--line)}
.find__ico{display:block; width:34px; aspect-ratio:1; color:var(--red); flex:none}
.find__ico svg{width:100%; height:100%; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:square; stroke-linejoin:miter}
.find__h{font-family:var(--display); text-transform:uppercase; line-height:1.06; font-size:clamp(1.25rem,2.6vw,1.95rem); max-width:20ch}
.find__p{color:var(--grey); margin-top:clamp(16px,1.8vw,22px); max-width:56ch}
.find__side{display:grid; gap:clamp(14px,1.8vw,20px)}
/* the numbers pulled out of the finding, so they are readable at a glance */
.find__stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(130px,1fr)); gap:1px; background:var(--line); border:1px solid var(--line)}
.find__stats div{background:var(--ink); padding:18px 20px}
.find__stats b{display:block; font-family:var(--display); font-size:clamp(1.15rem,2.2vw,1.6rem); line-height:1.05; color:#fff}
.find__stats span{display:block; margin-top:9px; font-size:.66rem; letter-spacing:.16em; text-transform:uppercase; color:var(--grey); font-weight:700; line-height:1.5}
/* one quotation per finding, the strongest one, treated as evidence */
.find__q{
  margin:0; padding:20px 22px; background:var(--ink); border-left:2px solid var(--red);
  color:#fff; font-size:.98rem; line-height:1.55; font-weight:300;
}
.find__q cite{display:block; margin-top:12px; font-style:normal; font-size:.6rem; letter-spacing:.22em; text-transform:uppercase; color:var(--red); font-weight:700}
@media (max-width:900px){ .find{grid-template-columns:1fr} }

/* the closing figure, given the weight the rest of the page builds toward */
.verdict{
  position:relative; overflow:hidden; margin-top:clamp(34px,4.5vw,60px);
  background:#0B0405; border:1px solid rgba(236,28,36,.34);
  padding:clamp(30px,4.6vw,66px); text-align:center;
}
.verdict::before{
  content:""; position:absolute; inset:0; pointer-events:none; opacity:.9;
  background:radial-gradient(80% 130% at 50% 0%, rgba(236,28,36,.2), transparent 64%);
}
.verdict > *{position:relative; z-index:1}
.verdict__lab{justify-content:center}
.verdict__q span{color:var(--red)}
.verdict__q{
  font-family:var(--display); text-transform:uppercase; line-height:1;
  font-size:clamp(2.6rem,9vw,6rem); margin:18px 0 0;
}
.verdict__cite{display:block; margin-top:clamp(18px,2.2vw,26px); font-style:normal; font-size:.62rem; letter-spacing:.24em; text-transform:uppercase; color:var(--red); font-weight:700}
.verdict__p{color:var(--grey); max-width:56ch; margin:clamp(20px,2.4vw,28px) auto 0}
/* the interview embed, opened through the same branded popup */
.watch{
  position:relative; width:100%; border:1px solid var(--line); background:#0C0C0C; color:#fff;
  aspect-ratio:16/9; overflow:hidden; cursor:pointer; padding:0; display:block;
}
.watch img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:.62; transition:opacity var(--t) var(--ease), transform 1s var(--ease)}
.watch:hover img{opacity:.8; transform:scale(1.03)}
.watch__play{
  position:absolute; left:50%; top:50%; translate:-50% -50%; z-index:2;
  width:clamp(62px,7vw,86px); aspect-ratio:1; border-radius:50%; background:var(--red);
  display:grid; place-items:center; box-shadow:0 0 0 10px rgba(236,28,36,.16); transition:scale var(--t) var(--ease);
}
.watch__play::before{content:""; width:0; height:0; margin-left:6px; border-block:13px solid transparent; border-left:21px solid #fff}
.watch:hover .watch__play{scale:1.08}
.watch__cap{
  position:absolute; left:0; right:0; bottom:0; z-index:2; padding:20px 22px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.9));
  font-size:.72rem; letter-spacing:.16em; text-transform:uppercase; font-weight:700; text-align:left;
}
/* backlinks out to the client */
.blinks{display:flex; flex-wrap:wrap; gap:12px; margin-top:clamp(22px,2.6vw,30px)}
.blinks a{
  padding:12px 20px; border:1px solid var(--line); background:var(--ink);
  font-size:.7rem; letter-spacing:.14em; text-transform:uppercase; font-weight:700;
  transition:border-color var(--t) var(--ease), background var(--t) var(--ease), transform var(--t) var(--ease);
}
.blinks a:hover{border-color:var(--red); background:#161616; transform:translateY(-3px)}

/* ---------- Resources hub ---------- */
.res{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:1px; background:var(--line); border:1px solid var(--line)}
.res article{background:var(--ink); padding:clamp(28px,3.4vw,46px); display:flex; flex-direction:column}
.res h2{font-family:var(--display); text-transform:uppercase; font-size:clamp(1.15rem,2.2vw,1.6rem); margin-bottom:14px}
.res p{color:var(--grey); margin-bottom:26px}
.res .btn{align-self:flex-start; margin-top:auto}
.res__soon{
  display:inline-block; margin-bottom:16px; padding:6px 12px;
  border:1px solid rgba(236,28,36,.5); color:var(--red);
  font-size:.58rem; letter-spacing:.22em; text-transform:uppercase; font-weight:700;
}

/* ==========================================================================
   Web design page: the media-led blocks
   This page sells work that is visual, so it leans on real screenshots and
   a photo of the builder rather than another wall of copy.
   ========================================================================== */

/* Full-bleed rail of recent builds, sitting straight under the page hero.
   Duplicated track scrolls forever; hover parks it so a screenshot can be
   looked at properly. */
.wrail{
  position:relative; overflow:hidden; background:var(--ink);
  border-block:1px solid var(--line); padding:clamp(20px,2.4vw,30px) 0;
}
.wrail::before,.wrail::after{
  content:""; position:absolute; top:0; bottom:0; width:clamp(50px,10vw,150px); z-index:2; pointer-events:none;
}
.wrail::before{left:0; background:linear-gradient(90deg,var(--ink),transparent)}
.wrail::after{right:0; background:linear-gradient(270deg,var(--ink),transparent)}
.wrail__track{display:flex; gap:clamp(14px,1.6vw,22px); width:max-content; animation:wrailrun 46s linear infinite}
.wrail:hover .wrail__track{animation-play-state:paused}
@keyframes wrailrun{to{transform:translateX(-50%)}}
.wrail__shot{
  margin:0; position:relative; flex:none; width:clamp(240px,26vw,380px); aspect-ratio:16/10;
  overflow:hidden; border:1px solid var(--line); background:#000;
}
.wrail__shot img{width:100%; height:100%; object-fit:cover; object-position:top center; filter:grayscale(1) contrast(1.05); transition:filter var(--t) var(--ease)}
.wrail:hover .wrail__shot img{filter:none}
.wrail__shot b{
  position:absolute; left:0; bottom:0; right:0; padding:26px 14px 11px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.92));
  font-size:.62rem; letter-spacing:.2em; text-transform:uppercase; color:#fff;
}

/* A screenshot in the offer slot wants its own proportions, not the portrait
   crop the photo version uses. */
.offer--shot .offer__media img{aspect-ratio:16/10; object-position:top center}

/* Builder block: portrait + a photo of the work happening, against copy. */
.builder{display:grid; grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr); gap:clamp(30px,5vw,72px); align-items:center}
.builder__stack{position:relative}
.builder__stack .builder__desk{
  display:block; width:100%; aspect-ratio:4/5; object-fit:cover; border:1px solid var(--line);
}
/* portrait tucked into the bottom corner, cut out of the desk shot by the
   page background so the two photos read as one object */
/* The source is a tall portrait and the face sits about a third of the way
   down it, so a top-anchored square crop parks the face on the bottom edge.
   Pull the crop window down to bring the face up into the middle of the tile. */
.builder__stack .builder__face{
  position:absolute; right:-16px; bottom:-24px; width:34%;
  aspect-ratio:1/1; object-fit:cover; object-position:50% 30%;
  border:1px solid var(--line); outline:7px solid var(--ink);
}
.builder__stack .builder__logo{
  position:absolute; left:-12px; top:-12px; z-index:2;
  width:clamp(58px,6vw,84px); height:auto; border:1px solid rgba(255,255,255,.16);
  background:#000; padding:12px;
}
.builder__body p{color:var(--grey); margin:20px 0 0; max-width:52ch}
.builder__body .ticks{margin-top:clamp(30px,3.4vw,44px)}
.builder__sig{
  display:flex; align-items:center; gap:14px; margin-top:clamp(26px,3vw,34px);
  padding-top:22px; border-top:1px solid var(--line);
}
.builder__sig b{font-family:var(--display); text-transform:uppercase; font-size:.95rem}
.builder__sig span{font-size:.72rem; letter-spacing:.16em; text-transform:uppercase; color:var(--grey)}

/* Screenshot gallery: a masonry wall. Every shot keeps its natural aspect
   ratio so nothing is ever cropped, short landing pages and full-length
   scrolls sit side by side, and it reads as a real portfolio. */
.shots{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:clamp(12px,1.4vw,20px); align-items:start;
}
/* Each column is its own track so placement is deliberate rather than left to
   the multicol balancer. That buys two things the auto version could not do:
   the three columns are hand-balanced to within a few dozen pixels, and every
   column can be made to lead with a dark full-bleed shot so the tops read
   level against the black page. */
.shots__col{display:grid; gap:clamp(12px,1.4vw,20px); align-content:start}
.shot{
  margin:0; position:relative; overflow:hidden;
  border:1px solid var(--line); background:#000; break-inside:avoid; display:block;
}
.shot img{width:100%; height:auto; display:block; transition:transform .6s var(--ease)}
.shot:hover img{transform:scale(1.03)}
.shot__tag{
  position:absolute; left:0; right:0; bottom:0; padding:34px 16px 14px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.92));
}
.shot__tag b{display:block; font-family:var(--display); text-transform:uppercase; font-size:.92rem}
.shot__tag span{display:block; margin-top:5px; font-size:.62rem; letter-spacing:.18em; text-transform:uppercase; color:var(--grey)}

@media (max-width:900px){
  .builder{grid-template-columns:1fr}
  .builder__face{width:32%; right:0; bottom:-16px}
  /* Below the 3-column breakpoint the hand-placed columns stop earning their
     keep, so the wrappers are dissolved and the shots are re-flowed by the
     multicol balancer instead. */
  .shots{display:block; columns:2; column-gap:clamp(12px,1.4vw,20px)}
  .shots__col{display:contents}
  .shot{margin:0 0 clamp(12px,1.4vw,20px)}
}
@media (max-width:560px){
  .shots{columns:1}
}

/* ==========================================================================
   Swipeable deck
   A PDF exported to slides and read sideways, the way the client reads it in
   person. Native scroll-snap does the swiping so touch feels right for free;
   the arrows, dots and keyboard handling are there for desktop.
   ========================================================================== */
.deck{position:relative}
.deck__rail{
  display:grid; grid-auto-flow:column; grid-auto-columns:100%;
  gap:clamp(10px,1.4vw,18px);
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
}
.deck__rail::-webkit-scrollbar{display:none}
.deck__slide{
  margin:0; position:relative; scroll-snap-align:center; scroll-snap-stop:always;
  background:#0A0A0A; border:1px solid var(--line); overflow:hidden;
  clip-path:polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}
.deck__slide img{display:block; width:100%; height:auto}

.deck__nav{
  display:flex; align-items:center; gap:clamp(12px,2vw,20px);
  margin-top:clamp(14px,2vw,22px);
}
.deck__btn{
  flex:none; width:clamp(40px,4.4vw,50px); aspect-ratio:1; display:grid; place-items:center;
  background:transparent; border:1px solid var(--line); color:#fff; cursor:pointer;
  transition:background var(--t) var(--ease), border-color var(--t) var(--ease), color var(--t) var(--ease);
}
.deck__btn:hover:not(:disabled){background:var(--red); border-color:var(--red)}
.deck__btn:disabled{opacity:.28; cursor:default}
.deck__btn svg{width:38%; height:38%; fill:none; stroke:currentColor; stroke-width:2.4; stroke-linecap:square}
.deck__btn--prev svg{transform:rotate(180deg)}

.deck__dots{display:flex; flex-wrap:wrap; justify-content:center; gap:8px; flex:1}
.deck__dot{
  width:9px; height:9px; padding:0; border:0; border-radius:50%; cursor:pointer;
  background:rgba(255,255,255,.2);
  transition:background var(--t) var(--ease), scale var(--t) var(--ease);
}
.deck__dot:hover{background:rgba(255,255,255,.45)}
.deck__dot.is-on{background:var(--red); scale:1.3}
.deck__count{
  flex:none; font-size:.62rem; font-weight:700; letter-spacing:.2em;
  text-transform:uppercase; color:var(--grey); font-variant-numeric:tabular-nums;
}
.deck__hint{
  margin-top:12px; text-align:center; font-size:.6rem; font-weight:700;
  letter-spacing:.22em; text-transform:uppercase; color:var(--grey);
}
@media (min-width:761px){ .deck__hint{display:none} }
@media (max-width:760px){
  .deck__dots{display:none}
  .deck__nav{justify-content:space-between}
  .deck__count{flex:1; text-align:center}
}

/* ==========================================================================
   Landscape video rail + lightbox
   The original rail was built for vertical clips. YouTube long-forms are
   16:9, so they get their own width and aspect ratio rather than being
   cropped into a portrait card.
   ========================================================================== */
.vrail--wide{grid-auto-columns:clamp(260px,32vw,380px)}
.vrail--wide .vcard{aspect-ratio:16/9; border-radius:14px; clip-path:inset(0 round 14px)}
.vrail--wide .vcard__cap{
  padding:22px 14px 14px; text-align:left; font-size:.62rem;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.88));
}
/* On the testimonials page the same cards are the whole point of the page, so
   they stack into a 2-up grid at full size instead of a rail you have to
   scroll sideways. One column once there is no room for two. */
.vrail--grid{
  display:grid; grid-auto-flow:row; grid-template-columns:repeat(2,minmax(0,1fr));
  grid-auto-columns:auto; overflow:visible; padding-bottom:0;
  scroll-snap-type:none; gap:clamp(16px,2.2vw,26px);
}
.vrail--grid .vcard{scroll-snap-align:none}
.vrail--grid .vcard__cap{font-size:.68rem; padding:26px 18px 16px}
@media (max-width:760px){
  .vrail--grid{grid-template-columns:minmax(0,1fr)}
}

.vbox--wide .vbox__panel{width:min(1020px,94vw)}
.vbox--wide .vbox__stage{aspect-ratio:16/9; border-radius:14px}
.vbox--wide .vbox__stage iframe{object-fit:contain}

/* ==========================================================================
   Sources
   The report and the interview sit under the case study as things you can
   open, not as a second slideshow competing with the deck above them.
   ========================================================================== */
.srcs{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:clamp(14px,2vw,22px)}

/* The interview leads with a frame from the video itself rather than a text
   link, and the report card sits beside it keeping its open-in-place popup. */
.srcgrid{
  display:grid; grid-template-columns:minmax(0,1.45fr) minmax(0,.55fr);
  gap:clamp(14px,2vw,22px); align-items:stretch;
}
@media (max-width:860px){ .srcgrid{grid-template-columns:minmax(0,1fr)} }
/* the report card is shorter than the video beside it, so centre its contents
   rather than leaving them pinned to the top of a tall box */
.srcgrid .src{align-items:center}
.srcvid{
  position:relative; display:block; width:100%; padding:0; border:0; cursor:pointer;
  aspect-ratio:16/9; overflow:hidden; background:#0C0C0C; isolation:isolate;
  border:1px solid var(--line); color:#fff; text-align:left;
  transition:border-color .3s ease;
}
.srcvid img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform 1s var(--ease)}
.srcvid::after{content:""; position:absolute; inset:0; background:linear-gradient(180deg,rgba(0,0,0,.12) 30%,rgba(0,0,0,.86)); pointer-events:none}
.srcvid:hover{border-color:rgba(236,28,36,.6)}
.srcvid:hover img{transform:scale(1.04)}
.srcvid__play{
  position:absolute; left:50%; top:50%; translate:-50% -50%; z-index:2;
  width:clamp(54px,6vw,74px); height:clamp(54px,6vw,74px); border-radius:50%;
  background:var(--red); box-shadow:0 10px 34px -10px rgba(236,28,36,.9);
  transition:scale .25s ease;
}
.srcvid__play::before{
  content:""; position:absolute; left:54%; top:50%; translate:-50% -50%;
  border-style:solid; border-width:11px 0 11px 18px; border-color:transparent transparent transparent #fff;
}
.srcvid:hover .srcvid__play{scale:1.1}
.srcvid__meta{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:clamp(18px,2.2vw,26px); display:block;
}
.srcvid__meta b{
  display:block; font-family:var(--display); text-transform:uppercase;
  font-size:clamp(1rem,1.5vw,1.25rem); line-height:1.15;
}
.srcvid__meta span{
  display:block; margin-top:8px; max-width:46ch;
  color:rgba(255,255,255,.78); font-size:.88rem; line-height:1.5;
}
@media (max-width:560px){ .srcvid__meta span{display:none} }
.src{
  position:relative; display:flex; gap:16px; align-items:flex-start; text-align:left;
  width:100%; padding:clamp(20px,2.4vw,28px); cursor:pointer;
  background:#0C0C0C; border:1px solid var(--line); color:#fff;
  clip-path:polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition:background var(--t) var(--ease), border-color var(--t) var(--ease);
}
.src:hover{background:#121212; border-color:rgba(236,28,36,.5)}
.src__ico{flex:none; width:38px; height:38px; display:grid; place-items:center; background:var(--red)}
.src__ico svg{width:19px; height:19px; fill:none; stroke:#fff; stroke-width:2}
.src__body h3{font-family:var(--display); text-transform:uppercase; font-size:.98rem; line-height:1.15}
.src__body p{margin-top:8px; color:var(--grey); font-size:.9rem; line-height:1.5}
.src__go{
  display:inline-flex; align-items:center; gap:.5em; margin-top:14px;
  font-size:.62rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:var(--red);
  transition:gap var(--t) var(--ease);
}
.src__go::after{content:"\2192"}
.src:hover .src__go{gap:.9em}

/* ==========================================================================
   Document popup
   A scrollable read of a supporting document. Deliberately plainer than the
   deck so it reads as a source you can check, not a second presentation.
   ========================================================================== */
.docbox{position:fixed; inset:0; z-index:210; display:grid; place-items:center; padding:clamp(14px,3vw,32px)}
.docbox[hidden]{display:none}
.docbox__scrim{position:absolute; inset:0; background:rgba(0,0,0,.88); backdrop-filter:blur(6px); animation:vfade .3s ease both}
.docbox__panel{
  position:relative; z-index:1; display:flex; flex-direction:column;
  /* an explicit height, not just a cap: the page images are lazy, so a
     content-sized panel opens as a sliver and then jumps once they land.
     Width is 100% rather than a vw figure so it stays inside the wrapper's
     own padding instead of overflowing it on a phone. */
  width:min(760px,100%); height:min(88vh,1000px); max-height:min(88vh,1000px);
  background:var(--ink); border:1px solid var(--line);
  box-shadow:0 30px 90px -20px rgba(0,0,0,.9);
  animation:vpop .4s cubic-bezier(.22,1,.36,1) both;
}
.docbox__head{
  flex:none; display:flex; align-items:center; gap:16px;
  padding:clamp(16px,2vw,22px) clamp(18px,2.4vw,26px);
  border-bottom:1px solid var(--line); background:#0C0C0C;
}
.docbox__head h3{
  flex:1; min-width:0; font-family:var(--display); text-transform:uppercase;
  font-size:clamp(.72rem,2.4vw,.92rem); line-height:1.2;
}
.docbox__dl{
  flex:none; font-size:.6rem; font-weight:700; letter-spacing:.18em; white-space:nowrap;
  text-transform:uppercase; color:var(--grey); transition:color var(--t) var(--ease);
}
.docbox__dl:hover{color:var(--red)}
@media (max-width:520px){
  .docbox__head{gap:10px}
  .docbox__dl{letter-spacing:.1em; font-size:.55rem}
}
.docbox__x{
  flex:none; width:34px; height:34px; background:none; border:0; color:#fff;
  font-size:1.7rem; line-height:1; cursor:pointer; transition:color .2s, transform .2s;
}
.docbox__x:hover{color:var(--red); transform:scale(1.1)}
.docbox__pages{
  flex:1; min-height:0;
  overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch;
  padding:clamp(14px,2vw,20px); display:grid; gap:clamp(12px,1.6vw,18px);
  /* an auto grid track sizes to the page image's intrinsic width (1400px) and
     blows the panel out sideways on a phone. Pin the column instead. */
  grid-template-columns:minmax(0,1fr);
  align-content:start; background:#080808;
}
/* the ratio is set per document on the trigger, so a lazy page still holds
   its slot and the scroll position does not jump as they load */
.docbox__pages img{
  display:block; width:100%; max-width:100%; height:auto; border:1px solid var(--line);
  aspect-ratio:var(--page-ratio,1400/1812); object-fit:contain; background:#111;
}
.docbox__pages::-webkit-scrollbar{width:8px}
.docbox__pages::-webkit-scrollbar-thumb{background:rgba(236,28,36,.5)}

/* ---------- Case study hero ----------
   The deck's own title lives in the standard page hero, so the ring, the wash
   and the height all behave exactly as they do on every other inner page. The
   full-screen control rides on the right of the title. */
.phero__in--row{
  max-width:none; display:flex; align-items:flex-end; justify-content:space-between; gap:20px;
}
.phero__in--row .phero__h1{max-width:none}

/* ---------- Case study page rhythm ----------
   The deck does the talking, so the sections around it sit closer together
   than the rest of the site. */
.cs-page{--sec-y:clamp(48px,5.4vw,86px)}
.cs-page .sechead{margin-bottom:clamp(28px,3.4vw,44px)}
.cs-page .sec--tighttop{padding-top:clamp(18px,2.2vw,30px)}
.cs-page .sec--tightbot{padding-bottom:clamp(26px,3vw,40px)}

/* ---------- Post-deck CTA ---------- */
.deckcta{
  display:grid; grid-template-columns:1.35fr .65fr; gap:clamp(24px,4vw,54px);
  align-items:center; padding:clamp(26px,3.6vw,44px);
  border:1px solid var(--line); background:rgba(255,255,255,.02);
  border-left:3px solid var(--red);
}
.deckcta__h{
  font-family:var(--display); text-transform:uppercase; line-height:.98;
  font-size:clamp(1.5rem,3.3vw,2.5rem); margin:14px 0 0;
}
.deckcta__p{margin-top:14px; color:var(--grey); max-width:52ch}
.deckcta__act{display:flex; flex-direction:column; gap:12px}
.deckcta__act .btn{justify-content:center; text-align:center}
@media (max-width:860px){
  .deckcta{grid-template-columns:1fr}
  .deckcta__act{flex-direction:row; flex-wrap:wrap}
}

/* ---------- Deck full-screen viewer ----------
   A zoom that stays out of the way: fit to the screen by default, one toggle
   to 2x, then the stage scrolls. ---- */
.deck__zoom{
  flex:none; display:inline-grid; place-items:center; width:44px; height:44px;
  background:transparent; color:var(--grey); cursor:pointer; border:1px solid var(--line);
}
.deck__zoom:hover{color:#fff; border-color:var(--red)}
.deck__zoom svg{width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:2.2}
/* header row: title on the left, the full-screen control on the right */


.slidebox{position:fixed; inset:0; z-index:220; display:flex}
.slidebox[hidden]{display:none}
.slidebox__scrim{position:absolute; inset:0; background:#000}
.slidebox__panel{
  position:relative; z-index:1; display:flex; flex-direction:column;
  width:100%; height:100%; padding:10px clamp(10px,2vw,26px) 14px;
}
.slidebox__bar{display:flex; align-items:center; gap:12px; padding:6px 2px 10px}
.slidebox__count{
  color:var(--grey); font-size:.78rem; letter-spacing:.1em; text-transform:uppercase; flex:1;
}
.slidebox__zoom{
  padding:8px 14px; background:var(--red); color:#fff; border:0; cursor:pointer;
  font:inherit; font-size:.78rem; text-transform:uppercase; letter-spacing:.08em;
}
.slidebox__x{
  width:38px; height:38px; background:transparent; color:#fff; cursor:pointer;
  border:1px solid var(--line); font-size:1.4rem; line-height:1;
}
.slidebox__x:hover{border-color:var(--red)}
.slidebox__stage{
  flex:1; min-height:0; overflow:auto; display:grid; place-items:center;
  overscroll-behavior:contain; cursor:zoom-in;
}
.slidebox__stage img{
  display:block; max-width:100%; max-height:100%; width:auto; height:auto;
}
.slidebox.is-zoom .slidebox__stage{place-items:start; cursor:grab}
.slidebox.is-zoom .slidebox__stage img{max-width:none; max-height:none; width:220%}
.slidebox.is-drag .slidebox__stage{cursor:grabbing}
.slidebox__nav{display:flex; justify-content:center; gap:14px; padding-top:12px}
/* on desktop the slide already fits the screen, so zoom is mobile-only */
@media (min-width:761px){
  .slidebox__zoom{display:none}
  .slidebox__stage{cursor:default}
}
@media (max-width:600px){
  .slidebox.is-zoom .slidebox__stage img{width:300%}
}
