/* ==================================================================
   Willsec — light, quiet, precise.
   A design system built for whitespace, motion, and restraint.
   ------------------------------------------------------------------
   1  Tokens          8  Cards            15 Partner locator
   2  Reset & base    9  Marquee          16 Partner program
   3  Typography     10  Scrollytelling   17 Forms
   4  Layout         11  Stats            18 Footer
   5  Header         12  Media            19 Cursor & chrome
   6  Buttons        13  Booking          20 Motion prefs
   7  Hero           14  CTA bands        21 Responsive
   ================================================================== */

/* ---------- 1 · Tokens ------------------------------------------ */
:root{
  /* surface */
  --bg:        #ffffff;
  --bg-2:      #f5f5f7;
  --bg-3:      #fafafb;
  --bg-tint:   #fbf7f8;
  --card:      #ffffff;
  --line:      rgba(20,20,26,.09);
  --line-2:    rgba(20,20,26,.055);

  /* ink */
  --ink:       #16161a;
  --ink-2:     #4b4b55;
  --ink-3:     #5c5c66;   /* 6.61:1 on white, 6.07:1 on tint — AA */
  --ink-4:     #6e6e76;   /* 5.05:1 on white, 4.64:1 on tint — AA */

  /* brand */
  --brand:     #c01a47;
  --brand-2:   #9b1941;
  --brand-3:   #e04a72;
  --brand-ink: #2b2b2b;
  --brand-wash:#fdf1f4;

  /* effects */
  --shadow-sm: 0 1px 2px rgba(16,16,22,.04), 0 2px 8px rgba(16,16,22,.04);
  --shadow:    0 2px 6px rgba(16,16,22,.05), 0 12px 32px rgba(16,16,22,.07);
  --shadow-lg: 0 4px 12px rgba(16,16,22,.05), 0 30px 70px rgba(16,16,22,.11);
  --shadow-brand: 0 10px 30px rgba(192,26,71,.22);
  --glass:     saturate(180%) blur(22px);

  /* geometry */
  /* One radius, everywhere. Buttons, cards, inputs, panels and the mega
     menu all sit at 5px; only true circles (avatars, dots) use 50%. */
  --r-sm: 5px;   --r: 5px;   --r-lg: 5px;   --r-xl: 5px;   --r-pill: 5px;
  --pad:  clamp(20px, 5vw, 40px);
  --wrap: 1240px;
  --nav-h: 68px;

  /* motion */
  --ease:      cubic-bezier(.22,1,.36,1);
  --ease-out:  cubic-bezier(.16,1,.3,1);
  --ease-soft: cubic-bezier(.4,0,.2,1);
  --t-fast: .22s; --t: .42s; --t-slow: .78s;

  /* type */
  --f-display: 'Poppins', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --f-text:    'Inter', -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, sans-serif;
}

/* ---------- 2 · Reset & base ------------------------------------ */
*,*::before,*::after{ box-sizing:border-box; }
*{ margin:0; }
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top: calc(var(--nav-h) + 24px);
  /* `clip` (not `hidden`) — it contains the off-canvas reveal transforms
     without creating a scroll container, so position:sticky keeps working. */
  overflow-x:hidden;
  overflow-x:clip;
}
body{
  font-family:var(--f-text);
  font-size:17px; line-height:1.6;
  color:var(--ink); background:var(--bg);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  overflow-x:clip;
}
img,svg,video,canvas{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button,input,select,textarea{ font:inherit; color:inherit; }
button{ background:none; border:0; cursor:pointer; }
:focus-visible{ outline:2.5px solid var(--brand); outline-offset:3px; border-radius:5px; }
::selection{ background:rgba(192,26,71,.16); }
.ic{ width:1em; height:1em; flex:none; }
/* Two-tone icons. The body inherits `color`; the detail group takes
   --ic-accent, which defaults to the same colour so single-tone callers are
   unaffected. Set both to get Willsec's two brand colours on one icon. */
.ic__a{ stroke:var(--ic-accent, currentColor); }
.ic--duo{ color:var(--brand-ink); --ic-accent:var(--brand); }
.sr{ position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }

/* film grain — barely there, keeps flat white from looking dead */
body::after{
  content:''; position:fixed; inset:0; z-index:9998; pointer-events:none; opacity:.028;
  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='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- 3 · Typography -------------------------------------- */
h1,h2,h3,h4{ font-family:var(--f-display); font-weight:600; line-height:1.06; letter-spacing:-.032em; }
.d1{ font-size:clamp(1.95rem, 7.4vw, 4.6rem); letter-spacing:-.04em; line-height:1.05; }
/* The headline's lines are single-line boxes (each .ln is one line of the
   set), so a line that is wider than the viewport gets clipped by
   overflow-x:clip rather than wrapping or scrolling — invisible to a
   document-overflow check. Below 640px the lines are allowed to wrap so a
   long phrase can never be cut off. */

.d2{ font-size:clamp(1.72rem, 6.2vw, 3.6rem); letter-spacing:-.036em; line-height:1.06; }
.d3{ font-size:clamp(1.34rem, 4.4vw, 2.2rem); letter-spacing:-.028em; line-height:1.14; }
.d4{ font-size:clamp(1.15rem, 1.6vw, 1.35rem); letter-spacing:-.02em; line-height:1.24; }

.eyebrow{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--f-text); font-size:.72rem; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase; color:var(--brand);
}
.eyebrow::before{
  content:''; width:20px; height:1.5px; border-radius:2px;
  background:linear-gradient(90deg, var(--brand), rgba(192,26,71,.15));
}
.eyebrow--plain::before{ display:none; }
.eyebrow--muted{ color:var(--ink-3); }
.eyebrow--muted::before{ background:linear-gradient(90deg, var(--ink-4), transparent); }

.lead{ font-size:clamp(1.06rem,1.5vw,1.28rem); line-height:1.55; color:var(--ink-2); letter-spacing:-.012em; }
.sub{ color:var(--ink-3); }
.tiny{ font-size:.82rem; line-height:1.5; color:var(--ink-3); }
.mono{ font-family:ui-monospace,'SF Mono',Menlo,monospace; font-size:.78rem; letter-spacing:.02em; }
.measure{ max-width:62ch; }
.balance{ text-wrap:balance; }
strong,b{ font-weight:600; }
em.hl{ font-style:normal; color:var(--brand); }

/* gradient ink for one word per headline — used sparingly */
.grad{
  font-style:normal;
  background:linear-gradient(102deg, var(--brand) 0%, var(--brand-3) 46%, var(--brand-2) 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}

/* ---------- 4 · Layout ------------------------------------------ */
.wrap{ width:min(var(--wrap), 100% - var(--pad)*2); margin-inline:auto; }
.wrap--narrow{ width:min(880px, 100% - var(--pad)*2); }
.wrap--wide{ width:min(1440px, 100% - var(--pad)*2); }
section{ position:relative; }
.sec{ padding-block:clamp(72px, 10vw, 140px); }
.sec--tight{ padding-block:clamp(52px, 7vw, 92px); }
.sec--flush{ padding-block:0; }
.tint{ background:var(--bg-2); }
.tint-soft{ background:var(--bg-3); }
.tint-brand{ background:linear-gradient(180deg,#fff, var(--bg-tint) 60%, #fff); }
.hr{ height:1px; background:var(--line-2); border:0; }

.sec-head{ max-width:760px; margin-bottom:clamp(34px,4.5vw,58px); }
.sec-head .d2{ margin-top:16px; }
.sec-head .lead{ margin-top:18px; }
.sec-head--center{ margin-inline:auto; text-align:center; }
.sec-head--center .eyebrow{ justify-content:center; }

/* The page's one head that spans the full wrap instead of a 760px column, so
   the partner section does not reopen with the services section's silhouette.
   Placed after .sec-head: both overrides tie on specificity and win on order. */
.sec-head--wide{ max-width:none; display:grid; grid-template-columns:1.15fr .85fr; gap:clamp(24px,4vw,64px); align-items:end; }
.sec-head--wide .lead{ margin-top:0; }
@media (max-width:900px){
  .sec-head--wide{ grid-template-columns:1fr; }
  .sec-head--wide .lead{ margin-top:18px; }
}

.grid{ display:grid; gap:clamp(16px,2vw,24px); }
.g-2{ grid-template-columns:repeat(2,1fr); }
.g-3{ grid-template-columns:repeat(3,1fr); }
.g-4{ grid-template-columns:repeat(4,1fr); }
.split{ display:grid; grid-template-columns:1.05fr .95fr; gap:clamp(28px,5vw,72px); align-items:center; }
.split--wide-r{ grid-template-columns:.9fr 1.1fr; }
/* Masthead beside content: the head must sit at the top of its column,
   not be vertically centred against a taller neighbour. */
.split--top{ align-items:start; }
.stack{ display:flex; flex-direction:column; gap:16px; }
.row{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }

/* aurora — slow drifting brand light, the only colour on white */
.aurora{ position:absolute; inset:-15% -10% auto; height:min(760px,90vh); pointer-events:none; z-index:0; overflow:hidden; }
.aurora::before,.aurora::after{
  content:''; position:absolute; border-radius:50%; filter:blur(90px); opacity:.5;
  animation:drift 26s var(--ease-soft) infinite alternate;
}
.aurora::before{
  width:52vw; height:52vw; left:-8vw; top:2vw;
  background:radial-gradient(circle at 40% 40%, rgba(192,26,71,.20), rgba(192,26,71,0) 68%);
}
.aurora::after{
  width:46vw; height:46vw; right:-6vw; top:-6vw; animation-duration:34s; animation-direction:alternate-reverse;
  background:radial-gradient(circle at 55% 45%, rgba(120,140,255,.16), rgba(120,140,255,0) 66%);
}
@keyframes drift{
  from{ transform:translate3d(0,0,0) scale(1); }
  to  { transform:translate3d(4vw,3vw,0) scale(1.14); }
}

/* reveal-on-scroll */
.reveal{
  opacity:0; transform:translate3d(0,26px,0);
  transition:opacity .85s var(--ease-out) var(--d,0ms), transform .85s var(--ease-out) var(--d,0ms);
  will-change:opacity, transform;
}
.reveal.in{ opacity:1; transform:none; }
.reveal--scale{ transform:translate3d(0,34px,0) scale(.975); }
.reveal--left{ transform:translate3d(-28px,0,0); }
.reveal--right{ transform:translate3d(28px,0,0); }

/* line-mask headline reveal */
.lines .ln{ display:block; overflow:hidden; padding-bottom:.06em; margin-bottom:-.06em; }
/* The marked line extends its clip box downward so the doodle fits inside
   the reveal mask. The negative margin only claws back part of that, leaving
   real space beneath — the mark now sits on the FIRST line, so the next line
   would otherwise ride up over the stroke. */
.lines .ln--mark{ padding-bottom:.60em; margin-bottom:-.34em; }
.lines .ln > span{
  display:block; transform:translateY(102%);
  transition:transform 1.05s var(--ease-out) var(--d,0ms);
}
.lines.in .ln > span{ transform:none; }

/* ---------- 5 · Header ------------------------------------------ */
.skip{ position:fixed; top:-60px; left:16px; z-index:1000; background:var(--ink); color:#fff; padding:10px 16px; border-radius:5px; transition:top .2s; }
.skip:focus{ top:12px; }

.hdr{
  position:fixed; inset:0 0 auto; z-index:900; height:var(--nav-h);
  display:flex; align-items:center;
  background:rgba(255,255,255,.88);
  -webkit-backdrop-filter:var(--glass); backdrop-filter:var(--glass);
  border-bottom:1px solid transparent;
  transition:background var(--t) var(--ease), border-color var(--t) var(--ease), height var(--t) var(--ease);
}
.hdr.is-stuck{ background:rgba(255,255,255,.95); border-bottom-color:var(--line-2); }
.hdr.is-open{ background:#fff; border-bottom-color:var(--line-2); }
.hdr__in{ width:min(var(--wrap), 100% - var(--pad)*1.4); margin-inline:auto; display:flex; align-items:center; gap:8px; }

.brand{ display:flex; align-items:center; gap:10px; margin-right:auto; padding:6px 0; }
.brand img{ height:28px; width:auto; transition:transform var(--t) var(--ease); }
.brand:hover img{ transform:scale(1.04); }

.nav{ display:flex; align-items:center; gap:2px; }
.nav__btn, .nav__lnk{
  position:relative; display:inline-flex; align-items:center; gap:5px;
  padding:8px 13px; border-radius:var(--r-pill);
  font-size:.885rem; font-weight:500; color:var(--ink-2); letter-spacing:-.006em;
  transition:color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.nav__btn:hover,.nav__lnk:hover,.nav__btn[aria-expanded="true"]{ color:var(--ink); background:rgba(20,20,26,.045); }
.nav__lnk.is-here{ color:var(--ink); }
.nav__lnk.is-here::after{
  content:''; position:absolute; left:13px; right:13px; bottom:2px; height:1.5px; border-radius:2px; background:var(--brand);
}
.nav__btn .ic{ width:14px; height:14px; opacity:.5; transition:transform var(--t-fast) var(--ease); }
.nav__btn[aria-expanded="true"] .ic{ transform:rotate(180deg); }

.hdr__act{ display:flex; align-items:center; gap:8px; margin-left:10px; }

/* mega panel */
.mega{
  position:absolute; left:50%; top:calc(var(--nav-h) - 6px); translate:-50% 0;
  width:min(var(--wrap), 100vw - 32px); z-index:2;
  background:#fff;
  border:1px solid var(--line); border-radius:var(--r-xl);
  box-shadow:0 1px 2px rgba(16,16,22,.06), 0 18px 44px rgba(16,16,22,.13), 0 44px 90px rgba(16,16,22,.10);
  padding:26px; opacity:0; visibility:hidden;
  transform:translateY(-10px) scale(.985); transform-origin:top center;
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease), visibility var(--t);
}
.mega.is-open{ opacity:1; visibility:visible; transform:none; }
.mega__grid{ display:grid; grid-template-columns:.85fr 2.15fr; gap:26px; }
.mega__aside .d4{ margin:10px 0 8px; }
.mega__aside p{ font-size:.9rem; color:var(--ink-3); line-height:1.5; }
.mega__links{ display:grid; grid-template-columns:repeat(2,1fr); gap:6px; }
.mega__lnk{
  display:flex; gap:13px; align-items:flex-start; padding:13px; border-radius:var(--r);
  transition:background var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.mega__lnk:hover{ background:var(--bg-2); transform:translateX(3px); }
.mega__lnk .ic{
  width:21px; height:21px; margin-top:1px;
  color:var(--brand-ink); --ic-accent:var(--brand);
  transition:color var(--t-fast) var(--ease);
}
.mega__lnk:hover .ic{ color:var(--brand); }
.mega__lnk b{ display:block; font-size:.925rem; font-weight:600; letter-spacing:-.012em; }
.mega__lnk span{ display:block; font-size:.8rem; color:var(--ink-3); line-height:1.42; margin-top:2px; }
.mega__foot{ margin-top:20px; padding-top:18px; border-top:1px solid var(--line-2); display:flex; gap:20px; flex-wrap:wrap; }

/* scrim behind an open mega panel */
.navscrim{
  position:fixed; inset:var(--nav-h) 0 0; z-index:890;
  background:rgba(18,18,24,.16);
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity var(--t) var(--ease), visibility var(--t);
}
.navscrim.is-on{ opacity:1; visibility:visible; }

/* mobile */
.burger{ display:none; width:40px; height:40px; border-radius:var(--r-pill); align-items:center; justify-content:center; color:var(--ink); }
.burger .ic{ width:21px; height:21px; }
.sheet{
  position:fixed; inset:var(--nav-h) 0 0; z-index:880; background:rgba(255,255,255,.98);
  -webkit-backdrop-filter:var(--glass); backdrop-filter:var(--glass);
  padding:22px var(--pad) 40px; overflow-y:auto;
  opacity:0; visibility:hidden; transform:translateY(-8px);
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease), visibility var(--t);
}
.sheet.is-open{ opacity:1; visibility:visible; transform:none; }
.sheet__grp{ border-bottom:1px solid var(--line-2); }
.sheet__hd{ width:100%; display:flex; justify-content:space-between; align-items:center; padding:17px 2px; font-size:1.02rem; font-weight:600; letter-spacing:-.018em; }
.sheet__hd .ic{ width:17px; height:17px; color:var(--ink-3); transition:transform var(--t) var(--ease); }
.sheet__hd[aria-expanded="true"] .ic{ transform:rotate(180deg); }
.sheet__body{ display:grid; grid-template-rows:0fr; transition:grid-template-rows var(--t) var(--ease); }
.sheet__hd[aria-expanded="true"] + .sheet__body{ grid-template-rows:1fr; }
.sheet__body > div{ overflow:hidden; }
.sheet__lnk{ display:flex; gap:11px; align-items:center; padding:11px 2px 11px 6px; font-size:.94rem; color:var(--ink-2); }
.sheet__lnk .ic{ width:18px; height:18px; color:var(--brand-ink); --ic-accent:var(--brand); }
.sheet__cta{ display:grid; gap:10px; margin-top:26px; }

/* ---------- 6 · Buttons ----------------------------------------- */
.btn{
  --bg-btn:var(--ink); --fg-btn:#fff;
  position:relative; display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:12px 22px; border-radius:var(--r-pill);
  background:var(--bg-btn); color:var(--fg-btn);
  font-size:.9rem; font-weight:550; letter-spacing:-.008em; white-space:nowrap;
  overflow:hidden; isolation:isolate;
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease), background var(--t) var(--ease), color var(--t) var(--ease);
}
.btn::before{ /* sheen */
  content:''; position:absolute; inset:0; z-index:-1;
  background:linear-gradient(100deg, transparent 20%, rgba(255,255,255,.28) 48%, transparent 76%);
  transform:translateX(-120%); transition:transform .85s var(--ease-out);
}
.btn:hover::before{ transform:translateX(120%); }
.btn:hover{ transform:translateY(-2px); box-shadow:0 10px 26px rgba(16,16,22,.18); }
.btn:active{ transform:translateY(0) scale(.985); }
.btn .ic{ width:15px; height:15px; transition:transform var(--t) var(--ease); }
.btn:hover .ic{ transform:translateX(3px); }
.btn--brand{ --bg-btn:var(--brand); box-shadow:var(--shadow-brand); }
.btn--brand:hover{ --bg-btn:var(--brand-2); box-shadow:0 14px 34px rgba(192,26,71,.3); }
.btn--ghost{ --bg-btn:transparent; --fg-btn:var(--ink); box-shadow:inset 0 0 0 1px var(--line); }
.btn--ghost:hover{ --bg-btn:rgba(20,20,26,.04); box-shadow:inset 0 0 0 1px rgba(20,20,26,.18); }
.btn--light{ --bg-btn:#fff; --fg-btn:var(--ink); box-shadow:var(--shadow-sm); }
.btn--onink{ --bg-btn:#fff; --fg-btn:var(--ink); }
.btn--onink-ghost{ --bg-btn:transparent; --fg-btn:#fff; box-shadow:inset 0 0 0 1px rgba(255,255,255,.32); }
.btn--onink-ghost:hover{ --bg-btn:rgba(255,255,255,.1); }
.btn--lg{ padding:15px 30px; font-size:.96rem; }
.btn--sm{ padding:9px 17px; font-size:.83rem; }
.btn--wide{ width:100%; }
.btn[disabled]{ opacity:.4; pointer-events:none; }

/* quiet text link with a growing rule */
.tlink{ display:inline-flex; align-items:center; gap:7px; font-size:.9rem; font-weight:550; color:var(--brand); }
.tlink .ic{ width:15px; height:15px; transition:transform var(--t) var(--ease); }
.tlink:hover .ic{ transform:translateX(4px); }
.tlink::after{ content:''; position:absolute; }
.tlink-u{ position:relative; }
.tlink-u::before{
  content:''; position:absolute; left:0; right:0; bottom:-3px; height:1.5px; background:currentColor;
  transform:scaleX(0); transform-origin:left; transition:transform var(--t) var(--ease);
}
.tlink-u:hover::before{ transform:scaleX(1); }

.pill{
  display:inline-flex; align-items:center; gap:7px; padding:6px 13px; border-radius:var(--r-pill);
  background:var(--bg-2); font-size:.775rem; font-weight:550; color:var(--ink-2); letter-spacing:-.004em;
}
.pill .ic{ width:13px; height:13px; color:var(--brand); }
.pill--brand{ background:var(--brand-wash); color:var(--brand-2); }

/* ---------- 7 · Hero -------------------------------------------- */
.hero{
  position:relative;
  padding-top:calc(var(--nav-h) + 56px); padding-bottom:clamp(48px,7vw,90px);
  overflow:hidden;
}
/* The scrim and .hero__canvas are gone with the node field they existed for:
   the scrim's only job was holding that field off the headline, and with no
   field it was a white gradient over white. The page's own aurora is gone from
   this section too — the hub is the hero's visual now, and a drifting glow
   behind it competed with the one thing the section is for. */
.hero__in{ position:relative; z-index:2; }
.hero__grid{ display:grid; grid-template-columns:1.02fr .98fr; gap:clamp(30px,4.5vw,60px); align-items:center; }
.hero__head{ min-width:0; }
/* The motto sets ragged over three or four lines in the copy column and is
   meant to: the Doodle is painted as a background on .dmark, so the marked
   word keeps its underline wherever the line happens to break. What must NOT
   happen is the break landing inside the marked word. */
.hero .d1{ margin:20px 0 0; }
/* Two-column hero only: the headline is bounded by its column, not the
   viewport, so it needs its own scale there. 5.6vw tracks the column (~45% of
   the viewport plus the gutter) and 4.45rem holds it once .wrap stops growing
   at 1240px. Below 1081px the hero is a single column and the shared clamp is
   correct again.

   Restored verbatim when the hero went back to two columns — it was removed
   while the hero was centred, which is exactly the condition it guards. */
@media (min-width:1081px){
  .hero .d1{ font-size:clamp(2.6rem, calc(5.6vw * var(--h1k,1)), calc(4.45rem * var(--h1k,1))); }
}
/* Per-locale headline scale, and it is load-bearing for one specific reason:
   tm() wraps the marked word and any punctuation glued to it in .dmark-run,
   which is white-space:nowrap — it has to be, or the Doodle would break in
   half. A nowrap run wider than its column is CLIPPED by overflow-x:clip, not
   wrapped, and clipping is silent: the page never scrolls, so a
   document-overflow sweep sees nothing wrong.

   So the invariant these factors buy is NOT "the marked line sets on one
   line" — it does not, in any Latin locale, and the ragged break reads fine.
   It is "the marked RUN fits its column". The narrowest two-column case is
   1081px, where the copy column is 486px; Spanish "innovación." is the widest
   run at 463px there, and would be 558px without its factor. Each value below
   is measured from that locale's own run against that column.

   Re-measure with the run-vs-column check, not a line count: the marked line
   legitimately wraps, so counting its line boxes only produces false alarms. */
html[lang="fr"]   { --h1k:.94; }
html[lang="de"]   { --h1k:.88; }
html[lang="es"]   { --h1k:.83; }
html[lang="pt-BR"]{ --h1k:.82; }
html[lang="it"]   { --h1k:.76; }
.hero .lead{ margin-top:24px; max-width:47ch; }
.hero__cta{ display:flex; gap:12px; flex-wrap:wrap; margin-top:34px; }
.hero__trust{ display:flex; align-items:center; gap:18px; flex-wrap:wrap; margin-top:40px; padding-top:26px; border-top:1px solid var(--line-2); }
.hero__trust .tiny{ max-width:34ch; }
.stars{ display:inline-flex; gap:2px; color:#f5a524; }
.stars .ic{ width:14px; height:14px; fill:currentColor; stroke:none; }

@keyframes float{ from{ transform:translateY(-7px); } to{ transform:translateY(9px); } }

/* ---------- 8b · The map -----------------------------------------
   The estate in the middle, what it is made of on the flanks, and what Willsec
   puts around it in the three weighted cards. Same trick as before and the
   reason it is worth repeating: the stage is aspect-ratio 620/600 and the SVG
   viewBox is 0 0 620 600, so a wire authored to end at x=214 meets a pill whose
   edge is at 214. Nothing here is measured twice.

   Two node weights, deliberately. Flat pills are things that already exist in
   the customer's world; bordered cards are things we add to it. Giving them the
   same weight would make the diagram a list. */
/* 500px cap, not 620. At 1440 the copy column is 602px and the old stage
   rendered 578 wide — 96% of the column, so the two read as competing columns
   rather than copy plus its illustration. 500 is 83% of it.
   The height is measured, not chosen: the five stacked rows (top card, pill,
   core, pill, lower card) need 424 units in German, the worst locale, and four
   breathing gaps take it to ~496. The old 600 carried ~104 units of pure fat,
   which is most of why the diagram read as a sprawl — nodes flung at the edges
   of a field that was 74% empty. 575 keeps a safe margin at the smaller render
   scale, where text stays at its clamp cap and so occupies MORE stage units. */
/* container-type, and it is the thing that makes this diagram resizable at all.
   Every font here used to be sized against the VIEWPORT and clamped, so shrinking
   the stage left the text the same size and the nodes simply ate more of it --
   the stage had to grow taller to compensate, and most of the width saved came
   straight back. Sized in cqw the whole diagram scales as one object, so the
   proportions below hold at any max-width and 620/610 stays correct. The cqw
   figures are calibrated at 500px, which is what they replaced. */
.map{ position:relative; width:100%; max-width:420px; margin-inline:auto;
      aspect-ratio:620/610; container-type:inline-size; }
.map__wires{ position:absolute; inset:0; width:100%; height:100%; overflow:visible; }

/* The track is static. It was the moving part before, and that was the bug:
   stroke-dashoffset ran 0 to -9 over 2.6s, which is 3.5px/sec across a 578px
   diagram. Measured with .claude/checks/motion-visible.mjs, settled frames
   differed by 0.29% of pixels at mean delta 47 — about 15 per channel, barely
   over the noise floor. It was animated and invisible at the same time. */
.map__trk{
  stroke:var(--line-2); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}
/* The moving part is a separate short dash that runs the whole wire.
   pathLength="1" restates each path as one unit long, so the dash lengths below
   are fractions of the wire rather than absolute units — one dasharray and one
   clock then make wires of 147 and 224 units depart and arrive together,
   instead of the shorter ones racing. Same harness now reads mean delta 280. */
.map__pulse{
  stroke:var(--brand); stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:.15 .85;
  animation:map-pulse 1.9s linear infinite; animation-delay:calc(var(--i) * -.27s);
}
/* No animation-direction here on purpose. The paths are authored pill -> core
   and core -> card, so a single start-to-end run already sends the estate's
   questions inward and what Willsec runs back outward. */
@keyframes map-pulse{ from{ stroke-dashoffset:1; } to{ stroke-dashoffset:0; } }

/* --- the core --- */
.map__core{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  /* 26%, up from 22%. In absolute terms the core barely changes (130px against
     127px) but the stage shrank around it, so it stops being a small box in a
     big empty field and starts reading as the subject the wires answer to. */
  width:26%; aspect-ratio:1; border-radius:22%;
  display:grid; place-content:center; justify-items:center; gap:1.8cqw; padding:0 6%;
  text-align:center; background:#fff;
  border:1px solid var(--line);
  box-shadow:0 0 0 7px rgba(255,255,255,.7), 0 0 0 8px var(--line-2),
             0 22px 50px -30px rgba(16,16,22,.4);
}
/* The stacked plates. Three of them, because a single rectangle reads as a box
   and the thing in the middle is an estate, not an object. */
.map__stack{ display:grid; gap:.6cqw; width:6.8cqw; }
.map__stack i{ display:block; height:1.4cqw; border-radius:3px; background:var(--brand); opacity:.28; }
.map__stack i:first-child{ opacity:.85; }
.map__stack i:nth-child(2){ opacity:.55; }
.map__coret{ font-family:var(--f-display); font-weight:650; color:var(--brand-2);
  font-size:clamp(.62rem,2.94cqw,.92rem); line-height:1.25; letter-spacing:-.02em; }

/* --- flat pills: what the estate already is --- */
.map__pill{
  position:absolute; display:inline-flex; align-items:center;
  padding:1.8cqw 2.6cqw; border-radius:var(--r); background:var(--bg-2);
  border:1px solid var(--line-2); color:var(--ink-2);
  font-size:clamp(.66rem,2.56cqw,.8rem); font-weight:550; line-height:1.3;
  /* FIXED, not max-: the wires end at 180 and 440, which is 29% of 620.
     29% and not 26%: the stage cap dropped 620 -> 500, so a 26% pill lost 20px
     of real width and every English question broke onto a second line. 29% of
     the smaller stage restores the old 145px and keeps them one line. */
  width:29%; justify-content:center; text-align:center;
}
.map__pill--1{ left:0;  top:27.1%; translate:0 -50%; }
.map__pill--2{ right:0; top:27.1%; translate:0 -50%; }
.map__pill--3{ left:0;  top:72.9%; translate:0 -50%; }
.map__pill--4{ right:0; top:72.9%; translate:0 -50%; }

/* --- weighted cards: what we add --- */
.map__card{
  position:absolute; display:flex; align-items:center; gap:2cqw;
  padding:2.2cqw 2.8cqw; border-radius:var(--r); background:#fff;
  border:1px solid rgba(192,26,71,.22);
  box-shadow:0 1px 2px rgba(16,16,22,.04), 0 14px 32px -24px rgba(16,16,22,.45);
}
.map__ic{ display:grid; place-items:center; width:6.4cqw; height:6.4cqw; flex:none;
  border-radius:9px; background:var(--brand-wash); color:var(--brand); }
.map__ic .ic{ width:3.4cqw; height:3.4cqw; }
.map__tx{ min-width:0; }
.map__tx b{ display:block; font-size:clamp(.7rem,2.82cqw,.88rem); letter-spacing:-.018em; }
.map__tx span{ display:block; margin-top:.4cqw; font-size:clamp(.66rem,2.43cqw,.76rem); color:var(--ink-3); line-height:1.35; }
/* Anchored by TOP, never bottom: a card's height changes with the locale, so
   a bottom anchor moves the edge the wire has to meet. */
.map__card--1{ left:50%; top:0; translate:-50% 0; width:40%; }
.map__card--2{ left:0;  top:81.3%; width:43%; }
.map__card--3{ right:0; top:81.3%; width:43%; }

/* Every endpoint is mirror-symmetric about x=310 (161<->459, 133<->487, the
   top card centred), so RTL needs no second set of wires — only the nodes
   change sides. That puts the first question top-right and runs the three
   cards in the order the lead sentence states them: operations, break, close. */
[dir="rtl"] .map__pill--1, [dir="rtl"] .map__pill--3{ left:auto; right:0; }
[dir="rtl"] .map__pill--2, [dir="rtl"] .map__pill--4{ right:auto; left:0; }
[dir="rtl"] .map__card--2{ left:auto; right:0; }
[dir="rtl"] .map__card--3{ right:auto; left:0; }

@media (max-width:900px){
  /* Wires connect nothing once the nodes stack, so the fixed-coordinate stage
     is dropped rather than squeezed. */
  .map{ aspect-ratio:auto; max-width:440px; display:grid; gap:10px; }
  .map__wires{ display:none; }
  .map__core{ position:static; translate:none; width:auto; aspect-ratio:auto;
    border-radius:var(--r-lg); padding:20px; box-shadow:var(--shadow-sm); order:0; }
  /* width:, not max-width: — the stage sets an explicit width on these so the
     wires can meet them, and only width:auto cancels that. max-width:none left
     every pill 26% of a 390px phone, which is one word per line. */
  .map__pill{ position:static; translate:none; width:auto; justify-content:flex-start; text-align:start; }
  .map__card{ position:static; translate:none; width:auto; }
  .map__pill--1{ order:1 } .map__pill--2{ order:2 }
  .map__pill--3{ order:3 } .map__pill--4{ order:4 }
  .map__card--1{ order:5 } .map__card--2{ order:6 } .map__card--3{ order:7 }
  /* The stage is abandoned here, so the container-relative type goes with it.
     A stacked full-width row should be set in rem, not as a fraction of a
     440px box -- left in cqw the pills came out at 9.6px on a 390px phone,
     smaller than they were before the diagram was made resizable. */
  .map__coret{ font-size:1rem; }
  .map__stack{ width:34px; gap:3px; }
  .map__stack i{ height:7px; }
  .map__pill{ font-size:.82rem; padding:11px 14px; }
  .map__card{ padding:14px 16px; gap:12px; }
  .map__ic{ width:34px; height:34px; }
  .map__ic .ic{ width:18px; height:18px; }
  .map__tx b{ font-size:.92rem; }
  .map__tx span{ font-size:.8rem; margin-top:3px; }
}
/* Hidden, not merely stopped. `animation:none` leaves each pulse frozen at
   dashoffset 0, which with pathLength="1" parks a 15% crimson dash at the start
   of every wire — seven bright stubs stuck against the nodes. Verified by
   rendering it. Removing the layer leaves the tracks, which is the diagram. */
@media (prefers-reduced-motion:reduce){ .map__pulse{ display:none; } }

.scrollcue{
  position:absolute; left:50%; bottom:26px; translate:-50% 0; z-index:3;
  display:flex; flex-direction:column; align-items:center; gap:8px;
  font-size:.66rem; letter-spacing:.19em; text-transform:uppercase; color:var(--ink-4);
}
.scrollcue i{ display:block; width:1px; height:38px; background:linear-gradient(var(--ink-4), transparent); position:relative; overflow:hidden; }
.scrollcue i::after{ content:''; position:absolute; inset:0; background:var(--brand); animation:cue 2.1s var(--ease-soft) infinite; }
@keyframes cue{ 0%{ transform:translateY(-100%);} 55%,100%{ transform:translateY(100%);} }

/* ---------- 8 · Cards ------------------------------------------- */
.card{
  position:relative; background:var(--card); border:1px solid var(--line);
  border-radius:var(--r-lg); padding:clamp(22px,2.4vw,30px);
  overflow:hidden; isolation:isolate;
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease), border-color var(--t) var(--ease);
}
.card:hover{ transform:translateY(-4px); box-shadow:var(--shadow); border-color:rgba(192,26,71,.22); }
.card__ic{
  width:46px; height:46px; border-radius:5px; display:grid; place-items:center;
  background:var(--brand-wash); color:var(--brand); margin-bottom:18px;
  transition:transform var(--t) var(--ease), background var(--t) var(--ease);
}
.card__ic .ic{ width:22px; height:22px; }
.card:hover .card__ic{ transform:scale(1.07) rotate(-3deg); background:var(--brand); color:#fff; }
.card h3{ font-size:1.08rem; letter-spacing:-.022em; }
.card p{ font-size:.92rem; color:var(--ink-3); line-height:1.55; margin-top:9px; }
.card__more{ display:inline-flex; align-items:center; gap:6px; margin-top:16px; font-size:.85rem; font-weight:550; color:var(--brand); }
.card__more .ic{ width:14px; height:14px; transition:transform var(--t) var(--ease); }
.card:hover .card__more .ic{ transform:translateX(4px); }
.card--flat{ border-color:var(--line-2); }
/* A flat card is not clickable, so it must not answer the cursor at all.
   Cancelling only transform left the shadow, the crimson border and the
   icon's scale/rotate/brand-fill firing — a promise the box cannot keep. */
.card--flat:hover{ transform:none; box-shadow:none; border-color:var(--line-2); }
.card--flat:hover .card__ic{ transform:none; background:var(--brand-wash); color:var(--brand); }
/* …unless it is genuinely a link. */
.card--flat.card-link:hover{ box-shadow:var(--shadow); border-color:rgba(192,26,71,.22); }
.card--flat.card-link:hover .card__ic{ transform:scale(1.07) rotate(-3deg); background:var(--brand); color:#fff; }
.card--ink{ background:var(--ink); color:#fff; border-color:transparent; }
.card--ink p{ color:rgba(255,255,255,.62); }
.card--ink .card__ic{ background:rgba(255,255,255,.1); color:#fff; }
.card-link{ display:block; }

/* tilt wrapper */
.tilt{ transform-style:preserve-3d; transition:transform var(--t) var(--ease); }
.tilt.is-tilting{ transition:transform .1s linear; }

/* feature rows */
.frow{ display:flex; gap:14px; align-items:flex-start; padding:16px 0; border-bottom:1px solid var(--line-2); }
.frow:last-child{ border-bottom:0; }
.frow .ic{ width:19px; height:19px; color:var(--brand); margin-top:3px; }
/* An <h3> is allowed in a row where the point is genuinely a heading (the
   service pages' "What's included"); main.css's global h3 would set it in
   Poppins 600 at lh 1.06, so it is pulled back to the row face here. */
.frow b, .frow h3{ display:block; font-family:var(--f-text); font-weight:700;
  font-size:.95rem; line-height:1.6; letter-spacing:-.014em; margin:0; }
.frow span{ display:block; font-size:.875rem; color:var(--ink-3); margin-top:3px; line-height:1.5; }
/* .frow as a full-row link: .card supplied hover feedback, .frow supplies
   none, so a link built from it would answer the cursor with nothing. */
a.frow{ text-decoration:none; color:inherit; transition:background var(--t-fast) var(--ease); }
a.frow:hover, a.frow:focus-visible{ background:var(--bg-2); }
a.frow:hover b{ color:var(--brand); }
.frow__go{ margin-inline-start:auto; align-self:center; flex:none; }
.frow__go .ic{ width:15px; height:15px; color:var(--ink-4); transition:transform var(--t) var(--ease), color var(--t-fast) var(--ease); }
a.frow:hover .frow__go .ic{ transform:translateX(3px); color:var(--brand); }
[dir="rtl"] a.frow:hover .frow__go .ic{ transform:translateX(-3px); }
/* A row-link's title should keep the display face at card scale. */
a.frow b, a.frow h3{ font-family:var(--f-display); font-size:1.08rem; letter-spacing:-.022em; }
/* .frow__go is align-self:center, which reads fine against a one-line row and
   badly against the blog index's three-line stack — the read time floats
   opposite the middle of the quote instead of the title it belongs to. */
a.frow .frow__go{ align-self:flex-start; white-space:nowrap; font-size:.8rem; color:var(--ink-4); }

/* Two-up rows: item 2 keeps a dangling divider at the foot of column one
   unless the second-to-last is cleared as well. */
/* The legal index: a top rule so the first row reads as part of a list
   rather than floating under the heading. */
.legal-index{ border-top:1px solid var(--line-2); }

/* Group label above a .frow directory — keeps the screen-reader grouping the
   three card headings used to provide. */
.dirg{
  font-family:var(--f-text); font-size:.72rem; font-weight:650; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-4); margin-bottom:4px;
}

.frows--2{ display:grid; grid-template-columns:1fr 1fr; column-gap:clamp(28px,3vw,52px); }
.frows--2 > .frow:nth-last-child(-n+2){ border-bottom:0; }
@media (max-width:760px){
  .frows--2{ grid-template-columns:1fr; }
  .frows--2 > .frow:nth-last-child(2){ border-bottom:1px solid var(--line-2); }
}

/* ---------- 9 · Marquee ----------------------------------------- */

/* ---------- 10 · Scrollytelling --------------------------------- */
.story{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(30px,6vw,86px); align-items:start; }
.story__pin{ position:sticky; top:calc(var(--nav-h) + 6vh); height:min(72vh,640px); display:grid; place-items:center; }
.story__stage{
  position:relative; width:100%; aspect-ratio:1; max-width:520px;
  border-radius:var(--r-xl); background:linear-gradient(165deg,#fff, var(--bg-2));
  border:1px solid var(--line); box-shadow:var(--shadow-lg); overflow:hidden;
}
.story__stage::after{ content:''; position:absolute; inset:0; background:radial-gradient(75% 55% at 50% 8%, rgba(192,26,71,.09), transparent 70%); }
.stage__svg{ position:absolute; inset:0; width:100%; height:100%; }
.stage__label{
  position:absolute; left:22px; bottom:20px; z-index:3;
  font-family:var(--f-display); font-size:.85rem; font-weight:600; letter-spacing:-.014em;
  display:flex; align-items:center; gap:9px; color:var(--ink-2);
}
.stage__label .n{ display:grid; place-items:center; width:24px; height:24px; border-radius:50%; background:var(--brand); color:#fff; font-size:.72rem; }
.story__steps{ display:flex; flex-direction:column; gap:6px; padding-block:8vh; }
.step{
  padding:clamp(24px,3vw,38px) 0; border-top:1px solid var(--line-2);
  opacity:.32; transition:opacity .6s var(--ease);
}
.step.is-active{ opacity:1; }
.step__n{
  display:inline-flex; align-items:center; gap:9px; font-size:.72rem; font-weight:600;
  letter-spacing:.15em; text-transform:uppercase; color:var(--ink-4); transition:color .6s var(--ease);
}
.step.is-active .step__n{ color:var(--brand); }
.step h3{ font-size:clamp(1.4rem,2.3vw,2rem); margin:14px 0 12px; }
.step p{ color:var(--ink-2); font-size:.98rem; line-height:1.6; max-width:46ch; }
.step__meta{ display:flex; gap:8px; flex-wrap:wrap; margin-top:18px; }

/* ---------- 11 · Stats ------------------------------------------ */
.stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(16px,2.4vw,30px); }
.stat{ padding:clamp(20px,2.4vw,30px) 0; border-top:2px solid var(--ink); }
.stat--brand{ border-top-color:var(--brand); }
.stat__n{ font-family:var(--f-display); font-size:clamp(2.3rem,4.4vw,3.4rem); font-weight:600; letter-spacing:-.045em; line-height:1; }
.stat__l{ font-size:.87rem; color:var(--ink-3); margin-top:12px; line-height:1.45; max-width:22ch; }

/* ---------- 12 · Media placeholders ----------------------------- */
.media{
  position:relative; aspect-ratio:var(--ratio,16/9); border-radius:var(--r-lg);
  overflow:hidden; background:var(--bg-2); margin:0;
}
.media.is-live .media__el{ width:100%; height:100%; object-fit:cover; }
.media.is-placeholder{
  background:
    radial-gradient(120% 90% at 18% 0%, rgba(192,26,71,.07), transparent 58%),
    radial-gradient(110% 90% at 92% 100%, rgba(110,130,255,.07), transparent 60%),
    linear-gradient(160deg,#fcfcfd,#f2f2f5);
  border:1px dashed rgba(20,20,26,.14);
  display:grid; place-items:center; text-align:center;
}
.media__grid{
  position:absolute; inset:0; opacity:.5;
  background-image:linear-gradient(rgba(20,20,26,.045) 1px, transparent 1px),
                   linear-gradient(90deg, rgba(20,20,26,.045) 1px, transparent 1px);
  background-size:34px 34px;
  -webkit-mask-image:radial-gradient(75% 75% at 50% 50%, #000, transparent);
          mask-image:radial-gradient(75% 75% at 50% 50%, #000, transparent);
}
.media__inner{ position:relative; z-index:2; padding:clamp(18px,3vw,34px); max-width:44ch; }
.media__badge{
  display:inline-flex; align-items:center; gap:7px; padding:5px 12px; border-radius:var(--r-pill);
  background:#fff; box-shadow:var(--shadow-sm); color:var(--brand);
  font-size:.68rem; font-weight:600; letter-spacing:.11em; text-transform:uppercase;
}
.media__badge .ic{ width:13px; height:13px; }
.media__title{ font-family:var(--f-display); font-size:clamp(.98rem,1.5vw,1.14rem); font-weight:600; letter-spacing:-.02em; margin-top:15px; line-height:1.3; color:var(--ink); }
.media__note{ font-size:.83rem; color:var(--ink-3); line-height:1.5; margin-top:9px; }
.media__spec{ font-family:ui-monospace,'SF Mono',Menlo,monospace; font-size:.7rem; color:var(--ink-4); margin-top:13px; letter-spacing:.01em; }
.media__play{
  position:absolute; z-index:3; left:50%; top:50%; translate:-50% -50%;
  width:66px; height:66px; border-radius:50%; display:grid; place-items:center;
  background:rgba(255,255,255,.9); box-shadow:var(--shadow-lg); color:var(--brand);
  opacity:0;
}
.media--video.is-placeholder .media__inner{ padding-bottom:96px; }
.media--video.is-placeholder .media__play{ opacity:1; top:auto; bottom:26px; translate:-50% 0; width:52px; height:52px; }
.media__play .ic{ width:20px; height:20px; fill:currentColor; stroke:none; }
.media--portrait{ border-radius:var(--r-xl); }
.media-cap{ font-size:.78rem; color:var(--ink-4); margin-top:11px; }

/* ------------------------------------------------------------------
   Product-UI slots render inside a computer monitor, not a browser
   window — bezel, screen, neck and foot. Applies to both the
   placeholder and the finished screenshot, so the framing never
   changes when the real asset lands.
   ------------------------------------------------------------------ */
.media--ui{
  background:none; border:0; border-radius:0; overflow:visible;
  aspect-ratio:auto; padding:0;
  /* screen and stand stack as one piece — no gap, no absolute offsets */
  display:flex; flex-direction:column; align-items:center;
}
.media--ui .media__screen{ width:100%; }
.media--ui .media__screen{
  position:relative; border-radius:5px;
  background:#17171c;
  padding:clamp(9px,1.1vw,14px);
  padding-bottom:clamp(20px,2.4vw,30px);          /* chin below the screen */
  box-shadow:
    0 1px 0 rgba(255,255,255,.10) inset,
    0 2px 6px rgba(16,16,22,.10),
    0 22px 50px rgba(16,16,22,.20);
}
.media--ui .media__glass{
  position:relative; overflow:hidden; border-radius:5px;
  aspect-ratio:var(--screen,16/10); background:var(--bg-2);
  box-shadow:0 0 0 1px rgba(0,0,0,.5);
}
.media--ui .media__glass > *{ position:absolute; inset:0; }
.media--ui .media__el{ width:100%; height:100%; object-fit:cover; object-position:top center; }
/* the faint sheen across the panel */
.media--ui .media__glass::after{
  content:''; position:absolute; inset:0; pointer-events:none; z-index:4;
  background:linear-gradient(103deg, rgba(255,255,255,.16) 0%, rgba(255,255,255,0) 34%, rgba(255,255,255,0) 100%);
}
/* brand mark on the chin */
.media--ui .media__screen::after{
  content:''; position:absolute; left:50%; bottom:clamp(7px,.9vw,11px); translate:-50% 0;
  width:26px; height:3px; border-radius:2px; background:rgba(255,255,255,.20);
}
/* stand: neck + foot, flush under the bezel */
.media--ui .media__stand{
  display:flex; flex-direction:column; align-items:center; pointer-events:none;
}
.media--ui .media__stand i{
  display:block; background:linear-gradient(180deg,#2a2a31,#1b1b20);
}
.media--ui .media__stand i:first-child{
  width:clamp(52px,7vw,80px); height:clamp(20px,2.6vw,30px);
  border-radius:0 0 4px 4px;
  box-shadow:inset 0 -6px 10px rgba(0,0,0,.35);
}
.media--ui .media__stand i:last-child{
  width:clamp(120px,16vw,190px); height:clamp(8px,1vw,11px);
  border-radius:0 0 100px 100px / 0 0 14px 14px;
  background:linear-gradient(180deg,#22222a,#131318);
  box-shadow:0 8px 18px rgba(16,16,22,.22);
}
/* placeholder content sits on the "screen" */
.media--ui.is-placeholder .media__glass{
  background:
    radial-gradient(120% 90% at 18% 0%, rgba(192,26,71,.07), transparent 58%),
    radial-gradient(110% 90% at 92% 100%, rgba(110,130,255,.07), transparent 60%),
    linear-gradient(160deg,#fcfcfd,#f2f2f5);
}
.media--ui.is-placeholder .media__inner{
  position:absolute; inset:0; display:grid; align-content:center; justify-items:center;
  padding:clamp(16px,2.6vw,30px); max-width:none;
}
.media--ui.is-placeholder .media__grid{ inset:0; }

@media (max-width:640px){
  .media--ui .media__screen{ padding-bottom:clamp(14px,4vw,20px); }
}

/* video facade — click to load the real embed */
/* video facade — click to load the real embed */
.facade{ position:relative; cursor:pointer; }
.facade:hover .media__play{ transform:scale(1.07); }
.facade .media__play{ transition:transform var(--t) var(--ease); }
.facade iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; }

/* ---------- 13 · CTA bands -------------------------------------- */
.band{
  position:relative; overflow:hidden; border-radius:var(--r-xl);
  background:linear-gradient(150deg, var(--brand-ink) 0%, #1b1b1f 55%, #121216 100%);
  color:#fff; padding:clamp(38px,6vw,76px);
}
.band::before{
  content:''; position:absolute; width:60%; height:180%; right:-12%; top:-40%;
  background:radial-gradient(circle at 50% 50%, rgba(192,26,71,.42), transparent 66%);
  filter:blur(50px); animation:drift 22s var(--ease-soft) infinite alternate;
}
.band::after{
  content:''; position:absolute; inset:0; opacity:.34;
  background-image:linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
                   linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size:44px 44px;
  -webkit-mask-image:radial-gradient(90% 80% at 20% 20%, #000, transparent);
          mask-image:radial-gradient(90% 80% at 20% 20%, #000, transparent);
}
.band > *{ position:relative; z-index:2; }
.band .d2{ max-width:18ch; }
.band .lead{ color:rgba(255,255,255,.66); max-width:52ch; margin-top:20px; }
.band__cta{ display:flex; gap:12px; flex-wrap:wrap; margin-top:34px; }
.band__side{ display:grid; grid-template-columns:1.2fr .8fr; gap:clamp(28px,5vw,64px); align-items:center; }
.band .eyebrow{ color:var(--brand-3); }
.band .eyebrow::before{ background:linear-gradient(90deg, var(--brand-3), transparent); }

/* ---------- 13b · Dark section ----------------------------------- */
/* The page ran white → near-white → white the whole way down, so nothing
   had any weight. This is the .band surface promoted to a full-bleed
   section: same obsidian-to-crimson gradient, same drifting glow, same
   faint grid, so the dark moments read as one material rather than a new
   invention. Used sparingly — two anchors, well apart. */
.sec--dark{
  position:relative; overflow:hidden; isolation:isolate;
  background:linear-gradient(150deg, var(--brand-ink) 0%, #1b1b1f 55%, #121216 100%);
  color:#fff;
}
.sec--dark::before{
  content:''; position:absolute; z-index:-1; width:56%; height:150%; right:-10%; top:-28%;
  background:radial-gradient(circle at 50% 50%, rgba(192,26,71,.34), transparent 66%);
  filter:blur(60px); animation:drift 22s var(--ease-soft) infinite alternate;
}
.sec--dark::after{
  content:''; position:absolute; z-index:-1; inset:0; opacity:.3;
  background-image:linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
                   linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size:44px 44px;
  -webkit-mask-image:radial-gradient(90% 80% at 20% 20%, #000, transparent);
          mask-image:radial-gradient(90% 80% at 20% 20%, #000, transparent);
}
.sec--dark h1, .sec--dark h2, .sec--dark h3, .sec--dark h4,
.sec--dark .d1, .sec--dark .d2, .sec--dark .d3, .sec--dark .d4{ color:#fff; }
.sec--dark .lead, .sec--dark p{ color:rgba(255,255,255,.68); }
.sec--dark .eyebrow{ color:var(--brand-3); }
.sec--dark .eyebrow::before{ background:linear-gradient(90deg, var(--brand-3), transparent); }
.sec--dark .frow{ border-color:rgba(255,255,255,.12); }
.sec--dark .frow b{ color:#fff; }
.sec--dark .frow span span{ color:rgba(255,255,255,.6); }
.sec--dark .frow .ic{ color:var(--brand-3); }
.sec--dark .media-cap{ color:rgba(255,255,255,.5); }
.sec--dark .tlink{ color:#fff; }
.sec--dark .tlink-u::after{ background:rgba(255,255,255,.45); }
.sec--dark .btn--ghost{ color:#fff; border-color:rgba(255,255,255,.24); background:transparent; }
.sec--dark .btn--ghost:hover{ background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.4); }
/* The doodle is drawn in brand crimson, which goes muddy on obsidian. */
.sec--dark .dmark__t{ --dk:.30em;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 104 500 52' preserveAspectRatio='none'%3E%3Cpath d='M6.7,111.6c0,0,487.1-6.7,488.2,7.4s-441.5-0.3-442.6,12.3c-1.1,12.6,296.4,5.6,309.9,16.6' fill='none' stroke='%23f2688f' stroke-width='11' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* A dark section already carries the contrast; the inner band would just
   stack one dark slab on another. */
.sec--dark .portal{ background:rgba(255,255,255,.04); border-color:rgba(255,255,255,.1); }

/* .stats on the dark slab. .stat's rule is 2px solid var(--ink) and vanishes;
   .stat--brand's crimson goes muddy; and .stat__n declares no colour of its
   own, so it would inherit `.sec--dark p` at 68% white. .stat__l KEEPS that
   68% deliberately — over #1b1b1f it is ~8:1, comfortably AA. */
.sec--dark .stat{ border-top-color:rgba(255,255,255,.2); }
.sec--dark .stat--brand{ border-top-color:var(--brand-3); }
.sec--dark .stat__n{ color:#fff; }

/* ---------- 13c · Product window --------------------------------- */
/* My Willsec is a web app, so it is shown in a browser window rather than a
   device. The capture is 2.54:1 — a window's own shape — so it fills the
   frame instead of being letterboxed into a laptop or phone screen. */
.shot{ position:relative; }
.win{
  margin:0; border-radius:12px; overflow:hidden; background:#fff;
  box-shadow:0 30px 70px rgba(0,0,0,.42);
}
.win__bar{
  display:flex; align-items:center; gap:7px; padding:10px 14px;
  background:#e9e9ee; border-bottom:1px solid rgba(0,0,0,.08);
}
.win__dot{ width:11px; height:11px; border-radius:50%; background:#c9ccd2; flex:none; }
.win__dot:nth-child(1){ background:#ff5f57; }
.win__dot:nth-child(2){ background:#febc2e; }
.win__dot:nth-child(3){ background:#28c840; }
.win__url{
  margin-inline-start:14px; flex:1; max-width:280px; padding:3px 12px;
  border-radius:var(--r-pill); background:#fff; color:#6b6b75;
  font-size:.72rem; text-align:center; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
.win__img{ width:100%; height:auto; display:block; }

/* ---------- 13c-0 · People grid ----------------------------------
   Copy on one side, a staggered column of tiles on the other. The stagger is
   the whole point: an even grid of portraits reads as a directory, and this
   section is not a directory — it is the claim that there are real people
   behind the work, made visually.

   Two columns, the second dropped by a fraction of a tile. Tiles keep their
   own aspect ratios rather than being forced square, so a 4:5 portrait and a
   4:3 scene can sit in the same field without either being cropped. */
.pgrid{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(14px,1.8vw,22px); align-items:start; }
.pgrid__col{ display:grid; gap:clamp(14px,1.8vw,22px); }
/* The offset. A percentage of the column width, so it scales with the grid
   instead of drifting out of proportion at either end of the range. */
.pgrid__col--drop{ margin-top:clamp(28px,7%,64px); }
.pgrid .media{ border-radius:var(--r); }
/* A tile that is not a photograph: a claim set large on brand ground, so the
   field reads as a composition rather than a contact sheet. */
.ptile{
  display:grid; align-content:end; gap:6px; padding:clamp(16px,2vw,24px);
  border-radius:var(--r); aspect-ratio:4/5; color:#fff;
  background:linear-gradient(160deg, var(--brand-2), var(--brand));
}
.ptile__n{ font-family:var(--f-display); font-size:clamp(1.6rem,3.4vw,2.4rem); font-weight:700; line-height:1; letter-spacing:-.03em; }
.ptile__l{ font-size:.8rem; line-height:1.4; color:rgba(255,255,255,.82); }
.ptile--ink{ background:linear-gradient(160deg,#1a1a22,#0c0c11); }
.ptile--ink .ptile__l{ color:rgba(255,255,255,.62); }

@media (max-width:900px){
  /* The .split stacks here, so the grid inherits the FULL wrap width and the
     tiles balloon to ~440px each — the section becomes taller than the hero.
     Capping it keeps the field a field rather than a stack of posters. */
  .pgrid{ max-width:560px; margin-inline:auto; }
}
/* index.php passes media() the slot NAME only — no note, no spec — so the art
   direction never reaches the page source. This is the belt to that braces: if
   a future slot is added with a brief attached, it still will not render here. */
.pgrid .media__note, .pgrid .media__spec{ display:none; }
.pgrid .media__title{ font-size:.92rem; }

@media (max-width:640px){
  /* Two columns of tiles beside stacked copy is already narrow; the drop only
     makes the shorter column look abandoned once the tiles are this small. */
  .pgrid__col--drop{ margin-top:0; }
}

/* ---------- 13c-1 · Neoma: the intelligence core -----------------
   The canvas runs Neoma's OWN fragment shader — the product's `fluidFragment`,
   read straight from ~/Desktop/noema/src/three/shaders/ by
   scratchpad/build-orb.py and executed here on raw WebGL2 instead of three.js.
   See assets/js/orb.js.

   So the CSS deliberately draws almost nothing. Every rim, terminator,
   highlight and sheet is computed per pixel by the shader; a CSS rim layered
   on top would be a second, disagreeing light source. What is left is the
   bloom the product does as a post pass and this page has no framebuffer for,
   plus a fallback sphere for when there is no WebGL2 at all. */
.orb{
  position:relative; width:min(440px,100%); aspect-ratio:1; margin-inline:auto;
  isolation:isolate;
}
/* The canvas runs the product's real bloom pass, but bloom cannot spill past
   the element it is drawn in. This carries the falloff on beyond the canvas
   edge so the core lights the section rather than stopping at a square. */
.orb::before{
  content:''; position:absolute; inset:-16%; border-radius:50%; z-index:-1;
  background:radial-gradient(closest-side, rgba(157,84,255,.32), rgba(0,72,198,.14) 52%, transparent 76%);
  filter:blur(34px);
}
.orb__c{
  position:absolute; inset:0; width:100%; height:100%;
  border-radius:50%; display:block; background:transparent;
}
/* No WebGL2 (or a context that will not allocate): orb.js returns before
   adding .is-ready, and these gradients describe a lit sphere so the section
   shows a core rather than a hole. Sampled from the Iris ramp the shader
   runs — #00c2ff, #0048c6, #9d54ff, #e5a1ef — so the fallback and the real
   core are the same object, not two different blues. */
.orb__c:not(.is-ready){ background:
  radial-gradient(44% 40% at 36% 32%, rgba(0,194,255,.42), transparent 60%),
  radial-gradient(50% 46% at 64% 60%, rgba(157,84,255,.55), transparent 66%),
  radial-gradient(38% 34% at 54% 78%, rgba(229,161,239,.32), transparent 64%),
  radial-gradient(closest-side, #150f28, #05050a 82%); }

.neo__t{ margin-top:0; }
.neo__chips{ display:flex; flex-wrap:wrap; gap:9px; margin-top:26px; }
/* .pill's ground is --bg-2, which is a light grey — invisible on obsidian. */
.sec--dark .pill{ background:rgba(255,255,255,.07); color:rgba(255,255,255,.8); }
.sec--dark .pill .ic{ color:var(--brand-3); }

@media (max-width:900px){
  .orb{ width:min(320px,78vw); }
}

/* ---------- 13c-2 · Window hotspots ------------------------------
   Pins on the product shot, each bound to one of the .frow claims beside
   it. Deliberately TOOLTIP-FREE: .portal is overflow:hidden, so a floating
   label on the pin nearest the end edge would be clipped by its own
   container — and the row already IS the label. Pointing at a claim and
   pointing at where that claim lives in the product is the whole feature;
   repeating the text in a bubble would only add a clipping bug.

   Percentages are IMAGE coordinates. The image does not mirror in RTL, so
   these use physical `left`/`top`, never the logical properties — flipping
   them would move every pin to the wrong panel in Arabic. */
.win__body{ position:relative; }
.hs{ position:absolute; inset:0; pointer-events:none; }
.hs__p{
  position:absolute; translate:-50% -50%; pointer-events:auto;
  width:26px; height:26px; padding:0; border:0; border-radius:50%; cursor:pointer;
  background:var(--brand); color:#fff; display:grid; place-items:center;
  box-shadow:0 0 0 4px rgba(192,26,71,.28), 0 6px 16px -6px rgba(16,16,20,.6);
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.hs__p::after{
  content:''; position:absolute; inset:-4px; border-radius:50%;
  border:1.5px solid var(--brand); opacity:.55;
  animation:hs-ping 2.6s var(--ease) infinite; animation-delay:var(--d,0ms);
}
@keyframes hs-ping{
  0%   { transform:scale(.85); opacity:.55; }
  70%  { transform:scale(1.9);  opacity:0; }
  100% { transform:scale(1.9);  opacity:0; }
}
.hs__n{ font-size:.72rem; font-weight:700; line-height:1; font-family:var(--f-display); }
.hs__p:hover, .hs__p:focus-visible, .hs__p.is-on{
  transform:translate(0,0) scale(1.25);
  box-shadow:0 0 0 7px rgba(192,26,71,.24), 0 8px 20px -6px rgba(16,16,20,.7);
}
.hs__p.is-on::after{ animation:none; opacity:0; }

/* The paired row. .frow rows inside the portal are not links, so they carry
   no hover state of their own — this is the only feedback that says which
   claim the pin belongs to. */
.frow.is-lit{ background:rgba(255,255,255,.07); border-radius:8px; }
.frow.is-lit b{ color:#fff; }
.frow.is-lit .ic{ color:var(--brand-3); }
/* .frow span{display:block} at :502 is (0,1,1) and outranks a bare class, so
   this numeral has to be scoped to .frow or it renders as a block and pushes
   the title it labels onto a second line. */
.frow .frow__n{
  display:inline-grid; place-items:center; width:17px; height:17px; flex:none;
  margin-inline-end:2px; border-radius:50%; font-size:.62rem; font-weight:700;
  background:rgba(255,255,255,.13); color:rgba(255,255,255,.75);
  font-family:var(--f-display); transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.frow.is-lit .frow__n, .frow.is-lit span.frow__n{ background:var(--brand); color:#fff; }

@media (max-width:900px){
  /* The window is a third of its desktop size once the split stacks, and the
     rows it points at are already directly beneath it. Pins here would be
     tap targets smaller than the guideline aiming at pixels nobody can read. */
  .hs{ display:none; }
  .frow__n{ display:none; }
}
@media (prefers-reduced-motion:reduce){
  .hs__p::after{ animation:none; opacity:.4; }
}


/* The hero chip is 82% white with a backdrop-filter, which reads as white
   over the light hero but as murky grey on the dark section — and its dark
   text then fails contrast. On a dark ground it has to be solid. */

@media (max-width:600px){
  .win__bar{ padding:8px 11px; }
  .win__dot{ width:9px; height:9px; }
  .win__url{ display:none; }        /* no room beside the dots on a phone */
}

/* ---------- 13d · Careers ---------------------------------------- */
/* Open roles */
.roles__bar{
  display:flex; gap:14px; flex-wrap:wrap; align-items:flex-end;
  padding-bottom:22px; margin-bottom:6px; border-bottom:1px solid var(--line-2);
}
.rfilter{ display:grid; gap:6px; }
.rfilter > span{ font-size:.72rem; font-weight:650; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-4); }
.rfilter select{
  appearance:none; -webkit-appearance:none;
  padding:9px 34px 9px 13px; border-radius:var(--r); border:1px solid var(--line);
  background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6b75' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 10px center/15px;
  font:inherit; font-size:.9rem; color:var(--ink); cursor:pointer; min-width:11rem;
}
.rfilter select:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
[dir="rtl"] .rfilter select{ padding:9px 13px 9px 34px; background-position:left 10px center; }
.roles__n{ margin-inline-start:auto; font-size:.86rem; color:var(--ink-3); }

.roles__list{ list-style:none; padding:0; margin:0; display:flex; flex-direction:column; }
.role{
  display:flex; gap:24px; align-items:center; justify-content:space-between;
  padding:26px 0; border-bottom:1px solid var(--line-2);
}
.role__t{ font-size:1.16rem; letter-spacing:-.022em; }
.role__s{ margin-top:7px; font-size:.93rem; line-height:1.6; color:var(--ink-3); max-width:62ch; }
.role__meta{ display:flex; gap:8px 18px; flex-wrap:wrap; margin-top:12px; font-size:.82rem; color:var(--ink-3); }
.role__meta span{ display:inline-flex; align-items:center; gap:6px; }
.role__meta .ic{ width:15px; height:15px; color:var(--brand); flex:none; }
.role__cta{ flex:none; }
.roles__empty{ padding:34px 0; color:var(--ink-3); }
@media (max-width:760px){
  .role{ flex-direction:column; align-items:flex-start; gap:16px; }
  .roles__n{ margin-inline-start:0; width:100%; }
  .rfilter{ flex:1 1 46%; }
  .rfilter select{ min-width:0; width:100%; }
}

/* ---------- 13e · Non-card content patterns ---------------------- */
/* The site had drifted into one shape: a bordered box in a three-up grid,
   53 of them. These are the alternatives — each is a genuinely different
   reading experience rather than the same box restyled. */

/* --- Accordion. For sets where the titles are the scannable part and the
       detail is optional. Uses <details>, so it opens without JS, is
       keyboard-operable for free, and Ctrl+F finds closed content. --- */
.acc{ border-top:1px solid var(--line-2); }
.acc__i{ border-bottom:1px solid var(--line-2); }
.acc__s{
  display:flex; align-items:center; gap:16px; width:100%;
  padding:clamp(18px,2vw,24px) 0; cursor:pointer; list-style:none;
  font-family:var(--f-display); font-size:clamp(1.05rem,1.6vw,1.3rem);
  font-weight:600; letter-spacing:-.02em; color:var(--ink);
  transition:color var(--t-fast) var(--ease);
}
.acc__s::-webkit-details-marker{ display:none; }
.acc__s:hover{ color:var(--brand); }
.acc__ic{ width:26px; height:26px; color:var(--brand); flex:none; }
.acc__ic .ic{ width:100%; height:100%; }
.acc__t{ flex:1; }
/* The +/- is drawn from two rules so it can animate without a glyph. */
.acc__x{ position:relative; width:16px; height:16px; flex:none; }
.acc__x::before, .acc__x::after{
  content:""; position:absolute; inset:50% 0 auto; height:2px; border-radius:2px;
  background:var(--ink-3); translate:0 -50%; transition:transform .3s var(--ease), background var(--t-fast) var(--ease);
}
.acc__x::after{ transform:rotate(90deg); }
.acc__i[open] .acc__x::after{ transform:rotate(0deg); }
.acc__i[open] .acc__x::before, .acc__i[open] .acc__x::after{ background:var(--brand); }
.acc__b{ padding:0 0 clamp(20px,2.4vw,28px) 42px; }
.acc__b p{ font-size:.98rem; line-height:1.7; color:var(--ink-2); max-width:68ch; }
[dir="rtl"] .acc__b{ padding-left:0; padding-right:42px; }
@media (max-width:560px){ .acc__b{ padding-left:0; } [dir="rtl"] .acc__b{ padding-right:0; } }
/* No icon in the summary, so no icon-width indent under it. */
.acc--plain .acc__b{ padding-left:0; }
[dir="rtl"] .acc--plain .acc__b{ padding-right:0; }

/* --- Editorial numbered rows. A list that reads like a page of a report:
       a big quiet numeral, a rule, and text. No box anywhere. --- */
.enum{ list-style:none; padding:0; margin:0; display:grid; gap:0; }
.enum__i{
  display:grid; grid-template-columns:auto 1fr; gap:clamp(20px,3vw,44px);
  padding:clamp(24px,3vw,36px) 0; border-top:1px solid var(--line-2);
}
.enum__i:last-child{ border-bottom:1px solid var(--line-2); }
.enum__n{
  font-family:var(--f-display); font-size:clamp(1.6rem,3.4vw,2.6rem); font-weight:700;
  line-height:1; letter-spacing:-.04em; color:var(--brand); opacity:.28;
  /* tabular-nums is a no-op here — the display face ships no tabular figures,
     so "01" measured 39px against "04" at 52px and every row set its own
     enumerator width, leaving the title column 10px ragged down the list.
     A fixed em width holds the column and still tracks the font-size clamp. */
  font-variant-numeric:tabular-nums; width:1.35em;
}
/* Letters are not numerals: `min-width:2ch` is not binding on a capital C at
   this size, so each row sized its own enumerator and the title column came
   out 7px ragged. A fixed em width holds the column and still tracks the
   font-size clamp. Scoped, because tabular numerals are already equal-width. */
.enum--acro .enum__n{ width:.9em; min-width:0; }
.enum__h{ font-size:clamp(1.08rem,1.7vw,1.32rem); letter-spacing:-.024em; margin:0 0 8px; }
.enum__p{ font-size:.97rem; line-height:1.68; color:var(--ink-2); max-width:64ch; }
@media (min-width:1000px){
  /* Two columns of rows, so six items do not become a six-screen scroll.
     In two columns the visual last ROW is the last two items, not just
     :last-child — closing the rule under only one of them looks like a bug. */
  .enum--2{ grid-template-columns:1fr 1fr; column-gap:clamp(36px,4vw,72px); }
  .enum--2 .enum__i:last-child{ border-bottom:0; }
  .enum--2 .enum__i:nth-last-child(-n+2){ border-bottom:1px solid var(--line-2); }
}
/* Vision & Mission borrow the .enum row geometry but not its numeral: the
   two are not ordered, so a "1." beside Vision would assert a rank that
   isn't there. The icon takes the numeral's auto column instead. */
.enum__ic{ width:26px; height:26px; color:var(--brand); opacity:.72; margin-top:2px; }

/* --- Timeline rail. The hiring steps, connected — the line is the point,
       it says "these happen in order" without a box per step. --- */
.tline{ list-style:none; padding:0; margin:0; position:relative; display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(18px,2.4vw,32px); }
/* Inset by half a node so the rail spans node centres rather than sticking
   out past the first and last markers. */
.tline::before{
  content:""; position:absolute; left:16px; right:16px; top:15px; height:2px;
  background:linear-gradient(90deg, var(--brand) 0%, var(--line-2) 82%);
}
/* The gradient carries the direction of travel, so it has to flip with the
   text. Without this the rail runs bright-to-faded left-to-right in Arabic —
   emphasis on the last step instead of the first. */
[dir="rtl"] .tline::before{ background:linear-gradient(270deg, var(--brand) 0%, var(--line-2) 82%); }

/* Three steps instead of four. A modifier, never an edit to the base rule —
   careers.php's 4-step rail shares it. */
.tline--3{ grid-template-columns:repeat(3,1fr); }
@media (min-width:901px){
  /* One-sixth of the width sits past the last node at 3 columns, so the rail
     stops short and the gradient reaches grey sooner than the 4-up default. */
  .tline--3::before{ right:calc(16.667% + 16px); background:linear-gradient(90deg, var(--brand) 0%, var(--line-2) 76%); }
  [dir="rtl"] .tline--3::before{ right:16px; left:calc(16.667% + 16px);
    background:linear-gradient(270deg, var(--brand) 0%, var(--line-2) 76%); }
}
.tstep{ position:relative; padding-top:44px; }
.tstep__n{
  position:absolute; top:0; inset-inline-start:0;
  display:grid; place-items:center; width:32px; height:32px; border-radius:50%;
  background:var(--bg); box-shadow:0 0 0 2px var(--brand) inset;
  color:var(--brand); font-family:var(--f-display); font-weight:700; font-size:.86rem;
}
.tline .tstep:first-child .tstep__n{ background:var(--brand); color:#fff; box-shadow:none; }
.tstep h3{ font-size:1.04rem; letter-spacing:-.02em; margin:0 0 8px; }
.tstep p{ font-size:.92rem; line-height:1.64; color:var(--ink-3); }
@media (max-width:900px){
  /* Vertical rail below tablet — a horizontal one at 4 columns is unreadable. */
  .tline{ grid-template-columns:1fr; gap:0; }
  .tline::before{ left:15px; right:auto; top:16px; bottom:16px; width:2px; height:auto;
    background:linear-gradient(180deg, var(--brand) 0%, var(--line-2) 88%); }
  [dir="rtl"] .tline::before{ left:auto; right:15px; }
  .tstep{ padding:0 0 30px 52px; }
  [dir="rtl"] .tstep{ padding:0 52px 30px 0; }
  .tstep:last-child{ padding-bottom:0; }
}

/* ---------- 14 · Forms ------------------------------------------ */
.form{ display:grid; gap:16px; }
.form-grid{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
.field{ position:relative; display:block; }
.field > .lbl{
  position:absolute; left:16px; top:15px; font-size:.92rem; color:var(--ink-3);
  pointer-events:none; transform-origin:left top;
  transition:transform var(--t) var(--ease), color var(--t) var(--ease);
}
.input, .select, .textarea{
  width:100%; padding:24px 16px 9px; border-radius:var(--r);
  background:var(--bg-2); border:1px solid transparent; color:var(--ink);
  font-size:.94rem; line-height:1.4;
  transition:background var(--t) var(--ease), border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.textarea{ min-height:132px; resize:vertical; padding-top:26px; }
.select{ appearance:none; cursor:pointer; padding-right:42px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%236e6e76' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 6 5 5 5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 16px center;
}
.input:hover,.select:hover,.textarea:hover{ background:#f0f0f3; }
.input:focus,.select:focus,.textarea:focus{
  outline:0; background:#fff; border-color:var(--brand);
  box-shadow:0 0 0 4px rgba(192,26,71,.11);
}
.field:has(.input:focus) > .lbl,
.field:has(.input:not(:placeholder-shown)) > .lbl,
.field:has(.textarea:focus) > .lbl,
.field:has(.textarea:not(:placeholder-shown)) > .lbl,
.field:has(.select) > .lbl{ transform:translateY(-9px) scale(.76); color:var(--ink-4); }
.field:has(.input:focus) > .lbl,
.field:has(.textarea:focus) > .lbl,
.field:has(.select:focus) > .lbl{ color:var(--brand); }
.field .req{ color:var(--brand); }
.hint{ font-size:.78rem; color:var(--ink-4); margin-top:7px; }

.check{ display:flex; gap:11px; align-items:flex-start; cursor:pointer; font-size:.85rem; color:var(--ink-2); line-height:1.5; }
.check input{ position:absolute; opacity:0; width:0; height:0; }
.check .box{
  flex:none; width:19px; height:19px; border-radius:5px; margin-top:1px;
  background:var(--bg-2); box-shadow:inset 0 0 0 1px var(--line); position:relative;
  transition:background var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.check .box::after{
  content:''; position:absolute; left:6px; top:2.5px; width:5px; height:10px;
  border:solid #fff; border-width:0 2px 2px 0; transform:rotate(45deg) scale(0);
  transition:transform var(--t-fast) var(--ease);
}
.check input:checked + .box{ background:var(--brand); box-shadow:none; }
.check input:checked + .box::after{ transform:rotate(45deg) scale(1); }
.check input:focus-visible + .box{ box-shadow:0 0 0 3px rgba(192,26,71,.28); }
.hp{ position:absolute; left:-9999px; opacity:0; }

.note{
  display:flex; gap:11px; padding:14px 16px; border-radius:var(--r);
  background:var(--brand-wash); font-size:.85rem; color:var(--brand-2); line-height:1.5;
}
.note .ic{ width:17px; height:17px; flex:none; margin-top:2px; }
.note--ok{ background:#eefaf1; color:#14663a; }
.note--warn{ background:#fff6e8; color:#8a5a08; }

/* ---------- 15 · Booking ---------------------------------------- */
.booker{ display:grid; grid-template-columns:1.35fr .65fr; gap:clamp(24px,4vw,54px); align-items:start; }

.stepper{ display:flex; align-items:center; gap:0; margin-bottom:34px; }
.stepper__i{ display:flex; align-items:center; gap:10px; }
.stepper__d{
  width:28px; height:28px; border-radius:50%; display:grid; place-items:center;
  background:var(--bg-2); color:var(--ink-4); font-size:.78rem; font-weight:600;
  transition:background var(--t) var(--ease), color var(--t) var(--ease), transform var(--t) var(--ease);
}
.stepper__t{ font-size:.83rem; font-weight:550; color:var(--ink-4); letter-spacing:-.006em; transition:color var(--t) var(--ease); }
.stepper__i.is-on .stepper__d{ background:var(--brand); color:#fff; transform:scale(1.06); }
.stepper__i.is-on .stepper__t{ color:var(--ink); }
.stepper__i.is-done .stepper__d{ background:var(--ink); color:#fff; }
.stepper__i.is-done .stepper__t{ color:var(--ink-2); }
.stepper__bar{ flex:1; height:2px; margin:0 14px; border-radius:2px; background:var(--line); overflow:hidden; }
.stepper__bar i{ display:block; height:100%; width:0; background:var(--brand); transition:width .6s var(--ease); }

.panes{ position:relative; }
.pane{ display:none; }
.pane.is-on{ display:block; animation:paneIn .55s var(--ease-out); }
@keyframes paneIn{ from{ opacity:0; transform:translateY(14px);} to{ opacity:1; transform:none;} }
.pane__nav{ display:flex; gap:12px; justify-content:space-between; margin-top:30px; padding-top:22px; border-top:1px solid var(--line-2); }

.choices{ display:grid; gap:12px; }
.choice{ position:relative; display:block; cursor:pointer; }
.choice input{ position:absolute; opacity:0; width:0; height:0; }
.choice__in{
  display:flex; gap:16px; align-items:flex-start; padding:20px;
  border-radius:var(--r-lg); background:#fff; box-shadow:inset 0 0 0 1px var(--line);
  transition:box-shadow var(--t) var(--ease), transform var(--t) var(--ease), background var(--t) var(--ease);
}
.choice:hover .choice__in{ transform:translateY(-2px); box-shadow:inset 0 0 0 1px rgba(20,20,26,.18), var(--shadow-sm); }
.choice input:checked + .choice__in{ box-shadow:inset 0 0 0 2px var(--brand), var(--shadow); background:linear-gradient(180deg,#fff,var(--brand-wash)); }
.choice input:focus-visible + .choice__in{ box-shadow:inset 0 0 0 2px var(--brand), 0 0 0 4px rgba(192,26,71,.2); }
.choice__ic{ width:42px; height:42px; border-radius:5px; display:grid; place-items:center; background:var(--bg-2); color:var(--brand); flex:none; transition:background var(--t) var(--ease), color var(--t) var(--ease); }
.choice input:checked + .choice__in .choice__ic{ background:var(--brand); color:#fff; }
.choice__ic .ic{ width:20px; height:20px; }
.choice b{ display:block; font-size:1rem; font-weight:600; letter-spacing:-.018em; }
.choice p{ font-size:.86rem; color:var(--ink-3); margin-top:5px; line-height:1.5; }
.choice__meta{ display:flex; gap:7px; margin-top:11px; flex-wrap:wrap; }
.choice__tick{
  position:absolute; right:18px; top:18px; width:21px; height:21px; border-radius:50%;
  background:var(--brand); color:#fff; display:grid; place-items:center;
  opacity:0; transform:scale(.6); transition:opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.choice__tick .ic{ width:12px; height:12px; stroke-width:2.6; }
.choice input:checked ~ .choice__tick{ opacity:1; transform:none; }

.sched{ display:grid; grid-template-columns:1.15fr .85fr; gap:clamp(18px,2.6vw,32px); align-items:start; }
.cal{ background:#fff; border:1px solid var(--line); border-radius:var(--r-lg); padding:20px; box-shadow:var(--shadow-sm); }
.cal__hd{ display:flex; align-items:center; justify-content:space-between; margin-bottom:16px; }
.cal__mo{ font-family:var(--f-display); font-size:1.02rem; font-weight:600; letter-spacing:-.02em; }
.cal__nav{ display:flex; gap:6px; }
.cal__nav button{ width:32px; height:32px; border-radius:50%; display:grid; place-items:center; color:var(--ink-2); transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease); }
.cal__nav button:hover:not([disabled]){ background:var(--bg-2); color:var(--ink); }
.cal__nav button[disabled]{ opacity:.25; cursor:not-allowed; }
.cal__nav .ic{ width:15px; height:15px; }
.cal__dow, .cal__days{ display:grid; grid-template-columns:repeat(7,1fr); gap:4px; }
.cal__dow span{ text-align:center; font-size:.68rem; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-4); padding-bottom:8px; }
.day{
  position:relative; aspect-ratio:1; border-radius:5px; display:grid; place-items:center;
  font-size:.86rem; font-weight:500; color:var(--ink); background:transparent;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.day:hover:not(:disabled):not(.is-sel){ background:var(--bg-2); transform:scale(1.06); }
.day:disabled{ color:var(--ink-4); opacity:.42; cursor:not-allowed; }
.day.is-sel{ background:var(--brand); color:#fff; font-weight:600; box-shadow:var(--shadow-brand); }
.day.is-today::after{ content:''; position:absolute; bottom:6px; width:4px; height:4px; border-radius:50%; background:var(--brand); }
.day.is-sel.is-today::after{ background:#fff; }
.day.is-void{ pointer-events:none; }

.slots__hd{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-bottom:12px; }
.slots__hd b{ font-size:.92rem; letter-spacing:-.014em; }
.slots{ display:grid; grid-template-columns:repeat(auto-fill,minmax(88px,1fr)); gap:8px; max-height:326px; overflow-y:auto; padding-right:4px; }
.slot{
  padding:11px 8px; border-radius:5px; background:var(--bg-2); font-size:.85rem; font-weight:550;
  color:var(--ink-2); text-align:center;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.slot:hover{ background:#ececed; transform:translateY(-2px); }
.slot.is-sel{ background:var(--brand); color:#fff; box-shadow:var(--shadow-brand); }
.slot:disabled{ opacity:.32; text-decoration:line-through; pointer-events:none; }
.slots__empty{ padding:34px 16px; text-align:center; color:var(--ink-4); font-size:.87rem; }

.summary{
  position:sticky; top:calc(var(--nav-h) + 22px);
  background:#fff; border:1px solid var(--line); border-radius:var(--r-lg);
  padding:24px; box-shadow:var(--shadow);
}
.summary h3{ font-size:1.02rem; letter-spacing:-.02em; }
.summary__rows{ margin-top:18px; display:grid; gap:2px; }
.srow{ display:flex; gap:12px; align-items:flex-start; padding:12px 0; border-bottom:1px solid var(--line-2); }
.srow:last-child{ border-bottom:0; }
.srow .ic{ width:17px; height:17px; color:var(--brand); margin-top:2px; flex:none; }
.srow small{ display:block; font-size:.72rem; letter-spacing:.09em; text-transform:uppercase; color:var(--ink-4); }
.srow b{ display:block; font-size:.9rem; font-weight:550; letter-spacing:-.01em; margin-top:3px; }
.srow b.is-empty{ color:var(--ink-4); font-weight:400; font-style:italic; }
.summary__foot{ margin-top:18px; padding-top:16px; border-top:1px solid var(--line-2); }

/* ---------- 16 · Partner locator -------------------------------- */
.mapbox{
  position:relative; border-radius:var(--r-xl); overflow:hidden;
  background:linear-gradient(165deg,#fff 0%, var(--bg-2) 70%, #fff 100%);
  border:1px solid var(--line); box-shadow:var(--shadow);
  aspect-ratio:720/292;
}
.mapbox svg{ position:absolute; inset:0; width:100%; height:100%; }
.mapbox .dots circle{ fill:#d8d8de; }
.mapbox::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(70% 90% at 28% 44%, rgba(192,26,71,.09), transparent 62%);
}
.pin{ cursor:pointer; transition:opacity var(--t) var(--ease); }
.pin .core{ fill:var(--brand); transition:r var(--t) var(--ease); }
/* Partners read as a ring, offices as a solid dot. Both were solid brand before,
   which was fine while the map held offices only -- the moment a partner landed
   on it, one legend swatch was standing for two different things. */
.pin:not([data-type="office"]) .core{ fill:#fff; stroke:var(--brand); stroke-width:2; }
.mapbox__legend i.is-partner{ background:#fff; border:2px solid var(--brand); }
.pin .halo{ fill:var(--brand); opacity:.2; transform-origin:center; animation:ping 3s var(--ease-soft) infinite; }
.pin .hit{ fill:transparent; }
.pin:hover .core, .pin.is-active .core{ r:7.5; }
.pin.is-dim{ opacity:.2; }
.pin__lbl{
  font-family:var(--f-text); font-size:11px; font-weight:600; fill:var(--ink-2);
  opacity:0; transition:opacity var(--t) var(--ease); paint-order:stroke;
  stroke:#fff; stroke-width:3px; stroke-linejoin:round;
}
.pin:hover .pin__lbl, .pin.is-active .pin__lbl{ opacity:1; }
@keyframes ping{ 0%{ transform:scale(.5); opacity:.28;} 70%,100%{ transform:scale(2.6); opacity:0;} }
.mapbox__legend{
  position:absolute; left:16px; bottom:14px; z-index:3; display:flex; gap:16px; flex-wrap:wrap;
  padding:9px 15px; border-radius:var(--r-pill); background:rgba(255,255,255,.84);
  -webkit-backdrop-filter:var(--glass); backdrop-filter:var(--glass); box-shadow:var(--shadow-sm);
  font-size:.73rem; color:var(--ink-2);
}
.mapbox__legend i{ display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--brand); margin-right:7px; vertical-align:middle; }
.mapbox__note{ position:absolute; right:24px; top:22px; z-index:3; background:rgba(255,255,255,.86); -webkit-backdrop-filter:var(--glass); backdrop-filter:var(--glass); box-shadow:var(--shadow-sm); }

.loc__tools{ display:grid; grid-template-columns:minmax(240px,1fr) auto; gap:16px; align-items:center; margin:clamp(26px,3vw,38px) 0 20px; }
.filters{ display:flex; gap:8px; flex-wrap:wrap; }
.fbtn{
  padding:9px 16px; border-radius:var(--r-pill); background:var(--bg-2);
  font-size:.82rem; font-weight:550; color:var(--ink-2); white-space:nowrap;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.fbtn:hover{ background:#e9e9ec; transform:translateY(-1px); }
.fbtn.is-on{ background:var(--ink); color:#fff; }
.fbtn small{ opacity:.55; margin-left:5px; }
.searchbox{ position:relative; }
.searchbox .ic{ position:absolute; left:17px; top:50%; translate:0 -50%; width:17px; height:17px; color:var(--ink-4); pointer-events:none; }
.searchbox input{
  width:100%; padding:14px 16px 14px 45px; border-radius:var(--r-pill);
  background:var(--bg-2); border:1px solid transparent; font-size:.92rem;
  transition:background var(--t) var(--ease), border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.searchbox input:focus{ outline:0; background:#fff; border-color:var(--brand); box-shadow:0 0 0 4px rgba(192,26,71,.1); }

.loc__count{ font-size:.82rem; color:var(--ink-4); margin-bottom:14px; }
.plist{ display:grid; grid-template-columns:repeat(2,1fr); gap:14px; }
.pcard{
  display:flex; gap:16px; align-items:flex-start; padding:22px;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-lg); position:relative;
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease), border-color var(--t) var(--ease);
}
.pcard:hover{ transform:translateY(-3px); box-shadow:var(--shadow); border-color:rgba(192,26,71,.26); }
.pcard > *{ position:relative; z-index:1; }
.pcard.is-hidden{ display:none; }
.pcard__ic{ width:46px; height:46px; border-radius:5px; display:grid; place-items:center; background:var(--bg-2); color:var(--brand); flex:none; }
.pcard__ic .ic{ width:21px; height:21px; }
/* In colour, not greyscale. This rule had never rendered -- no partner carried
   a logo until now -- and desaturating a partner's own mark to a grey smudge is
   not a directory treatment, it just makes their brand look broken. Supply a
   SQUARE mark: the tile is 46px, so a wide lockup lands about 10px tall. */
.pcard__ic img{ width:28px; height:28px; object-fit:contain; }
.pcard .type{ font-size:.68rem; font-weight:650; letter-spacing:.11em; text-transform:uppercase; color:var(--brand); }
.pcard b{ display:block; font-size:1.02rem; letter-spacing:-.02em; margin-top:4px; }
.pcard .city{ display:flex; align-items:center; gap:6px; font-size:.83rem; color:var(--ink-3); margin-top:3px; }
.pcard .city .ic{ width:14px; height:14px; color:var(--ink-4); }
.pcard ul{ list-style:none; padding:0; margin:11px 0 0; display:grid; gap:3px; }
.pcard li{ font-size:.85rem; color:var(--ink-3); line-height:1.5; }
.pcard__tags{ display:flex; gap:6px; flex-wrap:wrap; margin-top:13px; }
.pcard__tags .pill{ font-size:.7rem; padding:4px 10px; }
.plist__empty{ grid-column:1/-1; padding:54px 24px; text-align:center; border:1px dashed var(--line); border-radius:var(--r-lg); }
.plist__empty .d4{ margin-bottom:10px; }

/* ---------- 17 · Partner program tiers -------------------------- */
.tiers{ display:grid; grid-template-columns:repeat(3,1fr); gap:16px; align-items:start; }
.tier{
  position:relative; background:#fff; border:1px solid var(--line); border-radius:var(--r-xl);
  padding:clamp(24px,2.6vw,34px); overflow:hidden;
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.tier:hover{ transform:translateY(-5px); box-shadow:var(--shadow-lg); }
.tier--hot{ border-color:transparent; background:linear-gradient(160deg,var(--brand-ink),#141418); color:#fff; box-shadow:var(--shadow-lg); }
.tier--hot::before{
  content:''; position:absolute; width:70%; height:120%; right:-20%; top:-40%;
  background:radial-gradient(circle, rgba(192,26,71,.45), transparent 66%); filter:blur(44px);
}
.tier > *{ position:relative; z-index:2; }
.tier__tag{
  position:absolute; right:20px; top:20px; z-index:3; padding:5px 11px; border-radius:var(--r-pill);
  background:var(--brand); color:#fff; font-size:.66rem; font-weight:650; letter-spacing:.1em; text-transform:uppercase;
}
.tier__name{ font-family:var(--f-display); font-size:1.24rem; font-weight:600; letter-spacing:-.024em; }
.tier__sub{ font-size:.86rem; color:var(--ink-3); margin-top:7px; line-height:1.5; }
.tier--hot .tier__sub{ color:rgba(255,255,255,.62); }
.tier__list{ list-style:none; padding:0; margin:22px 0 0; display:grid; gap:11px; }
.tier__list li{ display:flex; gap:10px; align-items:flex-start; font-size:.885rem; line-height:1.5; }
.tier__list .ic{ width:16px; height:16px; color:var(--brand); margin-top:3px; flex:none; stroke-width:2.2; }
.tier--hot .tier__list .ic{ color:var(--brand-3); }
.tier--hot .tier__list li{ color:rgba(255,255,255,.84); }
.tier__foot{ margin-top:26px; padding-top:20px; border-top:1px solid var(--line-2); }
.tier--hot .tier__foot{ border-top-color:rgba(255,255,255,.14); }

/* ---------- 18 · Footer ----------------------------------------- */
.ftr{ background:var(--bg-2); border-top:1px solid var(--line-2); padding-block:clamp(50px,6vw,76px) 30px; }
.ftr__top{ display:grid; grid-template-columns:1.5fr repeat(3,1fr); gap:clamp(26px,4vw,48px); }
.ftr__brand img{ height:27px; }
.ftr__brand p{ font-size:.88rem; color:var(--ink-3); line-height:1.6; margin-top:16px; max-width:34ch; }
.ftr h2{ font-family:var(--f-text); font-size:.72rem; font-weight:650; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-4); }
.ftr ul{ list-style:none; padding:0; margin:16px 0 0; display:grid; gap:11px; }
.ftr a{ font-size:.885rem; color:var(--ink-2); transition:color var(--t-fast) var(--ease); }
.ftr a:hover{ color:var(--brand); }
.ftr__contact{ display:grid; gap:11px; margin-top:22px; }
.ftr__contact > a, .ftr__contact > span{ display:flex; gap:10px; align-items:flex-start; font-size:.85rem; color:var(--ink-2); }
.ftr__contact > span > span{ min-width:0; }   /* label + address stack, not sit side by side */
.ftr__contact .ic{ width:16px; height:16px; color:var(--brand); margin-top:2px; flex:none; }
.ftr__soc{ display:flex; gap:8px; margin-top:22px; }
.ftr__soc a{
  width:38px; height:38px; border-radius:50%; display:grid; place-items:center; background:#fff;
  box-shadow:var(--shadow-sm); color:var(--ink-2);
  transition:transform var(--t) var(--ease), color var(--t) var(--ease), background var(--t) var(--ease);
}
.ftr__soc a:hover{ transform:translateY(-3px); background:var(--brand); color:#fff; }
.ftr__soc .ic{ width:17px; height:17px; }
.ftr__bot{
  margin-top:clamp(34px,4vw,52px); padding-top:22px; border-top:1px solid var(--line);
  display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap; align-items:center;
}
.ftr__bot p, .ftr__bot a{ font-size:.79rem; color:var(--ink-4); }
.ftr__legal{ display:flex; gap:20px; flex-wrap:wrap; }

/* ---------- 17a · Orbit: the services ring ---------------------- */
/* A true closed ring, not an arc. Eight icons sit ON the circumference and
   the payload is sealed inside it, so the ring is a control surface and the
   middle is the display. That is why the node labels are screen-reader-only
   above 900px: eight service names drawn permanently around a circle is
   exactly the noise this replaces, and the name the reader wants is the one
   in the middle. Below 900px the whole thing becomes a plain labelled grid.
   Nodes are absolutely placed by PHP-computed percentages. */
.orbit{
  position:relative; width:min(620px,100%); aspect-ratio:1; margin-inline:auto;
}
/* The band. `inset:0` is the circle; the nodes straddle its edge. The tint
   is held in the outer sixth only — filled edge to edge it stops reading as
   a ring and becomes a pink disc with things on top of it. */
.orbit::before{
  content:''; position:absolute; inset:0; border-radius:50%;
  border:1px solid rgba(192,26,71,.16);
  background:radial-gradient(closest-side,
    #fff 0%, #fff 72%, var(--brand-wash) 93%, rgba(192,26,71,.07) 100%);
  box-shadow:0 30px 70px -50px rgba(16,16,20,.3);
}
/* A slow sweep around the band — the same radar motif as the hero canvas and
   the scrollytelling stage. Masked to a hairline annulus at the very edge so
   it reads as light travelling along the ring, not as a rotating pie. It
   pauses the moment a node is active so it never competes with reading. */
.orbit::after{
  content:''; position:absolute; inset:0; border-radius:50%; pointer-events:none;
  background:conic-gradient(from 0deg,
    transparent 0deg, rgba(192,26,71,.05) 8deg, rgba(192,26,71,.34) 26deg, transparent 33deg);
  -webkit-mask:radial-gradient(closest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
          mask:radial-gradient(closest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  animation:orbit-sweep 16s linear infinite;
}
.orbit.is-live::after{ animation-play-state:paused; }
/* The nodes run anticlockwise in RTL, so the sweep must travel with them. */
[dir="rtl"] .orbit::after{ animation-direction:reverse; }
@keyframes orbit-sweep{ to{ transform:rotate(360deg); } }

/* z-index, not DOM order: ::after (the sweep) is a pseudo-element of .orbit
   and paints after positioned siblings, so without this the sweep draws a
   line straight across the icon bubbles and reads as a scratch. */
.orbit__ring{ list-style:none; margin:0; padding:0; position:absolute; inset:0; z-index:1; }
.orbit__node{ position:absolute; translate:-50% -50%; }
.orbit__node a{
  /* The global :focus-visible outline follows the element box and rounds it
     to 5px. On a round node that draws a squircle around a circle. */
  display:block; text-decoration:none; border-radius:50%;
  opacity:0; transform:scale(.8);
  transition:opacity .5s var(--ease), transform .5s var(--ease);
  transition-delay:var(--d);
}
.reveal.in .orbit__node a{ opacity:1; transform:none; }
/* Above 900px the ring carries icons only. The name still reaches assistive
   tech through the link, and sighted users get it in the middle panel. */
.orbit__lbl{
  position:absolute; width:1px; height:1px; padding:0; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.orbit__ic{
  width:clamp(52px,5vw,62px); aspect-ratio:1; display:grid; place-items:center;
  border-radius:50%; background:#fff;
  box-shadow:inset 0 0 0 1px var(--line), var(--shadow-sm);
  color:var(--brand-ink); --ic-accent:var(--brand);
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease),
             color var(--t) var(--ease), background var(--t) var(--ease);
}
.orbit__ic .ic{ width:24px; height:24px; }
.orbit__node a:hover .orbit__ic,
.orbit__node a:focus-visible .orbit__ic{
  transform:scale(1.09); color:var(--brand);
  box-shadow:inset 0 0 0 1px rgba(192,26,71,.32), var(--shadow);
}
/* The committed node. Filled, so which one you are reading is unambiguous
   from anywhere on the ring. */
.orbit__node.is-on .orbit__ic{
  background:var(--brand); color:#fff; --ic-accent:#fff;
  transform:scale(1.09);
  box-shadow:0 0 0 5px var(--brand-wash), var(--shadow);
}

.orbit__mid{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:60%; text-align:center; z-index:2;
}
.orbit__eyebrow{
  font-size:.7rem; font-weight:650; letter-spacing:.14em; text-transform:uppercase;
  color:var(--brand); margin-bottom:10px;
}
.orbit__mid h2{ margin:0; transition:opacity .22s var(--ease); }
.orbit__d{
  margin-top:10px; font-size:.92rem; line-height:1.6; color:var(--ink-3);
  transition:opacity .22s var(--ease);
}
.orbit.is-swapping .orbit__mid h2, .orbit.is-swapping .orbit__d{ opacity:0; }
.orbit__cta{ margin-top:18px; }
/* A ring is a fixed circle but a translation is not a fixed length: German
   compounds and Arabic both run long, and the middle cannot grow sideways
   without leaving the circle. It grows DOWN instead, and the type steps
   down one notch, which a circle can absorb and a fixed height cannot. */
.orbit__mid .d3{ font-size:clamp(1.32rem,2.3vw,1.92rem); }

@media (max-width:900px){
  /* Below tablet the ring stops being readable — fall back to a plain grid,
     and give every node its name back. */
  .orbit{ width:auto; aspect-ratio:auto; padding:26px 20px 30px; }
  .orbit::before, .orbit::after{ display:none; }
  .orbit__mid{ position:static; translate:none; width:auto; text-align:left; }
  .orbit__ring{ position:static; display:grid; grid-template-columns:repeat(2,1fr); gap:18px; margin-top:26px; }
  .orbit__node{ position:static; translate:none; }
  .orbit__node a{
    display:grid; grid-template-columns:auto 1fr; justify-items:start; align-items:center;
    text-align:left; gap:12px; opacity:1; transform:none;
  }
  .orbit__ic{ border-radius:var(--r); width:46px; }
  /* The label shares its cell with a fixed-width icon. A grid item defaults
     to min-width:auto, so a long service name sets the cell wider than the
     column and the panel clips it — "Security Operations Center" at 320px. */
  .orbit__lbl{
    position:static; width:auto; height:auto; padding:0; overflow:visible;
    clip:auto; white-space:normal; min-width:0; overflow-wrap:break-word;
    font-size:.85rem; line-height:1.35; font-weight:600; letter-spacing:-.01em; color:var(--ink-2);
  }
  .orbit__node.is-on .orbit__ic{ box-shadow:inset 0 0 0 1px rgba(192,26,71,.32), var(--shadow); }
}
/* Two columns leave ~80px for the label on the narrowest phones. One column
   keeps every service name on a readable measure. */
@media (max-width:400px){
  .orbit__ring{ grid-template-columns:1fr; gap:14px; }
}
@media (prefers-reduced-motion:reduce){
  .orbit__node a{ opacity:1; transform:none; transition:none; }
  .orbit::after{ animation:none; opacity:.5; }
}

/* ---------- 18a · Leadership ------------------------------------ */
/* Leadership: 4:5 portraits at 250px, name beneath, left-aligned in a
   three-column row. Keeps the shoulders and the suits, which a square or
   circle crop throws away. */
.leaders{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(26px,3vw,44px); }
.leader{ margin:0; }
.leader img{
  width:100%; max-width:250px; aspect-ratio:4/5; height:auto; object-fit:cover;
  border-radius:var(--r); display:block; background:var(--bg-2);
}
.leader b{ display:block; margin-top:18px; font-family:var(--f-display);
  font-size:clamp(1.02rem,1.4vw,1.14rem); font-weight:650; letter-spacing:-.02em; color:var(--ink); }
.leader span{ display:block; margin-top:5px; font-size:.9rem; line-height:1.45; color:var(--ink-3); }
@media (max-width:760px){
  .leaders{ grid-template-columns:repeat(2,1fr); gap:30px; }
}
@media (max-width:520px){
  .leaders{ grid-template-columns:1fr; gap:32px; }
  .leader img{ max-width:260px; }
}

/* ---------- 18a1 · Trustpilot rating ----------------------------- */
/* Trustpilot's own shape: five square tiles with a star knocked out of each,
   the last partially filled. The star is WHITE in their mark — not "whatever
   the page background is". Tying it to a surface colour looked right only on
   a white page and broke on the grey footer, where the stars went dark. */
/* Stacked the way Trustpilot present it: wordmark, then the star row, then
   the score line. Two things matter and both were wrong at first:
   the rows align to the START, not the centre — everything around this block
   (the hero copy, the footer column) is left-aligned, so a centred group
   reads as misaligned; and the tiles are the dominant element at about 1.5x
   the wordmark's height, not the same size as it. */
.tp{ display:inline-grid; justify-items:start; gap:10px; text-decoration:none; }
.tp__logo{ height:22px; width:auto; display:block; }
.tp__logo-t{ fill:#191919; }
.tp__stars{ display:inline-flex; gap:4px; }
.tp__t{
  position:relative; border-radius:2px;
  background:#dcdce6;               /* Trustpilot's own empty-tile grey */
  overflow:hidden; display:block; flex:none;
}
.tp__fill{ position:absolute; inset:0 auto 0 0; width:var(--tp-fill,0%); }
.tp__s{ position:relative; width:100%; height:100%; display:block; }
.tp__s path{ fill:#fff; stroke:none; }
[dir="rtl"] .tp__fill{ inset:0 0 0 auto; }

.tp__meta{ display:inline-flex; align-items:baseline; gap:8px; flex-wrap:wrap; font-size:.92rem; color:var(--ink-2); }
.tp__score b{ color:var(--ink); font-weight:650; }
.tp__n{ color:var(--ink-3); }
.tp__n::before{ content:"·"; margin-inline-end:8px; color:var(--line-2); }
.tp:hover .tp__score b{ color:var(--brand); }

/* On a dark surface only the wordmark and the text need to flip — the tiles
   and their white stars are the same on any ground. */
.tp--dark .tp__logo-t{ fill:#fff; }
.tp--dark .tp__meta, .tp--dark .tp__score{ color:rgba(255,255,255,.72); }
.tp--dark .tp__score b{ color:#fff; }
.tp--dark .tp__n{ color:rgba(255,255,255,.55); }
.tp--dark:hover .tp__score b{ color:#fff; }

/* The tiles are the block's width, so they carry the responsive step. */
.tp__t{ width:clamp(30px, 2.6vw, 34px); height:clamp(30px, 2.6vw, 34px); }
@media (max-width:520px){ .tp__t{ width:28px; height:28px; } }

/* ---------- 18a2 · Brand film (YouTube facade) ------------------- */
/* The poster is a local image; the iframe replaces it in place on click, so
   the 16/9 box never reflows and nothing loads from YouTube until asked. */
.film{
  position:relative; aspect-ratio:16/9; border-radius:var(--r);
  overflow:hidden; background:var(--ink); box-shadow:var(--shadow-sm);
}
.film__a{ display:block; width:100%; height:100%; }
.film__ph{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .6s var(--ease), filter .4s var(--ease);
}
.film__a:hover .film__ph, .film__a:focus-visible .film__ph{ transform:scale(1.02); filter:brightness(.92); }
.film__btn{
  position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:74px; height:74px; display:grid; place-items:center;
  border-radius:50%;                 /* a play control is one of the few true circles */
  background:rgba(255,255,255,.94); color:var(--brand);
  box-shadow:0 10px 34px rgba(0,0,0,.28);
  transition:transform .3s var(--ease), background var(--t-fast) var(--ease);
}
.film__btn .ic{ width:28px; height:28px; margin-left:3px; }  /* optical centring */
.film__a:hover .film__btn, .film__a:focus-visible .film__btn{ transform:translate(-50%,-50%) scale(1.07); background:#fff; }
.film iframe{ width:100%; height:100%; border:0; display:block; }
.film.is-on .film__a{ display:none; }
@media (max-width:600px){ .film__btn{ width:58px; height:58px; } .film__btn .ic{ width:22px; height:22px; } }
@media (prefers-reduced-motion:reduce){
  .film__ph, .film__btn{ transition:none; }
  .film__a:hover .film__ph{ transform:none; }
}

/* ---------- 18b · The Doodle ------------------------------------ */
/* One path, stretched by preserveAspectRatio="none". Block form sizes
   with --dw; inline form takes the width of the text it wraps. */
.doodle{ display:block; width:var(--dw,260px); color:var(--brand); }
.doodle__i{ display:block; width:100%; height:var(--dh,.34em); overflow:visible; }
.doodle{ font-size:1em; }

/* The Doodle marking inline text.
   An absolutely positioned SVG can only cover one bounding box, so the mark
   used to force white-space:nowrap to guarantee a single line. That made the
   marked phrase unshrinkable: wherever it was wider than its column — the
   hero headline at 1440px, a long localised phrase at any width — the line
   was cut off by the .ln reveal mask rather than wrapping.
   The same path is painted as a background image instead. box-decoration-break
   clones it onto every line box and preserveAspectRatio="none" stretches each
   copy to that line's own width, so the mark wraps like the text it marks. */
.dmark-run{ white-space:normal; }
.dmark{ display:inline; }
.dmark__t{
  --dk:.40em;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 104 500 52' preserveAspectRatio='none'%3E%3Cpath d='M6.7,111.6c0,0,487.1-6.7,488.2,7.4s-441.5-0.3-442.6,12.3c-1.1,12.6,296.4,5.6,309.9,16.6' fill='none' stroke='%23c01a47' stroke-width='11' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:0 100%;
  background-size:0 var(--dk);
  padding-bottom:.16em;
  -webkit-box-decoration-break:clone;
          box-decoration-break:clone;
}
.d1 .dmark__t{ --dk:.54em; padding-bottom:.14em; }
.dmark__i{ display:none; }

/* Desktop mirrored the SVG with scaleX(-1); a transform here would flip the
   text too, so RTL gets its own mirrored copy of the same path, wiped from
   the opposite edge. */
[dir="rtl"] .dmark__t{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 104 500 52' preserveAspectRatio='none'%3E%3Cg transform='translate(500,0) scale(-1,1)'%3E%3Cpath d='M6.7,111.6c0,0,487.1-6.7,488.2,7.4s-441.5-0.3-442.6,12.3c-1.1,12.6,296.4,5.6,309.9,16.6' fill='none' stroke='%23c01a47' stroke-width='11' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/g%3E%3C/svg%3E");
  background-position:100% 100%;
}

.doodle path{
  fill:none; stroke:currentColor; stroke-width:11;
  stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:var(--len,1250); stroke-dashoffset:var(--len,1250);
}
.reveal.in .doodle path, .is-drawn path{
  animation:doodle-draw .85s cubic-bezier(.25,.6,.3,1) forwards;
}
@keyframes doodle-draw{ to{ stroke-dashoffset:0; } }

.reveal.in .dmark__t, .lines.in .dmark__t, .is-drawn .dmark__t{
  animation:doodle-wipe .85s cubic-bezier(.25,.6,.3,1) forwards;
}
@keyframes doodle-wipe{ to{ background-size:100% var(--dk); } }

[dir="rtl"] .doodle__i{ transform:scaleX(-1); }

@media (prefers-reduced-motion:reduce){
  .doodle path{ stroke-dasharray:none; stroke-dashoffset:0; animation:none; }
  .dmark__t{ background-size:100% var(--dk); animation:none; }
}

/* ---------- 19 · Chrome ----------------------------------------- */
.progress{ position:fixed; inset:0 0 auto; height:2px; z-index:950; background:transparent; pointer-events:none; }
.progress i{ display:block; height:100%; width:0; background:linear-gradient(90deg,var(--brand),var(--brand-3)); transition:width .1s linear; }
.totop{
  position:fixed; right:22px; bottom:22px; z-index:880; width:44px; height:44px; border-radius:50%;
  display:grid; place-items:center; background:rgba(255,255,255,.86);
  -webkit-backdrop-filter:var(--glass); backdrop-filter:var(--glass);
  box-shadow:var(--shadow); color:var(--ink-2);
  opacity:0; transform:translateY(12px); pointer-events:none;
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease), color var(--t) var(--ease);
}
.totop.is-on{ opacity:1; transform:none; pointer-events:auto; }
.totop:hover{ color:var(--brand); }
.totop .ic{ width:18px; height:18px; transform:rotate(180deg); }

/* cross-document page transitions (Chromium) */
@view-transition{ navigation:auto; }
::view-transition-old(root){ animation:vtOut .26s var(--ease-soft) both; }
::view-transition-new(root){ animation:vtIn .38s var(--ease-out) both; }
@keyframes vtOut{ to{ opacity:0; transform:translateY(-6px); } }
@keyframes vtIn{ from{ opacity:0; transform:translateY(10px); } }

/* ---------- 20 · Motion preferences ----------------------------- */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
  .reveal{ opacity:1 !important; transform:none !important; }
  .lines .ln > span{ transform:none !important; }
  @view-transition{ navigation:none; }
}

/* ---------- 21 · Responsive ------------------------------------- */
@media (max-width:1080px){
  .booker{ grid-template-columns:1fr; }
  .summary{ position:static; }
  .plist{ grid-template-columns:1fr; }
  .ftr__top{ grid-template-columns:1fr 1fr; }
}
@media (max-width:900px){
  :root{ --nav-h:62px; }
  /* Mega panels live inside the fixed header; below the nav breakpoint they are
     unreachable and their 100vw width leaks into the document scroll width. */
  .mega{ display:none; }
  .loc__tools{ grid-template-columns:1fr; }
  .plist{ grid-template-columns:1fr; }
  .mapbox{ aspect-ratio:720/380; }
  .nav, .hdr__act .btn--desk{ display:none; }
  .burger{ display:flex; }
  .story{ grid-template-columns:1fr; }
  .story__pin{ position:static; height:auto; margin-bottom:26px; }
  .story__steps{ padding-block:0; }
  .step{ opacity:1; }
  .g-4{ grid-template-columns:repeat(2,1fr); }
  .g-3{ grid-template-columns:repeat(2,1fr); }
  .stats{ grid-template-columns:repeat(2,1fr); }
  .tiers{ grid-template-columns:1fr; }
  .band__side{ grid-template-columns:1fr; }
  .split, .split--wide-r{ grid-template-columns:1fr; }
  .sched{ grid-template-columns:1fr; }
}
@media (max-width:400px){
  /* At 320-400px the primary CTA is wider than the room left beside the
     logo, which pushed the burger past the right edge and made the menu
     unreachable. The CTA still lives in the mobile sheet. */
  .hdr__act .btn--brand{ display:none; }
  .hdr__act{ gap:2px; margin-left:6px; }
}
@media (max-width:640px){
  body{ font-size:16px; }
  .g-2,.g-3,.g-4{ grid-template-columns:1fr; }
  .form-grid{ grid-template-columns:1fr; }
  .stats{ grid-template-columns:1fr 1fr; gap:8px 20px; }
  .ftr__top{ grid-template-columns:1fr; }
  .stepper__t{ display:none; }
  .stepper__bar{ margin:0 8px; }
  .hero{ min-height:auto; padding-top:calc(var(--nav-h) + 30px); }
  /* The hero stacks here. This rule went out with the old two-column visual and
     was not put back when the hero returned to two columns, which left a 390px
     phone rendering the map in a half-width column — every pill one word wide. */
  .hero__grid{ grid-template-columns:1fr; gap:40px; }
  .scrollcue{ display:none; }
  .totop{ right:14px; bottom:14px; }
  .band{ border-radius:var(--r-lg); }
}

/* ---------- Mega menu: multi-column variant --------------------- */
.mega--wide .mega__links{ grid-template-columns:repeat(3,1fr); gap:6px 14px; align-items:start; }
.mega__col{ display:grid; gap:2px; align-content:start; }
.mega__ttl{
  font-size:.67rem; font-weight:650; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-4); padding:6px 13px 8px; margin-bottom:2px; border-bottom:1px solid var(--line-2);
}
.mega__aside{ padding-right:20px; border-right:1px solid var(--line-2); display:flex; flex-direction:column; }
.mega__aside .btn{ margin-top:auto; align-self:flex-start; }
.mega__promo{
  margin-top:16px; padding:16px; border-radius:var(--r); background:linear-gradient(160deg,var(--brand-wash),#fff);
  border:1px solid rgba(192,26,71,.14);
}
.mega__promo b{ display:block; font-size:.9rem; letter-spacing:-.016em; }
.mega__promo p{ font-size:.8rem; color:var(--ink-3); margin-top:5px; line-height:1.45; }
.mega__promo .tlink{ margin-top:10px; font-size:.82rem; }

/* ---------- Story stage: 4 morphing scenes ---------------------- */
[data-stage]{
  opacity:0; transform:scale(.94); transform-origin:center;
  transition:opacity .7s var(--ease-out), transform .9s var(--ease-out);
  pointer-events:none;
}
[data-stage].is-on{ opacity:1; transform:none; }
[data-stage] .dash{ stroke-dasharray:var(--len,420); stroke-dashoffset:var(--len,420); }
[data-stage].is-on .dash{ animation:draw 1.5s var(--ease-out) forwards; }
@keyframes draw{ to{ stroke-dashoffset:0; } }
[data-stage] .pop{ transform:scale(0); transform-origin:center; }
[data-stage].is-on .pop{ animation:pop .6s var(--ease-out) forwards; }
@keyframes pop{ to{ transform:scale(1); } }
.spin{ transform-origin:center; animation:spin 7s linear infinite; }
@keyframes spin{ to{ transform:rotate(360deg); } }
.blink{ animation:blink 1.9s var(--ease-soft) infinite; }
@keyframes blink{ 0%,100%{ opacity:.25; } 50%{ opacity:1; } }

/* ---------- Portal / My Willsec panel --------------------------- */
.portal{
  position:relative; overflow:hidden; border-radius:var(--r-xl);
  background:linear-gradient(160deg,#fff,var(--bg-2)); border:1px solid var(--line);
  box-shadow:var(--shadow-lg); padding:clamp(28px,4vw,52px);
}
.portal::before{
  content:''; position:absolute; width:46%; height:150%; right:-8%; top:-30%;
  background:radial-gradient(circle, rgba(192,26,71,.16), transparent 66%); filter:blur(46px);
}
.portal > *{ position:relative; z-index:2; }
.uibar{ display:flex; gap:6px; padding:12px 14px; border-bottom:1px solid var(--line-2); }
.uibar i{ width:9px; height:9px; border-radius:50%; background:var(--line); display:block; }

/* ---------- Quote ----------------------------------------------- */

/* ---------- Booking teaser -------------------------------------- */
.bteaser{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(26px,4vw,60px); align-items:center; }
.bteaser__cal{ background:#fff; border:1px solid var(--line); border-radius:var(--r-xl); box-shadow:var(--shadow-lg); padding:22px; }
@media (max-width:900px){ .bteaser{ grid-template-columns:1fr; } }

/* programmatic focus targets (step headings) should not show a ring */
[tabindex="-1"]:focus{ outline:none; }

/* ==================================================================
   22 · Icon buttons, language picker, search overlay
   ================================================================== */
.iconbtn{
  width:36px; height:36px; border-radius:var(--r-pill); display:grid; place-items:center;
  color:var(--ink-2); flex:none;
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.iconbtn:hover{ background:rgba(20,20,26,.055); color:var(--ink); }
.iconbtn .ic{ width:18px; height:18px; }

/* ---- language picker ---- */
.langpick{ position:relative; }
.langpick__btn{ width:auto; padding:0 11px; gap:6px; display:inline-flex; align-items:center; }
.langpick__code{ font-size:.74rem; font-weight:650; letter-spacing:.06em; }
.langmenu{
  position:absolute; inset-inline-end:0; top:calc(100% + 10px); z-index:60;
  min-width:214px; padding:7px;
  background:#fff; border:1px solid var(--line); border-radius:var(--r);
  box-shadow:0 1px 2px rgba(16,16,22,.06), 0 16px 40px rgba(16,16,22,.14);
  opacity:0; visibility:hidden; transform:translateY(-8px) scale(.98); transform-origin:top right;
  transition:opacity var(--t) var(--ease), transform var(--t) var(--ease), visibility var(--t);
}
.langmenu.is-open{ opacity:1; visibility:visible; transform:none; }
.langmenu__i{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:9px 12px; border-radius:5px; font-size:.9rem; color:var(--ink-2);
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.langmenu__i:hover{ background:var(--bg-2); color:var(--ink); }
.langmenu__i.is-on{ color:var(--brand); font-weight:600; }
.langmenu__i .ic{ width:15px; height:15px; }
.sheet__lnk.is-on{ color:var(--brand); font-weight:600; }

/* ---- search overlay ---- */
.searchbox-overlay{
  /* Docks under the fixed header rather than covering it, so the logo and
     nav stay visible while searching. */
  position:fixed; inset:var(--nav-h) 0 0; z-index:960; display:block;
  background:rgba(18,18,24,.28);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  opacity:0; visibility:hidden;
  transition:opacity var(--t) var(--ease), visibility var(--t);
}
.searchbox-overlay.is-open{ opacity:1; visibility:visible; }
/* A full-width sheet docked under the header, not a floating card. */
.so__panel{
  width:100%; background:#fff; border-bottom:1px solid var(--line);
  box-shadow:0 20px 50px rgba(16,16,22,.14);
  transform:translateY(-12px);
  transition:transform var(--t) var(--ease-out);
}
.searchbox-overlay.is-open .so__panel{ transform:none; }
.so__in{ max-width:var(--wrap); margin-inline:auto; padding-inline:var(--pad); }
.so__bar{
  display:flex; align-items:center; gap:16px;
  padding:clamp(20px,3vh,34px) 0 clamp(16px,2.4vh,24px);
  border-bottom:1px solid var(--line-2);
}
.so__bar > .ic{ width:24px; height:24px; color:var(--ink-4); flex:none; }
.so__bar input{
  flex:1; min-width:0; border:0; background:none; padding:2px 0;
  font-family:var(--f-display); font-size:clamp(1.5rem,3.2vw,2.1rem);
  font-weight:500; letter-spacing:-.022em; color:var(--ink);
}
.so__bar input::placeholder{ color:var(--ink-4); opacity:.7; }
.so__bar input:focus{ outline:none; }
.so__bar input::-webkit-search-cancel-button{ display:none; }
.so__rec{ padding:clamp(20px,3vh,30px) 0 clamp(22px,3vh,34px); }
.so__rec-h{
  display:block; font-size:.72rem; font-weight:650; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-4); margin-bottom:18px;
}
.so__rec-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:14px clamp(20px,4vw,56px); }
.so__rec-grid a{
  font-size:.98rem; letter-spacing:-.012em; color:var(--ink-2);
  transition:color var(--t-fast) var(--ease);
}
.so__rec-grid a:hover{ color:var(--brand); }
.searchbox-overlay.has-query .so__rec{ display:none; }
.searchbox-overlay:not(.has-query) .so__meta,
.searchbox-overlay:not(.has-query) .so__results{ display:none; }
@media (max-width:760px){ .so__rec-grid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:520px){ .so__rec-grid{ grid-template-columns:1fr; } }

.so__meta{
  display:flex; justify-content:space-between; align-items:center; gap:12px;
  padding:10px 0; border-bottom:1px solid var(--line-2);
  font-size:.76rem; color:var(--ink-4);
}
.so__hint kbd{
  font-family:var(--f-text); font-size:.7rem; padding:2px 6px; border-radius:5px;
  background:#fff; box-shadow:inset 0 0 0 1px var(--line); margin:0 2px;
}
.so__results{ max-height:min(56vh,460px); overflow-y:auto; padding:10px 0 18px; }
.sres{
  display:flex; gap:14px; align-items:flex-start; padding:12px 14px; border-radius:var(--r);
  transition:background var(--t-fast) var(--ease);
}
.sres:hover, .sres.is-cursor{ background:var(--bg-2); }
.sres__ic{ width:34px; height:34px; border-radius:5px; display:grid; place-items:center; background:var(--brand-wash); color:var(--brand); flex:none; }
.sres__ic .ic{ width:16px; height:16px; }
.sres b{ display:block; font-size:.95rem; font-weight:600; letter-spacing:-.014em; }
.sres p{ font-size:.83rem; color:var(--ink-3); line-height:1.45; margin-top:3px; }
.sres__kind{ font-size:.66rem; font-weight:650; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-4); }
.sres mark{ background:rgba(192,26,71,.16); color:inherit; border-radius:3px; padding:0 2px; }
.so__empty{ padding:44px 22px; text-align:center; color:var(--ink-3); font-size:.9rem; }
.so__empty b{ display:block; color:var(--ink); font-family:var(--f-display); font-size:1.05rem; margin-bottom:8px; }

@media (max-width:900px){
  .langpick__code{ display:none; }
  .langpick__btn{ width:36px; padding:0; }
  .so__hint{ display:none; }
}

/* ==================================================================
   23 · RTL — Arabic
   ================================================================== */
[dir="rtl"]{
  --f-display:'IBM Plex Sans Arabic','Poppins','SF Pro Display',-apple-system,sans-serif;
  --f-text:'IBM Plex Sans Arabic','Inter',-apple-system,'Segoe UI',sans-serif;
}
[dir="rtl"] body{ letter-spacing:0; }
[dir="rtl"] h1,[dir="rtl"] h2,[dir="rtl"] h3,[dir="rtl"] h4,
[dir="rtl"] .d1,[dir="rtl"] .d2,[dir="rtl"] .d3,[dir="rtl"] .d4{ letter-spacing:0; line-height:1.25; }
[dir="rtl"] .eyebrow,[dir="rtl"] .mega__ttl,[dir="rtl"] .step__n,
[dir="rtl"] .tier__tag,[dir="rtl"] .sres__kind,[dir="rtl"] .pcard .type,
[dir="rtl"] .media__badge,[dir="rtl"] .ftr h2{ letter-spacing:0; }

/* directional icons mirror */
[dir="rtl"] .btn .ic.mirror,[dir="rtl"] .tlink .ic,[dir="rtl"] .card__more .ic,
[dir="rtl"] .nav__lnk .ic,[dir="rtl"] .sheet__hd > .ic,
[dir="rtl"] .cal__nav .ic,[dir="rtl"] .breadcrumb .ic{ transform:scaleX(-1); }
[dir="rtl"] .btn:hover .ic{ transform:translateX(-3px); }
[dir="rtl"] .tlink:hover .ic,[dir="rtl"] .card:hover .card__more .ic{ transform:scaleX(-1) translateX(-4px); }
[dir="rtl"] .totop .ic{ transform:rotate(180deg); }

/* physical offsets that logical properties do not cover */
[dir="rtl"] .skip{ left:auto; right:16px; }
[dir="rtl"] .mega__aside{ padding-right:0; padding-left:20px; border-right:0; border-left:1px solid var(--line-2); }
[dir="rtl"] .mega__aside .btn{ align-self:flex-end; }
[dir="rtl"] .langmenu{ transform-origin:top left; }
[dir="rtl"] .hero::before{ background:linear-gradient(260deg, rgba(255,255,255,.94) 0%, rgba(255,255,255,.8) 26%, rgba(255,255,255,0) 56%); }
[dir="rtl"] .aurora::before{ left:auto; right:-8vw; }
[dir="rtl"] .aurora::after{ right:auto; left:-6vw; }
[dir="rtl"] .stage__label{ left:auto; right:22px; }
[dir="rtl"] .mapbox__legend{ left:auto; right:16px; }
[dir="rtl"] .mapbox__note{ right:auto; left:24px; }
[dir="rtl"] .tier__tag{ right:auto; left:20px; }
[dir="rtl"] .choice__tick{ right:auto; left:18px; }
[dir="rtl"] .field > .lbl{ left:auto; right:16px; transform-origin:right top; }
[dir="rtl"] .input,[dir="rtl"] .textarea,[dir="rtl"] .select{ text-align:right; }
[dir="rtl"] .select{ padding-right:16px; padding-left:42px; background-position:left 16px center; }
[dir="rtl"] .searchbox .ic{ left:auto; right:17px; }
[dir="rtl"] .searchbox input{ padding:14px 45px 14px 16px; }
[dir="rtl"] .totop{ right:auto; left:22px; }
[dir="rtl"] .band::before{ right:auto; left:-12%; }
[dir="rtl"] .portal::before{ right:auto; left:-8%; }
[dir="rtl"] .tier--hot::before{ right:-20%; left:auto; }
[dir="rtl"] .mega__lnk:hover{ transform:translateX(-3px); }
[dir="rtl"] .reveal--left{ transform:translate3d(28px,0,0); }
[dir="rtl"] .reveal--right{ transform:translate3d(-28px,0,0); }
[dir="rtl"] .check .box::after{ left:auto; right:6px; }
[dir="rtl"] .stat{ text-align:right; }
[dir="rtl"] .row[style*="text-align:right"]{ text-align:left; }
/* numbers, phone numbers and specs stay LTR inside RTL text */
[dir="rtl"] .mono,[dir="rtl"] .stat__n,[dir="rtl"] .media__spec,
[dir="rtl"] .cal__mo,[dir="rtl"] .slot,[dir="rtl"] .day{ direction:ltr; unicode-bidi:isolate; }
@media (max-width:640px){ [dir="rtl"] .totop{ left:14px; right:auto; } }

/* ==================================================================
   24 · Insights — index, cards, article
   ================================================================== */
.feat{
  display:grid; grid-template-columns:1.05fr .95fr; gap:clamp(22px,3.4vw,46px); align-items:center;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-xl);
  padding:clamp(18px,2.2vw,26px); overflow:hidden;
  transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease), border-color var(--t) var(--ease);
}
.feat:hover{ transform:translateY(-4px); box-shadow:var(--shadow-lg); border-color:rgba(192,26,71,.24); }
.feat__media .media{ border-radius:var(--r); }
.feat__body{ padding-inline-end:clamp(0px,2vw,26px); }
.feat .card__more{ display:inline-flex; align-items:center; gap:6px; font-size:.88rem; font-weight:550; color:var(--brand); }
.feat:hover .card__more .ic{ transform:translateX(4px); }

.postcard{ display:flex; flex-direction:column; }
.postcard__media{ margin:calc(clamp(22px,2.4vw,30px) * -1) calc(clamp(22px,2.4vw,30px) * -1) 0; }
.postcard__media .media{ border-radius:0; }
.postcard.is-hidden{ display:none; }
.postcard h3{ font-size:1.06rem; line-height:1.28; }
.postcard p{ flex:1; }

.postmeta{
  display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-top:14px;
  font-size:.79rem; color:var(--ink-4);
}
.postmeta .pill{ font-size:.7rem; padding:4px 10px; }
.postmeta__who{ display:flex; align-items:center; gap:10px; }
.postmeta__av{
  width:34px; height:34px; border-radius:50%; display:grid; place-items:center;
  background:var(--brand-wash); color:var(--brand); flex:none;
}
.postmeta__av .ic{ width:16px; height:16px; }
.postmeta__who b{ display:block; font-size:.85rem; color:var(--ink); font-weight:600; letter-spacing:-.01em; }
.postmeta__who span span{ display:block; font-size:.76rem; color:var(--ink-4); }

/* long-form article body */
.rich{ font-size:1.06rem; line-height:1.72; color:var(--ink-2); }
.rich > * + *{ margin-top:1.05em; }
.rich h2{ margin-top:1.9em; color:var(--ink); }
.rich h2 + p{ margin-top:.7em; }
.rich p strong{ color:var(--ink); font-weight:600; }
.rich a{ color:var(--brand); text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px; }
.rich ul{ padding-inline-start:1.15em; margin-top:1em; }
.rich li{ margin-top:.55em; }
.rich li::marker{ color:var(--brand); }
.rich blockquote{
  margin-block:1.6em; padding:clamp(18px,2.4vw,26px) clamp(20px,2.6vw,30px);
  border-inline-start:3px solid var(--brand); background:var(--bg-2); border-radius:0 var(--r) var(--r) 0;
  font-family:var(--f-display); font-size:clamp(1.06rem,1.7vw,1.28rem); font-weight:500;
  line-height:1.42; letter-spacing:-.018em; color:var(--ink);
}
[dir="rtl"] .rich blockquote{ border-radius:var(--r) 0 0 var(--r); }
.rich .media{ margin-block:1.8em; }

@media (max-width:900px){
  .feat{ grid-template-columns:1fr; }
  .feat__body{ padding-inline-end:0; padding-bottom:8px; }
}

/* Latin brand names and figures inside RTL text keep their own direction */
[dir="rtl"] .pill,[dir="rtl"] .stat__l,
[dir="rtl"] .sres__kind,[dir="rtl"] .postmeta{ unicode-bidi:plaintext; }

/* ---------- CJK typography ---------------------------------------
   Han script has no lowercase and much denser glyphs: the tight
   Latin tracking and 1.05 display leading are unreadable, so both
   are relaxed and letter-spacing is reset to zero.
   ------------------------------------------------------------------ */
html[lang="zh-Hans"]{
  --f-display:'Noto Sans SC','PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
  --f-text:'Noto Sans SC','PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
}
html[lang="ja"]{
  --f-display:'Noto Sans JP','Hiragino Kaku Gothic ProN','Yu Gothic',Meiryo,sans-serif;
  --f-text:'Noto Sans JP','Hiragino Kaku Gothic ProN','Yu Gothic',Meiryo,sans-serif;
}
html[lang="zh-Hans"] h1, html[lang="ja"] h1,
html[lang="zh-Hans"] h2, html[lang="ja"] h2,
html[lang="zh-Hans"] h3, html[lang="ja"] h3,
html[lang="zh-Hans"] h4, html[lang="ja"] h4,
html[lang="zh-Hans"] .d1, html[lang="ja"] .d1,
html[lang="zh-Hans"] .d2, html[lang="ja"] .d2,
html[lang="zh-Hans"] .d3, html[lang="ja"] .d3,
html[lang="zh-Hans"] .d4, html[lang="ja"] .d4{ letter-spacing:0; line-height:1.32; }
html[lang="zh-Hans"] body, html[lang="ja"] body{ line-height:1.78; letter-spacing:0; }
html[lang="zh-Hans"] .lead, html[lang="ja"] .lead{ letter-spacing:0; line-height:1.75; }
html[lang="zh-Hans"] .eyebrow, html[lang="ja"] .eyebrow,
html[lang="zh-Hans"] .mega__ttl, html[lang="ja"] .mega__ttl,
html[lang="zh-Hans"] .step__n, html[lang="ja"] .step__n,
html[lang="zh-Hans"] .ftr h2, html[lang="ja"] .ftr h2,
html[lang="zh-Hans"] .sres__kind, html[lang="ja"] .sres__kind{ letter-spacing:.04em; }
/* CJK does not break on spaces — allow breaks anywhere but keep punctuation rules */
/* Han glyphs are full-width: the Latin display sizes overflow the measure. */
html[lang="zh-Hans"] .d1, html[lang="ja"] .d1{ font-size:clamp(2rem, 3.9vw, 3.25rem); }
html[lang="zh-Hans"] .d2, html[lang="ja"] .d2{ font-size:clamp(1.7rem, 3.2vw, 2.55rem); }
html[lang="zh-Hans"] .d3, html[lang="ja"] .d3{ font-size:clamp(1.3rem, 2.1vw, 1.8rem); }
/* CJK wraps between characters; never force mid-word Latin breaks in headings */
html[lang="zh-Hans"] p, html[lang="ja"] p{ line-break:strict; }
html[lang="zh-Hans"] h1, html[lang="ja"] h1,
html[lang="zh-Hans"] h2, html[lang="ja"] h2{ line-break:strict; word-break:normal; }

/* ==================================================================
   26 · Narrow-viewport headline safety
   These override base rules defined earlier in this file, so they must
   stay last — a media query adds no specificity of its own.
   ================================================================== */
@media (max-width:640px){
  /* Each .ln is one line of the headline set and never wraps, which is
     right on a wide screen and impossible on a phone: the longest line
     in Italian or Portuguese is far wider than the viewport, and
     overflow-x:clip hides the overspill instead of scrolling it. The
     reveal mask has to go with it — a wrapped line is taller than the
     box the mask was sized for. */
  .lines .ln{ overflow:visible; }
  .lines .ln > span{ display:block; white-space:normal; }
}

/* Flex and grid children default to min-width:auto, so they cannot shrink
   below their own min-content width. At narrow viewports that let a long
   word — or a phone number, or an email address, all far longer in French
   and Portuguese than English — push a column wider than the screen, where
   overflow-x:clip then hid the overspill instead of scrolling it. Letting
   these shrink is the systemic fix; the rules below just let text wrap. */
.hero__grid > *, .hero__head > *, .split > *, .grid > *, .stack > *,
.row > *, .frow > *, .band__side > *, .leaders > *, .tline > *,
.sec-head--wide > *, .enum__i > *{ min-width:0; }

/* Unbreakable tokens — addresses, emails, phone numbers — must wrap rather
   than set the column width. */
.stack, .frow, .ftr__contact, .sec-head p{ overflow-wrap:break-word; }

/* Between 900 and 1140px the desktop nav, the secondary button and a long
   localised CTA ("Réserver une consultation") together exceed the header.
   Drop the secondary button first — it is duplicated in the footer. */
@media (max-width:1140px) and (min-width:901px){
  .hdr__act .btn--desk{ display:none; }
}
/* Long words in a heading must break rather than push the column open. */
.d1, .d2, .d3{ overflow-wrap:break-word; }
