/* ============================================================
   neoSKiN — homepage chapters (post-hero layout)
   Ported from outputs zip index-no-hero.html (10 Aug direction).
   Everything here is scoped under .hm — the wrapper around the
   homepage's post-hero sections — so its variables and element
   rules never leak into the nav, hero, quiz or footer.
   Reveals are CSS + IntersectionObserver (home-motion.js);
   no GSAP anywhere.
   ============================================================ */
.hm a { color: inherit; text-decoration: none; }
.hm img, .hm video { display: block; width: 100%; height: 100%; object-fit: cover; }
.hm button { font: inherit; }

/* entrance reveals (driven by home-motion.js) */
html.js .hm [data-reveal] { opacity: 0; transform: translateY(28px);
  transition: opacity .75s var(--ease), transform .85s var(--ease); }
html.js .hm [data-reveal].in, html:not(.js) .hm [data-reveal] { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .hm [data-reveal] { opacity: 1; transform: none; transition: none; }
}
.hm{
      --putty: #efe9de;
      --putty-deep: #e4dccc;
      --bone: #f7f4ee;
      --ink: #211d18;
      --pine: #1f231b;
      --hero-pine: #191d16;
      --sage: #7c8370;
      --sage-text-light: #59604f;
      --sage-text-dark: #9ca38f;
      --sage-light: #d6d9cc;
      --salmon: #cf8b7d;
      --salmon-deep: #9d5f55;
      --salmon-text: #884a43;
      --display: "Expose", "Helvetica Neue", sans-serif;
      --sans: "Bespoke Sans", "Helvetica Neue", sans-serif;
      --script: "PP Editorial New", "Iowan Old Style", Baskerville, "Times New Roman", serif;
      --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
      --line: rgba(33, 29, 24, .17);
      --image-radius: clamp(14px, 1.35vw, 22px);
      --ease: cubic-bezier(.16, 1, .3, 1);
    }

.micro {
      font-family: var(--mono);
      font-size: var(--t-label);   /* 12px floor — house rule */
      font-weight: 500;
      line-height: 1.35;
      letter-spacing: .15em;
      text-transform: uppercase;
    }

.solution-screen {
      position: relative;
      isolation: isolate;
      min-height: 100svh;
      display: flex;
      flex-direction: column;
      overflow: hidden;
      padding: clamp(90px, 11vh, 122px) clamp(24px, 3.4vw, 56px) 30px;
      color: var(--ink);
      background: var(--putty);
    }

.solution-screen::before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: 0;
      pointer-events: none;
      /* rippled dune ground + a soft light well behind the copy — the
         invisible .02 grain wasn't earning its bytes */
      background:
        radial-gradient(58% 72% at 22% 30%, rgba(253, 251, 246, .55), transparent 68%),
        linear-gradient(160deg, transparent 42%, rgba(33, 29, 24, .07)),
        url("../assets/img/texture-dunes-putty.webp") center/cover no-repeat;
    }

.solution-top,
    .solution-base {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 20px;
      color: var(--sage-text-light);
    }

.solution-main {
      flex: 1;
      display: grid;
      grid-template-columns: minmax(280px, .88fr) minmax(280px, .62fr) minmax(380px, .92fr);
      gap: clamp(34px, 5vw, 84px);
      align-items: end;
      padding: clamp(34px, 5vh, 64px) 0 clamp(28px, 4vh, 48px);
    }

.solution-copy {
      align-self: stretch;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding-top: clamp(28px, 8vh, 92px);
    }

.solution-copy h2 {
      max-width: 12ch;
      margin: 0;
      font-family: var(--script);
      font-size: clamp(34px, 3.1vw, 52px);
      font-weight: 400;
      font-style: italic;
      line-height: .98;
      letter-spacing: -.035em;
      text-wrap: balance;
    }

.solution-note { max-width: 34ch; color: rgba(33, 29, 24, .72); }

.solution-note p { margin: 0; }

.all-concerns {
      display: inline-flex;
      align-items: center;
      gap: 11px;
      min-height: 44px;
      padding: 0 19px;
      white-space: nowrap;          /* one line, arrow riding the text */
      letter-spacing: .1em;
      color: var(--ink);
      border: 1px solid transparent;
      border-radius: 999px;
      /* the brand sage fill — same family as the Book buttons;
         AA against the ink label */
      background: var(--sage-fill);
      transition: color .25s, border-color .25s, background .25s;
    }

.all-concerns:hover,
    .all-concerns:focus-visible { color: var(--putty); background: var(--sage-label); outline: 0; }

.solution-list { min-width: 0; }

.solution-guide {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 18px;
      margin: 0 0 13px;
      color: var(--sage-text-light);
    }

.solution-guide-action,
    .solution-guide-auto { display: inline-flex; align-items: center; gap: 9px; }

.solution-guide-auto[hidden] { display: none; }

.solution-guide-auto {
      appearance: none;
      padding: 0;
      border: 0;
      color: var(--sage-text-light);
      background: transparent;
      font: inherit;
      letter-spacing: inherit;
      text-transform: inherit;
      cursor: pointer;
      transition: color .25s ease;
    }

.solution-guide-auto:hover,
    .solution-guide-auto:focus-visible { color: var(--ink); outline: 0; }

.solution-guide-mark {
      position: relative;
      width: 18px;
      height: 18px;
      border: 1px solid rgba(33, 29, 24, .38);
      border-radius: 50%;
    }

.solution-guide-mark::after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      width: 4px;
      height: 4px;
      border-radius: 50%;
      background: var(--ink);
      transform: translate(-50%, -50%);
    }

.solution-guide-auto::before {
      content: "";
      width: 5px;
      height: 5px;
      border-radius: 50%;
      background: var(--salmon);
      box-shadow: 0 0 0 4px rgba(207, 139, 125, .13);
    }

.solution-guide-auto[aria-pressed="false"]::before {
      background: transparent;
      box-shadow: 0 0 0 1px rgba(33, 29, 24, .28);
    }

.solution-link {
      position: relative;
      display: block;
      align-items: center;
      min-height: 58px;
      padding: 10px 0;
      opacity: .38;
      transition: opacity .28s, transform .42s var(--ease);
    }

.solution-link::after {
      content: "";
      position: absolute;
      right: 0;
      bottom: 2px;
      left: 0;
      height: 1px;
      background: rgba(33, 29, 24, .34);
      transform: scaleX(0);
      transform-origin: left center;
    }

.solution-list.is-auto .solution-link.is-active::after {
      animation: solution-cycle 4.2s linear both;
    }

@keyframes solution-cycle {
      from { transform: scaleX(0); }
      to { transform: scaleX(1); }
    }

.solution-link:hover,
    .solution-link:focus-visible,
    .solution-link.is-active { opacity: 1; transform: translateX(6px); outline: 0; }

.solution-name {
      font-family: var(--display);
      font-size: clamp(24px, 2.05vw, 34px);
      line-height: 1;
      letter-spacing: -.025em;
    }

.solution-arrow { display: none; }

.solution-thumb { display: none; }

.all-concerns { margin-top: 22px; }

.solution-media { min-width: 0; }

.solution-frame {
      position: relative;
      width: min(100%, clamp(400px, 31vw, 560px));
      aspect-ratio: 9 / 10;
      margin-left: auto;
      overflow: hidden;
      background: var(--putty-deep);
      border-radius: var(--image-radius);
      box-shadow: 0 26px 72px rgba(33, 29, 24, .14);
    }

.solution-frame::after { content: ""; position: absolute; z-index: 3; inset: 0; border: 1px solid rgba(33, 29, 24, .12); border-radius: inherit; pointer-events: none; }

/* the frame is a stack — one image per concern, revealed by the same
       bottom-up wipe the treatments stage uses. One page, one move: the
       incoming photo travels the full height of the frame and covers the
       one before it, which only resets below the fold once it is hidden.
       No crossfade — the rise is the reveal. See .treatment-image img. */
    .solution-frame img {
      position: absolute;
      inset: 0;
      z-index: 1;
      transform: translateY(103%);
      transition: transform .85s var(--ease) .9s;
    }

.solution-frame img.is-active {
      z-index: 2;
      transform: none;
      transition: transform .85s var(--ease);
    }

/* Under the pin the wipe is scroll-locked, not transitioned:
       home-motion.js writes --y straight from scroll position, so the
       photo tracks the wheel one-to-one and reverses exactly. A
       transition here would fight it and reintroduce the lag. */
    .solution-frame.is-scrubbed img,
    .solution-frame.is-scrubbed img.is-active {
      transform: translateY(var(--y, 103%));
      transition: none;
    }

.solution-frame img[data-solution-image="acne"] { object-position: 56% center; }

.solution-frame img[data-solution-image="lines"] { object-position: 76% center; }

.solution-caption {
      display: flex;
      justify-content: space-between;
      gap: 16px;
      width: min(100%, clamp(400px, 31vw, 560px));
      margin-left: auto;
      padding-top: 11px;
      color: var(--sage-text-light);
    }

.home-chapter {
      position: relative;
      isolation: isolate;
      min-height: 100svh;
      overflow: hidden;
      padding: clamp(96px, 11vh, 132px) clamp(24px, 3.4vw, 56px) clamp(54px, 7vh, 80px);
    }

.chapter-top {
      display: flex;
      justify-content: space-between;
      gap: 24px;
      color: var(--sage-text-light);
    }

.chapter-title {
      margin: 0;
      font-family: var(--display);
      font-size: clamp(40px, 5.1vw, 78px);
      font-weight: 400;
      line-height: .93;
      /* -.04em is the floor for display tracking; below it the letters
         start touching and it reads cramped rather than tight */
      letter-spacing: -.04em;
      text-wrap: balance;
    }

.chapter-title em { font-family: var(--script); font-weight: 400; font-style: italic; color: var(--salmon); }

.chapter-link {
      display: inline-flex;
      align-items: center;
      gap: 12px;
      min-height: 44px;
      padding: 0 17px;
      border: 1px solid currentColor;
      border-radius: 999px;
      transition: color .3s, background .3s, transform .4s var(--ease);
    }

.chapter-link:hover,
    .chapter-link:focus-visible { color: var(--putty); background: var(--sage); transform: translateY(-2px); outline: 0; }

.treatments-chapter { color: var(--putty); background: var(--pine); }

.treatments-layout {
      display: grid;
      grid-template-columns: minmax(300px, .82fr) minmax(420px, 1.18fr);
      gap: clamp(44px, 7vw, 116px);
      align-items: end;
      min-height: calc(100svh - 250px);
      padding-top: clamp(54px, 8vh, 92px);
    }

.treatments-intro { align-self: stretch; display: flex; flex-direction: column; justify-content: space-between; }

.treatments-intro .chapter-title { max-width: 9.5ch; }

.treatments-intro p { max-width: 38ch; margin: 28px 0 24px; color: rgba(239, 233, 222, .7); font-size: 15px; line-height: 1.58; }

.treatments-stage { display: grid; grid-template-columns: minmax(220px, .72fr) minmax(260px, 1fr); gap: clamp(28px, 4vw, 66px); align-items: end; }

/* the Dentea composition: the photo is the panel — full height,
   flush with the right and bottom edges of the screen — while the
   treatment list sits small and mono beside it. Hierarchy runs
   title (top left) → list (centre) → photo (right). */
@media (min-width: 1025px) {
  .treatments-stage {
    grid-template-columns: minmax(280px, .82fr) minmax(340px, 1.18fr);
    align-items: end;
    gap: clamp(30px, 4vw, 70px);
  }
  /* The list was align-self:center, which floated it up level with the
     headline and gave the eye a third competing anchor mid-column. The
     composition wants two: the title top-left and the CTA bottom-left.
     Dropping the list to the foot of the stage lets attention travel
     between those two and read the list on the way down. */
  .treatment-lines { order: -1; align-self: end; border-top-width: 0; }
  .treatment-line {
    grid-template-columns: 34px minmax(0, 1fr) auto;
    min-height: 54px;
    border-bottom-color: rgba(239, 233, 222, .14);
  }
  .hm .treatment-line b {           /* outranks the base display style */
    font-family: var(--mono) !important;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: .13em;
    text-transform: uppercase;
    white-space: nowrap;
  }
  .treatment-image {
    aspect-ratio: auto;
    height: 100%;
    min-height: clamp(520px, 74vh, 760px);
    margin-right: calc(-1 * clamp(24px, 3.4vw, 56px));
    margin-bottom: calc(-1 * clamp(54px, 7vh, 80px));
    border-radius: var(--image-radius) 0 0 0;
  }
}

.treatment-image {
      position: relative;
      aspect-ratio: 3 / 4;
      overflow: hidden;
      background: var(--ink);
      border-radius: var(--image-radius);
      box-shadow: 0 24px 70px rgba(33, 29, 24, .34);
    }

.treatment-image::after { content: ""; position: absolute; inset: 0; border: 1px solid rgba(239, 233, 222, .18); border-radius: inherit; pointer-events: none; }

/* the frame is a stack now — one image per featured treatment,
       crossfaded exactly like the concern navigator's stage. The BBL
       image ships with src + .is-active so mobile / no-JS render it
       with zero script; the rest stay data-src until needed. */
    .treatment-image img {
      position: absolute;
      inset: 0;
      z-index: 1;
      /* Dentea push — see .solution-frame img */
      transform: translateY(103%);
      transition: transform .85s var(--ease) .9s;
    }

.treatment-image img.is-active {
      z-index: 3;
      transform: none;
      transition: transform .85s var(--ease);
    }

.treatment-image img[data-treatment-image="moxi"] { object-position: 52% center; }

.treatment-lines { border-top: 1px solid rgba(239, 233, 222, .24); }

.treatment-line {
      display: grid;
      grid-template-columns: 44px minmax(0, 1fr) auto;
      gap: 14px;
      align-items: center;
      min-height: clamp(68px, 8vh, 84px);
      border-bottom: 1px solid rgba(239, 233, 222, .24);
      transition: color .28s, transform .4s var(--ease);
    }

.treatment-line:hover,
    .treatment-line:focus-visible { color: var(--sage); transform: translateX(6px); outline: 0; }

.treatment-line b { font-family: var(--display); font-size: clamp(24px, 2.1vw, 36px); font-weight: 400; letter-spacing: -.028em; }

.treatment-line span:first-child { color: var(--sage-text-dark); }

.treatments-chapter .chapter-top { color: var(--sage-text-dark); }

.results-chapter { background: var(--sage-light); }

.results-heading {
      display: grid;
      grid-template-columns: minmax(340px, 1fr) minmax(280px, .55fr);
      gap: 8vw;
      align-items: end;
      padding: clamp(54px, 7vh, 82px) 0 clamp(34px, 4.5vh, 50px);
    }

.results-heading .chapter-title { max-width: 10ch; font-size: clamp(40px, 4.4vw, 68px); }

.results-heading p { max-width: 42ch; margin: 0; color: rgba(33, 29, 24, .72); font-size: 15px; line-height: 1.6; }

.result-stage {
      position: relative;
      width: min(100%, 860px);
      aspect-ratio: 4 / 3;
      margin-left: auto;
      overflow: hidden;
      background: var(--putty-deep);
      border-radius: var(--image-radius);
      box-shadow: 0 28px 74px rgba(33, 29, 24, .14);
    }

.result-case {
      position: absolute;
      inset: 0;
      display: grid;
      grid-template-columns: 1fr 1fr;
      opacity: 0;
      visibility: hidden;
      transform: scale(1.012);
      transition: opacity .42s, visibility 0s .42s, transform .8s var(--ease);
    }

.result-case.is-active { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }

.result-case figure { position: relative; min-width: 0; margin: 0; overflow: hidden; }

.result-case figure:first-child { border-right: 1px solid rgba(239, 233, 222, .72); }

.result-case img { object-position: center; transform: scale(1.1); }

.result-case[data-result-case="redness"] img { object-position: center 48%; }

.result-case[data-result-case="jawline"] img { object-position: center 54%; transform: scale(1.065); }

.result-case figcaption {
      position: absolute;
      z-index: 2;
      left: 16px;
      bottom: 16px;
      padding: 9px 12px;
      color: var(--ink);
      background: rgba(239, 233, 222, .9);
      border-radius: 999px;
      backdrop-filter: blur(10px);
    }

/* pinned-mode companion — hidden in the ordinary layout */
    .result-current { display: none; }

.result-nav {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: clamp(22px, 3.2vw, 52px);
      width: min(100%, 860px);
      margin-top: 18px;
      margin-left: auto;
    }

.result-tab {
      position: relative;
      display: grid;
      grid-template-columns: 28px minmax(0, 1fr);
      gap: 10px;
      align-items: start;
      min-height: 58px;
      padding: 15px 0 8px;
      border: 0;
      border-top: 1px solid rgba(33, 29, 24, .22);
      color: #5b574f;
      background: transparent;
      text-align: left;
      cursor: pointer;
      transition: color .28s ease, border-color .28s ease;
    }

.result-tab::before {
      content: "";
      position: absolute;
      top: -1px;
      left: 0;
      width: 42px;
      height: 2px;
      background: var(--salmon);
      transform: scaleX(0);
      transform-origin: left center;
      transition: transform .42s var(--ease);
    }

.result-tab:hover,
    .result-tab:focus-visible,
    .result-tab[aria-selected="true"] { color: var(--ink); border-color: rgba(33, 29, 24, .48); outline: 0; }

.result-tab[aria-selected="true"]::before { transform: scaleX(1); }

.result-tab span:first-child { padding-top: 2px; color: var(--sage-text-light); }

.result-tab[aria-selected="true"] span:first-child { color: var(--salmon); }

.result-tab b {
      font-family: var(--sans);
      font-size: clamp(14px, 1.12vw, 17px);
      font-weight: 500;
      line-height: 1.25;
      letter-spacing: -.012em;
      transition: transform .42s var(--ease);
    }

.result-tab:hover b,
    .result-tab:focus-visible b { transform: translateX(3px); }

.results-note { display: flex; justify-content: space-between; gap: 28px; width: min(100%, 860px); margin: 18px 0 0 auto; color: var(--sage-text-light); }

/* ---- shop chapter: pine ground so the white product tiles carry
   the light. Intro column left, hairline-ruled 3×2 grid right —
   the composition the shop-page product band established. ---- */
.shop-chapter { color: var(--putty); background: var(--pine); }

.shop-chapter .chapter-top { color: var(--sage-text-dark); }

.shop-split {
      display: grid;
      grid-template-columns: minmax(300px, .74fr) minmax(460px, 1.26fr);
      gap: clamp(44px, 6vw, 104px);
      align-items: start;
      padding-top: clamp(54px, 8vh, 92px);
    }

.shop-intro { position: sticky; top: clamp(96px, 12vh, 140px); display: flex; flex-direction: column; align-items: flex-start; gap: 30px; }

.shop-intro .chapter-title { max-width: 9ch; }

.shop-intro p { max-width: 34ch; margin: 26px 0 0; color: rgba(239, 233, 222, .7); font-size: 15px; line-height: 1.6; }

.shop-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      border: 1px solid rgba(239, 233, 222, .16);
      border-radius: calc(var(--image-radius) * .8);
      overflow: hidden;
    }

.shop-cell {
      position: relative;
      min-width: 0;
      display: flex;
      flex-direction: column;
      gap: 20px;
      padding: clamp(16px, 1.6vw, 26px);
      border-right: 1px solid rgba(239, 233, 222, .16);
      border-bottom: 1px solid rgba(239, 233, 222, .16);
      transition: background .35s;
    }

.shop-cell:nth-child(3n) { border-right: 0; }

.shop-cell:nth-child(n+4) { border-bottom: 0; }

.shop-cell:hover, .shop-cell:focus-visible { background: rgba(239, 233, 222, .06); outline: 0; }

.shop-cell-visual {
      aspect-ratio: 1;
      display: grid;
      place-items: center;
      padding: clamp(14px, 1.4vw, 24px);
      background: #fff;
      border-radius: calc(var(--image-radius) * .55);
    }

.shop-cell-visual img { width: 100%; height: 100%; object-fit: contain; transition: transform .8s var(--ease); }

.shop-cell:hover .shop-cell-visual img { transform: scale(1.05); }

.shop-cell-meta { padding-bottom: 6px; }

.shop-cell-meta span { display: block; margin-bottom: 8px; color: var(--sage-text-dark); }

.shop-cell-meta b { display: block; font-family: var(--mono, inherit); font-size: 13px; font-weight: 500; letter-spacing: .06em; line-height: 1.4; text-transform: uppercase; }

.team-chapter { background: var(--putty); }

.team-layout {
      display: grid;
      grid-template-columns: minmax(340px, .92fr) minmax(350px, 1.08fr);
      gap: clamp(48px, 8vw, 128px);
      align-items: center;
      min-height: calc(100svh - 230px);
      padding-top: 52px;
    }

.team-image { position: relative; width: min(100%, 620px); aspect-ratio: 1; justify-self: center; overflow: hidden; border-radius: var(--image-radius); box-shadow: 0 28px 70px rgba(33, 29, 24, .15); }

.team-image::after { content: ""; position: absolute; inset: 0; border: 1px solid rgba(33, 29, 24, .12); border-radius: inherit; pointer-events: none; }

.team-copy { max-width: 640px; }

.team-copy .chapter-title { max-width: 10.5ch; }

.team-copy p { max-width: 47ch; margin: 34px 0 28px; color: rgba(33, 29, 24, .72); font-size: 16px; line-height: 1.62; }

.team-proof { display: grid; grid-template-columns: repeat(3, 1fr); margin: 40px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }

.team-proof span { padding: 18px 16px 18px 0; color: var(--sage-text-light); }

.consult-chapter {
      display: grid;
      place-items: center;
      min-height: 76svh;
      padding: 110px 24px;
      text-align: center;
      color: var(--putty);
      /* rain-on-leaf ambience under a pine veil — the image is baked
         dark, the gradient guarantees the copy's ground */
      background:
        linear-gradient(rgba(25, 29, 22, .42), rgba(25, 29, 22, .62)),
        url("../assets/img/leaf-rain-pine.webp") center/cover no-repeat,
        var(--pine);
    }

.consult-inner { max-width: 1050px; }

.consult-inner .chapter-title { font-size: clamp(44px, 6vw, 86px); }

.consult-inner p { max-width: 46ch; margin: 30px auto 32px; color: rgba(239, 233, 222, .7); font-size: 16px; line-height: 1.6; }

.consult-inner .chapter-link { color: var(--ink); background: var(--putty); border-color: var(--putty); }

.consult-inner .chapter-link:hover { color: var(--putty); background: var(--sage); border-color: var(--sage); }

.visit-chapter { min-height: auto; background: var(--putty-deep); }

.visit-layout {
      display: grid;
      grid-template-columns: minmax(300px, .72fr) minmax(460px, 1.28fr);
      gap: clamp(40px, 7vw, 108px);
      align-items: stretch;
      padding-top: clamp(52px, 8vh, 90px);
    }

.visit-copy { display: flex; flex-direction: column; justify-content: space-between; padding-bottom: 10px; }

.visit-copy .chapter-title { max-width: 9ch; }

.address-block { padding-top: 42px; border-top: 1px solid var(--line); }

.address-block address { margin: 0 0 26px; font-size: 21px; line-height: 1.45; font-style: normal; }

.address-block p { margin: 0 0 9px; color: rgba(33, 29, 24, .64); font-size: 14px; }

/* ---- opening hours, under the address (screenshot spec) ---- */
.hours-block { margin-top: clamp(30px, 4vh, 44px); }

.hours-label { display: block; margin-bottom: 14px; color: var(--sage-text-light); }

.hours-status {
      margin: 0 0 18px;
      font-family: 'JetBrains Mono', monospace;
      font-size: clamp(17px, 1.5vw, 22px);
      font-weight: 500;
      letter-spacing: .14em;
      text-transform: uppercase;
    }

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

.hours-list li { display: flex; gap: 20px; padding: 4px 0; color: rgba(33, 29, 24, .72); font-size: 17px; }

.hours-list li span:first-child { width: 48px; color: var(--sage-text-light); }

.hours-list li.is-today { color: var(--ink); font-weight: 500; }

.map-shell { position: relative; min-height: 620px; overflow: hidden; background: var(--putty); border-radius: var(--image-radius); box-shadow: 0 24px 64px rgba(33, 29, 24, .12); }

.map-shell iframe { display: block; width: 100%; height: 100%; min-height: 620px; border: 0; filter: grayscale(.7) sepia(.12) saturate(.72) contrast(.92); }

.map-shell::after { content: ""; position: absolute; inset: 0; border: 1px solid rgba(33, 29, 24, .12); border-radius: inherit; pointer-events: none; }

/* Quiet tonal light gives the fields depth without introducing a new colour. */
    .solution-screen,
    .results-chapter,
    .team-chapter {
      background-image:
        radial-gradient(circle at 88% 10%, rgba(124, 131, 112, .105), transparent 30%),
        linear-gradient(180deg, rgba(239, 233, 222, .12), transparent 34%);
    }

.shop-chapter,
    .visit-chapter {
      background-image: radial-gradient(circle at 12% 18%, rgba(124, 131, 112, .09), transparent 33%);
    }

.treatments-chapter {
      background-image:
        radial-gradient(circle at 78% 22%, rgba(124, 131, 112, .15), transparent 30%),
        linear-gradient(145deg, rgba(33, 29, 24, .11), transparent 44%);
    }

.consult-chapter {
      background-image:
        radial-gradient(circle at 78% 22%, rgba(124, 131, 112, .12), transparent 30%),
        linear-gradient(rgba(25, 29, 22, .42), rgba(25, 29, 22, .62)),
        url("../assets/img/leaf-rain-pine.webp");
      background-size: auto, auto, cover;
      background-position: center;
      background-repeat: no-repeat;
    }

@media (min-width: 1025px) and (max-width: 1180px) {
  .solution-main {
        grid-template-columns: minmax(280px, .82fr) minmax(360px, 1fr);
        grid-template-rows: auto 1fr;
        column-gap: clamp(42px, 5vw, 68px);
        row-gap: 34px;
        align-items: start;
      }
  .solution-copy { grid-column: 1; grid-row: 1; padding-top: 20px; }
  .solution-note { margin-top: 28px; }
  .solution-list { grid-column: 1; grid-row: 2; }
  .solution-media { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
  .solution-frame { width: min(100%, 390px); }
  .solution-caption { width: min(100%, 390px); }
  .solution-name { font-size: clamp(23px, 2.6vw, 30px); }
}

@media (max-width: 1024px) {
  .solution-screen { min-height: auto; padding: 92px 20px 34px; }
  .solution-top span:last-child { display: none; }
  .solution-main { display: block; padding: 56px 0 48px; }
  .solution-copy { display: block; padding: 0 0 50px; }
  .solution-copy h2 { max-width: 11ch; font-size: clamp(34px, 9.4vw, 46px); }
  .solution-note { margin-top: 32px; }
  .solution-media { display: none; }
  .solution-guide { display: none; }
  .solution-link {
        grid-template-columns: 58px minmax(0, 1fr) auto;
        display: grid;
        gap: 12px;
        min-height: 87px;
        padding: 9px 0;
        opacity: 1;
      }
  .solution-link:hover,
      .solution-link:focus-visible,
      .solution-link.is-active { transform: none; }
  .solution-thumb {
        display: block;
        width: 58px;
        aspect-ratio: 3 / 4;
        overflow: hidden;
        background: var(--putty-deep);
      }
  .solution-link[data-solution="acne"] .solution-thumb img { object-position: 56% center; }
  .solution-link[data-solution="lines"] .solution-thumb img { object-position: 76% center; }
  .solution-name { font-size: clamp(21px, 6.2vw, 26px); }
  .home-chapter { min-height: auto; padding: 88px 20px 54px; }
  .chapter-top span:last-child { display: none; }
  .treatments-layout, .team-layout, .visit-layout { grid-template-columns: 1fr; min-height: auto; }
  .treatments-layout { gap: 54px; padding-top: 54px; }
  .treatments-intro { display: block; }
  .treatments-stage { grid-template-columns: 1fr; }
  .treatment-image { width: min(78vw, 380px); margin: 0 auto; }
  .results-heading { grid-template-columns: 1fr; gap: 24px; }
  .result-stage { width: 100%; }
  .result-nav { grid-template-columns: 1fr; gap: 0; margin-top: 14px; }
  .result-tab { min-height: 58px; padding: 15px 0 10px; }
  .results-note { display: block; }
  .results-note span { display: block; margin-top: 8px; }
  .shop-split { grid-template-columns: 1fr; gap: 34px; }
  .shop-intro { position: static; }
  .shop-intro p { margin-top: 20px; }
  .shop-grid { grid-template-columns: 1fr 1fr; }
  .shop-cell:nth-child(3n) { border-right: 1px solid rgba(239, 233, 222, .16); }
  .shop-cell:nth-child(2n) { border-right: 0; }
  .shop-cell:nth-child(n+4) { border-bottom: 1px solid rgba(239, 233, 222, .16); }
  .shop-cell:nth-child(n+5) { border-bottom: 0; }
  .team-image { width: min(100%, 520px); }
  .team-proof { grid-template-columns: 1fr; }
  .team-proof span { border-bottom: 1px solid var(--line); }
  .team-proof span:last-child { border-bottom: 0; }
  .consult-chapter { min-height: 68svh; }
  .visit-layout { gap: 46px; }
  .map-shell, .map-shell iframe { min-height: 480px; }
}

@media (max-width: 480px) {
  /* phones under 390px: the quiz label can't hold one line — let it
     wrap, keeping the arrow tucked after the final word */
  .all-concerns { white-space: normal; padding: 10px 17px; line-height: 1.55; }
  .solution-screen, .home-chapter { padding-left: 16px; padding-right: 16px; }
  .solution-link { min-height: 80px; }
  .chapter-title { font-size: clamp(36px, 10.5vw, 46px); }
  .shop-grid { grid-template-columns: 1fr; }
  .shop-cell:nth-child(n) { border-right: 0; border-bottom: 1px solid rgba(239, 233, 222, .16); }
  .shop-cell:last-child { border-bottom: 0; }
  .result-tab b { font-size: 16px; }
  .map-shell, .map-shell iframe { min-height: 380px; }
}

@media (prefers-reduced-motion: reduce) {
  .hm *, .hm *::before, .hm *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
}

/* The portrait-to-walkthrough transition is part of the homepage
       story at every viewport size. The original direction hid the
       treatment film below 1025px, which made the live preview appear
       to skip the expansion entirely. Reduced-motion still keeps the
       static portrait via the rule above. */
    @media (max-width: 1024px) and (prefers-reduced-motion: no-preference) {
      .film-treatment { display: block; }
    }

/* ============================================================
   PINNED CONCERNS — desktop only. The navigator locks to the
   viewport and scroll steps through the five concerns before the
   page releases (the Dentea "solution" move). The section is the
   tall track; .solution-pin is the screen that sticks. Mobile,
   tablet, reduced-motion and no-JS keep the ordinary section.
   ============================================================ */
@media (min-width: 1025px) and (prefers-reduced-motion: no-preference) {
  html.js .hm .solution-screen.is-pinned {
    height: calc(100svh + 550vh);   /* 5 stops × 110vh of travel each.
                                       48vh let one trackpad flick clear two
                                       photos; 76vh still did on a fast flick,
                                       which is what made the sequence look
                                       like it skipped — the index jumped two
                                       stops before either photo had finished
                                       its wipe. This comment already said
                                       110vh, but the value stayed at 380vh
                                       (= 76vh a stop), so the fix it describes
                                       was never actually applied and the
                                       chapter still flicked. 550vh is the
                                       number the comment always meant.
                                       THE INVARIANT: a stop must be longer
                                       than one viewport, or a single flick
                                       clears two. Keep stops ≥ 100vh. */
    min-height: 0;
    padding: 0;
    display: block;
    /* the base rule's overflow:hidden would turn this section into the
       sticky scrollport and the pin would never hold; the pin below
       carries its own overflow:hidden for the visuals */
    overflow: visible;
  }
  html.js .hm .solution-screen.is-pinned .solution-pin {
    position: sticky;
    top: 0;
    height: 100svh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* +78px on the head: the two requested push-downs. NB this rule is
       the one that counts in pinned mode — the .solution-screen padding
       edits were silent no-ops here, which is why the head refused to
       move twice. */
    /* kicker rides 40px higher; the quote holds its line via the main
       grid's matching pad below */
    padding: calc(clamp(90px, 11vh, 122px) + 38px) clamp(24px, 3.4vw, 56px) 30px;
  }
  /* scroll drives the stage; the item's arrival gets a touch more
     presence so each stop reads as a step */
  html.js .hm .solution-screen.is-pinned .solution-link { transition-duration: .34s; }

  /* the treatments chapter takes the same move: tall track, sticky
     screen, scroll steps 01→05 while the frame crossfades */
  html.js .hm .treatments-chapter.is-pinned {
    height: calc(100svh + 550vh);   /* matched to the concerns track above —
                                       same move, same pace, same 110vh/stop.
                                       Was 380vh, i.e. 76vh a stop, despite
                                       this comment claiming 110: the chapter
                                       CP reported flicking through the five
                                       treatments. Same invariant applies. */
    min-height: 0;
    padding: 0;
    overflow: visible;         /* .home-chapter's overflow:hidden would
                                  break the sticky pin, as above */
  }
  html.js .hm .treatments-chapter.is-pinned .treatment-pin {
    position: sticky;
    top: 0;
    height: 100svh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: clamp(96px, 11vh, 132px) clamp(24px, 3.4vw, 56px) clamp(54px, 7vh, 80px);
  }
  /* on the pine ground the resting lines recede and the current one
     carries full ink — the same hierarchy the concern list has */
  html.js .hm .treatments-chapter.is-pinned .treatment-line {
    color: rgba(239, 233, 222, .34);
    transition-duration: .34s;
  }
  html.js .hm .treatments-chapter.is-pinned .treatments-layout { flex: 1; min-height: 0; }
  html.js .hm .treatments-chapter.is-pinned .treatment-line:hover,
  html.js .hm .treatments-chapter.is-pinned .treatment-line:focus-visible,
  html.js .hm .treatments-chapter.is-pinned .treatment-line.is-active {
    color: var(--putty);
    transform: translateX(6px);
  }

  /* ---- before/after wipe: the section pins, each case shows its
     BEFORE full-frame, and scroll wipes the AFTER across it left to
     right (three cases, one wipe each) before the page releases.
     JS drives a single custom property, --wipe (0–100), on the
     stage; everything else is CSS. ---- */
  html.js .hm .results-chapter.is-pinned {
    height: calc(100svh + 300vh);   /* 3 cases × ~100vh each */
    min-height: 0;
    padding: 0;
    overflow: visible;              /* keep the sticky pin alive */
  }
  html.js .hm .results-chapter.is-pinned .result-pin {
    position: sticky;
    top: 0;
    height: 100svh;
    display: grid;
    grid-template-columns: minmax(0, 1fr) min-content auto;
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    grid-template-areas:
      "top  top  top"
      "head head head"
      "cur  nav  stage"
      "note note note";
    column-gap: clamp(24px, 3vw, 52px);
    overflow: hidden;
    padding: clamp(84px, 10vh, 116px) clamp(24px, 3.4vw, 56px) clamp(28px, 4vh, 44px);
  }
  html.js .hm .results-chapter.is-pinned .chapter-top { grid-area: top; }
  html.js .hm .results-chapter.is-pinned .results-heading {
    grid-area: head;
    padding: clamp(16px, 2.6vh, 34px) 0 clamp(16px, 2.4vh, 26px);
  }
  /* the case currently on stage, named large in the once-empty corner */
  html.js .hm .results-chapter.is-pinned .result-current {
    grid-area: cur;
    align-self: end;
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding-bottom: 6px;
  }
  html.js .hm .results-chapter.is-pinned .result-current .micro { color: var(--sage-text-light); }
  html.js .hm .results-chapter.is-pinned .result-current em {
    max-width: 9ch;
    font-family: var(--script);
    font-style: italic;
    font-weight: 400;
    font-size: clamp(34px, 3.4vw, 56px);
    line-height: 1.04;
    letter-spacing: -.02em;
    color: var(--salmon);
    text-wrap: balance;
    animation: result-current-in .6s var(--ease) both;
  }
  /* the pair becomes a single full-frame comparison */
  html.js .hm .results-chapter.is-pinned .result-stage {
    grid-area: stage;
    height: min(50svh, 560px);
    width: auto;          /* derived from the 4:3 aspect-ratio */
    max-width: 100%;
    align-self: end;
    margin-left: 0;
  }
  html.js .hm .results-chapter.is-pinned .result-case { display: block; }
  html.js .hm .results-chapter.is-pinned .result-case figure {
    position: absolute;
    inset: 0;
    border-right: 0;
  }
  html.js .hm .results-chapter.is-pinned .result-case figure:nth-child(2) {
    clip-path: inset(0 calc(100% - var(--wipe, 0) * 1%) 0 0);
  }
  /* each label sits over its own image region: BEFORE rides the
     un-wiped right side, AFTER arrives with the reveal on the left */
  html.js .hm .results-chapter.is-pinned .result-case figure:first-child figcaption {
    left: auto;
    right: 16px;
  }
  /* the wipe seam — fades out at either end of its run */
  html.js .hm .results-chapter.is-pinned .result-case.is-active::after {
    content: "";
    position: absolute;
    z-index: 3;
    top: 0;
    bottom: 0;
    left: calc(var(--wipe, 0) * 1%);
    width: 1px;
    background: rgba(239, 233, 222, .9);
    opacity: min(calc(var(--wipe, 0) / 6), calc((100 - var(--wipe, 0)) / 6), 1);
    pointer-events: none;
  }
  /* the tab bar becomes a vertical 01/02/03 rail running down the
     side of the photo — scroll drives it, a click jumps to the case */
  html.js .hm .results-chapter.is-pinned .result-nav {
    grid-area: nav;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: clamp(18px, 3.2vh, 34px);
    width: auto;
    margin: 0 0 6px;
  }
  html.js .hm .results-chapter.is-pinned .result-tab {
    display: block;
    min-height: 0;
    padding: 0 0 0 16px;
    border-top: 0;
    text-align: left;
  }
  html.js .hm .results-chapter.is-pinned .result-tab b {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  html.js .hm .results-chapter.is-pinned .result-tab::before {
    top: 50%;
    left: 0;
    width: 2px;
    height: 26px;
    transform: translateY(-50%) scaleY(0);
    transform-origin: center top;
  }
  html.js .hm .results-chapter.is-pinned .result-tab[aria-selected="true"]::before {
    transform: translateY(-50%) scaleY(1);
  }
  html.js .hm .results-chapter.is-pinned .results-note {
    grid-area: note;
    width: 100%;
    margin: 14px 0 0;
  }

  @keyframes result-current-in {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: none; }
  }
}

/* ============================================================
   TRANSFORMATIONS — the Dentéa move applied to before/after.
   The heading holds still at the top of the frame while the
   comparison cards travel up through it in a staggered column,
   so the eye reads one outcome at a time instead of a grid.

   Each card is a real slider (an <input type=range> sits over
   the image), so it works on keyboard and reads correctly to a
   screen reader — a div with a drag handler would do neither.
   ============================================================ */
.hm .tx-chapter {
  position: relative; overflow: visible;
  /* keep .home-chapter's horizontal gutter — zeroing all padding let the
     cards and the italic note run off both edges of the viewport */
  padding: 0 clamp(24px, 3.4vw, 56px);
}

.hm .tx-head {
  /* z-index above the cards: the heading and the note must never be sat
     on by a photograph. Light type over a client photo is exactly the
     contrast failure this build has already been bitten by. */
  position: sticky; top: 0; z-index: 3;
  height: 100svh; padding: clamp(84px, 11vh, 132px) 0 0;
  pointer-events: none;                 /* cards below stay draggable */
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-content: start;
  gap: 0 clamp(24px, 5vw, 80px);
}
/* No scrim and no mask. The heading simply stops being sticky before the
   cards climb into it — .tx-headwrap is shorter than the track, and a
   sticky child releases when its containing block ends. The type leaves
   the way any other content leaves, which reads as deliberate rather
   than as a photograph dissolving. */
.hm .tx-headwrap { position: relative; height: 165vh; pointer-events: none; }
.hm .tx-head .chapter-top { grid-column: 1 / -1; margin-bottom: clamp(28px, 5vh, 60px); }
.hm .tx-head .chapter-title { grid-column: 1; margin: 0; max-width: 9ch; }
.hm .tx-note {
  grid-column: 2; justify-self: end; align-self: start;
  max-width: 30ch; margin: 0; text-align: right;
  font-family: var(--script); font-style: italic; font-weight: 400;
  font-size: clamp(19px, 1.7vw, 27px); line-height: 1.25;
  color: rgba(33, 29, 24, .74);
}

/* the flow is pulled back over the sticky head so the cards pass
   through the same frame the heading occupies */
.hm .tx-flow {
  position: relative; z-index: 2;
  margin-top: -165vh;
  padding: 92vh 0 24vh;   /* the heading gets a clear beat before the first card arrives */
  /* NB: masking this element does not work — it is the full height of the
     track, so a vh-based mask lands once near its top instead of at the
     viewport edge. The type band is protected by .tx-head::before instead. */
  display: flex; flex-direction: column;
  gap: clamp(120px, 22vh, 260px);
}

/* staggered: left, right, centre — the Dentéa rhythm */
.hm .tx-card { margin: 0; width: min(22vw, 285px); }
.hm .tx-card:nth-child(3n+1) { align-self: flex-start; }
.hm .tx-card:nth-child(3n+2) { align-self: flex-end; }
.hm .tx-card:nth-child(3n)   { align-self: center; width: min(25vw, 325px); }

.hm .tx-compare {
  position: relative; overflow: hidden;
  border-radius: var(--image-radius, 4px);
  background: rgba(33, 29, 24, .06);
  line-height: 0;
}
.hm .tx-compare img { display: block; width: 100%; height: auto; }
/* the after frame is clipped to the right of the divider */
.hm .tx-after {
  position: absolute; inset: 0;
  clip-path: inset(0 0 0 var(--p, 50%));
}
.hm .tx-line {
  position: absolute; top: 0; bottom: 0; left: var(--p, 50%);
  width: 1px; margin-left: -.5px; background: rgba(255, 255, 255, .92);
  box-shadow: 0 0 0 1px rgba(33, 29, 24, .12);
  pointer-events: none;
}
.hm .tx-line i {
  position: absolute; top: 50%; left: 50%;
  width: 10px; height: 34px; margin: -17px 0 0 -5px;
  border-radius: 999px; background: #fff;
  box-shadow: 0 2px 10px rgba(33, 29, 24, .28);
}
/* the range is the control: invisible, full-bleed, keyboard-native */
.hm .tx-range {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; padding: 0; border: 0; background: transparent;
  -webkit-appearance: none; appearance: none;
  cursor: ew-resize; touch-action: pan-y;   /* vertical scroll still works */
}
.hm .tx-range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 44px; height: 100%; /* 44px touch target */
  background: transparent; cursor: ew-resize;
}
.hm .tx-range::-moz-range-thumb {
  width: 44px; height: 100%; border: 0; background: transparent; cursor: ew-resize;
}
.hm .tx-range:focus-visible { outline: 2px solid var(--salmon); outline-offset: 3px; }

.hm .tx-card figcaption {
  margin-top: 12px;
  font-family: var(--script); font-style: italic;
  font-size: clamp(14px, 1.1vw, 18px);
  color: rgba(33, 29, 24, .78);
}
.hm .tx-disclaim {
  position: relative; z-index: 2;
  margin: 0 0 clamp(40px, 7vh, 90px); text-align: center;
  color: rgba(33, 29, 24, .5);
}

/* phone / tablet: no pin, no stagger — one column, full width */
@media (max-width: 1024px) {
  .hm .tx-headwrap { height: auto; pointer-events: auto; }
  .hm .tx-head {
    position: static; height: auto; padding: 0; pointer-events: auto;
    grid-template-columns: 1fr;
  }
  .hm .tx-head .chapter-title { grid-column: 1; max-width: 14ch; }
  .hm .tx-note {
    grid-column: 1; justify-self: start; text-align: left;
    max-width: 40ch; margin-top: 20px;
  }
  .hm .tx-flow {
    margin-top: 0; padding: clamp(40px, 8vh, 72px) 0 0;
    gap: clamp(54px, 9vh, 92px);
  }
  .hm .tx-card,
  .hm .tx-card:nth-child(3n) { width: 100%; align-self: stretch; }
}

/* ============================================================
   CONCERNS CHAPTER — type pass, measured against the Dentéa reference.

   Dentéa runs on two faces and an opacity ladder, nothing else:
     display  Instrument Serif, ONE weight (400), line-height .90,
              negative tracking that grows with size
     label    Tabular 13px / 600 / uppercase / letter-spacing -.512px
     rank     1.0 · .8 · .64 · .48 · .36 · .24

   Its small type is mono caps too — the same tool as ours. What makes
   theirs readable and ours not is weight 600 and NEGATIVE tracking;
   ours was 500 with +1.8px, which opens caps up until they stop
   reading as words. Matching the mechanism, not swapping the face.
   ============================================================ */

/* label ladder: the number recedes, the chapter name holds full ink.
   Shared with chapter 04's head — one ladder, so the two cannot drift. */
.hm .solution-top .sx-label,
.hm .tx-head .sx-label {
  display: inline-flex; align-items: baseline; gap: 14px;
  font-family: var(--mono, 'JetBrains Mono', monospace);
  font-size: 13px; font-weight: 600; text-transform: uppercase;
  letter-spacing: -.01em;              /* was +1.8px — that was the problem */
  color: var(--ivory, #211D18);
}
.hm .solution-top .sx-label i,
.hm .tx-head .sx-label i {
  font-style: normal; font-weight: 600;
  color: rgba(33, 29, 24, .48);        /* Dentéa dims the index, not the name */
  padding-right: 14px;
  border-right: 1px solid rgba(33, 29, 24, .18);
}
.hm .solution-top > span:last-child,
.hm .tx-head .chapter-top > span:last-child {
  font-size: 13px; font-weight: 600; letter-spacing: -.01em;
  color: rgba(33, 29, 24, .48);
}

/* quote: lifted, and given room for its descenders. Not .90 like the
   reference — Instrument Serif has shallow descenders and PP Editorial
   italic does not; at .98 the "y" of "why" was already colliding. */
.hm #solution-title {
  line-height: 1.04;
  letter-spacing: -.028em;             /* negative, scaling with size */
  margin-top: clamp(-30px, -2.4vh, -12px);
}
.hm #solution-title em {
  font-style: italic; color: var(--salmon);   /* locked brand accent — salmon-deep reverted 24 Aug */
}

/* body: same face, fixed mechanics — bigger, heavier, tighter, darker */
.hm .solution-note p {
  font-family: var(--mono, 'JetBrains Mono', monospace);
  font-size: 13px; font-weight: 600; line-height: 1.5;
  letter-spacing: -.01em; text-transform: uppercase;
  color: rgba(33, 29, 24, .8);         /* up from .72 */
  max-width: 30ch;
}

/* list: condensed, and on the reference's ladder rather than a guess */
.hm .solution-list .solution-link { padding-block: clamp(4px, .55vh, 8px); }
.hm .solution-name { line-height: 1.1; letter-spacing: -.02em; }
.hm .solution-link:not(.is-active) { opacity: .48; }   /* was .38 */
.hm .solution-link.is-active { opacity: 1; }

/* the list belongs against the image, not floating in the middle of the
   field. Dentéa sets its block hard against the photo's left edge with the
   items still left-aligned inside it — the void stays on the LEFT, under
   the quote, which is what carries the eye down before it moves right. */
@media (min-width: 1025px) {
  .hm .solution-main {
    grid-template-columns: minmax(280px, 1.15fr) minmax(230px, .42fr) minmax(380px, .92fr);
  }
  .hm .solution-list {
    justify-self: end;          /* block sits against the photo */
    text-align: left;           /* items stay left-aligned inside it */
    width: 100%;
    max-width: 320px;
  }
}

/* ============================================================
   BEFORE AND AFTER — type pass, same mechanism as chapter 02.

   Everything small in this chapter was still on the house .micro
   default (12px / 500 / +.15em). That is the exact setting the
   concerns pass replaced: positive tracking on mono caps opens the
   letters until they stop reading as words. Matched to the ladder
   above — 13 / 600 / -.01em — rather than given its own values.

   The note was the other outlier. PP Editorial italic at 27px is an
   accent face doing body-copy work, and it was heavier than the
   statement it sits opposite; the reference puts a quiet mono block
   there and lets the void carry the weight instead.
   ============================================================ */

/* note: mono like every other note on the page. The block is pulled
   to the right edge, the lines stay left-aligned inside it — same
   move as the concerns list against its photo. */
.hm .tx-note {
  font-family: var(--mono, 'JetBrains Mono', monospace);
  font-style: normal; font-weight: 600;
  font-size: 13px; line-height: 1.5;
  letter-spacing: -.01em; text-transform: uppercase;
  color: rgba(33, 29, 24, .8);
  max-width: 30ch; text-align: left;
}

/* the statement's accent word: --salmon-deep, the value the concerns
   pass moved to. --salmon is the lighter tint and it is sitting on
   cream here, which is the thinnest contrast on the chapter. */
.hm .tx-head .chapter-title em { color: var(--salmon);   /* locked brand accent — salmon-deep reverted 24 Aug */ }

/* caption: the concern name is a label, not an aside — same ladder,
   full ink rank. Script italic made it read as a footnote. */
.hm .tx-card figcaption {
  margin-top: 14px;
  font-family: var(--mono, 'JetBrains Mono', monospace);
  font-style: normal; font-weight: 600;
  font-size: 13px; line-height: 1.35;
  letter-spacing: -.01em; text-transform: uppercase;
  color: rgba(33, 29, 24, .8);
}

/* disclaimer: on the ladder, but NOT on the .48 index rank. That rank
   measures 2.95:1 on cream — under AA for 13px text — which is fine for
   a decorative index and not fine for a required disclosure. .64 is the
   first step that clears 4.5:1 (measures 4.68). */
.hm .tx-disclaim {
  font-size: 13px; font-weight: 600;
  letter-spacing: -.01em;
  color: rgba(33, 29, 24, .64);
}

/* one column: .tx-flow loses its bottom padding, so the disclaimer was
   landing 18px under the last caption and reading as part of it */
@media (max-width: 1024px) {
  /* the tilt layer centres the whole head block; one column does not.
     .tx-disclaim kept the base centring after the title and note were
     reset to start, so it sat off-axis under a left-aligned column. */
  .hm .tx-disclaim { margin-top: clamp(28px, 5vh, 44px); text-align: left; max-width: 34ch; }
}

/* ============================================================
   CONCERNS CHAPTER, MATCHED TO TREATMENTS — 21 Aug 2026

   Requested: "can we make the concerns the same as the treatments".
   Chapter 02 was running its own grammar — PP Editorial italic for
   the statement, mono caps for the note, a bare display list with no
   numbers or rules, and a floating rounded photo card with a caption
   under it. Chapter 03 is the Dentea composition: display roman
   statement, sentence-case note, a numbered mono list on hairlines,
   and a photo that IS the panel, bleeding off the right and bottom.

   This brings 02 onto 03's grammar. The ground stays putty — the
   pine/putty alternation is what separates the chapters, and only
   the layout was asked about. Say the word if the ground should
   flip too.
   ============================================================ */

/* 1. the statement: chapter 03's face, scaled to lead this chapter.
   The fluid range keeps the three-line composition while restoring
   enough presence for the statement to read as the section headline. */
.hm .solution-copy h2 {
  font-family: var(--display);
  font-style: normal;
  font-size: clamp(28px, 3.5vw, 54px);
  line-height: 1.02;
  letter-spacing: -.03em;
  max-width: 19ch;
  margin-top: 0;
}
.hm .solution-copy h2 em {
  font-family: var(--script); font-style: italic;
  color: var(--salmon);   /* locked brand accent — salmon-deep reverted 24 Aug */
}

/* 2. the note: chapter 03 sets a 15px sentence-case paragraph, not the
      mono caps block the type pass gave this chapter */
.hm .solution-note p {
  font-family: inherit;
  font-size: 15px; font-weight: 400; line-height: 1.58;
  letter-spacing: normal; text-transform: none;
  color: rgba(33, 29, 24, .72);
  max-width: 38ch;
}

/* 3. the list: numbered rows on hairlines, mono names — .treatment-line */
.hm .solution-list .solution-link {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: 14px; align-items: center;
  min-height: clamp(68px, 8vh, 84px);
  padding: 0;
  border-bottom: 1px solid rgba(33, 29, 24, .18);
  opacity: 1;                       /* the ladder is colour here, not opacity */
  color: rgba(33, 29, 24, .5);
  transition: color .28s, transform .4s var(--ease);
}
.hm .solution-list { border-top: 1px solid rgba(33, 29, 24, .18); }
.hm .solution-link:hover,
.hm .solution-link:focus-visible,
.hm .solution-link.is-active { color: var(--ink); transform: translateX(6px); }
.hm .solution-num { color: rgba(33, 29, 24, .42); font-size: 12px; }
.hm .solution-go { font-size: 13px; }
.hm .solution-name {
  font-family: var(--mono);
  font-size: 13px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase;
  line-height: 1.2; color: inherit;
}
/* the auto-cycle underline still runs, but on the row's own rule */
.hm .solution-link::after { bottom: -1px; background: rgba(33, 29, 24, .5); }

/* 4. the photo. NOT the bleeding panel that 03 uses — chapter 03 owns
      the big picture, and two full-bleed photographs back to back give
      the scroll no change in pressure. 02's stays a contained plate,
      right-aligned, and visibly the smaller of the two: roughly
      360x400 against 03's 500x666 at 1440. The caption comes back with
      it, since there is page left underneath again. */
@media (min-width: 1025px) {
  .hm .solution-frame {
    width: min(100%, clamp(280px, 25vw, 400px));
    aspect-ratio: 9 / 10;
    height: auto; min-height: 0;
    margin: 0 0 0 auto;
    border-radius: var(--image-radius);
  }
  .hm .solution-media { align-self: end; }
  .hm .solution-caption { display: flex; width: min(100%, clamp(280px, 25vw, 400px)); margin-left: auto; }
  /* the guide sits as a quiet label over the list, the way 03's list
     starts flush under its rule */
  .hm .solution-guide { margin-bottom: 10px; }
}

/* mobile keeps the thumb in column one; the number is a desktop device */
@media (max-width: 1024px) {
  .hm .solution-num { display: none; }
  .hm .solution-list .solution-link {
    grid-template-columns: 58px minmax(0, 1fr) auto;
    min-height: 87px; padding: 9px 0;
  }
  .hm .solution-name { font-size: 12px; letter-spacing: .12em; }
  /* Keep the statement clearly above body copy without forcing a
     compressed desktop treatment onto smaller screens. */
  .hm .solution-copy h2 { font-size: clamp(30px, 7.5vw, 38px); max-width: 20ch; }
}

/* corrections from the first render of the match:

   - the note inherited mono, because .solution-note also carries the
     .micro class; inherit was picking that up rather than the body face
   - .solution-frame kept `margin-left:auto` from the card layout, so at
     width:auto in a flex parent it shrank to zero and the photo vanished
   - concern names are long ("PIGMENTATION AND MELASMA") where treatment
     names are one or two words, so the list column needs the room that
     the bleeding photo no longer takes */
.hm .solution-note p { font-family: var(--sans); }

@media (min-width: 1025px) {
  .hm .solution-media { min-width: 0; }
  .hm .solution-main {
    grid-template-columns: minmax(280px, .84fr) minmax(320px, .74fr) minmax(360px, .86fr);
  }
}

/* the two chapters' label rows have to match as well — 03 was still on
   the house .micro default. On pine the ladder needs the light stops:
   ink at .48 is invisible there. */
.hm .treatments-chapter .sx-label {
  display: inline-flex; align-items: baseline; gap: 14px;
  font-family: var(--mono); font-size: 13px; font-weight: 600;
  text-transform: uppercase; letter-spacing: -.01em;
  color: var(--putty);
}
.hm .treatments-chapter .sx-label i {
  font-style: normal; font-weight: 600;
  color: var(--sage-text-dark);
  padding-right: 14px;
  border-right: 1px solid rgba(239, 233, 222, .22);
}
.hm .treatments-chapter .chapter-top > span:last-child {
  font-size: 13px; font-weight: 600; letter-spacing: -.01em;
  color: var(--sage-text-dark);
}

/* Two sentences, so the line break belongs at the full stop. Left to
   wrap on its own the measure put it mid-sentence — "has a story. Let's"
   — which orphans the second sentence from its own verb. Each sentence
   is its own block, balanced, so a narrow column breaks sentence one
   evenly instead of stranding "story." on a line by itself. */
.hm #solution-title .sx-s { display: block; text-wrap: balance; }
.hm .solution-copy h2 { max-width: min(100%, 24ch); }

/* ============================================================
   BEFORE AND AFTER — SCALE. 23 Aug 2026

   Measured at 1990x900 before this block:
     chapter height   2900px = 3.22 screens
     card width       285px  = 14% of the viewport
     cards as a share of the chapter's area:  7.5%

   Ninety-two percent of the one section whose entire job is
   "look at the result" was empty cream, and the result itself
   was thumbnail-sized. The travel-through-the-heading idea is
   fine; the scale was wrong.

   The track length and the flow's negative pull are the same
   number and were written out twice — one --tx-track variable
   now, so they cannot drift apart again.
   ============================================================ */
@media (min-width: 1025px) {
  .hm .tx-chapter { --tx-track: 108vh; }
  .hm .tx-headwrap { height: var(--tx-track); }
  .hm .tx-flow { margin-top: calc(-1 * var(--tx-track)); }
}

/* Height-bound as well as width-bound. The source frames are 2:3, so a
   560px card is 836px tall — taller than a 900px window once the nav is
   counted, and a before/after you cannot see both halves of at once has
   stopped being a comparison. 52vh keeps the whole card on screen. */
/* desktop only. Unscoped, these overrode the one-column mobile rule
   above and 38vw took the cards down to 143px wide on a phone — the
   fix for a too-small card, making the card smaller. */
@media (min-width: 1025px) {
  .hm .tx-card { width: min(38vw, 52vh, 560px); }
  .hm .tx-card:nth-child(3n) { width: min(42vw, 54vh, 620px); }
  .hm .tx-flow { padding: 42vh 0 11vh; gap: clamp(52px, 6.5vh, 96px); }
}

/* "Wells" joins "Street." — the street name is one proper noun, so the
   accent colour should not stop halfway through it. Colour only: the
   italic stays on Street. so the face change still marks the cadence.
   --salmon-deep, not --salmon: the light tint is 2.27:1 on putty, under
   the 3.0 large-text floor. Same move chapters 02 and 04 made. */
.hm .chapter-title .ac-word,
.hm .visit-chapter .chapter-title em { color: var(--salmon);   /* locked brand accent — salmon-deep reverted 24 Aug */ }

/* The stagger needs a measure of its own. Across a 1990px viewport the
   left-then-right rhythm throws the cards ~1400px apart and the eye
   crosses an empty field between each one; the diagonal only reads as
   rhythm when the two extremes are close enough to hold together. */
@media (min-width: 1025px) {
  .hm .tx-flow { max-width: 1180px; margin-left: auto; margin-right: auto; }
}

/* ============================================================
   03 + 04, THE DENTÉA PASS — 23 Aug 2026

   Reference: .qa/shots/dentea-list.png. Its grammar for a chapter:
   an italic serif statement top-left, the ACTIVE item's name set
   huge beside the photo, the list demoted to small mono rows, the
   active item's index ghosted large in the void, and the photo
   holding the right side full-height. And its motion: the chapter
   pins while scroll steps through the items.

   03 already had the pin; it gets the composition. 04 had neither;
   it gets both. Everything below is desktop-only — mobile,
   reduced-motion and no-JS keep the flows that already measure
   clean at 375.
   ============================================================ */
@media (min-width: 1025px) {
  /* ---- 03: statement in the reference's register ----
     This was the only chapter statement running the script face for the
     whole line. Every other one — results, shop, team, consult, visit —
     is the display face with the accent word alone in PP Editorial
     italic and salmon, which is the house pattern the accents commit
     (cd2fbad). Face and slope removed so it inherits .chapter-title;
     the <em> keeps the italic and the salmon from the base rule.
     Tracking goes to the -.04em display floor to match the others. */
  .hm .treatments-intro .chapter-title {
    font-weight: 400;
    font-size: clamp(26px, 2.2vw, 38px);
    line-height: 1.16;
    letter-spacing: -.04em;
    max-width: 26ch;
  }
  .hm .treatments-intro .chapter-title em { color: var(--salmon); }
  .hm .treatments-intro p { max-width: 32ch; }

  .hm .treatments-stage { grid-template-rows: auto; }
  .hm .treatments-stage .treatment-lines { grid-column: 1; grid-row: 1; order: 0; }
  .hm .treatments-stage .treatment-image { grid-column: 2; grid-row: 1; }

  /* the active index, ghosted in the bottom-left void — the reference's
     "02". Bone at .14 on pine: deliberately below reading contrast,
     it is a texture, not a label; the real index sits in the list. */
  .hm .t-foot { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
  .hm .t-index {
    display: block;
    font-family: var(--script); font-style: italic;
    font-size: clamp(88px, 8.5vw, 150px);
    line-height: .82;
    color: rgba(239, 233, 222, .14);
    user-select: none;
    transition: opacity .4s var(--ease);
  }

  /* ---- 04: the Ocha move (ocha.framer.website, reviews section).
     Measured on the live site at 1440: the heading layer holds, six
     cards in two edge columns scroll past it at exactly 1:1 — no
     parallax — and each card ENTERS TILTED and straightens as it
     rises: ±30° below the fold, ~20° at 86% of the viewport, 6–9° at
     70%, flat by 55%. The rotation is the whole effect. Ours: three
     cards, ±14° (a client photograph at 30° reads as a mistake the
     way a review card does not), same settle curve.
     .is-tilt is added by home-motion.js on desktop, non-reduced. ---- */
  html.js .hm .tx-chapter.is-tilt {
    padding: 0;
    overflow: visible;
  }
  html.js .hm .tx-chapter.is-tilt .tx-pin {
    position: sticky; top: 0; height: 100svh; z-index: 1;
    display: flex; flex-direction: column;
    padding: clamp(84px, 10vh, 120px) clamp(24px, 3.4vw, 56px) clamp(20px, 3vh, 34px);
    pointer-events: none;
  }
  html.js .hm .tx-chapter.is-tilt .tx-headwrap { height: auto; flex: 1; display: flex; flex-direction: column; pointer-events: none; }
  html.js .hm .tx-chapter.is-tilt .tx-head {
    position: static; height: auto; padding: 0; flex: 1;
    display: flex; flex-direction: column; align-items: center; text-align: center;
  }
  html.js .hm .tx-chapter.is-tilt .tx-head .chapter-top {
    align-self: stretch; display: flex; justify-content: space-between;
    text-align: left; margin: 0;
  }
  /* the statement sits in the middle of the held screen, the cards
     cross over it. Under the display ceiling (96px) — it is a statement
     the cards pass, not the reference's poster word. */
  html.js .hm .tx-chapter.is-tilt .tx-head .chapter-title {
    margin: auto 0 0; max-width: 12ch;
    font-size: clamp(56px, 6.6vw, 96px); line-height: .92;
  }
  html.js .hm .tx-chapter.is-tilt .tx-note {
    margin: clamp(18px, 3vh, 30px) 0 auto; text-align: center; max-width: 34ch;
  }
  html.js .hm .tx-chapter.is-tilt .tx-disclaim { margin: 0; text-align: center; }

  /* the cards: normal flow, pulled up over the held layer, two edge
     columns with the right one riding ~90px higher, like the reference */
  html.js .hm .tx-chapter.is-tilt .tx-flow {
    position: relative; z-index: 2;
    /* cards begin at 92% of the held screen, so the FIRST pair tilt in
       with the heading already pinned — at 18vh they were flat before
       the pin engaged and only the third card ever did the move */
    margin: calc(-100svh + 92vh) auto 0;
    padding: 0 clamp(24px, 3.4vw, 56px) 22vh;
    max-width: 1240px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 0; row-gap: clamp(120px, 24vh, 260px);
    align-items: start;
  }
  html.js .hm .tx-chapter.is-tilt .tx-card {
    width: min(30vw, 440px);
    margin: 0;
    background: var(--bg-2);
    padding: 12px 12px 16px;
    border-radius: 28px;
    box-shadow: 0 30px 70px -30px rgba(33, 29, 24, .34);
    transform-origin: 50% 50%;
    will-change: transform;
    /* the transition is only for the hover lift; scroll writes the
       rotation directly so it tracks the wheel one-to-one */
    transition: none;
  }
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(3n+1) { grid-column: 1; justify-self: start; align-self: start; }
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(3n+2) { grid-column: 2; justify-self: end; margin-top: -90px; align-self: start; }
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(3n)   { grid-column: 1; justify-self: start; align-self: start; width: min(30vw, 440px); }
  html.js .hm .tx-chapter.is-tilt .tx-compare { border-radius: 18px; }
  html.js .hm .tx-chapter.is-tilt .tx-card figcaption { margin: 12px 6px 0; }
  html.js .hm .tx-chapter.is-tilt .tx-card figcaption i { color: rgba(33, 29, 24, .42); }
  html.js .hm .tx-chapter.is-tilt .tx-card figcaption b { display: inline; }
}

/* the ghost index is a desktop device; the slide index inside the
   caption reads as a small mono prefix in the normal flow */
@media (max-width: 1024px) {
  .hm .t-index { display: none; }
}
.hm .tx-card figcaption i {
  font-style: normal; font-weight: 500;
  margin-right: 14px; padding-right: 14px;
  border-right: 1px solid rgba(33, 29, 24, .18);   /* the hairline the chapter kickers use */
  color: rgba(33, 29, 24, .48);
}
.hm .tx-card figcaption b { font-weight: inherit; }

/* tilt layer, two corrections off the first render:
   - the note inherited align-self:start from its old grid placement and
     sat against the left edge inside a centred flex column
   - the disclaimer ran ~560px wide across the bottom and the edge cards
     covered both ends of it; at 34ch it sits inside the clear centre */
@media (min-width: 1025px) {
  html.js .hm .tx-chapter.is-tilt .tx-note { align-self: center; justify-self: auto; }
  html.js .hm .tx-chapter.is-tilt .tx-disclaim { max-width: 34ch; margin: 0 auto; line-height: 1.5; }
}

/* which treatment made the result — a link to its page, under the
   case name. Sentence-case, not the caption's mono caps: it is a
   second fact, one step down the ladder. */
.hm .tx-card .tx-rx {
  display: flex; align-items: center; min-height: 44px; margin-top: 6px;
  font-family: var(--display); font-size: clamp(18px, 1.4vw, 22px); font-weight: 500;
  letter-spacing: -.015em; text-transform: none; line-height: 1.25;
  color: var(--ink);
  text-decoration: underline; text-decoration-color: rgba(33, 29, 24, .38);
  text-underline-offset: 4px; text-decoration-thickness: 1px;
  transition: color .25s, text-decoration-color .25s;
}
.hm .tx-card .tx-rx:hover, .hm .tx-card .tx-rx:focus-visible { color: var(--ink); text-decoration-color: var(--ink); outline: 0; }
.hm .tx-card .tx-rx span { font-size: 14px; margin-left: 4px; }

/* Contact details remain comfortably tappable even when the text itself
   occupies only one line. */
.hm .address-block p a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
@media (min-width: 1025px) {
  html.js .hm .tx-chapter.is-tilt .tx-card figcaption { margin: 12px 6px 2px; }
}

/* four cases now: columns alternate odd/left, even/right — the 3n
   pattern above was written for three and would have stacked 1, 3
   and 4 on the left */
@media (min-width: 1025px) {
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(odd)  { grid-column: 1; justify-self: start; margin-top: 0; width: min(30vw, 440px); }
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(even) { grid-column: 2; justify-self: end; margin-top: -90px; width: min(30vw, 440px); }
}

/* A right-column card at 14° has a ~611px bounding box and crossed the
   viewport edge, which opened a sideways scroll (measured: scrollWidth
   > innerWidth at 1440 while card 4 was still tilted). overflow-x:clip
   cuts the paint without making the chapter a scroll container, so the
   sticky heading layer keeps working — overflow:hidden would break it. */
html.js .hm .tx-chapter.is-tilt { overflow-x: clip; }

/* ============================================================
   02 — BACK TO THE LOCKED DENTÉA GRAMMAR. 23 Aug 2026.
   Against the marked-up screenshot at 1990x900:
     - statement floated 95px under the kicker      → flush, ~28px
     - list sat 287px off the photo                 → against it
     - photo floated 65px up with a caption under   → flush bottom, bleeds right
     - quiz CTA / list CTA 38px up                  → on the bottom line
   Statement measure 17ch so it sets three lines, breaking after
   "concern" as marked. Photo stays the smaller of the two chapters
   (58vh against 03's 74vh) — that was locked earlier today.
   ============================================================ */
@media (min-width: 1025px) {
  .hm .solution-copy { padding-top: 0; }
  .hm .solution-main {
    padding: calc(clamp(30px, 4.4vh, 44px) + 40px) 0 0;
    grid-template-columns: minmax(280px, 1fr) auto auto;
    gap: clamp(24px, 3vw, 48px);
    align-items: end;
  }
  .hm .solution-copy h2 { max-width: 17ch; margin-top: 0; }
  .hm .solution-list { justify-self: end; max-width: 340px; }
  .hm .solution-list .all-concerns { margin-bottom: 0; }
  .hm .solution-media { align-self: end; display: block; }
  .hm .solution-frame {
    width: clamp(300px, 23vw, 420px);
    height: 58vh; min-height: 0; aspect-ratio: auto;
    margin: 0 calc(-1 * clamp(24px, 3.4vw, 56px)) 0 0;   /* the grid already meets the bottom line; -30 was clipping 28px of photo */
    border-radius: var(--image-radius) 0 0 0;
  }
  .hm .solution-caption { display: none; }
}

/* 03 statement, sized off the site scale instead of a one-off clamp.
   base.css ladder: --t-6 page display · --t-5 section display ·
   --t-4 section heading. A chapter statement is section display:
   --t-5 = clamp(2.15rem, 4.4vw, 3.75rem) → 63px at 1440, 60px max.
   The 1.12 optical compensation that used to sit here existed only
   because the whole line was set in the italic, whose x-height runs
   small. The line is the display face now, which needs no correction,
   so the statement sits on the ladder step itself. The <em> still gets
   the compensation from the accent rule — that is where it belongs. */
@media (min-width: 1025px) {
  .hm .treatments-intro .chapter-title {
    font-size: var(--t-5);
    line-height: 1.06;
    max-width: 16ch;
  }
}

/* breathe at the top: the kicker sat inside the chapter's minimum pad;
   the pinned screen gets a deeper head so 02 | SKIN CONCERNS and the
   statement hang clear of the nav */
@media (min-width: 1025px) {
  .hm .solution-screen { padding-top: calc(clamp(110px, 14vh, 152px) + 48px); }   /* +half an inch, 24 Aug */
}

/* the registered mark rides small and raised, not full-size inline */
.hm .tx-rx .rmark{font-size:.62em;line-height:0;vertical-align:super;letter-spacing:0}

/* ============================================================
   THE QUIZ CTA — 25 Aug 2026.
   Single line, like every other button on the site. The two-line
   version put a sans subline under a mono label inside one pill,
   which read as a card with an arrow parked in the leftover space.
   The time now lives in the label, where it costs nothing.
   ============================================================ */
.hm .quiz-cta{
  display:inline-flex;align-items:center;gap:14px;
  min-height:52px;padding:0 8px 0 22px;
  border-radius:999px;white-space:nowrap;width:max-content;max-width:100%;
  background:var(--sage-fill,#858C79);color:var(--ink,#211D18);
  box-shadow:var(--e2,0 2px 4px rgba(33,29,24,.07),0 10px 26px rgba(33,29,24,.09)),
             inset 0 1px 0 rgba(255,255,255,.22);
  text-decoration:none;
  transition:transform .32s var(--ease),box-shadow .32s var(--ease),background .32s var(--ease);
}
.hm .quiz-cta b{
  font-family:var(--mono);font-size:13px;font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;line-height:1;
}
.hm .quiz-cta .qc-orb{
  flex:none;width:36px;height:36px;border-radius:999px;
  display:grid;place-items:center;font-size:13px;
  /* ink at .18 — the .14 orb was sage-on-sage and read as a smudge */
  background:rgba(33,29,24,.18);
  transition:transform .32s var(--ease),background .32s var(--ease);
}
.hm .quiz-cta:hover,.hm .quiz-cta:focus-visible{
  transform:translateY(-2px);outline:0;
  background:var(--sage-label,#4E5442);color:var(--putty,#EFE9DE);
  box-shadow:var(--e3,0 4px 8px rgba(33,29,24,.08),0 20px 44px rgba(33,29,24,.14)),
             inset 0 1px 0 rgba(255,255,255,.14);
}
.hm .quiz-cta:hover .qc-orb,.hm .quiz-cta:focus-visible .qc-orb{
  transform:translate(2px,-1px) scale(1.06);background:rgba(239,233,222,.22);
}
.hm .quiz-cta:active{transform:translateY(0) scale(.985);box-shadow:var(--e1)}
.hm .quiz-cta:focus-visible{outline:2px solid var(--ink);outline-offset:3px}

/* the note's <p> is margin:0 and the CTA is an inline-flex pill carrying no
   margin, so the button sat flush against the last line of copy. --s5 (24px)
   is the ramp's paragraph->control step. Top level on purpose: the first
   attempt went inside @media (max-width:420px) and was a silent no-op at
   every desktop width. */
.hm .solution-note .quiz-cta{margin-top:var(--s5,24px)}

/* the secondary link stops competing: outline, not a second fill */
.hm .all-concerns.is-quiet{
  background:transparent;border-color:rgba(33,29,24,.28);color:var(--ink);
}
.hm .all-concerns.is-quiet:hover,.hm .all-concerns.is-quiet:focus-visible{
  background:transparent;border-color:var(--ink);color:var(--ink);
}
@media (prefers-reduced-motion:reduce){
  .hm .quiz-cta,.hm .quiz-cta .qc-orb{transition:none}
  .hm .quiz-cta:hover{transform:none}
}

/* the note block caps at 34ch for the paragraph's sake; the button was
   inheriting that cap and wrapping its own subline inside 245px. Cap the
   paragraph, free the button. */
.hm .solution-note{max-width:none}
.hm .solution-note p{max-width:34ch}
.hm .quiz-cta{white-space:nowrap;width:max-content;max-width:100%}
.hm .quiz-cta i{white-space:nowrap}
@media (max-width:420px){
  .hm .quiz-cta{padding-left:20px;gap:12px}
  .hm .quiz-cta i{font-size:12px}
}

/* Chapter 04 head, on a phone. `.hm .tx-chapter` zeroes the block
   padding (it exists only to keep the horizontal gutter) and the
   <=1024 rule zeroes .tx-head's padding as well, so the kicker landed
   hard against the top of the section with the pine band directly
   above it. Every other chapter opens on .home-chapter's 88px; this
   one now matches. */
@media (max-width: 1024px) {
  .hm .tx-chapter { padding-top: clamp(72px, 11vh, 104px); }
  .hm .tx-chapter .tx-head .chapter-top { margin-bottom: clamp(18px, 3vh, 30px); }
}

/* ============================================================
   04 — TRANSFORMATIONS, scaled to the Dentéa reference.
   Measured on their section 04:
     wordmark  224px, line-height .80, tracking -.055em, full ink, x=48
     note      48px italic, line-height .90, full ink, right side
     label     13px / 600 / -.512px / ink @ .48
   Ours was 45px and 27px — the scale jump is the whole effect, so the
   display block gets it. Not a literal 224px: theirs is one word
   ("Smiles"), ours is a supplied sentence and must stay one.
   ============================================================ */
.hm .tx-head .chapter-title {
  font-size: clamp(54px, 8.6vw, 124px);
  line-height: .84;
  letter-spacing: -.045em;
  max-width: 11ch;
}
.hm .tx-note {
  font-size: clamp(24px, 3.1vw, 44px);
  line-height: .96;
  letter-spacing: -.012em;
  color: var(--ivory, #211D18);      /* full ink, as the reference */
  max-width: 22ch;
}
.hm .tx-head .sx-label,
.hm .tx-head .chapter-top > span:last-child {
  font-size: 13px; font-weight: 600; letter-spacing: -.01em;
}
@media (max-width: 1024px) {
  .hm .tx-head .chapter-title { font-size: clamp(38px, 10vw, 62px); max-width: 14ch; }
  .hm .tx-note { font-size: clamp(19px, 4.4vw, 26px); max-width: 34ch; }
}

/* --- 04 head: back to the reference composition -------------------
   The head had been changed to centred flex with the note in mono
   uppercase; at the reference's display size that reads as a wall of
   caps. Dentéa puts the wordmark hard left and the italic note on the
   right, both full ink, and its note is the script face, not the label
   face. Restoring that split. -------------------------------------- */
@media (min-width: 1025px) {
  .hm .tx-head {
    display: grid !important;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    align-content: start;
    text-align: left !important;
    column-gap: clamp(24px, 5vw, 80px);
  }
  .hm .tx-head .chapter-top { grid-column: 1 / -1; }
  .hm .tx-head .chapter-title {
    grid-column: 1; justify-self: start; text-align: left;
    margin: 0;
  }
  .hm .tx-note {
    grid-column: 2; justify-self: end; text-align: right;
    margin: 0;
  }
}
/* the note is the script face — italic, sentence case, never mono caps */
.hm .tx-note {
  font-family: var(--script, 'PP Editorial New', 'Iowan Old Style', Baskerville, serif) !important;
  font-style: italic !important;
  text-transform: none !important;
  font-weight: 400;
}

/* --- 04 cards: upright, contained, staggered ----------------------
   They had become 588px wide, rotated 14deg and bleeding off both
   edges (x=-29 on the left, 1468 against a 1440 viewport on the
   right). The Dentéa reference does not rotate its transformation
   cards at all — they sit upright and staggered, and the tilt is what
   makes ours read as a scrapbook rather than a clinical result.
   ---------------------------------------------------------------- */
@media (max-width: 1024px) {
  .hm .tx-card { transform: none !important; width: 100% !important; }
}

/* tablet band. 100% was sized for a phone: at 375 the card is 327px and the
   2:3 portrait lands at ~60vh, which is right. The same rule on an iPad
   gives a 954px card and a 1432px image — 105vh in portrait, 179vh in
   landscape — so a single before/after is taller than the screen. Cap it so
   the image keeps landing near 60vh whichever way the tablet is held.
   - floor 601px: no phone reaches that in portrait, so phones are untouched
   - !important: it has to beat the width above, which is itself !important
   - svh not vh: the cap must not resize when a mobile URL bar collapses */
@media (min-width: 601px) and (max-width: 1024px) {
  .hm .tx-card,
  .hm .tx-card:nth-child(3n) { width: min(100%, 46svh, 460px) !important; }
  /* once the card is narrower than the column, the desktop stagger
     (flex-start / flex-end / centre) comes back out of the base rules and
     card 02 jumps to the right edge under a left-aligned head. One column
     keeps one edge. */
  .hm .tx-card:nth-child(3n+1),
  .hm .tx-card:nth-child(3n+2),
  .hm .tx-card:nth-child(3n) { align-self: flex-start; }
}

/* chapter 08 visit: was ~1.9 screens; map carries the cut */
@media (min-width:1025px){
  .hm .visit-chapter{min-height:100svh;padding-block:clamp(74px,9vh,100px) clamp(20px,3vh,34px)}
  .hm .visit-layout{min-height:0;align-items:start}
  .hm .map-shell,.hm .map-shell iframe{min-height:0;height:clamp(240px,32vh,340px)}
  .hm .visit-chapter .chapter-title{font-size:clamp(32px,3.4vw,48px)}
  .hm .visit-chapter li,.hm .visit-chapter li p{font-size:.84rem;line-height:1.4}
}

/* ── chapter 04 · held head, cards rising either side ───────────────────
   One block. Do not append competing overrides above 1025px — edit here. */
@media (min-width:1025px){
  /* the head is one centred column and stays put while the cards travel */
  html.js .hm .tx-chapter.is-tilt .tx-head{
    display:flex !important;flex-direction:column;align-items:center;text-align:center;
  }
  html.js .hm .tx-chapter.is-tilt .tx-head .chapter-top{
    align-self:stretch;display:flex;justify-content:space-between;text-align:left;
  }
  html.js .hm .tx-chapter.is-tilt .tx-head .chapter-title{margin:auto 0 0;max-width:12ch}
  html.js .hm .tx-chapter.is-tilt .tx-note{
    margin:clamp(14px,2.2vh,24px) auto auto;text-align:center;
    max-width:22ch;font-size:clamp(19px,1.4vw,25px);line-height:1.3;
  }

  /* the cards ride the outer edges; the inset clears the 14deg tilt, which
     throws a tall card ~60px past its own box on each side */
  html.js .hm .tx-chapter .tx-flow{
    max-width:none;padding-inline:clamp(70px,7vw,120px);
  }
  html.js .hm .tx-chapter.is-tilt .tx-flow{
    margin-top:calc(-100svh + 62vh);
    row-gap:clamp(70px,11vh,150px);
  }
  html.js .hm .tx-chapter .tx-card{width:min(23vw,340px);max-width:none}
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(odd){grid-column:1;justify-self:start;margin-top:0}
  /* pairs rise together — left and right reach the same level at the same
     time, so no stagger offset on the right column */
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(even){grid-column:2;justify-self:end;margin-top:0}
}

/* chapter 08 · the visit band has to fit one screen */
@media (min-width:1025px){
  .hm .visit-chapter{min-height:100svh;padding-block:clamp(74px,9vh,100px) clamp(20px,3vh,34px)}
  .hm .map-shell,.hm .map-shell iframe{min-height:0;height:clamp(240px,32vh,340px)}
  .hm .visit-chapter .chapter-title{font-size:clamp(32px,3.4vw,48px)}
  .hm .visit-chapter li,.hm .visit-chapter li p{font-size:.84rem;line-height:1.4}
}
@media (min-width:1025px){
  /* the pair sits hard against the outer margins so the held head keeps
     the centre clear; specificity matches the .is-tilt flow rule above */
  html.js .hm .tx-chapter.is-tilt .tx-flow{
    grid-template-columns:auto auto;justify-content:space-between;
    padding-inline:clamp(48px,4.5vw,96px);
  }
  html.js .hm .tx-chapter.is-tilt .tx-card{width:min(21vw,320px)}
}
@media (min-width:1025px){
  /* width has to be set on the nth-child selectors — the older is-tilt
     odd/even rules carry the extra pseudo-class and outrank a plain .tx-card */
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(odd),
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(even){width:min(21vw,330px)}
}
@media (min-width:1025px){
  html.js .hm .tx-chapter.is-tilt .tx-flow{max-width:none;margin-inline:0}
}
@media (min-width:1025px){
  /* statement and note share one box, so they share one left edge —
     a centred note under a left-set heading read as crooked */
  html.js .hm .tx-chapter.is-tilt .tx-head .chapter-title,
  html.js .hm .tx-chapter.is-tilt .tx-note{
    width:min(34vw,540px);max-width:none;margin-inline:0;text-align:left;
  }
  html.js .hm .tx-chapter.is-tilt .tx-note{margin-top:clamp(14px,2.2vh,24px)}
}
@media (min-width:1025px){
  /* centred: statement and note share a box that sits on the page axis */
  html.js .hm .tx-chapter.is-tilt .tx-head .chapter-title,
  html.js .hm .tx-chapter.is-tilt .tx-note{
    width:min(34vw,540px);margin-inline:auto;text-align:center;
  }
}
@media (min-width:1025px){
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(odd),
  html.js .hm .tx-chapter.is-tilt .tx-card:nth-child(even){width:min(24vw,460px)}
}
@media (min-width:1025px){
  /* the map fills its column instead of floating as a small tile — the
     one-screen cap belongs on the band, not on the map */
  .hm .visit-layout{align-items:stretch}
  .hm .map-shell{align-self:stretch;height:auto;min-height:0}
  .hm .map-shell iframe{height:100%;min-height:0}
}

/* ============================================================
   VISIT CHAPTER — compaction pass (27 Aug 2026)
   The band was running well past one screen and the copy column
   used space-between, so every gap was a different size. Three
   corrections, all standard: one spacing rhythm instead of
   distributed slack; the status line demoted out of competition
   with the H2; the seven-row hours run chunked into two columns
   so the column ends with the map rather than dragging past it.
   ============================================================ */
@media (min-width: 1025px) {
  .hm .visit-chapter {
    min-height: 0;
    padding-block: clamp(76px, 8.5vh, 104px) clamp(48px, 6vh, 72px);
  }

  .hm .visit-layout {
    grid-template-columns: minmax(300px, .78fr) minmax(440px, 1.22fr);
    gap: clamp(40px, 5.4vw, 84px);
    align-items: stretch;
    padding-top: clamp(34px, 4.4vh, 52px);
  }

  /* one rhythm, top-aligned — no distributed slack */
  .hm .visit-copy {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: clamp(26px, 3vh, 38px);
    padding-bottom: 0;
  }

  .hm .visit-chapter .chapter-title { font-size: clamp(40px, 4vw, 60px); margin-bottom: 0; }

  .hm .address-block { padding-top: clamp(22px, 2.6vh, 30px); }
  .hm .address-block address { margin: 0 0 16px; font-size: 19px; line-height: 1.4; }
  .hm .address-block p { margin: 0 0 6px; font-size: 13.5px; }
  .hm .address-block .chapter-link { margin-top: 20px !important; }

  .hm .hours-block { margin-top: 0; padding-top: clamp(22px, 2.6vh, 30px); border-top: 1px solid var(--line); }
  .hm .hours-label { margin-bottom: 10px; }

  /* was competing with the H2 at 22px caps — a status, not a headline */
  .hm .hours-status {
    margin: 0 0 14px;
    font-size: 13px;
    letter-spacing: .12em;
    color: var(--ink);
  }

  /* seven rows chunked to four: reads down column one, then column two */
  .hm .hours-list {
    display: grid;
    grid-template-columns: repeat(2, max-content);
    grid-template-rows: repeat(4, auto);
    grid-auto-flow: column;
    column-gap: clamp(34px, 4vw, 62px);
  }
  .hm .hours-list li { gap: 14px; padding: 2px 0; font-size: 14.5px; }
  .hm .hours-list li span:first-child { width: 38px; }

  /* the map now ends level with the copy instead of setting the height */
  .hm .map-shell { min-height: clamp(400px, 52vh, 520px); }
  .hm .map-shell iframe { min-height: 0; }
}


/* ============================================================
   FRONT DOOR BAND — 30 Aug 2026.
   Full-bleed shopfront loop between the map and the footer.
   Height is capped so the band reads as a closing note rather
   than a second hero; the ink wash at the base carries the eye
   into the footer instead of ending on a hard cut.
   ============================================================ */
.front-film{
  position:relative;overflow:hidden;
  height:clamp(280px,42vh,460px);
  background:var(--ink,#211D18);
}
.front-film__video{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;
  display:block;
}
/* No wash across the base: the footer below is bone (#FDFBF6), so a
   dark gradient would fade the band toward ink and then hit a light
   surface — the opposite of a join. The address carries its own scrim
   instead, which also survives the bright glass in the middle of the
   shot where plain text on a shadow disappeared. */
.front-film__mark{
  position:absolute;left:0;right:0;bottom:0;
  padding:clamp(16px,2.4vw,26px) clamp(20px,5vw,64px);
  display:flex;justify-content:flex-end;
}
.front-film__mark .micro{
  padding:7px 14px;border-radius:999px;
  background:rgba(33,29,24,.62);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  color:var(--bone,#F7F4EE);
}
@media (max-width:760px){
  .front-film{height:clamp(230px,34vh,320px)}
  .front-film__mark{justify-content:flex-start}
}
