/* ==========================================================================
   Aria GPO — the site  (/)
   ==========================================================================

   The one-page, full-screen-section build. This is NOT the artboard
   transcription, which is still in styles.css and still served, as a
   reference copy, at /artboard/. Same copy, same palette, same faces, same
   section order, same photography — but the geometry is derived from the
   viewport rather than from the XD's 1920x7752 canvas, because a
   full-screen one-pager needs geometry the artboard cannot supply.

   THE ONE IDEA EVERYTHING ELSE FOLLOWS FROM
   -----------------------------------------
   styles.css scales the whole design off viewport WIDTH: `--p = 100vw/1920`.
   That is exactly right for reproducing a fixed comp, and exactly wrong here,
   because whether a section fits one screen depends on viewport HEIGHT. On a
   1280x720 laptop the artboard's "A different kind of GPO" measures 755px in a
   720px window; on a 2560x1440 monitor the same content sits small in a sea of
   gap. No amount of tuning fixes that, because the input is the wrong axis.

   So the root font-size here is a plane through both axes:

       html { font-size: clamp(15px, 0.26vw + 0.62vh + 7.6px, 23px); }

           1280 x  720  ->  15.4px
           1440 x  900  ->  16.9px
           1920 x 1080  ->  19.3px      (the artboard's 20px body, near enough)
           2560 x 1440  ->  23px        (capped)

   Every size below is then stated in `rem`, so the entire design — type,
   spacing, photo slots, form fields — breathes with the window in both
   directions at once. The XD's type ratios survive intact: 90/60/40/30/20
   design px become 4.5/3/2/1.5/1 rem.

   Vertical rhythm gets its own tokens (`--flow`, `--flow-lg`) keyed to `vh`
   alone, so on a short window the space between blocks collapses before the
   type does. Squeezing the reading size is the last resort, not the first.

   WHAT STILL DOES NOT FIT, AND WHY THAT IS FINE
   ---------------------------------------------
   On a 720px-tall window, two sections (the seven benefit cards, and the
   fiduciary accordion with a panel open) genuinely need more than one screen
   at a readable type size. They are `min-height`, not `height`, so they grow,
   and snapping is `proximity`, not `mandatory`, so a taller-than-screen
   section can still be scrolled through. Mandatory snapping plus an
   overflowing section is the classic trap: the middle of the section becomes
   unreachable.
   ========================================================================== */

/* ---------------------------------------------------------------- fonts -- */
@font-face{font-family:"Source Sans Pro";src:url(../fonts/SourceSansPro-Light.woff2) format("woff2");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Source Sans Pro";src:url(../fonts/SourceSansPro-Regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Source Sans Pro";src:url(../fonts/SourceSansPro-Semibold.woff2) format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Source Sans Pro";src:url(../fonts/SourceSansPro-Bold.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Salernomi J";src:url(../fonts/SalernomiJ.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}

/* --------------------------------------------------------------- tokens -- */
:root{
  /* palette — unchanged from the artboard build */
  --ink:        #26353a;
  --ink-soft:   #2f454c;
  --pink:       #ad0f5c;
  --pink-dark:  #96094e;
  --pink-logo:  #a80065;
  --beige:      #ede7df;
  --beige-88:   #f0eae3;
  --card:       #e9eaeb;
  --rule:       #707070;
  --white:      #fff;

  --track:      -0.025em;   /* XD charSpacing -25 */

  /* type scale — the XD's ratios, restated against the fluid root */
  --t-h1:   4.5rem;    /*  90 design px */
  --t-h2:   3rem;      /*  60 */
  --t-sub:  2rem;      /*  40 */
  --t-lead: 1.5rem;    /*  30 */
  --t-body: 1rem;      /*  20 */
  --t-sm:   0.9rem;    /*  18 */

  /* vertical rhythm — height-driven, so it collapses before the type does */
  --flow:     clamp(0.7rem, 1.7vh, 1.6rem);
  --flow-lg:  clamp(1.1rem, 3.2vh, 2.9rem);

  /* horizontal */
  --gutter: clamp(1.25rem, 3.5vw, 3.5rem);
  --maxw:   84rem;

  /* header height reserved by every section. Constant even while the header
     itself condenses, so nothing under it ever moves. */
  --hdr: 5.4rem;

  /* the footer shares the last screen with the contact section */
  --footer-h: 7.5rem;

  --ease: cubic-bezier(.22,.61,.36,1);
}

/* The fluid root. Stated as a bare math expression inside clamp() rather than
   a nested calc() — styles.css records a Safari parse failure with
   calc()-inside-min(), and there is no reason to go near it. */
html{ font-size: clamp(15px, 0.26vw + 0.62vh + 7.6px, 23px); }

/* Phones get their own scale: the two-axis plane is tuned for landscape
   windows, and on a 390x844 portrait screen it bottoms out at the 15px floor
   while the headings — sized in rem off that floor — stay far too large. */
@media (max-width: 999px){
  :root{
    --t-h1:   2.6rem;
    --t-h2:   2rem;
    --t-sub:  1.4rem;
    --t-lead: 1.15rem;
    --hdr:    4.2rem;
    --footer-h: auto;
  }
  html{ font-size: clamp(16px, 1.1vw + 13px, 19px); }
}

/* ----------------------------------------------------------------- base -- */
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--white);
  color:var(--ink);
  font-family:"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-size:var(--t-body);
  line-height:1.5;
  letter-spacing:var(--track);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
h1,h2,h3,p,ul,figure,blockquote{margin:0;padding:0}
ul{list-style:none}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
strong{font-weight:600}
.pink{color:var(--pink)}

.visually-hidden{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip-link{position:absolute;left:-9999px;top:0;z-index:99;background:var(--pink);color:#fff;padding:.6rem 1rem;font-size:var(--t-sm)}
.skip-link:focus{left:0}
:where(a,button,input,textarea):focus-visible{outline:2px solid var(--pink);outline-offset:3px}
.is-dark :where(a,button):focus-visible{outline-color:var(--white)}

/* Display face, every heading */
.hero__title,.sec__title{
  font-family:"Salernomi J","Source Sans Pro",serif;
  font-weight:400;
  letter-spacing:var(--track);
}

/* ══════════════════════════════════════════════ SCROLL BEHAVIOUR ═══
   Proximity, not mandatory: proximity snaps once you are already near a
   boundary — which is the "fill the section once it gets close" behaviour —
   and leaves you alone in the middle of a section that is taller than the
   screen. Mandatory would make the middle of such a section unreachable.

   `scroll-padding-top` stays 0 because each section reserves the header
   internally; a snapped section therefore lands with its top on the viewport
   top and the header floating over its own reserved space. */
@media (min-width: 1000px){
  html{
    scroll-snap-type:y proximity;
    scroll-padding-top:0;
  }
}
@media (prefers-reduced-motion: no-preference){ html{scroll-behavior:smooth} }

/* Snapping is motion nobody asked for, and it takes the scroll position out of
   the reader's hands. Anyone who has asked for less of that gets none. */
@media (prefers-reduced-motion: reduce){
  html{scroll-snap-type:none;scroll-behavior:auto}
}

/* ══════════════════════════════════════════════════════ SECTIONS ═══ */
.sec{
  position:relative;
  min-height:100vh;
  min-height:100svh;      /* svh, not vh or dvh — see the note below */
  display:grid;
  /* `minmax(0,1fr)`, and this line is load-bearing. Without it the grid has a
     single implicit `auto` column, and an `auto` track is sized from its
     content's max-content width. The testimonial track is a horizontal scroll
     container: `overflow-x:auto` zeroes its *minimum* size but not its
     max-content, which is the sum of all five cards. So the column grew to
     roughly 1100px, `.wrap{width:100%}` grew with it, and every percentage
     inside resolved against the wrong number — on a 375px phone the centred
     "Feedback" heading was laid out at x=573 and simply never appeared on
     screen, clipped away by `body{overflow-x:hidden}`. Capping the track at
     `0` minimum and `1fr` maximum ties it to the container instead. */
  grid-template-columns:minmax(0,1fr);
  align-content:center;
  padding-block:calc(var(--hdr) + var(--flow)) var(--flow-lg);
  scroll-snap-align:start;
  overflow:hidden;        /* keeps the dot decorations inside their section */
}
/* `svh` deliberately. `dvh` changes as a phone's address bar hides, which
   would resize every section mid-scroll; `vh` is the LARGEST viewport, which
   hides the bottom of the first screen behind the bar on first paint. `svh` is
   the stable one. `vh` above it is the fallback for anything that predates it. */

.wrap{
  position:relative;z-index:2;
  width:100%;max-width:var(--maxw);
  margin-inline:auto;padding-inline:var(--edge);
}
.wrap--narrow{max-width:68rem}

/* Once the section rail appears it owns a strip of the right edge, and copy
   must not run under it. The reservation is applied to BOTH sides so centred
   headings stay centred against the window rather than drifting left. */
:root{ --edge: var(--gutter); }
@media (min-width: 1100px){ :root{ --edge: calc(var(--gutter) + 2.4rem); } }

.sec__title{
  font-size:var(--t-h2);
  line-height:1.14;
  text-align:center;
  margin-bottom:var(--flow-lg);
  text-wrap:balance;
}
.sec__title--start{text-align:left;margin-bottom:var(--flow)}
/* A heading followed by a subtitle wants the small gap, not the big one. Said
   with `:has()` rather than by pulling the subtitle back up with a negative
   margin — the negative version has to restate `--flow-lg` to cancel it, so
   the two numbers have to be kept in step by hand. If `:has()` is unsupported
   the pair simply sits a little further apart, which is a fine way to fail. */
.sec__title:has(+ .sec__sub){margin-bottom:var(--flow)}
.sec__sub{
  font-size:var(--t-sub);
  line-height:1.2;
  text-align:center;
  max-width:44rem;
  margin:0 auto var(--flow-lg);
  text-wrap:balance;
}

/* ── copy blocks ──────────────────────────────────────────────────────────
   The bold line under a heading is the artboard's "subtitle at double size":
   2em of the block it sits in, so it never needs a hard number. */
.copy{font-size:var(--t-body);line-height:1.5}
.copy p + p{margin-top:var(--flow)}
.copy .sub{font-size:2em;line-height:1.15;letter-spacing:var(--track);text-wrap:balance}
.copy__lead{margin-top:calc(var(--flow) * 1.8)!important}
/* 48rem is roughly 75 characters at this size — centred copy needs a shorter
   measure than flush-left copy, because the reader has to find a new start
   position on every line. */
.copy--center{text-align:center;max-width:48rem;margin-inline:auto}
.copy--end{text-align:right}
.copy--hero{max-width:47rem;color:var(--white)}

/* ── two-column split ─────────────────────────────────────────────────────
   `align-items:center` so a short column sits against the middle of a tall
   photograph rather than the top of it. The columns are `minmax(0,1fr)` and
   not `1fr`: a bare `1fr` has an `auto` minimum, so a long unbreakable string
   would blow the grid wider than the screen. */
.split{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(1.5rem,4vw,3.75rem);
  align-items:center;
}
.split--top{align-items:start}

/* ── photography ──────────────────────────────────────────────────────────
   The slot is an aspect-ratio box rather than a fixed pixel size, and the
   image covers it. Same crops as the artboard build, so the existing 1x/2x
   exports and their `sizes` logic still hold. */
/* One aspect for all three, and it is the photographs' own. The fourth import
   batch arrives at 1264x843 — 3:2 to within a pixel — so a 3:2 slot throws
   nothing away. The artboard build keeps its three different slot shapes and
   crops the same files at display time via `object-fit: cover`; here there is
   no reason to inherit a crop that only existed because the XD drew one. */
.media{position:relative;width:100%;overflow:hidden;aspect-ratio:3 / 2}
.media picture,.media img{display:block;width:100%;height:100%;object-fit:cover}

/* ── decorations ──────────────────────────────────────────────────────────
   The dot waves and the arc are texture, not content: they run the full
   height of whatever the section turns out to be, and `cover` keeps a dot a
   dot instead of stretching it into an ellipse. */
.deco{position:absolute;z-index:0;pointer-events:none;user-select:none}
/* Hung off the edge and dialled back. On the artboard these waves had a
   1920px canvas to sit in and the copy began 258px clear of them; here the
   text column reaches much closer to the edge, and at full strength the dots
   read straight through the paragraphs. Bleeding them past the edge keeps the
   gesture — a wave entering the frame — without putting pattern under type. */
.deco--dots-left{left:-4vw;top:0;width:min(15rem,20vw);height:100%;object-fit:cover;object-position:left top;opacity:.5}
.deco--dots-right{right:-4vw;top:0;width:min(18rem,22vw);height:100%;object-fit:cover;object-position:right top;opacity:.5}
/* The arc was drawn to sit at the foot of a 1598px-tall section. In a
   720px-tall one it reaches the subtitle, so it is capped at just under half
   the section height — `object-fit:contain` is what makes that a proportional
   shrink rather than a squash — and dropped in strength. It is a base the
   section stands on, not a texture, so it is not stretched to fill. */
.deco--arc{
  left:50%;transform:translateX(-50%);bottom:0;
  width:min(80rem,92vw);max-height:46%;height:auto;
  object-fit:contain;object-position:bottom center;opacity:.45;
}

/* …and the sections that carry one give their content room to clear it. */
@media (min-width: 1000px){
  .sec--network .wrap{padding-left:calc(var(--edge) + min(6rem,8vw))}
  .sec--contact .wrap{padding-right:calc(var(--edge) + min(6rem,8vw))}
}

/* ══════════════════════════════════════════════════════════ HEADER ═══
   Transparent over the hero, white once you have left it. The artboard's
   header is white throughout, but on a page whose first screen is a
   full-bleed photograph a white bar cuts the top off the image — and the
   white logo lockup already exists in the asset folder for exactly this kind
   of ground. Both marks ship and cross-fade, so there is no swap flicker. */
.hdr{
  position:fixed;top:0;left:0;right:0;z-index:60;
  height:var(--hdr);
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--gutter);
  padding-inline:var(--gutter);
  transition:height .25s var(--ease), background-color .25s var(--ease), box-shadow .25s var(--ease);
}
/* Over the hero the nav is white type sitting on a photograph, and the right
   of that photograph is a bright window. A short scrim under the bar keeps the
   labels legible without putting a white block over the image. It has to be a
   pseudo-element rather than a background on .hdr itself, because .hdr
   transitions its background-color to solid white when stuck — a gradient
   there could not cross-fade to a colour. */
.hdr::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(to bottom, rgba(20,28,33,.62), rgba(20,28,33,0));
  transition:opacity .25s var(--ease);
}
.hdr.is-stuck::before{opacity:0}
.hdr.is-stuck{
  height:4.2rem;
  background:var(--white);
  box-shadow:0 .1rem 1rem rgba(38,53,58,.14);
}

.logo{position:relative;display:flex;align-items:baseline;gap:.55rem;flex:none}
.logo__mark{width:9.85rem;height:auto;transition:width .25s var(--ease)}
.hdr.is-stuck .logo__mark{width:8.2rem}
.logo__tagline{
  font-family:"Salernomi J",serif;font-size:1.55rem;line-height:1;
  color:var(--white);white-space:nowrap;
  transition:color .25s var(--ease),font-size .25s var(--ease);
}
.hdr.is-stuck .logo__tagline{color:var(--pink-logo);font-size:1.3rem}
/* Over the hero the pink mark is invisible on a dark ground, so it is
   filtered to white rather than swapped for a second file — one request, and
   nothing to go out of sync. */
.logo__mark{filter:brightness(0) invert(1)}
.hdr.is-stuck .logo__mark{filter:none}

.nav{display:flex;align-items:center;gap:clamp(1rem,2.2vw,2.1rem)}
.nav ul{display:flex;align-items:center;gap:clamp(1rem,2.2vw,2.1rem)}
.nav__link{
  position:relative;display:block;
  font-size:var(--t-body);line-height:1.2;
  text-transform:uppercase;white-space:nowrap;
  color:var(--white);
  transition:color .2s var(--ease);
}
.hdr.is-stuck .nav__link{color:var(--ink)}
.nav__link::after{
  content:"";position:absolute;left:0;right:0;bottom:-.35rem;height:2px;
  background:currentColor;transform:scaleX(0);transform-origin:left;
  transition:transform .25s var(--ease);
}
.nav__link:hover::after,.nav__link.is-current::after{transform:scaleX(1)}
.nav__link.is-current{color:var(--white)}
.hdr.is-stuck .nav__link.is-current{color:var(--pink)}
.nav__cta{flex:none}
.nav-toggle{display:none}

/* ══════════════════════════════════════════════════════════ BUTTONS ═══ */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:2.9rem;padding:.55rem 1.35rem;
  background:var(--pink);color:var(--white);border-radius:2px;
  font-size:var(--t-body);font-weight:600;line-height:1.2;
  text-transform:uppercase;text-align:center;
  transition:background-color .18s var(--ease),transform .18s var(--ease);
}
.btn:hover{background:var(--pink-dark);transform:translateY(-2px)}
.btn--sm{min-height:2.4rem;padding:.4rem 1rem;font-size:var(--t-sm)}
/* The hero's second action is secondary — two solid pink buttons side by side
   read as a choice between equals, which the copy does not intend. */
.btn--ghost{background:transparent;box-shadow:inset 0 0 0 2px rgba(255,255,255,.75)}
.btn--ghost:hover{background:rgba(255,255,255,.14)}

/* ════════════════════════════════════════════════════════════ HERO ═══ */
.sec--hero{background:#26323a;color:var(--white);padding-bottom:calc(var(--flow-lg) + 2.5rem)}
/* The slot starts at 38% rather than at the left edge, and that is a crop
   decision, not a layout one. The source is 1015x943 — very nearly square —
   so stretching the slot across the whole section makes `cover` scale it 1.26x
   and crop the top and bottom away, which pushes the subject's face to filling
   half the screen. From 38% the slot is about 1.10:1 against the image's
   1.076:1, so almost nothing is thrown away at any window shape. */
.hero__media{position:absolute;left:38%;right:0;top:0;bottom:0;z-index:0}
.hero__media picture,.hero__media img{width:100%;height:100%;object-fit:cover;object-position:60% center}

/* ── the diagonal ─────────────────────────────────────────────────────────
   The artboard ships this as hero-gradient.svg, 1465x945, which on a
   screen-height section either shears (if stretched) or leaves a seam (if it
   keeps its intrinsic height — the bug currently visible on the artboard
   build). Rebuilt here as two clipped gradient wedges holding the XD's own
   proportions: the first edge crosses from 51.3% of the width at the top to
   72.3% at the bottom (985 -> 1387.7 on a 1920 canvas), the second from 55.2%
   to 76.2% (1059 -> 1462.8), and the fills are the SVG's own stops. It now
   costs nothing to download and cannot seam at any section height. */
.hero__scrim{position:absolute;inset:0;z-index:1}
.hero__wedge{position:absolute;inset:0;display:block}
.hero__wedge--1{
  background:linear-gradient(90deg,#211728 0%,#75969d 100%);
  clip-path:polygon(0 0, 51.3% 0, 72.3% 100%, 0 100%);
}
.hero__wedge--2{
  opacity:.75;
  background:linear-gradient(215.5deg,#75969d 0%,#5d7a81 10%,#486067 22%,#374c53 35%,#2b3e44 51%,#25363c 69%,#23343a 100%);
  clip-path:polygon(0 0, 55.2% 0, 76.2% 100%, 0 100%);
}
/* Below the split the photograph goes above the copy instead of behind it, so
   the wedge has nothing to cut across. */
@media (max-width: 999px){ .hero__scrim{display:none} }

.hero__wrap{display:grid;justify-items:start}
.hero__title{
  font-size:var(--t-h1);line-height:1.0;color:var(--white);
  margin-bottom:var(--flow-lg);
  text-wrap:balance;
}
.hero__actions{display:flex;flex-wrap:wrap;gap:1.25rem;margin-top:var(--flow-lg)}

.pillars{
  display:flex;flex-wrap:wrap;
  gap:var(--flow) clamp(1.5rem,3.2vw,3.2rem);
  margin-top:var(--flow-lg);
}
.pillars li{display:flex;align-items:center;gap:.5rem;color:var(--white);font-size:1.1rem}

/* The XD paths are stroke centrelines with butt caps and a miter join.
   `overflow:visible` stops the tight viewBox slicing the miter point flat. */
.tick{flex:none;fill:none;overflow:visible;stroke-linecap:butt;stroke-linejoin:miter}
.tick--white{width:.84rem;height:.66rem;stroke:var(--white);stroke-width:4}
.tick--pink{width:1.27rem;height:1rem;stroke:var(--pink);stroke-width:4.5}

/* ── scroll cue ───────────────────────────────────────────────────────────
   A one-page site's first screen has to say that there is a second one. */
.scroll-cue{
  position:absolute;left:50%;bottom:1.6rem;z-index:3;
  width:2.6rem;height:2.6rem;margin-left:-1.3rem;
  display:grid;place-items:center;
  color:var(--white);opacity:.8;
}
.scroll-cue svg{width:1.3rem;height:auto;fill:none;stroke:currentColor;stroke-width:2}
.scroll-cue:hover{opacity:1}
@media (prefers-reduced-motion: no-preference){
  .scroll-cue svg{animation:cue 2.4s var(--ease) infinite}
}
@keyframes cue{0%,60%,100%{transform:translateY(0)}30%{transform:translateY(.35rem)}}

/* ══════════════════════════════════ THE POWER OF OUR NETWORK ═══ */
.sec--network{background:var(--beige)}

/* ══════════════════════════════════ A DIFFERENT KIND OF GPO ═══ */
.sec--gpo{background:var(--white)}
/* Seven cards, not eight — the artboard drew an eight-slot grid and filled
   seven of it. Flex rather than grid so the short last row centres itself
   instead of hanging off to the left. */
.cards{
  --card-gap:clamp(.6rem,1.1vw,1.1rem);
  position:relative;z-index:2;
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:var(--card-gap);
  width:100%;max-width:var(--maxw);
  margin:var(--flow-lg) auto 0;padding-inline:var(--edge);
}
.card{
  /* A percentage basis, not a rem one. At a fixed 15.5rem the row held four
     cards at 1280 and only three at 1024 — which turns the layout into
     3 + 3 + 1, an orphan card on its own line and a third row of height the
     section does not have. Four per row is now guaranteed at every width the
     full-screen layout runs at, and the seventh card sits in a centred row of
     three, which is what the artboard drew. */
  flex:0 1 calc(25% - var(--card-gap) * 3 / 4);
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  gap:.7rem;
  padding:clamp(.9rem,2vh,1.5rem) 1rem;
  background:var(--beige);
  transition:background-color .2s var(--ease),transform .2s var(--ease);
}
.card:hover{background:#e4dcd1;transform:translateY(-3px)}
.card span{
  font-size:var(--t-lead);line-height:1.24;
  text-align:center;color:var(--ink-soft);text-wrap:balance;
}

/* ════════════════════ HOW OUR FIDUCIARY MODEL CREATES VALUE ═══ */
.sec--fiduciary{background:var(--beige-88)}
.accordion{
  position:relative;z-index:2;
  background:var(--white);
  padding:clamp(.5rem,1.4vh,1.4rem) clamp(1.25rem,2.4vw,2.1rem);
}
.accordion__item h3{font-weight:400}
.accordion__item + .accordion__item{border-top:1px solid var(--rule)}
.accordion__head{
  display:flex;align-items:center;gap:1rem;
  width:100%;padding:clamp(.7rem,1.6vh,1.15rem) 0;text-align:left;
}
/* The XD numbered these in the label text ("1. Strategic…"). Pulled out into
   its own column so the five headings align on their first word rather than
   stepping in and out with the digit. */
.accordion__num{
  flex:none;width:2.2rem;
  font-family:"Salernomi J",serif;font-size:var(--t-lead);line-height:1;
  color:var(--pink);
}
.accordion__label{flex:1 1 auto;font-size:var(--t-lead);line-height:1.24;color:var(--ink)}
.accordion__head:hover .accordion__label{color:var(--pink)}
.accordion__icon{position:relative;flex:none;width:1.1rem;height:1.1rem}
.accordion__icon::before,.accordion__icon::after{
  content:"";position:absolute;left:0;top:50%;
  width:1.1rem;height:2px;margin-top:-1px;background:var(--ink);
  transition:transform .22s var(--ease),opacity .22s var(--ease);
}
.accordion__icon::after{transform:rotate(90deg)}
.accordion__head[aria-expanded="true"] .accordion__icon::after{transform:rotate(0);opacity:0}

/* A one-row grid animating 0fr -> 1fr, so the panel grows downwards out from
   under its heading. Spacing lives on the paragraphs, never on the panel or
   its inner wrapper: padding on the wrapper sets a floor on its used height
   under border-box, and margins on the panel apply even when collapsed —
   either one silently holds every closed row open. */
.accordion__panel{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .28s var(--ease);
  font-size:var(--t-body);line-height:1.5;color:var(--ink);
}
.accordion__item:not(.is-collapsed) .accordion__panel{grid-template-rows:1fr}
/* Closing is instant, only opening animates. If closing animated too, the item
   above would shrink over 280ms and drag the clicked heading up with it, and
   no single scroll correction can hold against motion spread over time. */
.accordion__item.is-collapsed .accordion__panel{transition:none}
.accordion__inner{overflow:hidden;min-height:0;padding-left:3.2rem;padding-right:2.1rem}
.accordion__inner > p:first-child{margin-top:.2rem}
.accordion__inner > p + p{margin-top:var(--flow)}
.accordion__inner > p:last-child{margin-bottom:clamp(1rem,2.2vh,1.6rem)}
@media (prefers-reduced-motion: reduce){ .accordion__panel{transition:none} }

/* An open panel can push this section past one screen. A section taller than
   the viewport must not be a snap stop, or every attempt to scroll within it
   gets dragged back to an edge. `site.js` sets this class. */
.sec--fiduciary.has-open{scroll-snap-align:none}

/* ══════════════════ SERVING THE PHARMACEUTICAL ECOSYSTEM ═══ */
.sec--ecosystem{background:var(--white)}
.lists__block + .lists__block{margin-top:var(--flow-lg)}
.lists__lead{font-size:var(--t-lead);line-height:1.2;margin-bottom:var(--flow)}
.ticked li{position:relative;padding-left:1.1rem;line-height:1.45}
.ticked li + li{margin-top:.4em}
.ticked li::before{
  content:"";position:absolute;left:0;top:.62em;
  width:.38rem;height:.38rem;border-radius:50%;background:var(--pink);
}
/* Nine items in one column is most of a screen on its own; two columns keeps
   the section to one. */
.ticked--two{columns:2;column-gap:clamp(1rem,2vw,2rem)}
.ticked--two li{break-inside:avoid}
.ticked--two li + li{margin-top:.4em}

/* ════════════════════════════════════════════════════════ FEEDBACK ═══ */
/* The artboard ships feedback-bg.svg for this ground; the same gradient
   already exists in CSS in mobile.css, and as a gradient it cannot seam. */
.sec--feedback{
  background:linear-gradient(158deg,#26323a 0%,#31424a 60%,#4b636a 100%);
  color:var(--white);
}
.sec--feedback .sec__title{color:var(--white)}

.carousel{position:relative;z-index:2;display:flex;align-items:center;gap:clamp(.5rem,1.5vw,1.5rem)}
.carousel__track{
  flex:1 1 auto;min-width:0;
  display:flex;gap:clamp(1rem,2.2vw,2.2rem);
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;
  overscroll-behavior-x:contain;
  scrollbar-width:none;
}
.carousel__track::-webkit-scrollbar{display:none}
@media (prefers-reduced-motion: no-preference){ .carousel__track{scroll-behavior:smooth} }

.quote{
  flex:0 0 calc((100% - 2 * clamp(1rem,2.2vw,2.2rem)) / 3);
  display:flex;flex-direction:column;justify-content:space-between;
  /* Height in `vh` rather than `rem`: this is the one section with far less
     content than screen, so the cards are what take up the slack. */
  min-height:clamp(11rem,38vh,24rem);
  padding:clamp(1.2rem,3.4vh,2.6rem) clamp(1rem,1.6vw,1.6rem) clamp(1rem,2.6vh,1.8rem);
  background:var(--card);color:var(--ink);
  scroll-snap-align:start;scroll-snap-stop:always;
}
/* Every card is one slot, the manufacturer quote included. It runs to roughly
   twice the length of the others and the artboard build gives it two slots to
   sit in — but a card that wide sets its own text in four long lines across the
   top and leaves the rest of the box empty above the attribution. One slot lets
   the same words run to more, shorter lines, which fills the card and reads as
   a quotation rather than a banner. The type size is unchanged either way; only
   the measure moves. Cards in the flex track stretch to the tallest, so the row
   still lines up. */
.quote blockquote{
  font-size:1.45rem;font-weight:600;line-height:1.28;
  text-align:center;text-wrap:pretty;
}
.quote__by{margin-top:1.2rem;font-size:var(--t-body);font-weight:300;line-height:1.3;text-align:center}

.carousel__arrow{
  flex:none;width:2.2rem;height:2.6rem;
  display:grid;place-items:center;
  transition:opacity .15s var(--ease),transform .15s var(--ease);
}
.carousel__arrow svg{width:.85rem;height:1.55rem;fill:none;stroke:var(--white);stroke-width:3.06}
.carousel__arrow:hover{opacity:.65;transform:scale(1.12)}
.carousel__note{margin-top:var(--flow-lg);text-align:center;color:var(--white);font-size:var(--t-body)}

/* ══════════════════════════ YOUR SUCCESS IS OUR STRATEGY ═══ */
.sec--success{background:var(--white)}

/* ═════════════════════════════════════════════════════════ CONTACT ═══ */
/* The footer shares this screen, so the section gives up its height. */
.sec--contact{background:var(--beige)}
@media (min-width: 1000px){
  .sec--contact{
    min-height:calc(100vh - var(--footer-h));
    min-height:calc(100svh - var(--footer-h));
  }
}

.form{display:grid;gap:.7rem;justify-items:start}
.form input,.form textarea{
  display:block;width:100%;
  background:var(--white);border:1px solid var(--rule);border-radius:0;
  font-family:inherit;font-size:var(--t-body);line-height:1.4;
  letter-spacing:var(--track);color:var(--ink);
  padding:.85rem 1.2rem;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
}
.form textarea{min-height:7rem;resize:vertical}
.form input:focus,.form textarea:focus{border-color:var(--pink);box-shadow:0 0 0 1px var(--pink);outline:none}
.form ::placeholder{color:var(--rule);opacity:1}
.form__status{font-size:var(--t-sm);color:var(--pink);min-height:1.4em}
.form__status.is-ok{color:var(--ink)}

/* The honeypot. Off-canvas rather than `display:none` - a bot that skips
   hidden fields is exactly the one worth catching, and screen readers are kept
   out by aria-hidden and tabindex="-1" on the markup instead. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* A submission in flight: the button reads as busy and cannot be double-fired. */
.form button[disabled]{opacity:.6;cursor:progress}

/* ══════════════════════════════════════════════════════════ FOOTER ═══ */
.site-footer{
  position:relative;z-index:2;
  min-height:var(--footer-h);
  background:var(--ink);color:var(--white);
  display:grid;align-content:center;
  grid-template-columns:auto 1fr;
  gap:.35rem clamp(1.25rem,3vw,2.5rem);
  padding:1.5rem var(--gutter);
}
.site-footer__logo{grid-row:1 / span 3;align-self:center;width:7.8rem;height:auto}
.site-footer p{font-weight:300;font-size:var(--t-sm);line-height:1.35;text-align:right}
.site-footer__blurb{opacity:.8}
.site-footer__copyright{opacity:.7}

/* ═══════════════════════════════════════════════════ SECTION RAIL ═══
   Eight dots, one per section, fixed against the right edge. This is the part
   that makes the page legible as a single document: the header carries the
   four headline destinations, and this carries everything, with a label on
   hover and the current section filled.

   It is a real <nav> of real links, so it works with a keyboard and reads
   correctly to a screen reader; the dot is decoration on top of that. */
.rail{
  position:fixed;right:clamp(.8rem,1.6vw,1.6rem);top:50%;z-index:55;
  transform:translateY(-50%);
}
.rail ul{display:grid;gap:.85rem}
.rail a{
  position:relative;display:block;width:1.4rem;height:1.4rem;
}
.rail a::before{
  content:"";position:absolute;left:50%;top:50%;
  width:.5rem;height:.5rem;margin:-.25rem 0 0 -.25rem;
  border-radius:50%;
  background:transparent;
  box-shadow:inset 0 0 0 1.5px var(--ink);
  transition:background-color .22s var(--ease),box-shadow .22s var(--ease),transform .22s var(--ease);
}
.rail a:hover::before{transform:scale(1.35)}
.rail a.is-current::before{background:var(--pink);box-shadow:inset 0 0 0 1.5px var(--pink);transform:scale(1.35)}
/* Over a dark section the outline has to invert. `site.js` puts this class
   on the rail when the section under it is one of the dark ones. */
.rail.on-dark a::before{box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.85)}
.rail.on-dark a.is-current::before{background:var(--white);box-shadow:inset 0 0 0 1.5px var(--white)}

.rail span{
  position:absolute;right:calc(100% + .5rem);top:50%;
  transform:translateY(-50%) translateX(.3rem);
  padding:.3rem .6rem;border-radius:2px;
  background:var(--ink);color:var(--white);
  font-size:.75rem;line-height:1.2;text-transform:uppercase;white-space:nowrap;
  opacity:0;pointer-events:none;
  transition:opacity .2s var(--ease),transform .2s var(--ease);
}
.rail a:hover span,.rail a:focus-visible span{opacity:1;transform:translateY(-50%) translateX(0)}
@media (max-width: 1099px){ .rail{display:none} }

/* ══════════════════════════════════════════ REVEAL ANIMATIONS ═══
   Driven by IntersectionObserver in site.js, which adds `.is-in` once and
   then stops watching — the reveal is one-way. That is a deliberate choice
   over CSS scroll-driven animations (`animation-timeline: view()`), which are
   well supported now but SCRUB: scroll back up and the element un-reveals,
   which on a snapping one-pager reads as a bug rather than an effect.

   Everything is guarded behind `html.js`, so with JavaScript off the page is
   simply visible. `site-boot.js` sets that class in <head>, before the
   first paint, so nothing flashes in and back out. */
html.js .reveal,
html.js .reveal-group > *{
  opacity:0;
  transform:translateY(1.4rem);
  transition:opacity .7s var(--ease),transform .7s var(--ease);
  will-change:opacity,transform;
}
html.js .reveal.is-in,
html.js .reveal-group.is-in > *{opacity:1;transform:none;will-change:auto}

/* Hand-placed delays for the few blocks whose order matters. */
html.js .reveal--d1{transition-delay:.09s}
html.js .reveal--d2{transition-delay:.18s}
html.js .reveal--d3{transition-delay:.27s}

/* Grouped children stagger themselves, so adding a card or an accordion row
   needs no extra markup. */
html.js .reveal-group.is-in > *:nth-child(1){transition-delay:.05s}
html.js .reveal-group.is-in > *:nth-child(2){transition-delay:.11s}
html.js .reveal-group.is-in > *:nth-child(3){transition-delay:.17s}
html.js .reveal-group.is-in > *:nth-child(4){transition-delay:.23s}
html.js .reveal-group.is-in > *:nth-child(5){transition-delay:.29s}
html.js .reveal-group.is-in > *:nth-child(6){transition-delay:.35s}
html.js .reveal-group.is-in > *:nth-child(7){transition-delay:.41s}

/* Photographs get a slower, quieter reveal than type — a photo sliding as far
   as a headline reads as the layout being unstable. */
html.js .media.reveal{transform:translateY(1.4rem) scale(1.03);transition-duration:.9s}
html.js .media.reveal.is-in{transform:none}

@media (prefers-reduced-motion: reduce){
  html.js .reveal,
  html.js .reveal-group > *,
  html.js .media.reveal{opacity:1;transform:none;transition:none}
  .scroll-cue svg{animation:none}
}

/* ══════════════════════════════════════════════════════════ MOBILE ═══
   Below 1000px the full-screen conceit is dropped entirely: sections flow at
   their natural height and nothing snaps. A screen-high section on a phone is
   mostly gap, and snapping fights the address bar. */
@media (max-width: 999px){
  .sec{
    min-height:0;
    padding-block:clamp(2.75rem,8vh,4rem);
    scroll-snap-align:none;
  }
  .sec--hero{
    padding-block:0 clamp(2.5rem,7vh,3.5rem);
    background:linear-gradient(158deg,#26323a 0%,#31424a 55%,#4b636a 100%);
  }

  /* The photograph goes above the copy rather than behind it. */
  .hero__media{position:relative;inset:auto;width:100vw;margin-left:calc(50% - 50vw);aspect-ratio:5 / 4}
  .hero__wrap{padding-top:clamp(2rem,6vh,3rem)}
  .scroll-cue{display:none}

  /* Double-size is a proportion that works across a 1920px screen. In a 375px
     column the same line runs to four lines and stops reading as a subtitle. */
  .copy .sub{font-size:1.7em}

  .split{grid-template-columns:minmax(0,1fr);gap:clamp(1.5rem,5vh,2.25rem)}
  /* Photo above copy in every split, including the ones that put it second in
     the source order for the desktop arrangement. */
  .sec--network .media{order:-1}
  .copy--end{text-align:left}
  .sec__title--start{text-align:center}

  .cards{--card-gap:.6rem}
  .card{flex:0 1 calc(50% - var(--card-gap) / 2);padding:1.1rem .8rem}
  @media (min-width: 700px){ .card{flex:0 1 calc(25% - var(--card-gap) * 3 / 4)} }

  .ticked--two{columns:1}
  .accordion__inner{padding-left:0;padding-right:0}
  .accordion__num{width:1.8rem}

  /* Arrows below the track, not beside it. Flanking them costs ~90px of a
     375px screen, which left the card at 240 — two thirds of the width doing
     the actual work. The track is swipeable anyway; the arrows are here for
     discoverability, and they do that just as well underneath. */
  .carousel{
    display:grid;grid-template-columns:auto auto;
    justify-content:center;gap:clamp(.75rem,3vw,1.25rem);
  }
  .carousel__track{grid-column:1 / -1;grid-row:1}
  .carousel__arrow--prev{grid-column:1;grid-row:2}
  .carousel__arrow--next{grid-column:2;grid-row:2}

  .quote{flex:0 0 100%;min-height:0}
  /* 1.45rem across a full-width card is a pull-quote; down a 332px column it
     runs the longest testimonial to nine lines. */
  .quote blockquote{font-size:1.15rem;line-height:1.35}
  .quote__by{font-size:.9rem}
  @media (min-width: 700px){
    .quote{flex:0 0 calc(50% - clamp(1rem,2.2vw,2.2rem) / 2)}
  }

  .deco--dots-left{left:-8%;opacity:.2}
  .deco--dots-right{right:-8%;opacity:.2}
  .deco--arc{display:none}

  /* ── header: a real hamburger panel ────────────────────────────────── */
  .hdr{
    position:sticky;
    background:var(--white);
    box-shadow:0 1px 0 rgba(38,53,58,.12);
  }
  /* The bar is white from the top here, so the scrim that keeps white nav type
     legible over the hero photograph has nothing to do but darken the logo. */
  .hdr::before{display:none}
  /* 9.85rem is a tenth of the artboard's width; on a 375px screen it is nearly
     half of it. Sized against the viewport here instead. */
  .logo__mark{filter:none;width:clamp(6rem,26vw,8.6rem)}
  .logo__tagline{color:var(--pink-logo);font-size:1.15rem}
  @media (max-width: 520px){ .logo__tagline{display:none} }

  .nav-toggle{
    display:flex;flex-direction:column;justify-content:center;gap:5px;
    width:44px;height:44px;padding:10px;margin-right:-10px;flex:none;z-index:41;
  }
  .nav-toggle span{display:block;height:2px;background:var(--ink);transition:transform .2s var(--ease),opacity .2s var(--ease)}
  .nav-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .nav-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
  .nav-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

  .nav{
    position:fixed;inset:0 0 auto;top:0;z-index:39;
    flex-direction:column;align-items:stretch;gap:1rem;
    background:var(--white);
    padding:calc(var(--hdr) + 1.5rem) var(--gutter) 2rem;
    transform:translateY(-100%);visibility:hidden;
    transition:transform .25s var(--ease),visibility .25s;
    box-shadow:0 12px 30px rgba(38,53,58,.16);
  }
  body.nav-open .nav{transform:translateY(0);visibility:visible}
  .nav ul{flex-direction:column;align-items:stretch;gap:0}
  .nav__link{color:var(--ink);padding:.9rem 0;border-bottom:1px solid rgba(38,53,58,.12)}
  .nav__link::after{display:none}
  .nav__link.is-current{color:var(--pink);font-weight:700}
  .nav__cta{align-self:start}

  /* ── footer ───────────────────────────────────────────────────────── */
  .site-footer{
    grid-template-columns:minmax(0,1fr);
    justify-items:center;text-align:center;gap:.75rem;
    padding-block:clamp(2rem,6vh,3rem);
  }
  .site-footer__logo{grid-row:auto}
  .site-footer p{text-align:center;max-width:36rem}
}
