/* ==========================================================================
   Build Your AI Super Team — page compositions on top of the FGC design system.
   theme.css is the system, carried across verbatim from For Good Club Store.dc.html
   (Direction 02, dark editorial) so it can be re-synced. Everything here is
   either a composition of existing components or a documented gap in them.
   ========================================================================== */

/* The system's course-page pieces (.pull-quote, .badge-pill, .creds-strip)
   read --pg-accent and --pg-pill, which only .course-theme defines. This page
   runs the base dark editorial palette, so those two tokens are completed with
   the studio lime rather than shipping components with dead declarations. */
:root {
  --pg-accent: var(--fgc-lime);
  --pg-pill: rgba(232, 255, 191, 0.14);
}

/* GAP IN THE SYSTEM: there is no dark button for a light ground. .btn--fill is
   cream on black, which disappears on lime. Same idiom as .btn--lime. */
.btn--ink { background: #000; color: var(--fgc-cream); }
.btn--ink:hover { color: var(--fgc-cream); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--fgc-lime); color: #000; padding: 12px 18px;
  font-size: 13px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
}
.skip:focus { left: 12px; top: 12px; color: #000; }

/* ---------- Hero: copy left, registration right ---------- */
.hero__split {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 25rem);
  gap: clamp(28px, 5vw, 72px); align-items: end; width: 100%;
}
.hero__copy { display: grid; gap: 18px; align-content: end; }
.hero__copy .lede { color: rgba(255, 249, 238, 0.86); }
.hero .h1 em { font-style: italic; }

/* ---------- Registration card ----------
   Authored once in a <template> and mounted in the hero and the closing band.
   The plate is lime in both places: the system already styles .bg-lime .field
   and .bg-lime .form-note--ok, so the form was designed for this ground. */
.reg {
  background: var(--fgc-lime); color: #000;
  border-radius: var(--radius-card);
  padding: clamp(20px, 3vw, 30px);
  display: grid; gap: 14px; text-align: left;
}
.reg .field-row { display: grid; gap: 7px; }
.reg label {
  font-size: 11px; font-weight: 500; letter-spacing: 0.16em;
  text-transform: uppercase; color: rgba(0, 0, 0, 0.72);
}
.reg .field { border-color: rgba(0, 0, 0, 0.3); color: #000; background: transparent; }
.reg .field:hover { border-color: rgba(0, 0, 0, 0.55); }
.reg .field:focus { outline: none; border-color: #000; }
.reg .field:focus-visible { outline: 2px solid #000; outline-offset: 2px; }
.reg .field[aria-invalid="true"] { border-color: var(--fgc-orange); border-width: 2px; }
.reg fieldset { border: 0; margin: 0; padding: 0; display: grid; gap: 14px; }
.reg .btn:focus-visible { outline: 2px solid #000; outline-offset: 3px; }
.reg-actions { display: grid; gap: 9px; }
.reg .form-note { color: rgba(0, 0, 0, 0.72); }
/* Errors are never colour alone: a bordered plate, a mark, and live text. */
.reg .form-note--err {
  display: flex; gap: 9px; align-items: flex-start;
  background: #000; color: var(--fgc-cream);
  border-radius: 14px; padding: 12px 14px; font-size: 14px; line-height: 1.45;
}
.reg .form-note--err[hidden] { display: none; }
.reg .form-note--err .mk { flex: 0 0 auto; color: var(--fgc-orange); font-weight: 700; }
.reg-done { display: grid; gap: 8px; }
.reg-done b { font-family: var(--font-serif); font-weight: 400; font-size: clamp(26px, 3vw, 34px); line-height: 1.1; letter-spacing: -0.02em; }
.reg-done span { font-size: 15px; line-height: 1.5; color: rgba(0, 0, 0, 0.75); }
.reg-done:focus { outline: 2px solid #000; outline-offset: 4px; }

/* ---------- Struggle list ---------- */
.loop-list { display: grid; gap: 0; }
.loop-list .fit-item { padding-top: 18px; padding-bottom: 18px; align-items: flex-start; }
.loop-list .fit-item:last-child { border-bottom: 1px solid var(--pg-line); }
.loop-n { flex: 0 0 auto; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--pg-muted); letter-spacing: 0.08em; }

/* ---------- Press band ----------
   The real press artwork, recoloured to a single light grey with its own
   transparency so the row reads as one set rather than eight brand palettes.
   Heights are matched optically, not literally: Whole Foods is a stacked
   lockup and needs roughly twice the height of a single-line wordmark to
   carry the same weight. Opacity is the one number to tune the grey. */
.press { display: grid; gap: 24px; justify-items: center; text-align: center; }
.press-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: clamp(22px, 3.5vw, 44px) clamp(26px, 4vw, 52px);
}
.press-mark { display: flex; align-items: center; }
.press-mark img {
  display: block; width: auto; opacity: 0.68;
  transition: opacity 200ms var(--ease);
}
.press-mark:hover img { opacity: 1; }
.press-mark.vogue img           { height: 26px; }
.press-mark.elle img            { height: 24px; }
.press-mark.elle-decor img      { height: 23px; }
.press-mark.forbes img          { height: 24px; }
.press-mark.marie-claire img    { height: 21px; }
.press-mark.selfridges img      { height: 21px; }
.press-mark.holland-barrett img { height: 19px; }
.press-mark.whole-foods img     { height: 44px; }
@media (max-width: 560px) {
  .press-mark.vogue img { height: 21px; } .press-mark.elle img { height: 19px; }
  .press-mark.elle-decor img { height: 18px; } .press-mark.forbes img { height: 19px; }
  .press-mark.marie-claire img { height: 17px; } .press-mark.selfridges img { height: 17px; }
  .press-mark.holland-barrett img { height: 15px; } .press-mark.whole-foods img { height: 35px; }
}

/* ---------- Review wall ----------
   Masonry via CSS columns so each screenshot keeps its own height. */
.reviews { columns: 1; column-gap: 16px; }
@media (min-width: 760px) { .reviews { columns: 2; } }
@media (min-width: 1100px) { .reviews { columns: 3; } }
.review {
  -webkit-column-break-inside: avoid; break-inside: avoid;
  margin: 0 0 16px; border-radius: var(--radius-img); overflow: hidden;
  background: #fff; border: 1px solid var(--pg-line);
}
.review img { width: 100%; height: auto; display: block; }

/* ---------- Sticky CTA (mobile) ---------- */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  background: rgba(0, 0, 0, 0.94); backdrop-filter: blur(12px);
  border-top: 1px solid var(--pg-line);
  padding: 10px var(--gutter);
  display: none; align-items: center; justify-content: space-between; gap: 14px;
  transform: translateY(110%); transition: transform 320ms var(--ease);
}
.sticky-cta.is-shown { transform: translateY(0); }
.sticky-cta__txt { display: grid; gap: 1px; min-width: 0; }
.sticky-cta__txt b { font-size: 14px; font-weight: 500; letter-spacing: -0.01em; }
.sticky-cta__txt span { font-size: 11px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--pg-muted); }
@media (max-width: 860px) { .sticky-cta { display: flex; } }

/* ---------- Unfinished copy, flagged so it cannot ship by accident ---------- */
.todo {
  display: inline-block; padding: 7px 11px; border-radius: 6px;
  border: 1px dashed var(--fgc-orange); color: var(--fgc-orange);
  font-size: 10px; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase;
}
.ph {
  border: 1px dashed rgba(251, 83, 32, 0.55); border-radius: 12px;
  padding: 20px; display: grid; gap: 6px; color: var(--fgc-orange);
}
.ph b { font-size: 11px; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; }
.ph span { font-size: 15px; line-height: 1.55; color: rgba(255, 249, 238, 0.78); }

/* ---------- Reveal on scroll ----------
   Visible by DEFAULT. The hidden state is only applied once the bootstrap in
   the page confirms IntersectionObserver, so a script failure cannot blank it. */
.rv { opacity: 1; transform: none; }
.js-anim .rv { opacity: 0; transform: translateY(24px); transition: opacity 900ms var(--ease), transform 900ms var(--ease); }
.js-anim .rv.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js-anim .rv { opacity: 1; transform: none; }
}

/* ---------- Mobile: the hero CTA has to clear a 390px viewport ---------- */
@media (max-width: 860px) {
  .hero, .hero--sm { padding-top: 0; }
  .hero__split { grid-template-columns: 1fr; gap: 20px; align-items: start; }
  .hero__body { justify-content: flex-start; padding-top: 22px; padding-bottom: 40px; gap: 20px; }
  .hero__copy { gap: 12px; }
}
@media (max-width: 560px) {
  .hero .h1 { font-size: 34px; line-height: 0.98; letter-spacing: -0.03em; }
  .hero .lede { font-size: 16px; line-height: 1.45; }
  .hero__body { padding-top: 18px; }
  .reg { padding: 18px; gap: 11px; border-radius: 18px; }
  .reg .field { padding: 13px 18px; font-size: 16px; }  /* 16px stops iOS zooming on focus */
  .reg label { font-size: 10px; }
  .reg .btn--block { padding: 15px 20px; font-size: 15px; }
}

/* The system sets .marquee__sep to opacity .35, which lands at 2.9:1. The words
   either side carry real information, so the dividers are lifted to clear AA. */
.marquee__sep { opacity: 0.62; }

/* The width/height attributes carried by these images to prevent layout shift
   are presentational hints that also set CSS height. Without height:auto that
   fixed height wins and the system's aspect-ratio on .img-r never applies, so
   the editorial plates render at full natural height. */
.img-r { height: auto; }

/* ==========================================================================
   SIMPLIFICATION PASS
   The page had accumulated 30+ hairlines: a rule on every section, a rule
   under every head, plus borders on cards, stats, list items, the marquee and
   the footer status bar. When everything is outlined nothing reads as
   structure. Two rules now govern:
     1. A container gets a background OR a border, never both.
     2. Sections are separated by their ground, not by a line.
   ========================================================================== */
.section.rule-top { border-top: 0; }
.marquee { border-top: 0; }
.press.rule-top { border-top: 0; }
/* The numbers are the structure here; the boxes were competing with them. */
.stat { border: 0; background: none; padding: 0; gap: 6px; }
/* Already carries a background, so it does not also need an outline. */
.q-card { border: 0; }

/* ---------- One type scale ----------
   Body copy was being pushed to five sizes with inline overrides. Two sizes
   now: .lede for a section's opening sentence, .body for everything else. */
.lede { font-size: 20px; line-height: 1.5; }
.body { font-size: 17px; line-height: 1.6; }
.pull-quote .h3 { font-weight: 500; }
.pull-quote { display: grid; gap: 14px; margin: 0; }

/* ---------- Layout utilities, so the markup carries no inline type ---------- */
.stack-md { display: grid; gap: 22px; align-content: start; }
.stack-lg { display: grid; gap: 26px; align-content: start; }
.mt-m { margin-top: clamp(28px, 4vw, 44px); }
.mt-l { margin-top: clamp(36px, 5vw, 56px); }
.mt-xl { margin-top: clamp(44px, 6vw, 72px); }
.measure-s { max-width: 26ch; }
.measure-m { max-width: 46ch; }
.measure-l { max-width: 62ch; }

/* The section eyebrow sits opposite the heading and must never wrap onto a
   second line; "Where you are" was breaking after "you". */

/* ---------- Responsive ----------
   The hero splits copy against the registration card. Below ~1024px the copy
   column gets too narrow for a headline set at 6.4vw, so it stacks well before
   the system's own 860px breakpoint. */
@media (max-width: 1024px) {
  .hero__split { grid-template-columns: 1fr; gap: 24px; align-items: start; }
  .hero__body { justify-content: flex-start; padding-top: 28px; padding-bottom: 44px; }
  .hero, .hero--sm { height: auto; min-height: 0; padding-top: 0; }
}
@media (max-width: 700px) {
  .grid--3 { grid-template-columns: 1fr; }
}

/* ==========================================================================
   TYPE SCALE PASS
   The page was rendering 14 distinct sizes. Small text had drifted to five
   near-identical values (10/11/12/13/14) that read as noise rather than
   hierarchy, and there were six separate heading treatments. Collapsed to one
   label size, one body size, and four heading steps.
   ========================================================================== */
.reg label, .todo { font-size: 11px; }          /* was 10, now the label size  */
.numbered__n, .loop-n { font-size: 11px; }      /* was 13, these are labels    */
.form-note, .reg .form-note--err { font-size: 14px; }  /* was 12, read under pressure */
.stat__label { font-size: 15px; }               /* was 14, joins the button size */

/* ---------- Fewer rules again ----------
   A numbered list already separates its items with a numeral and space; the
   hairline under each one was doing the same job a third time. The rule stays
   on .numbered, where it is the system's signature above a column of four. */
.loop-list .fit-item,
#fit .fit-item { border-top: 0; padding-top: 0; }
.loop-list .fit-item:last-child { border-bottom: 0; }
.loop-list { gap: 20px; }
#fit .stack-md > div { gap: 16px; }

/* At 320px the header ran mark + CTA + menu button past the right edge and put
   a horizontal scrollbar on the page. The registration form is the first thing
   on screen and the sticky bar follows it, so the header CTA is redundant on a
   phone that narrow. */
@media (max-width: 400px) {
  .site-header__cta { display: none; }
  .press-row { gap: 18px 22px; }
  .press-mark.holland-barrett img { height: 13px; }
  .press-mark.marie-claire img { height: 15px; }
  .press-mark.selfridges img { height: 15px; }
  .press-mark.whole-foods img { height: 30px; }
}

/* ---------- Section head: eyebrow above the heading ----------
   The system sets .head as a baseline row with the eyebrow opposite the
   title, which squeezed it into two lines at most widths. Stacked, it reads
   as a label on the section and the wrap problem cannot come back. */
.head {
  display: grid; justify-items: start; gap: 14px;
  align-items: start;
}
.head .eyebrow { white-space: normal; }

/* The number is a label at 11px sitting beside 17px copy. Aligning the boxes
   left the numeral floating above the text; aligning the baselines sits it on
   the same line the reader is on. */
.loop-list .fit-item { align-items: baseline; }
.loop-n { flex: 0 0 24px; }

/* ==========================================================================
   THE DECK
   Four open loops as a fanned hand of cards rather than a stacked list. A list
   invites skimming; cards that overlap and arrive one at a time ask to be read
   one at a time. On a phone the same markup becomes a snapping rail, using the
   system's own .rail behaviour, so it is a genuine flip-through with the next
   card peeking to say there is more.
   ========================================================================== */
.deck {
  display: flex; list-style: none; margin: 0; padding: 0;
  align-items: stretch;
}
.deck-card {
  position: relative; flex: 1 1 0; min-width: 0;
  background: var(--pg-alt); border-radius: var(--radius-card);
  padding: 34px 34px 34px 30px; display: grid; gap: 16px; align-content: start;
  /* The overlap is exactly the card's right padding, so a card can never
     cover a neighbour's text, only its gutter. */
  transform: rotate(var(--rot, 0deg)) translateY(var(--ty, 0px));
  transition: transform 420ms var(--ease), box-shadow 420ms var(--ease),
              opacity 620ms var(--ease);
}
.deck-card + .deck-card { margin-left: -30px; }
.deck-card:nth-child(1) { z-index: 1; }
.deck-card:nth-child(2) { z-index: 2; }
.deck-card:nth-child(3) { z-index: 3; }
.deck-card:nth-child(4) { z-index: 4; }
.deck-card:nth-child(5) { z-index: 5; }
.deck-card p { margin: 0; font-size: 17px; line-height: 1.55; }
.deck-n {
  font-size: 20px; font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em; color: var(--pg-muted);
}
/* Straighten and lift the one being read. */
.deck-card:hover, .deck-card:focus-within {
  --rot: 0deg; --ty: -10px; z-index: 9;
  box-shadow: 0 24px 50px -28px rgba(0, 0, 0, 0.9);
}

/* Arrive one at a time as the section comes up. */
.js-anim .deck.rv .deck-card { opacity: 0; --ty: 30px; }
.js-anim .deck.rv.is-in .deck-card { opacity: 1; --ty: 0px; }
.js-anim .deck.rv.is-in .deck-card:nth-child(1) { transition-delay: 0ms; }
.js-anim .deck.rv.is-in .deck-card:nth-child(2) { transition-delay: 110ms; }
.js-anim .deck.rv.is-in .deck-card:nth-child(3) { transition-delay: 220ms; }
.js-anim .deck.rv.is-in .deck-card:nth-child(4) { transition-delay: 330ms; }
.js-anim .deck.rv.is-in .deck-card:nth-child(5) { transition-delay: 440ms; }

@media (max-width: 900px) {
  .deck {
    gap: 14px; overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none; -ms-overflow-style: none;
    padding-bottom: 4px;
    /* let the rail run to the screen edge so the peek reads as "more" */
    margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter);
  }
  .deck::-webkit-scrollbar { display: none; }
  .deck-card {
    flex: 0 0 78%; scroll-snap-align: center;
    margin-left: 0; --rot: 0deg;
  }
  .deck-card + .deck-card { margin-left: 0; }
  .deck-card:hover, .deck-card:focus-within { --ty: 0px; box-shadow: none; }
  .deck:focus-visible { outline: 2px solid var(--fgc-lime); outline-offset: 4px; }
}
@media (max-width: 560px) { .deck-card { flex: 0 0 84%; padding: 24px; } }

@media (prefers-reduced-motion: reduce) {
  .deck-card { transform: none; }
  .deck-card:hover, .deck-card:focus-within { --ty: 0px; }
}

/* ---------- The line that lands, over the picture ----------
   The portrait moved out of the list layout when the deck went full width.
   It carries more here, under the one sentence it actually illustrates. */
.closer {
  position: relative; margin: 0; overflow: hidden;
  border-radius: var(--radius-card);
  min-height: clamp(320px, 46vw, 520px);
  display: flex; align-items: flex-end;
}
.closer__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Tuned so cream type clears AA over the brightest part of this frame. */
.closer::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.92) 0%, rgba(0,0,0,0.72) 38%, rgba(0,0,0,0.4) 70%, rgba(0,0,0,0.25) 100%);
}
.closer__body { position: relative; z-index: 1; padding: clamp(24px, 4vw, 48px); }
.closer .chant { color: var(--fgc-cream); }

/* The footer is now just the wordmark and the legal line, so the wordmark
   centres rather than hanging off the left edge. */
.footer-wordmark { text-align: center; }

/* Framing for the two photographs: keep her face in the upper part of the
   crop so the headline and the quote sit in the clear space below it. */
.hero__img { object-position: 55% 20%; }
.closer__img { object-position: 50% 22%; }

/* ---------- Marquee: close the seam ----------
   The system's track animates from 0 to -50%, which is only seamless when the
   two halves are byte-identical in width. With flex `gap` the midpoint lands
   half a gap early, so the loop jumped every 34 seconds. Carrying the spacing
   on the items themselves instead makes the halves exactly equal. */
.marquee__track { gap: 0; }

/* ==========================================================================
   ROUND FIVE
   ========================================================================== */

/* ---------- Hero framing ----------
   The view shot is a portrait crop in a landscape band, so hold the horizon
   and the figure rather than the sky. */
.hero__img { object-position: 50% 42%; }

/* ---------- Deck cards: make them read as cards ----------
   The surface was --pg-alt on a black ground, a two per cent difference that
   read as nothing. The outline is what does the work here, so this is the one
   place a container carries both a background and a border. */
.deck-card {
  border: 1px solid var(--pg-line);
  background: var(--pg-alt);
}
.deck-card:hover, .deck-card:focus-within {
  border-color: rgba(255, 249, 238, 0.55);
  background: #16160F;
}
.deck-card:hover .deck-n, .deck-card:focus-within .deck-n { color: var(--fgc-lime); }
.deck-n { transition: color 260ms var(--ease); }

/* ---------- Press band: higher up the page, and louder ---------- */
.press-band {
  background: var(--pg-alt);
  border-block: 1px solid var(--pg-line);
  padding-block: clamp(30px, 4.5vw, 52px);
}
.press-band .eyebrow { color: var(--pg-fg); font-weight: 700; letter-spacing: 0.2em; }
.press-band .press-mark img { opacity: 0.82; }
.press-band .press-mark:hover img { opacity: 1; }
.press-band .press-mark.vogue img           { height: 32px; }
.press-band .press-mark.elle img            { height: 29px; }
.press-band .press-mark.elle-decor img      { height: 28px; }
.press-band .press-mark.forbes img          { height: 29px; }
.press-band .press-mark.marie-claire img    { height: 26px; }
.press-band .press-mark.selfridges img      { height: 26px; }
.press-band .press-mark.holland-barrett img { height: 23px; }
.press-band .press-mark.whole-foods img     { height: 52px; }
@media (max-width: 560px) {
  .press-band .press-mark.vogue img { height: 24px; } .press-band .press-mark.elle img { height: 22px; }
  .press-band .press-mark.elle-decor img { height: 21px; } .press-band .press-mark.forbes img { height: 22px; }
  .press-band .press-mark.marie-claire img { height: 19px; } .press-band .press-mark.selfridges img { height: 19px; }
  .press-band .press-mark.holland-barrett img { height: 17px; } .press-band .press-mark.whole-foods img { height: 40px; }
}

/* ---------- The reframe, rebuilt ----------
   The rule down the side of the quote was the loudest thing in a section whose
   job is to land one sentence. It now runs in the order the argument actually
   goes: the diagnosis, the principle, then what has changed. One centred
   column, and the supporting lines set large enough to read as statements
   rather than as footnotes under the headline. */
.reframe {
  display: grid; gap: clamp(24px, 3.5vw, 40px);
  justify-items: center; text-align: center;
}
.reframe__head { display: grid; gap: 18px; justify-items: center; }
.reframe__head .h2--loud { max-width: 18ch; }
.reframe__line {
  margin: 0; font-size: 20px; line-height: 1.5;
  color: var(--pg-muted); max-width: 44ch;
}
.reframe__claim {
  margin: 0; max-width: 26ch; color: var(--pg-fg); font-weight: 500;
}

/* ---------- Portraits, shown whole ----------
   A 2:3 photograph in a 16:6 band shows a face peeking over a crop line. These
   two sit at their own ratio beside the words instead. */
.portrait-say {
  margin: 0; display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(24px, 4vw, 56px); align-items: center;
}
.portrait-say__img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  object-position: 50% 26%; border-radius: var(--radius-card); display: block;
}
.portrait-say figcaption { display: grid; }
.proof-intro {
  display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: clamp(24px, 4vw, 56px); align-items: center;
}
.proof-intro__img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  object-position: 52% 20%; border-radius: var(--radius-card); display: block;
}
@media (max-width: 860px) {
  .portrait-say, .proof-intro { grid-template-columns: 1fr; }
  .portrait-say__img, .proof-intro__img { max-width: 22rem; }
}

/* ---------- Client work: a carousel you click through ----------
   Eight brands in a grid made a wall; as a rail it is one thing at a time and
   the arrows say there is more. 4:3 rather than 4:5, because storefront shots
   are not portraits and the taller crop was blowing them up. */
.carousel { display: grid; gap: 20px; }
.carousel__head { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.carousel__nav { display: flex; gap: 8px; }
.carousel__btn {
  width: 40px; height: 40px; border-radius: 999px; flex: 0 0 auto;
  border: 1px solid var(--pg-line); background: transparent; color: var(--pg-fg);
  display: grid; place-items: center; cursor: pointer;
  transition: border-color 180ms var(--ease), background 180ms var(--ease), opacity 180ms var(--ease);
}
.carousel__btn:hover:not(:disabled) { border-color: var(--pg-fg); background: rgba(255,249,238,0.06); }
.carousel__btn:focus-visible { outline: 2px solid var(--fgc-lime); outline-offset: 3px; }
.carousel__btn:disabled { opacity: 0.3; cursor: default; }
.carousel[hidden-nav] .carousel__nav { display: none; }

.cases {
  display: flex; gap: clamp(14px, 2vw, 22px);
  overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
  scroll-behavior: smooth; padding-bottom: 4px;
  margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter);
}
.cases::-webkit-scrollbar { display: none; }
.cases:focus-visible { outline: 2px solid var(--fgc-lime); outline-offset: 4px; }
.case {
  flex: 0 0 clamp(230px, 25vw, 310px); scroll-snap-align: start;
  display: grid; gap: 10px; align-content: start; text-decoration: none;
  transition: transform 300ms var(--ease);
}
.case__media {
  display: block; overflow: hidden; border-radius: var(--radius-img);
  background: var(--pg-alt); border: 1px solid var(--pg-line);
}
.case__media img {
  width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; display: block;
  transition: transform 600ms var(--ease);
}
a.case:hover .case__media img { transform: scale(1.05); }
a.case:hover { transform: translateY(-4px); }
a.case:focus-visible { outline: 2px solid var(--fgc-lime); outline-offset: 4px; }
.case .eyebrow { margin-top: 4px; }
.case__name { font-size: 20px; font-weight: 500; letter-spacing: -0.015em; color: var(--pg-fg); }
.case__win { font-size: 14px; line-height: 1.5; color: var(--pg-muted); }
@media (prefers-reduced-motion: reduce) { .cases { scroll-behavior: auto; } }

/* ---------- What it's for ---------- */
.life-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 2vw, 20px);
}
@media (max-width: 760px) { .life-grid { grid-template-columns: 1fr 1fr; } .life-grid > :last-child { display: none; } }

/* Seven cases: auto-fit gave five across at 1440, leaving an orphan row of two.
   Capped at four so it breaks 4 + 3. */

/* ==========================================================================
   LOGO RAIL
   Replaces the dates ticker. The roster is the thing worth repeating; the dates
   are on the buttons, in the copy and in the footer already.
   Two rules keep the loop invisible: the spacing rides on the items rather than
   flex `gap`, so half the track is exactly half its width; and the roster is
   repeated four times, so half the track is wider than any viewport and never
   runs out of logos mid-cycle.
   ========================================================================== */
.logo-rail { border: 0; padding: 12px 0 0; }
.logo-rail .marquee__track {
  align-items: center;
  animation-duration: 60s;          /* ~48px a second, a drift rather than a scroll */
  will-change: transform;
}
.logo-rail .press-mark { flex: 0 0 auto; margin-right: clamp(34px, 5vw, 64px); }
.logo-rail .press-mark img { opacity: 0.82; }
/* WCAG 2.2.2: moving content needs a way to stop. Reduced motion halts it
   outright (the system rule), and pointer or keyboard focus pauses it. */
.logo-rail:hover .marquee__track,
.logo-rail:focus-within .marquee__track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .logo-rail { overflow-x: auto; }
  .logo-rail .marquee__track { animation: none; }
}
.press-band__label { text-align: center; }
.press-band { padding-block: clamp(26px, 4vw, 44px); }
.press-band .press { gap: 0; }

/* ---------- Images sized by CSS must release the height attribute ----------
   width/height attributes prevent layout shift but are presentational hints
   that also set CSS height, which beats any aspect-ratio set here. Without
   this the seated portrait rendered at its full 2102px. */
.portrait-say__img,
.proof-intro__img,
.case__media img,
.life-grid img { height: auto; }

/* And a sensible ceiling, so a portrait beside a paragraph stays a portrait
   rather than a poster. */
.portrait-say { grid-template-columns: minmax(0, 0.6fr) minmax(0, 1fr); align-items: center; }
.portrait-say__img { max-width: 24rem; }
.proof-intro { grid-template-columns: minmax(0, 0.55fr) minmax(0, 1fr); }
.proof-intro__img { max-width: 22rem; }
@media (max-width: 860px) {
  .portrait-say, .proof-intro { grid-template-columns: 1fr; }
  .portrait-say__img, .proof-intro__img { max-width: 18rem; }
}

/* ---------- Session icons ----------
   Drawn rather than set: open loops that do not quite meet, uneven radii and
   rounded caps. Cream rather than lime, because lime is the CTA colour and
   these are decoration. They carry no meaning the copy does not already, so
   they are hidden from assistive tech. */
.numbered__icon { display: block; color: var(--fgc-cream); opacity: 0.9; }
.numbered__icon svg { width: 40px; height: 40px; display: block; }
.numbered { gap: 14px; }
@media (max-width: 560px) { .numbered__icon svg { width: 34px; height: 34px; } }

/* ---------- The five layers ----------
   Uses the system's .method-row, which is already a number / title / detail /
   right-aligned meta row and already collapses at 1100px. Figures are UK market
   ranges as of September 2026, sourced from published agency pricing guides;
   they need Kim's sign-off before this goes live. */
.layers { border-bottom: 1px solid var(--pg-line); }
.layers .method-row__title { color: var(--pg-fg); }
.layers .method-row__weeks {
  font-size: 13px; letter-spacing: 0.04em; text-transform: none;
  opacity: 1; color: var(--fgc-lime); white-space: nowrap;
}
/* ---------- Hire it, or build it ----------
   The comparison is the argument, so both figures are set at display size and
   put side by side. Like for like: year one against year one, with the monthly
   price carried in the note rather than compared against an annual total. */
.versus {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(24px, 4vw, 56px); align-items: start;
}
.versus__col { display: grid; gap: 12px; align-content: start; }
.versus__figure {
  margin: 0; font-variant-numeric: tabular-nums; letter-spacing: -0.05em;
  font-size: clamp(44px, 6.5vw, 104px); display: flex; align-items: baseline;
  gap: 0.16em; flex-wrap: wrap;
}
.versus__col--alt .versus__figure { color: var(--fgc-lime); }
.versus__per {
  font-size: 15px; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--pg-muted); white-space: nowrap;
}
.versus__col--alt .versus__per { color: var(--fgc-lime); opacity: 0.75; }
.versus__note { margin: 0; font-size: 17px; line-height: 1.55; color: var(--pg-muted); max-width: 30ch; }
.versus__after { display: grid; gap: 16px; max-width: 62ch; }
@media (max-width: 760px) {
  .versus { grid-template-columns: 1fr; gap: 32px; }
  .versus__figure { font-size: clamp(40px, 13vw, 64px); }
}
@media (max-width: 1100px) {
  .layers .method-row__weeks { text-align: left; margin-top: 2px; }
}

/* ---------- Room to breathe ----------
   The line that lands now has a section to itself. It gets roughly half again
   the usual section padding, the portrait steps back so the sentence leads,
   and the pair sits centred rather than hard against the left edge. */
.breathe { padding-top: clamp(88px, 12vw, 168px); padding-bottom: clamp(88px, 12vw, 168px); }
.breathe .portrait-say {
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 1fr);
  gap: clamp(28px, 6vw, 88px); align-items: center;
  max-width: 68rem; margin-inline: auto;
}
.breathe .portrait-say__img { max-width: 20rem; }
.breathe .chant { max-width: 22ch; }
@media (max-width: 860px) {
  .breathe { padding-top: clamp(56px, 12vw, 88px); padding-bottom: clamp(56px, 12vw, 88px); }
  .breathe .portrait-say { grid-template-columns: 1fr; gap: 28px; }
  .breathe .portrait-say__img { max-width: 16rem; }
  .breathe .chant { max-width: none; }
}

/* The reframe headline is two deliberate lines: the false diagnosis, then the
   real one. Blocks rather than a <br> so the balance algorithm cannot rewrap it. */
.reframe__title span { display: block; }
.reframe__title { text-wrap: normal; }
