/*
 * Follow Me Therapy: the shared stylesheet, loaded by every page after
 * css/tokens.css. css/home.css and css/pages.css add only what's unique to
 * the home page and to the inner pages.
 *
 * Every size, colour, font, radius, shadow, duration, easing and layer comes
 * from a token (design/tokens.json → css/tokens.css). tools/check_tokens.py
 * fails the build if a raw value creeps in. Fluid tokens grow smoothly with
 * the window, so the only places the layout changes are the breakpoints in
 * the tokens: 480px (xs), 640px (sm) and 960px (md: the side menu).
 *
 * Contents
 *   1. Fonts            6. Buttons           11. Steps
 *   2. Base             7. Chips             12. Pop-ups
 *   3. Links and focus  8. Cards and tiles   13. Contact me button
 *   4. Page layout      9. Notes             14. Motion
 *   5. Section titles  10. Lists             15. Page transitions
 */

/* ── 1. Fonts ─────────────────────────────────────────────────────────── */
/* Metric-matched fallbacks, so text doesn't jump when the web fonts land. */
@font-face {
  font-family: "QS Fallback";
  src: local("Arial"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 102.2%;
  ascent-override: 97.8%;
  descent-override: 24.5%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Fredoka Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Helvetica Bold"), local("Liberation Sans Bold");
  font-weight: 600;
  size-adjust: 94.2%;
  ascent-override: 103.4%;
  descent-override: 25.1%;
  line-gap-override: 0%;
}
/* Fredoka is one variable font (every weight from 300 to 700 in one file), so
   the practice name can sit at exactly the weight of the logo's lines. */
@font-face { font-family: "Fredoka"; font-weight: 300 700; font-display: swap; src: url(../fonts/fredoka-latin-variable.woff2) format("woff2-variations"), url(../fonts/fredoka-latin-variable.woff2) format("woff2"); }
@font-face { font-family: "Quicksand"; font-weight: 500; font-display: swap; src: url(../fonts/quicksand-latin-500-normal.woff2) format("woff2"); }
@font-face { font-family: "Quicksand"; font-weight: 600; font-display: swap; src: url(../fonts/quicksand-latin-600-normal.woff2) format("woff2"); }
@font-face { font-family: "Quicksand"; font-weight: 700; font-display: swap; src: url(../fonts/quicksand-latin-700-normal.woff2) format("woff2"); }

/* ── 2. Base ──────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Keep the scrollbar's room when a pop-up stops the page scrolling, so
     nothing shifts sideways as it opens. */
  scrollbar-gutter: stable;
  /* What shows past the ends of the page (a phone's overscroll, behind
     Safari's toolbar): the page colour at the top, the footer's purple once
     you're in the bottom half (js: html.near-end). */
  background: var(--paper);
}
html.near-end {
  background: var(--deep);
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
  background: var(--paper);
  overflow-x: clip;
}
h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
  text-wrap: balance;
}
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-md); font-weight: 500; margin-bottom: var(--space-2); }
p {
  margin: 0 0 var(--space-4);
  text-wrap: pretty;
}
b,
strong {
  font-weight: 700;
  color: var(--ink);
}
img,
svg {
  max-width: 100%;
}
img {
  height: auto;
}
ul,
ol {
  margin: 0 0 var(--space-4);
}
blockquote {
  margin: 0;
}
/* Words of headings that glide when they move to another line (js/reflow.js). */
.rw {
  display: inline-block;
}
.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── 3. Links and focus ───────────────────────────────────────────────── */
/* Links are bold and coloured at rest; the underline comes on hover and
   keyboard focus. Things that look like buttons never underline. */
a {
  color: var(--purple);
  font-weight: 700;
  text-decoration: none;
  text-decoration-thickness: var(--border-outline);
  text-underline-offset: var(--space-1);
}
a:hover,
a:focus-visible {
  text-decoration-line: underline;
}
:is(.btn, .btn-secondary, .btn-outline, .fab, .modal-link, .modal-choice, .contact-tile, .book-note, .fixed-header a, .facts a, .back-btn, .brand, .nav-logo, .skip-link):is(:hover, :focus-visible) {
  text-decoration: none;
}
/* One focus ring everywhere: the focus colour, offset from the edge. */
:focus-visible {
  outline: var(--border-focus) solid var(--focus);
  outline-offset: var(--border-focus);
}
.skip-link {
  position: absolute;
  left: var(--space-3);
  top: calc(-1 * var(--space-16));
  z-index: var(--z-skip);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--purple);
  color: var(--paper);
  transition: top var(--dur-fast) var(--ease-standard);
}
.skip-link:focus {
  top: var(--space-3);
}

/* Chevrons after "Learn more" and other links, nudging along on hover. */
.chev {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-left: 0.2em;
  vertical-align: -0.08em;
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--dur-base) var(--ease-spring);
}
a:hover > .chev,
:is(.service-item, .funding-card):hover .chev {
  transform: translateX(var(--space-1));
}

/* ── 4. Page layout ───────────────────────────────────────────────────── */
/* Bands: full-width colour stripes with a wavy top edge. Each holds a
   column of content (.content-section on the home page, .wrap on the inner
   pages) that is never wider than --content, keeps --gutter from the edges
   and, when the side menu is showing, starts clear of it (--nav-inset, set
   in home.css; it glides, so the content slides rather than jumps). */
@property --nav-inset {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
.tone-lilac { background-color: var(--purple-tint); --accent: var(--purple); }
.tone-cream { background-color: var(--butter); --accent: var(--sun); }
.tone-mint { background-color: var(--teal-tint); --accent: var(--teal); }
.tone-white { background-color: var(--paper); --accent: var(--purple); }
.tone-deep { background-color: var(--deep); --accent: var(--sun); color: color-mix(in srgb, var(--paper) 85%, transparent); }

.section-wrapper,
.band {
  position: relative;
}
/* The wave: a band's own colour rising into the band above it. */
.wave-top::before,
.band + .band::before,
.site-foot::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(1px - var(--wave));
  height: var(--wave);
  background: inherit;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0 40V22C40 6 80 6 120 22S200 38 240 22V40Z'/%3E%3C/svg%3E") 0 0 / calc(var(--wave) * 12) var(--wave) repeat-x;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 40' preserveAspectRatio='none'%3E%3Cpath d='M0 40V22C40 6 80 6 120 22S200 38 240 22V40Z'/%3E%3C/svg%3E") 0 0 / calc(var(--wave) * 12) var(--wave) repeat-x;
  pointer-events: none;
  z-index: var(--z-base);
}

.content-section,
.wrap {
  --col: min(100% - var(--nav-inset) - 2 * var(--gutter), var(--content));
  width: var(--col);
  margin-inline: auto;
  margin-left: max(calc((100% - var(--col)) / 2), calc(var(--nav-inset) + var(--gutter)));
}
.content-section {
  padding-block: var(--section-top) var(--section-space);
}
.band {
  padding-block: var(--section-top) var(--section-space);
}
/* Paragraphs keep a comfortable reading width. */
.content-section p,
.wrap p {
  max-width: var(--measure);
}

/* ── 5. Section titles ────────────────────────────────────────────────── */
/* One style for every section: centred, with a short hand-drawn squiggle
   in the band's accent colour (the same stroke as the hero's underline and
   the waves between bands), and an optional line under it (.tap-hint,
   .contact-lead) as a subtitle. */
.content-section h2,
.band:not(.site-foot) > .wrap > h2 {
  display: block;
  margin: 0 auto var(--stack);
  text-align: center;
}
.content-section h2::after,
.band:not(.site-foot) > .wrap > h2::after {
  content: "";
  display: block;
  width: var(--space-20);
  height: var(--space-4);
  margin: var(--space-4) auto 0;
  background: var(--accent, var(--purple));
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 16'%3E%3Cpath d='M3 8c6-5 11-5 17 0s11 5 17 0 11-5 17 0 11 5 17 0 5-3 6-2' fill='none' stroke='%23000' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%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 80 16'%3E%3Cpath d='M3 8c6-5 11-5 17 0s11 5 17 0 11-5 17 0 11 5 17 0 5-3 6-2' fill='none' stroke='%23000' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* A subtitle sits close under the title, centred. */
.tap-hint,
.contact-lead {
  max-width: var(--measure);
  margin: calc(var(--space-2) - var(--stack)) auto var(--stack);
  text-align: center;
}

/* ── 6. Buttons ───────────────────────────────────────────────────────── */
.btn,
.btn-secondary,
.btn-outline {
  --glow: var(--button-purple-fill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--size-button);
  padding: var(--space-2) var(--space-7);
  border: var(--border-outline) solid var(--button-purple-line);
  border-radius: var(--radius-pill);
  background: var(--button-purple-fill);
  color: var(--button-purple-ink);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--text-md);
  line-height: var(--leading-snug);
  text-align: center;
  cursor: pointer;
  box-shadow: var(--shadow-glow);
  transition:
    transform var(--dur-base) var(--ease-spring),
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}
:is(.btn, .btn-secondary):hover {
  background: var(--button-purple-fill-hover);
  border-color: var(--button-purple-fill-hover);
  transform: translateY(calc(-1 * var(--space-hair)));
}
.btn-outline,
.btn.btn-outline {
  background: var(--button-outline-fill);
  color: var(--button-purple-outline-ink);
  box-shadow: none;
}
.btn-outline:hover {
  background: var(--button-purple-outline-fill-hover);
  color: var(--button-purple-outline-ink-hover);
  transform: translateY(calc(-1 * var(--space-hair)));
}
/* Teal: "Ask a question", wherever it appears (solid in a card, outlined
   beside a purple button). */
:is(.btn, .btn-secondary, .btn-outline).is-teal {
  --glow: var(--button-teal-fill);
  box-shadow: var(--shadow-glow-teal);
  border-color: var(--button-teal-line);
  background: var(--button-teal-fill);
  color: var(--button-teal-ink);
}
:is(.btn, .btn-secondary).is-teal:hover {
  border-color: var(--button-teal-fill-hover);
  background: var(--button-teal-fill-hover);
}
.btn-outline.is-teal,
.btn.btn-outline.is-teal {
  box-shadow: none;
  background: var(--button-outline-fill);
  color: var(--button-teal-outline-ink);
}
.btn-outline.is-teal:hover {
  background: var(--button-teal-outline-fill-hover);
  color: var(--button-teal-outline-ink-hover);
}
:is(.btn, .btn-secondary, .btn-outline):active {
  transform: scale(0.96);
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* ── 7. Chips ─────────────────────────────────────────────────────────── */
/* Labels in a pill, outlined in their own line colour. Chips that are links
   (the home hero) are 44px tall; plain labels are smaller. */
.chips,
.modal-chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
}
.chips li,
.modal-chips li {
  margin: 0;
  padding: var(--space-1) var(--space-3);
  border: var(--border-outline) solid var(--chip-purple-line);
  border-radius: var(--radius-pill);
  background: var(--chip-outline-fill);
  color: var(--chip-purple-ink);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: var(--leading-normal);
}
.modal-chips {
  justify-content: center;
}
.modal-chips li,
.chips.is-teal li {
  border-color: var(--chip-teal-line);
  background: var(--chip-teal-fill);
  color: var(--chip-teal-ink);
}

/* ── 8. Cards and icon tiles ──────────────────────────────────────────── */
/* Service and funding cards, wrapped in their icon's colour. A service card
   has its icon tile with the title beside it, a sentence and "Learn more";
   a funding card is just the tile and the name, small enough for three in
   a row even on a phone. Both open their details and lift on hover. */
.svc-grid,
.services-grid,
.fund-grid,
.funding-grid,
.cards,
.contact-actions {
  display: grid;
  gap: var(--grid-gap);
  margin: 0;
}
.svc-grid,
.services-grid,
.contact-actions {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}
.cards {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}
.fund-grid,
.funding-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  max-width: calc(var(--space-30) * 4);
  margin-inline: auto;
}
.service-item,
.funding-card,
.card,
.contact-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  --band: var(--card-purple-line);
  padding: var(--card-pad);
  border: var(--border-outline) solid var(--band);
  /* Nest rule: concentric with the icon tile in the top corner. */
  border-radius: calc(var(--radius-tile) + var(--card-pad) + var(--border-outline));
  background: var(--card-fill);
  box-shadow: var(--shadow-rest);
  text-align: left;
}
/* Cards without a tile take turns through the colours, like the steps. */
.card:nth-child(3n + 2) { --band: var(--card-teal-line); }
.card:nth-child(3n + 3) { --band: var(--card-sun-line); }
.service-item,
.funding-card {
  cursor: pointer;
  transition:
    transform var(--dur-slow) var(--ease-spring),
    box-shadow var(--dur-slow) var(--ease-standard);
}
:is(.service-item, .funding-card):has(.svc-stairs) { --band: var(--card-teal-line); }
:is(.service-item, .funding-card):has(.svc-esdm) { --band: var(--card-sun-line); }
:is(.service-item, .funding-card):has(.svc-assessments) { --band: var(--card-pink-line); }
:is(.service-item, .funding-card):is(:hover, :focus-visible) {
  transform: translateY(calc(-1 * var(--space-2))) rotate(1deg);
  box-shadow: var(--shadow-raised);
}
:is(.service-item, .funding-card):nth-child(even):is(:hover, :focus-visible) {
  transform: translateY(calc(-1 * var(--space-2))) rotate(-1deg);
}
:is(.service-item, .funding-card):active {
  transform: scale(0.97);
}
:is(.service-item, .funding-card, .card, .contact-card) h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-lg);
}
:is(.service-item, .funding-card, .card, .contact-card) p {
  margin: 0 0 var(--space-4);
}
:is(.service-item, .funding-card, .card) p:last-child {
  margin-bottom: 0;
}
:is(.service-item, .funding-card) .more {
  margin-top: auto;
  color: var(--card-more);
  font-family: var(--font-display);
  font-weight: 500;
}
/* Service card: the tile and the title side by side, the rest beneath. */
.service-item {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: var(--space-4);
}
.service-item > :not(.svc-icon, h3) {
  grid-column: 1 / -1;
}
.service-item > .svc-icon {
  margin-bottom: 0;
}
.service-item > h3 {
  margin: 0;
}
.service-item > p {
  margin: var(--space-4) 0;
}
.service-item > .more {
  justify-self: center;
  align-self: end;
}
/* Funding card: the tile fills the card's width with the same padding on
   the top, left and right, the name beneath; corners nest round the tile. */
.funding-card {
  align-items: stretch;
  gap: var(--space-2);
  padding: var(--card-pad) var(--card-pad) calc(var(--card-pad) - var(--space-2));
  border-radius: calc(var(--radius-tile) + var(--card-pad) + var(--border-outline));
  text-align: center;
}
.funding-card > .svc-icon {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  margin-bottom: 0;
}
.funding-card > .svc-icon svg {
  width: 50%;
  height: 50%;
}
.funding-card > h3 {
  margin: 0;
  font-size: var(--text-md);
}
.contact-card {
  align-items: stretch;
  /* Nest rule: concentric with the full-width button at the bottom. */
  border-radius: calc(var(--size-button) / 2 + var(--card-pad) + var(--border-outline));
  text-align: center;
}
.contact-card:nth-child(2) {
  --band: var(--card-teal-line);
}
.contact-card > :is(.btn, .btn-secondary, .btn-outline) {
  margin-top: auto;
}

/* Icon tiles: a soft square of colour with the icon drawn in lines,
   outlined in its own line colour. */
.svc-icon {
  display: grid;
  place-items: center;
  width: var(--size-tile-md);
  height: var(--size-tile-md);
  margin-bottom: var(--space-3);
  border: var(--border-outline) solid var(--tile-purple-line);
  border-radius: var(--radius-tile);
  background: var(--tile-purple-fill);
  color: var(--tile-purple-icon);
  transition: transform var(--dur-slow) var(--ease-spring);
}
:is(.service-item, .funding-card):hover .svc-icon {
  transform: rotate(-8deg) scale(1.08);
}
.svc-icon svg {
  width: var(--size-icon-lg);
  height: var(--size-icon-lg);
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.svc-footprints:not(.fund-svg) svg {
  fill: currentColor;
  stroke: none;
}
.svc-stairs { background: var(--tile-teal-fill); color: var(--tile-teal-icon); border-color: var(--tile-teal-line); }
.svc-esdm { background: var(--tile-sun-fill); color: var(--tile-sun-icon); border-color: var(--tile-sun-line); }
.svc-assessments { background: var(--tile-pink-fill); color: var(--tile-pink-icon); border-color: var(--tile-pink-line); }

/* ── 9. Notes ─────────────────────────────────────────────────────────── */
/* A tinted strip with an icon tile in its top corner (an "i", a heart or
   a book). The words start level with the top of the tile and wrap round
   it, then run the full width beneath, so a long note never squeezes into a
   narrow column. Holds any length of text at any width. */
.info-note {
  --note-tint: var(--note-purple-fill);
  --note-ink: var(--note-purple-line-hover);
  --note-line: var(--note-purple-line);
  display: flow-root;
  max-width: var(--content);
  margin: var(--space-10) 0 0;
  padding: var(--card-pad);
  border: var(--border-outline) solid var(--note-line);
  /* Nest rule: the icon tile sits in the corner, so the note's corner runs
     parallel to it. */
  border-radius: calc(var(--radius-tile) + var(--card-pad) + var(--border-outline));
  background: var(--note-tint);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  text-align: left;
}
.content-section .info-note,
.wrap .info-note {
  max-width: none;
}
.info-note::before {
  content: "";
  float: left;
  margin: 0 var(--space-4) var(--space-2) 0;
  width: var(--size-tile-md);
  height: var(--size-tile-md);
  border: var(--border-outline) solid var(--note-line);
  border-radius: var(--radius-tile);
  background: /* token:note-purple-icon */ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23502eed' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11v5.5'/%3E%3Cpath d='M12 7.6v.1'/%3E%3C/svg%3E") center / var(--size-icon-lg) no-repeat, var(--note-tile-fill);
}
.info-note > span {
  display: block;
}
/* A note with a link ("Read the review") is one big target: the whole
   strip is clickable, lifts on hover and takes the focus ring. */
.info-note:has(a[href]) {
  position: relative;
  cursor: pointer;
  transition:
    transform var(--dur-base) var(--ease-spring),
    box-shadow var(--dur-base) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}
.info-note a[href]::after {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--border-outline));
  border-radius: calc(var(--radius-tile) + var(--card-pad) + var(--border-outline));
}
.info-note:has(a[href]):hover {
  border-color: var(--note-ink);
  box-shadow: var(--shadow-rest);
  transform: translateY(calc(-1 * var(--space-hair)));
}
.info-note:has(a[href]):hover a {
  text-decoration-line: underline;
}
.info-note:has(a[href]:focus-visible) {
  outline: var(--border-focus) solid var(--focus);
  outline-offset: var(--border-focus);
}
.info-note a[href]:focus-visible {
  outline: none;
}
/* The practice's promise: in the heading face, with a heart. */
.callout.info-note {
  --note-tint: var(--note-promise-fill);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--text-lg);
  color: var(--note-promise-ink);
  margin-top: var(--space-12);
}
.callout.info-note::before {
  background: /* token:note-purple-icon */ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23502eed' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z'/%3E%3C/svg%3E") center / var(--size-icon-lg) no-repeat, var(--note-purple-promise-tile-fill);
}
/* Research: a book, in teal. */
.evidence.info-note {
  --note-tint: var(--note-teal-fill);
  --note-ink: var(--note-teal-line-hover);
  --note-line: var(--note-teal-line);
}
.evidence.info-note::before {
  background: /* token:note-teal-icon */ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300626e' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5.5c3-1.3 6-1.3 9 .5 3-1.8 6-1.8 9-.5V19c-3-1.3-6-1.3-9 .5-3-1.8-6-1.8-9-.5z'/%3E%3Cpath d='M12 6v13.5'/%3E%3C/svg%3E") center / var(--size-icon-lg) no-repeat, var(--note-tile-fill);
}

/* ── 10. Lists ────────────────────────────────────────────────────────── */
.list-label {
  margin: var(--space-7) 0 var(--space-3);
  color: var(--ink);
  font-weight: 700;
}
.checklist {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
}
.checklist li {
  position: relative;
  margin: 0 0 var(--space-3);
  padding-left: var(--space-8);
  line-height: var(--leading-normal);
}
.checklist li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.15em;
  width: var(--size-icon-sm);
  height: var(--size-icon-sm);
  border-radius: 50%;
  background: /* token:paper */ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 12.5l4 4 8-9' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 65% no-repeat, var(--teal);
}

/* ── 11. Steps ────────────────────────────────────────────────────────── */
/* Numbered discs in a row, with footprints walking from one to the next
   (js adds the .step-trail). One column on phones, the trail walking down. */
.steps,
.steps-row {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
  gap: var(--space-10);
  margin: 0;
  padding: 0;
}
:is(.steps, .steps-row) li {
  position: relative;
  z-index: var(--z-base);
  margin: 0;
  padding: 0 var(--space-2);
  text-align: center;
}
:is(.steps, .steps-row) h3 {
  margin-bottom: var(--space-1);
}
:is(.steps, .steps-row) p {
  max-width: none;
  margin: 0;
}
.step-num {
  --glow: var(--purple);
  display: inline-grid;
  place-items: center;
  width: var(--size-step);
  height: var(--size-step);
  margin-bottom: var(--space-3);
  border: var(--border-outline) solid color-mix(in srgb, var(--glow) 35%, var(--paper));
  border-radius: 50%;
  background: var(--glow);
  color: var(--paper);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-xl);
  box-shadow: var(--shadow-glow);
}
:is(.steps, .steps-row) li:nth-child(2) .step-num { --glow: var(--teal); box-shadow: var(--shadow-glow-teal); }
:is(.steps, .steps-row) li:nth-child(3) .step-num { --glow: var(--sun); color: var(--ink); box-shadow: var(--shadow-glow-sun); }
:is(.steps, .steps-row) li:nth-child(4) .step-num { --glow: var(--pink); box-shadow: var(--shadow-glow-pink); }

/* The trail: four footprints, alternating left and right, at a natural
   stride, centred in the gap between two discs. */
.step-trail {
  position: absolute;
  top: calc(var(--size-step) / 2 - var(--space-3));
  left: calc(50% + var(--size-step) / 2);
  width: calc(100% - var(--size-step) + var(--space-10));
  height: var(--space-6);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  pointer-events: none;
}
.step-trail i,
.hero-trail i {
  width: var(--space-3);
  height: calc(var(--space-3) * 1.5);
  background: /* token:purple */ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 24'%3E%3Cg fill='%23502eed'%3E%3Cellipse cx='11.5' cy='3.1' rx='2.05' ry='2.55'/%3E%3Ccircle cx='8.15' cy='2.25' r='1.35'/%3E%3Ccircle cx='5.85' cy='2.9' r='1.2'/%3E%3Ccircle cx='3.95' cy='4.15' r='1.05'/%3E%3Ccircle cx='2.55' cy='5.85' r='0.9'/%3E%3Cpath d='M7.6 6.6C11.2 6.2 13.9 7.8 13.6 10.8 13.4 12.8 11.4 14 10.9 16.2 10.5 18 11.6 19.4 11.2 21.2 10.8 23.2 9.3 24 7.7 24 5.6 24 4.3 22.7 4.3 20.6 4.3 17.6 3 15.8 2.8 12.8 2.5 9.2 4.4 6.9 7.6 6.6Z'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
  transform: rotate(90deg) translateX(calc(-1 * var(--space-1)));
}
.step-trail i {
  opacity: 0;
}
:is(.step-trail, .hero-trail) i:nth-child(even) {
  background-image: /* token:purple */ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 24'%3E%3Cg fill='%23502eed'%3E%3Cg transform='translate%2816 0%29 scale%28-1 1%29'%3E%3Cellipse cx='11.5' cy='3.1' rx='2.05' ry='2.55'/%3E%3Ccircle cx='8.15' cy='2.25' r='1.35'/%3E%3Ccircle cx='5.85' cy='2.9' r='1.2'/%3E%3Ccircle cx='3.95' cy='4.15' r='1.05'/%3E%3Ccircle cx='2.55' cy='5.85' r='0.9'/%3E%3Cpath d='M7.6 6.6C11.2 6.2 13.9 7.8 13.6 10.8 13.4 12.8 11.4 14 10.9 16.2 10.5 18 11.6 19.4 11.2 21.2 10.8 23.2 9.3 24 7.7 24 5.6 24 4.3 22.7 4.3 20.6 4.3 17.6 3 15.8 2.8 12.8 2.5 9.2 4.4 6.9 7.6 6.6Z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  transform: rotate(90deg) translateX(var(--space-1));
}
/* Trails walk one after another: 1 to 2, pause, 2 to 3 (ambient loop). */
:is(.is-visible, .in) .step-trail i {
  animation: walkSlot2 5s ease-out infinite;
  animation-delay: calc(var(--k, 0) * 2.5s + var(--f, 0) * 0.22s);
}
.trails-3 .step-trail i {
  animation-name: walkSlot3;
  animation-duration: 7.5s;
}
@keyframes walkSlot2 {
  0% { opacity: 0; scale: 0.4; }
  4% { opacity: 0.8; scale: 1.1; }
  7% { scale: 1; }
  28% { opacity: 0.7; }
  38%, 100% { opacity: 0; }
}
@keyframes walkSlot3 {
  0% { opacity: 0; scale: 0.4; }
  3% { opacity: 0.8; scale: 1.1; }
  5% { scale: 1; }
  19% { opacity: 0.7; }
  26%, 100% { opacity: 0; }
}
@media (max-width: 640px) {
  .steps,
  .steps-row {
    grid-template-columns: 1fr;
    gap: var(--space-12);
  }
  :is(.steps, .steps-row) p {
    max-width: var(--measure);
    margin-inline: auto;
  }
  .step-trail {
    flex-direction: column;
    top: auto;
    bottom: calc(-1 * var(--space-10));
    left: 50%;
    width: var(--space-6);
    height: var(--space-8);
    margin-left: calc(-1 * var(--space-3));
    gap: var(--space-1);
  }
  .step-trail i {
    transform: rotate(180deg) translateX(calc(-1 * var(--space-1)));
  }
  .step-trail i:nth-child(even) {
    transform: rotate(180deg) translateX(var(--space-1));
  }
  .step-trail i:nth-child(n + 3) {
    display: none;
  }
}

/* ── 12. Pop-ups ──────────────────────────────────────────────────────── */
.modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: color-mix(in srgb, var(--deep) 55%, transparent);
  backdrop-filter: blur(3px);
}
.modal.show {
  display: block;
  animation: fadeIn var(--dur-base) var(--ease-standard);
}
.modal-content {
  --tone: var(--purple);
  --tone-tint: var(--purple-tint);
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(36rem, 100% - 2 * var(--space-3));
  max-height: calc(100dvh - 2 * var(--space-3));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: calc(var(--card-pad) * 1.5) var(--card-pad) var(--card-pad);
  border: var(--border-outline) solid var(--tone);
  /* Nest rule: concentric with the full-width button at the bottom. */
  border-radius: calc(var(--size-button) / 2 + var(--card-pad) + var(--border-outline));
  background: var(--paper);
  box-shadow: var(--shadow-overlay);
  text-align: center;
  transform: translate(-50%, -50%);
  animation: modalIn var(--dur-slower) var(--ease-out);
}
.modal-content:focus {
  outline: none;
}
.modal .close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: var(--size-target);
  height: var(--size-target);
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink);
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  cursor: pointer;
}
.modal .close:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}
.modal-content h3 {
  margin: 0 var(--space-10) var(--space-4);
  font-size: var(--text-xl);
  font-weight: 600;
  text-align: center;
}
.modal-content > :is(.btn, .btn-secondary) {
  display: flex;
  width: 100%;
  margin-top: var(--space-3);
}
/* Service and funding pop-ups take their card's colour: a band and a soft
   wash across the top, the card's icon, a tag, then the details. */
.modal[data-tone] .modal-content {
  background: linear-gradient(180deg, var(--tone-tint) 0, var(--paper) calc(var(--space-30) + var(--space-8))) var(--paper);
}
.modal[data-tone="teal"] .modal-content { --tone: var(--teal); --tone-tint: var(--teal-tint); }
.modal[data-tone="sun"] .modal-content { --tone: var(--sun-deep); --tone-tint: var(--sun-tint); }
.modal[data-tone="pink"] .modal-content { --tone: var(--pink-deep); --tone-tint: var(--pink-pale); }
.modal-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.modal-hero h3 {
  margin: 0 var(--space-8);
}
.modal-icon {
  display: grid;
  place-items: center;
  width: var(--size-tile-lg);
  height: var(--size-tile-lg);
  border: var(--border-outline) solid color-mix(in srgb, var(--tone) 30%, var(--paper));
  border-radius: var(--radius-card);
  background: var(--paper);
  color: var(--tone);
  box-shadow: var(--shadow-rest);
}
.modal-icon svg {
  width: var(--size-icon-xl);
  height: var(--size-icon-xl);
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.modal-icon.is-fill svg {
  fill: currentColor;
  stroke: none;
}
.modal-tag {
  display: inline-block;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--tag-purple-fill);
  color: var(--tag-purple-ink);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
}
.modal[data-tone="teal"] .modal-tag { background: var(--tag-teal-fill); color: var(--tag-teal-ink); }
.modal[data-tone="sun"] .modal-tag { background: var(--tag-sun-fill); color: var(--tag-sun-ink); }
.modal[data-tone="pink"] .modal-tag { background: var(--tag-pink-fill); color: var(--tag-pink-ink); }
.modal-body {
  text-align: left;
}
.modal-body p {
  max-width: none;
  margin: 0 0 var(--space-3);
}
.modal-lead {
  color: var(--ink);
  font-size: var(--text-md);
  font-weight: 600;
  text-align: center;
}
.modal-body .list-label {
  margin: var(--space-1) 0 var(--space-2);
}
.modal-body .checklist li {
  margin-bottom: var(--space-2);
}
.modal-note {
  max-width: none;
  margin: var(--space-4) 0 0;
  color: var(--ink-soft);
  font-size: var(--text-xs);
  text-align: center;
}
.modal-links {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-2) 0 var(--space-3);
}
.modal-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--size-target);
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4);
  border: var(--border-outline) solid transparent;
  border-radius: var(--radius-md);
  background: var(--tone-tint);
  color: var(--ink);
  font-size: var(--text-sm);
  text-align: left;
  transition: background-color var(--dur-fast) var(--ease-standard);
}
.modal-link.is-external {
  border-color: var(--tone-tint);
  background: var(--paper);
}
.modal-link svg {
  flex: none;
  width: var(--size-icon-sm);
  height: var(--size-icon-sm);
  fill: none;
  stroke: var(--tone);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--dur-base) var(--ease-spring);
}
.modal-link:is(:hover, :focus-visible) svg {
  transform: translateX(var(--space-1));
}
@media (prefers-reduced-motion: no-preference) {
  .modal.show .modal-icon {
    animation: iconBob var(--dur-slower) var(--ease-spring) both var(--dur-fast);
  }
  .modal.show .modal-body > *,
  .modal.show .modal-body .checklist li {
    animation: lineIn var(--dur-slow) var(--ease-out) both;
  }
  .modal.show .modal-body > :nth-child(2) { animation-delay: 80ms; }
  .modal.show .modal-body > :nth-child(3) { animation-delay: 160ms; }
  .modal.show .modal-body .checklist li:nth-child(1) { animation-delay: 180ms; }
  .modal.show .modal-body .checklist li:nth-child(2) { animation-delay: 260ms; }
  .modal.show .modal-body .checklist li:nth-child(3) { animation-delay: 340ms; }
  .modal.show .modal-body .checklist li:nth-child(4) { animation-delay: 420ms; }
  .modal.show .modal-body .checklist li:nth-child(5) { animation-delay: 500ms; }
}
/* Get started: two choices with the card band along the top. */
#contactModal .modal-content {
  width: min(30rem, 100% - 2 * var(--space-3));
}
#contactModal .modal-chips {
  margin-bottom: var(--space-6);
}
.modal-choice {
  --band: var(--purple);
  --tint: var(--purple-tint);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--size-target);
  margin-bottom: var(--space-3);
  /* The same gap round its icon tile as Simone's photo in her card. */
  padding: var(--card-pad);
  border: var(--border-outline) solid var(--band);
  border-radius: calc(var(--radius-tile) + var(--card-pad) + var(--border-outline));
  background: var(--paper);
  color: var(--ink);
  text-align: left;
  box-shadow: var(--shadow-rest);
  transition:
    transform var(--dur-base) var(--ease-spring),
    box-shadow var(--dur-base) var(--ease-standard);
}
.modal-choice:not(.primary) {
  --band: var(--teal-ink);
  --tint: var(--teal-tint);
}
.modal-choice:hover {
  transform: translateY(calc(-1 * var(--space-1)));
  box-shadow: var(--shadow-raised);
}
.modal-choice:active {
  transform: scale(0.97);
}
.mc-icon {
  /* Pinned to the corner, so the gap round it matches the padding even when
     the words beside it run to more lines. */
  align-self: flex-start;
  display: grid;
  place-items: center;
  flex: none;
  width: var(--size-tile);
  height: var(--size-tile);
  border: var(--border-outline) solid color-mix(in srgb, var(--band) 30%, var(--paper));
  border-radius: var(--radius-md);
  background: var(--tint);
  color: var(--band);
}
.mc-icon svg {
  width: var(--size-icon);
  height: var(--size-icon);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mc-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  line-height: var(--leading-snug);
}
.mc-text b {
  color: inherit;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
}
.mc-text small {
  margin-top: var(--space-hair);
  font-size: var(--text-sm);
  font-weight: 500;
}
.mc-arrow {
  display: grid;
  place-items: center;
  color: var(--band);
  transition: transform var(--dur-base) var(--ease-spring);
}
.mc-arrow svg {
  width: var(--size-icon-sm);
  height: var(--size-icon-sm);
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.modal-choice:hover .mc-arrow {
  transform: translateX(var(--space-1));
}
/* Short windows: everything tightens so the longest pop-up still fits. */
@media (max-height: 820px) {
  .modal-hero { gap: var(--space-1); margin-bottom: var(--space-3); }
  .modal-icon { width: var(--size-tile-md); height: var(--size-tile-md); border-radius: var(--radius-tile); }
  .modal-icon svg { width: var(--size-icon-lg); height: var(--size-icon-lg); }
  .modal-body .checklist li { margin-bottom: var(--space-1); }
  .modal-links { gap: var(--space-1); }
}
@media (max-height: 700px) {
  .modal-icon,
  .modal-tag { display: none; }
  .modal-content { font-size: var(--text-sm); }
  .modal-content h3 { font-size: var(--text-lg); }
}

/* ── 13. Contact me button ────────────────────────────────────────────── */
/* Floats bottom-right once you've scrolled past the opening section, says
   "Contact me", then shrinks to a circle; steps aside at the contact
   section (js toggles .show, .compact and .tucked). */
.fab {
  --glow: var(--purple);
  position: fixed;
  right: var(--gutter);
  bottom: calc(var(--gutter) + env(safe-area-inset-bottom));
  z-index: var(--z-fab);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--size-fab);
  padding: 0 var(--space-5) 0 var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--purple);
  color: var(--paper);
  font-size: var(--text-md);
  font-weight: 700;
  box-shadow: var(--shadow-glow);
  opacity: 0;
  transform: translateY(var(--space-6)) scale(0.6);
  pointer-events: none;
  transition:
    opacity var(--dur-slow) var(--ease-standard),
    transform var(--dur-slower) var(--ease-spring),
    padding var(--dur-slow) var(--ease-standard),
    gap var(--dur-slow) var(--ease-standard),
    background-color var(--dur-fast) var(--ease-standard);
}
.fab.show:not(.tucked) {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.fab:hover {
  background: var(--purple-dark);
}
.fab:active {
  transform: scale(0.92);
}
.fab:focus-visible {
  outline-color: var(--butter-deep);
}
.fab svg {
  flex: none;
  width: var(--size-icon);
  height: var(--size-icon);
}
.fab-label {
  max-width: 8em;
  overflow: hidden;
  white-space: nowrap;
  transition:
    max-width var(--dur-slow) var(--ease-standard),
    opacity var(--dur-base) var(--ease-standard);
}
.fab.compact {
  gap: 0;
  padding: 0 calc((var(--size-fab) - var(--size-icon)) / 2);
}
.fab.compact .fab-label {
  max-width: 0;
  opacity: 0;
}

/* ── 14. Motion ───────────────────────────────────────────────────────── */
@keyframes fadeIn {
  from { opacity: 0; }
}
@keyframes modalIn {
  from { opacity: 0; transform: translate(-50%, -46%); }
}
@keyframes popIn {
  from { opacity: 0; transform: translateY(var(--space-6)) scale(0.9) rotate(-2deg); }
}
@keyframes bounceIn {
  from { opacity: 0; transform: translateY(calc(-1 * var(--space-8))) scale(0.4); }
}
@keyframes iconBob {
  from { opacity: 0; transform: scale(0.4) rotate(-14deg); }
}
@keyframes lineIn {
  from { opacity: 0; transform: translateY(var(--space-2)); }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(var(--space-4)); }
}
/* Groups pop in one after another as their section scrolls into view
   (.stagger on the home page, .pop on the inner pages). */
@media (prefers-reduced-motion: no-preference) {
  .js .fade-in-content:not(.is-visible) .stagger > *,
  .js .band:not(.in) .pop > * {
    opacity: 0;
  }
  .is-visible .stagger > *,
  .band.in .pop > * {
    animation: popIn var(--dur-slower) var(--ease-spring) backwards;
  }
  :is(.stagger, .pop) > :nth-child(2) { animation-delay: 90ms; }
  :is(.stagger, .pop) > :nth-child(3) { animation-delay: 180ms; }
  :is(.stagger, .pop) > :nth-child(4) { animation-delay: 270ms; }
  :is(.stagger, .pop) > :nth-child(5) { animation-delay: 340ms; }
  :is(.stagger, .pop) > :nth-child(6) { animation-delay: 410ms; }
  :is(.stagger, .pop) > :nth-child(7) { animation-delay: 480ms; }
  :is(.stagger, .pop) > :nth-child(8) { animation-delay: 550ms; }
  :is(.is-visible, .band.in) .step-num {
    animation: bounceIn var(--dur-entrance) var(--ease-spring) backwards;
    animation-delay: inherit;
  }
  .rise {
    animation: rise var(--dur-entrance) var(--ease-out) both;
  }
  .rise-2 { animation-delay: 120ms; }
  .rise-3 { animation-delay: 240ms; }
}
/* Images fade in once decoded, instead of appearing in chunks. */
.js img:not(.loaded):not(.logo-image):not([src*="brand"]) {
  opacity: 0;
}
.js img {
  transition: opacity var(--dur-slow) var(--ease-standard);
}
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .step-trail i {
    opacity: 0.5;
  }
}

/* ── 15. Page transitions ─────────────────────────────────────────────── */
/* Moving between pages cross-fades, with the logo and the practice name
   gliding from where they were to where they land (browsers that support
   cross-document view transitions; others simply load the page). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
  ::view-transition-group(*) {
    animation-duration: var(--dur-slow);
    animation-timing-function: var(--ease-standard);
  }
  ::view-transition-old(root) {
    animation: var(--dur-base) var(--ease-standard) both vtOut;
  }
  ::view-transition-new(root) {
    animation: var(--dur-slow) var(--ease-out) both vtIn;
  }
}
@keyframes vtOut {
  to { opacity: 0; }
}
@keyframes vtIn {
  from { opacity: 0; transform: translateY(var(--space-3)); }
}
