/* ===============================================================
   Ecomatrix GmbH — agency site + Westmonth case study
   ---------------------------------------------------------------
   Type:   Space Grotesk (display) · Inter (prose) · IBM Plex Mono
           (labels only). Every stack ends in sans-serif.
   Weight: 400 / 500 / 700. Nothing in between — non-standard
           weights get faux-bolded and read as a different font.
   Colour: near-black ground, one violet accent. The accent carries
           every interactive and every number; nothing else is
           coloured, which is what keeps it from looking busy.
   Motion: transform + opacity only. Killed by prefers-reduced-motion
           and by ?still=1 (used for screenshots).
   =============================================================== */

:root {
  --bg:         #06060A;
  --bg-2:       #0A0A11;
  --surface:    #0F0F17;
  --surface-2:  #16161F;
  --ink:        #FFFFFF;
  --ink-2:      #C9C9D6;
  --muted:      #82828F;
  --accent:     #7B5CFF;
  --accent-hi:  #A78BFF;
  --accent-ink: #0A0614;
  --rule:       rgba(255, 255, 255, 0.09);
  --rule-2:     rgba(255, 255, 255, 0.16);

  --display: "Space Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --sans:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --t-label:   0.75rem;
  --t-small:   0.9375rem;
  --t-body:    1.0625rem;
  --t-h3:      1.25rem;
  --t-h2:      clamp(2rem, 4.2vw, 3.25rem);
  --t-display: clamp(2.6rem, 6.4vw, 5rem);
  --t-mega:    clamp(3rem, 9vw, 7rem);

  --wrap:  1180px;
  --prose: 660px;

  --ease: cubic-bezier(0.22, 0.7, 0.3, 1);
  --r:    16px;
}

/* Registered so the conic border angle can be animated. Where
   @property is unsupported the border simply shows without rotating. */
@property --a {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 90px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A single grain layer over the whole page. It sits above the glows
   and below the content, which is what stops large flat gradients
   from banding on cheap panels. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.16;
  /* own compositor layer — a fixed overlay that is not promoted forces
     the content underneath to repaint on every scrolled frame */
  transform: translateZ(0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

main, header, footer, section { position: relative; z-index: 2; }

img, video { max-width: 100%; display: block; }
strong, b { font-weight: 700; color: var(--ink); }
a { color: var(--accent-hi); }

::selection { background: var(--accent); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent-hi);
  outline-offset: 3px;
  border-radius: 4px;
}

/* --- layout ----------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 28px;
}

section { padding: 104px 0; }

.rule-top { border-top: 1px solid var(--rule); }

.center { text-align: center; }
.center .beat, .center .lede { margin-left: auto; margin-right: auto; }

/* --- type ------------------------------------------------------- */

h1, h2, h3, .stat-num, .kpi-num {
  font-family: var(--display);
  color: var(--ink);
}

h1 {
  font-size: var(--t-display);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.035em;
  margin: 0 0 24px;
}

h2 {
  font-size: var(--t-h2);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.03em;
  margin: 0 0 18px;
}

h3 {
  font-size: var(--t-h3);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
}

/* Headline words slide up out of their own clipped line. The clip is
   on .w, the movement on the <i> inside it — one element cannot both
   hide the overflow and move through it. */
.words .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  /* descenders (g, y) would otherwise be shaved off by the clip */
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}

.words .w i { display: inline-block; font-style: normal; }

.js .words .w i {
  transform: translateY(115%);
  transition: transform 0.95s var(--ease);
  transition-delay: var(--d, 0s);
}
.js .words.in .w i { transform: none; }

/* the one decorative move in the type: accent-filled words */
.grad {
  background: linear-gradient(96deg, #D9CCFF 2%, #B49BFF 45%, #8FB4FF 98%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.label {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent-hi);
  margin: 0 0 18px;
}

.label--muted { color: var(--muted); }

.lede {
  font-size: 1.125rem;
  color: var(--muted);
  max-width: var(--prose);
  margin: 0 0 40px;
  line-height: 1.55;
}

/* One sentence per line. The whole page reads on the skim. */
.beat { margin: 0 0 28px; max-width: var(--prose); color: var(--ink-2); }
.beat p { margin: 0 0 6px; }
.beat p:last-child { margin-bottom: 0; }
.beat--tight p { margin-bottom: 2px; }

.quote { color: var(--muted); font-style: italic; }

.block { margin-bottom: 48px; }
.block:last-child { margin-bottom: 0; }
.after-split { margin-top: 48px; }

.note {
  color: var(--muted);
  font-size: var(--t-small);
  max-width: var(--prose);
  margin: 0;
}

/* --- buttons ---------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-size: var(--t-body);
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
  padding: 15px 28px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--ink);
  color: #08080D;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease),
              background-color 0.3s var(--ease), border-color 0.3s var(--ease);
}

.btn .arw { transition: transform 0.3s var(--ease); }
.btn:hover { transform: translateY(-2px); box-shadow: 0 14px 40px rgba(123, 92, 255, 0.35); }
.btn:hover .arw { transform: translateX(4px); }

.btn--accent { background: var(--accent); color: #fff; }
.btn--accent:hover { background: var(--accent-hi); }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--rule-2);
}
.btn--ghost:hover { border-color: var(--accent); background: rgba(123, 92, 255, 0.08); }

.btn--bare {
  background: transparent;
  color: var(--ink);
  border-color: transparent;
  padding: 15px 8px;
}
.btn--bare:hover { box-shadow: none; color: var(--accent-hi); }

/* --- scroll progress -------------------------------------------- */

.progress {
  position: fixed;
  top: 0; left: 0;
  z-index: 90;
  height: 2px;
  width: 100%;
  transform: scaleX(var(--p, 0));
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--accent), var(--accent-hi) 60%, #8FB4FF);
  box-shadow: 0 0 14px rgba(123, 92, 255, 0.9);
  pointer-events: none;
}

/* --- rotating conic border on cards ------------------------------ */
/* A 1px ring drawn as a conic gradient, masked so only the border box
   shows. It spins while the pointer is on the card. */
.kpi::after, .case::after, .svc::after, .cmp__col::after, .cta-band::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--a),
              transparent 0 62%, var(--accent-hi) 78%, #8FB4FF 86%, transparent 94%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}

.kpi:hover::after, .case:hover::after, .svc:hover::after, .cmp__col:hover::after {
  opacity: 1;
  animation: spin 3.4s linear infinite;
}

.cta-band::after { opacity: 0.85; animation: spin 9s linear infinite; }

@keyframes spin { to { --a: 360deg; } }

/* --- nav -------------------------------------------------------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  border-bottom: 1px solid transparent;
  transition: background-color 0.35s var(--ease), border-color 0.35s var(--ease),
              backdrop-filter 0.35s var(--ease);
}

/* backdrop-filter is re-evaluated on every scrolled frame, so the
   background does most of the work and the blur is only a hint of
   depth on top of it. */
.nav.stuck {
  background: rgba(6, 6, 10, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom-color: var(--rule);
}

.nav__in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  height: 74px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: var(--ink);
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.03em;
}

.brand__mark {
  width: 30px; height: 30px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  background: linear-gradient(140deg, var(--accent-hi), var(--accent));
  color: #fff;
  font-size: 0.9375rem;
  font-weight: 700;
  box-shadow: 0 0 24px rgba(123, 92, 255, 0.5);
}

.nav__links { display: flex; align-items: center; gap: 28px; }

.nav__links a {
  font-size: var(--t-small);
  color: var(--muted);
  text-decoration: none;
  transition: color 0.25s var(--ease);
}
.nav__links a:hover { color: var(--ink); }

.nav .btn { padding: 11px 20px; font-size: var(--t-small); }

/* --- hero ------------------------------------------------------- */

.hero {
  position: relative;
  padding: 96px 0 72px;
  overflow: hidden;
  isolation: isolate;
  text-align: center;
}

/* A dark bed under the headline. The glow has to be bright at the
   edges to read as light, but bright behind type kills the contrast —
   this scrim keeps the wash and gives the words something to sit on. */
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 56% 44% at 50% 42%,
              rgba(6, 6, 10, 0.82), rgba(6, 6, 10, 0.34) 62%, transparent 78%);
}

/* the glow: one big violet wash, slowly breathing */
/* No filter: blur() here on purpose. A blurred layer has to be
   re-rasterised on every step of an animated transform, which is the
   expensive kind of smooth. Wide radial falloffs give the same soft
   edge for free, and the grain overlay hides any banding. */
.hero__glow {
  position: absolute;
  z-index: -2;
  left: 50%;
  top: -320px;
  width: min(1500px, 160vw);
  aspect-ratio: 1;
  transform: translate3d(-50%, 0, 0);
  background:
    radial-gradient(circle at 50% 40%, rgba(139, 108, 255, 0.62), rgba(139, 108, 255, 0.16) 30%, transparent 55%),
    radial-gradient(circle at 70% 30%, rgba(112, 76, 255, 0.48), rgba(112, 76, 255, 0.12) 28%, transparent 52%),
    radial-gradient(circle at 32% 52%, rgba(91, 140, 255, 0.3), transparent 54%);
  animation: breathe 16s ease-in-out infinite alternate;
  will-change: transform, opacity;
  pointer-events: none;
}

@keyframes breathe {
  to { transform: translate3d(-50%, 0, 0) scale(1.14); opacity: 0.82; }
}

/* The grid pans by moving the element, not its background-position —
   background-position repaints the whole surface every frame, transform
   does not. Inset is negative so the edges never enter the viewport. */
.hero__grid {
  position: absolute;
  z-index: -3;
  inset: -70px;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.055) 1px, transparent 1px);
  background-size: 62px 62px;
  mask-image: radial-gradient(ellipse 74% 58% at 50% 36%, #000 30%, transparent 76%);
  -webkit-mask-image: radial-gradient(ellipse 74% 58% at 50% 36%, #000 30%, transparent 76%);
  animation: gridpan 24s linear infinite;
  will-change: transform;
  pointer-events: none;
}

@keyframes gridpan { to { transform: translate3d(62px, 62px, 0); } }

.hero h1 { max-width: 16ch; margin-left: auto; margin-right: auto; }

.hero .lede { font-size: 1.1875rem; max-width: 44ch; margin: 0 auto 36px; color: var(--ink-2); }

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin-bottom: 56px;
}

/* trust bar with a rule running out to both sides */
.trust {
  display: flex;
  align-items: center;
  gap: 22px;
  justify-content: center;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}
.trust::before, .trust::after {
  content: "";
  height: 1px;
  flex: 1 1 60px;
  max-width: 260px;
  background: linear-gradient(90deg, transparent, var(--rule-2));
}
.trust::after { background: linear-gradient(90deg, var(--rule-2), transparent); }
.trust b { color: var(--ink); font-family: var(--display); letter-spacing: -0.01em; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-hi);
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  padding: 8px 16px;
  margin: 0 0 30px;
  background: rgba(123, 92, 255, 0.07);
}

.eyebrow .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent-hi);
  box-shadow: 0 0 0 0 rgba(167, 139, 255, 0.7);
  animation: pulse 2.4s ease-out infinite;
}

@keyframes pulse {
  70%  { box-shadow: 0 0 0 9px rgba(167, 139, 255, 0); }
  100% { box-shadow: 0 0 0 0 rgba(167, 139, 255, 0); }
}

/* --- KPI strip -------------------------------------------------- */

.kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}

/* The tilt angles come from JS as --rx/--ry, the lift from CSS as --ty.
   Composing them in one transform here means the two never fight over
   the property. */
.kpi {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  padding: 26px 24px 20px;
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--ty, 0px));
  transform-style: preserve-3d;
  transition: border-color 0.35s var(--ease), transform 0.25s var(--ease);
}

.kpi:hover { border-color: var(--rule-2); --ty: -5px; }

/* cursor spotlight — JS feeds --mx/--my */
.kpi::before, .case::before, .svc::before, .cmp__col::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0;
  transition: opacity 0.35s var(--ease);
  pointer-events: none;
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
              rgba(123, 92, 255, 0.16), transparent 62%);
}
.kpi:hover::before, .case:hover::before, .svc:hover::before, .cmp__col:hover::before { opacity: 1; }

.kpi-num {
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 8px;
}

.kpi-label {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 16px;
}

.spark { display: block; width: 100%; height: 34px; overflow: visible; }
.spark path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 320;
  stroke-dashoffset: 320;
  transition: stroke-dashoffset 1.5s var(--ease) 0.15s;
}
.spark .fill { fill: url(#sparkgrad); stroke: none; opacity: 0; transition: opacity 0.9s ease 0.7s; }
.in .spark path { stroke-dashoffset: 0; }
.in .spark .fill { opacity: 1; }

/* --- the creative ticker ---------------------------------------- */

.ticker { padding: 26px 0 30px; background: var(--bg-2); border-block: 1px solid var(--rule); }

.marq {
  overflow: hidden;
  padding: 9px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

.marq__track { display: flex; width: max-content; animation: marq 64s linear infinite; will-change: transform; }
.marq--rev .marq__track { animation-duration: 82s; animation-direction: reverse; }
.marq__set { display: flex; align-items: center; gap: 16px; padding-right: 16px; flex: none; }

@keyframes marq { to { transform: translateX(-50%); } }

.marq:hover .marq__track { animation-play-state: paused; }

.ad {
  flex: none;
  width: 152px;
  aspect-ratio: 9 / 16;
  border-radius: 13px;
  overflow: hidden;
  border: 1px solid var(--rule);
  background: var(--surface-2);
  transition: transform 0.35s var(--ease), border-color 0.35s var(--ease),
              box-shadow 0.35s var(--ease);
}

.ad img {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(0.6) brightness(0.7);
  transition: filter 0.35s var(--ease);
}

.ad:hover {
  transform: translateY(-8px) scale(1.03);
  border-color: var(--accent);
  box-shadow: 0 18px 46px rgba(123, 92, 255, 0.3);
}
.ad:hover img { filter: none; }

.ticker-cap {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  margin: 18px 0 0;
}

/* --- the text band ----------------------------------------------- */
/* Same duplicate-the-set trick as the ad marquee: the track runs to
   translateX(-50%), which is exactly one copy, so the wrap is unseen. */

.band {
  overflow: hidden;
  border-bottom: 1px solid var(--rule);
  background: var(--bg);
  padding: 26px 0;
}

.band__track { display: flex; width: max-content; animation: marq 38s linear infinite; will-change: transform; }

.band__set {
  display: block;
  flex: none;
  padding-right: 0.4em;
  white-space: nowrap;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.5rem, 3.6vw, 2.75rem);
  letter-spacing: -0.03em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 255, 255, 0.26);
}

.band__set em { font-style: normal; -webkit-text-stroke: 0; color: var(--accent); }

/* --- services --------------------------------------------------- */

.svcs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }

/* Column layout so the KPI line lands on the bottom edge of every
   card, whatever the list above it is doing. */
.svc {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  padding: 32px 28px;
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--ty, 0px));
  transition: border-color 0.35s var(--ease), transform 0.25s var(--ease);
}
.svc:hover { border-color: var(--rule-2); --ty: -5px; }

.svc__n {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  color: var(--accent-hi);
  display: block;
  margin-bottom: 26px;
}

.svc h3 { margin-bottom: 18px; }

.svc ul { list-style: none; margin: 0 0 26px; padding: 0; }

.svc li {
  position: relative;
  padding-left: 22px;
  color: var(--muted);
  font-size: var(--t-small);
  margin-bottom: 7px;
}

.svc li::before {
  content: "+";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-family: var(--mono);
}

.svc__kpi {
  margin-top: auto;
  border-top: 1px solid var(--rule);
  padding-top: 18px;
  font-family: var(--display);
  font-weight: 500;
  color: var(--ink);
  font-size: var(--t-small);
}
.svc__kpi b { color: var(--accent-hi); font-weight: 700; }

/* --- case study cards ------------------------------------------- */

.cases { display: grid; gap: 16px; }

.case {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: 232px 1fr;
  gap: 40px;
  align-items: center;
  border: 1px solid var(--rule);
  border-radius: 20px;
  background: var(--surface);
  padding: 30px;
  transition: border-color 0.35s var(--ease);
}
.case:hover { border-color: var(--rule-2); }

/* A card with nothing to show — an NDA client — drops the media column
   rather than filling it with an empty placeholder box. */
.case--solo { grid-template-columns: 1fr; padding: 34px 36px; }

.case__media { position: relative; z-index: 1; }

.case__media video {
  width: 100%;
  aspect-ratio: 9 / 16;
  border-radius: 13px;
  border: 1px solid var(--rule);
  background: var(--bg);
  object-fit: cover;
}

.case__body { position: relative; z-index: 1; }

.case__brand {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
  margin: 0 0 4px;
}

.case__meta {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 24px;
}

.case__kpis { list-style: none; margin: 0 0 26px; padding: 0; }

.case__kpis li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 11px;
  color: var(--ink-2);
  font-size: 1.0625rem;
}

.case__kpis li::before {
  content: "+";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--accent);
  font-family: var(--mono);
  font-weight: 500;
}

.case__kpis b {
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.02em;
}

.case__nda {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}

/* --- process ---------------------------------------------------- */

.steps { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; }

.step {
  position: relative;
  padding: 34px 22px 0;
  border-top: 1px solid var(--rule);
}

/* the dot that rides the top rule */
.step::before {
  content: "";
  position: absolute;
  top: -5px;
  left: 22px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 16px rgba(123, 92, 255, 0.9);
  transform: scale(0);
  transition: transform 0.5s var(--ease) var(--d, 0s);
}
.in .step::before { transform: scale(1); }

.step__n {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  color: var(--accent-hi);
  display: block;
  margin-bottom: 12px;
}

.step h3 { font-size: var(--t-body); margin-bottom: 6px; }
.step p { margin: 0; color: var(--muted); font-size: var(--t-small); }

/* --- comparison ------------------------------------------------- */

.cmp { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }

.cmp__col {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  padding: 30px 26px;
  transition: border-color 0.35s var(--ease), transform 0.35s var(--ease);
}

.cmp__col--us {
  border-color: rgba(123, 92, 255, 0.42);
  background:
    linear-gradient(180deg, rgba(123, 92, 255, 0.11), transparent 58%),
    var(--surface);
}
.cmp__col--us:hover { transform: translateY(-4px); }

.cmp__head {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 22px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--rule);
}
.cmp__col--us .cmp__head { color: var(--accent-hi); }

.cmp ul { list-style: none; margin: 0; padding: 0; }

.cmp li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 13px;
  color: var(--muted);
  font-size: var(--t-small);
  line-height: 1.5;
}
.cmp li:last-child { margin-bottom: 0; }

.cmp li::before {
  content: "–";
  position: absolute;
  left: 2px;
  color: var(--muted);
  font-family: var(--mono);
}

.cmp__col--us li { color: var(--ink-2); }
.cmp__col--us li::before { content: "+"; color: var(--accent); }

/* --- FAQ -------------------------------------------------------- */

.faq { display: grid; gap: 10px; max-width: 860px; }

details {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 13px;
  overflow: hidden;
  transition: border-color 0.3s var(--ease);
}
details[open] { border-color: var(--rule-2); }

summary {
  cursor: pointer;
  list-style: none;
  padding: 20px 24px;
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-body);
  letter-spacing: -0.015em;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 14px;
}

summary::-webkit-details-marker { display: none; }

summary::before {
  content: "";
  width: 8px; height: 8px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
  transition: transform 0.2s var(--ease);
  flex: none;
  margin-top: -3px;
}

details[open] summary::before { transform: rotate(45deg); margin-top: 2px; }
summary:hover { color: var(--accent-hi); }

.details-body {
  padding: 0 24px 24px;
  color: var(--muted);
  max-width: var(--prose);
}
.details-body > *:first-child { margin-top: 0; }
.details-body p { margin: 0 0 8px; }

/* --- final CTA -------------------------------------------------- */

.cta-band {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(123, 92, 255, 0.32);
  border-radius: 24px;
  background:
    radial-gradient(900px circle at 50% -40%, rgba(123, 92, 255, 0.3), transparent 62%),
    var(--surface);
  padding: 76px 40px;
  text-align: center;
}

/* three slow blobs drifting behind the CTA */
.aurora { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; }

/* Same rule as the hero glow: soft gradients, no filter. Three blurred
   layers drifting at once was the most expensive thing on the page. */
.aurora i {
  position: absolute;
  display: block;
  border-radius: 50%;
  opacity: 0.7;
  will-change: transform;
}

.aurora i:nth-child(1) {
  width: 620px; height: 620px; top: -260px; left: 2%;
  background: radial-gradient(circle, rgba(139, 108, 255, 0.6), rgba(139, 108, 255, 0.14) 34%, transparent 62%);
  animation: float-a 19s ease-in-out infinite alternate;
}
.aurora i:nth-child(2) {
  width: 520px; height: 520px; bottom: -240px; right: 8%;
  background: radial-gradient(circle, rgba(91, 140, 255, 0.5), rgba(91, 140, 255, 0.12) 34%, transparent 62%);
  animation: float-b 23s ease-in-out infinite alternate;
}
.aurora i:nth-child(3) {
  width: 420px; height: 420px; top: 24%; right: 28%;
  background: radial-gradient(circle, rgba(196, 178, 255, 0.36), transparent 60%);
  animation: float-c 27s ease-in-out infinite alternate;
}

@keyframes float-a { to { transform: translate3d(140px, 70px, 0) scale(1.2); } }
@keyframes float-b { to { transform: translate3d(-120px, -60px, 0) scale(1.15); } }
@keyframes float-c { to { transform: translate3d(80px, -90px, 0) scale(0.85); } }

.cta-band > *:not(.aurora) { position: relative; z-index: 1; }

.cta-band h2 { max-width: 18ch; margin-left: auto; margin-right: auto; }
.cta-band .lede { margin-left: auto; margin-right: auto; max-width: 46ch; }

.mail-big {
  font-family: var(--display);
  font-size: clamp(1.375rem, 3.4vw, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-decoration: none;
  display: inline-block;
  margin-top: 30px;
  border-bottom: 2px solid rgba(123, 92, 255, 0.5);
  padding-bottom: 3px;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.mail-big:hover { color: var(--accent-hi); border-color: var(--accent-hi); }

/* --- footer ----------------------------------------------------- */

.site-footer { border-top: 1px solid var(--rule); padding: 52px 0 64px; color: var(--muted); }

.site-footer__in {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  justify-content: space-between;
  align-items: flex-start;
}

.site-footer p { margin: 0 0 5px; font-size: var(--t-small); }
.site-footer a { color: var(--muted); text-decoration: none; }
.site-footer a:hover { color: var(--accent-hi); }
.site-footer .legal { font-family: var(--mono); font-size: var(--t-label); letter-spacing: 0.08em; margin-top: 18px; }

/* ===============================================================
   Case study page — same tokens, its own components
   =============================================================== */

.backlink {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  margin-bottom: 34px;
  transition: color 0.25s var(--ease);
}
.backlink:hover { color: var(--accent-hi); }

.hero--doc { padding: 64px 0 72px; text-align: left; }
.hero--doc h1 { max-width: 18ch; margin-left: 0; }
.hero-intro { max-width: var(--prose); }

.chapter { padding: 96px 0; }
.chapter-head { margin-bottom: 40px; max-width: var(--prose); }

.chapter-num {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent-hi);
  margin: 0 0 14px;
}

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin: 0 0 48px;
}

.stat {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: linear-gradient(180deg, var(--surface), var(--bg-2));
  padding: 24px 22px;
  transition: border-color 0.35s var(--ease), transform 0.35s var(--ease);
}
.stat:hover { border-color: var(--rule-2); transform: translateY(-3px); }

.stat-num {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 8px;
}

.stat-label {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
}

.stat--lead {
  border-color: rgba(123, 92, 255, 0.42);
  background: linear-gradient(180deg, rgba(123, 92, 255, 0.14), var(--surface));
}
.stat--lead .stat-num { color: var(--accent-hi); }
.stat--lead .stat-label { color: var(--accent-hi); }

.expanders { margin-top: 40px; display: grid; gap: 10px; }

.loop {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
  margin-bottom: 32px;
}

.loop-step {
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  padding: 24px 22px;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.loop-step:hover { border-color: var(--rule-2); transform: translateY(-3px); }

.loop-step .n {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  color: var(--accent-hi);
  display: block;
  margin-bottom: 14px;
}

.loop-step h3 { font-size: var(--t-body); margin-bottom: 5px; }
.loop-step p { margin: 0; color: var(--muted); font-size: var(--t-small); }

.split { display: grid; grid-template-columns: 1fr 320px; gap: 60px; align-items: start; }

.callout {
  background: linear-gradient(90deg, rgba(123, 92, 255, 0.11), transparent 70%), var(--surface);
  border: 1px solid var(--rule);
  border-left: 2px solid var(--accent);
  border-radius: 12px;
  padding: 20px 24px;
  margin: 0 0 32px;
  max-width: var(--prose);
}
.callout p { margin: 0 0 5px; }
.callout p:last-child { margin: 0; }

.video-card { position: sticky; top: 100px; }

.video-card video {
  width: 100%;
  aspect-ratio: 9 / 16;
  background: var(--bg);
  border-radius: 14px;
  border: 1px solid var(--rule);
}

.media-cap { margin: 12px 0 0; color: var(--muted); font-size: var(--t-small); }

figure { margin: 0 0 8px; }

.shot {
  border: 1px solid var(--rule);
  border-radius: var(--r);
  overflow: hidden;
  background: var(--surface);
}

/* Ads Manager and Premiere screenshots are light-on-white and glare on
   a black page. Held down until you actually look at one. Never
   inverted — that breaks the colours inside the charts. */
.shot img {
  width: 100%;
  filter: brightness(0.82) contrast(1.04);
  transition: filter 0.35s var(--ease);
}
.shot:hover img { filter: none; }

.shot--wide { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.scroll-hint { display: none; }
.figure-block { margin: 10px 0 48px; }

.diagram {
  margin: 0;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  padding: 10px 4px;
  overflow-x: auto;
}

.diagram svg { width: 100%; min-width: 720px; height: auto; display: block; }
.diagram figcaption { padding: 6px 18px 14px; }

.dg-line path { stroke: var(--rule-2); stroke-width: 1.5; fill: none; }
.diagram text { font-family: var(--sans); font-weight: 500; fill: var(--ink); }

.dg-row text { font-family: var(--mono); font-size: 12px; letter-spacing: 0.14em; fill: var(--accent-hi); }
.dg-row .dg-sub { font-family: var(--sans); font-size: 13px; font-weight: 400; letter-spacing: 0; fill: var(--muted); }

.dg-core rect { fill: var(--accent); }
.dg-core text { font-size: 17px; fill: #fff; text-anchor: middle; font-weight: 700; }

.dg-node rect { fill: var(--surface-2); stroke: var(--accent); stroke-width: 1.5; }
.dg-node text { font-size: 16px; text-anchor: middle; }

.dg-angle rect { fill: rgba(123, 92, 255, 0.14); stroke: var(--rule-2); stroke-width: 1; }
.dg-angle text { font-size: 14px; font-weight: 400; fill: var(--muted); text-anchor: middle; }

.grid6 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin: 0 0 20px; }

.cell {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 24px 22px;
}

.k {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-hi);
  display: block;
  margin-bottom: 12px;
}

.cell p { margin: 0 0 5px; font-size: var(--t-small); }
.cell p:last-child { margin: 0; }
.cell .sub { color: var(--muted); }

.desire-line {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 20px 24px;
  margin-bottom: 20px;
}
.desire-line p { margin: 0; }

.closing { padding: 96px 0; }

.closing .big {
  font-family: var(--display);
  font-size: var(--t-h2);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--ink);
  max-width: 20ch;
  margin: 0 0 32px;
}

/* ===============================================================
   Motion
   =============================================================== */

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

/* Hero uses the same mechanism rather than a keyframe: a transition
   that never runs leaves the text visible, a keyframe with fill:both
   leaves it invisible. The headline must never be hidden by a
   stalled animation. */
.js .rise {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.85s var(--ease), transform 0.85s var(--ease);
  transition-delay: var(--d, 0s);
}
.js .rise.in { opacity: 1; transform: none; }

/* Failsafe, set by motion.js 2.5s in: content is visible and settled
   whatever happened to the transitions. */
.motion-done .reveal,
.motion-done .rise,
.motion-done .words .w i {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* ?still=1 — freezes everything so screenshots are reproducible */
.js-still *, .js-still *::before, .js-still *::after {
  animation: none !important;
  transition: none !important;
}
.js-still .reveal, .js-still .rise { opacity: 1 !important; transform: none !important; }
.js-still .words .w i { transform: none !important; }
.js-still .spark path { stroke-dashoffset: 0 !important; }
.js-still .spark .fill { opacity: 1 !important; }
.js-still .step::before { transform: scale(1) !important; }
/* the card ring is hover-only, so it never shows in a screenshot anyway */
.js-still .kpi, .js-still .svc { transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .reveal, .js .rise { opacity: 1 !important; transform: none !important; }
  .js .words .w i { transform: none !important; }
  .spark path { stroke-dashoffset: 0 !important; }
  .spark .fill { opacity: 1 !important; }
  .step::before { transform: scale(1) !important; }
  .kpi, .svc { transform: none !important; }
}

/* ===============================================================
   Responsive
   =============================================================== */

@media (max-width: 1000px) {
  .kpis { grid-template-columns: repeat(2, 1fr); }
  .svcs { grid-template-columns: 1fr; }
  .cmp { grid-template-columns: 1fr; }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .step { padding-bottom: 26px; }
  .split { grid-template-columns: 1fr; gap: 36px; }
  .video-card { position: static; max-width: 320px; }
  .loop { grid-template-columns: repeat(2, 1fr); }
  .grid6 { grid-template-columns: repeat(2, 1fr); }
  .shot--wide img { width: 860px; max-width: none; }
  .scroll-hint { display: block; color: var(--accent-hi); font-family: var(--mono); font-size: var(--t-label); }
}

@media (max-width: 760px) {
  .case { grid-template-columns: 1fr; gap: 26px; padding: 24px; }
  .case__media { max-width: 210px; }
  .nav__links { display: none; }
}

@media (max-width: 620px) {
  .wrap { padding: 0 20px; }
  section { padding: 72px 0; }
  .chapter, .closing { padding: 64px 0; }
  .hero { padding: 64px 0 56px; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .kpis { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .kpi { padding: 20px 18px 16px; }
  .steps { grid-template-columns: 1fr; }
  .loop { grid-template-columns: 1fr; }
  .grid6 { grid-template-columns: 1fr; }
  .video-card { max-width: 100%; }
  .ad { width: 116px; }
  .hero-actions .btn { width: 100%; justify-content: center; }
  .cta-band { padding: 52px 24px; }
  .trust { font-size: 0.6875rem; gap: 12px; }
  .trust::before, .trust::after { max-width: 40px; }
}
