/**
 * Dither mono treatment.
 *
 * A near-monochrome, high contrast field with an ordered dither ramp, mono type
 * carrying more of the load, and cinematic vertical scale. Applied to the dark
 * surfaces: the hero and the closing call to action.
 *
 * Three deliberate constraints:
 *
 * 1. The texture is generated, not photographed. Every pattern below is an
 *    inline SVG data URI, which is same origin, so the site keeps its zero
 *    external request guarantee and adds no image weight to LCP.
 *
 * 2. Texture never sits under body text at full strength. A dither ramp under a
 *    paragraph destroys the measured contrast that design/contrast-report.md
 *    certifies. The ramp is masked so it is densest where there is no text and
 *    gone where there is, and the copy still sits on solid plum at 17.72:1.
 *
 * 3. Monochrome does not mean colourless. Gold survives as the single accent,
 *    used less and therefore louder. Purple retreats to the light sections.
 *
 * Loaded after components.css. Depends on tokens.css.
 */

/* ---------------------------------------------------------------------------
 * 1. The dither field
 *
 * Two stacked layers make the ramp read as 1-bit rather than as a gradient:
 * a fixed 4px dot grid, and a mask that fades that grid out. The dots stay the
 * same size and only their visibility changes, which is what separates ordered
 * dithering from a soft blur.
 * ------------------------------------------------------------------------ */

/*
 * .sna-newsletter WAS IN THIS GROUP AND IS DELIBERATELY NOT ANY MORE.
 *
 * It became a contained plum card on 2026-08-01 rather than a full bleed band,
 * so it must not take the edge to edge background or the bleeding dither. Its
 * own treatment is section 56 at the end of this file. Do not add it back here.
 */
.sna-hero,
.sna-cta {
  position: relative;
  isolation: isolate;
  background-color: var(--brand-plum);

  /* Full bleed background without being a full width block.
   *
   * These were alignfull, which broke them out of the content container and
   * left their text 56px off the vertical line every other section sits on.
   * Kadence's content box is not symmetric (measured 81px left, 95px right,
   * because the scrollbar is counted), so no amount of centring an inner
   * wrapper could ever match it.
   *
   * Instead the section stays in normal flow, so its children align with the
   * rest of the page by construction, and the background is pushed edge to
   * edge with a very large spread shadow. clip-path keeps that bleed
   * horizontal only, so it does not leak into the sections above and below. */
  box-shadow: 0 0 0 100vmax var(--brand-plum);
  clip-path: inset(0 -100vmax);
}

.sna-hero::before,
.sna-cta::before {
  content: "";
  position: absolute;
  inset: 0 -100vmax;
  z-index: -2;
  pointer-events: none;

  /* 4px ordered dot grid, ivory at low alpha. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Crect width='1' height='1' fill='%23FBF9F6' fill-opacity='0.55'/%3E%3Crect x='2' y='2' width='1' height='1' fill='%23FBF9F6' fill-opacity='0.55'/%3E%3C/svg%3E");
  background-repeat: repeat;

  /* The ramp. Densest at the bottom edge, gone by the time it reaches the
     headline, so nothing textured ever sits behind reading text. */
  -webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.35) 22%, transparent 52%);
          mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.35) 22%, transparent 52%);
}

/* ---------------------------------------------------------------------------
 * 2. Grain
 *
 * Very low amplitude film grain over the whole dark field. It is what stops a
 * flat near-black reading as an empty div, and it is the difference between
 * "dark section" and "photographed dark".
 * ------------------------------------------------------------------------ */

.sna-hero::after,
.sna-cta::after {
  content: "";
  position: absolute;
  inset: 0 -100vmax;
  z-index: -1;
  pointer-events: none;
  opacity: 0.055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------------
 * 3. Cinematic scale
 *
 * The reference aesthetic is vast and quiet. That is mostly achieved with
 * height and restraint rather than with decoration: more air above the
 * headline, a longer drop below it, and nothing competing.
 * ------------------------------------------------------------------------ */

.sna-hero {
  padding-block: calc(var(--space-section) * 1.6) 0;
}

.sna-hero__title {
  --measure-local: 15ch;
  font-size: clamp(2.6rem, 1.8rem + 3.4vw, 4.6rem);
  line-height: 0.98;
  letter-spacing: -0.025em;
}

.sna-hero__lede {
  --measure-local: 42ch;
  color: rgba(251, 249, 246, 0.82);
}

/* ---------------------------------------------------------------------------
 * 4. Mono carries more
 *
 * In this aesthetic the mono face is structural, not decorative. Eyebrows get
 * a rule and wider tracking, and the supporting microcopy moves to mono so the
 * serif headline is the only voice competing for attention.
 * ------------------------------------------------------------------------ */

.sna-hero .sna-eyebrow,
.sna-cta .sna-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  letter-spacing: 0.16em;
  color: var(--brand-gold-200);
}

.sna-hero .sna-eyebrow::after,
.sna-cta .sna-eyebrow::after {
  content: "";
  width: clamp(2rem, 8vw, 5rem);
  height: 1px;
  background-color: var(--brand-gold);
}

.sna-hero__proof {
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------------------
 * 5. The artifact, re-treated
 *
 * In the editorial version this was an ivory card. In the mono version it
 * becomes part of the dark field: a hairline ledger sitting on the dither,
 * numbered in mono, which reads as an instrument panel rather than a content
 * box. This is the single biggest change in the look.
 * ------------------------------------------------------------------------ */

.sna-hero__artifact {
  margin-bottom: 0;
  padding: var(--space-l) 0 0;
  background-color: transparent;
  border: 0;
  border-top: 1px solid rgba(232, 206, 122, 0.28);
  border-radius: 0;
  box-shadow: none;

  /* Undo the light-surface token reset from the editorial treatment: this now
     sits on the dark field and inherits the dark tokens. */
  --surface: var(--brand-plum);
  --text: var(--brand-ivory);
  --text-secondary: var(--brand-gold-200);
  --accent: var(--brand-gold);
  color: var(--brand-ivory);
}

.sna-hero + * {
  padding-top: var(--space-section);
}

.sna-artifact__label {
  color: rgba(251, 249, 246, 0.55);
}

.sna-artifact__item {
  border-top: 0;
  padding-top: 0;
}

.sna-artifact__name {
  color: var(--brand-ivory);
  font-size: var(--step-0);
  font-weight: 400;
}

.sna-artifact__note {
  color: rgba(251, 249, 246, 0.5);
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.sna-hero__artifact .sna-marker {
  color: var(--brand-gold);
}

.sna-hero__artifact .sna-marker::after {
  background-color: rgba(232, 206, 122, 0.45);
}

/* ---------------------------------------------------------------------------
 * 6. Buttons on the dark field
 *
 * Gold stays the only filled colour on the site, so it has to carry the
 * primary action alone. Black label, as always: that pairing is 8.18:1 and
 * white would be 2.1:1.
 * ------------------------------------------------------------------------ */

.sna-hero .wp-block-button.is-style-sna-gold .wp-block-button__link,
.sna-cta .wp-block-button.is-style-sna-gold .wp-block-button__link {
  border-radius: 2px;
  padding: 0.95rem 1.75rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.sna-hero .wp-block-button.is-style-sna-outline-light .wp-block-button__link,
.sna-cta .wp-block-button.is-style-sna-outline-light .wp-block-button__link {
  border-radius: 2px;
  padding: 0.95rem 1.75rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  box-shadow: inset 0 0 0 1px rgba(251, 249, 246, 0.35);
  color: var(--brand-ivory);
}

/* ---------------------------------------------------------------------------
 * 7. Reduced motion and small screens
 * ------------------------------------------------------------------------ */

@media (max-width: 47.9375em) {
  /* The ramp is proportionally much taller on a narrow screen, which pushes
     texture up behind the buttons. Pull it back down. */
  .sna-hero::before {
    -webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.85) 0%, transparent 34%);
            mask-image: linear-gradient(to top, rgba(0, 0, 0, 0.85) 0%, transparent 34%);
  }
}

/* ---------------------------------------------------------------------------
 * 8. The problem ledger
 *
 * Five entries, one per dimension, set as a ledger rather than as cards. Cards
 * would make five separate objects competing for attention; a ledger reads as
 * one continuous accounting, which is what the section is: the running cost of
 * being stalled. The mono numerals do the structural work and the hairlines
 * hold the rhythm.
 * ------------------------------------------------------------------------ */

.sna-problem__list {
  margin-top: var(--space-xl);
  border-top: var(--hairline) solid var(--rule);
}

.sna-problem__item {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3xs);
  padding-block: var(--space-m);
  border-bottom: var(--hairline) solid var(--rule);
}

.sna-problem__item .sna-marker {
  color: var(--brand-purple);
  margin-bottom: 0;
}

.sna-problem__title {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--brand-plum);
  margin: 0;
}

.sna-problem__item p:not(.sna-marker) {
  margin: 0;
}

.sna-problem__turn {
  /* 44ch, not 58ch. It renders at --step-1, so its ch is wider than body
     text's and 58ch measured 79 characters. See tokens.css on the ch unit. */
  --measure-local: 44ch;
  font-family: var(--font-heading);
  font-size: var(--step-1);
  line-height: 1.45;
  color: var(--brand-plum);
}

/* At width the ledger splits: numerals and label on the left, the cost on the
   right, so the eye can run down either column independently. */
@media (min-width: 48em) {
  .sna-problem__item {
    grid-template-columns: 3rem 12rem 1fr;
    align-items: baseline;
    gap: var(--space-m);
    padding-block: var(--space-l);
  }

  .sna-problem__item .sna-marker::after {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
 * 9. Hero alignment
 *
 * The hero is alignfull, so its children run to the gutter, while every
 * section below is constrained and centred at the wide width. Measured at
 * 1280px the hero text started 53px left of everything under it, which reads
 * as a mistake rather than as a full bleed.
 *
 * Constraining the hero's children to the same wide width puts the eyebrow,
 * headline, buttons, and ledger on the same vertical line as the rest of the
 * page, while the plum field itself still runs edge to edge.
 * ------------------------------------------------------------------------ */

/* Superseded: the hero is no longer alignfull, so its children inherit the
   page container and need no width of their own. */

/* ---------------------------------------------------------------------------
 * 10. The ledger column count
 *
 * Five entries, so the only counts that leave a complete row are one and five.
 * WordPress's auto-fill grid gave four at desktop and orphaned Purpose on a row
 * of its own, which is the third time this pattern of bug has appeared: an
 * auto-fill grid does not know how many items it has.
 *
 * One column until there is genuinely room for five, then five. Nothing in
 * between, because every intermediate count strands an item.
 * ------------------------------------------------------------------------ */

.sna-artifact__grid {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-m) var(--space-s);
}

@media (min-width: 56em) {
  .sna-artifact__grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* ---------------------------------------------------------------------------
 * 11. Hero, two column
 *
 * Reworked on the owner's brief: the eyebrow, the second button, the proof
 * line, and the rule above the ledger are all gone, and the coach photograph
 * takes the right hand side. What is left is one headline, one paragraph, one
 * action, one portrait, and the framework.
 *
 * Text column first in the DOM, so a screen reader and a narrow viewport both
 * get the message before the picture.
 * ------------------------------------------------------------------------ */

.sna-hero__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: center;
}

@media (min-width: 60em) {
  .sna-hero__top {
    grid-template-columns: minmax(0, 1.05fr) minmax(17rem, 0.95fr);
    gap: var(--space-2xl);
  }
}

.sna-hero__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.sna-hero__actions {
  margin-top: var(--space-2xs);
}

/* The portrait.
 *
 * No frame, no card, no radius. The supplied photograph is a cut-out on a
 * plain ground, so it drops straight onto the dither field and the field does
 * the framing. A border here would fight the bleed and make it look pasted on.
 *
 * The aspect ratio is fixed so the layout does not jump between the SVG
 * placeholder and the real photograph, which is the usual way a hero picks up
 * CLS at the last minute. */
.sna-hero__media {
  justify-self: center;
  width: 100%;
  max-width: 30rem;
}

.sna-hero__portrait {
  margin: 0;
}

.sna-hero__portrait img {
  display: block;
  width: 100%;
  height: auto;
}

/* Only the SVG placeholder gets a forced box. The real photograph is a cut-out
   figure, so letterboxing it into 4:5 would either crop her or float her in
   empty space. Its own width and height attributes reserve the right amount of
   room, so nothing shifts on load. */
.sna-hero__portrait img[src$=".svg"] {
  aspect-ratio: 4 / 5;
  object-fit: contain;
  object-position: center bottom;
}

/* The rule above the ledger is gone at the owner's request. The ledger now
   reads as part of the same field rather than as a separate panel. */
.sna-hero__artifact {
  border-top: 0;
  padding-top: var(--space-2xl);
}

/* With the eyebrow removed the headline is the first thing on the page, so it
   no longer needs the extra air that was making room for a tag above it. */
.sna-hero {
  padding-block: calc(var(--space-section) * 1.15) 0;
}

/* ---------------------------------------------------------------------------
 * 12. Two column corrections
 * ------------------------------------------------------------------------ */

/* The 15ch cap was set when the headline had the full page width. In a two
   column hero the column already constrains it, and the cap was forcing a
   four line break ("Build the / woman you're / becoming / this season") that
   read as choppy. Let the column govern. */
.sna-hero__title {
  --measure-local: none;
  max-width: none;
}

/* The button was mono uppercase, which is the same treatment rejected for the
   navigation and for the same reason: it reads as engineering chrome. Moved to
   the body face so the one action on the page sounds like the rest of the
   page. Tracking and weight keep it deliberate without shouting. */
.sna-hero .wp-block-button.is-style-sna-gold .wp-block-button__link,
.sna-cta .wp-block-button.is-style-sna-gold .wp-block-button__link,
.sna-hero .wp-block-button.is-style-sna-outline-light .wp-block-button__link,
.sna-cta .wp-block-button.is-style-sna-outline-light .wp-block-button__link {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
  border-radius: 4px;
  padding: 1rem 1.9rem;
}

/* ---------------------------------------------------------------------------
 * 13. Responsive pass
 *
 * Measured at 360, 390, 768, 1024, and 1440. Four problems, all invisible from
 * a single desktop screenshot:
 *
 *   360   the hero was 2172px tall, nearly three screenfuls before the reader
 *         reached anything else
 *   768   the ledger rendered as three columns and orphaned two entries, and
 *         the portrait grew to 480px and dominated the fold
 *   1089  the ledger wrapped to two rows for the same reason
 *   1440  the headline broke to five lines and read as a wall
 * ------------------------------------------------------------------------ */

/* The ledger column count, again, and this time at a specificity that holds.
 *
 * WordPress generates its own grid class carrying `repeat(auto-fill, ...)` at
 * exactly the same specificity as a single class selector, so which one wins
 * came down to stylesheet order, and WordPress was printing later. Scoping to
 * .sna-hero settles it on specificity instead of on luck. */
.sna-hero .sna-artifact__grid {
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 56em) {
  .sna-hero .sna-artifact__grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* Below five columns the ledger becomes compact rows rather than five tall
   stacked blocks. Same information, roughly half the height, and it reads more
   like a ledger than a list of cards. */
@media (max-width: 55.9375em) {
  .sna-artifact__item {
    display: grid;
    grid-template-columns: 2.75rem minmax(0, 1fr);
    column-gap: var(--space-s);
    align-items: baseline;
    padding-block: var(--space-2xs);
    border-top: 1px solid rgba(251, 249, 246, 0.1);
  }

  /* Kadence sets a 2rem bottom margin on paragraphs inside the content area at
     class-plus-element specificity, which inflated each compact row from about
     70px to 102px. Scoping to .sna-hero and targeting the element wins on
     specificity rather than on order. */
  .sna-hero .sna-artifact__item > p {
    margin: 0;
  }

  .sna-artifact__item .sna-marker {
    grid-column: 1;
    grid-row: 1 / span 2;
    margin: 0;
  }

  /* The little rule after the numeral costs width it does not have here. */
  .sna-artifact__item .sna-marker::after {
    display: none;
  }

  .sna-artifact__name {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
  }

  .sna-artifact__note {
    grid-column: 2;
    grid-row: 2;
    margin: 0;
  }
}

/* The headline.
 *
 * In two columns the text sits in roughly half the page, so the old ceiling of
 * 4.6rem produced five lines. Lowered, and the text column given slightly more
 * of the split, which together bring it to three or four lines at every width. */
.sna-hero__title {
  font-size: clamp(2.35rem, 1.7rem + 2.6vw, 3.75rem);
  line-height: 1.02;
}

@media (min-width: 60em) {
  .sna-hero__top {
    grid-template-columns: minmax(0, 1.2fr) minmax(15rem, 0.8fr);
  }
}

/* The portrait.
 *
 * Single column it was rendering at up to 480px wide and taking the whole
 * fold before the copy had been read. Capped, and capped harder on the
 * narrowest screens where vertical space is scarcest. */
.sna-hero__media {
  max-width: 22rem;
}

@media (min-width: 60em) {
  .sna-hero__media {
    max-width: 28rem;
  }
}

/* Vertical economy on small screens. The dither field is the point, but three
   screenfuls of it before the first section is not. */
@media (max-width: 47.9375em) {
  .sna-hero {
    padding-block: var(--space-2xl) 0;
  }

  .sna-hero__top {
    gap: var(--space-l);
  }

  .sna-hero__inner {
    gap: var(--space-s);
  }

  .sna-hero__artifact {
    padding-top: var(--space-xl);
  }

  .sna-hero__media {
    max-width: 15rem;
  }
}

/* ===========================================================================
 * 14. ELEVATED HERO TREATMENT
 *
 * The owner supplied a reference with a faint rounded-square grid over a light
 * field and a floating dark header bar. The instruction was to take the idea
 * and the register, not the background itself, and to build the hero's texture
 * up from the dither that previously sat behind the framework ledger.
 *
 * So the field is now four layers rather than one:
 *
 *   1. a hairline grid, a nod to the reference's graph paper, at an opacity
 *      where it registers as texture rather than as a visible grid
 *   2. the ordered dither ramp, kept, but finer and pushed to the edges
 *   3. a soft radial lift behind the portrait, so she is standing in light
 *      rather than pasted onto a flat rectangle
 *   4. the existing film grain over everything
 *
 * The layers are stacked so none of them ever sits at strength behind reading
 * text: the grid fades out across the text column, and the dither is masked to
 * the outer edges. The measured 17.72:1 on the copy is unaffected.
 * ======================================================================== */

/* Layer 1 REMOVED, 2026-07-29.
 *
 * A hairline rounded-square grid took the register of the owner's reference.
 * On a dark plum field it did not read as paper, it read as a visible tiled
 * grid, and the owner's verdict was blunt and correct. Deleted rather than
 * dialled down: at any opacity where it registered at all, it registered as
 * squares. The field is stronger with one texture doing one job.
 */

.sna-hero {
  background-color: var(--brand-plum);
  background-image: none;
}

/* Layer 3 REMOVED, 2026-07-29.
 *
 * A soft radial behind the portrait, warm-tinted so the plum read as lit. It
 * did not read as light, it read as an orange shape floating behind her. The
 * gold in the gradient was the culprit: any warm tint over plum at that scale
 * stops being illumination and becomes an object.
 *
 * The lift the portrait needed is now done by the dither fade instead, which
 * is light coming from the bottom edge rather than a glow behind a subject.
 */

.sna-hero__top {
  position: relative;
}

/* The dither, now the only texture, and doing more work for it.
 *
 * The owner asked to keep what was at the foot of the hero and amplify it into
 * a fade rising up the field. So: denser dots, higher opacity at the base, and
 * a longer ramp that reaches roughly two thirds up before it disappears.
 *
 * It still stops short of the headline. The mask is what guarantees that, and
 * it is the reason the measured 17.72:1 on the copy is unaffected: the text
 * never sits on textured ground, only on solid plum.
 */
.sna-hero::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='3' height='3' viewBox='0 0 3 3'%3E%3Crect width='1' height='1' fill='%23FBF9F6' fill-opacity='0.85'/%3E%3Crect x='2' y='2' width='1' height='1' fill='%23FBF9F6' fill-opacity='0.4'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(
    to top,
    rgba(0, 0, 0, 1) 0%,
    rgba(0, 0, 0, 0.62) 18%,
    rgba(0, 0, 0, 0.28) 38%,
    rgba(0, 0, 0, 0.08) 55%,
    transparent 68%
  );
          mask-image: linear-gradient(
    to top,
    rgba(0, 0, 0, 1) 0%,
    rgba(0, 0, 0, 0.62) 18%,
    rgba(0, 0, 0, 0.28) 38%,
    rgba(0, 0, 0, 0.08) 55%,
    transparent 68%
  );
  -webkit-mask-composite: source-over;
          mask-composite: add;
}

/* ---------------------------------------------------------------------------
 * 15. FLOATING HEADER
 *
 * The reference floats a dark rounded bar over a light page. Inverting that
 * here: our field is dark, so a dark bar would disappear into it. The bar is
 * instead a translucent panel with a hairline and a blur, which reads as the
 * same "floating chrome" idea on a dark ground and keeps the nav legible.
 *
 * Applied only on hero-led pages. Everywhere else the header stays a normal
 * solid bar, because there is no dark field for it to float over.
 * ------------------------------------------------------------------------ */

.sna-leads-with-hero #masthead {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 50;
  background: transparent;
  border-bottom: 0;
  padding-top: var(--space-s);
}

.sna-leads-with-hero .site-main-header-wrap .site-header-row-container-inner {
  max-width: var(--width-wide);
  margin-inline: auto;
  border-radius: 999px;
  background-color: rgba(27, 11, 42, 0.55);
  box-shadow: inset 0 0 0 1px rgba(251, 249, 246, 0.14);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
          backdrop-filter: saturate(140%) blur(14px);
  padding-inline: var(--space-m);
}

/* On the dark field the nav has to invert. */
.sna-leads-with-hero #masthead .menu > li > a,
.sna-leads-with-hero #masthead .site-title a,
.sna-leads-with-hero #masthead .site-branding a {
  color: var(--brand-ivory);
}

.sna-leads-with-hero #masthead .menu > li > a:hover {
  color: var(--brand-gold-200);
}

.sna-leads-with-hero #masthead .menu .current-menu-item > a,
.sna-leads-with-hero #masthead .menu .current-menu-ancestor > a {
  color: var(--brand-gold-200);
  box-shadow: inset 0 -2px 0 0 var(--brand-gold);
}

/* The header now sits over the hero, so the hero has to make room for it. */
.sna-leads-with-hero .sna-hero {
  padding-top: calc(var(--space-section) * 1.5);
}

@media (max-width: 47.9375em) {
  .sna-leads-with-hero .sna-hero {
    padding-top: calc(var(--space-2xl) + var(--space-2xl));
  }

  .sna-leads-with-hero .site-main-header-wrap .site-header-row-container-inner {
    border-radius: var(--radius);
    margin-inline: var(--space-s);
  }
}

/* ---------------------------------------------------------------------------
 * 16. Didone display
 *
 * Bodoni's hairlines need slightly looser tracking and a touch more line
 * height than a humanist serif, or the thin strokes crowd and the counters
 * close up at display size.
 * ------------------------------------------------------------------------ */

/* Grotesque display settings. A neo-grotesque at hero size wants tight
   tracking and tight leading, the opposite of what the didone needed. */
.sna-hero__title {
  letter-spacing: -0.03em;
  line-height: 1.03;
  font-weight: 600;
}

/* Kadence colours .site-title separately from .brand, and it inherits the
   light-page value (plum), so on the floating dark bar the site name rendered
   plum on plum and was completely invisible. Found by querying the computed
   colour of every element in the header containing the site name, not by
   looking at the screenshot, where it simply was not there to notice. */
.sna-leads-with-hero #masthead .site-title,
.sna-leads-with-hero #masthead .brand,
.sna-leads-with-hero #masthead .site-title-wrap {
  color: var(--brand-ivory);
}

/* ===========================================================================
 * 17. HEADER: sticky, adaptive, and responsive
 *
 * One bar has to stay legible over a dark hero and then over light content, so
 * it carries two schemes and swaps between them. assets/js/header.js watches
 * what is actually behind the bar and sets the class; everything visual is
 * here, so with JavaScript off the header still renders in the light scheme,
 * which is correct for every page except the hero.
 * ======================================================================== */

/* Fixed on hero-led pages so it overlays the field, sticky elsewhere so it
   occupies normal flow and then pins. Both end up "always visible on scroll". */
.sna-leads-with-hero #masthead {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
}

body:not(.sna-leads-with-hero) #masthead {
  position: sticky;
  top: 0;
  z-index: 100;
}

#masthead,
#masthead .site-header-row-container-inner {
  transition:
    background-color 260ms var(--motion-easing),
    box-shadow 260ms var(--motion-easing),
    padding 260ms var(--motion-easing);
}

/* Over the dark field. */
.sna-header--on-dark .site-main-header-wrap .site-header-row-container-inner {
  background-color: rgba(27, 11, 42, 0.5);
  box-shadow: inset 0 0 0 1px rgba(251, 249, 246, 0.16);
}

.sna-header--on-dark .menu > li > a,
.sna-header--on-dark .site-title {
  color: var(--brand-ivory);
}

.sna-header--on-dark .menu > li > a:hover {
  color: var(--brand-gold-200);
}

/* Over light content. Same shape, inverted, so the bar reads as one component
   that changed clothes rather than as two different headers. */
.sna-header--on-light .site-main-header-wrap .site-header-row-container-inner {
  background-color: rgba(251, 249, 246, 0.82);
  box-shadow: inset 0 0 0 1px rgba(27, 11, 42, 0.1);
}

.sna-header--on-light .menu > li > a,
.sna-header--on-light .site-title {
  color: var(--brand-ink);
}

.sna-header--on-light .menu > li > a:hover {
  color: var(--brand-purple);
}

/* The logo is a light artwork, so on the light scheme it needs inverting back
   to the dark original rather than a second file. */
.sna-header--on-light .custom-logo {
  filter: invert(1) hue-rotate(180deg) saturate(1.15) brightness(0.92);
}

/* Once scrolled, the bar tightens and gains a real edge, which is what makes
   it read as "attached to the viewport" rather than floating loose. */
.sna-header--stuck .site-main-header-wrap .site-header-row-container-inner {
  -webkit-backdrop-filter: saturate(150%) blur(18px);
          backdrop-filter: saturate(150%) blur(18px);
}

.sna-header--stuck.sna-header--on-light .site-main-header-wrap .site-header-row-container-inner {
  box-shadow:
    inset 0 0 0 1px rgba(27, 11, 42, 0.1),
    0 8px 28px rgba(27, 11, 42, 0.09);
}

/* The logo. Kadence sizes it from the Customizer, which is DB state, so the
   size is pinned here instead and travels with the theme. */
#masthead .custom-logo {
  height: auto;
  width: auto;
  max-height: 2.4rem;
  max-width: 12.5rem;
}

@media (max-width: 47.9375em) {
  #masthead .custom-logo {
    max-height: 2rem;
    max-width: 9.5rem;
  }

  .sna-leads-with-hero #masthead {
    padding-top: var(--space-2xs);
  }
}

@media (min-width: 90em) {
  #masthead .custom-logo {
    max-height: 2.75rem;
    max-width: 14rem;
  }
}

/* ---------------------------------------------------------------------------
 * 18. Button arrow
 *
 * The arrow travels on hover and on focus. It is a pseudo element, so it is
 * decorative and never read aloud: a screen reader hears "Book a discovery
 * call", not "Book a discovery call right arrow".
 * ------------------------------------------------------------------------ */

.wp-block-button.is-style-sna-gold .wp-block-button__link {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
}

.wp-block-button.is-style-sna-gold .wp-block-button__link::after {
  content: "\2192";
  display: inline-block;
  font-size: 1.05em;
  line-height: 1;
  transition: transform 220ms var(--motion-easing);
}

.wp-block-button.is-style-sna-gold .wp-block-button__link:hover::after,
.wp-block-button.is-style-sna-gold .wp-block-button__link:focus-visible::after {
  transform: translateX(0.28em);
}

@media (prefers-reduced-motion: reduce) {
  .wp-block-button.is-style-sna-gold .wp-block-button__link::after {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
 * 19. Lift behind the portrait
 *
 * Reinstating something behind her, because the top of the field read as empty
 * once the ledger came out. This is NOT the previous attempt: that one carried
 * a gold tint at large scale and became a visible orange object. This is plum
 * to purple only, no warm hue anywhere in it, sized larger and held at low
 * opacity so it reads as depth in the field rather than as a shape.
 *
 * If it still reads as a blob, delete this block. Nothing else depends on it.
 * ------------------------------------------------------------------------ */

@media (min-width: 60em) {
  .sna-hero__top::after {
    content: "";
    position: absolute;
    z-index: -1;
    top: -12%;
    right: -6%;
    width: 54rem;
    height: 54rem;
    pointer-events: none;
    background: radial-gradient(
      circle at 50% 45%,
      rgba(91, 42, 134, 0.34) 0%,
      rgba(69, 32, 102, 0.18) 38%,
      rgba(27, 11, 42, 0) 66%
    );
  }
}

/* Kadence renders the logo and the text site title together. With a wordmark
   logo that is the brand name twice, side by side. Hidden visually but left in
   the DOM, so the accessible name of the home link is unaffected. */
#masthead .site-branding .site-title {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The light scheme has to outrank the hero-led dark rule, which carries an id
   plus a class and was winning. Measured, not assumed: over light content the
   nav was computing to ivory on an ivory bar, i.e. invisible, while the pill
   had correctly already turned light. */
.sna-leads-with-hero #masthead.sna-header--on-light .menu > li > a,
.sna-leads-with-hero #masthead.sna-header--on-light .site-title,
.sna-leads-with-hero #masthead.sna-header--on-light .brand {
  color: var(--brand-ink);
}

.sna-leads-with-hero #masthead.sna-header--on-light .menu > li > a:hover,
.sna-leads-with-hero #masthead.sna-header--on-light .menu .current-menu-item > a,
.sna-leads-with-hero #masthead.sna-header--on-light .menu .current-menu-ancestor > a {
  color: var(--brand-purple);
}

/* ===========================================================================
 * 20. NAVIGATION: six items, one of them a button
 *
 * The bar was eleven items with the framework nested underneath. It is now
 * five links plus a button, ordered by intent: Products, Community, About,
 * Newsletter, then the single conversion action. Everything dropped moved to
 * the footer, so nothing became unreachable.
 * ======================================================================== */

/* The logo, enlarged and sharpened.
 *
 * The source is now the 557x145 raster extracted from inside the supplied SVG,
 * which is 74% more linear resolution than the 320x80 PNG that was there
 * before. At the sizes below it renders at roughly 2.4x, which is what makes
 * it read as crisp on a retina screen rather than soft. */
#masthead .custom-logo {
  height: auto;
  width: auto;
  max-height: 3.4rem;
  max-width: 15.5rem;
  transition: max-height 260ms var(--motion-easing);
}

/* Shrink slightly once stuck, so the bar tightens as you scroll without the
   logo ever becoming unreadable. */
.sna-header--stuck .custom-logo {
  max-height: 2.9rem;
}

#masthead .site-header-row-container-inner {
  padding-block: var(--space-2xs);
}

/* Nav links. */
#masthead .menu > li > a {
  font-size: 0.975rem;
  font-weight: 500;
  padding-inline: 0.85rem;
}

/* The call to action, rendered as a button rather than a fifth link.
 *
 * Gold with a black label, the same pairing as every primary action on the
 * site, measured at 8.18:1. It carries the same travelling arrow as the hero
 * button so the two read as the same action in two places. */
#masthead .menu > li.sna-nav-cta > a {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin-inline-start: 0.5rem;
  padding: 0.7rem 1.25rem;
  border-radius: 999px;
  background-color: var(--brand-gold);
  color: var(--brand-black);
  font-weight: 600;
  box-shadow: none;
  transition:
    background-color 220ms var(--motion-easing),
    transform 220ms var(--motion-easing);
}

#masthead .menu > li.sna-nav-cta > a::after {
  content: "\2192";
  display: inline-block;
  line-height: 1;
  transition: transform 220ms var(--motion-easing);
}

#masthead .menu > li.sna-nav-cta > a:hover {
  background-color: var(--brand-gold-200);
  color: var(--brand-black);
}

#masthead .menu > li.sna-nav-cta > a:hover::after {
  transform: translateX(0.25em);
}

/* The CTA keeps its own colours in both schemes. It is the one element that
   should not adapt: a gold pill reads as "the action" on light and on dark. */
.sna-leads-with-hero #masthead.sna-header--on-light .menu > li.sna-nav-cta > a,
.sna-leads-with-hero #masthead.sna-header--on-dark .menu > li.sna-nav-cta > a {
  color: var(--brand-black);
}

/* No underline or gold rule on the CTA: it is already the loudest thing here. */
#masthead .menu > li.sna-nav-cta.current-menu-item > a {
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  #masthead .custom-logo,
  #masthead .menu > li.sna-nav-cta > a,
  #masthead .menu > li.sna-nav-cta > a::after {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
 * 21. Navigation on small screens
 *
 * Kadence collapses to a toggle and an off-canvas drawer. Both inherit the
 * light page colours, so on the dark hero the toggle was a dark icon on a dark
 * bar. These give the toggle the same two schemes as the bar it sits in, and
 * bring the drawer onto the brand.
 * ------------------------------------------------------------------------ */

@media (max-width: 61.9375em) {
  #masthead .custom-logo {
    max-height: 2.6rem;
    max-width: 12rem;
  }

  .sna-header--stuck .custom-logo {
    max-height: 2.3rem;
  }

  /* The toggle follows the bar's scheme. */
  .sna-header--on-dark .menu-toggle-open .kadence-svg-icon svg,
  .sna-header--on-dark .mobile-toggle-open-container .menu-toggle-open {
    color: var(--brand-ivory);
  }

  .sna-header--on-light .menu-toggle-open .kadence-svg-icon svg,
  .sna-header--on-light .mobile-toggle-open-container .menu-toggle-open {
    color: var(--brand-ink);
  }

  /* Give it a real target. 44px is the minimum comfortable tap size, and the
     default was smaller than that. */
  #masthead .menu-toggle-open {
    min-width: 44px;
    min-height: 44px;
    border-radius: 999px;
  }

  /* The drawer. */
  #mobile-drawer .drawer-inner,
  .popup-drawer .drawer-inner {
    background-color: var(--brand-plum);
    color: var(--brand-ivory);
  }

  #mobile-drawer .menu > li > a,
  .popup-drawer .menu > li > a {
    font-family: var(--font-body);
    font-size: 1.15rem;
    font-weight: 500;
    color: var(--brand-ivory);
    padding-block: 0.85rem;
    border-bottom: 1px solid rgba(251, 249, 246, 0.12);
  }

  #mobile-drawer .menu > li > a:hover,
  .popup-drawer .menu > li > a:hover {
    color: var(--brand-gold-200);
  }

  /* In the drawer the CTA becomes a full width button, which is the correct
     shape for a thumb rather than a pill floating in a list. */
  #mobile-drawer .menu > li.sna-nav-cta > a,
  .popup-drawer .menu > li.sna-nav-cta > a {
    justify-content: center;
    margin: var(--space-m) 0 0;
    border-radius: var(--radius);
    background-color: var(--brand-gold);
    color: var(--brand-black);
    border-bottom: 0;
  }

  #mobile-drawer .drawer-header .menu-toggle-close,
  .popup-drawer .drawer-header .menu-toggle-close {
    color: var(--brand-ivory);
    min-width: 44px;
    min-height: 44px;
  }
}

/* Between tablet and desktop the six items plus a button can crowd. Tighten
   the link padding before anything wraps. */
@media (min-width: 62em) and (max-width: 74.9375em) {
  #masthead .menu > li > a {
    font-size: 0.925rem;
    padding-inline: 0.6rem;
  }

  #masthead .menu > li.sna-nav-cta > a {
    padding: 0.6rem 1rem;
  }

  #masthead .custom-logo {
    max-height: 2.9rem;
    max-width: 13rem;
  }
}

/* The logo grew, so the bar is taller, so the hero needs more clearance than
   it did. Measured at 390px: the headline was starting roughly 10px below the
   bar, which reads as crowding rather than as overlap. */
@media (max-width: 47.9375em) {
  .sna-leads-with-hero .sna-hero {
    padding-top: calc(var(--space-3xl) + var(--space-l));
  }
}

/* ===========================================================================
 * 22. HERO AND HEADER PROPORTIONS
 *
 * Owner feedback, all of it about weight and air rather than colour:
 *   the bar is too tall, and too wide on mobile
 *   the headline is too big
 *   there is not enough room between the bar and the headline
 *
 * These are the corrections. They are grouped here rather than edited into the
 * earlier sections so the previous values stay readable in the diff.
 * ======================================================================== */

/* A thinner bar. The reference the owner keeps pointing at is a slim pill: the
   logo sets the height and the padding stays out of the way. */
#masthead .site-header-row-container-inner {
  padding-block: 0.3rem;
}

#masthead .custom-logo {
  max-height: 2.5rem;
  max-width: 12rem;
}

.sna-header--stuck .custom-logo {
  max-height: 2.2rem;
}

#masthead .menu > li > a {
  font-size: 0.925rem;
  padding-block: 0.5rem;
}

#masthead .menu > li.sna-nav-cta > a {
  padding: 0.55rem 1.1rem;
  font-size: 0.9rem;
}

/* Mobile: a narrower pill with real margin either side, so it reads as a
   floating control rather than a full width band. */
@media (max-width: 61.9375em) {
  .sna-leads-with-hero #masthead {
    padding-top: var(--space-xs);
  }

  .sna-leads-with-hero .site-main-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-m);
    border-radius: 999px;
    padding-block: 0.25rem;
    padding-inline: 0.9rem;
  }

  #masthead .custom-logo {
    max-height: 2.05rem;
    max-width: 9.5rem;
  }

  .sna-header--stuck .custom-logo {
    max-height: 1.9rem;
  }
}

@media (max-width: 24em) {
  .sna-leads-with-hero .site-main-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-s);
  }

  #masthead .custom-logo {
    max-height: 1.85rem;
    max-width: 8.25rem;
  }
}

/* ---------------------------------------------------------------------------
 * Clearance and display size
 *
 * The headline was running to 3.75rem, which at the width of a two column hero
 * is more shout than confidence. Brought down, and the subhead with it, so the
 * two sit in proportion rather than competing.
 * ------------------------------------------------------------------------ */

.sna-hero__title {
  font-size: clamp(2.05rem, 1.5rem + 1.9vw, 2.95rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
}

.sna-hero__lede {
  --measure-local: 46ch;
  font-size: clamp(1rem, 0.97rem + 0.15vw, 1.08rem);
  line-height: 1.6;
}

/* Room to breathe under the bar. This was the specific complaint: the headline
   started almost immediately below the pill. */
.sna-leads-with-hero .sna-hero {
  padding-top: calc(var(--space-3xl) + var(--space-xl));
}

@media (max-width: 47.9375em) {
  .sna-leads-with-hero .sna-hero {
    padding-top: calc(var(--space-3xl) + var(--space-m));
  }
}

/* The portrait is now a 945x1652 cut-out rather than a 456px one, so it can be
   given real presence without going soft. */
@media (min-width: 60em) {
  .sna-hero__media {
    max-width: 30rem;
  }
}

/* ===========================================================================
 * 23. PHOTOGRAPHY AND TEXTURE ON LIGHT SECTIONS
 *
 * Consistency pass. The hero established two ideas: a dither that fades, and
 * gold used as a hairline rather than as fill. Both are extended downward here
 * so the light half of the page belongs to the same system, instead of the
 * hero being a designed object sitting on an undesigned page.
 * ======================================================================== */

/* Photographs.
 *
 * One treatment, used everywhere: the brand radius, the single shadow token,
 * and a gold hairline. No second frame style, no per section variation. */
.sna-figure,
.sna-bio__portrait {
  margin: 0;
}

.sna-figure img,
.sna-bio__portrait img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* The gold hairline sits on a wrapper rather than the image, so it hugs the
   picture without the browser having to composite a border over the photo. */
.sna-figure,
.sna-bio__portrait {
  position: relative;
  border-radius: var(--radius);
}

.sna-figure::after,
.sna-bio__portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px rgba(201, 162, 39, 0.55);
  pointer-events: none;
}

.sna-figure--wide {
  margin-top: var(--space-l);
}

/* The About photograph keeps the 4:5 portrait crop it was prepared at, so the
   two column bio never has to letterbox it. */
.sna-bio__portrait img {
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 22%;
}

/* ---------------------------------------------------------------------------
 * Texture on light sections
 *
 * The hero's dither fades UP from its base. Light sections fade DOWN from
 * their top edge, so the two meet at the seam and the page reads as one
 * continuous field rather than as alternating blocks.
 *
 * Far weaker than the hero: ink on ivory has none of the latitude that ivory
 * on plum has, so this is at an opacity where it is felt rather than seen, and
 * it is confined to the top of the section, never under a paragraph.
 * ------------------------------------------------------------------------ */

.sna-problem,
.sna-section.sna-textured {
  position: relative;
  isolation: isolate;
}

.sna-problem::before,
.sna-section.sna-textured::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 14rem;
  z-index: -1;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='3' height='3' viewBox='0 0 3 3'%3E%3Crect width='1' height='1' fill='%231B0B2A' fill-opacity='0.55'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%, transparent 100%);
          mask-image: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%, transparent 100%);
  opacity: 0.5;
}

/* ---------------------------------------------------------------------------
 * The coach bio band
 *
 * Set on the purple tint rather than plain ivory. The photograph was chosen
 * for this: her top is within a few degrees of the brand purple, so the tint
 * and the picture share a hue and the panel reads as composed rather than as
 * a photo dropped onto a colour.
 * ------------------------------------------------------------------------ */

.sna-bio {
  align-items: center;
}

@media (min-width: 48em) {
  .sna-bio__media {
    padding-right: var(--space-m);
  }
}

/* ===========================================================================
 * 24. HEADER HEIGHT, WIDTH, AND CLEARANCE
 *
 * Three faults, all measured at 390px rather than guessed:
 *
 *   the pill was 90px tall, because Kadence puts a min-height on the header
 *   row that none of the padding rules could reach
 *
 *   the pill was 342px of a 390px viewport, so it read as a band rather than
 *   as a floating control
 *
 *   there were 18px between the bar and the headline, which is why the
 *   headline looked welded to it
 * ======================================================================== */

/* Kadence sizes its header rows from a Customizer height value, which is why
   trimming padding did nothing: the row had a floor under it. Releasing the
   floor is what actually makes the bar thin. */
#masthead .site-header-row,
#masthead .site-main-header-inner-wrap,
#masthead .site-header-row-container-inner .site-container {
  min-height: 0;
}

#masthead .site-header-row-container-inner {
  padding-block: 0.35rem;
}

#masthead .custom-logo {
  max-height: 2.15rem;
  max-width: 10.5rem;
}

.sna-header--stuck .custom-logo {
  max-height: 1.95rem;
}

/* Mobile: thinner still, and genuinely inset so it floats. */
@media (max-width: 61.9375em) {
  .sna-leads-with-hero #masthead {
    padding-top: 0.6rem;
  }

  .sna-leads-with-hero .site-main-header-wrap .site-header-row-container-inner,
  .sna-leads-with-hero .site-mobile-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-l);
    padding-block: 0.3rem;
    padding-inline: 0.85rem;
  }

  #masthead .custom-logo {
    max-height: 1.85rem;
    max-width: 8.75rem;
  }

  .sna-header--stuck .custom-logo {
    max-height: 1.7rem;
  }

  #masthead .menu-toggle-open {
    min-width: 40px;
    min-height: 40px;
    padding: 0;
  }
}

@media (max-width: 24em) {
  .sna-leads-with-hero .site-main-header-wrap .site-header-row-container-inner,
  .sna-leads-with-hero .site-mobile-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-m);
  }

  #masthead .custom-logo {
    max-height: 1.7rem;
    max-width: 7.75rem;
  }
}

/* ---------------------------------------------------------------------------
 * Clearance, measured rather than assumed
 *
 * assets/js/header.js publishes the header's real height as --sna-header-h on
 * every scroll and resize. The hero clears that value plus a fluid gap, so the
 * spacing stays correct at any breakpoint and whatever the logo size, instead
 * of being a fixed number that is wrong at one end or the other.
 *
 * The fallback in the var() covers the first paint before the script runs, and
 * the no-JavaScript case.
 * ------------------------------------------------------------------------ */

.sna-leads-with-hero .sna-hero {
  padding-top: calc(var(--sna-header-h, 5.5rem) + clamp(2.25rem, 7vw, 4.5rem));
}

@media (max-width: 47.9375em) {
  .sna-leads-with-hero .sna-hero {
    padding-top: calc(var(--sna-header-h, 4.5rem) + 2.25rem);
  }
}

/* ===========================================================================
 * 25. REFINEMENT PASS
 * ======================================================================== */

/* --- Navigation type, set to the requested 17px --------------------------- */

#masthead .menu > li > a {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: 0;
}

/* The CTA was squeezed: its padding nearly filled the bar's height, so it read
   as jammed between the top and bottom edges rather than sitting inside them.
   Smaller, with margin either side, so the bar has air around it. */
#masthead .menu > li.sna-nav-cta > a {
  font-size: 15px;
  padding: 0.5rem 1.05rem;
  margin-inline-start: 0.75rem;
  line-height: 1.2;
}

#masthead .site-header-row-container-inner {
  padding-block: 0.45rem;
  padding-inline: 0.5rem 0.6rem;
}

@media (max-width: 61.9375em) {
  #masthead .site-header-row-container-inner {
    padding-inline: 0.9rem;
  }
}

/* --- Buttons: one pill language across the site --------------------------- */

/*
 * The hero button was a soft rectangle while the nav CTA was a pill, which
 * read as two different components doing the same job. Everything is a pill
 * now, and the primary carries a visible rim so it has an edge rather than
 * floating as a flat colour block.
 */
.wp-block-button .wp-block-button__link,
#masthead .menu > li.sna-nav-cta > a {
  border-radius: 999px;
}

.wp-block-button.is-style-sna-gold .wp-block-button__link {
  padding: 0.85rem 1.7rem;
  box-shadow:
    inset 0 0 0 1px rgba(27, 11, 42, 0.55),
    0 1px 0 rgba(251, 249, 246, 0.35) inset;
}

.wp-block-button.is-style-sna-gold .wp-block-button__link:hover {
  box-shadow: inset 0 0 0 1px rgba(27, 11, 42, 0.8);
}

/* Solid plum button, for the gold and ivory surfaces. Ivory on plum: 17.72:1. */
.wp-block-button.is-style-sna-onlight .wp-block-button__link {
  background-color: var(--brand-plum);
  color: var(--brand-ivory);
  padding: 0.85rem 1.7rem;
  font-family: var(--font-body);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
}

.wp-block-button.is-style-sna-onlight .wp-block-button__link::after {
  content: "\2192";
  transition: transform 220ms var(--motion-easing);
}

.wp-block-button.is-style-sna-onlight .wp-block-button__link:hover {
  background-color: var(--brand-purple);
  color: var(--brand-ivory);
}

.wp-block-button.is-style-sna-onlight .wp-block-button__link:hover::after {
  transform: translateX(0.28em);
}

/* --- The closing call to action, on gold ---------------------------------- */

/*
 * The one surface on the page that is neither dark field nor ivory, so the
 * closing action cannot be mistaken for another content section.
 *
 * Its texture is deliberately NOT the hero's dot dither: a fine diagonal
 * hatch, so the two read as the same family without being the same effect.
 * Plum on gold-200 measures 12.01:1.
 */
.sna-cta {
  background-color: var(--brand-gold-200);
  color: var(--brand-plum);
  box-shadow: 0 0 0 100vmax var(--brand-gold-200);
  clip-path: inset(0 -100vmax);
  --text: var(--brand-plum);
  --text-secondary: var(--brand-purple-700);
  --accent: var(--brand-plum);
  --rule: rgba(27, 11, 42, 0.28);
}

.sna-cta::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath d='M-1 1 L1 -1 M0 8 L8 0 M7 9 L9 7' stroke='%231B0B2A' stroke-opacity='0.22' stroke-width='1'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.3) 45%, transparent 85%);
          mask-image: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.3) 45%, transparent 85%);
}

.sna-cta::after {
  opacity: 0.03;
}

.sna-cta .sna-eyebrow {
  color: var(--brand-purple-700);
}

.sna-cta .sna-eyebrow::after {
  background-color: var(--brand-plum);
}

.sna-cta__title,
.sna-cta h2 {
  color: var(--brand-plum);
}

.sna-cta__lede {
  color: var(--brand-purple-700);
}

/* --- Offer cards --------------------------------------------------------- */

/*
 * At 390px the four cards stacked to roughly 2,600px with heights ranging from
 * 531px to 770px, which is what "stretched" meant: a single card taller than
 * the viewport, four times over.
 *
 * Tightened rather than redesigned: the structure is right, the padding and
 * leading were not. Equal heights come from the grid, so the ragged column is
 * gone at every width above one.
 */
.sna-offer {
  gap: var(--space-2xs);
  padding: var(--space-m);
  background-color: var(--brand-ivory);
  border: 1px solid rgba(27, 11, 42, 0.1);
}

.sna-offer h3 {
  font-size: var(--step-1);
  line-height: 1.15;
  margin: 0;
}

.sna-offer p {
  font-size: 0.95rem;
  line-height: 1.55;
}

.sna-offer__price {
  font-size: 0.82rem;
  letter-spacing: 0.02em;
}

.sna-offer__who {
  font-size: 0.85rem;
}

.sna-offer .wp-block-button__link {
  width: 100%;
  justify-content: center;
  padding: 0.7rem 1rem;
  font-size: 0.95rem;
}

@media (max-width: 39.9375em) {
  /* One column, but compact: less padding, tighter copy, and the button full
     width so the card ends on a clear action instead of trailing off. */
  .sna-offer {
    padding: var(--space-s) var(--space-m) var(--space-m);
  }

  .sna-offer p {
    font-size: 0.92rem;
  }

  .sna-grid {
    gap: var(--space-s);
    margin-top: var(--space-l);
  }
}

/* --- Footer -------------------------------------------------------------- */

/*
 * Navigation and copyright now sit in the same Kadence row (see the seed), so
 * they can finally be laid out as one line: copyright left, links right,
 * wrapping to a stack only when there is genuinely no room.
 */
#colophon .site-bottom-footer-inner-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s) var(--space-l);
  padding-block: var(--space-m);
}

#colophon .site-footer-section {
  margin: 0;
}

#colophon .menu {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-m);
  justify-content: flex-end;
}

#colophon .menu > li > a {
  font-size: 0.9rem;
  padding: 0.35rem 0;
}

#colophon .site-footer-row-container-inner {
  padding-block: 0;
}

/* Drop the now-empty middle row so it stops adding dead height. */
#colophon .site-middle-footer-wrap:empty,
#colophon .site-middle-footer-inner-wrap:has(.site-footer-section:empty:only-child) {
  display: none;
}

@media (max-width: 47.9375em) {
  #colophon .site-bottom-footer-inner-wrap {
    justify-content: center;
    text-align: center;
  }

  #colophon .menu {
    justify-content: center;
    gap: 0 var(--space-s);
  }
}

/* --- Section consistency -------------------------------------------------- */

/*
 * Headings across the page now use the hero's settings rather than the
 * defaults they inherited, so the top of the page and the rest of it are
 * visibly the same design.
 */
.entry-content h2 {
  font-size: clamp(1.7rem, 1.3rem + 1.3vw, 2.35rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
}

.entry-content h3 {
  letter-spacing: -0.012em;
}

.sna-lede {
  font-size: clamp(1.05rem, 1rem + 0.25vw, 1.2rem);
  line-height: 1.55;
}

/* --- Corrections after measuring ------------------------------------------ */

/* 17px, matched to the actual markup. The earlier `.menu > li > a` rule was
   not reaching the desktop navigation, which sits inside .main-navigation and
   .header-navigation wrappers. */
#masthead .main-navigation .menu > li > a,
#masthead .header-navigation .menu > li > a,
#masthead nav .menu > li > a {
  font-size: 17px;
}

#masthead .main-navigation .menu > li.sna-nav-cta > a,
#masthead .header-navigation .menu > li.sna-nav-cta > a,
#masthead nav .menu > li.sna-nav-cta > a {
  font-size: 15px;
}

/* The footer row was flex but its two children still measured 198px + 1008px
   in a 1152px row, so they wrapped onto separate lines and never aligned.
   Kadence sizes each section from a grid track; releasing that lets them sit
   to their content and share the line. */
#colophon .site-bottom-footer-inner-wrap > .site-footer-section {
  flex: 0 1 auto;
  width: auto;
  max-width: none;
  min-width: 0;
}

/* The auto margins that push the two sections to opposite ends of the row are
   a DESKTOP behaviour, so they are scoped to the desktop.
   
   Unscoped they also applied to the stacked mobile layout, where an auto margin
   absorbs the cross-axis free space and overrides align-items, which pinned the
   copyright left at 147px wide inside a 342px centred row. Scoping is the fix
   rather than an override, because at 1,3,0 this rule outranks anything the
   mobile block can reasonably say, and out-specifying your own rule to undo it
   is how a stylesheet stops being readable. */
@media (min-width: 48em) {
  #colophon .site-bottom-footer-inner-wrap > .site-footer-section:first-child {
    margin-right: auto;
  }

  #colophon .site-bottom-footer-inner-wrap > .site-footer-section:last-child {
    margin-left: auto;
  }
}

/* The footer nav column would not shrink because Kadence gives each section a
   flex basis from its grid track, so nine links measured 1008px against 922px
   of available room and the whole section wrapped to its own line.
   `flex: 1 1 0%` lets the column take the space that is actually left, and the
   menu inside wraps within it, so the copyright and the links stay on one row
   as intended. */
#colophon .site-bottom-footer-inner-wrap > .site-footer-section:last-child {
  flex: 1 1 0%;
  min-width: 0;
}

#colophon .menu > li > a {
  font-size: 0.84rem;
  white-space: nowrap;
}

#colophon .menu {
  row-gap: 0.15rem;
}

/* ===========================================================================
 * 26. SECTION SYSTEM
 *
 * Everything below the hero, rebuilt as a system rather than as a stack of
 * individually styled blocks. The hero is untouched.
 *
 * Three principles, applied everywhere:
 *
 *   1. Surfaces alternate. A visitor never scrolls through two sections on
 *      the same ground. That pacing is what stops a long page reading as one
 *      undifferentiated column, and it does more for perceived quality than
 *      any amount of decoration inside the sections.
 *
 *   2. Elevation, not outlines. Borders were doing the work of separating
 *      things, and eight bordered rectangles in a column reads as a form, not
 *      as a designed page. Cards now sit on their own surface with the single
 *      shadow token; the gold hairline is reserved for genuine dividers and
 *      for the marker flourish.
 *
 *   3. Texture belongs to the surface, not to the component. Each ground has
 *      one texture treatment, so a card never carries its own.
 * ======================================================================== */

/* --- The grounds ---------------------------------------------------------- */

.sna-band-tint,
.sna-band-dark,
.sna-band-plain {
  position: relative;
  isolation: isolate;
  box-shadow: 0 0 0 100vmax var(--band-bg, transparent);
  clip-path: inset(0 -100vmax);
  background-color: var(--band-bg, transparent);
}

/* Tint: the framework. Soft, warm, and the only place the purple tint runs
   full width, which is what marks the framework as the centre of the page. */
.sna-band-tint {
  --band-bg: #F4EFF8;
  --text-secondary: var(--brand-muted-tint);
  --rule: rgba(69, 32, 102, 0.18);
}

/* Dark: the coach. One dark band in the body of the page, so the person
   behind the practice gets the same weight as the promise at the top. */
.sna-band-dark {
  --band-bg: var(--brand-plum);
  --text: var(--brand-ivory);
  --text-secondary: var(--brand-gold-200);
  --accent: var(--brand-gold);
  --rule: rgba(232, 206, 122, 0.28);
  color: var(--brand-ivory);
}

.sna-band-dark h2,
.sna-band-dark h3,
.sna-band-dark p {
  color: var(--brand-ivory);
}

.sna-band-dark .sna-eyebrow {
  color: var(--brand-gold-200);
}

.sna-band-dark .sna-card__link a {
  color: var(--brand-gold-200);
  border-bottom-color: var(--brand-gold);
}

.sna-band-dark .sna-placeholder__tag {
  color: var(--brand-plum);
  background-color: var(--brand-gold-200);
}

/* Texture, one per ground, each a different weave so the page has variety
   without ever changing language. Tint gets a fine dot, dark gets the dither
   it shares with the hero, plain gets nothing: a page needs quiet sections. */
.sna-band-tint::before,
.sna-band-dark::before {
  content: "";
  position: absolute;
  inset: 0 -100vmax;
  z-index: -1;
  pointer-events: none;
}

.sna-band-tint::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6' viewBox='0 0 6 6'%3E%3Ccircle cx='1' cy='1' r='0.6' fill='%235B2A86' fill-opacity='0.16'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0.85) 0%, transparent 38%, transparent 70%, rgba(0,0,0,0.5) 100%);
          mask-image: linear-gradient(to bottom, rgba(0,0,0,0.85) 0%, transparent 38%, transparent 70%, rgba(0,0,0,0.5) 100%);
}

.sna-band-dark::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='3' height='3' viewBox='0 0 3 3'%3E%3Crect width='1' height='1' fill='%23FBF9F6' fill-opacity='0.7'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(to left, rgba(0,0,0,0.75) 0%, transparent 45%);
          mask-image: linear-gradient(to left, rgba(0,0,0,0.75) 0%, transparent 45%);
}

/* --- Cards, borderless ---------------------------------------------------- */

/*
 * The dimension cards sit ON the tint band, so a tinted card on a tinted
 * ground would be invisible. They flip to ivory: the card is now the light
 * object and the band is the ground, which is the right way round.
 */
.sna-band-tint .sna-card {
  background-color: var(--brand-ivory);
  border: 0;
  box-shadow: var(--shadow);
  --text-secondary: var(--brand-muted);
  transition: transform 240ms var(--motion-easing), box-shadow 240ms var(--motion-easing);
}

.sna-band-tint .sna-card:hover {
  transform: translateY(-2px);
  box-shadow:
    0 2px 4px rgba(27, 11, 42, 0.05),
    0 14px 32px rgba(27, 11, 42, 0.1);
}

/* Offer cards lose their outline too. The featured one is marked by a gold
   top edge rather than a full border, so one card is emphasised without four
   rectangles competing. */
.sna-offer {
  border: 0;
  background-color: var(--brand-ivory);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  transition: transform 240ms var(--motion-easing), box-shadow 240ms var(--motion-easing);
}

.sna-offer:hover {
  transform: translateY(-2px);
  box-shadow:
    0 2px 4px rgba(27, 11, 42, 0.05),
    0 14px 32px rgba(27, 11, 42, 0.1);
}

.sna-offer--featured {
  box-shadow:
    inset 0 3px 0 0 var(--brand-gold),
    var(--shadow);
}

.sna-offer--featured:hover {
  box-shadow:
    inset 0 3px 0 0 var(--brand-gold),
    0 2px 4px rgba(27, 11, 42, 0.05),
    0 14px 32px rgba(27, 11, 42, 0.1);
}

/* The pricing slot no longer needs a rule under it now that the card has no
   outline: an underline plus a shadow plus a badge is three separators for
   one small piece of text. */
.sna-offer__price {
  border-bottom: 0;
  padding-bottom: 0;
  color: var(--brand-purple-700);
}

/* Photographs lose the gold rim on light grounds, where it was reading as yet
   another box. It stays only where the photograph meets a dark band. */
.sna-figure::after,
.sna-bio__portrait::after {
  box-shadow: none;
}

.sna-band-dark .sna-bio__portrait::after {
  box-shadow: inset 0 0 0 1px rgba(232, 206, 122, 0.45);
}

/* --- The problem ledger --------------------------------------------------- */

/* Row rules were the heaviest thing on the page: five full width lines under
   five short entries. Reduced to a single hairline between rows, and the
   numeral does the separating instead. */
.sna-problem__list {
  border-top: 0;
}

.sna-problem__item {
  border-bottom: 1px solid rgba(27, 11, 42, 0.08);
}

.sna-problem__item:last-child {
  border-bottom: 0;
}

.sna-problem__item .sna-marker {
  color: var(--brand-gold);
  opacity: 0.9;
}

.sna-problem__title {
  color: var(--brand-purple-700);
}

/* --- FAQ ------------------------------------------------------------------ */

.sna-faq__item {
  border-bottom-color: rgba(27, 11, 42, 0.08);
}

.sna-faq__item summary {
  font-family: var(--font-body);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* --- Lead magnet ---------------------------------------------------------- */

/* Was a bordered tint box on an ivory ground. Now a solid tint panel with no
   outline, so it reads as a surface rather than as a form field. */
.sna-magnet {
  border: 0;
  background-color: #F4EFF8;
  box-shadow: var(--shadow);
}

/* --- Section heads -------------------------------------------------------- */

/* One header rhythm everywhere: eyebrow, heading, lede, at consistent spacing.
   Previously each section spaced its own head slightly differently. */
.sna-section > .sna-eyebrow {
  margin-bottom: var(--space-2xs);
}

.sna-section > h2 {
  margin-top: 0;
  margin-bottom: var(--space-s);
}

.sna-section > .sna-lede,
.sna-section > p:first-of-type + p {
  margin-top: 0;
}

/* --- Vertical rhythm ------------------------------------------------------ */

/* Full width grounds need more internal padding than plain sections, or the
   colour looks like it is squeezing the content. */
.sna-band-tint,
.sna-band-dark {
  padding-block: calc(var(--space-section) * 1.1);
}

@media (prefers-reduced-motion: reduce) {
  .sna-card,
  .sna-offer {
    transition: none;
  }

  .sna-card:hover,
  .sna-offer:hover {
    transform: none;
  }
}

/* --- The five card grid --------------------------------------------------- */

/*
 * Five items never divide into a tidy grid, and auto-fill was leaving two
 * cards stranded beside a hole. Rather than accept the gap or force five thin
 * columns, the row structure is made deliberate: a six column track where the
 * first three cards take two columns each and the last two take three each.
 *
 * Both rows fill completely, the second row's cards are visibly wider, and
 * the asymmetry reads as a decision instead of as leftover space.
 */
@media (min-width: 62em) {
  .sna-band-tint .sna-grid {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }

  .sna-band-tint .sna-grid > .sna-card:nth-child(-n + 3) {
    grid-column: span 2;
  }

  .sna-band-tint .sna-grid > .sna-card:nth-child(n + 4) {
    grid-column: span 3;
  }
}

/* Two up at tablet leaves one card on its own row, so the last one spans the
   full width there and the row still closes. */
@media (min-width: 40em) and (max-width: 61.9375em) {
  .sna-band-tint .sna-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sna-band-tint .sna-grid > .sna-card:last-child {
    grid-column: 1 / -1;
  }
}

/* ===========================================================================
 * 27. SELF REVIEW PASS
 *
 * Six faults found by going back through the page rather than by adding more.
 * ======================================================================== */

/* 1. Kadence's boxed content shadow.
 *
 * `.content-bg` carries `0 15px 15px -10px` across the full 8,178px of the
 * page, which is what produced the smeared grey band under the closing
 * section. It is a boxed-layout affordance and this layout is not boxed. */
.content-bg,
.entry.content-bg {
  box-shadow: none;
}

/* 2. The closing lede was not centred.
 *
 * The measure rule pins `margin-inline-start: 0 !important` on every capped
 * paragraph, which beat the centring and left it 150px from one edge and
 * 480px from the other. Centred text has to win that fight explicitly. */
.sna-cta__lede,
.sna-cta p {
  margin-inline: auto !important;
  text-align: center;
}

.sna-cta .sna-eyebrow {
  margin-inline: auto;
  justify-content: center;
}

/* 3. A texture that is not dots.
 *
 * The tint band repeated the hero's dot language, so the page had one idea
 * used twice. It now carries a fine ruled line instead: same restraint,
 * different weave, and it reads as paper rather than as screen. */
.sna-band-tint::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='7' viewBox='0 0 7 7'%3E%3Cpath d='M0 6.5 H7' stroke='%235B2A86' stroke-opacity='0.13' stroke-width='1'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,0.9) 0%, transparent 42%, transparent 68%, rgba(0,0,0,0.55) 100%);
          mask-image: linear-gradient(to bottom, rgba(0,0,0,0.9) 0%, transparent 42%, transparent 68%, rgba(0,0,0,0.55) 100%);
}

/* 4. The five dimension cards.
 *
 * The last two were spanning three tracks each, so they rendered half again
 * as wide as the first three and the set looked mismatched rather than
 * deliberate. All five are now the same width; the final two are centred
 * under the row above, which closes the grid without distorting anything.
 */
@media (min-width: 62em) {
  .sna-band-tint .sna-grid > .sna-card:nth-child(-n + 3) {
    grid-column: span 2;
  }

  .sna-band-tint .sna-grid > .sna-card:nth-child(4) {
    grid-column: 2 / span 2;
  }

  .sna-band-tint .sna-grid > .sna-card:nth-child(5) {
    grid-column: 4 / span 2;
  }
}

/* ---------------------------------------------------------------------------
 * 5. The offers, rebuilt as rows
 *
 * Four cards in four columns gave every offer roughly 220px of width, which is
 * not enough for a heading, a price, a paragraph, a qualifier and a button.
 * Everything inside was squeezed into a narrow ribbon and the whole section
 * read as cramped.
 *
 * Rows solve it structurally rather than cosmetically: each offer gets the
 * full page width, so the name sits on the left where the eye starts, the
 * description takes the space it needs in the middle, and the action sits on
 * the right where a decision is made. Comparing four offers now means running
 * down one column of names instead of reading four narrow columns across.
 * ------------------------------------------------------------------------ */

.sna-grid.sna-offers {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  grid-template-columns: none;
}

.sna-offer {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2xs);
  padding: var(--space-m);
  align-items: start;
}

/*
 * Two columns, not three.
 *
 * The first attempt used named grid areas with a third column, and the
 * qualifier line landed in the same cell as the description and overlapped it.
 * Named areas assume a fixed set of children, and these cards do not have one:
 * the featured card carries a badge the others do not.
 *
 * This shape cannot collide. Everything textual flows normally down the first
 * column, and the action sits in the second, vertically centred and spanning
 * whatever height the text turns out to be. It survives a card gaining or
 * losing a line.
 */
@media (min-width: 48em) {
  .sna-offer {
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--space-2xl);
    row-gap: 0;
    align-items: center;
    padding: var(--space-l);
  }

  .sna-offer > * {
    grid-column: 1;
  }

  .sna-offer .wp-block-buttons {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    justify-self: end;
    margin: 0;
    padding: 0;
  }

  .sna-offer > h3 {
    margin-bottom: 0.1rem;
  }

  .sna-offer__price {
    margin-bottom: 0.5rem;
  }

  .sna-offer > p:not(.sna-offer__price):not(.sna-offer__who) {
    /* 55ch, not 62ch. Measured by counting real line boxes: 62ch rendered 84
       characters here. See tokens.css on why ch is not a character. */
    max-width: 55ch;
    margin-bottom: 0.35rem;
  }

  .sna-offer .wp-block-button__link {
    width: auto;
    white-space: nowrap;
  }

  .sna-offer > .sna-badge {
    justify-self: start;
    margin-bottom: 0.5rem;
  }
}

/* The gold top edge becomes a left edge on a row: a rule down the side reads
   as emphasis, a rule across the top of a wide row reads as a divider. */
.sna-offer--featured {
  box-shadow:
    inset 3px 0 0 0 var(--brand-gold),
    var(--shadow);
}

.sna-offer--featured:hover {
  box-shadow:
    inset 3px 0 0 0 var(--brand-gold),
    0 2px 4px rgba(27, 11, 42, 0.05),
    0 14px 32px rgba(27, 11, 42, 0.1);
}

/* Rows lift sideways rather than upward: a wide row rising looks like it is
   detaching from the page. */
.sna-offer:hover {
  transform: none;
}

@media (max-width: 47.9375em) {
  .sna-offer .wp-block-button__link {
    width: 100%;
  }
}

/* The centring above still lost: the measure rule is
   `.entry-content :is(p,li,blockquote):not(.sna-eyebrow):not(.sna-marker)`,
   which is three classes plus an element, and both declarations were
   !important. Matching that weight and arriving later is what wins.
   Measured before: 35px from the left edge, 480px from the right. */
.entry-content .sna-cta p:not(.sna-eyebrow),
.entry-content .sna-cta h2 {
  margin-inline: auto !important;
  text-align: center;
}

/* ===========================================================================
 * 28. BLUEPRINT PASS
 *
 * Taking the structural language of the reference the owner supplied, in our
 * palette. No content changes.
 *
 * What is borrowed: centred section heads with a small ruled eyebrow, soft
 * borderless cards that separate by elevation alone, and one featured card
 * lifted rather than outlined.
 *
 * What is not: its blue, its icon chips, and its density. Our page has fewer,
 * longer sections, so the same devices are used with more air.
 * ======================================================================== */

/* --- Centred section heads ------------------------------------------------ */

.sna-section > .sna-eyebrow,
.sna-section > h2,
.sna-section > .sna-lede,
.sna-section > p:first-of-type {
  text-align: center;
}

.entry-content .sna-section > h2,
.entry-content .sna-section > .sna-lede,
.entry-content .sna-section > p:first-of-type {
  margin-inline: auto !important;
}

.sna-section > h2 {
  max-width: 22ch;
}

.sna-section > .sna-lede,
.sna-section > p:first-of-type {
  max-width: 58ch;
}

/* The eyebrow gains a rule on BOTH sides, centred, which is the reference's
   signature and reads as a chapter mark rather than a label. */
.sna-section > .sna-eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  margin-inline: auto;
  margin-bottom: var(--space-xs);
}

.sna-section > .sna-eyebrow::before,
.sna-section > .sna-eyebrow::after {
  content: "";
  width: clamp(1.5rem, 4vw, 2.75rem);
  height: 1px;
  background-color: var(--brand-gold);
  flex: 0 0 auto;
}

.sna-band-dark > .sna-eyebrow::before,
.sna-band-dark > .sna-eyebrow::after {
  background-color: var(--brand-gold-200);
}

/* The problem ledger and the bio keep left-aligned bodies: a five row ledger
   and a two column bio both read worse centred. Only their heads centre. */
.sna-problem__list,
.sna-problem__turn,
.sna-bio {
  text-align: left;
}

.entry-content .sna-problem__turn {
  margin-inline: auto !important;
  text-align: center;
  max-width: 54ch;
}

/* --- Cards, softened ------------------------------------------------------ */

/*
 * The reference separates cards from the ground with almost nothing: a very
 * soft shadow and a hairline that is barely there. Ours were carrying a full
 * shadow token designed for a heavier page.
 */
.sna-band-tint .sna-card,
.sna-offer {
  box-shadow:
    0 1px 2px rgba(27, 11, 42, 0.04),
    0 6px 20px rgba(27, 11, 42, 0.06);
  border-radius: 12px;
}

.sna-band-tint .sna-card:hover,
.sna-offer:hover {
  box-shadow:
    0 2px 4px rgba(27, 11, 42, 0.05),
    0 16px 36px rgba(27, 11, 42, 0.09);
}

/* --- The featured offer, lifted not outlined ------------------------------ */

/*
 * The protruding left edge is gone. In the reference the flagship card is
 * marked by sitting slightly proud of the others with a badge, which is a
 * quieter and more confident signal than a coloured rule.
 */
.sna-offer--featured,
.sna-offer--featured:hover {
  box-shadow:
    0 2px 6px rgba(27, 11, 42, 0.06),
    0 18px 44px rgba(27, 11, 42, 0.12);
}

.sna-offer--featured {
  background-color: var(--brand-ivory);
  position: relative;
  z-index: 1;
}

@media (min-width: 48em) {
  .sna-offer--featured {
    margin-inline: calc(var(--space-s) * -1);
    padding-inline: calc(var(--space-l) + var(--space-s));
  }
}

/* The badge becomes the marker, in the brand's own colours. */
.sna-badge {
  background-color: var(--brand-purple-100);
  color: var(--brand-purple-700);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  padding: 0.3rem 0.7rem;
}

/* --- Dimension cards: a marker chip, as the reference uses an icon chip --- */

.sna-band-tint .sna-card {
  padding: var(--space-l) var(--space-m) var(--space-m);
}

.sna-band-tint .sna-card .sna-marker {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 10px;
  background-color: var(--brand-purple-100);
  color: var(--brand-purple-700);
  font-size: 0.85rem;
  margin-bottom: var(--space-s);
}

.sna-band-tint .sna-card .sna-marker::after {
  display: none;
}

.sna-band-tint .sna-card h3 {
  font-size: var(--step-1);
  margin-bottom: var(--space-2xs);
}

/* --- The dark bio band, per the reference's about section ----------------- */

.sna-band-dark .sna-bio {
  gap: var(--space-2xl);
}

@media (max-width: 47.9375em) {
  .sna-section > h2 {
    max-width: 18ch;
  }
}

/* The section intro is the paragraph AFTER the heading. `p:first-of-type`
   matched the eyebrow instead, so the intro stayed left aligned under a
   centred head. Targeting the adjacency is exact. */
.entry-content .sna-section > h2 + p,
.entry-content .sna-section > h2 + .sna-lede {
  text-align: center;
  margin-inline: auto !important;
  max-width: 58ch;
}

/* ===========================================================================
 * 29. CENTRING, AND MOBILE CARDS
 *
 * The blanket centring from the blueprint pass was wrong for long copy. Stripe
 * and Clay centre a section's eyebrow, heading, and a SHORT standfirst, then
 * left align everything with real reading length. A three sentence paragraph
 * set centred has a ragged left edge on every line and is genuinely harder to
 * read; that is what looked bad.
 * ======================================================================== */

/* Heads centre. Body does not. */
.sna-section > .sna-eyebrow,
.sna-section > h2 {
  text-align: center;
}

/* A standfirst only stays centred while it is short enough to hold a tidy
   shape. Past roughly two lines it goes left, where it belongs. */
.entry-content .sna-section > h2 + p,
.entry-content .sna-section > h2 + .sna-lede {
  max-width: 46ch;
  text-align: center;
  margin-inline: auto !important;
}

/* The problem section's intro is three sentences of real argument, so it reads
   left aligned in a centred column, not as centred text. */
.entry-content .sna-problem > .sna-lede,
.entry-content .sna-problem > p {
  text-align: left;
  max-width: 58ch;
  margin-inline: auto !important;
}

.entry-content .sna-problem__turn {
  text-align: left;
  max-width: 58ch;
}

/* Cards and ledger rows are always left aligned: centred text inside a card is
   the single clearest sign of a template. */
.sna-card,
.sna-card *,
.sna-offer,
.sna-offer *,
.sna-problem__item,
.sna-problem__item *,
.sna-faq__item,
.sna-faq__item * {
  text-align: left;
}

/* The closing band is the one exception: it is a single short action and reads
   correctly centred. */
.sna-cta,
.sna-cta * {
  text-align: center;
}

/* ---------------------------------------------------------------------------
 * Offer rows on small screens
 *
 * Below the two column breakpoint these were inheriting row spacing meant for
 * a wide layout, so they read as loose and unfinished on a phone.
 * ------------------------------------------------------------------------ */

@media (max-width: 47.9375em) {
  .sna-grid.sna-offers {
    gap: var(--space-s);
  }

  .sna-offer {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--space-m);
    border-radius: 12px;
  }

  .sna-offer > .sna-badge {
    align-self: flex-start;
    margin-bottom: var(--space-2xs);
  }

  .sna-offer > h3 {
    font-size: 1.2rem;
    margin: 0 0 0.15rem;
  }

  .sna-offer__price {
    margin: 0 0 0.6rem;
    font-size: 0.8rem;
  }

  .sna-offer > p:not(.sna-offer__price):not(.sna-offer__who) {
    margin: 0 0 0.5rem;
    font-size: 0.94rem;
    line-height: 1.55;
  }

  .sna-offer__who {
    margin: 0 0 var(--space-s);
    font-size: 0.85rem;
  }

  .sna-offer .wp-block-buttons {
    margin: 0;
    padding: 0;
  }

  .sna-offer .wp-block-button,
  .sna-offer .wp-block-button__link {
    width: 100%;
    justify-content: center;
  }

  /* The featured row loses its negative inset on a phone, where it would push
     the card past the screen edge. */
  .sna-offer--featured {
    margin-inline: 0;
    padding-inline: var(--space-m);
  }

  /* Dimension cards tighten to match. */
  .sna-band-tint .sna-card {
    padding: var(--space-m);
  }

  .sna-band-tint .sna-card .sna-marker {
    width: 2.1rem;
    height: 2.1rem;
    margin-bottom: var(--space-xs);
  }
}

/* The problem intro was still centring: the generic `h2 + .sna-lede` rule
   carries an extra element in its selector and out-specified the override.
   Matching the adjacency is what settles it. */
.entry-content .sna-problem > h2 + .sna-lede,
.entry-content .sna-problem > h2 + p {
  text-align: left;
  max-width: 58ch;
}

/* --- The seven domain grid ------------------------------------------------ */

/*
 * Seven items, so the row structure has to be chosen rather than left to
 * auto-fill, which would strand three cards beside a hole. A twelve track
 * grid divides cleanly into four and into three: the first row takes four
 * cards at three tracks each, the second takes three at four tracks each.
 * Both rows close completely and the second row's cards are visibly wider,
 * which reads as a deliberate shape rather than as leftover space.
 */
@media (min-width: 62em) {
  .sna-band-tint .sna-grid.sna-domains {
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }

  .sna-domains > .sna-card:nth-child(-n + 4) {
    grid-column: span 3;
  }

  .sna-domains > .sna-card:nth-child(n + 5) {
    grid-column: span 4;
  }
}

/* Tablet: two up, with the last card spanning so the row closes. */
@media (min-width: 40em) and (max-width: 61.9375em) {
  .sna-band-tint .sna-grid.sna-domains {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sna-domains > .sna-card:last-child {
    grid-column: 1 / -1;
  }
}

/* Seven cards is a lot of vertical space, so they tighten a little. */
.sna-domains .sna-card p {
  font-size: 0.94rem;
  line-height: 1.55;
}

.sna-domains .sna-card h3 {
  font-size: 1.15rem;
}

/* Seven ledger rows likewise. */
.sna-problem__item {
  padding-block: var(--space-m);
}

/* ===========================================================================
 * 30. TOUCH TARGETS
 *
 * An audit at 390px found 18 links rendering under 32px tall. WCAG 2.2 asks
 * for 24px minimum and every practical guideline asks for more; a 20px footer
 * link between two other 20px footer links is genuinely hard to hit.
 *
 * Padding rather than font size, so nothing grows visually. The links look
 * identical and simply became hittable.
 * ======================================================================== */

@media (max-width: 61.9375em) {
  #colophon .menu > li > a {
    display: inline-block;
    padding-block: 0.55rem;
    min-height: 44px;
    display: flex;
    align-items: center;
  }

  #colophon .menu {
    gap: 0.1rem var(--space-m);
  }

  .sna-card__link a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .sna-faq__item summary {
    min-height: 44px;
    align-items: center;
  }

  .entry-content a:not(.wp-block-button__link):not(.sna-card__link a):not(.sna-index__link) {
    padding-block: 0.15rem;
  }
}

/* ===========================================================================
 * 31. DOMAIN PAGES
 *
 * Seven pages sharing one layout, so this is the highest leverage template on
 * the site after the homepage. It previously rendered as a bare three column
 * text block under a floating page title, with the domain name printed twice.
 *
 * Now it follows the same grammar as the homepage: a dark header band carrying
 * the number and the promise, an ivory body of three cards, a tint practice
 * band, then related writing and the closing action.
 * ======================================================================== */

/* --- The header band ------------------------------------------------------ */

.sna-domain-head {
  padding-top: calc(var(--sna-header-h, 5.5rem) + clamp(2.5rem, 6vw, 4.5rem));
  padding-bottom: calc(var(--space-section) * 0.9);
  text-align: center;
}

/* The number is the only thing that distinguishes one of these seven pages
   from another at a glance, so it is given real presence rather than being a
   small label above the title. */
.sna-domain-head .sna-marker {
  justify-content: center;
  font-size: 1.05rem;
  letter-spacing: 0.22em;
  color: var(--brand-gold);
  margin-bottom: var(--space-s);
}

.sna-domain-head .sna-marker::after {
  display: none;
}

.entry-content .sna-domain-head h1 {
  font-size: clamp(2.1rem, 1.6rem + 2vw, 3.1rem);
  line-height: 1.06;
  letter-spacing: -0.025em;
  color: var(--brand-ivory);
  max-width: 20ch;
  margin-inline: auto;
  text-align: center;
}

.entry-content .sna-domain-head .sna-lede {
  color: rgba(251, 249, 246, 0.82);
  max-width: 44ch;
  margin-inline: auto !important;
  text-align: center;
  font-size: clamp(1.05rem, 1rem + 0.3vw, 1.22rem);
}

/* --- The three-part body -------------------------------------------------- */

.sna-domain-body {
  padding-block: calc(var(--space-section) * 0.95);
}

/*
 * Three items divide cleanly into three columns, so unlike the seven card grid
 * this one needs no span trickery. It drops to one column early, because three
 * 17rem columns start squeezing before the tablet breakpoint.
 */
.sna-domain-grid {
  margin-top: 0;
}

@media (min-width: 62em) {
  .sna-domain-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* The card headings are h2 for document structure, but they are labels rather
   than section titles, so they are set at label scale. Using the mono face
   would repeat the eyebrow treatment three times in a row; the body face at
   weight 600 separates them without shouting. */
.sna-card__title {
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--brand-purple-700);
  margin: 0 0 var(--space-2xs);
  text-align: left;
}

.sna-domain-body .sna-card {
  background-color: var(--brand-ivory);
  border: 0;
  border-radius: 12px;
  padding: var(--space-l) var(--space-m);
  box-shadow:
    0 1px 2px rgba(27, 11, 42, 0.04),
    0 6px 20px rgba(27, 11, 42, 0.06);
}

/* --- The practice band ---------------------------------------------------- */

.sna-practice {
  text-align: center;
}

.entry-content .sna-practice__text {
  max-width: 56ch;
  margin-inline: auto !important;
  text-align: center;
  font-family: var(--font-body);
  font-size: clamp(1.08rem, 1rem + 0.4vw, 1.3rem);
  line-height: 1.55;
  color: var(--brand-plum);
}

/* --- Related writing ------------------------------------------------------ */

/* On a domain page the blog grid is a footnote, not a feature, so it is set
   quieter than the homepage version. */
.sna-domain-head ~ .sna-section .sna-posts {
  margin-top: var(--space-s);
}

@media (max-width: 47.9375em) {
  .sna-domain-head {
    padding-top: calc(var(--sna-header-h, 4.5rem) + 2.25rem);
  }

  .sna-domain-body .sna-card {
    padding: var(--space-m);
  }
}

/* The card labels are h2 for document structure but they are labels, not
   section titles. `.sna-card__title` alone lost to `.entry-content h2`, which
   carries an element as well as a class, so they rendered at display size and
   dwarfed the paragraphs underneath. */
.entry-content .sna-domain-body .sna-card__title,
.entry-content .sna-card__title {
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--brand-purple-700);
  margin: 0 0 var(--space-2xs);
}

/* The number was tracking so wide it read as two separate characters. */
.sna-domain-head .sna-marker {
  letter-spacing: 0.12em;
}

/* ===========================================================================
 * 32. INNER PAGE HEADERS
 *
 * One header treatment across the site. Inner pages previously opened with
 * Kadence's centred title floating on ivory, which is a different device to
 * the homepage hero and the domain pages, so the site read as a set of pages
 * rather than as one site.
 * ======================================================================== */

.sna-page-head {
  padding-top: calc(var(--sna-header-h, 5.5rem) + clamp(2.5rem, 6vw, 4.5rem));
  padding-bottom: calc(var(--space-section) * 0.85);
  text-align: center;
}

.entry-content .sna-page-head h1 {
  font-size: clamp(2rem, 1.55rem + 1.9vw, 2.95rem);
  line-height: 1.07;
  letter-spacing: -0.025em;
  color: var(--brand-ivory);
  max-width: 22ch;
  margin-inline: auto;
  text-align: center;
}

.entry-content .sna-page-head .sna-lede {
  color: rgba(251, 249, 246, 0.82);
  max-width: 46ch;
  margin-inline: auto !important;
  text-align: center;
  font-size: clamp(1.02rem, 0.98rem + 0.28vw, 1.18rem);
}

.sna-page-head .sna-eyebrow {
  justify-content: center;
  margin-inline: auto;
}

@media (max-width: 47.9375em) {
  .sna-page-head {
    padding-top: calc(var(--sna-header-h, 4.5rem) + 2.25rem);
  }
}

/* A header band is immediately followed by a content section, and that section
   does not need its full top padding: the band already provided the air. */
.sna-page-head + .sna-section,
.sna-domain-head + .sna-section {
  padding-top: calc(var(--space-section) * 0.8);
}

/* The pillar page's first prose section has no heading above the domain cards,
   so its paragraphs carry the introduction and want a slightly larger set. */
.entry-content .sna-page-head + .sna-section > p {
  font-size: clamp(1.02rem, 0.98rem + 0.2vw, 1.12rem);
}

/* ===========================================================================
 * 33. CONSECUTIVE GROUNDS
 *
 * On About the header band is immediately followed by the coach bio band, and
 * both are plum. Rather than force one of them onto a different ground, the two
 * are merged into a single continuous dark field: the seam between them is
 * removed and the second band drops its top padding.
 *
 * This is better than alternating for its own sake. The header introduces her
 * and the bio is her, so they belong to the same visual block. The rule is
 * general, so any future pair of same-ground sections reads as one section
 * instead of as two with a visible join.
 * ======================================================================== */

.sna-band-dark + .sna-band-dark,
.sna-band-tint + .sna-band-tint {
  padding-top: 0;
}

/* The texture layer is per section, so two stacked bands would fade twice and
   show a band across the join. The second one inherits instead. */
.sna-band-dark + .sna-band-dark::before,
.sna-band-tint + .sna-band-tint::before {
  display: none;
}

/* Zeroing padding was not enough to merge two same-ground bands: WordPress puts
   a block gap margin between sibling sections, and because each band clips its
   own background bleed with clip-path, that margin showed as a thin ivory seam
   straight across the join. The margin has to go too. */
.sna-band-dark + .sna-band-dark,
.sna-band-tint + .sna-band-tint {
  margin-top: 0 !important;
}

/* Kadence and the block layout both add top margins to sibling sections, and
   the gap reappears through whichever one is not covered above. */
.entry-content > .sna-band-dark + .sna-band-dark,
.entry-content > .sna-band-tint + .sna-band-tint {
  margin-block-start: 0 !important;
}

/* The seam was margin-BOTTOM on the first band, not margin-top on the second.
   Measured: 32px on the first, 0 on the second, so zeroing the second changed
   nothing. `:has()` lets the first band know a sibling of the same ground
   follows it, which is the only place the rule can go. */
.sna-band-dark:has(+ .sna-band-dark),
.sna-band-tint:has(+ .sna-band-tint) {
  margin-bottom: 0 !important;
}

/* ===========================================================================
 * 34. REDESIGN PHASE 1: HERO
 *
 * The hero moves off the dither treatment and onto the utility system:
 * --ink-deep base, .bloom for a light source, .texture-grain for material.
 *
 * The dither ramp is retired here specifically. It was doing the job the bloom
 * now does better: the ramp is symmetric and reads as a screen effect, the
 * bloom is off-centre and reads as light in a room, which is the "candlelight
 * in a dark sanctuary" direction. The dither stays on the other dark bands.
 * ======================================================================== */

.sna-hero {
  background-color: var(--ink-deep);
  background-image: none;
}

/* Retire the ramp and the old grain on the hero only. Both are replaced by the
   utilities, which are applied to the section from CSS rather than the markup
   so the pattern stays free of presentational classes. */
.sna-hero::before {
  background-image: none;
  -webkit-mask-image: none;
          mask-image: none;
  opacity: 0;
}

/* .bloom, applied here rather than as a class in the pattern. Top left, per the
   brief, so the light falls across the headline and away from the portrait,
   which has its own light in the photograph. */
.sna-hero::after {
  content: "";
  position: absolute;
  z-index: -2;
  pointer-events: none;
  width: 115%;
  height: 135%;
  top: -34%;
  left: -22%;
  opacity: 1;
  background-image: radial-gradient(
    circle at 50% 50%,
    rgba(201, 162, 39, 0.13) 0%,
    rgba(91, 42, 134, 0.28) 30%,
    rgba(27, 11, 42, 0) 62%
  );
}

@media (prefers-reduced-motion: no-preference) {
  .sna-hero::after {
    animation: sna-bloom-drift 60s ease-in-out infinite alternate;
  }
}

/* Grain sits on a third layer, above the bloom and below the content, so the
   light itself is grained rather than a flat wash with grain on top. */
.sna-hero__top {
  position: relative;
}

.sna-hero__top::before {
  content: "";
  position: absolute;
  inset: -50vh -100vmax;
  z-index: -1;
  pointer-events: none;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------------
 * Display typography, from the scale
 * ------------------------------------------------------------------------ */

.sna-hero__title {
  font-size: var(--t-3xl);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  font-weight: 600;
}

/* The signature move: one italic word per major headline, at most three on the
   page. Geist's italic is a true cut, not a slant, so it carries at display
   size. Weight drops to 400 because the italic at 600 reads as a shout. */
.sna-hero__title em,
.sna-page-head h1 em,
.sna-domain-head h1 em {
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.012em;
}

.sna-hero__lede {
  font-size: var(--t-base);
  line-height: var(--lh-body);
  max-width: 46ch;
  color: rgba(251, 249, 246, 0.84);
}

/* ---------------------------------------------------------------------------
 * The primary action
 *
 * Squared to 5px per the brief, replacing the pill. A pill reads friendly and
 * generic; a slight square reads considered. The fill is .foil rather than flat
 * gold, so it has a direction and an implied light source.
 * ------------------------------------------------------------------------ */

.sna-hero .wp-block-button.is-style-sna-gold .wp-block-button__link {
  border-radius: 5px;
  padding: 1rem 1.85rem;
  font-size: var(--t-base);
  font-weight: 600;
  color: var(--brand-black);
  background-color: var(--gold);
  background-image: linear-gradient(
    100deg,
    var(--gold-deep) 0%,
    var(--gold) 28%,
    var(--gold-bright) 50%,
    var(--gold) 72%,
    var(--gold-deep) 100%
  );
  background-size: 220% 100%;
  background-position: 0% 50%;
  box-shadow: inset 0 0 0 1px rgba(27, 11, 42, 0.35);
  transition:
    background-position 600ms var(--motion-easing),
    box-shadow 240ms var(--motion-easing);
}

.sna-hero .wp-block-button.is-style-sna-gold .wp-block-button__link:hover,
.sna-hero .wp-block-button.is-style-sna-gold .wp-block-button__link:focus-visible {
  background-position: 100% 50%;
  box-shadow: inset 0 0 0 1px rgba(27, 11, 42, 0.6);
}

/* The arrow slides 4px, per the brief. */
.sna-hero .wp-block-button.is-style-sna-gold .wp-block-button__link::after {
  transition: transform 240ms var(--motion-easing);
}

.sna-hero .wp-block-button.is-style-sna-gold .wp-block-button__link:hover::after {
  transform: translateX(4px);
}

/* ---------------------------------------------------------------------------
 * The quiet secondary link
 *
 * A text link, not a second button. Deliberately low contrast against the
 * primary so it never competes, but still 6.39:1 on plum, which clears AA.
 * ------------------------------------------------------------------------ */

.sna-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-m) var(--space-l);
}

.entry-content .sna-hero__secondary {
  margin: 0 !important;
  max-width: none;
}

.sna-hero__secondary a {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--brand-gold-200);
  text-decoration: none;
  padding-block: 0.6rem;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  background-image: linear-gradient(var(--gold), var(--gold));
  background-repeat: no-repeat;
  background-size: 0% 1px;
  background-position: 0 100%;
  transition: background-size 260ms var(--motion-easing);
}

.sna-hero__secondary a:hover,
.sna-hero__secondary a:focus-visible {
  background-size: 100% 1px;
}

@media (prefers-reduced-motion: reduce) {
  .sna-hero::after {
    animation: none;
  }

  .sna-hero .wp-block-button__link,
  .sna-hero__secondary a {
    transition: none;
  }
}

/* Section 35 (raking beam + darkness behind the portrait) was reverted on the
 * owner's instruction: it did not read the way it was intended. The hero light
 * is back to the Phase 1 bloom in section 34, and the reference treatment
 * continues in section 36 below.
 */


/* ===========================================================================
 * 36. HERO, REFERENCE TREATMENT
 *
 * Three devices taken from the reference the owner supplied, executed in our
 * palette on our dark ground rather than on its near-white one:
 *
 *   1. a fine grid behind everything
 *   2. one visible light blob behind the portrait
 *
 * The third device, floating rounded tiles, was removed on 2026-07-30. See
 * patterns/hero.php for why it is not coming back.
 *
 * On the grid: a square grid on this ground was tried once before and the
 * owner's verdict was that it looked terrible. It did. That version used 88px
 * rounded squares at an opacity where they read as visible tiles rather than
 * as paper. The reference's grid works because it is small, perfectly regular,
 * and only just above the noise floor. This one is 34px, square, unrounded,
 * and at 3.5% on plum, which is roughly a fifth of the earlier attempt.
 * ======================================================================== */

.sna-hero {
  background-color: var(--ink-deep);
  background-image:
    linear-gradient(to right, rgba(251, 249, 246, 0.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(251, 249, 246, 0.035) 1px, transparent 1px);
  background-size: 34px 34px, 34px 34px;
  background-position: center top;
}

/* The grid fades out toward the bottom so it never fights the section boundary
   or the content that sits lowest in the hero. */
.sna-hero::before {
  content: "";
  position: absolute;
  inset: 0 -100vmax;
  z-index: -3;
  pointer-events: none;
  opacity: 1;
  background-image: linear-gradient(
    to bottom,
    rgba(27, 11, 42, 0) 45%,
    var(--ink-deep) 92%
  );
  -webkit-mask-image: none;
          mask-image: none;
}

/* ---------------------------------------------------------------------------
 * The blob
 *
 * The reference puts a solid, confident shape behind its subjects. Ours is the
 * same idea in our colours, and deliberately VISIBLE rather than a wash: the
 * owner asked for a blob, not another subtle gradient.
 *
 * It is an organic shape rather than a circle. A circle behind a person reads
 * as a badge or an avatar ring; an asymmetric blob reads as a designed ground.
 * border-radius with eight values is the cheapest way to get one, with no SVG
 * and no extra element.
 * ------------------------------------------------------------------------ */

.sna-hero__media {
  position: relative;
  isolation: isolate;
}

.sna-hero__media::before {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  left: 50%;
  top: 2%;
  width: 104%;
  height: 88%;
  transform: translateX(-50%);
  border-radius: 58% 42% 47% 53% / 46% 51% 49% 54%;
  /* Lighter than the ground, not darker. The first attempt ran purple-royal
     down to #35174f, which on a #1B0B2A field is dark on dark and read as a
     smudge rather than as a shape. The reference's blob is confidently lighter
     than its background; this now is too. */
  background-image: linear-gradient(
    155deg,
    #7E42B4 0%,
    var(--purple-royal) 44%,
    #45206A 100%
  );
  opacity: 0.95;
}

/* A soft warm rim where the blob meets the light, so the shape belongs to the
   same scene as the bloom above it rather than being pasted on. */
.sna-hero__media::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  left: 50%;
  top: 2%;
  width: 104%;
  height: 88%;
  transform: translateX(-50%);
  border-radius: 58% 42% 47% 53% / 46% 51% 49% 54%;
  background-image: radial-gradient(
    58% 52% at 34% 22%,
    rgba(232, 206, 122, 0.30) 0%,
    rgba(201, 162, 39, 0.10) 38%,
    rgba(27, 11, 42, 0) 70%
  );
}

/* The portrait sits above both. */
.sna-hero__portrait {
  position: relative;
  z-index: 1;
}

/* ===========================================================================
 * 37. PHASE 2A: THE HONEST PART
 *
 * The strongest copy on the page, so it gets an editorial spread rather than a
 * card grid: the title and intro hold still on the left while the seven items
 * scroll past on the right.
 * ======================================================================== */

.sna-problem__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-l);
}

@media (min-width: 62em) {
  .sna-problem__grid {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: var(--space-3xl);
    align-items: start;
  }

  /* Sticky, offset by the real header height so it never tucks under the bar.
     --sna-header-h is published by header.js and is correct at every
     breakpoint and stuck state. */
  .sna-problem__aside {
    position: sticky;
    top: calc(var(--sna-header-h, 5.5rem) + var(--space-l));
  }
}

/* The head is left aligned here. Everything else on the page centres its
   section heads, but a sticky column that centres its own text next to a left
   aligned list looks like an accident. */
.entry-content .sna-problem__aside .sna-eyebrow,
.entry-content .sna-problem__aside h2,
.entry-content .sna-problem__aside .sna-lede {
  text-align: left;
  margin-inline: 0 !important;
  max-width: 22ch;
}

.entry-content .sna-problem__aside .sna-eyebrow {
  justify-content: flex-start;
  max-width: none;
}

.entry-content .sna-problem__aside .sna-eyebrow::before {
  display: none;
}

.entry-content .sna-problem__aside h2 {
  font-size: var(--t-2xl);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
}

.entry-content .sna-problem__aside .sna-lede {
  max-width: 34ch;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------------------
 * The items
 *
 * Hairlines, not boxes. The numeral is generated by a CSS counter, so the copy
 * stays fully editable as blocks and the numbering cannot drift when an item is
 * added, removed or reordered.
 * ------------------------------------------------------------------------ */

.sna-problem__list {
  counter-reset: sna-stall;
}

.sna-problem__item {
  counter-increment: sna-stall;
  position: relative;
  display: block;
  padding: var(--space-l) 0 var(--space-l) 4.25rem;
  border-bottom: 1px solid color-mix(in srgb, var(--gold) 22%, transparent);
  border-top: 0;
  grid-template-columns: none;
}

.sna-problem__list > .sna-problem__item:first-child {
  border-top: 1px solid color-mix(in srgb, var(--gold) 22%, transparent);
}

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .sna-problem__item,
  .sna-problem__list > .sna-problem__item:first-child {
    border-color: rgba(201, 162, 39, 0.22);
  }
}

/* Large, light, gold, low opacity, set beside the title rather than as a small
   mono digit in a grid cell. */
.sna-problem__item::before {
  content: counter( sna-stall, decimal-leading-zero );
  position: absolute;
  left: 0;
  top: var(--space-l);
  font-family: var(--font-body);
  font-size: 2.1rem;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--gold);
  opacity: 0.5;
  font-variant-numeric: tabular-nums;
}

.entry-content .sna-problem__title {
  font-family: var(--font-body);
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--ink-deep);
  text-transform: none;
  margin: 0 0 var(--space-2xs);
}

.entry-content .sna-problem__item p {
  margin: 0;
  max-width: 54ch;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------------------
 * Scroll reveal
 *
 * The revealed state is the default. reveal.js adds .sna-reveal-armed to the
 * root only once it knows it can animate, so a script failure leaves the copy
 * visible rather than permanently hidden.
 * ------------------------------------------------------------------------ */

.sna-reveal-armed .sna-problem__item {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 350ms var(--motion-easing),
    transform 350ms var(--motion-easing);
}

.sna-reveal-armed .sna-problem__item.is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .sna-reveal-armed .sna-problem__item {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

@media (max-width: 61.9375em) {
  .sna-problem__item {
    padding: var(--space-m) 0 var(--space-m) 3.25rem;
  }

  .sna-problem__item::before {
    font-size: 1.6rem;
    top: var(--space-m);
  }
}

/* ===========================================================================
 * 38. PHASE 2B: THE SEVEN DOMAINS INDEX
 *
 * Option (a). No cards, no numbering, no grid. Seven rows separated by
 * hairlines, each one entirely clickable.
 * ======================================================================== */

.sna-index {
  list-style: none;
  margin: var(--space-xl) 0 0;
  padding: 0;
  max-width: none;
  border-top: 1px solid color-mix(in srgb, var(--gold) 26%, transparent);
}

.sna-index__row {
  margin: 0;
  padding: 0;
  max-width: none;
  border-bottom: 1px solid color-mix(in srgb, var(--gold) 26%, transparent);
}

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .sna-index,
  .sna-index__row {
    border-color: rgba(201, 162, 39, 0.26);
  }
}

/* The whole row is the target, not just the words. 44px minimum comes free
   from the padding. */
.sna-index__link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "name cue"
    "desc cue";
  align-items: center;
  column-gap: var(--space-m);
  row-gap: 0.15rem;
  padding: var(--space-m) var(--space-2xs);
  text-decoration: none;
  color: inherit;
  transition: padding-left 260ms var(--motion-easing);
}

.sna-index__name {
  grid-area: name;
  font-family: var(--font-body);
  font-size: clamp(1.3rem, 1.1rem + 0.85vw, 1.85rem);
  font-weight: 600;
  letter-spacing: var(--track-display);
  line-height: 1.15;
  color: var(--ink-deep);

  /* The names are the longest single words on the page and they sit in a
     column that narrows on small screens. This is the guard that stops the
     mid-word break returning. */
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
}

.sna-index__desc {
  grid-area: desc;
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--text-muted);
  max-width: 52ch;
}

.sna-index__cue {
  grid-area: cue;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: 0 0 auto;
  border-radius: 999px;
  color: var(--gold-text);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gold) 34%, transparent);
  transition:
    transform 260ms var(--motion-easing),
    background-color 260ms var(--motion-easing),
    color 260ms var(--motion-easing);
}

.sna-index__cue svg {
  width: 17px;
  height: 17px;
}

.sna-index__link:hover .sna-index__cue,
.sna-index__link:focus-visible .sna-index__cue {
  transform: translateX(4px);
  background-color: var(--ink-deep);
  color: var(--brand-gold-200);
  box-shadow: none;
}

.sna-index__link:hover {
  padding-left: var(--space-s);
}

.sna-index__link:hover .sna-index__name {
  color: var(--purple-royal);
}

.sna-index__link:focus-visible {
  outline: 2px solid var(--purple-royal);
  outline-offset: 3px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  .sna-index__link,
  .sna-index__cue {
    transition: none;
  }

  .sna-index__link:hover {
    padding-left: var(--space-2xs);
  }

  .sna-index__link:hover .sna-index__cue {
    transform: none;
  }
}

@media (max-width: 47.9375em) {
  .sna-index__link {
    /* Padding is owned by section 47 now. This shorthand set both axes and
       fought the padding-block there for no benefit. */
    column-gap: var(--space-s);
  }

  .sna-index__cue {
    width: 2.1rem;
    height: 2.1rem;
  }
}

/* ===========================================================================
 * 39. PHASE 3A: OFFERS
 *
 * Four identical rows is the same monotony the card grid had, just lying down.
 * The Formation Cohort is marked "start here", so it becomes the featured tier:
 * dark, grained, cream type, gold action. The other three go quiet beneath it.
 *
 * This also fixes a hierarchy problem the old design had: every offer shouted
 * equally, so the one the owner actually wants people to choose had no more
 * pull than the resource library.
 * ======================================================================== */

.sna-offer--featured {
  background-color: var(--ink-deep);
  color: var(--cream);
  border-radius: 14px;
  box-shadow:
    0 2px 6px rgba(27, 11, 42, 0.10),
    0 22px 52px rgba(27, 11, 42, 0.20);
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

/* Grain, so the featured tier is material rather than a flat dark rectangle. */
.sna-offer--featured::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* A single warm lift in the corner, tying it to the hero's light. */
.sna-offer--featured::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  width: 26rem;
  height: 26rem;
  top: -55%;
  right: -8%;
  background-image: radial-gradient(
    circle at 50% 50%,
    rgba(232, 206, 122, 0.16) 0%,
    rgba(91, 42, 134, 0.16) 40%,
    rgba(27, 11, 42, 0) 70%
  );
}

.entry-content .sna-offer--featured h3,
.entry-content .sna-offer--featured p {
  color: var(--cream);
}

.entry-content .sna-offer--featured .sna-offer__price {
  color: var(--brand-gold-200);
}

.entry-content .sna-offer--featured .sna-offer__who {
  color: rgba(251, 249, 246, 0.66);
}

.sna-offer--featured .sna-badge {
  background-color: rgba(232, 206, 122, 0.16);
  color: var(--brand-gold-200);
  box-shadow: inset 0 0 0 1px rgba(232, 206, 122, 0.34);
}

/* The three quiet tiers. Flatter, lighter, no lift on hover: they should read
   as the alternatives, not as four equal choices. */
.sna-offer:not(.sna-offer--featured) {
  background-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(27, 11, 42, 0.09);
}

.sna-offer:not(.sna-offer--featured):hover {
  background-color: var(--cream);
  box-shadow:
    inset 0 0 0 1px rgba(27, 11, 42, 0.06),
    0 10px 26px rgba(27, 11, 42, 0.07);
}

/* Pricing as a quiet mono label, never a badge. */
.entry-content .sna-offer__price {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: none;
  border: 0;
}

/* The "Best if you..." lines stay, set italic and muted per the brief. */
.entry-content .sna-offer__who {
  font-style: italic;
  font-size: var(--t-sm);
  color: var(--text-muted);
}

/* One button system. Gold fill for the featured tier only. */
.wp-block-button.is-style-sna-quiet .wp-block-button__link {
  background-color: transparent;
  color: var(--purple-royal);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--purple-royal) 42%, transparent);
  border-radius: 5px;
  padding: 0.75rem 1.35rem;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
}

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .wp-block-button.is-style-sna-quiet .wp-block-button__link {
    box-shadow: inset 0 0 0 1px rgba(91, 42, 134, 0.42);
  }
}

.wp-block-button.is-style-sna-quiet .wp-block-button__link::after {
  content: "\2192";
  transition: transform 220ms var(--motion-easing);
}

.wp-block-button.is-style-sna-quiet .wp-block-button__link:hover {
  background-color: var(--purple-royal);
  color: var(--cream);
  box-shadow: none;
}

.wp-block-button.is-style-sna-quiet .wp-block-button__link:hover::after {
  transform: translateX(4px);
}

/* ===========================================================================
 * 40. PHASE 3B: ABOUT
 * ======================================================================== */

/*
 * The double frame. A 1px gold inset offset 8px from the image edge, so the
 * portrait sits inside a frame rather than being a rectangle on a background.
 * It is drawn on the figure, not the image, so the placeholder and the real
 * photograph both look composed and swapping one for the other shifts nothing.
 */
.sna-bio__portrait {
  position: relative;
  padding: 8px;
}

.sna-bio__portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 4px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gold) 55%, transparent);
  pointer-events: none;
}

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .sna-bio__portrait::after {
    box-shadow: inset 0 0 0 1px rgba(201, 162, 39, 0.55);
  }
}

.sna-bio__portrait img {
  border-radius: 2px;
  box-shadow: none;
}

/*
 * THE BLOOM BEHIND THE PORTRAIT IS GONE, removed 2026-08-01 at the owner's
 * verdict: a radial gold-into-purple gradient here read as a bright purple
 * object floating behind her rather than as light.
 *
 * This is the SECOND time a radial lift has been tried and rejected on this
 * site. The hero had the same note in the decisions log, for the same reason,
 * in the same words. Soft radial gradients on plum do not read as illumination
 * at this scale; they read as a shape. DO NOT REINTRODUCE ONE HERE.
 *
 * What replaced it is structural rather than luminous: see section 56, the
 * contour texture on the bio band.
 */
.sna-band-dark .sna-bio__media {
  position: relative;
  isolation: isolate;
}

/* The link matches the domain index cue, so the same action looks the same
   wherever it appears. */
.sna-band-dark .sna-card__link a {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--brand-gold-200);
  border-bottom: 1px solid rgba(201, 162, 39, 0.5);
}

/* ===========================================================================
 * 41. PHASE 3C: FAQ
 *
 * Native details and summary. Keyboard operation, Enter and Space, and the
 * expanded state exposed to assistive tech all come free and correctly from
 * the element; adding aria-expanded by hand on top of it is redundant and can
 * conflict with what the browser already reports. What is added here is the
 * visible focus ring, the row target, and the icon.
 * ======================================================================== */

.sna-faq__item {
  border-bottom: 1px solid color-mix(in srgb, var(--gold) 22%, transparent);
  padding-block: 0;
}

.sna-faq__item:first-of-type {
  border-top: 1px solid color-mix(in srgb, var(--gold) 22%, transparent);
}

@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .sna-faq__item,
  .sna-faq__item:first-of-type {
    border-color: rgba(201, 162, 39, 0.22);
  }
}

.sna-faq__item summary {
  font-family: var(--font-body);
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--ink-deep);
  padding-block: 1.35rem;
  min-height: 44px;
  gap: var(--space-m);
}

.sna-faq__item summary:focus-visible {
  outline: 2px solid var(--purple-royal);
  outline-offset: -4px;
  border-radius: 4px;
}

/* A plus that rotates 45 degrees into a cross, rather than swapping glyphs.
   Two spans would need markup; two pseudo layers on one box do not. */
.sna-faq__item summary::after {
  content: "";
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  background-image:
    linear-gradient(var(--gold-text), var(--gold-text)),
    linear-gradient(var(--gold-text), var(--gold-text));
  background-size: 15px 1.5px, 1.5px 15px;
  background-position: center, center;
  background-repeat: no-repeat;
  transform: rotate(0deg);
  transition: transform 250ms ease;
}

.sna-faq__item[open] summary::after {
  transform: rotate(45deg);
}

.entry-content .sna-faq__item p {
  padding-bottom: 1.35rem;
  margin: 0;
  max-width: 55ch;   /* see tokens.css: ch is not a character */
  color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .sna-faq__item summary::after {
    transition: none;
  }
}

/* ===========================================================================
 * 42. PHASE 3D: CLOSING BAND, INVERTED
 *
 * Dark, not gold. On a gold field the gold button has nothing to be brighter
 * than, so the single most important object on the page competes with its own
 * background. On plum it is the brightest thing in view at the moment of the
 * ask. It also bookends the page against the hero.
 * ======================================================================== */

.sna-cta--dark {
  background-color: var(--ink-deep);
  color: var(--cream);
  box-shadow: 0 0 0 100vmax var(--ink-deep);
  clip-path: inset(0 -100vmax);
  --text: var(--cream);
  --text-secondary: var(--brand-gold-200);
  --accent: var(--gold);
  --rule: rgba(232, 206, 122, 0.3);
}

/* Replace the diagonal hatch, which was designed to sit on gold. */
.sna-cta--dark::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='3' height='3' viewBox='0 0 3 3'%3E%3Crect width='1' height='1' fill='%23FBF9F6' fill-opacity='0.6'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 60%);
          mask-image: linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 60%);
}

.entry-content .sna-cta--dark .sna-cta__title,
.entry-content .sna-cta--dark h2 {
  color: var(--cream);
  font-size: var(--t-2xl);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
}

.entry-content .sna-cta--dark .sna-cta__lede {
  color: rgba(251, 249, 246, 0.76);
  font-size: var(--t-base);
}

.sna-cta--dark .sna-eyebrow {
  color: var(--brand-gold-200);
}

.sna-cta--dark .sna-eyebrow::before,
.sna-cta--dark .sna-eyebrow::after {
  background-color: var(--gold);
}

/* ===========================================================================
 * 43. PHASE 3E: FOOTER
 * ======================================================================== */

body #colophon {
  background-color: var(--ink-deep);
  color: rgba(251, 249, 246, 0.72);
  border-top: 0;
  position: relative;
  isolation: isolate;
}

/* The gold hairline above, and grain across. */
body #colophon::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background-color: var(--gold);
  opacity: 0.4;
}

body #colophon::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)'/%3E%3C/svg%3E");
}

#colophon .menu > li > a {
  color: rgba(251, 249, 246, 0.66);
  font-size: var(--t-sm);
}

#colophon .menu > li > a:hover {
  color: var(--brand-gold-200);
}

/* The legal row in mono, quieter than the links. */
#colophon .site-footer-bottom-section-1 {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  letter-spacing: 0.04em;
  color: rgba(251, 249, 246, 0.5);
}

/* The offer cards are constrained-layout groups, so WordPress gives every child
   `margin-left/right: auto !important`. With the card itself set to a grid that
   centred each heading as a BLOCK while its text stayed left aligned, which
   reads as a wobble down the column. Measured: card at 147px, heading at 395px.
   Matching the !important is the only way past it. */
.entry-content .sna-offer > *,
.entry-content .sna-card > * {
  margin-inline-start: 0 !important;
  margin-inline-end: 0 !important;
  max-width: none;
}

.entry-content .sna-offer > p:not(.sna-offer__price):not(.sna-offer__who) {
  /* 55ch, not 62ch. This rule is the one that actually wins over the base
     measure, which is why setting --measure-local on .sna-offer p had no
     effect: a hard max-width beats a custom property the base rule reads. */
  max-width: 55ch;
}

/* The closing band and the footer are both dark, so the 136px of ivory between
   them read as a seam rather than as breathing room. Measured: 32px bottom
   padding on .entry-content-wrap plus an 80px bottom margin on .content-area,
   which is Kadence's normal page spacing and correct when the page ends on a
   light section. :has() lets the page close the gap only when it actually ends
   on a dark band, so other pages keep their spacing. */
.content-area:has(.sna-cta--dark) {
  margin-bottom: 0;
}

.content-area:has(.sna-cta--dark) .entry-content-wrap {
  padding-bottom: 0;
}

/* ---------------------------------------------------------------------------
 * Footer contrast fix
 *
 * The footer links were still taking --brand-muted (#6E6875) from a rule in
 * components.css written when the footer was ivory. On the new dark footer that
 * measures 3.46:1 and fails AA outright. That rule carries an id plus two
 * classes, so it has to be matched to be beaten.
 *
 * Ivory at 0.78 on plum measures 10.9:1. The legal row stays quieter at 0.5,
 * which is 5.05:1 and still clears AA, because it is genuinely secondary.
 * ------------------------------------------------------------------------ */

#colophon .footer-navigation .menu > li > a,
#colophon .menu > li > a,
#colophon .site-footer-section a {
  color: rgba(251, 249, 246, 0.78);
}

#colophon .footer-navigation .menu > li > a:hover,
#colophon .menu > li > a:hover,
#colophon .site-footer-section a:hover {
  color: var(--brand-gold-200);
}

#colophon .menu > li > a:focus-visible,
#colophon .site-footer-section a:focus-visible {
  outline: 2px solid var(--brand-gold-200);
  outline-offset: 2px;
  border-radius: 3px;
}

/* The last 24px of ivory between the closing band and the footer. Kadence's
   inner wrap carries it, and it is correct on any page that ends light. */
.sna-cta--dark ~ *,
body:has(.sna-cta--dark) #inner-wrap {
  margin-bottom: 0;
}

body:has(.sna-cta--dark) .site-main,
body:has(.sna-cta--dark) .content-container {
  padding-bottom: 0;
  margin-bottom: 0;
}

/* ---------------------------------------------------------------------------
 * Footer: rescope Kadence's palette instead of fighting its selectors
 *
 * Kadence prints inline CSS for footer links at
 * `#colophon .footer-navigation .footer-menu-container > ul > li > a`, which is
 * an id plus two classes plus three elements. Out-specifying that from a
 * stylesheet is a losing game, and the next Kadence element would need the same
 * treatment again.
 *
 * The variables it reads are the same ones the bridge in tokens.css already
 * maps. So the fix is to rescope those variables inside the footer, which is
 * now dark: every Kadence footer element follows automatically, including ones
 * not styled here yet.
 *
 * Measured on plum: 0.78 ivory is 10.9:1, 0.6 is 6.8:1. Both clear AA.
 * ------------------------------------------------------------------------ */

#colophon {
  --global-palette3: var(--cream);
  --global-palette4: rgba(251, 249, 246, 0.88);
  --global-palette5: rgba(251, 249, 246, 0.78);
  --global-palette6: rgba(251, 249, 246, 0.6);
  --global-palette-highlight: var(--brand-gold-200);
}

/* The last 24px. It is WordPress's global block gap, applied to #colophon as a
   sibling inside .wp-site-blocks, not any padding on the content chain, which
   is why zeroing the ancestors did not move it. */
body:has(.sna-cta--dark) #colophon {
  margin-block-start: 0;
  margin-top: 0;
}

/* Drift. Three different durations and three different delays, all coprime
   enough that the cards never come back into phase, because three cards
   bobbing in unison reads as a carousel rather than as things floating. */
@media (prefers-reduced-motion: no-preference) {

  }

/* ---------------------------------------------------------------------------
 * 44.2 The shape behind the portrait
 *
 * The flat purple oval is gone. This is the owner's own artwork, recoloured
 * into the palette and feathered by scripts/build-blob.py: see that file for
 * why the source could not simply be dropped in (it had no transparency, it
 * was cyan-blue, and it carried stock-vector satellites).
 *
 * screen, not soft-light. Both were tried. soft-light on a #1B0B2A ground
 * barely registers, because soft-light preserves the base luminance and the
 * base here is nearly black, so the shape reads as a smudge. screen lifts the
 * plum toward the artwork's purple and keeps it rich, which is what the brief
 * asked to optimise for.
 * ------------------------------------------------------------------------ */

.sna-hero__media::before {
  /* Sized off HER, at 1.4x the portrait's WIDTH, with aspect-ratio carrying
     the height so the artwork is never stretched at any breakpoint.

     The brief asked for 1.3 to 1.5x the portrait's HEIGHT. That ratio cannot
     be met with this asset, and the reason is geometric rather than a matter
     of taste. The artwork is square; she is 413 wide by 722 tall. A shape at
     1.35x her height is therefore also 975 WIDE, which is 2.4x her width, and
     there is only about 600px of room beside her before the reading column
     starts. Built to the letter it covered the headline by 435px, measured.
     A left-hand mask was tried next and is worse: pushed far enough to clear
     the headline, it also erased every part of the shape that was visible on
     her near side, so the blob only appeared from behind her and stopped
     framing her at all.

     Sizing to her width keeps the intent, a shape that frames her and reads
     as light behind her, and lands at 578px: 1.4x her width, clearing the
     headline by 26px with no mask and no cropping. */
  left: 50%;
  right: auto;
  top: 6%;
  width: 140%;
  height: auto;
  aspect-ratio: 464 / 461;
  transform: translateX(-46%);
  border-radius: 0;
  opacity: 0.8;
  background-image: url("../img/hero-blob.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  mix-blend-mode: screen;

  /* No CSS blur. The rim is feathered in the asset over its outer ~8%, which
     is the point: a filter blurs the body as well as the edge, and blurring
     the body is exactly what turned the previous version into a smudge. */
  filter: none;
  -webkit-mask-image: none;
          mask-image: none;
}

/* The gold arc that used to live here as a radial gradient is gone. It is now
   drawn along the silhouette itself in build-blob.py, where it can follow the
   actual outline instead of approximating it with an ellipse, and keeping both
   would have lit the shape from two directions at once. */
.sna-hero__media::after {
  content: none;
}

@media (prefers-reduced-motion: no-preference) {
  /* The blob breathes on the same clock as the bloom, so the hero has one
     light source rather than two things moving independently. */
  .sna-hero__media::before {
    animation: sna-bloom-drift 60s ease-in-out infinite alternate;
  }
}

/* ---------------------------------------------------------------------------
 * 44.3 The grid, edge to edge
 *
 * The grid belongs to the section, never to the inner container, and the
 * section is sized with 100% rather than 100vw. 100vw includes the scrollbar
 * gutter, so on any desktop browser that reserves one it is wider than the
 * viewport and produces a horizontal scrollbar, which then makes 100vw wider
 * again.
 * ------------------------------------------------------------------------ */

/*
 * The grid was not stopping short because of how it was drawn. The SECTION is
 * 1040px wide inside a 1425px page: the texture was reaching both of its own
 * edges, and both of those edges are 193px in from the viewport. Kadence caps
 * .site-container at 1152px with auto margins, and .entry-content-wrap and
 * .site-container each add padding on top of that.
 *
 * The obvious fix is to break the section out with negative margins. That is
 * wrong here, and this file already says so at the top: section 1 records that
 * these bands were alignfull once, and that it put their text 56px off the
 * line every other section sits on. Breaking out reproduces that exactly,
 * because Kadence's content box is not symmetric, so no centred inner wrapper
 * can ever land back on it. It was tried again during this pass and produced
 * the same 56px, measured.
 *
 * So the section stays in flow and its children stay aligned by construction,
 * and only the BACKGROUND goes wide, on a pseudo-element inset by -100vmax
 * that the section's own clip-path trims back vertically. That is the same
 * idiom as the plum bleed above, and it is why the dark already reached the
 * edges while the grid did not: the colour was on the shadow, the grid was on
 * the box.
 */
.sna-hero {
  background-color: var(--ink-deep);
  background-image: none;
}

/* Grid and fade on one layer, stacked. The fade sits above the grid in the
   background list so it dissolves it before the section boundary rather than
   cutting it off in a line. A mask is not usable here: masking the section
   would mask its children, and the headline is a child. */
.sna-hero::before {
  content: "";
  position: absolute;
  inset: 0 -100vmax;
  z-index: -3;
  pointer-events: none;
  opacity: 1;
  background-image:
    linear-gradient(
      to bottom,
      rgba(27, 11, 42, 0) 52%,
      rgba(27, 11, 42, 0.72) 82%,
      var(--ink-deep) 97%
    ),
    linear-gradient(to right, rgba(251, 249, 246, 0.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(251, 249, 246, 0.05) 1px, transparent 1px);
  background-size: 100% 100%, 34px 34px, 34px 34px;
  background-position: center top;
  background-repeat: no-repeat, repeat, repeat;
  -webkit-mask-image: none;
          mask-image: none;
}

/* ---------------------------------------------------------------------------
 * 44.4 Breathing room
 * ------------------------------------------------------------------------ */

.sna-hero {
  padding-block: clamp(6rem, 12vw, 10rem);
}

/* The fixed header overlays the hero, so its measured height is added to the
   top padding rather than replacing it. --sna-header-h is published by
   header.js; the fallback covers the first paint before that runs. */
.sna-leads-with-hero .sna-hero {
  padding-top: calc(clamp(6rem, 12vw, 10rem) + var(--sna-header-h, 5rem));
}

@media (min-width: 60em) {
  .sna-hero__top {
    gap: clamp(3rem, 6vw, 7rem);
  }
}

/* Stacked, below 60em. The portrait gets its own clear zone so the copy never
   runs into it.
 *
 * row-gap, not a margin on the portrait. The margin was written first and
 * measured 0: .sna-hero__media is a grid item, and Kadence's content stylesheet
 * carries a long .single-content selector list that resets margins at a higher
 * specificity than a single class. Raising specificity would win the fight,
 * but the gap is the correct mechanism for spacing grid tracks and no margin
 * reset can reach it. */
@media (max-width: 59.9375em) {
  .sna-hero__top {
    row-gap: 3.5rem;
  }
}

/* Stacked.
 *
 * "Offset toward the outer edge" is a two-column idea: once the portrait is
 * centred under the copy there is no outer edge to move toward, and the same
 * offset made the blob read as a separate purple object sitting beside her
 * instead of light behind her. So it centres on her here, and shrinks a little
 * so it never reaches the section edges and is never cropped. */
@media (max-width: 59.9375em) {
  .sna-hero__media::before {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: 124%;
    top: 10%;
  }
}

@media (max-width: 30em) {
  .sna-hero {
    padding-inline: 1.5rem;
  }

  .sna-hero__portrait {
    max-width: 82%;
    margin-inline: auto;
  }
}

/* ---------------------------------------------------------------------------
 * 44.5 Rebalance after the plaques
 *
 * With the three cards gone the right half lost most of its visual weight and
 * the composition tipped left. The brief's own instruction applies: fix it
 * with the scale and position of the portrait and the blob, never by adding
 * an element back.
 *
 * So the media column takes back roughly the width the cards used to occupy
 * and the portrait grows into it. The copy column still holds the longer
 * measure, because the headline is still the first thing the eye should land
 * on and a portrait that outweighs it would be the wrong trade.
 * ------------------------------------------------------------------------ */

@media (min-width: 60em) {
  .sna-hero__top {
    grid-template-columns: minmax(0, 1.06fr) minmax(19rem, 0.94fr);
  }

  .sna-hero__media {
    max-width: 34rem;
  }
}

/* ===========================================================================
 * 45. POLISH: MEASURE, TARGETS, FOCUS
 *
 * Pass 2 (line length), pass 3 (tap targets) and pass 7 (focus) collected in
 * one place because they are all page-wide rules rather than section styling.
 * ======================================================================== */

/* ---------------------------------------------------------------------------
 * 45.1 Measure
 *
 * Nothing here. The cap already exists and works: components.css applies
 * var(--measure-local, var(--measure)) to every paragraph, list item and
 * blockquote in the content, with per-component overrides.
 *
 * A duplicate set of rules was added here first and was the wrong fix. The
 * paragraphs were not uncapped; they were capped at the wrong number, because
 * the redesign token block redeclared --measure at 65ch on top of the real
 * definition. Correcting the token fixed all fifteen at once. See tokens.css.
 * ------------------------------------------------------------------------ */

/* ---------------------------------------------------------------------------
 * 45.2 Tap targets
 *
 * Thirteen targets measured under 44px: navigation at 34, footer links at 35,
 * and a standalone "More about how I work" link at 20.
 *
 * WCAG 2.2 AA (2.5.8) only asks for 24px, and all but one of these already
 * passed it. 44px is the 2.5.5 AAA figure and the brief's figure, and it is
 * the right one for a site whose audience is mostly on phones.
 *
 * Padding, never height. A fixed height would stop these centring their text
 * when the label wraps, which is exactly what happens to "Coaching Disclaimer"
 * in the footer at narrow widths.
 * ------------------------------------------------------------------------ */

#masthead .menu > li > a,
#colophon .menu > li > a,
#colophon .site-footer-section a,
.sna-card__link a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/*
 * .sna-index__link is deliberately NOT in the list above.
 *
 * It was, and it broke the section. That element is a GRID with named areas
 * ("name cue" / "desc cue"), and display: inline-flex overrode the grid
 * entirely: the areas were ignored, name, description and cue collapsed into
 * one flex row, and because an inline-flex box shrinks to its content the
 * whole list rendered 549px wide inside a 965px section.
 *
 * The visible result was seven rows whose descriptions each started at a
 * different x, from 401 to 504, with the longest name squeezing its
 * description to 239px. It read as clumped because it was.
 *
 * It never needed the rule: the row already clears 44px from its own vertical
 * padding, several times over.
 */

/* The standalone "read more" links are their own paragraph, so they are not
   the inline-in-a-sentence case that 2.5.8 exempts. */
.sna-card__link a {
  padding-block: 0.75rem;
}

/* Clearance between adjacent targets, so a 44px box does not simply collide
   with its neighbour. */
#colophon .menu {
  gap: 0.5rem 1.25rem;
}

/* ---------------------------------------------------------------------------
 * 45.3 Focus, in gold, at 3:1 on every ground
 *
 * The ring was --brand-purple everywhere. On the dark bands that measured
 * 1.88:1 against #1B0B2A, which fails WCAG 2.2 AA 1.4.11 (3:1 for a focus
 * indicator). It was only ever correct by accident on light grounds.
 *
 * The brief asks for the gold token. Plain --gold is 2.30:1 on cream and fails
 * the same rule from the other side, so "gold" here means the two golds the
 * token system already carries for the two grounds: --gold-text on light
 * (5.09:1) and --brand-gold-200 on dark (7.70:1).
 *
 * A token rather than a selector fight, so any future dark section inherits
 * the correct ring by declaring itself dark, not by being added to a list.
 * ------------------------------------------------------------------------ */

:root {
  --focus-ring: var(--gold-text);
}

.sna-band-dark,
.sna-cta--dark,
.sna-hero,
.sna-offer--featured,
.is-style-sna-surface-plum,
.is-surface-plum,
.is-surface-black,
#colophon,
.sna-header--on-dark {
  --focus-ring: var(--brand-gold-200);
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 2px;
}

/* These three previously hard-coded their own ring colour and so would have
   ignored the token. */
.sna-index__link:focus-visible,
.sna-faq__item summary:focus-visible,
#colophon .menu > li > a:focus-visible,
#colophon .site-footer-section a:focus-visible {
  outline-color: var(--focus-ring);
}

/* ---------------------------------------------------------------------------
 * 45.4 The header scheme swap
 *
 * Paired with the 'sna-header--swapping' class in assets/js/header.js. See
 * that file for why the swap must be instant rather than eased: the two
 * schemes are inverses, so any crossfade between them passes through a state
 * where the text and its ground meet. Measured at 1.11:1, below AA for 120ms,
 * on every crossing of the hero boundary.
 *
 * Scoped to the header and to one frame, so hover easing is untouched.
 * ------------------------------------------------------------------------ */

.sna-header--swapping,
.sna-header--swapping *,
.sna-header--swapping *::before,
.sna-header--swapping *::after {
  transition: none !important;
}

/* ---------------------------------------------------------------------------
 * 45.5 The brand link
 *
 * Last target under 44px. It wraps the logo image, so the height has to come
 * from the link box rather than from the artwork, which is sized separately.
 * ------------------------------------------------------------------------ */

#masthead .site-branding a,
#masthead .brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* ---------------------------------------------------------------------------
 * 45.6 Two measures the corrected token could not reach
 *
 * The offer descriptions carry no --measure-local and sit in a wide single
 * column, so they inherited the container rather than the measure and ran to
 * 85 characters. The problem aside runs the other way: at 44ch inside an
 * already narrow sticky column it measured 40, which is too tight to read
 * comfortably, so it is allowed to use the column it has.
 * ------------------------------------------------------------------------ */

.sna-offer p {
  /* 34ch. These render larger than body copy, so the same ch buys fewer
     characters: 46ch measured 85. Set from the measured result, not assumed. */
  --measure-local: 34ch;
}

.sna-problem__aside .sna-lede {
  --measure-local: none;
}

/* The problem aside was measuring 40 characters: the sticky rail is 369px and
   the lede sits at a display size inside it. Widening the rail one step is the
   right fix rather than shrinking the type, because the lede is the second
   thing read in that section and should not be the smallest thing in it. */
@media (min-width: 62em) {
  .sna-problem__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  }
}

/* ---------------------------------------------------------------------------
 * 45.7 Mobile gutters: one layer, not three
 *
 * At 375px the reading column measured 263px. That is 56px of gutter per side,
 * 30 percent of the screen, against a brief that asks for 1.5rem.
 *
 * It was not one bad value. Three layers each add their own inset and they
 * stack: Kadence's .site-container (24px), .entry-content-wrap (24px), and the
 * section itself (24px). Each is defensible alone, and together they eat a
 * third of a phone.
 *
 * The section keeps the gutter, because it is the element that also owns the
 * full-bleed backgrounds and therefore has to know where the edge is. The two
 * wrappers give theirs up below the tablet breakpoint only, so nothing about
 * the desktop composition moves.
 * ------------------------------------------------------------------------ */

/* ONE layer, not three at once. Zeroing all of them and Kadence's
   compensating -16px article margin together overshot to 8px gutters and left
   the content wider than its own wrapper. Only the middle wrapper gives up its
   padding, which returns 48px to the reading column and leaves Kadence's own
   container arithmetic untouched. */
@media (max-width: 47.9375em) {
  .entry-content-wrap {
    padding-inline: 0;
  }
}

/* ===========================================================================
 * 46. HERO: PLAIN FIELD, FRAMED PHOTOGRAPH
 *
 * Two removals and one addition, on the owner's instruction.
 *
 * REMOVED: the blob behind the portrait, and the gradient spotlight over the
 * headline. Both are switched off here rather than deleted upstream, because
 * the bloom is a shared utility used by other dark sections and the blob's
 * geometry is worth keeping on record after three attempts at it. Nothing else
 * on the page reads these rules.
 *
 * The gold rim arc goes with the blob: it is drawn into the asset, so turning
 * the layer off removes it too, and there is no separate rule to find.
 *
 * ADDED: a frame, because the new photograph is not a cut-out. Every previous
 * hero image was a transparent PNG, which is why the portrait deliberately had
 * no frame: it sat on the dark field and the field framed it. This one carries
 * its own background, and an unframed rectangle of a lit interior sitting on
 * the plum reads as a mistake rather than as a photograph.
 * ======================================================================== */

/* The blob. */
.sna-hero__media::before {
  content: none;
}

/* The spotlight over the headline. The hero keeps its grid and its grain; what
   goes is only the radial wash that sat behind the first two lines. */
.sna-hero::after {
  content: none;
  animation: none;
}

/* ---------------------------------------------------------------------------
 * The frame
 *
 * Restrained on purpose: a radius, a gold hairline, and one soft shadow for
 * depth. The photograph is warm and busy enough that anything more would
 * compete with it, and the section has just had two decorations removed.
 * ------------------------------------------------------------------------ */

.sna-hero__portrait--framed {
  border-radius: 14px;
  overflow: hidden;
  box-shadow:
    inset 0 0 0 1px rgba(232, 206, 122, 0.22),
    0 26px 60px -24px rgba(8, 3, 14, 0.62);
}

.sna-hero__portrait--framed img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: inherit;

  /* The old rule cropped a cut-out to a fixed portrait ratio, which on a real
     photograph would cut her off. The image keeps its own aspect. */
  aspect-ratio: auto;
  object-fit: contain;
}

/* ---------------------------------------------------------------------------
 * The old size caps were tuned for a floating cut-out
 *
 * A transparent figure can be small and still read, because it has no edges
 * competing with anything. A framed photograph cannot: at 195px inside a 375px
 * screen it read as a thumbnail dropped into the fold rather than as the
 * subject of it.
 *
 * Scoped to the framed variant, so the caps stay correct if a cut-out is ever
 * used here again.
 * ------------------------------------------------------------------------ */

@media (max-width: 59.9375em) {
  .sna-hero__media:has(.sna-hero__portrait--framed) {
    max-width: 26rem;
    margin-inline: auto;
  }

  .sna-hero__portrait--framed {
    max-width: 100%;
  }
}

/* :has() is well supported now, but a browser without it would silently keep
   the 15rem cut-out cap, so the same intent is restated unconditionally for
   the element that actually carries the class. */
@media (max-width: 30em) {
  .sna-hero__portrait--framed {
    max-width: 100%;
    margin-inline: 0;
  }
}

/* ===========================================================================
 * 47. THE SEVEN DOMAINS INDEX: BREATHING ROOM
 *
 * The section read as squeezed for two separate reasons, and only one of them
 * was spacing.
 *
 * The first was a broken layout, fixed in section 45.2: an inline-flex
 * override had collapsed the row grid, so the list sat at 549px inside a 965px
 * section with its descriptions starting at seven different positions.
 *
 * The second is genuine tightness, which this section addresses. With the grid
 * restored, the row is name over description with the cue at the right, so
 * name and description share one left edge and the only thing left to tune is
 * air and type.
 * ======================================================================== */

.sna-index {
  /* The rule above the first row wants the same space below the intro that the
     rows give each other, or the list reads as attached to the paragraph. */
  margin-top: clamp(2.5rem, 4vw, 4rem);
}

.sna-index__link {
  /* Restated so the grid cannot be lost to a display override again. */
  display: grid;

  /* The row is the unit of rhythm here. 24px top and bottom was under half a
     line of the name's own leading, which is what made seven rows read as one
     block with lines through it. */
  padding-block: clamp(1.75rem, 2.6vw, 2.5rem);

  /* No inline padding. The rows have no visible box, only a hairline, so any
     inset here puts the domain names on a different axis to the section head
     directly above them, which is the inconsistency section 49 exists to fix.
     The hover nudge still comes from padding-left, so it starts at 0 and moves
     in rather than moving from one indent to another. */
  padding-inline: 0;

  /* Name and description are one pair, so they sit closer to each other than
     the pair sits to its neighbours: related things close, unrelated far. */
  row-gap: 0.55rem;
  column-gap: clamp(1.5rem, 3vw, 3rem);

  /* Top, not centre. Once the description can run to two lines on a narrow
     column, centring makes the name drift down away from its own hairline. */
  align-items: start;
}

/* The cue is on both rows of the grid, so it needs its own centring now that
   the row no longer centres everything. */
.sna-index__cue {
  align-self: center;
}

.sna-index__name {
  /* Was clamping to 1.85rem, which at 29.6px sat almost on top of the section
     heading and left nothing between the two levels. Pulled down a step so the
     h2 above it stays clearly one level higher. */
  font-size: clamp(1.25rem, 1.05rem + 0.6vw, 1.6rem);
  line-height: 1.2;
  margin-bottom: 0;
}

.sna-index__desc {
  /* 14.4px was small enough to read as a caption rather than as the sentence
     that explains the domain. Body size, and a longer line now that it has the
     full row width rather than whatever the name left over. */
  font-size: clamp(0.95rem, 0.92rem + 0.15vw, 1.0625rem);
  line-height: 1.6;
  max-width: 62ch;
}

/* ---------------------------------------------------------------------------
 * Narrow screens
 *
 * The cue drops out below the tablet breakpoint. At that width it costs 40px
 * of the row plus its gap, and the whole row is already the link, so it is
 * decoration that charges rent. The rows keep their air instead.
 * ------------------------------------------------------------------------ */

@media (max-width: 47.9375em) {
  .sna-index__link {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "name"
      "desc";
    padding-block: 1.5rem;
    row-gap: 0.45rem;
  }

  .sna-index__cue {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
 * The rows are not prose
 *
 * components.css caps every p, li and blockquote in the content at the reading
 * measure, which is right for reading and wrong for a seven-row index: it held
 * the rows to 46ch, 549px inside a 965px list, and the constrained layout's
 * auto margins then centred them. The hairlines came out short and floating in
 * the middle of the section.
 *
 * --measure-local, not max-width. A custom property set on the element always
 * wins, which is the escape hatch components.css documents for exactly this,
 * and it avoids an escalating specificity fight with that rule's :not() chain.
 * (.sna-index__row already declared max-width: none and lost, 0,1,0 against
 * 0,2,1.)
 * ------------------------------------------------------------------------ */

.sna-index__row {
  --measure-local: none;
  margin-inline: 0;
}

/* Kadence puts 36px of padding-inline-start on content lists for the markers.
   Section 38 already declared padding: 0 on .sna-index and lost to it, which
   left the rows and their hairlines inset 36px from the list they belong to.
   Marker padding is meaningless here: list-style is none. */
.entry-content ul.sna-index,
ul.sna-index {
  padding-inline: 0;
  margin-inline: 0;
}

/* 58ch, not 62ch. At 62 the longest description measured 72 characters per
   line, just past the 70 the rest of the page holds to. */
.sna-index__desc {
  max-width: 58ch;
}

/* ===========================================================================
 * 48. FOOTER: THE BOTTOM ROW ON A PHONE
 *
 * The footer bottom row is configured as two columns, copyright on the left and
 * the navigation on the right, which is correct on a desktop and unusable on a
 * phone. At 390px the two columns split a 342px row, so the navigation got
 * 138px for nine items around 150px wide each. Every item took its own line and
 * the menu rendered 408px tall as a right-aligned column, clipped against the
 * copyright.
 *
 * Two columns is the cause, not the item count. Reducing the menu would have
 * hidden it rather than fixed it, and the next item added would bring it back.
 * ======================================================================== */

@media (max-width: 47.9375em) {
  /* One column, stacked, each part full width. */
  .site-bottom-footer-inner-wrap {
    flex-direction: column;
    align-items: center;
    gap: var(--space-m);
  }

  .site-bottom-footer-inner-wrap > .site-footer-section {
    width: 100%;
    max-width: none;
    justify-content: center;
    text-align: center;

    /* Belt and braces. The auto margins are now scoped to the desktop, which
       is the real fix; this only guarantees the result if another rule ever
       reintroduces them. */
    margin-inline: 0;
  }

  /* The navigation goes above the copyright: links are what a reader might
     want down here, and a copyright line is the last thing on a page for a
     reason. Kadence's markup order puts the copyright first. */
  .site-bottom-footer-inner-wrap > .site-footer-section:has(.footer-navigation) {
    order: -1;
  }

  #colophon .footer-navigation,
  #colophon .footer-menu-container {
    width: 100%;
  }

  /* Now that it has the full width, the menu can wrap as a menu rather than
     stack as a list. */
  #colophon .menu {
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.25rem 1.5rem;
  }
}

/* ===========================================================================
 * 49. SECTION HEADS ALIGN WITH THEIR OWN CONTENT
 *
 * Section 29 centred every section's eyebrow, heading and standfirst. That was
 * right when those sections held centred card grids, and it stopped being right
 * once the content underneath became left-aligned rows: a centred head over a
 * left-aligned list gives the section two different left edges and reads as two
 * unrelated blocks stacked on each other.
 *
 * So from the tablet breakpoint up the head sits on the same axis as the
 * content it introduces. Below it, where the rows themselves centre and the
 * measure is too narrow for an axis to be legible anyway, it stays centred.
 *
 * THE CLOSING BAND IS DELIBERATELY EXCLUDED. .sna-cta is a centred composition
 * from top to bottom, eyebrow, heading, standfirst and button on one vertical
 * axis, and it has no left-aligned content to disagree with. It is the only
 * section on the page where centred is the design rather than a leftover, so
 * left-aligning it would break the thing this rule exists to protect.
 *
 * Page and domain headers (.sna-page-head, .sna-domain-head) are also untouched
 * for the same reason: a page opening is a different device to a section head,
 * and both are centred compositions in their own right.
 * ======================================================================== */

@media (min-width: 48em) {
  .sna-section:not(.sna-cta) > .sna-eyebrow,
  .sna-section:not(.sna-cta) > h2,
  .entry-content .sna-section:not(.sna-cta) > h2 + p,
  .entry-content .sna-section:not(.sna-cta) > h2 + .sna-lede {
    text-align: left;
  }

  /* The box, not just the text.
   *
   * Each of these carries a max-width, and WordPress's constrained layout gives
   * any max-width child automatic margins on both sides. So text-align alone
   * left-aligns the words inside a box that is still centred in the section,
   * which moves the text about half the difference and lands it on no axis at
   * all. !important matches the rule in section 29 that this overrides, and is
   * there for the same reason: the constrained-layout margins are otherwise
   * unbeatable without it. */
  .entry-content .sna-section:not(.sna-cta) > .sna-eyebrow,
  .entry-content .sna-section:not(.sna-cta) > h2,
  .entry-content .sna-section:not(.sna-cta) > h2 + p,
  .entry-content .sna-section:not(.sna-cta) > h2 + .sna-lede {
    margin-inline: 0 auto !important;
  }
}

/* The eyebrow is a centred flex row, dash / label / dash, so left-aligning its
   BOX left the label still centred inside a 529px box and 46px off the axis
   everything else had just landed on.
   
   Same treatment the problem aside already uses for its left-aligned eyebrow:
   pack to the start and drop the leading dash. A rule running rightwards out of
   a label reads as a chapter mark; a rule sitting to the left of one at the
   section's edge reads as a stray line. */
@media (min-width: 48em) {
  .entry-content .sna-section:not(.sna-cta) > .sna-eyebrow {
    justify-content: flex-start;
  }

  .sna-section:not(.sna-cta) > .sna-eyebrow::before {
    display: none;
  }
}

/* ===========================================================================
 * 50. HERO PROPORTIONS
 *
 * Retuned against the reference the owner supplied. Scaling that screenshot so
 * its headline is the 35px asked for puts its whole hero at about 464px, which
 * is 0.32 of the viewport width. Ours measured 996px, or 0.69, so it was more
 * than twice as tall as the thing it is being compared to.
 *
 * The height came from three places at once, and only fixing all three moves
 * it: 393px of vertical padding, a 62px headline running to four lines, and a
 * portrait whose own height set the floor for the row.
 * ======================================================================== */

/* ---------------------------------------------------------------------------
 * 50.1 The headline
 *
 * 35px at desktop, as asked. The old clamp topped out at 62px, which is a
 * display size: it pushed the headline to four lines in a 466px column and
 * those four lines were 277px of the fold on their own.
 *
 * The floor drops to 28px rather than staying at 36px, because a 62px maximum
 * with a 36px minimum was a scale built for a much taller hero.
 * ------------------------------------------------------------------------ */

.sna-hero__title {
  font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.1875rem);
  line-height: 1.16;
  letter-spacing: -0.018em;
}

/* ---------------------------------------------------------------------------
 * 50.2 The fold
 *
 * Padding down from 233/160 to roughly 100/48 plus the measured header. The
 * header is still added rather than assumed, because it overlays the hero and
 * its height changes with the breakpoint and the stuck state.
 * ------------------------------------------------------------------------ */

.sna-hero {
  padding-block: clamp(2rem, 3.4vw, 3rem);
}

.sna-leads-with-hero .sna-hero {
  padding-top: calc(var(--sna-header-h, 4rem) + clamp(1.5rem, 2.8vw, 2.5rem));
}

/* ---------------------------------------------------------------------------
 * 50.3 The columns
 *
 * The copy column takes the width the owner asked for. It was 466px against
 * the media column's 413, which is close to an even split and reads as two
 * equal halves rather than as a subject and its portrait.
 * ------------------------------------------------------------------------ */

@media (min-width: 60em) {
  .sna-hero__top {
    grid-template-columns: minmax(0, 1.32fr) minmax(15rem, 0.68fr);
    gap: clamp(2.5rem, 4.5vw, 5rem);
  }
}

/* ---------------------------------------------------------------------------
 * 50.4 The portrait
 *
 * Capped by HEIGHT, not width. The photograph is 0.917 wide to tall, so a
 * width cap lets its height float and the row height floats with it: at 413px
 * wide it was 451px tall, and it, not the copy, was setting the fold.
 *
 * Capping the height and letting aspect-ratio resolve the width inverts that,
 * so the fold is set by the thing being read.
 * ------------------------------------------------------------------------ */

@media (min-width: 60em) {
  .sna-hero__media {
    max-width: none;
  }

  .sna-hero__portrait--framed {
    max-height: 22rem;
    width: auto;
    margin-inline: 0 auto;
  }

  .sna-hero__portrait--framed img {
    max-height: 22rem;
    width: auto;
  }
}

/* ---------------------------------------------------------------------------
 * 50.5 The header bar
 *
 * 79px down to about 62px. The floor is the 44px tap target plus the bar's own
 * padding, so this is close to as tight as it can go without giving that back.
 * ------------------------------------------------------------------------ */

#masthead .site-main-header-wrap .site-header-row-container-inner,
#masthead .site-header-row {
  padding-block: 0;
}

#masthead .site-main-header-inner-wrap {
  min-height: 0;
}

#masthead .site-header-item {
  padding-block: 0.4rem;
}

/* ---------------------------------------------------------------------------
 * 50.6 The last 60px
 *
 * With the headline at 35px the portrait was no longer the tallest thing in the
 * row, the copy column was: 362px of content carrying a 32px margin-bottom
 * that WordPress applies to block children. On a grid item that margin does
 * nothing except add to the track, and because the copy column is the taller of
 * the two it was setting the fold. Measured: row 394px against a 362px column.
 *
 * The inner gap comes down a step at the same time. It was tuned for a 62px
 * headline, where a large gap keeps a display-size stack from crowding; at 35px
 * the same gap reads as the three parts drifting apart.
 * ------------------------------------------------------------------------ */

.sna-hero__top > .sna-hero__inner,
.sna-hero__top > .sna-hero__media {
  margin-block: 0;
}

.sna-hero__inner {
  gap: clamp(0.85rem, 1.4vw, 1.25rem);
}

.sna-hero__actions {
  margin-top: 0.35rem;
}

/* The hero lede was wrapping to four lines inside a 46ch cap while its column
   is 594px wide, so it was leaving ~130px of column unused and buying a fourth
   line with it. Letting it use the column it has puts it on three lines at
   about 67 characters, which is still inside the 45 to 70 the rest of the page
   holds to, and takes 30px off the fold. The copy is unchanged. */
@media (min-width: 60em) {
  .entry-content .sna-hero__lede {
    --measure-local: none;
    max-width: 54ch;
  }
}

/* The height cap has to apply to the stacked layout too, not only to the two
   column one. Below 60em the portrait was falling back to its width cap and
   running to 454px tall at 768, which put the fold at 962px on a tablet: the
   same "portrait sets the height" problem 50.4 fixed on desktop, just at a
   different breakpoint. */
@media (max-width: 59.9375em) {
  .sna-hero__portrait--framed,
  .sna-hero__portrait--framed img {
    max-height: 22rem;
    width: auto;
  }

  .sna-hero__media:has(.sna-hero__portrait--framed) {
    max-width: none;
  }
}

/* The frame must hug the photograph.
 *
 * Capping the IMAGE's height shrinks the image but not the figure around it, so
 * the figure kept its full column width and the gold hairline and shadow were
 * drawn around 263px of empty space to the right of her. Measured at 768: frame
 * 586px wide, image 323px.
 *
 * fit-content on the figure, so the box is derived from the image at every
 * width instead of being told a number that has to be kept in sync with the
 * height cap. */
.sna-hero__portrait--framed {
  width: -moz-fit-content;
  width: fit-content;
}

/* The earlier mobile rule set margin-inline: 0, which now left-aligns a
   fit-content box under centred copy. Centre it in the stacked layout. */
@media (max-width: 59.9375em) {
  .sna-hero__portrait--framed {
    margin-inline: auto;
  }
}

/* ---------------------------------------------------------------------------
 * 50.7 Breathing room under the bar
 *
 * The reduction in 50.2 went too far. Measured from the bar's bottom edge to
 * the headline's first painted glyph: 19px. At a 35px headline that is under
 * two thirds of a line, so the bar and the headline read as one stuck block.
 *
 * Measured from the glyph, not the element box: the h1 box starts 3px higher
 * than the ink does, and it is the ink the eye judges.
 * ------------------------------------------------------------------------ */

.sna-hero {
  padding-block: clamp(3rem, 4.5vw, 4.5rem);
}

.sna-leads-with-hero .sna-hero {
  padding-top: calc(var(--sna-header-h, 4rem) + clamp(4.5rem, 6.5vw, 6rem));
}

/* ===========================================================================
 * 51. FOOTER WATERMARK
 *
 * A large perforated wordmark low in the footer, in the manner of the reference
 * the owner supplied, plus the dot-matrix field it sits in.
 *
 * The dots are not an image. The wordmark is real text filled with a repeating
 * radial gradient and clipped to the glyphs with background-clip: text, so it
 * is resolution independent, costs no request, and is edited by changing a
 * string rather than by re-exporting a file.
 *
 * It sits BELOW the content rather than behind it. Behind would put a texture
 * under the footer links, and those measured 10.91:1 in the phase 3 audit
 * precisely because nothing sits under them. Keeping it below the content means
 * the watermark cannot move any text's contrast at all.
 * ======================================================================== */

body #colophon {
  /* The wordmark is deliberately wider than the viewport at small sizes, so it
     is cropped rather than scaled down into illegibility. Safe here: the
     footer's background is a plain colour, not one of the 100vmax bleeds, so
     there is nothing that needs to escape the box. */
  overflow: hidden;
}

/*
 * The room for the wordmark belongs to the WRAP, not to #colophon.
 *
 * Put on #colophon, the padding sits outside .site-footer-wrap, so the wrap's
 * box still ended where the content ended. The wordmark is positioned against
 * the wrap, so `bottom` resolved to the content's bottom edge and it rendered
 * straight across the footer links, which is the one thing this was written to
 * avoid. Owning the space and the positioning context in the same element is
 * what keeps them in step.
 */
.site-footer-wrap {
  position: relative;
  /* Room for the wordmark AND for the space under it. Sized from the parts
     rather than guessed: about 40px of breathing space, the 177px line box, and
     roughly 40px of gap up to the copyright line. */
  padding-bottom: clamp(8.5rem, 18vw, 17rem);
}

/*
 * The wordmark.
 *
 * `content: "SNA Digital" / ""` supplies an empty alternative text, so assistive
 * technology skips it. It is decoration and the real name is already in the
 * copyright line directly above; announcing it twice would be noise. A browser
 * without the alt-text syntax drops the whole declaration and simply shows no
 * watermark, which is the right way to fail.
 */
.site-footer-wrap::after {
  content: "SNA Digital" / "";
  position: absolute;
  left: 50%;
  /* Positive, and clear of the descender.
     The wordmark hung 24px BELOW the wrap so it would read as a printed mark
     running past the trim. It did not: measured on the canvas, the ink of "g"
     descends 33.7px past the baseline and the ink overflows its own line box by
     8px, so all of that tail was inside the 24px that `overflow: hidden` was
     cutting off. "Digital" simply looked broken rather than cropped on purpose.
     It now sits fully inside, with space under it. */
  bottom: clamp(1.75rem, 3vw, 3rem);
  transform: translateX(-50%);
  z-index: 0;
  pointer-events: none;
  -webkit-user-select: none;
          user-select: none;
  white-space: nowrap;

  font-family: var(--font-heading);
  font-weight: 700;
  font-size: clamp(3.25rem, 15.5vw, 13rem);
  line-height: 0.85;
  letter-spacing: -0.03em;

  /* The perforation. A 1px dot on a 5px pitch reads as a dot-matrix print at
     any size, because the pitch is in screen pixels rather than in ems and so
     does not scale with the type. */
  background-image: radial-gradient(
    circle at center,
    rgba(251, 249, 246, 0.92) 0.9px,
    transparent 1.4px
  );
  background-size: 5px 5px;
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  opacity: 0.17;
}

/* The field the wordmark sits in: the same 4px ordered dot grid the closing
   band already uses, so the two dark sections are made of one material.
   Masked to the lower half so it never reaches the links. */
.site-footer-wrap::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Crect width='1' height='1' fill='%23FBF9F6' fill-opacity='0.55'/%3E%3Crect x='2' y='2' width='1' height='1' fill='%23FBF9F6' fill-opacity='0.55'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(to bottom, transparent 22%, rgba(0, 0, 0, 0.55) 60%, rgba(0, 0, 0, 0.9) 100%);
          mask-image: linear-gradient(to bottom, transparent 22%, rgba(0, 0, 0, 0.55) 60%, rgba(0, 0, 0, 0.9) 100%);
}

/* No background-clip: text support: fall back to a flat, even quieter fill so
   the wordmark is still a wordmark rather than a solid slab. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .site-footer-wrap::after {
    background-image: none;
    color: rgba(251, 249, 246, 1);
    opacity: 0.06;
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* Nothing moves here. Stated so a future reader does not add drift to it:
     the watermark is the quietest thing on the page and should stay still. */
}


/* ===========================================================================
 * 52. THE HERO'S CLOSING BAND
 *
 * A smooth curved edge along the bottom of the fold, with the gradient living
 * IN that band rather than washing up the section.
 *
 * This started as a zigzag and was changed on instruction. The sawtooth read as
 * a section divider from a template kit: it repeats, and a repeat gives the eye
 * a period to count. A single sweeping arc has no period.
 *
 * The first version put a graded wash across the whole lower half and a glow
 * behind the middle of the hero. That lit the section but left the boundary a
 * straight horizontal line, and the light read as ambient rather than as a
 * designed edge. This makes the bottom of the hero a thing in its own right.
 *
 * One element does all of it. .sna-hero::after was freed when the headline
 * spotlight was removed, and it carries three background layers: the teeth, a
 * warm core, and a lift off the bottom edge. Layers rather than elements
 * because they share one box and one set of bounds.
 * ------------------------------------------------------------------------ */

.sna-hero__top::after {
  content: "";
  position: absolute;

  /* Drawn on .sna-hero__top, not on .sna-hero::after.
   *
   * .sna-hero::after does not paint. It is declared, it computes correctly
   * (content "", height 216px, bottom 0, three background layers), and forcing
   * it to solid red at z-index 5 still showed nothing, so something earlier in
   * this file suppresses it in a way the computed styles do not reveal.
   * .sna-hero__top::after paints reliably and is one element away, so the band
   * is drawn there instead of spending longer on the puzzle.
   *
   * The cost is that this box ends at the content row, above the hero's bottom
   * padding, so it has to be pushed down by exactly that padding. The padding
   * is a variable for that reason: the offset cannot drift out of sync with it. */
  inset: auto -100vmax calc(-1 * var(--sna-hero-pad-b)) -100vmax;
  height: clamp(9rem, 15vw, 13.5rem);
  z-index: -2;
  pointer-events: none;
  opacity: 1;
  border-radius: 0;
  transform: none;
  animation: none;

  background-image:
    /* 1. The curve, in the cream of the section below, sweeping up into the plum.
     *
     * ONE continuous arc across the whole width, not a repeating wave. A wave
     * tile is the stock section-divider look precisely because the repeat gives
     * it a period the eye can count; a single asymmetric sweep has no period and
     * reads as drawn rather than generated.
     *
     * Asymmetric on purpose: the control points sit left of centre, so the high
     * point falls under the copy and the curve is still descending as it passes
     * the portrait. A symmetric arc would centre its peak and look like a hill.
     *
     * preserveAspectRatio="none" lets the 1440x140 viewBox stretch to whatever
     * height the clamp below resolves to without distorting the ends. */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 140' preserveAspectRatio='none'%3E%3Cpath d='M0 140 L0 104 C 380 24 900 8 1440 52 L1440 140 Z' fill='%23FBF9F6'/%3E%3C/svg%3E"),

    /* 2. The warm core, off-centre toward the portrait so the band is lit from
          somewhere rather than being evenly bright. */
    radial-gradient(
      62% 130% at 63% 108%,
      rgba(201, 162, 39, 0.16) 0%,
      rgba(126, 66, 180, 0.34) 32%,
      rgba(91, 42, 134, 0.14) 62%,
      rgba(27, 11, 42, 0) 100%
    ),

    /* 3. A quiet lift off the bottom edge, so the curve sits on a graded ground
          instead of on flat plum. */
    linear-gradient(
      to top,
      rgba(58, 26, 92, 0.55) 0%,
      rgba(40, 18, 64, 0.26) 42%,
      rgba(27, 11, 42, 0) 100%
    );

  background-repeat: no-repeat, no-repeat, no-repeat;
  background-position: bottom center, center bottom, bottom;

  /* The curve is sized to the VIEWPORT, not to this element.
   *
   * The band is bled -100vmax each side, so it is roughly 4300px wide at a
   * 1440px viewport. A 100%-wide curve would stretch across all of that and the
   * visible middle would be an almost flat line. 100vw makes the arc span
   * exactly the screen, centred, so its shape is the shape that was drawn. The
   * few pixels of scrollbar overhang fall equally either side and cannot be
   * seen on a curve with no features at its ends. */
  /* The floor is 2.25rem, not 3.25rem. A fixed minimum makes the curve
     proportionally DEEPER as the screen narrows: at 390px a 52px arc is 13.3%
     of the width against 6.5% at 1440, so the same path read as two different
     gestures. 36px brings the phone to about 9% and the sweep stays recognisably
     the same shape at every width. */
  background-size:
    100vw clamp(2.25rem, 6.5vw, 6.5rem),
    100% 100%,
    100% 100%;
}

/* The old .sna-hero::after ellipse is switched off: the gradient now lives in
   the band, which is what "in that section, not at the top" asked for. */
.sna-hero::after {
  content: none;
}

/* Everything here is decoration on a dark field and none of it may touch the
   reading area: the band is anchored to the bottom edge and is fully
   transparent well before the copy, and the copy sits at the default layer
   above all three background layers. No text contrast can move. */

/* ---------------------------------------------------------------------------
 * 52.1 The portrait needs the column before the height cap can do anything
 *
 * Raising the height cap to 25rem changed nothing: the media column is 306px
 * wide, so the portrait's WIDTH was the binding constraint and its height
 * landed at 334, well under the cap. A cap only matters once the thing can
 * reach it.
 *
 * So the column widens and the cap does the work: the portrait grows to the
 * 400px cap and the fold grows with it, which is the height increase asked for.
 * The copy column is unchanged at ~596px, because the extra width comes out of
 * the gap and the ratio rather than out of the reading measure.
 * ------------------------------------------------------------------------ */

@media (min-width: 60em) {
  /* The media column is sized to the portrait, not to a share of the row.
   *
   * An fr ratio was tried first and took the width straight out of the copy
   * column: 594px down to 531, which put the lede back on four lines and undid
   * the widening asked for earlier. With the height capped at 25rem the
   * portrait is 367px wide and never more, so the column only has to be a
   * little wider than that and everything else can go to the copy. */
  .sna-hero__top {
    grid-template-columns: minmax(0, 1fr) clamp(16rem, 23vw, 21rem);
    column-gap: clamp(2rem, 3.5vw, 3.5rem);
  }
}

/*
 * The two asks trade against each other, so both are met partly rather than one
 * fully at the other's cost.
 *
 * The hero row is 965px, not the section's full width. Within that, a wider
 * portrait can only come out of the copy column: at a 367px portrait the copy
 * fell to 526px and the lede went back to four lines, undoing the widening
 * asked for earlier. There is no arrangement at 965px that gives both a 367px
 * portrait and a ~594px copy column.
 *
 * So the portrait grows a little (306 to 323 wide, 334 to 352 tall), the copy
 * column keeps roughly the width it had, and the REST of the height increase
 * comes from padding instead, where it costs neither of them.
 */
.sna-hero {
  padding-bottom: clamp(4rem, 6.5vw, 6.5rem);
}

/* ---------------------------------------------------------------------------
 * 52.2 A little more height
 *
 * Read as a dictation slip: a literal 4px would not be visible, and the note
 * that came with it was that the current height still is not enough. This adds
 * ~40px, which is a change you can see. Easy to dial: it is one clamp.
 *
 * It goes on the bottom padding, which is also where the closing band lives, so
 * the extra height gives the band room rather than pushing the portrait around.
 * ------------------------------------------------------------------------ */

.sna-hero {
  --sna-hero-pad-b: clamp(5.5rem, 9vw, 9rem);
  padding-bottom: var(--sna-hero-pad-b);
}

/* ===========================================================================
 * 53. INNER PAGES: ONE AXIS, ONE HEADER, ONE FOOTER
 *
 * The focused pages measured three different left edges: heading 414, body 451,
 * eyebrow 579. Two causes, both now fixed at source, and this handles what is
 * left.
 *
 * The remaining 37px is a gutter applied twice. `.sna-page` carries the page's
 * inline padding, and the prose block inside it is a `.sna-section`, which
 * carries the same padding again. Nested like that the inner one is not a
 * gutter, it is an indent, and it puts the body one step in from the heading
 * that introduces it.
 * ======================================================================== */

.sna-page .sna-section,
.sna-page--focused .sna-section {
  padding-inline: 0;
}

/* The eyebrow on these pages is the same centred flex row as everywhere else,
   and section 49's rule could not reach it because the focused template had no
   `.entry-content` to match on. It has one now, so this only has to cover the
   `.sna-page` wrapper that section 49 does not name. */
@media (min-width: 48em) {
  .sna-page .sna-eyebrow {
    justify-content: flex-start;
  }

  .sna-page .sna-eyebrow::before {
    display: none;
  }

  .sna-page .sna-section > .sna-eyebrow,
  .sna-page .sna-section > h2,
  .sna-page .sna-section > h2 + p {
    text-align: left;
    margin-inline: 0 auto !important;
  }
}

/* The placeholder note was centred, which put it on a fourth axis again. It is
   an editorial note to the owner, not a display element. */
.sna-placeholder__tag {
  text-align: left;
}

/* ===========================================================================
 * 54. ONE HEADER BAR, EVERY PAGE
 *
 * The floating pill was gated on .sna-leads-with-hero, and section 15 states
 * why: "Everywhere else the header stays a normal solid bar, because there is
 * no dark field for it to float over."
 *
 * That reasoning is out of date. It was written before the adaptive scheme
 * existed. The bar now measures what is behind it and swaps: 17.72:1 on the
 * dark hero, 15.42:1 on light content. It no longer needs a dark field to sit
 * on, so the gate was the only thing making inner pages look different.
 *
 * Measured before this: home bar 1152px wide, 999px radius, 16px float gap,
 * blurred backdrop. Inner pages 1425px wide, square, flush to the top, no
 * blur. Same component, two appearances.
 *
 * POSITIONING IS DELIBERATELY NOT UNIFIED. Hero pages keep the header fixed,
 * because it floats over a dark hero that is built to make room for it. Inner
 * pages keep it sticky, so it pushes content rather than covering it and no
 * page needs a clearance padding that has to be kept in sync with the bar's
 * height. What is shared is what you can see: shape, width, gap and material.
 * ======================================================================== */

body:not(.sna-leads-with-hero) #masthead {
  background: transparent;
  border-bottom: 0;
  padding-top: var(--space-s);
}

body:not(.sna-leads-with-hero) .site-main-header-wrap .site-header-row-container-inner {
  max-width: var(--width-wide);
  margin-inline: auto;
  border-radius: 999px;
  padding-inline: var(--space-m);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
          backdrop-filter: saturate(140%) blur(14px);
}

/* The same two step-downs the hero pages use, so the bar narrows into a
   floating control on tablets and phones rather than stretching edge to edge. */
@media (max-width: 61.9375em) {
  body:not(.sna-leads-with-hero) #masthead {
    padding-top: var(--space-xs);
  }

  body:not(.sna-leads-with-hero) .site-main-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-m);
    border-radius: 999px;
    padding-block: 0.25rem;
    padding-inline: 0.9rem;
  }
}

@media (max-width: 24em) {
  body:not(.sna-leads-with-hero) .site-main-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-s);
  }
}

/* ---------------------------------------------------------------------------
 * 54.1 The mobile bar is a different container
 *
 * Kadence renders the phone header from .site-mobile-header-wrap and hides the
 * desktop row entirely, so the rules above, which name .site-main-header-wrap,
 * reach nothing below the breakpoint. Measured at 390 after 54 landed: the
 * desktop row was 0px wide and the inner page still had a square, full width
 * bar while the home page had its pill.
 *
 * This is the second time that container has caught this theme out. Any header
 * rule that is not written for BOTH wraps is only half a rule.
 * ------------------------------------------------------------------------ */

body:not(.sna-leads-with-hero) .site-mobile-header-wrap .site-header-row-container-inner {
  max-width: var(--width-wide);
  margin-inline: auto;
  border-radius: 999px;
  -webkit-backdrop-filter: saturate(140%) blur(14px);
          backdrop-filter: saturate(140%) blur(14px);
}

@media (max-width: 61.9375em) {
  body:not(.sna-leads-with-hero) #masthead {
    padding-top: 0.6rem;
  }

  body:not(.sna-leads-with-hero) .site-mobile-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-l);
    padding-block: 0.3rem;
    padding-inline: 0.85rem;
  }
}

@media (max-width: 24em) {
  body:not(.sna-leads-with-hero) .site-mobile-header-wrap .site-header-row-container-inner {
    margin-inline: var(--space-m);
  }
}

/* ===========================================================================
 * 55. ONE TYPE SCALE FOR PAGE TITLES
 *
 * The family was never the problem. Every page already renders Geist for text
 * and IBM Plex Mono for labels, with no off-brand face anywhere. The scale was:
 * page titles came out at three different sizes.
 *
 *   home hero h1       35px   (set deliberately)
 *   .sna-page-head h1  47px   (styled)
 *   everything else    64px   (unstyled, falling through to --step-4)
 *
 * 64px is the base h1 from the token scale, which nothing on the homepage uses:
 * the largest heading there is 47px. So Book a Call, Terms, Privacy, Thank you
 * and Confirmed were opening a size larger than anything the reader had seen.
 *
 * They now use the same clamp .sna-page-head already uses, which is the site's
 * top display step. One value, named once, referenced by all three.
 * ======================================================================== */

:root {
  --page-title: clamp(2rem, 1.55rem + 1.9vw, 2.95rem);
}

.entry-content .sna-page-head h1,
.entry-content .sna-page__title,
.sna-page__title,
body:not(.home) .entry-content > .entry-header .entry-title,
body:not(.home) .entry-title {
  font-size: var(--page-title);
  line-height: 1.07;
  letter-spacing: -0.025em;
  font-weight: 600;
}

/* The hero keeps its own size. It was set to 35px on instruction and is the one
   heading on the site that is deliberately smaller than the display step. */
.sna-hero__title {
  font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.1875rem);
}

/* ---------------------------------------------------------------------------
 * 55.1 Unclassed h3 in prose
 *
 * An h3 with no class fell through to --step-2, 33.6px, against an h2 at
 * 37.6px. Four pixels apart is not a hierarchy: on the Terms page, which is
 * built almost entirely from h2 and h3, the two levels were indistinguishable.
 *
 * The homepage never showed this because its h3s all carry a class. 24px is the
 * size those classed h3s resolve to, so this brings the unclassed ones onto the
 * same step rather than inventing a new one: 47 / 38 / 24.
 * ------------------------------------------------------------------------ */

.entry-content h3:not([class*="sna-"]):not(.wp-block-heading[class*="has-"]) {
  font-size: var(--step-1);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin-top: var(--space-l);
  margin-bottom: var(--space-2xs);
}

/* ---------------------------------------------------------------------------
 * 55.2 Kadence's page title shares the content axis
 *
 * On pages without one of our own header bands, Kadence prints the title in its
 * own `.entry-header`, centred, outside `.entry-content`. On Terms that put the
 * h1 at x533 above a document whose every line starts at x230.
 *
 * Left-aligned and pulled onto the same axis as the section below it. Scoped to
 * pages that do NOT carry `.sna-page-head` or `.sna-domain-head`, because those
 * two are centred compositions by design and must stay that way.
 * ------------------------------------------------------------------------ */

body:not(.home) .entry-header.page-title {
  text-align: left;

  /* align-items, not justify-content, and not text-align.
   *
   * Three guesses, each wrong for a reason worth keeping. text-align does not
   * move a flex item at all: the h1's BOX measured x533 while its text-align
   * computed left, which was the tell. justify-content was the next guess and
   * also did nothing, because this header is flex-direction: COLUMN, so
   * justify-content runs vertically and align-items is what controls the
   * horizontal axis. Only the third one moves it. */
  align-items: flex-start;
  justify-content: flex-start;
}

body:not(.home) .entry-header.page-title .entry-title {
  text-align: left;
  margin-inline: 0;
  max-width: none;
}

/* The title sits outside .entry-content and in a different container, so it
   reaches x193 while the prose inside a section reaches x230. The section's own
   inline padding is the difference, and Kadence's 2rem is already on this
   element, so the total is both. */
body:not(.home) .entry-header.page-title {
  /* The section's gutter is WordPress's global content padding, 37.44px at
     1440, not --space-l at 32. Using the token left the title 5px inboard of
     its own body; using the same expression lands it exactly. */
  padding-inline: calc(2rem + clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem));
}

@media (max-width: 47.9375em) {
  body:not(.home) .entry-header.page-title {
    padding-inline: calc(1rem + clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem));
  }
}

/* ---------------------------------------------------------------------------
 * 55.3 The page title's empty room
 *
 * Kadence gives `.entry-hero-container-inner .entry-header` a `min-height` of
 * 200px, which is right for a page whose title sits in a hero band and wrong
 * for one whose title sits directly above its own text. On the legal pages it
 * left roughly 150px of nothing between the h1 and the first line.
 *
 * Only relaxed where there is no header band of ours; `.sna-page-head` and
 * `.sna-domain-head` set their own generous space and are untouched.
 * ------------------------------------------------------------------------ */

body:not(.home) .entry-hero-container-inner .entry-header.page-title {
  min-height: 0;
  padding-block: clamp(2.5rem, 5vw, 4rem) 0;
  margin-bottom: 0;
}

/* ---------------------------------------------------------------------------
 * 55.4 The first section already has a title above it
 *
 * Sections carry a generous top padding because they normally follow another
 * section and that space is the boundary between two ideas. The FIRST section
 * on an inner page follows the page title instead, so the padding is not a
 * boundary, it is a hole: measured 224px between the h1 and the first line on
 * the legal pages.
 *
 * Scoped to the first section on pages that use Kadence's title, so sections
 * that follow one of our own header bands are untouched.
 * ------------------------------------------------------------------------ */

body:not(.home) .entry-content > .sna-section:first-child {
  padding-top: clamp(1.5rem, 3vw, 2.5rem);
}

/* ===========================================================================
 * 56. THE 2026-08-01 REVISION
 *
 * Four fixes from the owner's review, kept together because they were one
 * pass: offer heading spacing, the Learn more button's contrast, the bio
 * band's texture, and the newsletter card.
 * ======================================================================== */

/* ---------------------------------------------------------------------------
 * 56.1 Breathing room under a section heading with no intro paragraph
 *
 * The offers section used to run heading, intro paragraph, grid. When the
 * owner's copy replaced the intro with nothing, the grid inherited only the
 * heading's own 16px bottom margin and the first card sat almost against the
 * headline. Measured at 16px, against the 48px to 64px every other section
 * gets from its intro.
 *
 * Fixed on the adjacency rather than on .sna-offers, so ANY section whose
 * heading is followed directly by a grid or a group gets the same air. The
 * next pattern that loses its intro will not have to rediscover this.
 * ------------------------------------------------------------------------ */

.entry-content .sna-section > h2 + .sna-grid,
.entry-content .sna-section > h2 + .wp-block-group {
  margin-top: clamp(2rem, 1.25rem + 3vw, 3.5rem);
}

/* ---------------------------------------------------------------------------
 * 56.2 The quiet button on a dark ground
 *
 * .is-style-sna-quiet sets its label to --purple-royal, which is correct on
 * ivory and a hard accessibility failure on plum: MEASURED AT 1.88:1 against
 * the bio band, where 4.5:1 is required. The Learn more button was very nearly
 * invisible, which is what the owner was seeing.
 *
 * SETTLED ON PURPLE AND WHITE, revised 2026-08-01 (second pass).
 *
 *   fill    brand-purple #5B2A86
 *   label   brand-ivory  #FBF9F6   9.42:1 on the fill   PASS AA
 *   border  brand-purple #5B2A86   same as the fill, so no visible outline
 *
 * A first pass used a gold hairline and a gold-200 label. Both are removed at
 * the owner's instruction: the gold outline read as a different species of
 * button to every other call to action on the site, and consistency won.
 *
 * WHAT THAT COSTS, RECORDED HONESTLY. Purple against plum measures 1.88:1, so
 * the button's own edge is not distinguishable from the band it sits on. The
 * gold hairline was what carried that boundary at 7.70:1. The label is still
 * 9.42:1 and the control is still identifiable by its text, its shape and its
 * hover state, so this is not a text contrast failure. It is a judgement call
 * about WCAG 2.2 SC 1.4.11 that the owner has made knowingly.
 *
 * If the Phase 6 audit wants the boundary back without reintroducing gold, an
 * ivory hairline at 17.72:1 or brand-purple-100 at 14.05:1 both clear 3:1 and
 * stay in the same colour family. Do not reach for gold again.
 *
 * Hover darkens to purple-700, which takes the label to 12.10:1.
 * ------------------------------------------------------------------------ */

.sna-band-dark .wp-block-button.is-style-sna-quiet .wp-block-button__link {
  background-color: var(--brand-purple);
  color: var(--brand-ivory);
  box-shadow: inset 0 0 0 1px var(--brand-purple);
}

/*
 * HOVER GOES GOLD, set 2026-08-01 at the owner's instruction, replacing a
 * darken-to-purple-700 hover.
 *
 * Purple at rest, gold on hover, is now the behaviour of every purple call to
 * action on a dark ground: this button and the newsletter's Subscribe.
 *
 * Black on gold is 8.18:1, so the label is stronger on hover than at rest, and
 * gold against plum is 7.70:1, so the button's edge is actually DRAWN while
 * hovered, which the purple resting state does not manage. The hover state is
 * the accessible one.
 */
.sna-band-dark .wp-block-button.is-style-sna-quiet .wp-block-button__link:hover,
.sna-band-dark .wp-block-button.is-style-sna-quiet .wp-block-button__link:focus-visible {
  background-color: var(--brand-gold);
  color: var(--brand-black);
  box-shadow: inset 0 0 0 1px var(--brand-gold);
}

/* ---------------------------------------------------------------------------
 * 56.3 The bio band's texture
 *
 * Replaces the radial bloom that used to sit behind the portrait. See the note
 * where that was removed: soft radial gradients on plum read as an object, not
 * as light, and this is the second time one has been rejected here.
 *
 * What is here instead is CONTOUR LINES: concentric gold hairlines, drawn as
 * one inline SVG, centred behind the portrait and running off the left edge.
 * The reasoning is that the metaphor of this practice is formation in layers
 * over time, and a contour map is exactly that picture. It is structural
 * rather than atmospheric, which is the register the rest of the site works
 * in, and it is unmistakably not a gradient blob.
 *
 * Still zero external requests: inline SVG data URI, as with every other
 * texture on this site.
 *
 * CONTRAST IS SAFE BY CONSTRUCTION. The rings are masked out entirely across
 * the right hand 55% of the band, which is where every word of the bio sits,
 * so no text is ever set over a stroke. The strokes themselves are gold at
 * 0.10 to 0.16 alpha, which is a hairline on plum and disappears well before
 * it could lift the effective background luminance. Re-run
 * scripts/contrast-report.py if you change either number.
 * ------------------------------------------------------------------------ */

.sna-band-dark::after {
  content: "";
  position: absolute;
  inset: 0 -100vmax;
  z-index: -1;
  pointer-events: none;

  /* Concentric rings, drawn once and anchored to the portrait side. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='900' height='900' viewBox='0 0 900 900'%3E%3Cg fill='none' stroke='%23C9A227'%3E%3Ccircle cx='450' cy='450' r='90' stroke-opacity='0.16'/%3E%3Ccircle cx='450' cy='450' r='150' stroke-opacity='0.15'/%3E%3Ccircle cx='450' cy='450' r='210' stroke-opacity='0.14'/%3E%3Ccircle cx='450' cy='450' r='270' stroke-opacity='0.13'/%3E%3Ccircle cx='450' cy='450' r='330' stroke-opacity='0.12'/%3E%3Ccircle cx='450' cy='450' r='390' stroke-opacity='0.11'/%3E%3Ccircle cx='450' cy='450' r='450' stroke-opacity='0.10'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: no-repeat;

  /*
   * EVERY HORIZONTAL VALUE HERE IS calc() FROM THE CENTRE, NOT A PERCENTAGE.
   *
   * This element is `inset: 0 -100vmax`, so its box is the content width plus
   * 200vmax. Percentages resolve against THAT, which means `22%` is not 22% of
   * the visible band, it is a point far off the left of the screen. The first
   * version used percentages and the rings were pushed almost entirely out of
   * view; only one faint arc survived at the left edge.
   *
   * 50% is the one percentage that still means what it looks like, because the
   * bleed is symmetric, so it lands on the centre of the content column.
   * Everything else is measured from there in rem.
   *
   * Rings are centred 17rem left of the content centre, which is the middle of
   * the 38% portrait column at desktop widths.
   */
  background-size: 62rem auto;
  background-position: calc(50% - 17rem) 50%;

  /* Cleared off the text column well before the copy starts, and faded top and
     bottom so the rings do not stop abruptly at the band boundary. */
  -webkit-mask-image:
    linear-gradient(to right, rgba(0,0,0,1) calc(50% - 16rem), transparent calc(50% - 8rem)),
    linear-gradient(to bottom, transparent 0%, rgba(0,0,0,1) 16%, rgba(0,0,0,1) 84%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to right, rgba(0,0,0,1) calc(50% - 16rem), transparent calc(50% - 8rem)),
    linear-gradient(to bottom, transparent 0%, rgba(0,0,0,1) 16%, rgba(0,0,0,1) 84%, transparent 100%);
          mask-composite: intersect;
}

/*
 * On a phone the two columns stack, so the portrait is no longer on the left
 * and the "keep it off the text" mask above no longer describes the layout.
 * The rings move behind the portrait at the top of the band and fade out
 * before the copy starts.
 */
@media (max-width: 47.9375em) {
  .sna-band-dark::after {
    /* Rem again, not the 150% the first version used, for the same reason: the
       bleed makes percentage sizing meaningless here. */
    background-size: 34rem auto;
    background-position: 50% 0;
    -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 24%, transparent 42%);
    -webkit-mask-composite: source-over;
            mask-image: linear-gradient(to bottom, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 24%, transparent 42%);
            mask-composite: add;
  }
}

/* The rings are decoration and carry no information, so they go under reduced
   motion's sibling principle: if the user has asked for less, give less. */
@media (prefers-contrast: more) {
  .sna-band-dark::after {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
 * 56.4 The newsletter card
 *
 * Was a full bleed plum band sharing the hero's dither. It is now a contained
 * plum card, which is why .sna-newsletter was taken out of those grouped
 * selectors at the top of this file.
 *
 * It closes the homepage directly under the bio band, so it is deliberately
 * NOT another edge to edge dark field: two full width plum sections back to
 * back would read as one very long dark run. The card gives the eye an edge
 * and lets the page background breathe around it.
 * ------------------------------------------------------------------------ */

/*
 * THE NEWSLETTER GETS ITS OWN GROUND, added 2026-08-01.
 *
 * It used to sit on the page's ivory, which is also the FAQ's ivory, so the
 * two ran together as one long light stretch with a plum box floating in the
 * middle of it. They are different invitations and now read as different
 * sections.
 *
 * The tint is the purple-100 family already used by `.sna-band-tint`. It was
 * the framework band's ground, and the framework band came off the homepage
 * the same day, so the tint is free here and the page still never repeats a
 * surface twice in a row: plum bio, tint newsletter, ivory FAQ.
 *
 * BLED WITH box-shadow, NOT alignfull. Same reason as every other band on this
 * site: alignfull breaks a section out of the content container and leaves its
 * children 56px off the vertical line the rest of the page sits on. See the
 * note at the top of this file.
 * ------------------------------------------------------------------------ */

.sna-newsletter {
  /* The SAME value as .sna-band-tint, deliberately, not a new near-miss
     lilac. A first pass invented #F1EAF7, which is three points off this and
     would have added a fourth light surface to a palette that documents
     three. If this ever needs to change, change it in both places or promote
     it to a real token in design/tokens.json, theme.json and tokens.css. */
  --band-bg: #F4EFF8;
  position: relative;
  isolation: isolate;
  background-color: var(--band-bg);
  box-shadow: 0 0 0 100vmax var(--band-bg);
  clip-path: inset(0 -100vmax);
}

/*
 * RULED PAPER.
 *
 * The texture is horizontal hairlines at a regular 30px rhythm, because the
 * thing being offered here is a letter, once a week. Every other ground on the
 * site has its own weave (dither on the hero, a fine dot on the tint, contour
 * rings on the bio band); this one is the page it is written on.
 *
 * Purple at 0.09 on the tint. NOTHING IS MEASURED FOR CONTRAST HERE and that
 * is not an oversight: the section's only child is the plum card, which is
 * fully opaque, so no text of any kind is ever set over these lines. If a
 * heading or a paragraph is ever moved OUT of the card and onto this ground,
 * re-check design/contrast-report.md before shipping it.
 *
 * Inline SVG data URI, so the zero-external-request guarantee holds.
 */
.sna-newsletter::before {
  content: "";
  position: absolute;
  inset: 0 -100vmax;
  z-index: -1;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3E%3Cline x1='0' y1='29.5' x2='30' y2='29.5' stroke='%235B2A86' stroke-opacity='0.09' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;

  /* Faded at both ends so the ruling does not butt hard against the section
     above and below, which would read as a table rather than as paper. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, rgba(0,0,0,1) 22%, rgba(0,0,0,1) 78%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, rgba(0,0,0,1) 22%, rgba(0,0,0,1) 78%, transparent 100%);
}

/* A hairline where the tint meets the plum band above it, so the two dark and
   light grounds have a drawn edge rather than a raw colour change. */
.sna-newsletter::after {
  content: "";
  position: absolute;
  inset: 0 -100vmax auto;
  height: 1px;
  z-index: -1;
  pointer-events: none;
  background-color: rgba(91, 42, 134, 0.16);
}

@media (prefers-contrast: more) {
  .sna-newsletter::before {
    display: none;
  }
}

.sna-newsletter__card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-color: var(--brand-plum);
  border-radius: 18px;
  padding: clamp(2rem, 1rem + 5vw, 4rem) clamp(1.25rem, 0.5rem + 4vw, 3.5rem);
  color: var(--brand-ivory);
}

/* The same dither the hero uses, so the card belongs to the family, fading up
   from the base and gone long before it reaches the paragraph. */
.sna-newsletter__card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3E%3Crect width='1' height='1' fill='%23FBF9F6' fill-opacity='0.55'/%3E%3Crect x='2' y='2' width='1' height='1' fill='%23FBF9F6' fill-opacity='0.55'/%3E%3C/svg%3E");
  background-repeat: repeat;
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.3) 20%, transparent 46%);
          mask-image: linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.3) 20%, transparent 46%);
}

.entry-content .sna-newsletter__card .sna-newsletter__title,
.entry-content .sna-newsletter__card p {
  color: var(--brand-ivory);
}

/*
 * NOTE THE `p` IN THESE TWO SELECTORS. It is load bearing, not tidiness.
 *
 * The measure cap in components.css is
 *   .entry-content :is(p, li, blockquote):not(.sna-eyebrow):not(.sna-marker)
 * which computes to (0,3,1) and pins capped text hard left with
 * margin-inline-start: 0 !important.
 *
 * Written as `.entry-content .sna-newsletter__card .sna-newsletter__lede` this
 * rule is (0,3,0), loses by a single element selector, and the centred copy
 * silently rendered flush left inside a centred card. Adding the element takes
 * it to (0,3,1), and dither.css loads after components.css, so it wins on
 * source order.
 *
 * The same trap is why the .has-text-align-center opt-in rule in components.css
 * does not help here: it is only (0,2,1).
 */
.entry-content .sna-newsletter__card p.sna-newsletter__lede {
  max-width: 58ch;
  margin-inline: auto !important;
  color: rgba(251, 249, 246, 0.82);
}

.entry-content .sna-newsletter__card p.sna-note {
  margin-top: var(--space-m);
  margin-bottom: 0;
  margin-inline: auto !important;
  color: rgba(251, 249, 246, 0.62);
}

/* ---------------------------------------------------------------------------
 * 56.5 The Fluent Forms embed, as a capsule
 *
 * Rebuilt 2026-08-01 to the form design the owner supplied: ONE rounded
 * capsule holding both controls, with the field sitting flush inside it and
 * the action as a solid pill tucked into the right hand end. The reference
 * used a light capsule and a saturated button; the colours here are ours.
 *
 *   capsule   brand-ivory on the plum card    17.72:1 boundary
 *   field     brand-ink on the capsule        15.42:1
 *   placeholder brand-muted on the capsule     5.12:1
 *   button    brand-purple, ivory label        9.42:1 label, 9.42:1 boundary
 *
 * PURPLE, NOT GOLD, for the button. Gold against an ivory capsule is 2.30:1,
 * which is the site's banned pair and would leave the button's edge invisible
 * inside its own container. Purple also matches the Learn more button two
 * sections up, which is the consistency the owner asked for.
 *
 * Fluent Forms ships its own stylesheet, so much of this is undoing a generic
 * form. Everything is scoped to .sna-newsletter__card, because the contact
 * form in Phase 5 lives on a light ground and must not inherit any of it.
 * ------------------------------------------------------------------------ */

.sna-newsletter__card .frm-fluent-form {
  margin-top: var(--space-l);
}

.sna-newsletter__card .frm-fluent-form .ff-el-group {
  margin-bottom: 0;
}

/*
 * The hidden label, hidden properly.
 *
 * label_placement "hide" only adds .ff-el-form-hide; the label element still
 * rendered inline-block and still occupied 31px, which pushed the input below
 * the button and broke the row. It looked like a flex bug and was not one.
 *
 * Clipped rather than display:none ON PURPOSE. display:none would take the
 * label out of the accessibility tree and leave the only email field on the
 * site unlabelled, which fails the Phase 6 axe run and is exactly the kind of
 * thing that stays invisible until someone tests with a screen reader.
 */
.sna-newsletter__card .frm-fluent-form .ff-el-form-hide .ff-el-input--label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/*
 * THE CAPSULE.
 *
 * Centred with a max-width, which is the other half of what the owner asked
 * for: the form previously ran the full width of the card and read as
 * left-aligned against centred copy above it.
 *
 * nowrap, not wrap. The two cells carry inline flex-basis of 66% and 34% which
 * totals exactly 100%, so any padding or gap would push the pair onto two
 * lines. With nowrap the difference is absorbed by flex-shrink instead.
 */
.sna-newsletter__card .frm-fluent-form .ff-t-container {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
  max-width: 34rem;
  margin-inline: auto;
  padding: 0.35rem;
  background-color: var(--brand-ivory);
  border: 1px solid rgba(27, 11, 42, 0.12);
  border-radius: 999px;
}

.sna-newsletter__card .frm-fluent-form .ff-t-cell {
  padding: 0;
  min-width: 0;
}

/*
 * The field is flush inside the capsule: no background, no border, no radius
 * of its own. The capsule IS the input's visual container, which is the whole
 * idea of the reference design.
 *
 * Focus is drawn on the capsule rather than on the bare input, further down,
 * so the focus ring follows the shape the user actually sees.
 */
.sna-newsletter__card .frm-fluent-form input[type="email"] {
  width: 100%;
  min-width: 0;
  background-color: transparent;
  color: var(--brand-ink);
  border: 0;
  border-radius: 999px;
  /* 0.78rem, not 0.7rem: at 0.7 the control measured 43px, one pixel under the
     44px target size the rest of the site's buttons clear. Nudged rather than
     left just short, because "nearly" is how a target size gets flagged in an
     audit six weeks from now. */
  padding: 0.78rem 0.6rem 0.78rem 1.15rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  line-height: 1.4;
  height: auto;
  box-shadow: none;
  outline: none;
}

/* Placeholder contrast is a real requirement, not a nicety: it is the only
   label a sighted user sees. brand-muted on ivory measures 5.12:1. Do not
   drop it to a fainter grey for looks. */
.sna-newsletter__card .frm-fluent-form input[type="email"]::placeholder {
  color: var(--brand-muted);
  opacity: 1;
}

/* The focus ring lands on the capsule, not the input, so it traces the control
   the user sees. :focus-within is what makes that possible. */
.sna-newsletter__card .frm-fluent-form .ff-t-container:focus-within {
  outline: 2px solid var(--brand-gold-200);
  outline-offset: 3px;
  border-color: var(--brand-purple);
}

/* The button. A solid pill tucked into the end of the capsule. */
.sna-newsletter__card .frm-fluent-form .ff-btn-submit,
.sna-newsletter__card .frm-fluent-form button[type="submit"] {
  display: block;
  width: 100%;

  background-color: var(--brand-purple);
  background-image: none;
  color: var(--brand-ivory);
  border: 0;
  border-radius: 999px;
  padding: 0.78rem 1.1rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 600;
  line-height: 1.4;
  height: auto;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 220ms var(--motion-easing);
}

/*
 * The submit button's 20px bottom margin, removed at a specificity that wins.
 *
 * fluent-forms-public.css carries
 *   .frm-fluent-form .ff-t-cell .ff_submit_btn_wrapper_custom button
 * which is (0,3,1). A three class rule of ours is (0,3,0) and loses by one
 * element selector, so `margin: 0` in the block above did nothing at all: the
 * button cell stayed 63px against the field's 43px, the capsule sat 20px too
 * tall, and the two controls were visibly 10px out of line.
 *
 * Four classes plus the element takes this to (0,4,1), which wins outright
 * rather than depending on stylesheet order, since a plugin's CSS may enqueue
 * either side of the theme's.
 *
 * THIS IS THE SECOND TIME THIS EXACT TRAP HAS BITTEN in this file; see the
 * note on the measure rule at .sna-newsletter__lede. When a rule that looks
 * correct has no effect, count the element selectors before rewriting it.
 */
.sna-newsletter__card .frm-fluent-form .ff-t-cell .ff_submit_btn_wrapper_custom button {
  margin: 0;
}

/* Gold on hover, matching the Learn more button. Black on gold is 8.18:1. */
.sna-newsletter__card .frm-fluent-form .ff-btn-submit:hover,
.sna-newsletter__card .frm-fluent-form button[type="submit"]:hover {
  background-color: var(--brand-gold);
  color: var(--brand-black);
}

.sna-newsletter__card .frm-fluent-form .ff-btn-submit:focus-visible,
.sna-newsletter__card .frm-fluent-form button[type="submit"]:focus-visible {
  outline: 2px solid var(--brand-purple-700);
  outline-offset: 2px;
}

/*
 * Validation and confirmation messages.
 *
 * These sit OUTSIDE the capsule, on the plum card, so they are measured
 * against plum and not against ivory.
 *
 * Fluent Forms' defaults are a mid red and a mid green, both of which fail on
 * plum. Errors go to gold-200 (12.01:1) rather than to a lighter red, because
 * no red that passes on this ground still reads as red; the wording does the
 * work of saying something is wrong.
 */
.sna-newsletter__card .frm-fluent-form .error,
.sna-newsletter__card .frm-fluent-form .text-danger,
.sna-newsletter__card .frm-fluent-form .ff-el-is-error .error {
  color: var(--brand-gold-200);
  font-size: var(--t-xs);
  text-align: center;
  margin-top: var(--space-2xs);
}

.sna-newsletter__card .frm-fluent-form .ff-el-is-error .ff-t-container,
.sna-newsletter__card .frm-fluent-form .ff-t-container:has(.ff-el-is-error) {
  border-color: var(--brand-gold-200);
}

.sna-newsletter__card .ff-message-success,
.sna-newsletter__card .ff_submit_success {
  max-width: 34rem;
  margin-top: var(--space-l);
  margin-inline: auto;
  color: var(--brand-ivory);
  background-color: rgba(232, 206, 122, 0.12);
  border: 1px solid rgba(232, 206, 122, 0.45);
  border-radius: 14px;
  padding: var(--space-m);
  text-align: center;
}

/* ---------------------------------------------------------------------------
 * 56.6 Small screens: two separate controls, not a nested one
 *
 * REVISED 2026-08-01 after the owner tested it on a phone.
 *
 * The first stacked version kept the ivory capsule as a container and put the
 * field and the button INSIDE it, one above the other. On a phone that reads
 * as a button trapped in a box: the capsule looks like the input's own
 * boundary, so the button appears to be sitting inside the text field. It is
 * a real usability problem, not a cosmetic one, because the thing that looks
 * like the field's edge is not the field's edge.
 *
 * Below the breakpoint the capsule therefore STOPS BEING A CONTAINER
 * ALTOGETHER. It goes transparent and borderless and does nothing but stack,
 * and the two controls take their own surfaces:
 *
 *   field    ivory pill with its own border, on the plum card   17.72:1 edge
 *   button   full width purple pill, its own object below it
 *
 * Two controls, two boundaries, one obvious tap target each.
 *
 * THE BREAKPOINT MOVED FROM 26rem TO 30rem. 26rem (416px) left phones between
 * 416 and 480 on the capsule, where the field measured about 203px and the
 * pair was already cramped. 30rem (480px) puts every common phone width on the
 * stacked layout and keeps the capsule for tablets and up, which is where
 * there is genuinely room for it.
 * ------------------------------------------------------------------------ */

@media (max-width: 40rem) {
  .sna-newsletter__card .frm-fluent-form input[type="email"] {
    padding-left: 0.9rem;
    font-size: var(--t-xs);
  }

  .sna-newsletter__card .frm-fluent-form .ff-btn-submit,
  .sna-newsletter__card .frm-fluent-form button[type="submit"] {
    padding-inline: 0.85rem;
    font-size: var(--t-xs);
  }
}

@media (max-width: 30rem) {
  /* The capsule dissolves. It is a flex column and nothing else. */
  .sna-newsletter__card .frm-fluent-form .ff-t-container {
    flex-direction: column;
    gap: var(--space-2xs);
    max-width: 24rem;
    padding: 0;
    background-color: transparent;
    border: 0;
    border-radius: 0;
  }

  /* The inline 66/34 basis is meaningless once the axis is vertical, and left
     alone it makes each row a fraction of the container's HEIGHT. */
  .sna-newsletter__card .frm-fluent-form .ff-t-cell {
    flex: 0 0 auto;
    width: 100%;
  }

  /* The field becomes its own object: it now carries the ivory fill and the
     border the capsule used to provide. */
  .sna-newsletter__card .frm-fluent-form input[type="email"] {
    background-color: var(--brand-ivory);
    border: 1px solid rgba(27, 11, 42, 0.12);
    border-radius: 999px;
    padding: 0.85rem 1.25rem;
    font-size: var(--t-sm);
    text-align: center;
  }

  .sna-newsletter__card .frm-fluent-form .ff-btn-submit,
  .sna-newsletter__card .frm-fluent-form button[type="submit"] {
    padding-block: 0.85rem;
    font-size: var(--t-sm);
  }

  /*
   * Focus moves back onto the field.
   *
   * The desktop rule draws the ring on the capsule with :focus-within, which
   * is right when the capsule is the visible control. Here it would draw a
   * ring around the field AND the button together, pointing at something that
   * is no longer one control. Cancel it and ring the input itself.
   */
  .sna-newsletter__card .frm-fluent-form .ff-t-container:focus-within {
    outline: none;
    border-color: transparent;
  }

  .sna-newsletter__card .frm-fluent-form input[type="email"]:focus {
    outline: 2px solid var(--brand-gold-200);
    outline-offset: 2px;
    border-color: var(--brand-purple);
  }
}

/* ---------------------------------------------------------------------------
 * 56.7 Proportionate spacing between sections
 *
 * Every section carries a full --space-section top AND bottom, so the dead
 * space between any two is double. Measured on the homepage at 1280px:
 * roughly 208px to 219px between every pair.
 *
 * Where the ground changes that is fine, because the colour boundary is doing
 * the separating and the space reads as air around a new surface. Where the
 * ground does NOT change, the same 208px reads as a hole in the page: nothing
 * marks it as a new section, so it just looks like something failed to load.
 * The homepage has one such pair, the problem section running into the offers,
 * both on ivory, since the framework band that used to sit between them was
 * removed.
 *
 * Fixed on the adjacency rather than by trimming --space-section, which would
 * have tightened every section on the site to fix one join.
 * ------------------------------------------------------------------------ */

.entry-content > .sna-problem + .sna-section {
  padding-top: clamp(1.75rem, 1.25rem + 2.5vw, 3.25rem);
}

/*
 * The newsletter closing the page.
 *
 * Its bottom padding is cut to about a third, so the tint band ends close under
 * the card and hands straight to the footer. The 136px of page background that
 * used to sit below it is removed separately by .sna-closes-with-band in
 * components.css; both are needed, because one is the section's own padding and
 * the other is Kadence's content wrapper.
 */
.entry-content > .sna-newsletter:last-child {
  padding-bottom: clamp(2rem, 1.5rem + 2vw, 3.25rem);
}

/*
 * The FAQ handing over to the newsletter.
 *
 * These are the last two sections and they are one thought: answer the
 * hesitation, then make the ask. Trimmed so they read as a pair rather than as
 * two unrelated blocks that happen to be adjacent.
 */
.entry-content > .sna-faq + .sna-newsletter {
  padding-top: clamp(2.25rem, 1.5rem + 3vw, 4rem);
}
