@charset "UTF-8";
/* =============================================================================
   Elena's Colon Care — custom Grav theme
   Built to the owner-approved mockups in design/.

   COLOUR
   ------
   Every value below is SAMPLED from the approved PNG mockups, not chosen by
   hand — see reports/GRAV-VISUAL-FIDELITY-PHASE2B.md for the sample points.

   The approved bright coral SURFACE is used as drawn (#F4796D, sampled from the
   mockup's Book Now button) and the FOREGROUND is darkened to reach contrast:
   --ink on coral measures 5.05:1, comfortably AA. Darkening the coral SURFACE
   instead was tried once and read as brick red — it lost the brand personality
   and was rejected. Same trick for the three "What to Expect" badges.

   PHASE 2C
   --------
   Three things changed the character of the page, in order of effect:
     1. Real illustrated foliage (images/leaf-cluster.svg) replaced the brand's
        two-leaf logo mark blown up to 200px at 50% opacity. That mark is a
        32px favicon shape; at hero scale it read pale and thin, and it was most
        of why the build did not look like the mockups.
     2. The mascot gained the mockup's amber sunburst and floating hearts, and
        varies by page instead of being the same waving pose five times.
     3. `.script` got `display:inline-block`. `transform:rotate()` does nothing
        to a non-replaced INLINE element, so every handwritten note in the build
        was silently rendering flat and level.
   ========================================================================== */

/* ---------- tokens ------------------------------------------------------- */
:root {
  /* sampled: page field #FEFAF6, hero band #FDF8F2, service card tints */
  --cream:        #FEFAF6;
  --cream-deep:   #FDF8F2;
  --card:         #FFFDFA;
  --white:        #FFFFFF;

  /* PHASE 2D — the mint scale was too pale to register. #ECF7F5 / #DDF2EE read
     as "slightly cool white" beside a warm cream page, which is why the build
     felt beige when the mockup does not. Roughly doubling the chroma makes the
     same areas read as mint without darkening or saturating the design.
     Every value below carries --ink, --ink-soft AND --ink-muted at AA or
     better; --mint-200 is the one exception and is BORDERS ONLY, never text. */
  --mint-wash:    #EDF7F4;   /*  full-band wash (What to Expect)     */
  --mint-50:      #DCF0EA;   /*  service card 1 / 3, prep band top   */
  --mint-100:     #D6EEE8;   /*  closing CTA band                    */
  --mint-200:     #B4DCD3;   /*  ✗ text — rules, borders, wave edge  */
  --pink-50:      #FCE7DF;   /*  service card 2                      */

  --ink:          #05314A;   /*  13.1:1 cream · 5.05:1 on coral · 5.44 on green
                                  Sampled from the mockup headings. Carries ALL
                                  text that sits on coral / green / amber.      */
  --ink-soft:     #0C6A78;   /*  6.04 cream · 5.28 mint-50 · 5.15 mint-100      */
  --ink-muted:    #4A6E78;   /*  5.33 cream · 4.67 mint-50 · 4.55 mint-100      */

  --coral:        #F4796D;   /*  APPROVED BRAND SURFACE. Text on it is --ink.   */
  --coral-hover:  #F68A7F;   /*  hover LIGHTENS, so --ink on it stays 5.6:1     */
  --coral-ring:   #EE6558;   /*  3.12:1 on the card — non-text indicators only  */
  --coral-tint:   #FDEEE8;
  --leaf:         #6CB382;   /*  step badge 2 — sampled               */
  --amber:        #F9B24F;   /*  step badge 3, sunburst — sampled     */

  --line:         #EAE4DA;
  --line-mint:    #C7E3DC;
  --cal-dim:      #5F777E;   /*  4.58:1 on the card — calendar day numbers      */

  --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-body:    'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-script:  'Caveat', 'Bradley Hand', 'Segoe Script', cursive;

  --radius-sm:  10px;
  --radius:     18px;
  --radius-lg:  26px;
  --radius-pill: 999px;

  --shadow-sm: 0 2px 8px rgba(1, 70, 90, .06);
  --shadow:    0 6px 22px rgba(1, 70, 90, .09);
  --shadow-lg: 0 14px 40px rgba(1, 70, 90, .12);

  --wrap: 1180px;
  --gutter: clamp(1.15rem, 4vw, 2.5rem);

  /* One vertical rhythm for the whole site. Phase 2B cut section padding to
     ~1.2rem to fight a page that felt too long — but the length came from
     duplicated SECTIONS, not from spacing, and the cure left every band
     touching the next. Phase 2C deletes the duplication instead and gives the
     remaining bands room to breathe. */
  --band-y: clamp(2rem, 3.6vw, 3.1rem);
  --band-y-tight: clamp(1.4rem, 2.4vw, 2rem);
}

/* ---------- reset -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;          /* belt-and-braces against decorative overhang */
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  line-height: 1.14;
  margin: 0 0 .5em;
  letter-spacing: -.01em;
}
h1 { font-size: clamp(2.2rem, 5.2vw, 3.7rem); font-weight: 800; }
h2 { font-size: clamp(1.7rem, 3.6vw, 2.6rem);  font-weight: 700; }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem);  font-weight: 700; }
h4 { font-size: 1.05rem; font-weight: 700; font-family: var(--font-body); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--ink-soft); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--ink); }

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 50%; top: 0;
  transform: translate(-50%, -140%);
  z-index: 999;
  background: var(--ink); color: #fff;
  padding: .7rem 1.2rem;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  font-weight: 700; text-decoration: none;
}
.skip-link:focus { transform: translate(-50%, 0); color: #fff; }

/* ---------- layout ------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--band-y); }
.section--tight { padding-block: var(--band-y-tight); }

/* PHASE 2D — a full-width pale mint field. Used for What to Expect, which sat
   on the same cream as everything above it. Positioned so the decorative
   foliage can be absolutely placed inside it. */
.section--mint {
  position: relative;
  overflow: hidden;
  background: var(--mint-wash);
}
.section--mint > .wrap { position: relative; z-index: 1; }

/* ---------- motion ------------------------------------------------------- */
/* Sections rise a few pixels as they enter the viewport. Short, single-shot
   and one-directional — nothing re-animates on the way back up. `.js` gates the
   hidden state so the page is fully readable if the script never runs. */
.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .55s ease, transform .55s cubic-bezier(.22, .8, .3, 1);
}
.js .reveal--2 { transition-delay: .07s; }
.js .reveal--3 { transition-delay: .14s; }
.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ---------- handwritten marginalia --------------------------------------- */
/* `display:inline-block` is load-bearing, not tidiness: `transform` is ignored
   on a non-replaced inline box, so the whole build was rendering these level. */
.script {
  display: inline-block;
  font-family: var(--font-script);
  font-size: clamp(1.2rem, 2.3vw, 1.55rem);
  line-height: 1.12;
  color: var(--ink-soft);
  font-weight: 700;
  max-width: 11ch;             /* the mockup stacks them 2–4 words per line */
}
.script--rot-l { transform: rotate(-7deg); }
.script--rot-r { transform: rotate(6deg); }
.script::after { content: ' ♥'; color: var(--coral); }
.script--plain::after { content: none; }
.script--wide { max-width: 24ch; text-align: right; }
@media (max-width: 720px) { .script--wide { text-align: left; } }

/* ---------- buttons ------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  min-height: 48px;
  padding: .75rem 1.5rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.02rem;
  text-decoration: none;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--coral);
  color: var(--ink);
  box-shadow: 0 4px 14px rgba(238, 101, 88, .28);
}
.btn--primary:hover {
  background: var(--coral-hover); color: var(--ink);
  box-shadow: 0 8px 22px rgba(238, 101, 88, .34);
}
.btn--primary .ic { color: var(--ink); }

.btn--outline {
  background: var(--white);
  color: var(--ink);
  border-color: var(--line-mint);
  box-shadow: var(--shadow-sm);
}
.btn--outline:hover { color: var(--ink); border-color: var(--ink-soft); box-shadow: var(--shadow); }

.btn--soft { background: var(--mint-100); color: var(--ink); }
.btn--soft:hover { background: var(--mint-200); color: var(--ink); }

.btn--block { width: 100%; }
.btn .ic { flex: 0 0 auto; }

.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; }

.btn-phone { line-height: 1.15; text-align: left; }
.btn-phone small { display: block; font-weight: 600; font-size: .8rem; opacity: .85; }

/* ---------- header ------------------------------------------------------- */
.site-header {
  position: relative;
  z-index: 20;
  background: var(--cream);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-block: .85rem;
}
.brand { flex: 0 0 auto; display: inline-block; line-height: 0; }
.brand img { width: clamp(176px, 21vw, 262px); }

/* The mockups centre the nav between the logo and the Book Now button. */
.site-nav { margin-inline: auto; }
.site-nav ul {
  list-style: none;
  display: flex;
  align-items: center;
  gap: clamp(.9rem, 2.2vw, 1.9rem);
  margin: 0; padding: 0;
}
.site-nav a {
  display: inline-block;
  padding: .45rem .1rem;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.site-nav a:hover { color: var(--ink-soft); border-bottom-color: var(--line-mint); }
.site-nav a[aria-current='page'] { color: var(--ink); border-bottom-color: var(--ink-soft); }
.header-cta { flex: 0 0 auto; }

.nav-toggle {
  display: none;
  align-items: center;
  gap: .5rem;
  min-height: 46px;
  padding: .5rem .9rem;
  background: var(--white);
  border: 2px solid var(--line-mint);
  border-radius: var(--radius-pill);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 700;
  cursor: pointer;
}
.nav-toggle .bars { display: block; width: 18px; }
.nav-toggle .bars span { display: block; height: 2px; background: var(--ink); border-radius: 2px; }
.nav-toggle .bars span + span { margin-top: 4px; }

/* Below 920px the links drop into a panel that OVERLAYS the page rather than
   being inserted into the header row. Phase 2B pushed a full-width Book Now bar
   under the logo instead, which gave a 390px phone a ~150px header before any
   content — the single worst thing on the mobile layout. */
@media (max-width: 919px) {
  .site-header__inner { gap: .6rem; }
  .nav-toggle { display: inline-flex; order: 3; }
  .header-cta { margin-left: auto; order: 2; }
  .header-cta .btn { padding-inline: 1.1rem; }

  .site-nav {
    position: absolute;
    top: 100%; left: 0; right: 0;
    margin: 0;
    background: var(--cream);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
  }
  .js .site-nav { display: none; }
  .js .site-nav.is-open { display: block; }
  .site-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: .35rem var(--gutter) .75rem;
    max-width: var(--wrap);
    margin-inline: auto;
  }
  .site-nav a { padding: .85rem .2rem; border-bottom: 1px solid var(--line); }
  .site-nav li:last-child a { border-bottom: 0; }
}

/* The booking row only exists inside the collapsed panel. */
.nav-book { display: none; }
.nav-book a { display: flex; align-items: center; gap: .5rem; font-weight: 800; color: var(--ink-soft); }

/* -----------------------------------------------------------------------------
   PHASE 2D — PHONE HEADER: LOGO + HAMBURGER, NOTHING ELSE.
   The coral Book Now was the third booking action on a 390px home page (header,
   hero, closing band) and the widest thing in a bar that has to hold a logo as
   well. It leaves the bar here and reappears as a row inside the open menu, so
   nothing becomes unreachable. The hero keeps the one real Book Now.
   Tablet and desktop are unaffected — the button stays in the bar there.
   -------------------------------------------------------------------------- */
@media (max-width: 700px) {
  .header-cta { display: none; }
  .nav-book { display: block; }
  .nav-toggle { margin-left: auto; }
}

@media (max-width: 430px) {
  .brand img { width: 158px; }
  .nav-toggle { padding: .5rem .7rem; }
  .nav-toggle__label { display: none; }
}

/* ---------- decorative foliage ------------------------------------------- */
/* One asset, three arrangements. Opacity stays high — these are illustrations
   in the composition, not a watermark. */
.leaves { position: absolute; inset: 0; pointer-events: none; user-select: none; z-index: 0; }
.leaves img { position: absolute; width: auto; }

/* PHASE 2D — the clusters were pushed 8% off both edges, so at 1440 roughly a
   third of each one was cropped away and what survived read as a pale sliver.
   The mockup plants are large and sit fully inside the band. Pulled back on to
   the canvas and grown; they are the site's main source of green. */
.leaves--hero .leaves__a {
  left: -3%; bottom: -4%;
  width: clamp(250px, 33vw, 500px);
  transform: rotate(-6deg);
}
/* The top-right cluster is the one that has to share its corner with the hero's
   right-hand handwriting, so it stays smaller than its opposite number and sits
   higher — grown to the same 500px as .leaves__a it crowded the script and
   clipped flat against the header rule. */
.leaves--hero .leaves__b {
  right: -6%; top: -22%;
  width: clamp(210px, 26vw, 390px);
  transform: rotate(168deg);
}
/* A third sprig low on the right, where the mockup sets a pot behind the
   mascot. Desktop only — it would collide with the stacked column below. */
.leaves--hero .leaves__c {
  right: 4%; bottom: -12%;
  width: clamp(150px, 17vw, 250px);
  transform: rotate(12deg) scaleX(-1);
}

.leaves--page .leaves__a {
  left: -3%; bottom: -4%;
  width: clamp(210px, 27vw, 390px);
  transform: rotate(-2deg);
}
.leaves--page .leaves__b {
  right: -6%; top: -24%;
  width: clamp(190px, 23vw, 340px);
  transform: rotate(172deg);
}

.leaves--band .leaves__a {
  left: -2%; bottom: -20%;
  width: clamp(175px, 21vw, 300px);
  transform: rotate(-4deg);
}
.leaves--band .leaves__b {
  right: -2%; bottom: -20%;
  width: clamp(175px, 21vw, 300px);
  transform: rotate(4deg) scaleX(-1);
}
/* The mockup flanks the What-to-Expect row with tall plants on both sides.
   They sit low so the section heading and its handwritten kicker stay clear. */
.leaves--steps .leaves__a {
  left: -5%; bottom: -18%;
  width: clamp(160px, 19vw, 280px);
  transform: rotate(-8deg);
}
.leaves--steps .leaves__b {
  right: -5%; bottom: -18%;
  width: clamp(160px, 19vw, 280px);
  transform: rotate(8deg) scaleX(-1);
}

.leaves--band .leaves__c { display: none; }
.leaves--page .leaves__c { display: none; }
.leaves--steps .leaves__c { display: none; }

/* Tablet keeps both sides — the hero is two columns here — but the clusters
   have to give the copy room, so they shrink and sit further out than at
   desktop. Without this the 820px hero has 270px of leaf on each side of a
   280px text column. */
@media (min-width: 761px) and (max-width: 1020px) {
  .leaves--hero .leaves__a { left: -9%; bottom: -6%; width: 24vw; }
  .leaves--hero .leaves__b { right: -9%; top: -8%;   width: 24vw; }
  .leaves--hero .leaves__c { display: none; }
  .leaves--page .leaves__a,
  .leaves--page .leaves__b { width: 20vw; }
  .leaves--band .leaves__a,
  .leaves--band .leaves__b { width: 16vw; }
}

/* On a phone the leaves would eat the content column, so only one small sprig
   survives, anchored where it cannot collide with text. */
@media (max-width: 760px) {
  .leaves__b, .leaves__c { display: none; }
  .leaves--hero .leaves__a { left: -13%; bottom: -8%; width: 165px; opacity: .85; }
  /* Page heroes are centred text, so a sprig at the TOP left landed against the
     first words of the tagline on About and Book. Dropped to the foot of the
     band, beside the mascot, where the column is empty. */
  .leaves--page .leaves__a { left: -15%; top: auto; bottom: -4%; width: 140px; opacity: .8; }
  .leaves--band .leaves__a { left: -15%; bottom: -16%; width: 140px; opacity: .8; }
}

/* ---------- mascot ------------------------------------------------------- */
.mascot {
  position: relative;
  width: var(--mascot-w, 260px);
  margin-inline: auto;
  aspect-ratio: 1 / 1;
}
.mascot__img {
  position: relative;
  z-index: 1;
  width: 100%;
  animation: mascot-float 6s ease-in-out infinite alternate;
}
.mascot--bare .mascot__img { animation: none; }

/* The amber ray ring the mockups draw behind the mascot. */
.mascot__rays {
  position: absolute;
  inset: -9%;
  width: 118%; height: 118%;
  z-index: 0;
  opacity: .9;
}

.mascot__heart { position: absolute; z-index: 2; width: 9%; min-width: 16px; }
.mascot__heart--a { top: 6%;  left: -2%;  animation: heart-drift 5.5s ease-in-out infinite alternate; }
.mascot__heart--b { top: 30%; right: -4%; width: 12%; animation: heart-drift 6.5s ease-in-out infinite alternate-reverse; }
.mascot__heart--c { bottom: 14%; left: 4%; width: 7%; animation: heart-drift 7.5s ease-in-out infinite alternate; }

@keyframes mascot-float { from { transform: translateY(0); } to { transform: translateY(-9px); } }
@keyframes heart-drift  { from { transform: translateY(0) rotate(-4deg); } to { transform: translateY(-11px) rotate(5deg); } }

/* ---------- bands -------------------------------------------------------- */
.band {
  position: relative;
  /* PHASE 2D — the old stop list put mint only in the last few percent, so it
     landed in a corner the eye never reaches and the whole band read warm. The
     mockup runs peach at the top-left into a clear mint field across the lower
     half, which is where the illustrated plants sit. */
  background: linear-gradient(162deg,
              #FDF6EE 0%, #FCF1E4 24%, var(--mint-wash) 56%, var(--mint-50) 100%);
  overflow: hidden;
}
.band > .wrap { position: relative; z-index: 1; }
.band__wave { display: block; width: 100%; height: auto; margin-top: -1px; position: relative; z-index: 1; }

.hero { padding-block: clamp(1.9rem, 3.6vw, 3.2rem) clamp(1.4rem, 2.6vw, 2.2rem); }
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, .9fr);
  gap: clamp(1.25rem, 4vw, 3rem);
  align-items: center;
}
.hero__copy { min-width: 0; }
.hero h1 { margin-bottom: .3em; font-size: clamp(2.15rem, 4.6vw, 3.45rem); }
.hero__sub {
  font-size: clamp(1.05rem, 2.2vw, 1.3rem);
  color: var(--ink-soft);
  font-weight: 600;
  margin-bottom: 1.6rem;
}
.hero__sub::after { content: ' ♥'; color: var(--coral); }
.hero__note { margin-bottom: .9rem; }
.hero__art { position: relative; min-width: 0; }
.hero__note-r { position: absolute; top: 2%; right: 0; }

/* -----------------------------------------------------------------------------
   TABLET (701–1020px) — a composition, not a squeezed desktop.
   Phase 2C collapsed the hero to one centred column at 860px, so 820 got the
   PHONE layout at tablet scale: a full-width headline, centred buttons and a
   235px mascot floating under them, ~780px tall before the fold. The mockup's
   side-by-side split does survive 820px if the column ratio is rebalanced
   towards the copy and the type is held back from its desktop size.
   -------------------------------------------------------------------------- */
@media (min-width: 701px) and (max-width: 1020px) {
  .hero__grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 1.5rem; }
  .hero h1 { font-size: clamp(2rem, 4.2vw, 2.5rem); }
  .hero__sub { font-size: 1.08rem; margin-bottom: 1.1rem; }
  .hero__art .mascot { --mascot-w: min(34vw, 260px); }
  /* The art column is only ~330px here, so this note has nowhere to go but the
     corner. Moving it inboard put it straight through the mascot's rays and a
     floating heart. It stays top-right, held to two short lines and lifted
     clear of the artwork — .leaves__b has been raised out of the same corner
     to make room for it. */
  .hero__note-r { top: -7%; right: 0; max-width: 11ch; font-size: 1rem; text-align: right; }
}

@media (max-width: 700px) {
  /* Phone composition is designed, not inherited: headline first, then the
     supporting line, then the actions, then the mascot. The mockup's side-by-
     side split does not survive a 390px column, and stacking the ART first —
     which the old build did — pushed the headline below the fold.

     PHASE 2D tightens it. Every gap here was carrying a desktop value: the
     grid gap alone put 24px between the buttons and the mascot, on top of the
     mascot's own square aspect-ratio box. The mascot now overlaps up into the
     button row so it reads as part of the hero rather than as the section
     after it. */
  .hero { padding-block: 1.3rem .6rem; }
  .hero__grid { grid-template-columns: 1fr; text-align: center; gap: .35rem; }
  .hero h1 { max-width: none; font-size: clamp(1.95rem, 8.2vw, 2.45rem); margin-bottom: .22em; }
  .hero__sub { font-size: 1.02rem; margin-bottom: 1rem; }
  /* Both actions on ONE row. Stacked full-width they cost ~120px and read as
     two equally-weighted decisions; side by side, Book Now stays the primary
     and Text or Call is plainly the alternative. 353px of content at 390px
     wide is just too narrow for them at desktop padding, so the padding comes
     in and the primary drops its trailing arrow — the calendar already says
     what the button does. */
  .hero .btn-row { justify-content: center; gap: .55rem; }
  .hero .btn { padding-inline: 1.1rem; font-size: .98rem; }
  .hero .btn--primary .ic:last-child { display: none; }
  .hero__copy { display: flex; flex-direction: column; align-items: center; }
  .hero__note { order: -1; margin-bottom: .45rem; }
  .hero__note-r { position: static; display: block; margin-inline: auto; margin-top: -.5rem; }
  .hero__art .mascot { --mascot-w: min(56vw, 225px); margin-top: -.6rem; }

  /* No actions in the hero: the negative margin above exists to overlap the
     button row, and with no row it drags the mascot's sunburst into the
     supporting line instead. Give the artwork its own space back. */
  .hero__grid--quiet .hero__art .mascot { margin-top: .35rem; }
  .hero__grid--quiet .hero__sub { margin-bottom: .25rem; }
}

/* -----------------------------------------------------------------------------
   HERO VIDEO                                      Phase: Homepage Video Hero
   -----------------------------------------------------------------------------
   Everything here is scoped to `.hero__grid--video` / `.hero-video`, which only
   the home page's hero can carry. The four other pages share this stylesheet and
   must not move by a pixel because of this phase.

   The reference mockup makes the film the hero's subject and the words its
   caption: the copy column is narrower than the art column, which is the inverse
   of the still-mascot hero that shipped before. So the column ratio is part of
   the VIDEO variant rather than a change to `.hero__grid` — turn the video off
   in Admin and the old proportions come back with it.
   -------------------------------------------------------------------------- */
.hero__grid--video { grid-template-columns: minmax(0, .66fr) minmax(0, 1fr); align-items: center; }
.hero__grid--video .hero h1,
.hero__grid--video h1 { font-size: clamp(2rem, 3.5vw, 3rem); }

/* The supporting paragraph under the headline. Held to a short measure so it
   stays a caption to the film rather than becoming body copy — the home page
   introduces the practice, Services explains it. */
.hero__body {
  margin: .85rem 0 0;
  max-width: 34ch;
  color: var(--ink-muted);
  font-size: clamp(.95rem, 1.15vw, 1.02rem);
  line-height: 1.6;
}

/* ---- the card ---- */
.hero-video {
  position: relative;
  margin: 0;
  /* The white frame in the mockup is a real 8px ring of card colour, not a
     border: it has to sit OUTSIDE the clipped video, or the rounded corners of
     the two do not nest and a hairline of black shows through at the radius. */
  padding: clamp(6px, .55vw, 9px);
  background: var(--card);
  border-radius: clamp(18px, 1.7vw, 26px);
  box-shadow: var(--shadow-lg);
}

.hero-video__el {
  display: block;
  width: 100%;
  height: auto;
  /* Stated in the markup too. Both are needed: the attribute reserves the box
     before any CSS has parsed, this keeps the box when the file 404s or a
     browser reports different intrinsic dimensions. */
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: clamp(13px, 1.25vw, 19px);
  /* Poster and film are both mint-cream, so the pre-load background is the
     artwork's own field rather than the browser default black. */
  background: var(--mint-50);
}

/* ---- play affordance ----
   Visible only while the film is paused; js/site.js owns the `hidden`
   attribute. `display:flex` would beat the UA's `[hidden]` rule, so the
   attribute needs saying again, louder. */
.hero-video__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(58px, 5.4vw, 78px);
  aspect-ratio: 1;
  padding: 0 0 0 4px;          /* optical centring: the glyph is a triangle */
  border: 0;
  border-radius: 50%;
  background: var(--coral);
  color: var(--ink);           /* 5.05:1 on the approved coral surface */
  box-shadow: 0 6px 20px rgba(1, 70, 90, .28);
  cursor: pointer;
  transition: background-color .18s ease, transform .18s ease;
}
.hero-video__play[hidden] { display: none; }
.hero-video__play:hover { background: var(--coral-hover); transform: translate(-50%, -50%) scale(1.06); }
.hero-video__play:focus-visible { outline: 3px solid var(--ink-soft); outline-offset: 3px; }

/* ---- sound control ------------------------------ Phase: Sound UX Polish
   A cream pill on the film's bottom-right, in the same rounded Elena language
   as the Book Now button: coral speaker, ink text, mint hairline, soft shadow.

   It sits ON the video, so it cannot rely on the artwork behind it being any
   particular colour — the film runs from pale cream to a mid-teal clinic. The
   pill is therefore an opaque cream surface rather than a translucent scrim, and
   --ink on --cream measures 13.1:1. Nothing here is left to a blur filter that
   Safari may or may not composite.

   `bottom/right` are in the same clamp() family as the card's own padding so the
   pill keeps an even margin from the rounded corner at every width. -------- */
.hero-video__sound {
  position: absolute;
  right: clamp(10px, 1.1vw, 16px);
  bottom: clamp(10px, 1.1vw, 16px);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .42rem .85rem .42rem .6rem;
  border: 1px solid var(--line-mint);
  border-radius: var(--radius-pill);
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: clamp(.82rem, 1vw, .92rem);
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(1, 70, 90, .22);
  transition: background-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
/* Hidden until js/site.js has wired it up: with no script it cannot unmute
   anything, and a button that does nothing is worse than no button. */
.hero-video__sound[hidden] { display: none; }
.hero-video__sound:hover { background: var(--white); transform: translateY(-1px); box-shadow: 0 6px 18px rgba(1, 70, 90, .26); }
.hero-video__sound:focus-visible { outline: 3px solid var(--ink-soft); outline-offset: 3px; }
.hero-video__sound:active { transform: translateY(0); }

.hero-video__sound-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--coral);
  color: var(--ink);            /* 5.05:1 on the approved coral surface */
  flex: 0 0 auto;
}
.hero-video__sound-ic svg { display: block; }

/* One glyph at a time, driven by the SAME attribute the assistive tree reads —
   so the icon cannot drift out of step with what a screen reader announces. */
.hero-video__sound .ic-sound { display: none; }
.hero-video__sound[aria-pressed="true"] .ic-sound { display: block; }
.hero-video__sound[aria-pressed="true"] .ic-muted { display: none; }

/* Sound ON is the quieter state: the visitor has what they came for and the
   pill stops advertising. Mint rather than cream, so it still reads as a live
   control and still passes contrast (--ink on --mint-50 is 5.28:1). */
.hero-video__sound[aria-pressed="true"] {
  background: var(--mint-50);
  border-color: var(--mint-200);
}
.hero-video__sound[aria-pressed="true"]:hover { background: var(--mint-100); }

/* A gentle two-pulse on the coral disc the first time the film plays muted —
   enough to catch the eye, then it stops and never runs again. Motion is a
   preference, not a default: the query below turns it off entirely. */
.hero-video__sound.is-nudge .hero-video__sound-ic { animation: sound-nudge 1.5s ease-in-out 2; }
@keyframes sound-nudge {
  0%, 62%, 100% { transform: scale(1); }
  72%           { transform: scale(1.16); }
  84%           { transform: scale(.97); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-video__sound { transition: none; }
  .hero-video__sound:hover { transform: none; }
  .hero-video__sound.is-nudge .hero-video__sound-ic { animation: none; }
}

/* At 390 the card is only ~343px wide. The label is the whole point of this
   control — "there is sound here" cannot be conveyed by a speaker icon alone,
   which is exactly the ambiguity this phase exists to remove — so the text
   stays and the pill tightens around it instead. */
@media (max-width: 700px) {
  .hero-video__sound {
    right: 8px;
    bottom: 8px;
    padding: .34rem .7rem .34rem .5rem;
    gap: .35rem;
    font-size: .8rem;
  }
  .hero-video__sound-ic { width: 22px; height: 22px; }
  .hero-video__sound-ic svg { width: 17px; height: 17px; }
}

/* The centre play badge and the sound pill can be on screen together (paused,
   autoplay refused). Keep them from touching on the smallest card. */
.hero-video__play { z-index: 2; }

/* ---- the handwritten note beside the film ----
   The mockup draws this note ON the video's left third. That works in a mockup,
   where the frame never changes; over a playing film it crosses a clinic scene
   and stops being readable for about two seconds in every ten. It is placed
   under the card instead — same hand, same voice, still attached to the film,
   legible in every frame. Recorded as a deliberate departure in the report. */
.hero__grid--video .hero__note-r {
  position: static;
  display: block;
  margin: .7rem 0 0 .25rem;
  max-width: 16ch;
  text-align: left;
}

/* Reduced motion: the film never auto-starts (js/site.js also refuses), so the
   play button is the whole interface and the card should not draw the eye with
   a hover lift either. */
@media (prefers-reduced-motion: reduce) {
  .hero-video__play { transition: none; }
  .hero-video__play:hover { transform: translate(-50%, -50%); }
}

/* -----------------------------------------------------------------------------
   TABLET (701–1020) — the video hero is composed, not squeezed.
   A 0.66/1 split at 820px leaves the copy column ~300px, which turns the
   headline into five short lines beside a 430px film and reads as a broken
   desktop. One centred column gives the film a confident 640px and the headline
   its full measure, in the order the phone uses. Measured at 820: 0px overflow.
   -------------------------------------------------------------------------- */
@media (min-width: 701px) and (max-width: 1020px) {
  .hero__grid--video { grid-template-columns: 1fr; gap: 1.1rem; text-align: center; }
  .hero__grid--video .hero__copy { align-items: center; display: flex; flex-direction: column; }
  .hero__grid--video h1 { font-size: clamp(2.1rem, 4.4vw, 2.6rem); margin-bottom: .2em; }
  .hero__grid--video .hero__sub { margin-bottom: .2rem; }
  .hero__grid--video .hero__body { max-width: 56ch; text-align: center; }
  .hero__grid--video .hero__art { max-width: 640px; margin-inline: auto; width: 100%; }
  .hero__grid--video .hero__note-r { margin: .6rem auto 0; max-width: none; text-align: center; }
}

/* -----------------------------------------------------------------------------
   PHONE (≤700) — headline first, then the film, then the supporting line.
   The film is the point of the page, so it must not be pushed under three
   paragraphs; equally it must not eat the whole first screen. Putting the
   supporting paragraph AFTER the card gets the film fully visible at 390×844
   with the headline still above it.

   `display: contents` on the copy column is what makes that possible: the
   headline, the supporting line and the paragraph become grid items in their own
   right and can be ordered around the art column, which is their sibling and not
   their cousin. (Ordering cannot reach inside a wrapper.) The wrapper's `.reveal`
   opacity stops applying at the same moment — that is fine and deliberate here:
   these children are above the fold and were revealed on the first frame anyway,
   and "text that cannot animate" is a far better failure than "text that stays
   at opacity 0".
   -------------------------------------------------------------------------- */
@media (max-width: 700px) {
  /* The one-column reset has to be repeated on the VARIANT. `.hero__grid` and
     `.hero__grid--video` are both a single class, so they have equal
     specificity, and the desktop `--video` ratio is declared later in this file
     than the phone block's `grid-template-columns: 1fr` — it therefore wins
     inside this media query too. Measured, not reasoned about: the first build
     of this rule left a two-column hero at 390px with a 200px film wedged into
     the right-hand track. */
  .hero__grid--video { grid-template-columns: 1fr; gap: .55rem; }
  .hero__grid--video .hero__copy { display: contents; }
  .hero__grid--video .hero__note   { order: 1; margin-bottom: .35rem; }
  .hero__grid--video h1            { order: 2; font-size: clamp(1.9rem, 7.8vw, 2.3rem); margin-bottom: .18em; }
  .hero__grid--video .hero__sub    { order: 3; margin-bottom: .55rem; font-size: 1rem; }
  .hero__grid--video .hero__art    { order: 4; margin-top: 0; }
  .hero__grid--video .hero__body   { order: 5; margin: .7rem auto 0; max-width: 40ch; }
  .hero__grid--video .btn-row      { order: 6; }
  .hero__grid--video .hero__note-r { order: 7; margin: .5rem auto 0; max-width: none; text-align: center; }
  .hero__grid--video .hero-video   { padding: 5px; }
  /* The band's own bottom padding plus the wave left the film sitting on a
     visible strip of nothing at phone width. */
  .band--hero:has(.hero__grid--video) .hero { padding-block: 1.1rem .9rem; }
}

/* page hero (About / Services / Contact / Book) */
.band--page .pagehero { padding-block: clamp(1.6rem, 3.2vw, 2.6rem); text-align: center; }
.pagehero__grid {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 2.7fr) minmax(0, .8fr);
  gap: clamp(.75rem, 2vw, 1.5rem);
  align-items: center;
}
.pagehero__center { min-width: 0; }
.pagehero__center h1 { margin-bottom: .18em; }
.pagehero__tagline {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.4vw, 1.5rem);
  font-weight: 700;
  color: var(--ink-soft);
  margin-bottom: .55rem;
}
.pagehero__tagline::after { content: ' ♥'; color: var(--coral); }
.pagehero__intro { max-width: 54ch; margin-inline: auto; color: var(--ink-muted); }
.pagehero__side { min-width: 0; display: flex; flex-direction: column; gap: .5rem; }
.pagehero__side--l { align-items: flex-start; }
.pagehero__side--r { align-items: flex-end; }
.pagehero__side--r .script { text-align: right; }

@media (max-width: 900px) {
  .pagehero__grid { grid-template-columns: 1fr; gap: 1.1rem; }
  .pagehero__side--l { display: none; }
  .pagehero__side--r { align-items: center; gap: .6rem; }
  .pagehero__side--r .script { text-align: center; }
  .band--page .pagehero { text-align: center; }
}
/* No small-screen override for the page-hero mascot: each template passes its
   own `clamp()`, whose lower bound IS the phone size, and an `!important` here
   would flatten Booking's deliberately tiny instance back up to the others. */

/* ---------- cards -------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.35rem;
}
.section-head h2 { margin: 0; display: flex; align-items: center; gap: .6rem; }
.section-head__leaf { width: 38px; }

/* ---------- service cards ------------------------------------------------ */
.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: clamp(1rem, 2.5vw, 1.6rem);
  align-items: stretch;
}

/* At tablet width the grid falls to two columns and a third service is left as
   an orphan with a card-sized hole beside it.

   PHASE 2D — Phase 2C centred that orphan at half width, which just moved the
   hole to both sides of it and read as a mistake. The card is a horizontal
   icon-and-text row, so letting it span the full width reads as a deliberate
   third row, and it matches what the What-to-Expect steps directly below it
   already do with their own orphan. */
@media (min-width: 640px) and (max-width: 1020px) {
  .services-grid > *:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

.svc {
  display: flex;
  flex-direction: column;
  padding: clamp(1.35rem, 3vw, 2rem);
  text-align: center;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform .2s ease, box-shadow .2s ease;
}
.svc:hover { transform: translateY(-4px); box-shadow: var(--shadow); }

/* The mockup sets each service icon in a soft tinted disc, not loose on the
   card. The disc is what makes the three cards read as a set. */
.svc__badge {
  display: grid;
  place-items: center;
  width: 108px; height: 108px;
  margin: 0 auto .9rem;
  border-radius: 50%;
  background: var(--mint-50);
  flex: 0 0 auto;
}
.svc__badge img { width: 84%; }
.services-grid > *:nth-child(3n + 2) .svc__badge { background: var(--coral-tint); }

.svc h3 { margin-bottom: .45rem; }
.svc__desc { color: var(--ink-muted); font-size: .98rem; margin-bottom: 1.1rem; }

.svc__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .5rem 1rem;
  padding-top: .3rem;
}
.svc__price {
  display: inline-flex; align-items: center; gap: .45rem;
  font-weight: 800; font-size: 1.22rem; color: var(--ink);
}
.svc__price small { font-weight: 600; font-size: .82rem; color: var(--ink-muted); }
.svc__sep { width: 1px; align-self: stretch; background: var(--line); }
.svc__dur {
  display: inline-flex; align-items: center; gap: .45rem;
  color: var(--ink-muted); font-weight: 600; font-size: .95rem;
}
.svc__pkg { margin-top: .5rem; font-size: .92rem; color: var(--ink-soft); font-weight: 700; }
.svc__pkg small { font-weight: 600; color: var(--ink-muted); }
/* Only the button is bottom-aligned; `margin-top:auto` on the price row opened
   a dead band under the shorter descriptions without aligning anything. */
.svc .btn { margin-top: auto; }
.svc__meta, .svc__pkg { margin-bottom: 1.15rem; }

/* compact preview cards (home) — tinted, borderless, and a LINK in their own
   right, so the whole card is the target rather than four words of it. */
.svc--mini {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 1rem;
  text-align: left;
  text-decoration: none;
  color: var(--ink);
  border-color: transparent;
  box-shadow: none;
  padding: clamp(1.1rem, 2.2vw, 1.35rem);
}
.services-grid > .svc--mini:nth-child(3n + 1),
.services-grid > .svc--mini:nth-child(3n + 3) { background: var(--mint-50); }
.services-grid > .svc--mini:nth-child(3n + 2) { background: var(--pink-50); }
.svc--mini:hover { color: var(--ink); box-shadow: var(--shadow); }
.svc--mini .svc__badge {
  width: 94px; height: 94px; margin: 0;
  background: rgba(255, 255, 255, .72);
}
.svc__mini-body { min-width: 0; }
.svc__mini-name {
  display: block;
  font-family: var(--font-display);
  font-size: 1.2rem; font-weight: 700; line-height: 1.2;
  margin-bottom: .12rem;
}
.svc--mini .svc__price { display: flex; font-size: 1.32rem; }
.svc__link {
  display: flex; align-items: center; gap: .35rem;
  margin-top: .4rem; font-weight: 700; color: var(--ink-soft);
}
.svc--mini:hover .svc__link { text-decoration: underline; }

/* ---------- steps -------------------------------------------------------- */
/* Flex rather than grid so the decorative arrows the mockup draws between the
   steps sit in the flow and vanish cleanly when the cards stack. */
.steps {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(.7rem, 1.6vw, 1.1rem);
  align-items: stretch;
  list-style: none;
  margin: 0; padding: 0;
}
.steps > .step { flex: 1 1 250px; min-width: 0; }
.step-arrow { flex: 0 0 auto; display: flex; align-items: center; color: var(--ink-soft); }
@media (max-width: 900px) { .step-arrow { display: none; } }
.step {
  display: flex; gap: .9rem; align-items: flex-start;
  padding: 1.2rem 1.3rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform .2s ease, box-shadow .2s ease;
}
.step:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
/* Approved badge fills, sampled from the mockup: coral / green / amber, with
   --ink numerals rather than white — 5.05 / 5.44 / 7.45:1. */
.step__num {
  flex: 0 0 auto;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: 50%;
  font-weight: 800; font-size: 1.1rem;
  color: var(--ink);
}
.step__num--a { background: var(--coral); }
.step__num--b { background: var(--leaf); }
.step__num--c { background: var(--amber); }
.step h3 { font-family: var(--font-body); font-size: 1.05rem; margin-bottom: .15rem; }
.step p { color: var(--ink-muted); font-size: .96rem; margin: 0; }

/* ---------- closing banner ----------------------------------------------- */
.closing {
  position: relative;
  background: linear-gradient(180deg, var(--mint-50), var(--mint-100));
  overflow: hidden;
}
.closing__inner {
  position: relative; z-index: 1;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: center; gap: clamp(1rem, 2.4vw, 2rem);
  padding-block: clamp(1.9rem, 3.4vw, 2.8rem);
  text-align: center;
}
.closing__copy { min-width: 0; position: relative; }
.closing__copy h2 { margin-bottom: .25rem; }
.closing__copy p { color: var(--ink-soft); font-weight: 600; margin: 0; }
.closing__note { flex: 0 0 auto; max-width: 12ch; text-align: left; }
.closing .btn-row { justify-content: center; }

/* PHASE 2D — below ~1020px the three pieces (handwritten note, copy, button)
   stopped fitting on one line: the note's last word sat on top of the first
   word of the paragraph. Stack them into one centred column and drop the note
   above the heading, where it reads as the aside it is. */
@media (max-width: 1020px) {
  .closing__inner { flex-direction: column; gap: .85rem; }
  .closing__note { max-width: none; text-align: center; order: -1; }
}
.wave-top { display: block; width: 100%; height: auto; margin-bottom: -1px; position: relative; z-index: 1; }

/* ---------- profiles (About) --------------------------------------------- */
.profiles {
  display: grid;
  /* 430px, not 320px: a profile is a photo beside a paragraph, so two columns
     at tablet width left the text three words wide. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 430px), 1fr));
  gap: clamp(1.1rem, 3vw, 2rem);
}
.profile {
  position: relative;
  display: flex;
  gap: clamp(1rem, 2.5vw, 1.6rem);
  padding: clamp(1.2rem, 2.6vw, 1.85rem);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform .2s ease, box-shadow .2s ease;
}
.profile:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.profile__photo { flex: 0 0 auto; width: clamp(136px, 20vw, 196px); }
.profile__photo img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius);
  border: 4px solid var(--white);
  box-shadow: var(--shadow);
}
.profile__body { min-width: 0; }
.profile__name {
  font-family: var(--font-display);
  font-size: clamp(1.55rem, 3vw, 2rem);
  font-weight: 800;
  margin: 0 0 .1em;
}
.profile__name::after { content: ' ♥'; color: var(--coral); font-size: .8em; }
.profile__role { color: var(--ink-soft); font-weight: 700; margin-bottom: .7rem; }
.profile__bio { color: var(--ink-muted); font-size: .99rem; }
.profile__chips {
  list-style: none; display: flex; flex-wrap: wrap; gap: .45rem;
  margin: .9rem 0 0; padding: 0;
}
.profile__chips li {
  background: var(--mint-100);
  color: var(--ink);
  font-size: .85rem; font-weight: 700;
  padding: .3rem .75rem;
  border-radius: var(--radius-pill);
}
.profile__quote {
  margin: 1rem 0 0;
  font-family: var(--font-script);
  font-size: 1.4rem; line-height: 1.2;
  color: var(--ink-soft); font-weight: 700;
}
.profile__quote::after { content: ' ♥'; color: var(--coral); }
/* a leaf sprig tucked into the lower corner, as the About mockup draws */
.profile__sprig {
  position: absolute;
  right: -54px; bottom: -58px;
  width: 190px;
  opacity: .5;
  pointer-events: none;
  transform: rotate(188deg);
}

@media (max-width: 560px) {
  .profile { flex-direction: column; align-items: center; text-align: center; }
  .profile__photo { width: min(66%, 200px); }
  .profile__chips { justify-content: center; }
  .profile__sprig { display: none; }
}

.about-closing { position: relative; z-index: 1; text-align: center; padding-block: clamp(1.8rem, 3.4vw, 2.6rem); }
.about-closing__script {
  font-family: var(--font-script);
  font-size: clamp(1.9rem, 4.5vw, 2.9rem);
  font-weight: 700;
  color: var(--ink-soft);
  margin-bottom: .4rem;
}
.about-closing__rule {
  display: flex; align-items: center; justify-content: center; gap: .8rem;
  margin: .3rem auto .9rem; max-width: 320px;
}
.about-closing__rule::before,
.about-closing__rule::after {
  content: ''; flex: 1; height: 2px; background: var(--line-mint); border-radius: 2px;
}
.about-closing__rule span { color: var(--coral); font-size: 1.2rem; }
.about-closing p { color: var(--ink-soft); font-weight: 600; }

/* ---------- preparation strip (Services) --------------------------------- */
/* ONE preparation area on the page. The service-specific detail lives inside
   it behind a disclosure, so it is available without permanently occupying a
   card — the build previously had a per-card accordion AND this band, which
   made the same subject appear twice. */
.prep {
  position: relative;
  background: linear-gradient(180deg, var(--mint-50), var(--mint-100));
  border-radius: var(--radius-lg);
  padding: clamp(1.4rem, 3vw, 2.1rem);
  overflow: hidden;
}
/* Headroom for the corner handwriting, which is absolutely placed and would
   otherwise sit on top of the first preparation item. */
@media (min-width: 1001px) { .prep { padding-top: 3.1rem; } }
/* The handwriting goes to the band's corners, as services.png draws it. Laying
   it out in a flex row beside the heading instead squeezed a six-word note into
   a four-line tower and pushed the heading off centre. */
.prep__title { margin: 0 auto 1.3rem; text-align: center; max-width: 22ch; position: relative; z-index: 1; }
.prep__note { position: absolute; z-index: 1; max-width: 16ch; font-size: 1.3rem; }
.prep__note--l { left: clamp(1rem, 3vw, 2.2rem); top: clamp(.9rem, 2vw, 1.5rem); text-align: left; }
.prep__note--r { right: clamp(1rem, 3vw, 2.2rem); top: clamp(.9rem, 2vw, 1.5rem); text-align: right; }
@media (max-width: 1000px) { .prep__note { display: none; } }
.prep__items {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  gap: 1rem clamp(1rem, 3vw, 2rem);
  position: relative; z-index: 1;
}
.prep__item { display: flex; gap: .8rem; align-items: flex-start; }
.prep__item h3 { font-family: var(--font-body); font-size: 1.02rem; margin-bottom: .1rem; }
.prep__item p { color: var(--ink-muted); font-size: .94rem; margin: 0; }
@media (max-width: 860px) { .prep__head .script { display: none; } }

.prep__more {
  position: relative; z-index: 1;
  margin: 1.4rem auto 0;
  max-width: 760px;
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--line-mint);
  border-radius: var(--radius);
  padding: .35rem 1.1rem;
}
.prep__more > summary {
  cursor: pointer;
  font-weight: 800;
  color: var(--ink-soft);
  list-style: none;
  display: flex; align-items: center; justify-content: center; gap: .45rem;
  padding: .6rem 0;
}
.prep__more > summary::-webkit-details-marker { display: none; }
.prep__more > summary::after { content: '▾'; margin-left: .2rem; transition: transform .18s ease; }
.prep__more[open] > summary::after { transform: rotate(180deg); }
.prep__more ul {
  margin: .3rem 0 1rem; padding-left: 1.15rem;
  columns: 2; column-gap: 2rem;
  border-top: 1px solid var(--line-mint);
  padding-top: .9rem;
}
.prep__more li { margin-bottom: .35rem; color: var(--ink-muted); font-size: .95rem; break-inside: avoid; }
@media (max-width: 700px) { .prep__more ul { columns: 1; } }

/* ---------- contact ------------------------------------------------------ */
/* ONE contact area. Phase 2B had the phone number in a tile, again as a Call
   button, again as a Text button and again in the footer; the address in a
   tile, again in Visit Us and again in the footer. A fact appears once. */
/* PHASE 2D — four facts, one row. The flex version sized tiles at 310–380px,
   so five of them wrapped 3 + 2 and the page ended on a half-empty row. With
   the email tile gone there are exactly four, and a fixed four-up grid at
   desktop / two-up at tablet keeps every row full at every width. */
.contact-tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(.85rem, 2vw, 1.15rem);
}
@media (max-width: 1080px) { .contact-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .contact-tiles { grid-template-columns: minmax(0, 1fr); } }
.tile {
  display: flex; align-items: center; gap: .95rem;
  padding: 1.05rem 1.15rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: var(--ink);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
a.tile:hover { border-color: var(--line-mint); box-shadow: var(--shadow); color: var(--ink); transform: translateY(-3px); }
.tile__icon {
  flex: 0 0 auto;
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--mint-100);
  color: var(--ink-soft);
}
.tile__icon--coral { background: var(--coral-tint); }
.tile__body { min-width: 0; flex: 1 1 auto; }
.tile__label {
  display: block; font-size: .8rem; font-weight: 800; color: var(--ink-soft);
  letter-spacing: .04em; text-transform: uppercase;
}
.tile__value { display: block; font-weight: 700; font-size: 1.04rem; overflow-wrap: anywhere; }
.tile__value--addr { font-size: .95rem; line-height: 1.35; }
.tile__value small { display: block; font-weight: 600; font-size: .86rem; color: var(--ink-muted); }
.tile__chev { margin-left: auto; color: var(--ink-soft); flex: 0 0 auto; }

/* Four-up, a tile is ~270px wide and the chevron is taking 20px of it from the
   longest value on the page — "@elenascoloncare" broke across two lines with
   the "are" orphaned. The chevron is decoration on an element that is already
   a link, so it goes rather than the handle. */
@media (min-width: 1081px) {
  .contact-tiles .tile { padding-inline: 1rem; gap: .8rem; }
  .contact-tiles .tile__chev { display: none; }
  .contact-tiles .tile__value { font-size: .98rem; overflow-wrap: normal; }
  .contact-tiles .tile__value--addr { font-size: .92rem; }
}

/* ---------- contact message form ----------------------------------------- */
.msgform {
  max-width: 820px;
  margin-inline: auto;
  background: var(--card);
  border: 1px solid var(--line-mint);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: clamp(1.3rem, 3.2vw, 2.2rem);
}
.msgform__head { text-align: center; margin-bottom: 1.25rem; }
.msgform__head h2 { margin-bottom: .3rem; }
.msgform__intro { color: var(--ink-muted); margin: 0; }

/* Shown while delivery is off. It is a plain, factual sentence in the client's
   own voice with the phone number beside it — not an error, and not a note
   about the build. */
.msgform__notice {
  display: flex; align-items: flex-start; gap: .7rem;
  margin: 0 0 1.35rem;
  padding: .9rem 1.05rem;
  background: var(--mint-wash);
  border: 1px solid var(--line-mint);
  border-radius: var(--radius);
  color: var(--ink-soft);
  font-weight: 600;
  font-size: .98rem;
}
.msgform__notice .ic { flex: 0 0 auto; margin-top: .15rem; }
.msgform__notice a { color: var(--ink); font-weight: 800; white-space: nowrap; }

.msgform fieldset { border: 0; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem clamp(.9rem, 2.2vw, 1.3rem); }
@media (max-width: 620px) { .msgform fieldset { grid-template-columns: minmax(0, 1fr); } }
.field--wide, .msgform__actions { grid-column: 1 / -1; }

.field { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.field label { font-weight: 700; font-size: .94rem; color: var(--ink); }
.field__opt { font-weight: 600; color: var(--ink-muted); font-size: .86rem; }

.field input, .field textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--white);
  border: 2px solid var(--line-mint);
  border-radius: var(--radius-sm);
  padding: .7rem .85rem;
  min-height: 48px;
  width: 100%;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field textarea { resize: vertical; min-height: 140px; line-height: 1.55; }
.field input:focus-visible, .field textarea:focus-visible {
  outline: none;
  border-color: var(--ink-soft);
  box-shadow: 0 0 0 3px rgba(12, 106, 120, .22);
}

/* Disabled is a real state, not a styling trick: the fieldset carries the
   `disabled` attribute, so these controls are genuinely out of the tab order
   and cannot be submitted. They are dimmed enough to read as unavailable
   while the labels stay at full contrast. */
.msgform fieldset[disabled] input,
.msgform fieldset[disabled] textarea { background: #F7F8F7; border-color: var(--line); color: var(--ink-muted); }
.msgform fieldset[disabled] .btn { opacity: .55; box-shadow: none; cursor: not-allowed; }
.msgform fieldset[disabled] .btn:hover { transform: none; background: var(--coral); }

.msgform__actions { display: flex; justify-content: center; margin-top: .3rem; }

/* Honeypot: off-screen, zero-size, hidden from assistive technology by the
   wrapper's aria-hidden. Never `display:none` — some bots skip those. */
.hp {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap;
}

/* ONE location area: a compact strip, not a second contact card. */
.visit {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: clamp(1.1rem, 3vw, 2rem);
  align-items: center;
  padding: clamp(1.3rem, 3vw, 1.9rem);
  background: linear-gradient(120deg, var(--mint-50), var(--mint-100));
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.visit__art {
  position: relative;
  display: grid; place-items: center;
  min-height: 190px;
  padding: 1.35rem 1rem;
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.visit__art > * { position: relative; z-index: 1; }
.visit__pin { color: var(--coral-ring); margin-bottom: .45rem; }
.visit__art { flex-direction: column; }
.visit__place {
  font-family: var(--font-script);
  font-size: 2.05rem; font-weight: 700; line-height: 1.1;
  color: var(--ink-soft);
  text-align: center;
}
.visit__body { position: relative; z-index: 1; min-width: 0; }
.visit h2 { font-size: clamp(1.35rem, 2.8vw, 1.8rem); margin-bottom: .35rem; }
.visit h2::after { content: ' ♥'; color: var(--coral); }
.visit p { color: var(--ink-muted); }
.visit__meta { color: var(--ink-muted); font-size: .95rem; }
.visit__meta strong { color: var(--ink); }
@media (max-width: 680px) {
  .visit { grid-template-columns: 1fr; text-align: center; }
  .visit .btn-row { justify-content: center; }
  .visit__art { max-width: 260px; margin-inline: auto; }
}

/* Survives only as the message an administrator sees if booking is switched to
   an external provider without supplying a URL — a configuration error that has
   to say something. It is not a public banner and does not render in normal
   operation. */
.demo-note {
  display: flex; gap: .6rem; align-items: flex-start;
  padding: .8rem 1rem;
  margin: 1rem 0;
  background: var(--mint-50);
  border: 1px solid var(--line-mint);
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  font-size: .92rem; font-weight: 600; line-height: 1.5;
}
.demo-note strong { color: var(--ink); }

/* ---------- booking ------------------------------------------------------ */
/* The calendar is the star. Everything that used to compete with it — the side
   panels, the repeated hours, the repeated address, the four-line disclaimer
   and the full-width phone band — is gone; what is left is one short line. */
.booking { display: grid; gap: clamp(.9rem, 2vw, 1.25rem); }
.booking__main {
  padding: clamp(1.3rem, 3vw, 2.2rem);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}

.cal { max-width: 780px; margin-inline: auto; }
.cal__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; margin-bottom: 1.1rem;
}
.cal__title {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 3vw, 1.85rem);
  font-weight: 700;
  margin: 0;
}
.cal__nav {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 2px solid var(--line-mint);
  background: var(--white);
  color: var(--ink);
  font-size: 1.1rem;
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}
.cal__nav:hover { border-color: var(--ink-soft); background: var(--mint-50); }
.cal__nav[disabled] { opacity: .35; cursor: not-allowed; }

.cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal__dow {
  text-align: center; font-weight: 800; font-size: .8rem;
  color: var(--ink-soft); padding-bottom: .35rem;
  text-transform: uppercase; letter-spacing: .02em;
}
.cal__cell {
  aspect-ratio: 1 / 1;
  min-height: 38px;
  max-width: 64px;
  width: 100%;
  margin-inline: auto;
  display: grid; place-items: center;
  border: 1px solid transparent;
  border-radius: 50%;
  background: transparent;
  font-family: var(--font-body);
  font-size: clamp(.85rem, 2.2vw, 1rem);
  font-weight: 700;
  color: var(--ink-muted);
  cursor: default;
  padding: 0;
  transition: background-color .15s ease, transform .15s ease;
}
.cal__cell--muted, .cal__cell--closed { color: var(--cal-dim); }
.cal__cell--open {
  background: var(--mint-100);
  color: var(--ink);
  cursor: pointer;
  border-color: var(--line-mint);
}
.cal__cell--open:hover { background: var(--mint-200); transform: scale(1.06); }
.cal__cell--today { box-shadow: inset 0 0 0 2px var(--coral-ring); }
.cal__cell[aria-pressed='true'] { background: var(--ink-soft); border-color: var(--ink-soft); color: #fff; }
.cal__legend {
  display: flex; flex-wrap: wrap; gap: .5rem 1.25rem;
  justify-content: center;
  margin-top: 1.1rem;
  font-size: .87rem; color: var(--ink-muted); font-weight: 600;
}
.cal__legend span { display: inline-flex; align-items: center; gap: .4rem; }
.cal__swatch {
  width: 16px; height: 16px; border-radius: 50%;
  border: 1px solid var(--line-mint); background: var(--mint-100);
}
.cal__swatch--today { background: transparent; border: 2px solid var(--coral-ring); }

.cal__out {
  margin-top: 1.1rem;
  padding: 1rem 1.15rem;
  background: var(--mint-50);
  border: 1px solid var(--line-mint);
  border-radius: var(--radius);
  text-align: center;
}
.cal__out h3 { font-family: var(--font-body); font-size: 1.05rem; margin-bottom: .25rem; }
.cal__out p { color: var(--ink-muted); font-size: .95rem; margin-bottom: .9rem; }
.cal__out .btn-row { justify-content: center; }

.booking-note {
  margin: .9rem auto 0;
  max-width: 54ch;
  text-align: center;
  color: var(--ink-muted);
  font-size: .93rem;
}

/* The whole fallback, in one centred line plus two buttons. */
.book-fallback {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .85rem clamp(1rem, 2.5vw, 1.75rem);
  padding-block: .35rem;
  text-align: center;
}
.book-fallback p { margin: 0; color: var(--ink-muted); font-weight: 600; }

/* ---------- footer ------------------------------------------------------- */
.site-footer {
  background: var(--cream);
  border-top: 1px solid var(--line);
  padding-block: clamp(1.5rem, 2.8vw, 2.1rem);
}
.site-footer__grid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem clamp(1rem, 3vw, 2.5rem);
}
.site-footer__brand { flex: 0 0 auto; line-height: 0; }
.site-footer__brand img { width: 194px; }
.site-footer__facts {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .6rem clamp(1rem, 2.6vw, 2.1rem);
}
.site-footer__item {
  display: inline-flex; align-items: center; gap: .55rem;
  color: var(--ink);
  font-weight: 700;
  font-size: .97rem;
  text-decoration: none;
}
.site-footer__item svg { flex: 0 0 auto; color: var(--ink-soft); }
a.site-footer__item:hover { color: var(--ink-soft); text-decoration: underline; }
.site-footer__legal {
  margin: 1.2rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  text-align: center;
  font-size: .88rem;
  color: var(--ink-muted);
}
@media (max-width: 880px) {
  .site-footer__grid { flex-direction: column; align-items: center; text-align: center; }
  .site-footer__facts { justify-content: center; }
}

/* ---------- prose (markdown body / error page) --------------------------- */
.prose { max-width: 68ch; }
.prose ul, .prose ol { padding-left: 1.3rem; }
.prose li { margin-bottom: .35rem; }
.prose blockquote {
  margin: 1.2rem 0; padding: .8rem 1.1rem;
  border-left: 4px solid var(--line-mint);
  background: var(--mint-50);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.notfound { position: relative; text-align: center; padding-block: clamp(2.5rem, 6vw, 4.5rem); }
.notfound .mascot { margin-bottom: 1.25rem; }
.notfound .btn-row { justify-content: center; margin-top: 1.5rem; }
