/* self-hosted — no third-party font CDN (DSGVO / LG München I 3 O 17493/20) */
@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-italic-33f25.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-b9202.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url(/assets/fonts/mulish-120b6.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* ═══════════════ NETFORGEX — "THE FORGE"═══════════════ */
:root{
  --canvas:#07091C; --canvas-deep:#04050F; --surface:#12162F; --surface-2:#1B2043;
  --canvas-light:#F0EFEF; --surface-light:#FFFFFF;
  --ink:#0A0B1E; --ink-inv:#F4F5FA; --muted:#8B90A8; --muted-dk:#8A8FA6;
  --brand:#424FA2; --brand-lite:#7B85D8; --signal:#92278F; --signal-hot:#E24FD8; --whisper:#76187E;
  /* two documented dim tiers — every secondary-text colour derives from these, never ad hoc */
  --dim-on-dark:#C4C8DC; --dim-on-dark-2:#A9AEC6; --dim-on-light:#3E4256; --dim-on-light-2:#5C6178;
  --state-err:#B22B2B; --state-ok:#1B7A4B;
  --hairline:rgba(244,245,250,.12); --hairline-dk:rgba(10,11,30,.14);
  --r-ctl:2px; --r-panel:24px;
  --e-base:cubic-bezier(.4,0,.2,1); --e-strike:cubic-bezier(.85,0,.15,1); --e-settle:cubic-bezier(.22,1,.36,1);
  --pad:clamp(20px,5vw,80px); --maxw:1440px;
  --z-header:900; --z-float:940; --z-backdrop:999; --z-drawer:1000; --z-cookie:1100;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--canvas);color:var(--ink-inv);
  font-family:"Mulish",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-size:clamp(1rem,.96rem + .2vw,1.09rem);line-height:1.68;font-weight:400;
  overflow-x:hidden;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
img,svg,video{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{font-family:"Archivo","Mulish",sans-serif;font-weight:800;line-height:1.03;
  letter-spacing:-.035em;margin:0;text-wrap:balance}
p{margin:0 0 1.1em}
::selection{background:var(--signal);color:#fff}
:focus-visible{outline:2px solid var(--signal-hot);outline-offset:3px;border-radius:2px}
.sec--light :focus-visible,.form-card :focus-visible,.faq :focus-visible{outline-color:var(--signal)}
.strip-track:focus-visible,.dual:focus-visible,.labs:focus-visible{outline-offset:-3px}
.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:var(--pad)}
.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}
.skip{position:absolute;left:-9999px;top:0;z-index:2000;background:var(--signal);color:#fff;padding:12px 20px}
.skip:focus{left:8px;top:8px}

/* ── GRAIN (tokenised, on every dark surface) ── */
.grain::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.035;z-index:2;
  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='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay}

/* ── TYPE SCALE ── */
.eyebrow{font-family:"Archivo",sans-serif;font-size:.72rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brand-lite);margin:0 0 20px;display:flex;align-items:center;gap:12px}
.eyebrow::before{content:"";width:26px;height:2px;background:var(--signal);flex:none}
/* the type utilities are self-sufficient — they must not depend on being used on an h1-h4 tag */
.h-xl,.h-lg,.h-md,.h-sm{font-family:"Archivo","Mulish",sans-serif;font-weight:800;line-height:1.03;
  letter-spacing:-.035em;text-wrap:balance}
.h-xl{font-size:clamp(3.2rem,9.5vw,9rem);font-variation-settings:"wdth" 92}
.h-lg{font-size:clamp(2.2rem,5.8vw,4.8rem)}
.h-md{font-size:clamp(1.5rem,2.6vw,2.3rem);letter-spacing:-.025em}
.h-sm{font-size:clamp(1.12rem,1.5vw,1.35rem);font-weight:700;letter-spacing:-.015em;line-height:1.25}
/* German runs ~15% longer than English — the variable width axis is exactly the tool for that.
   Narrowing the display cut is a typographic answer, not a shrink. */
html[lang="de"] .h-xl,html[lang="de"] .h1-a{font-variation-settings:"wdth" 80}
html[lang="de"] .h-lg{font-variation-settings:"wdth" 88}
.lead{font-size:clamp(1.02rem,1.15vw,1.2rem);color:var(--dim-on-dark);max-width:46ch}
.dim{color:var(--muted)}
.mono{font-family:ui-monospace,"SFMono-Regular",Menlo,monospace;font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}
.sec-no{font-family:"Archivo",sans-serif;font-variation-settings:"wdth" 70;font-weight:200;
  font-size:clamp(3.5rem,9vw,8.5rem);line-height:.8;color:transparent;
  -webkit-text-stroke:1px rgba(123,133,216,.34);letter-spacing:-.04em;pointer-events:none;user-select:none}

/* ── MASKED LINE REVEAL (the house heading mechanism — never fade-up) ── */
.ml{display:block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
.ml > span{display:block;transition:transform .82s var(--e-settle)}
.js .ml > span{transform:translateY(112%)}
.js .is-in .ml > span{transform:none}
.ml:nth-of-type(2) > span{transition-delay:.07s}
.ml:nth-of-type(3) > span{transition-delay:.14s}
/* [data-reveal] is now PROSE ONLY — supporting copy is the one content type that should not
   perform. Everything structural owns a mechanism of its own, below. */
.js [data-reveal]{opacity:0;transform:translateY(7px)}
.js .hero [data-reveal]{opacity:1;transform:none;transition:none}
[data-reveal]{transition:opacity .5s var(--e-base),transform .5s var(--e-base)}
.js [data-reveal].is-in{opacity:1;transform:none}
[data-reveal][data-d="1"]{transition-delay:.09s} [data-reveal][data-d="2"]{transition-delay:.18s}
[data-reveal][data-d="3"]{transition-delay:.27s} [data-reveal][data-d="4"]{transition-delay:.36s}

/* ⚠ REVEAL TRIGGERING RULE — read before editing any of the mechanisms below.
   An element clipped to zero area (clip-path: inset(0 0 100%) / circle(0%) / a degenerate
   polygon) reports intersectionRatio 0, so an IntersectionObserver watching THAT element can
   never fire — it stays clipped forever. Likewise, a card sitting off-screen to the right
   inside a horizontal swipe row never intersects the viewport at all.
   Therefore every clip-based or in-row reveal is keyed off its CONTAINER, which is never
   clipped and always crosses the viewport vertically. Never key one off the clipped node. */

/* image wipe RAKED to the X diagonal (the DNA asked for the diagonal; v1 shipped a straight inset) */
.wipe{transition:clip-path 1.05s var(--e-settle)}
.js .wipe{clip-path:polygon(0 0,0 0,-28% 100%,-28% 100%)}
.js .is-in .wipe,.js .wipe.is-in{clip-path:polygon(0 0,128% 0,100% 100%,-28% 100%)}

/* ── SERVICE CARDS: the layer strike. The section's own lead says security is "shaped —
   layer by layer". Six identical cards fading up said the opposite; now they arrive in
   sequence, each capped by its heat rule striking across. ── */
.js .svc{clip-path:inset(0 0 100% 0);transition:clip-path .62s var(--e-settle)}
.js .strip-wrap.is-in .svc{clip-path:inset(0 0 0 0)}
.js .strip-wrap.is-in .svc::before{transform:none}
.js .svc:nth-child(2){transition-delay:.09s} .js .svc:nth-child(3){transition-delay:.18s}
.js .svc:nth-child(4){transition-delay:.27s} .js .svc:nth-child(5){transition-delay:.36s}
.js .svc:nth-child(6){transition-delay:.45s}
.js .svc:nth-child(2)::before{transition-delay:.09s} .js .svc:nth-child(3)::before{transition-delay:.18s}
.js .svc:nth-child(4)::before{transition-delay:.27s} .js .svc:nth-child(5)::before{transition-delay:.36s}
.js .svc:nth-child(6)::before{transition-delay:.45s}

/* ── THE TWO HANDS: a vertical curtain, and the outlined numeral cools heat -> steel.
   The strike re-expressed at a third scale, with no new colour. ── */
.js .dual-card{clip-path:inset(0 0 100% 0);transition:clip-path .76s var(--e-settle),background .5s var(--e-base)}
.js .dual.is-in .dual-card{clip-path:inset(0 0 0 0)}
.js .dual-card:nth-child(2){transition-delay:.12s}
.js .dual-card .dc-n{-webkit-text-stroke-color:rgba(226,79,216,.5)}
.js .dual.is-in .dual-card .dc-n{-webkit-text-stroke-color:rgba(66,79,162,.3)}

/* ── THE 1,200+: the page's hardest proof point cools from white-hot over 1.2s —
   the same cooling the hero strike gets. It settles; it does not slide. ── */
.js .lab--stat{opacity:1;transform:none;filter:saturate(1.9) brightness(1.3);
  transition:filter 1.2s var(--e-settle)}
.js .lab--stat.is-in,.js .labs.is-in .lab--stat{filter:none}
/* cards inside the horizontal rows are revealed by the row, never by themselves */
.js .labs.is-in [data-reveal],.js .dual.is-in [data-reveal]{opacity:1;transform:none}

/* ── THE NAMED HUMAN: an aperture opens. A person is not a card. ── */
.js .cto-portrait{clip-path:circle(0% at 50% 50%);transition:clip-path .7s var(--e-settle)}
.js .is-in .cto-portrait{clip-path:circle(52% at 50% 50%)}

/* ── CONTROLS: bracket geometry, never pills ── */
.btn{--bg:var(--signal);position:relative;display:inline-flex;align-items:center;gap:12px;
  padding:17px 30px 17px 26px;border:0;border-radius:var(--r-ctl);background:transparent;color:var(--ink-inv);
  font-family:"Archivo",sans-serif;font-size:.86rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  cursor:pointer;overflow:hidden;isolation:isolate;min-height:48px;
  box-shadow:inset 0 0 0 1px rgba(244,245,250,.46)}
.btn::before{content:"";position:absolute;inset:0;background:var(--bg);z-index:-1;
  transform:scaleX(0);transform-origin:left;transition:transform .42s var(--e-strike)}
.btn::after{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--bg);z-index:-1}
.btn:hover::before,.btn:focus-visible::before{transform:none}
.btn--solid{box-shadow:none}
.btn--solid::before{transform:none}
.btn--solid:hover::before{background:var(--whisper)}
.btn--solid:hover{box-shadow:0 0 0 1px var(--signal-hot),0 10px 30px -14px rgba(226,79,216,.8)}
.btn--ghost{--bg:var(--brand)}
.btn--light{color:var(--ink);box-shadow:inset 0 0 0 1px rgba(10,11,30,.5)}
.btn--light:hover,.btn--light:focus-visible{color:var(--ink-inv)}
.btn .ar{transition:transform .42s var(--e-strike)}
.btn:hover .ar{transform:translateX(5px)}
.lnk{display:inline-flex;align-items:center;gap:9px;--sh:0;font-family:"Archivo",sans-serif;font-weight:700;
  font-size:.82rem;letter-spacing:.14em;text-transform:uppercase;color:var(--signal-hot);
  padding-top:16px;margin-top:-16px;padding-bottom:5px;
  border-bottom:1px solid rgba(226,79,216,.35);transition:border-color .3s var(--e-base),color .3s var(--e-base)}
.lnk svg{transition:transform .3s var(--e-strike)}
.lnk:hover svg{transform:translateX(6px)}
.lnk:hover{border-color:var(--signal-hot)}
/* #E24FD8 on the #F0EFEF daylight ground measures 2.90:1 — a real AA failure. On light the link
   goes to cooled steel (6.42:1) and only heats on hover. */
.sec--light .lnk{color:var(--brand);border-bottom-color:rgba(66,79,162,.35)}
.sec--light .lnk:hover,.sec--light .lnk:focus-visible{color:var(--signal);border-bottom-color:var(--signal)}
.dual-card:hover .lnk,.dual-card:focus-within .lnk{color:var(--signal-hot);border-bottom-color:rgba(226,79,216,.35)}

/* ── HEADER ── */
.site-header{position:fixed;top:0;left:0;right:0;z-index:var(--z-header);
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:16px var(--pad);padding-top:calc(16px + env(safe-area-inset-top));
  transition:background .4s var(--e-base),backdrop-filter .4s var(--e-base),padding .4s var(--e-base)}
.site-header.stuck{background:rgba(7,9,28,.86);backdrop-filter:blur(14px) saturate(1.4);
  box-shadow:0 1px 0 var(--hairline);padding-bottom:11px;padding-top:calc(11px + env(safe-area-inset-top))}
.brand{display:flex;align-items:center;flex:none}
.brand svg{height:26px;width:auto;transition:height .4s var(--e-base)}
.stuck .brand svg{height:22px}
.nav-desktop{display:none;gap:34px;align-items:center;margin-left:auto}
.nav-desktop a{font-family:"Archivo",sans-serif;font-size:.78rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;position:relative;padding:6px 0;color:var(--ink-inv)}
.nav-desktop a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--signal-hot);transform:scaleX(0);transform-origin:left;transition:transform .34s var(--e-strike)}
.nav-desktop a:hover::after,.nav-desktop a:focus-visible::after,.nav-desktop a[aria-current="page"]::after{transform:none}
.hdr-right{display:flex;align-items:center;gap:14px;flex:none}
.langs{display:flex;align-items:center;gap:2px;font-family:"Archivo",sans-serif;font-size:.72rem;font-weight:700;letter-spacing:.1em}
.lang-btn{background:none;border:0;color:var(--muted);padding:7px 11px;cursor:pointer;min-height:44px;min-width:44px;
  font:inherit;transition:color .25s var(--e-base)}
.lang-btn.active{color:var(--signal-hot)}
.lang-sep{color:var(--muted-dk)}
.menu-toggle{display:flex;flex-direction:column;justify-content:center;gap:5px;background:none;border:0;padding:8px;
  cursor:pointer;width:44px;height:44px;order:-1;margin-right:auto}
.menu-toggle span{width:22px;height:2px;background:var(--ink-inv);transition:transform .28s var(--e-base),opacity .28s var(--e-base)}
.menu-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.menu-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.menu-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.hdr-cta{display:none}
/* LEFT DRAWER */
.nav-mobile{position:fixed;top:0;left:0;bottom:0;z-index:var(--z-drawer);width:clamp(236px,66vw,344px);
  transform:translateX(-105%);visibility:hidden;display:flex;flex-direction:column;gap:2px;
  padding:calc(26px + env(safe-area-inset-top)) 26px calc(26px + env(safe-area-inset-bottom));
  background:var(--surface);box-shadow:0 0 60px rgba(0,0,0,.5);overflow-y:auto;
  border-right:1px solid var(--hairline);
  transition:transform .34s var(--e-settle),visibility 0s linear .34s}
.nav-mobile.open{transform:none;visibility:visible;transition:transform .34s var(--e-settle)}
.nav-mobile .dbrand{margin-bottom:26px}
.nav-mobile .dbrand svg{height:22px}
.nav-mobile a.dlink{font-family:"Archivo",sans-serif;font-size:1.32rem;font-weight:700;letter-spacing:-.02em;
  padding:14px 0;min-height:52px;display:flex;align-items:center;justify-content:space-between;
  border-bottom:1px solid var(--hairline)}
.nav-mobile a.dlink span.n{font-size:.66rem;font-weight:600;letter-spacing:.14em;color:var(--muted-dk);font-variant-numeric:tabular-nums}
.nav-mobile .dfoot{margin-top:auto;padding-top:26px}
.nav-mobile .dfoot .btn{width:100%;justify-content:center}
.nav-mobile .dtel{display:block;margin-top:16px;font-family:"Archivo",sans-serif;font-weight:700;font-size:1.02rem;color:var(--signal-hot)}
.nav-backdrop{position:fixed;inset:0;z-index:var(--z-backdrop);background:rgba(4,5,15,.6);
  backdrop-filter:blur(3px);opacity:0;pointer-events:none;transition:opacity .3s var(--e-base)}
.nav-backdrop.show{opacity:1;pointer-events:auto}
body.nav-open{overflow:hidden}
body.nav-open .float-stack,body.nav-open #toTop{opacity:0;pointer-events:none}
/* The header sits at z-index 900, the backdrop at 999 — so while the drawer was open the close
   "X" was buried under the backdrop and could not receive its own tap (the drawer still closed,
   but via the backdrop, not the control the user was aiming at). While open, the header is lifted
   above the backdrop, stripped of its own chrome, and everything except the toggle is hidden —
   so the page still dims correctly behind it and the X is the thing you actually press. */
body.nav-open .site-header{z-index:calc(var(--z-drawer) + 1);background:transparent;
  box-shadow:none;backdrop-filter:none}
body.nav-open .site-header > :not(.menu-toggle){opacity:0;pointer-events:none}
.float-stack{transition:opacity .3s var(--e-base),transform .3s var(--e-base);opacity:0;pointer-events:none;transform:translateY(10px)}
.float-stack.show{opacity:1;pointer-events:auto;transform:none}
[id]{scroll-margin-top:clamp(84px,12vh,112px)}
@media (min-width:1000px){
  .menu-toggle{display:none}
  .nav-desktop{display:flex}
  .nav-mobile{display:none!important}
  .hdr-cta{display:inline-flex}
  .brand{margin-right:0}
}


/* ═══ HERO — "THE STRIKE" ═══ */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;
  padding:clamp(104px,14vh,150px) 0 clamp(40px,7vh,90px);overflow:clip;background:var(--canvas-deep);isolation:isolate}
.hero-media{position:absolute;inset:0;z-index:-2}
.hero-media img,.hero-media video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.62}
/* The loop fades in over the still once it can actually play, so there is never a black flash.
   Specificity note: `.hero-media video` is (0,1,1) and would beat a bare `.hero-vid` (0,1,0) —
   which would leave the video's own poster stacked on top of the image at 62% on every device
   that never loads the video at all. Both rules below are therefore scoped the same way. */
.hero-media .hero-vid{opacity:0;transition:opacity 1.1s var(--e-base)}
.hero-media .hero-vid.on{opacity:.62}
.hero-media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(105deg,rgba(4,5,15,.95) 0%,rgba(4,5,15,.82) 34%,rgba(7,9,28,.5) 62%,rgba(118,24,126,.28) 100%),
             radial-gradient(120% 90% at 78% 32%,rgba(146,39,143,.34) 0%,transparent 62%)}
#sparks{position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:0}
/* ── CENTRED HERO ──
   One column, optically centred, everything on the same axis. The forged X sits BEHIND the
   headline as a struck seal rather than beside it, and the cinematic loop runs behind both. */
/* the headline needs the FULL measure — capping the grid here is what forced
   "Ready to respond." onto a third line. Only the prose is narrowed, below. */
.hero-grid{display:grid;grid-template-columns:1fr;justify-items:center;text-align:center;
  gap:clamp(20px,2.8vh,34px);width:100%;margin-inline:auto;position:relative;z-index:3}
.hero-head{max-width:none;width:100%;display:grid;justify-items:center;gap:0}
.hero .eyebrow{justify-content:center}
/* A scrim under the type. With the X now centred and a moving film behind it, the copy needs
   its own ground or the sparks and the footage read straight through the letterforms. It is a
   pure radial falloff — no visible edge, no box. */
.hero-grid::before{content:"";position:absolute;inset:-8vh -6vw;z-index:-1;pointer-events:none;
  background:radial-gradient(56% 54% at 50% 46%,rgba(4,5,15,.74),rgba(4,5,15,.36) 58%,transparent 80%)}
.h1-a{color:var(--brand-lite);font-style:italic;font-variation-settings:"wdth" 88}
.h1-b{color:var(--ink-inv)}
.hero-body{display:grid;justify-items:center;gap:clamp(22px,3vh,34px);max-width:min(100%,58ch)}
.hero .lead{max-width:56ch;margin-inline:auto}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;justify-content:center}
/* the forged X */
/* the X is now a seal struck behind the headline, on the same centre axis */
.xwrap{position:absolute;left:50%;top:50%;transform:translate(-50%,-54%);width:min(46vw,620px);
  z-index:0;pointer-events:none;opacity:.16;
  -webkit-mask-image:radial-gradient(72% 72% at 50% 50%,#000 42%,transparent 78%);
  mask-image:radial-gradient(72% 72% at 50% 50%,#000 42%,transparent 78%)}
.xwrap svg{width:100%;height:auto;overflow:visible}
#xpath{fill:none;stroke:var(--brand-lite);stroke-width:.85;opacity:.55;stroke-linejoin:round;stroke-dasharray:520}
.js #xpath{stroke-dashoffset:520}
#xfill{fill:var(--signal)}
.js #xfill{opacity:0}
.forged #xpath{animation:draw 1.15s var(--e-base) .35s forwards}
.forged #xfill{animation:strike 1.9s var(--e-strike) 1.4s forwards, breathe 9s ease-in-out 3.4s infinite}
@keyframes draw{to{stroke-dashoffset:0}}
@keyframes strike{
  0%{opacity:0;fill:#fff;filter:drop-shadow(0 0 62px rgba(255,255,255,.95))}
  9%{opacity:1;fill:#fff;filter:drop-shadow(0 0 90px rgba(255,255,255,1))}
  34%{fill:var(--signal-hot);filter:drop-shadow(0 0 56px rgba(226,79,216,.75))}
  100%{opacity:1;fill:var(--signal);filter:drop-shadow(0 0 26px rgba(146,39,143,.42))}}
@keyframes breathe{0%,100%{filter:drop-shadow(0 0 22px rgba(146,39,143,.34))}
  50%{filter:drop-shadow(0 0 46px rgba(226,79,216,.5))}}
/* GSOC live clocks — real data as design material, centred under the fold */
.gsoc{display:flex;flex-wrap:wrap;gap:0;justify-content:center;border-top:1px solid var(--hairline);padding-top:18px;
  position:relative;z-index:3;isolation:isolate;margin:0}
.gsoc::before{content:"";position:absolute;inset:-14px -22px;z-index:-1;border-radius:4px;
  background:radial-gradient(72% 130% at 50% 50%,rgba(4,5,15,.82),rgba(4,5,15,.34) 72%,transparent);backdrop-filter:blur(3px)}
.gsoc li{list-style:none;padding:2px 26px;margin:0;border-right:1px solid var(--hairline)}
.gsoc li:last-child{border-right:0}
.gsoc li:first-child{padding-left:0}
.gsoc .c-city{display:flex;align-items:center;gap:8px;color:var(--muted);font-family:ui-monospace,Menlo,monospace;
  font-size:.66rem;letter-spacing:.14em;text-transform:uppercase}
.gsoc .dot{width:6px;height:6px;border-radius:50%;background:var(--signal-hot);flex:none;
  box-shadow:0 0 0 0 rgba(226,79,216,.6);animation:live 2.8s ease-out infinite}
@keyframes live{0%{box-shadow:0 0 0 0 rgba(226,79,216,.55)}70%,100%{box-shadow:0 0 0 9px rgba(226,79,216,0)}}
.gsoc .c-time{font-family:"Archivo",sans-serif;font-weight:600;font-size:1.02rem;font-variant-numeric:tabular-nums;
  letter-spacing:.02em;color:var(--ink-inv);margin-top:2px;min-width:5ch;display:block}
@media (min-width:1000px){
  .hero{padding:150px 0 90px}
}

/* ═══ SECTION SHELL ═══ */
.sec{position:relative;padding:clamp(72px,11vh,168px) 0;overflow:hidden;overflow:clip}
.sec--dark{background:var(--canvas)}
.sec--deep{background:var(--canvas-deep)}
.sec--light{background:var(--canvas-light);color:var(--ink)}
.sec--light .lead{color:var(--dim-on-light)}
.sec--light .dim{color:var(--dim-on-light-2)}
.sec--light .eyebrow{color:var(--brand)}
.sec--light .sec-no{-webkit-text-stroke-color:rgba(66,79,162,.26)}
/* the strike rule — every section boundary re-heats */
.strike-rule{position:relative;height:2px;background:var(--hairline);overflow:hidden}
.sec--light .strike-rule{background:var(--hairline-dk)}
.strike-rule::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,var(--signal),var(--signal-hot));
  transform-origin:left;transition:transform .5s var(--e-strike)}
/* the Labs -> Statement boundary was the one seam of eight with no strike */
.strike-rule--edge{position:absolute;top:0;left:0;right:0;z-index:3;background:rgba(244,245,250,.14)}
.js .strike-rule::after{transform:scaleX(0)}
.js .strike-rule.is-in::after{transform:none}
.sec-head{display:grid;gap:22px;margin-bottom:clamp(38px,6vh,76px);max-width:60ch}
.sec-head--split{max-width:none;grid-template-columns:1fr;align-items:end}
@media (min-width:900px){.sec-head--split{grid-template-columns:minmax(0,1fr) minmax(0,.8fr);column-gap:60px}}

/* ═══ 01 · DUAL — the two hands ═══ */
.dual{display:grid;grid-template-columns:1fr;gap:2px;background:var(--hairline-dk)}
.dual-card{position:relative;background:var(--canvas-light);padding:clamp(32px,4vw,64px);
  display:grid;gap:20px;align-content:start;overflow:hidden;isolation:isolate;transition:background .5s var(--e-base)}
.dual-card::before{content:"";position:absolute;inset:0;z-index:-1;opacity:0;transition:opacity .55s var(--e-base);
  background:linear-gradient(150deg,var(--canvas-deep),var(--surface-2))}
.dual-card:hover::before,.dual-card:focus-within::before{opacity:1}
.dual-card:hover,.dual-card:focus-within{color:var(--ink-inv)}
.dual-card:hover .dc-lead,.dual-card:focus-within .dc-lead{color:#C4C8DC}
.dual-card:hover .dc-n,.dual-card:focus-within .dc-n{-webkit-text-stroke-color:rgba(226,79,216,.5)}
.dual-card:hover .dc-tag,.dual-card:focus-within .dc-tag{color:var(--signal-hot)}
.dual-card:hover .dc-list li::before,.dual-card:focus-within .dc-list li::before{background:var(--signal-hot)}
.dc-n{position:absolute;top:clamp(10px,2vw,22px);right:clamp(14px,2.4vw,34px);
  font-family:"Archivo",sans-serif;font-variation-settings:"wdth" 68;font-weight:200;font-size:clamp(3.2rem,7vw,6.4rem);
  line-height:.8;color:transparent;-webkit-text-stroke:1px rgba(66,79,162,.3);transition:-webkit-text-stroke-color .76s var(--e-settle);z-index:-1}
.dc-tag{font-family:"Archivo",sans-serif;font-size:.68rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--brand)}
.dc-lead{color:var(--dim-on-light);transition:color .5s var(--e-base);max-width:52ch}
.dc-list{margin:4px 0 0;padding:0;list-style:none;display:grid;gap:9px}
.dc-list li{position:relative;padding-left:20px;font-size:.94rem}
.dc-list li::before{content:"";position:absolute;left:0;top:.62em;width:9px;height:1px;background:var(--signal)}
@media (min-width:920px){.dual{grid-template-columns:1fr 1fr}}

/* ═══ 02 · SIX STRIKES — CSS scroll-driven horizontal pin (zero JS) ═══ */
.strip-wrap{position:relative}
.strip-track{display:flex;gap:22px;padding-inline:var(--pad);overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:8px}
.strip-track::-webkit-scrollbar{display:none}
.svc{scroll-snap-align:center;flex:0 0 min(78vw,404px);background:var(--surface);border:1px solid var(--hairline);
  border-radius:var(--r-panel);padding:clamp(24px,3vw,38px);display:grid;gap:14px;align-content:start;
  position:relative;overflow:hidden;isolation:isolate;min-height:0}
.svc::before{content:"";position:absolute;left:0;top:0;height:3px;width:100%;transform:scaleX(0);transform-origin:left;
  background:linear-gradient(90deg,var(--signal),var(--signal-hot));transition:transform .5s var(--e-strike)}
.svc:hover::before,.svc:focus-within::before{transform:none}
.svc-n{font-family:"Archivo",sans-serif;font-weight:700;font-size:.7rem;letter-spacing:.14em;color:var(--brand-lite);
  font-variant-numeric:tabular-nums}
.svc h3{font-size:clamp(1.16rem,1.5vw,1.42rem);line-height:1.16;letter-spacing:-.02em}
.svc p{color:var(--dim-on-dark-2);font-size:.95rem;margin:0}
.svc .glow{position:absolute;right:-30%;bottom:-40%;width:70%;aspect-ratio:1;border-radius:50%;z-index:-1;
  background:radial-gradient(circle,rgba(66,79,162,.42),transparent 68%);opacity:.6;transition:opacity .6s var(--e-base)}
.svc:hover .glow{opacity:1;background:radial-gradient(circle,rgba(146,39,143,.44),transparent 68%)}
.strip-hint{display:flex;align-items:center;gap:10px;padding-inline:var(--pad);margin-top:22px;color:var(--muted)}
.strip-hint .bar{height:2px;flex:1;max-width:200px;background:var(--hairline);position:relative;overflow:hidden}
.strip-hint .bar i{position:absolute;inset:0;background:var(--signal);transform-origin:left;transform:scaleX(.18)}
@supports (animation-timeline:view()){
 @media (min-width:1000px) and (prefers-reduced-motion:no-preference){
  /* card + gap are declared once here so the hslide distance can be computed from them */
  .strip-wrap{--svc-w:min(31vw,430px);--svc-gap:22px;height:186vh;view-timeline:--strip block}
  /* the pin sizes to its content instead of commandeering a whole viewport for a 310px row */
  .strip-pin{position:sticky;top:calc((100svh - min(100svh,620px)) / 2);height:auto;min-height:min(100svh,620px);
    display:flex;flex-direction:column;justify-content:center;gap:clamp(20px,3vh,36px);
    padding-block:clamp(30px,6vh,72px);overflow:hidden}
  .strip-track{overflow:visible;scroll-snap-type:none;padding-inline:var(--pad);
    animation:hslide linear both;animation-timeline:--strip;animation-range:contain 0% contain 100%}
  .svc{flex:0 0 var(--svc-w);min-height:0}
  /* -100% resolved against the TRACK'S BORDER BOX (= container width, 1440px), not the content
     width (2690px), so the strip advanced ~144px instead of ~1410px and services 05 and 06 were
     never reachable on desktop — no native scroll either, since the track is overflow:visible here.
     The distance is now computed from the real card metrics. */
  @keyframes hslide{to{transform:translateX(calc(100vw - var(--pad)*2 - (6*var(--svc-w) + 5*var(--svc-gap))))}}
  .strip-hint .bar i{animation:hbar linear both;animation-timeline:--strip;animation-range:contain 0% contain 100%}
  @keyframes hbar{from{transform:scaleX(.16)}to{transform:scaleX(1)}}
 }
}


/* ═══ 03 · LABS — broken editorial grid ═══ */
.labs{display:grid;grid-template-columns:1fr;gap:22px}
.lab{border:1px solid var(--hairline);border-radius:var(--r-panel);padding:clamp(24px,3vw,40px);
  display:grid;gap:14px;align-content:start;position:relative;overflow:hidden;background:var(--surface)}
/* the client's own third Labs card, restored — it was demoted to a caption and its slot given to a
   decorative image that mobile then hid entirely. Content back, image kept as its ground. */
.lab--reach{border-color:transparent;isolation:isolate;justify-content:start;align-content:end}
.lab--reach img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;opacity:.5}
.lab--reach::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(150deg,rgba(4,5,15,.62),rgba(27,32,67,.9) 78%)}
.lab--stat{background:linear-gradient(150deg,var(--whisper),var(--surface-2) 70%);border-color:transparent;
  display:grid;align-content:center;gap:6px}
.odo{font-family:"Archivo",sans-serif;font-weight:800;font-variation-settings:"wdth" 84;
  font-size:clamp(3.4rem,7.5vw,6rem);line-height:.86;letter-spacing:-.05em;font-variant-numeric:tabular-nums}
.odo-lbl{font-size:.98rem;line-height:1.3;color:#E4D6EA;max-width:14ch}
.lab .tagx{font-family:"Archivo",sans-serif;font-size:.66rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brand-lite)}
.lab p{color:var(--dim-on-dark-2);font-size:.95rem;margin:0}
.lab .cg{color:var(--brand-lite);font-style:italic}
@media (min-width:900px){
  /* auto rows: the grid no longer forces 504px boxes onto 217px of content */
  .labs{grid-template-columns:repeat(12,1fr);grid-auto-rows:minmax(0,auto)}
  .lab:nth-child(1){grid-column:1/7}
  .lab:nth-child(2){grid-column:7/13}
  .lab:nth-child(3){grid-column:1/5}
  .lab:nth-child(4){grid-column:5/13}
}

/* ═══ 04 · STATEMENT — full bleed, variable-font scrub ═══ */
.statement{position:relative;contain:layout paint;min-height:min(86svh,660px);display:grid;place-items:center;text-align:center;
  padding:clamp(80px,14vh,180px) var(--pad);overflow:hidden;isolation:isolate;background:var(--canvas-deep)}
.statement img.bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;opacity:.4}
.statement::before{content:"";position:absolute;inset:0;z-index:-1;
  background:radial-gradient(120% 80% at 50% 50%,transparent 0%,rgba(4,5,15,.86) 72%)}
.st-line{font-family:"Archivo",sans-serif;font-size:clamp(2.5rem,10vw,8rem);line-height:1;letter-spacing:-.045em;margin:0}
.st-1{font-weight:800;font-variation-settings:"wdth" 90;color:var(--ink-inv)}
.st-2{font-weight:300;font-style:italic;color:var(--signal-hot);font-variation-settings:"wdth" 100}
.st-sub{margin-top:26px;color:#A9AEC6;max-width:44ch;margin-inline:auto}
@supports (animation-timeline:view()){
 @media (prefers-reduced-motion:no-preference){
  .st-1{animation:wmorph linear both;animation-timeline:view();animation-range:entry 20% cover 62%}
  @keyframes wmorph{from{font-variation-settings:"wdth" 70;font-weight:200;letter-spacing:.02em}
    to{font-variation-settings:"wdth" 100;font-weight:800;letter-spacing:-.045em}}
 }
}

/* ═══ 05 · MOBILE SECURITY — arming checklist ═══ */
.ms{display:grid;grid-template-columns:1fr;gap:clamp(34px,5vw,72px);align-items:center}
.ms-list{margin:0;padding:0;list-style:none;display:grid;gap:2px;border-top:1px solid var(--hairline-dk)}
.ms-list li{display:flex;gap:16px;align-items:flex-start;padding:17px 4px;border-bottom:1px solid var(--hairline-dk)}
.ms-list .chk{flex:none;width:22px;height:22px;border:1px solid rgba(66,79,162,.8);border-radius:2px;
  display:grid;place-items:center;margin-top:2px;position:relative;overflow:hidden}
.ms-list .chk::before{content:"";position:absolute;inset:0;background:var(--signal);transition:transform .4s var(--e-strike)}
.js .ms-list .chk::before{transform:scale(0)}
.js .ms-list.is-in .chk::before{transform:none}
.ms-list li:nth-child(2) .chk::before{transition-delay:.1s} .ms-list li:nth-child(3) .chk::before{transition-delay:.2s}
.ms-list li:nth-child(4) .chk::before{transition-delay:.3s} .ms-list li:nth-child(5) .chk::before{transition-delay:.4s}
.ms-list .chk svg{position:relative;z-index:1;width:12px;height:12px;stroke:#fff;stroke-width:2.4;fill:none;transition:opacity .3s var(--e-base) .2s}
.js .ms-list .chk svg{opacity:0}
.js .ms-list.is-in .chk svg{opacity:1}
/* a resting ground so the column is never a blank white half-section before the wipe fires */
.ms-media{position:relative;border-radius:var(--r-panel);overflow:hidden;aspect-ratio:4/3;
  background:linear-gradient(150deg,var(--surface-2),var(--surface))}
.ms-media img{width:100%;height:100%;object-fit:cover}
@media (min-width:920px){.ms{grid-template-columns:minmax(0,1fr) minmax(0,.9fr)}
  .ms--rev .ms-media{order:-1}}

/* ═══ 06 · FAQ ═══ */
.faq{display:grid;gap:0;border-top:1px solid var(--hairline-dk);max-width:860px}
.faq details{border-bottom:1px solid var(--hairline-dk)}
.faq summary{list-style:none;cursor:pointer;padding:22px 44px 22px 0;position:relative;
  font-family:"Archivo",sans-serif;font-weight:700;font-size:clamp(1rem,1.4vw,1.2rem);letter-spacing:-.015em;
  min-height:48px;display:flex;align-items:center}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:8px;top:50%;width:13px;height:13px;
  border-right:2px solid var(--signal);border-bottom:2px solid var(--signal);
  transform:translateY(-70%) rotate(45deg);transition:transform .35s var(--e-base)}
.faq details[open] summary::after{transform:translateY(-20%) rotate(-135deg)}
.faq .a{padding:0 0 24px;color:var(--dim-on-light);max-width:70ch;margin:0}

/* ═══ 07 · CTA CHAPTER ═══ */
.chapter{position:relative;overflow:hidden;background:var(--canvas-deep);isolation:isolate}
.chapter img.bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;opacity:.34}
.chapter::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(100deg,rgba(4,5,15,.96),rgba(7,9,28,.72) 55%,rgba(118,24,126,.4))}
.chapter-grid{display:grid;gap:34px;align-items:end}
@media (min-width:960px){.chapter-grid{grid-template-columns:minmax(0,1.15fr) minmax(0,.75fr);column-gap:70px}}

/* ═══ 08 · CONTACT ═══ */
.contact{display:grid;grid-template-columns:1fr;gap:clamp(34px,4vw,64px)}
.c-meta{display:grid;gap:clamp(22px,3vh,30px);align-content:start}
.c-block .k{font-family:"Archivo",sans-serif;font-size:.68rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brand);margin-bottom:8px}
.c-block .v{font-size:1.06rem;line-height:1.5;color:var(--ink)}
.c-block a.v:hover{color:var(--signal)}
.c-grid2{display:grid;grid-template-columns:1fr 1fr;gap:26px}
.todo{display:inline-block;font-family:ui-monospace,Menlo,monospace;font-size:.66rem;letter-spacing:.06em;
  background:rgba(146,39,143,.10);color:var(--ink);padding:2px 7px;border-radius:2px;
  border:1px dashed rgba(146,39,143,.55);margin-left:6px;vertical-align:middle}
.form-card{background:var(--surface-light);border-radius:var(--r-panel);padding:clamp(26px,3.4vw,48px);
  box-shadow:0 30px 70px -40px rgba(10,11,30,.4);display:grid;gap:4px;align-content:start}
.field{position:relative;margin-bottom:22px}
/* .42 alpha measured 2.84:1 against white — below the 3:1 floor for a UI component boundary */
.field input,.field textarea,.field select{width:100%;border:0;border-bottom:1px solid rgba(10,11,30,.62);
  background:transparent;padding:14px 0 11px;font:inherit;font-size:16px;color:var(--ink);border-radius:0;
  transition:border-color .3s var(--e-base)}
.field textarea{resize:vertical;min-height:96px}
.field label{position:absolute;left:0;top:14px;color:var(--dim-on-light-2);pointer-events:none;font-size:16px;
  transform-origin:left top;transition:transform .28s var(--e-base),color .28s var(--e-base)}
.field input:focus,.field textarea:focus{border-color:var(--signal)}
.field input:focus:not(:focus-visible),.field textarea:focus:not(:focus-visible){outline:0}
.field input:focus-visible,.field textarea:focus-visible{outline:2px solid var(--signal);outline-offset:2px}
.field input[aria-invalid="true"],.field textarea[aria-invalid="true"]{border-color:var(--state-err)}
.field-err{color:var(--state-err);font-size:.76rem;margin:6px 0 0}
.field input:focus + label,.field textarea:focus + label,
.field input:not(:placeholder-shown) + label,.field textarea:not(:placeholder-shown) + label{
  transform:translateY(-22px) scale(.7);letter-spacing:.1em;text-transform:uppercase;color:var(--signal)}
.hp{position:absolute!important;left:-9999px!important}
.consent{display:flex;gap:11px;align-items:flex-start;font-size:.82rem;color:var(--dim-on-light-2);
  margin:4px 0 20px;line-height:1.5;padding:4px;border-radius:2px}
.consent input{margin-top:3px;width:20px;height:20px;accent-color:var(--signal);flex:none}
.consent a{color:var(--signal);text-decoration:underline;text-underline-offset:2px}
/* the consent box is not inside .field, so it was getting neither an error message nor a visible
   invalid state — it now gets both, like every other required control */
.consent:has(input[aria-invalid="true"]){outline:2px solid var(--state-err);outline-offset:2px}
.consent-err{color:var(--state-err);font-size:.76rem;margin:-14px 0 18px}
.form-msg{font-size:.9rem;margin-top:14px;min-height:1.4em}
.form-msg.ok{color:var(--state-ok)} .form-msg.err{color:var(--state-err)}

/* ═══ FOOTER + FLOATS ═══ */
.site-footer{background:var(--canvas-deep);padding:clamp(56px,8vh,96px) 0 30px;position:relative;overflow:hidden}
.f-top{display:grid;gap:36px;padding-bottom:44px;border-bottom:1px solid var(--hairline)}
@media (min-width:860px){.f-top{grid-template-columns:1.4fr 1fr 1fr;column-gap:50px}}
.f-nav{display:grid;gap:11px;align-content:start}
.f-nav .k{font-family:"Archivo",sans-serif;font-size:.66rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-dk);margin-bottom:5px}
.f-nav a{color:var(--dim-on-dark);font-size:.94rem;transition:color .25s var(--e-base)}
.f-nav a:hover{color:var(--signal-hot)}
.f-bot{display:flex;flex-wrap:wrap;gap:16px;justify-content:space-between;align-items:center;padding-top:24px}
.f-bot small{color:var(--muted-dk);font-size:.78rem}
.f-legal{display:flex;flex-wrap:wrap;gap:10px 18px}
.f-legal a{color:var(--muted);font-size:.78rem;text-decoration:underline;text-underline-offset:3px;
  padding-block:8px;display:inline-block}
.f-legal a:hover{color:var(--signal-hot)}
.float-stack{position:fixed;right:16px;bottom:calc(16px + env(safe-area-inset-bottom));z-index:var(--z-float);
  display:flex;flex-direction:column;gap:10px;align-items:flex-end}
.fab{width:52px;height:52px;border-radius:2px;display:grid;place-items:center;border:0;cursor:pointer;
  background:var(--signal);color:#fff;box-shadow:0 12px 30px -10px rgba(146,39,143,.8);
  transition:transform .3s var(--e-strike),background .3s var(--e-base)}
.fab:hover{transform:translateY(-3px);background:var(--signal-hot)}
.fab svg{width:22px;height:22px;fill:currentColor}
/* MOBILE-STANDARD §4.2: back-to-top lives bottom-LEFT — never stacked in the primary float's column */
#toTop{position:fixed;left:16px;right:auto;bottom:calc(16px + env(safe-area-inset-bottom));z-index:var(--z-float);
  width:44px;height:44px;border-radius:2px;border:1px solid var(--hairline);background:rgba(7,9,28,.94);
  color:var(--ink-inv);display:grid;place-items:center;cursor:pointer;opacity:0;pointer-events:none;
  transition:opacity .35s var(--e-base),transform .35s var(--e-base);transform:translateY(10px);backdrop-filter:blur(8px)}
#toTop.show{opacity:1;pointer-events:auto;transform:none}
/* a focused control must never be an invisible-but-live target, whatever the scroll position */
.float-stack:focus-within,#toTop:focus-visible{opacity:1!important;pointer-events:auto!important;transform:none!important}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .ml > span,[data-reveal]{transform:none!important;opacity:1!important}
  .wipe,.svc,.dual-card,.cto-portrait{clip-path:none!important}
  .lab--stat{filter:none!important}
  .dual-card .dc-n{-webkit-text-stroke-color:rgba(66,79,162,.3)!important}
  #xpath{stroke-dashoffset:0!important} #xfill{opacity:1!important;fill:var(--signal)!important}
  .strike-rule::after,.svc::before,.ms-list .chk::before{transform:none!important}
  .strip-wrap{height:auto!important} .strip-pin{position:static!important;height:auto!important}
  .strip-track{overflow-x:auto!important}
}


/* ═══ MOBILE CHOREOGRAPHY (MOBILE-STANDARD §3 · anti-endless-scroll) ═══ */
@media (max-width:919px){
  .sec{padding:52px 0}
  .hero{padding:96px 0 26px}
  .sec-head{margin-bottom:26px;gap:16px}
  /* two hands -> a REAL swipe row. Stacking them cost a full screen of scroll and left the
     "scroll horizontally" label lying about a grid that never scrolled. */
  .dual{display:flex;gap:13px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;
    background:transparent;padding:2px 0 10px;margin-inline:calc(var(--pad) * -1);padding-inline:var(--pad)}
  .dual::-webkit-scrollbar{display:none}
  .dual-card{flex:0 0 86vw;scroll-snap-align:center;padding:26px 22px;
    border:1px solid var(--hairline-dk);border-radius:var(--r-panel)}
  .site-footer .f-bot{padding-bottom:76px}
  .faq .a{padding-right:56px}
  .faq summary{padding-right:56px}
  /* labs -> swipe row, decorative media dropped */
  .labs{display:flex;gap:13px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;
    padding:2px 0 10px;margin-inline:calc(var(--pad) * -1);padding-inline:var(--pad)}
  .labs::-webkit-scrollbar{display:none}
  .lab{flex:0 0 82vw;scroll-snap-align:center;padding:26px 22px}
  .lab--reach{min-height:200px}
  .lab--stat{flex:0 0 68vw}
  /* mobile security: the image does not owe us a screen */
  .ms-media{display:none}
  .ms{gap:0}
  .ms-list li{padding:14px 2px}
  .statement{min-height:56svh;padding:64px var(--pad)}
  .f-top{gap:26px;padding-bottom:32px;grid-template-columns:1fr 1fr}
  .f-top > div:first-child{grid-column:1 / -1}
  .field{margin-bottom:17px}
  .form-card{padding:24px 20px}
  .c-grid2{gap:20px}
  .chapter-grid{gap:26px}
  .svc{min-height:0;padding:24px 22px}
  .site-header{padding:11px var(--pad)}
  .brand svg{height:21px}
}
@media (max-width:520px){
  .c-grid2{grid-template-columns:1fr}
  .hero-cta .btn{flex:1 1 100%;justify-content:center}
}
/* swipe affordance */
.swipe-cue{display:flex;align-items:center;gap:9px;margin-top:12px;color:var(--muted);
  font-family:ui-monospace,Menlo,monospace;font-size:.64rem;letter-spacing:.12em;text-transform:uppercase}
.sec--light .swipe-cue{color:var(--dim-on-light-2)}
.swipe-cue svg{width:26px;height:8px;stroke:currentColor;fill:none;stroke-width:1.4}
@media (min-width:920px){.swipe-cue{display:none}}


/* ── THE BRIDGE ──
   The client's second message ("Need a website you can trust?") used to sit inside the hero,
   which is why the fold was crowded. It now gets its own quiet band between the hero and the
   two-hands section: still the first thing after the fold, but no longer competing with the
   headline for the same screen. Its content survives verbatim — the fidelity contract holds. */
.bridge{position:relative;background:var(--canvas-deep);padding:0 0 clamp(52px,8vh,104px);
  overflow:clip;isolation:isolate}
.offer-card{position:relative;border-radius:var(--r-panel);padding:clamp(24px,3vw,40px);
  background:linear-gradient(155deg,rgba(27,32,67,.62),rgba(7,9,28,.5));
  border:1px solid var(--hairline);max-width:none;display:grid;gap:14px;
  box-shadow:inset 0 1px 0 rgba(244,245,250,.07)}
.oc-k{font-family:"Archivo",sans-serif;font-size:.64rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--brand-lite);margin:0}
.oc-h{font-family:"Archivo","Mulish",sans-serif;font-weight:800;
  font-size:clamp(1.24rem,2.2vw,1.9rem);letter-spacing:-.025em;line-height:1.12;margin:0;text-wrap:balance}
.oc-p{color:var(--dim-on-dark);font-size:.95rem;margin:0;max-width:52ch}
@media (min-width:820px){
  .offer-card{grid-template-columns:minmax(0,1fr) minmax(0,.9fr);
    grid-template-areas:"k lnk" "h p" "h cta";column-gap:clamp(30px,4vw,60px);row-gap:12px;align-items:start}
  .oc-k{grid-area:k} .oc-h{grid-area:h;align-self:center} .oc-p{grid-area:p}
  .offer-card .lnk{grid-area:cta;justify-self:start}
}
/* contact: two columns on desktop (the form must sit beside the copy, not below it) */
@media (min-width:960px){.contact{grid-template-columns:minmax(0,1fr) minmax(0,.88fr);align-items:start}}
/* low-capability devices: drop the expensive layers.
   The gate previously covered only blur+grain — it now also drops the two effects with real
   measured main-thread cost: the variable-font scrub (per-frame reflow of an 8rem headline)
   and the ambient heat-glow loop. The X still draws and strikes; only the costly parts go. */
.lowfi .site-header.stuck,.lowfi .nav-backdrop,.lowfi #toTop,.lowfi .offer-card,.lowfi .gsoc::before{backdrop-filter:none}
.lowfi .grain::after{display:none}
.lowfi .st-1{animation:none!important;font-variation-settings:"wdth" 90;font-weight:800}
.lowfi .forged #xfill{animation:strike 1.9s var(--e-strike) 1.4s forwards!important}


/* ── hero final composition — the centred fold ── */
.hero-grid{align-content:center}
@media (min-width:1000px){
  .hero-grid{row-gap:clamp(26px,3.8vh,46px)}
  .gsoc::before{inset:-12px -22px -10px -22px}
}
/* ── mobile hero — ONE block. Three earlier blocks re-declared the same six properties;
   only the last of each was ever reaching the browser. Consolidated to the winning values. ── */
@media (max-width:999px){
  .hero .eyebrow{font-size:.58rem;letter-spacing:.07em;margin-bottom:16px;align-items:center;gap:9px;justify-content:center}
  .hero .eyebrow::before{width:16px}
  .hero .lead{font-size:.92rem;line-height:1.6}
  .hero-grid{gap:22px}
  .hero-body{gap:22px}
  .hero{padding:96px 0 34px}
  /* the seal reads bigger and softer on a small screen, still behind the type */
  .xwrap{width:118vw;opacity:.2}
  .hero-cta{display:grid;grid-template-columns:1fr 1fr;gap:9px;width:100%}
  .hero-cta .btn{justify-content:center;padding:14px 10px;font-size:.72rem;
    letter-spacing:.03em;min-height:48px;text-align:center}
  .hero-cta .btn .ar{display:none}
  /* three clocks must stay on one line at 390 — 26px of side padding each pushed Sydney down */
  .gsoc{padding-top:15px}
  .gsoc li{padding:2px 13px}
  .gsoc .c-city{font-size:.6rem;letter-spacing:.1em;gap:6px}
  .gsoc .c-time{font-size:.92rem;min-width:4.6ch}
  .offer-card{padding:18px}
  .oc-p{font-size:.85rem;margin-bottom:11px}
  .gsoc{padding-top:14px}
  .gsoc li{padding-right:16px;margin-right:16px}
  .gsoc .c-time{font-size:.92rem}
}
@media (max-width:520px){
  .h-xl{font-size:clamp(2.55rem,11.2vw,4.4rem);overflow-wrap:normal;hyphens:none}
  .hero .lead{font-size:.86rem}
  .hero-cta{gap:10px}
  .btn{padding:15px 22px;font-size:.79rem;min-height:46px}
  /* the German eyebrow ran to x=378 of 390 — zero optical margin */
  .hero .eyebrow{flex-wrap:wrap;padding-right:8px;font-size:.55rem;letter-spacing:.05em}
}


@media (min-width:1000px){
  .strip-hint{position:static;margin-top:0;align-items:center;pointer-events:none}
  .strip-hint .bar{max-width:min(38vw,420px)}
}


/* ═══════════════ CRAFT LAYER ═══════════════
   The page was flat: flat panels, flat seams, flat states. Nothing below adds a new colour or a
   new idea — it adds the light that makes the existing material read as material. This is the
   difference between "a competent dark site" and "somebody made this on purpose". */

/* 1 · EDGE LIGHT. A surface that meets light has a bright top edge. One inset line per panel. */
.svc,.lab,.offer-card,.form-card,.nav-mobile{box-shadow:inset 0 1px 0 rgba(244,245,250,.075)}
.lab--stat{box-shadow:inset 0 1px 0 rgba(244,245,250,.16)}
.form-card{box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 30px 70px -40px rgba(10,11,30,.4)}

/* 2 · THE SEAM. Daylight met the smithy as a butt joint. Now the dark bleeds a little into the
   top of every light section, so the page reads as one lit room instead of stacked slabs. */
.sec--light{position:relative}
.sec--light::before{content:"";position:absolute;left:0;right:0;top:0;height:clamp(70px,9vh,140px);
  pointer-events:none;z-index:0;background:linear-gradient(180deg,rgba(7,9,28,.085),transparent)}
.sec--light > *{position:relative;z-index:1}

/* 3 · DEPTH IN THE DARK PANELS. A single flat fill has no interior. A very slight radial lift
   from the top-left gives each card an implied light source — the same one for all of them. */
.svc,.lab:not(.lab--stat):not(.lab--reach){
  background-image:radial-gradient(120% 100% at 0% 0%,rgba(123,133,216,.055),transparent 62%)}

/* 4 · HAIRLINES THAT CATCH LIGHT. A border that is the same value all the way round is a box.
   A border that is brighter where the light hits is an edge. */
.svc,.lab{border-color:rgba(244,245,250,.10)}
.svc:hover,.lab:hover{border-color:rgba(244,245,250,.17)}

/* 5 · STATES WITH INTENT. The buttons filled but did not feel struck; the links moved but did
   not settle. Same three curves, more considered. */
.btn--solid{box-shadow:0 1px 0 rgba(244,245,250,.18) inset}
.btn:active{transform:translateY(1px)}
.btn--light{background:rgba(10,11,30,.03)}
.lnk{transition:border-color .3s var(--e-base),color .3s var(--e-base),gap .3s var(--e-strike)}
.lnk:hover{gap:13px}
.f-nav a{transition:color .25s var(--e-base),padding-left .28s var(--e-strike);padding-left:0}
.f-nav a:hover{padding-left:5px}

/* 6 · THE STRIKE RULE, ESCALATING. Eight identical 2px bars is a tic. The rule now carries a
   soft heat bloom under it, so the strike reads as something that happened rather than a divider
   that was placed. */
.strike-rule{overflow:visible}
.strike-rule::before{content:"";position:absolute;left:0;right:0;top:-1px;height:16px;
  pointer-events:none;opacity:0;transition:opacity .7s var(--e-settle) .12s;
  background:radial-gradient(60% 300% at 8% 50%,rgba(226,79,216,.30),transparent 70%)}
.js .strike-rule.is-in::before{opacity:1}
.strike-rule::after{overflow:hidden}

/* 7 · SELECTION AND FOCUS, on brand. */
::selection{background:var(--signal);color:#fff;text-shadow:none}
.sec--light ::selection{background:var(--brand);color:#fff}

/* 8 · GRAIN WITH INTENT. It was a uniform 3.5% everywhere. It should be strongest where the
   material is darkest and absent where type must stay crisp. */
.grain::after{opacity:.028}
.hero.grain::after{opacity:.042}
.sec--deep.grain::after{opacity:.038}

/* ── mobile density pass (anti-endless-scroll) ── */
@media (max-width:919px){
  .dual-card{padding:22px 20px;gap:14px}
  .dc-lead{font-size:.9rem;line-height:1.58}
  .dc-list li{font-size:.87rem}
  .dc-list{gap:7px}
  .dc-n{font-size:clamp(2.6rem,11vw,4rem)}
  .c-meta{gap:20px}
  .c-grid2{gap:16px}
  .c-block .v{font-size:1rem}
  .ms-list li{padding:12px 2px}
  .lab p,.svc p{font-size:.9rem}
  .chapter-grid aside p{font-size:.9rem}
  .f-top{gap:20px;padding-bottom:24px}
  .f-nav{gap:8px}
  .faq summary{padding:18px 56px 18px 0}
  .faq .a{padding-bottom:18px}
  .sec-head{margin-bottom:26px}
}


/* ═══════════════════════ THE FORGE, MEASURED ═══════════════════════
   One numbered document, progressively worked. Heat arrives, heat cools, heat is never at
   rest. Applied as later-source overrides — nothing above this block is deleted, so the whole
   uplift reverts by removing this one stylesheet. ═══════════════════════ */

/* ── 2 · THE LADDER ──
   text-wrap:balance MINIMISES the longest line, i.e. it refuses any measure you give it —
   proven: widening the about head from 687px to 842px did not move the line widths at all.
   The .ml spans are the lines the copywriter wrote; the browser does not get a vote. */
h1,h2,h3,h4,.h-xl,.h-lg,.h-md,.h-sm{text-wrap:pretty}
/* the missing middle tier — the scale had a 2.09x void with nothing in it */
.h-mid{font-family:"Archivo","Mulish",sans-serif;font-weight:800;line-height:1.06;
  letter-spacing:-.03em;font-size:clamp(1.9rem,3.55vw,3.35rem);
  font-variation-settings:"wdth" 92;text-wrap:pretty}
html[lang="de"] .h-mid{font-variation-settings:"wdth" 84}
.h-sm{font-size:clamp(1.2rem,1.72vw,1.55rem);line-height:1.2}
.svc h3{font-weight:700;font-variation-settings:"wdth" 96;line-height:1.14}
@supports (text-box: trim-both cap alphabetic){
  .h-xl,.h-lg,.h-md,.h-sm,.h-mid,.st-line,.sec-no,.odo,.faq summary,.dc-n{text-box:trim-both cap alphabetic}
  .h-lg{margin-block:.06em .04em}
  .sec-no{margin-bottom:.1em}
}
@media (max-width:919px){
  .h-md{font-size:clamp(1.62rem,6.4vw,2rem);line-height:1.1;letter-spacing:-.028em;font-variation-settings:"wdth" 88}
  .dc-n{font-size:clamp(3rem,13vw,4.6rem);font-variation-settings:"wdth" 62}
}
@media (max-width:520px){ .mono,.gsoc .c-city{font-size:.7rem} }

/* ── 3 · THE MEASURE ──
   `.sec-head{max-width:60ch}` resolved `ch` against the SECTION's 17.44px body font — a body
   measure was hard-capping a 76.8px display face at 627.84px inside a 1296px column. */
:root{--measure-display:min(880px,100%)}
.sec-head{max-width:none}
@media (min-width:900px){
  .sec-head:not(.sec-head--split){max-width:var(--measure-display)}
  .sec-head--split{grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);
    column-gap:clamp(40px,5vw,72px);align-items:start}
  .sec-head--split > .lead{max-width:none;padding-top:.6em}
}
@media (min-width:920px){.ms{grid-template-columns:minmax(0,1.24fr) minmax(0,.78fr)}}
@media (min-width:960px){.chapter-grid{grid-template-columns:minmax(0,1.3fr) minmax(0,.66fr)}}
/* NO white-space:nowrap here. `.ml` is overflow:hidden for the masked reveal, so a nowrap line
   that does not fit is not merely tight — it is SILENTLY TRUNCATED mid-word. Measured: "The
   people who defend it" rendered 771px inside a 765px clip box and lost its final glyph.
   The width axis is tuned so the authored lines fit on their own, and wrapping stays available
   as the safety net: a line that breaks is recoverable, a line that is cut is not. */
@media (min-width:1000px){
  .h-lg{font-variation-settings:"wdth" 82}
  html[lang="de"] .h-lg{font-variation-settings:"wdth" 72}
}
/* both rules must repeat here: html[lang=de] (0,2,1) beats a bare .h-lg (0,1,0) across queries */
@media (min-width:1000px) and (max-width:1360px){
  .h-lg{font-variation-settings:"wdth" 76}
  html[lang="de"] .h-lg{font-variation-settings:"wdth" 68}
}

/* ── 4 · THE FOLIO ──
   design-dna promised "oversized section numbers outdented into the margin". The build shipped
   two orphan numerals for nine sections, neither outdented, both stacked on the same left edge
   as the rule, the label and the heading above them. Four elements on one edge is the most
   inert composition available. */
.sec-no{display:block;width:max-content;margin-left:calc(var(--pad) * -1);
  font-variation-settings:"wdth" 64;font-weight:150;
  font-size:clamp(3.6rem,10vw,9rem);line-height:.72;margin-bottom:.05em;
  -webkit-text-stroke:1.25px rgba(123,133,216,.30)}
.sec--light .sec-no{-webkit-text-stroke-color:rgba(66,79,162,.24)}
@media (min-width:1601px){.sec-no{margin-left:calc(var(--pad) * -1 - .055em)}}
.sec .wrap > .strike-rule{margin-inline:calc(var(--pad) * -1)}

/* THE STANDFIRST — 32 tracked-caps labels across 9 of 9 sections is the trap design-dna's own
   anti_templates list bans by name. Same copy, same bilingual pairs, a voice instead of a label. */
.eyebrow{font-family:"Archivo",sans-serif;font-style:italic;font-weight:400;
  font-size:clamp(.95rem,1.15vw,1.14rem);letter-spacing:0;text-transform:none;
  color:var(--brand-lite);margin:0 0 clamp(14px,1.6vw,22px);display:block;padding-left:.05em}
.eyebrow::before{display:none}
.sec--light .eyebrow{color:var(--brand)}
.hero .eyebrow{text-align:center}
.dc-tag,.oc-k,.lab .tagx{font-family:"Archivo",sans-serif;font-style:italic;font-weight:400;
  text-transform:none;letter-spacing:0;font-size:clamp(.92rem,1.05vw,1.06rem)}
@media (max-width:520px){
  .eyebrow,.hero .eyebrow{font-size:.95rem;letter-spacing:0;text-transform:none;font-style:italic}
  .dc-tag,.oc-k,.lab .tagx{font-size:.9rem}
}

/* ── 5 · RHYTHM. One padding value repeated nine times is a metronome, not a page. ── */
.sec--tight{padding-block:clamp(44px,6.5vh,96px)}
.sec--breathe{padding-block:clamp(104px,15vh,208px)}
@media (max-width:999px){
  .sec--tight{padding-block:clamp(34px,5vh,52px)}
  .sec--breathe{padding-block:clamp(76px,11vh,120px)}
  .sec-head{gap:16px;margin-bottom:clamp(26px,5vh,44px)}
  .sec--breathe .sec-head{margin-bottom:clamp(34px,7vh,58px)}
}
/* the page's one full-bleed interruption was 660px inside a 900px viewport — it never
   filled the screen and therefore never interrupted anything */
.statement{min-height:100svh}
@media (max-width:999px){.statement{min-height:88svh}}

/* ── 6 · THE CONTAINER BREAKS. --pad is the page gutter, so the bleed is exact at every
   width. No 100vw anywhere. ── */
@media (min-width:1000px){
  #endpoint-security .ms{align-items:stretch}
  #endpoint-security .ms-media{margin-right:calc(var(--pad) * -1);
    border-radius:var(--r-panel) 0 0 var(--r-panel);
    aspect-ratio:auto;height:100%;min-height:clamp(460px,54vh,560px)}
}
@media (max-width:999px){
  #endpoint-security .ms-media{margin-right:calc(var(--pad) * -1);
    border-radius:var(--r-panel) 0 0 var(--r-panel)}
}
@media (min-width:920px){
  #about .dual{margin-inline:calc(var(--pad) * -1)}
  #about .dual-card{padding:clamp(40px,4.4vw,72px)}
  #about .dual-card:first-child{padding-left:var(--pad)}
  #about .dual-card:last-child{padding-right:var(--pad)}
}
@media (max-width:919px){
  #about .dual{margin-inline:calc(var(--pad) * -1)}
  #about .dual-card{padding:clamp(26px,7vw,38px) var(--pad)}
}

/* ── 7 · THE HERO. The italic line stretches on the width axis until it locks flush with the
   roman line beneath it. The ratio is font-size independent, so it holds at every width. ── */
/* ── 19 · THE HEADLINE WAS SIZED TO THE MILLIMETRE ──
   Measured: at 1440 "Ready to respond." rendered 1290px inside a 1290px mask — it fit with
   ZERO headroom. At 1512 the mask rounds to 1289px, the line wraps, the hero grows ~300px,
   and the CTAs fall below the fold (52px under at 1512x850, 10px at 1920x1080). A display
   headline must never be tuned to its container's last pixel; one subpixel of padding change
   flips it. This cap leaves ~17% headroom on the longest line at every width, and the smaller
   vw coefficient buys back ~54px of vertical space so the buttons clear the fold on a 720p
   laptop — where the GSOC rail was also being pushed out of sight. */
.h-xl{font-size:clamp(2.6rem,9.6vw,8.6rem);line-height:.94;font-variation-settings:"wdth" 92}
.h1-a{font-variation-settings:"wdth" 107}
html[lang="de"] .h-xl{font-variation-settings:"wdth" 80}
html[lang="de"] .h1-a{font-variation-settings:"wdth" 82}
@media (max-width:999px){
  .h-xl{font-size:clamp(2.5rem,12.6vw,5.2rem);line-height:.96;
    font-variation-settings:"wdth" 76;overflow-wrap:normal;hyphens:none}
  .h1-a{font-variation-settings:"wdth" 88}
  html[lang="de"] .h-xl{font-variation-settings:"wdth" 66}
  html[lang="de"] .h1-a{font-variation-settings:"wdth" 76}
}
/* THE GRADE — built for the loop. A vignette holds the eye, a top scrim keeps the nav on
   ground whatever frame is playing, and the footage dissolves into the smithy floor before
   it ever reaches the seam. */
.hero-media::after{background:
  radial-gradient(118% 86% at 50% 42%,rgba(4,5,15,.26) 0%,rgba(4,5,15,.76) 56%,rgba(4,5,15,.95) 100%),
  radial-gradient(64% 52% at 50% 28%,rgba(146,39,143,.24) 0%,transparent 70%)}
.hero-media::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(4,5,15,.80) 0,rgba(4,5,15,0) 210px),
             linear-gradient(0deg,var(--canvas-deep) 0,rgba(4,5,15,0) 180px)}
.site-header::before{content:"";position:absolute;left:0;right:0;top:-1px;height:140px;z-index:-1;
  pointer-events:none;background:linear-gradient(180deg,rgba(4,5,15,.74),rgba(4,5,15,0));
  transition:opacity .4s var(--e-base)}
.site-header.stuck::before{opacity:0}
/* THE INSTRUMENT RAIL — real data as the HUD that grounds the frame */
@media (min-width:1000px){
  .hero{padding:150px 0 124px}
  .hero > .gsoc{position:absolute;left:0;right:0;bottom:0;width:100%;margin:0;z-index:4;
    padding:15px var(--pad) 16px;display:flex;flex-direction:row;justify-content:center;gap:0;
    border-top:1px solid var(--hairline);
    background:linear-gradient(180deg,rgba(4,5,15,0),rgba(4,5,15,.72) 55%);backdrop-filter:blur(3px)}
  .hero > .gsoc::before{display:none}
  .hero > .gsoc li{border-left:0;border-right:1px solid var(--hairline);padding:0 46px;margin:0;
    display:grid;justify-items:center}
  .hero > .gsoc li:last-child{border-right:0}
  .hero > .gsoc .c-city{justify-content:center}
}

/* ── 8 · THE STRIKE, MADE VISIBLE. At opacity .16 behind an 1150px headline the seal was
   invisible, so the signature moment read as 110 dots erupting from nothing. ── */
.xwrap{opacity:.12}
#xpath{opacity:.85}
.forged{animation:sealbloom 3.4s var(--e-settle) .3s both}
@keyframes sealbloom{0%,32%{opacity:.36}38%{opacity:.56}100%{opacity:.12}}
@media (max-width:999px){
  .forged{animation-name:sealbloomM}
  @keyframes sealbloomM{0%,32%{opacity:.40}38%{opacity:.62}100%{opacity:.20}}
}
/* the strike FINISHES the headline — it is not a firework behind a finished picture */
.h1-a{transition:color .9s var(--e-settle) .05s}
.js .hero-head:not(.struck) .h1-a{color:var(--muted)}
.js .hero-head.struck h1{animation:h1strike .52s var(--e-settle) both}
@keyframes h1strike{
  0%{filter:none;transform:translate3d(0,0,0)}
  15%{filter:drop-shadow(0 0 24px rgba(255,255,255,.55)) drop-shadow(0 0 56px rgba(226,79,216,.7));
      transform:translate3d(0,3px,0)}
  100%{filter:none;transform:translate3d(0,0,0)}}
@media (prefers-reduced-motion:reduce){
  .js .hero-head .h1-a{color:var(--brand-lite)!important}
  .forged{animation:none!important;opacity:.12}
  .js .hero-head.struck h1{animation:none!important}
}

/* ── 9 · SIX STRIKES ── */
.pin-head{max-width:var(--maxw);width:100%;margin-inline:auto;padding-inline:var(--pad);margin-bottom:0}
.svc-buy{margin:4px 0 0!important;padding-top:13px;border-top:1px solid var(--hairline);
  font-family:"Archivo",sans-serif;font-weight:700;font-size:.9rem!important;line-height:1.35;
  letter-spacing:-.012em;color:var(--brand-lite)!important;align-self:end}
.svc{align-content:space-between}
.layer-close{display:grid;gap:20px;margin-top:clamp(36px,5vh,72px);
  padding-top:clamp(26px,3.6vh,42px);border-top:1px solid var(--hairline)}
.layer-close p{font-family:"Archivo",sans-serif;font-weight:800;letter-spacing:-.025em;
  font-size:clamp(1.4rem,2.4vw,2.1rem);line-height:1.08;margin:0;max-width:22ch;color:var(--ink-inv)}
@media (min-width:820px){.layer-close{grid-template-columns:minmax(0,1fr) auto;align-items:end;column-gap:48px}}
@supports (animation-timeline:view()){
 @media (min-width:1000px) and (prefers-reduced-motion:no-preference){
  /* hslide recomputes from --svc-w, so the keyframe is NOT touched and the
     card-06-unreachable bug cannot return */
  .strip-wrap{--svc-w:min(26vw,364px);--svc-gap:22px;height:170vh}
  /* align-items:center survives from the pre-column layout, and in a COLUMN flex container it
     centres horizontally — which shrank .strip-track to its natural width (measured 459px
     instead of 1440px). hslide's travel is computed from 100vw, so a shrunken track meant the
     last two service cards never reached the viewport again. Both axes are pinned explicitly. */
  .strip-pin{top:calc((100svh - min(100svh,660px)) / 2);min-height:min(100svh,660px);
    gap:clamp(18px,2.6vh,32px);padding-block:clamp(20px,3vh,40px);align-items:stretch}
  .strip-pin > .strip-track{width:100%;flex:none}
  .pin-head{animation:headFade linear both;animation-timeline:--strip;animation-range:contain 36% contain 64%}
  @keyframes headFade{from{opacity:1}to{opacity:.34}}
  /* cancel the blanket that struck all six at once, before the pin even engaged */
  .js .strip-wrap.is-in .svc::before{transform:scaleX(0)}
  .svc::before{animation:svcstrike linear both;animation-timeline:--strip}
  .svc:nth-child(1)::before{animation-range:contain -6% contain  6%}
  .svc:nth-child(2)::before{animation-range:contain 10% contain 22%}
  .svc:nth-child(3)::before{animation-range:contain 27% contain 39%}
  .svc:nth-child(4)::before{animation-range:contain 44% contain 56%}
  .svc:nth-child(5)::before{animation-range:contain 61% contain 73%}
  .svc:nth-child(6)::before{animation-range:contain 78% contain 90%}
  @keyframes svcstrike{0%{transform:scaleX(0);opacity:1}46%{transform:scaleX(1);opacity:1}
    100%{transform:scaleX(1);opacity:.30}}
  .svc:hover::before,.svc:focus-within::before{opacity:1}
  /* no two adjacent cards share a top edge: a forged edge, not a filmstrip */
  .strip-track{align-items:flex-start}
  .svc:nth-child(even){margin-top:clamp(20px,3vh,42px)}
 }
}
@media (prefers-reduced-motion:reduce){.pin-head{animation:none!important;opacity:1!important}}

/* ── 10 · THE STRIKE, MEASURED. Eight identical bars was a tic. The rule now starts cold,
   reaches white-hot at its leading tip, goes out, and leaves cooled steel behind it — as far
   as each section's own measure goes. Compositor-only: transform + opacity. ── */
.strike-rule{--reach:100%;position:relative;height:2px;overflow:hidden;
  background:linear-gradient(90deg,var(--hairline) 0,var(--hairline) 56%,rgba(244,245,250,0) 100%)}
.sec--light .strike-rule{
  background:linear-gradient(90deg,var(--hairline-dk) 0,var(--hairline-dk) 56%,rgba(10,11,30,0) 100%)}
.strike-rule--edge{background:rgba(244,245,250,.14)}
.strike-rule::after{content:"";position:absolute;left:0;top:0;bottom:0;right:auto;width:var(--reach);
  background:linear-gradient(90deg,var(--brand),var(--brand-lite));
  transform-origin:left;transition:transform .68s var(--e-strike)}
.js .strike-rule::after{transform:scaleX(0)}
.js .strike-rule.is-in::after{transform:none}
.strike-rule::before{content:"";position:absolute;left:0;top:0;bottom:0;width:var(--reach);
  height:auto;z-index:1;opacity:1;
  background:linear-gradient(90deg,transparent 0 calc(100% - 96px),
    rgba(146,39,143,.9) calc(100% - 60px),var(--signal-hot) calc(100% - 22px),
    #fff calc(100% - 2px),#fff 100%);
  transform:translate3d(-101%,0,0);
  transition:transform .68s var(--e-strike),opacity .3s var(--e-base) .6s}
.js .strike-rule.is-in::before{transform:translate3d(0,0,0);opacity:0}
/* the forge is further along every time you meet it */
#about .strike-rule{--reach:34%}
#services .strike-rule{--reach:56%}
#labs .strike-rule{--reach:72%}
#endpoint-security .strike-rule{--reach:44%}
#faq .strike-rule{--reach:80%}
#team .strike-rule{--reach:92%}
#contact .strike-rule{--reach:100%}
@media (max-width:520px){
  .strike-rule::before{background:linear-gradient(90deg,transparent 0 calc(100% - 52px),
    rgba(146,39,143,.9) calc(100% - 34px),var(--signal-hot) calc(100% - 14px),
    #fff calc(100% - 2px),#fff 100%)}
}
@media (prefers-reduced-motion:reduce){
  .strike-rule::before{display:none}
  .strike-rule::after{transform:none!important}
}

/* ── 11 · THE FORGED LINE.
   `overflow:hidden` made this section its own scrollport, so `animation-timeline:view()` was
   pinned at 100% and this mechanism NEVER RAN ONCE on the shipped page. clip is not a
   scroll container. ── */
.statement{overflow:clip}
@supports (animation-timeline:view()){
 @media (prefers-reduced-motion:no-preference){
  .st-1{animation:wmorph linear both;animation-timeline:view();animation-range:entry 35% cover 52%}
  @keyframes wmorph{
    from{font-variation-settings:"wdth" 70;font-weight:200;letter-spacing:.02em}
    to  {font-variation-settings:"wdth" 100;font-weight:800;letter-spacing:-.045em}}
  .st-2{animation:wmorph2 linear both;animation-timeline:view();animation-range:entry 35% cover 52%}
  @keyframes wmorph2{from{font-variation-settings:"wdth" 118}to{font-variation-settings:"wdth" 100}}
 }
}
.lowfi .st-1,.lowfi .st-2{animation:none!important}
.lowfi .st-1{font-variation-settings:"wdth" 90;font-weight:800}
.lowfi .st-2{font-variation-settings:"wdth" 100}
@media (prefers-reduced-motion:reduce){ .st-1,.st-2{animation:none!important} }

/* ── 12 · THE FAQ. The questions ARE the section's content. 19.2px on 1.68 leading was a
   list; 31px on 1.14 is a Q&A. ── */
.faq summary{font-size:clamp(1.28rem,2.05vw,1.95rem);line-height:1.14;letter-spacing:-.026em;
  font-variation-settings:"wdth" 92;padding:24px 60px 24px 0;align-items:flex-start}
.faq summary::after{top:calc(24px + .5em);transform:translateY(0) rotate(45deg)}
.faq details[open] summary::after{transform:translateY(6px) rotate(-135deg)}
.faq .a{max-width:56ch;font-size:1.02rem;padding:4px 0 30px}
@media (max-width:999px){
  .faq summary{padding:20px 46px 20px 0}
  .faq summary::after{top:calc(20px + .5em)}
  .faq-aside{margin-top:22px;display:grid;gap:10px;justify-items:start}
}
@media (min-width:1000px){
  .faq-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
    column-gap:clamp(40px,5vw,80px);align-items:start}
  #faq .sec-head{margin-bottom:0;max-width:none;position:sticky;top:120px}
  #faq .h-lg{font-size:clamp(2rem,3.4vw,3.1rem)}
  #faq .h-lg .ml > span{white-space:normal}
  .faq{max-width:none}
  .faq-aside{margin-top:clamp(30px,4.5vh,54px);display:grid;gap:12px;justify-items:start}
}

/* ── 13 · MATERIAL. One light source, from above. The top edge catches it, the sides fall
   away, and the plate CASTS — the half the first craft pass never shipped. ── */
.svc,.lab:not(.lab--stat):not(.lab--reach),.offer-card{
  border-color:rgba(244,245,250,.055);
  border-top-color:rgba(244,245,250,.20);
  box-shadow:inset 0 1px 0 rgba(244,245,250,.07),
             inset 0 -14px 24px -22px rgba(4,5,15,.9),
             0 28px 46px -32px rgba(4,5,15,.95)}
.lab--stat,.lab--reach{box-shadow:inset 0 1px 0 rgba(244,245,250,.10),
                                  0 28px 46px -32px rgba(4,5,15,.95)}
/* the 1px struck edge on every section boundary — six light/dark seams were razor cuts */
.sec--dark,.sec--deep,.statement,.sec.chapter,.site-footer{
  background-image:linear-gradient(180deg,rgba(244,245,250,.20) 0 1px,
    rgba(123,133,216,.070) 1px,rgba(123,133,216,0) 150px)}
.sec--light::before{background:linear-gradient(180deg,rgba(10,11,30,.16) 0 1px,
  rgba(7,9,28,.085) 1px,transparent 100%)}
/* white on near-white separates by shadow ramp, never by fill */
.form-card{box-shadow:inset 0 1px 0 rgba(255,255,255,.9),
  0 1px 0 rgba(10,11,30,.10),0 2px 4px rgba(10,11,30,.05),
  0 18px 34px -18px rgba(10,11,30,.20),0 52px 96px -54px rgba(10,11,30,.55);
  position:relative;z-index:2}
.ms-media{box-shadow:0 1px 0 rgba(10,11,30,.10),0 24px 46px -28px rgba(10,11,30,.40)}
/* the inverted plate LIFTS — hot steel raised off the bench, not a hole cut in paper */
.dual-card:hover,.dual-card:focus-within{z-index:2;box-shadow:0 34px 64px -36px rgba(4,5,15,.62)}
.dual-card::before{box-shadow:inset 0 1px 0 rgba(244,245,250,.16)}
/* the same tooth, read as light instead of haze: overlay on the smithy, multiply in daylight */
.sec--light.grain::after{opacity:.055;mix-blend-mode:multiply;z-index:1}

/* ── 14 · THE PRESS — the one interaction language the page was missing ── */
@media (hover:hover) and (pointer:fine){
  .btn:active{transform:translate3d(0,1px,0) scale(.988);transition-duration:.09s}
  .lnk:active{transform:translate3d(0,1px,0)}
  .lnk:active svg{transform:translateX(9px)}
  .nav-desktop a:active::after{background:#fff}
  .fab:active{transform:translate3d(0,0,0) scale(.94)}
  #toTop:active{transform:scale(.94)}
}
.btn,.lnk,.fab,#toTop{transition-property:transform,box-shadow,color,border-color;
  transition-duration:.28s;transition-timing-function:var(--e-strike)}
.faq summary{transition:transform .12s var(--e-strike)}
.faq summary:active{transform:translate3d(2px,0,0)}
.dual-card{transition:transform .16s var(--e-strike),clip-path .76s var(--e-settle),background .5s var(--e-base)}
.dual-card:active{transform:scale(.996)}
.btn::before{transition:transform .42s var(--e-strike),background-color .34s var(--e-base)}
.btn--solid:hover::before,.btn--solid:focus-visible::before{background:var(--signal-hot)}
.btn--solid{box-shadow:inset 0 1px 0 rgba(244,245,250,.24),inset 0 -1px 0 rgba(4,5,15,.30),
  0 12px 28px -18px rgba(146,39,143,.80)}
.btn--solid:hover,.btn--solid:focus-visible{box-shadow:inset 0 1px 0 rgba(244,245,250,.30),
  0 0 0 1px var(--signal-hot),0 14px 34px -16px rgba(226,79,216,.75)}
/* hover must outrank the reveal: (0,5,1) > (0,4,1) */
.dc-n{transition:-webkit-text-stroke-color .5s var(--e-base),transform .5s var(--e-settle)}
.js .dual.is-in .dual-card:hover .dc-n,
.js .dual.is-in .dual-card:focus-within .dc-n{
  -webkit-text-stroke-color:rgba(226,79,216,.55);transform:translate3d(0,-4px,0) scale(1.04)}
/* zero-JS disclosure, @supports-guarded so nothing regresses */
@supports (interpolate-size:allow-keywords) and selector(::details-content){
  :root{interpolate-size:allow-keywords}
  .faq details::details-content{block-size:0;overflow:clip;opacity:.35;
    transition:block-size .42s var(--e-settle),opacity .3s var(--e-base) .06s,
               content-visibility .42s allow-discrete;
    transition-behavior:allow-discrete}
  .faq details[open]::details-content{block-size:auto;opacity:1}
}
/* prose does not perform: 7px is below the perceptual threshold at reading distance —
   14 transform layers buying nothing, and the Fade-Up Monoculture trap by name */
.js [data-reveal]{transform:none}
[data-reveal]{transition:opacity .66s var(--e-settle)}
/* the footage rises like a forge being lit, after the strike rather than on top of it */
.hero-media .hero-vid{transition:opacity 1.6s var(--e-settle)}
.odo-stake{display:block;margin-top:14px;padding-top:14px;border-top:1px solid rgba(244,245,250,.18);
  font-size:.88rem;line-height:1.45;color:#E4D6EA;max-width:26ch}
.fab--cta{width:auto;min-width:52px;height:52px;padding:0 16px;gap:10px;
  display:inline-flex;align-items:center;border-radius:2px}
.fab--cta .fab-t{font-family:"Archivo",sans-serif;font-weight:700;font-size:.74rem;
  letter-spacing:.08em;text-transform:uppercase;white-space:nowrap}
@media (max-width:400px){.fab--cta{padding:0 12px}.fab--cta .fab-t{font-size:.68rem;letter-spacing:.05em}}
@media (prefers-reduced-motion:reduce){
  .btn:active,.lnk:active,.fab:active,#toTop:active,.faq summary:active,.dual-card:active,
  .dc-n{transform:none!important}
  .faq details::details-content{transition:none!important;block-size:auto!important;opacity:1!important}
}

/* ── 17 · THE MOBILE HERO WAS A TWO-COLUMN ACCIDENT ──
   `.hero` is display:flex, and `.gsoc` is a SIBLING of `.hero-grid`, not a child. Above
   1000px the clock rail is position:absolute, so it leaves the flow and the hero reads as
   one centred column. Below 1000px it stayed in flow — and a row-direction flex container
   with two children put the clocks in a second column beside the copy. That is why the
   headline sat hard left, the prose was centred against a different axis, and the three
   GSOC clocks floated in the middle of the paragraph.
   The container was never meant to lay out two columns; it only ever had one child that
   mattered. Declaring the direction fixes every symptom at once. */
@media (max-width:999.98px){
  .hero{flex-direction:column;justify-content:center}
  .hero-grid{flex:0 0 auto}
  /* the rail becomes what it is on desktop — a full-width instrument strip under the copy */
  .hero > .gsoc{width:100%;margin:clamp(30px,6vh,54px) 0 0;padding:16px var(--pad) 0;
    display:grid;grid-template-columns:repeat(3,1fr);gap:0;border-top:1px solid var(--hairline)}
  .hero > .gsoc::before{display:none}
  .hero > .gsoc li{padding:0 6px;margin:0;display:grid;justify-items:center;
    border-right:1px solid var(--hairline)}
  .hero > .gsoc li:first-child{padding-left:6px}
  .hero > .gsoc li:last-child{border-right:0}
  .hero > .gsoc .c-city{justify-content:center;gap:5px}
}
/* Both labels were breaking onto two lines each, because the buttons were sized by their
   padding and then shrunk. Two equal columns, each label kept on one line.
   Do NOT reach for flex-direction:column here: `.hero-cta` is flex-wrap:wrap, and
   column+wrap against a constrained height wraps the items into COLUMNS — it renders
   side-by-side anyway, but for a reason that changes with the container height. An
   explicit row with flex:1 1 0 is the same picture, deterministically. */
@media (max-width:430px){
  .hero-cta{flex-direction:row;flex-wrap:nowrap;align-items:stretch;width:100%;gap:10px}
  .hero-cta .btn{flex:1 1 0;min-width:0;justify-content:center;white-space:nowrap;
    padding-inline:clamp(8px,3vw,18px)}
  .hero > .gsoc li{padding:0 3px}
  .hero > .gsoc .c-city{gap:4px;letter-spacing:.06em}
}

/* ── 21 · TYPE HIERARCHY ──
   Measured across all six pages: the page <h1> and every section <h2> both rendered at
   77px. Identical size means no hierarchy — every section shouts at the same volume, which
   is what "the letters are enormous" actually describes. The fix is a scale, not a shrink:
   the hero stays the loudest thing on the site, the page title sits clearly under it, and
   section headings drop to a size that lets the prose carry its share. */
.h-xl{font-size:clamp(2.5rem,8.4vw,7.5rem)}                 /* hero h1   ~120px @1440 */
.h-lg{font-size:clamp(1.85rem,3.4vw,3.05rem);line-height:1.02}  /* section h2 ~48px */
.pagehead .h-lg{font-size:clamp(2.15rem,4.3vw,3.85rem)}     /* page h1    ~60px */
.h-mid{font-size:clamp(1.7rem,2.9vw,2.6rem)}                /* cta band   ~40px */
@media (max-width:760px){
  .h-lg{font-size:clamp(1.7rem,6.4vw,2.2rem)}
  .pagehead .h-lg{font-size:clamp(1.9rem,7.4vw,2.5rem)}
  .h-mid{font-size:clamp(1.6rem,6vw,2rem)}
}

/* ── 22 · THE HEADER ──
   The wordmark anchors the left, the menu sits on the true centre of the viewport, and the
   language switch plus CTA hold the right. Centring by flex alone cannot work here: the
   brand and the right-hand group have different widths, so the nav lands wherever the
   leftovers put it — measured 117px off centre. Taking it out of flow fixes it exactly. */
@media (min-width:1100px){
  .site-header{position:relative}
  .nav-desktop{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
    display:flex;gap:clamp(18px,2.1vw,34px);white-space:nowrap}
}
.nav-desktop a[aria-current="page"]{color:var(--ink-inv)}
.nav-desktop a[aria-current="page"]::after{transform:scaleX(1)}

/* ── 23 · PROOF ── the numbers do the arguing, so they get the scale */
.proof .h-lg{max-width:20ch}
.proof-grid{list-style:none;margin:clamp(44px,6vh,76px) 0 0;padding:0;display:grid;
  gap:clamp(30px,3.4vw,56px);grid-template-columns:1fr}
.proof-grid li{display:grid;gap:7px;padding-top:26px;border-top:1px solid var(--hairline);position:relative}
.proof-grid li::before{content:"";position:absolute;left:0;top:-1px;height:2px;width:0;
  background:linear-gradient(90deg,var(--signal),var(--signal-hot));transition:width .68s var(--e-strike)}
.proof-grid li:hover::before{width:100%}
.proof-n{font-family:"Archivo",sans-serif;font-weight:800;letter-spacing:-.035em;
  font-variation-settings:"wdth" 86;font-size:clamp(2.7rem,4.6vw,4.1rem);line-height:.95;
  color:var(--ink-inv)}
.proof-l{font-family:"Archivo",sans-serif;font-weight:700;font-size:.79rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--brand-lite)}
.proof-s{color:var(--muted);max-width:34ch;font-size:.95rem}
@media (min-width:820px){.proof-grid{grid-template-columns:repeat(3,1fr)}}

/* ── 24 · THE SIX, INDEXED ── names only; the page that explains them is one click away */
.sixdex-list{list-style:none;margin:clamp(40px,5.4vh,68px) 0 0;padding:0;
  display:grid;gap:0;grid-template-columns:1fr;counter-reset:sx}
.sixdex-list li{display:flex;align-items:baseline;gap:clamp(14px,1.8vw,26px);
  padding:clamp(15px,1.9vh,22px) 0;border-top:1px solid rgba(7,9,28,.13);position:relative}
.sixdex-list li:last-child{border-bottom:1px solid rgba(7,9,28,.13)}
.sixdex-list li::before{content:"";position:absolute;left:0;top:-1px;height:2px;width:0;
  background:linear-gradient(90deg,var(--signal),var(--signal-hot));transition:width .6s var(--e-strike)}
.sixdex-list li:hover::before{width:100%}
.sx-n{font-family:ui-monospace,Menlo,monospace;font-size:.78rem;letter-spacing:.1em;
  color:var(--brand);flex:none;min-width:2.4em}
.sx-t{font-family:"Archivo",sans-serif;font-weight:700;letter-spacing:-.015em;
  font-variation-settings:"wdth" 90;font-size:clamp(1.05rem,1.75vw,1.42rem);color:var(--ink)}
.sixdex-cta{margin-top:clamp(30px,4vh,50px)}
/* .btn--ghost is drawn for dark grounds — white text and a white hairline. Dropped onto a
   light section it renders as an all-but-invisible button. Give the light sections their
   own ghost so the outline variant stays usable on both. */
.sec--light .btn--ghost{color:var(--ink);border-color:rgba(7,9,28,.28)}
.sec--light .btn--ghost:hover,.sec--light .btn--ghost:focus-visible{
  color:#fff;border-color:var(--signal);background:var(--signal)}
.sec--light .btn--ghost .ar{color:currentColor}
@media (min-width:900px){
  .sixdex-list{grid-template-columns:1fr 1fr;column-gap:clamp(34px,4vw,72px)}
  .sixdex-list li:nth-child(2){border-top:1px solid rgba(7,9,28,.13)}
}

/* ── 20 · MULTIPAGE COMPONENTS ──
   The site is six pages now. These are the only new pieces: a compact chapter opening for
   the five pages that do not get the full hero, the three-pillar router on the home page,
   the web-design argument list, and one closing conversion band used on every page. */
.pagehead{padding-block:clamp(116px,16vh,178px) clamp(30px,4vh,54px)}
.pagehead .h-lg{margin-top:10px}
.pagehead .lead{max-width:46ch;margin-top:4px}
/* the chapter head hands straight off to the section below it — it is an opening, not a
   section in its own right, so it must not sit in its own pool of empty space */
.pagehead + .sec{padding-top:clamp(34px,5vh,66px)}

/* The pillar grid deliberately refuses the three-identical-cards conveyor: the columns are
   staggered vertically, the ghost numeral bleeds off the top edge, and the heat rule is what
   moves on hover — the same strike language as the service cards, at a smaller scale. */
.pillar-grid{list-style:none;margin:clamp(48px,7vh,84px) 0 0;padding:0;display:grid;gap:clamp(28px,3vw,44px);
  grid-template-columns:1fr}
.pillar{position:relative;padding:34px 0 0;border-top:1px solid rgba(7,9,28,.14)}
.pillar::before{content:"";position:absolute;left:0;top:-1px;height:2px;width:0;
  background:linear-gradient(90deg,var(--signal),var(--signal-hot));
  transition:width .62s var(--e-strike)}
.pillar:hover::before,.pillar:focus-within::before{width:100%}
/* the numeral sits BELOW the rule, not across it — straddling the hairline read as a
   collision rather than as a watermark */
.pillar-n{position:absolute;right:2px;top:14px;font-family:"Archivo",sans-serif;font-weight:800;
  font-variation-settings:"wdth" 78;font-size:clamp(2.8rem,4.4vw,4rem);line-height:1;
  color:rgba(7,9,28,.08);pointer-events:none;user-select:none}
.pillar h3{font-family:"Archivo",sans-serif;font-weight:800;letter-spacing:-.02em;
  font-size:clamp(1.35rem,2.2vw,1.85rem);margin:0 0 12px;font-variation-settings:"wdth" 88}
.pillar p{margin:0 0 20px;color:#4A4F66;max-width:38ch}
@media (min-width:900px){
  .pillar-grid{grid-template-columns:repeat(3,1fr);gap:clamp(30px,2.6vw,46px)}
  .pillar:nth-child(2){margin-top:clamp(26px,3.4vw,54px)}
  .pillar:nth-child(3){margin-top:clamp(52px,6.8vw,108px)}
}

/* the web-design argument: three claims, each one earning its own rule */
.wd-list{list-style:none;margin:clamp(46px,6vh,80px) 0 0;padding:0;display:grid;
  gap:clamp(34px,4.4vh,58px);max-width:78ch}
.wd-list li{position:relative;padding-left:clamp(22px,3vw,44px);
  border-left:2px solid rgba(7,9,28,.12)}
.wd-list li::before{content:"";position:absolute;left:-2px;top:0;width:2px;height:0;
  background:linear-gradient(180deg,var(--signal),var(--signal-hot));
  transition:height .7s var(--e-strike)}
.wd-list li:hover::before,.wd-list li:focus-within::before{height:100%}
.wd-list h3{font-family:"Archivo",sans-serif;font-weight:800;letter-spacing:-.02em;
  font-size:clamp(1.25rem,2vw,1.7rem);margin:0 0 10px;font-variation-settings:"wdth" 88}
.wd-list p{margin:0;color:#4A4F66;max-width:56ch}

/* one conversion band, closing every page */
.ctaband{padding-block:clamp(72px,10vh,124px)}
.cta-inner{display:grid;justify-items:center;text-align:center;gap:22px;max-width:60ch;
  margin-inline:auto}
.cta-inner .lead{max-width:52ch}
.cta-inner .btn{margin-top:6px}

/* ── 18 · PENDING CLIENT DATA, NOT A DEBUG LABEL ──
   Four dashed magenta "TODO" chips were rendering on a page about to be shown to a paying
   client — the loudest possible signal of unfinished machine output. The phone, address and
   LinkedIn genuinely are not supplied yet and must never be invented, so the honest
   placeholder stays; it just reads as a deliberate pending state now, and is bilingual
   instead of English-only developer text. Swap the span for the real value on handoff. */
.pending{display:inline-block;color:var(--muted);font-size:.86em;letter-spacing:.01em;
  padding:2px 9px;border:1px solid var(--hairline);border-radius:2px;
  background:rgba(244,245,250,.03);white-space:nowrap}
.sec--light .pending{color:#5C6178;border-color:rgba(7,9,28,.16);background:rgba(7,9,28,.03)}

/* ── 25 · ENQUIRY-TYPE SELECT (client change list 7.20) ──
   The subject field became a real selector so enquiries arrive pre-routed: assessment,
   incident response, monitoring, pentest, web design, mobile security or other. A floating
   label cannot work on a select that always has a value, so the label sits above it. */
.field--select{display:grid;gap:7px}
.field--select > label{position:static;transform:none;font-size:.82rem;letter-spacing:.06em;
  text-transform:uppercase;font-family:"Archivo",sans-serif;font-weight:700;color:#5C6178;
  pointer-events:auto}
.sec--dark .field--select > label{color:var(--brand-lite)}
.field--select select{width:100%;min-height:52px;padding:14px 44px 14px 16px;
  font:inherit;font-size:1rem;color:var(--ink);background-color:#fff;
  border:1px solid rgba(7,9,28,.22);border-radius:2px;appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%235C6178' stroke-width='1.8' fill='none'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 16px center;
  transition:border-color .24s var(--e-base),box-shadow .24s var(--e-base)}
.field--select select:hover{border-color:rgba(7,9,28,.38)}
.field--select select:focus-visible{outline:none;border-color:var(--signal);
  box-shadow:0 0 0 3px rgba(146,39,143,.18)}
@media (prefers-reduced-motion:reduce){.field--select select{transition:none}}


/* ── 26 · CONTACT PAGE ──
   The chapter head was a plain .sec-head, capped at 60ch, so on a 1440 canvas it left roughly
   700px of nothing to its right. Splitting it puts the lead and the two quick actions in that
   space. The contact and FAQ sections each had a short left column beside a tall right one,
   which left a matching void underneath — centring one and pinning the other removes both. */
.ph-side{display:grid;gap:22px;align-content:start}
.ph-side .lead{margin:0}
.qa{display:flex;flex-wrap:wrap;gap:12px}
.qa .btn{flex:0 1 auto}
.qa-direct{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 12px;margin:2px 0 0;
  font-size:.93rem;color:var(--muted)}
.qa-k{font-family:"Archivo",sans-serif;font-weight:700;font-size:.74rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--brand-lite)}
.qa-direct a{color:var(--ink-inv);text-decoration:none;border-bottom:1px solid var(--signal);
  padding-bottom:1px;transition:color .3s var(--e-base),border-color .3s var(--e-base)}
.qa-direct a:hover,.qa-direct a:focus-visible{color:var(--signal-hot);border-color:var(--signal-hot)}

@media (min-width:900px){
  /* the details column is far shorter than the form card beside it */
  .contact{align-items:center}
}
@media (min-width:1000px){
  /* the questions run much longer than the aside, so the aside travels with them */
  .faq-grid > .sec-head,.faq-aside{position:sticky;top:112px;align-self:start}
  .faq-grid > .sec-head{margin-bottom:26px}
}
@media (max-width:899.98px){
  .qa .btn{flex:1 1 100%;justify-content:center}
}
@media (prefers-reduced-motion:reduce){
  .faq-grid > .sec-head,.faq-aside{position:static}
}

/* ── 27 · GERMAN HERO MUST FIT THE SAME TWO LINES ──
   Measured: "Bereit, wenn es darauf ankommt." is 31 characters where the English
   "Ready to respond." is 17, so at the shared size it wrapped to a third line, the h1 grew
   from ~190px to ~291px, and the hero CTAs fell 90px below the fold at 1280x720.
   Archivo's width axis is the right tool: narrowing the German glyphs costs far less than
   shrinking the type, so the headline keeps its weight and still lands on two lines. */
@media (min-width:1000px){
  html[lang="de"] .h-xl{font-size:clamp(2.3rem,7.3vw,6.2rem);font-variation-settings:"wdth" 68}
}

/* ── 28 · THE SCOPE LIST ON A DARK GROUND ──
   .sx-t and the row rules were authored for the light six-layer index on the home page.
   Dropped into the dark scope section on /web-design they rendered dark-on-dark and measured
   1.01:1 — the six list items were effectively invisible. */
.sec--dark .sx-t,.sec--deep .sx-t{color:var(--ink-inv)}
.sec--dark .sx-n,.sec--deep .sx-n{color:var(--brand-lite)}
.sec--dark .sixdex-list li,.sec--deep .sixdex-list li{border-top-color:var(--hairline)}
.sec--dark .sixdex-list li:last-child,.sec--deep .sixdex-list li:last-child{border-bottom-color:var(--hairline)}


/* ── 29 · FORM CONTROLS MUST NOT LAND UNDER FIXED CHROME ──
   Measured on /contact: the consent checkbox scrolled under the fixed header (z-index 900) at
   390px, and the message field sat beneath the float stack (z-index 940) at both widths.
   The float stack now hides over the form (see site.js); this handles the header side —
   anything the browser scrolls into view for focus keeps clear of it. */
#contact input,#contact select,#contact textarea,#contact button,
#contact .field,#contact label,#contact .consent{scroll-margin-top:104px;scroll-margin-bottom:120px}
/* the card itself, when a validation jump targets it */
.form-card{scroll-margin-top:104px}
/* a native select needs its own stacking room while open on mobile browsers that
   render the list inline */
.field--select{position:relative;z-index:3}
