/* ==========================================================================
   MG LUMEO DIGITAL — Homepage
   ========================================================================== */

/* Brand display typeface — LEMON MILK Pro (self-hosted) */
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-UltraLight.otf") format("opentype"); font-weight: 200; font-style: normal; font-display: swap; }
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-UltraLightItalic.otf") format("opentype"); font-weight: 200; font-style: italic; font-display: swap; }
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-Regular.otf") format("opentype"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-RegularItalic.otf") format("opentype"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-Medium.otf") format("opentype"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-MediumItalic.otf") format("opentype"); font-weight: 500; font-style: italic; font-display: swap; }
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-Bold.otf") format("opentype"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "LEMON MILK Pro"; src: url("../fonts/LEMONMILKPro-BoldItalic.otf") format("opentype"); font-weight: 700; font-style: italic; font-display: swap; }

:root {
  --black: #0d0c0a;
  --ink:   #161412;
  --paper: #faf9f6;
  --gray:  #efede7;
  --gray-2:#e7e4dc;

  --text:      #181612;
  --text-body: #4d4943;
  --text-mute: #8c867c;

  --w-100: #faf9f6;
  --w-70:  rgba(250, 249, 246, 0.72);
  --w-45:  rgba(250, 249, 246, 0.45);

  --line:      rgba(24, 22, 18, 0.14);
  --line-soft: rgba(24, 22, 18, 0.08);
  --line-dark: rgba(250, 249, 246, 0.16);

  --bronze: #b08c60;

  /* brand display font (named --serif for legacy; now the LEMON MILK geometric) */
  --serif: "LEMON MILK Pro", "Helvetica Neue", Arial, sans-serif;
  --sans: "Inter", system-ui, -apple-system, sans-serif;

  --ease: cubic-bezier(0.22, 0.61, 0.21, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.15, 1);

  --shell: 1560px;
  --header-h: 108px;   /* CardNav (68) + contact topbar (~34) + float gap */
  --gutter: clamp(20px, 2.8vw, 32px); /* site-wide left/right page gutter (one source of truth) */
  --hero-top-gap: clamp(18px, 2.2vw, 32px); /* breathing room below the navbar before the hero grid + headline */

  /* ---- fluid spacing scale (one source of truth for vertical rhythm) ----
     rem-based so it survives browser zoom; endpoints snapped near the 8-pt grid.
     Replaces the ~19 one-off clamp()s sections used to hard-code. */
  --space-2xs: clamp(0.5rem, 0.45rem + 0.25vw, 0.75rem);   /*  8–12 */
  --space-xs:  clamp(0.75rem, 0.65rem + 0.4vw, 1rem);      /* 12–16 */
  --space-s:   clamp(1rem, 0.85rem + 0.6vw, 1.5rem);       /* 16–24 */
  --space-m:   clamp(1.5rem, 1.3rem + 1vw, 2rem);          /* 24–32 */
  --space-l:   clamp(2rem, 1.6rem + 1.8vw, 3rem);          /* 32–48 */
  --space-xl:  clamp(2.5rem, 2rem + 2.4vw, 4rem);          /* 40–64 */
  /* section rhythm: every full section's top & bottom (symmetric) */
  --section-y:       clamp(3rem, 2.3rem + 3vw, 4.25rem);   /* 48–68 */
  --section-y-tight: clamp(2.25rem, 1.85rem + 1.8vw, 3.25rem); /* 36–52: page-heads */
  --head-gap:        var(--space-xl);                      /* a section heading → its grid/content */
}

/* ---------- Base ---------- */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* fluid root: 16px up to ~1280px (mobile/tablet untouched), ramping to 18px by
   ~1680px so all rem-based type + spacing scales up on the now-wider desktop. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; font-size: clamp(1rem, 0.6rem + 0.5vw, 1.125rem); }

body {
  font-family: var(--sans);
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--text-body);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.preloading, body.menu-open { overflow: hidden; }

img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible { outline: 1.5px solid var(--bronze); outline-offset: 3px; }

::selection { background: #e4d4c0; color: var(--black); }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.shell--narrow { max-width: 880px; }

section { scroll-margin-top: var(--header-h); }

/* ── Section rhythm ───────────────────────────────────────────────────────────
   One uniform vertical band per full section via --section-y (replaces the old
   per-section clamp()s — those declarations are now overridden by this). Kept as
   deliberate exceptions: the hero & page-heads carry the fixed-header clearance,
   the home CTA is a full-bleed dark plate (its inner pads the content), and the
   "Grow" feature stays tucked beneath "Build". */
.view > section { padding-block: var(--section-y); }
.view > .hero { padding-top: 0; }                       /* .hero__intro carries the header offset */
.view > .pagehead {
  padding-top: calc(var(--header-h) + var(--space-l));
  padding-bottom: var(--section-y-tight);
}
.view > .cta { padding-block: 0; }
.view > .feature--flip { padding-top: var(--space-l); } /* "Grow" tucks under "Build" */

.icon {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  flex: none;
}

.skip-link {
  position: fixed; top: 10px; left: 10px; z-index: 10001;
  padding: 8px 14px; background: var(--black); color: var(--paper);
  font-size: 0.75rem; transform: translateY(-300%);
  transition: transform 0.25s var(--ease);
}
.skip-link:focus-visible { transform: none; }

/* ---------- Type ---------- */

h1, h2, h3 { font-weight: 400; }

em { font-style: normal; }

/* Section header — a hairline rule carrying the section title on the left and an
   optional action link on the right. Same treatment on every page. */
.sectag {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 16px;
}
.sectag:empty { display: none; }
.sectag__title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.05rem, 1.7vw, 1.45rem);
  line-height: 1.1;
  letter-spacing: 0;
  color: var(--text);
}
/* when a header has only the title (no action link), keep it left-aligned */
.sectag:not(:has(.sectag__btn)) { justify-content: flex-start; }

/* Tertiary action — a plain underlined text link. The custom cursor handles
   the hover affordance now, so no sliding arrow. Used for View all / Learn more. */
.sectag__btn {
  flex: none;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-body);
  text-decoration: underline;
  text-decoration-color: currentColor;   /* always underlined */
  text-underline-offset: 4px;
  transition: color 0.25s var(--ease);
}
.sectag__btn:hover, .sectag__btn:focus-visible { color: var(--text); }

.tlink {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--text);
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: border-color 0.25s var(--ease), color 0.25s;
}
.tlink:hover { border-bottom-color: var(--text); }
.tlink span { transition: transform 0.25s var(--ease); }
.tlink:hover span { transform: translateX(3px); }

/* Site button system — ONE box used everywhere: a white box with a thin border
   and a small "+" crosshair on each corner. The two tiers differ only by the
   colour that fills it on hover:
     .gbtn--primary   : white → brand gold
     .gbtn--secondary : white → black
   ::before = the fill that rises from the bottom; ::after = the four + marks.
   Tertiary actions (View all / Learn more …) use .sectag__btn. */
.gbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.9375rem 2.125rem; /* rem so the button scales with the fluid root (=15px/34px at 16px root) */
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  overflow: visible;            /* let the corner + marks straddle the edges */
  isolation: isolate;
  background-color: #fff;        /* both tiers: solid white fill at rest */
  color: var(--ink);
  border: 1px solid #c2bcb2;     /* the box outline */
  transition: color 0.35s var(--ease);
}
.gbtn::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;    /* behind the label, inside the border */
  background: var(--gfill);
  transform: scaleY(0);                          /* rises up from the bottom on hover */
  transform-origin: bottom;
  transition: transform 0.5s var(--ease);
}
.gbtn:hover::before, .gbtn:focus-visible::before { transform: scaleY(1); }

/* the four corner "+" crosshairs — eight thin bars drawn in one layer, tinted
   from the current text colour so they track the hover colour change */
/* a small "+" crosshair centred on each corner — straddles the corner so it sits
   on the border. A fixed grey (not the text colour) keeps the marks visible over
   the page, the box and the colour fill, so they don't vanish on hover. */
.gbtn::after {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--over));   /* small overhang so the + can straddle the corner */
  z-index: 1;                      /* above the fill, so the marks survive the hover */
  pointer-events: none;
  --pc: #b3aca0; --arm: 5px; --thick: 1px; --over: 4px;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(var(--pc) 0 0), linear-gradient(var(--pc) 0 0),
    linear-gradient(var(--pc) 0 0), linear-gradient(var(--pc) 0 0),
    linear-gradient(var(--pc) 0 0), linear-gradient(var(--pc) 0 0),
    linear-gradient(var(--pc) 0 0), linear-gradient(var(--pc) 0 0);
  background-size:
    var(--arm) var(--thick), var(--thick) var(--arm),
    var(--arm) var(--thick), var(--thick) var(--arm),
    var(--arm) var(--thick), var(--thick) var(--arm),
    var(--arm) var(--thick), var(--thick) var(--arm);
  background-position:
    left  calc(var(--over) - var(--arm) / 2)   top    calc(var(--over) - var(--thick) / 2),
    left  calc(var(--over) - var(--thick) / 2) top    calc(var(--over) - var(--arm) / 2),
    right calc(var(--over) - var(--arm) / 2)   top    calc(var(--over) - var(--thick) / 2),
    right calc(var(--over) - var(--thick) / 2) top    calc(var(--over) - var(--arm) / 2),
    left  calc(var(--over) - var(--arm) / 2)   bottom calc(var(--over) - var(--thick) / 2),
    left  calc(var(--over) - var(--thick) / 2) bottom calc(var(--over) - var(--arm) / 2),
    right calc(var(--over) - var(--arm) / 2)   bottom calc(var(--over) - var(--thick) / 2),
    right calc(var(--over) - var(--thick) / 2) bottom calc(var(--over) - var(--arm) / 2);
}
.gbtn__label { position: relative; z-index: 1; }

.gbtn--primary   { --gfill: var(--bronze); }   /* white → brand gold on hover */
.gbtn--secondary { --gfill: var(--black); }    /* white → black on hover */
/* label turns white on hover so it reads over the colour fill (gold or black) */
.gbtn--primary:hover, .gbtn--primary:focus-visible,
.gbtn--secondary:hover, .gbtn--secondary:focus-visible { color: var(--w-100); }

/* ==========================================================================
   PRELOADER
   ========================================================================== */

.preloader {
  position: fixed; inset: 0; z-index: 10000;
  display: grid; place-items: center;
  cursor: pointer;
}
.preloader__backdrop {
  position: absolute; inset: 0;
  background: var(--black);
  transition: opacity 0.5s ease 0.3s;
}
.preloader__stage { position: relative; display: grid; place-items: center; }

.shutter {
  width: min(40vmin, 320px);
  height: min(40vmin, 320px);
  overflow: visible;
  transform-origin: 50% 50%;
  will-change: transform, opacity;
}
.shutter__plate { fill: var(--black); }
.shutter__ring { fill: none; stroke: rgba(250, 249, 246, 0.14); stroke-width: 1.25; }
.shutter__assembly path {
  fill: #d9d5cb;
  stroke: rgba(13, 12, 10, 0.42);
  stroke-width: 1;
}

.preloader__brand {
  position: absolute;
  top: calc(100% + 30px);
  display: grid;
  justify-items: center;
  gap: 6px;
  opacity: 0;
  animation: brandIn 0.9s var(--ease) 0.35s forwards;
  transition: opacity 0.3s ease;
}
@keyframes brandIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.preloader__name {
  font-family: var(--serif);
  font-size: 1.25rem;
  color: var(--w-100);
}
.preloader__sub {
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--w-45);
}

.preloader.is-opening { cursor: default; pointer-events: none; }
.preloader.is-opening .preloader__backdrop { opacity: 0; }
.preloader.is-opening .preloader__brand { opacity: 0; }
.preloader.is-opening .shutter {
  transform: scale(26);
  opacity: 0;
  transition: transform 1.15s var(--ease-io) 0.42s, opacity 0.3s ease 1.1s;
}
.preloader.is-done { display: none; }

/* ==========================================================================
   HEADER
   ========================================================================== */

.header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
  padding-top: clamp(8px, 1.2vw, 12px);   /* let the CardNav box float just under the top */
  transform: translateY(-100%);
  transition: transform 0.55s var(--ease), background-color 0.3s var(--ease),
              border-color 0.3s var(--ease);
}
body.loaded .header { transform: none; }

/* ---- Top contact / announcement bar — sits directly on the CardNav, one thin
   line between them. Muted contact details on the left (single line), green
   "WhatsApp us" pill on the right. ---- */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  height: 34px; padding: 0 16px;
  background: #100d0a;                                  /* near-black, a hair off the nav so it isn't a tonal gap */
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);  /* single subtle-white stroke divider */
  font-size: 0.78rem;
}
.topbar__contacts { display: flex; align-items: center; gap: 22px; min-width: 0; }
.topbar__item {
  display: inline-flex; align-items: center; gap: 7px;
  color: rgba(250, 249, 246, 0.66); white-space: nowrap;
  transition: color 0.25s var(--ease);
}
a.topbar__item:hover, a.topbar__item:focus-visible { color: var(--w-100); }
.topbar__ic { width: 14px; height: 14px; flex: none; fill: rgba(250, 249, 246, 0.5); transition: fill 0.25s var(--ease); }
a.topbar__item:hover .topbar__ic { fill: var(--bronze); }
.topbar__item--addr { min-width: 0; }
.topbar__item--addr span { overflow: hidden; text-overflow: ellipsis; }
.topbar__wa {                            /* no pill — just the green mark + label */
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  color: #25d366; font-weight: 600; letter-spacing: 0.01em;
  transition: opacity 0.25s var(--ease);
}
.topbar__wa:hover, .topbar__wa:focus-visible { opacity: 0.78; }
.topbar__wa-ic { width: 15px; height: 15px; flex: none; fill: #25d366; }
@media (max-width: 1024px) { .topbar__item--addr { display: none; } }
@media (max-width: 680px) {
  .topbar { padding: 0 12px; font-size: 0.72rem; }
  .topbar__item[href^="mailto"] { display: none; }     /* keep phone + WhatsApp */
}

/* Dim scrim shown behind the CardNav while it's expanded — darkens the page so
   the open menu reads as a focused layer. Sits below the header (z 1000) and
   above all page content; clicking it closes the nav (wired in main.js). */
.nav-scrim {
  position: fixed; inset: 0; z-index: 999;
  background: rgba(13, 12, 10, 0.42);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.45s var(--ease), visibility 0s 0.45s;
}
.nav-scrim.is-on {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity 0.45s var(--ease);
}

.header__inner {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--header-h);
}

.brand { display: inline-flex; align-items: center; gap: 9px; }
.brand__mark { width: 26px; height: auto; display: block; }
.brand__blades path { fill: #d9d5cb; stroke: rgba(13, 12, 10, 0.4); stroke-width: 1.4; }

.brand__name {
  font-family: var(--serif); /* brand wordmark in LEMON MILK, matching the logo */
  font-size: 0.9rem; font-weight: 500; letter-spacing: 0.02em;
  color: var(--text);
}
.brand__sub { font-weight: 400; color: var(--text-mute); }

/* ---- CardNav (React Bits "CardNav", ported & restyled to our boxy look) ----
   A sharp-edged white box wearing the same "+" corner marks as the buttons; the
   burger expands it downward to reveal dark nav cards. The CTA reuses .gbtn and
   the card links use the underlined tertiary style. JS (GSAP) runs the expand. */
.card-nav {
  --nav-h: 68px;
  position: relative;
  height: var(--nav-h);
  background: var(--black);                    /* dark nav by default */
  border: 1px solid rgba(255, 255, 255, 0.12); /* sharp box, faint edge */
  border-top: 0;                               /* topbar's bottom border is the seam */
  overflow: visible;                           /* content clips itself */
  will-change: height;
}
.card-nav__bar {
  position: absolute; top: 0; left: 0; right: 0;
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 14px 0 18px;
  z-index: 2;
}
.card-nav__burger {                  /* padded so the cursor target has breathing room */
  display: inline-flex; flex-direction: column; justify-content: center; gap: 6px;
  padding: 8px; margin-left: 4px;
  background: none; border: none; cursor: pointer; color: var(--w-100);
}
.card-nav__line {
  width: 24px; height: 2px; background: currentColor; transform-origin: center;
  transition: transform 0.3s var(--ease), opacity 0.2s var(--ease);
}
.card-nav.is-open .card-nav__line:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.card-nav.is-open .card-nav__line:nth-child(2) { opacity: 0; }
.card-nav.is-open .card-nav__line:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* logo — light mark + "MG LUMEO" wordmark sitting directly on the dark nav (no box).
   While scrolling the wordmark collapses away; the centered group then shrinks to
   just the mark, sliding it to true centre, and the mark spins subtly. */
.card-nav__logo {
  display: inline-flex; align-items: center;   /* sits at the left end of the bar */
  flex: none;
}
.card-nav__logo img { height: 38px; width: auto; object-fit: contain; transition: transform 0.75s var(--ease); }
/* the mark spins only on mobile; on desktop the logo stays static (per request) */
@media (max-width: 860px) {
  .card-nav__logo:hover img, .card-nav__logo:focus-visible img,
  .card-nav.nav-scrolling .card-nav__logo img { transform: rotate(360deg); }
}
.card-nav__logo-text {
  margin-left: 12px; max-width: 170px; overflow: hidden;
  font-family: var(--serif); font-size: 1.2rem; font-weight: 500;
  letter-spacing: 0.13em; color: var(--w-100); white-space: nowrap;
  transition: max-width 0.5s var(--ease), opacity 0.4s var(--ease),
              margin-left 0.5s var(--ease), transform 0.5s var(--ease);
}
/* left-aligned layout keeps the wordmark put while scrolling (collapsing it
   would shove the inline links sideways); only the mark still spins. */
.card-nav.nav-scrolling .card-nav__logo-text {
  max-width: 170px; opacity: 1; margin-left: 12px; transform: none;
}

/* CTA reuses the primary button, sized to the bar */
.card-nav__cta { padding: 13px 26px; }

/* ---- desktop inline nav: logo left, link tabs in the middle, CTA + (mobile)
   burger on the right. Only Services carries a hover dropdown; About Us, Our
   Work and Connect are plain links. The expanding menu is mobile-only. ---- */
.card-nav__links {
  display: flex; align-items: stretch; height: 100%;
  gap: clamp(0.3rem, 1.4vw, 1.5rem);
}
.navlink {
  position: relative; display: inline-flex; align-items: center; gap: 6px; height: 100%;
  padding: 0 6px;
  color: rgba(250, 249, 246, 0.82); font-size: 0.92rem; font-weight: 500;
  letter-spacing: 0.01em; white-space: nowrap;
  transition: color 0.25s var(--ease);
}
.navlink::after {                       /* bronze underline that grows in on hover */
  content: ""; position: absolute; left: 6px; right: 6px; bottom: calc(50% - 0.85em);
  height: 1.5px; background: var(--bronze);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.3s var(--ease);
}
.navlink:hover, .navlink:focus-visible { color: var(--w-100); }
.navlink:hover::after, .navlink-wrap:hover .navlink--menu::after,
.navlink-wrap:focus-within .navlink--menu::after { transform: scaleX(1); }
.navlink__caret { width: 9px; height: 6px; margin-top: 1px; color: currentColor; transition: transform 0.3s var(--ease); }
.navlink-wrap { position: relative; display: inline-flex; height: 100%; }
.navlink-wrap:hover .navlink__caret, .navlink-wrap:focus-within .navlink__caret { transform: rotate(180deg); }

/* Services dropdown — slides + fades down from the bar on hover/focus */
.navdrop {
  position: absolute; top: 100%; left: 50%;
  transform: translateX(-50%) translateY(9px);
  min-width: 230px; padding: 7px;
  background: #1b1916; border: 1px solid rgba(255, 255, 255, 0.13);
  box-shadow: 0 20px 44px -14px rgba(0, 0, 0, 0.55);
  display: flex; flex-direction: column; gap: 2px;
  opacity: 0; visibility: hidden;
  transition: opacity 0.26s var(--ease), transform 0.26s var(--ease), visibility 0s 0.26s;
  z-index: 5;
}
.navlink-wrap:hover .navdrop, .navlink-wrap:focus-within .navdrop {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
  transition: opacity 0.26s var(--ease), transform 0.26s var(--ease), visibility 0s 0s;
}
.navdrop__link {
  display: block; padding: 9px 14px;
  color: rgba(250, 249, 246, 0.76); font-size: 0.9rem; white-space: nowrap;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}
.navdrop__link:hover, .navdrop__link:focus-visible { background: rgba(255, 255, 255, 0.07); color: var(--w-100); }

.card-nav__right { display: inline-flex; align-items: center; gap: 12px; flex: none; }
.card-nav__burger { display: none; }    /* desktop: the inline links replace the menu */
.card-nav__content { display: none; }   /* the expanding menu is mobile-only */

@media (max-width: 860px) {
  .card-nav__links { display: none; }
  .card-nav__burger { display: inline-flex; }
  .card-nav__content { display: flex; }
}

/* expanded content — dark cards the box reveals */
.card-nav__content {
  position: absolute; left: 0; right: 0; top: var(--nav-h); bottom: 0;
  display: flex; gap: 8px; padding: 8px;
  overflow: hidden;                 /* clips the cards while the box is collapsed */
  z-index: 1;
}
.nav-card {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; gap: 8px;
  padding: 16px 18px;
  background: var(--ink); color: var(--w-100);    /* sharp dark cards, no radius */
}
/* box title is now a clickable link (page route) with the same underline-on-hover
   tell as the sub-links, just larger. */
.nav-card__title {
  width: fit-content;
  font-family: var(--serif); font-size: 1.3rem; letter-spacing: -0.01em; color: var(--w-100);
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  transition: text-decoration-color 0.25s var(--ease), color 0.25s var(--ease);
}
.nav-card__title:hover, .nav-card__title:focus-visible, .nav-card__title.is-active {
  text-decoration-color: currentColor;
}
.nav-card__links { margin-top: auto; display: flex; flex-direction: column; gap: 5px; }
.nav-card__link {
  width: fit-content; font-size: 0.85rem; color: var(--w-70);
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px;
  transition: color 0.25s var(--ease), text-decoration-color 0.25s var(--ease);
}
.nav-card__link:hover, .nav-card__link:focus-visible, .nav-card__link.is-active {
  color: var(--w-100); text-decoration-color: currentColor;
}

.header.scrolled { background: transparent; }

@media (max-width: 720px) {
  .card-nav__cta { display: none; }
  .card-nav__content { flex-direction: column; gap: 6px; align-items: stretch; }
  .nav-card { padding: 12px 14px; }
}

/* ==========================================================================
   HERO — flip-words headline, floating elements, brand video
   ========================================================================== */

.hero {
  position: relative;
  background: var(--paper);
  overflow: clip;
  padding-bottom: clamp(3rem, 6vw, 5.5rem);
}
/* warm wash that frames the hero from the top and the left/right ends and fades
   to a clean centre. Two layers breathe on offset cycles so the glow at the ends
   feels alive rather than static. Sits in the backdrop, behind grid + headline. */
.hero::before, .hero::after {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none;
}
.hero::before {
  background:
    radial-gradient(95% 80% at 50% -16%, rgba(176, 140, 96, 0.34), transparent 64%),   /* top */
    radial-gradient(46% 95% at -9% 34%, rgba(176, 140, 96, 0.30), transparent 60%),     /* left end */
    radial-gradient(46% 95% at 109% 34%, rgba(176, 140, 96, 0.30), transparent 60%);    /* right end */
  animation: heroGlow 6s ease-in-out infinite alternate;
}
.hero::after {                 /* offset accent so the ends don't pulse in lockstep */
  background:
    radial-gradient(66% 56% at 50% -10%, rgba(201, 165, 112, 0.24), transparent 58%),
    radial-gradient(40% 80% at -5% 18%, rgba(201, 165, 112, 0.20), transparent 56%),
    radial-gradient(40% 80% at 105% 50%, rgba(201, 165, 112, 0.20), transparent 56%);
  animation: heroGlow2 7.5s ease-in-out infinite alternate;
}
@keyframes heroGlow {
  from { opacity: 0.6; transform: scale(1); }
  to   { opacity: 1; transform: scale(1.06); }
}
@keyframes heroGlow2 {
  from { opacity: 0.48; transform: scale(1.06); }
  to   { opacity: 0.92; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .hero::before, .hero::after { animation: none; opacity: 1; transform: none; }
}

/* ---- Dark hero on load, crossfading to the light theme once the About headline
   nears (~past the video). main.js toggles body.hero-dark from the scroll
   position of #about; the colours below transition so it reads as a fade. ---- */
body { transition: background-color 0.8s var(--ease); }
.hero { transition: background-color 0.8s var(--ease); }
.hero__title, .hero__lede { transition: color 0.8s var(--ease); }
.hero__path { transition: border-color 0.25s var(--ease), color 0.8s var(--ease); }
.hbox, .hbox-strip { transition: border-color 0.8s var(--ease), background-color 1.8s ease; }

body.hero-dark { background: var(--black); }
body.hero-dark .hero { background: var(--black); }
body.hero-dark .hero__title { color: var(--w-100); }
body.hero-dark .hero__lede { color: rgba(250, 249, 246, 0.74); }
body.hero-dark .hero__path { color: var(--w-100); }
body.hero-dark .hbox-strip { border-left-color: rgba(255, 255, 255, 0.08); }
body.hero-dark .hbox { border-right-color: rgba(255, 255, 255, 0.08); border-top-color: rgba(255, 255, 255, 0.08); }
body.hero-dark .hbox--plus::before, body.hero-dark .hbox--plus::after { background: rgba(255, 255, 255, 0.16); }
/* white cursor over the dark hero (its data-cursor-solid="dark" otherwise forces ink) */
body.hero-dark .target-cursor-wrapper.is-dark { --cur: var(--w-100); }
/* the aurora light leads the dark to light handoff: held back while dark, fades in
   first; the About headline then writes on a beat later */
.aurora { transition: opacity 0.9s var(--ease); }
body.hero-dark .aurora { opacity: 0; }
.statement__title.split-reveal.sr-in .sr-char { transition-delay: calc(0.4s + var(--ci, 0) * 0.02s); }

/* ---- Digital partners — seamless flowing logo marquee. Two equal groups, each
   at least the container width, loop in lockstep so the strip never opens a gap
   (the gap between the copies matches the gap between logos). ---- */
.partners { padding-block: clamp(2.6rem, 5vw, 4.2rem); overflow: hidden; }
.partners__label {
  text-align: center; margin-bottom: clamp(1.8rem, 3.2vw, 2.6rem);
  font-size: 0.78rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--text-mute);
}
.marquee {
  --mg: clamp(4.5rem, 9vw, 10rem);          /* gap between logos AND between the looping copies */
  display: flex; overflow: hidden; gap: var(--mg);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee__group {
  flex: none; display: flex; align-items: flex-start; justify-content: space-around;
  gap: var(--mg); min-width: 100%; margin: 0; padding: 0; list-style: none;
  animation: marquee 22s linear infinite;
}
.marquee:hover .marquee__group { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(calc(-100% - var(--mg))); } }
.partners__logo { display: inline-flex; flex-direction: column; align-items: center; gap: 11px; flex: none; }
.partners__logo img {
  height: clamp(24px, 3vw, 31px); width: auto; display: block;
  opacity: 0.72; transition: opacity 0.3s var(--ease);
}
.partners__name {
  font-size: 0.72rem; letter-spacing: 0.04em; white-space: nowrap;
  color: var(--text-mute); transition: color 0.3s var(--ease);
}
.partners__logo:hover img { opacity: 1; }
.partners__logo:hover .partners__name { color: var(--text-body); }
@media (prefers-reduced-motion: reduce) { .marquee__group { animation: none; } }

/* ---- floating contact button (bottom-right). The trigger reuses the .gbtn boxy
   button (white box, "+" corner marks, bronze fill on hover); the dropup menu
   mirrors the navbar's Services dropdown (dark box, light links). ---- */
.chatfab {
  position: fixed; right: clamp(16px, 2.6vw, 30px); bottom: clamp(16px, 2.6vw, 30px);
  z-index: 950; display: flex; flex-direction: column; align-items: flex-end; gap: 12px;
}
.chatfab__menu {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 196px; padding: 7px;
  background: #1b1916; border: 1px solid rgba(255, 255, 255, 0.13);
  box-shadow: 0 20px 44px -14px rgba(0, 0, 0, 0.55);
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transform-origin: bottom right;
  transition: opacity 0.26s var(--ease), transform 0.26s var(--ease), visibility 0s 0.26s;
}
.chatfab.is-open .chatfab__menu {
  opacity: 1; visibility: visible; transform: translateY(0);
  transition: opacity 0.26s var(--ease), transform 0.26s var(--ease), visibility 0s 0s;
}
.chatfab__opt {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 14px;
  color: rgba(250, 249, 246, 0.76); font-size: 0.9rem; white-space: nowrap;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}
.chatfab__opt:hover, .chatfab__opt:focus-visible { background: rgba(255, 255, 255, 0.07); color: var(--w-100); }
.chatfab__ic { display: inline-flex; align-items: center; flex: none; }
.chatfab__ic svg { width: 17px; height: 17px; }
.chatfab__opt--wa .chatfab__ic svg { fill: #25d366; }
.chatfab__opt--mail .chatfab__ic svg, .chatfab__opt--phone .chatfab__ic svg { fill: var(--bronze); }
.chatfab__btn { padding: 0; width: 54px; height: 54px; }
.chatfab__btn-ic {
  position: absolute; inset: 0; z-index: 1;
  display: grid; place-items: center;
  transition: opacity 0.25s var(--ease), transform 0.35s var(--ease);
}
.chatfab__btn-ic svg { width: 23px; height: 23px; fill: currentColor; }
.chatfab__btn-ic--close { opacity: 0; transform: rotate(-90deg) scale(0.8); }
.chatfab.is-open .chatfab__btn-ic--chat { opacity: 0; transform: rotate(90deg) scale(0.8); }
.chatfab.is-open .chatfab__btn-ic--close { opacity: 1; transform: none; }

/* ---- Project modal — split zoomable image viewer + details sidebar,
   over a dark backdrop, opened from any .workpiece card ---- */
html.pmodal-lock { overflow: hidden; }
.pmodal {
  position: fixed; inset: 0; z-index: 1100;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(12px, 3vw, 40px);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.32s var(--ease), visibility 0s 0.32s;
}
.pmodal.is-open { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity 0.32s var(--ease); }
.pmodal__backdrop {
  position: absolute; inset: 0;
  background: rgba(11, 10, 8, 0.88);
}
.pmodal__dialog {
  position: relative; z-index: 1;
  display: flex; overflow: hidden;
  width: min(1180px, 100%); height: min(86vh, 820px); max-height: 100%;
  background: var(--paper);
  box-shadow: 0 40px 120px -30px rgba(0, 0, 0, 0.72);
  transform: translateY(16px) scale(0.985);
  transition: transform 0.32s var(--ease);
}
.pmodal.is-open .pmodal__dialog { transform: none; }
.pmodal__close {
  position: absolute; top: 12px; right: 12px; z-index: 5;
  width: 38px; height: 38px; display: grid; place-items: center;
  background: rgba(13, 12, 10, 0.5); color: #fff; border: none; cursor: pointer;
  transition: background-color 0.25s var(--ease);
}
.pmodal__close:hover { background: rgba(13, 12, 10, 0.85); }
.pmodal__close svg { width: 18px; height: 18px; fill: currentColor; }

/* left — zoomable, scrollable image viewer */
.pmodal__viewer { position: relative; flex: 1 1 62%; min-width: 0; background: #100e0b; display: flex; }
.pmodal__scroll { flex: 1; overflow: auto; padding: clamp(14px, 2vw, 30px); }
.pmodal__stage { width: 100%; margin-inline: auto; display: flex; flex-direction: column; gap: 14px; transition: width 0.22s var(--ease); }
.pmodal__img { width: 100%; height: auto; display: block; background: #1a1815; }
.pmodal__zoom {
  position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); z-index: 4;
  display: flex; align-items: center; gap: 2px;
  background: rgba(20, 18, 15, 0.94); border: 1px solid rgba(255, 255, 255, 0.14);
  padding: 4px 5px;
}
.pmodal__zbtn {
  width: 32px; height: 30px; display: grid; place-items: center;
  background: none; border: none; color: rgba(255, 255, 255, 0.85); cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}
.pmodal__zbtn:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.pmodal__zbtn svg { width: 17px; height: 17px; fill: currentColor; }
.pmodal__zlevel { min-width: 44px; text-align: center; font-size: 0.75rem; color: rgba(255, 255, 255, 0.85); font-variant-numeric: tabular-nums; }

/* right — details sidebar */
.pmodal__side {
  flex: 0 0 clamp(280px, 34%, 400px); min-width: 0;
  display: flex; flex-direction: column; gap: 0.9rem;
  padding: clamp(26px, 3vw, 42px) clamp(22px, 2.6vw, 36px);
  overflow-y: auto; border-left: 1px solid var(--line);
}
.pmodal__cat { align-self: flex-start; font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--bronze); font-weight: 600; }
.pmodal__title { font-family: var(--serif); font-size: clamp(1.6rem, 3vw, 2.3rem); line-height: 1.12; color: var(--text); }
.pmodal__desc { font-size: 0.9rem; line-height: 1.75; color: var(--text-body); }
.pmodal__meta { display: grid; grid-template-columns: auto 1fr; gap: 7px 18px; margin-top: 0.3rem; }
.pmodal__meta dt { font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-mute); align-self: center; }
.pmodal__meta dd { font-size: 0.85rem; color: var(--text); }
.pmodal__cta { margin-top: auto; align-self: flex-start; }

@media (max-width: 780px) {
  .pmodal__dialog { flex-direction: column; height: min(90vh, 100%); }
  .pmodal__viewer { flex: 1 1 auto; min-height: 0; }
  .pmodal__side { flex: 0 0 auto; max-height: 44%; border-left: none; border-top: 1px solid var(--line); }
}
/* mobile: modal fills the screen with a topbar strip that carries the close box */
.pmodal__topbar { display: none; }
@media (max-width: 640px) {
  .pmodal { padding: 0; }
  .pmodal__dialog { width: 100%; height: 100vh; height: 100dvh; max-height: none; padding-top: 52px; }
  .pmodal__topbar {
    display: flex; align-items: center;
    position: absolute; top: 0; left: 0; right: 0; height: 52px; z-index: 4;
    padding: 0 16px; background: var(--paper); border-bottom: 1px solid var(--line);
  }
  .pmodal__topbar-label { font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-mute); font-weight: 600; }
  .pmodal__close { top: 8px; right: 8px; width: 36px; height: 36px; background: var(--gray); color: var(--text); border: 1px solid var(--line); }
  .pmodal__close:hover { background: var(--ink); color: var(--w-100); }
  .pmodal__side { max-height: 48%; }
}
@media (prefers-reduced-motion: reduce) {
  .pmodal, .pmodal__dialog, .pmodal__stage { transition: none; }
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* intro text block — centred, biased upward (≈40% space above / 60% below),
   sized so the video reel only peeks in at the bottom of the first view */
.hero__intro {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  min-height: calc(57svh + var(--hero-top-gap));
  text-align: center;
  padding-top: calc(var(--header-h) + var(--hero-top-gap));
  pointer-events: none; /* hovers fall through to the boxes; links re-enable */
}
.hero__intro::before { content: ""; flex: 2.4 1 1rem; } /* space above */
.hero__intro::after  { content: ""; flex: 4.4 1 1rem; } /* space below — biased larger so the reel isn't cramped against the CTAs */

.hero__intro .overline {
  display: block;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--bronze);
  margin-bottom: 1.5rem;
}

.hero__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.4rem, 5.6vw, 4.9rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: var(--text);
}
.hero__line { display: block; }

/* flip word */
.flip {
  display: inline-block;
  position: relative;
  vertical-align: top;
  text-align: left; /* word hugs "to"; fixed min-width keeps the line stable */
  font-style: normal;
  color: var(--bronze);
  white-space: nowrap;
}
.flip__word { display: inline-block; }
.flip__char {
  display: inline-block;
  white-space: pre;
  will-change: transform, opacity, filter;
}

.hero__lede {
  margin: clamp(1.6rem, 3vw, 2.2rem) auto 0;
  max-width: 46ch;
  font-size: 0.9375rem;
  color: var(--text-body);
}

.hero__paths {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px 30px;
  margin-top: clamp(1.8rem, 3.5vw, 2.6rem);
}
.hero__path {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  pointer-events: auto; /* re-enable inside the pointer-events:none intro */
  font-family: var(--serif);
  font-size: 1.0625rem;
  color: var(--text);
  border-bottom: 1px solid transparent;
  padding-bottom: 3px;
  transition: border-color 0.25s var(--ease);
}
.hero__path:hover { border-bottom-color: var(--text); }
.hero__path-arrow {
  color: var(--bronze);
  font-size: 1.1rem; line-height: 1;
  transition: transform 0.3s var(--ease);
}
.hero__path:hover .hero__path-arrow { transform: translate(2px, 2px); }

/* brand video reel — a clean 16:9 frame (= video ratio, so no crop) */
.hero__reel { position: relative; z-index: 2; }
.hero__video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 0;
  background: var(--ink);
  /* scroll-linked scale-up — starts slightly small, settles to full size
     as it reaches viewport centre (JS drives --reveal-s) */
  transform: scale(var(--reveal-s, 0.9));
  transform-origin: center;
  will-change: transform;

  /* cursor-driven border glow (React-Bits "BorderGlow", ported — glow only).
     JS feeds --cursor-angle + --edge-proximity from the pointer position. */
  --cursor-angle: 90deg;
  --edge-proximity: 0;
  --edge-sensitivity: 36;   /* glow only kicks in as the cursor nears an edge */
  --glow-pad: 34px;         /* how far the halo bleeds beyond the frame */
  --gc:    hsl(33 52% 60% / 0.95);
  --gc-60: hsl(33 52% 60% / 0.52);
  --gc-50: hsl(33 52% 60% / 0.44);
  --gc-40: hsl(33 52% 60% / 0.35);
  --gc-30: hsl(33 52% 60% / 0.25);
  --gc-20: hsl(33 52% 60% / 0.15);
  --gc-10: hsl(33 52% 60% / 0.08);
}
/* the media is clipped to the rounded frame; the glow lives OUTSIDE this clip */
.hero__video-clip {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  background: var(--ink);
  z-index: 1;
}
.hero__video {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
/* directional glow ring — revealed only in the arc facing the cursor, and
   only as the cursor nears an edge (opacity ramps with --edge-proximity) */
.hero__glow {
  position: absolute;
  inset: calc(var(--glow-pad) * -1);
  pointer-events: none;
  z-index: 2;
  opacity: calc((var(--edge-proximity) - var(--edge-sensitivity)) / (100 - var(--edge-sensitivity)));
  transition: opacity 0.2s ease-out;
  -webkit-mask-image: conic-gradient(from var(--cursor-angle) at center,
    #000 2.5%, transparent 10%, transparent 90%, #000 97.5%);
  mask-image: conic-gradient(from var(--cursor-angle) at center,
    #000 2.5%, transparent 10%, transparent 90%, #000 97.5%);
}
.hero__glow::before {
  content: "";
  position: absolute;
  inset: var(--glow-pad);   /* pulls the lit ring back to the frame's edge */
  border-radius: 0;
  box-shadow:
    inset 0 0 0 1px var(--gc),
    inset 0 0 1px 0 var(--gc-60),
    inset 0 0 3px 0 var(--gc-50),
    inset 0 0 6px 0 var(--gc-40),
    inset 0 0 15px 0 var(--gc-30),
    inset 0 0 25px 2px var(--gc-20),
    inset 0 0 50px 2px var(--gc-10),
    0 0 1px 0 var(--gc-60),
    0 0 3px 0 var(--gc-50),
    0 0 6px 0 var(--gc-40),
    0 0 15px 0 var(--gc-30),
    0 0 25px 2px var(--gc-20),
    0 0 50px 2px var(--gc-10);
}
/* The glow is driven entirely by JS (assets/js/main.js): by default it orbits
   the frame on its own — so touch devices get it too — and hands control to the
   pointer while hovering. --edge-proximity defaults to 0, so with JS disabled
   there is simply no glow. Reduced-motion users get no auto-orbit. */
/* the sound toggle is a secondary .gbtn (see the button system above) floating
   over the reel's bottom-right corner — only positioning + the icon swap live
   here; the box, fill, "+" corners and colours all come from .gbtn--secondary. */
.hero__sound { position: absolute; right: 16px; bottom: 16px; }
.hero__sound .gbtn__label { display: inline-flex; align-items: center; gap: 8px; }
.hero__sound .icon--sound { display: none; }
.hero__sound[aria-pressed="true"] .icon--muted { display: none; }
.hero__sound[aria-pressed="true"] .icon--sound { display: block; }
/* label tracks state: muted -> "Unmute" (the action), unmuted -> "Mute" */
.hero__sound .snd-label--mute { display: none; }
.hero__sound[aria-pressed="true"] .snd-label--unmute { display: none; }
.hero__sound[aria-pressed="true"] .snd-label--mute { display: inline; }

/* interactive boxes grid backdrop (Aceternity "Background Boxes", ported) —
   recoloured for the light theme: warm hairlines, brand-tint hover flares */
.hero__boxes {
  position: absolute;
  top: var(--hero-top-gap); left: 0; right: 0;
  height: 54svh; /* matches the intro; grid overflows it and fades out (shifted down by the nav gap so the disc tracks the headline) */
  z-index: 0;
  overflow: clip;
  pointer-events: auto;
  /* a soft CIRCLE: opaque in the middle, fading to nothing well before the grid's
     real (rectangular) edge — so the reduced grid reads as a clean circular disc
     with no visible borders. Tightened so the disc stays a slim band behind the
     headline rather than bleeding down toward the video reel. */
  -webkit-mask-image: radial-gradient(circle at 50% 43%, #000 0%, #000 18%, transparent 42%);
  mask-image: radial-gradient(circle at 50% 43%, #000 0%, #000 18%, transparent 42%);
}
.hbox-grid {
  position: absolute;
  top: 50%; left: 50%;
  display: flex;
  transform: translate(-50%, -50%) skewX(-48deg) skewY(14deg) scale(0.74);
  transform-origin: center;
}
.hbox-strip {
  display: flex;
  flex-direction: column;
  /* explicit box: main.js culls the cells the mask hides, so a strip can hold
     fewer cells (or none) and must still hold its column open —
     60px cell + this 1px border-left, which is the grid's real column pitch */
  flex: none;
  width: 61px;
  border-left: 1px solid rgba(86, 79, 69, 0.13);
}
/* stands in for the culled run at the top of a strip, so the cells that remain
   keep their exact row positions */
.hbox-skip { flex: none; pointer-events: none; }
.hbox {
  position: relative;
  flex: none;
  width: 60px; height: 32px;
  border-right: 1px solid rgba(86, 79, 69, 0.13);
  border-top: 1px solid rgba(86, 79, 69, 0.13);
  transition: background-color 1.8s ease;
}
/* Periodic circular glow wave (JS sets --delay + --gcolor per cell).
   Two identical animations: consecutive waves alternate between them, so a
   re-lit cell gets a different animation-name and restarts on its own. That is
   what lets fireGlow() drop the forced reflow it needed to commit the reset. */
.hbox.glow-a { animation: hboxGlowA var(--gdur, 420ms) ease-out var(--delay, 0ms) both; }
.hbox.glow-b { animation: hboxGlowB var(--gdur, 420ms) ease-out var(--delay, 0ms) both; }
@keyframes hboxGlowA {
  0%   { background-color: transparent; }
  35%  { background-color: var(--gcolor, rgba(233, 207, 158, 0.3)); }
  100% { background-color: transparent; }
}
@keyframes hboxGlowB {
  0%   { background-color: transparent; }
  35%  { background-color: var(--gcolor, rgba(233, 207, 158, 0.3)); }
  100% { background-color: transparent; }
}
.hbox--plus::before,
.hbox--plus::after {
  content: "";
  position: absolute;
  background: rgba(86, 79, 69, 0.22);
  pointer-events: none;
}
.hbox--plus::before { left: -5px; top: -1px; width: 11px; height: 1px; }
.hbox--plus::after  { left: -1px; top: -5px; width: 1px;  height: 11px; }

/* Hero entrance */
.hero-item {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
  transition-delay: var(--d, 0s);
}
body.loaded .hero-item { opacity: 1; transform: none; }

/* ==========================================================================
   STATEMENT / ABOUT
   ========================================================================== */

.statement { padding-top: clamp(4.5rem, 8.5vw, 8rem); }
/* statement shell keeps the global gutters so its text lines up with the navbar
   box, every other section, and its own aurora (which is anchored to the global
   global --gutter token below). */

.statement__body {
  position: relative;
  /* padding (not child margin) keeps the text clear of the tag box while
     letting the aurora start flush beneath it; the section's --section-y now
     owns the bottom gap so this no longer doubles it. */
  padding-top: var(--space-xl);
  padding-bottom: 0;
}
.statement__body > .shell { position: relative; z-index: 1; }

/* aurora backdrop (ported from the React reference, recoloured to brand)
   — confined to the content shell width, fading out before its edges */
.aurora {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(max((100% - var(--shell)) / 2, 0px) + var(--gutter));
  right: calc(max((100% - var(--shell)) / 2, 0px) + var(--gutter));
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg,
      transparent, #000 clamp(60px, 12%, 150px),
      #000 calc(100% - clamp(60px, 12%, 150px)), transparent);
  mask-image: linear-gradient(90deg,
      transparent, #000 clamp(60px, 12%, 150px),
      #000 calc(100% - clamp(60px, 12%, 150px)), transparent);
}

.aurora__layer {
  --aurora: repeating-linear-gradient(100deg,
      #b08249 10%, #e9cf9e 15%, #d9cdb4 20%, #f0ddba 25%, #bb9058 30%);
  --stripes: repeating-linear-gradient(100deg,
      rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.85) 7%,
      transparent 10%, transparent 12%, rgba(255, 255, 255, 0.85) 16%);
  position: absolute;
  inset: -160px -15%;
  background-image: var(--stripes), var(--aurora);
  background-size: 300%, 200%;
  background-position: 50% 50%, 50% 50%;
  filter: blur(14px) saturate(1.25);
  opacity: 0.45; /* static fallback when animations are off */
  will-change: transform, opacity;
  /* glow centre sits below the section-header line, over the statement content
     (was 160px = level with the header line, which left it floating in the gap) */
  -webkit-mask-image: radial-gradient(ellipse 44% 72% at 50% 300px, #000 18%, transparent 70%);
  mask-image: radial-gradient(ellipse 44% 72% at 50% 300px, #000 18%, transparent 70%);
  animation: auroraSweep 18s ease-in-out infinite;
}

/* slow wipe: fade in at the left, drift across, fade out at the right */
@keyframes auroraSweep {
  0%   { transform: translateX(-28%); opacity: 0; }
  18%  { opacity: 0.5; }
  82%  { opacity: 0.5; }
  100% { transform: translateX(28%); opacity: 0; }
}

.statement__title {
  font-family: var(--serif);
  font-size: clamp(1.65rem, 3vw, 2.5rem);
  line-height: 1.22;
  letter-spacing: -0.005em;
  color: var(--text);
  max-width: 30ch;
}

.statement__cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 4vw, 4.5rem);
  margin-top: 3rem;
  max-width: none;
}
.statement__cols p { font-size: 0.95rem; color: var(--text-body); }

/* services velocity marquee — drifts continuously, speeds up & flips with
   page-scroll velocity (JS), looping seamlessly via a modulo wrap */
.svc-marquee {
  position: relative;
  margin-top: clamp(3.5rem, 7vw, 6rem);
  overflow: hidden; /* contained to the .shell content width (respects padding) */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.svc-marquee__track {
  display: flex;
  width: max-content;
  will-change: transform;
}
.svc-marquee__set { display: flex; align-items: center; flex: none; }
.svc-marquee__item {
  flex: none;
  font-family: var(--sans);
  font-size: clamp(0.8rem, 1.05vw, 0.95rem);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-body);
  white-space: nowrap;
  padding: 0 clamp(0.9rem, 2vw, 1.8rem);
}
.svc-marquee__sep {
  flex: none;
  font-size: 0.7rem;
  color: var(--bronze);
  transform: translateY(-0.04em);
}

/* ==========================================================================
   FEATURE SECTIONS (Build / Grow)
   ========================================================================== */

.feature { padding-block: clamp(4.5rem, 8vw, 7.5rem) clamp(3rem, 6vw, 5.5rem); }

.feature__grid {
  display: grid;
  /* copy gets the width; the portrait media is the narrower (5fr) column so it
     stays a balanced accent rather than a towering block. */
  grid-template-columns: 7fr 5fr;
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: center;
  margin-top: var(--head-gap);
}
.feature--flip .feature__grid { grid-template-columns: 5fr 7fr; }
.feature--flip .feature__copy { order: 2; }
.feature--flip .feature__media { order: 1; }

/* Grow sits directly under the "Our Services" tag of the Build block */
.feature--flip { padding-top: clamp(1.5rem, 3vw, 2.5rem); }
.feature--flip .feature__grid { margin-top: 0; }

.feature__title {
  font-family: var(--serif);
  font-size: clamp(1.6rem, 2.7vw, 2.35rem);
  line-height: 1.22;
  color: var(--text);
  max-width: 19ch;
}
.feature__copy > p {
  margin-top: 1.5rem;
  max-width: 44ch;
  font-size: 0.95rem;
}

.ticklist { margin-top: 1.5rem; display: grid; gap: 9px; }
.ticklist li {
  position: relative;
  padding-left: 1.2em;       /* hanging indent: bullet sits in the gutter, label + text flow inline */
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-body);
}
.ticklist li::before {
  content: "\2022"; /* • normal circular bullet */
  position: absolute;
  left: 0;
  top: 0;
  color: var(--bronze);
  line-height: inherit;
}
.ticklist strong { color: var(--text); font-weight: 500; }

.feature__copy .tlink { margin-top: 2rem; }
.feature__copy .gbtn { margin-top: 1.9rem; }

.feature__media {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line-soft);
  border-radius: 4px;
}
/* the container's default reveal is neutralised — the image wipes instead */
.feature__media.reveal { opacity: 1; transform: none; }
.feature__media:not(.feature__media--stack) img {
  width: 100%;
  display: block;
  /* wipe-up reveal: clip from the bottom edge upward, settling a subtle zoom */
  clip-path: inset(100% 0 0 0);
  transform: scale(1.05);
  transition:
    clip-path 1.05s var(--ease) var(--d, 0s),
    transform 1.3s var(--ease) var(--d, 0s);
}
.feature__media:not(.feature__media--stack).reveal.in img {
  clip-path: inset(0 0 0 0);
  transform: scale(1);
}

/* Layered media (Build / Grow): a fixed golden background that wipes up, then a
   transparent cutout that fades + lifts up over it once the wipe has played. */
.feature__media--stack { aspect-ratio: 3 / 4; background: var(--black); border: none; border-radius: 0; }
.feature__media--stack .feat-bg {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block; margin: 0;
  object-fit: cover;
  clip-path: inset(100% 0 0 0);
  transform: scale(1.05);
  transition: clip-path 1.05s var(--ease) var(--d, 0s), transform 1.3s var(--ease) var(--d, 0s);
}
.feature__media--stack.reveal.in .feat-bg { clip-path: inset(0 0 0 0); transform: scale(1); }
/* The foreground is placed + sized EXACTLY as its Figma child layer. The frames
   are 900×1200 — a 3:4 ratio, identical to this box — so each layer's x/y/w/h
   maps straight to a % of the container and reproduces the Figma crop/scale at
   ANY size (no re-tuning when the box is resized). object-fit:cover because each
   exported cutout already carries its layer's exact aspect ratio. */
.feature__media--stack .feat-fg {
  position: absolute; display: block; margin: 0;
  max-width: none;   /* the Figma layer is wider than the box; the global img cap would clamp it to 100% */
  object-fit: cover;
  opacity: 0;
  transform: translateY(34px);
  transition: opacity 1s var(--ease), transform 1.2s var(--ease);
  transition-delay: calc(var(--d, 0s) + 1.05s);   /* hold until the bg wipe (~1.05s) finishes, then lift */
}
.feature__media--stack.reveal.in .feat-fg { opacity: 1; transform: translateY(0); }
/* Each foreground maps straight to its Figma child layer's box (x/y/w/h) as a %
   of the 900×1200 frame, so the cutout sits exactly as composed at any size.
   Build: image 28 = 1537×1032 @ -141,80. Grow: image 30 = 1929×1113 @ -1069,87
   (dashboard zoomed and bleeding left, thin golden strip along the top and right). */
#build .feat-fg { left: -15.667%; top: 6.667%; width: 170.778%; height: 86%; }
#grow  .feat-fg { left: -118.778%; top: 7.25%; width: 214.333%; height: 92.75%; }

/* ==========================================================================
   WORK
   ========================================================================== */

.work {
  background: var(--gray);
  padding-block: clamp(4.5rem, 8vw, 7.5rem);
}
.work .sectag { border-color: var(--line); }

.work__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.6vw, 20px);
  margin-top: var(--head-gap);
}

.workpiece { display: block; }
.workpiece__media {
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 4.2;
  background: var(--gray-2);
  border-radius: 4px;
}
.workpiece__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.workpiece:hover .workpiece__media img { transform: scale(1.025); }

.workpiece__label {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 12px 2px 0;
}
.workpiece__name { font-size: 0.8125rem; font-weight: 500; color: var(--text); }
.workpiece__cat { font-size: 0.75rem; color: var(--text-mute); }

/* ==========================================================================
   TEAM
   ========================================================================== */

.team { padding-block: clamp(4.5rem, 8vw, 7.5rem) clamp(3.5rem, 6vw, 5.5rem); }

/* founder's note — CEO highlight before the team grid */
.founder {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.4fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  margin-top: var(--head-gap);
  padding-bottom: clamp(3rem, 6vw, 5rem);
  border-bottom: 1px solid var(--line-soft);
}
.founder__media {
  position: relative;
  aspect-ratio: 4 / 4.4;
  border-radius: 6px;
  overflow: hidden;
  background: var(--gray);
}
.founder__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 18%;
  filter: grayscale(1);
}
.founder__label {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bronze);
  margin-bottom: 1.4rem;
}
.founder__quote {
  font-family: var(--sans); /* long editorial text stays in the body font */
  font-size: clamp(1.1rem, 1.9vw, 1.45rem);
  line-height: 1.55;
  letter-spacing: -0.005em;
  color: var(--text);
  text-indent: -0.5em; /* hang the opening quote mark */
}
.founder__quote::before { content: "\201C"; }
.founder__quote::after { content: "\201D"; }
.founder__sign { margin-top: clamp(1.6rem, 3vw, 2.2rem); display: grid; gap: 2px; }
.founder__name {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  max-width: 340px;
  font-family: var(--serif);
  font-size: 1.5rem;
  font-style: normal;
  color: var(--text);
}
.founder__role { font-size: 0.8125rem; color: var(--text-mute); }

.team__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-top: clamp(2.2rem, 4vw, 3.2rem);
  margin-bottom: 1.8rem;
}

.team__title {
  font-family: var(--serif);
  font-size: clamp(1.6rem, 2.7vw, 2.35rem);
  line-height: 1.22;
  color: var(--text);
}

.team__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(14px, 1.8vw, 24px);
}

.member { display: block; }

.member__media {
  display: block;
  overflow: hidden;
  aspect-ratio: 3 / 4;
  border-radius: 4px;
  background: var(--gray);
}
.member__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 22%;
  filter: grayscale(1);
  transition: filter 0.5s var(--ease), transform 0.9s var(--ease);
}
.member:hover .member__media img {
  filter: grayscale(0);
  transform: scale(1.02);
}

.member__name {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 12px;
  font-size: 1rem;
  font-weight: 500;
  color: var(--text);
}
.member__role {
  display: block;
  margin-top: 2px;
  font-size: 0.75rem;
  color: var(--text-mute);
}

/* LinkedIn (etc.) icon — a sharp rectangle box anchored to the right end of the
   name row; name on the left, icon on the right. */
.social-link {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 25px;
  border: 1px solid var(--line);
  color: var(--text-mute);
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.social-link:hover, .social-link:focus-visible {
  background: var(--ink); color: var(--w-100); border-color: var(--ink);
}
.social-link svg { width: 13px; height: 13px; display: block; }

/* ==========================================================================
   TESTIMONIALS
   ========================================================================== */

.quotes { padding-block: clamp(4.5rem, 8vw, 7.5rem); }

.quotes__scroller { align-items: stretch; margin-top: var(--head-gap); }
.quotes__scroller .quote { flex: 0 0 clamp(300px, 34vw, 420px); }
.quote {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  padding: clamp(1.6rem, 2.4vw, 2.2rem);
  background: var(--gray);
  border-radius: 6px;
}
.quote blockquote {
  position: relative;
  flex: 1;
  font-family: var(--sans); /* long quote text stays in the body font */
  font-size: clamp(0.95rem, 1.4vw, 1.1rem);
  line-height: 1.6;
  color: var(--text);
}
.quote blockquote::before {
  content: "\201C";
  display: block;
  font-family: var(--serif);
  font-size: 2.6rem;
  line-height: 0.6;
  color: var(--bronze);
  margin-bottom: 0.5rem;
}
.quote figcaption { display: grid; gap: 2px; }
.quote__name { font-size: 0.8125rem; font-weight: 600; color: var(--text); }
.quote__role { font-size: 0.75rem; color: var(--text-mute); }

/* ==========================================================================
   INSIGHTS — auto-scrolling row
   ========================================================================== */

.insights { padding-block: clamp(4.5rem, 8vw, 7.5rem); }

.insights__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-top: clamp(2.2rem, 4vw, 3.2rem);
  margin-bottom: 1.8rem;
}

.insights__title {
  font-family: var(--serif);
  font-size: clamp(1.6rem, 2.7vw, 2.35rem);
  line-height: 1.22;
  color: var(--text);
}

.insights__scroller,
.quotes__scroller {
  --rail-edge: calc(max((100vw - var(--shell)) / 2, 0px) + var(--gutter));
  display: flex;
  align-items: flex-start;
  gap: clamp(14px, 1.6vw, 20px);
  overflow-x: auto;
  scrollbar-width: none;
  padding-inline: var(--rail-edge);
  padding-bottom: 6px;
  /* crop the peeking cards at the shell's content edge (a clean cut-off in line with
     every other section) instead of letting them bleed into the outer gutter. */
  clip-path: inset(-100px var(--rail-edge));
}
.quotes__scroller { align-items: stretch; }
.insights__scroller::-webkit-scrollbar,
.quotes__scroller::-webkit-scrollbar { display: none; }

.insight {
  display: flex;
  flex-direction: column;
  flex: 0 0 clamp(300px, 25vw, 380px);
}
.insight__media {
  position: relative;
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: 4px;
  background: var(--gray-2);
}
.insight__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.insight:hover .insight__media img { transform: scale(1.03); }

.insight__body {
  display: grid;
  gap: 7px;
  padding: 13px 2px 0;
}
.insight__body time {
  font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-mute);
}
.insight__heading {
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.32;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.insight__cta {
  justify-self: start;
  margin-top: 3px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mute);
  transition: color 0.3s var(--ease);
}
.insight__cta::after {
  content: "\2192";
  font-size: 0.95em;
  color: var(--bronze);
  transition: transform 0.3s var(--ease);
}
.insight:hover .insight__cta { color: var(--text); }
.insight:hover .insight__cta::after { transform: translateX(4px); }

/* ==========================================================================
   CTA — full-width plate, ripple anchored to the button
   ========================================================================== */

.cta { padding: 0; }

.cta__inner {
  position: relative;
  overflow: clip;
  background: var(--black);
}
.cta__inner > * { position: relative; z-index: 1; }

.cta-ripple {
  position: absolute;
  inset: 0;
  z-index: 0;
  -webkit-mask-image: radial-gradient(120% 150% at 26% 58%, #000 26%, rgba(0, 0, 0, 0.3) 56%, transparent 86%);
  mask-image: radial-gradient(120% 150% at 26% 58%, #000 26%, rgba(0, 0, 0, 0.3) 56%, transparent 86%);
}

.cta-ripple__grid {
  position: absolute;
  inset: 0;
  display: grid;
  justify-content: center;
  align-content: center;
}

.cta-ripple .cell {
  border: 1px solid rgba(250, 249, 246, 0.055);
  background: rgba(250, 249, 246, 0.016);
  opacity: 0.55;
  transition: opacity 0.2s var(--ease), background-color 0.2s var(--ease);
}
.cta-ripple .cell:hover {
  opacity: 1;
  background: rgba(250, 249, 246, 0.055);
}
/* Two identical animations: consecutive ripples alternate between them, so a
   re-fired cell gets a different animation-name and restarts on its own. Same
   trick as the hero grid's .glow-a/.glow-b — it is what lets ripple() drop the
   forced reflow it used to need to commit the reset. */
.cta-ripple .cell.rippling-a {
  animation: cellRippleA var(--duration, 300ms) ease-out var(--delay, 0ms) 1;
}
.cta-ripple .cell.rippling-b {
  animation: cellRippleB var(--duration, 300ms) ease-out var(--delay, 0ms) 1;
}

@keyframes cellRippleA {
  0%, 100% { background: rgba(250, 249, 246, 0.016); border-color: rgba(250, 249, 246, 0.055); }
  35% { background: rgba(176, 140, 96, 0.20); border-color: rgba(176, 140, 96, 0.38); }
}
@keyframes cellRippleB {
  0%, 100% { background: rgba(250, 249, 246, 0.016); border-color: rgba(250, 249, 246, 0.055); }
  35% { background: rgba(176, 140, 96, 0.20); border-color: rgba(176, 140, 96, 0.38); }
}

.cta__content { padding-top: clamp(4rem, 8vw, 6.5rem); }

.cta__title {
  font-family: var(--serif);
  font-size: clamp(1.7rem, 3.2vw, 2.7rem);
  line-height: 1.2;
  color: var(--w-100);
  max-width: 24ch;
}

.cta__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 28px;
  margin-top: 2.6rem;
}

.cta__contact { display: flex; flex-wrap: wrap; gap: 20px; }
.cta__contact a {
  font-size: 0.8125rem;
  color: var(--w-70);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: rgba(250, 249, 246, 0.3);
  transition: color 0.25s;
}
.cta__contact a:hover { color: var(--w-100); }

.cta__note { margin-top: 2rem; font-size: 0.75rem; color: var(--w-45); }

.cta__clients {
  display: flex; flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 26px;
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding-block: 22px clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--line-dark);
}
.cta__clients span {
  font-size: 0.75rem;
  color: var(--w-45);
  transition: color 0.25s;
}
.cta__clients span:hover { color: var(--w-100); }

/* ==========================================================================
   FOOTER — fixed layer beneath the page canvas
   ========================================================================== */

.footer {
  background: var(--gray);
  border-top: 1px solid var(--line-soft);
  overflow: clip;
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: clamp(28px, 4vw, 48px);
  padding-block: clamp(3rem, 5vw, 4.5rem) clamp(2rem, 3.5vw, 3rem);
}

.footer .brand__mark { width: auto; height: 40px; }
.footer .brand__name { color: var(--text); }
.footer .brand__sub { color: var(--text-mute); }
.footer__about p { margin-top: 1.2rem; font-size: 0.8125rem; line-height: 1.75; }

.footer__col h3 {
  font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 14px;
}
.footer__follow { margin-top: 1.6rem; }
.footer__col ul { display: grid; gap: 8px; }
.footer__col a {
  font-size: 0.8125rem;
  color: var(--text-body);
  transition: color 0.22s;
}
.footer__col a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

/* trust badges — placeholder chips above the footer bar divider. Centred on
   desktop; a flowing marquee on small screens so they all stay readable. */
.footer__badges {
  display: flex; justify-content: center;
  padding-block: clamp(0.4rem, 1.2vw, 0.9rem) clamp(1.6rem, 3vw, 2.3rem);
}
.footer__badges-group {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 10px 12px;
}
.footer__badges-group + .footer__badges-group { display: none; }   /* marquee copy, hidden until mobile */
.trust-badge {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 8px 14px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid var(--line);
  font-size: 0.76rem; font-weight: 500; letter-spacing: 0.01em;
  color: var(--text-body); white-space: nowrap;
  transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease),
              color 0.25s var(--ease), transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.trust-badge:hover {
  border-color: var(--bronze); background: #fff; color: var(--text);
  transform: translateY(-2px); box-shadow: 0 8px 18px -10px rgba(24, 22, 18, 0.32);
}
.trust-badge__ic { width: 17px; height: 17px; flex: none; fill: var(--bronze); transition: transform 0.25s var(--ease); }
.trust-badge:hover .trust-badge__ic { transform: scale(1.12); }
@media (max-width: 640px) {
  .footer__badges { --bmg: 12px; overflow: hidden; justify-content: flex-start; gap: var(--bmg); }
  .footer__badges-group {
    flex: none; flex-wrap: nowrap; justify-content: flex-start; gap: var(--bmg);
    min-width: 100%; animation: badgeMarquee 18s linear infinite;
  }
  .footer__badges-group + .footer__badges-group { display: flex; }
  .footer__badges:hover .footer__badges-group { animation-play-state: paused; }
}
@keyframes badgeMarquee { to { transform: translateX(calc(-100% - var(--bmg, 12px))); } }
@media (prefers-reduced-motion: reduce) { .footer__badges-group { animation: none; } }

.footer__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding-block: 16px 6px;
  border-top: 1px solid var(--line-soft);
  font-size: 0.75rem;
  color: var(--text-mute);
}
.to-top {
  font-size: 0.75rem;
  color: var(--text-mute);
  transition: color 0.25s;
}
.to-top:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

.footer__watermark {
  font-weight: 800;
  font-size: clamp(4rem, 14.5vw, 12.5rem);
  line-height: 0.78;
  letter-spacing: -0.03em;
  white-space: nowrap;
  text-align: center;
  color: rgba(24, 22, 18, 0.055);
  user-select: none;
  margin-top: 0.6rem;
  transform: translateY(10%);
}

/* ==========================================================================
   REVEAL
   ========================================================================== */

.reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
  transition-delay: var(--d, 0s);
}
.reveal.in { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   Staggered letter entrance — display headlines rise bottom-up, left → right.
   main.js splits the text into .sr-word / .sr-char spans and adds .split-reveal,
   which hands the entrance to the glyphs instead of the .hero-item / .reveal
   block fade. Each glyph is held below + transparent, then released on .sr-in
   with a per-letter delay so the reveal sweeps across the line.
   -------------------------------------------------------------------------- */
.split-reveal { opacity: 1 !important; transform: none !important; }
.split-reveal .sr-word { display: inline-block; white-space: nowrap; }
.split-reveal .sr-char {
  display: inline-block;
  transform: translateY(0.52em);
  opacity: 0;
  transition: transform 0.62s var(--ease), opacity 0.62s var(--ease);
  transition-delay: calc(var(--ci, 0) * 0.02s);
}
.split-reveal.sr-in .sr-char { transform: none; opacity: 1; }
/* hero flip-word holds back until the static letters have landed */
.hero__title.split-reveal .flip {
  opacity: 0;
  transition: opacity 0.5s var(--ease);
  transition-delay: calc(var(--n, 18) * 0.02s);
}
.hero__title.split-reveal.sr-in .flip { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .split-reveal .sr-char { transition: none; transform: none; opacity: 1; }
  .hero__title.split-reveal .flip { transition: none; opacity: 1; }
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 1080px) {
  .feature__grid, .feature--flip .feature__grid { grid-template-columns: 1fr; gap: var(--space-l); }
  .feature__copy { order: 2; }   /* mobile: image container first, copy below (site-wide) */
  .feature__media { order: 1; }
  .footer__grid { grid-template-columns: 1fr 1fr; }
  .founder { grid-template-columns: 1fr; gap: 1.8rem; }
  .founder__media { max-width: 360px; aspect-ratio: 4 / 3.4; }
}

@media (max-width: 820px) {
  .pill-nav { display: none; }
  .menu-toggle { display: flex; align-items: center; justify-content: center; }

  .work__grid { grid-template-columns: 1fr; }
  /* team members become a horizontal swipe carousel on mobile (the CEO/founder block is unchanged) */
  .team__grid {
    display: flex; gap: 14px;
    overflow-x: auto; scrollbar-width: none;
    scroll-snap-type: x proximity;
    clip-path: inset(-100px var(--gutter));   /* crop the peek at the shell content edge */
  }
  .team__grid::-webkit-scrollbar { display: none; }
  .team__grid .member { flex: 0 0 min(68vw, 240px); scroll-snap-align: start; }
  .team__head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .workpiece__media { aspect-ratio: 4 / 3; }
  .statement__cols { grid-template-columns: 1fr; }
}

@media (max-width: 620px) {
  .footer__grid { grid-template-columns: 1fr; gap: 0; }
  .footer__about { margin-bottom: 1.5rem; }
  /* footer columns collapse into a tap-to-expand accordion on mobile */
  .footer__col h3 {
    margin: 0; padding: 14px 2px;
    border-top: 1px solid var(--line);
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    cursor: pointer; user-select: none;
  }
  .footer__col h3::after {
    content: ""; flex: none;
    width: 8px; height: 8px;
    border-right: 2px solid var(--text); border-bottom: 2px solid var(--text);
    transform: translateY(-2px) rotate(45deg);
    transition: transform 0.3s var(--ease);
  }
  .footer__col h3.is-open::after { transform: translateY(1px) rotate(-135deg); }
  .footer__follow { margin-top: 0; }
  .footer__col ul {
    max-height: 0; overflow: hidden;
    transition: max-height 0.35s var(--ease);
  }
  .footer__col h3.is-open + ul { max-height: 360px; }
  .footer__col ul li { padding: 3px 0; }
  .footer__col ul li:last-child { padding-bottom: 14px; }
  .cta__row { align-items: flex-start; flex-direction: column; gap: 22px; }
  .cta__clients { justify-content: flex-start; }
  .insights__head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .hero__paths { flex-direction: column; align-items: center; gap: 14px; }
}

/* ── Mobile optimisation: readable copy, tap-safe inputs, tighter hero ────── */
@media (max-width: 640px) {
  body { font-size: 1rem; }                                          /* 16px copy reads better on phones */
  .hero__intro { min-height: 70svh; }                               /* trim the dead space above the reel */
  .hero__intro::after { flex: 2 1 1.5rem; }

  /* hero sound toggle: shows its label briefly, then fades the text out and
     collapses into an icon-only square to save space (JS adds .snd-collapsed) */
  .hero__sound { transition: color 0.35s var(--ease), padding 0.5s var(--ease); }
  .hero__sound .gbtn__label { transition: gap 0.45s var(--ease); }
  .hero__sound .snd-label {
    display: inline-block; overflow: hidden; white-space: nowrap;
    max-width: 5em; opacity: 1;
    transition: max-width 0.5s var(--ease), opacity 0.35s var(--ease);
  }
  .hero__sound .snd-label--mute { display: none; }
  .hero__sound[aria-pressed="true"] .snd-label--unmute { display: none; }
  .hero__sound[aria-pressed="true"] .snd-label--mute { display: inline-block; }
  .hero__sound.snd-collapsed { padding: 13px; }
  .hero__sound.snd-collapsed .gbtn__label { gap: 0; }
  .hero__sound.snd-collapsed .snd-label { max-width: 0; opacity: 0; }
}

/* full-page screenshots: show service images fully revealed */
html.capture .feature__media img { clip-path: none; transform: none; }
html.capture .feature__media--stack .feat-fg { opacity: 1; transform: none; }

/* ==========================================================================
   REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal, .hero-item { opacity: 1; transform: none; }
  .feature__media img, .pagehead__media img, .post__media img { clip-path: none !important; transform: none !important; }
  .feature__media--stack .feat-fg { opacity: 1 !important; }
  .preloader { display: none; }
}

/* ==========================================================================
   MULTI-PAGE ROUTER — views toggle inside <main>; the footer follows the
   active view. Home keeps its id-driven effects; inner pages reuse components.
   ========================================================================== */

.view { display: none; }
.view.is-active { display: block; animation: viewIn 0.45s var(--ease) both; }
@keyframes viewIn { from { opacity: 0; } to { opacity: 1; } }

/* inner-page header (clears the fixed header) */
.pagehead {
  padding-top: calc(var(--header-h) + clamp(3.25rem, 7vw, 6.5rem));
  padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
}
.pagehead__eyebrow {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--bronze);
}
.pagehead__title {
  font-family: var(--serif);
  font-size: clamp(2rem, 4.4vw, 3.6rem);
  line-height: 1.07; letter-spacing: -0.015em;
  color: var(--text); margin-top: 0.9rem; max-width: 18ch;
}
.pagehead__lede {
  margin-top: 1.3rem; max-width: 56ch;
  font-size: clamp(0.95rem, 1.4vw, 1.1rem); line-height: 1.6;
  color: var(--text-body);
}

/* Header collage — copy on the left, image tiles on the right. The tiles
   recreate the supplied Union.svg (a union of rectangles) so each rectangle
   can hold its own image; built by JS in the shape's 397x215 coordinate space. */
.pagehead__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.pagehead__copy { min-width: 0; }
.pagehead__collage {
  position: relative;
  width: 100%;
  aspect-ratio: 397 / 215;
}
.pagehead__tile {
  position: absolute;
  overflow: hidden;
  background-color: #e9e5de;
  background-repeat: no-repeat;     /* JS sets background-size & -position so all
                                       tiles share one continuous masked image */
  opacity: 0;
  transform: scale(0.92);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.pagehead__tile.is-in { opacity: 1; transform: none; }
/* instant reset between replays so tiles don't visibly fade back out */
.pagehead__collage.resetting .pagehead__tile { transition: none !important; }

@media (max-width: 860px) {
  .pagehead__grid { grid-template-columns: 1fr; gap: clamp(1.8rem, 5vw, 2.6rem); }
  .pagehead__copy { order: 2; }    /* mobile: collage image first, title/lede below */
  .pagehead__collage { order: 1; }
}

/* generic block + heading inside inner pages */
.block { padding-block: clamp(2.5rem, 5vw, 4.5rem); }
.block__head { border-bottom: 1px solid var(--line); padding-bottom: 16px; margin-bottom: clamp(1.8rem, 3.5vw, 2.8rem); }
.block__kicker {
  display: block; margin-bottom: 0.8rem;
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--bronze);
}
.block__title {
  font-family: var(--serif); font-size: clamp(1.05rem, 1.7vw, 1.45rem);
  line-height: 1.15; color: var(--text); max-width: 32ch;
}

/* prose */
.prose { display: grid; gap: 1.3rem; max-width: 66ch; }
.prose p { font-size: 0.9375rem; line-height: 1.78; color: var(--text-body); }
.prose--cols { max-width: none; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 4vw, 3.5rem); }

/* ── Blog post ───────────────────────────────────────────────────────────── */
.post__col { max-width: 700px; margin-inline: auto; padding-inline: var(--gutter); }
.post__head { padding-top: calc(var(--header-h) + clamp(2.25rem, 5vw, 4rem)); padding-bottom: clamp(1.6rem, 3vw, 2.4rem); }
.post__back {
  display: inline-flex; align-items: center;
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-mute); transition: color 0.2s var(--ease);
}
.post__back:hover { color: var(--text); }
.post__eyebrow {
  display: block; margin-top: 1.7rem;
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--bronze);
}
.post__title {
  font-family: var(--serif); font-size: clamp(2rem, 4.2vw, 3.1rem);
  line-height: 1.08; letter-spacing: -0.015em; color: var(--text); margin-top: 0.7rem;
}
.post__meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-top: 1.6rem; font-size: 0.8125rem; color: var(--text-mute);
}
.post__avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--ink); color: var(--w-100);
  font-family: var(--serif); font-size: 0.6875rem;
}
.post__by { font-weight: 500; color: var(--text); }
.post__dot { color: var(--line); }

.post__hero { max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); margin-top: clamp(0.4rem, 1.5vw, 1rem); }   /* image aligned to the site content width (navbar/shell) */
.post__media {
  aspect-ratio: 16 / 9; overflow: hidden; border-radius: 0; background: var(--gray-2);
}
.post__media.reveal { opacity: 1; transform: none; }
.post__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  clip-path: inset(100% 0 0 0); transform: scale(1.04);
  transition: clip-path 1.05s var(--ease), transform 1.3s var(--ease);
}
.post__media.reveal.in img { clip-path: inset(0 0 0 0); transform: scale(1); }

.post__body { padding-block: clamp(2.5rem, 5vw, 4rem); }
.post__prose { gap: 1.45rem; }   /* width comes from .post__col (700px) so the body keeps a readable measure + side margins */
.post__prose p, .post__prose li { font-size: 1.0625rem; line-height: 1.8; color: var(--text-body); }
.post__lead { font-size: 1.26rem; line-height: 1.62; color: var(--text); }
.post__prose h2 {
  font-family: var(--serif); font-size: clamp(1.45rem, 2.6vw, 1.9rem);
  line-height: 1.18; letter-spacing: -0.01em; color: var(--text); margin-top: 1rem;
}
.post__prose h3 {
  font-family: var(--serif); font-size: 1.22rem; line-height: 1.25; color: var(--text); margin-top: 0.6rem;
}
.post__prose ul { display: grid; gap: 0.7rem; padding-left: 1.25rem; margin: 0; }
.post__prose li::marker { color: var(--bronze); }
.post__pull {
  font-family: var(--serif); font-size: clamp(1.35rem, 2.6vw, 1.7rem); line-height: 1.4;
  color: var(--text); border-left: 2px solid var(--bronze); padding-left: 1.5rem; margin: 0.6rem 0;
}
.post__more { background: var(--gray); }

/* hairline card grid (values / pillars) */
.cardgrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line);
}
.card { background: var(--paper); padding: clamp(1.5rem, 2.6vw, 2.2rem); }
.card__title { font-family: var(--serif); font-size: 1.15rem; line-height: 1.25; color: var(--text); margin: 0.9rem 0 0.6rem; }
.card__text { font-size: 0.85rem; line-height: 1.65; color: var(--text-body); }

/* process steps */
.process { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.2rem, 2.4vw, 2rem); }
.step { display: flex; flex-direction: column; }
.step__media {                       /* boxy tile that now holds an animated icon */
  width: 100%; aspect-ratio: 4 / 5;  /* sharp-cornered, boxy — no radius */
  margin-bottom: 1.2rem; overflow: hidden;
  background: #e9e5de;
  display: grid; place-items: center;
}
.step__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.step__lottie { width: 62%; aspect-ratio: 1; }
.step__lottie svg { display: block; width: 100% !important; height: 100% !important; }
.step__name { font-family: var(--serif); font-size: 1.15rem; color: var(--text); margin: 0.7rem 0 0.5rem; }
.step__text { font-size: 0.82rem; line-height: 1.6; color: var(--text-body); }

/* services list */
.svc-group + .svc-group { margin-top: clamp(2.8rem, 5vw, 4.5rem); }
.svc-group__head {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
  gap: 10px 28px; padding-bottom: 16px; border-bottom: 1px solid var(--line);
  margin-bottom: clamp(1.6rem, 3vw, 2.4rem);
}
.svc-group__title { font-family: var(--serif); font-size: clamp(1.05rem, 1.7vw, 1.45rem); color: var(--text); }
.svc-group__note { font-size: 0.85rem; color: var(--text-mute); max-width: 42ch; }
/* Bento grid — services as sharp boxes; the discovery-highlighted services
   (App Dev, SEO/GEO, Content Creation) become wide feature cards with a square
   image. Our box style + a subtle hover tint (card-hover-effect, restyled). */
.bento { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.bento-card {
  position: relative; overflow: hidden;
  background: #fff; border: 1px solid var(--line);   /* sharp box, no radius */
  padding: clamp(1.3rem, 2.2vw, 2rem);
  display: flex; flex-direction: column; gap: 0.7rem;
  transition: border-color 0.3s var(--ease);
}
.bento-card > * { position: relative; z-index: 1; }
.bento-card::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: rgba(176, 140, 96, 0.08);
  opacity: 0; transition: opacity 0.3s var(--ease);
}
.bento-card:hover { border-color: var(--bronze); }
.bento-card:hover::before { opacity: 1; }

/* feature card — square image + body, spans the full row */
.bento-card--feat {
  grid-column: 1 / -1;
  flex-direction: row; align-items: stretch;
  gap: clamp(1.2rem, 2.5vw, 2rem);
}
.bento-card__media {
  flex: 0 0 clamp(150px, 28%, 280px);
  aspect-ratio: 1;                                   /* image stays a proper square */
  overflow: hidden; background: #e9e5de;
}
.bento-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.6s var(--ease); }
.bento-card--feat:hover .bento-card__media img { transform: scale(1.04); }
.bento-card__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.7rem; }

.svc-card__name { font-family: var(--serif); font-size: 1.3rem; color: var(--text); }
.svc-card__text { font-size: 0.85rem; line-height: 1.6; color: var(--text-body); }
.bento-card .ticklist { margin-top: 0.3rem; gap: 7px; }
.bento-card .ticklist li { font-size: 0.78rem; }

@media (max-width: 700px) {
  .bento { grid-template-columns: 1fr; }
  .bento-card--feat { grid-column: auto; flex-direction: column; }
  .bento-card__media { flex: none; width: 100%; aspect-ratio: 16 / 10; }
}

/* blog post grid (reuses .insight card styles) */
.postgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(290px, 100%), 1fr));
  gap: clamp(1.4rem, 2.6vw, 2rem);
}
.postgrid .insight { flex: none; width: auto; }

/* get-a-quote */
.quotewrap { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(2.5rem, 5vw, 5rem); align-items: start; }
.quoteform { display: grid; gap: 1.1rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
.field { display: grid; gap: 0.5rem; }
.field label { font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-mute); }
.field input, .field select, .field textarea {
  font: inherit; font-size: 0.875rem; color: var(--text);
  background: var(--paper); border: 1px solid var(--line);
  padding: 12px 14px; border-radius: 2px; width: 100%;
  transition: border-color 0.2s;
}
.field input::placeholder, .field textarea::placeholder { color: var(--text-mute); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--bronze); }
.field textarea { resize: vertical; min-height: 130px; }
.quoteform__note { font-size: 0.8125rem; color: var(--bronze); }
.quote-aside { display: grid; gap: 1.6rem; align-content: start; }
.quote-aside__block h3 { font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-mute); margin-bottom: 0.6rem; }
.quote-aside__block a, .quote-aside__block p { display: block; font-size: 0.875rem; color: var(--text-body); line-height: 1.7; }
.quote-aside__block a { width: fit-content; transition: color 0.2s; }
.quote-aside__block a:hover { color: var(--text); }

/* end-of-page CTA band (inner pages) — same cell-ripple grid as the home CTA */
.endcta {
  position: relative;
  overflow: clip;
  background: var(--black); color: var(--w-100); text-align: center;
  padding-block: clamp(3.5rem, 7vw, 6rem); margin-top: clamp(2.5rem, 5vw, 4.5rem);
}
.endcta > .shell { position: relative; z-index: 1; }
.endcta .cta-ripple {            /* centred mask — content/button sit in the middle */
  -webkit-mask-image: radial-gradient(120% 130% at 50% 52%, #000 30%, rgba(0,0,0,0.3) 62%, transparent 88%);
  mask-image: radial-gradient(120% 130% at 50% 52%, #000 30%, rgba(0,0,0,0.3) 62%, transparent 88%);
}
.endcta__title {
  font-family: var(--serif); font-size: clamp(1.7rem, 3.4vw, 2.8rem);
  line-height: 1.15; color: var(--w-100); max-width: 22ch; margin: 0 auto 1.8rem;
}

/* responsive — new components */
@media (max-width: 1080px) {
  .process { grid-template-columns: repeat(2, 1fr); }
  .quotewrap { grid-template-columns: 1fr; }
  .prose--cols { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  .process {                          /* horizontal scroll carousel on mobile */
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 0.9rem;
    padding-bottom: 0.6rem;
  }
  .step { flex: 0 0 70%; scroll-snap-align: start; }
  .step__media { aspect-ratio: 3 / 4; }
  .form-row { grid-template-columns: 1fr; }
  .pagehead__title { max-width: none; }
  .field input, .field select, .field textarea { font-size: 16px; } /* >=16px stops iOS zooming on focus */
}

/* ==========================================================================
   SCROLL STACK (React Bits "ScrollStack", ported) — Principles section
   Desktop: sticky intro on the left, cards that pin & stack on the right as you
   scroll. Mobile: intro on top, cards stack below. Cards are clean rectangles.
   The pin/scale transforms are JS-driven (window scroll); see main.js.
   ========================================================================== */
.principles-stack { padding-block: clamp(3rem, 6vw, 5.5rem); }
.stack-grid {
  display: grid;
  grid-template-columns: 0.82fr 1fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.stack-intro {
  position: sticky;
  top: calc(var(--header-h) + clamp(2rem, 8vh, 6rem));
}
/* landscape image above the heading (matches the Figma "Principles" frame, 16:9);
   fills the sticky intro column. */
.stack-intro__media {
  width: 100%; max-width: none;
  aspect-ratio: 16 / 9;
  margin-bottom: clamp(1.4rem, 2.4vw, 2rem);
  overflow: hidden; background: #e9e5de;
}
.stack-intro__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.stack-intro__desc {
  margin-top: 1.2rem; max-width: 34ch;
  font-size: 0.9rem; line-height: 1.7; color: var(--text-body);
}

.stack-cards { position: relative; }
.scroll-stack-card {
  position: relative;
  display: flex; flex-direction: column;
  min-height: 13.5rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 0;                         /* clean rectangle, not rounded */
  padding: clamp(1.8rem, 2.6vw, 2.4rem);
  box-shadow: 0 18px 50px rgba(13, 12, 10, 0.10);
  transform-origin: top center;
  backface-visibility: hidden;
  will-change: transform;
  margin-bottom: 1.4rem;                    /* compact list by default (no-JS / reduced motion) */
}
.scroll-stack-card .card__title { font-family: var(--serif); font-size: clamp(1.25rem, 1.8vw, 1.5rem); color: var(--text); margin: 0.9rem 0 0.7rem; }
.scroll-stack-card .card__text { font-size: 0.9rem; line-height: 1.7; color: var(--text-body); max-width: 44ch; }
.scroll-stack-end { display: none; width: 100%; height: 1px; }

/* JS-active state: open up the scroll distance so cards pin sequentially,
   and add the trailing space that lets the completed stack hold before release */
.stack-cards.is-stacking .scroll-stack-card { margin-bottom: 68px; }
.stack-cards.is-stacking .scroll-stack-card:last-of-type { margin-bottom: 0; }
.stack-cards.is-stacking .scroll-stack-end { display: block; margin-top: clamp(9rem, 26vh, 18rem); }

@media (max-width: 900px) {
  .stack-grid { grid-template-columns: 1fr; gap: clamp(1.6rem, 5vw, 2.5rem); }
  .stack-intro { position: static; }
  .scroll-stack-card { min-height: 12rem; }
  .stack-cards.is-stacking .scroll-stack-card { margin-bottom: 54px; }
}

/* ==========================================================================
   TARGET CURSOR (React Bits "TargetCursor", ported) + LENIS smooth scroll
   ========================================================================== */
/* Hide the native cursor everywhere once the custom one is active; the JS only
   adds .has-target-cursor on fine-pointer (non-touch) devices, so touch keeps
   its native cursor. */
html.has-target-cursor,
html.has-target-cursor * { cursor: none !important; }

.target-cursor-wrapper {
  --cur: #fff;
  position: fixed; top: 0; left: 0; width: 0; height: 0;
  pointer-events: none; z-index: 10000;
  mix-blend-mode: difference;
  transform: translate(-50%, -50%);
  opacity: 1;
  transition: opacity 0.28s var(--ease);   /* only opacity — never the gsap-driven transform */
}
/* The cursor fades out for the preloader and fades back in with the page. It
   used to also hide for the whole of every hero shimmer (body.cursor-hidden) to
   keep it from compositing against the animating grid; measurement showed that
   cost nothing, so that rule and the choreography driving it are gone. */
body.preloading .target-cursor-wrapper {
  opacity: 0; visibility: hidden;
  transition: opacity 0.28s var(--ease), visibility 0s 0.28s;
}
/* "Solid" mode: drop the blend entirely over performance-heavy zones (hero
   shimmer, CTA ripple) so the backdrop never has to be re-blended every frame.
   The cursor becomes a fixed colour, fully independent of what's behind it.
   .is-solid alone = white (for dark CTA backgrounds); add .is-dark = ink
   (for the light hero). */
.target-cursor-wrapper.is-solid { mix-blend-mode: normal; }
.target-cursor-wrapper.is-dark  { --cur: var(--ink); }
.target-cursor-dot {
  position: absolute; left: 50%; top: 50%;
  width: 4px; height: 4px; background: var(--cur); border-radius: 50%;
  transform: translate(-50%, -50%); will-change: transform;
}
.target-cursor-corner {
  position: absolute; left: 50%; top: 50%;
  width: 12px; height: 12px; border: 3px solid var(--cur); will-change: transform;
}
.corner-tl { transform: translate(-150%, -150%); border-right: none; border-bottom: none; }
.corner-tr { transform: translate(50%, -150%);  border-left: none;  border-bottom: none; }
.corner-br { transform: translate(50%, 50%);    border-left: none;  border-top: none; }
.corner-bl { transform: translate(-150%, 50%);  border-right: none; border-top: none; }

/* Hard guarantee the custom cursor never shows on touch / mobile / narrow views
   (the JS also skips creating it on touch — this covers responsive emulation). */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
  .target-cursor-wrapper { display: none !important; }
  html.has-target-cursor, html.has-target-cursor * { cursor: auto !important; }
}

/* Lenis smooth-scroll helper styles (required) */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-scrolling iframe { pointer-events: none; }

/* ==========================================================================
   WORK LIGHTBOX — full-screen image preview opened from Work-page cards
   ========================================================================== */
.lightbox {
  position: fixed; inset: 0; z-index: 9000;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(20px, 5vw, 64px);
  background: rgba(10, 9, 8, 0.93);
  opacity: 0; visibility: hidden;
  transition: opacity 0.4s var(--ease), visibility 0s 0.4s;
}
.lightbox.is-open {
  opacity: 1; visibility: visible;
  transition: opacity 0.4s var(--ease);
}
html.lightbox-lock { overflow: hidden; }

.lightbox__figure {
  margin: 0; max-width: min(1100px, 88vw);
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  transform: translateY(10px); opacity: 0;
  transition: transform 0.5s var(--ease), opacity 0.5s var(--ease);
}
.lightbox.is-open .lightbox__figure { transform: none; opacity: 1; transition-delay: 0.08s; }

.lightbox__img {
  display: block; max-width: 100%; max-height: 78vh;
  width: auto; height: auto; object-fit: contain;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: var(--black);
}
.lightbox__cap {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  justify-content: center; text-align: center;
}
.lightbox__name {
  font-family: var(--serif); font-weight: 500;
  font-size: clamp(1rem, 1.6vw, 1.25rem); color: var(--w-100);
}
.lightbox__cat {
  font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--bronze);
}

.lightbox__close, .lightbox__nav {
  position: absolute; z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid rgba(255, 255, 255, 0.22);
  color: var(--w-100);
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.lightbox__close:hover, .lightbox__nav:hover {
  background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.42);
}
.lightbox__close {
  top: clamp(16px, 3vw, 30px); right: clamp(16px, 3vw, 30px);
  width: 44px; height: 44px; font-size: 1.5rem; line-height: 1;
}
.lightbox__nav {
  top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px; font-size: 1.7rem; line-height: 1;
}
.lightbox__prev { left: clamp(12px, 3vw, 30px); }
.lightbox__next { right: clamp(12px, 3vw, 30px); }

@media (max-width: 640px) {
  .lightbox__nav { width: 40px; height: 40px; font-size: 1.4rem; }
  .lightbox__img { max-height: 70vh; }
}

/* ==========================================================================
   SERVICES (experimental) — numbered list + graphic stage that pushes up on hover
   ========================================================================== */
.svcx { padding-block: clamp(3.5rem, 7vw, 6.5rem); }
.svcx__grid {
  display: grid;
  grid-template-columns: clamp(280px, 38%, 460px) 1fr;
  gap: clamp(2rem, 5vw, 5.5rem);
  align-items: stretch;
  margin-top: var(--head-gap);
}

/* left: graphic stage — layers stack and slide together when --active changes */
.svcx__stage {
  position: relative;
  overflow: hidden;
  min-height: 520px;
  background: #c6c2ba;                 /* grey backdrop behind the media */
}
.svcx__graphic {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: #c6c2ba; overflow: hidden;
  transform: translateY(calc((var(--i, 0) - var(--active, 0)) * 100%));
  transition: transform 0.62s var(--ease);
  will-change: transform;
}
/* media containers on the grey backdrop (gif / mp4 / screenshot per service).
   Default: contained + centred (Content Production video stays centred). */
/* fill the frame so there are no empty / black bars (Branding gif + Content
   Production video both cover, centred; grey shows only while the file loads) */
.svcx__media { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; background: #c6c2ba; }
/* the Content Production clip (720x1280) has ~8% black bars baked into the top and
   bottom (100px each). object-fit can't drop bars that live inside the frames, so we
   overscan 1.2x: the bars get pushed past the overflow-hidden edges and clipped, the
   bottle stays centred. Verified bar-free from short (460px) to tall (680px) frames. */
.svcx__video { transform: scale(1.2); transform-origin: center; }
/* mobile auto-rotation progress lives on the ACTIVE service name's underline: a bronze
   fill sweeps across the bottom stroke over that service's dwell (which matches the
   service's animation length), then it advances to the next. Only present when JS
   enables auto-rotation (adds .svcx--auto). */
.svcx__item-fill {
  display: none; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--bronze); transform: scaleX(0); transform-origin: left; pointer-events: none;
}
/* soften the active row's dark underline while it's the progress track, so the black
   line doesn't fight the bronze fill sweeping across it */
.svcx--auto .svcx__item.is-active { border-bottom-color: rgba(24, 22, 18, 0.25); }
.svcx--auto .svcx__item.is-active .svcx__item-fill { display: block; }
.svcx--auto .svcx__item.is-active .svcx__item-fill.is-filling { animation: svcx-fill var(--fill-ms, 3400ms) linear forwards; }
@keyframes svcx-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.svcx__ph {
  position: relative; z-index: 1;
  font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(24, 22, 18, 0.42); text-align: center; padding: 1.2rem;
}
/* Website Development: a long page screenshot that scrolls top to bottom while
   its row is active, so it reads like the site scrolling. Image spans 80% width;
   the grey backdrop shows on the sides. The scroll waits a beat after the row
   activates, then eases through slowly; it snaps back quickly when it leaves. */
.svcx__webshot { position: relative; z-index: 1; width: 80%; height: 100%; overflow: hidden; }
.svcx__webshot img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center -13%;   /* negative = image pushed down, ~25% grey padding above the hero */
  transition: object-position 1s var(--ease);
}
.svcx__graphic.is-active .svcx__webshot img {
  object-position: center bottom;
  transition: object-position 7s ease-in-out 0.4s;
}

/* SEO & GEO: a compact "AI traffic" dashboard. The cards slide in from the right
   while the row is active, over the grey backdrop. */
.seodash {
  position: relative; z-index: 1;
  width: 100%; height: 100%;
  padding: clamp(12px, 2.4vw, 22px);
  display: flex; flex-direction: column; justify-content: center; gap: 10px;
}
.seodash__card {
  background: #fff; border: 1px solid rgba(24, 22, 18, 0.1); border-radius: 8px;
  padding: 9px 12px 11px;
  box-shadow: 0 5px 16px -10px rgba(0, 0, 0, 0.25);
  opacity: 0; transform: translateX(60px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.svcx__graphic.is-active .seodash__c1 { transition-delay: 0.12s; }
.svcx__graphic.is-active .seodash__c2 { transition-delay: 0.26s; }
.svcx__graphic.is-active .seodash__c3 { transition-delay: 0.4s; }
.svcx__graphic.is-active .seodash__card { opacity: 1; transform: none; }
.seodash__ch-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; font-size: 10.5px; font-weight: 600; color: #181612; }
.seodash__pill { padding: 2px 8px; border-radius: 10px; font-size: 8.5px; font-weight: 600; background: rgba(147, 52, 230, 0.09); color: #9334e6; white-space: nowrap; }
.seodash__pill--g { background: rgba(52, 168, 83, 0.12); color: #1e8e3e; }
/* grouped bar chart (6M vs prior 6M): grey = prior period, green = last period */
.seodash__glegend { list-style: none; display: flex; justify-content: center; gap: 14px; margin: 0 0 5px; font-size: 8.5px; color: #4d4943; }
.seodash__glegend li { display: flex; align-items: center; gap: 4px; }
.seodash__glegend i { width: 7px; height: 7px; border-radius: 2px; flex: none; }
.seodash__gbars { width: 100%; height: 48px; display: block; }
.seodash__gbars rect.pr { fill: #c9cdd6; }
.seodash__gbars rect.ls { fill: #34a853; }
.seodash__gbars line { stroke: rgba(24, 22, 18, 0.12); stroke-width: 1; }
.seodash__gcats { display: flex; justify-content: space-around; margin-top: 3px; font-size: 8px; color: #8c867c; }
.seodash__donut-row { display: flex; align-items: center; gap: 16px; }
.seodash__donut { width: 60px; height: 60px; flex: none; }
.seodash__legend { list-style: none; display: grid; gap: 4px; flex: 1; min-width: 0; font-size: 9.5px; color: #4d4943; }
.seodash__legend li { display: flex; align-items: center; gap: 6px; }
.seodash__legend i { width: 7px; height: 7px; border-radius: 2px; flex: none; }
.seodash__legend b { margin-left: auto; color: #181612; font-variant-numeric: tabular-nums; }
.seodash__table { width: 100%; border-collapse: collapse; font-size: 9px; }
.seodash__table th { text-align: left; font-weight: 600; color: #8c867c; text-transform: uppercase; letter-spacing: 0.04em; font-size: 7.5px; padding: 0 0 5px; }
.seodash__table th:not(:first-child), .seodash__table td:not(:first-child) { text-align: right; }
.seodash__table td { padding: 4px 0; border-top: 1px solid rgba(24, 22, 18, 0.07); color: #4d4943; }
.seodash__table td:first-child { font-weight: 600; color: #181612; }
.seodash__table td.sv { font-weight: 700; color: #181612; }
@media (prefers-reduced-motion: reduce) { .seodash__card { transition: none; } }

/* right: numbered service list */
.svcx__list { list-style: none; border-top: 1px solid var(--line-soft); }
.svcx__item {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;   /* was number | name | arrow, the number is gone */
  align-items: center;
  gap: clamp(0.8rem, 2vw, 1.8rem);
  padding: clamp(1.3rem, 2.6vw, 2.1rem) 0;
  border-top: 1px solid transparent;
  border-bottom: 1px solid var(--line-soft);
  color: var(--text-mute);
  text-decoration: none;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease), padding-left 0.35s var(--ease);
}
.svcx__item.is-active {
  color: var(--text);
  border-top-color: var(--text);
  border-bottom-color: var(--text);
  padding-left: clamp(0.4rem, 1.2vw, 1.1rem);
}
.svcx__name {
  font-family: var(--sans); font-weight: 400;
  font-size: clamp(1.25rem, 2.3vw, 2.05rem);
  letter-spacing: -0.012em; line-height: 1.12; text-transform: lowercase;
}
.svcx__item.is-active .svcx__name { font-weight: 500; }
/* arrow at the right end of each row: hidden until the row is hovered/active, so the
   service the pointer is on reads as clickable. Uses a mask so it inherits the row colour. */
.svcx__item::after {
  content: "";
  width: clamp(18px, 2vw, 26px); height: clamp(18px, 2vw, 26px); justify-self: end;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M5%2012h14M13%206l6%206-6%206'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M5%2012h14M13%206l6%206-6%206'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0; transform: translateX(-8px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.svcx__item:hover::after,
.svcx__item.is-active::after { opacity: 1; transform: none; }

/* in-SVG looping micro-animations (one motif per service) */
@keyframes gfx-scan { 0% { transform: translateY(0); opacity: 0; } 12% { opacity: .85; } 88% { opacity: .85; } 100% { transform: translateY(96px); opacity: 0; } }
.gfx-scan { animation: gfx-scan 2.8s linear infinite; }

@keyframes gfx-mnav { 0%, 26% { transform: translateX(0); } 33%, 59% { transform: translateX(15px); } 66%, 92% { transform: translateX(30px); } 100% { transform: translateX(0); } }
.gfx-mnav { animation: gfx-mnav 3.8s var(--ease) infinite; }

@keyframes gfx-swatch { 0%, 66%, 100% { transform: translateY(0); } 11% { transform: translateY(-9px); } 22% { transform: translateY(0); } }
.gfx-swatch { animation: gfx-swatch 3.4s var(--ease) infinite; animation-delay: calc(var(--n, 0) * 0.2s); }
@keyframes gfx-brush { 0% { transform: rotate(0); } 45%, 100% { transform: rotate(360deg); } }
.gfx-brush { transform-box: fill-box; transform-origin: center; animation: gfx-brush 4s var(--ease) infinite; }
/* drop stays hidden through the brush rotation (0-45%), then drops in + stretches
   a touch (kept small so it never spills past the tile), then fades for the loop */
@keyframes gfx-drop2 { 0%, 48% { transform: translateY(0) scaleY(.4); opacity: 0; } 62% { transform: translateY(0) scaleY(1); opacity: 1; } 84%, 94% { transform: translateY(2px) scaleY(1.2); opacity: 1; } 100% { transform: translateY(2px) scaleY(1.2); opacity: 0; } }
.gfx-drop2 { transform-box: fill-box; transform-origin: top; animation: gfx-drop2 4s var(--ease) infinite; }

@keyframes gfx-bub { 0% { transform: translateY(0); opacity: 0; } 18% { opacity: 1; } 100% { transform: translateY(-66px); opacity: 0; } }
.gfx-bub { animation: gfx-bub 3s var(--ease) infinite; animation-delay: calc(var(--n, 0) * 0.5s); }
@keyframes gfx-heartbeat { 0%, 100% { transform: scale(1); } 14% { transform: scale(1.16); } 28% { transform: scale(1); } 42% { transform: scale(1.1); } 56% { transform: scale(1); } }
.gfx-heart { transform-box: fill-box; transform-origin: center; animation: gfx-heartbeat 2.4s var(--ease) infinite; }

@keyframes gfx-grow { 0% { transform: scaleY(.12); } 30%, 86% { transform: scaleY(1); } 100% { transform: scaleY(.12); } }
.gfx-bar { transform-box: fill-box; transform-origin: bottom; animation: gfx-grow 3s var(--ease) infinite; animation-delay: calc(var(--n, 0) * 0.16s); }
@keyframes gfx-mag { 0%, 100% { transform: translate(0, 0); } 30% { transform: translate(-25px, 34px); } 55% { transform: translate(-52px, 60px); } 80% { transform: translate(-79px, 80px); } }
.gfx-mag { animation: gfx-mag 5.5s ease-in-out infinite; }

@keyframes gfx-flow { 0% { transform: translateY(0); opacity: 0; } 14% { opacity: 1; } 82% { opacity: 1; } 100% { transform: translateY(140px); opacity: 0; } }
.gfx-flow { animation: gfx-flow 2.6s var(--ease) infinite; animation-delay: calc(var(--n, 0) * 0.32s); }

@keyframes gfx-prog { 0% { transform: scaleX(0); } 92%, 100% { transform: scaleX(1); } }
.gfx-prog { transform-box: fill-box; transform-origin: left; animation: gfx-prog 3.4s linear infinite; }
@keyframes gfx-play { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.14); } }
.gfx-play { transform-box: fill-box; transform-origin: center; animation: gfx-play 2s var(--ease) infinite; }
@keyframes gfx-frame { 0% { stroke-dashoffset: 100; } 55%, 100% { stroke-dashoffset: 0; } }
.gfx-frame { stroke-dasharray: 100; animation: gfx-frame 3.6s var(--ease) infinite; }

/* stack on small screens (stage on top); JS auto-advances where hover is absent */
@media (max-width: 860px) {
  .svcx__grid { grid-template-columns: 1fr; gap: clamp(1.6rem, 4vw, 2.5rem); }
  .svcx__stage { order: -1; min-height: clamp(470px, 60vh, 540px); aspect-ratio: auto; }
  .svcx__graphic .gfx { width: min(42%, 210px); }
}

@media (prefers-reduced-motion: reduce) {
  .svcx__graphic { transition: none; }
  .gfx-scan, .gfx-mnav, .gfx-swatch, .gfx-brush, .gfx-drop2, .gfx-bub, .gfx-heart, .gfx-bar,
  .gfx-mag, .gfx-flow, .gfx-prog, .gfx-play, .gfx-frame { animation: none; }
}

/* ==========================================================================
   SINGLE SERVICE PAGE (one template, populated by slug)
   ========================================================================== */
.svcpage__head { padding-top: calc(var(--header-h) + clamp(2.5rem, 6vw, 5rem)); padding-bottom: clamp(2rem, 4vw, 3.5rem); }
/* ---- service hero -----------------------------------------------------------
   Copy left, measurement panel right. The mesh sits behind everything, masked so
   it fades out on every edge rather than being cut off by the section boundary,
   with the bronze aurora over it. Both are decorative and sit below the content. */
.svchero { position: relative; overflow: hidden; }
.svchero__inner { position: relative; z-index: 2; }
.svchero__aurora {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(44% 60% at 6% 26%, rgba(176, 140, 96, 0.22), transparent 68%),
    radial-gradient(38% 54% at 96% 76%, rgba(176, 140, 96, 0.16), transparent 66%);
  animation: svcheroBreathe 9s ease-in-out infinite alternate;
}
@keyframes svcheroBreathe { from { opacity: 0.74; transform: scale(1); } to { opacity: 1; transform: scale(1.04); } }
.svchero__grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(32px, 5vw, 56px); align-items: center; }

/* the panel: what the page argues for, shown rather than claimed */

@media (max-width: 900px) {
  .svchero__grid { grid-template-columns: 1fr; gap: 40px; }
}
@media (prefers-reduced-motion: reduce) {
  .svchero__aurora { animation: none; }
}
.svcpage__title { font-family: var(--serif); font-size: clamp(2.4rem, 6vw, 4.6rem); line-height: 1.02; letter-spacing: -0.02em; color: var(--text); }
.svcpage__tagline { max-width: 42ch; margin-top: 1.2rem; font-size: clamp(1.05rem, 1.7vw, 1.4rem); line-height: 1.5; color: var(--text-body); }
.svcpage__cta { margin-top: clamp(1.6rem, 3vw, 2.4rem); }
.svcpage__trust { margin-top: 24px; max-width: 52ch; font-size: 0.82rem; line-height: 1.6; color: var(--text-body); }

.svcpage__body { padding-block: clamp(2.5rem, 5vw, 4.5rem); border-top: 1px solid var(--line-soft); }
.svcpage__h { font-family: var(--sans); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-mute); margin-bottom: 1.1rem; }
.svcpage__overview p { font-size: clamp(1.05rem, 1.5vw, 1.25rem); line-height: 1.75; color: var(--text-body); max-width: 60ch; }

.svcpage__process { padding-block: clamp(2.6rem, 5vw, 4.2rem); }
.svcsteps { list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.4rem, 3vw, 2.4rem); margin-top: var(--head-gap); }
.svcstep__name { font-family: var(--serif); font-size: clamp(1.1rem, 1.6vw, 1.4rem); margin: 0.55rem 0 0.5rem; color: var(--text); }
.svcsteps li p { font-size: 0.85rem; line-height: 1.6; color: var(--text-body); }

.svcpage__more { padding-block: clamp(2.6rem, 5vw, 4.2rem); }
.svcpage__morelist { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(0.7rem, 1.4vw, 1rem); margin-top: var(--head-gap); }
/* these route to a service page, so they carry the same forward arrow the home
   page service rows use. Always visible, since the affordance is the point, and it
   nudges right on hover. Inherits currentColor, so it flips with the card. */
.svcmore { display: flex; align-items: center; justify-content: space-between; gap: 0.7rem; padding: clamp(1rem, 2vw, 1.4rem); border: 1px solid var(--line); color: var(--text); text-decoration: none; transition: background-color 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease); }
.svcmore::after {
  content: ""; flex: none; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M16.172 11l-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M16.172 11l-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z'/%3E%3C/svg%3E") center / contain no-repeat;
  opacity: 0.55; transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.svcmore:hover::after { transform: translateX(3px); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .svcmore:hover::after { transform: none; } }
.svcmore:hover { background: var(--ink); border-color: var(--ink); color: var(--w-100); }
.svcmore__name { font-family: var(--serif); font-size: clamp(1rem, 1.4vw, 1.2rem); }


/* ---- service page: client logo wall ----------------------------------------
   Sits directly under the hero, the placement the research found near universal.
   Monochrome and muted at rest so the row reads as one texture rather than a
   scatter of brand colours; brightens on hover like .partners__logo. Spacing is
   on the 8pt scale throughout. */
.svclogos { padding-block: 32px; border-top: 1px solid var(--line-soft); }
.svclogos__label {
  font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-body); margin-bottom: 24px;
}
.svclogos__row {
  list-style: none; display: grid;
  grid-template-columns: repeat(6, 1fr); align-items: center; gap: 32px;
}
.svclogos__row li {
  display: flex; align-items: center; justify-content: center;
  padding: 8px 12px;
  color: var(--text-mute); opacity: 0.7;
  transition: opacity 0.25s var(--ease), color 0.25s var(--ease), transform 0.25s var(--ease);
}
.svclogos__row li:hover { opacity: 1; color: var(--text); transform: translateY(-2px); }
.svclogos__row svg, .svclogos__row img { width: 100%; height: auto; max-height: 32px; display: block; }
@media (max-width: 820px) { .svclogos__row { grid-template-columns: repeat(3, 1fr); gap: 24px; } }
@media (max-width: 480px) { .svclogos__row { grid-template-columns: repeat(2, 1fr); gap: 16px; } }
@media (prefers-reduced-motion: reduce) { .svclogos__row li:hover { transform: none; } }

/* ---- cursor sweep: these hover but never framed under the custom cursor ---- */
/* ---- service page: capability strip ----------------------------------------
   Scope at a glance directly under the hero. Figures are display type, labels
   are quiet. No boxes: hairlines and space do the separating. */
/* --text-body, not --text-mute: at this size mute measures 3.4:1 and fails AA */

/* ---- service page: the shift ----------------------------------------------
   Prose beside the two search landscapes it is describing. */
/* fixed ratio + cover, so a replacement image of any dimensions drops straight in */

/* ---- service page: what makes us different ---------------------------------
   Three cards, each pairing a differentiator with the concrete things delivered
   under it. Structure follows the client's reference; the treatment follows this
   project: sharp corners, one bronze accent, tinted band instead of a shadow. */

/* ---- service page: fit ----------------------------------------------------- */

/* ---- service page: FAQ -----------------------------------------------------
   Native <details> so it is keyboard operable and open-by-find works. */
.svcfaq { padding-block: clamp(2.6rem, 5vw, 4.2rem); }
.svcfaq__split { display: grid; grid-template-columns: 1.4fr 1fr; gap: clamp(2rem, 4vw, 4rem); align-items: start; margin-top: var(--head-gap); }
.svcfaq__list { border-top: 1px solid var(--line-soft); }

/* enquiry panel: the one dark surface allowed mid page, so the form reads as a
   distinct action rather than another block of the article. */
.svcask { background: var(--black); color: var(--w-100); padding: clamp(1.6rem, 3vw, 2.4rem); }
.svcask__h { font-family: var(--serif); font-size: clamp(1.1rem, 1.7vw, 1.35rem); color: var(--w-100); }
.svcask__p { margin-top: 0.7rem; font-size: 0.85rem; line-height: 1.7; color: rgba(250, 249, 246, 0.72); }
.svcask__form { display: grid; gap: 1rem; margin-top: 1.6rem; }
.svcask .field label { color: rgba(250, 249, 246, 0.62); }
.svcask .field input, .svcask .field textarea {
  background: rgba(250, 249, 246, 0.06); border-color: rgba(250, 249, 246, 0.2); color: var(--w-100);
}
.svcask .field input::placeholder, .svcask .field textarea::placeholder { color: rgba(250, 249, 246, 0.52); }
.svcask .field input:focus, .svcask .field textarea:focus { border-color: var(--bronze); }
.svcask .field textarea { min-height: 96px; }
/* no colour override: .gbtn already rests as solid white with ink text, which is
   exactly right on the dark panel. Only the grid alignment needs setting. */
.svcask__btn { justify-self: start; }
.svcask__note { font-size: 0.78rem; line-height: 1.6; color: var(--bronze); }
.svcq { border-bottom: 1px solid var(--line-soft); transition: border-color 0.25s var(--ease); }
.svcq:hover, .svcq[open] { border-bottom-color: var(--line); }
.svcq__q {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem;
  padding: clamp(1rem, 2vw, 1.35rem) 0; cursor: pointer; list-style: none;
  font-family: var(--serif); font-size: clamp(0.98rem, 1.5vw, 1.15rem); line-height: 1.35;
  color: var(--text-body);
  transition: color 0.25s var(--ease), padding-left 0.25s var(--ease);
}
.svcq__q::-webkit-details-marker { display: none; }
/* clickable hairline row: same language as .svcx__item on the home page */
.svcq__q:hover, .svcq[open] .svcq__q { color: var(--text); }
.svcq__q:hover { padding-left: clamp(0.4rem, 1.2vw, 1.1rem); }
.svcq__q::after {                                  /* Remix Icon ri-arrow-down-s-line */
  content: ""; flex: none; width: 20px; height: 20px; margin-top: 0.1em;
  background: var(--bronze);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.3s var(--ease);
}
.svcq[open] .svcq__q::after { transform: rotate(180deg); }
.svcq__a { padding-bottom: clamp(1rem, 2vw, 1.35rem); }
.svcq__a p { font-size: 0.875rem; line-height: 1.75; color: var(--text-body); max-width: 68ch; }
.svcq:focus-within .svcq__q { color: var(--text); }

@media (max-width: 820px) {
  .svcgets__grid { grid-template-columns: 1fr; }
  .svcfaq__split { grid-template-columns: 1fr; }
}
@media (max-width: 1080px) and (min-width: 821px) {
  .svcgets__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .svcq__q::after { transition: none; }
  .svcq__q, .svcq { transition: none; }
  .svcq__q:hover { padding-left: 0; }
  .svcgets__card { transition: none; }
  .svcgets__grid li:hover { transform: none; }
  .svcgets__grid li:hover::before { transform: none; }
}

@media (max-width: 820px) {
  .svcsteps { grid-template-columns: repeat(2, 1fr); }
  .svcpage__morelist { grid-template-columns: 1fr; }
}

/* ==========================================================================
   SEO SERVICE PAGE, sections 2 to 9. Spacing is strictly on the 8pt scale.
   ========================================================================== */

/* 2. what the service includes: capsule then four area pointers */

/* 3. who it is for: four boxes on the tinted band */
.svcwho { padding-block: 64px; }
.svcwho__grid { list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 48px; }
.svcwho__grid li {
  background: #fff; border: 1px solid var(--line); padding: 24px;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease),
              transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.svcwho__grid li:hover {
  border-color: var(--bronze); transform: translateY(-2px);
  box-shadow: 0 8px 18px -10px rgba(24, 22, 18, 0.32);
}
.svcwho__n { display: block; font-family: var(--serif); font-size: clamp(1rem, 1.4vw, 1.15rem); line-height: 1.3; color: var(--text); }
.svcwho__d { display: block; margin-top: 12px; font-size: 0.82rem; line-height: 1.6; color: var(--text-body); }

/* 4. the close: argument beside the comparison table */
.svcvs { padding-block: 64px; }

/* 5. process lede sits under the section heading */

/* 6. scope cards, one per specialism */
.svcgets { padding-block: 64px; }
.svcgets__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 48px; }
.svcgets__card {
  display: block; background: #fff; border: 1px solid var(--line); padding: 24px;
  color: var(--text-body); text-decoration: none;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease),
              transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.svcgets__card:hover {
  border-color: var(--bronze); color: var(--text); transform: translateY(-2px);
  box-shadow: 0 8px 18px -10px rgba(24, 22, 18, 0.32);
}
.svcgets__n { display: block; font-family: var(--serif); font-size: clamp(1rem, 1.4vw, 1.15rem); line-height: 1.3; color: var(--text); }
.svcgets__d { display: block; margin-top: 12px; font-size: 0.82rem; line-height: 1.6; }

/* 7. proof: measurement statement beside the two standing commitments */
.svcproof { padding-block: 64px; }


/* 8. cost: how the number is arrived at, with the drivers beside it */

/* 9. worth it, and the three reversals that replace a ranking promise */

/* 11. final CTA additions */
.endcta__lede { max-width: 52ch; margin: 0 auto 32px; font-size: 0.95rem; line-height: 1.75; color: rgba(250, 249, 246, 0.78); }
.endcta__alt { margin-top: 24px; font-size: 0.85rem; line-height: 1.6; color: rgba(250, 249, 246, 0.72); }
.endcta__risk { margin-top: 8px; font-size: 0.78rem; letter-spacing: 0.04em; color: var(--bronze); }

@media (max-width: 1080px) {
}
@media (max-width: 820px) {
}
@media (max-width: 560px) {
}
@media (prefers-reduced-motion: reduce) {
  .svcwho__grid li:hover, .svcgets__card:hover { transform: none; }
}

/* ---- SEO page photography ---------------------------------------------------
   One treatment for every card photo: greyscale at rest, colour on hover, the
   same move .member__media makes on the team cards. Ratio is locked so a
   replacement file of any dimensions drops in without reflowing the grid. */
.svcwho__img, .svcgets__img { display: block; overflow: hidden; border-radius: 4px; background: var(--gray-2); margin-bottom: 16px; }
.svcwho__img img, .svcgets__img img {
  width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; display: block;
  filter: grayscale(1);
  transition: filter 0.5s var(--ease), transform 0.9s var(--ease);
}
.svcwho__grid li:hover .svcwho__img img,
.svcgets__card:hover .svcgets__img img { filter: grayscale(0); transform: scale(1.02); }

/* the proof photo is the one full-colour image on the page, and it does not hover */
.svcproof__img { display: block; overflow: hidden; border-radius: 4px; background: var(--gray-2); margin-bottom: 24px; }
.svcproof__img img { width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; display: block; }

@media (prefers-reduced-motion: reduce) {
  .svcwho__grid li:hover .svcwho__img img,
  .svcgets__card:hover .svcgets__img img { transform: none; }
}

/* ---- staggered card entrance -----------------------------------------------
   The grid itself only fades; its cards do the moving, one after another. Uses
   the existing .reveal observer, so no new scroll listener and no new library.
   Children cannot carry .reveal themselves (the observer scans once, at load),
   so the delay is driven off nth-child instead. */
.svc-stagger.reveal { transform: none; }
.svc-stagger > * {
  opacity: 0; transform: translateY(14px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.svc-stagger.in > * { opacity: 1; transform: none; }
.svc-stagger > *:nth-child(1) { transition-delay: 0.00s; }
.svc-stagger > *:nth-child(2) { transition-delay: 0.06s; }
.svc-stagger > *:nth-child(3) { transition-delay: 0.12s; }
.svc-stagger > *:nth-child(4) { transition-delay: 0.18s; }
.svc-stagger > *:nth-child(5) { transition-delay: 0.24s; }
.svc-stagger > *:nth-child(6) { transition-delay: 0.30s; }
.svc-stagger > *:nth-child(7) { transition-delay: 0.36s; }
.svc-stagger > *:nth-child(8) { transition-delay: 0.42s; }
@media (prefers-reduced-motion: reduce) {
  .svc-stagger > * { opacity: 1; transform: none; transition: none; }
}

/* a section heading that carries its own action. .sectag is baseline aligned for
   text links, so centre it when the action is a full button. */
/* the site packs a sectag left unless it holds a .sectag__btn; an action button
   is the same intent, so restore the split and let the button sit at the far right */
.sectag.sectag--action { align-items: center; flex-wrap: wrap; row-gap: 16px; justify-content: space-between; }
.sectag__cta { flex: none; }

/* what the reporting covers: fills the left column so it stands level with the
   taller right column instead of leaving a dead gap under the prose */
@media (max-width: 560px) { .sectag--action .sectag__cta { width: 100%; text-align: center; } }

/* ---- numbering removed site wide -------------------------------------------
   These titles previously sat beneath an 01/02/03 label and carried a top margin
   to clear it. With the number gone they lead their card, so the margin goes. */
.card__title:first-child, .step__name:first-child, .svcstep__name:first-child { margin-top: 0; }

/* ---- section 9: the centred break -------------------------------------------
   Every other section on this page runs a left/right split. This one centres, so
   the reader feels the change of gear before reading a word. The check marks draw
   themselves when the row arrives, staggered, and hold once drawn. */
.svcworth { padding-block: 96px; }
/* no ch cap here: 62ch resolves against the body face, but the title renders in
   the much wider display face and was breaking with room to spare */
.svcworth__head { max-width: none; margin-inline: auto; text-align: center; }
.svcworth__title {
  font-family: var(--serif); font-size: clamp(1.7rem, 3.2vw, 2.6rem);
  line-height: 1.12; letter-spacing: -0.015em; color: var(--text);
  text-wrap: balance;   /* only breaks when it genuinely must, and breaks evenly */
}
.svcworth__grid {
  list-style: none; display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 48px; margin: 64px auto 0; max-width: 1100px;
}
.svcworth__grid li { text-align: center; }
.svcworth__n { display: block; margin-top: 24px; font-family: var(--serif); font-size: clamp(1.05rem, 1.5vw, 1.25rem); line-height: 1.3; color: var(--text); }
.svcworth__d { display: block; margin-top: 12px; font-size: 0.875rem; line-height: 1.7; color: var(--text-body); max-width: 32ch; margin-inline: auto; }

/* the mark: ring first, then the tick, both drawn with stroke-dashoffset */
.svcworth__tick { display: block; width: 56px; height: 56px; margin-inline: auto; }
.svcworth__tick svg { width: 100%; height: 100%; display: block; }
.svcworth__tick circle, .svcworth__tick path { fill: none; stroke: var(--bronze); stroke-linecap: round; stroke-linejoin: round; }
.svcworth__tick circle { stroke-width: 1.25; stroke-dasharray: 151; stroke-dashoffset: 151; transition: stroke-dashoffset 0.85s var(--ease); }
.svcworth__tick path { stroke-width: 2; stroke-dasharray: 30; stroke-dashoffset: 30; transition: stroke-dashoffset 0.45s var(--ease) 0.5s; }
.svcworth__grid.in .svcworth__tick circle,
.svcworth__grid.in .svcworth__tick path { stroke-dashoffset: 0; }
.svcworth__grid li:nth-child(2) .svcworth__tick circle { transition-delay: 0.14s; }
.svcworth__grid li:nth-child(2) .svcworth__tick path { transition-delay: 0.64s; }
.svcworth__grid li:nth-child(3) .svcworth__tick circle { transition-delay: 0.28s; }
.svcworth__grid li:nth-child(3) .svcworth__tick path { transition-delay: 0.78s; }

@media (max-width: 860px) { .svcworth__grid { grid-template-columns: 1fr; gap: 48px; } }
@media (prefers-reduced-motion: reduce) {
  .svcworth__tick circle, .svcworth__tick path { transition: none; stroke-dashoffset: 0; }
}

/* ---- comparison: the pitch, struck through, answered ------------------------
   The list is the grid, not the row. display:contents on each pair lets column
   one size to max-content across every row at once, so the claim column hugs the
   longest claim while the ticks still line up. Sizing per row would ragged the
   ticks; a fixed width would be a guess that breaks when the copy changes. */
.svcvs__list {
  margin-top: 32px; display: grid;
  grid-template-columns: max-content minmax(0, 1fr); column-gap: 48px;
  border-top: 1px solid var(--line-soft);
}
.svcvs__list.reveal { opacity: 1; transform: none; }   /* the rows carry the motion, not the container */
.svcvs__pair { display: contents; }
.svcvs__claim, .svcvs__real { padding: 16px 0; border-bottom: 1px solid var(--line-soft); }
.svcvs__pair:last-child .svcvs__claim,
.svcvs__pair:last-child .svcvs__real { border-bottom: 0; }
.svcvs__claim { font-size: 0.92rem; line-height: 1.5; color: var(--text-mute); }
.svcvs__strike { position: relative; display: inline-block; font-style: normal; }
.svcvs__strike::after {
  content: ""; position: absolute; left: 0; top: 52%; width: calc(100% + 24px); height: 1px;
  background: linear-gradient(90deg, var(--text-mute) 0, var(--text-mute) calc(100% - 24px), rgba(140, 134, 124, 0) 100%);
  transform: scaleX(0); transform-origin: left;
}
.svcvs__real {
  display: flex; gap: 12px;
  font-size: 1.02rem; line-height: 1.5; color: var(--text); font-weight: 500;
}
.svcvs__real::before {
  content: ""; flex: none; width: 18px; height: 18px; margin-top: 3px; background: var(--bronze);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Each row plays claim, then strike, then answer, and the rows follow one
   another. --i is set by the renderer so the cadence survives a change in row
   count. Transform and opacity only, so it stays off the main thread. */
.svcvs__pair { --b: calc(0.10s + var(--i, 0) * 0.42s); }
.svcvs__claim, .svcvs__real { opacity: 0; transform: translateX(-16px); }
.svcvs__claim { transition: opacity 0.52s var(--ease) var(--b), transform 0.52s var(--ease) var(--b); }
.svcvs__strike::after { transition: transform 0.44s var(--ease) calc(var(--b) + 0.28s); }
.svcvs__real {
  transition: opacity 0.52s var(--ease) calc(var(--b) + 0.44s),
              transform 0.52s var(--ease) calc(var(--b) + 0.44s);
}
.svcvs__list.in .svcvs__claim,
.svcvs__list.in .svcvs__real { opacity: 1; transform: none; }
.svcvs__list.in .svcvs__strike::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .svcvs__claim, .svcvs__real { opacity: 1; transform: none; transition: none; }
  .svcvs__strike::after { transition: none; transform: scaleX(1); }
}

/* ---- process step photos -----------------------------------------------------
   Same treatment as every other card photo here: locked ratio so a swap never
   reflows the row, greyscale at rest, colour when pointed at. */
.svcsteps li { display: flex; flex-direction: column; }
.svcstep__img { display: block; overflow: hidden; border-radius: 4px; background: var(--gray-2); margin-bottom: 16px; }
.svcstep__img img {
  /* 4 / 5 to match .step__media on the about page, so the two process rows share
     the same container height rather than one reading short against the other */
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; display: block;
  filter: grayscale(1);
  transition: filter 0.5s var(--ease), transform 0.9s var(--ease);
}
.svcsteps li:hover .svcstep__img img { filter: grayscale(0); transform: scale(1.02); }
@media (prefers-reduced-motion: reduce) {
  .svcsteps li:hover .svcstep__img img { transform: none; }
}

/* ---- card grids: responsive steps ------------------------------------------
   These must sit after the base definitions. An earlier cleanup removed the
   shared rules and the surviving ones were declared before the bases, so the
   four column base was winning at every width. */
@media (max-width: 1080px) {
  .svcwho__grid, .svcgets__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .svcwho__grid, .svcgets__grid, .svcsteps { grid-template-columns: 1fr; }
}

/* ---- hero mesh, rebuilt ------------------------------------------------------
   Drawn with repeating gradients rather than a thousand divs, and sized far past
   the hero so the skew cannot expose a bare corner. The mask fades every edge, so
   the grid dissolves into the page instead of stopping at a hard line. */
.svchero__mesh-wrap {
  position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  -webkit-mask-image: radial-gradient(82% 92% at 50% 46%, #000 26%, rgba(0, 0, 0, 0.55) 62%, transparent 92%);
          mask-image: radial-gradient(82% 92% at 50% 46%, #000 26%, rgba(0, 0, 0, 0.55) 62%, transparent 92%);
}
.svchero__mesh {
  position: absolute; top: 50%; left: 50%;
  width: 280%; height: 320%;          /* generous: the skew eats a lot of the box */
  transform: translate(-50%, -50%) skewX(-48deg) skewY(14deg);
  background-image:
    repeating-linear-gradient(to right, rgba(86, 79, 69, 0.13) 0 1px, transparent 1px 64px),
    repeating-linear-gradient(to bottom, rgba(86, 79, 69, 0.13) 0 1px, transparent 1px 34px);
}
/* one cell that jumps around, so the grid breathes without a node per cell */
.svchero__spark {
  position: absolute; width: 64px; height: 34px;
  background: rgba(176, 140, 96, 0.22);
  opacity: 0; transition: opacity 1.2s ease;
}
@media (prefers-reduced-motion: reduce) { .svchero__spark { display: none; } }

/* no panel any more, so the copy takes the section on its own */
.svchero { min-height: 62vh; display: grid; align-items: center; }
.svchero__grid { display: block; }
/* the panel is gone, so the copy owns the section: give it room rather than
   leaving it pinned in a narrow column against a wide hero */
.svchero__copy { max-width: min(920px, 100%); }
.svchero .svcpage__tagline { max-width: 48ch; }
.svchero .svcpage__trust { max-width: 46ch; }   /* 62ch measured 74 characters, over the 65 cap */

/* the lit cell under the pointer. A pool of these is cycled, so a trail forms the
   way it does on the home page grid, without a node per cell. */
.svchero__hot {
  position: absolute; width: 64px; height: 34px;
  background: rgba(176, 140, 96, 0.30);
  opacity: 0; pointer-events: none;
  transition: opacity 1.8s ease;
}
@media (prefers-reduced-motion: reduce) { .svchero__hot { display: none; } }

/* ---- section 4: the research leads ------------------------------------------
   The GEO percentages were buried mid paragraph. They are the strongest evidence
   on the page, so they open the section. Set below the hero headline on purpose:
   this is the second loudest moment, not the first. */
.svcvs__lead { margin-top: 32px; max-width: 64ch; font-size: clamp(0.98rem, 1.4vw, 1.12rem); line-height: 1.65; color: var(--text-body); }
.svcvs__lead strong { color: var(--text); font-weight: 500; }
.svcvs__figures {
  list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  margin-top: 32px; padding-bottom: 28px; border-bottom: 1px solid var(--line);
}
.svcvs__fn { display: block; font-family: var(--serif); font-size: clamp(2rem, 3.6vw, 2.9rem); line-height: 1; color: var(--bronze); font-variant-numeric: tabular-nums; }
.svcvs__fk { display: block; margin-top: 10px; font-size: 0.78rem; line-height: 1.5; color: var(--text-body); max-width: 24ch; }
.svcvs__source { margin-top: 16px; font-size: 0.75rem; line-height: 1.6; color: var(--text-body); }

/* ---- section 7: the dashboard, and what lands in it ------------------------- */
.svcproof__split { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(24px, 4vw, 48px); align-items: center; margin-top: var(--head-gap); }
.svcproof__lead { font-size: clamp(0.98rem, 1.4vw, 1.12rem); line-height: 1.65; color: var(--text-body); max-width: 54ch; }
.svcproof__lead strong { color: var(--text); font-weight: 500; }
.svcproof__chips { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.svcproof__chips li {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 14px; border: 1px solid var(--line); background: #fff;
  font-size: 0.8rem; line-height: 1.3; color: var(--text);
  transition: border-color 0.25s var(--ease), transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.svcproof__chips svg { width: 15px; height: 15px; flex: none; fill: var(--bronze); display: block; }
.svcproof__chips li:hover { border-color: var(--bronze); transform: translateY(-2px); box-shadow: 0 8px 18px -10px rgba(24, 22, 18, 0.32); }
.svcproof__notes { margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--line); display: grid; gap: 12px; }
.svcproof__note { font-size: 0.82rem; line-height: 1.65; color: var(--text-body); }
.svcproof__note b { color: var(--text); font-weight: 500; }

@media (max-width: 900px) {
  .svcvs__figures { grid-template-columns: 1fr; gap: 20px; }
  .svcvs__list { grid-template-columns: 1fr; column-gap: 0; }
  .svcvs__claim { padding: 16px 0 0; border-bottom: 0; }
  .svcvs__real { padding: 8px 0 16px; }
  .svcproof__split { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) { .svcproof__chips li:hover { transform: none; } }


/* ---- symptoms list --------------------------------------------------------
   Sits between the 'who' cards and the process steps, so it is deliberately
   not a third card grid. A hairline per item with a bronze lead-in segment. */
.svcpoint__list { list-style: none; display: grid; gap: 24px; margin-top: 48px; }
.svcpoint__list li { position: relative; padding-top: 16px; border-top: 1px solid var(--line); font-size: 0.95rem; line-height: 1.6; color: var(--text-body); }
.svcpoint__list li::before { content: ""; position: absolute; top: -1px; left: 0; width: 32px; height: 1px; background: var(--bronze); }

/* ---- comparison table -----------------------------------------------------
   A real table: the rows are comparable facts and answer engines lift them as
   pairs. The 'ours' column sits on white so the eye lands there. */
.svccmp__wrap { margin-top: 48px; overflow-x: auto; }
.svccmp__table { width: 100%; min-width: 680px; border-collapse: collapse; }
.svccmp__table th, .svccmp__table td { text-align: left; vertical-align: top; padding: 16px; font-size: 0.92rem; line-height: 1.55; font-weight: 400; }
.svccmp__table thead th { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-mute); border-bottom: 1px solid var(--line); }
.svccmp__table tbody th, .svccmp__table tbody td { border-bottom: 1px solid var(--line-soft); }
.svccmp__table tbody tr:last-child th, .svccmp__table tbody tr:last-child td { border-bottom: 0; }
.svccmp__k { color: var(--text); font-weight: 500 !important; width: 22%; }
.svccmp__a { color: var(--text-mute); }
.svccmp__b { color: var(--text); background: #fff; }
.svccmp__hb { background: #fff; color: var(--bronze) !important; }

/* ---- platforms: the who-card grid at three across ---- */
.svcplat .svcwho__grid { grid-template-columns: repeat(3, 1fr); }

/* ---- work tagged to this service ---- */
.svcwork__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px; margin-top: 48px; }

/* ---- trust and E-E-A-T ---- */

@media (max-width: 900px) {
  .svcpoint__list, .svccred__grid { grid-template-columns: 1fr; gap: 24px; }
  .svcplat .svcwho__grid { grid-template-columns: 1fr; }
  .svcwork__grid { grid-template-columns: 1fr; gap: 16px; }
}


/* ---- band rhythm for the blocks added with the webdev page -----------------
   Every service section carries its own padding-block; these four shipped
   without it and sat flush against their neighbours. 64px is the value the
   surrounding content bands use. Tones alternate paper/gray down the page. */
.svcpoint { padding-block: 64px; }
.svccmp   { padding-block: 64px; }
.svcwork  { padding-block: 64px; }


/* ---- images for the pointer, platform and trust cards ----------------------
   These three shipped as bare text. The site's containers are image led, so
   they take the same 16:10 grayscale slot the who and gets cards use. */
.svcpoint__list { grid-template-columns: repeat(4, 1fr); gap: 24px; }
.svcpoint__img {
  display: block; overflow: hidden; border-radius: 4px;
  background: var(--gray-2); margin-bottom: 16px;
}
.svcpoint__img img {
  width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; display: block;
  filter: grayscale(1);
  transition: filter 0.5s var(--ease), transform 0.9s var(--ease);
}
.svcpoint__list li:hover .svcpoint__img img { filter: grayscale(0); transform: scale(1.02); }
.svcpoint__t { display: block; font-size: 0.92rem; line-height: 1.6; color: var(--text-body); }

/* the discarded column of the comparison table reads as struck through */
.svccmp__a { text-decoration: line-through; text-decoration-color: rgba(140, 134, 124, 0.55); text-decoration-thickness: 1px; }

@media (max-width: 900px) {
  .svcpoint__list { grid-template-columns: 1fr; gap: 24px; }
}
@media (prefers-reduced-motion: reduce) {
  .svcpoint__list li:hover .svcpoint__img img { transform: none; }
}

/* Other services can follow either tone depending on what a service has
   written, so it carries its own divider rather than relying on a tone change. */


/* ---- trust block: the worth treatment, four across -------------------------
   Reuses .svcworth outright. Only the things that genuinely differ are set
   here: a centred lead, four columns instead of three, and a fourth step in
   the tick sequence. */
/* The trust grid takes its column count from how many items it has. Fixed at
   four, a three item block sat in the first three columns and read as left
   aligned inside a centred section. */
.svccred .svcworth__grid { max-width: 700px; gap: 40px; }
/* Column counts are desktop only. Left unscoped they outrank the mobile stack
   below, which is how three items ended up in three cramped columns at 376px. */
@media (min-width: 861px) {
  .svccred .svcworth__grid { grid-template-columns: repeat(2, 1fr); }
  .svccred .svcworth__grid:has(> li:nth-child(3)) { grid-template-columns: repeat(3, 1fr); max-width: 1000px; }
  .svccred .svcworth__grid:has(> li:nth-child(4)) { grid-template-columns: repeat(4, 1fr); max-width: 1240px; }
}
.svcworth__grid li:nth-child(4) .svcworth__tick circle { transition-delay: 0.42s; }
.svcworth__grid li:nth-child(4) .svcworth__tick path { transition-delay: 0.92s; }
@media (max-width: 1100px) { .svccred .svcworth__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 860px)  { .svccred .svcworth__grid { grid-template-columns: 1fr; } }

/* Which sections a service page shows varies, so a fixed tone cannot alternate
   for every ordering. These two can land next to a band of their own tone, so
   they carry their own divider, the same way .svcwork and .svcpage__more do. */


/* ---- mobile: brand strip runs as one marquee row -------------------------- */
.svclogos__row li.is-dup { display: none; }
@media (max-width: 640px) {
  .svclogos { overflow: hidden; }
  .svclogos__row {
    --bg: 32px;
    display: flex; width: max-content; gap: var(--bg);
    grid-template-columns: none;
    animation: svclogos-marquee 20s linear infinite;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
            mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  }
  /* explicit sizes: a percentage or auto width inside a max-content track is
     circular and collapses the logo to zero, which empties the marquee */
  .svclogos__row li { flex: 0 0 132px; width: 132px; padding: 8px 0; }
  .svclogos__row li.is-dup { display: flex; }
  .svclogos__row svg, .svclogos__row img { width: 132px; height: 26px; max-height: none; object-fit: contain; object-position: left center; }
}
/* half the track plus half a gap is exactly one set, so the loop has no seam */
@keyframes svclogos-marquee { to { transform: translateX(calc(-50% - 16px)); } }

/* ---- mobile: the process runs as a scroll-snap carousel ------------------- */
.svcsteps__dots { display: none; }
@media (max-width: 640px) {
  .svcsteps {
    grid-template-columns: none;
    display: flex; gap: 16px;
    overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .svcsteps::-webkit-scrollbar { display: none; }
  .svcsteps > li { flex: 0 0 80%; scroll-snap-align: start; }
  .svcsteps__dots { display: flex; justify-content: center; gap: 8px; margin-top: 16px; }
  .svcsteps__dot {
    width: 8px; height: 8px; padding: 0; cursor: pointer;
    border: 1px solid var(--line); background: transparent;
    transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
  }
  .svcsteps__dot.is-on { background: var(--bronze); border-color: var(--bronze); }
}

/* ---- mobile: tick blocks stack, one per row ------------------------------- */
@media (max-width: 860px) {
  .svcworth__grid, .svccred .svcworth__grid { grid-template-columns: 1fr; gap: 40px; max-width: 420px; }
}
@media (prefers-reduced-motion: reduce) {
  .svclogos__row { animation: none; }
}


/* ---- band tone -------------------------------------------------------------
   Assigned by the renderer, by position among the visible sections, because
   which sections a service page shows varies. Alternating over what is actually
   on the page means two bands of one tone never meet and no divider is needed. */
/* any content view whose tones are assigned at render, not just the service page */
.view[data-route="service"] section.band-gray,
.view[data-route="guide"] section.band-gray { background: var(--gray); }

.svcvs__source a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--line); transition: text-decoration-color 0.25s var(--ease); }
.svcvs__source a:hover { text-decoration-color: var(--bronze); }


/* ==========================================================================
   Supporting (sub-service) page
   ========================================================================== */

/* ---- hero: the service grid and aurora, but centred ---------------------- */
.gdhero__copy { max-width: 880px; margin-inline: auto; text-align: center; }
.gdhero__parent {
  display: inline-block; margin-bottom: 20px;
  font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--text-mute); text-decoration: none;
  transition: color 0.25s var(--ease);
}
.gdhero__parent::before { content: ""; display: inline-block; width: 24px; height: 1px; background: var(--bronze); vertical-align: middle; margin-right: 10px; }
.gdhero__parent:hover { color: var(--bronze); }
.gdhero__title {
  font-family: var(--serif); font-size: clamp(1.9rem, 4.2vw, 3.2rem);
  line-height: 1.1; letter-spacing: -0.02em; color: var(--text); text-wrap: balance;
}
.gdhero__lede {
  margin-top: 24px; font-size: clamp(1rem, 1.6vw, 1.2rem); line-height: 1.6;
  color: var(--text-body); max-width: 68ch; margin-inline: auto;
}
.gdhero__sub {
  margin-top: 16px; font-size: 0.92rem; line-height: 1.7;
  color: var(--text-mute); max-width: 62ch; margin-inline: auto;
}
.gdhero__cta { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 32px; }

/* ---- the definition, set large. This is the paragraph an engine lifts ----- */
.gdcapsule { padding-block: 96px; }
.gdcapsule__grid { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(32px, 5vw, 64px); align-items: center; }
.gdcapsule__img { display: block; overflow: hidden; border-radius: 4px; background: var(--gray-2); }
.gdcapsule__img img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; display: block;
  filter: grayscale(1); transition: filter 0.5s var(--ease), transform 0.9s var(--ease);
}
.gdcapsule__img:hover img { filter: grayscale(0); transform: scale(1.02); }
.gdcapsule__title {
  font-family: var(--serif); font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  line-height: 1.2; color: var(--text);
}
.gdcapsule__body {
  margin-top: 24px; max-width: 60ch;
  font-size: clamp(1rem, 1.4vw, 1.1rem); line-height: 1.7; color: var(--text-body);
}
.gdcapsule__caveat {
  margin-top: 24px; max-width: 58ch;
  padding: 16px 24px; border-left: 2px solid var(--bronze); background: #fff;
  font-size: 0.86rem; line-height: 1.7; color: var(--text-body);
}

/* ---- three way comparison ------------------------------------------------ */
.gdcmp { padding-block: 64px; }
.gdcmp__wrap { margin-top: 48px; overflow-x: auto; }
.gdcmp__table { width: 100%; min-width: 820px; border-collapse: collapse; }
.gdcmp__table th, .gdcmp__table td {
  text-align: left; vertical-align: top; padding: 16px;
  font-size: 0.9rem; line-height: 1.55; font-weight: 400;
}
.gdcmp__table thead th {
  font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-mute); border-bottom: 1px solid var(--line);
}
.gdcmp__hmine { background: #fff; color: var(--bronze) !important; }
.gdcmp__table tbody th, .gdcmp__table tbody td { border-bottom: 1px solid var(--line-soft); }
.gdcmp__table tbody tr:last-child th, .gdcmp__table tbody tr:last-child td { border-bottom: 0; }
.gdcmp__k { color: var(--text); font-weight: 500 !important; width: 20%; }
.gdcmp__mine { background: #fff; color: var(--text); }
.gdcmp__notes { list-style: none; margin-top: 32px; display: grid; gap: 12px; max-width: 92ch; }
.gdcmp__notes li { position: relative; padding-left: 20px; font-size: 0.82rem; line-height: 1.7; color: var(--text-body); }
.gdcmp__notes li::before { content: ""; position: absolute; left: 0; top: 10px; width: 8px; height: 1px; background: var(--bronze); }
.gdcmp__notes a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--line); }
.gdcmp__notes a:hover { text-decoration-color: var(--bronze); }

/* ---- inline CTA strip: breaks the reading, twice ------------------------- */
.gdcta { padding-block: 48px; }
.gdcta__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 32px; border: 1px solid var(--line); background: #fff;
}
.gdcta__text { font-family: var(--serif); font-size: clamp(1.05rem, 1.8vw, 1.35rem); line-height: 1.35; color: var(--text); max-width: 46ch; }

/* ---- the three layers ---------------------------------------------------- */
.gdcards { padding-block: 64px; }
.gdcards__grid { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 32px; margin-top: 48px; }
.gdcards__grid li { display: flex; flex-direction: column; }
.gdcards__n { display: flex; align-items: baseline; gap: 12px; font-family: var(--serif); font-size: 1.1rem; line-height: 1.3; color: var(--text); }
.gdcards__n i { font-style: normal; font-size: 0.75rem; letter-spacing: 0.08em; color: var(--bronze); }
.gdcards__d { display: block; margin-top: 12px; font-size: 0.88rem; line-height: 1.7; color: var(--text-body); }
.gdcards__src { display: block; margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 0.72rem; line-height: 1.6; color: var(--text-mute); }

/* ---- myth and fact ------------------------------------------------------- */
.gdmyth { padding-block: 64px; }
.gdmyth__close { margin-top: 32px; max-width: 82ch; font-size: 0.92rem; line-height: 1.7; color: var(--text-body); }

/* ---- trust: the tick tiles, with a lead and a closing line --------------- */
.gdtrust__close { margin: 48px auto 0; max-width: 74ch; text-align: center; font-size: 0.92rem; line-height: 1.7; color: var(--text-body); }

/* ---- FAQ: answers visible, two columns, no accordion -------------------- */
.gdfaq { padding-block: 64px; }
.gdfaq__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 32px 48px; margin-top: 48px; }
.gdfaq__item { padding-top: 16px; border-top: 1px solid var(--line); }
.gdfaq__q { font-family: var(--serif); font-size: 1.02rem; line-height: 1.35; color: var(--text); }
.gdfaq__a { margin-top: 10px; font-size: 0.88rem; line-height: 1.75; color: var(--text-body); }

@media (max-width: 1000px) {
  .gdcards__grid { grid-template-columns: 1fr; gap: 40px; }
}
@media (max-width: 860px) {
  .gdfaq__grid { grid-template-columns: 1fr; gap: 24px; }
  .gdcta__inner { flex-direction: column; align-items: flex-start; padding: 24px; }
  .gdcapsule { padding-block: 64px; }
  .gdtrust__close { text-align: left; }
  .gdcapsule__grid { grid-template-columns: 1fr; gap: 32px; }
  .gdhero__copy { text-align: left; }
  .gdhero__lede, .gdhero__sub { margin-inline: 0; }
  .gdhero__cta { justify-content: flex-start; }
}

/* contact details, moved out of the column that now lists sub-services */
.footer__contact { list-style: none; margin-top: 16px; display: grid; gap: 8px; }
.footer__contact a { font-size: 0.85rem; color: var(--text-body); text-decoration: none; transition: color 0.25s var(--ease); }
.footer__contact a:hover { color: var(--bronze); }


/* ---- supporting page: process as plain pointers ------------------------- */
.gdsteps { padding-block: 64px; }
.gdsteps__list { list-style: none; margin-top: 48px; max-width: 900px; }
.gdsteps__list li {
  display: grid; grid-template-columns: 48px 1fr; gap: 24px; align-items: start;
  padding: 24px 0; border-top: 1px solid var(--line);
}
.gdsteps__list li:last-child { border-bottom: 1px solid var(--line); }
.gdsteps__n { font-size: 0.78rem; letter-spacing: 0.1em; color: var(--bronze); padding-top: 3px; }
.gdsteps__name { display: block; font-size: 1rem; line-height: 1.35; color: var(--text); font-weight: 500; }
.gdsteps__d { display: block; margin-top: 6px; font-size: 0.9rem; line-height: 1.7; color: var(--text-body); }
.gdsteps__note { margin-top: 32px; max-width: 82ch; font-size: 0.85rem; line-height: 1.7; color: var(--text-body); }

/* ---- supporting page: myth and fact, as a list not a table -------------- */
.gdmyth__list { list-style: none; margin-top: 48px; max-width: 900px; }
.gdmyth__list li { padding: 24px 0; border-top: 1px solid var(--line); }
.gdmyth__list li:last-child { border-bottom: 1px solid var(--line); }
.gdmyth__claim {
  display: block; font-size: 0.88rem; line-height: 1.5; color: var(--text-mute);
  text-decoration: line-through; text-decoration-color: rgba(140, 134, 124, 0.5); text-decoration-thickness: 1px;
}
.gdmyth__fact { display: block; margin-top: 8px; font-size: 0.98rem; line-height: 1.7; color: var(--text); }

@media (max-width: 640px) {
  .gdsteps__list li { grid-template-columns: 1fr; gap: 8px; }
  .gdsteps__n { padding-top: 0; }
}

@media (prefers-reduced-motion: reduce) { .gdcapsule__img:hover img { transform: none; } }


/* ---- supporting page: the team ------------------------------------------ */
.gdpeople { padding-block: 64px; }
.gdpeople__grid { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 32px; margin-top: 48px; }
.gdpeople__img { display: block; overflow: hidden; border-radius: 4px; background: var(--gray-2); margin-bottom: 16px; }
.gdpeople__img img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; display: block;
  filter: grayscale(1); transition: filter 0.5s var(--ease);
}
.gdpeople__grid li:hover .gdpeople__img img { filter: grayscale(0); }
.gdpeople__n { display: block; font-family: var(--serif); font-size: 1.05rem; line-height: 1.3; color: var(--text); }
.gdpeople__role { display: block; margin-top: 4px; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--bronze); }
.gdpeople__d { display: block; margin-top: 12px; font-size: 0.88rem; line-height: 1.7; color: var(--text-body); }


/* ---- [hidden] must win ------------------------------------------------------
   Any rule setting an explicit display beats the browser default for [hidden].
   That shipped once as an empty grey image box on 25 pages. */
[hidden] { display: none !important; }

/* ---- supporting page: process, two columns with the picture on the right --- */
.gdsteps__grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: clamp(32px, 5vw, 64px); align-items: center; }
.gdsteps__img { display: block; overflow: hidden; border-radius: 4px; background: var(--gray-2); }
.gdsteps__img img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; display: block;
  filter: grayscale(1); transition: filter 0.5s var(--ease), transform 0.9s var(--ease);
}
.gdsteps__img:hover img { filter: grayscale(0); transform: scale(1.02); }
.gdsteps__list { max-width: none; }

/* ---- cards that will not fit a row scroll instead of orphaning ------------- */
.gdcards__dots { display: none; }
.gdcards__grid.is-carousel {
  display: flex; gap: 24px; overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; -ms-overflow-style: none;
  grid-template-columns: none;
}
.gdcards__grid.is-carousel::-webkit-scrollbar { display: none; }
.gdcards__grid.is-carousel > li { flex: 0 0 clamp(260px, 30%, 340px); scroll-snap-align: start; }
.gdcards__grid.is-carousel + .gdcards__dots { display: flex; justify-content: center; gap: 8px; margin-top: 24px; }
.gdcards__dot {
  width: 8px; height: 8px; padding: 0; cursor: pointer;
  border: 1px solid var(--line); background: transparent;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.gdcards__dot.is-on { background: var(--bronze); border-color: var(--bronze); }

@media (max-width: 860px) {
  .gdsteps__grid { grid-template-columns: 1fr; gap: 32px; }
  .gdsteps__img { order: -1; }                 /* picture leads on a phone */
  .gdcapsule__img { order: -1; }
}
@media (max-width: 640px) {
  .gdcards__grid { display: flex; gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
  .gdcards__grid::-webkit-scrollbar { display: none; }
  .gdcards__grid > li { flex: 0 0 80%; scroll-snap-align: start; }
}
@media (prefers-reduced-motion: reduce) { .gdsteps__img:hover img { transform: none; } }


/* ---- supporting page: myth list beside a picture ------------------------- */
.gdmyth__grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: clamp(32px, 5vw, 64px); align-items: center; margin-top: 48px; }
.gdmyth__list { margin-top: 0; max-width: none; }
.gdmyth__img { display: block; overflow: hidden; border-radius: 4px; background: var(--gray-2); }
.gdmyth__img img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; display: block;
  filter: grayscale(1); transition: filter 0.5s var(--ease), transform 0.9s var(--ease);
}
.gdmyth__img:hover img { filter: grayscale(0); transform: scale(1.02); }
@media (max-width: 860px) {
  .gdmyth__grid { grid-template-columns: 1fr; gap: 32px; }
  .gdmyth__img { order: -1; }
}
@media (prefers-reduced-motion: reduce) { .gdmyth__img:hover img { transform: none; } }


/* ---- Resources mega menu ------------------------------------------------- */
.navdrop--wide {
  min-width: min(760px, 78vw); padding: 20px;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px 24px;
}
.navdrop__col { display: flex; flex-direction: column; gap: 2px; }
.navdrop__head {
  font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45); padding: 6px 10px 8px;
}

/* ---- Resource Centre hub ------------------------------------------------- */
.rescentre { padding-block: clamp(2.6rem, 5vw, 4.2rem); }
.rescentre__group + .rescentre__group { margin-top: 64px; }

@media (max-width: 1080px) { .navdrop--wide { grid-template-columns: repeat(2, 1fr); min-width: min(520px, 84vw); } }


/* ---- Resource Centre: a row list, so a short group leaves no empty cells --- */
.rescentre__group + .rescentre__group { margin-top: 64px; }
/* two columns with a rule down the middle, as a section index does it */
.reslist {
  list-style: none; margin-top: 32px; position: relative;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 64px;
}
.reslist::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: calc(50% - 0.5px);
  width: 1px; background: var(--line-soft);
}
.reslist__item.is-more { display: none; }
.rescentre__group.is-open .reslist__item.is-more { display: list-item; }
.reslist__row {
  display: block; padding: 20px 0; border-bottom: 1px solid var(--line-soft);
  text-decoration: none; color: inherit;
}
.reslist__meta {
  display: block; font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-mute); margin-bottom: 6px;
}
.reslist__title {
  display: block; position: relative; padding-right: 26px;
  font-size: 1.05rem; line-height: 1.35; color: var(--text);
  text-decoration: none; transition: color 0.25s var(--ease);
}
/* the same forward arrow the other-services cards and linked scope cards use */
.reslist__title::after {
  content: ""; position: absolute; right: 0; top: 0.32em; width: 14px; height: 14px;
  background: var(--bronze); opacity: 0.5;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M16.172 11l-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M16.172 11l-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.25s var(--ease), opacity 0.25s var(--ease);
}
.reslist__row:hover .reslist__title::after { opacity: 1; transform: translateX(3px); }
.reslist__row:hover .reslist__title { color: var(--bronze); }
.reslist__row:hover .reslist__meta { color: var(--text-body); }
.reslist__d { display: block; margin-top: 8px; font-size: 0.88rem; line-height: 1.65; color: var(--text-body); max-width: 78ch; }

@media (max-width: 700px) {
  .reslist__row { grid-template-columns: 1fr; gap: 8px; }
  .reslist__meta { padding-top: 0; }
}


/* Two paper sections meeting stack their padding into one large void, which is
   what read as a stray white band under the articles. The hub drops its top
   padding when something precedes it. */
.block + .rescentre { padding-top: 0; }


/* ---- related page strips ------------------------------------------------- */
.svcrelated { padding-block: 64px; }
.svcrelated .svcpage__morelist { margin-top: 48px; }

/* a scope card that leads somewhere shows it, and behaves like a link */
.svcgets__card--link, .svcwho__link { text-decoration: none; color: inherit; display: flex; flex-direction: column; }
.svcgets__card--link .svcgets__n, .svcwho__link .svcwho__n { position: relative; padding-right: 22px; }
.svcgets__card--link .svcgets__n::after, .svcwho__link .svcwho__n::after {
  content: ""; position: absolute; right: 0; top: 0.35em; width: 13px; height: 13px;
  background: var(--bronze); opacity: 0.55;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M16.172 11l-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M16.172 11l-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.25s var(--ease), opacity 0.25s var(--ease);
}
.svcgets__card--link:hover .svcgets__n::after, .svcwho__link:hover .svcwho__n::after { opacity: 1; transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .svcgets__card--link:hover .svcgets__n::after, .svcwho__link:hover .svcwho__n::after { transform: none; }
}


/* the control that opens the rest of a group */
.reslist__more {
  margin-top: 24px; padding: 10px 18px; cursor: pointer;
  background: transparent; border: 1px solid var(--line);
  font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-body);
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.reslist__more span { color: var(--bronze); margin-left: 4px; }
.reslist__more:hover { border-color: var(--bronze); color: var(--text); }

@media (max-width: 860px) {
  .reslist { grid-template-columns: 1fr; column-gap: 0; }
  .reslist::before { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .reslist__row:hover .reslist__title::after { transform: none; }
}
