/* ==========================================================
   Psychologist landing page — Orange theme (coolors.co/faa275-ff8c61-
   ce6a85-985277-5c374c) is the site default. Prune (client palette:
   392132-b55a30-ded4a1-e5dcce) lives on as data-theme="prune", alongside
   the original warm tan/maroon palette (data-theme="original") and blue.
   ========================================================== */

:root {
  /* Orange palette — tuned for WCAG AA contrast on both light and dark ground */
  --cream: #FDE6D8;
  --cream-deep: #FBE0CE;
  --tan: #FAA275;
  --tan-deep: #FFA47D;
  --maroon: #5C374C;
  --maroon-soft: #985277;
  --maroon-deep: #3E2733;
  --ink: #4A2E3F;
  --cream-text: #FDEEE3;
  --halo-color: #FF9D79;
  --mon-approche-bg: color-mix(in srgb, var(--tan) 20%, var(--cream) 80%);

  --white: #FFFFFF;

  --font-heading: "Ovo", Georgia, serif;
  --font-body: "Work Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --radius: 20px;
  --radius-sm: 10px;
  --shadow: 0 8px 30px rgba(57, 33, 50, 0.1);
  --max-width: 1120px;
  --header-h: 81px;
}

/* ---------- Prune theme (client palette: 392132-b55a30-ded4a1-e5dcce) —
   the previous site default, still selectable in the theme rotation. ---------- */
[data-theme="prune"] {
  --cream: #FDF2E1;        /* lightest section bg */
  --cream-deep: #F6E5CB;   /* soft alt section bg — a warm step down from
                               --cream, not the old grayish tone, so the
                               séance card reads as a gentle shade rather
                               than a mismatched, contrasty block */
  --tan: #B55A30;          /* logo ring / secondary accent */
  --tan-deep: #DED4A1;     /* bright accent, for text on dark maroon */
  --halo-color: #C1654A;   /* hero: the moving "tache" that follows the cursor */

  --maroon: #4D3746;       /* card / button bg */
  --maroon-soft: #614D5B;  /* nav links, body copy */
  --maroon-deep: #392132;  /* headings */
  --ink: #392132;          /* body copy fallback */
  --cream-text: #E5DCCE;   /* text on dark maroon */

  /* "Mon approche"'s background — Prune only gets a hand-picked flat
     value rather than the derived color-mix() formula the other three
     themes use below (see .section-tan). */
  --mon-approche-bg: #F6E5CB;
}
/* See the Anchored Sections comment below [data-theme="original"] — every
   other theme needs its own explicit .section-dark or it falls through to
   the default's tuned values, which clash. .section-tan no longer needs
   one: its background is now derived from each theme's own --tan/--cream
   tokens (see the base .section-tan rule), so it adapts automatically.
   Prune is the exception — no override here on purpose, so it falls
   through to the base .section-dark and matches the default's exact color. */

/* ---------- Blue theme (coolors.co/2b59c3-253c78-d36582-ffeecf-c9a690) ---------- */
[data-theme="blue"] {
  --cream: #FAE7C9;
  --cream-deep: #F6E2C6;
  --tan: #C9A690;
  --tan-deep: #E890A8;
  --maroon: #253C78;
  --maroon-soft: #2B59C3;
  --maroon-deep: #16244D;
  --ink: #1F3568;
  --cream-text: #FFEECF;
  --halo-color: #F3B4C4;
  --mon-approche-bg: color-mix(in srgb, var(--tan) 20%, var(--cream) 80%);
}
[data-theme="blue"] .section-dark { background: #684040; }

/* ---------- Original theme (the site's first warm tan/maroon palette,
   matching the previous Squarespace site) — no longer the default, kept
   in the rotation as data-theme="original" ---------- */
[data-theme="original"] {
  --cream: #F3E9DA;
  --cream-deep: #F0E6D8;
  --tan: #DCC08D;
  --tan-deep: #E8C687;
  --maroon: #5C3A32;
  --maroon-soft: #6E4C3E;
  --maroon-deep: #4A2C25;
  --ink: #4A362E;
  --cream-text: #F3E9DA;
  --halo-color: #E2B571;
  --mon-approche-bg: color-mix(in srgb, var(--tan) 20%, var(--cream) 80%);
}
/* "À propos" doesn't follow --tan / --maroon like the rest of the page
   (see .section-dark below) — set explicitly per theme instead.
   "Mon approche" (.section-tan) now derives from --tan/--cream directly,
   so it no longer needs a per-theme override here. */
[data-theme="original"] .section-dark { background: #684040; }

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

[id] { scroll-margin-top: var(--header-h); }

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--cream);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--font-heading);
  font-weight: 500;
  line-height: 1.2;
  margin: 0 0 0.5em;
  color: var(--maroon);
}

h1 { font-size: clamp(2.2rem, 5vw, 3.4rem); font-weight: 600; }
h2 { font-size: clamp(1.8rem, 3.4vw, 2.6rem); }
h3 { font-size: 1.15rem; }

p { margin: 0 0 1em; color: var(--maroon-soft); }

a { color: var(--maroon-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

.container {
  width: 100%;
  max-width: var(--max-width);
  margin: 0 auto;
  /* Scales with the viewport instead of a fixed 24px, so the side margin
     stays proportionally similar on a laptop screen as on a large desktop
     monitor, rather than shrinking to a sliver once the viewport gets
     close to --max-width. */
  padding: 0 clamp(32px, 9vw, 140px);
}

/* Fixed-width narrow boxes already get generous outer whitespace for free
   once the viewport passes ~760px + the base padding (the box just sits
   centered with empty space around it) — letting .container's vw-scaled
   padding keep growing on top of that eats into a width that never grows,
   which is what made the hero buttons wrap on wide screens. Cap it lower
   here instead. */
.section-narrow {
  max-width: 760px;
  padding-left: clamp(24px, 6vw, 56px);
  padding-right: clamp(24px, 6vw, 56px);
}
.section-medium { max-width: 980px; }

.placeholder-flag {
  color: var(--maroon-deep);
  font-weight: 500;
  font-size: 0.85em;
  opacity: 0.65;
}

/* Skip link */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--maroon);
  color: var(--cream-text);
  padding: 10px 16px;
  border-radius: 0 0 8px 0;
  z-index: 100;
}
.skip-link:focus { left: 0; }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  /* Was 0.38 — nearly see-through, which reads fine gliding over the
     page's light sections but, being sticky, this also has to sit atop
     .section-dark ("À propos") whenever that one scrolls underneath it;
     at that opacity the dark ground bled straight through and the nav
     links (--maroon-soft) lost all contrast against it. High enough now
     to stay legible over any section; backdrop-filter still keeps a bit
     of the frosted-glass feel rather than going flat opaque. */
  background: rgba(246, 238, 227, 0.85);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid rgba(92, 58, 50, 0.1);
}

/* Grid, not flex — the 1fr/auto/1fr split is what lets the middle column
   sit truly centered on the whole bar while still having a hard boundary
   it can never spill past. The old approach (nav-links absolutely
   centered on the full header, oblivious to the logo/CTA next to it)
   looked identical when there was room to spare, but had zero collision
   awareness: it overlapped the logo and CTA button across a wide,
   very-much-in-use range of viewport widths (~861–1150px). */
.header-inner {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: 20px;
  padding-top: 16px;
  padding-bottom: 16px;
  /* A percentage so it keeps growing with the viewport instead of hard-
     stopping at a fixed pixel cap like the rest of the site's content
     (max 1280px) — capped at 1600px so it doesn't stretch absurdly wide
     on an ultra-wide monitor, and floored at 1100px so it never shrinks
     below what the desktop nav (logo + 5 links + CTA, all nowrap) needs
     right above the 1220px breakpoint where it takes over from the
     hamburger menu. */
  max-width: clamp(1100px, 95%, 1600px);
}

.logo {
  grid-column: 1;
  justify-self: start;
  /* A 1fr grid track is free to shrink below its content's natural width
     (its default min-width is min-content, not the full single-line
     width) — without this, "Léa Di Fant" wraps onto three lines the
     moment things get tight, instead of the nav links (which are meant
     to be the part that adapts) taking the squeeze. */
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: "Playfair Display", var(--font-heading);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--maroon);
}
.logo:hover { text-decoration: none; }

.logo-mark {
  width: 48px;
  height: 48px;
  flex: 0 0 auto;
  display: block;
}
/* No per-theme override here on purpose — the center dot's fill is set
   on the element itself (fill="var(--halo-color)") so it always tracks
   whatever the current theme's own halo color is, instead of a value
   hand-picked once and left to drift out of sync as that color changes. */

@media (max-width: 600px) {
  .logo { font-size: 1.4rem; }
  .logo-mark { width: 36px; height: 36px; }
}

/* On desktop, .primary-nav's own box disappears from layout (display:
   contents) so its two children — .nav-links and the CTA — become direct
   grid items of .header-inner: nav-links takes the true-centered middle
   column, the CTA takes the right column. The mobile media query below
   turns this back into a real flex box for the dropdown, which overrides
   display:contents there. */
.primary-nav {
  display: contents;
}

.nav-links {
  grid-column: 2;
  display: flex;
  align-items: center;
  gap: 30px;
}
/* Same reasoning as .logo/.nav-cta's white-space: nowrap — a flex item's
   default min-width is min-content, so a two-word link ("Mon approche",
   "À propos") is free to break onto its own second line under the
   slightest squeeze instead of the row just running out of room. */
.nav-links a { white-space: nowrap; }

.nav-cta {
  grid-column: 3;
  justify-self: end;
  white-space: nowrap;
}

.primary-nav a:not(.btn) {
  color: var(--maroon-soft);
  font-weight: 500;
  font-size: 1.05rem;
}
.primary-nav a:not(.btn):hover { color: var(--maroon-deep); text-decoration: none; }

.nav-cta { margin-left: 4px; }

.nav-toggle {
  grid-column: 3;
  justify-self: end;
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}
.nav-toggle span {
  display: block;
  height: 2px;
  width: 24px;
  background: var(--maroon);
  margin: 0 auto;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  padding: 12px 26px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.95rem;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.btn:hover { text-decoration: none; }

.btn-primary {
  background: var(--maroon);
  color: var(--cream-text);
  box-shadow: var(--shadow);
}
.btn-primary:hover {
  background: var(--maroon-deep);
  transform: translateY(-1px);
}

.btn-outline {
  background: transparent;
  color: var(--maroon);
  border: 1.5px solid var(--maroon-soft);
  padding: 9px 22px;
}
.btn-outline:hover {
  background: var(--maroon);
  color: var(--cream-text);
}

.btn-ghost {
  background: transparent;
  color: var(--maroon);
  border: 1.5px solid rgba(92, 58, 50, 0.25);
}
.btn-ghost:hover {
  border-color: var(--maroon);
  background: rgba(92, 58, 50, 0.05);
}

.btn-large { padding: 16px 36px; font-size: 1.05rem; }

/* ---------- Hero quote banner ---------- */
.hero {
  position: relative;
  min-height: calc(100vh - var(--header-h));
  min-height: calc(100svh - var(--header-h));
  display: flex;
  align-items: center;
  background: var(--cream);
  overflow: hidden;
}
/* Prune only — a dedicated ground for the halo instead of the shared
   --cream token, so this one section can be tuned without moving
   --cream's other uses site-wide. */
[data-theme="prune"] .hero { background: #FEFAE0; }

/* The "tache" — a single colored patch, fixed at the center of the hero.
   A separate layer (not the background itself), so the ground stays flat
   and the patch reads clearly. Used to track the cursor (via --mx/--my
   set by JS); now static and centered instead, so that JS was removed. */
/* "circle <length>" rather than "80% 80%" — percentage radii on a
   radial-gradient size independently against the box's own width and
   height, so on a wide, short hero box (typical desktop) it draws as a
   stretched oval rather than a circle. vmin keeps it a true circle at
   any aspect ratio, since it's always the smaller of the two axes. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(circle 110vmin at 50% 50%, var(--halo-color) 0%, var(--halo-color) 35%, transparent 55%);
  opacity: 0.8;
  filter: contrast(1.15) saturate(1.15);
  /* The radial gradient's own "transparent 55%" only fully fades out
     within ~0.6x the *viewport's* smaller dimension (vmin) of its
     center — on any ordinary landscape screen that's less than half
     the hero's own height, so the gradient was still partway through
     fading, not yet invisible, exactly where #presentation starts.
     That leftover tint got hard-clipped at the section boundary
     instead of finishing its fade — worse the taller the hero (bigger
     screens), never actually about screen size specifically. A mask
     fading the whole layer to transparent over the hero's own last
     quarter guarantees it's fully gone by the boundary regardless of
     how far the radial gradient itself got, independent of viewport
     shape or size. */
  mask-image: linear-gradient(to bottom, black 0%, black 75%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 75%, transparent 100%);
}

/* subtle grain texture, no extra image asset */
.grain-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.35;
  mix-blend-mode: overlay;
  pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/></svg>");
}
/* A bit heavier here specifically — the extra texture is what gives the
   halo some perceived depth (a shallow, textured disc) instead of
   reading as a flat, too-clean gradient. */
.hero.grain-bg::before { opacity: 0.5; }


.hero-quote-wrap {
  position: relative;
  z-index: 1;
  /* Wide enough that even at max side padding, the content area can still
     reach .hero-quote's own 1200px max-width below — otherwise the base
     .container cap (1120px) bites first and leaves less room than the
     quote was actually designed for, forcing an extra line of wrap. */
  max-width: calc(1200px + 2 * 140px);
  /* Longhand on purpose — a "64px 0" shorthand here would zero out the
     side padding .container sets, undoing its side margin entirely. */
  padding-top: 64px;
  padding-bottom: 64px;
}

.hero-quote {
  position: relative;
  margin: 0 auto;
  max-width: 1200px;
  cursor: default;
}

/* Colorized: an oversized decorative quotation mark, tinted rather than
   left the same ink as the words it sits behind — a quiet editorial
   accent, not a second focal point. Painted before (behind) the real
   text in normal paint order; .hero's overflow:hidden clips it safely
   at small viewports. Pure decoration — no accessible text is attached. */
.hero-quote::before {
  content: "\201C";
  position: absolute;
  top: -0.5em;
  left: clamp(-0.6em, -4vw, -0.2em);
  font-family: var(--font-heading);
  font-size: clamp(6rem, 14vw, 11rem);
  line-height: 1;
  color: color-mix(in srgb, var(--maroon-soft) 45%, transparent);
  pointer-events: none;
  user-select: none;
}

.hero-quote p {
  font-family: var(--font-heading);
  font-size: clamp(1.6rem, 3.4vw, 3rem);
  color: var(--maroon-deep);
  line-height: 1.35;
  margin: 0 0 0.6em;
  transform-origin: left center;
  transition: transform 0.4s ease;
}
/* Prune only — a touch lighter than the site-wide --maroon-deep heading
   color, just for this quote. */
[data-theme="prune"] .hero-quote p { color: #513C4B; }
/* Hover anywhere on the quote block, but only the quoted text grows —
   the attribution line stays put. */
.hero-quote:hover p,
.hero-quote:focus-within p {
  transform: scale(1.06);
}

.hero-quote cite {
  display: block;
  text-align: right;
  font-family: var(--font-heading);
  font-style: normal;
  font-size: clamp(1.4rem, 2.6vw, 2rem);
  color: var(--maroon-soft);
}

/* ---------- Présentation intro ---------- */
.presentation-layout {
  display: block;
}
.intro-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
/* Name lockup — the big two-circle logo mark (same shapes as the nav
   logo) doubles as a stage for "Di Fant": that word sits inside the
   solid --maroon circle instead of running alongside "Léa" like a plain
   heading. --mark-size drives every dimension below it so the whole
   thing scales as one unit; .name-last is positioned in the mark's own
   0–100% box, which maps 1:1 to the SVG's viewBox, so left:38%/top:50%
   always lands exactly on the filled circle's center regardless of the
   mark's rendered size. A single <h1> with aria-label carries the real
   accessible name — the two spans inside are aria-hidden, since split
   across differently-styled fragments they're a visual effect, not
   structure a screen reader should announce piece by piece. */
.name-lockup {
  /* The circle has to be big enough to hold "Di Fant" at the exact same
     font-size as "Léa" (see --name-font-size) on one line. --name-font-size
     is derived FROM --mark-size (0.085 is the largest ratio that still
     leaves "Di Fant" comfortable margin inside the solid disc at the
     widest tested size) rather than tuned as its own independent clamp()
     — two separately-tuned values happened to line up at desktop sizes
     but drifted apart at the 860px breakpoint (mark-size shrunk further
     than font-size did), so "Di Fant" spilled out past the circle onto
     the page background below. Deriving one from the other makes that
     drift structurally impossible at any breakpoint, including ones
     added later. */
  --mark-size: clamp(480px, 62vw, 920px);
  --name-font-size: calc(var(--mark-size) * 0.085);
  display: inline-flex;
  align-items: center;
  /* The mark's own box is a full square (aspect-ratio:1) but the two
     circles only occupy its central ~45%, so a plain bottom margin
     leaves a lot of dead air before the subtitles below. Pulling up
     with a negative margin tied to --mark-size closes that gap without
     touching the ring itself, which ends well above this point. */
  margin: 0 0 calc(var(--mark-size) * -0.12);
  /* Didot itself isn't distributable as a webfont (commercial Linotype
     license) — it's listed first so a visitor with it installed
     locally (common on macOS) gets the real thing; everyone else falls
     back to Bodoni Moda, a free Didone-style lookalike loaded above. */
  font-family: "Didot", "Bodoni Moda", "Playfair Display", var(--font-heading);
  font-weight: 700;
  /* This box is centered on the section (flex + align-items:center on
     .intro-text) like everything else, but the box itself isn't a fair
     stand-in for what the eye reads as "the content": "Léa" + the solid
     circle (the only parts with real visual weight) sit bunched in its
     left ~60%, while the right side is mostly the hollow ring's empty
     interior. A dead-centered box therefore reads as shifted left, so
     this nudges the whole thing right until the *dense* part — not the
     bounding box — lands on center. */
  transform: translateX(calc(var(--mark-size) * 0.12));
}
.name-first {
  font-size: var(--name-font-size);
  color: var(--ink);
  position: relative;
  z-index: 2;
  transform-origin: right center;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.name-mark {
  position: relative;
  display: block;
  width: var(--mark-size);
  aspect-ratio: 1;
  flex: 0 0 auto;
  /* Pulls the mark left so the solid circle overlaps "Léa"'s trailing
     edge instead of sitting flush beside it. */
  margin-left: calc(var(--mark-size) * -0.13);
  z-index: 1;
}
.name-mark svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
  transform-origin: 50% 50%;
}
/* Hover EITHER WORD specifically — not `.name-lockup:hover`, which
   would also fire over the large gaps of empty transparent space this
   inline-flex box's own rectangle covers (between "Léa" and the mark,
   and past the ring on the right/below it) where there's nothing to
   react to. :has() lets hovering either text trigger every moving part
   at once: both words grow slightly and the two-circle mark gives a
   slow, small twist. Kept modest (12°, not a full spin) on purpose —
   "Di Fant" only scales in place rather than following the mark's
   rotation (it's a separate layer, not part of the rotating <svg>) at
   coordinates tuned for the solid circle's *resting* position; a
   bigger rotation would carry that circle out from under the word
   instead of just adding some life to the mark's stillness. */
.name-lockup:has(.name-first:hover, .name-last:hover) .name-first { transform: scale(1.04) translateX(-2%); }
.name-lockup:has(.name-first:hover, .name-last:hover) .name-last { transform: translate(-50%, -50%) scale(1.04); }
.name-lockup:has(.name-first:hover, .name-last:hover) .name-mark svg { transform: rotate(12deg); }
.name-last {
  position: absolute;
  left: 38%;
  top: 50%;
  /* No explicit width — left unset (rather than the old 80%, sized for
     an earlier two-line layout) so this absolutely-positioned box
     shrink-wraps to the word's own rendered width instead of a much
     wider box with empty space on either side of it. That empty space
     doesn't just look right anyway (text-align: center made it
     invisible) — it also used to count as "hovering the word" for the
     :has() rule above, well past the actual glyphs. */
  transform: translate(-50%, -50%);
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  /* A flat --cream-text reads fine against the solid --maroon circle,
     but the center dot sits right under the middle of this word (both
     dot and --cream-text are light/pale, so the letters over it drop to
     ~2:1 contrast — fails even the large-text 3:1 minimum). Tried
     mix-blend-mode: difference here — technically higher-contrast, but
     the color-inverting look read as a bug, not a feature. A dark
     drop-shadow instead: same "stop assuming one flat background"
     logic, but it darkens the glyph edges rather than shifting their
     hue, so it stays a plain cream word with a bit more definition
     rather than an odd two-tone effect over the dot. */
  color: var(--cream-text);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35), 0 2px 10px rgba(0, 0, 0, 0.3);
  font-size: var(--name-font-size);
  line-height: 1.05;
  white-space: nowrap;
}
@media (max-width: 860px) {
  /* --name-font-size is NOT re-set here — it derives from --mark-size
     (see .name-lockup above), so overriding only mark-size is enough to
     keep the two in lockstep at this breakpoint too. */
  .name-lockup {
    --mark-size: clamp(280px, 82vw, 420px);
  }
}

/* Stacked instead of side-by-side — the consultation line reads as the
   lead statement, with the location as a smaller line underneath. */
.intro-subtitles {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin: 0;
}
.intro-subtitle {
  font-family: var(--font-heading);
  font-size: clamp(1.35rem, 2.4vw, 1.7rem);
  font-weight: 400;
  color: var(--maroon-soft);
  margin: 0;
}
.intro-subtitle-primary {
  font-size: clamp(1.7rem, 3.2vw, 2.2rem);
  font-weight: 500;
}
.hero-actions {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-top: 52px;
  flex-wrap: wrap;
}

@media (max-width: 860px) {
  .intro-text { align-items: center; text-align: center; }
  .intro-subtitles { justify-content: center; }
  .hero-actions { justify-content: center; }
}

#presentation {
  position: relative;
  overflow: hidden;
  background: linear-gradient(165deg, var(--cream) 0%, var(--cream-deep) 58%, var(--cream) 100%);
}
#presentation .container { position: relative; z-index: 2; }

/* "Plus sur moi" — portrait in a left column, content on the right */
.plus-sur-moi-layout {
  display: grid;
  grid-template-columns: 380px 1fr;
  /* Column gap scales with the viewport too, so it narrows in step with
     the side margins instead of staying fixed while everything around
     it compresses — kept below the container's own side padding (see
     .container) so the outer margin always reads as the bigger gap. */
  gap: 40px clamp(28px, 5vw, 90px);
  align-items: center;
}
.plus-sur-moi-head,
.plus-sur-moi-credentials {
  grid-column: 1 / -1;
}
.plus-sur-moi-head { margin-bottom: 0; }

.intro-media {
  text-align: center;
  align-self: center;
}

/* Archway frame: a true semicircle top regardless of rendered size — the
   vertical radius (33.32% of height) is tuned to the image's own 917:1376
   aspect ratio so half-width in px always equals half-height's share. The
   frame clips to that same ratio; the photo inside is scaled up slightly
   so it fills the arch with a touch of zoom instead of the raw crop. */
.avatar-frame {
  width: 100%;
  max-width: 360px;
  aspect-ratio: 917 / 1376;
  margin: 0 auto;
  border-radius: 50% 50% 0 0 / 33.32% 33.32% 0 0;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.avatar-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.2);
  transform-origin: center 92%;
}

/* ---------- Sections (full screen) ---------- */
.section {
  min-height: calc(100vh - var(--header-h));
  min-height: calc(100svh - var(--header-h));
  padding: 88px 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.section-tan { background: var(--mon-approche-bg); }
.section-tan p { color: var(--maroon-deep); }
/* Prune only — matches .section-tan p's own color instead of the
   site-wide h2 default, so the title reads as the same ink as the
   section's body text. */
[data-theme="prune"] .section-tan h2 { color: var(--maroon-deep); }

/* Consultation gets a similarly derived, much subtler tint — enough to
   read as its own screen rather than a bare continuation of the page
   background, without competing with the pricing card's --cream-deep
   fill sitting on top of it. */
#consultation { background: color-mix(in srgb, var(--tan) 7%, var(--cream) 93%); }

/* Dark variant — same tone as the footer */
.section-dark { background: #21111C; }
.section-dark h1,
.section-dark h2,
.section-dark h3 { color: var(--cream-text); }
.section-dark p { color: var(--cream-text); opacity: 0.85; }
.section-dark .credentials-list li { color: var(--cream-text); }
.section-intro { font-size: 1.05rem; max-width: 60ch; }
.section-head { margin-bottom: 8px; }

/* ---------- Scroll-reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.7s ease, transform 0.6s ease;
}
.reveal.in-view {
  opacity: 1;
  transform: translateY(0);
}

.bio-text {
  max-width: 640px;
  margin: 0 0 32px;
  text-align: justify;
}
.bio-text p:last-child { margin-bottom: 0; }
.bio-text p:first-of-type::first-letter {
  font-family: var(--font-heading);
  font-size: 3rem;
  font-weight: 600;
  line-height: 0.7;
  float: left;
  padding: 0.08em 0.1em 0 0;
  color: var(--tan-deep);
}

.credentials-list {
  list-style: none;
  padding: 0;
  margin: 24px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.credentials-list li {
  padding-left: 28px;
  position: relative;
  color: var(--maroon-deep);
}
.credentials-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tan-deep);
}
/* Prune only. */
[data-theme="prune"] .credentials-list li::before {
  background: #FFA81F;
}
/* Default (orange) only — matches this theme's own --halo-color instead
   of the shared --tan-deep. */
html:not([data-theme]) .credentials-list li::before {
  background: var(--halo-color);
}

/* ---------- Accordion (Mon approche) ---------- */
.accordion { margin-top: 40px; display: flex; flex-direction: column; }

.accordion-item {
  border-top: 1px solid rgba(74, 44, 37, 0.25);
  padding: 6px 0;
}
.accordion-item:last-child { border-bottom: 1px solid rgba(74, 44, 37, 0.25); }

.accordion-item summary {
  cursor: pointer;
  padding: 18px 0;
  font-family: var(--font-heading);
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--maroon);
  list-style: none;
  position: relative;
  padding-right: 32px;
}
.accordion-item summary::-webkit-details-marker { display: none; }
.accordion-item summary::after {
  content: "";
  position: absolute;
  right: 4px;
  top: 28px;
  width: 12px;
  height: 12px;
  border-right: 2px solid color-mix(in srgb, var(--maroon-deep) 70%, black);
  border-bottom: 2px solid color-mix(in srgb, var(--maroon-deep) 70%, black);
  transform: rotate(-135deg);
  transition: transform 0.2s ease;
}
.accordion-item:not(.is-open) summary::after { transform: rotate(45deg); }

/* Height-animated by initAccordion() in script.js — kept as its own element,
   separate from summary, so the summary's own box never moves when a panel
   opens or closes; only the space below it grows or shrinks. The inner
   wrapper carries the padding so the outer box can cleanly animate to a
   true 0 without padding holding it open. */
.accordion-content {
  overflow: hidden;
  transition: height 0.35s ease;
}
.accordion-content-inner { padding: 0 32px 24px 20px; max-width: 68ch; }
.accordion-content-inner p { margin: 0 0 1em; text-align: justify; }
.accordion-content-inner p:last-child { margin-bottom: 0; }

.section-divider {
  height: 2px;
  margin: 20px auto 36px;
}

/* ---------- Consultation / pricing card ---------- */
.container-wide { max-width: 1280px; }
.consultation-layout {
  display: grid;
  grid-template-columns: minmax(300px, 460px) 1fr;
  gap: 40px clamp(28px, 5vw, 90px);
  align-items: center;
}
.consultation-steps { margin-bottom: 40px; }
.consultation-steps h3 { font-size: 1.55rem; margin-bottom: 0.7em; }
.consultation-steps .credentials-list { gap: 16px; }
.consultation-steps .credentials-list li { text-align: justify; }
.consultation-steps .credentials-list li { line-height: 1.5; }

/* Kept deliberately calm — a card-colored background barely a shade off
   the section behind it. */
.pricing-card {
  position: relative;
  background: var(--cream-deep);
  color: var(--maroon-deep);
  border: 1px solid rgba(74, 44, 37, 0.15);
  border-radius: var(--radius);
  padding: 44px 44px 40px;
  margin: 40px 0 70px;
  max-width: 460px;
  transition: transform 0.25s ease;
}
.pricing-card:hover {
  transform: translateY(-4px);
}

.pricing-card-head {
  position: relative;
  text-align: center;
  padding-bottom: 26px;
  margin-bottom: 26px;
  border-bottom: 1px solid rgba(74, 44, 37, 0.15);
}

.pricing-label {
  font-size: 0.95rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--maroon-soft);
  margin-bottom: 0.7em;
}

.pricing-amount {
  font-family: var(--font-heading);
  font-size: clamp(2.6rem, 6vw, 3.4rem);
  font-weight: 600;
  color: var(--maroon-deep);
  margin-bottom: 0;
  line-height: 1;
}
.pricing-currency {
  font-family: var(--font-body);
  font-size: 0.32em;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--maroon-deep);
  opacity: 0.75;
  margin-left: 8px;
}

.pricing-features {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--maroon-deep);
  opacity: 0.85;
  text-align: justify;
}

/* ---------- Motifs de consultation (interactive buttons) ---------- */
.motifs-interactive { margin-top: 8px; }

.motifs-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 24px;
}

.motif-btn {
  font-family: var(--font-body);
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--maroon-deep);
  background: var(--cream-deep);
  border: 1px solid rgba(74, 44, 37, 0.15);
  border-radius: 999px;
  padding: 9px 18px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.motif-btn:hover {
  transform: translateY(-1px);
  border-color: var(--maroon-soft);
}
.motif-btn:focus-visible {
  outline: 2px solid var(--maroon-soft);
  outline-offset: 2px;
}
.motif-btn.active {
  background: var(--maroon);
  color: var(--cream-text);
  border-color: var(--maroon);
}
/* Prune only. A lighter, punchier green than a muted-palette pick would
   normally allow — at that lightness, --cream-text no longer has enough
   contrast on it, so the label switches to --maroon-deep instead
   (still ≥4.5:1). */
[data-theme="prune"] .motif-btn.active {
  background: #E0D7B0;
  border-color: #E0D7B0;
  color: var(--maroon-deep);
}

.motifs-detail {
  min-height: 1.65em;
}

.motif-desc {
  font-size: 1.05rem;
  color: var(--maroon-soft);
  max-width: 56ch;
  margin: 0;
}

/* ---------- Contact ---------- */
.contact-section { text-align: center; }
.contact-inner p { margin-left: auto; margin-right: auto; }

.contact-actions { margin: 32px 0; }

.contact-details {
  margin-top: 40px;
  padding-top: 32px;
  border-top: 1px solid rgba(92, 58, 50, 0.18);
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-style: normal; /* reset <address> default italic */
}

/* ---------- Floating controls (theme toggle + back-to-top) ---------- */
.floating-btn {
  position: fixed;
  z-index: 60;
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: transform 0.15s ease, opacity 0.25s ease, background 0.15s ease, color 0.15s ease;
}
.floating-btn:hover { transform: translateY(-2px); }

.theme-toggle {
  left: 24px;
  bottom: 24px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--cream);
}
.theme-toggle .dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--tan-deep), var(--maroon));
  transition: background 0.2s ease;
}

/* Custom tooltip — a native title="" only shows after a long hover
   delay (and not at all on some setups), so we render our own bubble
   above the button instead, shown on hover/focus. */
.theme-tooltip {
  position: absolute;
  left: 0;
  bottom: calc(100% + 12px);
  background: var(--maroon-deep);
  color: var(--cream-text);
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1;
  padding: 8px 14px;
  border-radius: 999px;
  white-space: nowrap;
  box-shadow: var(--shadow);
  opacity: 0;
  transform: translateY(4px);
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.theme-toggle:hover .theme-tooltip,
.theme-toggle:focus-visible .theme-tooltip {
  opacity: 1;
  transform: translateY(0);
}

.back-to-top {
  right: 24px;
  bottom: 24px;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1.5px solid rgba(92, 58, 50, 0.25);
  background: var(--cream);
  color: var(--maroon);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
}
.back-to-top.visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.back-to-top:hover.visible { transform: translateY(-2px); }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--maroon);
  color: rgba(243, 233, 218, 0.85);
  padding: 56px 0 32px;
}
/* Prune only — #392132 is exactly --maroon-deep's value for this theme,
   so reusing the token rather than repeating the hex directly. */
[data-theme="prune"] .site-footer { background: var(--maroon-deep); }

.footer-membership {
  color: var(--tan-deep);
  font-weight: 600;
  font-size: 0.9rem;
  text-align: center;
  white-space: nowrap;
  margin: 0 0 56px;
}
.footer-membership a { color: inherit; text-decoration: underline; text-decoration-color: rgba(243, 233, 218, 0.4); }
.footer-membership a:hover,
.footer-membership a:focus-visible { text-decoration-color: currentColor; }

.footer-help { text-align: center; margin-bottom: 48px; }

.footer-help-title {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--tan-deep);
  font-size: 1.05rem;
  margin: 0 0 20px;
}

.footer-help-grid {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px 32px;
}
.footer-help-grid p {
  margin: 0;
  text-align: center;
  white-space: nowrap;
  color: rgba(243, 233, 218, 0.85);
  font-size: 0.95rem;
}
.footer-help-grid strong { color: var(--cream-text); }
.footer-help-grid a { color: inherit; text-decoration: none; }
.footer-help-grid a:hover,
.footer-help-grid a:focus-visible { text-decoration: underline; }

.footer-inner {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 0.85rem;
  padding-top: 24px;
  border-top: 1px solid rgba(243, 233, 218, 0.15);
}
.footer-inner p { color: rgba(243, 233, 218, 0.75); margin: 0; }

/* ---------- Responsive ---------- */
/* The desktop nav (logo + centered links + CTA, all on one row) needs
   genuine room — at minimum ~1000px in this environment's font metrics
   for the logo, five links and the button to coexist without any of
   them shrinking below their natural width (see .logo/.nav-cta/.nav-links
   a's white-space: nowrap). Real browsers/OSes render this same text
   measurably wider (confirmed: this is also why colors and other
   rendering differ between screens for this project) than this
   environment does, so the breakpoint carries a large safety margin
   above that measured minimum rather than hugging it — below it, the
   nav switches to the hamburger dropdown well before any squeeze could
   show. Deliberately higher than the one below it, which governs
   unrelated two-column layouts elsewhere on the page. */
@media (max-width: 1220px) {
  .nav-toggle { display: flex; }

  .primary-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--cream);
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 16px 24px 24px;
    border-bottom: 1px solid rgba(92, 58, 50, 0.1);
    display: none;
  }
  .primary-nav.open { display: flex; }
  .nav-links {
    position: static;
    transform: none;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    width: 100%;
  }
  .primary-nav a:not(.btn) { padding: 10px 0; width: 100%; }
  .nav-cta { margin-left: 0; margin-top: 8px; }
}

/* Both two-column sections pin a fixed-width left column (380px / a
   300–460px card) against a flexible right column — below ~1050px that
   right column gets squeezed down to ~300px or less, wrapping the
   Déroulement list into a ragged, word-per-line mess well before the
   old 860px breakpoint kicked in. Collapsing to one column earlier
   avoids that cramped in-between state entirely. */
@media (max-width: 1100px) {
  .plus-sur-moi-layout { grid-template-columns: 1fr; justify-items: center; }
  .intro-media { margin-bottom: 40px; }
  /* The photo (.intro-media) was already centered here (text-align:
     center on its own grid cell) — the title and bio copy weren't:
     both just stretched to the full single column and stayed
     left-aligned/justified, which read as lopsided next to a centered
     photo above them. */
  .plus-sur-moi-head { text-align: center; }
  /* The block itself is centered (auto margins, within its own
     max-width) so it doesn't stretch to the full single column like
     .plus-sur-moi-head does — the copy inside keeps the base rule's
     text-align: justify rather than centering, per feedback. */
  .bio-text { margin-left: auto; margin-right: auto; }
  .consultation-layout { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
  .hero-quote cite { text-align: left; }
  .hero-quote-wrap { padding-left: 32px; padding-right: 32px; }

  .pricing-card { padding: 32px 26px; }

  .footer-help-grid p { white-space: normal; }
  .footer-membership { white-space: normal; }

  /* The theme toggle (bottom-left) and back-to-top (bottom-right) are
     position: fixed, so they sit over whatever's scrolled to the exact
     bottom of the viewport — on mobile that's confirmed to land right on
     top of the motif description's last line and the bio's last line,
     since both are the trailing content of sections tall enough to
     scroll past a single small viewport. Reserving clearance at the end
     of those two specific blocks (rather than padding every section, most
     of which never reach the viewport-bottom danger zone) keeps the
     controls from hiding text the reader is mid-sentence on. */
  .motifs-detail { padding-bottom: 90px; }
  .bio-text { padding-bottom: 90px; }
}

@media (max-width: 480px) {
  .theme-toggle .label { display: none; }
  .theme-toggle { left: 16px; bottom: 16px; padding: 12px; }
  .back-to-top { right: 16px; bottom: 16px; }
}

@media (max-width: 600px) {
  /* text-align: justify is a deliberate choice on the wide columns these
     blocks normally sit in, but a narrow mobile column doesn't have
     enough words per line for the justify algorithm to distribute
     without ugly, uneven word-spacing ("rivers") — confirmed on all four
     of these blocks at 390px width. Left-align instead below the width
     where justify stops paying for itself. */
  .bio-text,
  .accordion-content-inner p,
  .pricing-features,
  .consultation-steps .credentials-list li {
    text-align: left;
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; }
}
