body{
  margin:0;
  background:var(--cream);
  color:var(--ink);
  font-family:var(--sans);
  font-weight:300;
  font-size:clamp(1rem,.94rem + .28vw,1.0625rem);
  line-height:1.78;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

/* type primitives -------------------------------------------- */
.display{font-family:var(--serif)}
.eyebrow{
  font-family:var(--cond);font-weight:400;
  font-size:clamp(.8125rem,.765rem + .2vw,.875rem);
  letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-soft);line-height:1;
}
.lede{font-size:clamp(1.0625rem,1rem + .38vw,1.25rem);line-height:1.72}

.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter)}
.narrow{max-width:820px}
section{position:relative}

/* rules ------------------------------------------------------- */
.rule{height:1px;background:var(--hairline);border:0;margin:0}
.btn:hover::before,.btn:focus-visible::before,.btn:active::before{transform:translateY(0)}
.btn:hover,.btn:focus-visible,.btn:active{color:var(--ink-deep);border-color:var(--apricot)}
.btn--ghost:hover{border-color:var(--apricot)}
.btn--terra::before{background:var(--ink-deep)}
.btn--terra:hover,.btn--terra:focus-visible,.btn--terra:active{color:var(--cream);border-color:var(--ink-deep)}
/* light apricot fill that wipes to deep terracotta on hover */
.btn--apricot{--bg:var(--apricot);--fg:var(--ink-deep)}
.btn--apricot::before{background:var(--terracotta)}
.btn--apricot:hover,.btn--apricot:focus-visible,.btn--apricot:active{color:#fff;border-color:var(--terracotta)}
.btn--lg{
  padding:1.32em 2.35em;letter-spacing:.14em;
  font-size:clamp(.9375rem,.89rem + .3vw,1.0625rem);
}
/* the button itself swells slightly while three rings ripple outwards,
   matching the request button on corporate-offerings.html */
.btn--pulse{animation:pulseRipple 3s infinite cubic-bezier(.25,.8,.25,1)}
.btn--pulse:hover,.btn--pulse:focus-visible{animation:none}
@keyframes pulseRipple{
  0%{
    transform:scale(1);
    box-shadow:0 0 0 0 rgba(196,99,60,.5),
               0 0 0 0 rgba(196,99,60,.3),
               0 0 0 0 rgba(196,99,60,.16);
  }
  50%{
    transform:scale(1.06);
    box-shadow:0 0 0 10px rgba(196,99,60,0),
               0 0 0 22px rgba(196,99,60,0),
               0 0 0 34px rgba(196,99,60,0);
  }
  100%{
    transform:scale(1);
    box-shadow:0 0 0 0 rgba(196,99,60,0),
               0 0 0 0 rgba(196,99,60,0),
               0 0 0 0 rgba(196,99,60,0);
  }
}

/* underline link ---------------------------------------------- */
.ulink{
  display:inline-flex;align-items:center;gap:.55em;
  font-family:var(--cond);font-weight:500;font-size:.9375rem;
  letter-spacing:.2em;text-transform:uppercase;text-decoration:none;
  padding-bottom:.42em;position:relative;color:var(--ink);
}
.ulink::after{
  content:"";position:absolute;left:0;bottom:0;height:1px;width:100%;
  background:currentColor;transform-origin:right;transform:scaleX(1);
  transition:transform .42s var(--ease);
}
.ulink:hover::after{transform:scaleX(0);transform-origin:left}
.ulink .arw{transition:transform .42s var(--ease)}
.ulink:hover .arw{transform:translateX(5px)}

/* arch mask --------------------------------------------------- */
.arch{border-radius:50vw 50vw 6px 6px;overflow:hidden}
.arch img{width:100%;height:100%;object-fit:cover}

/* ============================ NAV ============================ */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  transition:background .5s var(--ease),box-shadow .5s var(--ease),padding .5s var(--ease);
  padding:1.6rem 0;
}
.nav__sublink[aria-current="page"]{color:var(--terracotta)}


/* ============================ HERO =========================== */
/* this hero used to be shared verbatim with corporate-offerings.html so both
   pages opened on the same picture. That page has since moved to a dark,
   centred head; this one keeps the warm two-column version below, so the two
   sections are no longer in step and edits here do not carry over.
   the previous "Hi there, I'm Rosie Rapp" hero is kept in "Alte seiten backup/index.html".

   warm ground with gradient discs. the head stands on blush, the darker
   beige of the palette. soft discs in apricot, terracotta and tan sit
   along the edges, the cut-out portrait in the orange dress on the right.
   the terracotta stats bar runs full width underneath. */
.hero{
  background:var(--blush);
  /* the head pad lost about a rem with the greeting: the copy column hangs from
     the bottom of the row, so dropping that line pushed the wordmark down by its
     own height. the shorter pad lifts the whole row back up instead of reopening
     the gap at the foot.
     the foot pad is the whole distance from the press row to the stats bar now
     that the copy column sits flush at the bottom of the row — trimmed to about
     half of what that gap used to measure. the portrait fades out over its last
     12%, so it keeps its air even at the shorter value. */
  padding:clamp(7.5rem,13vh,10.25rem) 0 clamp(2.8rem,5vw,4.25rem);
  /* the glow layer measures itself against this box, and overflow keeps
     the discs from spilling onto the stats bar below */
  position:relative;
  overflow:hidden;
  isolation:isolate;
}

/* ---- gradient discs ------------------------------------------
   four soft discs, each half out of frame, so colour sits along the
   edges and the middle stays quiet. the blur is on the layer, not on
   every disc — one filter instead of four. */
.hero__glow{
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  filter:blur(clamp(45px,7vw,110px));
  /* the blur would otherwise pull the edges back in as a pale seam */
  transform:scale(1.08);
}
.hero__glow i{
  position:absolute;display:block;border-radius:50%;
}
/* top left, apricot */
.hero__glow i:nth-child(1){
  left:-8%;top:-18%;width:38vw;height:38vw;max-width:640px;max-height:640px;
  background:radial-gradient(circle,rgba(237,165,125,.85) 0,rgba(237,165,125,0) 70%);
}
/* bottom left, tan — holds the text column together at the foot */
.hero__glow i:nth-child(2){
  left:-14%;bottom:-26%;width:34vw;height:34vw;max-width:560px;max-height:560px;
  background:radial-gradient(circle,rgba(169,133,112,.5) 0,rgba(169,133,112,0) 70%);
}
/* top right, terracotta — sits behind the portrait */
.hero__glow i:nth-child(3){
  right:-12%;top:-14%;width:40vw;height:40vw;max-width:680px;max-height:680px;
  background:radial-gradient(circle,rgba(196,99,60,.42) 0,rgba(196,99,60,0) 70%);
}
/* bottom right, cream — lifts the corner above the bar */
.hero__glow i:nth-child(4){
  right:-6%;bottom:-22%;width:30vw;height:30vw;max-width:520px;max-height:520px;
  background:radial-gradient(circle,rgba(251,249,248,.9) 0,rgba(251,249,248,0) 70%);
}

/* ---- grid ----------------------------------------------------- */
.hero__grid{
  position:relative;
  /* the text column has priority: it carries the wordmark, while the
     cut-out gets by on the rest and scales off its height anyway */
  display:grid;grid-template-columns:1.75fr 1fr;
  gap:clamp(2.5rem,5vw,5rem);align-items:center;
  /* declared on the grid, not the copy column, because one column below 1080px
     hands the portrait the same rhythm value — see the media query */
  --hero-gap:clamp(2rem,3.4vw,3rem);
}

/* ---- left column ---------------------------------------------- */
/* the column is its own container so the wordmark can measure in cqi:
   100cqi is the column width, whatever the grid is currently doing.
   the column also carries the grid's larger share, 1.75fr against the
   cut-out's 1fr: the wordmark grows with the column it measures against,
   so widening the column is what makes it bigger without eating into the
   air around the longer line. */
/* --hero-gap is the column's single rhythm value: headline, promise, buttons
   and press row are all set one --hero-gap apart, so the four blocks read as
   an even stack instead of three different steps.
   align-self:end drops the column to the foot of the row (the portrait is the
   taller of the two and sets the row height), which is what closes most of the
   dead space that used to sit between the press row and the stats bar. */
.hero__copy{
  container-type:inline-size;
  align-self:end;
}
/* the wordmark is the first block in the copy column — the script greeting that
   used to sit above it is gone, so the head opens straight on the Playfair.
   measured off the shipped playfair-display-*-var.woff2 with fontTools, not
   estimated: "ADHD WORKPLACE" runs 8.64em at this -.035em, "& Strategy
   Consultant" 9.19em italic at -.028em. 10.35cqi puts the longer line at 95.1%
   of the column, so it keeps its ~5% of air at the larger size. */
.hero__t{
  font-family:var(--serif);font-weight:400;
  font-size:min(10.35cqi,74px);
  line-height:1.06;letter-spacing:-.035em;margin:0;
}
/* two lines, breaking after "Workplace" */
.hero__t .lo{display:block;text-transform:uppercase;white-space:nowrap}
/* -.028em, tighter than the -.02em this line carried at the smaller size: it is
   the line that binds the wordmark's width, and Playfair wants the closer fit
   the bigger it is set. same value as the italic line on corporate-offerings. */
.hero__t .hi{
  display:block;white-space:nowrap;
  font-style:italic;font-weight:500;color:var(--terracotta);
  letter-spacing:-.028em;
}
/* the whole text block runs one step larger: wordmark, promise, buttons
   and press row each about 20% up, so the column can hold its own
   against the cut-out */
.hero__line{
  margin:var(--hero-gap) 0 0;
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.54rem,1.26rem + 1.14vw,2.22rem);
  line-height:1.34;letter-spacing:-.022em;color:var(--ink-soft);
}
.hero__line em{font-style:italic;color:var(--terracotta)}
.hero__cta{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:clamp(1.1rem,2.4vw,2rem);
  margin-top:var(--hero-gap);
}
/* the buttons' padding is in em and grows along on its own */
.hero__cta .btn{font-size:1.125rem}
/* one --hero-gap from the buttons like everything else, only split around the
   hairline — 55% above it, 45% below, so the rule sits just past the middle
   and still reads as belonging to the press row */
.hero__press{
  margin-top:calc(var(--hero-gap) * .55);
  padding-top:calc(var(--hero-gap) * .45);
  border-top:1px solid rgba(83,79,81,.22);
}
/* the press line runs half again the shared .pressrow scale — label and the
   three marks all at 1.5×, so their relative weighting is untouched. the
   doubled class is deliberate: at equal specificity the .pressrow rules
   further down the sheet would win on source order and flatten these. */
.hero__press.pressrow .pressrow__t{font-size:clamp(1.56rem,1.46rem + .51vw,1.83rem)}
.hero__press.pressrow .logo-mark--stylist,
.hero__press.pressrow .logo-mark--huff{font-size:clamp(1.53rem,1.35rem + .9vw,2.16rem)}
.hero__press.pressrow .logo-mark--bbc{font-size:clamp(1.23rem,1.11rem + .66vw,1.74rem)}

/* ---- right column, the cut-out portrait -----------------------
   the same cut-out as on the keynotes page: no frame, no crop, scaled
   off its height and faded out at the foot. instead of the blush plate
   used there, a cream disc sits behind it — on this darker ground that
   is what lifts it off. */
.hero__cut{
  margin:0 0 0 auto;position:relative;isolation:isolate;
  width:fit-content;max-width:100%;
}
.hero__cut::before{
  content:"";position:absolute;z-index:-1;inset:6% -12% 10% -12%;border-radius:50%;
  background:radial-gradient(circle at 50% 45%,rgba(251,249,248,.85),rgba(251,249,248,0) 70%);
}
.hero__cut img{
  height:clamp(390px,57vh,600px);width:auto;max-width:100%;
  -webkit-mask-image:linear-gradient(180deg,#000 88%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 88%,transparent 100%);
}

/* ========================== STATS ============================ */
.stats{background:var(--terracotta);color:#fff}
.stats__grid{display:grid;grid-template-columns:repeat(4,1fr)}
.stat{
  position:relative;text-align:center;
  /* the numeral size lives on the card, not on .stat__n, because the label's
     optical pull below is a fraction of it and has to follow it through the
     clamp and through the 560px step-down */
  --stat-n:clamp(2.3rem,1.5rem + 2.7vw,3.85rem);
  padding:clamp(1.5rem,2.5vw,2.05rem) clamp(.9rem,2.2vw,2rem) clamp(1.25rem,2vw,1.6rem);
}
.stat + .stat::before{
  content:"";position:absolute;left:0;top:20%;bottom:20%;width:1px;
  background:rgba(255,255,255,.34);
}
.stat__n{
  display:block;font-family:var(--serif);font-weight:400;color:#fff;
  font-size:var(--stat-n);
  line-height:.92;letter-spacing:-.035em;
  font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1;
}
.stat__n i{font-style:normal}
.stat__l{
  display:block;margin:clamp(.55rem,1.1vw,.85rem) auto 0;
  font-family:var(--cond);font-weight:500;
  font-size:clamp(.75rem,.71rem + .18vw,.8125rem);
  /* Tracking was .2em, which opened the words up so far they read as loose
     letters rather than a label. .12em still sets them apart at this size. */
  letter-spacing:.12em;text-transform:uppercase;line-height:1.55;
  /* Optical centring under the numeral. letter-spacing is applied after the
     last letter too, so each line's ink sits half the tracking (.06em) left of
     its box -> pad that back. An extra .156em used to ride along here to
     compensate for the numerals' sidebearings, but it overshot and read as the
     label sitting right of the number, so it's gone.
     max-width carries the pad so the content box stays 20ch and the two-line
     breaks hold; 20ch keeps "Tailored Strategies" wrapping with room to spare
     at the tighter tracking, where 22ch left only ~1.6px of margin. */
  color:#fff;max-width:calc(20ch + .06em);padding-left:.06em;
  /* and then the pull below, which is what actually hangs it on the number.
     An offset rather than a margin, so it cannot touch the 20ch wrap width. */
  position:relative;left:calc(var(--stat-n) * var(--stat-pull,0));
}
/* Every numeral here closes on a sign the eye does not count as part of the
   number, and the label is hung on the centre of the whole line — so it lands
   right of the number itself, worst under the wide "%". Each pull is the
   distance from that line's centre to the centre of the number's own ink,
   measured with fontTools off the shipped Playfair (glyph advances under the
   numeral's -.035em tracking), and given in the numeral's own em so it follows
   --stat-n through both of its clamps:
       "56k+"  number "56k"  ->  -.239em    ~15px at the desktop maximum
       "5+"    number "5"    ->  -.256em    ~16px
       "100+"  number "100"  ->  -.262em    ~16px
       "100%"  number "100"  ->  -.205em    ~13px, on the shortened % below
   The k stays with "56": it is part of the count, only the + is a sign. */
.stat:nth-child(1){--stat-pull:-.239}
.stat:nth-child(2){--stat-pull:-.256}
.stat:nth-child(3){--stat-pull:-.262}
.stat:nth-child(4){--stat-pull:-.205}
/* Playfair's figures are old-style — "100" tops out at 529 of the em — but its
   "%" is drawn for lining figures and runs -55..824, half again as tall, which
   is why it read as a size larger than the number beside it. .642em sets its top
   on the digits' 529 and leaves it a 35-unit descender, so it measures 564
   against their 543. Scaling costs stroke: the ring stem goes 70 -> 45 where the
   digits carry 97, so the sign takes the 500 weight of the variable face to win
   a little of that back (50) without changing its drawing. The "+" signs are
   left alone — at 501 units they already sit inside the figures' height. */
.stat:nth-child(4) .stat__n i{font-size:.642em;font-weight:500}

/* ========================= INTRO ============================= */
.intro{padding:clamp(2.75rem,5.5vw,4.75rem) 0 clamp(2.6rem,5vw,4.4rem)}

/* — top: cut-out portrait + the big question —
   start, not center: the portrait's top edge has to sit level with the first
   line of the hook beside it. The copy column is the shorter of the two now
   that its last two paragraphs run full width below, so centring would have
   dropped the picture half a screen down its own cell. */
.intro__top{
  display:grid;grid-template-columns:.82fr 1.18fr;
  gap:clamp(2rem,5vw,5.5rem);align-items:start;
}
.intro__cut{margin:0;position:relative;isolation:isolate}
.intro__cut::before{
  content:"";position:absolute;z-index:-1;
  inset:12% -4% 16% -4%;border-radius:50%;
  background:radial-gradient(circle at 50% 45%,var(--blush),rgba(230,216,207,0) 70%);
}
/* alpha cut-out; bottom fades so the crop dissolves into the page */
.intro__cut img{
  width:100%;height:auto;display:block;
  -webkit-mask-image:linear-gradient(180deg,#000 88%,transparent 100%);
  mask-image:linear-gradient(180deg,#000 88%,transparent 100%);
}
/* opaque (non cut-out) photo: soft elliptical vignette instead of a hard crop */
.intro__cut.is-placeholder img,
.intro__cut--photo img{
  -webkit-mask-image:radial-gradient(ellipse 74% 80% at 50% 42%,#000 55%,transparent 94%);
  mask-image:radial-gradient(ellipse 74% 80% at 50% 42%,#000 55%,transparent 94%);
}
/* the hook used to be set in the big serif italic; it is body copy now, so the
   whole column runs at one size and the handwritten line is the only thing that
   stands out of it. .intro__q went with that change. */
/* the air around the handwriting is 30% tighter on both sides than it was, and
   most of that came out of the line box rather than the margins: at the body's
   inherited 1.78 a 54px line stands in a 96px box, and Caveat's ink only spans
   0.74em of it, so the leading was doing more of the spacing than either margin.
   line-height:1.25 gives it a hair of negative leading — harmless on one
   shrink-wrapped line — and the two margins take the rest. The numbers are
   solved against the font's own ascent, descent and ink extents, so the figures
   are measured from where the glyphs actually start and stop, not from the
   boxes. The top then came down a further quarter, which is why the two sides
   are no longer symmetrical — 29px above against 47px below. That is the right
   way round: the handwriting answers the paragraph it follows, so it sits with
   it rather than floating between the two. Almost nothing is left of the top
   margin at this point; the line box is doing that spacing. */
.intro__same{
  font-family:var(--script);font-size:clamp(2.25rem,1.75rem + 2.125vw,3.375rem);
  color:var(--terracotta);transform:rotate(-2deg);display:inline-block;
  line-height:1.25;
  margin:clamp(.215rem,.43vw,.34rem) 0 0;
}
.intro__same + .intro__body{margin-top:clamp(1.15rem,2.1vw,1.62rem)}
/* the argument. no max-width: the column it sits in is the measure, ~73
   characters, and the hook above shares that same right edge */
.intro__body{
  margin-top:clamp(1.4rem,2.6vw,2rem);
  color:var(--ink-soft);font-size:1.125rem;line-height:1.75;max-width:none;
}
/* the column opens on the copy, so its first block cannot carry the top margin
   the others use — the portrait beside it is aligned to the top of this cell */
.intro__qwrap .intro__body:first-child{margin-top:0}
.intro__body p{margin-bottom:1.05em}
.intro__body strong{font-weight:600;color:var(--ink)}
/* "Or maybe it's you." — the line the hook narrows to, and now the only thing
   marking it is its colour, so it takes the terracotta and the bold together */
.intro__body .mark{color:var(--terracotta);font-weight:600}
/* the last two paragraphs step out of the column and take the whole wrap, which
   is where the section stops being about the portrait beside it. Same size and
   colour as the two above — the width is the only thing that changes.
   Full-bleed prose runs a long line (~130 characters at 1320px), so the leading
   opens up: it is what lets the eye find the start of the next line back at the
   left edge. Its top margin is measured from the taller of the two cells above,
   so it clears the portrait rather than the copy. */
.intro__body--wide{
  margin-top:clamp(2rem,3.8vw,3.2rem);
  line-height:1.95;
}

/* .intro__statement / .intro__big and the .hl marker that filled under them
   stood here. "And that benefits everyone." is the last sentence of the
   paragraph above now rather than a display line of its own, and nothing else
   on this page used any of the four rules. */

/* ===================== INTRO LEAD HEADLINE ==================== */
/* the question runs 76 characters where the one before it ran 62. at the old
   ceiling of 4.25rem that is right on the edge of taking an extra line, which
   would have pushed the whole section down; a step down to 3.7rem keeps it at
   the two lines the old headline held, at display scale either way */
.intro__lead{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.8rem,1.05rem + 3.05vw,3.7rem);
  line-height:1.08;letter-spacing:-.035em;
  margin-bottom:clamp(2.4rem,4.6vw,3.6rem);
  padding-bottom:clamp(1.8rem,3.4vw,2.6rem);
  border-bottom:1px solid var(--hairline);
}
/* one short word in the handwriting, on the hinge of the sentence — the same
   job "with" did in the line this replaced */
.intro__lead em{
  font-family:var(--script);font-style:normal;color:var(--terracotta);
  font-size:1.22em;line-height:.8;display:inline-block;
  transform:rotate(-3deg);padding:0 .06em;
}

/* ==================== THE NARROW MIDDLE ======================
   The info panel between the closing line and the Featured strip. It runs the
   full wrap, on paper rather than cream so it reads as a panel set into the
   page rather than more of the page. Everything inside is namespaced .viz__ —
   the draft it came from used names like .dot, .lede and .count, three of which
   already mean something else in this file.
   ============================================================ */
/* blush, not paper. Paper is #FBF9F8 against the page's #F5F2F1 — three points
   of lightness apart, which on a full-width block reads as a printing fault
   rather than as a panel. Blush is a clear step down and still a brand tone. */
.viz{
  margin:clamp(2.2rem,4.2vw,3.4rem) 0 0;
  padding:clamp(1.2rem,2.6vw,2rem) clamp(1.1rem,2.4vw,2rem) clamp(1.1rem,2.2vw,1.7rem);
  background:var(--blush);border:1px solid rgba(83,79,81,.14);border-radius:6px;
}
.viz[hidden]{display:none}
/* no measure cap: the heading and the standfirst run the width of the panel,
   the same edge the drawing and the controls under them keep */
.viz__head{max-width:none}
/* the line that hands the panel to the reader, in the same handwriting the
   intro's "Believe me. I've been there." uses, a good deal smaller */
.viz__hand{
  display:block;font-family:var(--script);color:var(--terracotta);
  font-size:clamp(2.4rem,1.9rem + 1.8vw,3.4rem);line-height:1.02;
  transform:rotate(-2deg);transform-origin:left;margin-bottom:.5rem;
}
/* a third larger than it was at both ends of the clamp, and the slope between
   them scaled with it, so it grows at the same rate it did before */
.viz__t{
  font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:clamp(1.46rem,1.22rem + 1.13vw,2.06rem);
  line-height:1.24;letter-spacing:-.024em;margin:0;
}
/* the marker under the phrase the whole panel is about. Terracotta, not the
   page's apricot .hl: on blush that band lands within a few points of the panel
   itself and stops reading as a mark. The stops are cut for this heading's 1.24
   leading, and it fills a beat after the panel's own reveal has finished. */
.viz__mark{
  background-image:linear-gradient(
    transparent 8%, rgba(196,99,60,.32) 8%,
    rgba(196,99,60,.32) 90%, transparent 90%);
  background-repeat:no-repeat;background-size:0% 100%;
  transition:background-size .9s var(--ease) .35s;
  /* the band is strong enough that --ink over it only reaches 4.2:1, which is
     under the floor at the small end of the heading's clamp. --ink-deep takes it
     to 6.6:1 and darker type inside a marker is the natural reading anyway. */
  color:var(--ink-deep);
}
.is-in .viz__mark{background-size:100% 100%}
/* --- the four notes ------------------------------------------
   The standfirst used to be one paragraph of six sentences, which is more than
   anyone reads standing in front of a moving drawing. It is four cards now, one
   claim each, so the panel can be taken in at a glance and each line can be
   read against the part of the picture it describes. auto-fit rather than a
   fixed four-up: at 15rem a card still holds its longest line over three rows,
   and the row falls to two-up and then one-up on its own without a breakpoint.
   Paper on the panel's blush — the same figure/ground step the page uses for
   cards on cream. */
.viz__notes{
  list-style:none;margin:clamp(.9rem,1.8vw,1.3rem) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
  gap:clamp(.6rem,1.2vw,.85rem);
}
.viz__note{
  display:flex;flex-direction:column;gap:.5rem;
  padding:clamp(.75rem,1.4vw,.95rem) clamp(.8rem,1.5vw,1rem);
  background:var(--paper);border:1px solid rgba(83,79,81,.14);border-radius:5px;
  /* bold, like the line under the drawing: these are the panel's four claims,
     not a caption running alongside it. The tracking comes back in a touch with
     it — Open Sans 700 sets wider than the 400 the rest of the body runs at, and
     at this size in a column this narrow it was reading loose. */
  color:var(--ink-soft);font-size:.875rem;line-height:1.6;font-weight:700;
  letter-spacing:-.012em;
  /* they arrive after the panel does, one behind the other, so the reader is
     walked through them in order rather than handed all four at once */
  opacity:0;transform:translateY(10px);
  transition:opacity .6s var(--ease),transform .6s var(--ease);
}
.is-in .viz__note{opacity:1;transform:none}
.is-in .viz__note:nth-child(1){transition-delay:.10s}
.is-in .viz__note:nth-child(2){transition-delay:.22s}
.is-in .viz__note:nth-child(3){transition-delay:.34s}
.is-in .viz__note:nth-child(4){transition-delay:.46s}
/* each card opens with the mark from the drawing it is about — a filled dot, the
   cone, the crowd in the middle, the two ends — so the eye can pair the sentence
   with the picture without the text having to name the shape twice. 22 tall
   rather than 16: the crowd is a stack five dots high and it needs the room. */
.viz__glyph{display:block;width:44px;height:22px}
.viz__glyph .g-fill{fill:var(--terracotta)}
.viz__glyph .g-out{fill:none;stroke:var(--tan);stroke-width:1.5}
.viz__glyph .g-cone{fill:rgba(237,165,125,.4);stroke:var(--terracotta);stroke-width:1.2;stroke-opacity:.6}

/* --- the drawing ---------------------------------------------
   The viewBox is 900×274 on a laptop and the svg fills its box, so the whole
   composition scales as one and nothing inside needs a breakpoint of its own.
   The stack is deliberately flat — 9.8px between dots against a 3.7px radius —
   because the panel's height is set by this box and by nothing else. The floor
   is the min-width: below it the dots stop reading as separate people, so the
   box scrolls instead of shrinking further. On a phone the script swaps in a
   490-wide viewBox instead, which is why the floor drops with it — see the
   640px block and the WIDE/NARROW pair in the script. */
.viz__stage{
  margin-top:clamp(1.1rem,2.2vw,1.7rem);
  overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
}
.viz__svg{width:100%;min-width:460px;height:auto;display:block}
/* the cone. Its apex is pinned at the top of the middle column and its base
   opens and closes along the floor, so the middle is always under it and the
   further out a person stands the wider it has to open to reach them. Its
   points are rewritten every frame rather than scaled with a transform, so the
   stroke keeps its weight at every width instead of being squashed with the
   shape. The outline is solid: the dashed one the fixed bands used crawled along
   the edge as the shape morphed, sixty times a second. The fill is a gradient in
   user space, not in the shape's own box, which pins the colours to positions on
   the axis — the middle stays apricot while the cone grows out into the clay and
   the stone at the two ends. */
.viz__cone{stroke:var(--terracotta);stroke-width:1.2;stroke-opacity:.5;opacity:.94}
.viz__base{stroke:var(--ink-faint);stroke-width:1;opacity:.5}
/* short, because the cone sweeps past a dot in a fraction of a second and a
   long fade would leave the whole edge of it permanently half-lit */
.viz__dot{transition:fill .3s var(--ease),stroke .3s var(--ease),opacity .3s var(--ease)}
.viz__dot.is-in-reach{fill:var(--terracotta);stroke:none;opacity:.92}
.viz__dot.is-out{fill:none;stroke:var(--tan);stroke-width:1.5;opacity:.85}
/* the two ends of the axis used to carry small-caps labels here; the standfirst
   explains what the position along it means, so they said it twice */

/* --- the running count ---------------------------------------
   The cone opens and closes on its own, so there is no control to sit beside;
   the count is the only thing under the drawing and it runs the left edge.
   `tabular-nums` is load-bearing: the number changes every few frames and
   proportional figures would make the line twitch sideways as it counts. */
.viz__readout{
  margin:clamp(1.1rem,2.2vw,1.7rem) 0 0;
  /* .45rem, not .9: the figure and the line it belongs to now read as one
     statement, and the wide gap left the number looking like a separate mark */
  display:flex;align-items:baseline;flex-wrap:wrap;gap:.2rem .45rem;
}
.viz__n{
  font-family:var(--serif);font-style:italic;color:var(--terracotta);
  font-size:clamp(1.9rem,1.5rem + 1.6vw,2.6rem);line-height:1;
  font-variant-numeric:tabular-nums;min-width:2.4ch;
}
/* bold, so the sentence carries the same weight as the figure in front of it */
.viz__nl{color:var(--ink-soft);font-size:.875rem;line-height:1.5;font-weight:700}
/* it used to be held on one line by white-space:nowrap, with a query at 400px
   letting it break. The line is longer now and bold on top of that, so it runs
   past the panel on every phone rather than only the narrowest ones; it wraps
   on its own instead. align-items:baseline keeps its first line on the figure's
   baseline whether it takes one row or two. */

/* --- the line out of the panel -------------------------------
   Serif, a step under .sec-head__t, centred over the Featured strip that
   follows it. One sentence per line: they are a problem and its answer, and a break in
   the middle of either would blur which is which. The break is the markup's, not
   the measure's — .closer__line is a block — and 58ch is only the ceiling that
   keeps each sentence off a second row wherever the viewport can hold it. Under
   about 600px it can't, and the sentences wrap as any other line would. */
.closer{
  margin:clamp(1.8rem,3.4vw,2.8rem) auto 0;max-width:58ch;text-align:center;
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.35rem,1.05rem + 1.35vw,2.1rem);
  line-height:1.2;letter-spacing:-.024em;
}
.closer__line{display:block}
/* the offer, in the handwriting the panel opened with. display:block is what
   puts it on its own line under the sentence without a <br>, and the tilt is
   the same -2deg .viz__hand carries so the two read as one hand. */
.closer__hand{
  display:block;font-family:var(--script);color:var(--terracotta);
  font-size:clamp(2.2rem,1.7rem + 1.7vw,3.2rem);line-height:1.05;
  margin-top:.35rem;transform:rotate(-2deg);
}

/* ======================== FEATURED =========================== */
/* a hairline, then the label and the marks sharing one baseline row */
.featured{
  margin-top:clamp(2.4rem,4.4vw,3.6rem);
  padding-top:clamp(1.5rem,2.8vw,2.2rem);
  border-top:1px solid var(--hairline);
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  gap:clamp(1.6rem,4.2vw,3.6rem);
}
.featured__ttl{
  font-family:var(--serif);font-style:italic;font-weight:400;
  font-size:clamp(1.5rem,1.235rem + .975vw,2.2rem);
  line-height:1;letter-spacing:-.01em;color:var(--ink);
}
.featured__in{
  display:flex;align-items:center;
  gap:clamp(1.6rem,4.2vw,3.6rem);flex-wrap:wrap;
}
/* the marks are links now — a{color:inherit} in the reset does not
   strip the UA underline, and on the BBC blocks it would sit across
   the knocked-out letters */
.logo-mark{color:var(--ink);opacity:.78;transition:opacity .4s var(--ease);line-height:1;text-decoration:none}
.logo-mark:hover,.logo-mark:focus-visible{opacity:1}
/* Stylist — high-contrast didone, spaced */
.logo-mark--stylist{
  font-family:var(--serif);font-weight:500;font-style:italic;
  font-size:clamp(1.755rem,1.3rem + 1.885vw,2.925rem);
  letter-spacing:.06em;text-transform:uppercase;
}
/* HuffPost — heavy italic sans between rules */
.logo-mark--huff{
  font-family:var(--cond);font-weight:600;font-style:italic;
  font-size:clamp(1.755rem,1.3rem + 1.885vw,2.925rem);
  letter-spacing:-.012em;text-transform:uppercase;
  display:inline-flex;align-items:center;gap:.2em;
}
.logo-mark--huff::before,.logo-mark--huff::after{
  content:"";width:.13em;height:.82em;background:currentColor;
}
/* BBC — three boxed letters */
.logo-mark--bbc{
  display:inline-flex;gap:.14em;
  font-family:var(--cond);font-weight:600;
  font-size:clamp(1.495rem,1.105rem + 1.625vw,2.47rem);text-transform:uppercase;
}
.logo-mark--bbc span{
  background:var(--ink);color:var(--cream);
  padding:.15em .28em;line-height:1;letter-spacing:.02em;
}
/* the press line in compact form: one row, no plaque. the hero scales these
   back up through .hero__press.pressrow above; the standalone .featured strip
   further down keeps the larger base sizes. */
.pressrow{display:flex;align-items:center;flex-wrap:wrap;gap:clamp(1.1rem,2.6vw,2.2rem)}
.pressrow__t{
  font-family:var(--serif);font-style:italic;font-weight:400;line-height:1;
  font-size:clamp(.87rem,.81rem + .28vw,1.02rem);color:var(--ink);white-space:nowrap;
}
.pressrow .logo-mark--stylist,
.pressrow .logo-mark--huff{font-size:clamp(1.02rem,.9rem + .6vw,1.44rem)}
.pressrow .logo-mark--bbc{font-size:clamp(.82rem,.74rem + .44vw,1.16rem)}

/* ======================== SERVICES =========================== */
.services{padding:clamp(2.75rem,5.5vw,4.75rem) 0;background:var(--white)}
.sec-head{margin-bottom:clamp(3rem,6vw,5rem)}
.sec-head__t{
  font-family:var(--serif);font-size:clamp(1.85rem,5.6vw,5rem);
  line-height:1.03;letter-spacing:-.032em;white-space:nowrap;
}
.sec-head__t em{font-style:italic;color:var(--terracotta)}
.sec-head__side{
  align-self:end;text-align:right;margin:0;
  font-family:var(--cond);font-size:1.0625rem;letter-spacing:.04em;
  line-height:1.5;color:var(--ink-faint);text-transform:none;
}

.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.1rem,1.8vw,1.6rem);align-items:stretch}
.card{
  position:relative;display:flex;flex-direction:column;
  background:var(--paper);border:1px solid var(--hairline);border-radius:6px;
  padding:clamp(2rem,3vw,2.9rem) clamp(1.6rem,2.4vw,2.4rem) clamp(1.8rem,2.6vw,2.5rem);
  transition:transform .55s var(--ease),box-shadow .55s var(--ease),border-color .55s var(--ease),background .55s var(--ease);
  overflow:hidden;
}
.card::before{
  content:"";position:absolute;top:0;left:0;right:0;height:2px;background:var(--apricot);
  transform:scaleX(0);transform-origin:left;transition:transform .6s var(--ease);
}
/* the .services prefix is load-bearing: the cards also carry .rv, and
   .rv.is-in{transform:none} sits later in the sheet — at equal specificity it
   would win and the lift would never happen. .card--feature:hover has to climb
   with it, otherwise the white background here outranks the dark one there. */
.services .card:hover{transform:translateY(-8px);box-shadow:0 40px 70px -46px rgba(83,79,81,.6);border-color:transparent;background:var(--white);transition-delay:0s}
.card:hover::before{transform:scaleX(1)}
.card--feature{background:var(--ink);border-color:var(--ink);color:var(--cream)}
.services .card--feature:hover{background:var(--ink-deep);border-color:var(--ink-deep)}
.card--feature .card__num{color:rgba(237,165,125,.9)}
.card--feature .card__meta{color:rgba(245,242,241,.78);border-color:rgba(245,242,241,.2)}
.card--feature .card__body{color:rgba(245,242,241,.94)}
.card--feature .ulink{color:var(--apricot)}

.card__top{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;margin-bottom:1.6rem}
.card__num{font-family:var(--serif);font-style:italic;font-size:1.75rem;line-height:1;color:var(--apricot)}
.badge{
  font-family:var(--cond);font-weight:500;font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;
  background:var(--apricot);color:var(--ink-deep);padding:.42em .9em;border-radius:999px;line-height:1;white-space:nowrap;
}
.card__title{
  font-family:var(--serif);font-size:clamp(1.5rem,1.25rem + .9vw,2.05rem);
  line-height:1.06;letter-spacing:-.025em;text-transform:uppercase;
  min-height:2.12em;   /* two lines, so the rules below align across cards */
}
.card--feature .card__title,.card__title{text-transform:uppercase}
.card__meta{
  display:inline-flex;align-items:center;gap:.6rem;margin-top:1rem;padding-top:.9rem;
  border-top:1px solid var(--hairline);width:100%;
  font-family:var(--cond);font-weight:400;font-size:.875rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);
}
.card__body{margin-top:1.5rem;font-size:.9875rem;line-height:1.76;color:var(--ink-soft);flex:1}
.card__body p+p{margin-top:1em}
.card__foot{margin-top:2rem}
/* the "Read more" control belongs to the phone layout alone — side by side the
   three cards are already one screen and there is nothing to save. The rules
   that switch it on are in the 640px block at the foot of the sheet. */
.card__more{display:none}

/* ======================== LOVE NOTES ========================= */
.notes{background:var(--sand);padding:clamp(2.75rem,5.5vw,4.75rem) 0;position:relative;overflow:hidden}
.notes::before{
  content:"";position:absolute;inset:auto -10% -30% auto;width:46vw;aspect-ratio:1;
  border-radius:50%;background:radial-gradient(circle,rgba(237,165,125,.34),transparent 66%);
}
.notes__head{
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(.5rem,1.2vw,.9rem);margin-bottom:clamp(2.6rem,5vw,4rem);position:relative;
}
.notes__title{
  font-family:var(--script);font-size:clamp(3.2rem,2rem + 5vw,6.4rem);
  color:var(--terracotta);line-height:.85;transform:rotate(-2deg);display:inline-block;
}
.notes__sub{
  font-family:var(--cond);font-weight:500;font-size:clamp(.875rem,.82rem + .24vw,1rem);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);
}

/* ---- coverflow carousel ---- */
.slider{position:relative;max-width:1100px;margin-inline:auto}
.cf{
  display:grid;position:relative;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 15%,#000 85%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 15%,#000 85%,transparent 100%);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%;mask-size:100% 100%;
}
.cf-item{
  grid-area:1/1;justify-self:center;width:min(54%,600px);margin:0;
  background:var(--paper);border-radius:6px;
  padding:clamp(1.7rem,2.9vw,2.7rem);
  display:flex;flex-direction:column;
  box-shadow:0 44px 84px -62px rgba(83,79,81,.75);
  transition:transform .75s var(--ease),opacity .75s var(--ease);
  will-change:transform,opacity;
}
.cf-item:not(.is-active){cursor:pointer}
/* pre-JS default. go() inline-styles the whole stack, but it only runs with the
   script at the foot of the page — until then every card sits in the same grid
   cell untransformed and the LAST one in the DOM paints on top, so the slider
   opened on the wrong quote. The scroll reveal normally covers that (.slider is
   .rv, opacity:0 until it enters the viewport), but under prefers-reduced-motion
   .rv is opaque from the first frame and the flash was on show. */
.cf-item:not(:first-child){opacity:0}
.quote-card__pull{
  font-family:var(--serif);font-style:italic;
  font-size:clamp(1.15rem,.98rem + .8vw,1.65rem);
  line-height:1.26;letter-spacing:-.022em;position:relative;padding-top:.7em;
}
.quote-card__pull::before{
  content:"\201C";position:absolute;top:-.1em;left:-.06em;
  font-size:3.2em;line-height:1;color:var(--apricot);opacity:.5;font-style:normal;
}
/* the body is what sets the card's height — .9125rem at 1.8 ran the longest
   quotes well past a screen, so both it and the leading come down a step */
.quote-card__body{
  margin-top:1.15rem;font-size:.875rem;line-height:1.7;color:var(--ink-soft);flex:1;
}
.cf-item--long .quote-card__body{font-size:.82rem;line-height:1.66}
.cf-item--long .quote-card__pull{font-size:clamp(1.05rem,.92rem + .68vw,1.5rem)}
.quote-card__body p+p{margin-top:1em}
.quote-card__who{
  margin-top:1.5rem;padding-top:1.2rem;border-top:1px solid var(--hairline);
  display:flex;align-items:baseline;gap:.9rem;flex-wrap:wrap;
}
.quote-card__initials{font-family:var(--serif);font-size:1.35rem;letter-spacing:.06em}
.quote-card__loc{font-family:var(--cond);font-weight:400;font-size:.875rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
.slider__ui{display:flex;align-items:center;justify-content:center;gap:1.6rem;margin-top:clamp(2rem,3.6vw,2.8rem)}
.sbtn{
  width:52px;height:52px;border-radius:50%;border:1px solid var(--hairline);
  background:transparent;color:var(--ink);cursor:pointer;display:grid;place-items:center;
  transition:background .4s var(--ease),border-color .4s var(--ease),color .4s var(--ease);
}
.sbtn:hover{background:var(--ink);border-color:var(--ink);color:var(--cream)}
.dots{display:flex;gap:.6rem}
.dot{width:7px;height:7px;border-radius:50%;border:0;padding:0;background:var(--ink-faint);cursor:pointer;transition:.4s var(--ease)}
.dot[aria-current="true"]{background:var(--terracotta);width:26px;border-radius:999px}

/* ABOUT — the .about / .collage / .plaque rules stood here and went with the
   section they styled; see Backup/für später zur seite gelegt/. The love notes
   above now hand straight over to the CTA. */

/* =========================== CTA ============================= */
.cta{background:var(--apricot);color:var(--ink-deep);position:relative;overflow:hidden}
.cta::before{
  content:"";position:absolute;inset:-40% -10% auto auto;width:52vw;aspect-ratio:1;border-radius:50%;
  background:rgba(255,255,255,.24);
}
/* the band is shorter than it was — 2.5/5rem of air at the top and 5/8.5 at the
   foot left the three buttons floating in the middle of an orange field. The
   foot still carries more than the head: it is the last thing before the dark
   footer and needs the room to land. */
.cta__in{padding:clamp(1.9rem,3.8vw,3.2rem) 0 clamp(3.4rem,6.8vw,5.8rem);position:relative;text-align:center}
/* white, not --ink-deep: it is the handwriting that opens the band, and against
   the apricot it should read as the light thing on top of the field rather than
   as another line of dark type. The question under it keeps --ink-deep — it is
   the sentence that has to be read, and the two are not meant to weigh the
   same. Same at every width; nothing about the ground changes on a phone. */
.cta__script{
  font-family:var(--script);font-size:clamp(2.6rem,1.7rem + 3.8vw,5rem);
  line-height:.9;transform:rotate(-2deg);display:inline-block;color:var(--white);
}
/* 44ch, not 26: the break is the markup's now (.cta__l is a block, one clause
   each) and the measure only has to be wide enough to let each clause stand on
   its own row. Under about 600px it isn't, and they wrap as before. */
.cta__q{
  font-family:var(--serif);font-size:clamp(1.6rem,1.15rem + 1.9vw,2.85rem);
  line-height:1.16;letter-spacing:-.026em;max-width:44ch;margin:clamp(1.4rem,2.6vw,2rem) auto 0;
}
.cta__l{display:block}
/* three equal routes out of the page, side by side */
.cta__btns{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;
  gap:clamp(.8rem,1.6vw,1.4rem);
  margin-top:clamp(2.2rem,4vw,3.2rem);
}
.cta__btns .btn{text-align:center}
@media (max-width:1080px){
  .cta__btns{flex-direction:column;align-items:center}
  .cta__btns .btn{width:min(100%,26rem);justify-content:center}
}

/* ========================= FOOTER ============================ */
.foot{background:var(--ink-deep);color:#FFFFFF;padding:clamp(2.75rem,5.5vw,4.25rem) 0 1.75rem}

/* ======================== REVEALS ============================ */
.rv{opacity:0;transform:translateY(28px);transition:opacity .95s var(--ease),transform .95s var(--ease)}
.rv.is-in{opacity:1;transform:none}
.rv-d1{transition-delay:.1s}.rv-d2{transition-delay:.2s}.rv-d3{transition-delay:.3s}.rv-d4{transition-delay:.4s}

/* ====================== RESPONSIVE =========================== */
@media (max-width:1080px){
  /* five nav items no longer fit on one line — fold into the full-screen menu */
  .nav__links{
    position:fixed;inset:0 0 auto;top:0;background:var(--cream);
    flex-direction:column;justify-content:center;gap:2rem;height:100dvh;
    clip-path:inset(0 0 100% 0);transition:clip-path .7s var(--ease);margin-bottom:0;
  }
  .nav.is-open .nav__links{clip-path:inset(0 0 0 0)}
  .nav__link{font-size:1.5rem;font-family:var(--serif);letter-spacing:.04em;text-transform:none}
  .burger{display:block;position:relative;z-index:2}
  /* on one column the portrait belongs between the promise and the buttons, but
     it is the grid's second child and sits outside .hero__copy. display:contents
     lifts the copy's four blocks into this flow so the figure can be ordered in
     among them; the blocks keep their own --hero-gap margins, so the flow itself
     runs on gap:0 and the figure carries the same gap as a margin. */
  .hero__grid{
    display:flex;flex-direction:column;align-items:center;gap:0;text-align:center;
    /* .hero__copy is display:contents below and so establishes no container —
       the wordmark measures against the grid instead, same width up to 36rem */
    container-type:inline-size;
  }
  .hero__copy{display:contents}
  /* width:100% is required, not cosmetic: align-items:center would otherwise
     size each block to its content */
  .hero__t,.hero__line,.hero__cta,.hero__press{width:100%;max-width:36rem}
  /* past 36rem of container the blocks stop growing, so the wordmark caps with
     them: 36rem × 10.35% is the 59px that 10.35cqi would have given at that width */
  .hero__t{order:1;font-size:min(10.35cqi,59px)}
  .hero__line{order:2}
  .hero__cut{order:3;margin:var(--hero-gap) auto 0}
  .hero__cta{order:4;justify-content:center}
  .hero__press{order:5;justify-content:center}
  .hero__cut img{height:clamp(345px,48vh,483px)}
  /* upright the discs are otherwise too big for the area */
  .hero__glow i{max-width:420px;max-height:420px}
  .hero__glow i:nth-child(1),.hero__glow i:nth-child(3){width:58vw;height:58vw}
  .hero__glow i:nth-child(2),.hero__glow i:nth-child(4){width:52vw;height:52vw}
  .cards{grid-template-columns:1fr;max-width:640px;margin-inline:auto}
  .sec-head{grid-template-columns:1fr;gap:1.6rem}
  .sec-head__t{white-space:normal}
  .sec-head__side{justify-self:start;text-align:left}
  .cf-item{width:min(78%,600px)}
}
@media (max-width:860px){
  .stats__grid{grid-template-columns:1fr 1fr}
  .stat:nth-child(3)::before,.stat:nth-child(4)::before{top:0;bottom:0}
  .stat:nth-child(3)::after{
    content:"";position:absolute;left:0;right:0;top:0;height:1px;background:rgba(255,255,255,.34);
  }
  .stat:nth-child(4)::after{
    content:"";position:absolute;left:0;right:0;top:0;height:1px;background:rgba(255,255,255,.34);
  }
  .stat:nth-child(3)::before{display:none}
  .intro__top{grid-template-columns:1fr;gap:2.4rem}
  .intro__cut{max-width:380px;margin-inline:auto}
  /* the wide block's top margin exists to clear the portrait cell beside it.
     Stacked, there is nothing to clear — it simply follows the paragraph above
     in the same column, so the margin read as a hole in the middle of the copy.
     Dropping it leaves the preceding p's own margin-bottom doing the spacing,
     which is the same rhythm as every other paragraph break in the section. */
  .intro__body--wide{margin-top:0}
  .cf-item{width:min(88%,600px)}
  .cf{
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 8%,#000 92%,transparent 100%);
            mask-image:linear-gradient(90deg,transparent 0,#000 8%,#000 92%,transparent 100%);
  }
  .foot__grid{grid-template-columns:1fr 1fr}
  .foot__brand{grid-column:1/-1}
}
@media (max-width:640px){
  .hero{padding-top:clamp(7rem,20vh,9rem)}
  .hero__cta .btn{width:100%;justify-content:center}
  .hero__press{gap:1.1rem}
  /* on a phone the long quotes ran taller than the screen. the body drops
     another step, the card's padding and rules close up with it, and the
     --long variants are named too — they are two classes deep and a media
     query adds no specificity, so they would otherwise win on their own size. */
  .cf-item{padding:1.35rem 1.25rem 1.45rem}
  .quote-card__pull,
  .cf-item--long .quote-card__pull{font-size:1.06rem;line-height:1.3}
  .quote-card__body,
  .cf-item--long .quote-card__body{margin-top:.95rem;font-size:.8125rem;line-height:1.62}
  .quote-card__who{margin-top:1.1rem;padding-top:.9rem;gap:.6rem}
  .quote-card__initials{font-size:1.15rem}
  .quote-card__loc{font-size:.75rem;letter-spacing:.1em}
  /* all three cards sit in the same grid cell and stretch to the height of the
     longest one, so the two shorter notes were left with dead space under them.
     Their type goes up 10% to take some of it back — pull 1.06→1.17rem, body
     .8125→.89rem. The --long card keeps the sizes above; :not() puts these at
     (0,3,0), so they win on specificity as well as on order. */
  .cf-item:not(.cf-item--long) .quote-card__pull{font-size:1.17rem}
  .cf-item:not(.cf-item--long) .quote-card__body{font-size:.89rem}
  /* the drawing ran off the right edge of every phone and had to be dragged
     sideways to be seen at all. The script pulls the columns in below this same
     640px so the picture is 490 units wide instead of 900 — the dots and the
     row spacing keep their size, only the space between the columns closes —
     and the floor comes down with it. 240px is what a 320px phone has left
     after the gutter and the panel's own padding, so everything from there up
     now fits in one screen with no scrollbar at all. Narrower than that (a
     folded phone) it still scrolls, and the script opens it on the middle. */
  .viz__svg{min-width:240px}

  /* Only on a phone: the three service cards open on demand, the same control
     as the keynote cards on the speaking page and the offering cards on
     corporate-offerings.html. Stacked, each of these runs eleven to thirteen
     lines of copy, and the three together put three screens between the section
     head and the love notes — read straight through, the reader has chosen none
     of it. Clipped, the section is a list of three offers again and the copy is
     there for whichever one is theirs.
     --cline is one line box of .card__body — its .9875rem size times its 1.76
     leading — so everything below is stated in lines rather than in round rem
     figures that would drift the day that type scale is touched. The copy is cut
     at 6.5 lines and the last 4.5 of those are the fade, so two read clean before
     it opens.
     Unlike the offering cards this needs no measuring — those cut at a bullet,
     which is a position only the browser knows, this cuts at a line, which is
     arithmetic. So the clip lives here and the script only adds
     .card--collapsible. Without JS the class never lands, max-height is never
     set, the button stays display:none and the card stands whole.
     flex:none undoes the flex:1 above: the body is a growing item in the card's
     column, and an item that is both told to grow and capped by max-height gives
     the column two answers about how tall it wants to be. Nothing is left to
     grow into here anyway — on a phone the cards are one per grid row and each
     is as tall as its own content.
     max-height rather than height because the open state has no number to
     animate to: the script writes the measured pixel height in, lets the
     transition run, then clears it to none so the card can reflow. */
  .card--collapsible .card__body{
    --cline:calc(.9875rem * 1.76);
    --cfade:calc(var(--cline) * 4.5);
    flex:none;position:relative;overflow:hidden;
    max-height:calc(var(--cline) * 6.5);
    transition:max-height .55s var(--ease);
  }
  /* the fade, and it is a mask rather than the gradient overlay the keynote and
     offering cards use. Those paint the card's own colour over the copy at
     rising opacity, which works exactly as long as the thing behind is the
     colour the gradient was mixed from — and on these cards it is not. Card 02
     stands on --ink, every card goes to --white or --ink-deep on :hover, and a
     tap on a phone leaves :hover standing: the ground moved out from under the
     gradient and it showed as a pale rectangle sitting on the copy, with a
     visible edge where it stopped. A mask takes the *copy* to transparency
     instead, so there is nothing to match — it is right on paper, on ink, on
     either hover colour, and on whatever the card is painted next.
     Stated from the bottom up: alpha 1 until 4.5 lines before the cut, then a
     curve down to 0 exactly at the cut. It is a curve rather than the straight
     ramp two stops would interpolate because the eye finds the first few per
     cent of a fade against dark text, so a ramp that idles at the top reads as
     starting a full line late. These bite early, then run near-linear.
     4.5 lines, where the keynote cards use 2.5, and the reason is the paragraph
     break. Card 02's first paragraph runs five lines, so the line standing at
     the cut is not its sixth line at all but the *second paragraph's* first,
     sitting lower for the margin between them — far enough down that a shorter
     fade had barely opened before it reached those glyphs and left them half
     legible and then chopped. Reaching 4.5 lines up, the fade is well past
     halfway by the time it gets there whichever paragraph the line belongs to.
     All three cards take it, not just 02: where the fade opens is what the
     effect looks like, and it should not differ from card to card in one row. */
  .card--collapsible .card__body{
    -webkit-mask-image:linear-gradient(to bottom,
      #000            calc(100% - var(--cfade)),
      rgba(0,0,0,.92) calc(100% - var(--cfade) * .86),
      rgba(0,0,0,.80) calc(100% - var(--cfade) * .71),
      rgba(0,0,0,.62) calc(100% - var(--cfade) * .57),
      rgba(0,0,0,.42) calc(100% - var(--cfade) * .43),
      rgba(0,0,0,.22) calc(100% - var(--cfade) * .29),
      rgba(0,0,0,.06) calc(100% - var(--cfade) * .14),
      transparent     100%);
            mask-image:linear-gradient(to bottom,
      #000            calc(100% - var(--cfade)),
      rgba(0,0,0,.92) calc(100% - var(--cfade) * .86),
      rgba(0,0,0,.80) calc(100% - var(--cfade) * .71),
      rgba(0,0,0,.62) calc(100% - var(--cfade) * .57),
      rgba(0,0,0,.42) calc(100% - var(--cfade) * .43),
      rgba(0,0,0,.22) calc(100% - var(--cfade) * .29),
      rgba(0,0,0,.06) calc(100% - var(--cfade) * .14),
      transparent     100%);
  }
  /* card 02 fades over six lines where 01 and 03 fade over four and a half, and
     the difference is the paragraph break. On 01 and 03 the first paragraph runs
     past the cut, so all six and a half clipped lines are text and the ramp
     spends its whole travel dissolving words. 02's first paragraph stops at five
     lines: the gap after it and the empty half of its short last line fall inside
     the fade, and the ramp spends a fifth of itself on nothing. What reached the
     eye was the last real line still sitting at about 40% — the copy did not
     dissolve, it stopped — with a chopped ghost of the next paragraph under it.
     Starting a line and a half higher spreads the same curve across the five text
     lines that are actually there, so 02 reads like the other two: line two barely
     touched, line five nearly gone, nothing at the cut.
     Set on .card--feature because that is the card the short paragraph is in, not
     because it is the dark one — if that copy is ever rewritten to run past the
     cut, this override is what should go. */
  .card--feature.card--collapsible .card__body{--cfade:calc(var(--cline) * 6)}
  /* open, the copy is whole — a mask cannot be transitioned, so this lands at
     once and the height animation carries the movement */
  .card.is-open .card__body{-webkit-mask-image:none;mask-image:none}
  /* the control. It says what it does, in the card's own button styling, but it
     is not the card's call to action — "Tell me more!" under it is — so it is
     shrunk out of the way rather than stretched across the card: type and
     padding down about a fifth from .btn's own, and the width left to the label
     so the pill is as wide as the two words and no wider, centred under the
     fade. Full width in the standard size it read as the louder of the two
     controls, which is backwards. */
  .card--collapsible .card__more{display:flex;justify-content:center;margin-top:1rem}
  .card--collapsible .card__foot{margin-top:1.4rem}
  /* 02 again, and again the paragraph break. Its last line inside the clip is
     the ghost of the second paragraph, faded to almost nothing, so the gap the
     eye measures is not to the bottom of the box but to the last line it can
     actually read — about a line and a half further up than on 01 and 03, and
     the button looked adrift under it. It comes up by the best part of a line;
     not the whole difference, because the ghost is still there and the button
     should not sit on top of it. */
  .card--feature.card--collapsible .card__more{margin-top:.25rem}
  .card__more .btn{
    padding:.72em 1.55em;font-size:.75rem;letter-spacing:.14em;gap:.55em;
  }
  /* .btn--ghost is dark ink on a light ground; on the dark card that is
     invisible, so both the label and the hairline invert */
  .card--feature .card__toggle{--fg:var(--cream);border-color:rgba(245,242,241,.34)}
  /* .btn slides its arrow sideways on hover, which reads as "onward" — wrong for
     a control that opens the box you are standing in. It nods down instead, and
     turns over once the copy is out. */
  .card__toggle .arw{transform:none}
  .card__toggle:hover .arw,.card__toggle:focus-visible .arw{transform:translateY(3px)}
  .card.is-open .card__toggle .arw{transform:rotate(180deg)}
  .card.is-open .card__toggle:hover .arw,
  .card.is-open .card__toggle:focus-visible .arw{transform:rotate(180deg) translateY(3px)}

  /* the card's hover state comes off on a phone. There is no pointer to hover
     with, but a tap sets :hover anyway and leaves it set until something else is
     touched — so opening a card lifted it, dropped a shadow under it and
     repainted its ground (--white, or --ink-deep on 02), and the card the reader
     had just tapped was the one that looked different from the other two for the
     rest of the visit. The lift and the shadow are a pointer's feedback and a
     phone has its own; what is left is the card as drawn. Stated with the same
     selectors as the rules above so it wins on order rather than on weight. */
  .services .card:hover{
    transform:none;box-shadow:none;
    background:var(--paper);border-color:var(--hairline);
  }
  .services .card--feature:hover{background:var(--ink);border-color:var(--ink)}
  .card:hover::before{transform:scaleX(0)}

  /* the three routes out of the page stood at the full width of the wrap, which
     on a phone is the screen less the gutter — the pills ran edge to edge and
     the band had no margin left of its own. 85% of that pulls them in by about
     a finger's width each side without touching their height or their type, so
     they still read as the same buttons, just not as a wall. The 26rem ceiling
     from the 1080px block stays: it is what stops them stretching on a tablet. */
  .cta__btns .btn{width:min(85%,26rem)}
  /* the two sentences are a problem and its answer, and above 600px each holds
     one line, so the break between them is obvious without any space. On a phone
     both wrap to two lines at 1.2 leading and the four lines run together as one
     block — the reader can no longer see where the problem stops. Half a line
     between them separates the pair without opening a paragraph gap; it is set
     on the adjacent sibling so the first sentence keeps sitting tight under the
     panel above and the handwriting keeps its own .35rem below. */
  .closer__line + .closer__line{margin-top:.5em}
}
@media (max-width:560px){
  /* the three marks kept their full scale here and ran ~450px wide, so BBC broke
     onto a line of its own. a step down puts all three back on one row; the
     "Featured In" label still wraps above them, which is the intended stack. */
  .featured{gap:1rem}
  .featured__in{gap:clamp(.8rem,3.4vw,1.4rem);justify-content:center}
  .featured .logo-mark--stylist,
  .featured .logo-mark--huff{font-size:clamp(1rem,.55rem + 1.85vw,1.4rem)}
  .featured .logo-mark--bbc{font-size:clamp(.85rem,.47rem + 1.6vw,1.2rem)}
  .foot__grid{grid-template-columns:1fr}
  /* four stacked numerals took most of a phone screen. the 2×2 from 860px holds
     — including its dividers — and is tightened instead: less padding, numerals
     and labels a step down. */
  .stat{padding:clamp(1.1rem,4.2vw,1.5rem) clamp(.4rem,2.2vw,.9rem) clamp(.95rem,3.6vw,1.3rem)}
  .stat{--stat-n:clamp(2rem,1.15rem + 3.4vw,2.6rem)}
  /* the 20ch cap stays — at this size it is what still breaks the two long
     labels over two lines instead of three */
  .stat__l{font-size:.6875rem;letter-spacing:.1em;line-height:1.45;margin-top:.45rem}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  .rv{opacity:1;transform:none}
  /* the notes stagger in on the panel's own reveal rather than on .rv, so they
     need saying separately — with transitions off they would otherwise wait on
     a class that lands with no animation to carry them */
  .viz__note{opacity:1;transform:none}
}
