/* sprint 13 — Maven-method redesign, scoped entirely under .obc-mv so it cannot touch the accepted
   replica pages. Method borrowed from mavenclinic.com; identity kept from OBC.

   What is borrowed: one deep saturated ground doing most of the work, a warm cream second surface,
   display type set very large at weight 300 with leading at 1.0, an italic serif for a single
   emphasised word, full-bleed photography with text laid over it, a band of very large numbers with
   very small captions, and a great deal of air.

   What is kept: OBC's teal. Maven's forest green is deepened from OBC's own #75aab0 hue rather than
   replaced, so the site still looks like this clinic. */

/* sprint 25 — the Google Fonts import that used to be here has gone. Both faces are served by this
   site now, from assets/css/fonts.css. Nothing about how the page looks changes; what changes is
   that a clinic's website no longer tells Google who is reading it, on every page, before a single
   word is shown. */

/* sprint 27 — every colour below is now one of the twelve in the OBC Project Palette, confirmed by
   the owner on 15 August 2026. The shades that used to sit here were eyeballed during the redesign
   rather than taken from the palette, and each one is recorded in BRAND.md with what replaced it. */
.obc-mv {
  /* sprint 27 — text and small marks. Was #072e2d, a near-black green with no palette equivalent.
     Split from the dark surfaces below, which used to share this one token: a colour that is both
     the body text and the background behind it can only stay legible by accident. */
  --mv-ink: #1f2c31;
  /* sprint 27 — the dark ground: bands, jar cards, dark buttons. Deep Green rather than the old
     #072e2d, so the bands lift and keep their green character. Chosen by the owner over Deep Navy. */
  --mv-dark: #294f4b;
  /* hover beneath the dark ground */
  --mv-deep: #183e49;
  --mv-brand: #75aab0;
  /* sprint 27 — the light accent on dark ground: eyebrows, kickers, the hero link, hairlines. Was
     mint #8fe3cd, which has no relative in the palette. Warm Gold is the only approved colour that
     clears 4.5:1 against the dark bands, which this text needs at 12px uppercase. */
  --mv-highlight: #d7b47a;
  --mv-cream: #f6efe6;
  --mv-paper: #fff;
  --mv-muted: #758287;
  /* sprint 26 — what milk is, stated once, and it is the white the jars have always poured rather
     than the cream the spheres mix. Named separately from --mv-paper even though they are the same
     value, because one of them is the colour of the page and the other is the colour of a liquid,
     and a day will come when one of those moves. */
  --mv-milk: #fff;
  /* sprint 27 — colostrum, the first days' milk. Sprint 26 asked what should happen if the palette
     ever won, and the answer came back that it does not win here: colostrum is an approved material
     in its own right, and #e9c471 is allowed inside it by name. See BRAND.md.

     So this is not a stray gold that escaped the palette. It is one defined substance, the same one
     the seventeen thousand is poured from and the same one the spheres hold, and its stops belong
     together. Mixing any of them from Warm Gold instead makes the material read as metal rather than
     as milk, which is the whole point of it. The flat form, for where a gradient will not do, is
     --mv-gold itself. */
  --mv-gold: #e9c471;
  --mv-gold-deep: #dcb45f;
  --mv-gold-pale: #f6e2b0;
  /* sprint 27 — the fourth stop. It was only ever written inline in stats.js; named here because the
     jars now pour the same four-stop ramp and a recipe with one ingredient kept somewhere else is a
     recipe that drifts. */
  --mv-gold-deepest: #b8842c;

  --mv-display: "Figtree", "Helvetica Neue", Arial, sans-serif;
  --mv-accent: "Instrument Serif", Georgia, serif;

  --mv-gutter: clamp(20px, 5vw, 72px);
  --mv-measure: 1240px;

  margin: 0;
  padding: 0;
  background: var(--mv-paper);
  color: var(--mv-ink);
  font-family: var(--mv-display);
  font-size: 17px;
  line-height: 1.6;
  overflow-x: clip;
}

.obc-mv :where(h1, h2, h3, h4) {
  color: var(--mv-ink);
  font-family: var(--mv-display);
  font-weight: 300;
  letter-spacing: -0.02em;
}

/* the base theme sets a heading colour, which beats inheriting from the dark section — so state it */
.obc-mv .mv-dark :where(h1, h2, h3, h4),
.obc-mv .mv-hero :where(h1, h2, h3, h4) {
  color: var(--mv-paper);
}

/* the single borrowed gesture that carries the whole design: one word, set in an italic serif */
.obc-mv em {
  font-family: var(--mv-accent);
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
}

.obc-mv .mv-inner {
  width: 100%;
  max-width: var(--mv-measure);
  margin: 0 auto;
  padding: 0 var(--mv-gutter);
}

/* ---------- hero ---------- */
.obc-mv .mv-hero.wp-block-cover {
  min-height: min(88vh, 760px);
  padding: clamp(64px, 10vw, 128px) var(--mv-gutter);
  align-items: flex-end;
  color: var(--mv-paper);
}

.obc-mv .mv-hero .wp-block-cover__background {
  background: linear-gradient(
    to right,
    rgba(7, 46, 45, 0.95) 0%,
    rgba(7, 46, 45, 0.86) 38%,
    rgba(7, 46, 45, 0.45) 100%
  );
}

.obc-mv .mv-hero .wp-block-cover__inner-container {
  width: 100%;
  max-width: var(--mv-measure);
  margin: 0 auto;
}

.obc-mv .mv-eyebrow {
  margin: 0 0 clamp(20px, 3vw, 32px);
  color: var(--mv-highlight);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.obc-mv .mv-hero-title {
  max-width: 17ch;
  margin: 0 0 clamp(20px, 3vw, 28px);
  color: var(--mv-paper);
  font-size: clamp(40px, 7.2vw, 84px);
  line-height: 1;
}

.obc-mv .mv-hero-sub {
  max-width: 46ch;
  margin: 0 0 clamp(28px, 4vw, 40px);
  color: rgba(255, 255, 255, 0.86);
  font-size: clamp(16px, 1.5vw, 20px);
  line-height: 1.55;
}

/* ---------- buttons ----------
   sprint 26 — a call to action is a small glass of milk.

   The jars pour and the spheres fill, so a flat coloured pill between them was the last thing on the
   page still speaking the old language. These fill from the bottom the way everything else does and
   carry the same bubble, which is what makes it a theme rather than an effect used twice.

   Two things this is built around, both of which decide the markup.

   The milk is drawn at z-index -1 inside a link that isolates itself. That is not a trick for its own
   sake: a negative child paints above its parent's own background but below the parent's text, which
   is the only way to get liquid behind a label whose text node cannot be wrapped without adding raw
   HTML to a block the owner edits. The colour WordPress writes onto the button as an inline style
   stays where it is and becomes the empty glass behind the milk, so a page whose script never runs
   still shows exactly the button that is there today.

   Nothing here is clipped by the border, because overflow cuts at the padding box: the ghost keeps
   its rim above the milk, which is what stops the second button dissolving into the first. */
/* ---------- sprint 33: the locations page ---------- */
/* The map is a frame of somebody else's page, so it is held in a box of ours: a fixed shape the
   layout can rely on before it loads, and a border so the seam between our page and Google's is a
   line rather than a surprise. */
.obc-mv .mv-map {
  margin: clamp(20px, 3vw, 32px) 0 0;
  padding: clamp(16px, 2vw, 22px);
  border: 1px solid rgba(41, 79, 75, 0.16);
  border-radius: 10px;
  background: var(--mv-paper, #fff);
}

.obc-mv .mv-map-frame {
  display: block;
  width: 100%;
  height: clamp(360px, 60vh, 620px);
  margin: 0 0 14px;
  border: 0;
  border-radius: 6px;
}

.obc-mv .mv-map-note {
  margin: 0 0 12px;
  color: var(--mv-slate, #758287);
  font-size: 14px;
  line-height: 1.55;
}

/* the button the script adds. Colostrum, because on this page the map is the way forward. */
.obc-mv .mv-map-show {
  min-height: 46px;
  padding: 12px 26px;
  border: 0;
  border-radius: 999px;
  background: var(--mv-gold, #e9c471);
  color: var(--mv-ink, #1f2c31);
  font-family: inherit;
  font-size: 15.5px;
  font-weight: 500;
  cursor: pointer;
}

.obc-mv .mv-map-show:hover { background: var(--mv-gold-deep, #d7b47a); }

.obc-mv .mv-map-open { margin: 12px 0 0; font-size: 14.5px; }

/* sprint 33 — ten offices, laid out rather than stacked.
   A single column ten deep was a page of scrolling with two thirds of the width unused, and every
   card the same shape, so nothing could be found by looking. auto-fill rather than a fixed count:
   the number of columns follows the width, and the towns keep their reading order down the page. */
.obc-mv .loc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: clamp(16px, 2vw, 24px);
  margin-top: clamp(24px, 3vw, 36px);
}

/* a card now, because a grid cell needs an edge to be a thing. On the white band a hairline is
   enough: ten filled boxes would be a wall. */
.obc-mv .loc-office {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: clamp(18px, 2vw, 24px);
  border: 1px solid rgba(41, 79, 75, 0.16);
  border-radius: 10px;
  background: var(--mv-paper);
}

.obc-mv .loc-town {
  margin: 0 0 8px;
  color: var(--mv-dark, #294f4b);
  font-size: clamp(19px, 1.6vw, 22px);
  line-height: 1.2;
}

.obc-mv .loc-address { margin: 0 0 6px; font-size: 15.5px; line-height: 1.5; }
.obc-mv .loc-who,
.obc-mv .loc-when { margin: 0 0 6px; color: var(--mv-slate, #758287); font-size: 14.5px; line-height: 1.5; }

/* the same shape the Finder's directions button uses, so the two pages agree about what it is.
   margin-top auto so it sits on the floor of every card whatever is above it: a row of buttons at
   different heights reads as a row of different things. */
.obc-mv .loc-directions { margin: auto 0 0; padding-top: 14px; }

.obc-mv .loc-directions a {
  display: inline-block;
  min-height: 40px;
  padding: 9px 18px;
  border: 1px solid var(--mv-dark, #294f4b);
  border-radius: 999px;
  color: var(--mv-dark, #294f4b);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.4;
  text-decoration: none;
}

.obc-mv .loc-directions a:hover,
.obc-mv .loc-directions a:focus-visible { background: var(--mv-mist, #f6efe6); }

/* sprint 32 — air between the two buttons, which had none.

   theme.json sets blockGap to 0, so every wp:buttons row on the redesign sits flush: on the homepage
   hero the gold pill's edge is against the ghost's rim with nothing between them. At rest the white
   rim passes for a divider. Filled, it turns dark and the pair reads as one wide object with a line
   down the middle of it, which is what Beth is seeing. The same 0 reaches fifteen rows on ten other
   pages, so it is answered once here rather than on the hero.

   Row gap as well as column: wrapped onto two lines on a phone they were touching the other way. */
.obc-mv .wp-block-buttons {
  gap: clamp(14px, 1.8vw, 22px);
}

.obc-mv .mv-cta .wp-block-button__link,
.obc-mv .mv-cta-ghost .wp-block-button__link {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 999px;
  font-family: var(--mv-display);
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* the label turns a beat after the pour starts, not with it: the milk reaches the words about
     120ms in, and a label that darkens before then is dark type on a photograph */
  transition: transform 0.25s ease, color 0.36s ease 0.14s, border-color 0.36s ease 0.14s;
}

/* sprint 26 — the first button is colostrum, and it is the one thing in the family that holds still.
   Everything else on this page is liquid doing something, and a page where every surface moves has
   no emphasis left to give: the button you are most meant to press earns its weight by being the
   solid one. The colour is set on the block itself so she can see and change it in the editor. */
.obc-mv .mv-cta .wp-block-button__link {
  padding: 17px 34px;
  border: 0;
  color: var(--mv-ink);
  font-weight: 500;
}

/* the second button is the same milk poured thinner, in a glass you can see. Hierarchy has to come
   from somewhere once both are the same liquid, and it comes from the rim and the weight rather than
   from one of them being a different colour. */
.obc-mv .mv-cta-ghost .wp-block-button__link {
  padding: 17px 30px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: transparent;
  color: var(--mv-paper);
  font-weight: 400;
}

/* the label goes dark once there is milk behind it, and not a moment before: white on milk is 1.1.
   The rim turns with it, and for the same reason. A white rim is what an empty glass looks like
   against a photograph and it is what nothing looks like against cream: filled, the edge of a glass
   is the darker line where you are looking through more of it, which is also the only thing keeping
   these two buttons apart now that they hold the same liquid. */
.obc-mv .mv-cta-ghost .wp-block-button__link.is-milky {
  border-color: rgba(41, 79, 75, 0.34);
  color: var(--mv-ink);
}

@media (hover: hover) {
  .obc-mv .mv-cta .wp-block-button__link:hover,
  .obc-mv .mv-cta-ghost .wp-block-button__link:hover {
    transform: translateY(-2px);
  }

  /* the gold one has no liquid to answer with, so it warms instead: the same colostrum a shade
     richer, which is the bottom of the gradient the spheres are drawn with */
  .obc-mv .mv-cta .wp-block-button__link:hover { background-color: var(--mv-gold-deep) !important; }

  /* and the second tops up from a thinner pour to a full one */
  .obc-mv .mv-cta-ghost .wp-block-button__link:hover .mv-milk { background: var(--mv-milk); }
}

/* taller than the glass so that at rest the surface has already gone out through the top: a pill is
   52px of room and a line sitting on its top edge reads as a border, not as milk */
.obc-mv .mv-milk {
  position: absolute;
  z-index: -1;
  right: 0;
  bottom: 0;
  left: 0;
  height: 150%;
  background: var(--mv-milk);
  transform: translateY(100%);
  transition: transform 1.05s cubic-bezier(0.32, 0.02, 0.2, 1), background-color 0.25s ease;
}

/* thin enough to read as a thinner pour, thick enough that a busy photograph does not come through
   it and sit behind the words. 0.82 let a hard diagonal in one of the hero pictures show across the
   label; this does not, and still reads as glass. */
.obc-mv .mv-cta-ghost .mv-milk { background: rgba(255, 255, 255, 0.88); }

/* the surface, the same mint line the spheres carry, and visible only while the pour is running */
.obc-mv .mv-milk::before {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 1.5px;
  background: var(--mv-highlight);
  opacity: 0.55;
  content: "";
}

.obc-mv .wp-block-button__link.is-milky .mv-milk { transform: translateY(0); }

/* the bubbles ride inside the milk rather than inside the button, so none of them can be seen in the
   air above the surface while it is still climbing */
.obc-mv .mv-milk-bubbles {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
}

.obc-mv .mv-milk-bubble {
  position: absolute;
  bottom: -12px;
  border: 1.1px solid rgba(41, 79, 75, 0.42);
  border-radius: 50%;
  background: rgba(41, 79, 75, 0.1);
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .obc-mv .mv-milk { transition: none; }
}

.obc-mv .mv-cta-dark .wp-block-button__link {
  background: var(--mv-dark);
  color: var(--mv-paper);
}

.obc-mv .mv-cta-dark .wp-block-button__link:hover {
  background: var(--mv-deep);
}

/* ---------- section furniture ---------- */
.obc-mv .mv-section {
  padding: clamp(72px, 11vw, 148px) 0;
}

.obc-mv .mv-cream {
  background: var(--mv-cream);
}

.obc-mv .mv-dark {
  background: var(--mv-dark);
  color: var(--mv-paper);
}

.obc-mv .mv-kicker {
  margin: 0 0 clamp(24px, 3vw, 36px);
  color: var(--mv-muted);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.obc-mv .mv-dark .mv-kicker {
  color: var(--mv-highlight);
}

.obc-mv .mv-lede {
  max-width: 20ch;
  margin: 0 0 clamp(24px, 3vw, 40px);
  font-size: clamp(30px, 4.4vw, 56px);
  line-height: 1.06;
}

.obc-mv .mv-body {
  max-width: 62ch;
  margin: 0 0 20px;
  color: var(--mv-muted);
  font-size: clamp(16px, 1.3vw, 19px);
  line-height: 1.65;
}

.obc-mv .mv-dark .mv-body {
  color: rgba(255, 255, 255, 0.76);
}

/* ---------- the statistics band ---------- */
/* sprint 26 — a grid, not a flex row, and the reason is worth keeping.
 *
 * This is the first thing after the hero and the clinic's strongest claim, so the spheres get room
 * to make it. Reaching that through flex failed three times: columns in a flex row stretch to a
 * common height, so a square one is impossible and the shape came out a wide oval; told not to
 * stretch, their aspect ratio drove their width instead and four of them overflowed the row; and a
 * breakpoint adding flex-wrap lost to WordPress's own column rules. A grid asks for none of it. The
 * cell is as wide as its track and as tall as it is wide, and auto-fit decides how many fit in a row
 * without a single breakpoint to keep in step.
 *
 * It steps out of the 1240 measure the prose sits in, because four spheres inside that are badges. */
.obc-mv .mv-stats.wp-block-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(248px, 100%), 1fr));
  align-items: start;
  gap: clamp(14px, 2vw, 32px);
  margin: clamp(52px, 7vw, 96px) calc(50% - 50vw + var(--mv-gutter)) clamp(40px, 5vw, 64px);
}

/* the dividing lines went with the ring layout: a rule between two circles reads as a cage around
   them, and the shapes separate themselves */
.obc-mv .mv-stat.wp-block-column {
  position: relative;
  display: flex;
  flex-direction: column;
  /* centred on both axes by the flex container rather than by auto margins on each child: the
     margins were not winning and the number sat up to 57px left of the sphere's middle */
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  /* the type inside is sized from THIS box rather than from the window. The grid decides how many
     spheres are in a row, so the window and the sphere size stop tracking each other: at 768px the
     grid gave 338px spheres while the window-based scale gave them a 34px number, and at 540px an
     486px sphere got the same. A percentage of the sphere is right at every width and needs no
     breakpoints at all. */
  container-type: inline-size;
  padding: 13% 17%;
  text-align: center;
  /* these are tapped, and a tap that drifts a pixel selects a word */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  cursor: pointer;
}

/* sprint 25 — a ring around each research figure, drawn to that figure's own value. The figure
   becomes a square the number sits in the middle of, and the ring is laid over that square on a
   layer beneath the number, the way everything else that glows on this page is. */
/* the sphere is sized from the cell and centred in it. See assets/js/stats.js for the liquid. */
.obc-mv .mv-stat-orb {
  position: absolute;
  z-index: 0;
  top: 50%;
  left: 50%;
  width: 100%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%) scale(0.74);
  opacity: 0;
  transition: transform 0.72s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.42s ease;
  pointer-events: none;
}

.obc-mv .mv-stat.is-filled .mv-stat-orb {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
}

.obc-mv .mv-stat-figure,
.obc-mv .mv-stat-caption {
  position: relative;
  z-index: 1;
  /* the box hugs the glyphs rather than spanning the cell. A heading is a block, so its box was the
     full width of the sphere while the number sat centred and narrow inside it, which made every
     measurement of whether the words fit read as an overflow that was not there. */
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  transition: color 0.5s ease;
}

/* the words go dark once the liquid is behind them, held until it has passed */
.obc-mv .mv-stat.is-filled .mv-stat-figure,
.obc-mv .mv-stat.is-filled .mv-stat-caption {
  color: #1f2c31;
}

@media (prefers-reduced-motion: reduce) {
  .obc-mv .mv-stat-orb,
  .obc-mv .mv-stat-figure,
  .obc-mv .mv-stat-caption {
    transition: none;
  }
}

.obc-mv .mv-stat-figure {
  margin: 0 0 5cqw;
  color: var(--mv-paper);
  /* every digit the same width, so nothing shifts as the number counts up */
  font-variant-numeric: tabular-nums;
  font-size: clamp(34px, 31cqw, 104px);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.03em;
}

.obc-mv .mv-stat-figure .mv-unit {
  font-size: 0.52em;
  vertical-align: baseline;
}

.obc-mv .mv-stat-caption {
  max-width: 18ch;
  margin: 0 auto;
  color: rgba(255, 255, 255, 0.74);
  font-size: clamp(12px, 8.4cqw, 24px);
  line-height: 1.38;
}

.obc-mv .mv-source {
  max-width: 78ch;
  margin: 0;
  color: rgba(255, 255, 255, 0.5);
  font-size: 13px;
  line-height: 1.6;
}

.obc-mv .mv-source a {
  color: rgba(255, 255, 255, 0.72);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* sprint 25 — the hero is a slideshow rather than one photograph.

   The pictures after the first live in the page as a gallery, so they can be added to, reordered or
   swapped in the WordPress editor like any other block. This hides that gallery: the script reads
   the addresses out of it and does the showing itself. */
.obc-mv .mv-hero-slides {
  display: none;
}

/* the layers the script builds, stacked between the cover's own photograph and its scrim */
.obc-mv .mv-hero .mv-slide {
  position: absolute;
  z-index: 1;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  /* long enough to be a dissolve rather than a cut, short enough not to spend the whole hold in it */
  transition: opacity 1.0s ease;
}

.obc-mv .mv-hero .mv-slide.is-showing {
  opacity: 1;
}

/* a slow push in, so a still photograph is not simply sitting there for six seconds. It runs the
   whole time the picture is up and resets when the picture is next shown. */
@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-hero .mv-slide.is-showing {
    animation: mv-hero-press 9s ease-out both;
  }
}

@keyframes mv-hero-press {
  from { transform: scale(1); }
  to { transform: scale(1.06); }
}

/* the cover's own parts, given explicit layers. Without them the scrim can end up under the slides,
   and every word in the hero would be sitting on an undimmed photograph. */
.obc-mv .mv-hero > img.wp-block-cover__image-background { z-index: 0; }
.obc-mv .mv-hero > .wp-block-cover__background { z-index: 2; }
.obc-mv .mv-hero > .wp-block-cover__inner-container { z-index: 3; }

/* ---------- three ways in ---------- */
/* sprint 25 — the pathway cards are jars that fill with milk, chosen in the button lab over the
   photograph cards that were here before. The photographs carried no information and were the
   reason the cards needed a scrim at all.

   Ink cards on a light band, not the other way round: the milk is the page's own cream, so it needs
   the darkest card we have behind it or the surface has nothing to show against. */
.obc-mv .mv-paths.wp-block-columns {
  gap: clamp(16px, 2vw, 28px);
  margin-top: clamp(32px, 5vw, 56px);
}

/* the jar has to fill its column, or three cards of different copy lengths hold different levels */
.obc-mv .mv-paths .wp-block-column {
  display: flex;
}

.obc-mv .mv-jar {
  --milk-level: 0px;
  --jar-x: 0px;
  --row-w: 100%;
  /* wavelengths, named because the drift has to travel exactly one tile or the loop shows a seam */
  --tile-back: 760px;
  --tile-front: 420px;

  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: clamp(300px, 30vw, 350px);
  /* deep top padding on purpose: the milk stops at the title, so this gap is the air above the
     surface. Without it the crests reach the ceiling and the wave flattens against it. */
  padding: clamp(66px, 7vw, 88px) clamp(24px, 2.4vw, 32px) clamp(24px, 2.4vw, 32px);
  overflow: hidden;
  border-radius: 2px;
  background: var(--mv-dark);
  color: var(--mv-cream);
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* one body of milk, not three. The fill is as wide as the whole row and shifted left by the card's
   own offset within it, so the surface drawn in every card is the same surface: each card is a
   window onto one liquid rather than a jar of its own. */
.obc-mv .mv-jar-fill {
  position: absolute;
  bottom: 0;
  left: calc(-1 * var(--jar-x));
  width: var(--row-w);
  height: 132%;
  /* white, not cream: on this sand band a cream body dissolves into the page and the card loses its
     own edge below the surface. White also happens to be what milk is. */
  background: var(--mv-paper);
  transform: translateY(100%);
  /* slow: this is a pour, not a state change */
  transition: transform 2.6s cubic-bezier(0.32, 0.02, 0.2, 1);
}

/* The surface: two waves travelling sideways, rather than a curved top edge. A curve drawn on the
   box always peaks in the middle of that box, which gives every card its own hill; a repeating
   profile sliding past has no middle. Each strip straddles the milk line, so its crests rise above
   the level and its troughs cut below it. */
/* sprint 26 — each strip is one wavelength wider than the card and is slid by exactly that much,
   rather than having its background-position animated underneath it.
   background-position cannot be composited: every frame of it is a repaint of a strip as wide as the
   whole row, on the main thread, forever, whether or not anybody is looking at the card. Sliding the
   element instead is the same picture moving the same distance, handed to the compositor. The extra
   wavelength is what stops the far edge showing as it travels, and the jar clips it. */
.obc-mv .mv-jar-fill::before,
.obc-mv .mv-jar-fill::after {
  position: absolute;
  background-repeat: repeat-x;
  content: "";
}

/* the long, slow swell behind, translucent so it reads as depth rather than a second edge */
.obc-mv .mv-jar-fill::before {
  right: 0;
  bottom: calc(100% - 27px);
  /* one wavelength of runway on the side it travels away from */
  left: calc(-1 * var(--tile-back));
  height: 54px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0,20 C40,0 80,40 120,20 C160,0 200,40 240,20 L240,40 L0,40 Z' fill='%23ffffff' fill-opacity='.5'/%3E%3C/svg%3E");
  background-size: var(--tile-back) 100%;
  animation: milk-drift-back 23s linear infinite, milk-heave 9s ease-in-out infinite;
}

/* the smaller, quicker wave in front, in the same cream as the body so its trough is the visible
   edge. The two wavelengths never divide evenly, so the crests meet somewhere different every pass
   and the line never settles into a loop you can spot. */
.obc-mv .mv-jar-fill::after {
  right: calc(-1 * var(--tile-front));
  bottom: calc(100% - 17px);
  left: 0;
  height: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0,20 C40,0 80,40 120,20 C160,0 200,40 240,20 L240,40 L0,40 Z' fill='%23ffffff'/%3E%3C/svg%3E");
  background-size: var(--tile-front) 100%;
  animation: milk-drift-front 13s linear infinite, milk-heave 6.5s ease-in-out -2.2s infinite;
}

/* hover sends bubbles up through the milk. They live in a box that is exactly the milk in this
   card, so they can never be seen in the air above the surface. */
.obc-mv .mv-jar-bubbles {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  height: var(--milk-level);
  overflow: hidden;
  pointer-events: none;
}

/* sprint 26 — a bubble is a rim with almost nothing in it.
   It was a white disc at 0.62 with a rim at 0.2, on white milk: the body was invisible by definition
   and the rim was doing the whole job at a fifth of the strength it needed. Inverted here, and the
   same numbers the spheres use, so the site has one bubble rather than two. */
.obc-mv .mv-bubble {
  position: absolute;
  bottom: -18px;
  border: 1.1px solid rgba(41, 79, 75, 0.42);
  border-radius: 50%;
  background: rgba(41, 79, 75, 0.1);
  opacity: 0;
}

/* ---------- sprint 26 — the two jars hold two liquids ----------
 *
 * Her idea, and the best one on this page: the card for the family still waiting holds colostrum,
 * and the card for the family whose baby has arrived holds colostrum turning into milk. The change
 * on the second one is the same five seconds the spheres take, so the page says the same thing twice
 * in two places rather than doing a trick in one of them.
 *
 * The turn is built the way the spheres build it, with a second body of liquid laid over the first
 * and faded up, rather than by animating a colour: the surface is a repeating image and there is no
 * way to interpolate one of those. It also means the pour and the turn stay independent — the milk
 * arrives on a card that is already full, which is what turning is.
 *
 * The waves are duplicated per liquid because a data URI cannot take a variable. That is the price
 * of drawing the surface as an image, and the alternative — masking a shape and colouring it — is a
 * larger change to the one part of this file that has never given trouble.
 *
 * One honest note. The fill spans the whole row so the two cards read as one body of liquid seen
 * through two windows, and two different liquids at one level is not a thing that happens in a jar.
 * The meaning is worth more than the physics here, but it is a real seam and it is deliberate. */
/* sprint 27 — the four-stop ramp from the statistics spheres, not the flat gold. Flat, over an area
   this size, reads as brown; the ramp is what makes it colostrum. Same stops and same direction as
   stats.js, palest at the surface and deepening with depth, which is how the real thing looks in a
   jar.

   Sized to `--milk-level` rather than to the element. The fill is 132% of the card and spends most of
   its life below it, so a gradient measured against the element would spend its whole range off
   screen and only ever show the palest third — the deep end would never arrive. `--milk-level` is the
   distance from the card's foot to the surface, which is exactly the liquid you can see, so the ramp
   lands whole inside it at any card height and on a phone as well as a desk. The flat colour behind
   is what fills the element below the card, where nothing is ever looked at. */
.obc-mv .mv-jar-colostrum .mv-jar-fill,
.obc-mv .mv-jar-turns .mv-jar-fill {
  background:
    linear-gradient(
      180deg,
      /* sprint 27 — the surface layer, held at one colour for the first 28px. This is not a styling
         flourish, it is what stops the banding under the title.

         The two wave strips are painted a single flat colour and their solid halves hang below the
         line: the front one 17px down, the back one 27px. Against the old flat body that was
         invisible, a colour over itself. Against a ramp it is not: the body darkens with depth while
         the strips stay pale, so their footprints showed as two pale steps with hard edges, and the
         lower one moved, because both strips heave 5px up and down as they travel. That is the band
         reported under "Waiting for baby".

         Holding the body at the strips' own colour for slightly deeper than the deepest strip makes
         them a colour over itself again, exactly as before, so both edges vanish. The ramp then
         starts below anything the strips can reach, even at the top of their heave. It also happens
         to be how the real thing looks: the lit surface of a liquid is flatter than its depth.

         28px against a 178px pour on the smallest card, so the ramp keeps almost all of its run. */
      var(--mv-gold-pale) 0,
      var(--mv-gold-pale) 28px,
      var(--mv-gold) 34%,
      var(--mv-gold-deep) 68%,
      var(--mv-gold-deepest) 100%) top / 100% var(--milk-level) no-repeat,
    var(--mv-gold-deepest);
}

/* The swell behind, in colostrum — and it has to be the body colour AT THE SURFACE, not a paler one
   and no longer the flat gold.
   Both surface strips are rectangles that hang below the milk line: the front one covers the top
   17px of the liquid and the back one the top 27px, so there is a 10px band where only the back one
   is drawn. In white that band is white at half strength over white and cannot be seen. Painted a
   paler gold it became a lighter stripe with a hard edge top and bottom, sitting just under the
   waves and rising with the pour — which is exactly what it was reported as.

   sprint 27 — the body is a ramp now, so "the body colour" is no longer one value: at the top of the
   liquid, which is the only place these strips touch, it is the palest stop. Painting them #e9c471 as
   they were would put the old stripe back the other way up, a darker band across the surface. They
   move to the palest stop for the same reason they were the body colour before: invisible below the
   line, a translucent crest above it. If the first stop of the ramp changes, these change with it. */
.obc-mv .mv-jar-colostrum .mv-jar-fill::before,
.obc-mv .mv-jar-turns .mv-jar-fill::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0,20 C40,0 80,40 120,20 C160,0 200,40 240,20 L240,40 L0,40 Z' fill='%23f6e2b0' fill-opacity='.5'/%3E%3C/svg%3E");
}

.obc-mv .mv-jar-colostrum .mv-jar-fill::after,
.obc-mv .mv-jar-turns .mv-jar-fill::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0,20 C40,0 80,40 120,20 C160,0 200,40 240,20 L240,40 L0,40 Z' fill='%23f6e2b0'/%3E%3C/svg%3E");
}

/* The milk that arrives on top of it. It carries mv-jar-fill too, so it pours and sits exactly where
   the colostrum does and needs nothing said about its geometry; these rules come after the colostrum
   ones on purpose, since the two selectors weigh the same and the later one has to win. */
.obc-mv .mv-jar-turns .mv-jar-later {
  background: var(--mv-milk);
  opacity: 0;
  transition: opacity 5s ease-in-out, transform 2.6s cubic-bezier(0.32, 0.02, 0.2, 1);
}

.obc-mv .mv-jar-turns .mv-jar-later::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0,20 C40,0 80,40 120,20 C160,0 200,40 240,20 L240,40 L0,40 Z' fill='%23ffffff' fill-opacity='.5'/%3E%3C/svg%3E");
}

.obc-mv .mv-jar-turns .mv-jar-later::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0,20 C40,0 80,40 120,20 C160,0 200,40 240,20 L240,40 L0,40 Z' fill='%23ffffff'/%3E%3C/svg%3E");
}

.obc-mv .mv-jar-turns.is-turning .mv-jar-later { opacity: 1; }

/* a bubble takes the colour of what it is floating in. White on gold, as the spheres do, and back
   to the dark rim once the milk has arrived — held on a transition so the few still climbing at the
   moment of the change cross over with the liquid rather than snapping. */
.obc-mv .mv-jar-colostrum .mv-bubble,
.obc-mv .mv-jar-turns .mv-bubble {
  border-color: rgba(163, 116, 31, 0.5);
  background: rgba(255, 250, 240, 0.82);
  transition: background-color 1.2s ease, border-color 1.2s ease;
}

.obc-mv .mv-jar-turns.is-turned .mv-bubble {
  border-color: rgba(41, 79, 75, 0.42);
  background: rgba(41, 79, 75, 0.1);
}

/* the copy, and only the copy: the fill and the bubbles are the liquid and place themselves */
.obc-mv .mv-jar > *:not(.mv-jar-fill):not(.mv-jar-bubbles) {
  position: relative;
  z-index: 2;
}

.obc-mv .mv-jar-title {
  margin: 0 0 10px;
  color: inherit;
  font-size: clamp(22px, 2.4vw, 30px);
  line-height: 1.12;
  transition: color 0.9s ease 1.5s;
}

.obc-mv .mv-jar-note {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  opacity: 0.82;
  transition: color 0.9s ease 1.1s;
}

.obc-mv .mv-jar .wp-block-buttons {
  margin-top: auto;
  padding-top: 22px;
}

.obc-mv .mv-jar .wp-block-button {
  width: 100%;
}

/* a core button so the owner can edit the label and the link, dressed as the lab's foot label:
   a solid bar would be swallowed by the milk rising past it */
.obc-mv .mv-jar-link .wp-block-button__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  /* sprint 27 — colostrum, at the owner's request. These two labels are the entrances to the Finder,
     and they were milk, which made them the same colour as every other piece of text on the card.
     In colostrum they read as the way in, and they match the liquid the card is filled with.
     Approved by name in BRAND.md: this is the material's flat form, not a loose gold.
     5.44:1 against the card's dark green, so it still clears the 4.5 the standard asks for. */
  color: var(--mv-gold);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  transition: color 0.9s ease 0.5s;
}

/* Once the jar has poured, the card behind this label IS colostrum, and a colostrum label on it
   would disappear into its own liquid. The card already turns its text to ink at that moment and
   the label used to follow by inheritance; now that it states a colour of its own, it has to be
   told the same thing explicitly. Declared before the hover rule below so hover still wins. */
.obc-mv .mv-jar.is-poured .mv-jar-link .wp-block-button__link {
  color: var(--mv-ink);
}

.obc-mv .mv-jar-link .wp-block-button__link::after {
  content: "\2192";
  transition: transform 0.3s ease;
}

/* poured: settles at the top of the title. The surface keeps travelling on its own, so nothing here
   needs to animate afterwards. */
.obc-mv .mv-jar.is-poured .mv-jar-fill {
  transform: translateY(calc(100% - var(--milk-level)));
}

.obc-mv .mv-jar.is-poured {
  color: var(--mv-ink);
}

/* the card takes the click, so it has to look like it does. The class is added by the script: the
   pointer would be lying about a card that nothing is listening to. */
.obc-mv .mv-jar.is-clickable {
  cursor: pointer;
}

/* the fill no longer answers the pointer, so hover has to say "clickable" some other way */
@media (hover: hover) {
  .obc-mv .mv-jar:hover { transform: translateY(-4px); }
  .obc-mv .mv-jar:hover .wp-block-button__link::after { transform: translateX(5px); }

  /* the label is the card's own hover state now, so it has to move with the rest of it */
  .obc-mv .mv-jar:hover .mv-jar-link .wp-block-button__link {
    color: var(--mv-deep);
  }
}

/* one tile exactly, so the loop has no seam. Opposite directions, so the two never lock together. */
@keyframes milk-drift-back {
  from { translate: 0 0; }
  to { translate: var(--tile-back) 0; }
}

@keyframes milk-drift-front {
  from { translate: 0 0; }
  to { translate: calc(-1 * var(--tile-front)) 0; }
}

/* the whole surface rising and falling, which a sideways drift alone cannot do */
@keyframes milk-heave {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}

/* rising, drifting off true, and swelling on the way up as the pressure drops. It fades before it
   reaches the line rather than popping through it, because the surface above is already busy. */
@keyframes milk-bubble {
  0% { opacity: 0; transform: translate(0, 0) scale(0.55); }
  14% { opacity: 0.9; }
  50% { transform: translate(var(--drift), calc(var(--rise) * -0.5)) scale(1); }
  78% { opacity: 0.8; }
  100% { opacity: 0; transform: translate(calc(var(--drift) * -0.6), calc(var(--rise) * -1)) scale(1.2); }
}

@media (prefers-reduced-motion: reduce) {
  .obc-mv .mv-bubble,
  .obc-mv .mv-jar-fill,
  .obc-mv .mv-jar-fill::before,
  .obc-mv .mv-jar-fill::after,
  .obc-mv .mv-jar.is-poured .mv-jar-fill {
    animation: none !important;
    transition: none !important;
  }
}

@media (max-width: 781px) {
  /* a phone card is a narrower window, so the same wavelength would show barely half a crest */
  .obc-mv .mv-jar {
    --tile-back: 400px;
    --tile-front: 240px;

    min-height: 236px;
    padding: 58px 24px 24px;
  }
}

/* ---------- split feature ---------- */
.obc-mv .mv-split.wp-block-columns {
  gap: clamp(32px, 6vw, 88px);
  align-items: center;
}

.obc-mv .mv-split figure {
  margin: 0;
}

.obc-mv .mv-split img {
  width: 100%;
  height: auto;
  border-radius: 2px;
}

.obc-mv .mv-points {
  margin: 28px 0 32px;
  padding: 0;
  list-style: none;
}

.obc-mv .mv-points li {
  position: relative;
  margin: 0 0 14px;
  padding-left: 26px;
  color: var(--mv-muted);
  font-size: 16px;
  line-height: 1.6;
}

.obc-mv .mv-points li::before {
  position: absolute;
  top: 0.62em;
  left: 0;
  width: 10px;
  height: 1px;
  background: var(--mv-brand);
  content: "";
}

/* sprint 25 — the sentence takes the gold the number gave up. Not a copy of it: the fireflies carry
   it across and this is where they put it down.

   The cross-fade is done on the text fill rather than by stacking a second copy of the sentence on
   top. The gold sits behind the letters from the moment the class lands, hidden by a fill that is
   still the mist colour, and the fill is what animates to transparent — so the gold rises through
   the words themselves. A duplicate would have had to reproduce the italic inside the sentence, and
   would have drifted the moment anybody edited it. */
.obc-mv .mv-lede.is-gilded {
  background-image:
    linear-gradient(104deg, rgba(255, 255, 255, 0) 40%, rgba(255, 252, 238, 0.92) 49%, rgba(255, 255, 255, 0) 59%),
    linear-gradient(
      177deg,
      #7a5312 0%,
      #b8842c 14%,
      #e9c471 30%,
      #fff4d2 46%,
      #f0d18d 52%,
      #b07f28 58%,
      #8a5f18 66%,
      #dcb45f 80%,
      #f6e2b0 90%,
      #a3741f 100%);
  background-repeat: no-repeat;
  background-size: 240% 100%, 100% 100%;
  background-position: 0% 0, 0 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  transition: -webkit-text-fill-color 1.2s ease 0.15s;
}

/* the same travelling highlight the number had, so what arrived is recognisably what left */
@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-lede.is-gilded {
    animation: mv-sheen 9s ease-in-out infinite;
  }
}

/* sprint 25 — a firefly sits on every point, from the moment the page loads rather than only once
   the number has been clicked. Almost nobody clicks, and these are the best thing in the column: a
   soft gold bloom breathing on its own slow period, the way the drifting forms in the motion lab do,
   each on a different one so the list never pulses in step.

   The fireflies that fly down from the number still arrive here. They now join lights that are
   already burning instead of switching them on. */
.obc-mv .mv-points li::before {
  top: calc(0.62em - 4px);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff6e4 0%, #e8c68d 45%, rgba(226, 178, 110, 0.6) 100%);
  box-shadow: 0 0 10px 2px rgba(232, 198, 141, 0.4);
}

@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-points li::before {
    animation: mv-settled 9s ease-in-out infinite;
  }

  /* periods that share no common factor, so the column never falls into step with itself */
  .obc-mv .mv-points li:nth-child(2)::before { animation-duration: 13s; }
  .obc-mv .mv-points li:nth-child(3)::before { animation-duration: 17s; }
  .obc-mv .mv-points li:nth-child(4)::before { animation-duration: 23s; }
  .obc-mv .mv-points li:nth-child(5)::before { animation-duration: 11s; }
  .obc-mv .mv-points li:nth-child(6)::before { animation-duration: 19s; }
}

/* landed, not switched on: it keeps breathing, and never goes fully dark */
@keyframes mv-settled {
  0%, 100% {
    opacity: 0.62;
    box-shadow: 0 0 8px 1px rgba(232, 198, 141, 0.3);
    transform: scale(0.88);
  }
  50% {
    opacity: 1;
    box-shadow: 0 0 18px 5px rgba(232, 198, 141, 0.55);
    transform: scale(1.08);
  }
}

/* ---------- quote ---------- */
/* sprint 25 — the quote is read looking down at a pool of milk. The band it sits on is that surface,
   the words rise up through it the first time anybody scrolls this far, and the rings spread from
   where they broke it.

   Rings sit on a layer beneath the words for the same reason the fireflies do: a ripple that passes
   over a letter is a decal, and one that passes under it is a surface. */
.obc-mv .mv-section.is-pool {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  /* barely a colour. Left pure white this reads as a page; warmed by this much it reads as milk,
     and the rings have something to be rings in. */
  background: radial-gradient(130% 90% at 50% 38%, #ffffff 0%, #f6efe6 100%);
  /* the whole band answers a click, and clicking the same words repeatedly is how a browser is told
     to select them */
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* sprint 26 — quieter, and taking its time about it.
   The band was reading as a splash: three broad doughnuts crossing the whole width inside two
   seconds, over words that arrived from 18px of blur. It is a pool being rested on, not something
   dropped into. The geometry is unchanged and only the strength is down, because a wide soft band
   at low opacity is what milk moving looks like; a narrow one at the same weight is a drawn circle. */
.obc-mv .mv-drop {
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  /* a band rather than a border: a hard outline reads as a circle drawn on milk, and a soft one
     reads as milk moving */
  background: radial-gradient(circle,
    rgba(255, 255, 255, 0) 52%,
    rgba(206, 190, 160, 0.26) 63%,
    rgba(224, 212, 188, 0.14) 71%,
    rgba(255, 255, 255, 0) 78%);
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.04);
}

@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-drop {
    animation: mv-spread var(--spread, 2.4s) cubic-bezier(0.17, 0.72, 0.28, 1) var(--after, 0s) both;
  }
}

/* out and gone. It slows as it widens, the way a ring on water loses its push. It also comes up
   more gradually than it did: a ring at full strength by 12% arrives as a flash. */
@keyframes mv-spread {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.04); }
  22% { opacity: calc(0.44 * var(--strength, 1)); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1); }
}

/* under the surface, then through it: out of focus and low before it breaks, sharp once it is up */
@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-quote.is-below,
  .obc-mv .mv-quote-source.is-below {
    opacity: 0;
  }

  /* sprint 26 — 1.9s with a spring on the end of it, from 18px of blur, was a reveal. This is the
     same idea at half the amplitude over nearly twice the time, on an easing curve with no snap in
     it: the words settle rather than land. */
  .obc-mv .mv-quote.is-surfacing,
  .obc-mv .mv-quote-source.is-surfacing {
    animation: mv-surface 3.4s cubic-bezier(0.25, 0.55, 0.3, 1) both;
  }

  .obc-mv .mv-quote-source.is-surfacing {
    animation-delay: 1s;
  }
}

@keyframes mv-surface {
  0% { opacity: 0; filter: blur(7px); transform: translateY(9px) scale(0.99); }
  55% { opacity: 1; }
  100% { opacity: 1; filter: blur(0); transform: none; }
}

.obc-mv .mv-quote {
  max-width: 24ch;
  margin: 0 auto;
  font-size: clamp(26px, 3.6vw, 46px);
  font-weight: 300;
  line-height: 1.16;
  text-align: center;
  text-wrap: balance;
}

.obc-mv .mv-quote-source {
  margin: clamp(20px, 3vw, 28px) 0 0;
  color: var(--mv-muted);
  font-size: 13px;
  letter-spacing: 0.14em;
  text-align: center;
  text-transform: uppercase;
}

/* ---------- closing ---------- */
.obc-mv .mv-close {
  text-align: center;
}

.obc-mv .mv-close .mv-lede {
  max-width: 26ch;
  margin-right: auto;
  margin-left: auto;
}

.obc-mv .mv-close .mv-body {
  margin-right: auto;
  margin-left: auto;
  text-align: center;
}

/* ---------- entrance, one orchestrated load ---------- */
@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-hero .mv-eyebrow,
  .obc-mv .mv-hero .mv-hero-title,
  .obc-mv .mv-hero .mv-hero-sub,
  .obc-mv .mv-hero .wp-block-buttons {
    animation: mv-rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) backwards;
  }

  .obc-mv .mv-hero .mv-eyebrow { animation-delay: 0.05s; }
  .obc-mv .mv-hero .mv-hero-title { animation-delay: 0.16s; }
  .obc-mv .mv-hero .mv-hero-sub { animation-delay: 0.28s; }
  .obc-mv .mv-hero .wp-block-buttons { animation-delay: 0.34s; }
}

@keyframes mv-rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}

/* sprint 26 — the rules that ruled a line between each stacked figure went with the ring layout: a
   line between two spheres reads as a cage around them, and they separate themselves.

   The type below is keyed to how many spheres are in a row, not to the window. The grid drops to one
   across at about 540px, and only there is a sphere nearly the width of the screen and able to carry
   a 70px number. Keyed to the window instead, a 600px screen kept the one-across sizes while the
   grid had already gone to two, and a 92px number was dropped into a 263px sphere. */
@media (max-width: 781px) {
  .obc-mv .mv-hero-title {
    max-width: none;
  }
}

/* sprint 14 — centring for the closing call to action, previously carried by a layout attribute */
.obc-mv .mv-close .wp-block-buttons {
  justify-content: center;
}

/* sprint 15 — additions for the Emma-voice version, which reuses this first-pass look exactly:
   a hero text link beside the two buttons, a lead-in above the pull quote, and the approved logo. */
.obc-mv .mv-logo {
  margin: 0 0 clamp(18px, 3vw, 26px);
}

/* width only, so the browser keeps the file's 1:1 ratio; no filter, recolour or crop */
.obc-mv .mv-logo img {
  width: clamp(116px, 12vw, 164px);
  height: auto;
}

.obc-mv .mv-hero-link {
  margin: clamp(18px, 2.5vw, 24px) 0 0;
  font-size: 14px;
}

.obc-mv .mv-hero-link a {
  color: var(--mv-highlight);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.obc-mv .mv-hero-link a:hover {
  color: var(--mv-paper);
}

.obc-mv .mv-quote-lead {
  margin: 0 0 clamp(14px, 2vw, 20px);
  color: var(--mv-muted);
  font-size: 13px;
  letter-spacing: 0.18em;
  text-align: center;
  text-transform: uppercase;
}

.obc-mv .mv-secondary-link {
  margin: clamp(22px, 3vw, 32px) 0 0;
  color: var(--mv-muted);
  font-size: 14px;
}

.obc-mv .mv-secondary-link a {
  color: var(--mv-ink);
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* a card with no photograph behind it, for the Finder pathway */
.obc-mv .mv-tile-plain {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(360px, 40vw, 460px);
  padding: clamp(24px, 3vw, 36px);
  border: 1px solid var(--mv-brand);
  border-radius: 2px;
  background: var(--mv-cream);
}

.obc-mv .mv-tile-plain .mv-path-title {
  color: var(--mv-ink);
}

.obc-mv .mv-tile-plain .mv-path-note {
  color: var(--mv-muted);
}

.obc-mv .mv-tile-plain .mv-path-link .wp-block-button__link {
  border-bottom-color: var(--mv-ink);
  color: var(--mv-ink);
}

.obc-mv .mv-tile-plain .mv-path-link .wp-block-button__link:hover {
  border-bottom-color: var(--mv-brand);
  color: var(--mv-brand);
}

/* sprint 16 — the lactation consultant carousel.

   Built on scroll-snap rather than a transform track, so swiping on a phone, two-finger scrolling
   on a trackpad, and tabbing between the profile links all work without any script. The arrows and
   the progress rail are enhancement only and stay hidden until the script wires them up. */
.obc-mv .mv-lc-section {
  overflow: hidden;
}

/* sprint 25 — this section's own heading is centred over the row. Scoped to the carousel: every
   other band on the page still reads from the left margin, and that difference is the point. The
   auto margins matter as much as the alignment, because the lede and the body are both narrower
   than the column and would otherwise sit centred text in a left-hand block. */
.obc-mv .mv-lc-section .mv-kicker,
.obc-mv .mv-lc-section .mv-lede,
.obc-mv .mv-lc-section .mv-body {
  margin-right: auto;
  margin-left: auto;
  text-align: center;
}

.obc-mv .mv-lc-track {
  /* sprint 25 — the row is as wide as the window and runs off the right edge, rather than stopping
     at the measure the rest of the page keeps to. A row that ends where the text ends looks like a
     list of everyone there is; a row that leaves the screen says there is more, which for sixteen
     consultants is the truer thing to say.

     Cards come to rest in the middle of the window rather than against the left margin. The side
     padding is what makes that possible at all: a card can only reach the centre if there is half a
     screen of empty track either side of the row for it to sit in. It is worked out from the track's
     own width rather than from the viewport, because a vw unit counts the scrollbar and would push
     the whole page sideways by its width. */
  --lc-card: clamp(232px, 24vw, 288px);
  --lc-inset: calc((100% - var(--lc-card)) / 2);

  display: flex;
  gap: 24px;
  width: 100%;
  max-width: none;
  margin: clamp(28px, 4vw, 44px) auto 0;
  padding: 4px var(--lc-inset) 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* none: with centre alignment the snap point is the middle of the scrollport, and any scroll
     padding would shift that middle off the middle of the window */
  scroll-padding: 0;
  /* sprint 16 — hide the native scrollbar. The thin rail below the cards is the progress indicator;
     a styled scrollbar sitting directly under it read as a second, competing progress bar. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.obc-mv .mv-lc-track::-webkit-scrollbar {
  display: none;
}

.obc-mv .mv-lc-card {
  position: relative;
  display: flex;
  flex: 0 0 var(--lc-card);
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(392px, 41vw, 476px);
  overflow: hidden;
  border-radius: 4px;
  background: var(--mv-cream);
  scroll-snap-align: center;
  /* sprint 25 — one card per gesture, however hard the row is thrown. This is the speed limit: a
     flick that would otherwise sail past a dozen cards, faster than they can be painted, is stopped
     at the very next one. It is also the calmer way to read a row of people. */
  scroll-snap-stop: always;
}

.obc-mv .mv-lc-photo {
  position: absolute;
  inset: 0;
  margin: 0;
}

.obc-mv .mv-lc-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

/* sprint 25 — a grid rather than a stack, so the languages can sit beside the profile link instead
   of on a line of their own. Only three of the sixteen carry them, and the track stretches every
   card to the tallest, so one extra line anywhere would have raised the whole row. */
.obc-mv .mv-lc-body {
  position: relative;
  z-index: 1;
  display: grid;
  flex: 0 0 auto;
  grid-template-columns: auto 1fr;
  column-gap: 12px;
  padding: 18px 20px 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  /* sprint 28 — Deep Green at the same weight. This was rgba(7, 46, 45), the near-black green the
     palette sweep retired everywhere else, and it was left behind here because an rgba is easy to
     miss. It also has to match the team page, which uses the same pane. */
  background: rgba(41, 79, 75, 0.78);
  color: #fff;
}

/* without a backdrop filter the panel has to carry the legibility on its own */
@supports ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .obc-mv .mv-lc-body {
    /* measured against all sixteen portraits: at half strength the palest of them still puts white
       type at 5.6:1 and the small credentials line at 4.9:1, both clear of the 4.5:1 floor. Any
       lighter and the credentials fail on one card. */
    background: rgba(7, 46, 45, 0.5);
    -webkit-backdrop-filter: blur(60px) saturate(150%);
    backdrop-filter: blur(60px) saturate(150%);
  }
}

.obc-mv .mv-lc-name {
  grid-area: 1 / 1 / 2 / 3;
  margin: 0 0 4px;
  color: #fff;
  font-size: 19px;
  line-height: 1.25;
  text-align: left;
}

.obc-mv .mv-lc-creds {
  grid-area: 2 / 1 / 3 / 3;
  margin: 0 0 10px;
  color: rgba(255, 255, 255, 0.9);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* the last row, to the right of the link and hard against the edge. It must not wrap: a second line
   here is a second line on all sixteen cards. */
.obc-mv .mv-lc-note {
  grid-area: 3 / 2 / 4 / 3;
  align-self: center;
  justify-self: end;
  margin: 0;
  color: rgba(255, 255, 255, 0.9);
  font-size: 11px;
  letter-spacing: 0.01em;
  text-align: right;
  white-space: nowrap;
}

.obc-mv .mv-lc-actions.wp-block-buttons {
  grid-area: 3 / 1 / 4 / 2;
  margin: 0;
  justify-content: flex-start;
}

.obc-mv .mv-lc-link .wp-block-button__link {
  padding: 0;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 0;
  background: transparent;
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.obc-mv .mv-lc-link .wp-block-button__link:hover {
  border-bottom-color: #fff;
  color: #fff;
}

.obc-mv .mv-lc-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-top: 8px;
}

.obc-mv .mv-lc-controls[hidden] {
  display: none;
}

.obc-mv .mv-lc-rail {
  position: relative;
  flex: 1;
  height: 1px;
  background: rgba(31, 44, 49, 0.15);
}

.obc-mv .mv-lc-rail-fill {
  position: absolute;
  inset: 0;
  background: var(--mv-ink);
  transform: scaleX(0.08);
  transform-origin: left center;
  transition: transform 0.3s ease;
}

.obc-mv .mv-lc-arrows {
  display: flex;
  gap: 10px;
}

.obc-mv .mv-lc-arrow {
  width: 42px;
  height: 42px;
  border: 1px solid var(--mv-ink);
  border-radius: 50%;
  background: transparent;
  color: var(--mv-ink);
  font-size: 16px;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}

.obc-mv .mv-lc-arrow:hover:not(:disabled) {
  background: var(--mv-ink);
  color: var(--mv-paper);
}

.obc-mv .mv-lc-arrow:disabled {
  opacity: 0.3;
  cursor: default;
}

.obc-mv .mv-lc-all.wp-block-buttons {
  justify-content: center;
  margin-top: clamp(28px, 4vw, 40px);
}

@media (max-width: 600px) {
  /* a phone shows one card, and the inset above centres it from the same formula */
  .obc-mv .mv-lc-track {
    --lc-card: 78vw;
  }

  .obc-mv .mv-lc-arrows {
    display: none;
  }
}

/* sprint 17 — a single very large figure in place of the low-information photograph. Deliberately
   ink on cream rather than gold on navy, so it does not read as a repeat of the research band above:
   that one is evidence from a study, this one is the clinic's own count. */
.obc-mv .mv-bignum {
  padding: clamp(8px, 2vw, 24px) 0;
}

/* sprint 25 — solid gold, chosen from three readings in the assets lab. The metal is a fixed ramp
   with the abrupt steps real gold has, because a smooth blend reads as plastic; only a single
   specular band travels across it, out and back, while the warmth around the letters rises and falls
   on a different period so the two never line up twice.

   It is painted onto the letterforms, not behind them, so the number is still text: retypable in
   WordPress, readable by a screen reader, findable by search — and the mist colour set on the block
   in the editor is what shows if a browser cannot clip a background to text. */
.obc-mv .mv-bignum-figure {
  margin: 0 0 12px;
  font-size: clamp(76px, 11vw, 152px);
  font-weight: 300;
  line-height: 0.92;
  letter-spacing: -0.045em;
  text-align: left;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .obc-mv .mv-bignum-figure {
    background-image:
      linear-gradient(104deg, rgba(255, 255, 255, 0) 40%, rgba(255, 252, 238, 0.92) 49%, rgba(255, 255, 255, 0) 59%),
      linear-gradient(
        177deg,
        #7a5312 0%,
        #b8842c 14%,
        #e9c471 30%,
        #fff4d2 46%,
        #f0d18d 52%,
        #b07f28 58%,
        #8a5f18 66%,
        #dcb45f 80%,
        #f6e2b0 90%,
        #a3741f 100%);
    background-repeat: no-repeat;
    background-size: 240% 100%, 100% 100%;
    background-position: 0% 0, 0 0;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-bignum-figure {
    animation: mv-sheen 9s ease-in-out infinite;
  }
}

/* only the highlight moves; the metal underneath is fixed, because a polished face does not dim */
@keyframes mv-sheen {
  0%, 100% { background-position: 0% 0, 0 0; }
  50% { background-position: 100% 0, 0 0; }
}

.obc-mv .mv-bignum-label {
  max-width: 16ch;
  margin: 0 0 20px;
  padding-bottom: 20px;
  /* follows the text colour, so the rule stays visible whichever background is chosen */
  border-bottom: 1px solid rgba(128, 128, 128, 0.35);
  border-bottom-color: color-mix(in srgb, currentColor 28%, transparent);
  font-size: clamp(17px, 1.6vw, 21px);
  line-height: 1.35;
}

/* visible while the figure is unverified, and meant to be deleted once it is confirmed */
.obc-mv .mv-bignum-note {
  max-width: 34ch;
  margin: 0;
  opacity: 0.62;
  font-size: 12px;
  font-style: italic;
  line-height: 1.55;
}

@media (max-width: 900px) {
  .obc-mv .mv-bignum-figure {
    text-align: center;
  }

  .obc-mv .mv-bignum-label,
  .obc-mv .mv-bignum-note {
    margin-right: auto;
    margin-left: auto;
    text-align: center;
  }
}


/* sprint 21 — fireflies leaving the figure.

   Moved off the hero and onto the statistic, where the motion has a job: it carries the eye from the
   number on the left across to the paragraph on the right, which is the order the section wants to
   be read in. Decoration at the top of the page was only ever decoration.

   Each firefly is a pseudo-element on the figure or its label, so they leave from the number itself.
   No markup at all: nothing added for the owner to trip over in the editor, and nothing she can
   delete by accident.

   Two rhythms per firefly on different periods, one moving it and one breathing light into it, so
   none is ever the same brightness at the same point of its crossing twice. None goes fully dark,
   because a light that blinks out reads as a fault rather than as a firefly. */
.obc-mv .mv-bignum-figure,
.obc-mv .mv-bignum-label {
  position: relative;
}

@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-bignum-figure::before,
  .obc-mv .mv-bignum-figure::after,
  .obc-mv .mv-bignum-label::before,
  .obc-mv .mv-bignum-label::after {
    position: absolute;
    z-index: -1;
    border-radius: 50%;
    background: radial-gradient(circle, #fff6e4 0%, #e8c68d 45%, rgba(226, 178, 110, 0.6) 100%);
    content: "";
    pointer-events: none;
  }

  /* they set off from around the figure, not from a single point, so it reads as a drift rather
     than as something being emitted */
  .obc-mv .mv-bignum-figure::before {
    top: 22%; right: 8%; width: 9px; height: 9px;
    animation: mv-carry 21s ease-in-out infinite, mv-glow 3.1s ease-in-out infinite;
  }

  .obc-mv .mv-bignum-figure::after {
    top: 64%; right: 22%; width: 7px; height: 7px;
    animation: mv-carry 29s ease-in-out 5s infinite, mv-glow 4.3s ease-in-out infinite;
  }

  .obc-mv .mv-bignum-label::before {
    top: 8%; right: 14%; width: 6px; height: 6px;
    animation: mv-carry 37s ease-in-out 9s infinite, mv-glow 3.7s ease-in-out infinite;
  }

  .obc-mv .mv-bignum-label::after {
    top: 72%; right: 30%; width: 10px; height: 10px;
    animation: mv-carry 43s ease-in-out 14s infinite, mv-glow 5.1s ease-in-out infinite;
  }
}

/* across the gap and into the paragraph, lifting and stalling on the way, then gone before it
   reaches the far edge so it never distracts from the words it delivered the eye to */
/* the envelope uses filter rather than opacity, because the flicker below owns opacity and the last
   animation to declare a property wins. Filter and opacity multiply, so the two compose instead of
   one cancelling the other. */
@keyframes mv-carry {
  0% { filter: opacity(0); transform: translate(0, 0); }
  10% { filter: opacity(1); }
  32% { transform: translate(12vw, -30px); }
  58% { transform: translate(24vw, 16px); }
  84% { filter: opacity(0.55); transform: translate(35vw, -18px); }
  100% { filter: opacity(0); transform: translate(44vw, 6px); }
}

/* the glow, not the position; never fully dark */
@keyframes mv-glow {
  0%, 100% { opacity: 0.34; box-shadow: 0 0 8px 2px rgba(232, 198, 141, 0.34); }
  50% { opacity: 1; box-shadow: 0 0 26px 8px rgba(232, 198, 141, 0.72); }
}

/* sprint 22 — on a narrow screen the two columns stack, so the figure sits above the paragraph
   rather than beside it. Carrying the eye rightward there would point at nothing. Below the column
   breakpoint the fireflies fall instead, swaying as they go, and land where the words now are. */
@media (prefers-reduced-motion: no-preference) and (max-width: 781px) {
  .obc-mv .mv-bignum-figure::before,
  .obc-mv .mv-bignum-figure::after,
  .obc-mv .mv-bignum-label::before,
  .obc-mv .mv-bignum-label::after {
    animation-name: mv-fall, mv-glow;
  }
}

/* sprint 25 — shake the number and more come out of it. The four above drift on their own; these
   arrive a swarm at a time, when the figure is clicked, and are built by script because an element
   only has two pseudo-elements to give and fourteen were wanted. */
.obc-mv .mv-bignum {
  position: relative;
}

/* The flight crosses from the number to the list in the other column, so its canvas belongs to the
   band rather than to the number.

   isolation is what makes the depth work. A negative layer looks for the nearest element that is a
   layer of its own, and without this that is the page itself — so the fireflies would have gone
   behind the band's own background and vanished rather than behind its words. */
.obc-mv .mv-lc-section,
.obc-mv .mv-section {
  position: relative;
  isolation: isolate;
}

.obc-mv .mv-dissolve {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  pointer-events: none;
}

/* spent: the gold has gone with the fireflies and the mist underneath is what is left. The figure
   keeps the colour the block was given in the editor, which is why nothing here sets one. */
.obc-mv .mv-bignum.is-spent .mv-bignum-figure {
  background-image: none;
  -webkit-text-fill-color: currentColor;
  animation: none;
}

/* It does not simply change colour. For the first moment there is no number at all — only the
   fireflies standing in its shape — and the mist rises as they leave, so the white is uncovered by
   their going rather than swapped in behind them.

   On a class of its own, taken off again once it has played. Left on `is-spent` it held the figure's
   animation property for good, and every later shake was silently overruled by it. */
@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-bignum.is-revealing .mv-bignum-figure {
    animation: mv-reveal 1.8s ease-out both;
  }
}

@keyframes mv-reveal {
  0%, 16% { opacity: 0; }
  100% { opacity: 1; }
}

/* only once the script has wired it up: a pointer over something nothing is listening to is a lie.
   Selection is turned off with it, because shaking something means tapping it in quick succession
   and two taps in quick succession is how a browser is told to select a word. */
.obc-mv .mv-bignum.is-shakeable .mv-bignum-figure {
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* They fly the same path as the four that drift on their own, on the same long periods and with the
   same flicker, so a shaken one is indistinguishable from one that was always there: it crosses to
   the paragraph on a wide screen, and falls to it on a narrow one, exactly as they do. The script
   sets only the timings, never the animation itself, or an inline style would win over the media
   query below and the swarm would still drift sideways on a phone.

   They belong to the band rather than to the number, and sit behind its words: a firefly that passes
   behind a letter and out the other side gives the sentence a depth it cannot have on its own. */
.obc-mv .mv-spark {
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(circle, #fff6e4 0%, #e8c68d 45%, rgba(226, 178, 110, 0.6) 100%);
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-spark {
    animation:
      mv-carry var(--travel, 27s) ease-in-out var(--wait, 0s) 1 both,
      mv-glow var(--flicker, 3.4s) ease-in-out infinite;
  }
}

@media (prefers-reduced-motion: no-preference) and (max-width: 781px) {
  .obc-mv .mv-spark {
    animation-name: mv-fall, mv-glow;
  }
}

/* the branch, not the fireflies: a short judder that settles, so the number reads as the thing that
   was shaken rather than as something animating on its own.

   Matched through .mv-bignum on purpose. The spent figure sets `animation: none`, at a weight this
   could not reach without it, and a white number that refuses to shake is exactly what that cost. */
@media (prefers-reduced-motion: no-preference) {
  .obc-mv .mv-bignum .mv-bignum-figure.is-shaken {
    animation: mv-judder 0.52s cubic-bezier(0.36, 0.07, 0.19, 0.97);
  }
}

@keyframes mv-judder {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  15% { transform: translate(-4px, 1px) rotate(-0.7deg); }
  35% { transform: translate(4px, -2px) rotate(0.6deg); }
  55% { transform: translate(-3px, 1px) rotate(-0.4deg); }
  78% { transform: translate(2px, 0) rotate(0.2deg); }
}

/* a fall is not a drop: it sways across itself on the way down */
@keyframes mv-fall {
  0% { filter: opacity(0); transform: translate(0, 0); }
  10% { filter: opacity(1); }
  30% { transform: translate(26px, 84px); }
  56% { transform: translate(-20px, 178px); }
  82% { filter: opacity(0.55); transform: translate(18px, 266px); }
  100% { filter: opacity(0); transform: translate(-6px, 340px); }
}

/* sprint 26 — the bottom of the homepage is the Finder's first question.
   Whoever reaches here has scrolled past both booking buttons, so they are, by definition, the
   people who did not know what to book. A single "Book support" was the wrong thing to hand them. */
.obc-mv .mv-start {
  gap: clamp(12px, 2vw, 20px);
  margin: clamp(24px, 3vw, 34px) 0 clamp(20px, 2.6vw, 28px);
}

.obc-mv .mv-start-card {
  height: 100%;
  padding: clamp(20px, 2.6vw, 28px);
  border: 1px solid rgba(246, 246, 246, 0.28);
  border-radius: 4px;
}

.obc-mv .mv-start-title {
  margin: 0 0 8px;
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: 400;
}

.obc-mv .mv-start-note {
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 1.55;
  opacity: 0.82;
}

/* these are the primary action here, so they are filled while Book Now beside them is not */
.obc-mv .mv-start-link .wp-block-button__link {
  padding: 11px 22px;
  border-radius: 999px;
  background: #f6efe6;
  color: #294f4b;
  font-size: 15px;
}

.obc-mv .mv-start-link .wp-block-button__link:hover { background: #fff; }

/* the way out for somebody who already knows, deliberately quieter than the two cards */
.obc-mv .mv-start-aside {
  max-width: 62ch;
  margin: 0 0 16px;
  font-size: 15px;
  line-height: 1.6;
  opacity: 0.72;
}

@media (max-width: 600px) {
  .obc-mv .mv-start { gap: 12px; }
}

/* ============================================================================
   sprint 26 — holding still
   ============================================================================
   Two things live here: the rule that stops a band animating while it is off screen, and the snap
   points that let the page arrive on one band at a time. They are together because they are the same
   complaint — the page felt jittery, and it felt jittery for two different reasons.

   The first is measurable. Parked and untouched on a processor six times slower than this one, the
   page was burning 35% of the main thread on its own animations, 57ms of every second of it in style
   recalculation, against 3.9% with every animation cancelled. Almost none of that was on screen. The
   cost is not really paid by the animation; it is paid by the scroll, because the thread resolving
   those styles is the thread that has to answer the wheel. */

.obc-mv .is-resting,
.obc-mv .is-resting *,
.obc-mv .is-resting *::before,
.obc-mv .is-resting *::after,
.is-away .obc-mv *,
.is-away .obc-mv *::before,
.is-away .obc-mv *::after {
  /* !important, and not lightly. Every animation on this page is declared with the `animation`
     shorthand, which resets play-state to running as part of itself, and several of those selectors
     weigh exactly what this one weighs. A tie broken by source order would work today and break the
     first time somebody adds a rule underneath. */
  animation-play-state: paused !important;
}

/* ---------- one band at a time: removed ----------
   sprint 27 — the page used to carry `scroll-snap-type: y mandatory`, so it arrived on one band at a
   time. Taken out at the owner's request: she did not like how it felt, and a page that decides where
   your scroll stops is a page arguing with the reader. It now scrolls like an ordinary document.

   The idea may come back in a different form, so what was here is worth keeping a note of rather than
   only a diff. It was `scroll-snap-type: y mandatory` on `html:has(.obc-mv)`, with
   `scroll-snap-align: start` and `scroll-snap-stop: normal` on `.mv-hero` and `.mv-section`, plus a
   `scroll-padding-top` hook for the day the header becomes sticky. Two things were already known
   about it: `scroll-snap-align: end` markers at the foot of each band were tried and are wrong, and
   `proximity` is the softer setting if a lock is ever wanted again.

   The consultant carousel keeps its own horizontal snap. That one is a control being swiped through,
   not the page deciding where the reader stops, and it is a different thing entirely. */
