/* ===========================================================
   Granaura Technology Company — site stylesheet
   Palette and type ported from the master GTC deck.
   No webfonts: Georgia and Calibri are system fonts, so the
   page paints on first byte.

   Type scale (2026-08-18): body sits at 17.5px, headlines are
   Georgia *regular* — not bold. Georgia 700 at display sizes
   reads heavy and dated; at 58px the regular weight carries
   the line on its own. Small subheads (h3) stay at 700 so
   they still register as labels when scanning.
   =========================================================== */

:root{
  --ink:#1A1F36;      /* headlines, dark panels          */
  --ink2:#252B48;     /* darker panel variant            */
  --panel:#333F62;    /* lightened dark panel            */
  --body:#4A5270;     /* body text                       */
  --muted:#8892A7;    /* captions, eyebrows              */
  --blue:#4F8CFF;     /* the accent                      */
  --blue2:#7BABFF;    /* secondary accent, on dark       */
  --blue-soft:#EAF1FF;
  --bg:#F4F6FB;
  --line:#E3E7F0;
  --white:#fff;
  --serif:Georgia,'Times New Roman',serif;
  --sans:Calibri,Carlito,'Segoe UI',system-ui,-apple-system,BlinkMacSystemFont,sans-serif;
  --shadow:0 3px 12px rgba(26,31,54,.045);
  --maxw:1120px;
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  font:17.5px/1.65 var(--sans);
  color:var(--body);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
}
img,svg{display:block;max-width:100%}
a{color:inherit}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 32px}

h1,h2,h3,.serif{font-family:var(--serif);color:var(--ink)}
/* Every Georgia heading is regular. h3 was left at 700 in the first pass and
   it read as a different system next to a 400-weight h2 — chunky bold serif
   against an elegant light one. The serif/sans switch plus the size step plus
   --ink against --body is already enough to mark a heading; it does not also
   need weight. Numerals and names (.metrics .m, .step .n, .person .pn) keep
   their own 700 — those are emphasis, not headings. */
h1,h2,h3,.serif{font-weight:400}
h1{font-size:58px;line-height:1.1;letter-spacing:-.022em}
h2{font-size:40px;line-height:1.18;letter-spacing:-.015em}
h3{font-size:22px;line-height:1.32}
em{font-style:normal;color:var(--blue)}

.eyebrow{
  font-size:12.5px;font-weight:700;letter-spacing:.17em;
  text-transform:uppercase;color:var(--blue);
}
.rule{width:78px;height:4px;background:var(--blue)}

/* ---------------- header / nav ---------------- */
header.nav{
  background:var(--ink);
  position:sticky;top:0;z-index:40;
  /* The hero and every .phead are the SAME --ink as this bar, so without an
     edge the header simply dissolves into the page and the hero's blue corner
     bar (.hero::before) reads as a stray line hanging off the logo.
     box-shadow, NOT border-bottom: the hero's fold maths subtracts a literal
     74px for this bar (min-height:calc(100svh - 257px), 257 = 74 nav + 183
     facts strip). A border would make it 75px and quietly break that sum; a
     shadow paints outside the box and changes no layout. #2E3752 is the rule
     colour the footer already uses. */
  box-shadow:0 1px 0 #2E3752;
}
.nav .bar{
  display:flex;align-items:center;justify-content:space-between;
  height:74px;
}
/* The GTC lockup out of the design system's logo package — outlined paths, so
   it needs no webfont. 49px tall is 112px wide, which clears the package's
   110px minimum for the GTC lockup (the granaura one it replaced wanted 130).
   Don't go smaller; below the minimum the package wants the favicon instead.
   The company name beside it is live text, NOT gtc-lockup-horizontal-tagline
   .svg: that asset bakes its descriptor at ~9 units in a 100-unit viewBox, so
   at any height a 74px nav bar can hold it renders under 5px and is illegible.
   The rule this reverses — "granaura on the website, GTC on decks" — was
   changed deliberately on 2026-09-02; the design-system README says so too. */
.brand{display:flex;align-items:center;gap:14px;text-decoration:none}
.brand .lockup{height:49px;width:auto;display:block}
.brand .bf{
  font-size:9.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:#9AA4BC;line-height:1.5;max-width:13.5em;
  padding-left:14px;border-left:1px solid #3A4463;
}
/* gap and nowrap are load-bearing for the non-English locales: German and
   French labels run 20-40% longer, and the bar is a fixed 74px, so a wrapped
   item does not just look tight — it breaks the header. Measure ALL THREE
   locales after touching anything in here, not just English. */
.nav ul{display:flex;align-items:center;gap:24px;list-style:none}
.nav ul > li{white-space:nowrap}
.nav a{
  color:#C3CBDD;text-decoration:none;font-size:15.5px;
  transition:color .15s;
}
.nav a:hover{color:#fff}
.nav a[aria-current]{color:#fff}

/* --- the Use cases dropdown ---------------------------------------------
   A disclosure button plus a panel. The button carries aria-expanded and the
   script flips it; CSS also opens the panel on :focus-within and :hover, so it
   still works before the script runs and for a keyboard tabbing straight in.

   The panel is absolutely positioned, so opening it CANNOT change the height
   of the 74px bar — which the hero's fold constant depends on.
   -------------------------------------------------------------------- */
.has-menu{position:relative}
.mtoggle{
  display:flex;align-items:center;gap:7px;
  background:none;border:0;cursor:pointer;padding:0;
  font:inherit;font-size:15.5px;color:#C3CBDD;
  transition:color .15s;
}
.mtoggle:hover,.mtoggle[aria-expanded="true"]{color:#fff}
.mtoggle[data-current="true"]{color:#fff}
.mtoggle:focus-visible{outline:2px solid var(--blue);outline-offset:4px;border-radius:2px}
.caret{
  width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid currentColor;opacity:.7;transition:transform .15s;
}
.mtoggle[aria-expanded="true"] .caret{transform:rotate(180deg)}

/* Every selector here is prefixed .nav — `.nav ul{display:flex}` in the bar
   above also matches this panel (it IS a ul inside .nav) and outranks a bare
   .submenu at (0,1,1) vs (0,1,0). Without the prefix the panel inherited the
   bar's flex row and the six items rendered side by side across the header. */
.nav .submenu{
  position:absolute;top:calc(100% + 14px);left:-14px;z-index:50;
  display:block;min-width:232px;padding:8px;
  background:var(--ink2);border:1px solid #38415F;border-radius:4px;
  box-shadow:0 18px 44px -18px rgba(0,0,0,.6);
  list-style:none;
  /* visibility, not display:none — a display swap cannot transition and would
     also drop the panel out of the a11y tree mid-animation. */
  opacity:0;visibility:hidden;transform:translateY(-5px);
  transition:opacity .14s,transform .14s,visibility 0s .14s;
}
.nav .has-menu:hover .submenu,
.nav .has-menu:focus-within .submenu,
.nav .mtoggle[aria-expanded="true"] + .submenu{
  opacity:1;visibility:visible;transform:none;transition-delay:0s;
}
/* Escape has to win over :focus-within. Closing with Escape returns focus to
   the button — which is inside .has-menu, so :focus-within would immediately
   re-open the panel and Escape would look broken. The script sets this flag and
   clears it as soon as focus or the pointer leaves. */
.nav .has-menu[data-dismissed] .submenu{
  opacity:0;visibility:hidden;transform:translateY(-5px);
}
.nav .submenu li{display:block}
.nav .submenu a{
  display:block;padding:9px 12px;border-radius:3px;
  color:#C3CBDD;text-decoration:none;font-size:15px;line-height:1.35;
  transition:background .13s,color .13s;
}
.nav .submenu a:hover{background:#2A3355;color:#fff}
.nav .submenu a[aria-current]{color:#fff;background:var(--panel)}
/* the rule that separates "what we build" from "who it is for" */
.nav .submenu .sep{margin-top:7px;padding-top:8px;border-top:1px solid #38415F}

/* Language switcher — EN · FR · DE. A visible control, deliberately not an
   Accept-Language redirect: see lang_switch() in build.py. Sits after the CTA
   behind a hairline so it reads as chrome rather than as a fifth nav item.

   Each option is a padded box, not bare text. As bare text the hit areas
   measured 19-23px wide against a 44px accessibility floor, so tapping "DE" on
   a phone was a coin flip — a miss did nothing at all, which reads as "I
   selected it and nothing happened".

   The current locale gets a filled chip rather than just a lighter colour:
   at 12.5px, #fff against #7C87A3 is not a strong enough signal that the switch
   took. The fill is --panel, not --blue, so it does not compete with the
   "Book a call" button sitting right beside it. */
.nav .langs{
  display:flex;align-items:center;gap:3px;
  padding-left:14px;border-left:1px solid #38415F;
}
.nav .langs a,
.nav .langs .on{
  display:flex;align-items:center;justify-content:center;
  min-width:40px;height:34px;padding:0 6px;border-radius:3px;
  font-size:12.5px;font-weight:700;letter-spacing:.08em;
  transition:background .15s,color .15s;
}
.nav .langs a{color:#7C87A3;text-decoration:none}
.nav .langs a:hover{color:#fff;background:#2A3355}
.nav .langs a:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.nav .langs .on{color:#fff;background:var(--panel)}

.btn{
  display:inline-block;text-decoration:none;font-size:16px;font-weight:700;
  padding:13px 24px;border-radius:2px;transition:background .15s,border-color .15s;
}
.btn-p{background:var(--blue);color:#fff}
.btn-p:hover{background:#3B7AF0}
.btn-s{background:transparent;color:#fff;border:1px solid #57608000;box-shadow:inset 0 0 0 1px #5C6786}
.btn-s:hover{box-shadow:inset 0 0 0 1px #93A0C2}
.btn-lg{font-size:17.5px;padding:16px 32px}

.navcta{font-size:15px;padding:10px 19px}
.burger{display:none;background:none;border:0;cursor:pointer;padding:8px}
.burger span{display:block;width:22px;height:2px;background:#fff;margin:4px 0}

/* ---------------- hero ---------------- */
.hero{
  background:var(--ink);color:#fff;position:relative;overflow:hidden;
  padding:76px 0 84px;
  /* Fill whatever is left of the first screen once the sticky nav (74px) and
     the facts strip (183px while its grid is 4 columns) are taken out, so
     the facts row lands on the fold and completes the screen instead of
     floating with dead space under it on a tall monitor. Measured, not
     guessed — the numbers change with the facts grid, so the 960 and 680
     breakpoints below re-do the sum.
     `svh` so a phone collapsing its browser chrome does not resize the hero
     mid-scroll; the plain `vh` line above it is the fallback for engines
     without svh, where a little jump is the lesser problem.
     The padding stays as the floor: on a short laptop the min-height comes
     out under the content height and the padding wins, which is what keeps
     the type from being crushed. */
  min-height:calc(100vh - 257px);
  min-height:calc(100svh - 257px);
  display:flex;align-items:center;
}
.hero::before{
  content:"";position:absolute;top:0;right:0;width:300px;height:9px;
  background:var(--blue);z-index:2;
}
/* width:100% because .hero is now a flex container — without it the wrap
   shrinks to its content and the max-width/auto-margin centring is lost. */
.hero>.wrap{position:relative;z-index:1;width:100%}
.hero h1{color:#fff;max-width:15em;margin:20px 0 0}
.hero h1 em{color:var(--blue)}
/* The lead is the page's answer block — it states what GTC is, in the same
   words as the Organization node's description. That makes it ~55 words rather
   than the ~25 it used to be, so the measure widened from 31em to 34em (still
   ~68 characters, inside a comfortable line length) to keep it from stacking
   into seven lines and pushing the facts strip off the fold. The defining
   sentence is marked with <b> and carries its emphasis in colour, not weight —
   a bold 21px face here would fight the Georgia headline above it. */
.hero .lead{
  font-size:21px;line-height:1.6;color:#B9C2D6;max-width:34em;margin:26px 0 0;
}
.hero .lead b{color:#fff;font-weight:400}
.hero .cta{display:flex;flex-wrap:wrap;gap:14px;margin-top:42px}

/* --- the instrument panel -----------------------------------------------
   Shows the product instead of describing it: a plain-language question
   resolving through the semantic layer into an answer.

   HTML and CSS only. No image, no request, sharp at any zoom, and nothing
   under /assets that the week-long edge cache could serve stale.

   It began life in the home hero and moved out on 2026-09-03. Two reasons, and
   the second one is the useful one: the home hero should stay generic
   brand-level rather than demonstrating one specific module, and a panel that
   demonstrates Ask Your Data belongs beside the modules. Moving it also deleted
   an entire class of problem — in the hero it had to be height-budgeted against
   the fold constant, which had forced locale-scoped type compaction after
   French overflowed by 93px where English fitted. In a mid-page section
   nothing is competing for the fold and the panel can simply be its own size.
   ---------------------------------------------------------------------- */

/* A two-column section: copy left, panel right. Stacks below 900. */
.split{display:block}
@media (min-width:900px){
  .split{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center}
}
.split .sdek{font-size:17.5px;line-height:1.7;margin-top:18px;max-width:34em}
.split h2{margin-top:14px}
@media (max-width:899px){
  .hpanel{margin-top:34px}
}

.hpanel{
  /* Opaque, and no backdrop-filter. Both were there to let the hero's aurora
     glow through the panel; on a flat section they buy nothing and a
     backdrop-filter forces a compositing pass on every scroll frame. */
  background:linear-gradient(180deg,#252B48 0%,#161B2E 100%);
  border:1px solid #333F62;border-radius:5px;
  box-shadow:0 18px 44px -22px rgba(26,31,54,.45);
  overflow:hidden;font-size:14px;
}
.hpanel .hr{padding:13px 17px;border-bottom:1px solid #2E3752}
.hpanel .hh{
  display:flex;align-items:center;gap:10px;
  font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:#8892A7;
}
.hpanel .live{display:flex;align-items:center;gap:7px;color:var(--blue)}
.hpanel .live i{
  width:7px;height:7px;border-radius:50%;background:var(--blue);flex:none;
  animation:hplive 2.1s ease-in-out infinite;
}
@keyframes hplive{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.3;transform:scale(.68)}}
.hpanel .hh .sp{margin-left:auto;font-weight:400;letter-spacing:.06em}

/* The question rises into place, then a caret blinks after it.

   NOT a typewriter. The classic nowrap + steps(n) + max-width trick needs the
   question to sit on one line, and this string is translated: the German runs
   materially longer than the English, so nowrap would push it straight out of
   the panel. Measured on this site's own strings, short labels inflate up to
   2.8x in German. A reveal that survives wrapping is worth more than an effect
   that only holds in one locale. */
.hpanel .lbl{
  font-size:10.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:#6E7A99;margin-bottom:9px;
}
.hpanel .q{
  color:#fff;font-size:15.5px;line-height:1.5;
  font-family:var(--serif);
}
.hpanel .q span{
  /* inline-block, not inline: transform has no effect on an inline box. The
     box still shrink-to-fits and the text still wraps inside it. */
  display:inline-block;
  animation:hpask .7s cubic-bezier(.2,.7,.3,1) .35s both;
}
.hpanel .q span::after{
  content:"";display:inline-block;width:2px;height:1em;margin-left:3px;
  background:var(--blue);vertical-align:-2px;
  animation:hpcaret .9s step-end 1.1s infinite;
}
@keyframes hpask{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes hpcaret{0%,100%{opacity:1}50%{opacity:0}}

.hpanel .def{color:#C6CEDE;font-size:13.5px;line-height:1.5}
.hpanel .def b{color:#fff;font-weight:400;font-family:var(--serif);font-size:14.5px}
.hpanel .def em{font-style:normal;color:var(--blue)}

/* The answer. Bars grow from zero once, on load, and hold. */
.hpanel .rows{padding:14px 17px 4px}
.hpanel .row{display:flex;align-items:center;gap:12px;margin-bottom:11px;font-size:13px}
.hpanel .row .k{color:#8892A7;flex:none;width:74px;font-variant-numeric:tabular-nums}
.hpanel .row .t{flex:1;height:8px;background:rgba(255,255,255,.07);border-radius:2px;overflow:hidden}
.hpanel .row .t i{
  display:block;height:100%;border-radius:2px;
  background:linear-gradient(90deg,var(--blue) 0%,#7BABFF 100%);
  transform-origin:left center;animation:hpbar 1.1s cubic-bezier(.2,.7,.3,1) both;
}
@keyframes hpbar{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.hpanel .row:nth-child(1) .t i{width:86%;animation-delay:2.9s}
.hpanel .row:nth-child(2) .t i{width:54%;animation-delay:3.05s}
.hpanel .row:nth-child(3) .t i{width:29%;animation-delay:3.2s}
.hpanel .row .v{
  color:#fff;flex:none;width:56px;text-align:right;
  font-variant-numeric:tabular-nums;font-family:var(--serif);
}
.hpanel .foot{
  display:flex;gap:12px;padding:12px 17px;border-top:1px solid #2E3752;
  font-size:11.5px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:#6E7A99;
}
/* text-transform:none, or the uppercase on .foot renders the unit as "0.9 S". */
.hpanel .foot .sp{margin-left:auto;color:var(--blue);text-transform:none;letter-spacing:.04em}

/* Reduced motion. Every selector below repeats the :nth-child of the rule it
   is overriding, because a bare `.hpanel .row .t i` LOSES on specificity to
   `.hpanel .row:nth-child(1) .t i` and the bars keep animating — the exact
   trap that shipped a moving hero to motion-sensitive visitors once already.

   The panel must still be READABLE, not blank: the question is fully shown,
   the caret rests solid, and each bar sits at its final width. A reduced-motion
   fallback that empties the graphic is worse than no graphic. */
@media (prefers-reduced-motion:reduce){
  .hpanel .live i{animation:none;opacity:1;transform:none}
  .hpanel .q span{animation:none;opacity:1;transform:none}
  .hpanel .q span::after{animation:none;opacity:1}
  .hpanel .row:nth-child(n) .t i{animation:none;transform:none}
}


/* --- the hero fold in French and German --------------------------------
   A PRE-EXISTING bug, found 2026-09-03 and verified identical on production
   before any of that day's work: the hero subtracts a fixed constant so the
   facts strip lands on the fold, and that constant was only ever measured in
   English. The same copy runs much longer in the other two locales, so the
   hero is content-driven there and overruns:

       1440x900   EN  fits (24px spare)   FR/DE  27px over
       1366x768   EN  28px over           FR/DE  159px over
       1280x800   EN  fits                FR/DE  127px over

   A French visitor on a 1366x768 laptop had the whole facts strip pushed off
   the first screen. Fixed by compacting the type scale where the screen is
   short or narrow — for every locale on short screens (which also fixes the
   English 1366x768 case) and further for fr/de, which need more.

   Scoped with :lang() rather than by shortening the French copy: the lead is
   the GEO answer block and all three locales are meant to state the same
   thing.

   ORDER MATTERS. The narrow branch must not be overridden by a later rule with
   a LARGER size, which is why the mid block starts at 1101px rather than 960.
   -------------------------------------------------------------------- */
@media (min-width:960px) and (max-height:850px),
       (min-width:960px) and (max-width:1100px){
  .hero{padding:48px 0 54px}
  .hero h1{font-size:46px}
  .hero .lead{font-size:17.5px;margin-top:18px}
  .hero .cta{margin-top:26px}
}
@media (min-width:1101px) and (max-height:950px){
  html:lang(fr) .hero h1,    html:lang(de) .hero h1{font-size:44px}
  html:lang(fr) .hero .lead, html:lang(de) .hero .lead{font-size:17.5px;margin-top:16px}
  html:lang(fr) .hero .cta,  html:lang(de) .hero .cta{margin-top:24px}
  html:lang(fr) .hero,       html:lang(de) .hero{padding:56px 0 62px}
}
@media (min-width:960px) and (max-height:850px),
       (min-width:960px) and (max-width:1100px){
  html:lang(fr) .hero h1,    html:lang(de) .hero h1{font-size:37px}
  html:lang(fr) .hero .lead, html:lang(de) .hero .lead{font-size:16.5px;margin-top:14px}
  html:lang(fr) .hero,       html:lang(de) .hero{padding:34px 0 40px}
}

/* --- animated aurora ----------------------------------------------------
   Four soft radial-gradient blobs drifting over the indigo ground. There is
   no image and no JS: the effect is four gradients plus four keyframes, so
   it adds well under 2 KB and paints with the first frame like the rest of
   the page.

   Only `transform` is animated. That keeps every frame on the compositor —
   animating background-position, or a blur filter, would repaint a
   full-bleed layer 60 times a second and is the usual reason effects like
   this cost battery. The blobs need no blur filter either; a radial
   gradient is already soft.

   `mix-blend-mode:screen` makes the blobs add light to the ink rather than
   sit on it as flat colour, which is what reads as a glow.

   The blobs sit to the RIGHT and a scrim darkens the LEFT (.aura::before),
   because the headline is left-aligned — the copy keeps its contrast and
   the previously empty right half becomes the visual. Don't recentre the
   blobs without also moving the scrim.
   ---------------------------------------------------------------------- */
.aura{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
.aura i{
  position:absolute;display:block;border-radius:50%;
  mix-blend-mode:screen;will-change:transform;
}
/* base wash — largest and slowest */
.aura i:nth-child(1){
  width:1500px;height:1120px;top:-380px;right:-280px;
  background:radial-gradient(circle,rgba(79,140,255,.55) 0%,rgba(79,140,255,.17) 38%,rgba(79,140,255,0) 68%);
  animation:aura1 38s ease-in-out infinite alternate;
}
/* upper highlight */
.aura i:nth-child(2){
  width:900px;height:780px;top:-210px;left:40%;
  background:radial-gradient(circle,rgba(123,171,255,.48) 0%,rgba(123,171,255,0) 65%);
  animation:aura2 26s ease-in-out infinite alternate;
}
/* deeper blue, lower right — gives the wash some depth */
.aura i:nth-child(3){
  width:1120px;height:900px;bottom:-430px;right:5%;
  background:radial-gradient(circle,rgba(59,122,240,.44) 0%,rgba(59,122,240,0) 66%);
  animation:aura3 32s ease-in-out infinite alternate;
}
/* small hot core — reads as the light source */
.aura i:nth-child(4){
  width:520px;height:480px;top:3%;right:15%;
  background:radial-gradient(circle,rgba(168,201,255,.40) 0%,rgba(168,201,255,0) 62%);
  animation:aura4 22s ease-in-out infinite alternate;
}
/* left scrim, so white-on-indigo keeps its contrast under the glow */
.aura::before{
  content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(100deg,
    rgba(26,31,54,.93) 0%,rgba(26,31,54,.66) 36%,rgba(26,31,54,0) 72%);
}
/* settle back to solid ink at the bottom so the edge against the white
   facts strip is a deliberate line, not a clipped gradient */
.aura::after{
  content:"";position:absolute;inset:0;z-index:2;
  background:linear-gradient(to bottom,
    rgba(26,31,54,0) 42%,rgba(26,31,54,.55) 76%,var(--ink) 100%);
}
@keyframes aura1{from{transform:translate3d(0,0,0) scale(1)}   to{transform:translate3d(-140px,70px,0) scale(1.18)}}
@keyframes aura2{from{transform:translate3d(0,0,0) scale(1)}   to{transform:translate3d(120px,90px,0) scale(.88)}}
@keyframes aura3{from{transform:translate3d(0,0,0) scale(1.05)}to{transform:translate3d(-90px,-110px,0) scale(1.22)}}
@keyframes aura4{from{transform:translate3d(0,0,0) scale(1)}   to{transform:translate3d(-180px,120px,0) scale(1.3)}}

/* Motion is decoration here — the still frame is the same picture.
   `:nth-child(n)` matches every blob and is deliberate, not redundant: the
   rules above are `.aura i:nth-child(1)` etc. at specificity (0,2,1), so a
   plain `.aura i` (0,1,1) loses to them and the animation keeps running.
   This selector ties the specificity and wins on order instead. */
@media (prefers-reduced-motion:reduce){
  .aura i:nth-child(n){animation:none}
}

/* ---------------- facts strip ---------------- */
.facts{background:var(--white);border-bottom:1px solid var(--line)}
.facts .grid{
  display:grid;grid-template-columns:repeat(4,1fr);gap:28px;padding:40px 0;
}
.fact{border-left:3px solid var(--blue);padding:2px 0 2px 16px}
.fact .fl{
  font-size:11.5px;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--muted);
}
.fact .fv{font-size:17px;color:var(--ink);font-weight:700;margin-top:7px;line-height:1.42}
.fact .fv span{font-weight:400;color:var(--body)}

/* ---------------- generic section ---------------- */
section{padding:104px 0}
section.alt{background:var(--white)}
/* An industry section's mark. Sits above the eyebrow rather than beside it so
   the .shead keeps its single-column flow and needs no layout change — and so
   a longer German eyebrow has the full measure to wrap into. */
.shead .mk{
  display:flex;align-items:center;justify-content:center;
  width:46px;height:46px;margin-bottom:18px;
  background:var(--blue-soft);border-radius:3px;color:var(--blue);
}
.shead .mk svg{width:24px;height:24px}
.shead{max-width:38em;margin-bottom:52px}
.shead h2{margin:12px 0 0}
.shead p{font-size:19px;margin-top:16px;color:var(--body)}

/* ---------------- capability cards ---------------- */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.card{
  background:var(--white);border:1px solid var(--line);border-top:3px solid var(--blue);
  border-radius:3px;padding:32px 28px;box-shadow:var(--shadow);
  display:flex;flex-direction:column;
}
.card .kicker{font-size:12px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--blue);margin-bottom:10px}
/* The module a use-case column runs on, pinned to the bottom of the card so a
   row of cards with different bullet counts still lines its feet up. .card is
   already flex-column, so margin-top:auto does the pinning. */
/* The card's mark. A 40px tinted square above the kicker — the deck's .ci
   chip, brought over. Decorative by construction: the icon files carry
   aria-hidden and no text, which is why they cost nothing to translate.
   Sized in px rather than em so all twelve marks optically match regardless of
   the card's type scale. */
/* A card that is itself a link — the directory on the use-cases overview. */
.ucard{text-decoration:none;display:flex;flex-direction:column;transition:border-color .15s,transform .15s}
.ucard .kicker{margin-bottom:8px}
.ucard p{color:var(--body)}
.ucard:hover{border-color:#B9CCF2;transform:translateY(-2px)}
.ucard:focus-visible{outline:2px solid var(--blue);outline-offset:3px}
/* An industry mark on a dark page head — the light chip would glare here. */
.phead .mk{
  display:flex;align-items:center;justify-content:center;
  width:46px;height:46px;margin-bottom:20px;border-radius:3px;
  background:rgba(79,140,255,.14);color:var(--blue2);
}
.phead .mk svg{width:24px;height:24px}
.card .ci{
  display:flex;align-items:center;justify-content:center;
  width:40px;height:40px;margin-bottom:16px;flex:none;
  background:var(--blue-soft);border-radius:3px;color:var(--blue);
}
.card .ci svg{width:21px;height:21px}
.card .mod{
  margin-top:auto;padding-top:16px;border-top:1px solid var(--line);
  font-size:12px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted);line-height:1.5;
}
.card ul{list-style:none;margin:4px 0 18px}
.card ul li{position:relative;padding-left:17px;margin-bottom:9px;font-size:16px;line-height:1.55}
.card h3{margin-bottom:12px}
.card p{font-size:17px;line-height:1.6}
.card ul{list-style:none;margin-top:18px;padding-top:17px;border-top:1px solid var(--line)}
.card li{
  font-size:15.5px;color:var(--body);padding-left:16px;position:relative;
  margin-bottom:9px;line-height:1.5;
}
.card li:last-child{margin-bottom:0}
.card li::before{
  content:"";position:absolute;left:0;top:9px;width:5px;height:5px;
  border-radius:50%;background:var(--blue);
}
.card b{color:var(--ink)}
.card .more{
  margin-top:auto;padding-top:20px;font-size:15.5px;font-weight:700;
  color:var(--blue);text-decoration:none;
}
.card .more:hover{text-decoration:underline}

/* ---------------- metric rows inside cards ---------------- */
.metrics{list-style:none;margin-top:18px;padding-top:17px;border-top:1px solid var(--line)}
.metrics li{
  display:flex;align-items:baseline;gap:13px;padding:0 0 10px;font-size:15.5px;
  color:var(--body);line-height:1.4;
}
.metrics li:last-child{padding-bottom:0}
/* .card li::before draws a bullet at left:0 — it would sit on the numeral. */
.metrics li::before{content:none}
.metrics .m{
  font-family:var(--serif);font-weight:700;font-size:22px;color:var(--blue);
  line-height:1;flex:none;min-width:84px;
}
.srcnote{font-size:14.5px;color:var(--muted);margin-top:26px;line-height:1.6}

/* ---------------- flow diagram ---------------- */
.flow{display:flex;flex-direction:column}
.fband{
  background:var(--white);border:1px solid var(--line);border-radius:3px;
  padding:17px 22px;display:grid;grid-template-columns:126px 1fr;
  align-items:center;gap:18px;box-shadow:var(--shadow);
}
.fband .fl{
  font-size:11.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted);
}
.fband .fc{display:flex;flex-wrap:wrap;gap:9px}
.chip{
  font-size:14px;font-weight:700;background:#EEF2FA;border:1px solid #DDE4F1;
  color:var(--ink);padding:7px 12px;border-radius:2px;line-height:1.35;
}
.chip small{display:block;font-weight:400;color:var(--muted);font-size:12.5px;margin-top:2px}
.fstack{background:var(--panel);border-radius:3px;padding:16px 19px;margin:11px 0}
/* Must out-specify any section-scoped .fband background rule. */
.fstack .fband,section .fstack .fband{
  background:transparent;border-color:#4A5578;box-shadow:none;margin-bottom:10px;
}
.fstack .fband:last-child{margin-bottom:0}
.fstack .fband .fl{color:#8B96B2}
.fstack .chip{
  background:rgba(255,255,255,.10);border-color:rgba(255,255,255,.15);color:#fff;
}
.fstack .chip small{color:#9AA4BC}
.farrow{text-align:center;color:#B6C0D6;font-size:19px;font-weight:700;line-height:1;padding:3px 0}

/* ---------------- dark feature section ---------------- */
section.dark{background:var(--ink);color:#B9C2D6;position:relative;overflow:hidden}
section.dark::before{content:"";position:absolute;top:0;right:0;width:300px;height:9px;background:var(--blue)}
section.dark h2,section.dark h3{color:#fff}
section.dark h2 em{color:var(--blue)}
section.dark .shead p{color:#B9C2D6}
.dcols{display:grid;grid-template-columns:repeat(3,1fr);gap:26px}
.dcol{border-left:3px solid var(--blue);padding:3px 0 3px 18px}
.dcol h3{font-size:20px;margin-bottom:9px}
.dcol p{font-size:17px;line-height:1.6;color:#AAB4CC}
.dcol p b{color:#fff;font-weight:700}

/* ---------------- numbered steps ---------------- */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
.step{
  background:var(--white);border:1px solid var(--line);border-radius:3px;
  padding:30px 26px;box-shadow:var(--shadow);
}
section.alt .step{background:var(--bg)}
.step .n{font-family:var(--serif);font-size:34px;font-weight:700;color:var(--blue);line-height:1}
.step h3{font-size:19px;margin:14px 0 9px}
.step p{font-size:16px;line-height:1.6}

/* ---------------- case entries ---------------- */
.case{
  background:var(--white);border:1px solid var(--line);border-left:3px solid var(--blue);
  border-radius:3px;box-shadow:var(--shadow);padding:40px 42px;margin-bottom:26px;
}
.case .kicker{font-size:12px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--blue)}
.case h2{font-size:30px;margin:10px 0 5px}
.case .who{font-size:15.5px;color:var(--muted);margin-bottom:24px}
.case .row{display:grid;grid-template-columns:1fr 1fr;gap:32px}
.case .row h4{
  font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);font-family:var(--sans);margin-bottom:9px;
}
.case .row p{font-size:16.5px;line-height:1.6}
.case .why{
  margin-top:26px;padding-top:20px;border-top:1px solid var(--line);
  font-size:16.5px;line-height:1.6;
}
.case .why b{color:var(--ink)}

/* ---------------- founders ---------------- */
.people{display:grid;grid-template-columns:repeat(2,1fr);gap:24px}
.person{
  background:var(--white);border:1px solid var(--line);border-left:3px solid var(--blue);
  border-radius:3px;padding:30px 30px;box-shadow:var(--shadow);
}
section.alt .person{background:var(--bg)}
.person .pn{font-family:var(--serif);font-size:24px;font-weight:700;color:var(--ink)}
.person .pr{font-size:13.5px;font-weight:700;color:var(--blue);margin-top:4px}
/* Founder LinkedIn. Its own line under the bio rather than a link inside it —
   the bio names four past employers and an inline link there would read as a
   link to one of them. */
.person .pli{
  display:inline-flex;align-items:center;gap:7px;margin-top:16px;
  font-size:14px;font-weight:700;color:var(--blue);text-decoration:none;
}
.person .pli:hover{color:var(--blue-deep,#2B5AB8);text-decoration:underline}
.person .pli svg{width:15px;height:15px;flex:none;fill:currentColor}
.person .pd{font-size:16.5px;line-height:1.6;margin-top:14px}
.person .pd b{color:var(--ink)}

/* ---------------- principles ---------------- */
.princ{display:grid;grid-template-columns:repeat(2,1fr);gap:26px 34px}
.princ .p{border-left:3px solid var(--blue);padding:3px 0 3px 18px}
.princ h3{font-size:19px;margin-bottom:7px}
.princ p{font-size:16.5px;line-height:1.6}

/* ---------------- CTA band ---------------- */
.band{
  background:var(--panel);color:#fff;border-radius:3px;
  padding:54px 52px;position:relative;overflow:hidden;text-align:center;
}
.band::before{content:"";position:absolute;top:0;left:0;width:180px;height:4px;background:var(--blue)}
.band h2{color:#fff;margin-bottom:14px}
.band h2 em{color:var(--blue2)}
.band p{font-size:18.5px;color:#C3CBDD;max-width:38em;margin:0 auto 30px;line-height:1.6}

/* ---------------- page head (inner pages) ---------------- */
.phead{background:var(--ink);color:#fff;padding:84px 0 76px;position:relative;overflow:hidden}
.phead::before{content:"";position:absolute;top:0;right:0;width:300px;height:9px;background:var(--blue)}
.phead h1{color:#fff;font-size:50px;margin:16px 0 0;max-width:16em}
.phead h1 em{color:var(--blue)}
.phead p{font-size:19px;color:#B9C2D6;max-width:36em;margin-top:20px;line-height:1.6}

/* ---------------- contact ---------------- */
.ccols{display:grid;grid-template-columns:1.15fr .85fr;gap:34px;align-items:start}
.cbox{
  background:var(--white);border:1px solid var(--line);border-top:3px solid var(--blue);
  border-radius:3px;padding:36px 36px;box-shadow:var(--shadow);
}
.cbox h3{margin-bottom:12px}
.cbox p{font-size:17px;line-height:1.6}
.clist{list-style:none;margin-top:22px}
.clist li{
  display:flex;gap:13px;align-items:baseline;
  padding:14px 0;border-top:1px solid var(--line);font-size:16.5px;
}
.clist li:first-child{border-top:0;padding-top:4px}
.clist .l{
  font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);width:84px;flex:none;
}
.clist a{color:var(--ink);font-weight:700;text-decoration:none}
.clist a:hover{color:var(--blue)}

/* ---------------- footer ---------------- */
footer{background:var(--ink);color:#8F99B2;padding:64px 0 30px;font-size:15.5px}
footer .cols{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.2fr;gap:34px}
footer h4{
  font-family:var(--sans);font-size:11.5px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--blue2);margin-bottom:15px;
}
footer ul{list-style:none}
footer li{margin-bottom:10px}
footer a{color:#B9C2D6;text-decoration:none}
footer a:hover{color:#fff}
footer .about{max-width:25em;line-height:1.65;margin-top:15px}
footer .brand{margin-bottom:4px}
footer .legal{
  margin-top:48px;padding-top:24px;border-top:1px solid #2E3752;
  display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;font-size:14px;
}

/* ---------------- client strip ---------------- */
.clients{background:var(--white);border-bottom:1px solid var(--line)}
.clients .wrap{padding:60px 32px;text-align:center}
.clients .eyebrow{display:block;margin-bottom:28px}
/* Client logos — a continuous marquee, self-hosted in /assets/logo/clients.
   The boxed version this replaced read as a table of mismatched rectangles.
   No cards now: the logos sit straight on white, which is the ground they were
   drawn for, with an 88px gap so five different marks don't crowd each other.

   The track holds the set twice and travels exactly -50%, so the loop is
   seamless. The second copy is aria-hidden with empty alt in the markup —
   duplicating it would announce five client names twice to a screen reader and
   list them twice to a crawler. */
.clogos{
  position:relative;overflow:hidden;margin-top:6px;
  /* Fade the ends so logos enter and leave instead of being guillotined by the
     container edge. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
}
/* Paused until the strip is actually on screen. Without this the marquee starts
   at page load, and by the time a visitor has read the hero and scrolled down
   the first logo has long since left — which is exactly what was reported.
   `.run` is added by the observer in parts/scripts.html; with no JS the strip
   stays put, showing the set from its start, which is a fine resting state. */
.ctrack{
  display:flex;width:max-content;
  animation:cmarquee 90s linear infinite;animation-play-state:paused;
}
.clogos.run .ctrack{animation-play-state:running}
/* After .run so it wins on equal specificity. */
.clogos:hover .ctrack,.clogos:focus-within .ctrack{animation-play-state:paused}
.cset{
  display:flex;align-items:center;
  /* The right padding must equal the gap: it is the space between the last logo
     of one set and the first of the next, and at 60px against a 120px gap the
     seam was visibly tighter than everywhere else. It also pushes the set wider
     than the 1056px container, without which the track has nothing to scroll. */
  gap:120px;padding:26px 120px 26px 0;
  list-style:none;margin:0;
}
/* Every logo gets the same box and is fitted inside it. max-height alone was
   wrong twice over: it only ever SHRINKS, so IFB (78x26) and HandPickd (140x26)
   sat at their tiny intrinsic size instead of scaling up to the row; and an SVG
   with only a viewBox has no definite intrinsic size, so as a flex item it
   collapsed to 0x0 and Indofast vanished from the strip entirely.
   A fixed box plus object-fit:contain scales every mark to the largest size
   that fits, preserving ratio — which is what makes ten logos of wildly
   different proportions read as the same size. */
.clogo{display:flex;align-items:center;justify-content:center;flex:none;
  width:150px;height:40px}
.clogo img{width:100%;height:100%;object-fit:contain;display:block}
/* Taller boxes for the two stacked marks: The Man Company is emblem over
   wordmark (the way they use it themselves) and BeastLife is two lines. Both
   need the extra height before their smaller type is readable. */
.clogo.mark{height:62px}
.clogo.mid{height:52px}
@keyframes cmarquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
  /* No motion: show one set, centred and wrapped, and drop the edge fade since
     nothing is entering or leaving any more. */
  .ctrack{animation:none;width:100%}
  .clogos{-webkit-mask-image:none;mask-image:none}
  .cset[aria-hidden]{display:none}
  .cset{flex-wrap:wrap;justify-content:center;gap:76px;padding:26px 0;width:100%}
}

/* ---------------- tech stack ---------------- */
.stack{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}
.slayer{
  background:var(--white);border:1px solid var(--line);border-top:3px solid var(--blue);
  border-radius:3px;padding:26px 28px;box-shadow:var(--shadow);
}
.slayer .sl{
  font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);margin-bottom:15px;
}
.slayer .sc{display:flex;flex-wrap:wrap;gap:9px}
.stacknote{font-size:16.5px;color:var(--body);margin-top:28px;line-height:1.6;max-width:46em}
.stacknote b{color:var(--ink)}

/* ---------------- founder monogram ---------------- */
.person .phd{display:flex;align-items:center;gap:16px;margin-bottom:10px}
.mono{
  width:58px;height:58px;flex:none;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--serif);font-weight:700;font-size:21px;color:#fff;
  background:var(--blue);letter-spacing:.02em;
}

/* ---------------- data boundary / security ---------------- */
.tiers{display:grid;grid-template-columns:1fr 1fr;gap:22px}
.tier{
  background:var(--white);border:1px solid var(--line);border-top:3px solid var(--blue);
  border-radius:3px;padding:30px 30px;box-shadow:var(--shadow);
}
.tier .tk{
  font-size:12px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--blue);margin-bottom:10px;
}
.tier h3{margin-bottom:10px}
.tier p{font-size:16.5px;line-height:1.6}
.tier p b{color:var(--ink)}
.guarantee{display:flex;flex-wrap:wrap;gap:10px;margin-top:26px}
.guarantee .chip{font-size:14.5px;padding:9px 15px 9px 32px;position:relative}
.guarantee .chip::before{
  content:"✓";position:absolute;left:13px;top:9px;color:var(--blue);font-weight:700;
}

/* ---------------- big metric tiles (case pages) ---------------- */
.mtiles{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
.mtile{
  background:var(--white);border:1px solid var(--line);border-top:3px solid var(--blue);
  border-radius:3px;padding:26px 24px;box-shadow:var(--shadow);
}
.mtile .v{font-family:var(--serif);font-size:38px;font-weight:700;color:var(--blue);line-height:1}
/* A proportion bar under a stat tile. Deliberately rare: it appears only on
   the tile whose number is a share of a stated denominator (96% of 8,140
   invoices). The other tiles carry absolute amounts, and a bar for one of
   those would be drawing a scale that does not exist. The remainder is left
   visible rather than hidden — the 4% IS the exceptions the caption names. */
/* The module row on the home page. Same chip, plus the module's own mark —
   and NOT .guarantee, whose ::before tick reads as "included in the deal"
   rather than "this is a thing we build". */
.mods{display:flex;flex-wrap:wrap;gap:11px}
.mods .mchip{display:inline-flex;align-items:center;gap:9px;padding:9px 14px}
.mods .mchip svg{width:17px;height:17px;color:var(--blue);flex:none}
.mtile .mbar{
  height:6px;background:#DFE6F3;border-radius:2px;overflow:hidden;margin-top:14px;
}
.mtile .mbar i{
  display:block;height:100%;background:var(--blue);border-radius:2px;
  transform-origin:left center;
}
.mtile .l{font-size:15px;color:var(--body);margin-top:11px;line-height:1.45}
.mtile .l b{color:var(--ink)}

/* ---------------- blue callout (data-boundary line on case pages) ---------------- */
.callout{
  background:var(--blue-soft);border:1px solid #CFE0FF;border-left:3px solid var(--blue);
  border-radius:3px;padding:22px 26px;font-size:16.5px;line-height:1.6;color:var(--ink2);
}
.callout b{color:var(--ink)}
.callout .cl{
  display:block;font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--blue);margin-bottom:8px;
}

/* subhead inside a section, used to separate two capabilities on one case page */
.subhead{margin:64px 0 30px;padding-top:8px}
.subhead .eyebrow{display:block;margin-bottom:8px}
.subhead h2{font-size:32px}

/* ---------------- contact form ---------------- */
.cform{margin-top:24px}
.cform .fld{margin-bottom:16px}
.cform label{
  display:block;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);margin-bottom:7px;
}
.cform input,.cform textarea{
  width:100%;font:16px/1.5 var(--sans);color:var(--ink);
  background:var(--bg);border:1px solid var(--line);border-radius:3px;padding:12px 14px;
  transition:border-color .15s,box-shadow .15s;
}
.cform input:focus,.cform textarea:focus{
  outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(79,140,255,.15);background:#fff;
}
.cform textarea{resize:vertical;min-height:118px}
.cform .row2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.cform .hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cform button{border:0;cursor:pointer;width:100%;margin-top:4px}
.cform button[disabled]{opacity:.62;cursor:default}
.cform .status{margin-top:15px;font-size:15px;line-height:1.55;display:none}
.cform .status.show{display:block}
.cform .status.ok{color:#1A7A4C}
.cform .status.err{color:#C0392B}
.cform .status a{font-weight:700}

/* ---------------- responsive ---------------- */
@media (max-width:1280px){
  /* The descriptor is 130px of the brand's 254px. German needs that width back
     well before 960px — it was overflowing the bar even at 1440. The footer
     keeps it; that column is full width once it stacks. */
  .nav .brand .bf{display:none}
}
@media (max-width:960px){
  .cards,.steps,.facts .grid,footer .cols,.dcols{grid-template-columns:repeat(2,1fr)}
  .ccols,.people,.princ,.case .row,.stack,.tiers{grid-template-columns:1fr}
  .mtiles{grid-template-columns:repeat(2,1fr)}
  h1{font-size:46px}
  h2{font-size:34px}
  .phead h1{font-size:40px}
  /* facts grid drops to 2 columns here, so it measures 241px not 183px */
  .hero{padding:72px 0 80px;min-height:calc(100vh - 315px);min-height:calc(100svh - 315px)}
  section{padding:80px 0}
  .fband{grid-template-columns:1fr;gap:10px}
}
/* Nav ONLY. The burger takes over here because the German menu runs out of
   room around 1000px — but nothing else about the page should become a phone
   at 1000px. Widening the old 680px block wholesale was a mistake: it dragged
   single-column cards, 34px headlines, a collapsed hero and full-width buttons
   onto every laptop window under 1000px. Keep this block to the nav. */
@media (max-width:1000px){
  .nav ul{
    display:none;position:absolute;top:74px;left:0;right:0;
    background:var(--ink2);flex-direction:column;align-items:stretch;
    gap:0;padding:8px 22px 18px;border-top:1px solid #2E3752;
  }
  .nav ul.open{display:flex}
  .nav li{padding:11px 0}
  .nav .navcta{display:inline-block;margin-top:8px;text-align:center}
  /* The menu is a column here, so the hairline moves from left to top. Targets
     go to the full 44px touch minimum — this is the width where the miss was
     actually happening. */
  .nav .langs{
    padding-left:0;border-left:0;gap:8px;
    margin-top:12px;padding-top:14px;border-top:1px solid #2E3752;
  }
  .nav .langs a,.nav .langs .on{min-width:58px;height:44px;font-size:14px}
  /* Inside the burger the panel is part of the column, not an overlay: static
     position, always visible, indented under its heading. A floating panel
     anchored to a full-width row has nothing sensible to float against, and
     hover does not exist here. */
  .has-menu{position:static}
  .mtoggle{display:none}
  /* `.nav .submenu`, not `.submenu`. The burger rule above is `.nav ul`, which
     also matches this panel (it IS a ul inside .nav) and outranks a bare
     .submenu at (0,1,1) vs (0,1,0) — so a plain .submenu here lost, and the
     submenu inherited `display:none` and vanished from the burger menu
     entirely. Same trap the nav has hit before: match the specificity of the
     rule you mean to override. */
  .nav .submenu{
    display:block;position:static;opacity:1;visibility:visible;transform:none;
    min-width:0;padding:0;margin:0;background:none;border:0;box-shadow:none;
    transition:none;
  }
  .nav .submenu a{padding:11px 0 11px 16px;border-left:1px solid #38415F;border-radius:0}
  .nav .submenu a:hover{background:none;color:#fff}
  .nav .submenu .sep{margin-top:0;padding-top:0;border-top:0}
  /* the row that holds the panel must not carry the column's own padding twice */
  .nav li.has-menu{padding:11px 0 4px}
  .burger{display:block}
}

/* Phone layout proper. */
@media (max-width:680px){
  .wrap{padding:0 22px}
  /* Burger from here: below this width the German menu has under 20px of
     slack, which is not a margin worth defending. */
  .wrap{padding:0 22px}
  .cards,.steps,.facts .grid,footer .cols,.dcols,.mtiles{grid-template-columns:1fr}
  .subhead h2{font-size:24px}
  h1,.phead h1{font-size:34px}
  h2{font-size:28px}
  .hero .lead{font-size:19px}
  /* One column here means the facts strip alone is 380–430px tall, so there
     is no fold to complete — pinning the hero to the viewport would only
     squeeze it. Back to padding-driven height. */
  .hero{min-height:0;padding:64px 0 72px}
  /* Blobs sized for a 1440 canvas become one flat wash on a phone, and the
     copy now runs full width so a left-biased scrim no longer covers it —
     shrink the blobs and even out the scrim. */
  .aura i:nth-child(1){width:760px;height:600px;top:-200px;right:-200px}
  .aura i:nth-child(2){width:520px;height:440px;top:-130px;left:22%}
  .aura i:nth-child(3){width:600px;height:500px;bottom:-240px;right:-10%}
  .aura i:nth-child(4){width:300px;height:280px;top:2%;right:8%}
  .aura::before{
    background:linear-gradient(160deg,
      rgba(26,31,54,.80) 0%,rgba(26,31,54,.62) 45%,rgba(26,31,54,.30) 100%);
  }
  .case h2{font-size:25px}
  .cform .row2{grid-template-columns:1fr}
  /* Two logos per row on a phone; the cards shrink rather than the logos,
     so the marks stay legible. */
  /* Tighter gap and smaller marks so a phone still gets three or four logos
     across the track rather than one at a time. */
  .cset{gap:76px;padding:20px 38px 20px 0}
  .clogo{width:112px;height:32px}
  .clogo.mark{height:48px}
  .clogo.mid{height:40px}
  .clogo.mark img{max-height:46px}
  .clogo.mid img{max-height:34px}
  .clients .wrap{padding:48px 22px}
  section{padding:64px 0}
  .band{padding:38px 28px}
  .case{padding:28px 26px}
  .hero .cta .btn{width:100%;text-align:center}
}

/* ---------------- cookie consent ----------------
   Bottom-left card, not a full-width bar: it must not cover the CTA or push
   the fold. Fixed, so it never enters the document flow and cannot shift
   layout. Removed from the DOM on answer rather than hidden — there is
   nothing left to keep. See assets/consent.js for why the choice lives in
   localStorage and not in a cookie. */
.consent{
  position:fixed;left:22px;bottom:22px;z-index:60;
  width:min(360px,calc(100vw - 44px));
  background:var(--white);border:1px solid var(--line);border-top:3px solid var(--blue);
  border-radius:3px;padding:20px 22px 18px;
  box-shadow:0 10px 34px rgba(26,31,54,.16);
  opacity:0;transform:translateY(10px);transition:opacity .22s,transform .22s;
}
.consent.in{opacity:1;transform:none}
.consent p{font-size:14px;line-height:1.6;color:var(--body)}
.consent .cbtns{display:flex;gap:10px;margin-top:16px;justify-content:flex-end}
.consent button{
  font-family:var(--sans);font-size:14px;font-weight:700;cursor:pointer;
  padding:9px 18px;border-radius:2px;border:0;transition:background .15s,box-shadow .15s;
}
.consent .cyes{background:var(--blue);color:#fff}
.consent .cyes:hover{background:#3B7AF0}
.consent .cno{background:transparent;color:var(--body);box-shadow:inset 0 0 0 1px var(--line2)}
.consent .cno:hover{box-shadow:inset 0 0 0 1px var(--muted)}
.consent button:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
@media (max-width:680px){
  .consent{left:14px;right:14px;bottom:14px;width:auto}
}
@media (prefers-reduced-motion:reduce){
  .consent{transition:none}
}
