/* ============================================================
   INTERFACET® — interface intelligence studio
   Palette + typography carried over from the Interface
   Intelligence concept. One committed dark world; the footer
   is its acid inversion.

   Two rules this sheet is built on:
   · anything that must fit the screen is clamped by height as
     well as width — min(Xvw, Yvh)
   · separation is done with space, not with rules; a 1px line
     appears only where it carries meaning
   ============================================================ */

:root{
  /* ground */
  --ink:#090A0B;
  --ink-1:#0D0F11;
  --ink-2:#121417;

  /* ink on paper */
  --paper:#F0F1EB;
  --muted:rgba(240,241,235,.62);
  --dim:rgba(240,241,235,.40);
  --line:rgba(240,241,235,.13);
  --line-2:rgba(240,241,235,.06);
  --tint:rgba(240,241,235,.05);

  /* signal */
  --lime:#C8FF38;    /* found / fixed */
  --alert:#FF2E88;   /* loss / friction */

  /* type */
  --sans:"Neue Haas Grotesk Display Pro","Neue Haas Grotesk Text Pro","NeueHaasDisplay","Helvetica Neue","Inter","Arial Nova",Arial,sans-serif;
  --serif:"Newsreader","Instrument Serif","Iowan Old Style",Baskerville,"Times New Roman",serif;
  --mono:"JetBrains Mono","SFMono-Regular","Roboto Mono",Consolas,monospace;

  --t-hero:clamp(34px,min(6.4vw,8.8vh),106px);
  --t-h2:clamp(29px,4.6vw,74px);
  --t-body:clamp(14px,1.02vw,16px);
  --t-lab:clamp(9px,.66vw,10px);

  /* rhythm */
  --pad:clamp(18px,3.2vw,58px);
  --sec:clamp(76px,8.4vw,140px);
  --nav-h:78px;
  --strip-h:52px;

  /* motion */
  --ez:cubic-bezier(.16,1,.3,1);
  --ez2:cubic-bezier(.65,0,.35,1);
  --ez3:cubic-bezier(.76,0,.24,1);

  /* runtime */
  --cx:50vw; --cy:50vh; --sp:0;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html.js{scroll-behavior:smooth}
body{
  margin:0;background:var(--ink);color:var(--paper);
  font-family:var(--sans);font-size:var(--t-body);line-height:1.55;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
html.js body.is-locked{overflow:hidden;height:100svh}
h1,h2,h3{margin:0;font-weight:500;letter-spacing:-.05em;line-height:.94;text-wrap:balance}
p{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%;height:auto}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;text-align:left}
::selection{background:var(--lime);color:var(--ink)}
:focus-visible{outline:2px solid var(--lime);outline-offset:3px;border-radius:2px}
em{font-family:var(--serif);font-style:italic;font-weight:400;letter-spacing:-.012em}

body::after{
  content:"";position:fixed;inset:0;z-index:990;pointer-events:none;opacity:.15;
  mix-blend-mode:soft-light;background-size:7px 7px;
  background-image:repeating-radial-gradient(circle at 17% 32%,transparent 0,rgba(255,255,255,.06) 1px,transparent 2px 4px);
}

/* ---------------- atoms ---------------- */
.lab,.idx{
  font-family:var(--mono);font-size:var(--t-lab);font-weight:400;
  letter-spacing:.17em;text-transform:uppercase;color:var(--dim);
}
.lab-lime{color:var(--lime)}
.good{color:var(--lime)}
.dot{
  width:7px;height:7px;border-radius:50%;background:var(--lime);flex:none;
  box-shadow:0 0 16px rgba(200,255,56,.7);animation:pulseDot 2.6s var(--ez) infinite;
}
@keyframes pulseDot{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.68)}}

/* soft filled chips replace the outlined pills — fewer rectangles */
.case-tags li,.srv-tags li{
  font-family:var(--mono);font-size:10px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--muted);background:var(--tint);border-radius:2px;padding:7px 10px;
}

.sec{padding:var(--sec) var(--pad);position:relative}
section[id],footer[id]{scroll-margin-top:calc(var(--nav-h) + 14px)}
.sec-head{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.75fr);
  gap:clamp(22px,4vw,72px);align-items:end;margin-bottom:clamp(36px,4.6vw,76px);
}
.sec-head h2{font-size:var(--t-h2);max-width:16ch}
.sec-head > p{color:var(--muted);max-width:44ch;padding-bottom:.6em}
.sec-head-cta > .btn{justify-self:end}
.eyebrow{display:flex;align-items:center;gap:10px;margin-bottom:24px}

/* ---------------- buttons ---------------- */
/* the fill runs left → right and the element never moves, so the
   pointer cannot chase it the way the old magnetic pull made it */
.btn{
  position:relative;display:inline-flex;align-items:center;justify-content:space-between;gap:24px;
  padding:15px 20px;min-width:206px;color:var(--paper);background:var(--tint);
  font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  overflow:hidden;isolation:isolate;transition:color .45s var(--ez);
}
.btn span,.btn i{position:relative;z-index:2}
/* the arrow is a vector so it renders identically on every platform —
   the ↗ glyph fell back to a colour emoji font on mobile */
.arw{width:1em;height:1em;display:block;overflow:visible}
i:has(> .arw){display:inline-flex;align-items:center;font-style:normal}
.btn i{font-style:normal;transition:transform .45s var(--ez)}
.btn::before{
  content:"";position:absolute;inset:0;z-index:1;background:var(--lime);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .55s var(--ez);
}
.btn:hover{color:var(--ink)}
.btn:hover::before{transform:scaleX(1)}
.btn:hover i{transform:translate(3px,-3px)}

.btn-solid{background:var(--lime);color:var(--ink)}
.btn-solid::before{background:var(--paper)}
.btn-solid:hover{color:var(--ink)}
.btn-ghost{background:none;box-shadow:inset 0 0 0 1px var(--line);min-width:170px}

/* progress + aura */
.progress{
  position:fixed;top:0;left:0;right:0;height:2px;background:var(--lime);z-index:1001;
  transform:scaleX(var(--sp));transform-origin:0 50%;pointer-events:none;
  box-shadow:0 0 14px rgba(200,255,56,.5);
}
.aura{
  position:fixed;top:0;left:0;width:440px;height:440px;border-radius:50%;z-index:3;pointer-events:none;
  background:radial-gradient(circle,rgba(200,255,56,.07),transparent 62%);mix-blend-mode:screen;
  transform:translate3d(calc(var(--cx) - 220px),calc(var(--cy) - 220px),0);
}

/* ============================================================
   CALIBRATION — the acid curtain
   Three words arrive in the same spot, a rule fills underneath
   them, then the whole panel lifts away. The timing lives in CSS
   (the exit transition carries its own delay), so a throttled
   frame callback cannot leave the curtain stuck on screen.
   ============================================================ */
.intro{display:none}
html.js .intro{
  position:fixed;inset:0;z-index:2000;display:grid;place-items:center;overflow:hidden;
  background:var(--lime);color:var(--ink);
  transition:transform .85s cubic-bezier(.82,0,.18,1) 1.65s;
}
html.js .intro.out{pointer-events:none;transform:translateY(-105%)}
html.js.no-intro .intro{display:none}

.intro-word{
  position:absolute;opacity:0;transform:translateY(40px);
  font-size:clamp(52px,9.4vw,152px);line-height:.82;letter-spacing:-.07em;font-weight:500;
}
.intro-word-a{animation:introWord .5s 50ms both}
.intro-word-b{animation:introWord .5s .55s both}
.intro-word-c{animation:introWord .55s 1.05s both}
@keyframes introWord{
  0%{opacity:0;transform:translateY(45px)}
  35%,70%{opacity:1;transform:translateY(0)}
  100%{opacity:0;transform:translateY(-45px)}
}

.intro-index{
  position:absolute;top:28px;left:var(--pad);
  font:400 11px/1 var(--mono);letter-spacing:.14em;color:rgba(9,10,11,.75);
}
.intro-line{
  position:absolute;left:var(--pad);right:var(--pad);bottom:28px;
  height:1px;background:rgba(9,10,11,.22);overflow:hidden;
}
.intro-line i{
  display:block;width:100%;height:100%;background:var(--ink);
  transform-origin:0 50%;animation:introFill 1.55s cubic-bezier(.7,0,.2,1) both;
}
@keyframes introFill{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* ============================================================
   NAV
   ============================================================ */
.nav{
  position:sticky;top:0;z-index:60;height:var(--nav-h);
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  padding:0 var(--pad);border-bottom:1px solid var(--line);
  background:rgba(9,10,11,.72);backdrop-filter:blur(20px) saturate(140%);
  -webkit-backdrop-filter:blur(20px) saturate(140%);
  transition:height .4s var(--ez),background .4s var(--ez);
}
.nav.tight{height:60px;background:rgba(9,10,11,.9)}
.brand{display:inline-flex;align-items:center;gap:11px;width:max-content;font-weight:600;font-size:14px;letter-spacing:-.02em}
.brand-glyph{width:24px;height:24px;flex:none;color:var(--paper);transition:transform .6s var(--ez)}
.brand:hover .brand-glyph{transform:rotate(90deg)}
.brand sup{font-size:10px;line-height:1;color:var(--lime);top:-.62em;position:relative;margin-left:2px}
.nav-links{display:flex;gap:clamp(18px,2.2vw,34px);justify-self:center}
.nav-links a{position:relative;font-size:13px;color:var(--muted);padding:6px 0;transition:color .3s var(--ez)}
.nav-links a::after{
  content:"";position:absolute;left:0;bottom:0;height:1px;width:100%;background:var(--lime);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .45s var(--ez);
}
.nav-links a:hover,.nav-links a.on{color:var(--paper)}
.nav-links a:hover::after,.nav-links a.on::after{transform:scaleX(1)}
.nav-right{display:flex;align-items:center;gap:clamp(14px,1.6vw,26px);justify-self:end}
.lang{display:flex;align-items:center;background:var(--tint);border-radius:2px;overflow:hidden}
.lang-btn{font-family:var(--mono);font-size:9px;letter-spacing:.12em;padding:6px 9px;color:var(--dim);transition:color .3s,background .3s}
.lang-btn.is-on{background:var(--lime);color:var(--ink)}
.lang-btn[data-soon]{cursor:not-allowed}
.nav-cta{display:inline-flex;align-items:center;gap:12px;font-size:13px;white-space:nowrap}
.nav-cta i{font-style:normal;color:var(--lime);font-size:15px;transition:transform .3s var(--ez)}
.nav-cta:hover i{transform:translate(3px,-3px)}

/* ============================================================
   1 · HERO — the Figma frame (twjbtQeReaHbpRC0ex6Bq1, node 25:534)
   The design is a 1200 × 600 frame. .hero-frame reproduces it as a
   fixed-ratio box and every child is placed in % of it, so the whole
   composition is proportionally identical at any width. Type inside
   scales with the frame through container units (1cqw = 12px of the
   design), never with the viewport — that is what keeps the copy
   column and the cluster locked to each other.
   ============================================================ */
.hero{
  position:relative;display:grid;place-items:center;overflow:hidden;
  height:calc(100svh - var(--nav-h) - var(--strip-h));min-height:380px;
  background:var(--ink);
}
.hero-frame{
  container-type:size;
  position:relative;z-index:2;
  /* the frame is 2:1, so the height available on screen caps the width */
  width:min(100% - var(--pad) * 2, calc((100svh - var(--nav-h) - var(--strip-h)) * 2));
  aspect-ratio:1200 / 600;
  --px:0;--py:0;                       /* pointer, -1 … 1, set by the runtime */
  --card-r:.67cqw;                     /* 8 of 1200, shared by every hero card */
}

/* ---------- left column ---------- */
.hero-copy{
  position:absolute;left:16.6667%;top:50%;translate:0 -50%;
  /* The design column is 322 wide because that is what its headline measures.
     Sized from the headline here for the same reason — hardcoding 322 makes
     the headline wrap the moment a substituted font runs wider than Neue Haas. */
  width:max-content;max-width:32%;
  display:flex;flex-direction:column;align-items:flex-start;gap:1cqw;
}
.hero-copy .eyebrow{display:flex;align-items:center;gap:.83cqw;margin:0}
.hero-copy .dot{width:.67cqw;height:.67cqw}
.hero-kicker{
  font-family:var(--sans);font-size:1cqw;font-weight:700;
  letter-spacing:0;text-transform:uppercase;color:var(--lime);white-space:nowrap;
}
.hero-h1{
  margin:0;font-size:4.17cqw;line-height:1.1;
  font-weight:700;letter-spacing:-.03em;color:#F7F8F4;
  /* The <br> in the markup are the only breaks — nowrap keeps it three lines
     whatever font the machine falls back to. */
  white-space:nowrap;
}
.hero-h1 em{font-family:"Newsreader",var(--serif);font-style:italic;font-weight:400;letter-spacing:0}
.hero-lede{
  margin:0;font-size:1cqw;line-height:1.35;color:#E5E5E5;
  width:min-content;min-width:100%;    /* wraps to the column, never widens it */
}
.hero-cta{display:flex;align-items:center;gap:.83cqw;padding-top:1.67cqw;width:100%}
/* the fill runs left → right and the element never moves */
.hbtn{
  position:relative;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;gap:.5cqw;
  padding:1cqw .83cqw;
  font-family:var(--sans);font-size:1cqw;font-weight:500;letter-spacing:-.005em;
  line-height:1.17;white-space:nowrap;      /* 12 + 12 padding + 14 line box = the design's 38 */
  overflow:hidden;isolation:isolate;transition:color .45s var(--ez);
}
.hbtn span,.hbtn i{position:relative;z-index:2}
.hbtn i{font-style:normal;transition:transform .45s var(--ez)}
.hbtn:hover i{transform:translate(.17cqw,-.17cqw)}
.hbtn-solid{background:var(--lime);color:var(--ink)}
.hbtn-solid::before{
  content:"";position:absolute;inset:0;z-index:1;background:var(--paper);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .55s var(--ez);
}
.hbtn-solid:hover::before{transform:scaleX(1)}

/* ---------- the cluster: one layer per Figma node, placed in % of the frame ---------- */
.hero-stage,.hero-cluster{position:absolute;inset:0;pointer-events:none}
/* The 1200x600 artboard leaves a wide dead margin around the cluster, so on a
   desktop screen the right half reads as smaller than the headline it answers.
   Scale the cluster inside the frame — origin on the cluster's own centre, not
   the frame's, so it grows into that margin instead of drifting at the copy. */
@media (min-width:1181px){
  .hero-cluster{transform:scale(1.18);transform-origin:72% 42%}
}
.orbit{
  position:absolute;left:51.8065%;top:13.7795%;width:37.7786%;height:75.5573%;
  pointer-events:none;overflow:visible;
}
.orbit-ring{fill:none;stroke:#2E2E2E;stroke-width:1}
.orbit-ring-inner{stroke-opacity:.5}
.orbit-name text{
  fill:var(--lime);font-family:var(--sans);font-size:10px;
  font-weight:500;letter-spacing:2px;
}
/* the wordmark rides the ring — it starts where the design puts it */
.orbit-name{
  transform-box:view-box;transform-origin:230px 222px;
  animation:orbitTravel 48s linear infinite;
}
@keyframes orbitTravel{to{transform:rotate(360deg)}}

.fcard{
  position:absolute;pointer-events:none;
  translate:calc(var(--px) * var(--dx) * 1px) calc(var(--py) * var(--dy) * 1px);
  transition:translate var(--t) cubic-bezier(.22,.61,.36,1);
  animation:fcardBob var(--bob) ease-in-out var(--phase) infinite alternate;
}
@keyframes fcardBob{to{transform:translateY(-7px)}}
.fcard img{display:block;width:100%;height:auto;position:relative;z-index:1}
/* Each plate in the export is fill-opacity .2 over a hairline border — glass.
   Figma's Background blur is a LAYER EFFECT and does not survive SVG export,
   so the exported card keeps the translucent fill but loses the blur behind
   it, which is exactly what makes it read flat. Put it back in CSS, clipped
   to each plate's own radius. flow has no plate, so it gets none. */
.fcard-system,.fcard-metric,.fcard-proto{
  -webkit-backdrop-filter:blur(1cqw);backdrop-filter:blur(1cqw);
}
/* card2 draws no plate — its glass is the controls inside it. An SVG inside an
   <img> cannot blur the page behind it (SVG filters only ever see the SVG's own
   content), so each control gets a DOM pane underneath at its own coordinates,
   in % of the 220 x 130 card. The artwork paints over them, and because every
   control fill is .2 opaque the blur reads straight through. */
/* card2 ships as two layers. The wiring has to sit BEHIND the panes, or the
   blur has nothing to work on — in the design the lines running under a control
   are smeared by its glass, and a single flat image over the panes cannot do
   that. Back layer in flow (it gives the wrapper its height), panes over it,
   controls on top. */
.fcard-flow .lay-back{z-index:0}
.fcard-flow .lay-front{position:absolute;left:0;top:0;z-index:2}
.gpane{
  position:absolute;display:block;pointer-events:none;z-index:1;
  -webkit-backdrop-filter:blur(1cqw);backdrop-filter:blur(1cqw);
}
.gpane-plus  {left:34.091%;top:10.769%;width:20.909%;height:21.538%;border-radius:var(--card-r)}
.gpane-toggle{left:75%;    top:40%;    width:19.091%;height:21.538%;border-radius:999px}
.gpane-minus {left:75%;    top:69.231%;width:19.091%;height:21.538%;border-radius:var(--card-r)}
.gpane-node  {left:5.455%; top:44.615%;width:7.273%; height:12.308%;border-radius:999px}

.fcard-system{border-radius:999px}      /* 210 x 62 pill */
.fcard-metric{border-radius:var(--card-r)}
.fcard-proto {border-radius:var(--card-r)}
/* The lit edge. In Figma the plate carries a light rim — bright along the
   bottom and right, brightest at the bottom-right corner, fading out before it
   reaches the top-left. It is a layer effect, so the export flattens it to the
   plate's own even grey stroke and the card loses its thickness. Rebuilt as a
   one-pixel ring above the artwork: a directional gradient, masked to the ring
   with the padding-box XOR trick. Inset by one design pixel so it lands on the
   plate's own stroke instead of just outside it. */
.fcard-system::after,.fcard-metric::after,.fcard-proto::after{
  content:"";position:absolute;inset:1px;border-radius:inherit;pointer-events:none;z-index:2;
  padding:1px;
  /* Two lights rather than one diagonal: a single 315deg gradient dies at the
     bottom-LEFT corner, but in Figma the whole bottom edge stays lit. Bottom
     and right are separate layers, so they sum at the bottom-right corner —
     which is where the design is brightest — and neither edge goes dark. */
  background:
    linear-gradient(  0deg,rgba(247,248,244,.62) 0%,rgba(247,248,244,.10) 38%,rgba(247,248,244,0) 62%),
    linear-gradient(270deg,rgba(247,248,244,.48) 0%,rgba(247,248,244,.08) 40%,rgba(247,248,244,0) 66%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask-composite:exclude;
}
/* left/top/width are the design's own coordinates over 1200 × 600; the
   motion values are deliberately all different so no two cards travel together */
.fcard-proto {left:70.25%;   top:56.5%;    width:15.3333%;--dx:26;--dy:20;--t:.55s;--bob:7.5s;--phase:0s}
.fcard-system{left:56.0833%; top:30.3333%; width:17.5%;   --dx:22;--dy:16;--t:.62s;--bob:8.0s;--phase:-2.1s}
.fcard-flow  {left:71.9167%; top:31.8333%; width:18.3333%;--dx:15;--dy:11;--t:.78s;--bob:9.1s;--phase:-3.2s}
.fcard-metric{left:54.25%;   top:48.3333%; width:12.75%;  --dx:34;--dy:26;--t:.48s;--bob:6.2s;--phase:-1.4s}

/* ---------- background layers ---------- */
/* the frame's own fill: a rotated violet ellipse at 20% over the ink.
   CSS cannot rotate a radial-gradient, and at 20% the −22° is not
   readable, so it is reproduced upright. */
.bg-tint{
  position:absolute;inset:0;pointer-events:none;opacity:.2;
  background:radial-gradient(ellipse 59.5% 238% at 50% 50%,
    #1D1441 0%,#0F0A21 50%,#070510 75%,#000 100%);
}
.bg-blob{position:absolute;border-radius:50%;pointer-events:none}
/* the design blurs these by 250 — a radial gradient is the same picture
   without asking the compositor for a 500px-wide blur every frame */
.bg-blob-purple{
  left:-43.33%;top:-86.17%;width:79.08%;aspect-ratio:1;
  background:radial-gradient(circle closest-side,
    rgba(129,25,255,.30) 0%,rgba(129,25,255,.28) 40%,
    rgba(129,25,255,.16) 62%,rgba(129,25,255,.05) 82%,transparent 100%);
}
.bg-blob-teal{
  left:65%;top:4.5%;width:75.83%;aspect-ratio:1;
  background:radial-gradient(circle closest-side,
    rgba(1,105,194,.30) 0%,rgba(1,105,194,.28) 40%,
    rgba(1,105,194,.16) 62%,rgba(1,105,194,.05) 82%,transparent 100%);
}
/* the UI texture. The design places one 1300px copy; it repeats so a
   screen wider than that never shows an edge. */
.bg-shot{
  position:absolute;inset:0;pointer-events:none;
  background:url(assets/hero/bg-glow.png?v=17) center/1300px auto repeat;
  /* .45 screened over the ink puts the background at mean luma 15 / sd 3,
     which is what the design frame itself measures. Unblurred — the panel
     edges are legible in the design and blur washes them out. */
  mix-blend-mode:screen;opacity:.45;
}
.bg-dots{
  position:absolute;inset:0;pointer-events:none;opacity:.035;
  background:radial-gradient(circle at center,#F0F1EB 0 1px,transparent 1px) 0 0/12px 12px;
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 50%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 0%,#000 50%,transparent 100%);
}
/* the frame carries a fractalNoise grain; rendered once as a tile rather
   than as a live filter over the whole hero */
.bg-grain{
  position:absolute;inset:0;pointer-events:none;opacity:.12;
  background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n' color-interpolation-filters='sRGB'><feTurbulence type='fractalNoise' baseFrequency='1 0.5' numOctaves='3' stitchTiles='stitch' seed='9918'/><feComponentTransfer><feFuncA type='discrete' tableValues='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'/></feComponentTransfer><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>") repeat;
}

/* word-mask reveal */
.w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
html.js .w > i{
  display:inline-block;font-style:inherit;transform:translateY(112%);
  transition:transform 1s var(--ez);transition-delay:calc(var(--i) * .055s + .1s);
}
html.js body.ready .hero-h1 .w > i{transform:translateY(0)}
html.js [data-reveal].in .w > i{transform:translateY(0)}

html.js .hero-r{opacity:0;transform:translateY(28px);filter:blur(8px)}
html.js body.ready .hero-r{
  opacity:1;transform:none;filter:blur(0);
  transition:opacity .9s var(--ez),transform 1.1s var(--ez),filter 1s var(--ez);
}
html.js body.ready .hero-r3{transition-delay:.38s}
html.js body.ready .hero-r4{transition-delay:.56s}
html.js .fcard{opacity:0}
html.js body.ready .fcard{
  opacity:1;
  transition:opacity .9s var(--ez) calc(.30s + var(--dx) * .006s),
             translate var(--t) cubic-bezier(.22,.61,.36,1);
}

/* ============================================================
   CAPABILITY STRIP — acid, replacing the dark ticker
   ============================================================ */
.strip{
  --strip-h:52px;
  height:var(--strip-h);background:var(--lime);color:var(--ink);
  display:flex;align-items:center;overflow:hidden;position:relative;z-index:5;
}
.strip ::selection{background:var(--ink);color:var(--lime)}
.strip-track{display:flex;align-items:center;flex:none;animation:strip 42s linear infinite}
.strip:hover .strip-track{animation-play-state:paused}
.strip span{
  padding:0 clamp(26px,3.4vw,58px);white-space:nowrap;
  font-size:clamp(10px,.8vw,12px);font-weight:600;letter-spacing:.06em;text-transform:uppercase;
}
@keyframes strip{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ============================================================
   THE COVER — the light page rides up over the dark one
   The transition sits on the colour change rather than after the hero:
   a paper sheet arriving over an ink one reads far harder than ink
   over ink. #cost simply holds still under the nav — no fade, no scale,
   no blur — and everything from the light section down rides up over it
   as one sheet with its own ground. All the motion is on the arriving
   page: its leading corners, its lift shadow and its edge light.
   ============================================================ */
.cost{position:sticky;top:var(--nav-h);z-index:0}
.cost.is-covered{visibility:hidden}

/* ============================================================
   THE SHEET — the second page
   Only border-radius, shadow and opacity animate; nothing here
   changes width or height, so covering the hero costs no reflow.
   ============================================================ */
.sheet{
  position:relative;z-index:2;background:var(--ink);overflow:hidden;
  box-shadow:0 -24px calc(60px + (1 - var(--cover,0)) * 70px) -18px
             rgba(0,0,0,calc(.5 + (1 - var(--cover,0)) * .45));
}
.sheet::before{
  content:"";position:absolute;top:0;left:0;right:0;height:1px;z-index:4;pointer-events:none;
  background:linear-gradient(90deg,
    transparent,
    rgba(200,255,56,calc((1 - var(--cover,0)) * .9)),
    transparent);
  box-shadow:0 0 calc((1 - var(--cover,0)) * 22px) rgba(200,255,56,calc((1 - var(--cover,0)) * .55));
}


/* ============================================================
   2 · PROOF
   ============================================================ */
.proof{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(20px,3vw,54px);padding:clamp(38px,4.4vw,68px) var(--pad);
}
.proof-cell{position:relative;display:flex;flex-direction:column;gap:11px;padding-bottom:16px}
.proof-cell b{
  font-size:clamp(34px,4.2vw,72px);font-weight:500;letter-spacing:-.06em;line-height:.85;
  font-variant-numeric:tabular-nums;
}
.proof-cell::after{
  content:"";position:absolute;left:0;bottom:0;height:2px;width:100%;background:var(--lime);
  transform:scaleX(0);transform-origin:0 50%;transition:transform 1.1s var(--ez);
}
.proof.in .proof-cell::after{transform:scaleX(1)}
.proof.in .proof-cell:nth-child(2)::after{transition-delay:.12s}
.proof.in .proof-cell:nth-child(3)::after{transition-delay:.24s}
.proof.in .proof-cell:nth-child(4)::after{transition-delay:.36s}

/* ============================================================
   4 · THE COST
   ============================================================ */
.cost-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,2.6vw,46px)}
.cost{display:flex;flex-direction:column;gap:11px}
.cost b{
  font-size:clamp(31px,3.5vw,58px);font-weight:500;letter-spacing:-.06em;line-height:.85;
  font-variant-numeric:tabular-nums;
}
.cost h3{font-size:clamp(15px,1.2vw,19px);letter-spacing:-.025em;line-height:1.25;flex:1}
.cost-bar{position:relative;display:block;height:2px;background:var(--line);margin-top:6px}
.cost-bar::after{
  content:"";position:absolute;inset:0;background:var(--paper);
  transform:scaleX(0);transform-origin:0 50%;transition:transform 1.3s var(--ez) .25s;
}
.cost.in .cost-bar::after{transform:scaleX(calc(var(--v) / 100))}
.cost-crit b{color:var(--lime)}
.cost-crit .cost-bar::after{background:var(--lime)}


/* ============================================================
   5 · WORK — the one light section
   Redefining the four ground tokens flips everything scoped inside
   it. Lime is never text here: on paper it drops to ~1.4:1, so it
   only ever appears as a fill with ink on top.
   ============================================================ */
.is-light{
  background:#F5F7F9;color:var(--ink);
  --muted:rgba(9,10,11,.64);
  --dim:rgba(9,10,11,.48);
  --line:rgba(9,10,11,.14);
  --line-2:rgba(9,10,11,.07);
  --tint:rgba(9,10,11,.055);
}
.is-light ::selection{background:var(--ink);color:var(--lime)}
.is-light .btn{color:var(--ink)}
.is-light .case-n{
  background:var(--lime);color:var(--ink);
  padding:4px 8px;border-radius:2px;letter-spacing:.12em;
}
.is-light .good{
  background:var(--lime);color:var(--ink);
  width:max-content;padding:2px 8px;border-radius:2px;
}
.is-light .shot img{filter:grayscale(1) brightness(.94) contrast(.96)}
.is-light .case.in .shot img{filter:grayscale(0) brightness(1) contrast(1)}

/* ============================================================
   5b · WORK layout
   ============================================================ */
.cases{display:flex;flex-direction:column;gap:clamp(52px,6.4vw,124px)}
.case-meta{display:flex;flex-wrap:wrap;align-items:center;gap:10px clamp(12px,1.6vw,24px);margin-bottom:clamp(10px,1.1vw,18px)}
.case-n{font-family:var(--mono);font-size:clamp(12px,1.05vw,15px);color:var(--lime);letter-spacing:.1em}
/* names the service this case is an example of, so the work reads back to
   what can actually be bought */
.case-service{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:var(--t-lab);letter-spacing:.14em;
  text-transform:uppercase;color:var(--paper);white-space:nowrap;
}
.case-service i{width:6px;height:6px;background:var(--lime);border-radius:1px;flex:none}
.is-light .case-service{color:var(--ink)}
.case-main{
  display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
  gap:clamp(26px,4vw,80px);align-items:center;
}
.case:nth-child(even) .case-copy{order:2}
/* order:2 moves the copy after the visual, but not out of column 1 —
   without this swap the mirrored case gives the wide track to the text. */
.case:nth-child(even) .case-main{grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr)}
.case-copy h3{font-size:clamp(25px,3.1vw,52px);letter-spacing:-.05em;line-height:.96}
.case-copy > p{color:var(--muted);margin-top:clamp(14px,1.5vw,22px);max-width:50ch;font-size:clamp(14px,1vw,16px)}
.case-tags{display:flex;flex-wrap:wrap;gap:7px;margin-top:clamp(16px,1.7vw,24px)}
.case-res{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-top:clamp(20px,2.2vw,34px)}
.case-res div{display:flex;flex-direction:column;gap:7px}
.case-res b{font-size:clamp(18px,1.8vw,29px);font-weight:500;letter-spacing:-.045em;line-height:1}

.case-visual{position:relative;perspective:1500px}
/* The case images arrive as finished device mockups on transparent ground,
   with their own shadow — so .mock draws nothing and only carries the lean.
   --px/--py come from the pointer loop in script.js. */
.mock{
  --px:0;--py:0;--lean:8deg;
  position:relative;
  transform:rotateY(calc(var(--lean) + var(--px) * -4deg))
            rotateX(calc(var(--py) * -3deg));
}
.case:nth-child(even) .mock{--lean:-8deg}
.shot{position:relative;margin:0;overflow:hidden}
/* A case still on a flat screenshot rather than a device mockup: it has no
   edge of its own, so the frame comes from CSS until the artwork is redone. */
.shot-plain{
  border-radius:7px;
  box-shadow:0 0 0 1px var(--line),0 30px 64px -40px rgba(9,10,11,.5);
}
/* No overscale on reveal: inside a browser frame a 5% zoom reads as the
   screenshot being cropped by the chrome. Colour and the scan carry it. */
.shot img{
  width:100%;filter:grayscale(1) brightness(.62) contrast(1.05);
  transition:filter 1.3s var(--ez);
}
/* A near-square mockup at full column width towers over the wide one in case
   01. A fixed px cap is wrong here — it bites hard at 1600 and not at all at
   1388, where the column is already under it. Cap the BOX at 16:10 of the
   column so the limit scales with the layout, and let contain hold each
   picture's own aspect; the artwork is on transparent ground, so the slack
   reads as margin. max-height still ceilings it on very wide screens.
   Two-column layout only — stacked below 1180 the image should fill.
   Not on .shot-plain: there the frame is CSS, so it must hug the picture. */
@media (min-width:1181px){
  .shot:not(.shot-plain) img{aspect-ratio:16/11;max-height:560px;object-fit:contain}
}
.case.in .shot img{filter:grayscale(0) brightness(1) contrast(1)}
.scan{
  position:absolute;left:0;right:0;top:0;height:100%;opacity:0;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(200,255,56,0) 0%,rgba(200,255,56,.05) 74%,
    rgba(200,255,56,.22) 94%,rgba(200,255,56,.95) 99.4%,rgba(200,255,56,0) 100%);
}
/* Cases dropped the sweep: their images are device mockups on transparent
   ground, so the line ran on past the device into empty page. */
.person.in .scan{animation:scanOnce 1.8s var(--ez) .15s}
@keyframes scanOnce{
  0%{opacity:0;transform:translateY(-101%)}
  14%{opacity:1}86%{opacity:1}
  100%{opacity:0;transform:translateY(101%)}
}

/* ============================================================
   6 · METHOD — four steps on one rail
   The per-step charts are gone on purpose: three of the four were
   rows of bars and read as one repeated texture, not four ideas.
   ============================================================ */
.steps{
  position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(22px,3vw,54px);padding-top:30px;
}
.steps-rail{position:absolute;top:0;left:0;right:0;height:1px;background:var(--line)}
.steps-rail::after{
  content:"";position:absolute;inset:0;background:var(--lime);
  transform:scaleX(0);transform-origin:0 50%;transition:transform 1.8s var(--ez) .2s;
  box-shadow:0 0 10px rgba(200,255,56,.5);
}
.steps.in .steps-rail::after{transform:scaleX(1)}
.step{position:relative;display:flex;flex-direction:column;gap:10px}
.step::before{
  content:"";position:absolute;top:-34px;left:0;width:7px;height:7px;border-radius:50%;
  background:var(--ink);box-shadow:0 0 0 1px var(--line);
  transition:background .5s var(--ez),box-shadow .5s var(--ez);
}
.steps.in .step::before{background:var(--lime);box-shadow:0 0 0 1px var(--lime),0 0 14px rgba(200,255,56,.6)}
.steps.in .step:nth-child(3)::before{transition-delay:.42s}
.steps.in .step:nth-child(4)::before{transition-delay:.84s}
.steps.in .step:nth-child(5)::before{transition-delay:1.26s}
.step-n{font-family:var(--mono);font-size:10px;letter-spacing:.15em;color:var(--lime)}
.step h3{font-size:clamp(19px,1.8vw,29px);letter-spacing:-.04em}
.step p{color:var(--muted);font-size:14px;line-height:1.55;max-width:34ch}

/* ============================================================
   7 · SERVICES
   ============================================================ */
/* the row content is inset from the row's own edges, so the number has
   air around it instead of butting into the tint when a row opens */
.srv-list{
  border-top:1px solid var(--line);
  --srv-pad:clamp(14px,1.6vw,26px);
  --srv-in:calc(var(--srv-pad) + 15px + clamp(14px,2.4vw,40px));
}
.srv{position:relative;border-bottom:1px solid var(--line)}
.srv::before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(90deg,rgba(200,255,56,.05),transparent 60%);
  transition:opacity .5s var(--ez);
}
.srv:hover::before,.srv.is-open::before{opacity:1}
.srv-head{
  width:100%;display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;
  gap:clamp(14px,2.4vw,40px);align-items:center;
  padding:clamp(18px,2vw,30px) var(--srv-pad);
}
.srv-n{font-family:var(--mono);font-size:10px;letter-spacing:.15em;color:var(--dim);transition:color .4s}
.srv-t{
  font-size:clamp(19px,2.3vw,38px);font-weight:500;letter-spacing:-.045em;line-height:1;
  transition:transform .55s var(--ez);
}
.srv:hover .srv-n,.srv.is-open .srv-n{color:var(--lime)}
.srv:hover .srv-t{transform:translateX(10px)}
.srv-tag{white-space:nowrap}
.srv-x{position:relative;width:16px;height:16px;flex:none}
.srv-x::before,.srv-x::after{content:"";position:absolute;background:var(--paper);transition:transform .5s var(--ez),background .4s}
.srv-x::before{left:0;right:0;top:50%;height:1px;transform:translateY(-50%)}
.srv-x::after{top:0;bottom:0;left:50%;width:1px;transform:translateX(-50%)}
.srv.is-open .srv-x::after{transform:scaleY(0)}
.srv.is-open .srv-x::before{background:var(--lime)}
.srv-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows .6s var(--ez)}
.srv.is-open .srv-body{grid-template-rows:1fr}
.srv-cols{
  overflow:hidden;display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.75fr);
  gap:clamp(20px,3vw,60px);padding:0 var(--srv-pad) 0 var(--srv-in);
}
.srv-cols > *{opacity:0;transform:translateY(14px);transition:opacity .5s var(--ez),transform .6s var(--ez)}
.srv.is-open .srv-cols > *{opacity:1;transform:none;transition-delay:.18s}
.srv-cols p{color:var(--muted);padding-bottom:clamp(20px,2.2vw,34px);max-width:58ch;font-size:clamp(14px,1vw,16px)}
.srv-tags{display:flex;flex-wrap:wrap;gap:7px;align-content:flex-start;padding-bottom:clamp(20px,2.2vw,34px)}

/* ============================================================
   8 · STUDIO
   ============================================================ */
.people{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(28px,4vw,80px)}
.person{display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(20px,2.4vw,38px);align-items:start}
.person-ph{
  position:relative;margin:0;flex:none;border-radius:50%;overflow:hidden;
  width:clamp(92px,8.4vw,138px);height:clamp(92px,8.4vw,138px);
}
.person-ph img{width:100%;height:100%;object-fit:cover;filter:grayscale(1) brightness(.88);transition:filter 1.2s var(--ez)}
.person.in .person-ph img{filter:grayscale(.12) brightness(1)}
.person-copy{display:flex;flex-direction:column;gap:11px}
.person-copy h3{font-size:clamp(20px,2vw,32px);letter-spacing:-.04em}
.person-copy p{color:var(--muted);font-size:14px;line-height:1.6;max-width:42ch}
.person-skills{font-family:var(--mono);font-size:10px;letter-spacing:.11em;text-transform:uppercase;color:var(--dim)}

/* the roster reads as one full-width strip. This is the one place on the
   page where repeated vertical rules are right: they are columns of a
   single row, not a stack of parallel lines. */
.crew{
  margin-top:clamp(40px,4.6vw,84px);padding-top:clamp(18px,2vw,30px);
  border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:clamp(14px,1.6vw,22px);
}
.crew ul{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:0}
.crew li{
  padding-left:clamp(14px,1.8vw,28px);
  border-left:1px solid var(--line);
  font-size:clamp(15px,1.35vw,21px);letter-spacing:-.025em;line-height:1.2;
  transition:color .4s var(--ez);
}
.crew li:first-child{padding-left:0;border-left:0}
.crew li:hover{color:var(--lime)}

/* ============================================================
   9 · PRINCIPLE
   ============================================================ */
.creed{
  position:relative;padding:clamp(90px,10vw,170px) var(--pad);text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:20px;overflow:hidden;
}
.creed-orbit{
  position:absolute;left:50%;top:50%;width:min(70vw,560px);height:min(70vw,560px);
  transform:translate(-50%,-50%);border:1px solid var(--line-2);border-radius:50%;
  animation:orbit 34s linear infinite;pointer-events:none;
}
.creed-orbit::before{content:"";position:absolute;inset:26%;border:1px dashed rgba(141,123,255,.14);border-radius:50%}
.creed-orbit i{
  position:absolute;width:8px;height:8px;border-radius:50%;background:var(--lime);
  box-shadow:0 0 18px var(--lime);top:50%;left:-4px;margin-top:-4px;
}
.creed-orbit i:last-child{background:var(--alert);box-shadow:0 0 18px var(--alert);top:12%;left:auto;right:11%}
@keyframes orbit{to{transform:translate(-50%,-50%) rotate(360deg)}}
.creed blockquote em{color:var(--lime);display:inline-block}
.studio .sec-head h2 em{color:var(--lime)}
.creed blockquote{
  position:relative;margin:0;font-size:clamp(28px,4.2vw,68px);font-weight:500;
  letter-spacing:-.055em;line-height:1;max-width:18ch;
}
.creed > p{position:relative;color:var(--muted);max-width:54ch;font-size:clamp(14px,1vw,16px)}
.creed .idx{position:relative}

/* ============================================================
   10 · ACID FOOTER — fits one screen
   ============================================================ */
footer{
  background:var(--lime);color:var(--ink);position:relative;z-index:4;
  min-height:100svh;display:flex;flex-direction:column;
}
footer ::selection{background:var(--ink);color:var(--lime)}
footer .idx,footer .lab{color:rgba(9,10,11,.6)}
.foot-main{
  flex:1;display:grid;grid-template-columns:minmax(0,1fr) auto;
  align-items:center;gap:clamp(24px,4vw,70px);
  padding:calc(var(--nav-h) + clamp(18px,3vh,44px)) var(--pad) clamp(28px,4vh,60px);
}
.foot-main h2{
  font-size:clamp(38px,min(9vw,16vh),176px);letter-spacing:-.062em;line-height:.92;
  margin:0;max-width:17ch;
}
.foot-main p{
  margin-top:min(2.4vw,2.6vh);color:rgba(9,10,11,.72);max-width:48ch;
  font-size:clamp(13px,min(1.35vw,2.3vh),20px);
}
.foot-orb{
  align-self:center;border-radius:50%;background:var(--ink);color:var(--paper);
  width:clamp(132px,min(13vw,20vh),190px);height:clamp(132px,min(13vw,20vh),190px);
  display:flex;flex-direction:column;justify-content:space-between;padding:clamp(24px,2.6vw,32px);
  font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;line-height:1.5;
  transition:transform .5s var(--ez),border-radius .5s var(--ez);
}
.foot-orb i{align-self:flex-end;font-style:normal;font-size:22px;line-height:1;color:var(--lime)}
.foot-orb:hover{transform:rotate(-8deg) scale(1.05);border-radius:34%}

.foot-links{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid rgba(9,10,11,.28)}
.foot-link{
  position:relative;display:flex;flex-direction:column;gap:8px;overflow:hidden;
  padding:clamp(16px,2vh,30px) var(--pad);transition:color .45s var(--ez);
}
.foot-link b{position:relative;z-index:2;font-weight:500;font-size:clamp(14px,1.3vw,20px);letter-spacing:-.03em}
.foot-link .lab{position:relative;z-index:2;transition:color .45s var(--ez)}
.foot-link i{
  position:absolute;right:var(--pad);bottom:clamp(16px,2vh,30px);z-index:2;
  font-style:normal;font-size:18px;transition:transform .45s var(--ez);
}
.foot-link::before{
  content:"";position:absolute;inset:0;background:var(--ink);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .5s var(--ez);
}
.foot-link:hover{color:var(--paper)}
.foot-link:hover .lab{color:var(--lime)}
.foot-link:hover::before{transform:scaleX(1)}
.foot-link:hover i{transform:translate(3px,-3px)}

.foot-bottom{
  display:grid;grid-template-columns:1fr 1fr 1fr;align-items:center;gap:14px;
  padding:clamp(14px,2vh,22px) var(--pad);border-top:1px solid rgba(9,10,11,.28);
  font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(9,10,11,.66);
}
.foot-bottom .brand{font-family:var(--sans);font-size:14px;letter-spacing:-.02em;color:var(--ink)}
.foot-bottom .brand sup,.foot-bottom .brand-glyph{color:var(--ink)}
.foot-bottom > span:nth-child(2){justify-self:center;text-align:center}
.foot-bottom > span:last-child{justify-self:end;text-align:right}

/* ============================================================
   REVEAL
   ============================================================ */
html.js [data-reveal]{
  opacity:0;transform:translateY(52px);filter:blur(6px);
  transition:opacity .95s var(--ez),transform 1.1s var(--ez),filter 1s var(--ez);
}
html.js [data-reveal].in{opacity:1;transform:none;filter:blur(0)}
html.js [data-reveal="soft"]{transform:none;filter:none;transition:opacity .9s var(--ez)}
html.js .cost[data-reveal]:nth-child(2){transition-delay:.09s}
html.js .cost[data-reveal]:nth-child(3){transition-delay:.18s}
html.js .cost[data-reveal]:nth-child(4){transition-delay:.27s}
html.js .person[data-reveal]:nth-child(2){transition-delay:.12s}
html.js .case[data-reveal]{clip-path:inset(5% 0 5% 0)}
html.js .case[data-reveal].in{
  clip-path:inset(0 0 0 0);
  transition:opacity .95s var(--ez),transform 1.1s var(--ez),filter 1s var(--ez),clip-path 1.35s var(--ez);
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width:1100px){
  /* Stacks: message first, cluster under it. The cluster keeps the design's
     coordinates — .hero-stage crops to the region the cluster actually
     occupies (461 x 453 of the 1200 x 600 frame) and .hero-cluster is the
     full frame shifted inside it, so nothing has to be re-measured. */
  .hero{height:auto;min-height:0;padding:clamp(34px,6vw,64px) 0}
  .hero-frame{
    width:min(100% - var(--pad) * 2,560px);aspect-ratio:auto;
    container-type:inline-size;
    display:flex;flex-direction:column;gap:clamp(26px,5vw,44px);
  }
  .hero-copy{position:static;translate:none;width:100%;max-width:none;gap:clamp(12px,2.4vw,18px)}
  .hero-stage{position:relative;inset:auto;width:100%;aspect-ratio:461 / 453;overflow:hidden}
  .hero-cluster{top:-18.26%;left:-134.87%;right:auto;bottom:auto;width:260.3%;aspect-ratio:1200 / 600}
  /* the cards render 2.603 x (frame/1200) of design size here */
  .fcard-system,.fcard-metric,.fcard-proto{-webkit-backdrop-filter:blur(2.6cqw);backdrop-filter:blur(2.6cqw)}
  .hero-frame{--card-r:1.74cqw}
  .gpane{-webkit-backdrop-filter:blur(2.6cqw);backdrop-filter:blur(2.6cqw)}
  /* 1cqw is the column now, not the 1200px frame, so the type is re-scaled */
  .hero-copy .dot{width:7px;height:7px}
  .eyebrow{gap:9px}
  .hero-kicker{font-size:max(11px,2.4cqw)}
  .hero-h1{font-size:clamp(34px,10.4cqw,58px)}
  .hero-lede{font-size:max(13px,2.9cqw);line-height:1.5}
  .hero-cta{gap:10px;padding-top:6px}
  .hbtn{font-size:max(12px,2.7cqw);padding:14px 16px;gap:8px}
  .hbtn:hover i{transform:translate(3px,-3px)}
}
@media (max-width:1180px){
  /* below this the hero stops trying to fit one screen: it stacks */
  .case-main,.case:nth-child(even) .case-main{grid-template-columns:1fr;gap:clamp(24px,4vw,44px)}
  .case:nth-child(even) .case-copy{order:0}
  .steps{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:clamp(30px,4vw,52px)}
  /* the rail only spans the first row, so node dots on wrapped rows
     would float with nothing to sit on */
  .step::before{display:none}
  .cost-grid{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:clamp(28px,3.4vw,48px)}
}
@media (max-width:980px){
  .nav-links{display:none}
  .nav{grid-template-columns:1fr auto;gap:16px}
  .proof{grid-template-columns:1fr 1fr;row-gap:clamp(26px,4vw,44px)}
  .people{grid-template-columns:1fr;gap:clamp(26px,4vw,44px)}
  .crew ul{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(12px,1.8vw,20px) 0}
  .crew li:nth-child(odd){padding-left:0;border-left:0}
  .srv-cols{grid-template-columns:1fr}
  .srv-cols p{padding-bottom:16px}
  .sec-head{grid-template-columns:1fr;align-items:start;gap:18px}
  /* a button is narrow enough to stay beside the heading on a tablet —
     only the paragraph variants need to stack */
  .sec-head-cta{grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:24px}
  .sec-head-cta > .btn{justify-self:end}
}
@media (max-width:720px){
  :root{--nav-h:62px}
  .nav-right{gap:12px}
  .nav-cta{font-size:12px}
  .proof{grid-template-columns:1fr}
  .cost-grid{grid-template-columns:1fr}
  .steps{grid-template-columns:1fr}
  /* keep the three metrics side by side while they fit; below ~330px of
     content width the grid drops to two of its own accord */
  .case-res{grid-template-columns:repeat(auto-fit,minmax(94px,1fr));gap:12px 10px}
  .case-res .lab{letter-spacing:.1em}
  .person{grid-template-columns:1fr}
  /* three across, two rows — a column of five ate too much height */
  .crew ul{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 0}
  .crew li{padding-left:10px;border-left:1px solid var(--line);font-size:14px}
  .crew li:nth-child(3n+1){padding-left:0;border-left:0}
  .foot-main{grid-template-columns:1fr;align-items:start;gap:30px}
  .foot-orb{align-self:flex-end}
  .foot-links{grid-template-columns:1fr}
  .foot-link{border-top:1px solid rgba(9,10,11,.28)}
  .foot-links .foot-link:first-child{border-top:0}
  .foot-bottom{grid-template-columns:1fr;justify-items:start;gap:10px;padding:20px var(--pad)}
  .foot-bottom > span:nth-child(2),
  .foot-bottom > span:last-child{justify-self:start;text-align:left}
  .srv-head{grid-template-columns:auto minmax(0,1fr) auto;gap:14px}
  .sec-head-cta{grid-template-columns:1fr;align-items:start;gap:18px}
  .sec-head-cta > .btn{justify-self:start}
  .srv-tag{display:none}
  .aura{display:none}

  /* Section rhythm was set by the 76px floor in --sec: at 390px the vw term
     is only 33px, so every gap between sections was a flat 152px. Retune the
     floor for phones; the desktop token is untouched above 720px. */
  :root{--sec:clamp(46px,11vw,76px)}
  .creed{padding-block:clamp(56px,14vw,90px)}
  .cases{gap:clamp(40px,10vw,52px)}
}
@media (max-width:560px){
  .brand span{display:none}
  footer{min-height:0}
}

/* ============================================================
   REDUCED MOTION — end states only
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  html.js{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  html.js [data-reveal],
  html.js .hero-r{opacity:1 !important;transform:none !important;filter:none !important;clip-path:none !important}
  html.js .w > i{transform:none !important}
  .creed-orbit{display:none}
  .fcard{animation:none;translate:none}
  .orbit-name{animation:none}
  .cost{position:relative;top:0}
  .sheet{box-shadow:none;overflow:visible}
  .sheet::before{display:none}
}


/* a case preview that has a page behind it says so */
.case-more{
  display:inline-flex;align-items:center;gap:8px;
  margin-top:clamp(18px,2vw,28px);font-size:13px;
  border-bottom:1px solid var(--line);padding-bottom:3px;
  transition:border-color .3s var(--ez),gap .3s var(--ez);
}
.case-more:hover{border-color:currentColor;gap:11px}
.case-more .arw{width:.9em;height:.9em}
