/* ==========================================================================
   Nourished Minds & Bodies — motion layer
   --------------------------------------------------------------------------
   Motion direction: THE BREATH IS THE CLOCK.
   Every ambient loop on this site runs on a 10s cycle — 4s in, 6s out — the
   same extended-exhale cadence as the breathing tool already on the recovery
   and course pages. Nothing snaps. Nothing bounces. Things settle.

   SAFETY ARCHITECTURE (read before editing):
   Nothing is ever hidden by this stylesheet on its own. Every hiding rule is
   scoped under `html.nmb-motion`, and that class is only ever added by the
   inline head script — which refuses to add it when JS is off, when the
   visitor prefers reduced motion, or when the browser is too old. If anything
   in the motion pipeline fails, the class is removed and the page is simply
   a normal, fully visible page. Content must never depend on animation.
   ========================================================================== */

:root {
  /* the breath */
  --nmb-inhale: 4s;
  --nmb-exhale: 6s;
  --nmb-breath: 10s;

  /* eases — settling, never springing */
  --nmb-settle: cubic-bezier(0.22, 0.61, 0.36, 1);
  --nmb-breathe: cubic-bezier(0.37, 0, 0.63, 1);

  --nmb-rise-dist: 22px;
  --nmb-dur: 0.9s;
}

/* --------------------------------------------------------------------------
   1. Neutralise the prototype's own reveal system.
   The old .reveal{opacity:0} + IntersectionObserver is superseded by GSAP.
   Reset it to visible here so that if GSAP never arrives, .reveal content is
   not left stranded at opacity 0.
   -------------------------------------------------------------------------- */
.reveal { opacity: 1; transform: none; transition: none; }

/* --------------------------------------------------------------------------
   1b. Images now carry width/height attributes so that a late-loading image
   cannot shift the layout out from under ScrollTrigger's cached positions.
   Those attributes map to presentational hints, which quietly supply a height
   to any image whose CSS deliberately left height to aspect-ratio — .hq-ava is
   sized by aspect-ratio:5/4, and the hint stretched it from 240px to 969px.
   Restoring height:auto hands sizing back to aspect-ratio.

   :where() gives this zero specificity on purpose: it loses to every author
   rule that genuinely sets a height (.hq-res img, .path-card .photo img), and
   only fills the gap where none exists.
   -------------------------------------------------------------------------- */
:where(img[width][height]) { height: auto; }

/* --------------------------------------------------------------------------
   2. Reveal primitives. Hidden ONLY under html.nmb-motion.
   -------------------------------------------------------------------------- */
html.nmb-motion .nmb-rise { opacity: 0; transform: translate3d(0, var(--nmb-rise-dist), 0); }
html.nmb-motion .nmb-lift { opacity: 0; transform: translate3d(0, 28px, 0) scale(0.985); }
html.nmb-motion .nmb-fade { opacity: 0; }
html.nmb-motion .nmb-veil { opacity: 0; clip-path: inset(14% 0 0 0); }

/* Headlines are held until JS has split them into words, so the split itself
   is never visible. If JS never runs, .nmb-motion is absent and the headline
   is simply a headline. */
html.nmb-motion .hero h1 { opacity: 0; }

/* Hero entrance states are declared here rather than as markup classes, so the
   hero choreography needs no extra classes in the HTML. */
html.nmb-motion .hero .eyebrow,
html.nmb-motion .hero .sub,
html.nmb-motion .hero .btn,
html.nmb-motion .hero .cred-pill,
html.nmb-motion .hero .hero-photo,
html.nmb-motion .hero .hq,
html.nmb-motion .hero .tag {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}
html.nmb-motion .hero .hero-photo,
html.nmb-motion .hero .hq { clip-path: inset(12% 0 0 0); }

/* --------------------------------------------------------------------------
   THE GUARD — do not remove.
   The quiz, the companion page and the homepage hero card are step flows:
   their panels are display:none until the visitor reaches them. An element
   hidden by this stylesheet inside one of those panels would be animated while
   invisible and then stranded at opacity 0 when its panel finally opened —
   a bug that is invisible in review and fatal in use. Everything inside a
   [data-nmb-flow] container is therefore exempted from every hidden state.
   The container itself is still animated, as a single unit.
   -------------------------------------------------------------------------- */
html.nmb-motion [data-nmb-flow] .nmb-rise,
html.nmb-motion [data-nmb-flow] .nmb-lift,
html.nmb-motion [data-nmb-flow] .nmb-fade,
html.nmb-motion [data-nmb-flow] .nmb-veil,
html.nmb-motion [data-nmb-flow] .nmb-word,
html.nmb-motion [data-nmb-flow] .eyebrow,
html.nmb-motion [data-nmb-flow] .sub,
html.nmb-motion [data-nmb-flow] .btn,
html.nmb-motion [data-nmb-flow] .cred-pill,
html.nmb-motion [data-nmb-flow] h1 {
  opacity: 1;
  transform: none;
  clip-path: none;
}

/* --------------------------------------------------------------------------
   Step-flow entrances: DELIBERATELY NOT HANDLED HERE.

   These pages already animate their own panels, and better than a generic rule
   could: .step uses `rise`, .hq-step uses `hqrise`, and both have a `celebrate`
   variant (`pop` / `hqpop`) that fires on the results panel — the payoff moment
   of the quiz.

   An earlier version of this file added its own `nmbStepIn` to `.step.on > *`.
   It looked harmless. It was not: the `animation` shorthand resets every
   animation property, so it silently replaced the sprig's `sway` loop, and at
   specificity (0,3,0) it outranked `.step.celebrate` (0,2,0) and killed the
   celebration outright. It was duplicating animation that already existed and
   destroying animation that was better.

   If a flow-page entrance ever needs changing, change the page's own keyframes.
   Do not add a competing rule here.
   -------------------------------------------------------------------------- */

/* words are split by JS; keep them on the type baseline */
.nmb-line { display: block; }
.nmb-word {
  display: inline-block;
  white-space: pre;
  will-change: transform, opacity;
}
.nmb-word em { font-style: italic; font-weight: 400; }

/* --------------------------------------------------------------------------
   3. The signature: the vagal thread.
   A single hairline that runs the length of the page and draws itself as you
   scroll — you are drawing your own path down. A slow highlight travels the
   drawn portion on the breath clock.
   -------------------------------------------------------------------------- */
.nmb-spine {
  position: absolute;
  top: 0;
  left: 50%;
  width: 160px;
  height: 100%;
  transform: translateX(-50%);
  z-index: 0;
  pointer-events: none;
  overflow: visible;
}
.nmb-spine path {
  fill: none;
  stroke: var(--thread, #B0672F);
  stroke-width: 1.25;
  stroke-linecap: round;
  opacity: 0.22;
}
.nmb-spine .nmb-spine-glow {
  stroke: var(--amber, #B9702B);
  stroke-width: 2.25;
  opacity: 0;
  filter: blur(0.4px);
}
/* Anything the thread runs behind must sit above it. */
.nmb-spined { position: relative; }
.nmb-spined > *:not(.nmb-spine) { position: relative; z-index: 1; }

/* the existing homepage thread, upgraded to draw on scroll */
html.nmb-motion .thread path { opacity: 0.3; }

/* --------------------------------------------------------------------------
   4. Ambient hero field (three.js canvas). Purely atmospheric — it sits
   underneath everything and is removed entirely on failure.
   -------------------------------------------------------------------------- */
.nmb-field {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 2.4s var(--nmb-breathe);
}
.nmb-field.nmb-field-on { opacity: 1; }
.nmb-field canvas { display: block; width: 100%; height: 100%; }
/* keep hero content above the field */
.hero > *:not(.nmb-field):not(.hero-bg) { position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   5. Header: condenses once you leave the hero.
   -------------------------------------------------------------------------- */
.topbar {
  transition: background 0.5s var(--nmb-settle),
              box-shadow 0.5s var(--nmb-settle),
              padding 0.5s var(--nmb-settle),
              backdrop-filter 0.5s var(--nmb-settle);
}
.topbar.nmb-condensed {
  position: fixed;
  background: rgba(245, 241, 232, 0.88);
  backdrop-filter: saturate(150%) blur(12px);
  -webkit-backdrop-filter: saturate(150%) blur(12px);
  box-shadow: 0 1px 0 rgba(34, 55, 43, 0.08), 0 10px 30px rgba(34, 55, 43, 0.06);
  padding-top: 12px;
  padding-bottom: 12px;
}
.topbar.nmb-condensed .wm-main { font-size: 1.25rem; }

/* thread-coloured scroll progress — the same signature, doing a second job */
.nmb-progress {
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--sage, #DCE3D5), var(--thread, #B0672F));
  z-index: 60;
  pointer-events: none;
}

/* Once the header condenses it becomes position:fixed, so an anchor jump —
   "Get in touch" -> #start, the skip link -> #nmb-main — would land its target
   underneath it. Reserve the header's height above every jump destination.
   :where() keeps this at zero specificity so any page rule still wins. */
:where([id]) { scroll-margin-top: 96px; }
@media (max-width: 768px) {
  :where([id]) { scroll-margin-top: 78px; }
}

/* --------------------------------------------------------------------------
   6. Micro-interactions. Restrained on purpose: this is a trauma-informed
   practice, not a product launch. No tilt, no magnetism, no cursor tricks.
   -------------------------------------------------------------------------- */
html.nmb-motion .path-card,
html.nmb-motion .mini-card,
html.nmb-motion .quote {
  transition: transform 0.55s var(--nmb-settle), box-shadow 0.55s var(--nmb-settle);
}
html.nmb-motion .mini-card:hover,
html.nmb-motion .quote:hover { transform: translateY(-4px); }

html.nmb-motion .btn {
  transition: transform 0.35s var(--nmb-settle), background 0.35s var(--nmb-settle),
              box-shadow 0.35s var(--nmb-settle);
}
html.nmb-motion .btn:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(199, 126, 43, 0.34); }
html.nmb-motion .btn:active { transform: translateY(0); }

/* the primary CTA carries one slow breath so the eye returns to it */
@keyframes nmbBreathGlow {
  0%, 100% { box-shadow: 0 6px 20px rgba(199, 126, 43, 0.30); }
  40%      { box-shadow: 0 10px 30px rgba(199, 126, 43, 0.46); }
}
html.nmb-motion .hero .btn:not(:hover) {
  animation: nmbBreathGlow var(--nmb-breath) var(--nmb-breathe) infinite;
}

/* --------------------------------------------------------------------------
   7. Stat counters. tabular-nums only — the digits then all share a width, so
   counting up cannot make the row twitch.
   Do NOT add a display value here: the page's own .stat b sets display:block,
   and a rule at equal specificity loaded later would silently override it.
   -------------------------------------------------------------------------- */
.stat b { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   7b. Footer.
   The original footer stacked five different kinds of information as five
   near-identical centred lines, and an earlier version of this file made it
   worse by dropping eight equal-weight links on top. Crowding here was not a
   spacing problem, it was a hierarchy problem: nothing told you what was a
   service, what was a phone number and what was an ABN.

   So the content is grouped by what it is for, the groups are labelled with the
   eyebrow device already used across the site, and the width finally gets used
   instead of everything queueing down one narrow centre column.
   -------------------------------------------------------------------------- */
footer.site { padding-top: clamp(44px, 6vw, 64px); padding-bottom: 30px; }

.nmb-foot { max-width: 1140px; margin: 0 auto; text-align: left; line-height: 1.7; }

.nmb-foot-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr 1fr;
  gap: 38px clamp(22px, 3.6vw, 52px);
  padding-bottom: clamp(30px, 4vw, 42px);
}

/* group labels reuse the site's existing eyebrow treatment */
.nmb-foot-h {
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--thread, #B0672F);
  margin-bottom: 15px;
}

.nmb-foot ul { list-style: none; margin: 0; padding: 0; }
.nmb-foot li + li { margin-top: 10px; }

.nmb-foot a {
  color: #C9D2C6;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color .25s var(--nmb-settle), border-color .25s var(--nmb-settle);
}
.nmb-foot a:hover { color: var(--bone, #F5F1E8); border-bottom-color: var(--thread, #B0672F); }
.nmb-foot [aria-current="page"] { color: #7E8C80; }

/* identity block */
.nmb-foot-mark {
  font-family: 'Fraunces', serif;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--bone, #F5F1E8);
  letter-spacing: -0.01em;
  display: block;
  line-height: 1;
}
a.nmb-foot-mark:hover { border-bottom-color: transparent; }
.nmb-foot-submark {
  display: block;
  font-size: .58rem;
  font-weight: 600;
  letter-spacing: .32em;
  text-transform: uppercase;
  color: var(--thread, #B0672F);
  margin-top: 6px;
}
.nmb-foot-place { margin-top: 16px; font-size: .86rem; }
.nmb-foot-who { margin-top: 13px; font-size: .84rem; color: var(--bone, #F5F1E8); }
.nmb-foot-who span { display: block; color: #9FB0A2; font-size: .79rem; }

/* contact — the most actionable thing in here, so it is allowed to read first */
.nmb-foot-contact { margin-bottom: 13px; font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: #9FB0A2; }
.nmb-foot-tel {
  display: block;
  margin-top: 3px;
  font-family: 'Fraunces', serif;
  font-size: 1.08rem;
  color: var(--bone, #F5F1E8) !important;
  white-space: nowrap;      /* a phone number must never break across lines */
  text-transform: none;
  letter-spacing: .01em;
}
.nmb-foot-note { margin-top: 14px; font-size: .78rem; color: #8FA093; line-height: 1.6; }

/* crisis notice — given its own band. On a mental-health practice site this is
   the most important line in the footer; it should not be the smallest text. */
.nmb-foot-crisis {
  border-top: 1px solid rgba(159, 176, 162, .22);
  border-bottom: 1px solid rgba(159, 176, 162, .22);
  padding: 18px 20px;
  margin: 0 0 24px;
  text-align: center;
  font-size: .88rem;
  line-height: 1.65;
  color: #C9D2C6;
  background: rgba(220, 227, 213, .045);
}
.nmb-foot-crisis strong { color: var(--bone, #F5F1E8); white-space: nowrap; }

/* legal bar */
.nmb-foot-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  align-items: baseline;
  justify-content: space-between;
  font-size: .76rem;
  color: #7E8C80;
  line-height: 1.6;
}
.nmb-foot-legal a { color: #9FB0A2; font-size: .78rem; }

/* ---- light footer, used on the two single-viewport flow pages ------------ */
.nmb-foot-lite { text-align: center; line-height: 1.75; }
.nmb-foot-lite p { margin: 0 0 8px; }
.nmb-foot-lite a { color: var(--pine, #22372B); text-decoration: none;
  border-bottom: 1px solid rgba(34, 55, 43, .28); }
.nmb-foot-lite a:hover { border-bottom-color: var(--thread, #B0672F); }
.nmb-foot-lite .nmb-foot-tel { display: inline; font-family: inherit; font-size: inherit;
  color: var(--pine, #22372B) !important; }
.nmb-foot-lite .nmb-foot-crisis {
  background: rgba(34, 55, 43, .05);
  border-color: rgba(34, 55, 43, .14);
  color: var(--ink, #232620);
  font-size: .8rem;
  padding: 12px 16px;
  margin: 12px auto;
  max-width: 560px;
}
.nmb-foot-lite .nmb-foot-crisis strong { color: var(--pine, #22372B); }
.nmb-foot-lite .nmb-foot-legal { justify-content: center; font-size: .72rem; }

/* Mid widths: a balanced 2x2 rather than letting the identity block span the
   full width, which pushed everything else into a third row. */
@media (max-width: 940px) {
  .nmb-foot-grid { grid-template-columns: 1fr 1fr; gap: 34px; }
  /* Pair the tall blocks with each other. Left in source order, the tall
     identity column sat beside the shortest link list and left a band of dead
     space under it, because a grid row is as tall as its tallest cell. */
  .nmb-foot-id    { order: 1; }
  .nmb-foot-talk  { order: 2; }
  .nmb-foot-work  { order: 3; }
  .nmb-foot-start { order: 4; }
}

/* Phones: the two link lists are short enough to sit side by side, and so are
   the two phone numbers. Stacking all four groups added most of a screen of
   scrolling. The identity block is deliberately NOT split — the practitioner
   credentials are long and go ragged in a half-width column. */
@media (max-width: 560px) {
  .nmb-foot-grid { grid-template-columns: 1fr 1fr; gap: 26px 20px; }
  .nmb-foot-id,
  .nmb-foot-talk { grid-column: 1 / -1; }
  .nmb-foot-id    { order: 1; }
  .nmb-foot-work  { order: 2; }
  .nmb-foot-start { order: 3; }
  .nmb-foot-talk  { order: 4; }
  .nmb-foot-talk { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; }
  .nmb-foot-talk .nmb-foot-h,
  .nmb-foot-talk .nmb-foot-note { grid-column: 1 / -1; }
  .nmb-foot-who { margin-top: 12px; }
  .nmb-foot li + li { margin-top: 8px; }
  .nmb-foot-legal { justify-content: flex-start; gap: 6px 16px; }
}

/* Below 360px even the short page names start breaking mid-phrase, so
   everything goes single file. Legibility beats compactness here. */
@media (max-width: 359px) {
  .nmb-foot-grid { grid-template-columns: 1fr; gap: 24px; }
  .nmb-foot-talk { display: block; }
}
}

/* --------------------------------------------------------------------------
   8. Accessibility floor.
   -------------------------------------------------------------------------- */
:where(a, button, summary, input, select, textarea):focus-visible {
  outline: 2px solid var(--thread, #B0672F);
  outline-offset: 3px;
  border-radius: 4px;
}

.nmb-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--pine, #22372B);
  color: var(--bone, #F5F1E8);
  padding: 12px 20px;
  border-radius: 0 0 10px 0;
  font-weight: 600;
  text-decoration: none;
}
.nmb-skip:focus { left: 0; }

/* --------------------------------------------------------------------------
   9. Hard stop for reduced motion. Belt and braces: the inline head script
   already refuses to add .nmb-motion, but if anything ever adds it anyway,
   this cancels every hidden state and every loop.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html.nmb-motion .nmb-rise,
  html.nmb-motion .nmb-lift,
  html.nmb-motion .nmb-fade,
  html.nmb-motion .nmb-veil,
  html.nmb-motion .nmb-word,
  html.nmb-motion .hero h1,
  html.nmb-motion .hero .eyebrow,
  html.nmb-motion .hero .sub,
  html.nmb-motion .hero .btn,
  html.nmb-motion .hero .cred-pill,
  html.nmb-motion .hero .hero-photo,
  html.nmb-motion .hero .hq,
  html.nmb-motion .hero .tag {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
  html.nmb-motion .hero .btn:not(:hover) { animation: none !important; }
  .nmb-field, .nmb-progress { display: none !important; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    /* delay must be zeroed too: the step-flow entrance uses animation-fill-mode
       both, so a surviving delay would hold content at opacity 0 for its
       duration — up to 380ms of blank panel for the people who least want it. */
    animation-delay: 0s !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   10. Mobile: no ambient field, shorter travel.
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
  :root { --nmb-rise-dist: 14px; --nmb-dur: 0.7s; }
  /* the quiz and companion pages are designed to sit in one viewport; a full
     link list here would push their footer into a second screen */
  .nmb-footnav { gap: 2px 12px !important; font-size: .74rem !important;
                 margin-bottom: 12px !important; padding-bottom: 12px !important;
                 line-height: 1.7 !important; }
  .nmb-field { display: none; }
  .nmb-spine { display: none; }
  .topbar.nmb-condensed { padding-top: 10px; padding-bottom: 10px; }
}

/* --------------------------------------------------------------------------
   11. The listening panel.
   The vagal thread, made audible. At rest it breathes on the 4-in / 6-out
   clock; on play the same line is driven by a live FFT of the recording.
   One motif doing a second job, rather than a new decoration.
   -------------------------------------------------------------------------- */
.listen {
  background: var(--pine-deep, #182A20);
  color: var(--bone, #F5F1E8);
  padding: clamp(56px, 8vw, 96px) clamp(20px, 5vw, 56px);
  position: relative;
  overflow: hidden;
  /* The pathway section's thread starts 40px above its own box (top:-40px) and
     was bleeding a copper hairline into the bottom of this dark panel. That
     section sets z-index:1, so this one has to sit above it. */
  z-index: 2;
}
.listen::before {           /* a slow copper wash, no image weight */
  content: '';
  position: absolute;
  inset: -40% 30% auto -20%;
  height: 120%;
  background: radial-gradient(60% 50% at 30% 40%, rgba(176,103,47,.16), transparent 70%);
  pointer-events: none;
}
.listen-inner {
  position: relative;
  max-width: 1140px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas: "head player" "copy player";
  gap: 0 clamp(32px, 5vw, 70px);
  align-items: start;
}
.listen-head   { grid-area: head; }
.listen-copy   { grid-area: copy; }
.listen-player { grid-area: player; align-self: center; }
.listen .eyebrow { color: var(--thread-lit, #C97B3E); margin-bottom: 16px; }
.listen h2 {
  font-family: 'Fraunces', serif;
  font-size: clamp(1.9rem, 3.4vw, 2.7rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-bottom: 18px;
  color: var(--bone, #F5F1E8);
}
.listen h2 em { font-style: italic; font-weight: 400; color: var(--thread-lit, #C97B3E); }
.listen p { color: #C9D2C6; margin-bottom: 14px; max-width: 46ch; }
.listen p strong { color: var(--bone, #F5F1E8); font-weight: 600; }

.listen-facts {
  list-style: none; margin: 26px 0 28px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px 30px;
}
.listen-facts li { display: flex; flex-direction: column; }
.listen-facts b {
  font-family: 'Fraunces', serif; font-size: 1.15rem; font-weight: 600;
  color: var(--bone, #F5F1E8); line-height: 1.2;
}
.listen-facts span { font-size: .78rem; color: #9FB0A2; margin-top: 3px; }

.listen-cta { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.listen-alt { font-size: .86rem; color: #9FB0A2; }
.listen-alt a { color: var(--thread-lit, #C97B3E); }

/* ---- the player ---------------------------------------------------------- */
.lp-frame {
  background: rgba(220, 227, 213, .05);
  border: 1px solid rgba(159, 176, 162, .20);
  border-radius: 22px;
  padding: clamp(20px, 2.4vw, 28px);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.nmb-wave {
  display: block; width: 100%; height: 152px;
  margin-bottom: 16px;
}
.lp-controls { display: flex; align-items: center; gap: 16px; }
.nmb-play {
  flex: none; width: 62px; height: 62px; border-radius: 50%;
  border: none; cursor: pointer;
  background: var(--amber, #B9702B); color: #fff;
  display: grid; place-items: center;
  box-shadow: 0 8px 24px rgba(185, 112, 43, .34);
  transition: transform .3s var(--nmb-settle), background .3s var(--nmb-settle);
}
.nmb-play:hover { background: var(--amber-dark, #9C5A1D); transform: scale(1.05); }
.nmb-play:active { transform: scale(.97); }
.nmb-play svg { width: 26px; height: 26px; fill: currentColor; }
.nmb-play .ic-pause { display: none; }
.is-playing .nmb-play .ic-play { display: none; }
.is-playing .nmb-play .ic-pause { display: block; }

/* the button breathes while idle, so the eye finds it — and stops once playing */
@keyframes nmbListenPulse {
  0%, 100% { box-shadow: 0 8px 24px rgba(185,112,43,.30); }
  40%      { box-shadow: 0 10px 34px rgba(185,112,43,.52); }
}
html.nmb-motion .nmb-play { animation: nmbListenPulse var(--nmb-breath, 10s) var(--nmb-breathe) infinite; }
html.nmb-motion .is-playing .nmb-play { animation: none; }

.lp-meta { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lp-title { font-size: .92rem; color: var(--bone, #F5F1E8); font-weight: 600; }
.lp-time { font-size: .8rem; color: #9FB0A2; font-variant-numeric: tabular-nums; }

.lp-scrub-wrap { display: block; margin: 16px 0 4px; }
.nmb-scrub {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 4px; border-radius: 4px; cursor: pointer;
  background: linear-gradient(90deg, var(--thread, #B0672F) var(--nmb-played, 0%),
                                     rgba(159,176,162,.24) var(--nmb-played, 0%));
}
.nmb-scrub::-webkit-slider-thumb {
  -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%;
  background: var(--bone, #F5F1E8); border: none; cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,.3);
}
.nmb-scrub::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%; border: none;
  background: var(--bone, #F5F1E8); cursor: pointer;
}

.lp-chapters {
  list-style: none; margin: 20px 0 0; padding: 18px 0 0;
  border-top: 1px solid rgba(159,176,162,.18);
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px 18px;
}
.lp-chapters li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  font-size: .82rem; color: #9FB0A2; cursor: pointer;
  padding: 4px 0; transition: color .25s var(--nmb-settle);
}
.lp-chapters li:hover { color: var(--bone, #F5F1E8); }
.lp-chapters li b { font-weight: 500; }
.lp-chapters li.is-past { color: var(--thread-lit, #C97B3E); }
.lp-chapters li span { font-variant-numeric: tabular-nums; opacity: .7; flex: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 900px) {
  /* The player is the whole point of this section, so on a phone it comes
     straight after the heading rather than at the end of the argument. */
  .listen-inner {
    grid-template-columns: 1fr;
    grid-template-areas: "head" "player" "copy";
    gap: 0;
  }
  .listen-player { margin: 24px 0 30px; }
  .listen p { max-width: none; }
  .nmb-wave { height: 118px; }
}
@media (max-width: 520px) {
  .lp-chapters { grid-template-columns: 1fr; }
  .listen-facts { gap: 10px 22px; }
}
@media (prefers-reduced-motion: reduce) {
  html.nmb-motion .nmb-play { animation: none !important; }
}
