:root {
    /* Brand guide: deep purple #2B1A4A, violet #3D2766,
       lavender #8B6FE0, gold #C79A2E. Everything else below is a
       tint or shade derived from those four. */
    --ground: #2B1A4A;   /* brand deep purple — the page field */
    --band: #3D2766;     /* brand violet — lifted section bands */
    --deep: #1A0F2E;     /* darkest tier — hero fields, footer, deep bands */
    --header: #120A21;   /* one shade below --deep, so the top bar always
                            separates from the section beneath it */
    --ice: #EFEAF9;
    --ice-2: #E1D9F2;
    --slate: #6B4FB8;
    --accent: #8B6FE0;        /* brand lavender */
    --accent-bright: #A78FEC; /* lavender, lightened for type on --band */
    --text: #F3EFFB;
    --muted: #C5B8E4;
    --muted-2: #9C8AC4;
    --ink: #2B1A4A;
    --ink-soft: #54407A;
    --gold: #C79A2E;     /* brand gold */
    --gold-bright: #E0B54F;
    --gold-deep: #9B7520;
    --rule: rgba(243,239,251,0.15);
    --rule-strong: rgba(243,239,251,0.32);
    --rule-ink: rgba(43,26,74,0.16);
    --rule-ink-strong: rgba(43,26,74,0.32);
    --serif: "Newsreader", Georgia, "Times New Roman", serif;
    --sans: "Calibri", "Carlito", "Segoe UI", system-ui, sans-serif;
    --ease: cubic-bezier(0.16, 1, 0.3, 1);
  }
  html { scroll-behavior: smooth; }
  body { margin: 0; background: var(--ground); color: var(--text); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
  h1, h2, h3 { margin: 0; font-family: var(--serif); font-weight: 400; letter-spacing: -0.015em; }
  h1, h2 { text-wrap: balance; }
  p { margin: 0; text-wrap: pretty; }
  a { color: var(--gold); text-decoration: none; }
  a:hover { color: var(--gold-bright); }
  em { font-style: italic; }
  ul { margin: 0; }
  img { max-width: 100%; }
  ::selection { background: rgba(199,154,46,0.3); }
  ::-webkit-scrollbar { width: 10px; }
  ::-webkit-scrollbar-track { background: var(--deep); }
  ::-webkit-scrollbar-thumb { background: rgba(243,239,251,0.2); }
  ::-webkit-scrollbar-thumb:hover { background: rgba(199,154,46,0.5); }
  html.reveal-on [data-reveal] { opacity: 0; transform: translateY(26px); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); will-change: opacity, transform; }
  html.reveal-on [data-reveal].in { opacity: 1; transform: none; }
  @media (prefers-reduced-motion: reduce) { html.reveal-on [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; } }

.photo-slot { background: linear-gradient(150deg, #3D2766 0%, #1A0F2E 100%); box-shadow: inset 0 0 0 1px rgba(243,239,251,0.08); }
nav a[data-current] { color: var(--gold) !important; }

/* ============================================================
   Keyboard focus
   ============================================================ */
a:focus-visible, button:focus-visible, iframe:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 4px;
  border-radius: 3px;
}

/* ============================================================
   Film grain — a single fixed layer that gives the flat purple
   some tooth. Never intercepts pointer events.
   ============================================================ */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: 0.042;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================
   Scroll progress — hairline of gold across the very top
   ============================================================ */
#scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 0;
  z-index: 60;
  pointer-events: none;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold-bright));
  box-shadow: 0 0 14px rgba(199,154,46,0.55);
}

header { transition: box-shadow 0.4s var(--ease); }
header.is-scrolled { box-shadow: 0 14px 38px rgba(0,0,0,0.45); }

/* ============================================================
   Figures — the photo treatment that makes stock photography
   read as part of the brand rather than dropped on top of it.
   Grayscale base, violet-into-shadow / gold-into-highlight wash,
   gold rim, bottom vignette so overlaid type stays legible.
   ============================================================ */
.fig {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--deep);
}
.fig img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.48) contrast(1.07) saturate(0.72) brightness(0.86);
  transform: scale(var(--figscale, 1.02));
  transition: transform 1.4s var(--ease), filter 1.4s var(--ease);
}
.fig::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(155deg, rgba(61,39,102,0.60) 0%, rgba(26,15,46,0.26) 52%, rgba(199,154,46,0.30) 100%);
  mix-blend-mode: overlay;
}
.fig::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  box-shadow:
    inset 0 0 0 1px rgba(199,154,46,0.24),
    inset 0 -90px 110px -50px rgba(26,15,46,0.92);
}
a:hover .fig img, .fig:hover img { --figscale: 1.065; filter: grayscale(0.12) contrast(1.04) saturate(0.95) brightness(0.96); }

/* whole-image variant: nothing is cropped, so wide artwork with type in it
   stays readable. Sits on the deep field with the gold rim kept. */
.fig-whole { background: var(--deep); }
.fig-whole img { object-fit: contain; filter: grayscale(0.10) contrast(1.02) saturate(0.95) brightness(0.96); }
.fig-whole::after { opacity: 0.45; }
.fig-whole::before { box-shadow: inset 0 0 0 1px rgba(199,154,46,0.24); }
a:hover .fig-whole img, .fig-whole:hover img { --figscale: 1.03; filter: grayscale(0) contrast(1) saturate(1) brightness(1); }

/* parallax carrier: extra bleed top and bottom so the image can
   drift without exposing an edge */
.fig-par {
  position: absolute;
  inset: -7% 0;
  display: block;
  will-change: transform;
}

/* caption block pinned to the bottom of a figure */
.fig-cap { position: absolute; left: 0; right: 0; bottom: 0; z-index: 4; padding: clamp(18px, 2.4vw, 28px); pointer-events: none; }
.fig-rule {
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--gold), var(--gold-bright));
  margin-top: 10px;
  transform: scaleX(0.16);
  transform-origin: left center;
  transition: transform 1.3s var(--ease) 0.35s;
}
[data-reveal].in .fig-rule { transform: scaleX(1); }

/* ============================================================
   Image bands — full-bleed photography behind a section, scrimmed
   hard enough that body copy keeps its contrast.
   ============================================================ */
.band { position: relative; isolation: isolate; overflow: hidden; }
.band > .band-media { position: absolute; inset: 0; z-index: 0; }
.band > .band-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.62) contrast(1.06) saturate(0.5) brightness(0.46);
}
.band > .band-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(26,15,46,0.82) 0%, rgba(43,26,74,0.74) 45%, rgba(26,15,46,0.90) 100%);
}
.band > .band-media::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(130% 95% at 12% 0%, rgba(199,154,46,0.15), rgba(199,154,46,0) 62%);
}
.band > :not(.band-media) { position: relative; z-index: 1; }

/* ============================================================
   Ambient glow — soft coloured light behind key sections so the
   flat fields read as lit space instead of paint.
   ============================================================ */
.glow { position: relative; overflow: clip; }
.glow > * { position: relative; z-index: 1; }
.glow::before, .glow::after {
  content: '';
  position: absolute;
  z-index: 0;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(40px);
}
.glow::before {
  width: 62vw; height: 62vw; max-width: 820px; max-height: 820px;
  top: -24vw; right: -12vw;
  background: radial-gradient(closest-side, rgba(139,111,224,0.20), rgba(139,111,224,0) 70%);
}
.glow::after {
  width: 48vw; height: 48vw; max-width: 620px; max-height: 620px;
  bottom: -22vw; left: -14vw;
  background: radial-gradient(closest-side, rgba(199,154,46,0.16), rgba(199,154,46,0) 70%);
}

/* ============================================================
   Staggered reveal for grids — children cascade in
   ============================================================ */
html.reveal-on [data-stagger] > * {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.75s var(--ease), transform 0.75s var(--ease);
}
html.reveal-on [data-stagger].in > * { opacity: 1; transform: none; }
html.reveal-on [data-stagger].in > *:nth-child(1) { transition-delay: 0s; }
html.reveal-on [data-stagger].in > *:nth-child(2) { transition-delay: 0.08s; }
html.reveal-on [data-stagger].in > *:nth-child(3) { transition-delay: 0.16s; }
html.reveal-on [data-stagger].in > *:nth-child(4) { transition-delay: 0.24s; }
html.reveal-on [data-stagger].in > *:nth-child(5) { transition-delay: 0.32s; }
html.reveal-on [data-stagger].in > *:nth-child(6) { transition-delay: 0.40s; }

/* ============================================================
   Service / list rows — gold wipe and nudge on hover
   ============================================================ */
.row-link { position: relative; }
.row-link > * { position: relative; z-index: 1; }
.row-link::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  z-index: 0;
  background: linear-gradient(90deg, rgba(199,154,46,0.15), rgba(199,154,46,0) 72%);
  transition: width 0.6s var(--ease);
}
.row-link::after {
  content: '';
  position: absolute;
  left: 0; bottom: -1px;
  height: 1px;
  width: 0;
  z-index: 1;
  background: var(--gold);
  transition: width 0.6s var(--ease);
}
.row-link:hover::before, .row-link:focus-visible::before,
.row-link:hover::after, .row-link:focus-visible::after { width: 100%; }
.row-num, .row-arrow { transition: transform 0.55s var(--ease); display: inline-block; }
.row-link:hover .row-num { transform: translateX(7px); }
.row-link:hover .row-arrow { transform: translateX(9px); }

/* ============================================================
   Cards that lift, stat numbers with an inked gradient
   ============================================================ */
.lift { transition: transform 0.55s var(--ease); }
a:hover .lift, .lift:hover { transform: translateY(-5px); }

.stat { position: relative; }
.stat-num {
  font-family: var(--serif);
  line-height: 1.04;
  padding-top: 0.14em;
  margin-top: -0.14em;
  background: linear-gradient(140deg, var(--ink) 18%, var(--slate) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* portrait frames on the network page */
.portrait { position: relative; overflow: hidden; isolation: isolate; background: var(--deep); }
.portrait img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  filter: contrast(1.04) saturate(0.92) brightness(0.97);
  transform: scale(1.01);
  transition: transform 1.4s var(--ease), filter 1.4s var(--ease);
}
.portrait:hover img { transform: scale(1.05); filter: contrast(1.02) saturate(1) brightness(1); }
.portrait::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(200deg, rgba(61,39,102,0.30) 0%, rgba(26,15,46,0) 46%, rgba(26,15,46,0.55) 100%);
}
.portrait::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(199,154,46,0.3);
}

/* ============================================================
   The Book — hero. Sized so the cover, the title and the call to
   action all land together on arrival instead of the cover being
   cut in half by the fold.

   The cover frame carries its own width in absolute units at every
   breakpoint. It used to be set on the image as min(..., 100%)
   inside an `auto` grid track, which asks the browser to resolve a
   percentage against a column whose width depends on that very
   percentage: the cover column then sized itself off the file's
   1100px intrinsic width and squeezed the whole copy block into a
   narrow strip against the right edge of the section.
   ============================================================ */
.book-hero {
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(28px, 4vw, 48px);
  align-items: center;
}
/* one column: jacket centred over the copy, capped so a tall phone
   still shows the title and the buttons without a scroll */
.book-hero-cover {
  justify-self: center;
  width: min(300px, 68vw, 34vh);
}
.book-hero-cover img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 3px;
  box-shadow: 0 34px 66px rgba(0,0,0,0.6);
}
@media (min-width: 880px) {
  /* two columns: the copy keeps the larger share and starts where it
     does everywhere else on the site, and the jacket sits centred in
     its own column rather than shoved up against the text */
  .book-hero {
    grid-template-columns: minmax(0, 0.78fr) minmax(0, 1fr);
    gap: clamp(36px, 4.4vw, 64px);
  }
  /* height-aware, at the cover's own 1100:1793 ratio, so the whole
     jacket stays in frame on a short laptop screen */
  .book-hero-cover { width: min(320px, 38vh); }
}

/* the book cover, lit */
.cover-lit { position: relative; }
.cover-lit img { position: relative; z-index: 1; transition: transform 1s var(--ease); }
.cover-lit:hover img { transform: translateY(-8px) rotate(-0.6deg); }

/* ============================================================
   Network — practitioner rows. The portrait comes first in source
   order for everyone, so a phone always scrolls portrait, then
   name, then story. Alternating rows only flip the portrait to the
   right once there are two columns to flip it between.
   ============================================================ */
.bio {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(28px, 5vw, 84px);
  align-items: start;
}
.bio-portrait {
  width: 100%;
  justify-self: center;
  border-radius: 6px;
  box-shadow: 0 26px 56px rgba(0,0,0,0.4);
}
@media (min-width: 880px) {
  .bio { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .bio-portrait { justify-self: start; }
  .bio-flip .bio-portrait { order: 2; justify-self: end; }
}

/* ============================================================
   Home hero

   The photograph now sits beside the entire copy block instead of
   under the headline. Stacking it under the headline made the hero
   taller than any laptop viewport, so the picture only appeared
   after a scroll. Type is sized against viewport height as well as
   width for the same reason: on a short window the headline steps
   down rather than pushing everything below the fold.
   ============================================================ */
.hero { padding: clamp(40px, 7vh, 104px) clamp(20px, 5vw, 76px) clamp(44px, 7vh, 92px); }
.hero-grid {
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(30px, 4vw, 52px);
  align-items: center;
}
.hero-eyebrow {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  color: var(--gold);
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.26em;
  text-transform: uppercase;
}
/* held to the middle of the first line rather than the middle of the
   block, so the rule still reads as a lead-in when the label takes two
   lines in a narrow column */
.hero-eyebrow > span:first-child { flex: none; width: 44px; height: 1px; margin-top: 9px; background: var(--gold); }
/* on a phone the label takes two lines, and a rule floating between
   them reads as a mistake — give it its own line instead */
@media (max-width: 560px) {
  .hero-eyebrow { display: block; }
  .hero-eyebrow > span:first-child { display: block; margin-bottom: 15px; }
}
.hero-title {
  margin-top: clamp(20px, 3.4vh, 44px);
  font-size: clamp(44px, min(7.4vw, 9.6vh), 104px);
  line-height: 0.94;
  letter-spacing: -0.03em;
  max-width: 14ch;
}
.hero-lede {
  margin-top: clamp(22px, 3.4vh, 38px);
  font-size: clamp(19px, 1.6vw, 24px);
  line-height: 1.5;
  color: var(--text);
  max-width: 52ch;
}
.hero-sub { margin-top: 18px; font-size: 17px; line-height: 1.65; color: var(--muted); max-width: 54ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 18px 24px; align-items: center; margin-top: clamp(26px, 3.4vh, 34px); }
.hero-fig {
  min-height: clamp(300px, 44vh, 560px);
  border-radius: 10px;
  box-shadow: 0 34px 74px rgba(0,0,0,0.42);
}
@media (min-width: 900px) {
  .hero-grid { grid-template-columns: minmax(0, 1.04fr) minmax(0, 1fr); gap: clamp(36px, 4.6vw, 68px); }
  /* stretched to the height the copy sets, so the frame is always
     full and the caption lands on the bottom edge of the copy */
  .hero-fig { align-self: stretch; min-height: min(560px, 60vh); }
}
/* short laptop windows: step the whole hero down a size so the
   headline, the buttons and the picture arrive together */
@media (min-width: 900px) and (max-height: 820px) {
  .hero { padding-top: clamp(30px, 5.2vh, 60px); padding-bottom: clamp(34px, 5.2vh, 60px); }
  .hero-title { font-size: clamp(40px, min(6.2vw, 8.4vh), 86px); margin-top: clamp(16px, 2.6vh, 30px); }
  .hero-lede { font-size: 20px; margin-top: clamp(18px, 2.6vh, 28px); }
  .hero-actions { margin-top: clamp(22px, 2.8vh, 28px); }
}

/* ============================================================
   Header navigation

   Above 980px the full set of links fits on one line. Below it the
   links no longer fit, so site.js collapses them into a drawer and
   sets html.nav-js. Without JavaScript the row stays put and
   scrolls sideways, which is what it did before.
   ============================================================ */
.nav-toggle {
  display: none;
  flex: none;
  align-items: center;
  justify-content: center;
  gap: 5px;
  flex-direction: column;
  width: 44px;
  height: 40px;
  padding: 0;
  margin: 0;
  background: none;
  border: 1px solid var(--rule-strong);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.3s var(--ease);
}
.nav-toggle:hover { border-color: var(--gold); }
.nav-toggle span {
  display: block;
  width: 18px;
  height: 1.5px;
  border-radius: 2px;
  background: var(--text);
  transition: transform 0.32s var(--ease), opacity 0.2s linear;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.nav-drawer {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 39;
  display: grid;
  gap: 2px;
  padding: 10px clamp(20px, 5vw, 76px) 22px;
  background: var(--header);
  border-bottom: 1px solid var(--rule);
  box-shadow: 0 26px 48px rgba(0,0,0,0.5);
  max-height: calc(100svh - 72px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* a class selector outranks the user-agent `[hidden]` rule, so the
   closed state has to be spelled out here */
.nav-drawer[hidden] { display: none; }
.nav-drawer a {
  padding: 13px 2px;
  border-bottom: 1px solid var(--rule);
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.nav-drawer a:hover, .nav-drawer a:focus-visible { color: var(--gold); }
.nav-drawer a[data-current] { color: var(--gold); }
.nav-drawer a.nav-drawer-cta {
  justify-self: start;
  margin-top: 18px;
  padding: 13px 24px;
  border: 1px solid var(--gold);
  border-radius: 999px;
  color: var(--text);
}
.nav-drawer a.nav-drawer-cta:hover { background: var(--gold); color: var(--deep); }

@media (max-width: 979px) {
  html.nav-js header nav { display: none !important; }
  html.nav-js .nav-toggle { display: flex; }
  /* no JavaScript: keep the single scrolling row rather than a
     six-line stack */
  header nav {
    flex-wrap: nowrap !important;
    justify-content: flex-start !important;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 2px;
  }
  header nav::-webkit-scrollbar { display: none; }
  header nav > a { flex: none; white-space: nowrap; }
}
@media (min-width: 980px) {
  .nav-drawer { display: none; }
}

/* ============================================================
   Small screens: keep long strings inside their column and give
   footer links a finger-sized target
   ============================================================ */
footer a { overflow-wrap: anywhere; }
@media (max-width: 700px) {
  footer a { padding: 3px 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .fig img, .portrait img, .cover-lit img, .fig-rule, .row-num, .row-arrow, .lift { transition: none !important; }
  .fig-par { transform: none !important; }
  .fig-rule { transform: scaleX(1) !important; }
  html.reveal-on [data-stagger] > * { opacity: 1 !important; transform: none !important; transition: none !important; }
}
