@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=Source+Sans+3:ital,wght@0,300;0,400;0,500;0,600;1,400&display=swap');

/* ── Custom Properties ── */
:root {
  --color-cream: #F7F5F0;
  --color-sage: #8FAF8A;
  --color-sage-light: #A8C4A3;
  --color-sage-dark: #7A9B75;
  --color-taupe: #C4B9A8;
  --color-taupe-light: #D6CEC1;
  --color-olive: #4A5E46;
  --color-amber: #E8AA14;
  --color-rust: #D74E09;
  --color-slate: #3A5683;
  --color-text: #3D3B37;
  --color-text-light: #6B6760;
  --color-cream-dark: #EDE9E0;

  --font-heading: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --font-body: 'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --max-width-text: 720px;
  --max-width-wide: 1080px;
  --section-padding: 3rem 2rem;
  --section-padding-mobile: 3rem 2rem;

  /* Calm, decisive deceleration curves — no bounce, no elastic. */
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ── Reset & Base ── */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

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

body {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1.75;
  color: var(--color-text);
  background-color: var(--color-cream);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

a {
  color: var(--color-olive);
  text-decoration: none;
  transition: color 0.25s ease;
}

a:hover {
  color: var(--color-sage-dark);
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--color-sage);
  outline-offset: 3px;
  border-radius: 6px;
}

.btn:focus-visible {
  outline: 2px solid var(--color-olive);
  outline-offset: 3px;
}

ul, ol {
  list-style: none;
}

/* ── Typography ── */
h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 500;
  color: var(--color-olive);
  line-height: 1.25;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.25rem, 5vw, 3.25rem);
  font-weight: 400;
  letter-spacing: -0.01em;
}

h2 {
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  margin-bottom: 1.5rem;
}

h3 {
  font-size: clamp(1.25rem, 2.5vw, 1.5rem);
  margin-bottom: 1rem;
}

p {
  margin-bottom: 1.25rem;
  text-wrap: pretty;
}

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

/* ── Utility ── */
.container {
  max-width: var(--max-width-text);
  margin: 0 auto;
  padding: 0 2rem;
}

.container--wide {
  max-width: var(--max-width-wide);
}

.text-center {
  text-align: center;
}

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

/* Keyboard skip link — held off-screen until focused, then it drops in
   above the fixed header so keyboard users can jump past the nav. */
.skip-link {
  position: absolute;
  top: -4rem;
  left: 1rem;
  z-index: 1100;
  padding: 0.625rem 1.25rem;
  background-color: var(--color-olive);
  color: var(--color-cream);
  border-radius: 6px;
  font-size: 0.875rem;
  font-weight: 500;
  transition: top 0.2s var(--ease-out-quart);
}

.skip-link:focus,
.skip-link:hover {
  color: var(--color-cream);
}

.skip-link:focus-visible {
  top: 1rem;
  outline: 2px solid var(--color-cream);
  outline-offset: 2px;
}

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

/* ── Buttons ── */
.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 0.875rem 2rem;
  border-radius: 6px;
  border: none;
  cursor: pointer;
  transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease;
  text-decoration: none;
}

.btn--primary {
  background-color: var(--color-sage);
  color: #fff;
}

.btn--primary:hover {
  background-color: var(--color-sage-dark);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(74, 94, 70, 0.2);
}

.btn--amber {
  background-color: var(--color-amber);
  color: #3D2600;
  font-weight: 600;
}

.btn--amber:hover {
  background-color: #f0b82e;
  color: #3D2600;
  transform: translateY(-1px);
  box-shadow: 0 4px 16px rgba(232, 170, 20, 0.3);
}

/* Directional arrow affordance for the primary booking CTA */
.btn--arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
}

.btn--arrow .btn__arrow {
  font-size: 0.8125rem;
  transition: transform 0.25s var(--ease-out-quart);
}

.btn--arrow:hover .btn__arrow {
  transform: translateX(4px);
}

@media (prefers-reduced-motion: reduce) {
  .btn--arrow .btn__arrow {
    transition: none;
  }
  .btn--arrow:hover .btn__arrow {
    transform: none;
  }
}

.btn--outline {
  background-color: transparent;
  color: var(--color-olive);
  border: 1.5px solid var(--color-sage);
}

.btn--outline:hover {
  background-color: var(--color-sage);
  color: #fff;
  transform: translateY(-1px);
}

.btn--outline-light {
  background-color: transparent;
  color: var(--color-cream);
  border: 1.5px solid rgba(247, 245, 240, 0.55);
}

.btn--outline-light:hover {
  background-color: var(--color-cream);
  border-color: var(--color-cream);
  color: var(--color-olive);
  transform: translateY(-1px);
}

/* ── Header / Navigation ── */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  background-color: rgba(247, 245, 240, 1);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: box-shadow 0.3s ease;
}

.site-header--scrolled {
  box-shadow: 0 1px 8px rgba(74, 94, 70, 0.08);
}

.site-header__inner {
  max-width: var(--max-width-wide);
  margin: 0 auto;
  padding: 1rem 2rem;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.site-header__logo {
  display: flex;
  align-items: center;
  gap: 10px;
}

.site-header__logoimg {
  width: 36px;
  height: auto;
}
.site-header__logotext {
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--color-olive);
  text-decoration: none;
  transition: opacity 0.25s ease;
}

.site-header__logo:hover {
  opacity: 0.8;
  color: var(--color-olive);
}

.site-nav {
  margin-left: auto; /* keep the links flush to the right edge on desktop */
}

.site-nav__list {
  display: flex;
  gap: 1.85rem;
  align-items: center;
}

.site-nav__link {
  font-size: 1rem;
  font-weight: 400;
  color: var(--color-text);
  text-decoration: none;
  position: relative;
  padding: 0.5rem 0;
  transition: color 0.25s ease;
}

.site-nav__link::after {
  content: '';
  position: absolute;
  bottom: 0.15rem;
  left: 0;
  width: 0;
  height: 1.5px;
  background-color: var(--color-olive);
  transition: width 0.3s ease;
}

.site-nav__link:hover,
.site-nav__link--active {
  color: var(--color-olive);
}

.site-nav__link:hover::after,
.site-nav__link--active::after {
  width: 100%;
}

.site-nav__cta {
  font-size: 0.875rem;
  padding: 0.625rem 1.5rem;
}

/* Booking CTA + contact block — only rendered inside the mobile drawer */
.site-nav__footer {
  display: none;
}

/* ── Mobile Menu Toggle ── */
.menu-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.5rem;
  color: var(--color-olive);
  font-size: 1.25rem;
}

/* Three-line hamburger that morphs into an X. The icon element is the middle
   bar; its ::before/::after are the top and bottom bars. On open (driven by the
   button's aria-expanded, which the JS already toggles) the outer bars rotate
   into an X and the middle bar fades out — a smooth, non-bouncy ease-out morph
   that doubles as the open/close feedback. */
.menu-toggle__icon,
.menu-toggle__icon::before,
.menu-toggle__icon::after {
  display: block;
  width: 22px;
  height: 2px;
  background-color: currentColor;
  transition: transform 0.3s var(--ease-out-quart),
              opacity 0.2s var(--ease-out-quart),
              background-color 0.2s var(--ease-out-quart);
}

.menu-toggle__icon {
  position: relative;
}

.menu-toggle__icon::before,
.menu-toggle__icon::after {
  content: '';
  position: absolute;
  left: 0;
}

.menu-toggle__icon::before { top: -7px; }
.menu-toggle__icon::after  { top: 7px; }

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

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

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

/* Load state: the bars ease in shortly after first paint (opacity only, so it
   never fights the morph's transforms). Mobile-only in practice — the button is
   display:none on desktop. */
@keyframes menu-icon-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.js .menu-toggle__icon {
  animation: menu-icon-in 0.5s var(--ease-out-quart) 0.2s both;
}

/* ── Hero Section ── */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  background-color: var(--color-olive);
  overflow: hidden;

  /* Composition knobs. --sun-crest is how far the sun peeks above the cards;
     because the sun's vertical offset is derived from it (see .hero__sun-wrap),
     the crest stays this tall at every screen size, so the label always clears
     the copy and sits on the same sliver of sun. */
  --card-w: clamp(100px, 22vw, 240px);
  --sun-size: clamp(240px, 30vw, 360px);
  --sun-crest: 96px;
}

.hero__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Copy + deck are one centered group, so the empty olive splits evenly top and
   bottom instead of pooling above the copy. */
.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  padding: 8rem 2rem 3rem;
  max-width: var(--max-width-wide);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
}

/* The gap below the copy is where the sun's crest + label live, so it's sized
   to the crest — the label sits clear of the subtitle at every width. */
.hero__content {
  max-width: 640px;
  margin-bottom: calc(var(--sun-crest) + 2.5rem);
}

/* ── Hero deck: the illustrated cards, shown in full as the hero's artwork ──
   A warm, candlelit fan of illustrations, centered with the copy as one group. */
.hero__deck {
  position: relative;
  align-self: stretch;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  pointer-events: none;
}

.hero__card {
  position: relative;
  z-index: 1;
  width: var(--card-w);
  margin-inline: clamp(-1.5rem, -2vw, -0.5rem);
  transform-origin: 50% 100%;
  transform: rotate(var(--rot, 0deg)) translateY(var(--dy, 0px));
}

/* Center cards ride above the outer pair for a natural hand-of-cards overlap. */
.hero__card:nth-child(2) { z-index: 3; }
.hero__card:nth-child(3) { z-index: 2; }

.hero__card-plane {
  display: block;
  position: relative;
}

.hero__card-art {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
  user-select: none;
  -webkit-user-drag: none;
}

/* Diegetic lamplight seated on each card's own painted flame (--lx / --ly),
   breathing slowly so the deck never feels frozen — matters most on touch,
   where there's no pointer parallax. */
.hero__card-bloom {
  position: absolute;
  left: var(--lx, 50%);
  top: var(--ly, 50%);
  width: 55%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  background: radial-gradient(circle,
    rgba(255, 224, 150, 0.5) 0%,
    rgba(245, 195, 110, 0.22) 36%,
    rgba(230, 170, 70, 0) 70%);
  animation: tarot-bloom 6.5s var(--ease-out-quart) infinite;
}

/* ── The sun: the Book a Session CTA, rising from behind the deck ──
   A warm disc centered behind the cards; only its labelled crest shows above
   the arc. It rises in as the load's finale and glows hard on hover / focus /
   touch. The resting glow is a deliberate, scoped exception to the Earned
   Shadow Rule — this is the single hero action and the point of the whole
   composition.

   The vertical offset is derived so the sun's top sits exactly --sun-crest
   above the cards' tops (card height = --card-w × 1.5 for the 2:3 art),
   keeping the visible crest a constant height across screen sizes. */
.hero__sun-wrap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--card-w) * 1.5 + var(--sun-crest) - var(--sun-size));
  z-index: 0;                    /* behind the cards (z 1–3) */
  display: flex;
  justify-content: center;
  pointer-events: none;
}

.hero__sun {
  display: block;
  /* Narrower than the card arc at every width so only the crest shows and the
     sun's sides stay hidden behind the cards. */
  width: var(--sun-size);
  aspect-ratio: 1;
  border-radius: 50%;
  text-decoration: none;
  pointer-events: auto;         /* clickable even where cards overlay it */
}

/* Hidden only when JS can rise it in; the fallback (or GSAP) reveals it, and
   without .js it ships resting and visible. */
.js .hero__sun { opacity: 0; }

.hero__sun-disc {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 44%,
    #FCE7A8 0%, #F5C64F 40%, #E8AA14 68%, #CE8B06 100%);
  box-shadow: 0 0 55px 6px rgba(232, 170, 20, 0.32);
  transition:
    box-shadow 0.5s var(--ease-out-quart),
    transform 0.5s var(--ease-out-quart),
    filter 0.5s var(--ease-out-quart);
}

.hero__sun-label {
  position: absolute;
  /* Sits within the visible crest, a constant distance below the sun's top. */
  top: calc(var(--sun-crest) * 0.55);
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  white-space: nowrap;
  font-family: var(--font-body);
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #3D2600;               /* dark ink on amber — same as the old CTA text */
}

.hero__sun-label i {
  transition: transform 0.4s var(--ease-out-quart);
}

/* Strong glow when hovered, focused, or tapped — the invitation lighting up. */
.hero__sun:hover .hero__sun-disc,
.hero__sun:focus-visible .hero__sun-disc,
.hero__sun:active .hero__sun-disc {
  box-shadow:
    0 0 130px 34px rgba(232, 170, 20, 0.66),
    0 0 46px 10px rgba(255, 224, 150, 0.6);
  filter: brightness(1.05);
  transform: translateY(-6px) scale(1.02);
}

.hero__sun:hover .hero__sun-label i,
.hero__sun:focus-visible .hero__sun-label i {
  transform: translateX(3px);
}

.hero__sun:focus-visible {
  outline: 3px solid var(--color-cream);
  outline-offset: 5px;
}

@media (prefers-reduced-motion: reduce) {
  .hero__sun-disc { transition: box-shadow 0.4s var(--ease-out-quart); }
  .hero__sun:hover .hero__sun-disc,
  .hero__sun:focus-visible .hero__sun-disc,
  .hero__sun:active .hero__sun-disc { transform: none; }
}

/* Page-leave wash: the screen fades to solid cream — the booking page's own
   background — so the final frame matches it and the swap is seamless. Injected
   + faded in by JS at the end of the exit animation. */
.hero-veil {
  position: fixed;
  inset: 0;
  z-index: 2000;
  opacity: 0;
  pointer-events: none;
  background: var(--color-cream);
}

.hero__tagline {
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #E5F0E3;
  margin-bottom: 1.5rem;
}

.hero h1 {
  margin: 0 0 1.5rem;
  color: var(--color-cream);
}

.hero__subtitle {
  font-size: 1.125rem;
  color: rgba(247, 245, 240, 0.92);
  max-width: 500px;
  margin: 0 0 2.5rem;
  line-height: 1.55;
}


/* ── Color Accent Utilities ── */
.icon--sage { color: var(--color-sage); }
.icon--amber { color: var(--color-amber); }
.icon--rust { color: var(--color-rust); }
.icon--slate { color: var(--color-slate); }
.icon--olive { color: var(--color-olive); }

/* ── Delight: living icons & quiet asides ── */
/* Section icons warm gently when their content row is hovered — a small
   sign of life on otherwise static cards. Calm scale, no bounce. */
.service-preview-item__icon,
.approach-card__icon {
  transform-origin: left center;
  transition: transform 0.3s var(--ease-out-quart), filter 0.3s var(--ease-out-quart);
}

/* A single quiet, human aside, set in the serif italic like a note left
   in the margin. One deliberate moment, not a recurring pattern. */
.reassurance {
  max-width: 480px;
  margin: 2.75rem auto 0;
  text-align: center;
  font-family: var(--font-heading);
  font-size: 1.1875rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--color-olive);
}

/* ── Section Styles ── */
.section {
  padding: var(--section-padding);
}

.section--sage {
  background-color: var(--color-sage-light);
}

.section--alt {
  background-color: var(--color-cream-dark);
}

.section--warm {
  background-color: #F0ECE3;
}

.section__label {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-olive);
  margin-bottom: 1rem;
}

.section__header {
  max-width: var(--max-width-text);
  margin: 0 auto 3rem;
}

/* ── Who I Work With: the illustrated spread (Home) ── */
.audience__intro {
  max-width: 540px;
  margin: 0 auto;
  color: var(--color-text-light);
}

/* Three cards laid out as a quiet arc. Baseline is a plain, fully-visible
   grid; the fan angle, dealt entrance and pointer-tilt are all layered on in
   JS only when motion is welcome, so no-JS and reduced-motion visitors get the
   same legible, static composition. */
.audience-spread {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem 2rem;
  max-width: var(--max-width-wide);
  margin: 0 auto;
  justify-items: center;
}

/* Mobile: a small card centered above a comfortably wide caption — the card
   art stays small, but the text spans most of the column so it isn't cramped. */
/* The card now holds its own copy on a flip side, so the article is just a
   centered card. perspective lives here (not baked into each transform) so the
   tilt on .tarot__card and the flip on .tarot__flip share one 3D scene. */
.tarot {
  width: 100%;
  max-width: 300px;
  display: flex;
  flex-direction: column;
  align-items: center;
  perspective: 1100px;
}

/* Wide: three cards across. */
@media (min-width: 880px) {
  .audience-spread {
    grid-template-columns: repeat(3, 1fr);
    gap: 3rem 1.75rem;
    align-items: start;
  }
  .tarot { max-width: 300px; }
}

/* A quiet instruction so the flip is discoverable — the copy now lives on the
   card backs, so visitors need to know to turn them over. */
.audience__hint {
  max-width: 540px;
  margin: -1.25rem auto 2.5rem;
  text-align: center;
  font-size: 0.9375rem;
  color: var(--color-text-light);
}

.audience__hint-icon {
  display: inline-block;
  margin-right: 0.4em;
  color: var(--color-olive);
  font-size: 1.05em;
}

/* The card is a <button> that carries the tilt (JS sets rotationX/Y here) and
   houses the flip layer. No fill or clipping of its own — the rounded corners
   and any clipping live on the two faces, so the 3D flip isn't cut off. */
.tarot__card {
  position: relative;
  display: block;
  width: 100%;
  max-width: 300px;
  aspect-ratio: 600 / 900;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  overflow: visible; /* any clip would flatten preserve-3d and kill the flip */
  transform-style: preserve-3d;
  transition: filter 0.4s var(--ease-out-quart);
}

/* Wide: the card fills its column. */
@media (min-width: 880px) {
  .tarot__card { max-width: none; }
}

/* Touch devices have no hover to drive the tilt. Instead of a baked-in static
   pose, JS drives a live gyroscope tilt (setupGyro) so the cards respond to the
   device being tilted. The resting dealt-by-hand pose is set there too, so no
   CSS preset is needed. Reduced-motion / no-JS visitors simply keep them flat. */

/* The flip layer sits inside the tilt layer so the two 3D transforms don't
   fight: the card tilts, the flip turns, both under the article's perspective. */
.tarot__flip {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transition: transform 0.75s var(--ease-out-expo);
}
.tarot__card[aria-pressed="true"] .tarot__flip {
  transform: rotateY(180deg);
}

/* Two faces stacked in depth. Each clips its own rounded corners so the flip
   edge stays crisp; backface-visibility hides whichever face is turned away. */
.tarot__face {
  position: absolute;
  inset: 0;
  border-radius: 10px;
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* The painted card back: the frame tan (#d4b587, the card's own border colour)
   with a fine paper grain and the audience copy centered on it. */
.tarot__face--back {
  transform: rotateY(180deg);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1.75rem 1.5rem;
  text-align: center;
  background-color: #d4b587;
  /* A double hairline drawn in the frame tone reads as a card-back border. */
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--color-olive) 22%, transparent),
    inset 0 0 0 6px #d4b587,
    inset 0 0 0 7px color-mix(in srgb, var(--color-olive) 14%, transparent);
}

/* Grain overlay: a self-contained SVG fractal-noise tile, desaturated to a
   neutral speckle and blended into the tan so it reads as paper, not pixels. */
.tarot__face--back::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='140'%20height='140'%3E%3Cfilter%20id='n'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.9'%20numOctaves='2'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='saturate'%20values='0'/%3E%3C/filter%3E%3Crect%20width='100%25'%20height='100%25'%20filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 140px 140px;
  opacity: 0.5;
  mix-blend-mode: overlay;
  pointer-events: none;
}

.tarot__back {
  position: relative; /* above the ::before grain */
  z-index: 1;
}

.tarot__back-title {
  display: block;
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.2;
  margin-bottom: 0.6rem;
  color: var(--color-olive);
}

.tarot__back-text {
  display: block;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--color-text);
}

.tarot__art {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
}

/* Diegetic lamplight: a soft gold bloom seated on the lantern already painted
   into each card (position passed per-card via --lx / --ly). It reads as the
   picture's own light, not a UI accent — warm-gold rather than the rationed
   booking amber, and it lives on a screen that carries no Book CTA. */
.tarot__bloom {
  position: absolute;
  left: var(--lx, 50%);
  top: var(--ly, 50%);
  width: 46%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  background: radial-gradient(circle,
    rgba(255, 224, 150, 0.55) 0%,
    rgba(245, 195, 110, 0.28) 34%,
    rgba(230, 170, 70, 0) 70%);
  animation: tarot-bloom 6.5s var(--ease-out-quart) infinite;
}

@keyframes tarot-bloom {
  0%, 100% { opacity: 0.6;  transform: translate(-50%, -50%) scale(0.94); }
  50%      { opacity: 0.92; transform: translate(-50%, -50%) scale(1.06); }
}

/* Gilded glare that tracks the pointer across the card face (JS sets --mx/--my). */
.tarot__sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: soft-light;
  background: radial-gradient(
    120px 160px at calc(var(--mx, 0.5) * 100%) calc(var(--my, 0.35) * 100%),
    rgba(255, 240, 205, 0.9) 0%,
    rgba(255, 226, 165, 0.35) 30%,
    rgba(255, 226, 165, 0) 62%);
  transition: opacity 0.35s var(--ease-out-quart);
}

@media (hover: hover) and (pointer: fine) {
  /* Earned shadow: cards stay flat at rest, lifting only under the pointer.
     drop-shadow (not box-shadow) so the lift follows the card's rounded
     silhouette rather than casting a rectangle behind its transparent corners.
     It sits on the faces, not the card: a filter on the preserve-3d .tarot__card
     would flatten the flip. backface-visibility keeps it to the shown side. */
  .tarot__card:hover .tarot__face {
    filter: drop-shadow(0 16px 26px rgba(28, 22, 8, 0.5));
  }
  .tarot__card:hover .tarot__sheen { opacity: 1; }
}

/* Reduced motion: the flip is an intentional response to a tap, so it stays —
   but as an instant swap rather than a 0.75s rotation, and the sheen stops. */
@media (prefers-reduced-motion: reduce) {
  .tarot__flip { transition: none; }
  .tarot__bloom { animation: none; opacity: 0.72; }
}

/* ── Services Preview (Home) ── */
.services-preview {
  max-width: var(--max-width-text);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
}

.service-preview-item {
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
}

.service-preview-item__icon {
  flex-shrink: 0;
  font-size: 1.5rem;
  margin-top: 1.5rem;
}

.service-preview-item h3 {
  margin-bottom: 0.5rem;
}

.service-preview-item p {
  font-size: 0.9375rem;
  color: var(--color-text-light);
}

/* ── Services Index (Home "What I Offer") ──
   A compact, left-headed contents band: the section title sits in its own
   column beside a tight, hairline-separated list of services with soft
   tinted icon chips (sage / amber / rust, matching the icon rotation). */
.services-index {
  padding: clamp(2.5rem, 5vw, 4rem) 2rem;
  background-color: var(--color-cream);
}

.services-index__inner {
  max-width: var(--max-width-wide);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.5fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.services-index__eyebrow {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-olive);
  margin: 0 0 0.6rem;
}

.services-index__title {
  font-size: clamp(2rem, 3.5vw, 3rem);
  line-height: 1.1;
  margin: 0;
}

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

.services-index__item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.1rem;
  align-items: start;
  padding-block: 1.35rem;
}

.services-index__item + .services-index__item {
  border-top: 1px solid rgba(196, 185, 168, 0.45);
}

.services-index__chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 10px;
  font-size: 1.15rem;
  flex-shrink: 0;
}

.services-index__chip--sage { background-color: rgba(143, 175, 138, 0.16); color: var(--color-sage-dark); }
.services-index__chip--amber { background-color: rgba(232, 170, 20, 0.15); color: #7A5C00; }
.services-index__chip--rust { background-color: rgba(215, 78, 9, 0.12); color: var(--color-rust); }

.services-index__name {
  font-size: 1.3rem;
  margin: 0 0 0.25rem;
}

.services-index__desc {
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--color-text);
  margin: 0;
}

.services-index__cta {
  margin-top: 1.75rem;
}

@media (max-width: 768px) {
  .services-index__inner {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  .services-index__cta {
    display: block;
    width: max-content;
    margin: 1.75rem auto 0;
  }
}

/* ── CTA Banner ── */
.cta-banner {
  position: relative;
  overflow: hidden;
  padding: var(--section-padding);
  text-align: center;
  background-color: var(--color-olive);
  color: rgba(247, 245, 240, 0.9);
}

.cta-banner__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Lift the banner's copy above the ambient shader canvas. */
.cta-banner > :not(.cta-banner__canvas) {
  position: relative;
  z-index: 1;
}

.cta-banner h2 {
  color: var(--color-cream);
  margin-bottom: 1rem;
}

.cta-banner p {
  color: rgba(247, 245, 240, 0.88);
  max-width: 500px;
  margin: 0 auto 2rem;
  font-size: 1.0625rem;
}

/* The booking CTA on the drenched banner renders in amber (via .btn--amber in
   markup) — the one action worth the glow. Any .btn--primary here (e.g. the
   "Email Me" support action on the Book page) stays sage: calmer, secondary. */

/* ── About Page ── */
.about-intro-split {
  max-width: var(--max-width-wide);
  margin: 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 4rem;
}

.about-intro-split__text {
  flex: 1;
  max-width: var(--max-width-text);
}

.about-intro-split__photo {
  flex: 0 0 280px;
  clip-path: circle(50%);
}

/* Crop the (portrait) source to a square so the circle stays round. */
.about-intro-split__photo img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.about-intro {
  max-width: var(--max-width-text);
  margin: 0 auto;
}

.about-intro p {
  color: var(--color-text-light);
}

.approach-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  max-width: var(--max-width-wide);
  margin: 0 auto;
}

.approach-card {
  padding: 2rem 0;
}

.approach-card__icon {
  font-size: 2rem;
  margin-bottom: 1rem;
}

.approach-card h3 {
  margin-bottom: 0.75rem;
}

.approach-card p {
  font-size: 0.9375rem;
  color: var(--color-text-light);
  line-height: 1.7;
}

.values-list {
  max-width: var(--max-width-text);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

.values-list__item {
  display: flex;
  align-items: flex-start;
  gap: 1.25rem;
}

.values-list__marker {
  flex-shrink: 0;
  color: var(--color-amber);
  font-size: 1rem;
}

.values-list__item h3 {
  font-size: 1.125rem;
  margin-bottom: 0.375rem;
}

.values-list__item p {
  font-size: 0.9375rem;
  color: var(--color-text-light);
}

/* ── Services Page ── */
.service-detail {
  max-width: var(--max-width-text);
  margin: 0 auto;
}

.service-detail + .service-detail {
  margin-top: 4rem;
}

.service-detail__icon {
  font-size: 1.375rem;
  margin-bottom: 1rem;
}

.service-detail h3 {
  font-size: 1.5rem;
  margin-bottom: 1rem;
}

.service-detail p {
  font-size: 1rem;
  color: var(--color-text-light);
}

.service-detail .focus-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.25rem;
}

.focus-tag {
  display: inline-block;
  font-size: 0.8125rem;
  font-weight: 500;
  padding: 0.375rem 0.875rem;
  border-radius: 20px;
  background-color: rgba(143, 175, 138, 0.1);
  color: var(--color-olive);
  transition: transform 0.2s ease;
}

.focus-tag:nth-child(3n+2) {
  background-color: rgba(232, 170, 20, 0.1);
  color: #7A5C00;
}

.focus-tag:nth-child(3n+3) {
  background-color: rgba(196, 185, 168, 0.25);
  color: var(--color-text);
}

.focus-tag:hover {
  transform: translateY(-1px);
}

.session-format {
  max-width: var(--max-width-text);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
}

.session-format__option {
  padding: 2rem;
  text-align: center;
}

.session-format__option i {
  font-size: 1.5rem;
  color: var(--color-sage);
  margin-bottom: 1rem;
  display: block;
}

.session-format__option h3 {
  font-size: 1.125rem;
  margin-bottom: 0.5rem;
}

.session-format__option p {
  font-size: 0.9375rem;
  color: var(--color-text-light);
}

/* ── Book Page ── */
/* The booking invitation: the page's one clear next step, framed as a calm,
   low-pressure moment rather than a naked button. Flat at rest — the only lift
   is the amber CTA's own hover (Earned Shadow Rule). The soft sage wash ties the
   alcove to the brand's own hue, not a generic beige panel. */
.book-invite {
  max-width: 600px;
  margin: 0 auto;
  padding: clamp(2.25rem, 5vw, 3.5rem) clamp(1.5rem, 5vw, 3.25rem);
  text-align: center;
  background-color: rgba(143, 175, 138, 0.08);
  border: 1px solid rgba(143, 175, 138, 0.26);
  border-radius: 12px;
}

/* ── Booking surface ──
   A calm cream section holding the booking card: a light, lightly-frosted cream
   glass with dark text for AA legibility, amber reserved for the button. */
.booking {
  padding: clamp(3.5rem, 7vw, 5.5rem) 2rem;
  background-color: var(--color-cream);
}

.booking .book-invite {
  position: relative;
  z-index: 1;
  background-color: rgba(255, 253, 248, 0.05);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(74, 94, 70, 0.18);
  box-shadow: 0 10px 34px rgba(74, 94, 70, 0.14);
}

.booking .book-invite__lead { color: var(--color-text); }
.booking .book-hint { color: var(--color-text-light); }

.booking .book-invite__alt {
  color: var(--color-text-light);
  border-top-color: rgba(74, 94, 70, 0.18);
}

.booking .book-invite__alt a {
  color: var(--color-olive);
  text-decoration: underline;
}

.booking .book-assurance { color: var(--color-text); }
.booking .book-assurance svg { color: var(--color-olive); }

.book-invite__title {
  margin-bottom: 1rem;
  text-wrap: balance;
}

.book-invite__lead {
  font-size: 1.0625rem;
  line-height: 1.7;
  color: var(--color-text);
  max-width: 46ch;
  margin: 0 auto;
  text-wrap: pretty;
}

.book-cta {
  margin: 2rem auto 0;
}

.book-cta__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  font-size: 1.1875rem;
  padding: 1.15rem 2.75rem;
}

.book-cta__btn i {
  font-size: 0.95em;
}

/* Concrete, friction-reducing reassurances sitting just under the CTA */
.book-assurances {
  list-style: none;
  margin: 1.5rem auto 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem 1.75rem;
}

.book-assurance {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9375rem;
  color: var(--color-text);
}

.book-assurance svg {
  width: 1.15em;
  height: 1.15em;
  flex-shrink: 0;
  color: var(--color-sage-dark);
}

.book-invite .book-hint {
  margin-top: 1.25rem;
  font-size: 0.8125rem;
  color: var(--color-text-light);
}

/* Low-pressure fallback, set off from the primary action by a hairline rule */
.book-invite__alt {
  max-width: 46ch;
  margin: 1.75rem auto 0;
  padding-top: 1.75rem;
  border-top: 1px solid rgba(143, 175, 138, 0.22);
  font-size: 0.9375rem;
  color: var(--color-text-light);
}

/* Booking button: the calendar icon re-draws its check on hover, with a soft press */
.book-ico {
  width: 1.3em;
  height: 1.3em;
  display: inline-block;
  vertical-align: -0.22em;
}

.book-ico__check {
  stroke-dasharray: 22;
  stroke-dashoffset: 0;
}

@keyframes bookDraw {
  from { stroke-dashoffset: 22; }
  to { stroke-dashoffset: 0; }
}

.book-cta__btn:hover .book-ico__check {
  animation: bookDraw 2s var(--ease-out-quart);
}

.book-cta__btn:active {
  transform: translateY(1px) scale(0.995);
}

@media (prefers-reduced-motion: reduce) {
  .book-cta__btn:hover .book-ico__check {
    animation: none;
  }
}

/* The three steps read as one ordered sequence: numbers sit in olive rings
   linked by a hairline connector. Amber is deliberately kept off these
   markers so it stays reserved for the booking action (Rationed Amber Rule). */
.book-steps {
  max-width: var(--max-width-text);
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3rem;
  text-align: center;
  position: relative;
}

.book-steps::before {
  content: "";
  position: absolute;
  top: 1.5rem;
  left: 16.666%;
  right: 16.666%;
  height: 1px;
  background-color: rgba(196, 185, 168, 0.7);
  z-index: 0;
}

.book-step {
  position: relative;
  z-index: 1;
}

.book-step__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  border: 1.5px solid var(--color-olive);
  background-color: var(--color-cream-dark);
  font-family: var(--font-heading);
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--color-olive);
  line-height: 1;
  margin-bottom: 1rem;
}

.book-step h3 {
  font-size: 1.125rem;
  margin-bottom: 0.5rem;
}

.book-step p {
  font-size: 0.9375rem;
  color: var(--color-text-light);
}

@media (max-width: 640px) {
  .book-steps {
    grid-template-columns: 1fr;
  }
  .book-steps::before {
    display: none;
  }
}

/* ── Page Header (inner pages) ── */
.page-header {
  padding: 9rem 2rem 4rem;
  text-align: center;
}

.page-header h1 {
  margin-bottom: 1rem;
}

.page-header p {
  font-size: 1.125rem;
  color: var(--color-text-light);
  max-width: 540px;
  margin: 0 auto;
}

/* ── Footer ── */
.site-footer {
  padding: 3.5rem 2rem 2.5rem;
  border-top: 1px solid rgba(196, 185, 168, 0.3);
}

.site-footer__inner {
  max-width: var(--max-width-wide);
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 2rem;
}

.site-footer__brand {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-olive);
  margin-bottom: 0.5rem;
}

.site-footer__contact {
  font-size: 0.875rem;
  color: var(--color-text-light);
  line-height: 1.8;
}

.site-footer__contact a {
  color: var(--color-text-light);
}

.site-footer__contact a:hover {
  color: var(--color-olive);
}

.site-footer__nav {
  display: flex;
  gap: 1.75rem;
}

.site-footer__nav a {
  font-size: 0.875rem;
  color: var(--color-text-light);
}

.site-footer__nav a:hover {
  color: var(--color-olive);
}

.site-footer__bottom {
  max-width: var(--max-width-wide);
  margin: 2rem auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(196, 185, 168, 0.2);
  text-align: center;
  font-size: 0.8125rem;
  color: var(--color-text-light);
}

/* ── GSAP scroll choreography (home page) ──
   Reveal targets start hidden (opacity only — no layout shift) and are brought
   in by GSAP ScrollTrigger in main.js. Scoped to .js so no-JS visitors ship
   fully visible; forced visible under reduced motion (GSAP short-circuits to a
   static reveal there too). If GSAP fails to load, main.js reveals them on load
   so nothing is ever stranded at opacity 0. */
.js [data-reveal],
.js [data-reveal-group] > * {
  opacity: 0;
}

/* The hero copy carries a scrubbed parallax as the hero scrolls away. */
.js .hero__content {
  will-change: transform, opacity;
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js [data-reveal-group] > * {
    opacity: 1 !important;
    transform: none !important;
  }
  .js .hero__content {
    will-change: auto;
  }
}

/* ── Hero Entrance Motion ──
   Hidden-then-reveal states are scoped to .js so the page always ships
   fully visible when JavaScript is unavailable — no blank sections.
   Scroll reveals are handled by the GSAP data-reveal system above; this
   block is the hero's one-time page-load choreography.

   Hero page-load choreography: content rises in sequence on first paint.
   Pure CSS with a forwards fill, so it always completes on its own; the
   .js scope keeps no-JS visitors on a fully static hero. */
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

.js .hero__tagline,
.js .hero h1,
.js .hero__subtitle {
  opacity: 0;
  animation: hero-rise 0.8s var(--ease-out-quart) forwards;
}

.js .hero__tagline  { animation-delay: 0.15s; }
.js .hero h1        { animation-delay: 0.28s; }
.js .hero__subtitle { animation-delay: 0.42s; }

/* Deck cards start hidden only when JS can deal them in; the fallback in
   main.js (or GSAP itself) reveals them, so JS-on / GSAP-off never strands
   them. Without .js at all they ship fully visible in the arc. */
.js .hero__card { opacity: 0; }

/* ── Reduced Motion ── */
@media (prefers-reduced-motion: reduce) {
  .js .hero__tagline,
  .js .hero h1,
  .js .hero__subtitle,
  .js .site-nav__link,
  .js .site-nav__footer {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
    transition: none !important;
  }

  /* Cards keep their static arc pose — only the entrance and the breathing
     lamplight are removed. The sun rests in place, visible and lit. */
  .js .hero__card { opacity: 1 !important; }
  .js .hero__sun { opacity: 1 !important; }
  .hero__card-bloom { animation: none; opacity: 0.7; }

  /* Hamburger still morphs to an X (it's a state indicator, not decoration) —
     just without the tween or the load-in fade. */
  .js .menu-toggle__icon,
  .menu-toggle__icon,
  .menu-toggle__icon::before,
  .menu-toggle__icon::after,
  .menu-overlay {
    animation: none !important;
    transition: none !important;
  }

  .audience-card:hover .audience-card__icon,
  .service-preview-item:hover .service-preview-item__icon,
  .approach-card:hover .approach-card__icon {
    transform: none !important;
  }

  html {
    scroll-behavior: auto;
  }
}

/* ── Responsive ── */
@media (max-width: 768px) {
  :root {
    --section-padding: var(--section-padding-mobile);
  }

  .site-header__inner {
    padding: 0.875rem 1.25rem;
  }

  /* No backdrop-filter here: it would make the header a containing block for
     the fixed drawer/overlay below, trapping them inside the header box.
     A translucent (un-blurred) background keeps the see-through look. */
  .site-header {
    background-color: rgba(247, 245, 240, 1);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .menu-toggle {
    display: flex;
  }

  .site-nav {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(80vw, 310px);
    background-color: var(--color-cream-dark);
    padding: 5.25rem 1.75rem 2rem;
    transform: translateX(100%);
    transition: transform 0.35s var(--ease-out-quart);
    box-shadow: -8px 0 30px rgba(0, 0, 0, 0.12);
    z-index: 1101;
    border-left: 1px solid rgba(196, 185, 168, 0.3);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
  }

  .site-nav--open {
    transform: translateX(0);
  }

  .site-nav__list {
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0;
    align-items: stretch;
    margin-top: 0.25rem;
  }

  /* Each list item grows to share the panel height equally (the <li> is the
     flex child of the list, so the distribution has to live here), and the
     link stretches to fill its row — so the four links spread from the header
     down to the contact block and fill the drawer instead of clustering up top. */
  .site-nav__list li {
    flex: 1 1 0;
    display: flex;
  }

  /* Full-width divider rows give the four links real structure. */
  .site-nav__link {
    display: flex;
    flex: 1;
    align-items: center;
    min-height: 56px;
    font-size: 1.5rem;
    color: var(--color-text);
    border-bottom: 1px solid rgba(196, 185, 168, 0.4);
  }

  .site-nav__list li:last-child .site-nav__link {
    border-bottom: none;
  }

  /* The desktop grow-underline clashes with the row dividers here */
  .site-nav__link::after {
    display: none;
  }

  .site-nav__link:hover,
  .site-nav__link--active {
    color: var(--color-olive);
    font-weight: 500;
  }

  /* Contact block anchored to the bottom — fills what was empty space below
     the links without piling on another booking CTA. */
  .site-nav__footer {
    display: block;
    margin-top: auto;
    padding-top: 1.75rem;
  }

  .site-nav__contact {
    margin-top: 1.25rem;
    font-size: 0.8125rem;
    line-height: 1.7;
    text-align: center;
    color: var(--color-text-light);
  }

  /* Open choreography: links and the contact block ease in from the right in a
     gentle sequence once the drawer is open. The stagger delays live only on the
     open state, so closing lets everything fade straight out with the sliding
     drawer rather than lingering. Scoped to .js so a no-JS drawer (which never
     opens) keeps its links visible. */
  .js .site-nav__link,
  .js .site-nav__footer {
    opacity: 0;
    transform: translateX(14px);
    transition: opacity 0.35s var(--ease-out-quart),
                transform 0.35s var(--ease-out-quart),
                color 0.25s ease;
  }

  .js .site-nav--open .site-nav__link,
  .js .site-nav--open .site-nav__footer {
    opacity: 1;
    transform: none;
  }

  .js .site-nav--open .site-nav__list li:nth-child(1) .site-nav__link { transition-delay: 0.10s; }
  .js .site-nav--open .site-nav__list li:nth-child(2) .site-nav__link { transition-delay: 0.16s; }
  .js .site-nav--open .site-nav__list li:nth-child(3) .site-nav__link { transition-delay: 0.22s; }
  .js .site-nav--open .site-nav__list li:nth-child(4) .site-nav__link { transition-delay: 0.28s; }
  .js .site-nav--open .site-nav__footer { transition-delay: 0.32s; }

  /* When GSAP owns the reveal it sets opacity/visibility/transform inline; drop
     the CSS transition on those props here so the browser doesn't also tween
     them (which would smear GSAP's overshoot). Only colour still transitions. */
  .site-nav--gsap .site-nav__link,
  .site-nav--gsap .site-nav__footer {
    transition: color 0.25s ease;
  }

  /* Overlay crossfades in/out with the drawer (opacity + visibility, so it can
     transition — display can't). */
  .menu-overlay {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.25);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s var(--ease-out-quart), visibility 0.3s var(--ease-out-quart);
    z-index: 999;
  }

  .menu-overlay--visible {
    opacity: 1;
    visibility: visible;
  }

  .hero__inner {
    padding: 6.5rem 1.25rem 2.5rem;
    align-items: center;
    text-align: center;
  }

  .hero h1 {
    font-size: 2.5rem;
  }

  .hero__subtitle {
    font-size: 1rem;
  }

  .about-intro-split {
    flex-direction: column;
    gap: 2rem;
  }

  .about-intro-split__photo {
    flex: none;
    width: 200px;
    clip-path: circle(50%);
    margin: 0 auto;
    position: static;
  }

  .approach-grid {
    grid-template-columns: 1fr;
  }

  .session-format {
    grid-template-columns: 1fr;
  }

  .site-footer__inner {
    flex-direction: column;
    gap: 1.5rem;
  }

  .site-footer__nav {
    flex-wrap: wrap;
    gap: 1rem;
  }

  .page-header {
    padding: 7rem 1.25rem 2rem;
  }
}

@media (max-width: 480px) {
  .btn {
    width: 100%;
    max-width: 280px;
    text-align: center;
  }
}

/* On shorter/narrower screens, keep the deck anchored to the bottom but center
   the copy in the space above it — so it sits midway between the navbar and the
   sun/deck, instead of floating high or pinned to the top. */
@media (max-width: 900px) {
  .hero__content {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
}
