/* ==========================================================================
   PAGE-OVERRIDES Page-specific styles only
   No responsive rules here all responsive lives in breakpoints.css
   ========================================================================== */

/* ---------- CONTACT PAGE ---------- */

/* Hero banner. Same band as About, FAQ and poem: the section is listed in the
   shared :is() groups further down rather than given parallel per-page rules, so
   this block holds only what is genuinely different about this banner.

   The source is 2172x724 (aspect 3.000) while the band is pinned to 2170/725
   (aspect 2.993), so the band takes the shared aspect ratio and the image is
   cover-fitted into it. The difference is a quarter of a percent, which is why
   the crop is invisible. */
.contact-hero-media { aspect-ratio: 2170 / 725;}
.contact-hero-bg { height: 100%; object-fit: cover; object-position: center 45%;}

/* The panorama is bright and warm across the whole band, and the header sits on
   its top edge where the sky is, so white header ink needs the veil the poem
   banner gets. About and FAQ have theirs baked into the JPEG and must not be
   given a second one; this source is served as-is, so it is painted in CSS.

   0.59 is the lightest strength that clears AA for every header ink, measured
   per pixel over the cover-fitted image rather than worked out on average: at
   1436px the nav reads 4.55, the logo 5.32 and the h1 5.27. The translucent
   logo tagline is the binding constraint everywhere on this site and sits at
   3.64 here, which is where the FAQ banner (3.68) and the poem banner (3.65)
   already sit. */
.contact-hero-media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgb(4 9 14 / 0.59);
}
.contact-hero-content { z-index: 2;}

/* Contact grid */
.contact-section { background: var(--butter);}

/* ---------- Bands outside the .section class ---------- */
/* Audited all 25 pages for section-level bands whose background was not white.
   These are the ones that escaped .section because they predate it or were
   given their own class: the booking and calendar flows, the intake chat, and
   the standalone checkout page, plus the text-only heroes that had no image to
   cover them and so were showing the ivory body through.

   The photo heroes (.hero--full on index, services, packages, programs and the
   three wellbeing pages, and the .about-hero / .faq-hero / .poem-hero /
   .contact-hero banners) are deliberately left alone. They carry white ink and
   a baked or CSS veil over a photograph; whitening the surface behind them
   would not show through the image, but any edge that ever failed to paint
   would then flash white instead of the intended dark. */
:is(.hero:not(.hero--full), .booking-hero, .cal-hero, .intake-hero, .post-hero,
    .legal-hero, .fine-hero) {
  background: var(--butter);
}
:is(.booking-section, .cal-section, .chat-section) {
  background: var(--butter);
}
/* The seven photo banners keep white, not butter. The image covers the whole band,
   so this is belt and braces against the ground showing at a media edge on a slow
   load, and white is the correct flash for a photograph: a pale yellow sliver
   beside a photo reads as a rendering fault, a white one does not. */
:is(.about-hero, .faq-hero, .poem-hero, .contact-hero, .services-banner, .packages-banner, .resources-banner, .blog-hero) {
  background: var(--white);
}
/* payment.html is a standalone checkout with its own inline token block, so its
   card surface is fixed there (--pay-card) rather than from a rule here. */
#first-step.final-cta { background: var(--butter);}

/* ---------- Section start and end mark ---------- */
/* Every band above now wears the same light yellow, which is the point of the
   change but also its cost: with no tonal difference there is nothing left to
   tell one section from the next, and the page runs together as a single sheet.
   The fix is a hairline bracket. The top rule is the section's start mark, the
   bottom rule is its end mark.

   The rule stays --line. On --butter #FFFFF5 it reads 1.33:1, which is exactly
   what it reads on --white, so the bracket keeps the weight it has always had and
   no second border token is needed. That was not true of the 12% ground this
   replaced: --line dropped to 1.27:1 there, close enough to invisible that it
   would have erased every boundary on the site at the moment the boundaries
   became the only thing telling one band from the next.

   The same class list drives both the mark and the collapse below. It is
   written out longhand twice rather than kept in a custom property, because
   var() cannot be interpolated into a selector. Two copies is the failure mode
   to watch: shortening one and not the other silently doubles or drops every
   boundary on the site, so the lists are identical by inspection. */
:is(.section, .final-cta, #first-step, .booking-section, .cal-section,
    .chat-section) {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
/* One rule per boundary, not two. Adjacent bands each carry their own start and
   end mark, so both land on the shared edge and stack into a 2px band. Dropping
   the second leaves a single hairline that reads at once as the end of the band
   above and the start of the one below.

   The selector has to name both halves of the pair. A bare ".section +
   .section" only caught the one pairing where two .section elements touch, and
   left a doubled line wherever a .final-cta or a page hero sat between two
   content sections.

   .packages-img is in the second list only, and has no mark of its own. It is
   a full-bleed figure band with no background and no padding, so giving it a
   hairline would draw a rule straight across the photograph. Naming it as the
   second half of the pair is what stops the .section above it and the .section
   below it from each claiming the edge and stacking. */
:is(.section, .final-cta, #first-step, .booking-section, .cal-section,
    .chat-section, .packages-img) +
:is(.section, .final-cta, #first-step, .booking-section, .cal-section,
    .chat-section, .packages-img) {
  border-top: 0;
}

/* Form */
.contact-form-wrap {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(28px, 4vw, 44px);
}
.contact-form-header { margin-bottom: 32px;}
.contact-form-header h2 { margin-bottom: 0.3em;}
.contact-form-header p { color: var(--muted); font-size: 0.92rem; margin: 0;}
.contact-form { display: grid; gap: 20px;}
/* The submit button is a direct grid child, so inline-flex on .btn blockifies
   to flex and the initial justify-self of stretch spans the whole column.
   justify-self: start returns it to its content width. Kept in both copies of
   this file (static and theme), and mirrors theme-wp.css:174 which fixed the
   same bug on WordPress as 4.57.0. */
.contact-form > button[type="submit"] { justify-self: start;}
.contact-form .field label {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
/* Padding, border and font are shared, but the height rules below are NOT.
   min-height and resize belong to the textarea alone. Leaving them in this
   shared block forced every single-line input to the textarea's 120px minimum,
   which is why Name, Email and Phone rendered as tall boxes. An input sizes
   itself from its line box, so it needs no minimum at all. */
.contact-form .field input,
.contact-form .field textarea {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--ivory);
  padding: 14px 16px;
  font-family: var(--font-ui);
  font-size: 0.92rem;
  color: var(--charcoal);
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.contact-form .field textarea {
  resize: vertical;
  min-height: 120px;
}
.contact-form .field input::placeholder,
.contact-form .field textarea::placeholder { color: var(--muted); opacity: 0.6;}
.contact-form .field input:focus,
.contact-form .field textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-soft);
}
.contact-form .error { min-height: 1em; color: #b42318; font-size: 0.78rem; margin-top: 4px;}
.btn-full { width: 100%; justify-content: center;}
.contact-form .form-success {
  margin: 0;
  color: var(--gold);
  font-weight: 600;
  font-size: 0.92rem;
  display: none;
}

/* Info cards */
/* minmax(0, 1fr), not the implicit auto track.

   The track had no explicit size, so it resolved to auto, whose floor is
   min-content. Two of the five cards carry an address, and
   Coaching.happiness2u@gmail.com is 356px of unbroken text, so the floor was
   356px while the container was 253px on a 320px phone. The cards ran 103px
   past their own column and were cut off by the body's overflow-x: hidden,
   which meant the full address could not be read or copied at all.

   That clipping was invisible to a scrollWidth check, because the body clip is
   exactly what stops scrollWidth from growing. The overflow had to be found by
   comparing each element's right edge against the viewport. */
.contact-info { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr);}
/* The text half of each card is a bare div, so it is a flex item with the
   default min-width: auto and the same 356px floor. .cic-icon is also a div
   here, and takes width from flex-shrink: 0 with an explicit 44px, so the
   min-width does not disturb it. */
.contact-info-card > div { min-width: 0;}
.contact-info-card {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--ivory);
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.contact-info-card:hover { border-color: var(--gold); box-shadow: var(--shadow-sm);}
.cic-icon {
  width: 44px; height: 44px;
  border-radius: 12px;
  background: var(--stone);
  display: grid; place-items: center;
  color: var(--charcoal);
  flex-shrink: 0;
}
.cic-icon .ph { font-size: 1.4rem; line-height: 1;}

/* The Email card has no icon, on the client's request. Without this its text
   started 60px left of the four cards below it, because the icon column is a
   real flex item: .cic-icon at flex-shrink: 0, plus the card's own gap.
   Reserving exactly that much as padding keeps the five cards on one left edge
   without leaving an empty box where the icon used to be.

   The three steps below track the icon and the card gap in breakpoints.css,
   which is where both are resized:
     above 768px   20px card padding + 44px icon + 16px gap = 80px
     768px and down 14px + 40px + 12px                     = 66px
     320px and down 10px + 32px +  8px                     = 50px

   A single fixed value does not work here. 80px alone left the Email text 14px
   right of the others at 768px and 30px right at 320px, because the reserved
   slot stops matching the icon it stands in for as both shrink. Measured at
   768, 576, 390 and 320 before these steps were added. */
.contact-info-card.cic-no-icon { padding-left: 80px;}

@media (max-width: 768px) {
  .contact-info-card.cic-no-icon { padding-left: 66px;}
}
@media (max-width: 320px) {
  .contact-info-card.cic-no-icon { padding-left: 50px;}
}
.cic-label {
  display: block;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
.cic-value {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  /* break-word rather than anywhere. It is the second half of the fix above:
     the grid and the flex item now allow the card to shrink, but an address has
     no break opportunity in it, so without this the text would still run past
     the card edge. break-word only breaks when the string genuinely cannot fit,
     which at 320px is the address and nothing else. It is preferred to
     anywhere because anywhere also feeds back into min-content sizing, and the
     min-content floor is what caused the fault. */
  overflow-wrap: break-word;
  font-size: 0.95rem;
  color: var(--charcoal);
}
a.cic-value { transition: color 0.3s ease, opacity 0.2s var(--ease);}
a.cic-value:hover { color: var(--gold);}
/* Press, for the same touch reason as .socials a below the footer. These five are
   the phone numbers, the two addresses and the site link on contact.html, and a
   tap on a phone number is exactly the gesture that has to confirm. Dimming
   rather than moving: these are text links on a flat card, so a translate would
   shift the value the visitor is trying to read. */
a.cic-value:active { opacity: 0.6;}
.cic-sub { display: block; font-size: 0.82rem; color: var(--muted); margin-top: 2px;}

/* Socials */
.contact-socials {
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--ivory);
}
.contact-socials .socials { display: flex; gap: 10px; margin-top: 10px;}
.contact-socials .socials a {
  width: 44px; height: 44px;
  border-radius: 12px;
  border: 1px solid var(--line);
  display: grid; place-items: center;
  color: var(--charcoal);
  transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease, transform 0.2s var(--ease);
}
.contact-socials .socials a:hover { background: var(--gold); border-color: var(--gold); color: #fff;}
/* transform joins the transition above so the shared .socials a:active press in
   layout.css eases here instead of snapping. This rule is (0,3,0) and restates
   the whole transition, so without transform in the list it would have quietly
   dropped the property for every social icon on contact.html while the other 23
   pages still had it. Measured across all five sampled pages before and after. */
.contact-socials .socials a:active { transform: scale(0.94);}
.contact-socials .socials a .ph { font-size: 1.35rem; line-height: 1;}

/* ---------- TYPEWRITER ---------- */
/* The caret is white, not var(--charcoal).

   It was a charcoal block, which was right when this ran on a pale .hero
   section, and is wrong now that the heading sits in the blog banner: the band
   carries a 0.55 veil over a bright photograph, so a charcoal block on it is
   darker than its surroundings and reads as a hole rather than a cursor. The
   typed glyphs were already white - they take their colour from the h1 - so it
   was only the caret that disagreed with the text it was attached to.

   blog.html is the only page that carries a .typewriter, so nothing else is
   affected by this. The veil it sits on is measured at .blog-hero-media::before. */
.typewriter { visibility: hidden;}
.typewriter-cursor {
  display: inline-block;
  width: 2px;
  height: 0.9em;
  background: var(--white);
  margin-left: 2px;
  vertical-align: middle;
  animation: blink 0.8s step-end infinite;
}
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0}}

/* ---------- CERTIFICATE CAROUSEL ---------- */
.cert-track:hover { cursor: grab;}
.cert-track:active { cursor: grabbing;}

/* ---------- LEGAL PAGE ---------- */
.legal-hero { padding: 84px 0 40px;}
.fine-hero { padding: 96px 0 56px;}
.page-legal {
  /* TOC column and gap. 812 - 240 - 72 leaves a 500px reading column. At the
     0.95rem body size an average glyph is about 6.9px wide here, which puts the
     fullest line at roughly 77 characters, inside the 65-78 range where the eye
     reliably finds the start of the next line. Measured per character rather
     than estimated from paragraph length divided by line count, which
     under-reports because the last line is normally short. The single 760px
     column this replaced held about 110 characters per line. */
  --legal-toc-w: 240px;
  --legal-gap: 72px;
}
.legal-hero .container, .legal-body .container { max-width: 812px;}
.legal-body { padding-top: 0;}
.legal-body .legal-grid {
  display: grid;
  grid-template-columns: var(--legal-toc-w) minmax(0, 1fr);
  gap: var(--legal-gap);
  align-items: start;
}
.legal-block { scroll-margin-top: 96px;}
/* The three documents used to run together as one undifferentiated wall. A rule
   plus matching space makes the boundaries between them obvious. */
.legal-block + .legal-block {
  margin-top: clamp(48px, 6vw, 72px);
  padding-top: clamp(40px, 5vw, 60px);
  border-top: 1px solid var(--line);
}
#one-on-one, #group-coaching, #financial-coaching, #corporate-wellbeing { scroll-margin-top: calc(var(--header-h, 76px) + 24px);}

/* Comparison tables. DORMANT: packages.html held the last .table-wrap and
   .compare-table on the site, and its seven-row comparison table was removed at
   the client's request once the two pricing cards carried the same rows in
   summary. Nothing matches these selectors today.

   Kept rather than deleted, because the component is sound, its horizontal
   scroll wrapper is the right answer for any wide data table, and it is one class
   away from coming back. The first-child header colour below was corrected while
   the component was still live, so if it returns it returns fixed: see the note on
   that line for what was wrong and why. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 12px; border: 1px solid rgba(0,0,0,.1); box-shadow: var(--shadow-card, 0 8px 30px rgba(0,0,0,.06));}
.compare-table { width: 100%; min-width: 640px; border-collapse: collapse; font-size: 0.95rem; line-height: 1.55; background: #fff;}
.compare-table th, .compare-table td { padding: 14px 16px; text-align: left; vertical-align: top; border-bottom: 1px solid rgba(0,0,0,.08);}
.compare-table thead th { background: var(--charcoal, #1a1a1a); color: #fff; font-weight: 600; font-size: 0.95rem; border-bottom: 0;}
/* #1a1a1a here was the default fallback for --gold, inherited from a build when
   --gold was a pale brass #b8963e and dark text on it was 8.6:1. --gold is now
   #22544C, a dark teal, and that same #1a1a1a on it measured 2.02:1, which fails
   AA on normal text. The fallback was never revisited when the token changed.
   White on the current --gold measures 8.6:1 and gold-soft on it 7.3:1; white is
   used so this header cell matches the white-on-charcoal cells beside it. */
.compare-table thead th:first-child { background: var(--gold, #22544C); color: var(--white, #FFFFFF);}
.compare-table tbody th { font-weight: 700; color: var(--charcoal, #1a1a1a); background: #faf8f3; white-space: normal; width: 16%;}
.compare-table tbody tr:last-child th, .compare-table tbody tr:last-child td { border-bottom: 0;}
.compare-table tbody tr:hover td { background: rgba(184,150,62,.05);}
.compare-table ul { margin: 0; padding-left: 1.1em;}
.compare-table li { margin: 0.25em 0;}
.compare-table strong { color: var(--charcoal, #1a1a1a);}
.legal-block h2 { margin-bottom: 0.5em;}
/* These two rules used to name Bricolage Grotesque explicitly, to route around
   a --font-display token that led with Satoshi. The token leads with Bricolage
   now, so the explicit name is redundant and the inline comment claiming
   otherwise is stale; it is dropped rather than left to mislead the next
   reader. */
.legal-block h3 {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--black);
  margin: 2.2em 0 0.55em;
  scroll-margin-top: 100px;
}
.legal-block h3:first-child { margin-top: 0;}
.legal-block h4 {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  line-height: 1.35;
  color: var(--black);
  margin: 1.6em 0 0.4em;
  scroll-margin-top: 100px;
}
.legal-date { font-size: 0.85rem; color: var(--muted); margin-bottom: 1.2em;}
.legal-copy a { color: var(--gold); text-decoration: underline;}
.legal-copy p { color: var(--charcoal-2); font-size: 0.95rem; line-height: 1.75;}
.legal-copy p + p { margin-top: 1em;}
/* The global reset in design-tokens.css sets list-style: none, and this rule was
   only restoring padding-left, so every list on this page was rendering as an
   indented paragraph with no marker at all. */
.legal-copy ul { list-style: disc; margin: 0.8em 0; padding-left: 1.5em;}
.legal-copy li { color: var(--charcoal-2); font-size: 0.95rem; line-height: 1.7; margin-bottom: 0.45em;}
.legal-copy li::marker { color: var(--gold);}

/* ---------- On this page ---------- */
.legal-toc { position: sticky; top: 104px; align-self: start;}
.legal-toc-title {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 14px;
}
.legal-toc ul { list-style: none; margin: 0; padding: 0;}
.legal-toc li { margin: 0;}
.legal-toc a {
  display: block;
  padding: 6px 0 6px 14px;
  line-height: 1.4;
  color: var(--charcoal-2);
  border-left: 2px solid var(--line);
  transition: color 0.2s ease, border-color 0.2s ease;
}
.legal-toc a:hover, .legal-toc a:focus-visible { color: var(--gold); border-left-color: var(--gold);}
.legal-toc-sub a { padding-left: 26px; font-size: 0.8rem; color: var(--muted);}

/* ---------- SERVICES PAGE ---------- */
.section-head.narrow { max-width: 820px; margin-inline: auto;}
.section-head.narrow .lead { max-width: 640px; margin-inline: auto;}
.section-head.narrow-600 .lead { max-width: 600px; margin-inline: auto;}
.section-head.space { margin-bottom: clamp(32px, 4vw, 56px);}
.section.top-sm { padding-top: 32px;}
.section.top-none { padding-top: 0;}
.center-block { margin-inline: auto;}
.media-ratio { border-radius: var(--radius-md); aspect-ratio: 4/3; object-fit: cover; width: 100%;}
.edi-float-static {
  grid-column: auto;
  grid-row: auto;
  justify-self: end;
  align-self: end;
  position: static;
}
.hidden-more { display: none; margin-top: 32px;}

/* Shared little helpers */
.block-sm { margin-top: 24px;}
.block-md { margin-top: 32px;}
.block-xs { margin-top: 8px;}
.blog-more { margin-top: clamp(32px, 4vw, 56px);}
.note-center { text-align: center; margin-top: clamp(24px, 4vw, 40px);}
.note-center + .cert-slider,
.cert-slider + .note-center,
.cert-slider ~ .note-center { margin-top: clamp(12px, 2vw, 20px);}

/* Testimonial cards */
.quote-mark { color: var(--gold); letter-spacing: 3px; font-size: 1.05rem;}
.quote-text { font-size: 1.5rem; font-style: normal;}
.quote-meta { margin-top: 20px;}
.avatar-round { width: 60px; height: 60px; border-radius: 50%; object-fit: cover;}
.hide-media { aspect-ratio: auto; height: 0; padding: 0; display: block;}

/* Resource cards */
.res-media { aspect-ratio: 3/4; border-radius: var(--radius-md); overflow: hidden;}
.res-media img { width: 100%; height: 100%; object-fit: cover;}
.res-title { margin-bottom: 0.2em;}
.res-desc { margin-top: 12px;}
.res-more { margin-top: auto;}
.res-narrow { max-width: 720px; margin-inline: auto;}
.res-mid { max-width: 900px; margin-inline: auto;}
.section-head.narrow-md { max-width: 720px; margin-inline: auto;}

.container-860 { max-width: 860px;}
.container-720 { max-width: 720px;}
.container-640 { max-width: 640px;}

/* Booking redirect */
/* min-height removed: the hero holds 201px of content, and 60vh plus
   align-items:center left 331px of empty space above and below it. The
   180px/72px padding below already sets the rhythm for this page. */
.booking-hero {
  display: flex;
  align-items: center;
  text-align: center;
}
.booking-title {
  font-size: clamp(2rem, 5vw, 3.5rem);
  margin-bottom: 1em;
}
.booking-link { color: var(--gold); text-decoration: underline;}

.cta-big { padding: clamp(80px, 10vw, 140px) 0;}

/* Mini-cards page overrides base is in layout.css */
.mini-cards.portrait .mini-card .media { aspect-ratio: 3/4; overflow: hidden;}
.mini-cards.portrait .mini-card .media img { width: 100%; height: 100%; object-fit: cover; display: block;}
.mini-card-gap-sm { margin-top: clamp(18px, 3vw, 28px);}
.program-panel .program-body .text-link { margin-top: auto;}

/* Card wrapper helper */
.form-card-box {
  max-width: 560px;
  margin-inline: auto;
  background: var(--ivory);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 4vw, 40px);
}
.field-error { min-height: 1em; color: #b42318; font-size: 0.8rem;}
.form-status-success { margin: 12px 0 0; color: var(--gold, #B9974F); font-weight: 600;}

/* ---- Utility classes (replacing inline styles) ---- */
.mt-1em { margin-top: 1em;}
.mt-1_5em { margin-top: 1.5em;}
.mt-2em { margin-top: 2em;}
.mt-2_5em { margin-top: 2.5em;}
.mb-4px { margin-bottom: 4px;}
.mb-0_6em { margin-bottom: 0.6em;}
.mb-0_8em { margin-bottom: 0.8em;}
.mb-1_5em { margin-bottom: 1.5em;}
.pt-0 { padding-top: 0;}
.center-flex { justify-content: center;}
.text-center { text-align: center;}
.w-full { width: 100%;}
.w-1300 { width: 1300px; max-width: 100%;}
.about-page .story-grid .w-1300 { grid-column: 1 / -1; width: 100%;}

/* Check circle icon in testimonials */
.check-icon { color: var(--gold); font-size: 0.85rem;}

/* Testimonial inline (services page) */
.testi-inline--white { background: var(--white);}

/* Card label + description */
.card-desc { font-size: 0.9rem; color: var(--charcoal-2); line-height: 1.7;}

/* Package card icon */
.pkg-icon { font-size: 1.5rem; color: var(--gold); margin-bottom: 8px; display: block;}

/* Package card foot */
.pkg-foot { text-align: center; margin-top: auto;}

/* Section with no bottom padding */
.section-pt0 { padding-bottom: 0;}

/* Final CTA with rounded corners */
.cta-rounded { border-radius: var(--radius-lg); overflow: hidden;}

/* Services hero section padding override */
.services-hero .section-pad-override { margin-top: 2em;}

.cert-caption {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--charcoal);
  padding: 12px 16px;
  text-align: center;
}

/* Cert slider (home page) */
#credentials.section,
.section:has(.cert-slider) {
  padding-top: clamp(20px, 3vw, 36px);
  padding-bottom: clamp(20px, 3vw, 36px);
}
#credentials .section-head,
.section:has(.cert-slider) .section-head {
  margin-bottom: clamp(8px, 1.5vw, 16px);
}
.cert-slider {
  /* Height of the caption below the certificate, for the current width. Read by
     .cert-arrow so the arrows centre on the image rather than on the image plus
     this. Measured across all six captions at 1200/900/768/600/430/390/360/320:
     one line at 13.6px with a 23.12px line box, so 47px above 768px where the
     captions hold one line, and 70px at and below 768px where the longest of
     them ("Certified Professional Trainer (UKIQ)") wraps to two. The phone step
     overrides it in the media block lower down. */
  --cert-cap: 47px;
  position: relative;
  overflow: visible;
  margin-bottom: 0;
  padding: 0 24px;
  /* 900, not 1060, and this is what makes the arrows mean anything on a desktop.

     The track is this width less the 24px padding either side, so 1060 gave a
     1012px track. The three certificates are 3 x 300px = 900px, which fits
     inside 1012 with 112px to spare, so there was nothing to scroll and
     main.js correctly disabled both arrows. Measured at 1440px: clientWidth
     1012 against scrollWidth 1012, overflow no, both arrows off.

     At 900 the track is 852, the content is 900, and the third certificate
     overhangs by 48px. That is the standard carousel peek: it reads as a strip
     with more behind it rather than as three finished cards, and the arrows now
     have something to do at every width from 1920 down to 320.

     The certificates keep their 300px width either way. Narrowing the frame is
     what forces the overflow; widening the slides would have had the same
     effect while pushing the documents past comfortable reading size. */
  max-width: 900px;
  margin-inline: auto;
}
.cert-track {
  display: flex;
  justify-content: center;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 0;
  scroll-behavior: smooth;
}
.cert-track::-webkit-scrollbar { display: none;}
.cert-slide {
  flex: 0 0 min(300px, 80vw);
  scroll-snap-align: start;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.cert-slide .cert-view {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--white);
  font-size: 0.85rem;
  font-weight: 600;
  opacity: 0;
  transition: opacity 0.3s ease;
  z-index: 2;
  pointer-events: none;
  cursor: pointer;
}
.cert-slide:hover .cert-view { opacity: 1;}
.cert-slide { position: relative;}
.cert-slide img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: cover;
}
.cert-slide .cert-caption {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--charcoal);
  padding: 12px 16px;
  text-align: center;
}
.cert-arrow {
  position: absolute;
  /* Centred on the CERTIFICATE, not on the slider.

     top: 50% put the arrow on the centre of .cert-slider, and the slider is the
     image PLUS the caption below it, so the arrow landed on the caption's
     midpoint. Measured on index.html, the arrow's vertical centre sat 35px BELOW
     the image's centre at every width from 768 down to 320 - constant, because
     the caption is a fixed string at a fixed size.

     --cert-cap carries the caption's measured height for the current width, set
     on .cert-slider below, and the half of it is taken back off. The caption is
     entirely below the image, so subtracting half its height lands exactly on
     the image's centre at any width.

     The 0px fallback is kept so that if .cert-cap is ever unset the arrow still
     centres on the slider rather than shifting by half of nothing. */
  top: calc(50% - var(--cert-cap, 0px) / 2);
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  min-width: 48px;
  min-height: 48px;
  border-radius: 50%;
  background: #22544C;
  border: none;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
  cursor: pointer;
  display: grid;
  place-items: center;
  color: #fff;
  transition: transform 0.22s ease-out, box-shadow 0.22s ease-out, border-color 0.22s ease-out, color 0.22s ease-out, background 0.22s ease-out, opacity 0.22s ease-out;
  z-index: 2;
  outline: none;
}
.cert-arrow svg {
  width: 18px;
  height: 18px;
  pointer-events: none;
}
.cert-arrow:hover {
  transform: translateY(-50%) scale(1.05);
  /* Gold, not red. This was #b01a00, a dark red, on a button that rests at
     #22544C and carries a GREEN shadow, so the hover was already contradicting
     its own shadow. On a desktop pointer that reads as a mistake. On a phone it
     is worse: a tap leaves :hover applied, so the arrow turned red and STAYED
     red until the user tapped elsewhere. That is the red in the screenshot, and
     it is the only red on this component.
     var(--gold) is the resting fill, so the hover now reads as a lift and a
     deepening rather than as a colour change, which is the same treatment every
     other card hover on the site uses. */
  box-shadow: 0 4px 14px rgba(34, 84, 76,0.35);
  background: var(--gold);
  color: #fff;
}
.cert-arrow:active {
  transform: translateY(-50%) scale(0.97);
  box-shadow: 0 1px 4px rgba(0,0,0,0.1);
  transition-duration: 0.1s;
}
.cert-arrow:focus-visible {
  outline: 3px solid #22544C;
  outline-offset: 3px;
}
.cert-arrow:disabled {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}
.cert-prev-home { left: -6px;}
.cert-next-home { right: -6px;}

/* ---------- Large screens: show the certificates directly ----------

   A carousel is a small-screen affordance. From 1024px up there is room for
   all three certificates side by side, and making the visitor drag a strip to
   reach a third of the evidence on a 27-inch monitor is worse than not offering
   the control at all. So above 1024px the track stops being a scroller: it
   becomes a three-column grid, the arrows are removed, and the certificates
   simply sit there.

   This is the counterpart to the 900px max-width below, and the two are one
   decision. 900px exists only so the three 300px slides overflow and the
   arrows have something to do; here the width goes back to 1060px because
   there is no longer a strip to make scrollable, and the three columns get to
   be as large as the frame allows - about 318px each rather than the 277px a
   900px frame would have forced.

   overflow-x, scroll-snap-type and scroll-behavior all go back to their resting
   values as well. Leaving a scroller behind a grid would leave a horizontal
   scroll region that a keyboard can still focus and that a trackpad can still
   drag, with nothing to see and no arrows to say so.

   The JS keeps running updateDisabled() at this width and will set both buttons
   to disabled, which is now harmless: they are display: none. It is left in
   place rather than special-cased, because the same buttons are the carousel
   controls below 1024px and one code path that always tells the truth about
   scroll position is better than two. */

@media (min-width: 1024px) {
  .cert-slider { max-width: 1060px;}
  .cert-track {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(16px, 2vw, 28px);
    overflow: visible;
    scroll-snap-type: none;
    scroll-behavior: auto;
}
  .cert-slide { flex: none;}
  .cert-arrow { display: none;}
}

@media (max-width: 768px) {
  .cert-slide { flex: 0 0 min(260px, 75vw);}
  .cert-slider { --cert-cap: 70px; padding: 0 4px;}
  .cert-arrow {
    width: 40px;
    height: 40px;
    min-width: 40px;
    min-height: 40px;
}
  .cert-arrow svg {
    width: 16px;
    height: 16px;
}
  .cert-prev-home { left: 0;}
  .cert-next-home { right: 0;}
}

/* Why list margin */
.why-mt { margin-top: 2em;}

/* Services hero scoped to services page only */
.services-hero { position: relative; text-align: center;}
.services-hero .hero-bg img { object-position: center center;}
.services-hero .container { position: relative; z-index: 2;}
.services-hero .eyebrow { color: var(--gold);}
/* Was --gold: a dark teal word inside a white headline on a photograph, 1.43:1
   against the darkest pixel of the banner. The accent span is dropped so the
   headline is one ink, and it inherits the white the rest of the line has. */
.services-hero .em-serif { color: inherit;}
.services-hero .lead { color: rgba(255,255,255,0.85); max-width: 700px; margin-inline: auto;}
.services-hero .display { color: var(--white);}

/* Services card page-specific overrides */
.services-grid .service-card { display: flex; flex-direction: column; height: 100%;}
.services-grid .service-card .body { padding: clamp(20px, 2.5vw, 28px); display: flex; flex-direction: column; gap: 10px; flex: 1;}
.services-grid .service-card .num {
  position: static;
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: var(--gold);
  background: none;
  padding: 0;
  margin-bottom: 4px;
}

/* Shared card inner styles used by BOTH services and packages */
.service-card .body h3 { font-size: 1.2rem; margin-bottom: 0;}
.service-card .body > p { color: var(--charcoal-2); line-height: 1.7; font-size: 0.92rem;}
.service-card .card-block { margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line);}
.service-card .card-label {
  font-weight: 600;
  font-size: 0.75rem;
  margin-bottom: 6px;
  color: var(--gold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.service-card .foot { margin-top: 1.5em; padding-top: 12px; text-align: center;}
.check-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.check-list li {
  padding-left: 1.2em;
  position: relative;
  font-size: 0.88rem;
  line-height: 1.6;
}
.check-list li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--gold);
  font-weight: 700;
}
.card-note { margin-top: 1.5em; font-size: 0.85rem; color: var(--muted);}

/* Packages pricing grid separate from services */
.packages-grid > * { min-width: 0;}
.packages-grid .service-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: 100%;
}
.packages-grid .service-card:hover {
  border-color: var(--gold);
  box-shadow: var(--shadow-soft);
}
.packages-grid .service-card > .body {
  padding: clamp(24px, 4vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}

/* How it works steps */
.step { text-align: center; padding: 1.5em;}
.step-num {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--gold-soft);
  color: var(--gold);
  display: grid;
  place-items: center;
  margin: 0 auto 1em;
  font-weight: 700;
  font-size: 1.1rem;
}
.step h3 { font-size: 1rem; margin-bottom: 0.4em;}
.step p { font-size: 0.9rem; color: var(--muted); max-width: 280px; margin-inline: auto;}

/* ---------- ABOUT: POEM / QUOTE CARD ---------- */
.section.top-xs { padding-top: 24px;}
.poem-card {
  max-width: 860px;
  margin: 0 auto;
  background: var(--stone);
  border-radius: var(--radius-lg);
  padding: clamp(48px, 7vw, 80px) clamp(32px, 6vw, 72px);
  position: relative;
  overflow: hidden;
}
.poem-card .quote-big {
  position: absolute;
  top: 10px;
  left: 24px;
  font-size: 8rem;
  font-family: var(--font-display);
  color: var(--gold);
  opacity: 0.12;
  line-height: 1;
  pointer-events: none;
}
.poem-header { text-align: center; margin-bottom: 2em;}
.poem-body {
  color: var(--ink);
  line-height: 2;
  font-size: 1.05rem;
  max-width: 640px;
  margin: 0 auto;
}
.poem-body p + p { margin-top: 1em;}
.poem-body .poem-em { font-weight: 700; color: var(--charcoal); }

/* Verse lineation, and why it is not a <br>.

   These lines were authored as breaks, and a break is a hard promise that the
   line fits the measure. Measured, the longest of them, "must exist somewhere at
   some time because" in the bold .poem-em face, needs 365px. The poem column is
   84% of the viewport, so it only reaches 365px at a 560px viewport and above.
   Below that every authored line was being broken a second time by the measure,
   and because each line was already full the break fell wherever it had to:
   "Because happiness is a memory" became "Because happiness is a" over
   "memory", "at the same time" became "at the same" over "time", and so on.
   Four orphan words across four stanzas, on every phone.

   A <br> cannot be restyled, so it could only ever be all or nothing: either the
   lineation holds or it is destroyed. Each line is a span instead, which lets CSS
   hold the lineation where it fits and let the text reflow where it does not.
   Inline is the base, so a phone reads the poem as prose and wraps it at the
   measure. The block step at 560px in breakpoints.css puts the breaks back.

   The space between the spans is deliberate. As blocks it collapses and is
   invisible, so the desktop lineation is exactly as it was; as inline it is the
   only thing separating the end of one line from the start of the next, without
   which the lines would run together mid-sentence. */
.poem-line { display: inline; }
.poem-body .poem-cta {
  margin-top: 1.8em;
  font-style: normal;
  color: var(--charcoal);
  font-size: 1.15rem;
  text-align: center;
}
.poem-by {
  margin-top: 2.5em;
  font-size: 0.78rem;
  color: var(--muted);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
}

/* Poem page: caption + attribution sit below the card, outside it */
.poem-attrib {
  max-width: 860px;
  margin: 0 auto;
  text-align: center;
}

/* Poem page: tighten the handoff from the hero into the poem card.
   The two .fine-hero rules that used to sit here are gone rather than left in place.
   The hero is now the shared .poem-hero banner at y=0, exactly as on About and FAQ,
   so there is no .fine-hero on this page for them to match - they were carrying a
   min-height override and a zero h1 margin that the banner does not need, because
   .poem-hero-content centres the heading with auto margins instead. */
body.poem-page #happiness { padding-top: 40px;}
.poem-attrib .poem-caption {
  margin: 1.8em 0 0;
  font-size: 1.15rem;
  line-height: 1.7;
  color: var(--charcoal);
}
.poem-attrib .poem-by { margin-top: 1.4em;}

/* About: testimonial */
.client-quote h2 {
  font-style: normal;
  line-height: 1.6;
}
.client-attribution {
  margin-top: 1.5em;
}
.client-attribution .muted { color: var(--muted);}

/* Commitment grid */
.note-center-lg { text-align: center; margin-top: 48px;}
.head-tight { margin-bottom: 24px;}
.flush-top { padding-top: 0;}
.flush-bottom { padding-bottom: 0;}

/* ---------- BLOG POST PAGE ---------- */
.post-hero { padding: clamp(76px,10vh,132px) 0 clamp(32px,5vh,56px); position: relative; overflow: hidden;}
.post-hero .eyebrow { margin-bottom: 12px;}
/* Hero h1: 50px, the same flat figure index.html's headline sits at from 769px
   up. Was clamp(2rem, 5vw, 3.4rem), which landed at 54.4px at 1296px and made
   this the only page hero on the site that was neither 50 nor 68.7. */
.post-hero h1 { max-width: 800px; font-size: 50px;}
.post-hero .lead { margin-top: 16px; max-width: 640px;}
.post-meta { display: flex; align-items: center; gap: 16px; margin-top: 20px; font-size: 0.82rem; color: var(--muted);}
.post-meta .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--line);}
.post-featured { width: 100%; max-width: 960px; margin: 0 auto; border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 16/9;}
.post-featured img { width: 100%; height: 100%; object-fit: cover;}
.post-body { max-width: 720px; margin: 0 auto;}
.post-body p { margin-bottom: 1.4em; line-height: 1.85; font-size: 1.05rem;}
/* Section level: clamp(1.6rem, 3.1vw, 36px), the shared ladder. Was
   clamp(1.4rem, 2.4vw, 1.8rem), which put every article subhead at 28.8px
   against 36px for every other h2 on the site. line-height 1.0 from .h-section
   is tight for a subhead inside running text, so it keeps 1.15 here. */
.post-body h2 { font-family: var(--font-display); font-size: clamp(1.6rem, 3.1vw, 36px); line-height: 1.15; font-weight: 600; color: var(--black); margin: 2.4em 0 0.8em; letter-spacing: -0.02em;}
.post-body blockquote { border-left: 3px solid var(--gold); padding: 16px 24px; margin: 2em 0; background: var(--stone); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; font-style: normal; color: var(--charcoal);}
.post-body ul, .post-body ol { margin: 1.4em 0; padding-left: 1.4em;}
.post-body li { margin-bottom: 0.6em; line-height: 1.75;}
.post-author { display: flex; align-items: center; gap: 20px; padding: 32px; background: var(--stone); border-radius: var(--radius-lg);}
.post-author img { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; flex-shrink: 0;}
.post-author h4 { font-size: 1rem; margin-bottom: 4px;}
.post-author p { font-size: 0.88rem; color: var(--muted); margin: 0; line-height: 1.6;}
.post-author-stats { display: flex; gap: 16px; margin-top: 8px; font-size: 0.78rem; color: var(--muted);}
.post-author-stats span { display: flex; align-items: center; gap: 4px;}
.post-author-stats strong { color: var(--charcoal);}
/* ---------- Post: comments ----------
   The author card and the comment thread both sit on the same 720px measure as
   .post-body, so the page keeps one vertical edge from the article down. */
.post-aside,
.comments-section { max-width: 720px; margin: 0 auto;}

/* The form was three bare inputs floating between the section heading and the
   thread, with no way to tell where one ended and the other began. It now sits
   in a panel, matching .post-author directly above it, and the thread below
   gets its own ruled heading. */
.comment-form {
  background: var(--stone);
  border-radius: var(--radius-lg);
  padding: clamp(20px, 3vw, 32px);
  margin-bottom: clamp(32px, 5vw, 48px);
}
.comment-form-title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--black);
  margin: 0 0 20px;
}
.comment-form .form-row { margin-bottom: 16px;}
.comment-form .field textarea { min-height: 120px; resize: vertical;}

/* Secondary text inside a label. .no-uppercase only cancelled the uppercase,
   leaving the note at weight 600 so "(not published)" and "(optional)" read as
   part of the field name. This drops it to body weight and italic. */
.field-hint {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  font-style: italic;
  color: var(--muted);
}

/* Submit row. With the note removed only the top offset still does anything;
   the flex/gap pair existed purely to seat that note beside the button. */
.comment-actions { margin-top: 20px;}
.comment-actions .btn { margin: 0;}

/* Thread */
.comment-list-head {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}
.comment-list-title {
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* Was --muted. This is the worst heading-ink case on the site: a real h3 set in
     the body grey at 4.83:1, which read as a caption rather than as a heading
     even though it is the "3 comments" line above the thread. Black like
     everything else. */
  color: var(--black);
  margin: 0;
}
/* The old rule put a border under every item including the last, leaving a
   dangling rule under the final comment. */
.comment-item { padding: 22px 0; border-bottom: 1px solid var(--line);}
.comment-item:last-child { border-bottom: 0; padding-bottom: 0;}
.comment-header { display: flex; align-items: center; gap: 12px; margin-bottom: 10px;}
.comment-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--gold-soft); color: var(--gold);
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-weight: 700; font-size: 0.85rem;
  flex-shrink: 0;
}
/* Stacked name over time. Previously the pair sat on one baseline held apart by
   margin-left, which broke as soon as a name wrapped. */
.comment-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0;}
.comment-name { font-size: 0.92rem; font-weight: 600; color: var(--charcoal);}
.comment-time { font-size: 0.75rem; color: var(--muted);}
.comment-body { font-size: 0.92rem; line-height: 1.7; margin: 0; color: var(--ink); max-width: 62ch;}

.comment-empty {
  color: var(--muted);
  font-size: 0.9rem;
  margin: 0;
  padding: 24px 0;
}
.post-nav a { display: block; padding: 24px; border: 1px solid var(--line); border-radius: var(--radius-md); text-decoration: none; transition: border-color 0.3s ease, box-shadow 0.3s ease;}
.post-nav a:hover { border-color: var(--gold); box-shadow: var(--shadow-sm);}
.post-nav .label { font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px;}
.post-nav .title { font-family: var(--font-display); font-weight: 700; font-size: 1rem; color: var(--charcoal);}
.post-nav .next { text-align: right;}

/* ---------- FAQ ACCORDION ---------- */
.faq-list .faq-item summary { text-align: left;}
/* "Line equally end" formula, synchronized site-wide with My Journey. */
.faq-list .faq-item p { hyphens: manual; }
.faq-item[open] {
  border-color: var(--gold);
  box-shadow: var(--shadow-card);
}
.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  color: var(--charcoal);
  cursor: pointer;
  list-style: none;
  gap: 16px;
  transition: color 0.3s ease;
}
.faq-item summary::-webkit-details-marker { display: none;}
.faq-item summary::after {
  content: "+";
  font-family: var(--font-ui);
  font-size: 1.4rem;
  font-weight: 400;
  color: var(--gold);
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--gold-soft);
  transition: transform 0.3s ease, background 0.3s ease;
}
.faq-item[open] summary::after {
  content: "\2212";
  transform: rotate(180deg);
  background: var(--gold);
  color: var(--white);
}
.faq-item summary:hover { color: var(--gold);}
.faq-item p {
  padding: 0 24px 20px;
  font-size: 0.92rem;
  line-height: 1.7;
  color: var(--charcoal-2);
  margin: 0;
}
.faq-item summary:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: -2px;
}

/* ---------- ABOUT PAGE HERO IMAGE ---------- */
.about-page .hero-visual { max-width: 560px;}
.about-page .hero-figure { aspect-ratio: 4/5;}
.about-page .hero-figure img { transform: scale(1.15);}

/* ---------- INLINE TESTIMONIALS ON SERVICES PAGE ---------- */
.testi-inline {
  background: var(--cream);
  border-radius: var(--radius-md);
  border-left: 3px solid var(--gold);
}

/* ---------- ABOUT PAGE TEXT ---------- */
.about-page .story-grid > div:not(.story-media) { max-width: 100%;}
.about-page .story-grid p { hyphens: manual; font-size: clamp(1.05rem, 1.4vw, 1.2rem); line-height: 1.75; margin-bottom: 1em;}
/* Left and italic, where every other .lead on the site is centred.
   "Good day! I am glad that you landed here to look a little further." is a
   line of address to the visitor, not a section intro, and centred italic body
   copy at this size sets badly - a centred rag makes every line look deliberate
   when none of it is.

   This selector reaches exactly one paragraph. The other three .lead elements on
   about.html sit in .section-head.center, which is where the shared centred
   treatment belongs, and a fourth is display:none in the footer. Scoping to
   .story-grid is what keeps the change to the one line it was asked for, and it
   is why this rides on the existing rule rather than standing alone.

   font-style: italic follows the .field-hint precedent at :1051, the only other
   italic in the stylesheet.

   font-weight: 600 rides alongside it. This line is a greeting and the site's
   only piece of body copy set in the display weight, which is what makes it read
   as an opening line rather than as the first of four paragraphs. 600 is the one
   weight the whole site uses, on every .h-section and .h-display, so it is the
   value that keeps this line consistent with the headings above it.

   It costs nothing in measure: 66px tall over two lines at weight 400, and the
   same two lines at 600, because Manrope runs its weights close at 18.83px. */
.about-page .story-grid .lead {
  hyphens: manual;
  max-width: 100%;
  text-align: left;
  font-style: italic;
  font-weight: 600;
}
/* "About The Mentorship Coach", left aligned with the heading and copy below it,
   and back on the shared eyebrow size.

   Alignment: it was the only centred thing in this column. layout.css:80 sets
   .section .eyebrow to text-align: center outright, and that lands here too, so
   the label sat centred above a left-aligned heading, two left-aligned paragraphs
   and a left-aligned blockquote.

   Size: this rule carried font-size: 0.6rem and letter-spacing: 0.15em, which
   made it 9.6px against 11.52px for the other two eyebrows on the same page,
   "Credentials" and "Ready to Begin". It was the smallest text in the section,
   sitting above a 36px heading, which is not a label an eye can pick up.

   Both are raised to the shared .eyebrow values, 0.72rem and 0.2em, so all three
   eyebrows on this page are one size.

   They have to be stated here rather than inherited. Dropping them was tried and
   the label jumped to 18.83px, because .about-page .story-grid p at (0,2,1)
   matches this <p class="eyebrow"> as well as the body copy, and it outranks the
   shared .eyebrow at (0,1,0). This selector is (0,3,0), which is what lets it
   win. Same reason the original 0.6rem had to be written here.

   This selector reaches one eyebrow: the greeting above it in the first
   .story-grid is a .lead, not an .eyebrow, so nothing else is touched. */
.about-page .story-grid .eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-align: left;
}
/* Dropped: .about-page .section:first-of-type { padding-top: ...} gave the
   opening section extra room under the header. The hero banner now owns that
   job with the same .hero padding every other page uses. The rule had already
   gone inert anyway, because :first-of-type matches the first <section>
   sibling whether or not it carries .section, so the moment a
   <section class="hero"> was added ahead of it nothing matched. */

/* ---------- About hero banner ----------
   Supplied as a standalone 3:1 photograph and used UNCROPPED, on request. That
   matters because the previous asset was a composite graphic whose left panel
   had "My Journey" set at display size plus a body paragraph baked into the
   pixels - two titles fighting this page's own h1, "My Story.". This file is
   the photograph alone, so the heading can be live text again. (The "SAEED UR
   RIAZ" lockup was alpha-keyed out of the old composite as a stopgap, but it
   has since been dropped: the header already carries the name, and repeating
   it here just crowded the card.)

   Shape: full-bleed, edge to edge, starting at y=0 so the fixed header floats
   INSIDE the photograph rather than above it. That is also why the top corners
   are square: no radius on the top-left and top-right, only the bottom pair
   stays rounded, where the band lifts off the page. A rounded top edge would
   frame the header instead of letting it sit on the image.

   The img is width:100%/height:auto so the browser reserves 725/2170 up front
   and nothing below jumps, and so the band inherits the photo's own 3:1 exactly
   rather than being re-proportioned by a fixed height, which would crop it.

   The scrim is a text-protection gradient, not a flat wash: heavier through the
   middle band where the h1 sits, easing off at the edges so the mosque, the
   hills and the city lights stay legible. The top band stays dark for the
   header, which now sits on the image. A uniform overlay dark enough to carry
   white text would flatten the photograph.

   No .hero class: that is a flex container with min-height and tall clamp()
   padding, which would inject empty space and pull the band away from 3:1.

   .faq-hero is the same band on the FAQ page and .poem-hero the same band on
   the poem page, both built from the same source treatment. All three are listed
   in every rule here rather than duplicated into parallel per-page blocks, so the
   banners cannot drift apart. :is() is used deliberately: it takes the
   specificity of its most specific argument, which is a single class here -
   exactly what .about-hero on its own contributed - so widening the selector did
   not quietly change which rule wins. A new banner therefore means adding one
   argument to each of these groups, not writing new CSS. */
:is(.about-hero, .faq-hero, .poem-hero, .contact-hero, .services-banner, .packages-banner, .resources-banner, .blog-hero) {
  padding-top: 0;
}
/* Square at the top pair (flush with the top of the document) and square again
   at the bottom-left; only the bottom-right corner keeps its radius. */
:is(.about-hero-media, .faq-hero-media, .poem-hero-media, .contact-hero-media, .services-banner-media, .packages-banner-media, .resources-banner-media, .blog-hero-media) {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  border-radius: 0 0 clamp(16px, 2.2vw, 32px) 0;
}
:is(.about-hero-bg, .faq-hero-bg, .poem-hero-bg, .contact-hero-bg, .services-banner-bg, .packages-banner-bg, .resources-banner-bg, .blog-hero-bg) {
  display: block;
  width: 100%;
  height: auto;
}
/* Poem banner: the source is 2048x768 (aspect 2.667) while the About and FAQ bands
   are 2170x725 (aspect 2.993). The band is pinned to the shared aspect ratio and the
   image is cover-fitted into it, so all three banners stay the same height. The source
   is only 11% taller per unit width, so the crop trims a little sky and foreground and
   keeps the horizon sitting behind the heading. */
.poem-hero-media { aspect-ratio: 2170 / 725;}
.poem-hero-bg { height: 100%; object-fit: cover; object-position: center 45%;}

/* The source is a bright golden-hour photograph - the heading band peaks at relative
   luminance 0.99 - so it cannot carry white text the way the About and FAQ photographs
   do. A veil is painted over it in CSS at 0.55, lighter than the original 0.65, so the
   photograph reads more clearly. Measured on the cover-fitted pixels that lands the
   0.88-alpha nav at 4.6:1, the wordmark at 4.5:1 and the h1 (large text) at
   4.5:1; the 0.72-alpha tagline sits lower at 3.7:1. The 4.5:1 wordmark figure was
   taken while "Saeed" was --gold-soft and is now a floor rather than a value: the
   wordmark is white on both words, and white sits above pale mint against any dark
   ground (relative luminance 1.0 against 0.842), so this measurement can only have
   got better and cannot have dropped below 4.5:1. About and FAQ already have their
   veil baked into the JPEG and must not be given a second one, so this is scoped to
   .poem-hero only. */
.poem-hero-media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgb(4 9 14 / 0.55);
}
.poem-hero-content { z-index: 2;}

/* Blog banner: the same treatment the poem banner gets, at the same strength.

   The source is another bright golden-hour photograph and it needed it just as
   much. Measured per pixel over the cover-fitted image, before any veil, the
   brightest pixel behind the heading is luminance 0.995 and the brightest pixel
   behind the header is 0.970. White ink on those is 1.00:1 and 1.03:1, so the
   heading was genuinely invisible where it crossed the sun.

   0.55 is the same strength the poem banner uses and it is measured the same
   way, not carried over on faith. At 0.55 the heading lands at 4.47:1 on its
   worst pixel, the 72%-alpha logo tagline at 4.56:1 and the full-ivory nav at
   4.83:1. For reference the same ladder at 0.58 gives 4.98 / 5.06 / 5.36, at
   0.60 it gives 5.35 / 5.44 / 5.76, and at 0.65 it gives 6.44. 0.55 is kept
   over those because the poem banner already sets the precedent for a
   photograph this bright: a lighter veil lets the picture read, and this is
   still AA for large text and AA for the nav.

   It stays a scoped rule rather than an extra argument on a shared group,
   because About and FAQ carry their darkening baked into the JPEG and must
   never be given a second veil. Each veil strength is measured against its own
   file. */
.blog-hero-media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgb(4 9 14 / 0.55);
}
.blog-hero-content { z-index: 2;}
/* No .about-hero-scrim any more, and no .faq-hero-scrim either. The darkening is
   baked into the JPEG itself - a flat veil of rgb(4,9,14) over the whole frame,
   applied to the source PNG before the encode - because the request was for the
   overlay to live in the image, not on top of it. Keeping both would have stacked
   two veils and crushed the photograph to near black. Text protection is the
   file's own job.

   The banners do not all take the same veil strength, and the number is measured
   per file against the inks that actually sit on it rather than picked once.

   How the measurement works, because getting it wrong silently flatters every
   result. A translucent ink composites onto the PHOTOGRAPH, not onto white. The
   0.88-alpha nav link is not "88% white sitting on white", it is white mixed
   into whatever is behind it, so on a mid-tone pixel it comes out darker than
   pure white and its contrast drops. Compositing translucent ink onto a white
   page first reports the ratio for solid ink and overstates the tinted ones.
   Both inks are measured per pixel and the 1st percentile is taken, i.e. the
   worst 1% of the region, rather than trusting a single mean.

   FAQ is baked at 0.70. Its source is a sunset with a genuinely hot sky, p99
   relative luminance 0.74 across the top 100px, and the glow sits on the RIGHT
   of that band, exactly where the header CTA and right-hand nav sit. Measured on
   the shipped pixels: header band worst case 7.81:1 for pure white and 5.91:1
   for the 0.88 tint the nav uses; heading band 7.57:1 and 5.73:1.

   About is baked at 0.55. That number is not a round guess, it is the lightest
   flat veil that clears every header ink on this particular frame, and it is
   lower than it looks like it should be only because the tagline ink was raised
   from 0.72 to 0.88 first. See the rule further down for why that was the lever.

   The source is an illustration rather than a photograph, and it is bright: p99
   relative luminance 0.60 across the header strip and 0.83 across the heading
   band, before any veil at all. Measured on the shipped file at 0.55, worst 1%
   of each region: logo-name and the menu bars 5.60:1, tagline and nav and phone
   4.78:1, h1 white 4.61:1 against 3.0 required. .logo-first measured 4.76:1 as
   --gold-soft and is now the same white as logo-name, so it has no figure of its
   own any more: identical ink on identical ground is an identical ratio, so it
   takes logo-name's 5.60:1. The three that remain clustered within 0.02 of each
   other near 4.78 are tagline, nav and phone, and that clustering is still the
   signature of a veil set by the smallest text rather than by the average
   ground.

   Two earlier values on this same artwork, for anyone tempted to go lighter
   again. At the original 0.72 tagline the file needed 0.62, which rounds up to
   0.65, and at 0.55 that combination FAILED at 3.80:1. So 0.55 was only ever
   legal because of the ink change, not on its own.

   The file before this one was the Islamabad dusk photograph, a much darker
   image that passed at 0.55 on its own with the tagline at 6.92:1. Two files at
   the same veil number can sit at very different contrast, because the number is
   a property of the artwork, not of the rule. Re-measuring is the only way to
   know, which is why these figures are recorded rather than assumed.

   Geometry: the source is 2172x724, aspect 3.0000. The band is 2170x725, aspect
   2.9931, so the frame is taller for its width than the source is. Keep the full
   height and centre-crop the width to 724 * 2170/725 = 2167, then LANCZOS to
   2170x725. Cropping the height instead would have thrown away sky.

   Colour survives the bake: 89% of pixels are still chromatic, mean saturation
   35%, down from 41% in the source. */
:is(.about-hero-content, .faq-hero-content, .poem-hero-content, .contact-hero-content, .services-banner-content, .packages-banner-content, .resources-banner-content, .blog-hero-content) {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: clamp(18px, 2.6vw, 40px);
}
/* margin-top:auto plus margin-bottom:auto each pin half the leftover space,
   which centres the heading vertically in the band, and text-align centres it
   horizontally.

   The old standalone `.about-hero .section-head { margin-bottom: 0}` is gone
   rather than left in place: it matched at the same specificity as this rule
   and appeared later in the file, so it always won and reset margin-bottom,
   which would have silently defeated the vertical centring. */
:is(.about-hero-content, .faq-hero-content, .poem-hero-content, .contact-hero-content, .services-banner-content, .packages-banner-content, .resources-banner-content, .blog-hero-content) .section-head {
  margin-top: auto;
  margin-bottom: auto;
  text-align: center;
}
/* No font-size here on purpose: it comes from the shared .h-display scale, and
   the phone-size override for this heading lives in breakpoints.css. */
:is(.about-hero, .faq-hero, .poem-hero, .contact-hero, .services-banner, .packages-banner, .resources-banner, .blog-hero) h1 {
  margin-top: 0;
  margin-bottom: 0;
  color: var(--white);
  text-align: center;
}
/* A banner eyebrow needed its own ink here for one revision, then the packages
   eyebrow was promoted to the h1 and no banner carries an eyebrow any more.

   Worth keeping the numbers, because the trap is not obvious. An eyebrow's
   default is --gold #22544C, a dark teal, and against the packages banner photo
   it measures 1.00:1. Not "low contrast", but literally nothing: the ink is
   darker than the ground it sits on. .eyebrow.light does not save it either,
   because that modifier is ALSO --gold. --gold-soft #E4EFEB was the fix, at
   5.29:1 for the worst pixel in the whole 2170x725 band and 6.50:1 across the
   top 30% where a centred eyebrow sits. White at 0.88 would have passed too at
   5.27:1; white at 0.72 fails at 4.14:1 and is the header tagline, so the two
   are not interchangeable.

   If a banner ever grows an eyebrow again, put it back with gold-soft and
   re-measure on the shipped JPEG rather than trusting these figures on a
   different photograph. */

/* ---- Header inside the banner, white "until" ----
   .about-hero starts at y=0, so the fixed header now floats ON the hero rather
   than above it. The default header ink (--charcoal / --gold / --muted) is
   invisible against the dark wordmark plate, so while the header has NOT yet
   picked up .scrolled - animations.js sets that at y > 10 - every link, the
   wordmark and the hamburger bars go white. The moment it scrolls, the frosted
   light bar returns and the dark ink comes back with it, which is the "until"
   part.

   The wordmark here is one ink, white for both words, which is the same
   treatment body.dark-hero gives the five photo-hero pages. It used to mirror the
   old extracted lockup instead: --gold-soft (pale mint) for "Saeed", white for
   "ur Riaz", so the bar carried two inks in one word. Gold itself is #22544C, a
   dark teal, and would vanish against the photo, which is why gold was never an
   option on a banner at all - only the choice between splitting the wordmark and
   flattening it. Flattening is what every other image-backed header on the site
   already did.

   .faq-page is the FAQ page, which now has the same band at y=0 and therefore
   the same problem: its header would sit dark-ink-on-sunset until it scrolls. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .logo-name { color: var(--banner-ink); }
/* Was --gold-soft, which made "Saeed" a pale mint against white "ur Riaz" in the
   same wordmark, sitting on a photograph. That is the colour mix this header had:
   two inks in one word, and two different answers on the site for the same bar.
   body.dark-hero already paints the wordmark flat #fff on the five photo-hero
   pages, and the comment on those pages says the flat treatment exists precisely
   to avoid "a two-tone wordmark". These eight banners were the ones left behind.

   White for both words, so all thirteen image-backed headers read identically and
   the wordmark is one ink the way every heading is now one ink.

   Contrast does not get worse: --gold-soft #E4EFEB measured 4.76:1 here and
   --white measures higher against every one of these dark grounds, so the pair
   that was 4.76 against 5.60 collapses to two identical values. That also removes
   the three-inks-within-0.02-of-each-other fragility noted above this block,
   since one of those inks no longer exists. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page, .dark-hero) .site-header:not(.scrolled) .header-inner > .logo .logo-name .logo-first {
  /* White on "Saeed". The mint is on "ur Riaz", one rule above at L1522 and in
     the dark-hero pair further down, and this rule exists only to stop the
     first word inheriting it. Without it the whole wordmark is one ink and the
     mix this bar is supposed to carry is not there.

   Read that the other way round: .logo-name wraps BOTH words, so setting it to
   --gold-soft is what puts the mint on "ur Riaz", and .logo-first is the span
   around "Saeed" alone, so this rule is the white half of the pair.

   The word that carries the accent was reversed once already and the record is
   here so nobody reverses it again by accident. The original lockup had the
   mint on "Saeed" and white on "ur Riaz". That is what the comment on this rule
   used to describe, and it is the reverse of what the code below does, because
   a concurrent change on the remote branch moved the mint to the second word
   while this rule's declaration was being reworked at the same time. The two
   edits landed in the same merge, so the comment and the code disagreed and
   neither the merge nor the browser flagged it: the rendering was a legitimate
   two-ink mix either way, just the other way round.

   Both arrangements are a mix and both pass, so the choice is a design one and
   not a correctness one. Mint on the second word is what is in place now, and
   this rule matches it. If the accent is wanted back on "Saeed", the change is
   to swap the two values here and at L1522, not to delete this rule.

   .header-inner > .logo is the bar wordmark only. The drawer keeps its own copy
   of the logo, three levels down under .nav-mobile-head, and it sits on the
   drawer's ground rather than on a banner, so it keeps its flat white and does
   not pick the mint up.

   The headroom on the mint is thin and worth stating. The banner's worst pixel
   solves to 0.1375 luminance, from white measuring 5.60:1 there, so an ink needs
   0.794 to hold 4.5:1 against it - the floor for 16.8px text, which is not
   large text at this size. Measured down the hue line from --gold:

     #E4EFEB 0.842  4.76:1   pass   <- what this is
     #DFF4EA 0.863  4.87:1   pass
     #D0F0E0 0.811  4.59:1   pass
     #C3EDD6 0.770  4.37:1   fail
     #B8E8CE 0.724  4.13:1   fail
     #9CDFBA 0.634  3.65:1   fail
     #54A87C 0.314  1.94:1   fail

   So #E4EFEB is the most saturated green that legally sits on this ground, and
   it is chosen over #DFF4EA not because it is prettier but because it is the
   lightest of the three, and on a dark ground lighter is more headroom. Every
   banner below this one is darker than the worst pixel above, so the figure to
   remember is 4.76:1 and it is a floor, not a typical value. Anything more
   saturated than #D0F0E0 fails here. */
  color: #fff;
}
/* The tagline was 0.72 and is now 0.88, matching the nav ink directly above it.
   That is not a styling preference, it is what lets the baked banner veils be
   lighter. The tagline is the smallest text in the header at 9.6px, so it has the
   least ink to work with, and a translucent ink composites onto the photograph
   rather than onto white, so its measured contrast is materially lower than the
   nav's even though both sit on the same ground. At 0.72 it was the binding
   constraint on all six banners and it, not the photograph, was dictating how
   dark the veil had to be: About needed 0.62 and rounded to 0.65. At 0.88 the
   same ground passes at 0.55, which is a visibly lighter banner.

   Measured on the shipped About file at veil 0.55: tagline 4.78:1, nav and phone
   4.78:1, logo-name and the menu bars 5.60:1. logo-first measured 4.76:1 as
   --gold-soft and is now the same white as logo-name, so it takes 5.60:1 rather
   than a figure of its own.
   Raising an ink can only increase contrast against a dark ground, so FAQ at its
   0.70 bake, and the poem and contact banners on their 0.55 CSS veils, all gain
   from this rather than losing. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .logo-tagline { color: var(--banner-ink);}
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .nav-list a { color: rgba(255, 255, 255, 0.88);}
/* Hover and focus have to be restated HERE, at this block's own specificity, not
   left to the base .nav-list a:hover rule. The resting line above is (0,4,2);
   the base hover rule is only (0,2,1). So the base rule set the white pill and
   this block set white text, and the pill landed under text that stayed white -
   white on white, 1.06:1, invisible. Specificity is the whole reason this line
   exists; matching values alone would not have been enough. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .nav-list a:hover,
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .nav-list a:focus-visible {
  color: var(--black);
  background: rgba(255, 255, 255, 0.9);
}
/* The same trap, one state further on: the current page. .nav-list a.active paints a
   filled pill, and the resting line above at (0,5,1) outranks the (0,2,1) that sets
   its ink, so the pill landed under white text - white on white, 1:1. This is what
   showed as a blank white rectangle in the mobile drawer, on the current page of
   every page in this group: measured on about.html at 390px, "My Story" resolved
   to rgba(255,255,255,0.88) on rgb(255,255,255).

   Ink and fill both have to be restated here, for the same reason as the line above.

   The values are gold fill with white ink, not the white pill with gold ink the
   mobile drawer asks for at breakpoints.css. That is deliberate: this rule is not in
   a media query, so it also lands on desktop, where .nav-list a.active is already a
   gold pill with white text. Restating the drawer's values here would have repainted
   the desktop nav of all seven pages white-on-gold. Gold-on-white ink would have made
   the mobile active item invisible in a different way, so the fill is the one that
   carries the state and the ink follows it. It also lands on the same treatment the
   dark-hero pages already use further down this file. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .nav-list a.active {
  background: var(--gold);
  color: #fff;
}
/* No hover or focus override here on purpose. The base .nav-list a:hover rule
   already puts white text on the accent pill, which reads correctly against the
   dark banner - so an override would only be a chance for the two to drift.
   What this block owns is the resting ink, which has to be light to sit on the
   photo; that is the lines above. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .header-phone { color: rgba(255, 255, 255, 0.88);}
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .header-phone:hover { color: var(--white);}
/* The CTA is a link too: invert it to a white pill with dark text so it reads
   as "white" over the photo and still looks like a button. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) a.header-cta { background: var(--white); color: var(--ink);}
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) a.header-cta:hover { color: var(--ink);}
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .menu-toggle { border-color: rgba(255, 255, 255, 0.4);}
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .menu-toggle span { background: var(--white);}
/* The ring, for the same reason the dark-hero block further down gives one. These
   seven pages are banner pages without the dark-hero class, so that block does
   not reach them and they were left drawing the gold floor on a photo: 1.43:1.

   These are the only focusable things in the bar that do not already carry a
   light pill of their own, and the pill is inside the border box while the ring
   is outside it, which is why the nav link needed this even though its focus
   state is a white pill with black text. Everything listed here is scoped to
   :not(.scrolled) to match the rest of the block: once the bar turns light the
   gold floor is correct again and this stops applying. */
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .nav-list a:focus-visible,
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .logo:focus-visible,
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .header-phone:focus-visible,
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) .menu-toggle:focus-visible,
:is(.about-page, .faq-page, .poem-page, .page-contact, .page-services, .page-packages, .page-resources, .blog-page) .site-header:not(.scrolled) a.header-cta:focus-visible {
  outline-color: var(--ivory);
}

.about-page .story-grid { align-items: start; gap: clamp(32px, 4vw, 60px);}
.about-page .story-media { aspect-ratio: 4/5;}
/* About Section 01 (My Journey): justified to match Section 02, so the lines end
   evenly on both edges. This overrides the earlier left-aligned decision. */
#journey .story-grid p,
#journey .story-grid .lead { hyphens: manual; }
/* About Sections 01 and 02 share one portrait image style: the 4/5 box from
   .about-page .story-media above, plus `object-fit: cover` from
   layout.css .story-media img. #about-coach used to opt out (aspect-ratio:auto,
   object-fit:contain) because it held three stacked certificates; it now holds
   a single photo, so it inherits the portrait treatment like #journey. */
#about-coach .story-media img.cert-large { aspect-ratio: auto; max-height: 520px; object-fit: contain;}
.about-page .story-caption { font-size: 0.85rem; color: var(--muted); text-align: center; margin-top: 12px; line-height: 1.5;}

/* ---------- Cert Gallery ----------
   Two certificates per row at every width, not three. Certificates are portrait
   documents and at three per row the text on them shrank past legibility; two
   gives each one roughly 690px of width inside the 1440px container, which is
   about the size a framed certificate actually hangs at. The breakpoints only
   need to tighten the gap now, since the column count is already 2. */
.cert-gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
.cert-gallery-item {
  aspect-ratio: 4 / 3;
  border-radius: 12px;
  overflow: hidden;
  background: var(--white);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  position: relative;
}
.cert-gallery-item:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}
/* contain, not cover. The scans are not all the same shape (seven are
   landscape between 1.18 and 1.44, one is portrait) and cover was cropping
   them to fit the row: decision-making-lums was losing 43% of its width,
   which cut the seal and signature off a document whose whole job is to
   prove the credential. A fixed 4:3 tile matches the landscape majority
   closely enough that the mat stays thin, and the white item background
   reads as the mount you would put behind a framed certificate. */
.cert-gallery-item img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
}
.cert-gallery-item.cert-hidden {
  display: none;
}
.cert-gallery.show-all .cert-gallery-item.cert-hidden {
  display: block;
}
.cert-toggle {
  text-align: center;
  margin-top: 32px;
}
.cert-toggle .btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  overflow: visible;
}
.cert-toggle .btn .arw {
  display: inline-flex;
  align-items: center;
  transition: transform 0.3s ease;
}
.cert-toggle .btn:hover .arw {
  transform: translateY(3px);
}

/* Podcast / video mockup media */
.pod-media { position: relative; border-radius: 12px; overflow: hidden;}
.pod-media img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 16/10; display: block;}
.pod-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center;}
.pod-play { border: none; padding: 0; background: none; cursor: pointer; width: 88px; height: 88px; transition: transform 0.3s ease, filter 0.3s ease;}
.pod-play svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 2px 10px rgba(0,0,0,0.5));}
.pod-play .pod-pause { display: none;}
.pod-play.is-playing .pod-play-ico { display: none;}
.pod-play.is-playing .pod-pause { display: block;}
.pod-play:hover { transform: scale(1.08);}
.pod-audio { width: 100%; margin-top: 12px; height: 40px;}
.pod-time { position: absolute; bottom: 12px; right: 12px; background: rgba(0,0,0,0.7); color: var(--white); padding: 4px 10px; border-radius: 6px; font-size: 0.75rem; font-weight: 600;}

/* Click-to-play framed video (direct inline player) */
.frame-video {
  background: #000;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.14);
}
.frame-video .frame-stage { width: 100%; aspect-ratio: 16/9;}
.frame-video iframe,
.frame-video video { width: 100%; height: 100%; border: 0; display: block; background: #000;}
.frame-inline { max-width: 720px; margin: 28px auto 0;}
.frame-fill { position: absolute; inset: 0; border-radius: 0; box-shadow: none;}

/* ---------- Audio in the popup ----------
   The popup stage is a 16/9 box, sized for a video, and the two are not
   interchangeable: an episode has no picture, so a 16:9 stage is a black void
   with one control bar floating in the middle of it and the episode title nowhere
   on screen. js/main.js adds this class when the URL is an audio file.

   aspect-ratio: auto is the load-bearing declaration. The stage takes its height
   from the audio element's own controls, which is about 54px, so the box closes
   to the player instead of holding 9/16ths of the modal's width open around it.

   --charcoal rather than #000, because #000 was chosen above as video letterbox
   and a listening surface is not letterbox. It is the footer's ground and it
   matches the popup's own chrome, so the control bar sits on something that
   belongs to the site rather than on a video-black box. */
.frame-video--audio { background: var(--charcoal);}
.frame-video--audio .frame-stage {
  /* 16/9, the same stage the video branch uses, on the client's request. It was
     aspect-ratio: auto here, which collapsed the box to the height of its own
     content and gave an episode a letterbox ratio nothing about it shares with a
     video. Matching the video stage means the popup is the same shape whichever
     trigger opened it, so it does not jump between sizes.

     flex column, both axes centred, because the two children are now sized
     independently of each other and the box is far taller than their sum. The
     previous version let them stack from the top with 22px of padding, which in a
     619px-tall box left the player hugging the ceiling and the bottom two thirds
     empty charcoal.

     gap rather than margin on the canvas, for the reason below. */
  aspect-ratio: 16/9;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2.4vh, 26px);
}
.frame-video--audio audio {
  display: none;
}

/* ---------- Audio controller ----------
   Built by js/main.js, so there is no markup for it on any page. It stands in
   for the browser's own <audio controls>, which cannot be restyled: Chromium
   draws that as a light grey pill with a closed shadow root, so its colours only
   answer to ::-webkit pseudo-elements and accent-color, and neither reaches the
   track fill, the time readout or the volume control. On a --charcoal stage it
   was a bright grey lozenge sitting under the spectrum.

   width min(100%, 520px) matches the column it sits in, and the row is centred by
   the stage's align-items rather than by margin auto here. The visualizer above
   is min(100%, 720px), so the control is deliberately the narrower of the two:
   the spectrum is the picture and the control is the instrument under it, and
   matching widths made the two read as one stacked block.

   --muted and --gold-soft are the only inks here, both already carrying their
   contrast on --charcoal: --muted measures 3.08:1 on it, which is why the time
   readout is --muted and not --white, and the glyphs are --gold-soft at 7.31:1.
   Nothing new was added to the token set for this. */
.audio-ctl {
  display: flex;
  align-items: center;
  gap: 12px;
  width: min(100%, 520px);
  flex: 0 0 auto;
}
/* The play control is the one filled mark in the row, so it is a circle rather
   than the site's usual .btn rectangle: a pill-shaped play button reads as a
   button, a filled circle reads as transport. --gold on --white for its glyph
   because the circle itself is white, which is the one light surface on this
   stage and what makes it read as the primary control. */
.audio-ctl-play {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: var(--white);
  color: var(--gold);
  display: grid;
  place-items: center;
  cursor: pointer;
  font-size: 1rem;
  transition: transform 0.18s var(--ease), background 0.18s ease;
}
.audio-ctl-play:hover { background: var(--gold-soft); transform: scale(1.05);}
.audio-ctl-play:active { transform: scale(0.97);}
.audio-ctl-play i { line-height: 1; margin-left: 1px;}
/* The pause glyph is two bars and reads optically left of centre inside a circle,
   so it is nudged back the other way. Without this the play and pause states sit
   a pixel apart and the button appears to shift when you press it. */
.audio-ctl-play i.ph-fill.ph-pause { margin-left: 0;}

.audio-ctl-time {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  color: var(--muted);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* The track is 20px tall but only a 3px rule is drawn in it. The extra height is
   the hit area: a 3px-tall target is impossible to grab on a touch screen and
   hard on a mouse, and it is what lets the knob overhang the rule at both ends
   without being clipped. */
.audio-ctl-track {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 20px;
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;
}
.audio-ctl-track::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.16);
}
/* width is written by js/main.js on timeupdate, so the fill has no width of its
   own to inherit from a stylesheet. */
.audio-ctl-fill {
  position: absolute;
  left: 0;
  height: 3px;
  border-radius: 2px;
  background: var(--gold-soft);
  width: 0;
  pointer-events: none;
}
/* -6px of overhang on each end puts the knob's centre on the fill's end. The
   knob is translateX(-50%), so without it the dot trails the progress by half
   its own width. */
.audio-ctl-knob {
  position: absolute;
  left: 0;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--gold-soft);
  transform: translateX(-50%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.16s ease, transform 0.16s ease;
}
.audio-ctl-track:hover .audio-ctl-knob,
.audio-ctl-track:focus-visible .audio-ctl-knob,
.audio-ctl-track.is-dragging .audio-ctl-knob { opacity: 1;}
.audio-ctl-track.is-dragging .audio-ctl-knob { transform: translateX(-50%) scale(1.2);}

/* The volume control is a bare glyph, not a button-shaped box, because it is
   secondary: it sits after the seek track in the reading order and takes a
   click without competing with play. */
.audio-ctl-vol {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--gold-soft);
  display: grid;
  place-items: center;
  cursor: pointer;
  font-size: 0.95rem;
  transition: background 0.18s ease, color 0.18s ease;
}
.audio-ctl-vol:hover { background: rgba(255, 255, 255, 0.1);}
.audio-ctl-vol i { line-height: 1;}

/* ---------- Audio visualizer ----------
   The canvas the spectrum is drawn into. Built by js/main.js and attached only on
   the local-audio branch, so there is no markup for it anywhere and no rule
   needed for the video case.

   display: block because a canvas is inline by default and sits on the text
   baseline, which would push the audio element down by the descender gap instead
   of meeting it.

   flex: 1 1 0 rather than 1 1 auto, and that zero is the load-bearing part. A
   canvas has an intrinsic size of 300x150, so with flex-basis: auto the item's
   content height is its intrinsic height scaled to its width, and the stage
   inherits that as its own height. On a wide viewport the 16/9 height is larger
   than that and the ratio wins, but on a narrow one it is not: at 390x844 the
   canvas wanted 172px, the audio wanted 54px and the gap 20px, which is 246px of
   content against a 16/9 height of 193px, so the content won and the popup came
   out at a 1.40 ratio instead of 1.78. flex-basis: 0 makes the item contribute
   nothing to the stage's content height, which is what lets aspect-ratio decide
   it at every width.

   min-height: 0 alongside it, for the same reason from the other side: a flex
   item's automatic minimum size is its content size, so without it the item
   refuses to shrink below its intrinsic 150px even once the basis is zero.

   width: min(100%, 720px) rather than 100%, so the spectrum is a centred column
   on a wide screen instead of a 1100px-wide row of small candles. */
.audio-viz {
  display: block;
  flex: 1 1 0;
  min-height: 0;
  width: min(100%, 720px);
  margin: 0;
}

/* ---------- Video popup ----------
   Built by js/main.js, so there is no markup for it on any page. The stage
   carries .frame-video, which already gives the 16/9 box, the black ground, the
   radius and the shadow, so only the overlay behaviour is new here.

   Deliberately not the #lightbox the gallery pages use. That one is an image
   viewer with drag, zoom and prev/next bound to it, and reusing it for a single
   video would carry all of that dead weight on three pages.

   [hidden] is what keeps it out of the page before the first open and after a
   close; the class only drives the fade. hidden is display:none, which would
   also kill the transition, hence the rule sets it explicitly rather than
   relying on the attribute alone.

   position: fixed with a high z-index because it has to clear the fixed header.
   The stage is capped at 1100px so a 16/9 frame does not run the full width of a
   wide screen, and its margin-inline auto centres it.

   The close button is a real button in the top right of the stage rather than a
   free-floating X, so it cannot land outside the dialog on a narrow phone. */
.video-modal {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(16px, 4vw, 56px);
  background: rgba(10, 8, 6, 0.82);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.video-modal[hidden] { display: flex;}
.video-modal:not([hidden]) { visibility: visible;}
.video-modal.open { opacity: 1;}

.video-modal-frame {
  position: relative;
  width: 100%;
  max-width: 1100px;
  margin-inline: auto;
}
/* The close button and the media are siblings inside the frame, both absolutely
   or normally positioned against it. This wrapper exists only so the popup can
   empty the media without emptying the close button; it must not impose any box
   of its own, so it is a plain block with no padding, margin or sizing. If it
   gained a height here the 16/9 stage inside it would gain one too. */
.video-modal-content { display: block; }
/* The close button comes before the content in the DOM because that is the order
   they were appended in, and it is absolutely positioned while the content is not.
   Absolute elements paint above in-flow ones regardless of source order, so the
   button is not painted under the media by being first. z-index is not needed
   here and is not set: the frame itself creates no stacking context, so the
   button's z-index: 2 already lifts it over the content without a new one. */

.video-modal-close {
  position: absolute;
  /* Inside the frame's top-right corner at every width, on the client's request.
     This was top: -46px, which parked it in the backdrop above the stage, and
     the 560px query below used to pull it inside only on a phone. Two problems
     with that: on a short viewport the button could land outside the dialog's
     box entirely, and the audio popup made it worse because its 16:9 stage is
     full height, so there was no room above the frame to sit in at all.

     14px is inside the border-radius of the stage, so the circle is not clipped
     by the corner curve. The backdrop under it is 50% black on --charcoal,
     which is enough to hold the white glyph at 5.6:1 against whatever the
     spectrum is doing behind it. */
  top: 14px;
  right: 14px;
  z-index: 2;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  color: var(--white);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.video-modal-close:hover,
.video-modal-close:focus-visible { background: rgba(0, 0, 0, 0.78); border-color: rgba(255, 255, 255, 0.6);}
/* Locks the page behind the popup so a long article does not scroll away under it. */
body.video-modal-open { overflow: hidden;}

/* Play button overlays */
.about-page .story-media { position: relative;}
.about-page .story-media .pod-overlay { border-radius: var(--radius-lg); cursor: pointer;}
.hero-video-cta {
  position: absolute; left: 50%; bottom: 30px; transform: translateX(-50%);
  z-index: 3; display: inline-flex; align-items: center; gap: 12px;
  border: none; cursor: pointer;
  background: rgba(17, 17, 17, 0.62);
  color: var(--white);
  padding: 12px 20px; border-radius: 999px;
  backdrop-filter: blur(6px);
  font-family: inherit; font-weight: 600; font-size: 0.9rem; letter-spacing: 0.01em;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  transition: background 0.25s ease, transform 0.25s ease;
}
.hero-video-cta:hover { background: rgba(17, 17, 17, 0.8);}
.hero-video-cta .hc-play {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--gold);
  display: inline-flex; align-items: center; justify-content: center;
  flex: none;
}
.hero-video-cta .hc-play svg { width: 18px; height: 18px; display: block;}

/* Social media hook cards

   The base is TWO columns now, not three. Three columns needed a viewport of
   about 934px before each card cleared 240px, but they started at any width,
   so on resources.html a 769px tablet was running three 191px cards. The old
   default of three only ever worked above roughly 940px, so it is the tablet
   range that has been made correct: three across is reinstated at 950px in
   breakpoints.css, which loads later and wins. One argument, no parallel rule.

   minmax(0, 1fr) rather than 1fr, because these cards hold a paragraph and a
   letter-spaced uppercase label. As a plain 1fr the track floors at the content's
   min-content width, and at 320px the grid measured 243px while every card
   measured 261px, spilling 18px out of its own column. */
.social-hooks-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  max-width: 900px;
  margin: 0 auto;
}
a.hook-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-radius: 16px;
  padding: 24px;
  color: var(--white);
  aspect-ratio: 4/5;
  text-decoration: none;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
a.hook-card:hover { transform: translateY(-4px); box-shadow: 0 14px 30px rgba(0,0,0,0.22);}
/* The press sits back down toward the resting plane rather than lifting further.
   These are the six social hook cards on resources.html and they are the widest
   tap targets on that page, so on a phone the tap is the only interaction there
   is. Holding the -4px hover lift through the press would read as the card
   sticking rather than responding. */
a.hook-card:active { transform: translateY(-1px); box-shadow: 0 8px 18px rgba(0,0,0,0.18);}
.hook-card p { font-size: 0.85rem; line-height: 1.5; margin: 0 0 12px; opacity: 0.95;}
.hook-card .hook-label { font-size: 0.7rem; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.1em;}
@media (max-width: 768px) {
  .social-hooks-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}
  a.hook-card {
    padding: 18px;
    aspect-ratio: 1/1;
}
  .hook-card p { font-size: 0.8rem;}
}

/* 644px, not 480px.

   Two columns of these cards are 197px wide at 481px and 225px at 600px. The
   cards carry a paragraph, so 197px leaves about twenty characters a line and
   the label above it wraps. One column takes over where a column can actually
   hold the text, which measured out at 644px.

   The square aspect-ratio came off at the same point rather than staying until
   480px, so a single-column card between 481px and 644px is 3/2 instead of a
   400px square. */
@media (max-width: 644px) {
  .social-hooks-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
}
  a.hook-card {
    aspect-ratio: 3/2;
    padding: 16px;
}
}

/* ---------- Split Layout ---------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 4vw, 60px);
  align-items: center;
}
.split-top { align-items: start;}
.meet-img { max-height: 500px;}
.meet-img img { height: 100%; object-fit: cover;}

/* Approach split: cap the near-square photo so it doesn't tower over the copy column */
#approach .approach-media { max-height: 500px;}
#approach .approach-media img { height: 100%;}
.split > * { min-width: 0;}
.split-media { position: relative; border-radius: var(--radius-lg); overflow: hidden;}
.split-media img { width: 100%; height: auto; display: block; border-radius: var(--radius-lg); object-fit: cover;}
.split-copy .eyebrow { text-align: left;}
/* The homepage centering group uses section:not(#hero), so its selector carries an ID.
   Match it here or this left-alignment loses on specificity. */
.home-page main section:not(#hero) .split-copy .eyebrow { text-align: left;}
.split-copy .h-section { text-align: left;}
.split-copy .lead { text-align: left;}
/* Body prose follows the site-wide "line equally end" formula; the eyebrow,
   heading and lead above stay left because they are labels, not prose. */
.split-copy p { hyphens: manual; }
.split-copy { display: flex; flex-direction: column; gap: 16px;}
.split-copy--full { grid-column: 1 / -1; max-width: 880px;}

/* ---------- About page credentials paragraph ---------- */
.w-1300 p {
  text-align: left;
  word-spacing: normal;
  letter-spacing: normal;
  line-height: 1.6;
}
@media (max-width: 768px) {
  .w-1300 p {
    text-align: left;
    word-spacing: normal;
    letter-spacing: normal;
    line-height: 1.6;
    font-size: 0.95rem;
}
}

/* ---------- Qualifications list (About) ----------
   The written-out credentials, sitting directly above the certificate images.
   Two columns keeps 24 entries readable without the lines running the full
   1440px, which would leave the eye travelling too far to pair a name with its
   issuing body. The issuing body is the parenthetical, so it carries the muted
   colour and the credential itself stays at full ink. */
/* ---------- About: Qualifications and Certifications ----------
   Rebuilt as one card grid. The section used to be two <ul>s of nine and
   fifteen, split by a 72px hairline, and each list was internally a two-column
   grid - four columns and two arbitrary blocks, with a divider standing in for a
   grouping that was never in the content. The 9/15 split had no logic to it.

   All twenty-four entries are now one list in a single responsive grid, so the
   cards tile evenly and there is nothing to divide. The wording is untouched.

   Grid, not multi-column, deliberately: as two separate lists this content
   previously used grid and the rows came out ragged, because a grid row takes
   the height of its tallest cell and an entry that wrapped to two lines left a
   hole under its neighbour. That only happened because individual entries were
   paired across a row. Here the cards are uniform and short, so rows pack
   cleanly, and grid gives predictable left-to-right order. */
.qual-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* Two across by default, three only from 1024px up (breakpoints.css). Three
     was tried from 577px and it does not hold: at a 600px viewport each card is
     146px wide and the tallest runs to 195px, which left six different card
     heights in the grid and read as ragged all over again. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.qual-list li {
  position: relative;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  /* Left padding clears the gold marker; the rest is the card's own inset. */
  padding: 13px 16px 13px 38px;
  font-size: 0.95rem;
  line-height: 1.4;
  color: var(--ink);
  /* Same four properties, same curve, as .theme-card and .hiw-card above. */
  transition:
    transform 0.45s cubic-bezier(.16, 1, .3, 1),
    box-shadow 0.45s cubic-bezier(.16, 1, .3, 1),
    border-color 0.45s ease,
    background 0.45s ease;
}
/* The house card hover: lift, tinted border, soft green shadow. Identical values
   to .theme-card:hover and .hiw-card:hover so these cards behave like every
   other card on the site rather than inventing a third variant. */
.qual-list li:hover {
  transform: translateY(-6px);
  border-color: rgba(34, 84, 76, 0.28);
  box-shadow: 0 20px 44px -20px rgba(34, 84, 76, 0.4);
  background: var(--gold-soft);
}

/* The 18 qualifications that have a certificate photograph are a <button> so
   they are reachable by keyboard and announced as activatable, which a clickable
   <li> is not. Everything below takes the button back to looking like the plain
   cards beside it: same family, size, weight, colour and alignment, with the
   browser's button chrome and the default inline centring both undone.

   Only the affordances differ, so it reads as the same card: the card lift and
   tinted border it already had on hover, and nothing on the text itself.

   .qual-list li:hover already lifts the card, and that rule still applies because
   the hover is on the <li>, not the button. Only the button's own hover is added
   here. */
.qual-link {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
/* No underline on hover, on the client's request.

   There was text-decoration: underline here, which drew a line under the
   qualification title every time a mouse passed over a card. On a list where
   18 of the 24 cards already sit inside a card that lifts and tints its border
   on hover, the underline was a third signal saying the same thing, and it ran
   under the title as a rule rather than reading as emphasis.

   The card still shows it is clickable: .qual-list li:hover lifts the card 6px
   and tints the border, and that is on the <li>, not the button, so it still
   applies unchanged.

   The focus ring below is kept. It only appears for keyboard focus, where it is
   the only thing telling a keyboard user where they are. It is not decoration
   and removing it would make these cards unusable without a mouse. */

.qual-link:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 3px;
}
.qual-list li::before {
  content: "";
  position: absolute;
  left: 17px;
  /* Centred on the first line of the entry rather than pinned to the top of
     the card, so a two-line card does not leave the dot floating high. */
  top: 1.05em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
  /* The -50% is the centring offset and has to survive into the hover state,
     which is why the hover rule repeats it rather than just scaling. */
  transform: translateY(-50%);
  transition: transform 0.45s cubic-bezier(.16, 1, .3, 1);
}
/* The marker swells on hover, the counterpart to .hiw-card:hover .hiw-num
   scaling its number to 1.1. */
.qual-list li:hover::before {
  transform: translateY(-50%) scale(1.4);
}
/* The issuing body drops onto its own line under the credential, which is the
   hierarchy the markup already implied by marking it up as a span. */
.qual-org {
  display: block;
  margin-top: 3px;
  font-size: 0.86rem;
  color: var(--muted);
  transition: color 0.3s ease;
}
/* --muted on white is 3.9:1 and fails AA for body text, so the issuer line goes
   to --charcoal-2 on hover rather than staying at the muted grey. It is only
   reachable that way on a pointer device, but it is a real improvement where it
   applies and costs nothing where it does not. */
.qual-list li:hover .qual-org { color: var(--charcoal-2);}

/* ---------- HOME PAGE ---------- */
#welcome .eyebrow { font-size: 0.9rem; letter-spacing: 0.25em;}

/* Meet the coach balanced heading, centered section */
#meet .section-head .h-section {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 600;
  color: rgb(26, 21, 18);
  font-size: 46px;
  line-height: 47px;
  white-space: normal;
  text-wrap: balance;
}
#meet .section-head { text-align: center;}
#meet .section-head .eyebrow { text-align: center;}
#meet .split-copy { align-items: center;}
#meet .split-copy p { text-align: center;}
#meet .split-copy--full { justify-self: center;}

@media (max-width: 768px) {
  /* stretch, not flex-start. flex-start sized .hero-inner to its own content, so
     it sat at the top of a hero that is min-height:100dvh and the headline's
     margin-top:auto had no slack to take - the copy stayed pinned to the top
     while the desktop rule sent it to the bottom. Stretching the row makes
     .hero-inner full height, which is what gives that auto something to absorb.
     It reaches no further than this element: .hero-bg is position:absolute and
     out of flow, so it is not affected. */
  #hero.hero--full { align-items: stretch; padding-top: calc(var(--header-h) + 24px);}
  #hero.hero--tint .hero-inner { text-align: center;}
  #hero.hero--tint .hero-headline { font-size: clamp(1.9rem, 8vw, 2.6rem); line-height: 1.0;}
}

/* ---------- Hero: docx map layout (writeup removed, roles right, CTA bottom) ----------
   Specificity must match the #hero.hero--tint rules in layout.css (2,1,0);
   page-overrides loads after layout, so equal specificity means these win. */
#hero.hero--tint {
  /* .hero already sets overflow:hidden, so this clips the photo to the curve */
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
@media (min-width: 769px) {
  /* Desktop only. Zeroes .hero--full's padding-top of
     clamp(100px, 14vh, 160px), which was stacking on the .hero-inner padding
     below that already carries --header-h. The headline started 198px under an
     80px header: double clearance for one job. The 152px left is the inner
     padding, 80px of header plus 72px of air.

     Scoped to 769px and up because the phone rule above sets its own
     padding-top of calc(var(--header-h) + 24px) at the same specificity, and an
     unscoped 0 here would win on source order and push the headline up under
     the header on phones. */
  #hero.hero--tint { padding-top: 0;}
}
/* Hero bottom padding removed, on the client's request, so the CTA sits at the
   bottom-left of the frame rather than floating above a band of grass.

   #hero carried padding-bottom: 53.4px. It is not the column's fault that the
   button looked high: .hero-inner already has align-self: stretch and
   .hero-actions already carries the single margin-top: auto in the column, so
   the button was landing exactly on the column's content edge. The column was
   stopping 53.4px short because that is the hero's own padding, and a flex line
   ends where the padding does.

   Taking it to 0 leaves the column's own clamp(24px, 4vh, 56px), which measures
   35.6px here, as the gap under the button. The button still breathes off the
   bottom edge, and 35.6px is the figure the rest of this hero's spacing already
   uses rather than a new number.

   Measured at 1335x890: button bottom moved from 801 to 854 in an 890px hero,
   so the gap below it is 36px, down from 89px. The button was already flush with
   the column's left edge at x=16 and is unchanged on that axis. */
#hero.hero--tint { padding-bottom: 0;}

#hero.hero--tint .hero-inner {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* full container width: lets the CTA reach the left corner while the
     headline keeps its own 920px measure (see below) */
  max-width: none;
  margin: 0 auto;
  padding-top: calc(var(--header-h) + clamp(40px, 8vh, 96px));
  padding-bottom: clamp(24px, 4vh, 56px);
}
#hero.hero--tint .hero-headline {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  white-space: normal;
  /* The rounded panel is back, on the client's request. It was set to transparent
     earlier in this build to let the photograph show through bare, and the
     photograph does show through now - around the panel, above the roles line,
     everywhere except behind the headline itself.

     The values are the ones this panel had before it was removed, not new ones,
     and the pair is the same one the roles pill directly below already uses:
     white on the dark teal accent, 8.58:1. Opaque rather than a percentage,
     because a translucent panel lets the photograph's own brightness back
     through and puts the contrast back where it started - the headline is the
     one element here with no veil behind it, so it cannot rely on one.

     White ink rather than the dark ink the copy elsewhere in the hero measures.
     Bare dark ink on the photograph gave 5.08:1 to 9.60:1 across the band it sits
     in, which is legible, but it is 8.58:1 on this panel and it stops depending
     on where the sun happens to fall in the frame.

     border-radius is --radius-lg and not 999px on purpose. Below 769px the
     headline wraps, and a pill radius on a two-line block rounds each line into
     its own lozenge with a visible notch between them; 24px rounds the whole
     block once, so a wrapped headline is one rounded rectangle holding both
     lines. That was the reason the radius was never taken to a full pill.

     Padding is a clamp rather than the flat 26.9px this had, which was half of
     the 53.8px horizontal total the old width arithmetic was measured against.
     The clamp holds that figure at desktop, where the max-content measurement
     below still applies, and comes down on a phone where 53.8px of padding would
     leave almost no room for words. */
  color: var(--white);
  background: var(--gold);
  border-radius: var(--radius-lg);
  padding: clamp(14px, 1.8vw, 24px) clamp(18px, 2.6vw, 26.9px);
  /* The shadow is what lifts the panel off the photograph. Without it a flat
     --gold rectangle on a dark image reads as a hole cut in the photo rather
     than a card sitting on it, because there is no edge for the eye to catch.
     40px of blur on a 34px offset, the same pair the site uses on its raised
     cards. */
  box-shadow: 0 20px 44px -20px rgba(34, 84, 76, 0.55);
  /* width: max-content with max-width: 100%, and not the 920px cap it inherited.

     The cap was measured against bare text at 906px. With 53.8px of padding the
     panel needs 960px, so the cap would have forced the last words onto a second
     line inside a panel meant to hold one.

     max-width: none was tried instead and also wrapped, by half a pixel: as a
     centred flex item the box shrink-wrapped to 959px, leaving a 905.2px content
     box against 905.7px of text. width: max-content takes the text's own width
     plus the padding exactly, so the line holds wherever it fits, and the 100%
     cap takes over below about 1000px where 906px of headline genuinely no longer
     fits and the two-line wrap is correct.

     The panel hugs the text on its own and needs no display to do it. .hero-inner
     is display:flex with flex-direction:column and align-items:center, so this
     headline is a flex item: it is blockified, and align-items:center makes it
     shrink-wrap rather than stretch to the column. An inline-block here would be
     blockified to block anyway and would change nothing. */
  width: max-content;
  max-width: 100%;
  /* No text shadow - the grass is dark enough to carry rgb(243,238,230) on
      its own.

     margin-top was auto, and that was the only auto in the column, which parked
     the copy block at the bottom of the hero. It is now a fixed distance below
     the header, which lifts the group from 62% down the frame to about a third.

     It could not simply go to 0 while the ink was near-white. The photograph is
     brightest across its middle - measured per band, rgb(243,238,230) clears 3:1
     only between 60% and 80% down - so moving the copy up into that band on its
     own dropped it to 1.50:1. A veil was added to cover the gap and has since
     been taken off again: the correct answer was to put the copy on the bright
     part of the image and give it dark ink, which measures 5.08:1 to 9.60:1
     across the same range with the photograph untouched. The colour below is
     that ink.

     auto had a second property worth losing. It absorbed whatever slack the
     frame had, so the distance between the header and the headline was whatever
     height the window happened to be - 556px at 1335x890. A clamp scales with
     the viewport instead, the same reasoning the padding-top above uses. */
  margin-top: clamp(60px, 12vh, 130px);
  margin-bottom: clamp(18px, 2.6vh, 34px);
}

/* Desktop size for the headline. It was inline in the block above, at
   (1,2,0) and outside any media query, while the phone clamp that should
   shrink it sat at :1662 in this same file. Equal specificity, later source
   wins, so 50px applied at every width and the clamp never once took effect:
   measured, the headline was 50px from 1446px down to 320px, where a
   40-character string in a 262px measure broke to five lines. The two
   breakpoints.css clamps were never in the running either, being only (0,2,0).

   Scoping it to desktop is the whole fix: it makes the pair exhaustive rather
   than overlapping, so the phone clamp owns mobile and this owns desktop, and
   nothing depends on source order between them.

   769 and 768 rather than 768 and 767, and that correction is what a boundary
   audit of every media query on the site turned up. Every other query splits at
   768/769 - breakpoints.css pairs max-width: 768px with min-width: 769px
   throughout, and layout.css sits at min-width: 1400px alongside it. These two
   rules were the only ones in page-overrides.css using 767/768, which put 768px
   itself in BOTH buckets at once.

   768 is the iPad portrait width, and it was being given this 50px desktop
   headline while breakpoints.css was applying the phone rules in the same
   breath. Measured across 766 to 772px: the headline ran 41.6px at 767px and
   50px at 768px, a 20% jump on a single pixel, and .hero-actions was still
   align-self: center at 768px having already turned flex-start at 769px. The
   two halves of one hero disagreed with each other at exactly one width, which
   is the kind of fault that survives review because nobody resizes to 768 and
   stops. 768 now belongs to mobile, like 767. */
@media (min-width: 769px) {
  #hero.hero--tint .hero-headline {
    font-size: 50px;
    line-height: 46px;
}
}
/* Lift query removed. It pushed the headline down with margin-top:
   clamp(40px, 27vh, 260px), parking the headline and the roles line in the
   upper third. Both now start near the top of the hero; the clearance below the
   header is the .hero-inner padding-top above, which already scales with the
   viewport. Phones had margin-top:0 from the 768px rule in breakpoints.css all
   along, so this makes the desktop match them. */
#hero.hero--tint .hero-actions {
  /* Centred, so all three children sit on the same axis as the hero itself.
     This row spent two rounds on flex-start: first centred, then put back to
     flex-start so the CTA could sit at the left edge under centred copy. Left it
     was, and left it measured - at a 1296x890 viewport the headline centre is
     643px and the pill centre is 643px, both on the hero's own centre line, while
     the button centre came out at 137px. Three elements in one column, on two
     different axes, which reads as a slip rather than a choice.

     align-self is what moves it: .hero-inner is a centred column, so the row's
     cross-axis position defaults to that centre only while align-items holds.
     flex-start overrode it. justify-content is the other half and matters on its
     own - it positions the button INSIDE the row - but the row itself is
     fit-content here, so the two move together and both are set.

     margin-top stays 0, not auto, so this row still does not take the slack. The
     headline's margin-top does, and that is what keeps the whole block on the
     bottom of the hero; a second auto would split the slack and lift the copy
     back into the middle. The gap above the button is still the .hero-roles
     margin-bottom, unchanged.

     Safe on phones: this rule is (1,2,0) and beats breakpoints.css's
     .hero--full .hero-actions at (0,2,0), so centring applies at every width,
     where before the phone inherited the same left alignment the desktop had. */
  align-self: flex-start;
  justify-content: flex-start;
  margin-top: auto;
  margin-bottom: 0;
}
/* Back to the left edge and the bottom, on the client's request.
   The comment above argues for centring this row on the hero's own axis, and
   that is what the rule did: align-self center and justify-content center put
   the button at x=546, centred, with 364px of empty grass below it because
   margin-top was 0 and nothing else in the column takes the slack.

   The client has asked for the button at the bottom-left twice now, so the
   centring argument stands as history rather than as the outcome.

   flex-start on both axes puts the button back on the container's left edge, and
   margin-top: auto gives this row the slack, which drops it to the bottom of the
   column. That auto is safe here and was not safe under the old centring rule:
   the headline's margin-top is clamp(60px, 12vh, 130px), a fixed distance rather
   than an auto, so this is the only auto in the column and it cannot split the
   slack with anything. The block above stays exactly where it is. */
/* The roles line sits in the flow column, directly under the headline and above
   the CTA. It used to live outside .hero-inner, absolutely positioned on the
   right and vertically centred on the hero, which read as a floating badge
   beside the copy rather than as part of it.

   align-self is explicit rather than inherited: .hero-inner is a centred flex
   column, so the pill lands on the same centre line as the headline above it.
   Without it, a future align-items:stretch on .hero-inner would silently widen
   the pill into a full-width bar.

   margin-top is 0 because the headline already carries the gap above the pill
   through its own margin-bottom.

   margin-bottom is the gap between this line and the CTA. While the copy block
   sat at the bottom of the hero this was the only thing that could lift the copy
   off the button, because .hero-headline carried margin-top:auto and parked the
   whole block there; raising it moved the text without moving the button.

   That relationship is gone. The auto now belongs to .hero-actions, so the button
   is pinned to the bottom by the slack itself and this value only sets a floor
   beneath the pill. It is still worth having, and the value is unchanged:
   clamp(44px, 9vh, 88px), which measures 51px between the pill and the button on
   a 320x568 phone and 81px at a 1446x900 desktop.

   Measured head-to-pill, the gap above this line, is untouched by any of that:
   18px to 27px from 1446 down to 320. */
#hero.hero--tint .hero-roles {
  position: static;
  align-self: center;
  display: flex;
  flex-direction: row;
  align-items: center;
  /* The two roles are separate elements now, not one string joined by a middot,
     so the space between them is the container's gap rather than a character.
     0.9em keeps it close to the old "· " width without the dot. */
  gap: 0.9em;
  flex-wrap: wrap;
  margin: 0 0 clamp(44px, 9vh, 88px);
  max-width: 100%;
}
#hero .hero-roles span {
  display: inline-block;
  font-family: var(--font-ui);
  /* Was a flat 0.72rem, the smallest type in the hero and smaller than the
     button label under it - 11.52px against the CTA's own, so the credential line
     read as a footnote to a call to action. Raised, and made to scale: the pill
     carries white-space: nowrap, so a flat larger value cannot work.

     The floor is 0.62rem, not the old 0.72rem. nowrap applies from 577px up (the
     576px rule below releases it), and at 577px the measure is 495px while the
     label needs 512px at 11.52px - a 17px overhang that .hero's overflow:hidden
     then clips off both rounded ends. That overhang is not new; it is what the
     old flat value already did at exactly this width, and the clamp inherited it
     by flooring at 0.72rem. Flooring at 0.62rem takes the box to 446px against
     the same 495px, 49px inside, and it is also the size the 576px rule below
     already uses, so the pill no longer jumps from 9.92px to 11.52px across that
     one-pixel boundary - it now grows out of the phone value instead of snapping.

     The ceiling of 1.15rem is reached at 1082px and holds above it: 798px in a
     1254px measure at 1296px, and 798px in 1440px at the container cap. Every
     width in between has been measured rather than assumed - 446/495 at 577,
     527/618 at 700, 598/758 at 800, 798/1058 at 1100 - and the tightest of them
     is the 577px floor with 49px to spare. */
  font-size: clamp(0.62rem, 1.7vw, 1.15rem);
  font-weight: 700;
  /* Was 600. Manrope ships no italic, so this is the browser's synthetic slant
     rather than a designed italic face - it is consistent and it holds up at this
     size, but it is worth knowing that it is not the foundry's letterforms. */
  font-style: italic;
  letter-spacing: 0.16em;
  /* 0.625rem, down from 0.72rem. 10px, on the client's request to reduce these
     two role labels.
     10px is the floor rather than something smaller. This is uppercase text at
     weight 600 on a pill, read once on the way past, and 10px is the smallest
     size at which that stays comfortable rather than becoming a smudge. It is
     measured down from 11.52px rather than guessed at.

     Tracking and padding come down with it, so the pill shrinks as a unit
     instead of the type shrinking inside a pill that stayed the same size. At
     10px the original 0.16em opened enough space between letters to make the
     words read apart, and 9px of vertical padding on a 10px cap height made the
     pill feel taller than the text it held. */
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--white);
  /* 0.92, not 0.5. At half opacity this pill was a dark wash over whatever was
     behind it, which was safe while the copy sat low over dark grass and is not
     safe over the bright middle of the frame where it sits now: white 11.5px
     text on gold at 0.5 composited to 2.93:1, which is under AA for small text.

     At 0.92 the composited ground is about 0.12 luminance against the band
     median of 0.545, which puts the white text at 6.2:1. The border follows to
     match, since a 28%-white hairline over a bright band was carrying the pill's
     edge rather than describing it. */
  background: rgba(34, 84, 76, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.55);
  padding: 7px 13px;
  border-radius: 999px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  white-space: nowrap;
}

/* Header over photo hero light text until scrolled past

   .logo-first is no longer in this list. It used to be the second line, taking
   #fff with the rest, and the wordmark was one ink on all thirteen banners. The
   client wants the mix reversed in the banner bar - "Saeed" is now white
    and "ur Riaz" inherits light text-into --gold-soft - so it is
    taken out of the group and given the two rules below:.logo-name gets
    --gold-soft, .logo-first gets white. Scoped .header-inner > .logo, so the
    drawer's own copy of the wordmark keeps its flat treatment. */
body.dark-hero .site-header:not(.scrolled) .header-inner > .logo .logo-name { color: var(--banner-ink);}
body.dark-hero .site-header:not(.scrolled) .header-inner > .logo .logo-first { color: #fff;}
body.dark-hero .site-header:not(.scrolled) .nav-list a,
body.dark-hero .site-header:not(.scrolled) .header-phone,
body.dark-hero .site-header:not(.scrolled) .header-phone-sep {
  color: #fff;
}
/* The tagline is out of the group above, for the same reason .logo-first is: it
   carries the accent over a banner rather than plain white, so it needs its own
   declaration instead of inheriting the one the nav and phone share.

   --banner-ink, not --gold. Over a photograph the brand colour is unusable at
   this size: --gold measures 0.072 luminance against a worst banner pixel of
   0.1374, so it would be darker than the ground. --banner-ink is the same hue
   family carried to the lightness that ground needs, and it measures 4.84:1
   where the rgba white it replaces measured about 4.78:1, so the swap is
   contrast-neutral as well as being the accent.

   9.6px is the smallest text in the bar and never counts as large text, so 4.5:1
   is the floor and this is close to it. That is the whole budget on these
   banners: the baked veils are light enough that the tagline is what limits how
   light they could be made. */
body.dark-hero .site-header:not(.scrolled) .logo-tagline { color: var(--banner-ink);}
/* Same reason as the :is(.about-page, .faq-page, .poem-page, .page-contact) pair further up. The resting
   .nav-list a line in the block above is (0,4,2) and beats the base (0,2,1)
   hover rule, so without this line the white pill painted under white text. */
body.dark-hero .site-header:not(.scrolled) .nav-list a:hover,
body.dark-hero .site-header:not(.scrolled) .nav-list a:focus-visible {
  color: var(--black);
  background: rgba(255, 255, 255, 0.9);
}
/* The hover here used to be rgba(255,255,255,0.14): a translucent white slab
   that sat on the photo as a washed-out grey box, and it painted no focus state
   at all. Dropping it lets the base rule take over, which is white on the accent
   pill - the same thing .nav-list a.active does two rules below, so hover,
   current page and focus all look alike across every banner page.

   The phone numbers kept their own hover rather than following the nav, because
   they are not pills: they sit as bare digits in the header and a filled block
   behind a phone number reads as a button that is not one. */
body.dark-hero .site-header:not(.scrolled) .header-phone:hover,
body.dark-hero .site-header:not(.scrolled) .header-phone:focus-visible {
  color: var(--white);
  background: transparent;
}
/* Focus rings over a photo banner.

   The floor set in design-tokens.css is a gold ring, which is right on the light
   scrolled bar and wrong here. Until the page moves, this header is transparent
   over the hero image, and gold on that ground measures 1.43:1. Keyboard focus
   was landing on a ring nobody could see.

   The phone numbers were the worse case: they carried outline: none outright,
   so they painted no ring at all rather than a bad one. That is gone, and they
   take the ivory ring below with the rest of the bar.

   Ivory rather than white because it is the ink this header already sets, and a
   ring drawn in a different colour from the text it is marking reads as foreign
   rather than as part of the same control.

   The .active rule underneath is deliberately untouched by this. Its gold pill
   is a fill with white text sitting inside the bar, not a ring drawn outside
   the border box, so the contrast argument that applies to a ring does not
   apply to it. */
body.dark-hero .site-header:not(.scrolled) .nav-list a:focus-visible,
body.dark-hero .site-header:not(.scrolled) .logo:focus-visible,
body.dark-hero .site-header:not(.scrolled) .header-phone:focus-visible,
body.dark-hero .site-header:not(.scrolled) .menu-toggle:focus-visible,
body.dark-hero .site-header:not(.scrolled) a.header-cta:focus-visible {
  outline-color: var(--ivory);
}
body.dark-hero .site-header:not(.scrolled) .nav-list a.active {
  background: var(--gold);
  color: #fff;
}
body.dark-hero .site-header:not(.scrolled) .has-dropdown > a .ph { color: #fff;}
body.dark-hero .site-header:not(.scrolled) .menu-toggle span { background: #fff;}

/* Home: What we work on / How it works ---------- */
/* Was gold-soft #E4EFEB, the last coloured section band on the site. Now
   matches .section so the white runs unbroken top to bottom. */
.section--mint { background: var(--butter);}
/* The #work-on .lead rule that stood here was removed with the lead itself: the
   section head is now just the eyebrow and the heading, so nothing matched it. */
.themes-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(14px, 1.8vw, 24px);
}
.theme-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid rgba(34, 84, 76, 0.08);
  border-radius: var(--radius-lg);
  padding: clamp(22px, 2vw, 30px);
  gap: 10px;
}
.theme-card h3 {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  font-weight: 600;
  color: var(--black);
  margin: 0;
}
.theme-card p {
  color: var(--charcoal-2);
  font-size: 0.95rem;
  line-height: 1.7;
  margin: 0;
}
/* 620px cap kept, margin-inline removed.
   The auto margins centred the lead box itself while it was centred text, which
   was right for the .section-head.center this block used to be. It is now left
   aligned, so the auto margins left a 620px box floating in the middle of a
   1088px column, starting 234px in from the heading above it. margin-inline: 0
   puts the box back on the container's left edge with its heading. */
#the-process .section-head .lead { max-width: 620px; margin-inline: 0;}
.hiw-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(14px, 1.6vw, 22px);
}
.hiw-card {
  background: var(--white);
  border: 1px solid rgba(34, 84, 76, 0.08);
  border-radius: var(--radius-lg);
  padding: clamp(20px, 2vw, 28px);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
}
.hiw-num {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--gold-soft);
  color: var(--gold);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.1rem;
  display: grid;
  place-items: center;
  margin: 0 auto 6px;
}
.hiw-label {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  line-height: 1.4;
}
.hiw-card h3 {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  font-weight: 600;
  color: var(--black);
  margin: 0;
}
.hiw-card p {
  color: var(--charcoal-2);
  margin: 0;
  text-align: center;
  hyphens: manual;
  text-justify: auto;
}
.hiw-card p:not(.hiw-label) {
  font-size: 0.92rem;
  line-height: 1.65;
}

/* Hover lift, accent border, heading tint, number pop */
.theme-card,
.hiw-card {
  transition:
    transform 0.45s cubic-bezier(.16, 1, .3, 1),
    box-shadow 0.45s cubic-bezier(.16, 1, .3, 1),
    border-color 0.45s ease;
}
.theme-card:hover,
.hiw-card:hover {
  transform: translateY(-6px);
  border-color: rgba(34, 84, 76, 0.28);
  box-shadow: 0 20px 44px -20px rgba(34, 84, 76, 0.4);
}
/* Was --gold on hover. The card still lifts, tints its border and takes the
   green shadow, so the hover is not lost - the heading simply stops changing
   colour. A heading that recolours on hover is the last colour-mix left on a
   light card. */
.theme-card:hover h3,
.hiw-card:hover h3 { color: var(--black);}
.hiw-num {
  transition: transform 0.45s cubic-bezier(.16, 1, .3, 1), background 0.45s ease;
}
.hiw-card:hover .hiw-num {
  transform: scale(1.1);
  background: var(--gold);
  color: #fff;
}

/* The Process (detailed steps) step cards in one row, wider */
#the-process .container { width: min(100% - 32px, 1700px);}
#the-process .hiw-grid {
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(14px, 1.6vw, 22px);
}
#the-process .hiw-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: clamp(20px, 2vw, 28px);
}
#the-process .hiw-num {
  width: 44px;
  height: 44px;
  font-size: 1.1rem;
  /* 0, not 6px. .hiw-num carries margin: 0 auto 6px at page-overrides.css:2077,
     which was written when the card was block layout and the margins did the
     spacing. #the-process .hiw-card is a column FLEX with gap: 8px, so that 6px
     was adding to the gap rather than replacing it: measured 14px between the
     badge and the label where every other gap in the card is 8px.

     The horizontal auto is kept and is still load bearing. On a column flex
     item, auto side margins centre it in the cross axis, so it is what centres
     the badge; only the bottom is reset. */
  margin-bottom: 0;
}
/* The heading rule that used to sit here,
   `#the-process .section-head .h-section { font-size: clamp(1.3rem, 2.2vw, 1.9rem)}`,
   is gone. At (1,2,0) it beat the shared .h-section scale and left this the only
   section heading on the page at a different size from its siblings: measured
   21.8px here against 30.7px for every other .h-section at 1446, and 20.8px
   against 20.0px at 390.

   Nothing else separated them. The markup is identical to #testimonials -
   .section-head.center.space > .container wrapping a .h-section - and dropping
   the rule gives 30.7px at 1446, the same value the other sections get. It still
   holds one line at every width, this section's container running to 1700px.

   Everything left in this block sizes the .hiw-* cards, which is what the
   section was actually tuned for. The heading was never part of that. */
#the-process .hiw-card h3 { font-size: clamp(0.9rem, 1vw, 1rem);}
#the-process .hiw-card p:not(.hiw-label) { font-size: 0.95rem; line-height: 1.65;}
/* Five columns only where five columns fit.

   The 5 to 3 step sat at 1100px, which left a band from 1101 to roughly 1300px
   where the cards were narrower than they are at ANY other width on the site.
   Measured card width and paragraph length, before this change:

     1101px  5 col  card 162px  body 14, 11, 12, 10, 11 lines  card 509px tall
     1280px  5 col  card 190px  body 11,  8,  9,  9, 10 lines  card 426px tall
     1024px  3 col  card 262px  body  7,  5,  6,  6,  6 lines  card 316px tall

   So the five-column layout was at its worst exactly where the three-column one
   took over and got better. 162px holds a 14-line paragraph in a 509px box:
   five tall thin columns, and the shortest body text on the page is 10 lines.

   Moving the step to 1400px makes the narrowest five-column card about 210px
   instead of 162px, which is where the body runs to about 8 lines rather than
   14. Below 1400px the three-column cards pick up from 379px at the top of that
   band down to 262px at 1024px, so no width anywhere gets a card worse than it
   had.

   The arithmetic above 1400px is arithmetic, not measured: the offscreen
   browser used for this audit caps its iframe at 1325px, so the five-column
   cards could only be observed up to there. Everything from 769 to 1325 was
   measured directly. */
@media (max-width: 1400px) {
  #the-process .hiw-grid { grid-template-columns: repeat(3, 1fr);}
}
/* Two columns from 1022px down, and one from 760px.

   The first pass at this fixed the 5-column band and moved the same fault
   straight down to the next step. Three columns stop at 680px, so from 681px
   the cards were narrower than they had been at any width since:

     681px  3 col  card 167px  body 11, 9, 10, 10, 11 lines  card 415px tall
     768px  3 col  card 192px  body  9, 8,  8,  8,  8 lines  card 365px tall
     900px  3 col  card 228px  body  8, 6,  7,  7,  7 lines  card 340px tall
    1024px  3 col  card 262px  body  7,  5,  6,  6,  6 lines  card 316px tall

   So the worst cards on the page had become the ones just above the single
   column step. 167px holding an 11-line paragraph is the fault that was just
   fixed at 162px, one breakpoint down.

   Three columns only hold a readable card above about 1024px, which is where
   the measured 262px and 7 lines above sit. Below that two columns give:

     900px  2 col  card 310px  body 5 lines
     768px  2 col  card 244px  body 7 lines

   and one column takes over at 760px, where two columns would drop back to
   about 200px. At 390px the single column is 286px with 5 to 6 lines, which
   was already the best result anywhere on the page and is unchanged.

   All three queries share one selector and one specificity, so the cascade
   resolves them by order: at 900px only the 3 and 2 column rules match and the
   later one wins; at 390px all three match and the last wins. No min-width
   ranges are needed and there is no width where two of these disagree. */
@media (max-width: 1022px) {
  #the-process .hiw-grid { grid-template-columns: repeat(2, 1fr);}
}
@media (max-width: 760px) {
  #the-process .hiw-grid { grid-template-columns: 1fr;}
}

/* ---------- Half-hour CTA banner ---------- */
.halfhour-cta {
  text-align: center;
  padding: clamp(72px, 9vw, 120px) 0;
  /* Full bleed, on the client's request.
     This band is a photographic panel, and it was sitting inside the section's
     --section-inset on both sides: 1120px of band in a 1335px section, so a
     column of page either side of it that the band did not fill.

     The inset is cancelled with the token rather than reached past with width:
     100vw. --section-inset is calc(--page-pad / 2) and --page-pad is
     clamp(32px, 16vw, 226.8px), so 100vw would have to subtract the scrollbar by
     hand at every width and would put the scrollbar inside the band. This
     measures 107.6px per side at 1325px, which is exactly the padding it is
     cancelling, and it tracks the token on its own at every breakpoint.

     The content is unaffected. The block is text-align: center, the lead already
     caps itself at 620px with margin-inline: auto, and the two buttons are centred
     by .cta-actions, so nothing inside widens with the band. */
  margin-inline: calc(-1 * var(--section-inset));
  background:
    linear-gradient(rgba(34, 84, 76, 0.8), rgba(22, 54, 48, 0.88)),
    url("https://images.pexels.com/photos/19328973/pexels-photo-19328973.jpeg?auto=compress&cs=tinysrgb&w=2560") center / cover no-repeat;
}
.halfhour-cta .h-section { color: #fff;}
/* Was --gold-soft. It passed contrast, so this is not a legibility fix: the
   point is that a heading is one colour. The pale mint sat inside a white
   headline and read as a second, weaker colour run. Inherit keeps the whole
   line white. */
.halfhour-cta .em-serif { color: inherit;}
.halfhour-cta .lead { color: rgba(255, 255, 255, 0.85); max-width: 620px; margin-inline: auto;}
.halfhour-cta .cta-actions { margin-top: 1.8em;}
.halfhour-cta .btn-gold { background: #2E6B60;}

/* ---------- FAQ ---------- */
/* The half-hour CTA now closes the section, so the trailing .section padding
   would only add dead space below it. The top padding is gone for the same
   reason from the other side: the banner is a sibling section now, so a second
   band of padding underneath it would just open a gap.

   The old .faq-banner block - a flat white slab with the eyebrow, heading and
   lead stacked in a container - is deleted rather than left in place. Nothing
   references it any more, and the heading it sized has moved into the hero. */
.faq-section { padding-top: 0; padding-bottom: 0;}
.faq-list {
  max-width: 760px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.faq-item {
  background: var(--white);
  border: 1px solid rgba(34, 84, 76, 0.08);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.faq-item:hover { border-color: rgba(34, 84, 76, 0.22);}
.faq-item.open {
  border-color: rgba(34, 84, 76, 0.3);
  box-shadow: 0 16px 36px -22px rgba(34, 84, 76, 0.35);
}
.faq-q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: clamp(18px, 2vw, 24px) clamp(20px, 2.5vw, 30px);
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-display);
  font-size: clamp(1rem, 1.4vw, 1.15rem);
  font-weight: 600;
  color: var(--charcoal);
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
/* The FAQ rows are the other big phone target on the site. A tint rather than a
   move, because each one is a full-width row: translating a row that wide looks
   like the layout shifting, while a 6% wash of the accent reads as the row
   acknowledging the finger. 0.06 is deliberately faint, it is a press and not a
   state, and the row must not look selected once the finger lifts. */
.faq-q:active { background: rgba(34, 84, 76, 0.06);}
.faq-q span:first-child { min-width: 0;}
/* FAQ list is centre-aligned to match the centred section header */
.faq-list .faq-q { justify-content: center; text-align: center;}
.faq-list .faq-a p { text-align: center;}
.faq-ic { position: relative; flex: 0 0 16px; width: 16px; height: 16px; color: var(--gold);}
.faq-ic::before,
.faq-ic::after {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: translateY(-50%);
  transition: transform 0.35s var(--ease);
}
.faq-ic::after { transform: translateY(-50%) rotate(90deg);}
.faq-item.open .faq-ic::after { transform: translateY(-50%) rotate(0deg);}
.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ease);
}
.faq-item.open .faq-a { grid-template-rows: 1fr;}
.faq-a p {
  overflow: hidden;
  min-height: 0;
  margin: 0;
  padding: 0 clamp(20px, 2.5vw, 30px);
  color: var(--charcoal-2);
  font-size: 0.95rem;
  line-height: 1.75;
}
.faq-item.open .faq-a p { padding-bottom: clamp(18px, 2vw, 24px);}
/* collapsed answers must shrink to exactly 0 mobile padding rules add a bottom pad
   that keeps a sliver of the first line visible under every closed card */
.faq-list .faq-item:not(.open) .faq-a p { padding-bottom: 0;}
.faq-a a { color: var(--gold); font-weight: 600;}
@media (max-width: 480px) {
  .halfhour-cta .cta-actions { flex-direction: column;}
  .halfhour-cta .cta-actions .btn { justify-content: center;}
}
@media (max-width: 1100px) {
  .hiw-grid { grid-template-columns: repeat(3, 1fr);}
}
@media (max-width: 680px) {
  .hiw-grid { grid-template-columns: 1fr;}
}
@media (max-width: 768px) {
  #meet .section-head .h-section { white-space: normal;}
}

/* ---------- 1-ON-1 COACHING PAGE ---------- */
.page-one-on-one .section-head .eyebrow { font-size: 0.9rem; letter-spacing: 0.25em;}
.page-one-on-one .section-head.center { margin-bottom: 12px;}
/* Was --gold. This is the only light-ground heading on the site that was still
   two-toned, so the accent word is dropped and the span takes the heading ink. */
.page-one-on-one .section-head .em-serif { color: inherit;}
.page-one-on-one .why-item h3 { font-size: 1.6rem; font-weight: 600;}
.page-one-on-one .card-note { text-align: center;}

/* ---------- CORPORATE WELLBEING PAGE ---------- */
.services-hero { align-items: flex-end;}
.services-hero .section-head.narrow { max-width: 1040px;}

/* ---------- Home: Core Philosophy statement band ---------- */
/* Was white #FFFFFF, brighter than the ivory around it, which read as a hole
   punched in the page rather than a band. Now matches .section either way. */
.philosophy-section { background: var(--butter);}
/* .philosophy-section's container used to cap at 1080px while the shared
   .container caps at --container (1440px). Both are centered, so on any screen
   wide enough for that 1080/1440 difference the philosophy heading and every
   paragraph started ~180px to the right of the section they sat next to (the
   Welcome copy above). Matching the shared cap aligns this section's left edge
   with every other section at any viewport width. */
.philosophy-section .container { max-width: var(--container);}
.philosophy-section .philosophy-body { max-width: 900px; margin-inline: auto; text-align: center; padding: clamp(12px, 2vw, 28px) 0;}
/* "The Core Philosophy" was an <p class="eyebrow">, a 0.72rem gold uppercase label. It is
   a real <h2> now, so the small eyebrow treatment is gone and it needs a size of its own.
   .h-section would not do: that class is tuned for a heading sitting above body copy, and
   at its 3.6rem ceiling this one would be the loudest thing in a band whose whole point
   is that the quote is. Hence .h-mid, sized against the quote rather than in isolation.

   2.1vw is 0.75 of the pull quote's 2.8vw, so the two stay in the same proportion across
   the range instead of drifting as a fixed cap would. This matters more than it looks:
   with the 2rem cap this heading sat at 32px while the quote was only 30.8px at 1090px,
   so the label out-shouted the statement it introduces at every width below 1143px. The
   1.75rem cap is where it stops on desktop, under the quote's own 2.3rem ceiling.

   The 13px floor is the price of the one-line rule, and it is worth being plain about.
   The heading beneath it is 39 characters and needs 17.83px of column per px of type, so
   on a phone it only fits at about 19px. A section heading at a fixed 21.6px floor would
   therefore render LARGER than the h3 below it, inverting the outline. Since one line is
   not negotiable the h2 yields instead and tracks the h3 downward: the shallower slope and
   the -1px offset guarantee h2 < h3 at every width, not merely at the ones measured.

   On real phones this lands at 13px, under the 16px body size, because the quote's own
   floor of 22.4px and the h3's 15.6px leave no room. That is a real cost, and the only
   way out is to let this heading wrap on phones, which is a decision rather than a
   measurement. This heading's own ceiling is nowhere near binding (900/9.42 = 95px on
   desktop), so every number here is a hierarchy or design choice, never a fit limit. */
.philosophy-section .philosophy-body .h-mid {
  font-size: clamp(13px, calc(2.1vw - 1px), 1.75rem);
  margin-bottom: clamp(20px, 3vw, 36px);
}
.philosophy-section .philosophy-quote {
  margin: 0;
  padding: 0;
  border-left: none;
  border-radius: 0;
  background: none;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.1vw, 1.75rem);
  line-height: 1.5;
  font-weight: 500;
  color: var(--charcoal);
  /* Left, with the rest of the section. It was centre, held there on the
     judgement that a 28px quotation reads as body copy that got bigger if it
     sits flush left. The client has the call on that and asked for it left,
     starting on the same edge as the heading above and the four paragraphs
     below. See "Home: the Core Philosophy section, left aligned" below, which
     previously recorded this as the one deliberate exception in the block.

     text-wrap: balance stays. It is a fit rule rather than an alignment rule and
     still helps a 900px measure, but with the text flush left it now balances
     each line's length instead of centring it. */
  text-align: left;
  text-wrap: balance;
}
.philosophy-section .philosophy-quote::before {
  content: "\201C";
  display: block;
  font-family: var(--font-display);
  font-size: 2.4rem;
  line-height: 1;
  color: var(--gold);
  opacity: 0.55;
  margin-bottom: clamp(18px, 2.5vw, 30px);
}

/* ---------- Home: Section 03 detail copy under the philosophy quote ---------- */
#philosophy .philosophy-detail {
  max-width: 820px;
  margin: clamp(40px, 5vw, 72px) auto 0;
}
/* Demoted from h2 to h3 when "The Core Philosophy" became the section heading.

   It keeps the .h-section class, which is what put it on two lines: that class caps at
   3.6rem, and this 39-character heading needs 17.83px of column per px of type. The box
   it has to fit is 820px on desktop but only 348px at 380px, so the desktop ceiling is
   46px and the same text at 380px only fits at 19px. No single cap serves both, which
   is why the middle term is a slope.

   5.3vw - 1.4px was swept live rather than derived on paper, because deriving it went
   wrong twice: the factor of 100 that separates px from vw got inverted once, sending
   the coefficient to 0.0538vw, which evaluated to 0.54px and pinned every width to the
   floor. Injected as real CSS so the browser resolves vw itself, 5.5vw overflows by up
   to 9.7px through the middle of the phone range and 5.3vw is the shallowest slope that
   clears every width from 320px to 1440px.

   320px is the floor because that is where the rest of the site stops holding one line:
   at 310px ten other headings already wrap and the page carries 8px of overflow, so
   widths below it were never a target and the 14px floor is never reached in practice.
   Above ~890px the box stops widening at 820px and the 2.7rem cap takes over, so the
   slope only governs where it is the correct constraint. */
#philosophy .philosophy-detail .h-section {
  /* Left, on the client's request, with the rest of this section.
     It was text-align: center. See "Home: the Core Philosophy section, left
     aligned" below for the whole block and why the cap is unchanged. */
  text-align: left;
  margin-bottom: 0.6em;
  font-size: clamp(14px, calc(5.3vw - 1.4px), 2.7rem);
}
/* left-aligned inside a centred column: four body paragraphs set centred
   are hard to track back to the next line */
#philosophy .philosophy-detail p {
  hyphens: manual;
  color: var(--charcoal-2);
  margin-bottom: 1.1em;
}
#philosophy .philosophy-detail p:last-child { margin-bottom: 0;}

/* ---------- Home: the Core Philosophy section, left aligned ----------
   "The Core Philosophy" and everything under it were centred: the section
   heading, the pull quote, the sub-heading, and all four paragraphs. They are
   left aligned now, on the client's request, and the two columns are pulled off
   the page centre to meet the container's left edge so the text does not sit as a
   centred column of left-aligned lines.

   The two centred blocks each carried margin-inline: auto to hold them at 900px
   and 820px. That is what centred the boxes, and it is changed to 0 rather than
   left alone, or the text would be left aligned inside a box still floating in
   the middle of the container with 218px of space above nothing on either side.

   The quote was left as the one centred element in this block, on the judgement
   that a 28px quotation reads as body copy that got bigger if it sits flush left.
   The client has since asked for it left as well, so the whole section now starts
   from one edge: the section heading, the pull quote, the sub-heading and all four
   paragraphs.

   text-align has to be set on .philosophy-detail itself, not on its paragraphs.
   .philosophy-section sets text-align: center, and the four paragraphs were
   inheriting it from three levels up rather than being targeted by any rule of
   their own. Moving the boxes left and leaving alignment alone was tried first
   and produced left-aligned headings over still-centred body copy.

   The sub-heading cap is unchanged. It is clamp(14px, 5.3vw - 1.4px, 2.7rem),
   swept live to hold this 39-character heading to one line from 320px to 1440px,
   and alignment does not change how much width the string needs, so re-sweeping
   it would be work with no effect. */
#philosophy .philosophy-body { text-align: left; margin-inline: 0; }
#philosophy .philosophy-body .h-section,
#philosophy .philosophy-body h1 { text-align: left; }
#philosophy .philosophy-detail { margin-inline: 0; text-align: left; }

/* ---------- Home: Section 04 transformation outcomes ---------- */
.achieve-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2vw, 26px);
}
.achieve-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid rgba(34, 84, 76, 0.08);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 2.4vw, 34px);
  transition:
    transform 0.45s cubic-bezier(.16, 1, .3, 1),
    box-shadow 0.45s cubic-bezier(.16, 1, .3, 1),
    border-color 0.45s ease;
}
.achieve-card:hover {
  transform: translateY(-6px);
  border-color: rgba(34, 84, 76, 0.28);
  box-shadow: 0 20px 44px -20px rgba(34, 84, 76, 0.4);
}
.achieve-label {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.6vw, 1.32rem);
  font-weight: 600;
  line-height: 1.2;
  color: var(--black);
  margin: 0 0 10px;
  transition: color 0.45s ease;
}
/* Was --gold, same hover-accent change as .theme-card and .hiw-card above. The
   card still lifts and takes the accent border and shadow, so the hover state is
   intact; the heading just stops recolouring. */
.achieve-card:hover .achieve-label { color: var(--black);}
.achieve-card p {
  color: var(--charcoal-2);
  font-size: 0.95rem;
  line-height: 1.7;
  margin: 0;
}

/* ---------- Home: What coaching is (scope & safety note) ---------- */
.coaching-scope .scope-card { max-width: 1040px; margin-inline: auto;}
.coaching-scope .faq-item { border-radius: var(--radius-lg);}
.coaching-scope .faq-a p { padding-bottom: 0;}
.coaching-scope .faq-item.open .faq-a p { padding-bottom: 0;}
/* Left, and evenly spaced, on the client's request.

   These three paragraphs were centred. They are running copy at 15.2px, not a
   pull quote, and centred running copy over three paragraphs makes the second
   and third lines of each paragraph ragged against each other with no common
   left edge to come back to. Left, all three start at the same x, 30px inside
   the card, which is the card's own padding rather than an indent added here.

   The space is set in one place rather than per paragraph. Measured before this
   change: 22px of text-to-text gap between each pair, but the first paragraph
   had no top margin at all, so the drop from the "A note on scope and safety"
   question down to the first line was tighter than the two gaps inside the copy.
   One margin-top on every paragraph makes the two gaps inside the copy the same,
   and it uses an em so it scales with the clamp on the paragraph size instead of
   being a fixed number of pixels.

   The first paragraph keeps no margin of its own, because the space above it is
   already governed by the question's own 24px padding-bottom. Giving it the same
   1.1em as the other two was tried and made the drop from the question to the
   first line 43px against 22px between the paragraphs, which is worse than the
   26px it was before. The question's padding is trimmed by the same 4px so all
   three gaps land on 22px rather than nearly on it. */
.coaching-scope .faq-item.open .faq-a p {
  text-align: left;
  margin-top: 1.1em;
}
.coaching-scope .faq-item.open .faq-a p:first-child { margin-top: 0;}
.coaching-scope .faq-q { padding-bottom: 20px;}

/* ---------- Home: Section 02 welcome brief (copy left, image right) ---------- */
#meet .welcome-grid {
  display: grid;
  /* The photo column is sized to the circle rather than taking an equal 1fr
     share. With two 1fr columns the circle was 420px wide but centred in a
     557px column, and that 68px of slack on its left was dead space pushing it
     away from the copy: about 140px between the brief and the photo at 1446, of
     which only 72px was the gap. Sizing the column to the circle means the
     circle fills it and the gap is the whole distance again.

     The column is clamp(260px, 34vw, 420px) rather than a flat 420px. Flat
     420px measured the brief down to 160px wide at 769px, about 20 characters
     a line, which is too narrow to read. The clamp gives the full 420px at
     1446 and then scales the photo down with the viewport, which keeps the
     brief between 743px and 329px across 769px to 1446.

     The gap drops from clamp(32px, 5vw, 72px) to clamp(24px, 3vw, 48px) on top
     of that, which takes the space between the two to roughly 43px at 1446.

     Below 769px breakpoints.css collapses this to a single column with its own
     24px gap, so neither declaration applies on a phone. */
  grid-template-columns: minmax(0, 1fr) minmax(0, clamp(260px, 34vw, 420px));
  gap: clamp(24px, 3vw, 48px);
  /* start, not center: the brief's top edge lines up with the top of the
     photo instead of floating midway down it */
  align-items: start;
}
/* The photo is clipped to a true ellipse by a 50% radius. This replaced the SVG
   blob path that used to live in <defs> on index.html and was referenced here as
   clip-path: url(#welcome-blob); that shape is gone.

   A 50% radius follows the image's own 750x713 proportions, so the clip stays an
   ellipse that matches the photo's ratio instead of a letterboxed circle.

   The radius is carried twice, on the figure and on the image below, because the
   two do different jobs and neither one alone is enough. On the <img> it is the
   shape the photo is actually clipped to. On the figure it is what gives the
   box-shadow an elliptical edge; the shadow is painted by the figure, so an
   image-only radius would leave a rectangular shadow behind, which reads as a
   box around a circle. */
#meet .welcome-media {
  /* Capped and centred. The figure is a grid item in a 1fr column, so before
     this it took the full column width: measured 661x628 at 1446 and 726x690 at
     768, which is wider than the copy beside it and pulled the eye off the
     text. min(100%, 420px) holds it to 420x400 wherever the column is wider,
     and the auto inline margins centre it in what is left, so the circle no
     longer sits hard against the left edge with 241px of dead space to its
     right. Below 420px of column the min() hands back to the column and the
     circle is unchanged: still 348x331 at 390 and 294x279 at 320. */
  margin: 0 auto;
  width: min(100%, 420px);
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 24px 60px -28px rgba(32, 28, 22, 0.45);
}
/* The box stays 750/713 even though the photo is now 363x409, which is portrait
   at 0.8875 rather than the 1.052 this ratio was pinned for. Matching the source
   ratio here would turn the circle into a tall ellipse, and the circular clip is
   what was asked for. cover never distorts, so the cost of holding the shape is
   a crop: at 420px wide the portrait scales to 420x473 and about 37px comes off
   the top and 37px off the bottom, roughly 8% at each end. If that ever cuts the
   top of the head, object-position is the dial - it defaults to centre and can
   be pushed up without touching the box.

   The 50% radius here is the ellipse the photo is clipped to, matching the one on
   the figure above so the image edge and the shadow edge are the same curve. */
#meet .welcome-media img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  aspect-ratio: 750 / 713;
  border-radius: 50%;
}
/* This block was set in Calibri, Candara, "Segoe UI" - a Windows-only stack.
   It rendered in Calibri on the machine that built it and fell back to Arial on
   Mac and Linux, so the "Meet the coach" copy was a visibly different typeface
   from the rest of the page. var(--font-ui) is the body face this was reaching
   for; the title takes the display face like every other heading. */
#meet .welcome-brief {
  text-align: left;
  font-family: var(--font-ui);
}
#meet .welcome-title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--black);
  margin-bottom: 14px;
}
#meet .welcome-brief p {
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.7;
  color: var(--charcoal-2);
  margin-bottom: 14px;
  hyphens: manual;
}
#meet .welcome-brief p:last-child { margin-bottom: 0;}

/* The floor was 0.8rem, which is 12.8px. 3.2vw only climbs past that at about a
   400px viewport, so on every phone the floor won and the hero headline rendered
   at 13px - smaller than the body copy under it. Measured on financial-wellbeing
   at 390px: 13px against 20px for the section headings below and 16px for body
   copy. 1.3rem is the same 20.8px the shared .h-section ladder reaches on a
   phone, so the hero now opens the page at the size the sections below it use.

   Nothing above a 650px viewport moves: 3.2vw passes 1.3rem at 650px and the cap
   is unchanged. The same 0.8rem floor was on the .page-corporate variant and had
   the same defect. */
.services-hero .display { font-size: clamp(1.3rem, 3.2vw, 2.8rem);}
.services-hero .lead { margin-top: 0.5em;}
/* The font-size is gone from this selector too. It was clamp(1.3rem, 3.2vw,
   2.8rem), 41.5px at 1296px, and at (0,3,0) it outranked the
   h1.display.h-display rule that carries every other page hero, so corporate
   opened at 41.5px where emotional, financial and programs opened at 50px on
   identical markup. Above 769px all four .services-hero heroes now share the
   one 50px figure. Below 769px the clamp above still governs, and that is the
   only range this selector was ever needed for. */
.page-corporate .services-hero .display { }
/* nowrap has to go on a phone, or the larger type overflows the measure: 20.8px
   across a 29-character headline needs roughly 302px of the 286px a 390px
   viewport leaves inside .services-hero. Above 576px there is room and it stays
   on one line as before. */
/* nowrap is now gone at every width, not just below 576px, and it is the size
   unification that forces it. It was holding these four headings to a single
   line, which was safe while they carried their own clamp - at 769px that clamp
   gave 24.6px. At the shared 50px the same nowrap no longer fits: measured, the
   corporate heading overflows its own box by 309px at 769px and 178px at 900px,
   and programs by 157px at 769px. The text cannot break, so it spills out of the
   heading rather than wrapping, and .hero clips it.

   Letting it wrap is what the home page already does with a longer headline -
   .hero-headline is white-space: normal and sets "Elevate Your Life. Restore
   Your Balance." over two lines at 50px. These four are now on that figure, so
   they wrap with it. Both affected strings set on two lines between 769px and
   about 1100px and return to one line above that, which is the same shape home
   already has. */
/* .page-packages .services-hero .display used to sit here, widening this
   heading to clamp(2rem, 5vw, 4.2rem) and letting it wrap instead of holding
   one line. Both are gone with the class: packages is a .packages-banner now
   and its h1 is "Packages and Fee", 16 characters, which holds one line on the
   shared .h-display scale at every width from 1600px down to 320px. The
   nowrap the wrapping rule existed to cancel is still live two lines above for
   programs and the three wellbeing pages, which still carry .services-hero. */
.what-to-expect .section-head { margin-bottom: 0; text-align: left;}
.what-to-expect .section-head .h-section { text-align: center;}
.what-to-expect .card-note { margin-top: 0; text-align: left;}
.what-to-expect .cta-actions { justify-content: center; margin-top: 2rem;}

/* Large section heading "Corporate Services" as h1, on corporate-wellbeing.html.
   The .page-packages half of this selector is gone. Packages used to carry three
   of these, one above each Package section, which made it the only page on the
   site with four h1 elements, and all three of those sections are gone. The
   companion "+ .h-section" rule went with them: it sized the heading that
   followed an eyebrow, and corporate-wellbeing.html's eyebrow is the only child
   of its .section-head, so nothing on the site matches it any more. */
.page-corporate .section-head h1.eyebrow {
  /* Section level: the shared clamp(1.6rem, 3.1vw, 36px). Was
     clamp(2.4rem, 5vw, 4.2rem), 64.8px at 1296px - the largest heading on the
     site after the heroes it sat below. It is a .section-head heading, not a
     hero: the h1 here is a promoted eyebrow, and the page's actual hero is the
     .display.h-display above it. The rest of the rule is unchanged and still
     load-bearing - it strips the eyebrow's tracking and uppercase, points it at
     the display face and holds the black ink, none of which .h-section does. */
  font-size: clamp(1.6rem, 3.1vw, 36px);
  letter-spacing: 0;
  text-transform: none;
  font-family: var(--font-display);
  font-weight: 600;
  /* Black like every other heading. This one is a promoted eyebrow, so it used to
     sit at 0.72rem in the accent before it was scaled up; the size is handled
     here but the ink was left behind, which is why this heading was the only one
     on a light ground still wearing the accent. */
  color: var(--black);
  margin: 0 0 0.35em;
}

/* Packages image band. Dead: all five .packages-img bands are off the page.
   Left in place rather than deleted because the component is sound and the five
   gallery photographs it framed are still on disk, so it is one class away from
   coming back. It also still holds a slot in the section-mark pair selectors
   above, which must not be narrowed without checking both halves. */
.packages-img { display: block; padding: 0 0 clamp(24px, 4vw, 48px);}
#corporate-wellbeing { padding-bottom: 0;}
.packages-img img {
  display: block;
  width: 100%;
  max-width: 820px;
  margin-inline: auto;
  height: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

/* ---------- Packages: section heading ceiling ----------
   "Invest in Your Balance, Health, and Happiness" is 45 characters, the longest
   heading on the site, and it still has to hold ONE line at 320px. Measured on
   real rendered line boxes in Bricolage Grotesque 600, the string is 20.62em
   wide, so it needs 14.74px to fit the 304px a 320px viewport leaves inside
   .container. The shared .h-section floors at 2rem, and breakpoints.css drops
   .section-head h2 to 1.2rem and .h-section to 1.3rem at 320px, so every existing
   step on the scale was too large for this string and it wrapped on every phone.

   The 14px floor is not a new idea. #philosophy .philosophy-detail .h-section
   further up this file already runs clamp(14px, ..., 2.7rem) for the same reason.

   One rule, both heading classes, so the four section headings stay one size and
   read as siblings. The other three are 28 to 34 characters and clear this clamp
   with room to spare at every width. The desktop half of the range is in the
   per-page ceilings block in breakpoints.css, which loads later and so has to be
   met with specificity: this is (0,3,0) against that file's (0,2,1) and (0,1,0). */
/* Retired: was clamp(14px, 4.3vw, 2.5rem), 45px at 1296px, which made these
   the largest section headings on the site by 25%. They take the shared
   clamp(1.6rem, 3.1vw, 36px) like every other .section-head now.

   The 14px floor was real work - it is what held "Invest in Your Balance,
   Health, and Happiness", 45 characters, to one line at 320px - but the shared
   ladder only reaches 36px above 1161px and carries the same 1.6rem floor the
   other section headings carry everywhere else, so that string now wraps on a
   320px phone. index.html's own 38-character closing band wraps to 3 lines at
   390px for the same reason, and these four read as siblings again. */

/* ---------- Packages: left-aligned section intros ----------
   Two .section-head blocks lost their .center class on the client's request:
   "Invest in Your Balance, Health, and Happiness" and "The 3-Stage Transformation
   Process". Removing .center left-aligns the headings, because .section-head
   without it has no text-align of its own and the headings inherit start.

   The leads below them did not follow. layout.css:79 sets .section .lead to
   text-align: center outright, so the two blocks came out as a left-aligned
   heading sitting over a centred paragraph. This puts the lead back in step with
   the heading above it.

   Scoped to .page-packages and to .section-head, so the centred intros elsewhere
   on the page keep their centred leads. It sits here rather than in
   breakpoints.css because nothing about it is responsive. */
.page-packages .section-head:not(.center) .lead { text-align: left; }

/* ---------- Packages: the group photograph above "Included in Every Enrollment" ----------
   The image is 1600x1200. It used to sit in the intro split, where the
   half-column width and the align-self: stretch + height: 100% pair below kept
   it at 500px. The client moved it above the "Included in Every Enrollment"
   heading, where it is a full container wide, so the same cap is what stops it
   becoming an 885px band, and the object-fit: cover already on .split-media img
   crops to reach it rather than letterboxing.

   500px is the same figure as #coaching .split-media on services.html, .meet-img
   and #approach .approach-media, so the photograph still caps at the one value
   every other capped split on the site uses.

   Only max-height, not the stretch pair. Those two were there because .split is
   align-items: center, so the media box took its height from the image's own
   aspect ratio and height: 100% was circular until align-self: stretch broke the
   loop. That loop only exists inside .split. Here the .split-media is a plain
   block child of .container, it is the only thing on its line, and a capped box
   with a cover-fitted image needs nothing else. Keeping align-self: stretch and
   height: 100% would be carrying two declarations for a condition this element
   does not have.

   The margin below is the gap to the centred .section-head that follows. Without
   it the photograph runs straight into the heading; .section-head carries no
   margin of its own on this page, so the space has to come from one side.

   height: 100% on the image is not optional here and was measured rather than
   assumed. At the full container width this photograph scales to 1088x816, so a
   500px box holds an 816px image and the overflow: hidden already on
   .split-media clips 158px off it - off the bottom, not off both sides, because
   a block box clips bottom and right only. object-fit: cover has nothing to do
   in that state, because the image element is already exactly its own scaled
   size. The result is a bottom-weighted crop, which on a group shot takes the
   legs off and leaves the frame sitting high. Filling the box with height: 100%
   hands the crop to object-fit, which centres it, and loses 158px split evenly
   instead of all at one edge. */
#included-every .split-media { max-height: 500px; margin-bottom: clamp(40px, 5vw, 64px);}
#included-every .split-media img { height: 100%;}

/* ---------- Packages: intro heading inside the split ----------
   There was a clamp here, taking this heading down to 24px in the split column
   so it would hold one line. It is gone, on the client's request: the heading
   goes back to the shared 36px .h-section like every other section heading on the
   site, and is allowed to wrap.

   What it traded against, for the record. "Invest in Your Balance, Health, and
   Happiness" is 45 characters and measures 20.617em, the longest heading string on
   the site. In a full-width .section-head it needs 742px against 1088px and comes
   out on one line at 36px. In a 517px split column it needs 742px against 517px,
   so at 36px it runs to two lines. Measured for that column: 36px needs 742,
   32px 655, 30px 612, 28px 568, 26px 525, 24px 481. So 24px was the largest size
   that held one line there.

   On a phone it could not be held to one line at a readable size at all: the
   largest font fitting the 243px column a 320px viewport leaves is 11.79px, and
   14px needs 289px while 12px needs 247px, both still over 243px. So the old
   clamp broke the one-line rule on phones anyway, while also making this the only
   24px section heading on the site. Letting it wrap at 36px is the better trade:
   it is the same size as the other 48 section headings, and it wraps in the one
   place where the alternative was an unreadable heading.

   .split-top was added to the wrapper so the two columns line up at the top
   rather than being vertically centred against each other. With the heading now
   two lines, .split's default align-items: center would have floated the copy
   block down to sit in the middle of the photograph while the heading read as
   level with the image's centre. */

/* ---------- Packages: closing CTA heading, matched to the home page ----------
   "Take the First Step toward Your Growth" is the same 38-character string in the
   same .final-cta band over the same --butter ground on both index.html:276 and
   packages.html:378. It was rendering at 36px on one and 64px on the other, which
   is the same line in the same band at two sizes.

   It now takes the home page's own scale rather than a ceiling of its own. The
   five values below are the .home-page :is(...) ladder in breakpoints.css, which
   is where index gets its size, restated for this one selector so the two bands
   agree at every width and not only where a cap happens to bind. Matching only
   the 36px cap was tried first and left packages at 36px from 769px up while the
   home page scaled back to 31.7px at 1024px and 25.6px at 769px, so on a tablet
   this band would have been the larger of the two rather than the same size.

   The string measures 17.59em, so at these sizes it needs 633px at 36px against a
   1303px column. It holds one line at every width down to 480px and wraps below
   that, on both pages, which is the home page's own behaviour and so is kept
   rather than papered over with a floor.

   These five restate the ladder rather than extend the home rule to this page,
   because that rule is gated on the .home-page body class and adding packages to
   it would move every other heading on this page with it. Specificity is (0,3,0),
   as before, so the desktop half in breakpoints.css still has to be met here. */
.page-packages #first-step .h-display {
  font-size: clamp(1.25rem, 5vw, 1.6rem);
}
@media (min-width: 481px) and (max-width: 576px) {
  .page-packages #first-step .h-display {
    font-size: clamp(1.4rem, 5vw, 1.8rem);
}
}
@media (min-width: 577px) and (max-width: 768px) {
  .page-packages #first-step .h-display {
    font-size: clamp(1.6rem, 5vw, 2.2rem);
}
}
@media (max-width: 320px) {
  .page-packages #first-step .h-display {
    font-size: 1.2rem;
}
}

/* ---------- Site footer: the "honest conversation" heading ----------
   "Start with an honest conversation." sits in the footer on all 24 pages, and it
   was rendering at 70.225px on 23 of them while the home page showed the same
   line at 36px. Every one of these is the same string in the same footer slot, so
   there is no case for 23 different sizes and one different size.

   They all inherit the site-wide .h-display at breakpoints.css:1131,
   clamp(2.4rem, 5.3vw, 76px), which is 70.225px at 1325px. The home page escapes
   it through the .home-page :is(...) ladder, which lists .h-display and lands at
   36px. This rule hands the other 23 that same ladder.

   The five values are the home ladder verbatim, restated for one selector rather
   than widening the .home-page rule, because that rule is gated on the .home-page
   body class and its :is() group carries .h-section and .welcome-title with it,
   so adding the footer to it would move every heading on every page.

   Selector is .site-footer h2.display.h-display, which is (0,2,2) against the
   .h-display it replaces at (0,1,0). It also has to outrank the per-page closing
   band ceilings further down this file, which are why the two "Take the First
   Step" bands this also matches are left exactly as they are rather than reset.

   It matches the home page too, at the size it already had, so this is a no-op
   there. Markup check: 23 of the 24 are byte-identical, and index.html:424 differs
   only by omitting the full stop inside the .em-serif span, which no selector
   here cares about.

   The string is 36 characters and needs about 633px at 36px against a footer
   container of about 1300px, so it holds one line from 769px up and wraps below
   that, on every page, exactly as the home page already did. */
.site-footer h2.display.h-display {
  font-size: clamp(1.25rem, 5vw, 1.6rem);
}
@media (min-width: 481px) and (max-width: 576px) {
  .site-footer h2.display.h-display {
    font-size: clamp(1.4rem, 5vw, 1.8rem);
}
}
@media (min-width: 577px) and (max-width: 768px) {
  .site-footer h2.display.h-display {
    font-size: clamp(1.6rem, 5vw, 2.2rem);
}
}
@media (min-width: 769px) {
  .site-footer h2.display.h-display {
    font-size: clamp(1.6rem, 3.1vw, 36px);
}
}
@media (max-width: 320px) {
  .site-footer h2.display.h-display {
    font-size: 1.2rem;
}
}

/* ---------- Packages: pricing cards ----------
   The card shell, its surface, its radius, its shadow and its four responsive
   states are all the existing .packages-grid .service-card rules and are not
   restated here. Only the parts this page adds are below.

   Neither card is filled with colour, which is deliberate. A dark featured card
   would have needed a second set of inks re-verified against --charcoal, and
   every ink used in these cards already clears AA on --white with room to spare:
   --ink 15.4, --charcoal 15.9, --muted 4.9, --gold 8.6, and --white on --gold
   8.6 for the filled badge. */
/* The selectors in this block carry .pkg-card as well as the class, and that is
   not decoration. .service-card .body > p is (0,2,1) and sets both colour and
   size on every direct paragraph in a card, so a bare .page-packages .pkg-badge
   at (0,2,0) loses to it and the badge comes out --charcoal-2 instead of --gold.
   The same collision silently took .pkg-meta off --muted. Reaching past .body to
   name the element class directly is what puts these three back on their tokens. */
.page-packages .pkg-card .pkg-badge {
  display: inline-block;
  align-self: center;
  margin: 0 0 2px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--gold-soft);
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.page-packages .pkg-card .pkg-meta {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0;
}
/* The price line. Neither package has a published figure, the client asked for
   the price to be agreed on a call, so this is a word not a number and it is set
   at heading weight to hold that place in the card. 15 characters, so it clears
   its column at every width: 44.3px would fit the narrowest, and the floor here
   is 25.6px. */
.page-packages .pkg-price {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 4.4vw, 2.15rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 2px 0 4px;
}
.page-packages .pkg-card .pkg-for {
  font-size: 0.92rem;
  color: var(--charcoal-2);
  line-height: 1.65;
  margin: 10px 0 0;
}
/* margin-top: auto pins the call to action to the bottom of the card, so both
   buttons sit on one line even though the two check lists differ in length. The
   shared .service-card .foot uses a fixed 1.5em, which cannot do that. */
.page-packages .pkg-card .foot {
  margin-top: auto;
  padding-top: clamp(16px, 2vw, 24px);
}
/* Feature card: a gold border and a filled badge, nothing else. Gold on white is
   8.6:1 and white on gold is 8.6:1, so the border is a real marker rather than
   decoration and the badge text stays legible in both states. */
.page-packages .pkg-card--feature { border-color: var(--gold);}
.page-packages .pkg-card--feature .pkg-badge { background: var(--gold); color: var(--white);}

/* ---------- Packages: pricing card alignment ----------
   Card text is centred, at the client's request. Two things are deliberately
   left alone and the reasons are not the same.

   .check-list stays left. Its ticks are absolutely positioned at the left edge
   of a 1.2em pad (.check-list li and li::before), so centring the list text
   would slide every line away from its own tick and leave a column of orphaned
   marks floating down the middle of the card.

   .pkg-for stays left, with the ticks below it. It is a sentence in the same
   voice as that list, and pulling it to the centre while the list beneath it
   stayed left would split one block into two.

   The badge centres too, via the align-self on .pkg-badge above, because the
   card body is a column flex container and a flex item stretches to the full
   width by default, which would square off the pill. This is the same trick as
   text-align on the rest.

   Specificity has to clear the blanket patches at the top of layout.css, which
   force .section p to justify and .card-label and .card-note to the left. Those
   are (0,1,1) and (0,2,0); the rules here are (0,3,1) and (0,4,1).

   The selector is .body p and not .body > p on purpose. .pkg-price sits one level
   down inside .card-block, so a child combinator never reached it and it kept the
   justify from .section p. Nothing looked wrong, because justify only stretches
   all but the last line of a paragraph and that is one line, but the next person
   to widen a price line would have found their words spread edge to edge. */
.page-packages .pkg-card .body { text-align: center;}
.page-packages .pkg-card .body p { text-align: center;}
.page-packages .pkg-card .body p.pkg-for { text-align: left;}
.page-packages .pkg-card .check-list { text-align: left;}
.page-packages .pkg-card .card-label,
.page-packages .pkg-card .card-note { text-align: center;}

/* Tool icon in the enrollment cards. 40px square on --gold-soft with --gold at
   1.25rem, which is 7.3:1. */
.page-packages .pkg-tool-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: 12px;
  border-radius: 10px;
  background: var(--gold-soft);
  color: var(--gold);
  font-size: 1.25rem;
}

/* ---------- Packages: free bonus callout ----------
   Set apart from the three enrollment tools because it is the one item that is
   not in both packages by default, and running it as a fourth card would have
   made it look like one of the three. --ink on --gold-soft measures 13.0:1 and
   --gold on it 7.3:1. */
.page-packages .pkg-bonus {
  margin-top: clamp(24px, 3vw, 40px);
  padding: clamp(20px, 3vw, 30px) clamp(22px, 3vw, 34px);
  background: var(--gold-soft);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius-md);
}
.page-packages .pkg-bonus-label {
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 8px;
}
.page-packages .pkg-bonus-text {
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--ink);
  margin: 0;
}

/* ---------- Services: opening prose ----------
   The client's three opening paragraphs plus the Best For note, as one measured
   column. A plain .section p is justified by the blanket patch at the top of
   layout.css, and three long paragraphs set justified at full container width
   gives rivers at 1200px. Capping the measure fixes that.

   The first paragraph is .lead, and .lead is the one paragraph the blanket patch
   does not justify: layout.css:9 sets .section .lead to text-align center, at
   (0,2,0), which beats the .section p justify at (0,1,1). That is correct for a
   .lead that sits in a .section-head and runs under a centred heading, but this
   one is the first of three body paragraphs in a left-set prose column, and
   centring it alone left the opening line ragged while the two after it were
   justified. It is put back in line here rather than at layout.css:9, because
   changing the shared rule would re-centre every other page's section lead.

   Same treatment as the two .story-grid leads at page-overrides.css:1130 and
   :1382, which override this same centre rule for the same reason: a .lead that
   lives in prose belongs to the prose, and hyphens: auto plus
   text-justify: inter-word are what stop justified text opening wide word gaps
   at a 68ch measure.

   One size for all four paragraphs.

   This block held three different sizes in five lines of copy. Measured at
   1440px: .lead 18.69px, the two plain paragraphs 16px, the Best For note
   13.6px. Below 1200px the lead dropped to 16.8px and the other two stayed put,
   so the ladder was 16.8 / 16 / 13.6 on a phone. Three sizes inside one 68ch
   column reads as three different voices rather than as one paragraph block,
   and the 5px step down to the note was the worst of it because 13.6px is
   already below the size at which this site's body copy sits anywhere else.

   1rem is the value two of the four already had, so this is the smallest
   correction rather than a new decision: the two middle paragraphs do not
   move at all, the lead gives up 2.69px at 1440px and 0.8px below 1200px, and
   the note gains 2.4px. A larger shared size would have meant growing two of
   the four and pushing an already long justified measure past comfortable.

   What the note loses in size it keeps in every other signal. It is still set
   off by margin-top, still ragged rather than justified, and its "Best For:"
   run is still the only bold ink in the block. Weight and space now do the
   work that size was doing, which is the more durable way to mark a line
   anyway - a note that only reads as a note because it is smaller stops
   reading as one the moment anyone zooms the text.

   The measure was wrong too, and it was the more visible of the two. The shared
   .lead caps itself at max-width 52ch, while .svc-prose is 68ch. Inside one
   column that gave the opening paragraph a 508px line against 664px for the
   three below it, at every width above about 520px - a 156px difference. With
   all four justified, the first paragraph's right edge visibly stopped short
   of the other three and the block read as a narrow quotation sitting on top of
   a full-width one. max-width: none puts it back on the column. Below 520px the
   cap never bound anyway - the lead measured 286px and the paragraphs 286px -
   so this changes desktop and tablet only.

   68ch is a long measure for 16px justified text and it is the one this block
   already chose for its own paragraphs, so matching it is the consistent
   choice. Narrowing the column instead would have moved three paragraphs to
   fix one. */
.page-services .svc-prose {
  max-width: 68ch;
  margin-inline: auto;
}
.page-services .svc-prose .lead {
  font-size: 1rem;
  max-width: none;
  hyphens: manual;
}

#coaching .split-media { align-self: stretch; max-height: 500px;}
#coaching .split-media img { height: 100%;}

/* ---------- Services: opening split photograph ----------
   The photo is 1600x1200, so at the split's half-column width it renders 388px
   tall against a 500px copy column and leaves 113px of empty space below it. The
   two halves stop reading as a pair.

   Capped at 500px with height: 100% and the object-fit: cover already on
   .split-media img, so the photograph fills its column and crops rather than
   letterboxing. This is the same two-line treatment .meet-img uses and the same
   one #approach .approach-media uses, on the same 500px figure, so all three
   splits on the site cap identically instead of each one guessing its own.

   The source is 4:3 and the column is closer to 1:1.03, so cover crops the sides,
   not the top, which on this frame is where the two figures are. It is centred by
   default, and object-position is left alone for the same reason.

   Scoped to #coaching rather than to .page-services, because this page now has
   two splits and the other one, further down, is not capped. An id was added to
   the section for it: .section:first-of-type was tried first and matched nothing,
   since the banner above is the first section on the page, not this one. */

/* ---------- Services: Best For note ----------
   Pulled off the prose column's rhythm so it reads as a footer to the three
   paragraphs rather than a fourth paragraph. --charcoal-2 on --white is 12.31:1. */
.page-services .svc-bestfor {
  font-size: 1rem;
  margin-top: clamp(20px, 2.4vw, 30px);
}

/* ---------- Services: the seven work-on cards ----------
   .why-item draws its own top rule and padding, and the client wrote these as
   seven equal items, so they get one modifier that makes them read as a set:
   equal height so the row does not stair-step, and the icon tone matched to the
   packages tool icons so the two pages agree.

   --gold on --gold-soft is 7.31:1 for the icon glyph. */
.page-services .svc-areas {
  align-items: stretch;
}
.page-services .svc-area-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: 12px;
  border-radius: 10px;
  background: var(--gold-soft);
  color: var(--gold);
  font-size: 1.25rem;
}
.page-services .svc-areas .why-item > div {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.page-services .svc-areas .why-item h3 {
  margin-bottom: 0.5em;
}
.page-services .svc-areas .why-item p {
  margin: 0;
}

/* ---------- Services: the three short panels ----------
   .balance-step is the existing white, 1px --line, 4px --gold-left panel. The
   three panels are stacked with the component's own 32px gap, which is right for
   three, and the section head already owns the gap above them.

   The Free Bonus panel is tinted so it does not read as a third equal item: it
   is the one that is not part of the standard engagement, the same reason
   packages.html sets its bonus callout apart from the three tools beside it.
   --ink on --gold-soft is 13.05:1 and --gold on it 7.31:1. */
.page-services .svc-notes {
  max-width: 860px;
  margin-inline: auto;
}
.page-services .svc-bonus {
  background: var(--gold-soft);
  border-color: transparent;
}
.page-services .svc-bonus p {
  color: var(--ink);
}

/* ---------- Services: the three stage cards ----------
   .stage is the existing dark panel with a big .st-num, a heading and a
   gold-en-dash bullet list. It was written for this exact shape and no page was
   using it, so the three transformation stages reuse it whole.

   One ink correction. .stage paints .st-num and the bullet dashes in --gold
   #22544C, a dark teal, on --charcoal-2 #3A342B. That measures 1.43:1 and is
   effectively invisible; the component had never been rendered, so the mistake
   was never seen. --gold-soft #E4EFEB on the same card is 10.46:1, and 9.81:1 on
   the hover state, so both the number and the bullet dashes move to --gold-soft.
   This is the rule the banner eyebrows already follow for the same reason, gold
   fails on dark and gold-soft is the token that works there. The hover border
   also moves, since --gold as a border on that card is the same 1.43:1.

   The stage subtitle is the client's own promise line, one per stage. It is set
   apart from the h3 by weight and tracking rather than by colour, because inside
   .stage every element is forced to --ivory by layout.css:815 and fighting that
   would need a second set of ink overrides.

   The "The Outcome:" line is the last bullet in each stage and is the client's own
   emphasis. .stage li::before is a content pseudo-element, not markup, so the
   bold is the only thing marking it, and gold-soft on the bold run carries it. */
/* The card ground moves from --charcoal-2 #3A342B to the accent --gold #22544C.
   That is a request for the accent colour behind the three stages, and it is
   scoped to this page because .stage exists nowhere else.

   Every ink already on the card was measured against the new ground and none of
   it had to move: --ivory on --gold is 8.06:1, --gold-soft is 7.31:1, and the
   85% ivory used for body copy and bullets is 6.35:1. All three clear AA, so the
   correction the block above made for the old dark ground still holds and none of
   it was rewritten. The hairline also still works: rgba(251,247,240,0.18) on gold
   is a visible light edge, where --gold on --charcoal-2 was the 1.43:1 failure.
   The card itself reads 8.55:1 against the --butter band it sits on.

   Hover needed a value rather than inheriting one. The component lifts by
   translateY(-6px) and deepened its fill to #3f3830, which is a lighter step of
   its own ground; against gold that brown would have been a colour change rather
   than a state change. #1B463E is the same hue one step down, so the hover reads
   as pressure on the same colour. Deepening also holds the text contrast up
   instead of letting it fall: 85% ivory goes from 6.35:1 at rest to 7.64:1 on
   hover, where a lighter gold, #2E6A5F, would have dropped it to 4.76:1.

   The stage numeral had to move and it is the one thing here that was not purely
   cosmetic. .st-num carries opacity 0.3, which on the old charcoal read as a soft
   watermark at 2.34:1. On gold it collapses to 2.03:1, because the numeral is
   --gold-soft and the ground is now its own dark neighbour. At 2.8rem bold it is
   large text, so it needs 3:1 and 2.03:1 misses it. 0.6 measures 3.76:1, which
   clears that and still stays behind the h3 rather than competing with it. The
   bullet dashes keep the 0.3 of their own: they are small, they are decorative,
   and their full-opacity 7.31:1 is what marks them. */
.page-services .stage {
  background: var(--gold);
  border-color: rgba(251, 247, 240, 0.18);
}
.page-services .stage:hover {
  background: #1B463E;
  border-color: var(--gold-soft);
}
.page-services .st-num,
.page-services .stage li::before {
  color: var(--gold-soft);
}
.page-services .st-num { opacity: 0.6;}
.page-services .stage-sub {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--gold-soft);
  margin: 0 0 1em;
}
.page-services .stage > p:not(.stage-sub) {
  color: rgba(251, 247, 240, 0.85);
  margin: 0 0 1.2em;
}
.page-services .stage li strong {
  color: var(--gold-soft);
  font-weight: 600;
}
.page-services .stage ul {
  margin-bottom: 0;
}

/* ---------- Services: closing CTA heading ceiling ----------
   "Are You Ready to Lead with High Clarity and Energy" is 50 characters, the
   longest heading on the site, and it is .h-display, so it cannot borrow either
   the shared .h-section scale or the packages ceiling.

   Measured in Bricolage Grotesque 600 at -0.035em tracking, the string is 22.904em
   wide, or 0.458em a character. Against the measure actually available that allows
   one line at 12.84px at 320px, 19.12px at 480px, 24.36px at 600px, 31.70px at
   768px and 60.86px at 1446px, where the container stops growing.

   So the one-line rule is not achievable here below 769px. Holding it at 320px
   means setting a closing headline at 12.8px, smaller than the body copy above it,
   and the whole phone range below 769px lands under 32px. That was measured, it
   was built, and it read as broken. The rule is therefore dropped for this one
   string below 769px and the heading runs to two lines at a size a phone can
   read. Above 769px one line is comfortably achievable, so it is held there and
   the two halves meet without a step.

   Below 769px, 26px to 30px. The 30px cap is not arbitrary: at 768px the measure
   holds 52.8 characters at 30px, and this string is 50, so the cap is the largest
   size at which the heading is still one line at the seam. Any larger and it
   breaks to two lines just before the desktop term takes over, with one word
   alone on the second line. At the 26px floor the string divides 25 and 25 at
   320px, so the two lines are balanced rather than an orphan.

   Above 769px the term and its reasoning are in breakpoints.css.

   line-height: 1.06, because this heading is the one on the site that actually
   wraps. .h-display ships line-height 0.95 from design-tokens.css:309, which is
   right for a display heading that stays on one line and tightens its own box,
   and wrong as soon as it does not: the line gap becomes font x 0.95, while the
   cap-height plus descender of Bricolage Grotesque is about 0.96em, so the descender
   in "You", "Clarity" or "Energy" meets the cap below it. Measured, it is 6px of
   overlap at 320px and 7px at every other wrapped width. It was never seen because
   the heading only wraps below 768px.

   1.06 rather than 1.15 leaves the box close to the 0.95 it replaces when the
   heading is a single line, so the desktop gap to the button does not visibly move,
   while giving the two- and three-line phone states room to breathe. */
/* Retired: was clamp(26px, 5.6vw, 30px), so this band opened at 30px against
   68.7px for the identical band on the other twenty-one pages and 36px on
   index.html. It takes the shared .h-display ladder with all of them.

   The line-height below is kept and is still load-bearing. */
.page-services .final-cta .h-display { line-height: 1.06; }

/* ---------- Services: closing CTA button ----------
   The band has one button and one label, so the only thing deciding how wide it
   looks is how much padding surrounds that label. .btn's shared 14px 28px is
   sized for the short labels elsewhere on the site, and on "Schedule a Free
   Consultation" 56px of horizontal padding sat around 192px of text: the pill
   measured 273px for a label 192px wide, about a fifth of its own area being
   empty gold.

   18px takes it to 1.4x the 13.12px label, in the same range as .btn-sm's 22px
   around an 11.8px label, and the gap follows the arrow down from 10px to 8px.
   Text width is fixed by the client's string and the font size is fixed by .btn,
   so padding is the only free variable; if this is still too wide the next lever
   is the font size, not more padding.

   padding-inline rather than padding, so the responsive vertical padding that
   breakpoints.css sets at 375px and 320px still lands: this rule is about the
   horizontal footprint, and taking the block padding as well would have pushed a
   phone's button from 40px tall back to 52px. */
.page-services #first-step .cta-actions .btn {
  padding-inline: 18px;
  gap: 8px;
}

.final-cta-note { color: rgba(255,255,255,0.85); margin: 0 0 1.5em;}

/* Home Section 08: single button, so cap the row instead of stretching it to 720px */
#first-step .final-cta-note { max-width: 620px; margin-inline: auto; color: rgba(32, 28, 22, 0.72);}
#first-step .cta-actions { max-width: 340px; margin-inline: auto;}
#first-step .cta-actions .btn { flex: 0 0 auto;}

/* The button is inline-flex by design, so it already sizes to its own label, and
   .cta-actions centres it. The width: 100% this rule carried took that away and
   made every closing button a fixed 340px pill by inheriting the row's own
   max-width, which is a pill for "Book a Free Discovery Call" and a wider pill
   for "Schedule a Free Consultation" that still had 80px of empty gold to the
   right of the text. Dropping it puts the width back on the label where it
   belongs; the row cap above still keeps the row, and so the button, centred. */

/* Home Section 08: light accent background instead of the dark CTA block.
   .final-cta ships charcoal + ivory text, so the text colours are inverted
   here to sit properly on the light accent surface. */
/* Was gold-soft #E4EFEB. This is the one light band that did not carry the
   .section class, so it was missed by the .section rule and stayed mint while
   everything around it turned stone. */
#first-step.final-cta {
  background: var(--butter);
  color: var(--charcoal);
}
#first-step .display,
#first-step h2 { color: var(--black);}
#first-step .lead { color: rgba(32, 28, 22, 0.78);}
/* Split from the shared rule below: the eyebrow is a label and keeps the
   accent, the em-serif span is inside the heading and no longer does. This band
   is the light one, so the accent word in the headline was the last place a
   heading read as two colours on a light ground. */
#first-step .eyebrow { color: var(--gold);}
#first-step .em-serif { color: inherit;}

/* Homepage CTA buttons one row, wider */
body.home-page .halfhour-cta .cta-actions,
body.home-page .final-cta .cta-actions {
  flex-direction: row;
  flex-wrap: nowrap;
  gap: clamp(10px, 1.6vw, 16px);
  max-width: 720px;
  margin-inline: auto;
}
body.home-page .halfhour-cta .cta-actions .btn,
body.home-page .final-cta .cta-actions .btn {
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
  text-align: center;
  white-space: nowrap;
}

/* Split collapses at 1024px, not 768px.

   .split is the two column copy-plus-photo layout, and it stayed 2 column all the
   way down to 768px. Anything multi-column NESTED inside .split-copy therefore
   only ever got half the container to work with, and the cards inside it
   collapsed. Measured on index.html, sweeping every grid on the page for a dip
   where an item is narrower than at the widths either side:

     .work-options   820px viewport -> cards 142px wide
                     (900px: 158px, 768px: 603px)

   142px is the narrowest item anywhere on the page, 85px below the next worst,
   and it is narrower than these same two cards are on a 390px phone. Two
   engagement cards sat in a column 328px wide, so each got half of that.

   Root cause is the nesting, not the cards. .work-options is two columns and it
   lives inside .split-copy, which is itself one of two columns. Two half-width
   decisions multiplied. Fixing it in .split gives the copy the whole container
   from 1024px down:

     1024px  copy 797px -> work cards 386px
      900px  copy 673px -> work cards 324px
      820px  copy 621px -> work cards 298px
      769px  copy 573px -> work cards 274px

   All four are above the 240px that the rest of the page treats as the floor
   for a card holding a sentence, and no width drops below it.

   This also lifts every other grid nested in a split at the same widths -
   .themes-grid, .why-list, .achieve-grid, .testi-grid and the rest - because
   they were all being squeezed by the same half. The 768px block below is left
   in place for the gap and radius work it does; its grid-template-columns is now
   redundant but agrees, so nothing conflicts at any width. */
@media (max-width: 1024px) {
  .split { grid-template-columns: 1fr;}
}

/* Split responsive mobile */
@media (max-width: 768px) {
  .split { grid-template-columns: 1fr; gap: 24px;}
  .split-media { border-radius: var(--radius-md);}
  .split-media img { border-radius: var(--radius-md);}
  .split-copy { gap: 12px;}
}

@media (max-width: 480px) {
  .split { gap: 20px;}
  .split-copy .eyebrow { font-size: 0.75rem;}
  .split-copy .h-section { font-size: clamp(1.5rem, 7vw, 2rem);}
  .split-copy .lead { font-size: 0.95rem;}
}
