/* ---- tokens.css ---- */
/* Generated from src/tokens/. Do not edit by hand: run `npm run tokens`. */
:root{
  --space-hair:1px;
  --space-tight:0.5rem;
  --space-snug:0.75rem;
  --space-base:1rem;
  --space-roomy:1.5rem;
  --space-block:2.5rem;
  --space-section:clamp(3.5rem, 8vw, 7rem);
  --space-gutter:max(clamp(0.875rem, 2.2vw, 1.5rem), env(safe-area-inset-left), env(safe-area-inset-right));
  --space-pad:clamp(1.25rem, 5vw, 3.5rem);
  --density-tight:clamp(2rem, 5vw, 3.5rem);
  --density-normal:clamp(3.5rem, 8vw, 7rem);
  --density-open:clamp(5rem, 11vw, 10rem);
  --measure-prose:68ch;
  --measure-wide:92ch;
  --measure-page:none;
  --measure-full:none;
  --radius-none:0;
  --radius-sm:4px;
  --radius-lg:12px;
  --radius-pill:999px;
  --bp-sm:640px;
  --bp-md:900px;
  --bp-lg:1200px;
  --hue-teal950:#062627;
  --hue-teal900:#0C4243;
  --hue-teal800:#134F51;
  --hue-teal700:#1D6465;
  --hue-teal300:#9FBDBB;
  --hue-brand:#008487;
  --hue-teal-deep:#007073;
  --hue-parchment:#F7F1E6;
  --hue-parchment2:#EFE5D3;
  --hue-parchment3:#E3D5BE;
  --hue-hair:#CFC3B0;
  --hue-stone:#D9D0C4;
  --hue-stone2:#CFC7BB;
  --hue-stone3:#B9B1A6;
  --hue-orange:#d6712d;
  --hue-orange-hi:#E07F3C;
  --hue-orange-deep:#B85E22;
  --hue-orange-action:#A85520;
  --hue-orange-action-deep:#8E4517;
  --hue-amber:#E9A82E;
  --hue-ink:#1F2A29;
  --hue-ink-muted:#4C5C5A;
  --hue-white:#FFFFFF;
  --tone-paper-bg:#F7F1E6;
  --tone-paper-fg:#1F2A29;
  --tone-paper-muted:#4C5C5A;
  --tone-paper-rule:#CFC3B0;
  --tone-paper-cta-bg:#A85520;
  --tone-paper-cta-fg:#FFFFFF;
  --tone-paper-cta-hover:#8E4517;
  --tone-raised-bg:#EFE5D3;
  --tone-raised-fg:#1F2A29;
  --tone-raised-muted:#4C5C5A;
  --tone-raised-rule:#CFC3B0;
  --tone-raised-cta-bg:#A85520;
  --tone-raised-cta-fg:#FFFFFF;
  --tone-raised-cta-hover:#8E4517;
  --tone-sand-bg:#E3D5BE;
  --tone-sand-fg:#1F2A29;
  --tone-sand-muted:#4C5C5A;
  --tone-sand-rule:#B9B1A6;
  --tone-sand-cta-bg:#A85520;
  --tone-sand-cta-fg:#FFFFFF;
  --tone-sand-cta-hover:#8E4517;
  --tone-deep-bg:#0C4243;
  --tone-deep-fg:#F7F1E6;
  --tone-deep-muted:#9FBDBB;
  --tone-deep-rule:rgba(159,189,187,.22);
  --tone-deep-cta-bg:#F7F1E6;
  --tone-deep-cta-fg:#062627;
  --tone-deep-cta-hover:#E3D5BE;
  --tone-deepest-bg:#062627;
  --tone-deepest-fg:#F7F1E6;
  --tone-deepest-muted:#9FBDBB;
  --tone-deepest-rule:rgba(159,189,187,.22);
  --tone-deepest-cta-bg:#F7F1E6;
  --tone-deepest-cta-fg:#062627;
  --tone-deepest-cta-hover:#E3D5BE;
  --action-primary-bg:#A85520;
  --action-primary-fg:#FFFFFF;
  --action-primary-hover:#8E4517;
  --action-secondary-bg:#008487;
  --action-secondary-fg:#FFFFFF;
  --action-secondary-hover:#007073;
  --action-quiet-bg:transparent;
  --action-quiet-fg:#1F2A29;
  --action-quiet-hover:#E3D5BE;
  --font-serif:var(--newsreader),Georgia,"Times New Roman",serif;
  --font-sans:var(--figtree),"Helvetica Neue",Arial,sans-serif;
  --text-display-family:var(--font-serif);
  --text-display-size:clamp(min(3rem, 13.5vw), 7vw, 4.5rem);
  --text-display-leading:1;
  --text-display-weight:400;
  --text-display-tracking:-0.02em;
  --text-title-family:var(--font-serif);
  --text-title-size:clamp(min(2.25rem, 10.5vw), 5vw, 3.5rem);
  --text-title-leading:1;
  --text-title-weight:400;
  --text-title-tracking:-0.018em;
  --text-heading-family:var(--font-serif);
  --text-heading-size:clamp(1.5rem, 2.2vw, 1.75rem);
  --text-heading-leading:1.1;
  --text-heading-weight:400;
  --text-heading-tracking:-0.01em;
  --text-lede-family:var(--font-sans);
  --text-lede-size:1rem;
  --text-lede-leading:1.45;
  --text-lede-weight:400;
  --text-lede-tracking:0;
  --text-body-family:var(--font-sans);
  --text-body-size:1rem;
  --text-body-leading:1.5;
  --text-body-weight:400;
  --text-body-tracking:0;
  --text-small-family:var(--font-sans);
  --text-small-size:0.875rem;
  --text-small-leading:1.45;
  --text-small-weight:400;
  --text-small-tracking:0;
  --text-label-family:var(--font-sans);
  --text-label-size:0.6875rem;
  --text-label-leading:1.6;
  --text-label-weight:600;
  --text-label-tracking:0.1em;
}
.tone-paper{background:var(--tone-paper-bg);color:var(--tone-paper-fg);--fg:var(--tone-paper-fg);--muted:var(--tone-paper-muted);--rule-colour:var(--tone-paper-rule);--cta-bg:var(--tone-paper-cta-bg);--cta-fg:var(--tone-paper-cta-fg);--cta-hover:var(--tone-paper-cta-hover);}
.tone-raised{background:var(--tone-raised-bg);color:var(--tone-raised-fg);--fg:var(--tone-raised-fg);--muted:var(--tone-raised-muted);--rule-colour:var(--tone-raised-rule);--cta-bg:var(--tone-raised-cta-bg);--cta-fg:var(--tone-raised-cta-fg);--cta-hover:var(--tone-raised-cta-hover);}
.tone-sand{background:var(--tone-sand-bg);color:var(--tone-sand-fg);--fg:var(--tone-sand-fg);--muted:var(--tone-sand-muted);--rule-colour:var(--tone-sand-rule);--cta-bg:var(--tone-sand-cta-bg);--cta-fg:var(--tone-sand-cta-fg);--cta-hover:var(--tone-sand-cta-hover);}
.tone-deep{background:var(--tone-deep-bg);color:var(--tone-deep-fg);--fg:var(--tone-deep-fg);--muted:var(--tone-deep-muted);--rule-colour:var(--tone-deep-rule);--cta-bg:var(--tone-deep-cta-bg);--cta-fg:var(--tone-deep-cta-fg);--cta-hover:var(--tone-deep-cta-hover);}
.tone-deepest{background:var(--tone-deepest-bg);color:var(--tone-deepest-fg);--fg:var(--tone-deepest-fg);--muted:var(--tone-deepest-muted);--rule-colour:var(--tone-deepest-rule);--cta-bg:var(--tone-deepest-cta-bg);--cta-fg:var(--tone-deepest-cta-fg);--cta-hover:var(--tone-deepest-cta-hover);}

/* ---- system.css ---- */
/*
 * The layout primitives.
 *
 * Namespaced `sys-` on purpose. site.css already owns `.sec`, `.wrap` and
 * `.prose`, and two stylesheets fighting over one class name is how spacing
 * ends up depending on which file loaded last. Nothing here shares a name with
 * anything in the older sheet.
 *
 * Every length is a token. There are no numbers in this file.
 */

.sys-sec {
  padding-block: var(--density-normal);
  padding-inline: var(--space-gutter);
}
.sys-sec[data-density="tight"] { padding-block: var(--density-tight); }
.sys-sec[data-density="open"]  { padding-block: var(--density-open); }

/* Two sections of the same ground read as one run of colour, so they get one
 * run of padding rather than two stacked.
 *
 * A band is excluded at both ends. It carries the same tone as its neighbours
 * so the strip beside a shorter picture matches the page, but it is a
 * photograph, not a continuation of the colour: collapsing the padding after
 * one put the first line of body text hard against the bottom of the image. */
.sys-sec.tone-paper:not([data-band])   + .sys-sec.tone-paper:not([data-band]),
.sys-sec.tone-raised:not([data-band])  + .sys-sec.tone-raised:not([data-band]),
.sys-sec.tone-sand:not([data-band])    + .sys-sec.tone-sand:not([data-band]),
.sys-sec.tone-deep:not([data-band])    + .sys-sec.tone-deep:not([data-band]),
.sys-sec.tone-deepest:not([data-band]) + .sys-sec.tone-deepest:not([data-band]) { padding-block-start: 0; }

/*
 * A hairline between one section and the next, which is what the home page
 * does and the system pages did not.
 *
 * `.sec` in site.css has carried `border-top: var(--rule)` from the beginning.
 * It is the cheapest device on the page and it does the most work: without it
 * a run of sections on one ground is a scroll of paragraphs, and with it the
 * page reads as composed of parts.
 *
 * Only where the ground does not already change. A rule at a colour boundary
 * is redundant, and a rule directly under a full bleed photograph cuts it off
 * from the words that belong to it.
 */
.sys-sec.tone-paper:not([data-band])   + .sys-sec.tone-paper:not([data-band]),
.sys-sec.tone-raised:not([data-band])  + .sys-sec.tone-raised:not([data-band]),
.sys-sec.tone-sand:not([data-band])    + .sys-sec.tone-sand:not([data-band]),
.sys-sec.tone-deep:not([data-band])    + .sys-sec.tone-deep:not([data-band]),
.sys-sec.tone-deepest:not([data-band]) + .sys-sec.tone-deepest:not([data-band]) {
  /* The collapse above removed the padding so the two would read as one run of
     colour. With a rule between them they are two sections again, and the rule
     needs air on both sides. */
  padding-block-start: var(--density-normal);
}
.sys-sec[data-band] + .sys-sec { border-block-start: 0; }

/* Children are spaced by the layout, not by margins.
 *
 * This used to be `.sys-wrap > * + * { margin-block-start: ... }`, which lost
 * every argument with a component that resets its own margin. `.t-title`,
 * `.steps` and others all declare `margin: 0` at the same specificity further
 * down the file, so the last one written won and the gap silently became zero.
 * Nothing failed. The pages just quietly lost their rhythm. A grid gap cannot
 * be overridden by a child at all, which is the point. */
.sys-wrap {
  margin-inline: auto; min-width: 0; width: 100%;
  display: grid; align-content: start; gap: var(--space-block);
  /* One column the width of the wrap, never wider. Left to size itself, the
   * column grew to the widest thing inside it, which on a phone at 200% zoom
   * pushed every block on the page past the right edge (ECHOSTUDIO-762). */
  grid-template-columns: minmax(0, 1fr);
}

/* A grid stretches its children. Things that are shaped by their own content
 * say so. */
.sys-wrap > .btn-cta, .sys-wrap > .crumbs { justify-self: start; }

/* An eyebrow belongs to the heading under it, not to the block above it. */
.sys-wrap hgroup { display: grid; gap: var(--space-tight); }
.sys-wrap[data-measure="prose"] { max-width: var(--measure-prose); }
.sys-wrap[data-measure="wide"]  { max-width: var(--measure-wide); }
.sys-wrap[data-measure="full"]  { max-width: none; }

/* ---- type roles. A component picks a role, never a size. ---- */
.t-display, .t-title, .t-heading, .t-lede, .t-body, .t-small, .t-label { margin: 0; }
.t-display { font: var(--text-display-weight) var(--text-display-size)/var(--text-display-leading) var(--text-display-family); letter-spacing: var(--text-display-tracking); text-wrap: balance; }
.t-title   { font: var(--text-title-weight) var(--text-title-size)/var(--text-title-leading) var(--text-title-family); letter-spacing: var(--text-title-tracking); text-wrap: balance; }
.t-heading { font: var(--text-heading-weight) var(--text-heading-size)/var(--text-heading-leading) var(--text-heading-family); letter-spacing: var(--text-heading-tracking); text-wrap: balance; }
.t-lede    { font: var(--text-lede-weight) var(--text-lede-size)/var(--text-lede-leading) var(--text-lede-family); color: var(--muted, inherit); }
.t-body    { font: var(--text-body-weight) var(--text-body-size)/var(--text-body-leading) var(--text-body-family); }
.t-small   { font: var(--text-small-weight) var(--text-small-size)/var(--text-small-leading) var(--text-small-family); color: var(--muted, inherit); }
.t-label   { font: var(--text-label-weight) var(--text-label-size)/var(--text-label-leading) var(--text-label-family); letter-spacing: var(--text-label-tracking); text-transform: uppercase; color: var(--muted, inherit); }

/* Paragraph rhythm inside a block is tighter than the gap between blocks. */
.sys-prose > * + * { margin-block-start: var(--space-base); }

/* ---- the one button. Colour comes from the surrounding tone. ---- */
.btn-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-tight);
  padding: var(--space-snug) var(--space-roomy);
  background: var(--cta-bg);
  color: var(--cta-fg);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font: var(--text-label-weight) var(--text-small-size)/1 var(--text-label-family);
  letter-spacing: var(--text-label-tracking);
  text-transform: uppercase;
}
.btn-cta:hover { background: var(--cta-hover); }
.btn-cta--small { padding: var(--space-tight) var(--space-base); }

/*
 * The system button, made the same object as the home page's.
 *
 * Hers is a pill carrying a dark circle with an arrow in it, and it is the
 * single most recognisable thing on the page. The system pages had a small
 * square uppercase chip instead, which is a different design speaking a
 * different language on the same site.
 *
 * The circle is drawn here rather than added to the markup of a dozen call
 * sites, and it works on both grounds without a variant: on parchment the
 * button is orange with a teal circle, on teal it is parchment with a teal
 * circle, and the arrow is light in both.
 */
.btn-cta {
  gap: var(--space-base);
  padding: var(--space-tight) var(--space-tight) var(--space-tight) var(--space-roomy);
  border-radius: var(--radius-pill);
  /* A button is the size of its label. Without this a grid stretches it, and
     "Book with Maggie" became a 460px bar across half the page. The home
     page's button has carried this from the beginning. fit-content, not
     max-content: the same size whenever the label fits, but a max-content
     button counted its whole label as the narrowest its column could be, so
     at 200% zoom on a phone every block beside it went off the screen (ECHOSTUDIO-762). */
  width: fit-content;
  max-width: 100%;
  font: var(--text-body-weight) var(--text-body-size)/1 var(--text-body-family);
  letter-spacing: 0;
  text-transform: none;
  min-height: 3.125rem;
}
.btn-cta::after {
  content: "";
  inline-size: 2.375rem; block-size: 2.375rem; flex: none;
  border-radius: var(--radius-pill);
  background: var(--tone-deepest-bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23F7F1E6' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8h10M9 4l4 4-4 4'/%3E%3C/svg%3E") center / 0.9375rem no-repeat;
  transition: transform .3s var(--ease, ease);
}
.btn-cta:hover::after { transform: rotate(-45deg); }
/* The same button as a <button>: no browser border. Not `font: inherit`, which
   outranks .btn-cta's own font by specificity. */
button.btn-cta { border: 0; cursor: pointer; }
.btn-cta--small { min-height: 2.625rem; padding-inline-start: var(--space-base); font-size: var(--text-small-size); }
.btn-cta--small::after { inline-size: 2rem; block-size: 2rem; }
/* A button that is only an arrow, for a row that already says where it goes. */
.btn-cta--bare { padding: 0; background: none; color: inherit; min-height: 0; }
.btn-cta--bare:hover { background: none; color: var(--muted, inherit); }

/* ---- prices: a list, because one column of numbers is a list ---- */
.pricelist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-snug); }
.pricelist > li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-tight) var(--space-base);
  padding-block: var(--space-snug);
  border-block-end: var(--space-hair) solid var(--rule-colour);
}
.pricelist > li > :first-child { flex: 1 1 14rem; }
.pricelist .price { font-variant-numeric: tabular-nums; }
/* Several durations on one treatment: each on its own line, never run together. */
.prices { flex: 0 1 auto; display: grid; gap: var(--space-tight); justify-items: start; }
.pricerow {
  display: flex; gap: var(--space-snug); align-items: baseline;
  font-variant-numeric: tabular-nums;
}
.pricerow > b { font-weight: 600; }

/* ---- cards ---- */
.cards {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--space-roomy);
  /* auto-fit, not auto-fill. auto-fill keeps making empty columns once the
   * items run out, so eight practitioners on a 2560px page sat in eight
   * cramped columns with a ninth left empty on the right. auto-fit collapses
   * the empty tracks and the cards share the room instead. */
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
/* No maximum track width here, deliberately. Capping the card at 22rem looked
 * right in the abstract and put eight practitioners into six columns and a
 * second row of two, with a quarter of the page empty beside them. Letting the
 * tracks stretch keeps whatever the row holds spread evenly across it, which is
 * what the grid is for. */
.cards > li > a { display: grid; gap: var(--space-tight); text-decoration: none; color: inherit; }
.cards img { width: 100%; height: auto; border-radius: var(--radius-sm); }

.crumbs { font: var(--text-small-weight) var(--text-small-size)/1.4 var(--text-small-family); color: var(--muted, inherit); }
.crumbs a { color: inherit; }

/* Wide content scrolls inside itself so the page never scrolls sideways. */
.overflow-guard { overflow-x: auto; max-width: 100%; }

/* ------------------------------------------------------------------ blocks
 * One rule per block wrapper. Most only need to say how their own children sit
 * together; spacing between blocks is the Section's job and is never set here.
 */

.blk-hero { display: grid; gap: var(--space-roomy); }

/* A heading and the words under it. Spaced by a gap rather than margins, for
 * the same reason as .sys-wrap: every type role resets its own margin, so a
 * margin rule here lost to .t-title and .t-lede and the heading sat on the
 * paragraph below it. */
.blk-text { display: grid; gap: var(--space-base); align-content: start; }
/* The designed pages set a label and a display heading against the prose rather
 * than stacking everything into one reading column. */
.blk-text--head { gap: var(--space-base) var(--space-block); align-items: start; }
/* The same two columns as a section head, and packed left for the same
 * reason: a fractional heading column takes every spare pixel, so the words
 * were pushed against the right edge with a gap in the middle of the page. */
@media (min-width: 900px) {
  .blk-text--head { grid-template-columns: minmax(0, var(--head-col)) minmax(0, 1fr); }
}
.blk-text--head > div:first-child { display: grid; gap: var(--space-tight); align-content: start; }
.blk-text--head > .prose { max-width: 54ch; }
/* The hero's own photograph only. `.blk-hero img` also caught the laurels in
   the rating badges and drew each one the full width of the page. */
.blk-hero > img { width: 100%; height: auto; border-radius: var(--radius-sm); }

.blk-split {
  display: grid;
  gap: var(--space-roomy) var(--space-block);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .blk-split { grid-template-columns: 1fr 1fr; }
  .blk-split[data-side="left"] > :first-child { order: 2; }
}
/*
 * The photograph fills its half of the section.
 *
 * Half her library is a 1800x536 banner crop, so `height: auto` drew a letter
 * box sliver beside three paragraphs: the foot bath on About was 253px tall in
 * an 850px column. The picture is given the height of the words beside it and
 * covers it, with a floor so a two line section still gets a photograph rather
 * than a strip.
 */
.blk-split img { width: 100%; border-radius: var(--radius-sm); aspect-ratio: 4 / 3; object-fit: cover; }
@media (min-width: 900px) {
  .blk-split { align-items: stretch; }
  .blk-split > div { align-content: center; }
  /* A floor and a ceiling rather than a ratio: her library runs from 1800x536
   * to square, and left alone one drew a 253px strip and the other a 670px
   * tower beside the same three paragraphs. Between these two the photograph
   * is the height of the words wherever the words allow it. */
  .blk-split img { height: 100%; aspect-ratio: auto; min-height: 22rem; max-height: 32rem; }
  /* The photograph touches the edges of its section: the outer page edge on
     its own side, and the top and bottom of the band. Phil: it was "just
     sitting there within the section, not touching any borders". The words
     keep the page gutter and the grid; only the picture leaves the frame, by
     the section's own padding, so nothing else moves. */
  .blk-split img {
    margin-block: calc(-1 * var(--density-normal));
    height: calc(100% + 2 * var(--density-normal));
    min-height: calc(22rem + 2 * var(--density-normal));
    max-height: calc(32rem + 2 * var(--density-normal));
    border-radius: 0;
  }
  /* max-width: none, or the global image cap holds the picture at its column
     width and the right hand one stops a gutter short of the edge. */
  .blk-split[data-side="right"] img { margin-inline-end: calc(-1 * var(--space-gutter)); width: calc(100% + var(--space-gutter)); max-width: none; }
  .blk-split[data-side="left"] img { margin-inline-start: calc(-1 * var(--space-gutter)); width: calc(100% + var(--space-gutter)); max-width: none; }
  .sys-sec:has(> .sys-wrap > .blk-split) { overflow: hidden; }
}
.blk-split > div { display: grid; gap: var(--space-base); justify-items: start; }

.blk-statement { margin: 0; display: grid; gap: var(--space-snug); justify-items: start; }
.blk-statement blockquote { margin: 0; }

.blk-grid, .blk-people, .blk-reviews, .blk-events, .blk-journal,
.blk-prices, .blk-faq, .blk-steps, .blk-where, .blk-itinerary,
.blk-cta, .blk-retreat, .blk-enquiry, .blk-ebook {
  display: grid;
  gap: var(--space-roomy);
  justify-items: start;
}
.blk-grid > ul, .blk-people > ul, .blk-reviews > ul, .blk-events > ul,
.blk-journal > ul, .blk-prices > ul, .blk-retreat > ul { width: 100%; }

.blk-cta { justify-items: start; }

/* A one line notice and the thing to do about it.
 *
 * On a finished retreat this is "this one has run, the next is in October"
 * and a button. Stacked, the two of them used 15% of a 2560px page and 27% of
 * a 1440 one, which made a band of colour look like a mistake rather than a
 * message. Side by side, with the action against the right edge. */
.noticebar { display: grid; gap: var(--space-roomy); align-items: center; width: 100%; }
@media (min-width: 900px) {
  .noticebar { grid-template-columns: 1fr auto; column-gap: var(--space-block); }
  .noticebar > .btn-cta { justify-self: end; }
}
.noticebar .t-body { max-width: 68ch; }
/* The left hand side can be a heading and a line rather than a bare sentence. */
.noticebar > div { display: grid; gap: var(--space-snug); align-content: start; }

/* The enquiry block is a heading, a few questions people ask, and the form.
 * Stacked, it used 39% of a 2560px page with the rest empty. The words and
 * the questions go on the left, the form on the right, which is the same
 * arrangement as every section opener on the site.
 *
 * Columns are assigned rather than taken in order, because the form is the
 * last of several siblings and the document order is worth leaving alone: a
 * screen reader should still meet the answers before the form. */
.blk-enquiry { justify-items: start; width: 100%; }
@media (min-width: 1000px) {
  .blk-enquiry { grid-template-columns: 1fr auto; align-items: start; column-gap: var(--space-block); justify-items: stretch; }
  .blk-enquiry > :not(.enquiry-wrap) { grid-column: 1; justify-self: start; }
  .blk-enquiry > .enquiry-wrap { grid-column: 2; grid-row: 1 / span 4; justify-self: end; width: min(30rem, 100%); }
}

/* The newsletter block is a short invitation and two fields, and stacked it
 * used half the page and left the other half empty. Beside each other they
 * read as one thing and the section uses its width, which is the same move as
 * the section opener: words on the left, the thing you do on the right. */
.blk-ebook { width: 100%; }
@media (min-width: 900px) {
  .blk-ebook { grid-template-columns: 1fr auto; align-items: start; column-gap: var(--space-block); }
  /* The heading and the invitation are siblings of the form rather than being
   * wrapped, in both places this block is used, so the columns are assigned
   * rather than taken in order. */
  .blk-ebook > :not(.ebook-form) { grid-column: 1; }
  .blk-ebook > .ebook-form { grid-column: 2; grid-row: 1 / span 3; justify-self: end; min-width: 22rem; }
}

/* Reviews read as quotes, not cards in a shop. */
.blk-reviews .cards > li { display: grid; gap: var(--space-tight); }

/* A row of short pieces, which is what the block is for: the four doshas,
 * what to bring, what a respite stay includes. It had only ever been a stack,
 * so on /about "Treading lightly" was three sentences down the left hand side
 * using 36% of a 2560px page. Wide enough to keep each one readable, and they
 * wrap to fewer columns rather than getting narrower. */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-block); width: 100%; }
@media (min-width: 900px) {
  .steps { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: var(--space-block) var(--space-roomy); }
}
.steps > li { display: grid; gap: var(--space-tight); justify-items: start; }
.steps[data-numbered="true"] { counter-reset: step; }
.steps[data-numbered="true"] > li { counter-increment: step; }
.steps[data-numbered="true"] > li > h3::before {
  content: counter(step) ". ";
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.steps img { max-width: 13rem; height: auto; }

.blk-faq .faq { width: 100%; border-block-end: var(--space-hair) solid var(--rule-colour); padding-block: var(--space-snug); }
.blk-faq summary { cursor: pointer; }
.blk-faq .faq > p { margin-block-start: var(--space-tight); color: var(--muted); }

.hours { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-tight); }
.hours > li { display: flex; gap: var(--space-base); align-items: baseline; }

.blk-itinerary section { display: grid; gap: var(--space-snug); width: 100%; }
.blk-itinerary ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-tight); }
.blk-itinerary li { display: flex; gap: var(--space-base); align-items: baseline; }

.blk-gallery {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--space-roomy);
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
}
.blk-gallery img { width: 100%; height: auto; border-radius: var(--radius-sm); }

.blk-drawing, .blk-media { margin: 0; display: grid; gap: var(--space-snug); justify-items: start; }
.blk-drawing img { max-width: 44rem; width: 100%; height: auto; }
.blk-media img { width: 100%; height: auto; border-radius: var(--radius-sm); }
/* A video as a still until it is clicked (ECHOSTUDIO-207): 16:9, a play disc
   in the middle, the player swapped in on the same box so nothing moves. */
.blk-media--video { width: 100%; max-width: 56rem; }
.video-facade { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-sm); overflow: hidden; background: var(--rule-colour); }
.video-facade img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; }
.video-facade iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-play { position: absolute; top: 50%; left: 50%; translate: -50% -50%; display: grid; place-items: center; width: 4.5rem; aspect-ratio: 1; border-radius: 50%; background: rgba(6, 38, 39, .82); color: var(--parchment, #f7f1e6); transition: transform .3s ease, background .3s ease; }
.video-play svg { width: 42%; margin-left: 6%; }
.video-facade:hover .video-play, .video-facade:focus-visible .video-play { transform: scale(1.08); background: rgba(6, 38, 39, .95); }
@media (prefers-reduced-motion: reduce) { .video-play { transition: none; } }

/* Vagaro paints its own white interface inside an iframe we cannot style, so
 * the join is made from the outside. The container carries the ground, the
 * hairline and the radius, and the widget sits in it like a card rather than a
 * hole cut in the page. Anything that would need to line up with their layout
 * is kept off this section entirely. */
.blk-vagaro { display: grid; gap: var(--space-snug); width: 100%; }

.vagaro-embed {
  position: relative;
  width: 100%;
  min-height: 34rem;
  background: var(--hue-white);
  border: var(--space-hair) solid var(--rule-colour, var(--hue-hair));
  border-radius: var(--radius-lg);
  overflow: hidden;
}

/* The scaffolding the loader needs, built in VagaroWidget rather than in JSX.
 * Their own stylesheet styles everything from .vagaro-container inwards. */
.vagaro-outer { display: block; width: 100%; }
.vagaro-embed iframe { display: block; width: 100%; border: 0; }
/* Their footer repeats the attribution we already carry once, below the card. */
.vagaro-embed .vagaro-footer, .vagaro-embed .vagaro-download { display: none; }

/* Held space in the widget's own shape: a header bar, then rows of times. */
.vagaro-skeleton {
  position: absolute; inset: 0;
  display: grid; gap: var(--space-base); align-content: start;
  padding: var(--space-pad);
  background: var(--hue-white);
}
.vagaro-skeleton > span {
  display: block; height: var(--space-block);
  background: var(--tone-raised-bg);
  border-radius: var(--radius-sm);
  animation: vagaro-breathe 1.8s ease-in-out infinite;
}
.vagaro-skeleton > span:nth-child(1) { width: 45%; }
.vagaro-skeleton > span:nth-child(2) { width: 100%; animation-delay: .15s; }
.vagaro-skeleton > span:nth-child(3) { width: 78%; animation-delay: .3s; }

@keyframes vagaro-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) {
  .vagaro-skeleton > span { animation: none; }
}

.vagaro-fallback { padding: var(--space-pad); }

/* Vagaro's terms ask for the attribution. It is a footnote, not a feature. */
.vagaro-by { justify-self: end; }
.vagaro-by a { color: inherit; }

.vagaro-frame { position: relative; display: block; width: 100%; min-height: 34rem; border: 0; }

.screening { width: 100%; display: grid; gap: var(--space-tight); }
.enquiry, .ebook-form { width: 100%; display: grid; gap: var(--space-tight); max-width: var(--measure-prose); }
.enquiry input, .enquiry textarea, .ebook-form input {
  font: inherit;
  padding: var(--space-snug);
  border: var(--space-hair) solid var(--rule-colour);
  border-radius: var(--radius-sm);
  background: var(--tone-paper-bg);
  color: var(--tone-paper-fg);
  width: 100%;
}
.enquiry button, .ebook-form button { justify-self: start; margin-block-start: var(--space-tight); }

/* The honeypot. Off screen rather than display:none, because some bots skip
 * hidden fields and a screen reader should not announce it either. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.enquiry-done { display: grid; gap: var(--space-tight); }
.enquiry-problem { color: var(--hue-orange-action-deep); }

.inclusions { margin: 0; padding-left: var(--space-roomy); display: grid; gap: var(--space-tight); }

/* ------------------------------------------------------------------ bands
 *
 * A picture that is the section, edge to edge.
 *
 * Meadowell alternate a flat colour field carrying words with a full bleed
 * picture carrying almost none, and that alternation is what separates their
 * sections. No card, no radius, no shadow, no gutter: the change of ground is
 * the separation. `.sys-sec[data-band]` drops the section's own padding so the
 * image touches the sections above and below it.
 */
.sys-sec[data-band] { padding-inline: 0; padding-block: 0; }
.sys-sec[data-band] .sys-wrap { max-width: none; gap: 0; }
.band-figure { margin: 0; display: block; }
.band-figure img {
  display: block; width: 100%; height: clamp(18rem, 46vw, 34rem);
  object-fit: cover; border-radius: var(--radius-none);
}
/* A small photograph at its own size, centred, rather than upscaled to soft. */
.band-figure--native { padding: var(--space-block) var(--gutter, 1.25rem); }
.band-figure--native img {
  width: auto; max-width: 100%; height: auto; margin-inline: auto;
  border-radius: var(--radius-sm);
}
/* A band is a landscape frame and a head shot is not, so one run through the
 * other comes out as a strip across somebody's eyes. Faces get their own
 * container instead: the picture at its own aspect on one side, the words on
 * the other, which is where a portrait has always gone in print. */
.portrait {
  display: grid; gap: var(--space-block) var(--space-block); width: 100%;
  align-items: start;
}
.portrait > figure { margin: 0; display: grid; gap: var(--space-snug); }
.portrait img { width: 100%; height: auto; border-radius: var(--radius-none); display: block; }
.portrait > .portrait-words { display: grid; gap: var(--space-roomy); align-content: start; }
.portrait .t-body, .portrait .t-lede { max-width: 58ch; }
@media (min-width: 900px) {
  /* The picture grows with the page, the words do not.
   *
   * A fixed 22rem plate beside a 58ch column is a third of a 2560px screen and
   * two thirds of nothing, while every other section on the page runs gutter to
   * gutter. Prose cannot be the thing that fills the space, because a longer
   * line is harder to read and not more generous. A photograph can, and at this
   * size it stops being a thumbnail of somebody and becomes their portrait. */
  .portrait { grid-template-columns: minmax(0, clamp(22rem, 40vw, 64rem)) minmax(0, 1fr); }
  /* Three paragraphs against a full height portrait leaves the hole at the
   * bottom of the column rather than spread through it. Set against the
   * picture, not hung from its top corner. */
  .portrait > .portrait-words { align-self: center; }
}

/* ------------------------------------------------------------------ tlist
 *
 * A list of treatments, set like a page of a menu rather than a grid of cards.
 *
 * `.cards` packs into as many 16rem columns as fit, which at 1440 is four
 * cramped ones. Two columns with a rule between rows gives each treatment a
 * full line of its own, which is how a long list stays readable.
 */
.tlist {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 0;
  border-block-start: var(--space-hair) solid var(--rule-colour);
}
@media (min-width: 900px) {
  .tlist { grid-template-columns: 1fr 1fr; column-gap: var(--space-block); }
}
.tlist > li { border-block-end: var(--space-hair) solid var(--rule-colour); }
.tlist > li > a {
  display: grid; gap: var(--space-tight); text-decoration: none; color: inherit;
  padding-block: var(--space-roomy);
}
.tlist > li > a:hover .t-heading {
  text-decoration: underline; text-underline-offset: var(--space-tight);
}
.tlist .t-small { max-width: 46ch; }

/* The page container, wider than any reading measure. */
.sys-wrap[data-measure="page"] { max-width: var(--measure-page); }

/*
 * The line every two-up hangs from. A section head, a CMS words block and a
 * set of notes all take their left column from this, so their right hand
 * columns start at the same x down a page. It used to be each heading's own
 * width, and one page had its body text starting at three different places.
 * A percentage so a tablet keeps a usable right column; a cap so a 2560px
 * screen does not push the words into the middle of nowhere.
 */
.sys-wrap { --head-col: min(36rem, 40%); }

/*
 * Running text keeps a reading measure even inside the page container.
 *
 * `page` is 82rem so a grid and a picture band can use the full width. A
 * paragraph at 16px across 82rem is about 200 characters a line, which nobody
 * can read, so the text roles hold themselves to the prose measure. Headings
 * are exempt: a heading is scanned, not read, and running one wide is the
 * point of the scale.
 */
.sys-wrap[data-measure="page"] > .t-lede,
.sys-wrap[data-measure="page"] > .t-body,
.sys-wrap[data-measure="page"] > .t-small,
.sys-wrap[data-measure="page"] > p { max-width: var(--measure-prose); }

/* ------------------------------------------------------------------ svchead
 *
 * A treatment opens with its name beside its drawing.
 *
 * The forty three engraved drawings exist because Marye will never have a
 * photograph of every individual treatment and forty stock photos would look
 * like a stock library. Forty drawings read as one set. The drawing sits
 * straight on the ground with no card, no plate and no border, because a panel
 * behind it makes it read as interface rather than as content.
 */
.svchead { display: grid; gap: var(--space-block); align-items: start; }
@media (min-width: 900px) { .svchead { grid-template-columns: 1.2fr 0.8fr; } }
.svchead .svchead-words { display: grid; gap: var(--space-base); align-content: start; }
.svchead .svchead-words > .t-lede { max-width: var(--measure-prose); }
.svchead .svchead-art { display: flex; justify-content: flex-end; }
.svchead .svchead-art img { width: 100%; max-width: 22rem; height: auto; }
@media (max-width: 899px) { .svchead .svchead-art { justify-content: flex-start; } }

/* A price table, set full width like their list of labs rather than squeezed
 * into a reading column. The row is a line in a menu: what you get, what it
 * costs, and the way to book it. */
.pricetable { list-style: none; margin: 0; padding: 0; display: grid; gap: 0;
  border-block-start: var(--space-hair) solid var(--rule-colour); }
.pricetable > li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-base) var(--space-roomy);
  padding-block: var(--space-roomy);
  border-block-end: var(--space-hair) solid var(--rule-colour);
}
.pricetable > li > .what { flex: 1 1 18rem; }
.pricetable > li > .amt { font-variant-numeric: tabular-nums; }
.pricetable > li > .btn-cta { margin-inline-start: auto; }

/* ------------------------------------------------------------------ sechead
 *
 * Their signature opener: the heading on the left, one 16px paragraph on the
 * right, both starting on the same line.
 *
 * Every wide section on meadowell.com opens this way. "Foundational labs" at
 * 100px sits on the left with four lines of 16px sitting in the top right
 * corner beside it, and "Meadowell Method" does the same. Stacking the
 * paragraph under the heading is what leaves the right half of the page empty,
 * which is the single biggest reason our sections were not using the width.
 *
 * The paragraph is deliberately small and deliberately short. It is a caption
 * to the heading, not an introduction to the section.
 */
.sechead { display: grid; gap: var(--space-roomy) var(--space-block); align-items: start; }
@media (min-width: 900px) {
  /*
   * Two columns that pack from the left, not a heading that eats the page.
   *
   * This was `1fr auto` with the paragraph pushed to the far edge. A `1fr`
   * heading column takes every spare pixel, so the two halves were only ever
   * as close as the page was narrow. With a long heading that reads as a
   * spread; with a short one it is a void, and a page opener's heading is a
   * name. "Maggie" sat seven hundred pixels away from the words about her.
   *
   * fit-content caps the heading column at a width a display line can
   * actually fill, and shrinks it to the words when they are shorter, so a
   * one word name and a full sentence both sit next to their paragraph.
   */
  .sechead { grid-template-columns: minmax(0, var(--head-col)) minmax(0, 1fr); align-items: start; }
  .sechead > .sechead-aside { padding-block-start: var(--space-snug); }
}
.sechead > .sechead-words { display: grid; gap: var(--space-snug); align-content: start; }
/* 42ch here was a caption's measure, and it is right for one sentence beside a
 * heading. Four paragraphs of it is a narrow gutter of text down the middle of
 * the page with the heading's column empty beneath it, so the cap is a reading
 * measure rather than a caption's. */
.sechead > .sechead-aside { display: grid; gap: var(--space-base); align-content: start; max-width: 54ch; }
/* A button in the aside (the gift voucher opening) sits at its own width. */
.sechead-aside > .btn-cta { justify-self: start; }
/* Inside a sechead the paragraph is already in its own column, so the page
 * container's prose clamp would narrow it twice. */
.sechead .t-lede, .sechead .t-body, .sechead .t-small { max-width: none; }

/* ------------------------------------------------------------------ rowlist
 *
 * A list where every entry gets the full width of the page.
 *
 * Their foundational labs list: a thumbnail, a name at display size, a small
 * caps line under it, and an affordance pushed to the far right, separated by
 * dotted rules. It reads as a list rather than as a grid of cards, which is
 * what a long menu of treatments actually is, and it gives each of the forty
 * three engraved drawings somewhere to be.
 */
.rowlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 0;
  border-block-start: var(--space-hair) dashed var(--rule-colour); }
.rowlist > li { border-block-end: var(--space-hair) dashed var(--rule-colour); }
.rowlist > li > a {
  display: grid; align-items: center; gap: var(--space-base) var(--space-roomy);
  grid-template-columns: auto 1fr auto;
  padding-block: var(--space-roomy);
  text-decoration: none; color: inherit;
}
.rowlist .rowlist-art { width: 4.5rem; flex: none; }
.rowlist .rowlist-art img { display: block; width: 100%; height: auto; }
.rowlist .rowlist-words { display: grid; gap: var(--space-tight); min-width: 0; }
/* Wide enough that the description reaches towards the price rather than
 * stopping halfway and leaving a corridor of nothing across the row. Still a
 * measure: past about 80 characters a line is hard to track back from. */
.rowlist .rowlist-words .t-small { max-width: 78ch; }
.rowlist .rowlist-amt { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Held on one line, "Saturday 31 October" or "60 min · $155" ran off the right
 * edge of a phone at 200% text (ECHOSTUDIO-762). The cell still gets its whole
 * line first, since an auto column is filled before the 1fr beside it; it only
 * wraps once the row can't hold it, which at normal sizes it always can. */
@media (max-width: 560px) { .rowlist .rowlist-amt { white-space: normal; } }
/* The right hand cell is a price almost everywhere, and a price that wraps
 * reads as two prices, hence the nowrap above. On the practitioners list it is
 * the days someone works, which is a sentence: "Tuesdays, Wednesdays and
 * Fridays, and alternate Saturdays" held on one line pushed a 390px page out
 * to 543px. This is the same cell, told it may wrap. */
.rowlist .rowlist-amt--words { white-space: normal; max-width: 20ch; }
.rowlist > li > a:hover .t-heading { text-decoration: underline; text-underline-offset: var(--space-tight); }
/* The drawing answers the pointer the way a photograph tile does on the home
 * page: a small lift and a touch larger, so a row reads as something to open
 * rather than a line of print. No cursor label here: on a photo tile it covers
 * a picture, on a row it sat over the description somebody was reading. */
.rowlist .rowlist-art img { transition: transform .5s var(--ease, ease); transform-origin: 50% 70%; }
.rowlist > li > a:hover .rowlist-art img { transform: translateY(-4px) scale(1.08) rotate(-2deg); }
@media (prefers-reduced-motion: reduce) {
  .rowlist .rowlist-art img, .rowlist > li > a:hover .rowlist-art img { transition: none; transform: none; }
}
/* Not every treatment has a drawing yet. The column is still reserved, so the
 * names down the list all start at the same place instead of stepping in and
 * out as the set fills up. */
.rowlist > li > a.no-art .rowlist-art { visibility: hidden; }
@media (max-width: 639px) {
  .rowlist > li > a { grid-template-columns: auto 1fr; }
  .rowlist .rowlist-amt { grid-column: 2; text-align: start; }
  .rowlist .rowlist-amt--words { max-width: none; }

}

/* ---------------------------------------------------------- where and when
 *
 * Address, hours and how to reach us, side by side across the page.
 *
 * The shared block rule sets `justify-items: start`, which is right for a block
 * whose content is one button but wrong here: it collapsed the whole thing to
 * the width of its longest line, so "Where and when" was a 233px column in the
 * middle of a 1440px page. These are three separate facts and they read better
 * as three columns than as one stack.
 */
.blk-where { justify-items: stretch; width: 100%; }
@media (min-width: 720px) {
  .blk-where { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); align-items: start; }
  /* The heading introduces all three columns, so it takes the whole row. */
  .blk-where > :is(h2, .t-title, .t-heading, .sechead) { grid-column: 1 / -1; }
}
.blk-where address { font-style: normal; }
.blk-where .hours { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-tight); }
.blk-where .hours > li { display: grid; gap: var(--space-hair); }


/* The event rows are a .rowlist, which brings its own layout. The block only
 * has to stop the shared rule shrinking it to its content. */
.blk-events { justify-items: stretch; width: 100%; }

/* Inclusions are half a line each, so they read as columns rather than as one
 * narrow stack down the middle of a page that is mostly empty. */
.inclusions--cols { padding-left: 0; list-style: none; }
@media (min-width: 720px) {
  .inclusions--cols {
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--space-base) var(--space-block);
  }
}
.inclusions--cols > li { padding-left: var(--space-roomy); position: relative; }
.inclusions--cols > li::before {
  content: ""; position: absolute; left: 0; top: 0.65em;
  width: var(--space-tight); height: var(--space-hair);
  background: currentColor; opacity: .45;
}

/* ------------------------------------------------------------------ rail
 *
 * A column of facts beside a column of prose.
 *
 * Reading text has to keep a reading measure, so a section that is nothing but
 * a description sits at 740px with half the page empty beside it. The answer is
 * not to stretch the paragraph, it is to put something true in the space. Here
 * that is the things somebody scanning a retreat actually wants: when it runs,
 * what it costs, how long it is.
 */
.withrail { display: grid; gap: var(--space-block); align-items: start; }
@media (min-width: 900px) {
  /* The facts sit in the right hand column, which is where the paragraph
   * beside a section heading sits too, so the two openers on a page agree
   * with each other.
   *
   * It is also the only arrangement that holds up on a wide screen. With the
   * rail on the left in fixed proportions, the prose kept its reading measure
   * and everything to the right of it was empty: on a 2560px screen a
   * treatment's description ran from 24px to 1515px with a thousand pixels of
   * nothing after it. Now the prose starts at the left gutter and the rail
   * ends at the right one, so the section spans the page at any width.
   *
   * Placed explicitly rather than reordered, so the document order is
   * untouched and a screen reader still reads the facts before the
   * description. */
  .withrail { grid-template-columns: minmax(0, 1fr) auto; }
  .withrail > .rail { grid-column: 2; grid-row: 1; justify-self: end; min-width: 12rem; max-width: 24rem; }
  .withrail > .sys-prose { grid-column: 1; grid-row: 1; }
  /* An article: the byline in the heading column and the writing from the
   * grid line, so a post lines up with the opener above it. */
  .withrail--line { grid-template-columns: minmax(0, var(--head-col)) minmax(0, 1fr); column-gap: var(--space-block); }
  .withrail--line > .rail { grid-column: 1; justify-self: start; min-width: 0; }
  .withrail--line > .sys-prose { grid-column: 2; }
}
.withrail .rail, .masthead .rail { display: grid; gap: var(--space-roomy); align-content: start; }
/* In a masthead the rail is a stack of facts rather than a column beside
 * prose, so the rows are separated the way the fact bar's columns are. */
/* The facts are separated by space, not a rule. */
.masthead .rail > div + div {
  padding-block-start: var(--space-tight);
}
.masthead .rail > div { display: grid; gap: var(--space-tight); }
.masthead .rail dt, .masthead .rail dd { margin: 0; }
.withrail .rail > div { display: grid; gap: var(--space-hair); }
.withrail .rail dt, .withrail .rail dd { margin: 0; }


/* ==========================================================================
 * Devices.
 *
 * Each of these exists because some part of her content genuinely has that
 * shape, not because the page needed decoration. A ritual is an ordered
 * sequence, so it gets a numbered run with a rule through it. A retreat has
 * four facts everybody checks before reading a word, so they get a bar. A
 * section that has just made its case gets somewhere to go.
 * ========================================================================== */

/* -------------------------------------------------------------- masthead
 *
 * The top of a page: identity and the thing to do about it on one side, the
 * facts on the other.
 *
 * This is deliberately not the section head. A section head's heading is a
 * sentence that fills its column; an opener's heading is a name, and a name
 * next to a paragraph in the same layout leaves a screen of nothing between
 * them. Here the left column is the whole of the identity, stacked as it reads
 * aloud, and the right column is the facts, which is content rather than air.
 */
.masthead { display: grid; gap: var(--space-block); align-items: start; width: 100%; }
.masthead > .masthead-words { display: grid; gap: var(--space-roomy); align-content: start; justify-items: start; }
.masthead > .masthead-words > hgroup { display: grid; gap: var(--space-tight); }
.masthead .t-lede { max-width: 46ch; }
@media (min-width: 900px) {
  .masthead { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); column-gap: var(--space-block); }
}

/* The block wrapper: the heading, then the answers under it. */
.blk-notes { display: grid; gap: var(--space-block); width: 100%; }
.blk-notes > div { display: grid; gap: var(--space-snug); }

/* The portrait in a page opener. Four to five, the proportion a portrait has
 * been printed at for four hundred years, and bottom aligned with the words so
 * the name and the face sit on the same line. */
.masthead-art { margin: 0; justify-self: end; width: 100%; max-width: 32rem; }
.masthead-art img { display: block; width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
@media (min-width: 900px) {
  /* The name and the face sit on the same line, and the words take the room
   * they need rather than a fixed fraction: a portrait column and a paragraph
   * column with four hundred pixels of nothing between them is the fault this
   * layout was built to fix. */
  .masthead:has(.masthead-art) { align-items: end; grid-template-columns: minmax(0, 1fr) minmax(0, 32rem); }
  .masthead:has(.masthead-art) .t-lede { max-width: 54ch; }
}

/* ------------------------------------------------------------------ notes
 *
 * The parts of a long description, set beside each other instead of stacked.
 *
 * A retreat description is six paragraphs about six different things: who it
 * is for, the house, the mornings, the treatments, the food, and what to tell
 * us. Run together in one column it is a wall, and the questions inside it are
 * only findable by reading the whole thing. Given their own headings they are
 * answers, and they take the width of the page the way the rest of it does.
 *
 * Not numbered, and not ruled into one line like the arc. These are parts of a
 * thing rather than steps through it, and nothing is lost by reading the food
 * before the bedrooms.
 */
.notes { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-block); width: 100%; }
/* No rule above each answer (Phil, 17 Sep): the swatch and heading already
   start each one, and a line over every answer read as a form. */
.notes > li {
  display: grid; gap: var(--space-base); align-content: start;
}
.notes .t-body { max-width: 46ch; }
.notes .note-head { display: flex; align-items: center; gap: var(--space-base); }
.notes .note-head .t-heading { margin: 0; }
@media (min-width: 640px) {
  .notes { grid-template-columns: 1fr 1fr; column-gap: var(--space-block); }
}

/* ------------------------------------------------------------------ aboutgrid
 *
 * A heading and its opening paragraph on the left, the answers two by two on
 * the right. The left column is the page's grid line, the same one every
 * section head uses, and it stays in view while the answers scroll past it, so
 * the question the section is answering is never off screen.
 *
 * Built for "What it is" on a retreat, where the answers were six paragraphs
 * in one column: the page's empty space is on the left under the heading, on
 * purpose, rather than scattered through a wall of words.
 */
.aboutgrid { display: grid; gap: var(--space-block); width: 100%; align-items: start; }
.aboutgrid > .aboutgrid-head { display: grid; gap: var(--space-roomy); align-content: start; }
.aboutgrid > .aboutgrid-head .t-lede,
.aboutgrid > .aboutgrid-head .t-body { max-width: 42ch; }
@media (min-width: 900px) {
  .aboutgrid { grid-template-columns: minmax(0, var(--head-col)) minmax(0, 1fr); column-gap: var(--space-block); }
  .aboutgrid > .aboutgrid-head { position: sticky; top: calc(var(--head-h, 68px) + var(--space-roomy)); }
}
/* Whatever runs under it, the day by day arc, takes the full width again. */
.aboutgrid + .arc { margin-block-start: var(--space-block); }

/* ------------------------------------------------------------------ photorow
 *
 * Photographs side by side, three to a row, no captions. For a place: the house,
 * the room, the fire. They are proof, not links, so they do not move on hover.
 */
.photorow { display: grid; gap: var(--space-base); width: 100%; }
.photorow-im { border-radius: var(--radius-sm); overflow: hidden; aspect-ratio: 4 / 3; background: var(--rule-colour); }
.photorow-im img { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 720px) { .photorow { grid-template-columns: repeat(3, 1fr); } }
/* A small photograph at its own size, centred in its column, not upscaled. */
.photorow-im--native { aspect-ratio: auto; background: none; justify-self: center; align-self: center; width: 100%; max-width: var(--native-w); }
.photorow-im--native img { height: auto; }
/* More than three (Marye, 5 Oct 2026: the Sacred Return and the cottages on
 * Personalised): rows of three that wrap, two a row on a phone, and a short
 * last row centred rather than left hanging against one edge. */
.photorow--many { display: flex; flex-wrap: wrap; justify-content: center; }
.photorow--many > .photorow-im { flex: 0 0 calc((100% - var(--space-base)) / 2); }
@media (min-width: 720px) { .photorow--many > .photorow-im { flex-basis: calc((100% - 2 * var(--space-base)) / 3); } }
.photorow--many > .photorow-im--native { flex: 0 1 var(--native-w); max-width: min(var(--native-w), calc((100% - var(--space-base)) / 2)); }

/* ------------------------------------------------------------ circlefeature
 *
 * A photograph in a large circle beside its words: the answer swatch at full
 * scale, so the inner pages share one signature shape. After August Health's
 * circular masks. Photographs only; a texture belongs in a swatch. The circle
 * sits on the page's grid line; the words take the other column.
 */
.circlefeature { display: grid; gap: var(--space-block); align-items: center; width: 100%; }
.circlefeature-art { margin: 0; justify-self: center; width: min(100%, 30rem); }
.circlefeature-art img {
  display: block; width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: 50%; background: var(--rule-colour);
}
.circlefeature-words { display: grid; gap: var(--space-roomy); align-content: center; }
.circlefeature-words .t-body, .circlefeature-words .t-lede { max-width: 54ch; }
@media (min-width: 900px) {
  .circlefeature { grid-template-columns: minmax(0, var(--head-col)) minmax(0, 1fr); column-gap: var(--space-block); }
  .circlefeature-art { justify-self: start; }
  /* Photograph on the right: the words take the wide column, so the pair
     doesn't leave a gap between a narrow column of text and the circle. */
  .circlefeature--right { grid-template-columns: minmax(0, 1fr) minmax(0, var(--head-col)); }
  .circlefeature--right .circlefeature-art { grid-column: 2; grid-row: 1; justify-self: end; }
  .circlefeature--right .circlefeature-words { grid-column: 1; grid-row: 1; }
}

/* The portrait variant (ECHOSTUDIO-207): upright, the small radius, the face
   kept in the top third. Narrower than the circle so it does not take over. */
.circlefeature--portrait .circlefeature-art { width: min(100%, 26rem); }
.circlefeature--portrait .circlefeature-art img {
  aspect-ratio: 4 / 5; border-radius: var(--radius-sm); object-position: 50% 25%;
}

/* ------------------------------------------------------------------ ttiles
 *
 * Options somebody chooses between: a gift, a membership, a rebate. Each is a
 * tinted tile with no border and no shadow, a large round texture, its name,
 * what it costs, one line, and where to go. After the tinted feature cards of
 * Function Health and Leandra Isler. The tile takes the other tone from its
 * section, so it lifts off paper and sinks into raised.
 */
.ttiles-wrap { display: grid; gap: var(--space-block); width: 100%; }
.ttiles { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-base); width: 100%; }
@media (min-width: 640px) { .ttiles { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); } }
.ttile {
  --tile-bg: var(--tone-raised-bg);
  background: var(--tile-bg); border-radius: 16px;
  padding: clamp(1.5rem, 2.4vw, 2.25rem);
  display: grid; grid-template-rows: auto auto auto 1fr auto; gap: var(--space-snug); align-content: start;
}
.tone-raised .ttile, .tone-sand .ttile { --tile-bg: var(--tone-paper-bg); }
.ttile-art { display: block; inline-size: 7rem; block-size: 7rem; border-radius: 50%; object-fit: cover; margin-block-end: var(--space-snug); background: var(--rule-colour); }
/* A drawing is not a swatch: it sits on the tile with no plate behind it and no
 * crop, because the cast shadow is part of the drawing. Pulled left by its own
 * optical margin, the way the treatment pages place them. */
.ttile-draw {
  display: block; inline-size: min(11rem, 70%); block-size: auto;
  margin-inline-start: -0.5rem; margin-block-end: var(--space-snug);
}
.ttile-price { font-variant-numeric: tabular-nums; }
/* Fixed rows, so a tile without a price keeps its words and button level with
 * the tile beside it instead of moving up one row. */
.ttile > .ttile-price { grid-row: 3; }
.ttile > .t-body, .ttile > span:not(.ttile-art) { grid-row: 4; }
.ttile > .ttile-link { grid-row: 5; }

/* The journal tiles under a section heading on a post: the heading already
 * separates them, and there are no hairlines above content. The layout gap
 * spaces them, so the older sheet's margin and padding go too. */
.sys-wrap > .jgrid { margin-block-start: 0; padding-block-start: 0; border-block-start: 0; }

/*
 * A short left column stays with its section.
 *
 * `.aboutgrid` has done this since it was built and it is right everywhere the
 * same shape appears: a heading, or a heading and a line, on the grid line with
 * something long beside it. Sticky costs nothing when the two columns are the
 * same height, so it is safe on every one of them.
 */
@media (min-width: 900px) {
  .sechead > .sechead-words,
  .blk-text--head > div:first-child,
  .circlefeature-words,
  .withrail--line > .rail {
    position: sticky;
    top: calc(var(--head-h, 68px) + var(--space-roomy));
  }
}
.ttile .t-body { max-width: 40ch; }
.ttile-link { justify-self: start; margin-block-start: var(--space-snug); }
/* A tile with two ways on: the button, and a quieter link beside it. */
.ttile-links { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-snug) var(--space-base); }
.ttile-more { font-size: var(--text-small-size); color: inherit; text-decoration: underline; text-underline-offset: 0.2em; }
.ttile-more:hover { text-decoration-thickness: 2px; }

/* ------------------------------------------------------------------ figures
 *
 * A few numbers that show scale at a glance, in the display serif, each with a
 * small texture beside its label. Only facts: dates from her sources, counts
 * from Site settings.
 */
.figures { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-block) var(--space-base); width: 100%; }
@media (min-width: 640px) { .figures { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .figures { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); } }
.figures > li { display: grid; gap: var(--space-snug); align-content: start; }
.figures-value {
  font-family: var(--text-display-family); font-weight: var(--text-display-weight);
  font-size: clamp(3rem, 6vw, 5rem); line-height: .95; letter-spacing: -.02em; font-variant-numeric: lining-nums;
}
.figures-label { display: flex; align-items: center; gap: var(--space-base); }
.figures-label .swatch { inline-size: 2.5rem; block-size: 2.5rem; }
.figures-label .t-body { max-width: 26ch; }

/* ------------------------------------------------------------------ topics
 *
 * Pill links that jump to the sections of a long page, each with its texture.
 * Anchored sections leave room for the sticky header.
 */
.topics { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-snug); }
.topics a {
  display: inline-flex; align-items: center; gap: .65rem; min-height: 3rem;
  padding: .35rem 1.1rem .35rem .35rem; border-radius: var(--radius-pill);
  background: var(--tone-raised-bg); color: inherit; text-decoration: none;
  transition: background .25s var(--ease, ease);
}
.tone-raised .topics a { background: var(--tone-paper-bg); }
.topics a:hover { background: var(--rule-colour); }
.topics .swatch { inline-size: 2.3rem; block-size: 2.3rem; }
[id].blk-faq { scroll-margin-top: calc(var(--head-h, 68px) + 1.5rem); }

/* ------------------------------------------------------------------ swatch
 *
 * A small round crop of one of the film stills, beside the name of a thing.
 *
 * Not a picture of the thing. "Food" is not a photograph of food and "The
 * house" is not the house: they are macro crops of clay, creek water, dry
 * grass and haze from the six stills the bands already use, so the set shares
 * one palette and one hand, the way Meadowell pair a symptom with a texture
 * rather than an illustration of it. They are decoration, so they carry no
 * alt text and are hidden from screen readers.
 */
.swatch {
  inline-size: 3.75rem; block-size: 3.75rem; flex: none; border-radius: var(--radius-pill);
  background-image: var(--sw);
  background-position: var(--sw-at);
  background-size: var(--sw-zoom);
  background-repeat: no-repeat;
  background-color: var(--rule-colour);
}
/* A generated texture of the answer's own: the image fills the circle. */
img.swatch--image { display: block; object-fit: cover; background: var(--rule-colour); }
.swatch--clay    { --sw: url("/assets/img/w/film-band-clay-800.webp");    --sw-at: 82% 72%; --sw-zoom: 700%; }
.swatch--pool    { --sw: url("/assets/img/w/film-band-pool-800.webp");    --sw-at: 52% 48%; --sw-zoom: 500%; }
.swatch--straw   { --sw: url("/assets/img/w/film-band-ridge-800.webp");   --sw-at: 35% 88%; --sw-zoom: 900%; }
.swatch--water   { --sw: url("/assets/img/w/film-band-river-800.webp");   --sw-at: 66% 74%; --sw-zoom: 700%; }
.swatch--haze    { --sw: url("/assets/img/w/film-band-ridge-800.webp");   --sw-at: 62% 36%; --sw-zoom: 900%; }
.swatch--tussock { --sw: url("/assets/img/w/film-band-tussock-800.webp"); --sw-at: 32% 62%; --sw-zoom: 550%; }
.swatch--mist    { --sw: url("/assets/img/w/film-band-river-800.webp");   --sw-at: 58% 18%; --sw-zoom: 650%; }
.swatch--meadow  { --sw: url("/assets/img/w/film-band-running-800.webp"); --sw-at: 8% 85%;  --sw-zoom: 650%; }

/* ---------------------------------------------------------------- eyebrow
 *
 * "02  PRACTITIONERS", the way the home page sets it: the number first in the
 * muted ink, the name of the section after it. It tells somebody where they
 * are in a page, which a bare label does not.
 */
.eyebrow { display: flex; align-items: baseline; gap: var(--space-snug); }
.eyebrow > .n { font-variant-numeric: tabular-nums; color: var(--muted, inherit); }

/* ------------------------------------------------------------------- arc
 *
 * An ordered run of steps with a rule through it and a dot on each one.
 *
 * For the things that really are sequences: a spa ritual is a foot soak, then
 * a massage, then a facial, then tea, in that order and no other; a retreat
 * runs Friday to Sunday; panchakarma has stages. Setting those as a bulleted
 * list throws away the one thing that matters most about them.
 *
 * The rule is carried on each step rather than the container, and the steps
 * are flush, so the segments join into one line across the page.
 */
.arc { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-block); width: 100%; }
.arc > li {
  display: grid; gap: var(--space-snug); align-content: start;
  padding-block-start: var(--space-roomy); position: relative;
  border-block-start: var(--space-hair) solid var(--rule-colour);
}
/* The dot sits on the rule, not under it. */
.arc > li::before {
  content: ""; position: absolute; inset-block-start: -0.3125rem; inset-inline-start: 0;
  inline-size: 0.5625rem; block-size: 0.5625rem; border-radius: var(--radius-pill);
  background: currentColor;
}
.arc .n { font-variant-numeric: tabular-nums; color: var(--muted, inherit); }
.arc .t-body { max-width: 42ch; }
@media (min-width: 900px) {
  /* No column gap, so the segments of rule join into one line across the page.
   * A row gap all the same: five steps on a 960px screen wrap to a second row,
   * and with gap:0 that row's rule was drawn straight through the last line of
   * the step above it. */
  .arc { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); column-gap: 0; row-gap: var(--space-block); }
  .arc > li { padding-inline-end: var(--space-block); }
}

/* The same run of steps when there are a dozen of them rather than four, and
 * they are things included rather than things that happen in order: two
 * columns, the number against the left, still ruled and still counted. */
.arc--dense > li { grid-template-columns: auto 1fr; align-items: baseline; column-gap: var(--space-base); padding-block: var(--space-snug); }
.arc--dense > li::before { display: none; }
.arc--dense .t-body { max-width: 52ch; }
@media (min-width: 900px) {
  .arc--dense { grid-template-columns: 1fr 1fr; column-gap: var(--space-block); }
  .arc--dense > li { padding-inline-end: 0; }
}

/* ----------------------------------------------------------------- chips
 *
 * Short facts in a row, each in its own outline: twelve to thirty-six weeks,
 * two nights, all meals, sixteen places. They are read at a glance and never
 * in sentences, which is exactly what a list of them should look like.
 *
 * Square rather than a capsule. The rest of this design is nearly square and
 * that was a decision, so a row of lozenges would be a visitor from another
 * site.
 */
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-tight); }
.chips > li {
  border: var(--space-hair) solid var(--rule-colour);
  border-radius: var(--radius-sm);
  padding: var(--space-tight) var(--space-snug);
  font: var(--text-small-weight) var(--text-small-size)/1.2 var(--text-small-family);
}

/* --------------------------------------------------------------- factbar
 *
 * The four things somebody checks before they read anything: when, where, how
 * long, how much. Across the page under the opener, divided by hairlines.
 */
.factbar {
  display: grid; gap: var(--space-roomy); width: 100%;
  padding-block: var(--space-roomy);
}
.factbar > div { display: grid; gap: var(--space-tight); align-content: start; }
.factbar dt, .factbar dd { margin: 0; }
@media (min-width: 720px) {
  /* Packed from the left and capped, rather than stretched across the page.
     Two facts spread over 1440px put a hairline divider in the middle of
     nowhere with a screen between the label and the next one. */
  .factbar { grid-template-columns: repeat(auto-fit, minmax(11rem, 18rem)); justify-content: start; gap: 0; }
  .factbar > div + div {
    border-inline-start: var(--space-hair) solid var(--rule-colour);
    padding-inline-start: var(--space-roomy);
  }
  .factbar > div { padding-inline-end: var(--space-roomy); }
}

/* ---------------------------------------------------------------- ctarow
 *
 * A section that has made its case, and the thing to do about it.
 *
 * Every page used to keep all of its invitations for the very bottom, so a
 * reader convinced by the second section had nowhere to go but the scrollbar.
 */
.ctarow {
  display: grid; gap: var(--space-roomy); width: 100%;
  padding-block-start: var(--space-roomy);
}
.ctarow .t-body, .ctarow .t-lede { max-width: 58ch; }
@media (min-width: 900px) {
  .ctarow { grid-template-columns: 1fr auto; align-items: center; column-gap: var(--space-block); }
  .ctarow > .btn-cta { justify-self: end; }
}

/* A small picture at its own size, centred in its column, never bled to the
   edges or stretched to the height of the words (ECHOSTUDIO-207). */
.blk-split.blk-split--inset img,
.blk-split.blk-split--inset[data-side] img {
  justify-self: center; align-self: center;
  width: min(100%, var(--inset-w, 340px)); max-width: 100%;
  height: auto; min-height: 0; max-height: none; aspect-ratio: auto;
  margin: 0; border-radius: var(--radius-sm);
}

/* ---- site.css ---- */
/* ============================================================
   Maiaveda concept site
   Palette: her teal (#008487) as structure, palm-leaf parchment as
   canvas, her brand orange (#d6712d) as the single action colour.
   Type: Newsreader (display) + Figtree (text)
   ============================================================ */

:root{
  --teal-950:#062627;
  --teal-900:#0C4243;
  --teal-800:#134F51;
  --teal-700:#1D6465;
  --brand:#008487;
  --teal-deep:#007073;   /* small teal text on light: 5.2:1 */
  --teal-300:#9FBDBB;    /* muted text on dark: 5.6:1 on teal-900 */

  --parchment:#F7F1E6;
  --parchment-2:#EFE5D3;
  --parchment-3:#E3D5BE;
  --hair:#CFC3B0;        /* hairlines on light */
  --stone:#D9D0C4;
  --stone-2:#CFC7BB;
  --stone-3:#B9B1A6;

  --orange:#d6712d;      /* her brand orange. Text on it is always teal-950: 4.8:1 */
  --orange-hi:#E07F3C;
  --orange-deep:#B85E22;
  --orange-action:#A85520; /* white on this: 5.27:1 */
  --orange-action-deep:#8E4517;
  --amber:#E9A82E;       /* dark grounds only: date stamp, prices */

  --ink:#1F2A29;
  --ink-muted:#4C5C5A;

  /* Never less than the safe area, so a phone on its side keeps the logo, menu
     and text clear of the notch. The insets are 0 everywhere else (ECHOSTUDIO-789). */
  --gutter:max(clamp(.875rem,2.2vw,1.5rem), env(safe-area-inset-left), env(safe-area-inset-right));
  --pad:clamp(1.25rem,5vw,3.5rem);
  --gap:clamp(2.5rem,6vw,5rem);
  --rule:1px solid var(--hair);
  --rule-dark:1px solid rgba(159,189,187,.22);
  --r:4px;

  /* --newsreader and --figtree are the self-hosted faces from next/font, set
     on <html> by the site layout (ECHOSTUDIO-789). */
  --serif:var(--newsreader),Georgia,"Times New Roman",serif;
  --sans:var(--figtree),"Helvetica Neue",Arial,sans-serif;
  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
/* Route changes must land at the top rather than animating there. In-page
   anchors are smoothed in the behaviour layer instead. */
html{-webkit-text-size-adjust:100%; scroll-behavior:auto; scroll-padding-top:90px}

body{
  margin:0; background:var(--parchment); color:var(--ink);
  font-family:var(--sans); font-size:1.0625rem; line-height:1.6;
  font-variant-numeric:tabular-nums; overflow-x:clip; text-rendering:optimizeLegibility;
}
img{max-width:100%; height:auto; display:block}
a{color:var(--teal-deep); text-underline-offset:3px; text-decoration-thickness:1px}
a:hover{color:var(--ink)}
:focus-visible{outline:3px solid var(--brand); outline-offset:3px; border-radius:2px}
.on-dark :focus-visible{outline-color:var(--amber)}
h1,h2,h3,h4{
  font-family:var(--serif); font-weight:500;
  font-variation-settings:"SOFT" 28,"WONK" 1; line-height:1.04; letter-spacing:-.018em;
  margin:0; text-wrap:balance;
}
h1{font-size:clamp(2.6rem,7vw,5.6rem); font-variation-settings:"SOFT" 20,"WONK" 1,"opsz" 144; letter-spacing:-.03em}
h2{font-size:clamp(2rem,4.8vw,3.6rem); font-variation-settings:"SOFT" 24,"WONK" 1,"opsz" 96}
h3{font-size:clamp(1.25rem,2.3vw,1.6rem); font-variation-settings:"SOFT" 30,"WONK" 1,"opsz" 40}
h4{font-size:1.1rem}
p{margin:0 0 1rem}
.lede{font-size:clamp(1.08rem,1.6vw,1.25rem); color:var(--ink-muted); max-width:56ch; line-height:1.55}
.on-dark .lede{color:var(--stone-2)}
.small{font-size:.86rem; color:var(--ink-muted)}
.on-dark .small{color:var(--teal-300)}
.serif-i{font-family:var(--serif); font-style:italic; font-variation-settings:"SOFT" 60,"WONK" 1}
.wrap{width:100%; padding-inline:var(--gutter)}
.narrow{max-width:72ch}
.measure{max-width:60ch}
.skip{position:absolute; left:-9999px; top:0; z-index:200; background:var(--teal-900); color:var(--parchment); padding:.75rem 1.25rem; font-weight:600}
.skip:focus{left:.5rem; top:.5rem}
.vh{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}

/* labels ------------------------------------------------------- */
.label{
  font-size:.72rem; font-weight:600; letter-spacing:.16em; text-transform:uppercase;
  color:var(--teal-deep); margin:0 0 1rem; display:block;
}
.on-dark .label{color:var(--amber)}
.label .n{display:inline-block; min-width:2.4em; color:var(--ink-muted)}
.on-dark .label .n{color:var(--teal-300)}

/* grain -------------------------------------------------------- */
.grain{
  position:fixed; inset:0; pointer-events:none; z-index:95; opacity:.35;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.3'/%3E%3C/svg%3E");
  mix-blend-mode:multiply;
}

/* header ------------------------------------------------------- */
/*
 * Solid by default, transparent only over a hero.
 *
 * It was the other way round: the bar had no background anywhere and blended
 * with `difference` so its marks inverted over whatever was behind them. That
 * is a lovely idea and it only works over a photograph. On the pages with no
 * hero, and on every page once you had scrolled past one, the nav sat directly
 * on top of running text with nothing separating the two, and hovering a top
 * level link that has no dropdown gave no feedback at all, because only an
 * open mega menu ever painted a background.
 *
 * `over-hero` is the exception now rather than the rule. site-behaviours.ts has
 * been computing it for months, adding and removing the class on scroll; no
 * rule in any stylesheet ever read it, so the work was thrown away every frame.
 *
 * No backdrop-filter: it would create a stacking context and the blend inside
 * the exception would have nothing behind it to work against.
 */
.site-head{
  position:fixed; left:0; right:0; top:0; z-index:80; padding-top:env(safe-area-inset-top);
  background:var(--parchment); border-bottom:1px solid var(--hair);
  transition:background .2s var(--ease), border-color .2s var(--ease);
}
.site-head .brand{background:transparent; padding:0}
.site-head .nav a.top, .site-head .nav button.top{color:var(--ink-muted)}
.site-head .nav li.open > .top{color:var(--ink)}
.site-head .burger{color:var(--ink)}
.site-head .head-cta .btn2{color:var(--ink)}
.site-head .head-cta .btn2:hover{color:var(--teal-deep)}
/* The mark is drawn light for the photograph, so on parchment it inverts. */
.site-head .brand-mark{filter:invert(1)}

/*
 * Over a hero the bar is the photograph.
 *
 * A solid strip across the top of a full bleed image costs the first thing
 * anyone sees, and on a phone that strip was a third of what fitted above the
 * fold. The blend goes on the bar, not on the marks inside it: `position:fixed`
 * with a z-index makes the header its own stacking context, so a child blending
 * inside it has nothing behind it but transparency. The bar blends against the
 * page and everything in it inverts together.
 *
 * White is the only colour this blend can be trusted with. Dark ink under
 * difference against a mid-toned photograph subtracts to something close to the
 * photograph itself, which is how the phone number went muddy and nearly
 * vanished.
 */
.site-head.over-hero{
  background:transparent; border-bottom-color:transparent;
  mix-blend-mode:difference;
}
.site-head.over-hero .burger{color:#fff}
.site-head.over-hero .nav a.top, .site-head.over-hero .nav button.top{color:#fff}
.site-head.over-hero .head-cta .btn2{color:#fff}
.site-head.over-hero .head-cta .btn2:hover{color:#bfbfbf}
.site-head.over-hero .brand-mark{filter:none}
/*
 * The hero starts at the top of the screen.
 *
 * No negative margin is needed: over a hero the bar is `fixed`, so it is out of
 * the flow already and the hero begins at zero on its own. The content inside
 * is pushed down instead, or the first line sits behind the logo.
 */
body.hero-top .hero{padding-block-start:calc(var(--head-h, 68px) + clamp(1.5rem, 4vw, 3rem))}
/* Pages that do not open with a hero would otherwise start under the bar. */
body:not(.hero-top) main,
body:not(.hero-top) .page-hero:first-child{padding-block-start:var(--head-h, 68px)}
/* The same decision from the markup, so a page that opens with a hero is drawn
   that way from the first paint. Waiting for the script moved the whole hero up
   68px once it ran, a layout shift Google counts (ECHOSTUDIO-789). The class
   above stays for browsers without :has(). */
body:has(> main > :is(.hero, .mh):nth-child(1 of :not(script, style, template, noscript))) main{padding-block-start:0}
/* 69px before the script measures it: the bar's 68px and its 1px rule. */
body:has(> main > .hero:nth-child(1 of :not(script, style, template, noscript))) .hero{padding-block-start:calc(var(--head-h, 69px) + clamp(1.5rem, 4vw, 3rem))}
.site-head .bar{display:flex; align-items:center; gap:1.5rem; min-height:68px; padding-block:.55rem}
.brand{display:inline-flex; align-items:center; text-decoration:none; background:var(--brand); padding:.5rem .85rem .45rem; border-radius:var(--r); flex:none}
.brand img{width:124px; height:auto}
/* One or the other, never both. */
.brand-mark{display:block; width:40px !important}
/* The lock up with its teal box is never used in the bar now. */
.brand-full{display:none}
@media (max-width:430px){.brand{padding:.42rem .65rem .38rem}.brand img{width:98px}}
.nav{display:none; gap:.25rem; margin-inline:auto}
@media (min-width:1080px){.nav{display:flex}}
.nav > li{list-style:none; position:static}
.nav{padding:0; margin-block:0}
.nav a.top, .nav button.top{
  appearance:none; background:none; border:0; cursor:pointer; font:inherit;
  display:inline-flex; align-items:center; gap:.4rem; padding:.7rem .8rem;
  font-size:.8rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-muted); text-decoration:none; border-radius:999px;
}
/*
 * Six items, a mark and the Book button share 1080 pixels at the narrowest
 * desktop width. At full padding the button was pushed off the right edge, and
 * before the regroup "Gift vouchers" wrapped onto two lines. Tighter padding
 * until there is room for the full amount.
 */
@media (min-width:1080px) and (max-width:1279px){.nav a.top, .nav button.top{padding-inline:.55rem}}
.nav a.top:hover, .nav button.top:hover, .nav li.open > .top, .nav a.top[aria-current="page"]{color:var(--ink); background:var(--parchment-2)}
.nav button.top svg{width:10px; height:10px; transition:transform .25s var(--ease)}
.nav li.open > button.top svg{transform:rotate(180deg)}
.head-cta{display:none; align-items:center; gap:.4rem; margin-left:auto}
@media (min-width:640px){.head-cta{display:flex}}
/*
 * Two fine lines, close together, that cross into an X when the menu is open.
 *
 * Three thick bars with air between them is the default every framework ships
 * with. This is lighter and tighter, and it is one control rather than two: the
 * same button opens and closes, so there is no second cross floating inside the
 * panel.
 */
.burger{
  appearance:none; background:none; border:0; cursor:pointer; padding:0;
  width:44px; height:44px; position:relative; display:block; margin-left:auto; color:var(--ink);
}

@media (min-width:640px){.burger{margin-left:0}}
@media (min-width:1080px){.burger{display:none}}
.burger span{
  position:absolute; left:50%; top:50%;
  display:block; width:24px; height:1.5px; background:currentColor; border-radius:2px;
  transition:transform .42s cubic-bezier(.65,0,.35,1);
}
/* Closed: a tight pair, 5px apart. */
.burger span:nth-child(1){transform:translate(-50%,-50%) translateY(-2.75px)}
.burger span:nth-child(2){transform:translate(-50%,-50%) translateY(2.75px)}
/* Open: the same two lines, crossed. Nothing appears or disappears. */
.burger[aria-expanded="true"] span:nth-child(1){transform:translate(-50%,-50%) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){transform:translate(-50%,-50%) rotate(-45deg)}

/* The bar stays above the open panel so the button is still the way out. */
.site-head{z-index:130}

/*
 * With the panel open the backdrop is a known colour, so the blend stands down.
 * Difference against deep teal turns white into salmon, which is a fine effect
 * over a photograph and the wrong one for a close button.
 */
body.menu-open .site-head{mix-blend-mode:normal; color:var(--parchment)}
body.menu-open .burger{color:var(--parchment)}

/*
 * The same for a desktop dropdown, which was the bug: the panels live inside
 * the bar, so the bar's blend composited them against the page as well. They
 * opened see-through, with the page text showing through the menu and every
 * photograph in it turned to a negative. With a panel open the backdrop is the
 * panel's own parchment, so the bar goes solid and uses its real colours, and
 * the light mark is inverted to read on it.
 */
/*
 * Over a hero the bar comes forward as soon as you reach for it.
 *
 * Three ways in, and they all land on the same state: an open mega menu, the
 * pointer anywhere in the bar, or the keyboard arriving in it. The bar is a
 * fixed full width strip, so `:hover` on the element itself fires the moment
 * the pointer crosses into that band, which is what you expect of a navigation
 * that is otherwise invisible. Hovering a top level link with no dropdown used
 * to do nothing at all, because an open panel was the only trigger.
 *
 * `:focus-within` is not decoration. Without it a keyboard user tabs into a
 * white link sitting on a photograph with no background behind it.
 */
.site-head.over-hero:has(.nav > li.open),
.site-head.over-hero:hover,
.site-head.over-hero:focus-within{mix-blend-mode:normal; background:var(--parchment); border-bottom-color:var(--hair)}
.site-head.over-hero:has(.nav > li.open) .nav a.top,
.site-head.over-hero:has(.nav > li.open) .nav button.top,
.site-head.over-hero:hover .nav a.top,
.site-head.over-hero:hover .nav button.top,
.site-head.over-hero:focus-within .nav a.top,
.site-head.over-hero:focus-within .nav button.top{color:var(--ink-muted)}
.site-head.over-hero:has(.nav > li.open) .burger,
.site-head.over-hero:hover .burger,
.site-head.over-hero:focus-within .burger{color:var(--ink)}
.site-head.over-hero:has(.nav > li.open) .brand-mark,
.site-head.over-hero:hover .brand-mark,
.site-head.over-hero:focus-within .brand-mark{filter:invert(1)}
.site-head.over-hero:has(.nav > li.open) .head-cta .btn2,
.site-head.over-hero:hover .head-cta .btn2,
.site-head.over-hero:focus-within .head-cta .btn2{color:var(--ink-muted)}
/*
 * The Book button is drawn in its own fixed layer outside the header, because
 * the header blends and everything inside a blending element blends with it.
 * That layer cannot see the header's hover, so it is told about it here: the
 * two sit on top of each other and have to change together or the button
 * appears to float on nothing.
 */
.head-book{transition:background .2s var(--ease)}
.site-head:has(.nav > li.open) .nav li.open > .top{color:var(--ink); background:var(--parchment-2)}
/*
 * The Book button's own layer, outside the blended header. See Header.tsx.
 * The bar's measurements are repeated here rather than shared, because the
 * header's rules are scoped to .site-head; if one changes, change both. The
 * header keeps an invisible copy of the button so everything else holds still.
 */
.head-cta .book-space{visibility:hidden}
.head-book{position:fixed; top:0; left:0; right:0; z-index:131; pointer-events:none; display:none; padding-top:env(safe-area-inset-top)}
@media (min-width:640px){.head-book{display:block}}
.head-book .bar{display:flex; align-items:center; justify-content:flex-end; gap:1.5rem; min-height:68px; padding-block:.55rem}
.head-book .btn{pointer-events:auto}
.head-book .burger-space{width:44px; height:44px; flex:none}
@media (min-width:1080px){.head-book .burger-space{display:none}}

@media (prefers-reduced-motion: reduce){.burger span{transition:none}}

/* mega menu ---------------------------------------------------- */
.mega{
  overflow:hidden; position:absolute; left:0; right:0; top:100%; background:var(--parchment);
  border-bottom:var(--rule); box-shadow:0 30px 60px -40px rgba(6,38,39,.45);
  opacity:0; visibility:hidden; transform:translateY(-6px);
  transition:opacity .22s var(--ease), transform .22s var(--ease), visibility 0s linear .22s;
  /* A closed menu is not rendered at all, so the photographs inside it are not
     downloaded until someone opens it. With visibility alone the browser still
     fetched every thumbnail in every menu on every page: about 6MB. */
  content-visibility:hidden;
}
.nav li.open > .mega{opacity:1; visibility:visible; transform:none; transition-delay:0s; content-visibility:visible}
/* Switching between two menus: no drop, no rise, the panels crossfade where
   they are. The class is put on by the behaviour layer for the length of the
   fade. */
.nav.switching > li > .mega{transform:none; transition:opacity .18s var(--ease), visibility 0s linear .18s}
.nav.switching > li.open > .mega{transition-delay:0s}
.mega-in{display:grid; gap:0; padding:0}
.mega-in{grid-template-columns:1.1fr 1fr 1fr 1.2fr}
.mega-col{padding:1.5rem 1.5rem 1.75rem; border-right:var(--rule)}
.mega-col:last-child{border-right:0}
.mega-col .label{margin-bottom:.8rem}
.mega-col ul{list-style:none; margin:0; padding:0}
.mega-col li a{display:flex; justify-content:space-between; gap:1rem; padding:.5rem 0; border-bottom:1px solid var(--parchment-3); text-decoration:none; color:var(--ink); font-size:.95rem}
.mega-col li a small{color:var(--ink-muted); font-size:.8rem}
.mega-col li a:hover{color:var(--teal-deep)}
.mega-col li:last-child a{border-bottom:0}
/* The rule above was written for the first mega menus, plain link lists. In
   the list and photograph layout the only <a> inside an <li> is "See details",
   and it inherited a hairline under it on every row but the last. No lines
   under a link, and no line between the list and the photograph. */
.mega-col .llist li a{border-bottom:0; padding:0}
.mega-2 .mega-col{border-right:0}
.mega-tile{display:block; text-decoration:none; color:var(--ink); border-radius:var(--r); overflow:hidden; position:relative}
.mega-tile img{aspect-ratio:4/3; object-fit:cover; width:100%; border-radius:var(--r); transition:transform .6s var(--ease)}
.mega-tile:hover img{transform:scale(1.03)}
.mega-tile b{display:block; font-family:var(--serif); font-weight:500; font-size:1.25rem; margin-top:.75rem}
.mega-tile span{display:block; color:var(--ink-muted); font-size:.86rem}

h2[tabindex]:focus{outline:0}
.mega-in{max-width:1400px; margin-inline:auto}
/* drawer ------------------------------------------------------- */
/*
 * The menu arrives rather than slides.
 *
 * A panel sliding in from the right is the default every template ships with.
 * This opens from the corner the burger is in: the ground expands out from
 * under the button, then the links rise into it one after another. The whole
 * thing is about half a second, which is long enough to read as deliberate and
 * short enough not to be in the way on the second use.
 */
.drawer{
  position:fixed; inset:0; z-index:120; background:var(--teal-900); color:var(--parchment);
  overflow-y:auto; overscroll-behavior:contain;
  /* Sides come from the gutter; top and bottom keep the links off the status
     bar and the home indicator (ECHOSTUDIO-789). */
  padding-top:env(safe-area-inset-top); padding-bottom:env(safe-area-inset-bottom);
  clip-path:circle(0% at calc(100% - 2.4rem) 2.4rem);
  opacity:0;
  transition:clip-path .52s cubic-bezier(.4,0,.2,1), opacity .2s linear .02s;
  pointer-events:none;
}
.drawer.open{
  clip-path:circle(145% at calc(100% - 2.4rem) 2.4rem);
  opacity:1;
  pointer-events:auto;
}

/* The links come up after the ground has arrived under them. */
.drawer .grp, .drawer .top{
  opacity:0; transform:translateY(14px);
  transition:opacity .34s var(--ease), transform .34s var(--ease);
}
.drawer.open .grp, .drawer.open .top{opacity:1; transform:none}
.drawer.open .top{transition-delay:.10s}
.drawer.open .grp:nth-of-type(1){transition-delay:.16s}
.drawer.open .grp:nth-of-type(2){transition-delay:.22s}
.drawer.open .grp:nth-of-type(3){transition-delay:.28s}
.drawer.open .grp:nth-of-type(4){transition-delay:.34s}
.drawer.open .grp:nth-of-type(5){transition-delay:.40s}
.drawer.open .grp:nth-of-type(n+6){transition-delay:.44s}

/* Someone who has asked for less movement gets the panel, not the performance. */
@media (prefers-reduced-motion: reduce){
  .drawer{transition:opacity .2s linear; clip-path:none; visibility:hidden}
  .drawer.open{visibility:visible}
  .drawer .grp, .drawer .top{transition:none; transform:none; opacity:1}
}
.drawer .top{display:flex; align-items:center; justify-content:space-between; padding:.75rem var(--gutter); border-bottom:var(--rule-dark); min-height:68px}
/* Hidden: the burger is the close button now, and two crosses on one screen is
   one too many. Kept in the markup so anything relying on it still finds it. */
.drawer .close{display:none}
.drawer nav, .drawer .drawer-links{padding:1rem var(--gutter) 6rem}
.drawer .grp{border-bottom:var(--rule-dark); padding:.9rem 0}
.drawer .grp > a, .drawer .grp > b{display:block; font-family:var(--serif); font-size:1.7rem; color:var(--parchment); text-decoration:none; font-weight:500}
.drawer .grp ul{list-style:none; margin:.5rem 0 0; padding:0; display:grid; grid-template-columns:1fr 1fr; gap:.15rem 1rem}
.drawer .grp ul a{color:var(--stone); text-decoration:none; font-size:.95rem; display:block; padding:.3rem 0}
.drawer .meta{margin-top:1.5rem; color:var(--teal-300); font-size:.9rem}
.drawer .meta a{color:var(--parchment)}

/* buttons: primary pill + borderless secondary ----------------- */
.btn{
  display:inline-flex; align-items:center; gap:.9rem; min-height:50px;
  padding:.45rem .45rem .45rem 1.35rem; border-radius:999px; border:0; cursor:pointer;
  background:var(--orange-action); color:#fff; text-decoration:none;
  font:600 1.0625rem/1 var(--sans); letter-spacing:.01em; white-space:nowrap; width:fit-content; max-width:100%;
  transition:background .2s var(--ease), transform .2s var(--ease);
}
/* On a phone a label longer than the screen (200% text or zoom) wraps inside
   its pill rather than running off the edge. At normal sizes every label fits
   on one line, so none wraps (ECHOSTUDIO-762). */
@media (max-width:560px){.btn{white-space:normal; line-height:1.15}}
.btn .arr{width:38px; height:38px; border-radius:50%; background:var(--teal-950); color:#fff; display:grid; place-items:center; flex:none; transition:transform .3s var(--ease)}
.btn .arr svg{width:15px; height:15px}
.btn:hover{background:var(--orange-action-deep); color:#fff; transform:translateY(-1px)}
.btn:hover .arr{transform:rotate(-45deg)}
.btn.ghost{background:transparent; color:var(--ink); border:1px solid var(--ink)}
.btn.ghost .arr{background:var(--ink); color:var(--parchment)}
.on-dark .btn.ghost{color:var(--parchment); border-color:rgba(247,241,230,.5)}
.on-dark .btn.ghost .arr{background:var(--parchment); color:var(--teal-900)}
.btn.sm{min-height:42px; padding:.3rem .3rem .3rem 1rem; font-size:.95rem}
.btn.sm .arr{width:32px; height:32px}
.btn.teal{background:var(--teal-900); color:var(--parchment)}
.btn.teal .arr{background:var(--parchment); color:var(--teal-900)}
.btn.teal:hover{background:var(--teal-800); color:var(--parchment)}

.btn2{
  display:inline-flex; align-items:center; gap:.55rem; min-height:50px; padding:.5rem .6rem;
  font:600 .92rem/1 var(--sans); color:var(--ink); text-decoration:none; white-space:nowrap; border-radius:999px;
}
.btn2 svg{width:18px; height:18px; flex:none}
.btn2:hover{color:var(--teal-deep)}
.on-dark .btn2{color:var(--parchment)}
.on-dark .btn2:hover{color:var(--amber)}
.ctas{display:flex; flex-wrap:wrap; align-items:center; gap:.6rem 1rem; margin-top:1.75rem}
/* The button that closes a grid (the full menu under the treatment tiles, the
   team under the portraits) sits under the middle of the grid, not its left
   edge, so it reads as belonging to the whole set rather than the first tile. */
.ctas--center{justify-content:center}
/* On a phone a call to action fills the column it sits in. A button sized to
   its own text reads as an afterthought next to one that does not. */
@media (max-width:560px){
  .ctas{flex-direction:column; align-items:stretch; width:100%}
  .ctas .btn, .ctas .btn2, .ctas .quiet{width:100%; justify-content:space-between}
  .ctas .btn2{justify-content:center}
}
/* The same rule for every page button, not only the ones in a .ctas row: a
   block's "Buy a gift voucher" sat at the width of its label under two rating
   badges that fill the column (Phil, 15 Oct 2026, ECHOSTUDIO-788). That
   includes the small ones in a tile or a price row. The header's small button
   and the arrow-only button keep their own size. In the enquiry form's
   Back/Next row the button takes what Back leaves. */
@media (max-width:560px){
  main .btn:not(.sm), .site-foot .btn,
  .btn-cta:not(.btn-cta--bare){width:100%; justify-self:stretch; justify-content:space-between}
  .enq-nav > .btn-cta{width:auto; flex:1 1 auto}
  .ttile-links{width:100%; justify-self:stretch}
}

/* sections ----------------------------------------------------- */
main{position:relative; z-index:2; background:var(--parchment)}
.sec{padding-block:clamp(3.25rem,7vw,6.5rem); border-top:var(--rule)}
.sec.tight{padding-block:clamp(2rem,4vw,3.5rem)}
.sec.dark{background:var(--teal-900); color:var(--parchment); border-top:0}
.sec.deep{background:var(--teal-950); color:var(--parchment); border-top:0}
.sec.alt{background:var(--parchment-2)}
.dark h1,.dark h2,.dark h3,.deep h1,.deep h2,.deep h3{color:var(--parchment)}
.sec-head{display:grid; gap:1rem 3rem; margin-bottom:clamp(1.75rem,4vw,3rem); align-items:end}
@media (min-width:900px){.sec-head{grid-template-columns:1.3fr 1fr}.sec-head .lede{margin:0}}
.split{display:grid; gap:var(--gap)}
@media (min-width:900px){.split{grid-template-columns:1fr 1fr; align-items:start}}
.split-3{display:grid; gap:1.25rem}
@media (min-width:760px){.split-3{grid-template-columns:repeat(3,1fr)}}
.split-4{display:grid; gap:1.25rem}
@media (min-width:640px){.split-4{grid-template-columns:1fr 1fr}}
@media (min-width:1080px){.split-4{grid-template-columns:repeat(4,1fr)}}
.prose p{max-width:60ch}
.prose ul{padding-left:1.2rem; max-width:60ch}
.prose li{margin-bottom:.35rem}
.dark .prose p, .deep .prose p{color:var(--stone)}
.pull{font-family:var(--serif); font-size:clamp(1.3rem,2.6vw,1.8rem); line-height:1.3; font-style:italic; font-variation-settings:"SOFT" 40,"WONK" 1; color:var(--teal-deep); max-width:30ch; margin:0 0 1.4rem}
.dark .pull{color:var(--amber)}

/* hairline lists ----------------------------------------------- */
.lines{list-style:none; margin:0; padding:0; border-top:var(--rule)}
.lines li{padding:.75rem 0; border-bottom:var(--rule); display:flex; justify-content:space-between; gap:1rem; align-items:baseline}
.lines li em{font-style:normal; color:var(--ink-muted); font-size:.86rem; display:block; margin-top:.15rem}
.dark .lines, .dark .lines li{border-color:rgba(159,189,187,.22)}
.dark .lines li em{color:var(--teal-300)}
dl.facts{margin:0; display:grid; gap:.1rem}
/* Label column then value, side by side while the value has room for 8em
   (true on a 320px phone at normal size); at large text the value drops under its label rather
   than the label running into it (ECHOSTUDIO-762). Sizes in em so the label
   column grows with the reader's text. */
dl.facts > div{display:flex; flex-wrap:wrap; gap:.25rem 1rem; padding:.7rem 0; border-bottom:var(--rule)}
dl.facts > div > dt{flex:0 0 calc(8.5em / .74)} /* 8.5rem at the label's own .74rem */
dl.facts > div > dd{flex:1 1 8em; min-width:0}
/* An email address can't break anywhere sensible, so when it doesn't fit
   beside its label it goes under it whole (ECHOSTUDIO-762). */
dl.facts > div > dd:has(> a[href^="mailto:"]){flex-basis:auto}
dl.facts dt{font-size:.74rem; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-muted); font-weight:600; padding-top:.2rem}
dl.facts dd{margin:0}
.dark dl.facts > div{border-color:rgba(159,189,187,.22)}
.dark dl.facts dt{color:var(--teal-300)}

/* hero --------------------------------------------------------- */
.hero{position:relative; padding-block:clamp(2.5rem,6vw,5rem) clamp(2.5rem,6vw,4.5rem)}
.hero.dark{background:var(--teal-900); color:var(--parchment); overflow:hidden}
.hero.dark::before{content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(120% 90% at 10% 0%,rgba(214,113,45,.22),transparent 55%),radial-gradient(80% 70% at 100% 100%,rgba(233,168,46,.10),transparent 62%)}
.hero .wrap{position:relative; z-index:2}
.hero-grid{display:grid; gap:clamp(2rem,4vw,3.5rem); align-items:end}
@media (min-width:980px){.hero-grid{grid-template-columns:1.15fr .85fr; align-items:stretch}}
.kicker{font-size:.74rem; font-weight:600; letter-spacing:.18em; text-transform:uppercase; color:var(--amber); margin:0 0 1rem}
.hero:not(.dark) .kicker{color:var(--teal-deep)}
.datestamp{display:block; font-family:var(--serif); color:var(--amber); font-size:clamp(3.6rem,15vw,10.5rem); font-weight:600; line-height:.82; letter-spacing:-.045em; font-variation-settings:"SOFT" 12,"WONK" 1,"opsz" 144; margin:.3rem 0 .1rem; font-feature-settings:"lnum" 1}
.datestamp .mo{display:inline-block; font-size:.4em; letter-spacing:.02em; vertical-align:.42em; margin-left:.12em}
.h1-name{display:block; font-family:var(--sans); font-weight:600; font-size:clamp(1.05rem,2.4vw,1.5rem); letter-spacing:.02em; line-height:1.25; color:var(--parchment)}
.dateline{display:flex; flex-wrap:wrap; gap:.4rem 1rem; align-items:baseline; border-top:var(--rule-dark); padding-top:.85rem; margin-top:.9rem; font-size:.9rem; color:var(--teal-300); letter-spacing:.03em}
.dateline b{color:var(--parchment); font-weight:600}
.pricebar{margin-top:1.5rem; padding:1rem 1.15rem; border:var(--rule-dark); background:rgba(6,38,39,.5); border-radius:var(--r); display:flex; flex-wrap:wrap; gap:.5rem 1.6rem; align-items:baseline}
.pricebar .amt{font-family:var(--serif); font-size:1.6rem; color:var(--amber); font-weight:600; line-height:1}
.pricebar .lbl{font-size:.74rem; text-transform:uppercase; letter-spacing:.12em; color:var(--teal-300); display:block; margin-bottom:.2rem}
.pricebar .dep{font-size:.86rem; color:var(--stone); flex-basis:100%; padding-top:.6rem; border-top:var(--rule-dark)}
.pricebar .dep b{color:var(--parchment)}
@media (min-width:620px){.pricebar .dep{margin-left:auto; flex-basis:auto; padding-top:0; border-top:0}}
.rating{margin-top:1.5rem; padding-top:1rem; border-top:var(--rule-dark); display:flex; flex-wrap:wrap; align-items:center; gap:.5rem .9rem; font-size:.86rem; color:var(--stone)}
.stars{color:var(--amber); letter-spacing:.12em; font-size:1rem}
.rating b{color:var(--parchment)}
.hero:not(.dark) .rating{border-top:var(--rule); color:var(--ink-muted)}
.hero:not(.dark) .rating b{color:var(--ink)}
.hero:not(.dark) .stars{color:var(--orange-deep)}
.hero-fig{margin:0; position:relative; display:flex; flex-direction:column; justify-content:flex-end}
.hero-fig img{width:100%; aspect-ratio:4/5; object-fit:cover; object-position:50% 42%; border-radius:var(--r)}
.hero-fig figcaption{margin-top:.7rem; font-size:.74rem; letter-spacing:.06em; text-transform:uppercase; color:var(--teal-300)}
.hero:not(.dark) .hero-fig figcaption{color:var(--ink-muted)}
@media (min-width:980px){.hero-fig img{aspect-ratio:auto; flex:1 1 auto; min-height:clamp(420px,52vh,620px)}}
@media (max-width:979px){.hero-fig img{aspect-ratio:5/4; object-position:50% 38%}}
.page-hero{padding-block:clamp(3rem,7vw,6rem) clamp(2rem,5vw,4rem)}
.page-hero .lede{margin-top:1.25rem}
/* In the media, one appearance: the intro under the title, and the way back to the list. */
.press-intro{margin-top:1.25rem; max-width:40rem}
.press-back{margin-top:1.5rem}
.page-hero .split{align-items:center !important}
.page-hero .split figure img{max-width:min(100%,460px); margin-left:auto}
.crumbs{font-size:.8rem; color:var(--ink-muted); margin:0 0 1.25rem; letter-spacing:.02em}
.crumbs a{color:var(--ink-muted); text-decoration:none}
.crumbs a:hover{color:var(--teal-deep)}
.on-dark .crumbs, .on-dark .crumbs a{color:var(--teal-300)}

/* proof strip -------------------------------------------------- */
.proof{border-top:var(--rule); border-bottom:var(--rule); background:var(--parchment-2)}
.proof .wrap{display:grid; grid-template-columns:1fr}
@media (min-width:640px){.proof .wrap{grid-template-columns:1fr 1fr}}
@media (min-width:1020px){.proof .wrap{grid-template-columns:repeat(4,1fr)}}
.proof-item{padding:1.25rem 0; border-bottom:var(--rule)}
@media (min-width:640px){.proof-item{padding:1.4rem 1.5rem; border-right:var(--rule)}.proof-item:nth-child(2n){border-right:0}}
@media (min-width:1020px){.proof-item{border-bottom:0; border-right:var(--rule)}.proof-item:nth-child(2n){border-right:var(--rule)}.proof-item:last-child{border-right:0}.proof-item:first-child{padding-left:0}}
.proof-item b{display:block; font-family:var(--serif); font-size:1.3rem; font-weight:500; margin-bottom:.15rem; color:var(--teal-deep)}
.proof-item span{display:block; font-size:.86rem; color:var(--ink-muted); line-height:1.45}

/* tiles -------------------------------------------------------- */
.tiles{display:grid; gap:1.25rem}
@media (min-width:640px){.tiles{grid-template-columns:1fr 1fr}}
@media (min-width:1080px){.tiles.c3{grid-template-columns:repeat(3,1fr)}.tiles.c4{grid-template-columns:repeat(4,1fr)}}
.tile{display:block; text-decoration:none; color:inherit; position:relative}
.tile .im{border-radius:var(--r); overflow:hidden; aspect-ratio:4/3; background:var(--parchment-2)}
.tile .im.tall{aspect-ratio:3/4}
.tile .im.sq{aspect-ratio:1}
.tile .im img{width:100%; height:100%; object-fit:cover; transition:transform .7s var(--ease)}
.tile:hover .im img{transform:scale(1.035)}
.tile .cap{display:flex; justify-content:space-between; gap:1rem; align-items:baseline; padding:.85rem 0 0}
.tile .cap b{font-family:var(--serif); font-weight:500; font-size:1.25rem; letter-spacing:-.01em}
.tile .cap span{font-size:.85rem; color:var(--ink-muted); white-space:nowrap}
.tile .cap em{display:block; font-style:normal; color:var(--ink-muted); font-size:.88rem; margin-top:.15rem}
.dark .tile .cap span, .dark .tile .cap em{color:var(--teal-300)}
.tile .circ{position:absolute; right:.75rem; top:.75rem; width:44px; height:44px; border-radius:50%; background:rgba(247,241,230,.9); color:var(--teal-900); display:grid; place-items:center; transform:scale(.6); opacity:0; transition:all .3s var(--ease)}
.tile:hover .circ{transform:none; opacity:1}
@media (hover:hover) and (pointer:fine){.tile[data-cursor] .circ{display:none}}
.cursor-tag{
  position:fixed; left:0; top:0; z-index:110; pointer-events:none; width:86px; height:86px; border-radius:50%;
  /* The deeper orange, because white on the brand orange is 3.36:1 and fails. */
  background:var(--orange-action); color:#fff; display:grid; place-items:center;
  font:600 .78rem/1 var(--sans); letter-spacing:.12em; text-transform:uppercase;
  transform:translate(-50%,-50%) scale(0); transition:transform .28s var(--ease); will-change:transform;
}
/* --rot, --sx and --sy come from the cursor loop: it leans into the direction of
   travel and stretches with speed. The transition softens them further. */
.cursor-tag.on{transform:translate(-50%,-50%) rotate(var(--rot,0deg)) scale(var(--sx,1), var(--sy,1))}
@media (hover:none),(pointer:coarse){.cursor-tag{display:none}}

/* Parked: the lit pill that hangs off the pointer instead of sitting under it.
   Nothing applies this class at the moment. To try it again, have the cursor tag
   in src/lib/site-behaviours.ts add "cursor-tag--pill" alongside "cursor-tag". */
.cursor-tag--pill{
  width:auto; height:40px; border-radius:999px; padding:0 1.15rem;
  background:
    radial-gradient(120% 90% at 28% 8%, rgba(255,255,255,.42) 0%, rgba(255,255,255,0) 58%),
    linear-gradient(to bottom, var(--orange-hi) 0%, var(--orange) 46%, var(--orange-action-deep) 100%);
  /* Inner shading only: the pill lights itself and casts nothing on the page. */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.55),
    inset 0 -6px 10px -6px rgba(64,24,4,.75),
    inset 0 8px 14px -10px rgba(255,255,255,.5);
  text-shadow:0 1px 1px rgba(74,30,6,.5);
  transform:translate(14px,14px) scale(.6); opacity:0;
  transition:transform .26s var(--ease), opacity .2s var(--ease);
  transform-origin:top left;
  overflow:hidden; isolation:isolate;
}
.cursor-tag--pill::after{
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  opacity:.3; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23g)' opacity='0.5'/%3E%3C/svg%3E");
}
.cursor-tag--pill.on{transform:translate(14px,14px) scale(1); opacity:1}

/* photo band with parallax -------------------------------------- */
.pband{position:relative; overflow:hidden; height:clamp(260px,46vw,560px); border-radius:0}
.pband img{position:absolute; left:0; top:-12%; width:100%; height:124%; object-fit:cover; will-change:transform}
.pband .cap{position:absolute; left:var(--gutter); bottom:1rem; color:var(--parchment); font-size:.76rem; letter-spacing:.06em; text-transform:uppercase; text-shadow:0 1px 2px rgba(0,0,0,.4)}
.pband .cap.dk{color:var(--ink); text-shadow:none}
.pband.r{border-radius:var(--r)}

/* pictogram lists ---------------------------------------------- */
.picto{display:grid; gap:1.25rem}
@media (min-width:640px){.picto{grid-template-columns:1fr 1fr}}
@media (min-width:1080px){.picto{grid-template-columns:repeat(4,1fr)}}
.picto .it{border-top:1px solid var(--teal-deep); padding:1rem 0 .5rem}
.picto .it svg{width:44px; height:44px; stroke:var(--teal-deep); fill:none; stroke-width:1.4; stroke-linecap:round; stroke-linejoin:round; margin-bottom:.8rem}
.picto .it b{display:block; font-family:var(--serif); font-weight:500; font-size:1.15rem; margin-bottom:.25rem}
.picto .it p{font-size:.92rem; color:var(--ink-muted); margin:0}
.dark .picto .it{border-color:var(--amber)}
.dark .picto .it svg{stroke:var(--amber)}
.dark .picto .it p{color:var(--stone-2)}
.inline-picto{width:26px; height:26px; stroke:currentColor; fill:none; stroke-width:1.4; stroke-linecap:round; stroke-linejoin:round; flex:none}

/* menu / price rows -------------------------------------------- */
.menu-group{border-top:2px solid var(--teal-deep); padding-top:1.25rem; margin-bottom:2.5rem}
.menu-group h3{margin-bottom:.35rem}
.menu-group .intro{color:var(--ink-muted); font-size:.95rem; max-width:60ch; margin-bottom:1rem}
/* Mind Body's workshops, after its treatments (Marye, 7 Oct 2026). */
.menu-group h4{margin:2rem 0 .5rem; color:var(--teal-deep)}
.mrow{display:grid; grid-template-columns:1fr auto; gap:.25rem 1rem; padding:.85rem 0; border-bottom:var(--rule); text-decoration:none; color:inherit; align-items:start}
a.mrow:hover .nm{color:var(--teal-deep)}
.mrow .nm{font-family:var(--serif); font-weight:500; font-size:1.12rem; letter-spacing:-.01em}
.mrow .nm small{display:block; font-family:var(--sans); font-size:.82rem; color:var(--ink-muted); margin-top:.15rem; font-weight:400}
.mrow .pr{text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap}
/* The price column fills first and wraps only when the row can't hold it, so at
   200% text "$145 weekends" stays on the screen (ECHOSTUDIO-762). */
@media (max-width:560px){.mrow .pr{white-space:normal}}
.mrow .pr b{display:block; font-weight:600}
.mrow .pr span{display:block; font-size:.78rem; color:var(--ink-muted)}
.mrow .dur{grid-column:1; font-size:.8rem; color:var(--ink-muted); letter-spacing:.04em; text-transform:uppercase}
.price-key{display:flex; flex-wrap:wrap; gap:.5rem 1.5rem; font-size:.84rem; color:var(--ink-muted); padding:.75rem 0; border-bottom:var(--rule); margin-bottom:.5rem}
.price-key b{color:var(--ink)}
.menu-jump{display:flex; flex-wrap:wrap; gap:.5rem; margin:1.25rem 0 0}
.menu-jump a{display:inline-flex; align-items:center; min-height:40px; padding:.35rem .95rem; border:1px solid var(--hair); border-radius:999px; text-decoration:none; font-size:.84rem; font-weight:600; color:var(--ink)}
.menu-jump a:hover{border-color:var(--ink)}

/* treatment page ------------------------------------------------ */
.tblock{display:grid; gap:2rem}
@media (min-width:960px){.tblock{grid-template-columns:1.25fr .9fr; align-items:start}}
.tblock .tcopy{display:flex; flex-direction:column}
.tblock .tcopy .ctas{margin-top:auto; padding-top:1.75rem}
.tblock .prose p{margin:1.25rem 0 0}
.pricebox{background:var(--parchment-2); border-radius:12px; padding:clamp(1rem,2vw,1.5rem); display:grid; gap:.6rem; align-content:start}
.alt .pricebox{background:var(--parchment)}
.pricebox .ptiles{display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:.6rem}
.ptile{background:var(--parchment); border-radius:8px; padding:.9rem 1rem; border:1px solid rgba(31,42,41,.06)}
.alt .ptile{background:var(--parchment-2)}
.ptile span{display:block; font-size:.72rem; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-muted); font-weight:600}
.ptile b{display:block; font-family:var(--serif); font-size:1.7rem; font-weight:500; line-height:1.1; margin:.25rem 0 .15rem}
.ptile small{display:block; font-size:.82rem; color:var(--ink-muted); line-height:1.35}
.ptile.with b{font-size:1.05rem; font-family:var(--sans); font-weight:600; line-height:1.35}
.pricebox .note{margin:0; background:transparent; padding:.9rem 0 0; border-left:0; border-top:1px solid rgba(31,42,41,.1); border-radius:0; font-size:.88rem}
.t-head{display:grid; gap:1.5rem}
@media (min-width:900px){.t-head{grid-template-columns:1.2fr .8fr; align-items:end}}
.t-meta{display:grid; grid-template-columns:repeat(auto-fit,minmax(130px,1fr)); gap:0; border-top:var(--rule); border-bottom:var(--rule)}
.t-meta > div{padding:.9rem 1rem .9rem 0; border-right:var(--rule)}
.t-meta > div:last-child{border-right:0}
.t-meta b{display:block; font-family:var(--serif); font-size:1.35rem; font-weight:500}
.t-meta span{display:block; font-size:.74rem; text-transform:uppercase; letter-spacing:.12em; color:var(--ink-muted); margin-bottom:.15rem}
.sanskrit{font-family:var(--serif); font-style:italic; color:var(--ink-muted); font-size:1.15rem; margin:.25rem 0 0}
.note{margin-top:1.5rem; padding:1rem 1.15rem; background:var(--parchment-2); border-left:3px solid var(--orange); font-size:.92rem; color:var(--ink-muted); max-width:70ch; border-radius:0 var(--r) var(--r) 0}
.note b{color:var(--ink)}
.dark .note{background:rgba(6,38,39,.5); color:var(--stone)}
.dark .note b{color:var(--parchment)}

/* booking card (one per page, the only saturated block) -------- */
.bookcard{
  background:var(--orange-action); color:#fff; border-radius:var(--r);
  padding:clamp(1.5rem,4vw,2.75rem); display:grid; gap:1.25rem 3rem; align-items:center; position:relative; overflow:hidden;
}
@media (min-width:900px){.bookcard{grid-template-columns:1.4fr 1fr}}
.bookcard h2,.bookcard h3{color:#fff}
.bookcard p{color:#fff; max-width:52ch; margin:.6rem 0 0}
.bookcard .btn{background:var(--teal-950); color:#fff}
.bookcard .btn .arr{background:var(--parchment); color:var(--teal-950)}
.bookcard .btn:hover{background:var(--teal-900); color:#fff}
.bookcard .btn2{color:#fff}
.bookcard .btn2:hover{color:var(--amber)}
.bookcard .ctas{margin-top:1.6rem}
.bookcard svg.mark{display:none}
.bookcard .facts{font-size:.9rem; display:grid; gap:.3rem; margin:0}
.bookcard .facts div{display:flex; justify-content:space-between; gap:1rem; border-bottom:1px solid rgba(255,255,255,.35); padding:.4rem 0}
.bookcard .facts b{font-weight:600}

/* team --------------------------------------------------------- */
.team{display:grid; gap:1.25rem 1rem}
@media (min-width:560px){.team{grid-template-columns:1fr 1fr}}
@media (min-width:900px){.team{grid-template-columns:repeat(4,1fr)}}
.person{display:block; text-decoration:none; color:inherit; position:relative}
.person img{width:100%; aspect-ratio:6/7; object-fit:cover; border-radius:var(--r); filter:saturate(.92)}
.person b{display:block; font-family:var(--serif); font-weight:500; font-size:1.3rem; margin-top:.75rem}
.person span{display:block; font-size:.86rem; color:var(--ink-muted); line-height:1.4}
.person em{display:block; font-style:normal; font-size:.78rem; color:var(--teal-deep); margin-top:.3rem; letter-spacing:.02em}
.dark .person span{color:var(--stone-2)}
.dark .person em{color:var(--amber)}
.creds{list-style:none; margin:1.25rem 0 0; padding:0; border-top:var(--rule)}
.creds li{padding:.55rem 0; border-bottom:var(--rule); font-size:.92rem; display:flex; gap:.9rem}
.creds li b{color:var(--teal-deep); min-width:5.4rem; font-weight:600; flex:none}
.dark .creds, .dark .creds li{border-color:rgba(159,189,187,.22)}
.dark .creds li b{color:var(--amber)}
.postnom{font-size:.9rem; color:var(--ink-muted); letter-spacing:.01em; margin:.35rem 0 0}

/* quote -------------------------------------------------------- */
blockquote.q{margin:0; font-family:var(--serif); font-size:clamp(1.25rem,2.4vw,1.75rem); line-height:1.4; font-variation-settings:"SOFT" 50,"WONK" 1; max-width:34ch; color:var(--ink)}
blockquote.q + figcaption{margin-top:1rem; font-size:.86rem; color:var(--ink-muted)}
.dark blockquote.q{color:var(--parchment)}
.dark blockquote.q + figcaption{color:var(--teal-300)}

/* forms -------------------------------------------------------- */
.form{display:grid; gap:1.1rem}
.field{display:grid; gap:.4rem}
.field label{font-size:.82rem; font-weight:600; letter-spacing:.03em; color:var(--ink)}
.field input,.field select,.field textarea{
  font:inherit; font-size:1rem; color:var(--ink); background:var(--parchment); border:1px solid var(--hair);
  border-radius:var(--r); padding:.8rem .9rem; min-height:50px; width:100%;
}
.field textarea{min-height:120px; resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{outline:3px solid var(--brand); outline-offset:1px; border-color:var(--brand)}
.field .err{font-size:.82rem; color:#8A2C0F; margin:0}
.field.invalid input{border-color:#8A2C0F}
.two{display:grid; gap:1.1rem}
@media (min-width:560px){.two{grid-template-columns:1fr 1fr}}
.opts{display:grid; gap:.5rem}
.opt{display:flex; gap:.8rem; align-items:flex-start; padding:.85rem .95rem; border:1px solid var(--hair); border-radius:var(--r); cursor:pointer; background:var(--parchment)}
.opt:has(input:checked){border-color:var(--brand); box-shadow:inset 0 0 0 1px var(--brand)}
.opt input{margin-top:.3rem; accent-color:var(--brand)}
.opt b{display:block}
.opt span{display:block; font-size:.86rem; color:var(--ink-muted)}
.thanks{display:none; background:var(--parchment-2); padding:clamp(1.25rem,3vw,2rem); border-radius:var(--r); border-top:3px solid var(--brand)}
.thanks.show{display:block}
.thanks ol{padding-left:1.2rem; margin:1rem 0 0}
.thanks li{margin-bottom:.4rem}

/* steps (conversational contact) -------------------------------- */
.stepper{display:flex; gap:.4rem; margin-bottom:1.5rem; flex-wrap:wrap}
.stepper span{height:4px; flex:1 1 40px; background:var(--parchment-3); border-radius:2px}
.stepper span.on{background:var(--brand)}
.step{display:none}
.step.on{display:block}
.step h3{margin-bottom:1rem}
.step .row{display:flex; gap:.6rem; margin-top:1.25rem; flex-wrap:wrap}

/* journal ------------------------------------------------------ */
.post-list{display:grid; gap:0; border-top:var(--rule)}
.post-row{display:grid; gap:.5rem 2rem; padding:1.5rem 0; border-bottom:var(--rule); text-decoration:none; color:inherit; align-items:center}
@media (min-width:800px){.post-row{grid-template-columns:200px 1fr auto}}
.post-row img{aspect-ratio:4/3; object-fit:cover; border-radius:var(--r); width:100%}
.post-row b{font-family:var(--serif); font-weight:500; font-size:clamp(1.3rem,2.4vw,1.8rem); letter-spacing:-.01em; display:block}
.post-row p{margin:.35rem 0 0; color:var(--ink-muted); max-width:60ch}
.post-row .when{font-size:.8rem; color:var(--ink-muted); text-transform:uppercase; letter-spacing:.1em}
.post-row:hover b{color:var(--teal-deep)}
.article{max-width:66ch}
.article p{font-size:1.1rem; line-height:1.7}
.article h2{font-size:clamp(1.5rem,2.6vw,2rem); margin:2rem 0 .75rem}
.article .byline{font-size:.86rem; color:var(--ink-muted); margin-bottom:2rem; display:flex; gap:.75rem; align-items:center}
.article .byline img{width:40px; height:40px; border-radius:50%; object-fit:cover}

/* faq ---------------------------------------------------------- */
details.faq{border-bottom:var(--rule)}
details.faq summary{cursor:pointer; list-style:none; padding:1.1rem 2.5rem 1.1rem 0; font-family:var(--serif); font-size:1.2rem; font-weight:500; position:relative}
details.faq summary::-webkit-details-marker{display:none}
details.faq summary::after{content:"+"; position:absolute; right:.2rem; top:50%; transform:translateY(-50%); width:32px; height:32px; border:1px solid var(--hair); border-radius:50%; display:grid; place-items:center; font-family:var(--sans); font-size:1.1rem; color:var(--teal-deep)}
details.faq[open] summary::after{content:"\2212"}
details.faq .a{padding:0 0 1.25rem; max-width:64ch; color:var(--ink-muted)}
.faq-wrap{border-top:var(--rule)}

/* reveal ------------------------------------------------------- */
.rv{opacity:0; transform:translateY(22px); transition:opacity .8s var(--ease), transform .8s var(--ease); transition-delay:var(--d,0ms)}
.rv.in{opacity:1; transform:none}
/* The first screen reveals itself. Everything else waits for the script to see
   it scroll into view, but the hero's words, and the opening of every page,
   were waiting for the script too: opacity 0 until the bundle had run, 5 to 6
   seconds into a phone's visit, which was the page's LCP (ECHOSTUDIO-1427).
   Same curve, same delays, run by CSS from the first paint; the script's .in
   lands on an element already there. */
@keyframes rv-in{to{opacity:1; transform:none}}
@keyframes rv-h-in{to{transform:none}}
main > :is(section,header):first-of-type .rv{animation:rv-in .8s var(--ease) var(--d,0ms) forwards}
main > :is(section,header):first-of-type .rv-h > span{animation:rv-h-in .7s var(--ease) var(--d,0ms) forwards}
/* The mask has to sit below the baseline or descenders get sliced off the
   finished heading. The negative margin puts the extra space back. */
/* Clipped rather than overflow:hidden so the mask reaches above the first
   line, where accented capitals sit (ECHOSTUDIO-207). The extra .45em start
   keeps ascenders and accents out of sight until the heading rises. */
.rv-h{clip-path:inset(-.25em -.1em 0 -.1em); padding-bottom:.22em; margin-bottom:-.22em}
.rv-h > span{display:block; transform:translateY(calc(130% + .45em)); transition:transform .7s var(--ease); transition-delay:var(--d,0ms)}
.rv-h.in > span{transform:none}
@media (prefers-reduced-motion:reduce){.rv,.rv-h > span{opacity:1; transform:none; transition:none}}

/* final cta + footer reveal ------------------------------------ */
.final{position:relative; overflow:hidden; background:var(--teal-950); color:var(--parchment); min-height:clamp(420px,56vw,640px); display:flex; align-items:flex-end}
.final > img{position:absolute; inset:-12% 0; width:100%; height:124%; object-fit:cover; will-change:transform}
.final::after{content:""; position:absolute; inset:0; background:linear-gradient(180deg,rgba(6,38,39,.15) 0%,rgba(6,38,39,.55) 55%,rgba(6,38,39,.85) 100%); pointer-events:none}
/* `> .in`, not ` .in`: the reveal script marks a shown element by adding the
   class `in`, so a descendant selector also matched the heading and paragraph
   once they revealed. Each picked up this padding, the band grew 172px mid
   scroll and the photo sized to it zoomed with it. */
.final > .in{position:relative; z-index:2; width:100%; padding:clamp(2.5rem,6vw,5rem) var(--gutter) clamp(2.5rem,5vw,4rem); display:grid; gap:1rem}
@media (min-width:900px){.final > .in{grid-template-columns:1.4fr 1fr; align-items:end}}
.final h2{font-size:clamp(2.4rem,6vw,5.2rem); letter-spacing:-.03em; color:var(--parchment); margin:0}
.final p{color:var(--stone); max-width:40ch; margin:.75rem 0 0}
.final .quiet{justify-self:start; width:fit-content; max-width:100%; display:inline-flex; align-items:center; gap:.75rem; color:var(--parchment); text-decoration:none; font:600 1rem var(--sans); border:1px solid rgba(247,241,230,.5); border-radius:999px; padding:.8rem .5rem .8rem 1.25rem; min-height:50px}
.final .quiet .arr{width:34px; height:34px; border-radius:50%; border:1px solid rgba(247,241,230,.6); display:grid; place-items:center}
.final .quiet .arr svg{width:14px; height:14px}
.final .quiet:hover{background:rgba(247,241,230,.12)}
@media (min-width:900px){.final .quiet{justify-self:end}}
/* ---- footer: one teal surface in two parts (ECHOSTUDIO-339) ----
   .foot-cover (sign-up, links, legal) scrolls with the page and sits over
   .foot-reveal, which is pinned to the bottom of the window, so the page and
   the cover slide up off the logo and name. Only the band is pinned because
   the whole footer was taller than a phone or a short laptop window. The band
   is sized by the page width alone and stays well inside a 360x640 screen.
   Sticky inside the footer, so the band never shows before the footer does. */
.site-foot{position:relative; background:var(--teal-900); color:var(--stone)}
.foot-cover{position:relative; z-index:2; background:var(--teal-900); padding-top:clamp(2rem,5vw,4rem)}
.foot-reveal{position:sticky; bottom:0; z-index:1; background:var(--teal-900)}
.site-foot[data-reveal="off"] .foot-reveal{position:relative}
/* The footer ripple (ECHOSTUDIO-207, desktop with a mouse only): under the words,
   over the teal. The cover's z-index makes it the stacking context. */
.foot-ripple{position:absolute; inset:0; width:100%; height:100%; z-index:-1; pointer-events:none}
.foot-grid{display:grid; gap:2rem; padding-bottom:2rem}
@media (min-width:760px){.foot-grid{grid-template-columns:1.2fr 1fr 1fr 1fr}}
.site-foot h4, .site-foot .foot-head{font-family:var(--sans); font-size:.74rem; letter-spacing:.14em; text-transform:uppercase; color:var(--teal-300); margin-bottom:.8rem; font-weight:600}
.site-foot ul{list-style:none; margin:0; padding:0}
.site-foot li{margin:.3rem 0; font-size:.93rem}
.site-foot a{color:var(--parchment); text-decoration:none}
.site-foot a:hover{color:var(--amber)}
.site-foot p{font-size:.93rem; color:var(--stone-2); max-width:38ch}
.newsletter-footer{padding-bottom:clamp(2rem,5vw,4rem)}
.newsletter{
  display:grid; gap:clamp(1.5rem,4vw,3.5rem); align-items:end;
  padding-block:clamp(1.5rem,4vw,2.75rem); border-block:1px solid var(--hair);
}
.newsletter-copy{display:grid;gap:.55rem;max-width:34rem}
.newsletter h2{margin:0;font-family:var(--serif);font-size:clamp(2rem,4vw,3.5rem);line-height:1;letter-spacing:-.025em;font-weight:400}
.newsletter p{margin:0;color:var(--ink-muted)}
.newsletter-kicker{font-size:.7rem !important;line-height:1.4;text-transform:uppercase;letter-spacing:.14em;font-weight:600}
.newsletter-form{display:grid;gap:.9rem;min-width:0}
.newsletter-fields{display:grid;gap:.7rem;align-items:end;grid-template-columns:minmax(0,1fr)}
.newsletter-field{display:grid;gap:.35rem;min-width:0}
.newsletter-field label{font-size:.72rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase}
.newsletter-field input{
  width:100%;min-width:0;height:3.25rem;padding:.72rem .85rem;border:1px solid var(--hair);
  border-radius:4px;background:rgba(255,255,255,.38);color:var(--ink);font:inherit;
}
.newsletter-field input:focus{outline:3px solid var(--brand);outline-offset:1px;border-color:var(--brand)}
.newsletter-submit{
  min-height:3.25rem;padding:.75rem 1.2rem;border:0;border-radius:999px;background:var(--orange-action);
  color:#fff;font:600 .95rem var(--sans);cursor:pointer;white-space:nowrap;
}
.newsletter-submit:hover{background:var(--orange-action-deep)}
.newsletter-submit:disabled{cursor:wait;opacity:.7}
.newsletter-submit--desktop{display:none}
/* full width on a phone, so its label wraps at large text rather than widening the page (ECHOSTUDIO-762) */
.newsletter-submit--mobile{width:100%;white-space:normal}
.newsletter-consent{display:flex;align-items:flex-start;gap:.65rem;font-size:.82rem;line-height:1.4;color:var(--ink-muted);cursor:pointer}
.newsletter-consent input{width:1rem;height:1rem;margin-top:.1rem;accent-color:var(--brand);flex:none}
.newsletter-problem{min-height:1.2em;font-size:.82rem;color:#8A2C0F !important}
.newsletter--sent{align-content:center;min-height:15rem}
@media(min-width:900px){
  .newsletter--inline{grid-template-columns:minmax(0,.85fr) minmax(32rem,1.15fr)}
  .newsletter-fields{grid-template-columns:minmax(8rem,.7fr) minmax(13rem,1fr) auto}
  .newsletter--inline .newsletter-submit--desktop{display:block}
  .newsletter--inline .newsletter-submit--mobile{display:none}
}
.newsletter--footer{border-color:rgba(159,189,187,.28)}
.newsletter--footer h2{color:var(--parchment);font-size:clamp(1.9rem,3vw,3rem)}
.newsletter--footer .newsletter-copy>p:not(.newsletter-kicker){color:var(--stone-2)}
.newsletter--footer .newsletter-kicker{color:var(--teal-300)}
.newsletter--footer .newsletter-field label{color:var(--teal-300)}
.newsletter--footer .newsletter-field input{border-color:rgba(247,241,230,.35);background:rgba(247,241,230,.08);color:var(--parchment)}
.newsletter--footer .newsletter-field input:focus{outline-color:var(--amber);border-color:var(--amber)}
.newsletter--footer .newsletter-submit{background:var(--parchment);color:var(--teal-950)}
.newsletter--footer .newsletter-submit:hover{background:var(--parchment-3)}
.newsletter--footer .newsletter-consent{color:var(--stone-2)}
.newsletter--footer .newsletter-consent input{accent-color:var(--amber)}
.newsletter--footer .newsletter-problem{color:#FFD1BD !important}
/* Copy beside the form only from 1000px: the two minimum widths add up to more
   than a 768px tablet, which pushed the button off the right edge. Between
   760 and 1000 the copy sits above and the fields keep their row. */
@media(min-width:1000px){
  .newsletter--footer{grid-template-columns:minmax(14rem,.65fr) minmax(28rem,1.35fr)}
}
@media(min-width:760px){
  .newsletter--footer .newsletter-fields{grid-template-columns:minmax(8rem,.65fr) minmax(12rem,1fr) auto}
  .newsletter--footer .newsletter-submit--desktop{display:block}
  .newsletter--footer .newsletter-submit--mobile{display:none}
}
/* ---- footer wordmark ----
   The mark and the name side by side, centred, the pair as wide as the page
   allows, sitting on the bottom edge of the screen. Sized with container query
   units on the footer row so it scales with the page and never overflows:
   --fit is the width of mark plus name at 1em of the name, measured in both
   engines. Re-measure if the face, weight or mark changes. No border: the
   footer is one surface, not two stacked bands. */
.foot-brand{
  container-type:inline-size;
  display:flex; justify-content:center; align-items:flex-end;
  gap:.22em; padding-block:0; margin-top:clamp(1rem,3vw,2.5rem);
  font-size:calc(100cqi / var(--fit, 5.6)); line-height:0; overflow:hidden;
}
.foot-brand-mark{display:block; height:.78em; width:auto; flex:none; margin-bottom:.07em}
.foot-brand-name{
  display:block; font-family:var(--serif); font-weight:400; color:var(--parchment);
  font-size:1em; line-height:.74; letter-spacing:-.02em; white-space:nowrap;
  /* The descender-free word's baseline sits on the bottom of the screen. */
  margin-bottom:-.02em;
}
.foot-legal{display:flex; flex-wrap:wrap; gap:.5rem 1.5rem; font-size:.78rem; color:var(--teal-300); padding-block:0 .25rem}
.foot-legal a{color:var(--teal-300)}
/* The phone's Book/Call bar is fixed over the bottom of the screen, so the
   pinned band carries the room for it and the name sits above the bar. */
.has-bar .foot-reveal{padding-bottom:4.75rem}
/* The home page's retreat pill sits above the bar, so there the name rises
   clear of the pill too, and the pill rests underneath it (Marye, 9 Oct). The
   pill sits on the bar's measured height, so the room does too (ECHOSTUDIO-820). */
.has-bar:has(#upc) .foot-reveal{padding-bottom:calc(var(--mbar-h, 4.5rem + env(safe-area-inset-bottom)) + 4.1rem)}
@media (min-width:640px){.has-bar .foot-reveal, .has-bar:has(#upc) .foot-reveal{padding-bottom:env(safe-area-inset-bottom)}}

/* sticky mobile bar -------------------------------------------- */
.mbar{position:fixed; left:0; right:0; bottom:0; z-index:100; display:flex; gap:.5rem; padding:.6rem var(--gutter) calc(.6rem + env(safe-area-inset-bottom)); background:rgba(247,241,230,.96); backdrop-filter:blur(10px); border-top:var(--rule); transform:translateY(110%); transition:transform .35s var(--ease)}
.mbar.show{transform:none}
.mbar .btn{flex:1 1 auto; width:auto; justify-content:space-between}
.mbar .btn2{flex:0 0 auto; border:1px solid var(--hair)}
/* At large text or zoom, Call drops under Book instead of off the screen (ECHOSTUDIO-762). */
.mbar{flex-wrap:wrap}
@media (min-width:640px){.mbar{display:none}}

/* misc --------------------------------------------------------- */
.ph{background:repeating-linear-gradient(135deg,var(--parchment-2) 0 12px,var(--parchment) 12px 24px); border:1px dashed var(--hair); border-radius:var(--r); display:grid; place-items:center; text-align:center; padding:1.5rem; color:var(--ink-muted); font-size:.85rem; min-height:220px}
.ph b{display:block; color:var(--ink); font-family:var(--serif); font-size:1.1rem; margin-bottom:.35rem; font-weight:500}
.spine{display:none !important}
.big-num{font-family:var(--serif); font-size:clamp(3rem,8vw,6rem); line-height:.9; letter-spacing:-.04em; font-weight:500; color:var(--teal-deep)}
.dark .big-num{color:var(--amber)}
.day{border-top:var(--rule-dark); padding-top:1.1rem; margin-bottom:2rem}
.day h3{color:var(--amber); font-size:1rem; letter-spacing:.14em; text-transform:uppercase; font-family:var(--sans); font-weight:600; margin-bottom:.5rem}
.day h3 span{color:var(--teal-300); letter-spacing:.04em; text-transform:none; font-weight:400; font-size:.85rem; margin-left:.5rem}
.sched{list-style:none; margin:0; padding:0}
.sched li{display:grid; grid-template-columns:4.6rem 1fr; gap:.4rem 1rem; padding:.62rem 0; border-bottom:1px solid rgba(159,189,187,.18); align-items:baseline}
.sched time{color:var(--amber); font-size:.86rem; font-weight:600}
.sched .what{font-size:.98rem; color:var(--parchment)}
.sched .who{display:block; color:var(--teal-300); font-size:.82rem; margin-top:.12rem}
.tiers{display:grid; gap:1.25rem; margin-top:2rem}
@media (min-width:820px){.tiers{grid-template-columns:1fr 1fr}}
.tier{background:var(--parchment); border:1px solid var(--hair); border-radius:var(--r); padding:clamp(1.4rem,3vw,2.1rem); display:flex; flex-direction:column; position:relative}
.tier.feature{border-color:var(--brand); box-shadow:inset 0 0 0 1px var(--brand)}
.tier .flag{position:absolute; top:-1px; right:-1px; background:var(--orange-action); color:#fff; font-size:.66rem; letter-spacing:.14em; text-transform:uppercase; font-weight:600; padding:.35rem .7rem; border-radius:0 var(--r) 0 var(--r)}
.tier .price{font-family:var(--serif); font-size:clamp(2.4rem,6vw,3.2rem); font-weight:500; line-height:1; letter-spacing:-.03em; margin:.6rem 0 .15rem}
.tier .per{font-size:.8rem; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-muted)}
.tier ul{list-style:none; margin:1.2rem 0 1.5rem; padding:0; border-top:var(--rule)}
.tier li{padding:.55rem 0 .55rem 1.4rem; border-bottom:var(--rule); font-size:.93rem; position:relative; color:var(--ink-muted)}
.tier li::before{content:""; position:absolute; left:0; top:1.05em; width:9px; height:1px; background:var(--brand)}
.tier .btn{margin-top:auto}
.fit{display:grid; gap:var(--gap)}
@media (min-width:880px){.fit{grid-template-columns:1fr 1fr}}
.fit ul{list-style:none; margin:1rem 0 0; padding:0}
.fit li{padding:.7rem 0 .7rem 2rem; border-bottom:var(--rule); position:relative; font-size:.98rem}
.fit .yes li::before{content:""; position:absolute; left:.15rem; top:1.2em; width:11px; height:6px; border-left:2px solid var(--brand); border-bottom:2px solid var(--brand); transform:rotate(-45deg)}
.fit .no li::before{content:""; position:absolute; left:.15rem; top:1.4em; width:12px; height:2px; background:var(--ink-muted)}
.inc-grid{display:grid; gap:0}
@media (min-width:760px){.inc-grid{grid-template-columns:1fr 1fr}}
@media (min-width:1080px){.inc-grid{grid-template-columns:repeat(4,1fr)}}
.inc-col{border-top:2px solid var(--brand); padding:1.1rem 0 1.4rem}
@media (min-width:760px){.inc-col{padding-right:1.5rem}}
.inc-col h3{font-size:1.02rem; margin-bottom:.8rem; display:flex; align-items:center; gap:.6rem}
.inc-col ul{list-style:none; margin:0; padding:0}
.inc-col li{padding:.5rem 0; border-bottom:var(--rule); font-size:.92rem; line-height:1.45}
.inc-col li em{display:block; font-style:normal; color:var(--ink-muted); font-size:.8rem; margin-top:.1rem}

/* small screens: pills may wrap, never overflow */
@media (max-width:640px){
  .btn{white-space:normal; max-width:100%; text-align:left; line-height:1.2}
  .tblock .ctas{flex-direction:column; align-items:flex-start}
}
.tblock > *, .split > *, .sec-head > *, .hero-grid > *, .final > .in > *{min-width:0}
@media (max-width:640px){.btn{width:auto}}

/* Leandra list: large muted headings, hovered row outlined, image panel swaps ---- */
.llist-wrap{display:grid; gap:2rem; align-items:start}
@media (min-width:960px){.llist-wrap{grid-template-columns:1.15fr .85fr; gap:3rem}}
.llist{list-style:none; margin:0; padding:0}
.llist > li{margin:0}
.li-item{display:block; position:relative; border:1px solid transparent; border-radius:12px; padding:.55rem 3.4rem .55rem .9rem; margin:0; cursor:pointer; outline:none; transition:border-color .25s var(--ease), background .25s var(--ease)}
.li-item .t{display:block; font-family:var(--serif); font-weight:500; font-size:clamp(2rem,4.2vw,3.6rem); line-height:1.08; letter-spacing:-.025em; color:var(--ink); opacity:.42; transition:opacity .25s var(--ease)}
.li-item .plus{position:absolute; right:.9rem; top:50%; width:34px; height:34px; margin-top:-17px; border-radius:50%; border:1px solid var(--ink); display:grid; place-items:center; font:400 1.35rem/1 var(--sans); color:var(--ink); opacity:0; transition:opacity .25s var(--ease), transform .3s var(--ease)}
.li-item .d{display:grid; grid-template-rows:0fr; transition:grid-template-rows .35s var(--ease)}
.li-item .d > div{overflow:hidden}
.li-item .d p{margin:.35rem 0 0; color:var(--ink-muted); font-size:.95rem; max-width:52ch}
.li-item .d a{display:inline-block; margin:.5rem 0 .4rem; font-weight:600; color:var(--teal-deep); text-decoration:none}
.li-item.on, .li-item:focus-visible{border-color:var(--ink)}
.li-item.on .t, .li-item:focus-visible .t{opacity:1}
.li-item.on .plus, .li-item:focus-visible .plus{opacity:1}
.li-item.open .plus{transform:rotate(45deg)}
.li-item.open .d{grid-template-rows:1fr}
@media (hover:hover) and (pointer:fine){.li-item.on .d{grid-template-rows:1fr}}
.lpanel{position:sticky; top:96px; border-radius:12px; overflow:hidden; aspect-ratio:4/5; background:var(--parchment-2)}
@media (max-width:959px){.lpanel{aspect-ratio:16/10; position:relative; top:auto}}
.lpanel img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity .45s var(--ease); transform:scale(1.02)}
.lpanel img.on{opacity:1; transform:none}
.lpanel .cap{position:absolute; left:1rem; bottom:.9rem; color:var(--parchment); font-size:.74rem; letter-spacing:.08em; text-transform:uppercase; text-shadow:0 1px 2px rgba(0,0,0,.4)}
/* small variant inside the mega menu */
.llist.sm .li-item{padding:.35rem 2.8rem .35rem .7rem; margin:0; border-radius:10px}
.llist.sm .li-item .t{font-size:1.75rem; line-height:1.1}
.llist.sm .li-item .plus{width:28px; height:28px; margin-top:-14px; font-size:1.1rem; right:.7rem}
.llist.sm .li-item .d p{font-size:.86rem}
.mega-in.mega-treat{grid-template-columns:1fr 1.6fr 1fr}
.mega-treat .lpanel{aspect-ratio:4/3; position:relative; top:auto}

/* journal grid ------------------------------------------------- */
.feat{display:grid; gap:1.5rem; text-decoration:none; color:inherit; border-radius:12px}
@media (min-width:900px){.feat{grid-template-columns:1.5fr 1fr; align-items:center; gap:2.5rem}}
.feat .im{border-radius:12px; overflow:hidden; aspect-ratio:3/2}
.feat .im img{width:100%; height:100%; object-fit:cover; transition:transform .7s var(--ease)}
.feat:hover .im img{transform:scale(1.03)}
.feat h2{font-size:clamp(1.8rem,3.4vw,2.8rem); letter-spacing:-.025em; margin:.75rem 0 .75rem}
.feat p{color:var(--ink-muted); max-width:48ch}
.chips{display:flex; flex-wrap:wrap; gap:.4rem; margin:0}
.chip{display:inline-flex; align-items:center; min-height:30px; padding:.25rem .75rem; border:1px solid var(--hair); border-radius:999px; font-size:.76rem; font-weight:600; letter-spacing:.04em; color:var(--ink-muted)}
.chip.tag{background:var(--teal-900); color:var(--parchment); border-color:var(--teal-900)}
.jgrid{display:grid; gap:1.5rem; margin-top:2.5rem; padding-top:2.5rem; border-top:var(--rule)}
@media (min-width:760px){.jgrid{grid-template-columns:repeat(3,1fr)}}
.jtile{text-decoration:none; color:inherit; display:block}
.jtile .im{border-radius:12px; overflow:hidden; aspect-ratio:4/3}
.jtile .im img{width:100%; height:100%; object-fit:cover; transition:transform .7s var(--ease)}
.jtile:hover .im img{transform:scale(1.03)}
.jtile h3{margin:.9rem 0 .4rem; font-size:1.35rem}
.jtile .chips{margin-top:.6rem}

.llist-wrap .llist{margin-left:-.8rem}
.mega-col{min-width:0}

/* category page top band: real height */
.page-hero + .pband{height:clamp(260px,34vw,460px)}

/* ---- trust badges: logo and rating marks (the laurels came off, Marye 8 Oct 2026) ---- */
/* Text in rem so it follows the reader's own text size, and the pair wraps to a
   second row when the two no longer fit side by side. On a phone set to large
   text they ran into each other (Marye's walkthrough, 14 Oct 2026, ECHOSTUDIO-762):
   the row was held on one line and each badge allowed to shrink below its words. */
.badges{display:flex;gap:clamp(14px,2vw,26px);align-items:center;flex-wrap:wrap;margin-top:1.5rem;padding-top:0}
.badge{display:flex;align-items:center;gap:9px;width:fit-content;max-width:100%;color:var(--parchment)}
.badge-mid{display:flex;flex-direction:column;align-items:center;gap:5px;min-width:0;text-align:center}
.badge-title{font-size:.78125rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;white-space:nowrap}
.badge-row{display:flex;align-items:center;gap:7px}
.badge-logo{width:20px;height:20px;flex:none;display:block}
.badge-marks{display:flex;gap:3px;align-items:center}
.badge-marks svg{width:16px;height:16px;display:block}
.badge-sub{font-size:.75rem;font-weight:600;letter-spacing:.02em;opacity:.94}
.badge--google .badge-marks svg{fill:#E9A82E}
.badge--ta .badge-marks svg{fill:#00AA6C}
.badge--ink{color:var(--ink)}
@media(max-width:560px){
  /* Two equal halves, as before. When a review count is longer than its half
     it wraps under itself inside the badge, and when even "Rated Excellent"
     can't fit beside the other badge, the second drops to its own row. The
     badge's minimum is the width of its title (min-width auto), where it used
     to be zero, which is what let the two run into each other. */
  .badges{gap:8px;width:100%;justify-content:center}
  .badge{gap:4px;flex:1 1 0;width:auto;min-width:auto;justify-content:center}
  .badge-title{font-size:.59375rem;letter-spacing:.08em}
  .badge-sub{font-size:.55rem}
  .badge-logo{width:14px;height:14px}
  .badge-marks{gap:2px}
  .badge-marks svg{width:11px;height:11px}
}
/* A phone zoomed to 200% is under 360px wide: there a badge alone on its row
   may be narrower than its title, which wraps inside it. */
@media(max-width:359px){.badge{min-width:0}.badge-title{white-space:normal}}

/* ---- "As featured on Sunrise": a hairline and one line under the ratings ---- */
.sr-line{display:flex;align-items:center;gap:14px;width:fit-content;margin:1.1rem 0 0;padding-top:1rem;border-top:1px solid color-mix(in srgb,currentColor 28%,transparent);color:var(--parchment);font-size:.78125rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;line-height:1}
.sr-line--ink{color:var(--teal-900)}
.sr-logo{display:block;flex:none;height:34px;aspect-ratio:609/360;background:currentColor;-webkit-mask:url(/assets/img/sunrise-logo.webp) center/contain no-repeat;mask:url(/assets/img/sunrise-logo.webp) center/contain no-repeat}
.hero.seo .sr-line,.rvw-badges .sr-line{margin-inline:auto}
.sr-line a{color:inherit;font-size:.8125rem;font-weight:600;letter-spacing:.02em;text-transform:none;text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;opacity:.9}
.sr-line a:hover{opacity:1}
/* The footer's paragraph rule greys and enlarges p; the line keeps its own cream
   and a tighter set so it stays on one line in the first column. */
.site-foot .sr-line{margin-top:1.5rem;max-width:none;white-space:nowrap;gap:10px;color:var(--parchment);font-size:.71875rem}
.site-foot .sr-line a{font-size:.78125rem}
.site-foot .sr-line a:hover{color:inherit}
@media(max-width:560px){
  /* On a phone the line wraps rather than running off the edge when the
     reader's text is larger (ECHOSTUDIO-762). At normal size it still fits on
     one line; wider screens keep it held on one line, as before. */
  .sr-line,.site-foot .sr-line{flex-wrap:wrap;white-space:normal;gap:6px 10px;font-size:.625rem}
  .sr-line > span:first-child{white-space:nowrap}
  .sr-logo{height:28px}
  .sr-line a,.site-foot .sr-line a{font-size:.6875rem}
  /* Under the badges it spans the column they fill and sits in its middle,
     rather than hanging off the left edge (ECHOSTUDIO-788). The footer's
     column is set left, so its line stays with it. */
  .sr-line{width:100%;justify-content:center}
  .site-foot .sr-line{width:fit-content;justify-content:flex-start}
}

/* journal post: centred article column */
.article{max-width:680px; margin-inline:auto}
.article .byline{justify-content:center}
.post-hero .wrap{text-align:center}
.post-hero h1{margin-inline:auto}
.post-hero .lede{margin-inline:auto}
.post-hero .crumbs{justify-content:center}

/* ---- SEO hero with slideshow ---- */
.hero.seo{position:relative; overflow:hidden; background:var(--teal-950); color:var(--parchment); min-height:clamp(560px,82vh,820px); display:flex; align-items:center; justify-content:center; text-align:center; padding-block:clamp(3rem,7vw,5rem) clamp(4rem,9vw,7rem)}
.hero.seo::before{display:none}
.hero.seo .slides{position:absolute; inset:0; z-index:0}
.hero.seo .slides img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity 1.8s var(--ease); transform:scale(1.04)}
.hero.seo .slides img.on{opacity:1; transform:none; transition:opacity 1.8s var(--ease), transform 7s linear}
.hero.seo .slides::after{content:""; position:absolute; inset:0; background:rgba(6,38,39,.6)}
.hero.seo .wrap{position:relative; z-index:2; max-width:960px; margin-inline:auto; display:flex; flex-direction:column; align-items:center}
.hero.seo .kicker{color:var(--amber)}
.hero.seo h1{font-size:clamp(2.4rem,5.6vw,4.6rem); max-width:18ch; margin-inline:auto; color:#fff}
.hero.seo .lede{margin:1.25rem auto 0; color:var(--stone); max-width:58ch}
.hero.seo .ctas{justify-content:center; margin-top:1.75rem}
@media (max-width:560px){.hero.seo .ctas{align-items:center}}
.hero.seo .badges{justify-content:center; margin-top:2.25rem; padding-top:0; width:100%; max-width:640px}
@media (prefers-reduced-motion:reduce){.hero.seo .slides img{transition:none}}
/* ---- upcoming retreat card: the pill is the card, collapsed ---- */
.upc{position:fixed; right:var(--gutter); bottom:calc(1.25rem + env(safe-area-inset-bottom)); z-index:70; max-width:calc(100% - 2*var(--gutter))}
/* Condensed on a phone, where 250px of pill is most of the screen. */
.txt-short{display:none}
@media (max-width:560px){
  .upc{--upc-w:min(320px, calc(100vw - 2*var(--gutter)))}
  .upc .tile-box{width:var(--upc-w)}
  .upc .txt-long{display:none}
  .upc .txt-short{display:inline}
  .upc .pill{padding-inline:.7rem .9rem}
}
/* The sticky bar pushes the pill up rather than covering it, and it moves with
   the bar instead of jumping once it has arrived. */
.upc{transition:bottom .35s var(--ease)}
/* On a phone the pill arrives with the Book/Call bar and leaves with it, so it
   never floats over the hero on load (Phil, ECHOSTUDIO-820). It rests on the
   bar, lifted by the bar's measured height (--mbar-h, safe area included, set
   in site-behaviours). Pill and bar drop out of sight by the same distance on
   the same curve, so the two move as one piece. Without the script the bar
   never shows, and neither does the pill. */
@media (max-width:639px){
  body:has(#mobileBar) .upc{
    bottom:calc(var(--mbar-h, 4.5rem + env(safe-area-inset-bottom)) + .75rem);
    transform:translateY(calc(var(--mbar-h, 4.5rem) + 6rem)); visibility:hidden;
    transition:transform .35s var(--ease), visibility 0s linear .35s;
  }
  body:has(#mobileBar.show) .upc{transform:none; visibility:visible; transition:transform .35s var(--ease)}
  body:has(#upc) .mbar{transform:translateY(calc(100% + 6rem))}
  body:has(#upc) .mbar.show{transform:none}
}
@media (prefers-reduced-motion:reduce){
  .mbar,body:has(#mobileBar) .upc,body:has(#mobileBar.show) .upc{transition:none}
}

/* One shell holds both states so the change of size is a single movement. */
.upc .shell{
  position:relative; overflow:hidden; margin-left:auto;
  background:var(--parchment); color:var(--ink);
  border:1px solid var(--hair); border-radius:16px;
  box-shadow:0 26px 54px -26px rgba(6,38,39,.55);
  width:var(--upc-w,340px); max-height:var(--upc-h,520px);
  transition:
    width .62s cubic-bezier(.22,.61,.36,1),
    max-height .62s cubic-bezier(.22,.61,.36,1),
    box-shadow .5s cubic-bezier(.22,.61,.36,1);
}
.upc.collapsed .shell{
  width:var(--pill-w,250px); max-height:var(--pill-h,46px);
  box-shadow:0 14px 28px -16px rgba(6,38,39,.45);
}
.upc.collapsed.open .shell{
  width:var(--upc-w,340px); max-height:var(--upc-h,520px);
  box-shadow:0 26px 54px -26px rgba(6,38,39,.55);
}
.upc .shell:hover{border-color:var(--teal-300)}

/* The card keeps its own width so nothing reflows while the shell narrows. */
.upc .tile-box{width:var(--upc-w,340px); opacity:1; transition:opacity .36s ease .14s}
.upc.collapsed .tile-box{opacity:0; transition:opacity .18s ease}
.upc.collapsed.open .tile-box{opacity:1; transition:opacity .36s ease .14s}
/* High, not centred: a figure's head sits in the top third, and a centred crop
   of the retreat's statue showed her from the neck down (Marye, 1 Oct 2026). */
.upc .shot{display:block; width:100%; height:132px; overflow:hidden}
.upc .shot img{display:block; width:100%; height:100%; object-fit:cover; object-position:50% 20%}
/* On a phone turned sideways the open card would be taller than the screen, so
   it goes without the photo there and the dates, name and link all fit. */
@media (max-height:500px){.upc .shot{display:none}}
/* The smallest phone on its side (568x320) also keeps the card above the
   Book/Call bar, so the one-line description goes too and the card stays clear
   of the header. */
@media (max-width:639px) and (max-height:500px){.upc .tile-box .fr{display:none}}
.upc .tb-in{display:grid; gap:.35rem; padding:1rem 1.15rem 1.15rem}
.upc .tile-box .lbl{font-size:.68rem; letter-spacing:.16em; text-transform:uppercase; font-weight:600; color:var(--teal-deep)}
.upc .tile-box .ds{font-family:var(--serif); font-size:2rem; line-height:1; letter-spacing:-.03em; font-weight:500}
.upc .tile-box .ds small{font-size:.5em; letter-spacing:.02em; vertical-align:.35em; margin-left:.15em}
.upc .tile-box .nm{font-weight:600}
.upc .tile-box .fr{font-size:.86rem; color:var(--ink-muted)}
.upc .tile-box .go{display:inline-flex; align-items:center; gap:.5rem; margin-top:.4rem; font-weight:600; color:var(--teal-deep); text-decoration:none}
.upc .tile-box .go:hover{color:var(--ink)}
.upc .x{
  position:absolute; top:.6rem; right:.6rem; z-index:2; width:30px; height:30px; border-radius:50%;
  border:1px solid rgba(247,241,230,.5); background:rgba(6,38,39,.45); color:var(--parchment);
  cursor:pointer; font-size:1rem; line-height:1; display:grid; place-items:center;
  backdrop-filter:blur(6px); transition:background .25s ease, opacity .3s ease;
}
.upc .x:hover{background:rgba(6,38,39,.7)}
.upc.collapsed .x{opacity:0; pointer-events:none}
.upc.collapsed.open .x{opacity:1; pointer-events:auto}

/* The pill label rides on top of the same parchment, so nothing changes colour. */
.upc .pill{
  position:absolute; left:0; top:0; width:max-content;
  display:flex; align-items:center; gap:.6rem; padding:.85rem 1.15rem;
  background:transparent; border:0; color:var(--teal-deep);
  font:600 .84rem/1 var(--sans); cursor:pointer; white-space:nowrap;
  opacity:0; pointer-events:none; transition:opacity .26s ease;
}
.upc.collapsed .pill{opacity:1; pointer-events:auto; transition:opacity .34s ease .18s}
.upc.collapsed.open .pill{opacity:0; pointer-events:none; transition:opacity .16s ease}
.upc .pill .dot{width:8px; height:8px; border-radius:50%; background:var(--amber); flex:none}
.upc .pill .txt{overflow:hidden; text-overflow:ellipsis}
/* Never wider than the screen: at large text the name ends in "..." inside the
   pill, and opening it shows the whole card (ECHOSTUDIO-762). */
.upc .shell{max-width:100%}
.upc .pill{max-width:calc(100vw - 2*var(--gutter))}

@media (prefers-reduced-motion: reduce){
  .upc .shell,.upc .tile-box,.upc .pill,.upc .x{transition:none}
}

/* Before the script has run (ECHOSTUDIO-789). Wherever the open card would
   cover the hero, the server's markup is already the pill, sized by its own
   label, so nothing moves when the script takes over. This query is the exact
   opposite of upcomingRoom in src/tokens/space.ts; change both together. The
   -2px matches the measured pill, which is the label's own size including the
   shell's 1px border. */
.upc.pre,.upc.pre *{transition:none !important}
@media (width < 1152px), (height < 700px), (width < 1400px) and (height < 900px){
  .upc.pre .shell{width:auto; max-height:none; box-shadow:0 14px 28px -16px rgba(6,38,39,.45)}
  .upc.pre .tile-box{position:absolute; top:0; left:0; opacity:0}
  .upc.pre .x{opacity:0; pointer-events:none}
  .upc.pre .pill{position:relative; opacity:1; pointer-events:auto; margin:0 -2px -2px 0}
  .upc.pre .shot img{display:none}
}
/* A lazy picture that is not displayed is not fetched, so the pill costs nothing. */
.upc.unseen .shot img{display:none}

/* forms never wait on scroll reveal */
form.rv,form .rv,.form.rv{opacity:1 !important;transform:none !important;transition:none}

/* option rows: radio fixed size, text takes the rest */
.opt input[type=radio],.opt input[type=checkbox]{width:18px !important;height:18px;flex:none;margin:.2rem 0 0;padding:0}
.opt>span{flex:1;min-width:0}

/* hero: two cut panels beside the centred copy */
.hero.seo{min-height:0; display:block; padding-block:clamp(2.5rem,5vw,4rem) clamp(3.5rem,7vw,5.5rem)}
.hero.seo .slides{display:none}
.hero.seo .wrap.hero-3{max-width:none; display:grid; gap:clamp(1rem,2.5vw,2.5rem); align-items:center; grid-template-columns:1fr}
@media (min-width:960px){.hero.seo .wrap.hero-3{grid-template-columns:minmax(200px,.8fr) minmax(0,1.6fr) minmax(200px,.8fr)}}
.hero.seo .hcopy{display:flex; flex-direction:column; align-items:center; text-align:center}
.hpanel{position:relative; border-radius:12px; overflow:hidden; aspect-ratio:4/5; background:var(--teal-900); min-height:0}
.hpanel img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:none}
.hpanel img.on{display:block}
.hpanel::after{content:""; position:absolute; inset:0; background:rgba(6,38,39,.38)}
@media (max-width:959px){
  .hero.seo .wrap.hero-3{grid-template-columns:1fr 1fr}
  .hero.seo .hcopy{grid-column:1 / -1; order:-1}
  .hpanel{aspect-ratio:3/4}
}
.badges.ink-wrap{border-top:0}
.badge--ink .badge-title, .badge--ink .badge-sub{color:var(--ink)}
.badges:has(.badge--ink){border-top:0}

/* proof tiles */
.proof-tiles{padding-block:clamp(1.5rem,3vw,2.5rem) clamp(2rem,4vw,3rem)}
.proof-tiles .tile .cap b{font-size:1.15rem}
/* cursor tag: auto width for longer labels, so it becomes a lozenge */
.cursor-tag{width:auto; min-width:86px; padding:0 1.1rem; border-radius:999px; white-space:nowrap}
/* practitioner tiles: lift on hover */
.person img{transition:transform .5s var(--ease), box-shadow .5s var(--ease)}
.person:hover img{transform:translateY(-6px); box-shadow:0 22px 40px -26px rgba(6,38,39,.55)}
/* treatment pages: breathing room above the CTA pair */
.tblock .tcopy .ctas{padding-top:2.5rem}

/* two-column mega menu: list left, one swapping image right, parchment */
.mega-in.mega-2{grid-template-columns:1.5fr 1fr; background:var(--parchment)}
.mega-2 .mega-col{padding:1.5rem 1.75rem 1.5rem}
.mega-2 .mega-col:last-child{padding:1.25rem 1.25rem 1.25rem 0; border-right:0}
.mega-2 .lpanel{aspect-ratio:4/3; position:relative; top:auto; height:100%; max-height:420px}
.mega-2 .llist.sm .li-item .t{font-size:1.55rem}
.mega-2 .llist.sm .li-item{padding:.3rem 2.8rem .3rem .7rem}
.mega-more{display:inline-block; margin-top:1rem; font-weight:600; color:var(--teal-deep); text-decoration:none}
.mega-more:hover{color:var(--ink)}

/* hero correction: full-bleed background, hard cuts, ~80vh */
.hero.seo{min-height:80vh; display:flex; align-items:center; justify-content:center; padding-block:clamp(3rem,6vw,4.5rem) clamp(4.5rem,8vw,6.5rem)}
.hero.seo .slides{display:block}
.hero.seo .slides img{transition:none !important; transform:none !important}
.hero.seo .slides::after{background:rgba(6,38,39,.6)}
.hero.seo .wrap{max-width:960px; display:flex; flex-direction:column; align-items:center; text-align:center}
.hpanel{display:none}

/* ==== HERO OVERRIDE (Phil, 17:52): one full-bleed background, hard cut, centred copy ==== */
.hero.seo{position:relative;min-height:80vh;display:flex;align-items:center;overflow:hidden;background:var(--teal-950,#062627)}
.hero.seo .wrap.hero-3{display:block !important;position:static;max-width:none;width:100%;padding:0;margin:0;grid-template-columns:none}
.hero.seo .hpanel{position:absolute !important;inset:0;width:100% !important;height:100% !important;border-radius:0;overflow:hidden;z-index:0;aspect-ratio:auto;margin:0;transform:none}
.hero.seo .hpanel[data-panel="1"]{display:none !important}
.hero.seo .hpanel img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:none !important;transform:none !important}
.hero.seo .hpanel img.on,.hero.seo .hpanel img:first-child:not(.off){opacity:1}
.hero.seo .hpanel::after{content:"";position:absolute;inset:0;background:rgba(6,38,39,.62)}
.hero.seo .hcopy{position:relative;z-index:1;max-width:980px;margin:0 auto;text-align:center;padding:clamp(56px,9vw,110px) 24px}
.hero.seo .hcopy h1{margin-left:auto;margin-right:auto}
.hero.seo .ctas,.hero.seo .badges{justify-content:center}
.hero.seo .hcopy .lede{margin-left:auto;margin-right:auto}
@media (max-width:640px){.hero.seo{min-height:auto}.hero.seo .hcopy{padding:48px 18px 120px}}

/* ---- content image parallax ---- */
/* site-behaviours writes the offsets as custom properties, so the hover
   transforms below compose with the movement instead of clobbering it. */
img.plx{transform:translate3d(0,var(--plx-y,0px),0) scale(var(--plx-s,1))}
.tile .im img.plx,.feat .im img.plx,.jtile .im img.plx,.person img.plx,.post-row img.plx{transition:transform .25s var(--ease)}
.tile:hover .im img.plx,.feat:hover .im img.plx,.jtile:hover .im img.plx{transform:translate3d(0,var(--plx-y,0px),0) scale(calc(var(--plx-s,1) * 1.035))}
.person:hover img.plx{transform:translate3d(0,calc(var(--plx-y,0px) - 6px),0) scale(var(--plx-s,1))}
@media (prefers-reduced-motion:reduce){img.plx{transform:none; transition:none}}

/* ---- large text, zoom and reflow (ECHOSTUDIO-762) ---- */
/* On a phone, a word wider than its column breaks onto the next line instead
   of pushing the page sideways or running off the edge. That's where it's
   needed: 200% text or zoom on a phone, where "Treatments", "Shiroabhyanga" or
   an email address is wider than the screen. "anywhere" also lets a column
   narrow below its longest word, so it stays on phone widths only: on a
   1024px screen it let the About page's heading break as
   "Acknowledgemen / t of Country" and narrowed the footer's first column. */
@media (max-width:560px){
  h1,h2,h3,h4,h5,h6,p,li,dt,dd,blockquote,figcaption,label,legend,summary,td,th,.btn,.btn2,.mrow .nm{overflow-wrap:anywhere}
  /* The name may shrink, but the price can't take more than about half the
     row, or a long note ("25% off regular prices") at large text squeezes the
     name to one letter a line. */
  .mrow{grid-template-columns:minmax(0,1fr) fit-content(55%)}
  /* Except the number beside a list item: it sits in a column exactly its own
     width, and WebKit broke "01" into "0" over "1". */
  .n{overflow-wrap:normal}
}

/* At large text a treatment's name and its price don't both fit on a phone, so
   the price goes under the name instead of breaking the name mid-word. A
   container's em follows the reader's text size, which a media query's doesn't:
   17em is never reached at normal size (a 320px phone's menu is 18em wide),
   only once the text is about 130% or more. */
.menu-group{container-type:inline-size}
@container (max-width:17em){
  .mrow{grid-template-columns:minmax(0,1fr)}
  .mrow .pr{text-align:left}
}

/* ---- Windows high contrast / forced colours (ECHOSTUDIO-762) ---- */
/* Forced colours repaint every background in the page colour. The menu
   button's two lines and the Sunrise logo are drawn as background, so they
   vanished, and the pill buttons, which have no border, lost their outline.
   Only applies when the reader has turned high contrast on. */
@media (forced-colors: active){
  .burger span{forced-color-adjust:none; background:ButtonText}
  .sr-logo{forced-color-adjust:none; background:CanvasText}
  .btn,.btn-cta,button.btn-cta,.btn2,.final .quiet,.upc .shell{border:1px solid ButtonText}
}

/* ---- reviews.css ---- */
/* Maiaveda reviews section. Self-contained: rendered by assets/reviews.js into <div data-reviews>. */
.rvw{padding-block:clamp(3.25rem,7vw,6.5rem);overflow:hidden}
.rvw-head{padding-inline:var(--gutter);margin-bottom:clamp(1.5rem,3vw,2.5rem)}
.rvw-head h2{font-family:var(--serif);font-weight:500;font-size:clamp(2rem,4.2vw,3.2rem);letter-spacing:-.015em;line-height:1.05;margin:0 0 .6rem}
.rvw-head p{margin:0;color:var(--ink-muted);font-size:clamp(1rem,1.4vw,1.15rem)}
.rvw-row{overflow:hidden;width:100%;margin-bottom:1rem;-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.rvw-track{display:flex;gap:1rem;width:max-content;animation:rvw-left 90s linear infinite;will-change:transform}
.rvw-row[data-dir="right"] .rvw-track{animation-name:rvw-right}
/* No reaction to the mouse: the rows keep moving under the pointer. Keyboard
   focus inside a row still pauses it, so someone tabbing to "Read on Google" can
   reach the link, and reduced motion stops the rows altogether. */
.rvw-row:focus-within .rvw-track{animation-play-state:paused}
@keyframes rvw-left{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes rvw-right{from{transform:translateX(-50%)}to{transform:translateX(0)}}
.rvw-tile{flex:none;width:340px;background:var(--parchment-2);border:1px solid var(--hair);border-radius:12px;padding:1.25rem 1.35rem;display:flex;flex-direction:column;gap:.7rem;color:var(--ink)}
.rvw-stars{display:flex;gap:2px}.rvw-stars svg{width:15px;height:15px;fill:#E9A82E;display:block}
/* Paragraph breaks show as Google shows them (pre-line). Clamped to five lines
   in the band and eight on /reviews; "See more" (ReviewWords) opens the rest. */
.rvw-q{margin:0;font-family:var(--serif);font-size:1.05rem;line-height:1.5;font-weight:400;white-space:pre-line;display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
.rvw-tile--fixed .rvw-q{-webkit-line-clamp:8}
.rvw-see{align-self:flex-start;margin:-.25rem 0 0;padding:0;border:0;background:none;font:inherit;font-size:.82rem;font-weight:600;color:var(--teal-deep);cursor:pointer}
.rvw-see:hover{text-decoration:underline}
.rvw-see:focus-visible{outline:2px solid var(--teal-deep);outline-offset:2px}
/* "Read on Google" and the name sit together at the bottom of the card; the
   stars, the words and See more stay at the top (Phil, 3 Nov 2026). */
.rvw-more{margin-top:auto;font-size:.82rem;font-weight:600;color:var(--teal-deep);text-decoration:none;width:fit-content}
.rvw-more:hover{text-decoration:underline}
.rvw-who{padding-top:.75rem;border-top:1px solid var(--parchment-3);font-size:.86rem;line-height:1.35}
/* A review sent to her directly has no link, so the name alone takes the bottom. */
.rvw-tile > .rvw-who:first-of-type:not(.rvw-more + .rvw-who){margin-top:auto}
.rvw-who b{display:block;font-weight:600}.rvw-who span{color:var(--ink-muted)}
.rvw-all{color:var(--teal-deep);font-weight:600;text-decoration:none;white-space:nowrap}
.rvw-all:hover{text-decoration:underline}
.rvw-grid{display:grid;gap:1rem;padding-inline:var(--gutter)}
.rvw-grid .rvw-tile{width:auto}
/* On the reviews page every card is the same size, the tallest the clamp
   allows, with "Read on Google" and the name pinned to the bottom (Phil, 3 Nov 2026:
   "rather than a wall with different sized cards they're all consistent").
   A long review opens in the dialog, so nothing in the wall moves. */
.rvw-grid{grid-auto-rows:1fr;align-items:stretch}
.rvw-grid .rvw-tile--fixed{height:100%;min-height:19rem}
/* The whole review, over the page. */
.rvw-dialog{border:1px solid var(--hair);border-radius:12px;background:var(--parchment-2);color:var(--ink);padding:0;width:min(40rem,calc(100vw - 2rem));max-height:calc(100vh - 2rem);margin:auto}
.rvw-dialog::backdrop{background:rgba(20,30,28,.45)}
.rvw-dialog-in{padding:clamp(1.25rem,3vw,2rem);display:flex;flex-direction:column;gap:1rem}
.rvw-dialog-q{margin:0;font-family:var(--serif);font-size:1.1rem;line-height:1.55;white-space:pre-line}
.rvw-dialog-who{margin:0;padding-top:.75rem;border-top:1px solid var(--parchment-3);font-size:.9rem;line-height:1.35}
.rvw-dialog-who b{display:block;font-weight:600}.rvw-dialog-who span{color:var(--ink-muted)}
.rvw-dialog-close{align-self:flex-start;padding:.55rem 1rem;border:1px solid var(--teal-deep);border-radius:999px;background:none;font:inherit;font-size:.9rem;font-weight:600;color:var(--teal-deep);cursor:pointer}
.rvw-dialog-close:hover{background:var(--teal-deep);color:var(--parchment-2)}
.rvw-dialog-close:focus-visible,.rvw-see:focus-visible{outline:2px solid var(--teal-deep);outline-offset:2px}
.rvw-page-foot{padding-inline:var(--gutter);margin-top:clamp(1.5rem,3vw,2.5rem);color:var(--ink-muted);font-size:clamp(1rem,1.3vw,1.1rem)}
.rvw-page-foot a{color:var(--teal-deep);font-weight:600;text-decoration:none}
.rvw-page-foot a:hover{text-decoration:underline}
@media(min-width:700px){.rvw-grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.rvw-grid{grid-template-columns:repeat(3,1fr)}}
.rvw-badges{padding-inline:var(--gutter)}
.rvw-badges .badges{margin-top:clamp(1.25rem,3vw,2rem);padding-top:0;border-top:0;justify-content:center}
.rvw-badges .badge{color:var(--ink)}
@media(max-width:640px){
  .rvw-tile{width:280px;padding:1.1rem 1.15rem}
  /* Side by side, not stacked. Two proofs read as corroboration; one above the
     other reads as a list you stop reading. Only when the reader's text is too
     large for both on one line does the second drop below (ECHOSTUDIO-762). */
  .rvw-badges .badges{flex-direction:row;flex-wrap:wrap;align-items:flex-start;justify-content:center;gap:.75rem}
  .rvw-badges .badge{flex:1 1 0;min-width:auto}
  .rvw-badges .badge-mid{min-width:0}
  /* Each count may use 5px of the 12px gap before it wraps, as it always has at
     390px, so the line stays whole on 375 and 390 phones and the two counts can
     never come closer than 2px. Narrower than that, the count wraps under itself
     (on a 360px phone it used to hang 16px over, 3px from the Google count). */
  .rvw-badges .badge-sub{margin-inline:-5px}
  .rvw-badges .badge b,.rvw-badges .badge span{font-size:.72rem;line-height:1.25}
}
@media(max-width:359px){.rvw-badges .badge{min-width:0}}
/* The right-moving row's own rule is more specific, so it is named here too, or it kept moving under reduced motion (ECHOSTUDIO-517). */
@media(prefers-reduced-motion:reduce){.rvw-track,.rvw-row[data-dir="right"] .rvw-track{animation:none}}
/* Stopped, the rows showed one review on a phone and three on a desktop, and
   the rest sat past the edge with no way to reach them (ECHOSTUDIO-762). Under
   reduced motion each row is a strip you swipe or scroll instead, holding one
   copy of each review; the copies that fill the moving loop are dropped. The
   fade at the edges goes too, so the last review isn't half hidden. */
@media(prefers-reduced-motion:reduce){
  .rvw-row{overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;scroll-padding-inline:var(--gutter);padding-inline:var(--gutter);padding-bottom:.5rem;-webkit-mask-image:none;mask-image:none}
  .rvw-track{transform:none}
  .rvw-tile[aria-hidden="true"]{display:none}
  .rvw-tile{scroll-snap-align:start}
}

/* The mark sits on the same line as the stars so each card says where it came
   from without repeating it in the byline. */
.rvw-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .55rem;
}
.rvw-top .rvw-stars { margin: 0; }
.rvw-top .badge-logo {
  width: 18px;
  height: 18px;
  flex: none;
  opacity: .85;
}

/* ---- book.css ---- */
/* Maiaveda booking widget. Loaded only by book/index.html. */
.bw-sec{padding-block:clamp(1.5rem,4vw,3rem) clamp(3rem,7vw,6rem)}
.widget{background:var(--parchment-2);border-radius:14px;max-width:760px;margin:0 auto;padding:clamp(1rem,3vw,1.75rem);border:1px solid var(--parchment-3)}
.seg{display:grid;grid-template-columns:repeat(3,1fr);gap:.25rem;background:var(--parchment-3);border-radius:10px;padding:.25rem;margin-bottom:1.25rem}
.seg button{appearance:none;border:0;background:none;font:600 .86rem/1.2 var(--sans);color:var(--ink-muted);padding:.7rem .5rem;border-radius:8px;cursor:pointer;min-height:44px}
.seg button[aria-selected="true"]{background:var(--orange);color:var(--teal-950)}
.seg button:hover:not([aria-selected="true"]){color:var(--ink)}
.pane{display:none}.pane.on{display:block}
.pane .form{max-width:none}
.pane-intro{margin-bottom:1rem}.pane-intro h2{font-size:clamp(1.4rem,2.6vw,1.9rem);margin-bottom:.25rem}
.thanks{display:none;border-top:3px solid var(--brand);background:var(--parchment);border-radius:10px;padding:1.25rem}.thanks.on{display:block}
.thanks h3{font-size:1.5rem;margin-bottom:.35rem}
.form.sent{display:none}
.slots3{display:grid;grid-template-columns:repeat(3,1fr);gap:.4rem}
.slots3 .tbtn{width:100%}
.bnav{list-style:none;margin:0 0 1rem;padding:0;display:flex;gap:.25rem;align-items:center;counter-reset:st}
.bnav li{counter-increment:st;font-size:.7rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-muted);flex:1;border-top:3px solid var(--parchment-3);padding-top:.4rem;cursor:default;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bnav li.on{color:var(--teal-950);border-top-color:var(--orange)}
.bnav li.done{color:var(--teal-deep);border-top-color:var(--teal-deep);cursor:pointer}
@media(max-width:640px){.bnav li{font-size:0;padding-top:.3rem}.bnav li.on{font-size:.68rem;flex:3}}
.bsum-strip{display:flex;flex-wrap:wrap;gap:.25rem .9rem;font-size:.84rem;margin:0 0 1rem;padding:.6rem .8rem;background:var(--parchment);border-radius:8px;min-height:2.4rem}
.bsum-strip div{display:flex;gap:.35rem;align-items:baseline}.bsum-strip span{color:var(--ink-muted);font-size:.7rem;text-transform:uppercase;letter-spacing:.06em}.bsum-strip p{margin:0}
.bstep{display:none}.bstep.on{display:block}
.bstep h2{font-size:clamp(1.4rem,2.6vw,1.9rem);margin-bottom:.35rem}
.bgroup h3{font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;font-family:var(--sans);font-weight:600;color:var(--teal-deep);margin:1.25rem 0 .25rem}
.tscroll{position:relative;margin-top:.75rem}
@media(min-width:760px){.tscroll{max-height:440px;overflow-y:auto;overscroll-behavior:contain;padding-right:.25rem}}
.tsearch{position:sticky;top:0;z-index:2;background:var(--parchment-2);padding:.1rem 0 .5rem;margin:0}
.trow,.prow{appearance:none;background:none;border:0;border-bottom:var(--rule);width:100%;text-align:left;font:inherit;color:inherit;cursor:pointer;display:grid;grid-template-columns:1fr auto;gap:.5rem 1rem;align-items:center;padding:.75rem .5rem;border-radius:0}
.trow:hover,.prow:hover{background:var(--parchment)}
.trow.sel,.prow.sel{background:var(--parchment);box-shadow:inset 3px 0 0 var(--brand)}
.trow .nm{font-family:var(--serif);font-size:1.05rem;font-weight:500}.trow .nm small,.prow .nm small{display:block;font-family:var(--sans);font-size:.8rem;color:var(--ink-muted);font-weight:400;margin-top:.1rem}
.trow .pr{text-align:right}.trow .pr b{display:block}.trow .pr span{display:block;font-size:.74rem;color:var(--ink-muted)}
.prow{grid-template-columns:56px 1fr}.prow .av{width:56px;height:56px;border-radius:50%;object-fit:cover;display:grid;place-items:center;background:var(--parchment)}.prow .av svg{width:34px;height:34px;stroke:var(--teal-deep);fill:none;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.prow .nm{font-family:var(--serif);font-size:1.05rem;font-weight:500}
.dhead{display:flex;justify-content:space-between;align-items:center;margin:1rem 0 .5rem}
.dhead button{appearance:none;background:none;border:1px solid var(--hair);border-radius:50%;width:40px;height:40px;cursor:pointer;font-size:1.1rem;color:var(--ink)}
.dstrip{display:grid;grid-template-columns:repeat(7,1fr);gap:.3rem}
.dbtn{appearance:none;background:var(--parchment);border:1px solid var(--hair);border-radius:8px;padding:.5rem .15rem;cursor:pointer;font:inherit;color:inherit;display:grid;gap:.1rem;text-align:center;min-height:72px}
.dbtn span{font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-muted)}.dbtn b{font-family:var(--serif);font-size:1.3rem;font-weight:500;line-height:1}.dbtn small{font-size:.62rem;color:var(--teal-deep)}
.dbtn.sel{background:var(--teal-900);color:var(--parchment);border-color:var(--teal-900)}.dbtn.sel span,.dbtn.sel small{color:var(--teal-300)}
.dbtn.off{opacity:.45;cursor:not-allowed}.dbtn.off small{color:var(--ink-muted)}
.tgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:.4rem;margin-top:.5rem}
.tbtn{appearance:none;background:var(--parchment);border:1px solid var(--hair);border-radius:999px;padding:.6rem .4rem;cursor:pointer;font:600 .86rem var(--sans);color:var(--ink);min-height:44px}
.tbtn:hover{border-color:var(--ink)}.tbtn.sel{background:var(--orange);border-color:var(--orange);color:var(--teal-950)}
.wtrust{list-style:none;padding:1rem 0 0;margin:1.25rem 0 0;border-top:1px solid var(--parchment-3);font-size:.8rem;color:var(--ink-muted);display:grid;gap:.35rem .9rem}
@media(min-width:640px){.wtrust{grid-template-columns:1fr 1fr}}
.wtrust li{display:flex;gap:.45rem;align-items:flex-start}.wtrust svg{width:16px;height:16px;flex:none;stroke:var(--teal-deep);fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;margin-top:.15rem}
.back{font-size:.86rem;color:var(--ink-muted);text-decoration:none;display:inline-block;margin-bottom:.75rem}.back:hover{color:var(--teal-deep)}
.paybox{border:var(--rule);border-radius:10px;padding:1.1rem;background:var(--parchment);margin-bottom:1.25rem}
.paybox .row{display:flex;justify-content:space-between;padding:.4rem 0;border-bottom:var(--rule)}.paybox .row.big{font-family:var(--serif);font-size:1.4rem;border:0;padding-top:.75rem}
.done{border-top:3px solid var(--brand);background:var(--parchment);border-radius:10px;padding:clamp(1.1rem,3vw,1.75rem)}
.done .ref{font-family:var(--serif);font-size:2rem;letter-spacing:-.02em;color:var(--teal-deep)}
.sms{margin-top:1.5rem;max-width:420px;opacity:0;transform:translateY(14px);transition:all .6s var(--ease)}.sms.in{opacity:1;transform:none}
.sms .bubble{background:var(--teal-900);color:var(--parchment);padding:.9rem 1rem;border-radius:18px 18px 18px 4px;font-size:.92rem;line-height:1.45}
.sms .from{font-size:.72rem;color:var(--ink-muted);margin:.35rem 0 0;letter-spacing:.06em;text-transform:uppercase}
.next-list{list-style:none;padding:0;margin:1.25rem 0 0;border-top:var(--rule)}.next-list li{display:flex;gap:.9rem;padding:.75rem 0;border-bottom:var(--rule);font-size:.95rem}.next-list svg{width:26px;height:26px;flex:none;stroke:var(--teal-deep);fill:none;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.widget .ctas{margin-top:1.25rem}
.bctx{display:grid;grid-template-columns:56px 1fr auto;gap:.9rem;align-items:center;background:var(--parchment);border-radius:10px;padding:.75rem .9rem;margin:0 0 .75rem}
.bctx img{width:56px;height:56px;border-radius:50%;object-fit:cover}
.bctx b{display:block;font-family:var(--serif);font-size:1.15rem;font-weight:500}.bctx span{display:block;font-size:.8rem;color:var(--ink-muted)}
.bctx a{font-size:.82rem;color:var(--teal-deep);white-space:nowrap}
@media(max-width:520px){.bctx{grid-template-columns:48px 1fr}.bctx img{width:48px;height:48px}.bctx a{grid-column:2}}
.bctx[hidden]{display:none}
.done .badges{margin-top:1.25rem;padding-top:1rem;border-top:var(--rule);justify-content:flex-start}
.done .badge{color:var(--ink)}
@media(max-width:640px){.done .badges{flex-direction:column;align-items:flex-start;gap:1rem}}

/* ---- sketches.css ---- */
/* Engraved line drawings. They sit directly on the page background: a card or a
   plate behind one makes it read as an interface element rather than an image. */

.sketch {
  display: block;
  width: 100%;
  height: auto;
  /* The drawings carry their own optical margin and look indented otherwise. */
  margin-left: -0.5rem;
  mix-blend-mode: multiply;
}

.sketch-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 2rem 2.25rem;
}
.sketch-grid li { break-inside: avoid; }
.sketch-grid a {
  display: block;
  text-decoration: none;
  color: inherit;
}
.sketch-grid .sketch {
  /* A fixed box so the labels line up across the row no matter how tall or
     wide each drawing happens to be. */
  width: auto;
  max-width: 13rem;
  height: 8.5rem;
  object-fit: contain;
  object-position: left bottom;
  margin-bottom: 0.9rem;
  transition: transform 0.5s var(--ease);
}
.sketch-grid a:hover .sketch { transform: translateY(-3px); }
.sketch-grid b {
  display: block;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 1.1rem;
  letter-spacing: -0.01em;
  margin-bottom: 0.15rem;
}
.sketch-grid a:hover b { color: var(--teal-deep); }
.sketch-grid span {
  display: block;
  font-size: 0.88rem;
  color: var(--ink-muted);
  line-height: 1.45;
}

@media (prefers-reduced-motion: reduce) {
  .sketch-grid .sketch { transition: none; }
}

/* ---- treatment page: words on the left, drawing on the right, prices under ---- */
.svc-head {
  display: grid;
  gap: 2rem 3rem;
  align-items: start;
}
@media (min-width: 900px) {
  .svc-head { grid-template-columns: 1.15fr .85fr; }
}
.svc-art {
  display: flex;
  justify-content: center;
}
.svc-art .sketch {
  max-width: 24rem;
  margin-left: 0;
}
/* The copy no longer sits in a grid column, so its own block spacing applies. */
.svc-copy .tcopy { display: block; }
.svc-copy .tcopy .ctas { margin-top: 2rem; padding-top: 0; }

.svc-prices {
  margin-top: clamp(2rem, 5vw, 3.25rem);
}
.svc-prices .pricebox {
  max-width: 56rem;
  margin-inline: auto;
}
.svc-prices .ptiles { justify-content: center; }

/* A price tile is a link into the booking flow for that treatment. */
a.ptile {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform .25s var(--ease), border-color .25s var(--ease);
}
a.ptile:hover {
  transform: translateY(-2px);
  border-color: rgba(31, 42, 41, .18);
}
a.ptile:hover b { color: var(--teal-deep); }

@media (prefers-reduced-motion: reduce) {
  a.ptile { transition: none; }
}

/* ---- refine.css ---- */
/* The three fixes from Phil's 26 Sep review (ECHOSTUDIO-199), built to Iris's
 * mocks in direction/echostudio-199/. */

/* ---- the icon disc: "Worth knowing" on retreats and treatments ---------- */
.ico-disc {
  display: grid; place-items: center; flex: none;
  inline-size: 3.5rem; block-size: 3.5rem; border-radius: var(--radius-pill);
  background: var(--hue-parchment2); color: var(--hue-teal-deep);
  transition: background-color .5s cubic-bezier(0.2, 0.7, 0.2, 1), color .5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.ico-disc svg { inline-size: 1.625rem; block-size: 1.625rem; }
.tone-raised .ico-disc, .tone-sand .ico-disc { background: var(--hue-parchment); }
@media (max-width: 768px) {
  .ico-disc { inline-size: 2.75rem; block-size: 2.75rem; }
  .ico-disc svg { inline-size: 1.375rem; block-size: 1.375rem; }
}

/* A retreat's four "Worth knowing" rows: heading on the left, rows on the right. */
.wk { display: grid; gap: var(--space-block); width: 100%; }
@media (min-width: 900px) {
  .wk { grid-template-columns: 4fr 1fr 7fr; column-gap: var(--space-roomy); align-items: start; }
  .wk > :first-child { grid-column: 1; }
  .wk > .rowlist { grid-column: 3; }
}
.rowlist > li > a.rowlist-ico { grid-template-columns: auto 1fr auto; }
.rowlist-ico .arr { display: block; inline-size: 1.25rem; color: var(--muted, currentColor);
  transition: transform .5s cubic-bezier(0.2, 0.7, 0.2, 1); }
.rowlist-ico .arr svg { display: block; inline-size: 100%; block-size: auto; }
@media (max-width: 639px) {
  .rowlist > li > a.rowlist-ico { grid-template-columns: auto 1fr auto; }
}

/* The treatment pages' four answers: the icon above the name, like the mock. */
.notes--icons .note-head { flex-direction: column; align-items: flex-start; gap: var(--space-snug); }

/* ---- the Matriarch Threshold, "What it is", as chapters ----------------- */
.mt { display: grid; width: 100%; }
.mt-row { display: grid; gap: var(--space-roomy); padding-block: var(--space-block); }
.mt-row + .mt-row, .mt-quote + .mt-row, .mt-panel + .mt-row { border-block-start: var(--space-hair) solid var(--rule-colour); }
.mt-intro { padding-block-start: 0; }
@media (min-width: 800px) {
  .mt-row { grid-template-columns: 4fr 1fr 7fr; column-gap: var(--space-roomy); }
  .mt-side { grid-column: 1; }
  .mt-body { grid-column: 3; }
  .mt-chap { padding-block: calc(var(--space-block) * 1.4); }
}
.mt-side { display: grid; gap: var(--space-roomy); align-content: start; }
.mt-body { display: grid; gap: var(--space-base); align-content: start; justify-items: start; }
.mt-body > p { max-width: 60ch; margin: 0; }
.mt-facts { margin: 0; border-block-start: var(--space-hair) solid var(--rule-colour); }
.mt-facts > div { display: flex; justify-content: space-between; gap: var(--space-base);
  padding-block: var(--space-snug); border-block-end: var(--space-hair) solid var(--rule-colour); }
.mt-facts dt { color: var(--muted); }
.mt-facts dd { margin: 0; text-align: end; }
.mt-lede { font-family: var(--text-heading-family); font-size: var(--text-heading-size); line-height: 1.2;
  letter-spacing: -.01em; max-width: 30ch; margin: 0 0 var(--space-tight); }
.mt-strong { font-weight: 500; }
.mt-soft { font-family: var(--text-heading-family); font-style: italic; font-size: 1.25rem; line-height: 1.35;
  color: var(--hue-teal900); max-width: 40ch; margin-block-start: var(--space-tight); }
.mt-come { font-family: var(--text-heading-family); font-size: 1.25rem; line-height: 1.35; max-width: 44ch; }
.chapter-photo { aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--radius-sm); max-width: 20rem;
  background: var(--rule-colour); }
.chapter-photo img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 40% 30%; }
.mt-quote { margin: 0; padding-block: calc(var(--space-block) * 2.2); text-align: center;
  border-block: var(--space-hair) solid var(--rule-colour); }
.mt-quote blockquote { margin: 0 auto; max-width: 18ch; quotes: none; }
.mt-panel { background: var(--hue-parchment2); border-radius: var(--radius-sm); padding: var(--space-block);
  margin-block: var(--space-block); display: grid; gap: var(--space-roomy); }
.tone-raised .mt-panel { background: var(--hue-parchment); }
.mt-panel ol { list-style: none; margin: 0; padding: 0; display: grid; column-gap: calc(var(--space-block) * .8); }
@media (min-width: 800px) { .mt-panel ol { grid-template-columns: 1fr 1fr; } }
.mt-panel li { display: grid; grid-template-columns: 2.1rem 1fr; align-items: baseline;
  padding-block: var(--space-snug); border-block-start: var(--space-hair) solid var(--rule-colour); }
.mt-panel .n { color: var(--hue-teal-deep); }
.mt-price { font-family: var(--text-heading-family); font-size: 1.75rem; line-height: 1.1; margin: var(--space-tight) 0 0; }
.mt-close .btn-cta { margin-block-start: var(--space-tight); }
@media (max-width: 799px) {
  .chapter-photo { aspect-ratio: 3 / 2; max-width: none; }
  .mt-panel { padding: var(--space-roomy); }
  .mt-quote { padding-block: calc(var(--space-block) * 1.4); }
}

/* ---- the enquire page: words left, the form in a card on the right ----- */
.blk-enquiry.enq { display: grid; gap: var(--space-block); width: 100%; justify-items: stretch; }
.enq-intro { display: grid; gap: var(--space-roomy); align-content: start; }
.enq-intro .t-lede { max-width: 40ch; }
.enq-contact { margin: 0; border-block-start: var(--space-hair) solid var(--rule-colour); }
.enq-contact > div { display: flex; justify-content: space-between; gap: var(--space-snug);
  padding-block: var(--space-snug); border-block-end: var(--space-hair) solid var(--rule-colour); }
.enq-contact dt { color: var(--muted); }
.enq-contact dd { margin: 0; text-align: end; }
.enq-contact-wide { display: none; }
@media (min-width: 1000px) {
  .blk-enquiry.enq { grid-template-columns: 5fr 1fr 6fr; column-gap: var(--space-roomy); align-items: start; }
  .blk-enquiry.enq > .enq-intro { grid-column: 1; grid-row: 1; justify-self: stretch; position: sticky; top: calc(var(--head-h, 5rem) + var(--space-block)); }
  .blk-enquiry.enq > .enquiry-wrap { grid-column: 3; grid-row: 1; justify-self: stretch; width: 100%; }
  .enq-contact-wide { display: block; margin-block-start: var(--space-base); }
  .enq-contact-narrow { display: none; }
}
.enq .enquiry-wrap { background: var(--hue-parchment); border: var(--space-hair) solid var(--rule-colour);
  border-radius: var(--radius-sm); padding: var(--space-block); }
@media (max-width: 767px) { .enq .enquiry-wrap { padding: var(--space-roomy); } }

.enquiry--steps { max-width: none; gap: 0; }
.enq-progress { display: flex; gap: var(--space-tight); margin-block-end: var(--space-roomy); }
.enq-progress span { flex: 1; block-size: 2px; border-radius: 2px; background: var(--rule-colour); transition: background-color .35s; }
.enq-progress span.on { background: var(--hue-teal-deep); }
html:not(.js) .enq-progress, html:not(.js) .enq-js { display: none; }
.enq-step { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: var(--space-base); }
html:not(.js) .enq-step + .enq-step { margin-block-start: var(--space-block); }
html.js .enq-step:not(.on) { display: none; }
html.mv .enq-step.on { animation: enq-in .35s cubic-bezier(0.2, 0.7, 0.2, 1); }
@keyframes enq-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.enq-legend { padding: 0; display: grid; gap: var(--space-tight); margin-block-end: var(--space-tight); }
.enq-legend .t-heading { margin: 0; }
.enq-legend .t-heading:focus { outline: none; }
.enq-legend .t-heading:focus-visible { outline: 2px solid var(--hue-teal-deep); outline-offset: 4px; }
.enquiry--steps .field { display: grid; gap: var(--space-tight); }
.enquiry--steps .field.invalid input, .enquiry--steps .field.invalid textarea { border-color: var(--hue-orange-action-deep); }
.enq-nav { display: flex; justify-content: space-between; align-items: center; gap: var(--space-base); margin-block-start: var(--space-tight); }
.enq-nav > .btn-cta:only-child, .enq-nav > .btn-cta:first-child:last-child { margin-inline-start: auto; }
html:not(.js) .enq-nav > .btn-cta { margin-inline-start: 0; }
.enq-back { background: none; border: 0; padding: 0; font: inherit; color: var(--muted); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; }
.enq-back:hover { color: var(--fg); }

.enq-chips { display: flex; flex-wrap: wrap; gap: var(--space-tight); }
.enq-chip { position: relative; display: inline-flex; }
.enq-chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.enq-chip span { display: inline-flex; align-items: center; gap: .35em; min-height: 2.75rem;
  padding: var(--space-tight) var(--space-base); border: var(--space-hair) solid var(--rule-colour);
  border-radius: var(--radius-pill); font-size: var(--text-body-size); line-height: 1.2;
  transition: background-color .25s, color .25s, border-color .25s; }
.enq-chip input:checked + span { background: var(--hue-teal900); border-color: var(--hue-teal900); color: var(--hue-parchment); }
.enq-chip input:checked + span::before { content: "\2713"; }
.enq-chip input:focus-visible + span { outline: 2px solid var(--hue-teal-deep); outline-offset: 2px; }
@media (hover: hover) { .enq-chip:hover span { border-color: var(--hue-teal-deep); } }
.enq-chips--small .enq-chip span { min-height: 2.25rem; font-size: var(--text-small-size); padding: .35rem .85rem; }
.enq-which { display: grid; gap: var(--space-snug); margin-block-start: var(--space-tight);
  padding-block-start: var(--space-base); border-block-start: var(--space-hair) dashed var(--rule-colour); }
html.js .enq-which:not(.on) { display: none; }

/* ---- draft mode in a tab of its own (ECHOSTUDIO-740) -------------------- */
/* Only rendered while an editor previews drafts; visitors never get it. */
.preview-bar {
  position: fixed; z-index: 210;
  /* Clear of the notch and the home indicator on a phone (ECHOSTUDIO-789). */
  inset-block-end: calc(var(--space-base) + env(safe-area-inset-bottom));
  inset-inline-start: max(var(--space-base), env(safe-area-inset-left));
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-tight) var(--space-snug);
  max-inline-size: calc(100% - 2 * var(--space-base));
  padding: var(--space-snug) var(--space-roomy); border-radius: var(--radius-lg);
  background: var(--hue-teal900); color: var(--hue-parchment);
  font-family: var(--font-sans); font-size: .875rem; line-height: 1.4;
  box-shadow: 0 6px 24px rgb(6 38 39 / .25);
}
.preview-bar p { margin: 0; }
.preview-bar a { color: var(--hue-parchment); font-weight: 600; text-decoration: underline; text-underline-offset: .2em; }
.preview-bar a:focus-visible { outline: 2px solid var(--hue-parchment); outline-offset: 3px; }

/* ---- motion.css ---- */
/* The interaction set (ECHOSTUDIO-199, Iris's DIRECTION-199.md).
 *
 * Slow, warm and certain: every motion should feel like breathing out, and
 * anything noticed as an effect is too much. Motion belongs to titles, images
 * and the change between pages. Body copy keeps its fade.
 *
 * Everything here stops under prefers-reduced-motion. The script that sets
 * `mv` on <html> never sets it then, and the rules that hold anything back all
 * hang off `mv`, so nothing is ever left hidden.
 *
 * The first-visit preloader was dropped on 26 Sep: Beacon measured it at
 * +201ms desktop LCP on the home page, over the 100ms limit. */

/* ---- 1. page transition: oreana's line, over the old page ----------------
 * PageTransitions.tsx animates the clip-path on the new page. The browser's
 * own crossfade is switched off so the old page stays exactly where it is. */
::view-transition-old(root),
::view-transition-new(root) { animation: none !important; mix-blend-mode: normal; }
::view-transition-group(root) { z-index: auto !important; }
::view-transition-image-pair(root) { isolation: isolate; will-change: clip-path; z-index: 1; }
::view-transition-new(root) { z-index: 10000; }
::view-transition-old(root) { z-index: 1; }

/* ---- 3. title lines rise out of a mask -----------------------------------
 * site-behaviours splits titles into lines. On a first load, titles already
 * on screen are never touched, so nothing the page paints first is hidden
 * (Beacon measured what that cost LCP). During a client-side page change the
 * new page's titles are held back until they are split, with a failsafe: if
 * the script never gets there, they show after 2.5s regardless. */
@keyframes mv-show { to { visibility: visible; } }
html.mv[data-vt] main :is(h1.t-display, h1.t-title, h2.t-title, h2.t-display):not([data-lines]):not(.rv):not(.rv-h) {
  visibility: hidden;
  animation: mv-show 0s 2.5s forwards;
}
/* The titles are set solid (line-height 1), and Newsreader's accented capitals
 * rise .21em above the line box while descenders stop just inside it. The mask
 * was the line box plus .08em below, so accents were cut off once a line
 * landed, and a line pushed down 105% still showed its ascenders and accents
 * along the bottom before it rose (ECHOSTUDIO-207). A clip-path reaches .25em
 * above and .12em below the line without moving the layout, and the line
 * starts .45em further down, where nothing of it shows. */
[data-lines] .ln { display: block; clip-path: inset(-.25em -.1em -.12em -.1em); }
[data-lines] .ln-in {
  display: block;
  transform: translateY(calc(100% + .45em));
  transition: transform .9s cubic-bezier(0.2, 0.7, 0.2, 1);
  transition-delay: calc(var(--ln, 0) * 70ms);
}
[data-lines].in .ln-in { transform: none; }

/* ---- 5. hovers: pointer devices only ------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  /* The CTA arrow leaves to the right and comes back in from the left. */
  .btn-cta:hover::after { transform: none; animation: mv-arrow .5s cubic-bezier(0.2, 0.7, 0.2, 1); }
  @keyframes mv-arrow {
    0% { background-position: 50% 50%; }
    45% { background-position: calc(50% + 2.4rem) 50%; }
    45.1% { background-position: calc(50% - 2.4rem) 50%; }
    100% { background-position: 50% 50%; }
  }

  /* Inline links in her words: the underline draws in from the left. */
  main :is(.prose, .sys-prose, .mt-body, .t-lede) a:not([class]) {
    text-decoration-color: currentColor;
    background: linear-gradient(currentColor, currentColor) 0 100% / 0 var(--space-hair) no-repeat;
    transition: background-size .45s cubic-bezier(0.2, 0.7, 0.2, 1), text-decoration-color .2s;
  }
  main :is(.prose, .sys-prose, .mt-body, .t-lede) a:not([class]):hover {
    text-decoration-color: transparent;
    background-size: 100% var(--space-hair);
  }

  /* Card photographs: a slow 1.04 inside their frame. */
  .tile .im img, .feat .im img, .jtile .im img, .mega-tile img, .photorow-im img {
    transition: transform 1.2s cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  .tile:hover .im img, .feat:hover .im img, .jtile:hover .im img, .mega-tile:hover img, .photorow-im:hover img {
    transform: scale(1.04);
  }
  .tile:hover .im img.plx, .feat:hover .im img.plx, .jtile:hover .im img.plx {
    transition: transform 1.2s cubic-bezier(0.2, 0.7, 0.2, 1);
    transform: translate3d(0, var(--plx-y, 0px), 0) scale(calc(var(--plx-s, 1) * 1.04));
  }
  .tile .arr, .feat .arr, .jtile .arr { transition: transform .5s cubic-bezier(0.2, 0.7, 0.2, 1); }
  .tile:hover .arr, .feat:hover .arr, .jtile:hover .arr { transform: translateX(6px); }

  /* "Worth knowing" rows: the disc fills teal and the arrow eases along. */
  .rowlist > li > a.rowlist-ico:hover .ico-disc { background: var(--hue-teal-deep); color: var(--hue-parchment); }
  .rowlist > li > a.rowlist-ico:hover .arr { transform: translateX(6px); }
}

/* ---- reduced motion: all of it off -------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-lines] .ln-in { transform: none; transition: none; }
  .btn-cta:hover::after { animation: none; }
  .ico-disc, .rowlist-ico .arr { transition: none; }
}
