/* ==========================================================================
   The Brow Girl - main stylesheet
   Mobile first. Desktop layout from 64em (1024px).
   ========================================================================== */


/* --------------------------------------------------------------------------
   Fonts - self-hosted, Latin subset
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "DM Serif Display";
  src: url("/assets/fonts/dm-serif-display-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "DM Serif Display";
  src: url("/assets/fonts/dm-serif-display-latin-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-latin-600-normal.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}


/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Palette - client supplied */
  --ivory: #f6f2ec;
  --soft-white: #fcfaf7;
  --stone: #d8d0c7;
  --nude: #c7a89a;
  --cocoa: #8b7568;
  --espresso: #292421;

  /* Colour roles
     Espresso carries all body copy on light backgrounds.
     On espresso: ivory for text, stone for secondary text (about 10:1),
     nude for small accents (about 6.9:1). Cocoa is decorative only on
     light backgrounds, never body text (about 3.9:1 on ivory). */
  --color-bg: var(--ivory);
  --color-text: var(--espresso);
  --color-line-dark: rgba(216, 208, 199, 0.16);

  /* Type */
  --font-display: "DM Serif Display", Georgia, "Times New Roman", serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

  /* Fluid type scale. Each step reaches its maximum at roughly 2200-2600px,
     so it keeps responding at 1920. */
  --step--1: clamp(0.8125rem, 0.78rem + 0.1vw, 0.9375rem);
  --step-0: clamp(1rem, 0.95rem + 0.15vw, 1.1875rem);
  --step-1: clamp(1.125rem, 1.05rem + 0.25vw, 1.4375rem);
  --step-2: clamp(1.375rem, 1.2rem + 0.5vw, 2rem);
  --step-3: clamp(1.75rem, 1.45rem + 0.95vw, 3rem);
  --step-4: clamp(2.125rem, 1.6rem + 1.55vw, 3.75rem);
  --step-5: clamp(2.25rem, 1.75rem + 2.9vw, 5.75rem);

  /* Spacing scale */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-s: 1rem;
  --space-m: 1.5rem;
  --space-l: 2rem;
  --space-xl: 3rem;
  --space-2xl: 4.5rem;
  --space-3xl: 6.5rem;
  --section-pad: clamp(4rem, 2.5rem + 6vw, 9rem);

  /* Layout. The container widens fluidly above the design width rather
     than capping and stranding content at 1920. Header and hero share it. */
  --gutter: clamp(1rem, 0.5rem + 2.5vw, 2.5rem);
  --container: clamp(72rem, 82vw, 100rem);
  --header-h: 4.5rem;

  /* Shape and motion */
  --radius: 0.125rem;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --dur: 200ms;
}

@media (min-width: 64em) {
  :root {
    --header-h: 5.5rem;
  }
}


/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + var(--space-s));
}

html.nav-open {
  overflow: hidden;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.1;
  text-wrap: balance;
}

p {
  margin: 0;
}

a {
  color: inherit;
}

button {
  font: inherit;
}

:focus-visible {
  outline: 2px solid var(--focus-color, var(--espresso));
  outline-offset: 3px;
}

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

.skip-link {
  position: absolute;
  top: var(--space-s);
  left: var(--space-s);
  z-index: 100;
  padding: var(--space-xs) var(--space-m);
  background: var(--ivory);
  color: var(--espresso);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}

.skip-link:focus-visible {
  transform: none;
  outline-color: var(--espresso);
}

.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}

/* Inner pages: one centred measure for all content, so wide screens keep
   even margins either side instead of spreading content to the edges */
.container--narrow {
  width: min(100% - 2 * var(--gutter), 70rem);
}


/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: 0.625rem 1.25rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background-color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.btn:active {
  transform: translateY(1px);
}

.btn--large {
  min-height: 3.25rem;
  padding: 0.875rem 1.75rem;
}

/* On dark backgrounds */
.btn--primary {
  background: var(--ivory);
  color: var(--espresso);
}

.btn--secondary {
  background: transparent;
  border-color: var(--stone);
  color: var(--ivory);
}

/* Hover only where there is a real pointer, so a tap on a phone does not
   leave the hover colour stuck on */
@media (hover: hover) {
  .btn--primary:hover {
    background: var(--nude);
  }

  .btn--secondary:hover {
    background: var(--ivory);
    border-color: var(--ivory);
    color: var(--espresso);
  }
}

.btn--primary:active {
  background: var(--stone);
}

.btn--secondary:active {
  background: var(--stone);
  border-color: var(--stone);
  color: var(--espresso);
}

/* On light backgrounds */
.btn--dark {
  background: var(--espresso);
  border-color: var(--espresso);
  color: var(--ivory);
}

@media (hover: hover) {
  .btn--dark:hover {
    background: transparent;
    color: var(--espresso);
  }
}

.btn--dark:active {
  background: var(--stone);
  border-color: var(--stone);
  color: var(--espresso);
}


/* --------------------------------------------------------------------------
   Header

   Stays visible for the first part of the page, hides when scrolling down
   past that point, and comes back on any scroll up (main.js adds and
   removes .is-hidden). The transform only exists while hidden: a transform
   on the header would otherwise become the containing block for the fixed
   mobile menu panel and collapse it.
   -------------------------------------------------------------------------- */

.site-header {
  --focus-color: var(--nude);
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--espresso);
  color: var(--ivory);
  /* A shadow rather than a border, so the header is exactly --header-h tall
     and the hero's height calculation lands on the fold to the pixel */
  box-shadow: 0 1px 0 var(--color-line-dark);
  transition: transform 300ms var(--ease);
}

.site-header.is-hidden {
  transform: translateY(-100%);
}

.site-header__inner {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-s);
  height: var(--header-h);
}

.site-header__logo {
  display: inline-flex;
  margin-right: auto;
  padding-block: var(--space-2xs);
  color: var(--ivory);
  text-decoration: none;
  transition: opacity var(--dur) var(--ease);
}

.site-header__logo:hover {
  opacity: 0.8;
}

/* The logo SVG is a black wordmark. Using it as a mask lets it take any
   colour from currentColor without a second file. */
.logo {
  display: block;
  width: clamp(8.5rem, 7rem + 5vw, 12rem);
  aspect-ratio: 815 / 197;
  background-color: currentColor;
  -webkit-mask: url("/assets/icons/logo.svg") center / contain no-repeat;
  mask: url("/assets/icons/logo.svg") center / contain no-repeat;
}

.site-header__book {
  flex-shrink: 0;
}

/* Small phones (360px and below). Logo, Book and the toggle only just fit
   at 360 with the default sizes and overflow at 320, so everything
   tightens slightly. */
@media (max-width: 23.75em) {
  .site-header__inner {
    gap: var(--space-xs);
  }

  /* The logo gives way first if the row is still too tight, rather than
     pushing the menu toggle off the edge of the screen */
  .site-header__logo {
    flex: 0 1 7rem;
    min-width: 0;
  }

  .logo {
    width: 100%;
  }

  .site-header__book {
    padding-inline: 0.875rem;
    letter-spacing: 0.04em;
  }
}


/* Mobile nav toggle */

.nav-toggle {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  margin-right: calc(var(--space-2xs) * -1);
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--radius);
  color: var(--ivory);
  cursor: pointer;
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 1.375rem;
  height: 1.5px;
  background: currentColor;
  transition:
    transform var(--dur) var(--ease),
    background-color var(--dur) var(--ease);
}

.nav-toggle__bars {
  position: relative;
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-toggle__bars::before {
  top: -7px;
}

.nav-toggle__bars::after {
  top: 7px;
}

@media (hover: hover) {
  .nav-toggle:hover .nav-toggle__bars,
  .nav-toggle:hover .nav-toggle__bars::before,
  .nav-toggle:hover .nav-toggle__bars::after {
    background-color: var(--nude);
  }
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars {
  background-color: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  transform: translateY(-7px) rotate(-45deg);
}


/* Mobile nav panel */

.site-nav__panel {
  position: fixed;
  top: var(--header-h);
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  padding: var(--space-m) var(--gutter) var(--space-2xl);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--espresso);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-0.5rem);
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease),
    visibility 0s linear var(--dur);
}

.site-header.is-open .site-nav__panel {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

.site-nav__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav__item {
  border-bottom: 1px solid var(--color-line-dark);
}

/* Shared by links and dropdown triggers */
.site-nav__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2xs);
  width: 100%;
  padding: var(--space-xs) 0;
  background: none;
  border: 0;
  color: var(--ivory);
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.2;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--dur) var(--ease);
}

.site-nav__link:hover,
.site-nav__link[aria-current="page"],
.site-nav__trigger.is-current,
.site-nav__trigger[aria-expanded="true"] {
  color: var(--nude);
}

.site-nav__chevron {
  flex-shrink: 0;
  width: 0.875rem;
  height: auto;
  transition: transform var(--dur) var(--ease);
}

.site-nav__trigger[aria-expanded="true"] .site-nav__chevron {
  transform: rotate(180deg);
}


/* Dropdowns. Visibility is driven only by aria-expanded on the trigger,
   so the announced state and what is on screen cannot disagree. On mobile
   they open as accordions inside the menu. */

.site-nav__sub {
  display: none;
  padding-bottom: var(--space-m);
}

.site-nav__trigger[aria-expanded="true"] + .site-nav__sub {
  display: block;
}

.site-nav__sub-title,
.site-nav__sub-text {
  display: none;
}

.site-nav__sub-group {
  margin-top: var(--space-s);
}

.site-nav__sub-heading {
  margin-bottom: var(--space-3xs);
  color: var(--nude);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.site-nav__sub-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav__sub-link {
  display: block;
  padding-block: 0.5625rem;
  color: var(--stone);
  font-size: var(--step-1);
  line-height: 1.4;
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.site-nav__sub-link:hover,
.site-nav__sub-link[aria-current="page"] {
  color: var(--ivory);
}

.site-nav__sub-link--all {
  color: var(--ivory);
  text-decoration: underline;
  text-decoration-color: var(--nude);
  text-underline-offset: 0.25em;
}


/* Phone and clinic days, mobile menu only */

.site-nav__extra {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.site-nav__extra-label {
  color: var(--stone);
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.site-nav__tel {
  align-self: flex-start;
  color: var(--ivory);
  font-size: var(--step-1);
  text-decoration: underline;
  text-decoration-color: var(--nude);
  text-underline-offset: 0.25em;
  transition: color var(--dur) var(--ease);
}

.site-nav__tel:hover {
  color: var(--nude);
}


/* Desktop nav */

@media (min-width: 64em) {
  .site-header__inner {
    gap: var(--space-l);
  }

  .nav-toggle {
    display: none;
  }

  .site-nav__panel {
    position: static;
    display: block;
    padding: 0;
    overflow: visible;
    background: none;
    visibility: visible;
    opacity: 1;
    transform: none;
    transition: none;
  }

  .site-nav__extra {
    display: none;
  }

  /* Items fill the header height so dropdowns open flush with its
     bottom edge, leaving no gap for the pointer to fall through. */
  .site-nav__list {
    display: flex;
    gap: clamp(1.25rem, 0.5rem + 1.2vw, 2.25rem);
    height: var(--header-h);
  }

  .site-nav__item {
    position: relative;
    display: flex;
    align-items: center;
    border-bottom: 0;
  }

  /* The treatments panel spans the header container, so it is positioned
     from .site-header__inner rather than from its own item */
  .site-nav__item--mega {
    position: static;
  }

  .site-nav__link {
    position: relative;
    justify-content: flex-start;
    gap: 0.375rem;
    width: auto;
    padding: var(--space-2xs) 0;
    color: var(--stone);
    font-family: var(--font-body);
    font-size: var(--step--1);
    letter-spacing: 0.02em;
  }

  .site-nav__link::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 0.125rem;
    left: 0;
    height: 1px;
    background: var(--nude);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur) var(--ease);
  }

  .site-nav__link:hover,
  .site-nav__link[aria-current="page"],
  .site-nav__trigger.is-current,
  .site-nav__trigger[aria-expanded="true"] {
    color: var(--ivory);
  }

  .site-nav__link:hover::after,
  .site-nav__link[aria-current="page"]::after,
  .site-nav__trigger.is-current::after,
  .site-nav__trigger[aria-expanded="true"]::after {
    transform: scaleX(1);
  }

  .site-nav__chevron {
    width: 0.625rem;
  }

  /* Dropdown panels */
  .site-nav__sub {
    position: absolute;
    top: 100%;
    z-index: 10;
    padding: var(--space-m) var(--space-l);
    background: var(--espresso);
    border: 1px solid var(--color-line-dark);
    border-top: 0;
    box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.28);
  }

  /* Training: a simple list under its trigger */
  .site-nav__sub:not(.site-nav__sub--mega) {
    left: calc(var(--space-l) * -1);
    min-width: 17rem;
  }

  .site-nav__sub-link {
    padding-block: 0.4375rem;
    font-size: var(--step-0);
  }

  /* Treatments: full container width. Three columns at laptop widths with
     the intro as a strip across the top; four columns from 80em with the
     intro as the first column. Narrowest column at 1024 is about 265px,
     wide enough for "Beauty spots and freckles" on one line. */
  .site-nav__sub--mega {
    right: 0;
    left: 0;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-m) var(--space-xl);
    padding: var(--space-xl);
  }

  .site-nav__trigger[aria-expanded="true"] + .site-nav__sub--mega {
    display: grid;
  }

  .site-nav__sub-intro {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2xs) var(--space-l);
    padding-bottom: var(--space-m);
    border-bottom: 1px solid var(--color-line-dark);
  }

  .site-nav__sub-title {
    display: block;
    color: var(--ivory);
    font-family: var(--font-display);
    font-size: var(--step-2);
    line-height: 1.1;
  }

  .site-nav__sub-text {
    display: block;
    flex: 1 1 18rem;
    color: var(--stone);
    font-size: var(--step--1);
  }

  .site-nav__sub-intro .site-nav__sub-link--all {
    padding-block: 0;
  }

  .site-nav__sub-group {
    margin-top: 0;
  }

  .site-nav__sub-heading {
    margin-bottom: var(--space-2xs);
  }
}

@media (min-width: 80em) {
  .site-nav__sub--mega {
    grid-template-columns: 1.2fr repeat(3, minmax(0, 1fr));
  }

  .site-nav__sub-intro {
    grid-column: auto;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-s);
    padding-bottom: 0;
    padding-right: var(--space-xl);
    border-bottom: 0;
    border-right: 1px solid var(--color-line-dark);
  }

  .site-nav__sub-text {
    flex: 0 0 auto;
  }
}


/* --------------------------------------------------------------------------
   Hero - full bleed

   Three crops of the same working shot, chosen by screen shape in the
   picture element: 16:9 for screens 16:10 and wider, 4:3 for other
   landscape screens (landscape tablets, squarer laptops), 3:4 for portrait
   screens (phones, portrait tablets).

   Mobile and portrait tablet (below 64em): the photo fills the hero and the
   text is centred vertically. The overlay covers the whole photo, darkest
   at the top and lighter towards the bottom. It never drops below 65%
   espresso, so the text keeps at least 4.5:1 contrast even over the
   lightest skin tones in the shot.

   Desktop: the photo fills the hero. A scrim runs from the left, solid
   behind the text column and fading out before the centre of the image.
   The solid zone is measured from the container edge, so it tracks the
   text at every width.
   -------------------------------------------------------------------------- */

.hero {
  --focus-color: var(--nude);
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: calc(100vh - var(--header-h));
  padding-block: var(--space-xl);
  overflow: hidden;
  background: var(--espresso);
  color: var(--ivory);
}

@supports (height: 1svh) {
  .hero {
    min-height: calc(100svh - var(--header-h));
  }
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.hero__media picture,
.hero__media img {
  display: block;
  width: 100%;
  height: 100%;
}

/* Anchored to the top so any crop comes off the bottom of the image,
   keeping Alex's head in frame */
.hero__media img {
  object-fit: cover;
  object-position: 50% 0%;
}

/* Dark at the top, lighter towards the bottom */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(41, 36, 33, 0.92) 0,
    rgba(41, 36, 33, 0.65) 100%
  );
}

.hero__content {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--nude);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.hero__eyebrow::before {
  content: "";
  flex-shrink: 0;
  width: 2rem;
  height: 1px;
  background: currentColor;
}

/* Same treatment as the section headings: one colour, broken into lines,
   the second indented */
.hero__title {
  font-size: var(--step-5);
  line-height: 0.95;
  letter-spacing: -0.02em;
}

.hero__title span {
  display: block;
}

.hero__title .indent {
  padding-left: 0.9em;
}

.hero__lead {
  max-width: 34rem;
  color: var(--stone);
  font-size: var(--step-1);
  line-height: 1.55;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin-top: var(--space-2xs);
}

.hero__actions .btn {
  flex: 1 1 auto;
}

.hero__trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-l);
  max-width: 34rem;
  margin: var(--space-2xs) 0 0;
  padding: var(--space-s) 0 0;
  border-top: 1px solid var(--color-line-dark);
  color: var(--stone);
  font-size: var(--step--1);
  list-style: none;
}

.hero__trust-item {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}

.hero__stars {
  flex-shrink: 0;
  width: 5rem;
  height: 1rem;
  fill: var(--nude);
}

.hero__trust-item--award::before {
  content: "";
  flex-shrink: 0;
  width: 0.4rem;
  height: 0.4rem;
  margin-inline: 0.3rem;
  background: var(--nude);
  transform: rotate(45deg);
}

/* Phones: trim so the text leaves room for the photo. The header already
   carries a Book button and the nav reaches every treatment, so the lead
   and the secondary button are the least costly things to drop here. */
@media (max-width: 39.99em) {
  .hero__lead,
  .hero__actions .btn--secondary {
    display: none;
  }
}

@media (min-width: 40em) {
  .hero {
    padding-block: var(--space-2xl);
  }

  .hero__content {
    gap: var(--space-m);
  }

  .hero__actions .btn {
    flex: 0 0 auto;
  }

  .hero__trust {
    gap: var(--space-s) var(--space-l);
    margin-top: var(--space-xs);
    padding-top: var(--space-m);
  }
}

@media (min-width: 64em) {
  /* The hero fills the viewport below the header and no more. Padding,
     gaps and headline size all scale with viewport height, so the content
     fits inside that box on a 1920 x 1080 monitor and on a short laptop
     alike, instead of pushing the hero taller than the screen. */
  .hero {
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    min-height: clamp(32rem, calc(100vh - var(--header-h)), 60rem);
    padding-block: clamp(2rem, 6vh, 6rem);
  }

  @supports (height: 1svh) {
    .hero {
      min-height: clamp(32rem, calc(100svh - var(--header-h)), 60rem);
      padding-block: clamp(2rem, 6svh, 6rem);
    }
  }

  /* Desktop swaps the top-down overlay for a scrim from the left */
  .hero__media::after {
    background: linear-gradient(
      90deg,
      rgba(41, 36, 33, 0.92) 0,
      rgba(41, 36, 33, 0.88) calc(max(var(--gutter), (100% - var(--container)) / 2) + 38rem),
      rgba(41, 36, 33, 0) calc(max(var(--gutter), (100% - var(--container)) / 2) + 38rem + 20%)
    );
  }

  .hero__content {
    gap: clamp(0.75rem, 2.2vh, 1.5rem);
  }

  .hero__title {
    font-size: min(var(--step-5), 8vh);
  }

  @supports (height: 1svh) {
    .hero__title {
      font-size: min(var(--step-5), 8svh);
    }
  }

  /* Wide enough for both trust items on one line */
  .hero__trust {
    max-width: 40rem;
  }
}


/* --------------------------------------------------------------------------
   Sections

   Background rotation for the home page, top to bottom. No two neighbours
   share a colour, including the last section against the footer.

     Hero         espresso
     Treatments   ivory
     Our work     espresso
     Meet Alex    soft white
     Reviews      stone
     Training     espresso
     FAQs         ivory
     Visit        stone
     Footer       espresso
   -------------------------------------------------------------------------- */

.section {
  padding-block: var(--section-pad);
}

.section--ivory {
  background: var(--ivory);
  color: var(--espresso);
}

.section--soft-white {
  background: var(--soft-white);
  color: var(--espresso);
}

.section--stone {
  background: var(--stone);
  color: var(--espresso);
}

.section--espresso {
  --focus-color: var(--nude);
  background: var(--espresso);
  color: var(--ivory);
}


/* Section headings - oversized statement

   The heading is set large with tight leading, broken across lines by the
   spans in the markup, with the second line indented. The short intro and
   any section link sit beside it on desktop, aligned to its last line, so
   the heading adds as little height to the section as possible. On phones
   they sit beneath it.

   Two sizes: full width (.display-title) for headings that span the
   container, and column (.display-title--col) for headings that sit in one
   half of a split layout. --col-size is shared so the intro and Alex's role
   line can line up with the indent.
   -------------------------------------------------------------------------- */

:root {
  --display-size: clamp(2.25rem, 1.6rem + 2vw, 3.75rem);
  --col-size: clamp(2rem, 1.4rem + 1.7vw, 3.25rem);
}

.display-head {
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}

.display-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-size);
  line-height: 0.88;
  letter-spacing: -0.02em;
}

.display-title span {
  display: block;
}

.display-title .indent {
  padding-left: 0.9em;
}

.display-title--col {
  font-size: var(--col-size);
}

.display-aside {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
  max-width: 22rem;
  margin-top: var(--space-m);
}

.display-lead {
  max-width: 22rem;
  font-size: clamp(0.9375rem, 0.9rem + 0.15vw, 1.0625rem);
  line-height: 1.6;
}

/* In a column, the intro lines up with the indented line of the heading */
.display-lead--col {
  max-width: 26rem;
  padding-left: calc(var(--col-size) * 0.9);
}

.section--espresso .display-lead {
  color: var(--stone);
}

@media (max-width: 39.99em) {
  .display-lead--col {
    padding-left: 0;
  }
}

/* Heading left, intro and link right, sharing a baseline */
@media (min-width: 48em) {
  .display-head:has(.display-aside) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
    align-items: end;
    column-gap: clamp(2rem, 6vw, 8rem);
  }

  .display-head:has(.display-aside) .display-aside {
    margin: 0 0 0.35em;
  }
}


/* --------------------------------------------------------------------------
   Page hero - inner pages

   A compact espresso title band inside the narrow centred measure:
   breadcrumbs over a hairline, then the heading and the intro with Book.
   From 64em they split the width into two equal halves, each centred
   vertically between the hairline and the end of the band.
   -------------------------------------------------------------------------- */

:root {
  --page-title-size: clamp(2.75rem, 1.5rem + 4vw, 5.5rem);
}

.page-hero {
  --focus-color: var(--nude);
  padding-block: var(--space-l) var(--space-2xl);
  background: var(--espresso);
  color: var(--ivory);
}

.page-hero__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}

.page-hero .breadcrumbs {
  padding-bottom: var(--space-m);
  border-bottom: 1px solid var(--color-line-dark);
}

.page-hero__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}

.page-hero__title {
  font-size: var(--page-title-size);
  line-height: 0.9;
  letter-spacing: -0.02em;
}

.page-hero__title span {
  display: block;
}

.page-hero__title .indent {
  padding-left: 0.9em;
}

.page-hero__aside {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
  max-width: 30rem;
}

.page-hero__lead {
  color: var(--stone);
  font-size: var(--step-0);
  line-height: 1.6;
}

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

@media (min-width: 64em) {
  .page-hero {
    padding-block: var(--space-xl) clamp(3.5rem, 7vh, 5rem);
  }

  /* The same space above the heading (from the hairline) as below it (to
     the end of the band), with the heading and intro each centred in the
     row between, so the title sits in the middle of that space */
  .page-hero__content {
    gap: var(--space-2xl);
  }

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


/* --------------------------------------------------------------------------
   Inner section heading

   Section headings on inner pages sit centred above their content, a size
   below the page title, with the intro and any link centred beneath. The
   home page keeps its oversized statement headings.
   -------------------------------------------------------------------------- */

.inner-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-m);
  max-width: 40rem;
  margin: 0 auto var(--space-2xl);
  text-align: center;
}

.inner-head__title {
  font-size: clamp(2.25rem, 1.5rem + 2.4vw, 3.75rem);
  line-height: 1;
  letter-spacing: -0.015em;
}

.inner-head__lead {
  max-width: 34rem;
  line-height: 1.7;
}

.section--espresso .inner-head__lead {
  color: var(--stone);
}

@media (min-width: 64em) {
  .inner-head {
    margin-bottom: var(--space-3xl);
  }
}


/* Breadcrumbs */

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-s);
  margin: 0;
  padding: 0;
  font-size: var(--step--1);
  list-style: none;
}

.breadcrumbs li {
  display: flex;
  align-items: center;
  gap: var(--space-s);
}

/* Drawn divider, so there is no separator character to announce */
.breadcrumbs li + li::before {
  content: "";
  width: 1px;
  height: 0.85em;
  background: var(--nude);
  transform: rotate(20deg);
}

.breadcrumbs a {
  color: var(--stone);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.25em;
  transition:
    color var(--dur) var(--ease),
    text-decoration-color var(--dur) var(--ease);
}

@media (hover: hover) {
  .breadcrumbs a:hover {
    color: var(--ivory);
    text-decoration-color: var(--nude);
  }
}

.breadcrumbs [aria-current="page"] {
  color: var(--ivory);
}

/* --------------------------------------------------------------------------
   Treatment styles - ivory

   An index of the six styles rather than a stack of cards. Each style is a
   numbered row with its name set large; opening a row reveals the
   description and "best for", and only one is open at a time (main.js).

   Phones and tablets: each row carries its own photo, shown when the row
   is open. From 64em the photos move into one tall frame on the left that
   stays in view while the list is read, and changes to the open style.
   Without JS every row shows open.
   -------------------------------------------------------------------------- */

.sx {
  --sx-muted: #7a6a60;
  --sx-rule: rgba(41, 36, 33, 0.18);
}

.sx__stage {
  display: none;
}

.sx__list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--sx-rule);
}

.sx__item {
  border-top: 1px solid var(--sx-rule);
}

.sx__head {
  margin: 0;
  font: inherit;
}

.sx__trigger {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr) 1.25rem;
  align-items: baseline;
  gap: var(--space-s);
  width: 100%;
  padding: var(--space-m) 0;
  background: none;
  border: 0;
  color: var(--espresso);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.sx__num {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--sx-muted);
  font-variant-numeric: tabular-nums;
}

.sx__name {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.3rem + 1.5vw, 2.75rem);
  line-height: 1.05;
  letter-spacing: -0.01em;
  transition:
    color var(--dur) var(--ease),
    transform 500ms var(--ease);
}

/* Plus that turns into a minus, matching the FAQs */
.sx__icon {
  position: relative;
  align-self: center;
  width: 1rem;
  height: 1rem;
}

.sx__icon::before,
.sx__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transition: transform 300ms var(--ease);
}

.sx__icon::after {
  transform: rotate(90deg);
}

.sx__trigger[aria-expanded="true"] .sx__icon::after {
  transform: rotate(0deg);
}

.sx__trigger:focus-visible {
  outline-offset: 4px;
}

/* Space below the words sits on the last child, not the wrapper, so a
   closed row folds right down to its name */
.sx__panel-inner {
  display: grid;
  gap: var(--space-s);
  padding-left: calc(2.75rem + var(--space-s));
}

.sx__panel-inner > :last-child {
  margin-bottom: var(--space-l);
}

.sx__media {
  margin: 0 0 var(--space-2xs);
}

.sx__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  background: var(--stone);
}

.sx__caption {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--sx-muted);
}

.sx__text,
.sx__best {
  text-wrap: pretty;
}

.sx__text {
  max-width: 34rem;
  line-height: 1.7;
}

.sx__best {
  max-width: 34rem;
  font-size: var(--step--1);
  line-height: 1.6;
}

.sx__best span {
  display: block;
  margin-bottom: var(--space-3xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}


/* Enhanced: closed rows fold away and names of closed rows are muted */

.sx.is-enhanced .sx__panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition:
    grid-template-rows 600ms var(--ease),
    visibility 0s linear 600ms;
}

.sx.is-enhanced .sx__panel-inner {
  min-height: 0;
  overflow: hidden;
}

.sx.is-enhanced .sx__item.is-open .sx__panel {
  grid-template-rows: 1fr;
  visibility: visible;
  transition-delay: 0s;
}

.sx.is-enhanced .sx__trigger[aria-expanded="false"] .sx__name {
  color: var(--sx-muted);
}

.sx.is-enhanced .sx__trigger[aria-expanded="true"] .sx__name {
  font-style: italic;
}

@media (hover: hover) {
  .sx.is-enhanced .sx__trigger:hover .sx__name {
    color: var(--espresso);
    transform: translateX(0.25rem);
  }
}


/* Phones: the photo and the words both run the full width of the list,
   level with the number, so the open row isn't boxed in on both sides */
@media (max-width: 47.99em) {
  .sx__panel-inner {
    padding-left: 0;
  }
}


/* Tablets: text beside the photo inside each open row */
@media (min-width: 48em) and (max-width: 63.99em) {
  .sx__panel-inner {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    grid-template-rows: auto 1fr;
    column-gap: var(--space-l);
    align-items: start;
  }

  .sx__media {
    grid-row: span 2;
    margin: 0 0 var(--space-l);
  }

  .sx__media img {
    aspect-ratio: 1;
  }
}


/* Desktop: one tall photo frame on the left, the index on the right */
@media (min-width: 64em) {
  .sx {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: start;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .sx__stage {
    position: sticky;
    top: calc(var(--header-h) + var(--space-l));
    display: grid;
  }

  .sx__frame {
    grid-area: 1 / 1;
    margin: 0;
    opacity: 0;
    visibility: hidden;
    transition:
      opacity 700ms var(--ease),
      visibility 0s linear 700ms;
  }

  .sx__photo {
    overflow: hidden;
    background: var(--stone);
    aspect-ratio: 4 / 5;
  }

  /* Caption on the right of the line beneath the photo, the count on the
     left */
  .sx__frame-caption {
    margin-top: var(--space-s);
    padding-left: 6rem;
    font-size: var(--step--1);
    color: var(--sx-muted);
    text-align: right;
  }

  .sx__frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--pos, 50% 50%);
    transform: scale(1.04);
    transition: transform 1400ms var(--ease);
  }

  .sx__frame.is-active {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
  }

  .sx__frame.is-active img {
    transform: none;
  }

  .sx__count {
    position: absolute;
    bottom: 0;
    left: 0;
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: 0.12em;
    color: var(--sx-muted);
    font-variant-numeric: tabular-nums;
  }

  .sx__count span {
    color: var(--espresso);
  }

  /* The photo lives in the frame, so the row keeps only its words */
  .sx__media {
    display: none;
  }

  .sx__trigger {
    padding: var(--space-m) 0;
  }
}

/* The index also runs on stone, where the muted tone needs to be darker */
.section--stone .sx {
  --sx-muted: #574c45;
  --sx-rule: rgba(41, 36, 33, 0.22);
}

/* Words-only index, for pages without photos: one centred column at the
   same measure as the FAQs */
.sx--text {
  max-width: 50rem;
  margin-inline: auto;
}

@media (min-width: 64em) {
  .sx.sx--text {
    display: block;
  }
}

/* Without JS every row is open, so the frame has nothing to follow */
@media (min-width: 64em) {
  .sx:not(.is-enhanced) {
    display: block;
  }

  .sx:not(.is-enhanced) .sx__stage {
    display: none;
  }

  .sx:not(.is-enhanced) .sx__media {
    display: block;
    max-width: 28rem;
  }
}


/* --------------------------------------------------------------------------
   Treatment results - espresso

   Reuses the editorial gallery and lightbox from the home page, inside the
   narrow measure, with an Instagram link centred beneath.
   -------------------------------------------------------------------------- */

.treatment-results__more {
  display: flex;
  justify-content: center;
  margin-top: var(--space-xl);
}


/* --------------------------------------------------------------------------
   Spread - any background

   A heading on the left and a column of text on the right, with an optional
   photo. Used for the sections that explain a treatment in prose: the
   bespoke appointment, correction work, microblading, gender affirming
   brows. Stacks on phones and tablets.
   -------------------------------------------------------------------------- */

.spread {
  --spread-muted: #7a6a60;
  --spread-rule: rgba(41, 36, 33, 0.18);
}

.section--stone.spread,
.section--stone .spread {
  --spread-muted: #574c45;
  --spread-rule: rgba(41, 36, 33, 0.22);
}

.section--espresso.spread,
.section--espresso .spread {
  --spread-muted: var(--stone);
  --spread-rule: var(--color-line-dark);
}

.spread__inner {
  display: grid;
  gap: var(--space-xl);
}

.spread__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.spread__kicker {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--spread-muted);
}

.section--espresso .spread__kicker {
  color: var(--nude);
}

.spread__title {
  font-size: clamp(2.25rem, 1.4rem + 2.8vw, 4rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
}

.spread__title span {
  display: block;
}

.spread__title .indent {
  padding-left: 0.9em;
}

.spread__media {
  width: 100%;
  max-width: 24rem;
  margin: 0;
}

.spread__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  background: var(--stone);
}

.spread__media--video {
  max-width: 18rem;
}

.spread__caption {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--spread-muted);
}

.spread__body {
  display: grid;
  gap: var(--space-s);
  max-width: 38rem;
}

.spread__body p,
.spread__body li {
  line-height: 1.75;
}

.section--espresso .spread__body p,
.section--espresso .spread__body li {
  color: var(--stone);
}

.spread__body a:not(.btn):not(.text-link) {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--cocoa);
  text-underline-offset: 0.2em;
}

.section--espresso .spread__body a:not(.btn):not(.text-link) {
  color: var(--ivory);
  text-decoration-color: var(--nude);
}

.spread__list {
  display: grid;
  gap: var(--space-2xs);
  margin: var(--space-2xs) 0 0;
  padding-left: 1.25rem;
}

.spread__list li::marker {
  color: var(--nude);
}

.spread__foot {
  margin-top: var(--space-s);
}


/* --------------------------------------------------------------------------
   Prices - any background

   One row per option: what it is on the left, the price on the right, on a
   fine rule. A note underneath points at the booking page for the latest.
   -------------------------------------------------------------------------- */

.prices {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--spread-rule, rgba(41, 36, 33, 0.18));
}

.prices__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--space-m);
  padding-block: var(--space-s);
  border-bottom: 1px solid var(--spread-rule, rgba(41, 36, 33, 0.18));
}

.prices__name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.2;
}

.prices__note {
  grid-column: 1;
  margin-top: var(--space-3xs);
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--spread-muted, #7a6a60);
}

.prices__value {
  grid-column: 2;
  grid-row: 1;
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.2;
  white-space: nowrap;
}

.prices__foot {
  margin-top: var(--space-m);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--spread-muted, #7a6a60);
}

/* Group headings for a long list split into sections, such as the laser
   hair removal prices. Styled like the spread kicker. */
.prices__group {
  margin-top: var(--space-l);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--spread-muted, #7a6a60);
}

.section--espresso .prices__group {
  color: var(--nude);
}

/* A serif subheading inside a spread body, for pages that group labelled
   lists under a larger heading, such as the SPMU masterclass days */
.spread__sub {
  margin-top: var(--space-l);
  font-size: var(--step-2);
  line-height: 1.15;
}

.spread__sub + .prices__group {
  margin-top: var(--space-s);
}

/* The course price sits on its own line under the description, so every
   row reads the same way and the price never splits across lines */
.prices__course {
  display: block;
  white-space: nowrap;
}

/* A note on that line rather than a price, such as the laser hair removal
   underarm add-on, may wrap on a narrow phone */
.prices__course--text {
  white-space: normal;
}

/* Photo spreads: heading, photo, then text, with the same small gap
   between heading and photo as inside the heading */
.spread--centred .spread__inner {
  row-gap: var(--space-m);
}

.spread--centred .spread__body {
  margin-top: var(--space-m);
}

@media (min-width: 64em) {
  .spread__inner {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    align-items: start;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  /* The head column is 4fr of the narrow container, so a title sized from
     the viewport can outgrow it. Each line stays on one line, so the title
     is sized from its own column instead. Each title carries --fit, worked
     out from its own longest line (with the indent) so it fills the column
     without running past it: short titles come out larger, long ones
     smaller. Capped at the old 4rem. Titles without --fit use 11.4, which
     suits the longest line on the site ("One appointment,"). When a title's
     wording changes, its --fit needs recalculating */
  .spread__head {
    container-type: inline-size;
  }

  /* The heading only follows you down the page where the text beside it
     is much longer than the heading, such as a long price list. Short
     sections stay still */
  .spread--sticky .spread__head {
    position: sticky;
    top: calc(var(--header-h) + var(--space-l));
  }

  .spread__title {
    font-size: min(4rem, calc(var(--fit, 11.4) * 1cqi));
  }

  .spread__title span {
    white-space: nowrap;
  }

  /* For a spread with a photo under the heading and shorter text beside
     it. The photo sits outside .spread__head in the markup, so the text
     can share its row and line up with it, centred, rather than starting
     level with the kicker */
  .spread--centred .spread__inner {
    grid-template-rows: auto auto;
  }

  .spread--centred .spread__head {
    grid-column: 1;
    grid-row: 1;
  }

  .spread--centred .spread__media {
    grid-column: 1;
    grid-row: 2;
  }

  .spread--centred .spread__body {
    grid-column: 2;
    grid-row: 2;
    align-self: center;
    margin-top: 0;
  }
}


/* --------------------------------------------------------------------------
   Treatment notes - espresso

   Stands in for the results gallery on pages with too few photos, so the
   dark band between the ivory sections stays. Three numbered points, each
   under a fine rule: stacked on phones, side by side from 48em.
   -------------------------------------------------------------------------- */

.notes {
  display: grid;
  gap: var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

.notes__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-line-dark);
}

.notes__num {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--nude);
  font-variant-numeric: tabular-nums;
}

.notes__name {
  font-size: var(--step-3);
  line-height: 1.05;
}

.notes__text {
  max-width: 34rem;
  margin-top: var(--space-2xs);
  color: var(--stone);
  line-height: 1.7;
}

@media (min-width: 48em) {
  .notes {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--space-l);
  }
}

@media (min-width: 64em) {
  .notes {
    column-gap: var(--space-xl);
  }
}


/* --------------------------------------------------------------------------
   Treatments hub - ivory, espresso, ivory

   Three groups, each with its heading on the left and an index of its
   treatments on the right (stacked on phones and tablets). Every row is one
   link: a small portrait photo, the name set large, a one-line summary and
   an arrow. The heading stays in view while its list is read on desktop.
   -------------------------------------------------------------------------- */

.hub-group {
  --hub-muted: #7a6a60;
  --hub-rule: rgba(41, 36, 33, 0.18);
}

.hub-group.section--espresso {
  --hub-muted: var(--stone);
  --hub-rule: var(--color-line-dark);
}

.hub-group__inner {
  display: grid;
  gap: var(--space-xl);
}

.hub-group__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-s);
  max-width: 30rem;
}

.hub-group__num {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--hub-muted);
  font-variant-numeric: tabular-nums;
}

.section--espresso .hub-group__num {
  color: var(--nude);
}

.hub-group__title {
  font-size: clamp(2.25rem, 1.5rem + 2.4vw, 3.75rem);
  line-height: 1;
  letter-spacing: -0.015em;
}

.hub-group__lead {
  line-height: 1.7;
  text-wrap: pretty;
}

.section--espresso .hub-group__lead {
  color: var(--stone);
}

.t-list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--hub-rule);
}

.t-item {
  border-bottom: 1px solid var(--hub-rule);
}

.t-item__link {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-m);
  padding-block: var(--space-s);
  color: inherit;
  text-decoration: none;
}

.t-item__link:focus-visible {
  outline-offset: 4px;
}

.t-item__media {
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--stone);
}

.section--espresso .t-item__media {
  background: #3a332f;
}

.t-item__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  transition: transform 900ms var(--ease);
}

.t-item__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  min-width: 0;
}

.t-item__name {
  font-size: clamp(1.375rem, 1.1rem + 1vw, 2.25rem);
  line-height: 1.1;
  transition: transform 500ms var(--ease);
}

.t-item__desc {
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--hub-muted);
}

.t-item__arrow svg {
  display: block;
  width: 1.5rem;
  height: auto;
  transition: transform 400ms var(--ease);
}

@media (hover: hover) {
  .t-item__link:hover .t-item__media img {
    transform: scale(1.06);
  }

  .t-item__link:hover .t-item__name {
    font-style: italic;
    transform: translateX(0.25rem);
  }

  .t-item__link:hover .t-item__arrow svg {
    transform: translateX(0.35rem);
  }
}

@media (min-width: 48em) {
  .t-item__link {
    grid-template-columns: 6.5rem minmax(0, 1fr) auto;
    gap: var(--space-l);
  }
}

@media (min-width: 64em) {
  .hub-group__inner {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    align-items: start;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .hub-group__head {
    position: sticky;
    top: calc(var(--header-h) + var(--space-l));
  }
}


/* --------------------------------------------------------------------------
   About page

   Title band (espresso) > story (ivory) > numbers (espresso) > approach
   (ivory) > award (stone) > studio (ivory) > reviews (stone) > training
   (espresso) > book band (stone) > footer (espresso).

   Each section pairs a photo with a split heading, alternating sides down
   the page, so it reads like a magazine profile rather than a stack of
   blocks. Everything stacks on phones and tablets.
   -------------------------------------------------------------------------- */

.about-kicker {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #7a6a60;
}

.section--stone .about-kicker {
  color: #574c45;
}

.about-kicker--light {
  color: var(--nude);
}

/* Split headings, set like the title band: two lines, the second indented */
.about-approach__title,
.about-award__title,
.about-studio__title,
.about-training__title {
  font-size: clamp(2.25rem, 1.4rem + 2.8vw, 4rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
}

.about-approach__title span,
.about-award__title span,
.about-studio__title span,
.about-training__title span {
  display: block;
}

.about-approach__title .indent,
.about-award__title .indent,
.about-studio__title .indent,
.about-training__title .indent {
  padding-left: 0.9em;
}

.about-story__caption,
.about-approach__caption,
.about-award__caption {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: #7a6a60;
}

.about-award__caption {
  color: #574c45;
}


/* Story */

.about-story__inner {
  display: grid;
  gap: var(--space-xl);
}

.about-story__media {
  width: 100%;
  max-width: 28rem;
  margin: 0;
}

.about-story__photo {
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--stone);
}

.about-story__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
}

.about-story__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.about-story__quote {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.2rem + 1.8vw, 3rem);
  font-style: italic;
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.about-story__text {
  display: grid;
  gap: var(--space-s);
  max-width: 36rem;
  line-height: 1.75;
}

.about-story__text a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--cocoa);
  text-underline-offset: 0.2em;
}

/* Specialisms on one line, separated by small nude dots */
.about-story__skills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-s);
  margin: var(--space-2xs) 0 0;
  padding: var(--space-s) 0 0;
  list-style: none;
  border-top: 1px solid rgba(41, 36, 33, 0.18);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.about-story__skills li {
  display: flex;
  align-items: center;
  gap: var(--space-s);
}

/* Phones: two neat columns, no separators */
@media (max-width: 47.99em) {
  .about-story__skills {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .about-story__skills li::after {
    display: none;
  }
}

.about-story__skills li:not(:last-child)::after {
  content: "";
  width: 0.3rem;
  height: 0.3rem;
  border-radius: 50%;
  background: var(--nude);
}


/* Numbers */

.about-stats__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-l) var(--space-m);
  margin: 0;
  padding: 0;
  list-style: none;
}

.about-stats__item {
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-line-dark);
}

.about-stats__value {
  font-family: var(--font-display);
  font-size: clamp(3rem, 2rem + 3.4vw, 5.5rem);
  line-height: 1;
  letter-spacing: -0.02em;
}

.about-stats__label {
  max-width: 14rem;
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--stone);
}


/* Approach */

.about-approach__inner {
  display: grid;
  gap: var(--space-xl);
}

.about-approach__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.about-approach__media {
  width: 100%;
  max-width: 22rem;
  margin: var(--space-s) 0 0;
}

.about-approach__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  background: var(--stone);
}

.about-approach__list {
  display: grid;
  gap: var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

.about-approach__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-top: var(--space-m);
  border-top: 1px solid rgba(41, 36, 33, 0.18);
}

.about-approach__num {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: #7a6a60;
  font-variant-numeric: tabular-nums;
}

.about-approach__name {
  font-size: var(--step-3);
  line-height: 1.05;
  text-wrap: balance;
}

.about-approach__text {
  max-width: 30rem;
  margin-top: var(--space-2xs);
  line-height: 1.7;
}


/* Award */

.about-award__inner {
  display: grid;
  gap: var(--space-xl);
}

.about-award__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.about-award__text {
  max-width: 32rem;
  line-height: 1.75;
}

.about-award__media {
  width: 100%;
  max-width: 24rem;
  margin: 0;
}

.about-award__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  background: var(--cocoa);
}


/* Studio: a large room photo with the entrance tucked over its corner */

.about-studio__inner {
  display: grid;
  gap: var(--space-xl);
}

.about-studio__media {
  position: relative;
  width: 100%;
  max-width: 34rem;
  padding-bottom: var(--space-2xl);
}

.about-studio__main,
.about-studio__inset {
  margin: 0;
}

.about-studio__main {
  width: 78%;
}

.about-studio__inset {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 42%;
  border: 0.5rem solid var(--ivory);
}

.about-studio__main img,
.about-studio__inset img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  background: var(--stone);
}

.about-studio__main img {
  aspect-ratio: 4 / 5;
}

.about-studio__inset img {
  aspect-ratio: 3 / 4;
}

.about-studio__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.about-studio__text {
  max-width: 32rem;
  line-height: 1.75;
}

.about-studio__hours {
  display: grid;
  gap: var(--space-2xs);
  width: 100%;
  max-width: 24rem;
  margin: 0;
  padding: var(--space-s) 0;
  border-block: 1px solid rgba(41, 36, 33, 0.18);
}

.about-studio__hours div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-s);
}

.about-studio__hours dt {
  font-weight: 600;
}

.about-studio__hours dd {
  margin: 0;
}


/* Training */

.about-training__inner {
  display: grid;
  gap: var(--space-xl);
}

.about-training__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.about-training__text {
  max-width: 32rem;
  color: var(--stone);
  line-height: 1.75;
}

.about-training__links {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--color-line-dark);
}

.about-training__links li {
  border-bottom: 1px solid var(--color-line-dark);
}

.about-training__links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block: var(--space-s);
  color: var(--ivory);
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.15;
  text-decoration: none;
}

.about-training__links a::after {
  content: "";
  flex: none;
  width: 1.5rem;
  height: 0.75rem;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cpath d='M0 6h22M17 1l5 5-5 5' fill='none' stroke='black' stroke-width='1.25'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cpath d='M0 6h22M17 1l5 5-5 5' fill='none' stroke='black' stroke-width='1.25'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 400ms var(--ease);
}

.about-training__links a:focus-visible {
  outline-offset: 4px;
}

@media (hover: hover) {
  .about-training__links a:hover {
    font-style: italic;
  }

  .about-training__links a:hover::after {
    transform: translateX(0.35rem);
  }
}


@media (min-width: 48em) {
  .about-stats__list {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .about-approach__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-l);
  }
}

@media (min-width: 64em) {
  .about-story__inner {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: center;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .about-approach__inner {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    align-items: start;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .about-approach__head {
    position: sticky;
    top: calc(var(--header-h) + var(--space-l));
  }

  .about-award__inner {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: center;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .about-award__media {
    justify-self: end;
  }

  .about-studio__inner {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    align-items: center;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .about-training__inner {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    align-items: center;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  /* Split headings stay on two lines */
  .about-approach__title span,
  .about-award__title span,
  .about-studio__title span,
  .about-training__title span {
    white-space: nowrap;
  }
}


/* --------------------------------------------------------------------------
   Contact page

   Title band (espresso) > ways to get in touch (ivory) > visit (espresso)
   > FAQs (ivory) > footer (espresso). No form: each way in is one large
   link row, WhatsApp opens with a message already started.
   -------------------------------------------------------------------------- */

.contact-title {
  font-size: clamp(2.25rem, 1.4rem + 2.8vw, 4rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
}

.contact-title span {
  display: block;
}

.contact-title .indent {
  padding-left: 0.9em;
}

.contact-ways__inner {
  display: grid;
  gap: var(--space-xl);
}

.contact-ways__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
  max-width: 30rem;
}

.contact-ways__lead {
  line-height: 1.7;
  text-wrap: pretty;
}

.c-list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid rgba(41, 36, 33, 0.18);
}

.c-item {
  border-bottom: 1px solid rgba(41, 36, 33, 0.18);
}

.c-item__link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-m);
  row-gap: var(--space-3xs);
  padding-block: var(--space-m);
  color: inherit;
  text-decoration: none;
}

.c-item__link:focus-visible {
  outline-offset: 4px;
}

.c-item__label {
  grid-column: 1;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #7a6a60;
}

/* Sized so the email address fits on one line at 320px */
.c-item__value {
  grid-column: 1;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem);
  line-height: 1.15;
  overflow-wrap: anywhere;
  transition: transform 500ms var(--ease);
}

.c-item__text {
  grid-column: 1;
  max-width: 32rem;
  font-size: var(--step--1);
  line-height: 1.5;
  color: #7a6a60;
}

.c-item__arrow {
  grid-column: 2;
  grid-row: 1 / span 3;
  align-self: center;
}

.c-item__arrow svg {
  display: block;
  width: 1.5rem;
  height: auto;
  transition: transform 400ms var(--ease);
}

@media (hover: hover) {
  .c-item__link:hover .c-item__value {
    font-style: italic;
    transform: translateX(0.25rem);
  }

  .c-item__link:hover .c-item__arrow svg {
    transform: translateX(0.35rem);
  }
}

.contact-visit__inner {
  display: grid;
  gap: var(--space-xl);
}

.contact-visit__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.contact-visit__address {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-style: normal;
  line-height: 1.3;
}

.contact-visit__text {
  max-width: 30rem;
  color: var(--stone);
  line-height: 1.7;
}

.contact-visit__hours {
  display: grid;
  gap: var(--space-2xs);
  width: 100%;
  max-width: 24rem;
  margin: 0;
  padding: var(--space-s) 0;
  border-block: 1px solid var(--color-line-dark);
}

.contact-visit__hours div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-s);
}

.contact-visit__hours dt {
  font-weight: 600;
}

.contact-visit__hours dd {
  margin: 0;
  color: var(--stone);
}

.contact-visit__media {
  margin: 0;
}

.contact-visit__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  background: #3a332f;
}

@media (min-width: 40em) and (max-width: 63.99em) {
  .contact-visit__media img {
    aspect-ratio: 4 / 3;
  }
}

@media (min-width: 64em) {
  .contact-ways__inner {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    align-items: start;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  /* Same fix as .spread__title: each line stays on one line, so the title
     is sized from its own column rather than the viewport. "However suits"
     is about 6em in DM Serif Display, so 15cqi leaves a margin */
  .contact-ways__head {
    position: sticky;
    top: calc(var(--header-h) + var(--space-l));
    container-type: inline-size;
  }

  .contact-ways__head .contact-title {
    font-size: min(4rem, 15cqi);
  }

  .contact-visit__inner {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: center;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .contact-title span {
    white-space: nowrap;
  }
}


/* --------------------------------------------------------------------------
   Legal pages - ivory

   Privacy policy and terms. A contents list stays in view on the left on
   desktop, with the text in a comfortable reading measure on the right.
   -------------------------------------------------------------------------- */

.legal__inner {
  display: grid;
  gap: var(--space-xl);
}

.legal__toc {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.legal__toc-list {
  display: grid;
  gap: var(--space-3xs);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: toc;
}

.legal__toc-list li {
  counter-increment: toc;
}

.legal__toc-list a {
  display: inline-flex;
  gap: var(--space-s);
  padding-block: var(--space-3xs);
  color: inherit;
  text-decoration: none;
  line-height: 1.4;
}

.legal__toc-list a::before {
  content: counter(toc, decimal-leading-zero);
  min-width: 1.5rem;
  color: #7a6a60;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.9;
  font-variant-numeric: tabular-nums;
}

@media (hover: hover) {
  .legal__toc-list a:hover {
    text-decoration: underline;
    text-decoration-color: var(--cocoa);
    text-underline-offset: 0.2em;
  }
}

.legal__updated {
  margin-top: var(--space-2xs);
  padding-top: var(--space-s);
  border-top: 1px solid rgba(41, 36, 33, 0.18);
  font-size: var(--step--1);
  color: #7a6a60;
}

.legal__body {
  display: grid;
  gap: var(--space-xl);
  max-width: 42rem;
}

.legal__section {
  display: grid;
  gap: var(--space-s);
  padding-top: var(--space-l);
  border-top: 1px solid rgba(41, 36, 33, 0.18);
  scroll-margin-top: var(--space-l);
}

.legal__section:first-child {
  padding-top: 0;
  border-top: 0;
}

.legal__title {
  margin-bottom: var(--space-3xs);
  font-size: var(--step-3);
  line-height: 1.1;
}

.legal__section p,
.legal__section li {
  line-height: 1.75;
}

.legal__section ul {
  display: grid;
  gap: var(--space-3xs);
  margin: 0;
  padding-left: 1.25rem;
}

.legal__section li::marker {
  color: var(--nude);
}

.legal__section a,
.text-link-inline {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--cocoa);
  text-underline-offset: 0.2em;
}

@media (min-width: 64em) {
  .legal__inner {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    align-items: start;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  .legal__toc {
    position: sticky;
    top: calc(var(--header-h) + var(--space-l));
  }
}


/* --------------------------------------------------------------------------
   Process timeline - ivory

   Five stages joined by a fine line, each labelled with when it happens.
   Phones and tablets: the line runs down the left with a dot at each stage.
   From 64em: one row across the page, the line running through the dots.
   -------------------------------------------------------------------------- */

.process {
  --dot: 0.75rem;
  --rail: rgba(41, 36, 33, 0.22);
  position: relative;
  display: grid;
  gap: var(--space-xl);
  margin: 0;
  padding: 0 0 0 calc(var(--dot) + var(--space-l));
  list-style: none;
}

/* The line */
.process::before {
  content: "";
  position: absolute;
  top: 0.4rem;
  bottom: 0.4rem;
  left: calc(var(--dot) / 2 - 0.5px);
  width: 1px;
  background: var(--rail);
}

.process__step {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

/* The dot for each stage */
.process__step::before {
  content: "";
  position: absolute;
  top: 0.3rem;
  left: calc((var(--dot) + var(--space-l)) * -1);
  width: var(--dot);
  height: var(--dot);
  border-radius: 50%;
  background: var(--nude);
  box-shadow: 0 0 0 0.375rem var(--ivory);
}

.process__when {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.process__name {
  font-size: var(--step-2);
  line-height: 1.1;
}

.process__text {
  max-width: 34rem;
  line-height: 1.7;
}

.process__text a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--cocoa);
  text-underline-offset: 0.2em;
}

.treatment-process__cta {
  display: flex;
  justify-content: center;
  margin-top: var(--space-2xl);
}

@media (min-width: 64em) {
  .process {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    column-gap: var(--space-l);
    padding: calc(var(--dot) + var(--space-m)) 0 0;
  }

  .process::before {
    top: calc(var(--dot) / 2 - 0.5px);
    right: 0;
    bottom: auto;
    left: 0;
    width: auto;
    height: 1px;
  }

  .process__step::before {
    top: calc((var(--dot) + var(--space-m)) * -1);
    left: 0;
  }

  .process__text {
    font-size: var(--step--1);
    line-height: 1.65;
  }
}

/* Small laptops: columns are at their narrowest, so the labels are tracked
   in slightly to keep each one on a single line */
@media (min-width: 64em) and (max-width: 79.99em) {
  .process__when {
    letter-spacing: 0.06em;
  }
}


/* --------------------------------------------------------------------------
   Treatments - image tiles

   Phones and tablets: a swipe row. Tall tiles nearly the width of the
   screen, the next one peeking in from the right, running edge to edge
   past the container gutter. Each tile shows its name, description and
   Discover, like an open desktop panel. A thin bar underneath tracks the
   scroll position (main.js).

   Desktop (hover devices from 64em): four tall panels side by side that
   behave like an accordion. The brow panel starts wide with its description
   showing; hovering or focusing another panel widens it and reveals its
   description while the rest narrow. Closed panels carry their name
   vertically. No JS.

   Each image's crop is set per tile with --pos in the markup.
   -------------------------------------------------------------------------- */

.treatments__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "head"
    "tiles"
    "progress";
}

.treatments__head {
  grid-area: head;
}


/* Swipe row */

.tiles {
  grid-area: tiles;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 80%;
  gap: var(--space-xs);
  margin: 0 calc(var(--gutter) * -1);
  padding: 0 var(--gutter);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  scrollbar-width: none;
  list-style: none;
}

.tiles::-webkit-scrollbar {
  display: none;
}

.tile {
  scroll-snap-align: start;
}

.tile__link {
  position: relative;
  isolation: isolate;
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--stone);
  color: var(--ivory);
  text-decoration: none;
}

.tile__img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  transition: transform 900ms var(--ease);
}

/* Shade at the foot of the photo so the text reads on any image */
.tile__link::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    0deg,
    rgba(41, 36, 33, 0.9) 0,
    rgba(41, 36, 33, 0.6) 32%,
    rgba(41, 36, 33, 0) 62%
  );
}

.tile__link:focus-visible {
  outline-offset: -4px;
  outline-color: var(--ivory);
}

.tile__body {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  padding: var(--space-m);
}

.tile__name {
  font-size: var(--step-3);
  line-height: 1.1;
}

.tile__desc {
  display: block;
  max-width: 22rem;
  padding-top: var(--space-xs);
  color: var(--stone);
  font-size: var(--step--1);
  line-height: 1.55;
}

.tile__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-s);
  color: var(--ivory);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.tile__cta svg {
  width: 1.5rem;
  height: auto;
}

/* Position bar. Hidden until main.js confirms it can drive it. */
.tiles-progress {
  grid-area: progress;
  position: relative;
  display: none;
  height: 1px;
  margin-top: var(--space-l);
  background: rgba(41, 36, 33, 0.16);
}

.tiles-progress.is-ready {
  display: block;
}

.tiles-progress__thumb {
  position: absolute;
  top: -1px;
  left: 0;
  width: var(--thumb, 25%);
  height: 3px;
  background: var(--espresso);
  transform: translateX(var(--offset, 0));
}

@media (min-width: 40em) {
  .tiles {
    grid-auto-columns: 44%;
    gap: var(--space-s);
  }

  .tile__body {
    padding: var(--space-l);
  }
}


/* Desktop: heading and More link share the top row; tiles become panels */

@media (min-width: 64em) {
  .tile__body {
    padding: var(--space-l);
  }

  .tiles {
    display: flex;
    gap: var(--space-xs);
    height: clamp(30rem, 72vh, 46rem);
    margin: 0;
    padding: 0;
    overflow: visible;
    scroll-snap-type: none;
  }

  .tile {
    flex: 1 1 0;
    min-width: 0;
    transition: flex-grow 700ms var(--ease);
  }

  .tile__link {
    height: 100%;
    aspect-ratio: auto;
  }

  .tiles-progress,
  .tiles-progress.is-ready {
    display: none;
  }

  .tile__desc {
    padding-top: var(--space-s);
  }
}

/* The accordion reveal only applies where panels open on hover */
@media (min-width: 64em) and (hover: hover) {
  /* Height-based reveal: animates from nothing to the content's own height */
  .tile__reveal {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition:
      grid-template-rows 600ms var(--ease),
      opacity 400ms var(--ease);
  }

  .tile__reveal-inner {
    min-height: 0;
    overflow: hidden;
  }
}

/* Touch screens at desktop width: four equal panels, names only */
@media (min-width: 64em) and (hover: none) {
  .tile__reveal {
    display: none;
  }

  .tile__name {
    font-size: var(--step-2);
  }
}

/* The accordion needs a pointer; touch screens at this width keep four
   equal panels with names only */
@media (min-width: 64em) and (hover: hover) {
  /* Open panel: the brow panel by default, or whichever is hovered or
     focused */
  .tiles:not(:hover):not(:focus-within) .tile:first-child,
  .tile:hover,
  .tile:focus-within {
    flex-grow: 2.4;
  }

  .tiles:not(:hover):not(:focus-within) .tile:first-child .tile__reveal,
  .tile:hover .tile__reveal,
  .tile:focus-within .tile__reveal {
    grid-template-rows: 1fr;
    opacity: 1;
  }

  .tile:hover .tile__img,
  .tile:focus-within .tile__img {
    transform: scale(1.04);
  }

  /* Closed panels carry their name vertically up the left edge, reading
     bottom to top, so it never wraps in a narrow column. The open panel
     sets it horizontally, fading in as it switches. */
  .tile__name {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    white-space: nowrap;
  }

  .tiles:not(:hover):not(:focus-within) .tile:first-child .tile__name,
  .tile:hover .tile__name,
  .tile:focus-within .tile__name {
    writing-mode: horizontal-tb;
    transform: none;
    white-space: normal;
    animation: tile-name-in 600ms var(--ease) both;
  }
}


@keyframes tile-name-in {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }

  to {
    opacity: 1;
    transform: none;
  }
}


/* Text link, shared */

.text-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  padding-block: var(--space-2xs);
  color: var(--espresso);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-decoration: none;
  text-transform: uppercase;
  border-bottom: 1px solid var(--espresso);
}

.text-link svg {
  width: 1.5rem;
  height: auto;
  transition: transform 400ms var(--ease);
}

.text-link--light {
  color: var(--ivory);
  border-bottom-color: var(--nude);
}

@media (hover: hover) {
  .text-link:hover svg {
    transform: translateX(0.375rem);
  }
}


/* --------------------------------------------------------------------------
   Our work - editorial gallery

   A mixed-size grid: one large feature, one tall, one wide and squares,
   packed with dense flow so there are no holes at either column count.
   Row height is tied to column width with container query units, so a
   single cell is always square and the square before-and-after composites
   are never cropped.

     Phones, 2 columns     From 40em, 4 columns
     F F                   F F T S
     F F                   F F T S
     T S                   S W W S
     T S
     S S
     W W

   Each item links to the full-size image, so it still works without JS;
   main.js opens it in the lightbox instead.
   -------------------------------------------------------------------------- */

.work__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "head"
    "gallery";
}

.work__head {
  grid-area: head;
}

.gallery-wrap {
  grid-area: gallery;
  container-type: inline-size;
}

.gallery {
  --cols: 2;
  --gap: var(--space-xs);
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  grid-auto-rows: calc((100cqi - (var(--cols) - 1) * var(--gap)) / var(--cols));
  grid-auto-flow: row dense;
  gap: var(--gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

.gallery__item--feature {
  grid-column: span 2;
  grid-row: span 2;
}

.gallery__item--tall {
  grid-row: span 2;
}

.gallery__item--wide {
  grid-column: span 2;
}

.gallery__link {
  position: relative;
  display: block;
  height: 100%;
  overflow: hidden;
  background: #3a332f;
  cursor: zoom-in;
}

.gallery__link img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  transition:
    transform 900ms var(--ease),
    opacity 400ms var(--ease);
}

.gallery__link:focus-visible {
  outline-offset: 3px;
}

/* Caption on hover, desktop pointers only; the lightbox carries it too */
.gallery__caption {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  padding: var(--space-xl) var(--space-s) var(--space-s);
  background: linear-gradient(0deg, rgba(41, 36, 33, 0.92) 0, rgba(41, 36, 33, 0) 100%);
  color: var(--ivory);
  font-size: var(--step--1);
  line-height: 1.4;
  opacity: 0;
  transform: translateY(0.5rem);
  transition:
    opacity 400ms var(--ease),
    transform 400ms var(--ease);
}

@media (hover: hover) {
  .gallery__link:hover img,
  .gallery__link:focus-visible img {
    transform: scale(1.04);
  }

  .gallery__link:hover .gallery__caption,
  .gallery__link:focus-visible .gallery__caption {
    opacity: 1;
    transform: none;
  }
}

@media (min-width: 40em) {
  .gallery {
    --cols: 4;
    --gap: var(--space-s);
  }
}



/* --------------------------------------------------------------------------
   Meet Alex - overlapping photos

   A tall portrait with a smaller landscape photo overlapping its lower
   corner, beside a pull quote, short bio, specialisms and the award.
   Phones: photos first, the inset hanging off the right of the main image,
   then the text. From 64em: photos left, text right.
   -------------------------------------------------------------------------- */

.meet__inner {
  display: grid;
  gap: var(--space-l);
}

.meet__media {
  position: relative;
  padding-bottom: 18%;
}

.meet__main,
.meet__inset {
  margin: 0;
  overflow: hidden;
  background: var(--stone);
}

.meet__main {
  width: 78%;
  aspect-ratio: 4 / 5;
}

.meet__inset {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 52%;
  aspect-ratio: 4 / 3;
  outline: var(--space-xs) solid var(--soft-white);
}

.meet__main img,
.meet__inset img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.meet__main img {
  object-position: 50% 20%;
}

.meet__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

/* Pulled up under the heading so the two read as one unit */
.meet__role {
  margin-top: calc(var(--space-xs) * -1);
  padding-left: calc(var(--col-size) * 0.9);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.meet__quote {
  margin: 0;
  padding: 0;
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-style: italic;
  line-height: 1.2;
  max-width: 34rem;
}

.meet__bio {
  max-width: 34rem;
  font-size: var(--step-0);
  line-height: 1.7;
}

/* Items wrap as whole units, each led by its own rule, so there is never a
   stray separator at the end of a line */
.meet__skills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1.4;
  text-transform: uppercase;
}

.meet__skills li {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
  white-space: nowrap;
}

.meet__skills li::before {
  content: "";
  flex-shrink: 0;
  width: 1rem;
  height: 1px;
  background: var(--cocoa);
  transform: translateY(-0.3em);
}

.meet__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m) var(--space-l);
  width: 100%;
  padding-top: var(--space-m);
  border-top: 1px solid rgba(41, 36, 33, 0.14);
}

.meet__award {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.3;
  text-wrap: balance;
}

.meet__award svg {
  flex-shrink: 0;
  width: 1.125rem;
  height: auto;
  color: var(--cocoa);
}

/* Side by side from tablet portrait upwards, so the photos never fill the
   screen on their own */
@media (min-width: 48em) {
  /* Sized so the whole section fits a laptop or desktop screen: padding
     follows the viewport height and the columns are even, giving the
     photos more room */
  .meet {
    padding-block: clamp(3.5rem, 9vh, 7rem);
  }

  .meet__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    column-gap: clamp(3.5rem, 6vw, 8rem);
  }

  .meet__media {
    padding-bottom: 12%;
  }

  /* Never taller than about two thirds of the screen */
  .meet__main {
    width: min(82%, 62vh * 4 / 5);
  }

  .meet__inset {
    width: 56%;
    outline-width: var(--space-s);
  }

  .meet__content {
    gap: var(--space-m);
  }

  .meet__quote {
    font-size: min(var(--step-3), 4vh);
  }
}

/* Tablet: the text column is narrow, so the quote steps down a size */
@media (min-width: 48em) and (max-width: 63.99em) {
  .meet__inner {
    column-gap: var(--space-xl);
  }

  .meet__quote {
    font-size: var(--step-2);
  }

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


/* --------------------------------------------------------------------------
   Reviews - stone

   One centred column: heading, one review at a time set large, the arrows,
   then the Google rating as a slim bar along the foot. Reviews step through
   with the arrows or a swipe (main.js). No autoplay. Without JS every
   review simply shows as a list.

   -------------------------------------------------------------------------- */

.reviews {
  padding-block: clamp(4rem, 10vh, 7.5rem);
}

.reviews__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* The quote mark under the heading already gives the review its own
   space, so the heading needs little margin of its own */
.reviews__head {
  align-self: stretch;
  margin-bottom: var(--space-2xs);
  text-align: left;
}

.reviews__carousel {
  width: 100%;
  max-width: 50rem;
}

.reviews__list {
  display: grid;
  gap: var(--space-xl);
  margin: 0;
  padding: 0;
  list-style: none;
}

.review {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-m);
}

/* Drawn opening mark, so no curly quote character sits in the page */
.review__quote {
  position: relative;
  margin: 0;
  padding-top: var(--space-xl);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-style: italic;
  line-height: 1.4;
}

.review__quote::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 2.75rem;
  height: 2rem;
  background: rgba(41, 36, 33, 0.22);
  transform: translateX(-50%);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 44 32'%3E%3Cpath d='M0 32V19C0 8.5 5.6 2.2 16.8 0l1.6 4.2C12.3 6 9.4 9.5 9.2 14.4H18V32H0zm26 0V19c0-10.5 5.6-16.8 16.8-19l1.2 4.2C38 6 35.2 9.5 35 14.4h8.8V32H26z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 44 32'%3E%3Cpath d='M0 32V19C0 8.5 5.6 2.2 16.8 0l1.6 4.2C12.3 6 9.4 9.5 9.2 14.4H18V32H0zm26 0V19c0-10.5 5.6-16.8 16.8-19l1.2 4.2C38 6 35.2 9.5 35 14.4h8.8V32H26z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.review__who {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-s);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.review__who span {
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: none;
}


/* One at a time once main.js has taken over. All reviews share one grid
   cell so the block is as tall as the longest and nothing jumps. */

.reviews__carousel.is-enhanced .reviews__list {
  gap: 0;
}

.reviews__carousel.is-enhanced .review {
  grid-area: 1 / 1;
  justify-content: flex-start;
  opacity: 0;
  visibility: hidden;
  transform: translateY(0.75rem);
  transition:
    opacity 500ms var(--ease),
    transform 500ms var(--ease),
    visibility 0s linear 500ms;
}

.reviews__carousel.is-enhanced .review.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.reviews__controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--space-m);
  margin-top: var(--space-l);
}

.reviews__controls[hidden] {
  display: none;
}

.reviews__count {
  min-width: 4.5rem;
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-style: italic;
  text-align: center;
}


/* Inner pages: centred heading and lead in place of the oversized one.
   The quote mark gives the review its own space, so the heading margin is
   pulled in to match the home page. */
.reviews--inner .inner-head {
  margin-bottom: var(--space-l);
}


/* Rating bar */

.reviews__summary {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-s) var(--space-m);
  width: 100%;
  max-width: 50rem;
  margin-top: var(--space-xl);
  padding-top: var(--space-l);
  border-top: 1px solid rgba(41, 36, 33, 0.18);
}

.reviews__score {
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1;
}

.reviews__stars {
  width: 6.75rem;
  height: auto;
  fill: var(--espresso);
}

.reviews__from {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* The link sits on its own line on phones */
@media (max-width: 39.99em) {
  .reviews__summary .text-link {
    flex-basis: auto;
    margin-top: var(--space-2xs);
  }

  .reviews__summary::after {
    content: "";
    order: 1;
    flex-basis: 100%;
    height: 0;
  }

  .reviews__summary .text-link {
    order: 2;
  }
}


/* Round outlined button for light backgrounds */

.round-btn {
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  padding: 0;
  background: transparent;
  border: 1px solid var(--espresso);
  border-radius: 50%;
  color: var(--espresso);
  cursor: pointer;
  transition:
    background-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.round-btn svg {
  width: 1.25rem;
  height: auto;
}

@media (hover: hover) {
  .round-btn:hover {
    background: var(--espresso);
    color: var(--ivory);
  }
}

.round-btn:active {
  background: var(--cocoa);
  color: var(--ivory);
}

/* --------------------------------------------------------------------------
   Training - espresso

   Text and the list of courses on the left, the course video on the right
   in a tall frame. The video loads nothing until it is played (preload
   none, poster only). main.js swaps the native controls for a single play
   button, then hands the controls back once it is playing.
   Phones: text first, then the video.
   -------------------------------------------------------------------------- */

.training__inner {
  display: grid;
  gap: var(--space-2xl);
}

.training__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}


/* Courses: two columns of name and one line, hairline above each */

.courses {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: var(--space-l);
  width: 100%;
  margin: var(--space-s) 0 0;
  padding: 0;
  list-style: none;
}

.course {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding: var(--space-s) var(--space-xl) var(--space-s) 0;
  border-top: 1px solid var(--color-line-dark);
  color: var(--ivory);
  text-decoration: none;
}

.course__name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.2;
  transition: color var(--dur) var(--ease);
}

.course__desc {
  color: var(--stone);
  font-size: var(--step--1);
  line-height: 1.5;
}

.course__arrow {
  position: absolute;
  top: 50%;
  right: 0;
  width: 1.25rem;
  height: auto;
  color: var(--nude);
  transform: translateY(-50%);
  transition: transform 400ms var(--ease);
}

.course:focus-visible {
  outline-offset: 2px;
}

@media (hover: hover) {
  .course:hover .course__name {
    color: var(--nude);
  }

  .course:hover .course__arrow {
    transform: translate(0.375rem, -50%);
  }
}

.training__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-m) var(--space-l);
  margin-top: var(--space-m);
}


/* Video */

.training__media {
  justify-self: center;
  width: min(72%, 18rem);
  margin: 0;
}

.training__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: #3a332f;
}

.training__frame video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.training__play {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-s);
  padding: var(--space-l) var(--space-s);
  background: linear-gradient(0deg, rgba(41, 36, 33, 0.8) 0, rgba(41, 36, 33, 0) 55%);
  border: 0;
  color: var(--ivory);
  cursor: pointer;
}

.training__play[hidden] {
  display: none;
}

.training__play-icon {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  padding-left: 0.25rem;
  border: 1px solid rgba(246, 242, 236, 0.7);
  border-radius: 50%;
  transition:
    background-color var(--dur) var(--ease),
    color var(--dur) var(--ease),
    transform 400ms var(--ease);
}

.training__play-icon svg {
  width: 1rem;
  height: auto;
}

.training__play-label {
  white-space: nowrap;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.training__play:focus-visible {
  outline-offset: -4px;
}

@media (hover: hover) {
  .training__play:hover .training__play-icon {
    background: var(--ivory);
    color: var(--espresso);
    transform: scale(1.06);
  }
}

.training__caption {
  margin-top: var(--space-s);
  color: var(--stone);
  font-size: var(--step--1);
  line-height: 1.5;
}

@media (min-width: 40em) {
  .courses {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Tablet: the video sits beside the heading and intro, and the courses and
   buttons run full width underneath, so the video is never left on its own
   below everything. display: contents lets the text column's children take
   part in the section grid directly. */
@media (min-width: 48em) and (max-width: 63.99em) {
  .training__inner {
    grid-template-columns: minmax(0, 1fr) 14rem;
    grid-template-areas:
      "title media"
      "lead media"
      "courses courses"
      "actions actions";
    align-items: start;
    gap: var(--space-m) var(--space-xl);
  }

  .training__content {
    display: contents;
  }

  #training-title {
    grid-area: title;
    align-self: end;
  }

  .training .display-lead {
    grid-area: lead;
  }

  .courses {
    grid-area: courses;
    margin-top: var(--space-s);
  }

  .training__actions {
    grid-area: actions;
    margin-top: 0;
  }

  .training__media {
    grid-area: media;
    justify-self: end;
    width: 100%;
  }
}

@media (min-width: 64em) {
  /* Padding follows the screen height so the section fits one screen */
  .training {
    padding-block: clamp(3.5rem, 9vh, 7rem);
  }

  /* The video column is exactly as wide as the video, so the space
     between text and video is only the column gap */
  .training__inner {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: clamp(3rem, 6vw, 7rem);
  }

  /* Never taller than about two thirds of the screen */
  .training__media {
    justify-self: start;
    width: min(24rem, 66vh * 9 / 16);
  }
}


/* --------------------------------------------------------------------------
   FAQs - ivory

   Native details and summary, so open and closed states are announced
   without any ARIA or JS to keep in step. Heading and a contact link on the
   left, the questions on the right; stacked on phones.
   -------------------------------------------------------------------------- */

.faqs__inner {
  display: grid;
  gap: var(--space-xl);
}

.faqs__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
  max-width: 28rem;
}

.faqs__list {
  border-top: 1px solid rgba(41, 36, 33, 0.18);
}

.faq {
  border-bottom: 1px solid rgba(41, 36, 33, 0.18);
}

.faq__q {
  position: relative;
  display: block;
  padding: var(--space-m) var(--space-2xl) var(--space-m) 0;
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.3;
  list-style: none;
  cursor: pointer;
}

.faq__q::-webkit-details-marker {
  display: none;
}

/* Plus that turns into a minus */
.faq__q::before,
.faq__q::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0.25rem;
  width: 1rem;
  height: 1px;
  background: var(--espresso);
  transition: transform 300ms var(--ease);
}

.faq__q::after {
  transform: rotate(90deg);
}

.faq[open] .faq__q::after {
  transform: rotate(0deg);
}

.faq__q:focus-visible {
  outline-offset: 2px;
}

@media (hover: hover) {
  .faq__q:hover {
    color: var(--cocoa);
  }
}

.faq__a {
  max-width: 44rem;
  padding: 0 var(--space-2xl) var(--space-m) 0;
  line-height: 1.7;
}

.faq__a p + p {
  margin-top: var(--space-s);
}

@media (min-width: 64em) {
  .faqs__inner {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    align-items: start;
    column-gap: clamp(3rem, 7vw, 9rem);
  }

  .faqs__head {
    position: sticky;
    top: calc(var(--header-h) + var(--space-l));
  }
}


/* Inner pages: centred heading above, the questions in one centred column */
.faqs--inner .faqs__list {
  max-width: 50rem;
  margin-inline: auto;
}


/* --------------------------------------------------------------------------
   Book band - stone

   Closes each treatment page and mirrors the title band at the top: the
   heading broken over two lines on the left, the lead, Book and Call on the
   right, both sitting on the same baseline. Related treatments run beneath
   a hairline, label on the left. Everything reads from the left edge of the
   narrow measure; stacked on phones and tablets. Sits between an ivory
   section and the espresso footer.
   -------------------------------------------------------------------------- */

.book-band__main {
  display: grid;
  gap: var(--space-l);
}

.book-band__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

.book-band__kicker {
  text-wrap: balance;
}

.book-band__kicker,
.book-band__related-title {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.book-band__title {
  font-size: clamp(2.5rem, 1.4rem + 3vw, 4.25rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
}

.book-band__title span {
  display: block;
}

.book-band__title .indent {
  padding-left: 0.9em;
}

.book-band__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
  max-width: 30rem;
}

.book-band__lead {
  line-height: 1.7;
  text-wrap: pretty;
}

.book-band__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-m) var(--space-l);
  margin-top: var(--space-2xs);
}

.book-band__note {
  font-size: var(--step--1);
}

.nowrap {
  white-space: nowrap;
}

.book-band__note a,
.book-band__links a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--cocoa);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.25em;
  transition: text-decoration-color var(--dur) var(--ease);
}

@media (hover: hover) {
  .book-band__note a:hover,
  .book-band__links a:hover {
    text-decoration-color: var(--espresso);
  }
}

.book-band__related {
  display: grid;
  gap: var(--space-s);
  margin-top: var(--space-2xl);
  padding-top: var(--space-l);
  border-top: 1px solid rgba(41, 36, 33, 0.18);
}

.book-band__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Comfortable tap targets on phones */
.book-band__links a {
  display: inline-block;
  padding-block: var(--space-3xs);
}

/* Desktop: heading left, the rest right, meeting on the baseline as in the
   title band. The related row lines its label up with the heading column. */
@media (min-width: 64em) {
  .book-band__main {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: end;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }

  /* Two lines exactly, as in the title band */
  .book-band__title span {
    white-space: nowrap;
  }

  .book-band__related {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: baseline;
    column-gap: clamp(3rem, 6vw, 6.5rem);
  }
}


/* --------------------------------------------------------------------------
   Visit and book - stone

   Address, clinic days and contact in three short blocks, the areas served
   line, then Book and Call. The studio photo sits beside it on desktop and
   below it on phones, cropped away from the photographer's shadow in the
   bottom right corner.
   -------------------------------------------------------------------------- */

.visit__inner {
  display: grid;
  gap: var(--space-2xl);
}

.visit__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-m);
}

/* Address across the full width, then hours and contact side by side,
   wrapping to a stack when there isn't room */
.visit__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.visit__details {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-l) var(--space-xl);
  width: 100%;
  margin-top: var(--space-s);
}

.visit__block--address {
  flex-basis: 100%;
}

.visit__block {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2xs);
}

.visit__label {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.visit__address {
  font-style: normal;
  line-height: 1.6;
}

.visit__link {
  color: var(--espresso);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.25em;
  overflow-wrap: anywhere;
}

@media (hover: hover) {
  .visit__link:hover {
    text-decoration-thickness: 2px;
  }
}

/* Day and time on one line, times in bold, aligned in two columns */
.visit__hours {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  gap: var(--space-3xs) var(--space-m);
  margin: 0;
}

.visit__hours div {
  display: contents;
}

.visit__hours dd {
  margin: 0;
  font-weight: 600;
}

.visit__areas {
  max-width: 36rem;
  padding-top: var(--space-m);
  border-top: 1px solid rgba(41, 36, 33, 0.18);
  font-size: var(--step--1);
  line-height: 1.6;
}

.visit__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-m) var(--space-l);
  margin-top: var(--space-s);
}

.visit__media {
  margin: 0;
  overflow: hidden;
  background: var(--nude);
  aspect-ratio: 4 / 3;
}

.visit__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 35% 45%;
}

.visit__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-l);
}

@media (min-width: 64em) {
  /* Padding and photo height follow the screen so the section fits it */
  .visit {
    padding-block: clamp(3.5rem, 9vh, 7rem);
  }

  .visit__inner {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: center;
    column-gap: clamp(3rem, 7vw, 9rem);
  }

  .visit__inner {
    align-items: stretch;
  }

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

  /* Intro beside the heading, on its last line, to save height */
  .visit__head {
    flex-direction: row;
    align-items: flex-end;
    gap: var(--space-xl);
    margin-bottom: var(--space-2xs);
  }

  .visit__head .display-lead--col {
    flex: 1 1 18rem;
    padding-left: 0;
    padding-bottom: 0.35em;
  }

  .visit__details {
    gap: var(--space-m) var(--space-2xl);
  }

  /* The photo takes the height of the text beside it */
  .visit__media {
    position: relative;
    aspect-ratio: auto;
  }

  .visit__media img {
    position: absolute;
    inset: 0;
  }
}


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

   Intro line with Book and WhatsApp, then visit, contact, clinic days and
   social in four columns, then the full link set: every treatment, every
   course and every top level page, so every page is one click from every
   other. Treatments take double width and split into two columns inside
   it, so no label wraps. The logo sits large across the foot as a
   signature, above the legal line.
   -------------------------------------------------------------------------- */

.site-footer {
  --focus-color: var(--nude);
  padding: var(--space-3xl) 0 var(--space-l);
  background: var(--espresso);
  color: var(--stone);
  font-size: var(--step--1);
}

.site-footer a:not(.btn) {
  color: var(--ivory);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

@media (hover: hover) {
  .site-footer a:not(.btn):hover {
    color: var(--nude);
  }
}

/* Intro: one line about the business, with Book and WhatsApp */
.site-footer__intro {
  display: grid;
  gap: var(--space-l);
  padding-bottom: var(--space-2xl);
}

.site-footer__statement {
  max-width: 42rem;
  color: var(--ivory);
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 1.25rem + 1.2vw, 2.375rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.site-footer__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
}

.site-footer__wa {
  gap: var(--space-2xs);
}

.site-footer__wa svg {
  flex: none;
}

/* Visit, get in touch, clinic days, follow */
.site-footer__info {
  display: grid;
  gap: var(--space-xl) var(--space-l);
  padding-block: var(--space-2xl);
  border-top: 1px solid var(--color-line-dark);
}

.site-footer__heading {
  margin-bottom: var(--space-s);
  color: var(--nude);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.site-footer__address {
  font-size: var(--step-0);
  font-style: normal;
  line-height: 1.6;
}

.site-footer__more {
  display: inline-block;
  margin-top: var(--space-s);
  padding-bottom: 0.125rem;
  border-bottom: 1px solid var(--nude);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.site-footer__contact,
.site-footer__social {
  display: grid;
  gap: var(--space-3xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer__contact a,
.site-footer__social a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding-block: 0.3125rem;
  font-size: var(--step-0);
  line-height: 1.4;
}

.site-footer__social svg {
  flex: none;
  color: var(--nude);
}

.site-footer__hours {
  display: grid;
  gap: var(--space-2xs);
  max-width: 20rem;
  margin: 0;
  font-size: var(--step-0);
  line-height: 1.4;
}

/* Day on one line, times beneath, so it fits a narrow column */
.site-footer__hours dt {
  color: var(--ivory);
}

.site-footer__hours dd {
  margin: 0;
}

/* Every page on the site, in three groups */
.site-footer__nav {
  display: grid;
  gap: var(--space-xl) var(--space-l);
  padding-block: var(--space-2xl);
  border-top: 1px solid var(--color-line-dark);
}

.site-footer__list {
  display: grid;
  gap: 0 var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer__list a {
  display: inline-block;
  padding-block: 0.3125rem;
  font-size: var(--step-0);
  line-height: 1.4;
}

/* The logo, set large across the full width as a signature */
.site-footer__signature {
  display: block;
  padding-block: var(--space-xl) var(--space-l);
  border-top: 1px solid var(--color-line-dark);
}

.site-footer a.site-footer__signature {
  color: var(--nude);
}

.site-footer__signature .logo {
  width: 100%;
  max-width: 60rem;
  margin-inline: auto;
}

@media (hover: hover) {
  .site-footer a.site-footer__signature:hover {
    color: var(--ivory);
  }
}

.site-footer__signature:focus-visible {
  outline-offset: 4px;
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s) var(--space-l);
  padding-top: var(--space-l);
  border-top: 1px solid var(--color-line-dark);
}

.site-footer__legal {
  display: flex;
  gap: var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer__bottom a:not(.btn) {
  color: var(--stone);
  text-decoration: underline;
  text-decoration-color: var(--color-line-dark);
  text-underline-offset: 0.25em;
}

@media (min-width: 40em) {
  .site-footer__info {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .site-footer__nav {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .site-footer__group--wide {
    grid-column: 1 / -1;
  }

  .site-footer__list--split {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .site-footer__intro {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    column-gap: var(--space-2xl);
  }

  .site-footer__info {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Four link columns only once the split treatment column has room for
   "Beauty spots and freckles" on one line */
@media (min-width: 80em) {
  .site-footer__nav {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .site-footer__group--wide {
    grid-column: span 2;
  }
}


/* --------------------------------------------------------------------------
   Lightbox - native dialog, opened by main.js

   Full screen on espresso: count and close across the top, the image as
   large as the screen allows in the middle, caption and arrows below.
   -------------------------------------------------------------------------- */

html.lightbox-open {
  overflow: hidden;
}

.lightbox {
  --focus-color: var(--nude);
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: var(--space-s) var(--gutter);
  border: 0;
  background: var(--espresso);
  color: var(--ivory);
}

.lightbox[open] {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: var(--space-s);
}

.lightbox::backdrop {
  background: rgba(0, 0, 0, 0.4);
}

.lightbox__bar,
.lightbox__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.lightbox__nav {
  justify-content: center;
  gap: var(--space-s);
}

.lightbox__count {
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-style: italic;
  color: var(--stone);
}

.lightbox__figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  min-height: 0;
  margin: 0;
}

.lightbox__img {
  flex: 0 1 auto;
  min-height: 0;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

.lightbox__caption {
  flex-shrink: 0;
  max-width: 40rem;
  color: var(--stone);
  font-size: var(--step--1);
  text-align: center;
}

.lightbox__btn {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  background: transparent;
  border: 1px solid rgba(216, 208, 199, 0.35);
  border-radius: var(--radius);
  color: var(--ivory);
  cursor: pointer;
  transition:
    background-color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.lightbox__btn svg {
  width: 1.25rem;
  height: auto;
}

.lightbox__close svg {
  width: 1rem;
}

@media (hover: hover) {
  .lightbox__btn:hover {
    background: var(--ivory);
    border-color: var(--ivory);
    color: var(--espresso);
  }
}

.lightbox__btn:active {
  background: var(--stone);
  color: var(--espresso);
}

@media (min-width: 64em) {
  .lightbox {
    padding: var(--space-l) var(--space-xl);
  }
}


/* --------------------------------------------------------------------------
   Entrance motion

   Hero: plays once on load, CSS only. The photo settles from a slight zoom,
   then the text arrives line by line.

   Sections: main.js marks elements with data-reveal and adds .reveal-on to
   the html element, then adds .is-visible as each one scrolls into view.
   Nothing is hidden until the script is running, so if it fails everything
   simply shows. Animation rather than transition, so it never overrides an
   element's own transitions (the treatment panels, for instance).
   Both are switched off under prefers-reduced-motion.
   -------------------------------------------------------------------------- */

@keyframes reveal-up {
  from {
    opacity: 0;
    transform: translateY(1.5rem);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes hero-settle {
  from {
    transform: scale(1.06);
  }

  to {
    transform: none;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .hero__media img {
    animation: hero-settle 1800ms var(--ease) both;
  }

  .hero__eyebrow,
  .hero__title span,
  .hero__lead,
  .hero__actions,
  .hero__trust {
    animation: reveal-up 900ms var(--ease) both;
  }

  .page-hero .breadcrumbs,
  .page-hero__head > * {
    animation: reveal-up 900ms var(--ease) both;
  }

  .page-hero .breadcrumbs { animation-delay: 100ms; }
  .page-hero__title { animation-delay: 200ms; }
  .page-hero__aside { animation-delay: 350ms; }

  .hero__eyebrow { animation-delay: 150ms; }
  .hero__title span:nth-child(1) { animation-delay: 250ms; }
  .hero__title span:nth-child(2) { animation-delay: 350ms; }
  .hero__title span:nth-child(3) { animation-delay: 450ms; }
  .hero__title span:nth-child(4) { animation-delay: 550ms; }
  .hero__lead { animation-delay: 650ms; }
  .hero__actions { animation-delay: 750ms; }
  .hero__trust { animation-delay: 850ms; }

  .reveal-on [data-reveal] {
    opacity: 0;
  }

  .reveal-on [data-reveal].is-visible {
    animation: reveal-up 1000ms var(--ease) var(--reveal-delay, 0ms) both;
  }
}


/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   Article - blog posts

   One readable column on ivory: a meta line, a feature photo, then prose
   with serif subheadings. Photos are cropped to 4:3 with --pos.
   -------------------------------------------------------------------------- */

.article__inner {
  max-width: 42rem;
  margin-inline: auto;
}

.article__meta {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #7a6a60;
}

.article__media {
  margin: var(--space-l) 0;
}

.article__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  background: var(--stone);
}

.article__caption {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: #7a6a60;
}

.article__body > * + * {
  margin-top: var(--space-s);
}

.article__body h2 {
  margin-top: var(--space-xl);
  font-size: var(--step-3);
  line-height: 1.1;
}

.article__body h3 {
  margin-top: var(--space-l);
  font-size: var(--step-1);
  line-height: 1.25;
}

.article__body h2 + *,
.article__body h3 + * {
  margin-top: var(--space-xs);
}

.article__body p,
.article__body li {
  line-height: 1.75;
}

.article__body ul {
  display: grid;
  gap: var(--space-2xs);
  padding-left: 1.25rem;
}

.article__body li::marker {
  color: var(--nude);
}

.article__body a:not(.btn):not(.text-link) {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--cocoa);
  text-underline-offset: 0.2em;
}

.article__body .article__media {
  margin: var(--space-l) 0;
}

.article__meta + .article__body {
  margin-top: var(--space-m);
}

/* Blog post titles run longer than page names, so the hero title steps
   down a size on post pages */
.page-hero__title--long {
  font-size: clamp(2.25rem, 1.4rem + 2.8vw, 4rem);
  line-height: 1.02;
}
