/* ═══════════════════════════════════════════════════════════
   Noxia — AI Consultancy, Edinburgh
   Chaptered journey · refined monochrome (Apple-grade dark)
   ═══════════════════════════════════════════════════════════ */

@font-face{
  font-family:'InterVariable';
  font-style:normal;font-weight:100 900;font-display:swap;
  src:url('fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face{
  font-family:'GreatVibes';
  font-style:normal;font-weight:400;font-display:swap;
  src:url('fonts/great-vibes-latin-400-normal.woff2') format('woff2');
}

:root{
  --bg:#000000;
  --panel:#161617;
  --ink:#f5f5f7;
  --mut:#c6c6cc;   /* holds up over the lit band, not just over black */
  --dim:#8a8a90;   /* 6.0:1 on black */
  --line:rgba(255,255,255,.10);
  --font:'InterVariable',-apple-system,'SF Pro Display','Helvetica Neue',Arial,sans-serif;
  --pad:clamp(1.4rem,5vw,4rem);
  --ease:cubic-bezier(.32,.08,.24,1);
  --r-lg:26px;
  --r-md:18px;
}

*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden;overscroll-behavior:none}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font);
  font-size:16px;
  line-height:1.5;
  letter-spacing:-.01em;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

::selection{background:#f5f5f7;color:#000}
::-webkit-scrollbar{width:8px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:#2a2a2c;border-radius:4px}

a{color:inherit;text-decoration:none}
button{background:none;border:0;color:inherit;font-family:inherit;cursor:pointer;text-align:inherit}
img,canvas,svg{display:block}
.center{text-align:center}

/* ── type ──────────────────────────────────────────────── */
.eyebrow{font-size:12px;font-weight:600;color:var(--mut);letter-spacing:.16em;
  text-transform:uppercase;margin-bottom:1.15rem}
.chapter-inner:not(.center) .eyebrow{position:relative;padding-left:28px}
.chapter-inner:not(.center) .eyebrow::before{
  content:'';position:absolute;left:0;top:.66em;width:18px;height:1px;background:var(--mut);
  transform:scaleX(0);transform-origin:left;transition:transform .8s var(--ease) .2s;
}
.chapter.is-active .chapter-inner:not(.center) .eyebrow::before{transform:scaleX(1)}
.h2{font-size:clamp(2rem,4.6vw,3.6rem);font-weight:640;letter-spacing:-.025em;line-height:1.05;margin-bottom:.9rem}
.statement{font-size:clamp(2.1rem,5vw,4.1rem);font-weight:640;letter-spacing:-.026em;line-height:1.06}
.sub{font-size:clamp(1rem,1.4vw,1.2rem);color:var(--mut);max-width:600px;letter-spacing:-.012em}
.sub.center{margin-left:auto;margin-right:auto}
.grad{
  background:linear-gradient(180deg,#ffffff 4%,#dedee3 52%,#8e8e93 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* ── pills ─────────────────────────────────────────────── */
.pill{
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:980px;padding:.8em 1.65em;font-size:15px;font-weight:500;
  letter-spacing:-.005em;transition:all .35s var(--ease);white-space:nowrap;
  position:relative;overflow:hidden;
}
.pill::after{
  content:'';position:absolute;top:0;bottom:0;left:-70%;width:55%;
  transform:skewX(-18deg);opacity:0;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.28),transparent);
}
.pill--fill::after{background:linear-gradient(90deg,transparent,rgba(0,0,0,.07),transparent)}
.pill:hover::after{animation:sheenSweep .85s var(--ease) forwards}
@keyframes sheenSweep{0%{left:-70%;opacity:0}18%{opacity:1}100%{left:115%;opacity:0}}
.pill--fill{background:#f5f5f7;color:#000}
.pill--fill:hover{background:#fff;transform:scale(1.03)}
/* secondary pills must hold their shape over the weave, not just over black */
.pill--ghost{
  border:1px solid rgba(255,255,255,.30);color:var(--ink);
  background:rgba(0,0,0,.28);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
}
.pill--ghost:hover{border-color:rgba(255,255,255,.6);background:rgba(255,255,255,.10);transform:scale(1.03)}
.pill--mini{padding:.52em 1.15em;font-size:13px;border:1px solid #5a5a5e}
.pill--mini:hover{border-color:#86868b;background:rgba(255,255,255,.06)}
.pill:active{transform:scale(.97)}

/* ── intro ─────────────────────────────────────────────── */
.intro{
  position:fixed;inset:0;z-index:990;background:#000;
  display:flex;align-items:center;justify-content:center;
}
.intro-word{
  /* the opening is drawn as real glyph outlines — no webfont, no CSS mask,
     no filters. Those were what made it stutter. */
  --ink-k:clamp(0.42px, 0.088vw, 1.15px);
  display:grid;place-items:center;
  padding:0 var(--pad);will-change:transform,opacity;
}
/* all four lines occupy the same grid cell — a stack, not a row —
   so hidden layers take no space and every word sits dead centre */
.intro-word .ink{grid-area:1/1;max-width:min(88vw,1180px);height:auto;overflow:visible;opacity:0}
/* There was a progress bar here. It is gone, with the wait it measured:
   the city is no longer raised before the site is shown, so the opening
   has nothing to report the progress of. */
.intro-skip{
  position:absolute;bottom:2rem;left:50%;transform:translateX(-50%);
  font-size:12px;color:var(--dim);opacity:0;animation:skipIn .3s ease .55s forwards;
}
@keyframes skipIn{to{opacity:1}}
@media (prefers-reduced-motion:reduce){.intro-skip{opacity:1;animation:none}}

/* ── header ────────────────────────────────────────────── */
.site-head{
  position:fixed;top:0;left:0;right:0;z-index:800;
  display:flex;align-items:center;justify-content:space-between;
  padding:.9rem var(--pad);
  pointer-events:none;
}
.site-head>*{pointer-events:auto}
.brand{
  font-size:19px;font-weight:640;letter-spacing:-.02em;cursor:pointer;
  display:inline-flex;align-items:center;line-height:1;
  /* the wordmark draws at 19px; the target has to clear 24 */
  min-height:24px;
}
/* the wordmark is baked outlines, so it is crisp at any size and never
   waits on the webfont the rest of the page is still loading */
.brand svg{display:block;height:19px;width:auto;transition:opacity .3s var(--ease)}
.brand:hover svg{opacity:.82}

/* ── hit areas ─────────────────────────────────────────────────────────
   Several of these controls are deliberately small — a 19px wordmark, a
   12px chapter number, an 8px dot on a phone. Small is the design; a
   small *target* is not. WCAG 2.2 asks for 24x24 CSS pixels and a thumb
   really wants 44, and the chapter nav — the primary navigation of the
   whole site — was eight pixels square on a phone. A transparent ::after
   grows the target without touching a single pixel of the drawing. */
.brand,.chap-nav button,.copy-chip{position:relative}
.brand::after{content:'';position:absolute;inset:-9px -6px}
.copy-chip::after{content:'';position:absolute;inset:-7px -4px}

/* ── chapter nav (right side) ──────────────────────────── */
.chap-nav{
  position:fixed;right:clamp(14px,2.4vw,36px);top:50%;transform:translateY(-50%);
  z-index:810;display:flex;flex-direction:column;gap:15px;align-items:flex-end;
}
.chap-nav button{
  /* N1-06, 8 September 2026. This was `padding:2px 0` with an absolutely
     positioned ::after meant to extend the target to 32px — but the button
     was never `position:relative`, so every one of those pseudo-elements
     was being laid out against `.chap-nav` instead. Six enlarged hit areas
     stacked on the container, and six 20px-tall buttons. The comment
     described a target that did not exist for two months.

     Now the button's own box clears 24x24 at every width, which is a thing
     a test can measure, and the ::after still softens the edges. */
  display:flex;align-items:center;justify-content:flex-end;gap:10px;
  padding:2px 0;position:relative;min-height:24px;min-width:24px;
}
.chap-nav button::after{content:'';position:absolute;inset:-4px -8px -4px -14px}
.chap-nav span{
  font-size:12px;font-weight:500;color:var(--mut);opacity:0;transform:translateX(6px);
  transition:opacity .3s,transform .3s var(--ease),color .3s;
}
.chap-nav i{
  font-style:normal;font-size:12px;font-weight:600;color:var(--dim);
  transition:color .3s;min-width:18px;text-align:right;
}
.chap-nav button:hover span{opacity:1;transform:none}
.chap-nav button:hover i{color:var(--mut)}
.chap-nav button.on i{color:var(--ink)}
.chap-nav button.on span{opacity:1;transform:none;color:var(--ink)}

.chap-counter{
  position:fixed;left:var(--pad);bottom:1.5rem;z-index:810;
  display:flex;align-items:baseline;gap:.45rem;
}
.chap-counter b{
  font-size:15px;font-weight:640;position:relative;display:inline-block;
  min-width:2.1ch;height:1.15em;overflow:hidden;vertical-align:bottom;
}
.chap-counter b i{font-style:normal;position:absolute;left:0;top:0;line-height:1.15}

#turn-edge{
  position:fixed;top:0;bottom:0;left:-10%;width:140px;z-index:600;
  pointer-events:none;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.08) 42%,rgba(255,255,255,.22) 50%,rgba(255,255,255,.08) 58%,transparent);
}
.chap-counter em{font-style:normal;font-size:12.5px;color:var(--dim)}
.chap-counter span{font-size:12.5px;color:var(--mut);margin-left:.35rem}
/* on a phone the chapters scroll, so copy dissolves into black behind the
   counter instead of colliding with it */
@media(max-width:760px){
  .chap-counter::before{
    content:'';position:fixed;left:0;right:0;bottom:0;height:112px;z-index:-1;
    pointer-events:none;
    background:linear-gradient(180deg,transparent,rgba(0,0,0,.62) 46%,#000 90%);
  }
}

/* ── stage & chapters ──────────────────────────────────── */
.stage{position:fixed;inset:0;overflow:hidden;perspective:1500px}
#stage-canvas{position:absolute;inset:0;width:100%;height:100%;z-index:0}
.stage-glow{
  position:absolute;left:50%;top:40%;transform:translate(-50%,-50%);z-index:0;
  width:min(58vw,720px);aspect-ratio:1.5;pointer-events:none;border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(255,255,255,.06), transparent 62%);
  animation:breathe 8s ease-in-out infinite;
}
@keyframes breathe{0%,100%{opacity:.6;transform:translate(-50%,-50%) scale(1)}50%{opacity:1;transform:translate(-50%,-50%) scale(1.07)}}

/* Legibility scrim — the silk is atmosphere; type always sits on controlled
   contrast. Darkens the edges where the UI furniture lives, keeps the centre
   open so the sheet still reads. */
.stage-scrim{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    /* the plate the copy sits on. Type over a moving field needs its own
       pool of contrast, or it drops out the moment the light crosses it. */
    radial-gradient(46% 33% at 50% 45%,
      rgba(0,0,0,.80) 0%, rgba(0,0,0,.63) 52%, rgba(0,0,0,.26) 82%, rgba(0,0,0,0) 100%),
    linear-gradient(180deg,
      rgba(0,0,0,.80) 0%, rgba(0,0,0,.34) 16%,
      rgba(0,0,0,.17) 38%, rgba(0,0,0,.26) 58%,
      rgba(0,0,0,.46) 82%, rgba(0,0,0,.80) 100%),
    radial-gradient(128% 82% at 50% 48%, rgba(0,0,0,0) 38%, rgba(0,0,0,.58) 100%);
}

.chapter{
  position:absolute;inset:0;z-index:2;
  display:flex;align-items:center;justify-content:center;
  visibility:hidden;opacity:0;
  backface-visibility:hidden;
}
.sr-only{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.lx-time{color:var(--dim);font-variant-numeric:tabular-nums;white-space:nowrap}
.chapter.is-active{visibility:visible;opacity:1}
.chapter-inner{
  width:min(1120px,100%);max-height:100svh;overflow-y:auto;overflow-x:hidden;
  padding:76px var(--pad) 64px;
  scrollbar-width:thin;
  /* When the copy is taller than the frame this column scrolls, and the
     platform draws its own rail for it — a pale vertical stripe straight
     down a black full-bleed page, right where the eye reads it as a seam.
     Dressed to disappear: no track at all, and a thumb you only notice
     when you go looking for it. */
  scrollbar-color:rgba(255,255,255,.15) transparent;
}
.chapter-inner::-webkit-scrollbar{width:8px}
.chapter-inner::-webkit-scrollbar-track{background:transparent}
.chapter-inner::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15);border-radius:99px}
.chapter-inner::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.26)}
.chapter-inner.center{display:flex;flex-direction:column;align-items:center;text-align:center}

/* 01 · overview */

/* The headline is measured against its own column, not the window. The
   column stops growing at 1120px but vw keeps climbing, so past that width
   the type outran the box and dropped "business" onto a line of its own.
   cqi tracks the column, so the ratio of type to measure never changes.
   The vw line stays first as the fallback for anything without cq units. */
#ch-overview .chapter-inner{container-type:inline-size}
.hero-title{
  font-size:clamp(2.9rem,6.9vw,5.9rem);
  font-size:clamp(2.9rem,9.3cqi,5.9rem);
  font-weight:640;letter-spacing:-.036em;
  line-height:0.97;margin-bottom:1.55rem;
  text-wrap:balance;
}
.hero-title .grad{
  background:linear-gradient(115deg,#ffffff 10%,#dedee3 38%,#8e8e93 52%,#dedee3 66%,#ffffff 92%);
  background-size:230% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:heroSheen 9s ease-in-out infinite;
  /* background-clip:text paints inside the inline box, and that box is only
     as tall as the line — at line-height .97 the descender of the "g" in
     "Agents" fell outside it and was sliced flat. The padding puts the paint
     box back around the ink; it costs no layout, an inline box doesn't grow
     the line. */
  padding:.12em 0 .24em;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
}
@keyframes heroSheen{0%,100%{background-position:0% 0}50%{background-position:100% 0}}
.hero-sub{
  font-size:clamp(1.05rem,1.6vw,1.32rem);color:var(--mut);max-width:600px;
  letter-spacing:-.008em;line-height:1.55;margin-bottom:2.3rem;
}
/* a hairline over the eyebrow: the rule that says this was set, not typed */
.chapter-inner.center .eyebrow{position:relative;padding-top:1.5rem}
.chapter-inner.center .eyebrow::before{
  content:'';position:absolute;left:50%;top:0;width:56px;height:1px;
  background:currentColor;opacity:.5;transform:translateX(-50%) scaleX(0);
  transition:transform 1s var(--ease) .35s;
}
.chapter.is-active .chapter-inner.center .eyebrow::before{transform:translateX(-50%) scaleX(1)}
.hero-ctas{display:flex;gap:.9rem;flex-wrap:wrap;justify-content:center;align-items:center}

/* 05 · sphere facts */
.sph-facts{
  display:flex;justify-content:center;align-items:stretch;
  margin:2.1rem 0 2.3rem;
}
.sph-facts div{
  display:flex;flex-direction:column;align-items:center;gap:.2rem;
  padding:0 clamp(1.5rem,4.5vw,3.4rem);
}
.sph-facts div + div{border-left:1px solid rgba(255,255,255,.12)}
.sph-facts b{
  font-size:clamp(1.5rem,2.6vw,2.1rem);font-weight:620;letter-spacing:-.02em;
  background:linear-gradient(180deg,#fff 6%,#d6d6db 60%,#8e8e93 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.sph-facts span{
  font-size:12px;font-weight:600;color:var(--mut);white-space:nowrap;
  letter-spacing:.09em;text-transform:uppercase;
}
.scroll-cue{
  position:absolute;bottom:1.6rem;left:50%;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:.5rem;
  font-size:12px;color:var(--dim);
}
.scroll-cue i{
  width:1px;height:30px;background:linear-gradient(180deg,var(--mut),transparent);
  animation:cue 2s var(--ease) infinite;transform-origin:top;
}
@keyframes cue{0%{transform:scaleY(0)}45%{transform:scaleY(1)}100%{transform:scaleY(0);transform-origin:bottom}}

/* 02 · manifesto */
.mani-cols{
  display:grid;grid-template-columns:1.35fr 1fr;gap:clamp(1.6rem,4vw,3.6rem);
  margin:clamp(1.8rem,4.5vh,3rem) 0;
}
.mani-big{font-size:clamp(1.15rem,1.9vw,1.55rem);font-weight:560;letter-spacing:-.02em;line-height:1.32}
.mani-small{font-size:14px;color:var(--mut);align-self:center}
.stats{display:grid;gap:1rem}
/* The footer link row came back when it had somewhere real to point. It went
   under N0-11 because all four social links were href="#". */
/* Five links now, and at 360px the row used to run off the right edge of
   the footer — the sweep caught it clipped. It wraps, and each link is a
   real 24px target rather than a line of 12.5px text. */
.foot-links{display:flex;flex-wrap:wrap;gap:.1rem .35rem;justify-content:center}
.foot-links a{color:var(--mut);display:inline-flex;align-items:center;
  min-height:28px;padding:0 .3rem;text-decoration:none}
.foot-links a:hover{color:var(--ink);text-decoration:underline}
@media(max-width:480px){.foot-line{justify-content:center;text-align:center}
  .foot-line>span{width:100%;text-align:center}}
.pill--ghost{background:transparent;color:var(--mut);
  border:1px solid var(--line);text-decoration:none}
.pill--ghost:hover{color:var(--ink);border-color:var(--ink)}
.stat b{display:block;font-size:clamp(2rem,3.8vw,3.3rem);font-weight:640;letter-spacing:-.03em;line-height:1}
.stat b::after{content:attr(data-suffix);font-size:.45em;font-weight:600;vertical-align:.5em;margin-left:.06em}
.future-stats{border-top:1px solid var(--line);margin-top:1.6rem;padding-top:1.3rem}
.fs-cap{font-size:12px;font-weight:600;color:var(--mut);letter-spacing:.07em;text-transform:uppercase;margin-bottom:.8rem}
.stats--future{grid-template-columns:repeat(3,1fr);text-align:left}
.stats--future .stat b{font-size:clamp(1.5rem,2.6vw,2.3rem)}
.stats--future .stat span{font-size:13px;max-width:34ch;margin-top:.4rem;line-height:1.5}
/* N1-12: no numeral renders without a visible source. The caption says what
   the number means; the cite says who published it and when it was checked,
   because a figure with no date is a figure nobody has to keep true. */
.stat cite{display:block;font-style:normal;font-size:11.5px;line-height:1.45;
  color:var(--dim);margin-top:.5rem;max-width:34ch;letter-spacing:.005em}
.stat span{display:block;font-size:13px;color:var(--mut);margin-top:.45rem}

/* 03 · services grid + line */
.ch-head{margin-bottom:clamp(1.4rem,3.5vh,2.4rem)}
.ch-head .sub{margin-top:.4rem}
.serv-grid{
  position:relative;display:grid;grid-template-columns:repeat(3,1fr);
  gap:14px;
}
.line-svg{position:absolute;inset:-20px;width:calc(100% + 40px);height:calc(100% + 40px);z-index:0;overflow:visible;pointer-events:none}
.line-svg path{fill:none;stroke-linecap:round}
.line-base{stroke:rgba(255,255,255,.06);stroke-width:1}
.line-glow{stroke:rgba(255,255,255,.12);stroke-width:6}
.line-core{stroke:rgba(245,245,247,.9);stroke-width:1.4}
.line-head{position:absolute;left:-20px;top:-20px;z-index:1;pointer-events:none;will-change:transform;opacity:0}
.line-head i{
  display:block;width:6px;height:6px;border-radius:50%;background:#fff;transform:translate(-50%,-50%);
  box-shadow:0 0 8px 2px rgba(255,255,255,.7),0 0 26px 8px rgba(255,255,255,.2);
}
.s-card{
  position:relative;z-index:2;border-radius:var(--r-md);overflow:hidden;
  background:rgba(22,22,23,.72);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  border:1px solid rgba(255,255,255,.07);
  padding:clamp(.95rem,1.8vw,1.4rem);
  transition:border-color .45s,background .45s,transform .45s var(--ease);
}
.s-card::after{
  content:'';position:absolute;inset:0;opacity:0;pointer-events:none;
  transition:opacity .4s var(--ease);
  background:radial-gradient(190px circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,.09), transparent 62%);
}
.s-card:hover::after{opacity:1}
.s-card:hover{transform:translateY(-3px);border-color:rgba(255,255,255,.2)}
.s-card.active{border-color:rgba(255,255,255,.24);background:rgba(30,30,32,.85)}
.s-card em{font-style:normal;font-size:12px;font-weight:600;color:var(--dim);transition:color .4s}
.s-card.active em{color:var(--ink)}
.s-card h3{font-size:clamp(.98rem,1.5vw,1.18rem);font-weight:620;letter-spacing:-.018em;margin:.35rem 0 .3rem;line-height:1.15}
.s-card p{font-size:12.5px;color:var(--mut);line-height:1.45}

/* 04 · solutions journey */
.sol-tiles{
  display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:.4rem;
}
.sol-tile{
  position:relative;overflow:hidden;text-align:left;
  background:var(--panel);border:1px solid rgba(255,255,255,.07);border-radius:var(--r-md);
  padding:1.05rem 1.1rem 1rem;min-height:104px;
  transition:transform .4s var(--ease),border-color .4s,background .4s;
}
.sol-tile:hover{transform:translateY(-3px);border-color:rgba(255,255,255,.22);background:#1a1a1c}
.sol-tile b{
  position:absolute;right:8px;top:-14px;font-size:78px;font-weight:640;line-height:1;
  color:rgba(245,245,247,.05);pointer-events:none;
}
.sol-tile h3{font-size:15.5px;font-weight:620;letter-spacing:-.015em;margin-bottom:.2rem}
.sol-tile p{font-size:13px;color:var(--mut);line-height:1.45}
.sol-tile--other{border-style:dashed}
/* the seventh tile fills the remainder of the last row — no ragged hole */
.sol-tiles .sol-tile:last-child{grid-column:span 2}
.sol-tile::after{
  content:'';position:absolute;inset:0;opacity:0;pointer-events:none;
  transition:opacity .4s var(--ease);
  background:radial-gradient(170px circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,.09), transparent 62%);
}
.sol-tile:hover::after{opacity:1}

.sol-offer{display:none}
/* breadcrumb sits above the title, on the left margin — never beside it */
.offer-head{margin-bottom:1.1rem}
.offer-head .h2{margin-bottom:0}
.offer-head .sub{margin-top:.55rem}
.sol-back{
  display:inline-flex;align-items:center;margin-bottom:.85rem;
  font-size:12.5px;font-weight:500;color:var(--mut);
  border:1px solid rgba(255,255,255,.14);border-radius:980px;padding:.5em 1.05em;
  transition:color .3s,border-color .3s,background .3s,transform .3s var(--ease);
}
.sol-back:hover{transform:translateX(-3px)}
.sol-back:hover{color:var(--ink);border-color:rgba(255,255,255,.35);background:rgba(255,255,255,.06)}
.offer-groups{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;align-items:start}
.offer-group{display:flex;flex-direction:column;gap:8px}
.offer-group h3{
  font-size:12.5px;font-weight:600;color:var(--mut);letter-spacing:.06em;
  text-transform:uppercase;margin-bottom:.15rem;
}
.offer-item{
  position:relative;overflow:hidden;text-align:left;width:100%;
  background:rgba(22,22,23,.72);border:1px solid rgba(255,255,255,.07);border-radius:14px;
  padding:.8rem .95rem;
  transition:transform .35s var(--ease),border-color .35s,background .35s;
}
.offer-item:hover{transform:translateY(-2px);border-color:rgba(255,255,255,.22)}
/* the card is a box holding two real buttons — one to open the piece, one
   to add it to the plan — rather than a button with a button inside it */
.offer-open{
  display:block;width:100%;text-align:left;color:inherit;font:inherit;
  background:none;border:0;cursor:pointer;border-radius:11px;
}
.offer-open:focus-visible{outline:2px solid #f5f5f7;outline-offset:2px}
html[data-theme="light"] .offer-open:focus-visible{outline-color:#1d1d1f}
.offer-item h4{font-size:13.5px;font-weight:620;letter-spacing:-.012em;margin-bottom:.15rem}
.offer-item p{font-size:13px;color:var(--mut);line-height:1.5}
.offer-item::after{
  content:'';position:absolute;inset:0;opacity:0;pointer-events:none;
  transition:opacity .4s var(--ease);
  background:radial-gradient(160px circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,.08), transparent 62%);
}
.offer-item:hover::after{opacity:1}
.offer-cta{display:flex;align-items:center;gap:1.1rem;margin-top:1.2rem;flex-wrap:wrap}
.offer-note{font-size:13px;color:var(--mut);max-width:480px;line-height:1.55}
.offer-note b{color:var(--ink)}

/* build-plan configurator */
.offer-item{padding-right:2.6rem}
.add-btn{
  position:absolute;top:9px;right:9px;z-index:2;
  width:24px;height:24px;border-radius:50%;
  border:1px solid rgba(255,255,255,.28);background:rgba(0,0,0,.25);
  color:var(--mut);font-size:14px;line-height:1;font-weight:500;
  display:flex;align-items:center;justify-content:center;
  transition:all .3s var(--ease);
}
.add-btn:hover{border-color:#f5f5f7;color:#f5f5f7;transform:scale(1.1)}
.add-btn.sel{background:#f5f5f7;color:#000;border-color:#f5f5f7}
.offer-item.sel{border-color:rgba(255,255,255,.34);background:rgba(34,34,36,.9)}

.sol-bar{
  position:absolute;left:50%;bottom:3.4rem;transform:translateX(-50%);z-index:6;
  display:none;align-items:center;gap:.9rem;
  padding:.45rem .5rem .45rem 1.15rem;border-radius:980px;
  background:rgba(22,22,23,.85);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  border:1px solid rgba(255,255,255,.12);
  box-shadow:0 18px 50px rgba(0,0,0,.5);
}
.sol-bar.show{display:flex}
.sol-bar span{font-size:12.5px;color:var(--mut);white-space:nowrap}
.sol-bar .pill{padding:.55em 1.2em;font-size:13px}

.sol-plan{display:none}
.plan-stack{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:1.3rem}
.p-chip{
  display:inline-flex;align-items:baseline;gap:.5em;
  font-size:12px;font-weight:500;color:var(--ink);
  border:1px solid rgba(255,255,255,.14);border-radius:980px;padding:.5em 1.05em;
  background:rgba(255,255,255,.04);
}
.p-chip i{font-style:normal;font-size:12px;color:var(--dim);text-transform:uppercase;letter-spacing:.04em}
.p-chip--note{border-style:dashed;color:var(--mut)}
.plan-phases{
  position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:14px;
  padding-top:20px;margin-bottom:1.4rem;
}
.plan-line{
  position:absolute;left:8px;right:8px;top:9px;height:1px;
  background:linear-gradient(90deg,rgba(245,245,247,.65),rgba(245,245,247,.12));
  transform:scaleX(0);transform-origin:left;
}
.phase{position:relative}
.phase::before{
  content:'';position:absolute;top:-15px;left:0;width:7px;height:7px;border-radius:50%;
  background:#f5f5f7;box-shadow:0 0 10px 2px rgba(255,255,255,.35);
}
.phase em{font-style:normal;font-size:12px;font-weight:600;color:var(--dim)}
.phase h3{font-size:14px;font-weight:640;letter-spacing:-.012em;margin:.15rem 0 .25rem}
.phase p{font-size:13px;color:var(--mut);line-height:1.5}
.phase span{display:block;font-size:12px;color:var(--dim);margin-top:.3rem}
.plan-report{border-top:1px solid var(--line);padding-top:1rem;margin-bottom:.4rem}
.plan-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.p-stat{
  background:var(--panel);border:1px solid rgba(255,255,255,.06);border-radius:14px;
  padding:.85rem 1rem;
}
.p-stat b{display:block;font-size:clamp(1.4rem,2.4vw,2rem);font-weight:640;letter-spacing:-.02em;line-height:1.05}
.p-stat span{font-size:12px;color:var(--mut)}

/* 07 · contact */
.statement--xl{font-size:clamp(2.5rem,6.6vw,5.7rem);line-height:1.03}
.contact-rows{
  display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;
  border-top:1px solid var(--line);padding-top:1.6rem;text-align:left;
  max-width:860px;margin:2rem auto 0;width:100%;
}
.c-row h3{font-size:12.5px;font-weight:600;color:var(--dim);margin-bottom:.35em;letter-spacing:.02em}
.c-row a,.c-row p{font-size:14.5px;font-weight:500}
.c-row a{display:inline-flex;align-items:center;min-height:28px}
.c-row a:hover{text-decoration:underline}
.copy-chip{
  font-size:12px;font-weight:600;color:var(--mut);margin-left:.5rem;
  border:1px solid rgba(255,255,255,.18);border-radius:980px;padding:.3em .85em;
  transition:color .3s,border-color .3s,background .3s;vertical-align:1px;
}
.copy-chip:hover{color:var(--ink);border-color:rgba(255,255,255,.4)}
.copy-chip.done{background:#f5f5f7;color:#000;border-color:#f5f5f7}
.foot-line{
  display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap;
  border-top:1px solid var(--line);margin-top:2rem;padding-top:1.1rem;
  font-size:12.5px;color:var(--dim);width:100%;max-width:860px;margin-left:auto;margin-right:auto;
}
.foot-quote{
  font-family:'GreatVibes','Snell Roundhand',cursive;
  font-size:1.35rem;letter-spacing:0;color:#a1a1a6;
}

/* ── gallery ───────────────────────────────────────────── */
.gallery{position:fixed;inset:0;z-index:950;background:#000;opacity:0;visibility:hidden}
#sphere-canvas{position:absolute;inset:0;width:100%;height:100%;touch-action:none;cursor:grab}
#sphere-canvas.dragging{cursor:grabbing}
.gal-vignette{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(circle at 50% 50%, transparent 52%, rgba(0,0,0,.6) 100%);
}
.gal-head{
  position:absolute;top:0;left:0;right:0;z-index:3;
  display:flex;justify-content:space-between;align-items:center;
  padding:.9rem var(--pad);
}
.gal-brand{font-size:13px;color:var(--mut);font-weight:500}
.gal-close{
  width:34px;height:34px;border-radius:50%;font-size:14px;color:var(--ink);
  background:rgba(255,255,255,.1);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  display:flex;align-items:center;justify-content:center;transition:background .3s,transform .3s;
}
.gal-close:hover{background:rgba(255,255,255,.2);transform:scale(1.06)}
.gal-filters{
  position:absolute;top:3.9rem;left:50%;transform:translateX(-50%);z-index:3;
  display:flex;gap:6px;padding:5px;border-radius:980px;
  /* N1-18 · axe-core flagged the unselected filter labels at serious
     contrast over a translucent bar sitting on a moving canvas. The bar is
     now opaque enough to compute against and the label is brighter: 13:1
     rather than the 3-point-something it was managing against whatever
     happened to be behind it that frame. */
  background:rgba(12,12,13,.94);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  border:1px solid rgba(255,255,255,.12);
}
.gal-filters button{
  font-size:12.5px;font-weight:500;color:#d8d8de;border-radius:980px;
  padding:.5em 1.15em;transition:color .3s,background .3s,transform .2s var(--ease);
}
.gal-filters button:active{transform:scale(.9)}
.gal-filters button:hover{color:var(--ink)}
.gal-filters button.on{background:#f5f5f7;color:#000}
.gal-hint{
  position:absolute;bottom:1.5rem;left:50%;transform:translateX(-50%);z-index:3;
  font-size:12.5px;color:var(--mut);white-space:nowrap;
}
.hint-short{display:none}
.gal-meta{
  position:absolute;left:var(--pad);bottom:1.3rem;z-index:3;
  display:flex;flex-direction:column;gap:.15em;pointer-events:none;opacity:0;
}
.gal-meta b{font-size:12.5px;font-weight:600;color:var(--mut);letter-spacing:.02em}
.gal-meta span{font-size:17px;font-weight:600;letter-spacing:-.015em;min-height:1.3em}

/* ── card detail page ──────────────────────────────────── */
.card-page{
  position:fixed;inset:0;z-index:960;background:#000;color:var(--ink);
  transform:translateY(102%);visibility:hidden;overflow-y:auto;overscroll-behavior:contain;
}
.cp-inner{min-height:100%;display:flex;flex-direction:column;max-width:860px;margin:0 auto;padding:0 var(--pad)}
.cp-head{
  display:flex;justify-content:space-between;align-items:center;
  padding:.95rem 0;border-bottom:1px solid rgba(255,255,255,.08);
  position:sticky;top:0;z-index:2;
  background:rgba(0,0,0,.75);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
}
.cp-back{font-size:14px;color:var(--mut);transition:color .3s;
  min-height:32px;min-width:44px;display:inline-flex;align-items:center;padding:0 .4rem}
.cp-back:hover{color:var(--ink)}
.cp-brand{font-size:15px;font-weight:640}
.cp-body{padding:clamp(1.8rem,5vh,2.8rem) 0 4rem}
.cp-visual{
  position:relative;margin:0 0 clamp(1.8rem,4vh,2.6rem);
  border-radius:var(--r-lg);overflow:hidden;
  border:1px solid rgba(255,255,255,.09);
  aspect-ratio:12/5;background:#0e0e10;
}
.cp-visual canvas{width:100%;height:100%;display:block}
.cp-visual::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.06),rgba(0,0,0,.34));
}
.cp-cat{font-size:14px;font-weight:600;color:var(--mut);margin-bottom:1rem}
.cp-title{
  font-size:clamp(2rem,5vw,3.4rem);font-weight:640;letter-spacing:-.025em;line-height:1.06;
  max-width:18ch;
  background:linear-gradient(180deg,#fff 8%,#d6d6db 60%,#98989d 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.cp-rule{height:1px;background:rgba(255,255,255,.08);margin:clamp(1.5rem,4vh,2.2rem) 0}
.cp-text{font-size:clamp(1.02rem,1.4vw,1.2rem);line-height:1.6;max-width:62ch;color:#a1a1a6}
.cp-tags{list-style:none;display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1.4rem}
.cp-tags li{
  font-size:12.5px;font-weight:500;color:var(--mut);
  background:rgba(255,255,255,.07);border-radius:980px;padding:.5em 1.1em;
}
.cp-meta{
  display:grid;grid-template-columns:repeat(3,1fr);gap:1.2rem;
  border-top:1px solid rgba(255,255,255,.08);margin-top:clamp(1.8rem,4vh,2.6rem);padding-top:1.4rem;
}
.cp-meta h3{font-size:12.5px;font-weight:600;color:var(--dim);margin-bottom:.3em}
.cp-meta p{font-size:14px}
.cp-cta{margin-top:clamp(1.8rem,4vh,2.6rem);width:max-content}

/* ── focus ─────────────────────────────────────────────── */
.pill:focus-visible,button:focus-visible,a:focus-visible{
  outline:1.5px solid rgba(245,245,247,.75);outline-offset:3px;border-radius:6px;
}
.pill:focus-visible{border-radius:980px}
.chap-nav button{transition:transform .2s var(--ease)}
.chap-nav button:active{transform:scale(.88)}

/* ── text scrims (legibility over the silk) ────────────── */
.eyebrow,.sub,.hero-sub,.offer-note,.mani-small,.mani-big,
.stat span,.fs-cap,.phase p,.phase span,.phase em,.p-stat span,.p-chip,
.chap-counter,.chap-nav span,.chap-nav i,.scroll-cue,
.s-card p,.s-card em,.sol-tile p,.offer-item p,
.sph-facts span,.offer-group h3,.gal-brand,
.c-row a,.c-row p,.c-row h3,.foot-line{
  text-shadow:0 1px 12px rgba(0,0,0,.85),0 0 32px rgba(0,0,0,.55);
}
.h2,.statement,.hero-title,.phase h3,.s-card h3,.sol-tile h3,.offer-item h4,.grad{text-shadow:none}

/* contact legibility panels */
#ch-contact .contact-rows{
  background:rgba(0,0,0,.42);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border:1px solid rgba(255,255,255,.07);border-radius:16px;
  padding:1.3rem 1.5rem;border-top:1px solid rgba(255,255,255,.07);
}
#ch-contact .foot-line{
  background:rgba(0,0,0,.42);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border:1px solid rgba(255,255,255,.06);border-radius:14px;
  padding:.85rem 1.3rem;border-top:1px solid rgba(255,255,255,.06);
}

/* ── initial states (JS only) ──────────────────────────── */
body.js .chapter [data-anim]{opacity:0}
body.js .chapter.is-active [data-anim]{opacity:1}

/* ── responsive ────────────────────────────────────────── */
@media(max-width:1000px){
  .mani-cols{grid-template-columns:1fr;gap:1rem}
  .contact-rows{grid-template-columns:1fr;gap:.9rem;padding-top:1.2rem}
  .serv-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:760px){
  body{font-size:15px}
  .chapter-inner{padding:66px 1.2rem 92px}
  /* The dots are unchanged — same eight pixels, same place. What changed
     is the target around them: this was the site's primary navigation at
     8x8 on a phone, a third of the 24x24 WCAG 2.2 asks for and a fraction
     of what a thumb can actually hit. The target is a fixed 24px band
     rather than an inset, so the active dot growing to 22px cannot make
     its target swallow its neighbours'. The gap goes 12 → 16 so the bands
     meet exactly and never overlap. */
  .chap-nav{right:10px;gap:16px}
  .chap-nav span,.chap-nav i{display:none}
  .chap-nav button{width:8px;height:8px;border-radius:4px;background:#3a3a3c;padding:0;transition:height .3s var(--ease),background .3s}
  .chap-nav button.on{height:22px;background:#f5f5f7}
  .chap-nav button::after{
    /* a fixed 24px band centred on the dot, not an inset — the active dot
       grows to 22px, and an inset would grow its target with it until it
       swallowed the dots either side. top/height/margin rather than
       top/bottom, so the box is never over-constrained. */
    content:'';position:absolute;
    left:-20px;right:-8px;bottom:auto;
    top:50%;height:24px;margin-top:-12px;transform:none;
  }
  .chap-counter{bottom:1.1rem}
  .serv-grid{grid-template-columns:1fr;gap:10px}
  .line-svg,.line-head{display:none}
  .s-card p{display:none}
  .s-card h3{margin:.2rem 0 0}
  .sol-tiles{grid-template-columns:repeat(2,1fr)}
  .offer-groups{grid-template-columns:1fr}
  /* without the drawn line, restore 01→06 reading order */
  .s-card[data-s="0"]{order:1}.s-card[data-s="1"]{order:2}.s-card[data-s="2"]{order:3}
  .s-card[data-s="3"]{order:4}.s-card[data-s="4"]{order:5}.s-card[data-s="5"]{order:6}
  .plan-phases{grid-template-columns:repeat(2,1fr);row-gap:1.2rem}
  .plan-line{display:none}
  .phase::before{display:none}
  .plan-stats{grid-template-columns:1fr}
  .stats--future{grid-template-columns:1fr;row-gap:.9rem}
  .sol-bar{bottom:4.6rem;width:max-content;max-width:92vw}
      .hero-sub .bp,.sub .bp{display:none}
  .gal-meta{display:none}
  .hint-long{display:none}
  .hint-short{display:inline}
  /* Six families now, not four: at 390px the bar was 450px wide and
     clipped "All" and "Journal" off either edge. It wraps to two rows and
     stays inside the padding; the radius drops so a two-row pill does not
     read as a capsule with a bite out of it. */
  .gal-filters{top:auto;bottom:3.6rem;width:max-content;max-width:calc(100% - 2*var(--pad));flex-wrap:wrap;justify-content:center;
    gap:4px;border-radius:22px}
  .gal-filters button{padding:.45em .85em;font-size:12px}
  .foot-line{justify-content:center;text-align:center}
  .foot-quote{display:none}
}
@media(hover:none){
  }
@media(max-height:700px){
  .hero-title{font-size:clamp(2.2rem,6vw,4rem)}
  .statement{font-size:clamp(1.8rem,4.2vw,3rem)}
  .chapter-inner{padding-top:60px;padding-bottom:92px}
}

/* ── reduced motion ────────────────────────────────────── */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* ═══════════════════════════════════════════════════════════
   LIGHT THEME — the default. White gallery-wall monochrome:
   dark ink on porcelain, particles as graphite dust.
   (Dark theme is the base stylesheet; these override it.)
   ═══════════════════════════════════════════════════════════ */
html[data-theme="light"]{
  --bg:#f5f5f7;--panel:#ffffff;--ink:#1d1d1f;--mut:#4a4a50;--dim:#6c6c72;
  --line:rgba(0,0,0,.10);
}
html[data-theme="light"] ::selection{background:#1d1d1f;color:#fff}
html[data-theme="light"] ::-webkit-scrollbar-thumb{background:#c7c7cc}

/* type */
html[data-theme="light"] .grad,
html[data-theme="light"] .hero-title .grad,
html[data-theme="light"] .sph-facts b{
  background:linear-gradient(180deg,#1d1d1f 8%,#3a3a3c 55%,#7c7c81 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:none;
}
html[data-theme="light"] .eyebrow,html[data-theme="light"] .sub,html[data-theme="light"] .hero-sub,
html[data-theme="light"] .offer-note,
html[data-theme="light"] .mani-small,html[data-theme="light"] .mani-big,html[data-theme="light"] .stat span,
html[data-theme="light"] .fs-cap,html[data-theme="light"] .phase p,html[data-theme="light"] .phase span,
html[data-theme="light"] .phase em,html[data-theme="light"] .p-stat span,html[data-theme="light"] .p-chip,
html[data-theme="light"] .chap-counter,html[data-theme="light"] .chap-nav span,html[data-theme="light"] .chap-nav i,
html[data-theme="light"] .scroll-cue,html[data-theme="light"] .s-card p,html[data-theme="light"] .s-card em,
html[data-theme="light"] .sol-tile p,html[data-theme="light"] .offer-item p,
html[data-theme="light"] .sph-facts span,html[data-theme="light"] .offer-group h3,
html[data-theme="light"] .gal-brand,html[data-theme="light"] .c-row a,html[data-theme="light"] .c-row p,
html[data-theme="light"] .c-row h3,html[data-theme="light"] .foot-line,
html[data-theme="light"] .h2,html[data-theme="light"] .statement,html[data-theme="light"] .hero-title,
html[data-theme="light"] .phase h3,html[data-theme="light"] .s-card h3,html[data-theme="light"] .sol-tile h3,
html[data-theme="light"] .offer-item h4{text-shadow:none}

/* pills */
html[data-theme="light"] .pill--fill{background:#1d1d1f;color:#f5f5f7}
html[data-theme="light"] .pill--fill:hover{background:#000}
html[data-theme="light"] .pill--fill::after{background:linear-gradient(90deg,transparent,rgba(255,255,255,.16),transparent)}
html[data-theme="light"] .pill--ghost{
  border:1px solid rgba(0,0,0,.26);color:var(--ink);
  background:rgba(255,255,255,.55);
}
html[data-theme="light"] .pill--ghost:hover{border-color:rgba(0,0,0,.5);background:rgba(255,255,255,.9)}
html[data-theme="light"] .pill--mini{border:1px solid rgba(0,0,0,.24)}
html[data-theme="light"] .pill--mini:hover{border-color:rgba(0,0,0,.45);background:rgba(0,0,0,.05)}
html[data-theme="light"] .pill::after{background:linear-gradient(90deg,transparent,rgba(0,0,0,.06),transparent)}

/* stage furniture */
html[data-theme="light"] .stage-glow{display:none}
html[data-theme="light"] .stage-scrim{
  background:
    radial-gradient(46% 33% at 50% 45%,
      rgba(245,245,247,.52) 0%, rgba(245,245,247,.34) 52%,
      rgba(245,245,247,.16) 82%, rgba(245,245,247,0) 100%),
    linear-gradient(180deg,
      rgba(245,245,247,.9) 0%, rgba(245,245,247,.4) 16%,
      rgba(245,245,247,.14) 38%, rgba(245,245,247,.2) 58%,
      rgba(245,245,247,.5) 82%, rgba(245,245,247,.9) 100%),
    radial-gradient(128% 82% at 50% 48%, rgba(245,245,247,0) 38%, rgba(245,245,247,.6) 100%);
}
html[data-theme="light"] #turn-edge{
  background:linear-gradient(90deg,transparent,rgba(0,0,0,.05) 42%,rgba(0,0,0,.14) 50%,rgba(0,0,0,.05) 58%,transparent);
}
@media(max-width:760px){
  html[data-theme="light"] .chap-counter::before{
    background:linear-gradient(180deg,transparent,rgba(245,245,247,.72) 46%,#f5f5f7 90%);
  }
}

/* intro */
html[data-theme="light"] .intro{background:var(--bg)}

/* cards, tiles, rows */
html[data-theme="light"] .s-card,html[data-theme="light"] .sol-tile{
  background:var(--panel);border:1px solid rgba(0,0,0,.09);
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 8px 26px rgba(0,0,0,.05);
}
html[data-theme="light"] .s-card:hover,html[data-theme="light"] .sol-tile:hover{
  background:#fff;border-color:rgba(0,0,0,.18);
}
html[data-theme="light"] .s-card::after,html[data-theme="light"] .sol-tile::after{
  background:radial-gradient(170px circle at var(--mx,50%) var(--my,50%), rgba(0,0,0,.05), transparent 62%);
}
html[data-theme="light"] .sol-tile b{color:rgba(29,29,31,.06)}
html[data-theme="light"] .line-base{stroke:rgba(0,0,0,.07)}
html[data-theme="light"] .line-glow{stroke:rgba(0,0,0,.10)}
html[data-theme="light"] .line-core{stroke:rgba(29,29,31,.85)}
html[data-theme="light"] .add-btn{border-color:rgba(0,0,0,.3);color:var(--mut)}
html[data-theme="light"] .add-btn:hover{border-color:#1d1d1f;color:#1d1d1f}
html[data-theme="light"] .add-btn.sel{background:#1d1d1f;color:#fff;border-color:#1d1d1f}
html[data-theme="light"] .copy-chip:hover{color:var(--ink);border-color:rgba(0,0,0,.4)}
html[data-theme="light"] .copy-chip.done{background:#1d1d1f;color:#fff;border-color:#1d1d1f}
html[data-theme="light"] .sph-facts div + div{border-left:1px solid rgba(0,0,0,.14)}

/* frosted panels */
html[data-theme="light"] #ch-contact .contact-rows,html[data-theme="light"] #ch-contact .foot-line,
html[data-theme="light"] .sol-bar{
  background:rgba(255,255,255,.6);border-color:rgba(0,0,0,.08);
}

/* gallery + card pages */
html[data-theme="light"] .gallery{background:#f5f5f7}
html[data-theme="light"] .gal-vignette{
  background:radial-gradient(120% 90% at 50% 50%, transparent 55%, rgba(245,245,247,.85) 100%);
}
html[data-theme="light"] .card-page{background:#fbfbfd;color:var(--ink)}
html[data-theme="light"] .cp-head{background:rgba(251,251,253,.8);border-bottom:1px solid rgba(0,0,0,.08)}
html[data-theme="light"] .cp-title{
  background:linear-gradient(180deg,#1d1d1f 8%,#3a3a3c 60%,#6e6e73 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
html[data-theme="light"] .cp-visual{border:1px solid rgba(0,0,0,.08);background:#fff}
html[data-theme="light"] .cp-visual::after{background:linear-gradient(180deg,rgba(255,255,255,.04),rgba(0,0,0,.05))}

/* theme toggle */
.head-actions{display:flex;align-items:center;gap:.6rem}
/* Three destinations plus the toggle fits from 700px up. Below that the
   Field notes pill folds away: the footer carries it, and so does every
   journal card in the Sphere, so nothing becomes unreachable. */
@media(max-width:700px){.head-actions{gap:.45rem}#head-notes{display:none}}
@media(max-width:430px){#head-vertical{display:none}}
.theme-toggle{
  width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid rgba(255,255,255,.28);color:var(--ink);transition:border-color .3s,background .3s,transform .3s var(--ease);
}
.theme-toggle:hover{transform:scale(1.08);background:rgba(255,255,255,.08)}
.theme-toggle .tt-sun{display:none}
.theme-toggle .tt-moon{display:block}
html[data-theme="light"] .theme-toggle{border-color:rgba(0,0,0,.26)}
html[data-theme="light"] .theme-toggle:hover{background:rgba(0,0,0,.05)}
html[data-theme="light"] .theme-toggle .tt-sun{display:none}
html[data-theme="light"] .theme-toggle .tt-moon{display:block}
html:not([data-theme="light"]) .theme-toggle .tt-sun{display:block}
html:not([data-theme="light"]) .theme-toggle .tt-moon{display:none}

/* hero headline words — split at runtime for the arrival */
.hero-title .hw{display:inline-block;will-change:transform,opacity,filter}

/* failsafe: if the visual field can't start, the site still reads normally */
html.nx-fallback .chapter [data-anim],
html.nx-fallback .hero-title .hw{opacity:1 !important;transform:none !important;filter:none !important}
html.nx-fallback .site-head,
html.nx-fallback .chap-nav,
html.nx-fallback .chap-counter{opacity:1 !important}
html.nx-fallback #ch-overview{visibility:visible !important;opacity:1 !important}
html.nx-nogl #stage-canvas{display:none}

/* Last-resort backstop: with JavaScript completely dead the intro overlay
   lifts on its own, so the site is never a blank rectangle. It is armed
   only when nothing else can do the job — the head script sets .js-alive
   before this stylesheet has finished parsing, and the failsafe there both
   lifts the overlay AND reveals the copy underneath, which a CSS animation
   cannot. Left permanently armed it hid a *running* opening at thirteen
   seconds on a slow machine, leaving a genuinely blank page behind it
   until the JS failsafe caught up ten seconds later. */
html:not(.js-alive) .intro{animation:nxIntroBackstop 0s linear 13s forwards}
@keyframes nxIntroBackstop{to{opacity:0;visibility:hidden;pointer-events:none}}


/* the glass field on Contact: the cursor should say the blocks can be
   picked up, and a drag must never turn into a text selection */
.nx-grabbing, .nx-grabbing * { cursor: grabbing !important; user-select: none; }

/* Contact trades the city for the blocks, and the blocks are the point —
   the copy there sits on its own plates, so the stage scrim can drop */
.nx-contact .stage-scrim { opacity: .62; transition: opacity .7s ease; }
.nx-contact .stage-glow { opacity: 0; }
.stage-scrim { transition: opacity .7s ease; }

/* the mailto fallback: shown only when the platform swallowed the click */
.mail-toast{
  position:fixed;left:50%;bottom:26px;transform:translate(-50%,14px);z-index:120;
  max-width:min(92vw,460px);padding:14px 16px 13px;border-radius:16px;
  background:rgba(18,18,20,.92);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
  border:1px solid rgba(255,255,255,.14);box-shadow:0 18px 48px rgba(0,0,0,.5);
  opacity:0;pointer-events:none;transition:opacity .3s ease, transform .3s cubic-bezier(.2,.8,.2,1);
}
.mail-toast.show{opacity:1;transform:translate(-50%,0);pointer-events:auto}
.mail-toast p{margin:0 0 10px;font-size:13.5px;line-height:1.45;color:#f5f5f7}
.mail-toast p b{font-weight:600}
.mail-toast .mt-row{display:flex;gap:8px;flex-wrap:wrap}
.mail-toast button,.mail-toast a{
  font:inherit;font-size:12.5px;line-height:1;padding:9px 13px;border-radius:999px;cursor:pointer;
  border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.08);color:#f5f5f7;text-decoration:none;
}
.mail-toast .mt-copy{background:#f5f5f7;color:#0a0a0c;border-color:#f5f5f7;font-weight:500}
.mail-toast .mt-copy.done{background:#9fe6b8;border-color:#9fe6b8}
.mail-toast button:hover,.mail-toast a:hover{background:rgba(255,255,255,.16)}
.mail-toast .mt-copy:hover{background:#fff}
[data-theme=light] .mail-toast{background:rgba(255,255,255,.94);border-color:rgba(0,0,0,.12);box-shadow:0 18px 48px rgba(0,0,0,.16)}
[data-theme=light] .mail-toast p{color:#141416}
[data-theme=light] .mail-toast button,[data-theme=light] .mail-toast a{background:rgba(0,0,0,.05);border-color:rgba(0,0,0,.14);color:#141416}
[data-theme=light] .mail-toast .mt-copy{background:#141416;color:#fafafa;border-color:#141416}

/* ── the light theme's plate ──────────────────────────────────────────
   The dark scrim pools black behind the copy, which is right over a
   night city and catastrophic over paper — it reads as smog on the
   page. On porcelain the same job is done with porcelain: the copy
   sits in a pool of clean paper and the drawing breathes at the edges. */
[data-theme=light] .stage-scrim{
  background:
    radial-gradient(46% 33% at 50% 45%,
      rgba(245,245,247,.94) 0%, rgba(245,245,247,.78) 52%, rgba(245,245,247,.34) 82%, rgba(245,245,247,0) 100%),
    linear-gradient(180deg,
      rgba(245,245,247,.90) 0%, rgba(245,245,247,.38) 16%,
      rgba(245,245,247,.14) 38%, rgba(245,245,247,.20) 58%,
      rgba(245,245,247,.44) 82%, rgba(245,245,247,.88) 100%),
    radial-gradient(128% 82% at 50% 48%, rgba(245,245,247,0) 44%, rgba(233,233,238,.55) 100%);
}
[data-theme=light] .stage-glow{
  background:radial-gradient(ellipse at center, rgba(0,0,0,.030), transparent 62%);
}
[data-theme=light] .nx-contact .stage-scrim{opacity:.55}

/* ── the enquiry form ─────────────────────────────────────────────────
   One field for who you are, one for what you need. It matches the
   contact card's glass, and the send button is the page's one filled
   pill now that the big CTAs have gone. */
.enquiry{
  width:min(92vw,600px);margin:clamp(18px,3vh,30px) auto 0;text-align:left;
  background:rgba(22,22,24,.55);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  border:1px solid rgba(255,255,255,.12);border-radius:20px;padding:16px 16px 14px;
}
.enquiry input,.enquiry textarea{
  display:block;width:100%;font:inherit;font-size:14.5px;color:#f5f5f7;
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);
  border-radius:12px;padding:11px 13px;outline:none;resize:vertical;min-height:0;
  transition:border-color .2s ease, background .2s ease;
}
.enquiry input{margin-bottom:9px}
.enquiry textarea{min-height:96px;max-height:38vh}
.enquiry input::placeholder,.enquiry textarea::placeholder{color:rgba(245,245,247,.38)}
.enquiry input:focus,.enquiry textarea:focus{border-color:rgba(255,255,255,.34);background:rgba(255,255,255,.09)}
.enquiry .enq-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:11px}
.enquiry .enq-note{font-size:12px;color:rgba(245,245,247,.42)}
.enquiry .enq-note.err{color:#ffb4a8}
.enquiry .enq-note.ok{color:#9fe6b8}
#enq-send{padding:11px 22px;font-size:14.5px}
@media (max-width:560px){
  .enquiry{padding:12px 12px 11px}
  .enquiry .enq-foot{flex-direction:column;align-items:stretch;text-align:center}
}
/* light mode is parked: the toggle goes with it */
.theme-toggle{display:none!important}

/* ═══════════════════════════════════════════════════════════════════════
   READABILITY PASS
   Type over a moving night city has to work harder than type on a page.
   Three things were against it: body copy sat at 12–12.5px, the muted
   greys were tuned against pure black rather than against the lit band
   the city actually puts behind them, and the cards were transparent
   enough for building lights to come through the paragraphs.

   So: nothing below 14px, the greys lifted, the card plates made opaque
   enough to be plates, and a hairline of shadow under free-floating
   copy. Sizes use clamp() so this scales rather than just inflating.
   ═══════════════════════════════════════════════════════════════════ */
:root{
  --mut:#d6d6dc;          /* was #c6c6cc — 12.5:1 on the card plate */
  --dim:#a6a6ae;          /* was #8a8a90 — 8.4:1, still clearly secondary */
}

/* ── body copy: nothing under 14px anywhere ─────────────────────────── */
.s-card p{font-size:clamp(14px,1.02vw,15.5px);line-height:1.55;color:var(--mut)}
.s-card h3{font-size:clamp(1.06rem,1.6vw,1.3rem);line-height:1.2}
.offer-note,.enq-note{font-size:13.5px;line-height:1.5}
.c-row h3{font-size:13px;letter-spacing:.06em;text-transform:uppercase}
.c-row a,.c-row p{font-size:clamp(15px,1.1vw,16.5px);line-height:1.5}
.foot-line{font-size:13.5px;line-height:1.6}
.eyebrow{font-size:clamp(12px,0.9vw,13.5px);letter-spacing:.18em}
.sub,.hero-sub{font-size:clamp(1.06rem,1.45vw,1.28rem);line-height:1.55}
.mani-small{font-size:clamp(14.5px,1.1vw,16px);line-height:1.6}
.stat span{font-size:13.5px;line-height:1.45}
.offer-item h4{font-size:clamp(15px,1.15vw,16.5px);line-height:1.3}
.offer-item p{font-size:clamp(13.5px,1vw,15px);line-height:1.55;color:var(--mut)}
.offer-group h3{font-size:12.5px;letter-spacing:.14em}
.p-chip,.phase p,.plan-report{font-size:13.5px;line-height:1.55}
.cp-body p,.cp-body li{font-size:clamp(14.5px,1.05vw,16px);line-height:1.65}

/* ── the plates: a card has to be a plate, not a window ─────────────── */
.s-card,.offer-item,.contact-rows,.foot-line,.enquiry,.plan-report{
  background:rgba(16,16,19,.80);
  -webkit-backdrop-filter:blur(20px) saturate(1.2);backdrop-filter:blur(20px) saturate(1.2);
  border-color:rgba(255,255,255,.15);
}
.s-card:hover,.offer-item:hover{background:rgba(22,22,26,.88)}

/* ── copy that floats free of a plate gets its own contrast ─────────── */
.eyebrow,.sub,.hero-sub,.statement,.h2,h1,h2{
  text-shadow:0 1px 12px rgba(0,0,0,.55);
}

/* ── controls: bigger targets, clearer focus ────────────────────────── */
.pill{font-size:15px;padding:13px 26px}
.pill--mini{font-size:14px;padding:10px 18px}
.copy-chip{font-size:13px;padding:6px 12px}
.chap-nav button{font-size:13px}
.chap-nav button span{font-size:13.5px}
a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible{
  outline:2px solid rgba(255,255,255,.75);outline-offset:3px;border-radius:8px;
}

/* ── phones: the cards carry the page, so give them room ────────────── */
@media (max-width:760px){
  .s-card p,.offer-item p{font-size:14.5px;line-height:1.6}
  .s-card h3{font-size:1.12rem}
  .c-row a,.c-row p{font-size:16px}
  .foot-line{font-size:13.5px}
}

/* the last two under-size labels: the chapter rail numerals and the
   scroll cue. Small by design, but not smaller than legible. */
.chap-nav button i{font-size:13.5px}
.scroll-cue span{font-size:13px;letter-spacing:.16em}

/* The manifesto lost its quotation marks and its two section captions,
   so the figures now sit directly under the copy — they need the air
   the captions used to provide. The self-scored skill bars that used to
   sit between the two are gone (N0-10), so only the sourced figures are
   left and only they need the spacing. */
.future-stats{margin-top:clamp(1.2rem,2.6vh,2rem)}

/* ── the rule beside a section label goes ─────────────────────────────
   "— 02 · Manifesto" read as an em dash bolted to the number. The
   label stands perfectly well on its own. */
.chapter-inner:not(.center) .eyebrow{padding-left:0}
.chapter-inner:not(.center) .eyebrow::before,
.chapter-inner.center .eyebrow::before{content:none}
.chapter-inner.center .eyebrow{padding-top:0}

/* Contact carries the most furniture of any chapter — heading, form,
   details card, footer — and on a laptop that is a couple of dozen pixels
   taller than the frame. Rather than hand the visitor a scrollbar for the
   sake of 24px, the rhythm tightens on short screens. */
@media (max-height:920px){
  #ch-contact .chapter-inner{padding-top:40px;padding-bottom:32px}
  #ch-contact .h2{margin-bottom:1.1rem}
}
@media (max-height:800px){
  #ch-contact .chapter-inner{padding-top:32px;padding-bottom:26px}
  #ch-contact .enquiry{margin-top:14px;padding:13px 14px 12px}
  #ch-contact .enquiry textarea{min-height:76px}
  #ch-contact .h2{margin-bottom:.8rem}
}


/* ── N1-16 · the qualifying form ────────────────────────────────────────
   Four answers instead of a blank box. A blank box asks the visitor to do
   the qualifying, and they write "we want to explore AI", which starts the
   conversation four emails behind where it should be. */
.enquiry--q{max-width:44rem;margin-inline:auto;text-align:left}
.enq-grid{display:grid;gap:.9rem}
@media(min-width:640px){.enq-grid{grid-template-columns:1fr 1fr;gap:.9rem 1.1rem}
  .enq-f--wide{grid-column:1 / -1}}
.enq-f label{display:block;font-size:13px;font-weight:620;letter-spacing:-.01em;
  margin-bottom:.35rem;opacity:.9}
.enq-f label .opt{font-weight:400;opacity:.55;font-size:12px}
.enq-f input,.enq-f select,.enq-f textarea{
  width:100%;min-height:44px;padding:.6rem .8rem;font:inherit;font-size:15px;
  color:inherit;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.16);
  border-radius:11px;appearance:none}
.enq-f textarea{min-height:76px;resize:vertical}
.enq-f select{background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 18px) 50%,calc(100% - 13px) 50%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:2.2rem}
.enq-f input:focus,.enq-f select:focus,.enq-f textarea:focus{
  outline:none;border-color:currentColor;background:rgba(255,255,255,.07)}
html[data-theme="light"] .enq-f input,html[data-theme="light"] .enq-f select,
html[data-theme="light"] .enq-f textarea{background:rgba(0,0,0,.03);border-color:rgba(0,0,0,.18)}

/* the crawlable page behind each chapter — the chapter is the teaser, the
   static page is the depth an answer engine can actually read */
.chapter-out{margin-top:1.6rem;text-align:center}
.chapter-out a{text-decoration:none}

/* Skip link. The generated pages carry this in notes.css; the homepage loads
   only this file, so the rule has to exist here too — a skip link with no
   stylesheet is a visible link at the top of the page, which is a worse
   outcome than not having one. Off-screen until focused, then the first thing
   a keyboard reaches. */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:#f5f5f7;color:#000;
  padding:.6rem 1rem;border-radius:0 0 8px 0;font-size:14px;font-weight:600;
  text-decoration:none}
.skip:focus{left:0}

/* Target size on the homepage's own contact and footer links, which the
   generated pages' stylesheet does not reach: 19-22px tall measured, 24px is
   the floor. Padding only, so the type does not move. */
.c-row a,.foot-links a{display:inline-block;padding-block:.25rem;min-height:24px;line-height:1.3}

/* 42x17 measured - a control, so the 24px floor applies. Padding, not type. */
.cp-back{min-height:24px;padding-block:.3rem}
