/*
Theme Name: Mayara Sousa
Theme URI: https://www.mayarasousa.com/
Author: Mayara Sousa
Author URI: https://www.mayarasousa.com/
Description: Portfolio and engagement site for Mayara Sousa. Brand, interface and build. Hand-written, no framework, no build step. Key values (links, palette, photos, videos, location, Resend) live under Appearance > Site Settings.
Version: 1.0.0
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: mayara
*/

/* ==========================================================================
   Mayara Sousa — prototype
   1. Fonts
   2. Tokens
   3. Base + reset
   4. Typography
   5. Components
   6. Header / nav
   7. Hero
   8. Marquee
   9. About
   10. Services
   11. Work
   12. Working together
   13. The other half + contact
   14. Footer
   15. Work with me (work-with-me.html)
   16. About (about.html)
   16b. Legal (privacy.html)
   17. Motion / reveal
   18. Responsive
   ========================================================================== */

/* ═══ 1. Fonts ═══ */
@font-face {
  font-family: "RL Madena";
  src: url("assets/fonts/rl-madena.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "RL Madena";
  src: url("assets/fonts/rl-madena-oblique.woff") format("woff");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Public Sans";
  src: url("assets/fonts/PublicSans-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Public Sans";
  src: url("assets/fonts/PublicSans-VariableItalic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

/* ═══ 2. Tokens ═══ */
:root {
  /* color */
  --blue: #0019be;
  --pink: #f486a6;
  --pink-pale: #f4d6d6;
  --cream: #f8f5f2;
  --ink: #222;
  --white: #fff;

  --line: rgba(34, 34, 34, .16);
  /* Full-strength, on purpose. Two jobs: the hard boundary between major
     sections, AND the rules between rows inside a list section (services, fit,
     arc, steps, story blocks). Home always used it for both; the other pages
     had drifted to the 16% --line for their rows, which read as a different
     design. If you add a new list section, its row rule is --rule. */
  --rule: var(--ink);
  --line-strong: rgba(34, 34, 34, .38);
  --line-light: rgba(255, 255, 255, .3);

  /* type */
  --font-display: "RL Madena", "Times New Roman", serif;
  --font-body: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "input-mono-condensed", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --track-body: -.012em;   /* slight negative tracking — reads more modern */
  --track-label: .16em;

  /* scale */
  --step-hero: clamp(3rem, 8.6vw, 8.75rem);
  --step-h2: clamp(2.1rem, 4.6vw, 4.1rem);
  --step-h3: clamp(1.5rem, 2.4vw, 2.1rem);
  --step-lead: clamp(1.0625rem, 1.25vw, 1.3125rem);
  --step-body: clamp(.95rem, 1.02vw, 1.0625rem);
  --step-fine: .8125rem;   /* fine print — consent lines, form small text */
  --step-label: .69rem;

  /* space */
  --gutter: clamp(1.25rem, 4.4vw, 4.5rem);
  --shell: 1560px;
  --section-y: clamp(5.5rem, 12vh, 11rem);
  --header-h: 78px;
  --bar-h: 2.5rem;

  --ease: cubic-bezier(.2, .7, .2, 1);
}

/* ═══ 3. Base ═══ */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-body);
  font-weight: 400;
  line-height: 1.62;
  letter-spacing: var(--track-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* paper grain — like the references, very subtle */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 999;
  pointer-events: none;
  opacity: .05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* height:auto is not optional now that every <img> carries width/height
   attributes: without it the height attribute acts as a presentational
   height and any image whose CSS sets only a width renders squashed. */
img { max-width: 100%; height: auto; display: block; }
svg { display: block; }
ul, ol { margin: 0; padding: 0; list-style: none; }
figure { margin: 0; }
blockquote { margin: 0; }

a { color: inherit; text-decoration: none; }

::selection { background: var(--blue); color: var(--cream); }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  background: var(--blue);
  color: var(--cream);
  padding: .75rem 1.25rem;
}
.skip-link:focus { left: 0; }

:focus-visible {
  outline: 1.5px solid var(--blue);
  outline-offset: 3px;
}

/* ═══ 4. Typography ═══ */
.h2, .hero__title, .service__name {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
}

.h2 {
  font-size: var(--step-h2);
  line-height: 1.02;
  margin: 0 0 1.1rem;
  max-width: 16ch;
}
.h2 em, .hero__title em { font-style: italic; }

.lead {
  font-size: var(--step-lead);
  line-height: 1.55;
  max-width: 46ch;
}

p { margin: 0 0 1.1em; max-width: 60ch; }
p:last-child { margin-bottom: 0; }

.eyebrow {
  display: block;           /* block, not flex — long labels must wrap */
  margin: 0 0 1.4rem;
  max-width: none;          /* opt out of the 60ch cap on <p> */
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 1;
}
.mark { width: 1em; height: 1em; fill: currentColor; flex: none; }
.eyebrow .mark { display: inline-block; vertical-align: -.08em; margin-inline: .2em; }
.mark--sm { width: .8em; height: .8em; }
.mark--lg { width: 2.4rem; height: 2.4rem; }

.section__head { margin-bottom: clamp(2.5rem, 5vw, 4.5rem); }
.section__head--split {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
}

/* ═══ 5. Components ═══ */
.btn {
  --btn-fg: var(--ink);
  --btn-bg: transparent;
  --btn-bd: var(--line-strong);
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  padding: .95rem 1.6rem;
  border: 1px solid var(--btn-bd);
  border-radius: 0;                      /* never rounded */
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  /* fill that rises on hover — no shadow, contrast only */
  background-image: linear-gradient(var(--btn-fill, var(--ink)), var(--btn-fill, var(--ink)));
  background-repeat: no-repeat;
  background-position: 50% 100%;
  background-size: 100% 0%;
  transition: background-size .45s var(--ease), color .45s var(--ease), border-color .45s var(--ease);
}
.btn:hover { background-size: 100% 100%; }

.btn--solid { --btn-fg: var(--cream); --btn-bg: var(--blue); --btn-bd: var(--blue); --btn-fill: var(--ink); }
.btn--ghost { --btn-fill: var(--blue); }
.btn--ghost:hover { color: var(--cream); border-color: var(--blue); }
.btn--invert { --btn-fg: var(--blue); --btn-bg: var(--cream); --btn-bd: var(--cream); --btn-fill: var(--pink); }
.btn--invert:hover { color: var(--ink); }
.btn--outline-light { --btn-fg: var(--cream); --btn-bd: var(--line-light); --btn-fill: var(--cream); }
.btn--outline-light:hover { color: var(--blue); border-color: var(--cream); }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  padding-bottom: .45rem;
  border-bottom: 1px solid var(--line-strong);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.link-arrow .mark { transition: transform .35s var(--ease); }
.link-arrow:hover { color: var(--blue); border-color: var(--blue); }
.link-arrow:hover .mark { transform: translateX(5px); }

/* blurred blobs — the blur the brand is built on */
.blob {
  position: absolute;
  display: block;
  pointer-events: none;
  filter: blur(90px);
  will-change: transform;
}
.blob--blue {
  width: 46vw; height: 46vw;
  top: -12vw; right: -6vw;
  background: var(--blue);
  opacity: .22;
  border-radius: 62% 38% 46% 54% / 55% 40% 60% 45%;
}
.blob--pink {
  width: 38vw; height: 34vw;
  bottom: -10vw; left: -8vw;
  background: var(--pink);
  opacity: .48;
  border-radius: 44% 56% 63% 37% / 48% 62% 38% 52%;
}
.blob--pale {
  width: 30vw; height: 30vw;
  top: 42%; left: 46%;
  background: var(--pink-pale);
  opacity: .7;
  border-radius: 58% 42% 38% 62% / 42% 55% 45% 58%;
}

/* --- 3D objects scattered across the page ---
   They sit in front and cross section boundaries, which is the whole point, but
   pointer-events:none means they can never swallow a click. Cream and pale-pink
   backgrounds only: the white enclosed inside the blue doodles is not connected
   to the image border, so the cutout keeps it — invisible on cream, obvious on blue. */
.deco {
  position: absolute;
  z-index: 2;
  width: clamp(130px, 15vw, 250px);
  height: auto;
  pointer-events: none;
  user-select: none;
}
.services, .about, .work, .other, .together, .contact { position: relative; }

/* floats like the laptop, but smaller drift and a slower, offset cycle so the
   two are never bobbing in step. See @keyframes float. */
.deco--coffee {
  right: 5%;
  top: -13%;
  width: clamp(140px, 15vw, 250px);
  transform: rotate(-8deg);
  --float-from: -8deg;
  --float-to: -4deg;
  --float-y: -16px;
  animation: float 8.5s ease-in-out infinite -2.5s;
}

/* these two hang off the portrait itself — sized in % so they scale with it */
.deco--eiffel { top: -15%;  right: -13%; width: 46%; transform: rotate(6deg);  z-index: 5; }
.deco--cat    { bottom: -15%; left: -9%;  width: 50%; transform: rotate(-5deg); z-index: 5; }

/* --- hand-drawn emphasis marks --- */
.scribble {
  position: relative;
  display: inline-block;
  white-space: nowrap;   /* the mark is one box, so the phrase must not wrap */
}
.doodle {
  position: absolute;
  left: 50%;
  pointer-events: none;
  overflow: visible;
  fill: none;
  stroke: var(--blue);
  stroke-width: 2;
  stroke-linecap: round;
}
.scribble--circle { margin-inline: .22em; }   /* room for the loop to clear its neighbours */
.doodle--line   { bottom: -.42em; width: 104%; height: .48em; transform: translateX(-50%); }
.doodle--circle { top: 50%; width: 142%; height: 2.1em; transform: translate(-50%, -50%); }

/* drawn in when the paragraph reveals. stroke-dashoffset is an inherited SVG
   property, so setting it here reaches the path inside <use>. */
.js .reveal .doodle--line   { stroke-dasharray: 230; stroke-dashoffset: 230; }
.js .reveal .doodle--circle { stroke-dasharray: 560; stroke-dashoffset: 560; }
.js .reveal.is-visible .doodle {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.1s var(--ease) .35s;
}

/* ═══ 6. Header ═══ */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background .4s var(--ease), border-color .4s var(--ease);
}
.site-header.is-stuck {
  background: rgba(248, 245, 242, .72);
  backdrop-filter: blur(18px) saturate(1.2);
  -webkit-backdrop-filter: blur(18px) saturate(1.2);
  border-bottom-color: var(--rule);
}
.announce {
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--bar-h);
  margin: 0;
  max-width: none;
  padding-inline: 1rem;
  background: var(--blue);
  color: var(--cream);
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 1;
  text-align: center;
}

.site-header__inner {
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0 var(--gutter);
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}
.site-header__logo img { width: clamp(124px, 12vw, 168px); }

.nav { display: flex; align-items: center; gap: clamp(1.5rem, 3vw, 3rem); }
.nav__list {
  display: flex;
  gap: clamp(1.25rem, 2.4vw, 2.4rem);
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
.nav__list a {
  position: relative;
  padding-block: .35rem;
  transition: color .3s var(--ease);
}
.nav__list a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--blue);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .4s var(--ease);
}
.nav__list a:hover { color: var(--blue); }
.nav__list a:hover::after { transform: scaleX(1); transform-origin: left; }
.nav__cta { padding: .8rem 1.25rem; }

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 0;
  background: transparent;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.nav-toggle span {
  width: 20px; height: 1px;
  background: var(--ink);
  transition: transform .35s var(--ease), opacity .3s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:first-child { transform: translateY(3.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:last-child { transform: translateY(-3.5px) rotate(-45deg); }

/* ═══ 7. Hero ═══ */
.hero {
  position: relative;
  min-height: 100svh;   /* the other two heroes match this — see .about-hero */
  padding-top: calc(var(--header-h) + var(--bar-h) + clamp(2rem, 6vh, 5rem));
  padding-bottom: clamp(2.5rem, 7vh, 5rem);
  display: flex;
  align-items: center;
  overflow: hidden;
}
.blobs { position: absolute; inset: 0; z-index: 0; }

.hero__inner { position: relative; z-index: 2; width: 100%; }

/* --- the centered stage: headline, portrait, clipped headline, side notes --- */
.hero__stage {
  --fig-w: clamp(190px, 19vw, 310px);
  --title-w: min(calc(100vw - 2 * var(--gutter)), 1080px);
  /* drops the headline off dead-center so line 1 clears her chin.
     Applied to both copies equally, so they stay aligned. */
  --title-shift: clamp(14px, 2.4vh, 34px);
  position: relative;
  display: grid;
  place-items: center;
}

.hero__title {
  grid-area: 1 / 1;
  place-self: center;
  width: var(--title-w);
  margin: 0;
  max-width: none;
  font-size: clamp(2.4rem, 6.2vw, 6.2rem);
  line-height: 1.12;
  text-align: center;
}
.hero__title .line { display: block; }
.hero__title em { font-style: italic; }

.hero__title--back {
  z-index: 1;
  color: var(--blue);
  transform: translateY(var(--title-shift));
}

.hero__figure {
  grid-area: 1 / 1;
  place-self: center;
  position: relative;      /* the front copy is absolutely placed inside it */
  z-index: 2;              /* also isolates the blend to this box */
  width: var(--fig-w);
  aspect-ratio: 3 / 4;
  margin: 0;
  overflow: hidden;
}
.hero__figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 16%;   /* face sits above the crossing text */
}

/* white + difference = a true negative of whatever the photo is doing underneath */
.hero__title--front {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) translateY(var(--title-shift));
  color: #fff;
  mix-blend-mode: difference;
  pointer-events: none;
}

/* --- the two swapping words --- */
.swap { display: inline-block; }
.hero__stage[data-font="1"] .swap {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
}
.hero__stage[data-font="2"] .swap {
  font-family: var(--font-body);
  font-style: normal;
  font-weight: 700;
  font-size: .88em;
  letter-spacing: -.045em;   /* the brand's tight tracking */
}
.hero__stage[data-font="3"] .swap {
  font-family: var(--font-mono);
  font-style: normal;
  font-weight: 400;
  font-size: .86em;      /* condensed, so it can carry more size than a normal mono */
  letter-spacing: -.02em;
}

.hero__note {
  position: absolute;
  bottom: 0;
  z-index: 4;
  max-width: 30ch;
  margin: 0;
  font-size: var(--step-body);
  line-height: 1.55;
}
.hero__note--left { left: 0; }
.hero__note--right { right: 0; text-align: right; }

.hero__actions {
  display: flex;
  justify-content: center;
  gap: .75rem;
  flex-wrap: wrap;
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
}

/* ═══ 8. Marquee ═══ */
.marquee {
  background: var(--blue);
  color: var(--cream);
  padding-block: clamp(.9rem, 1.6vw, 1.3rem);
  overflow: hidden;
  white-space: nowrap;
}
.marquee__track { display: flex; width: max-content; animation: slide 38s linear infinite; }
.marquee__group {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 2.4vw, 2.4rem);
  padding-right: clamp(1.25rem, 2.4vw, 2.4rem);
  font-size: clamp(1.05rem, 1.7vw, 1.55rem);
}
/* the two group labels: display oblique, caps */
.marquee__group em {
  font-family: var(--font-display);
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: .04em;
}
/* the names themselves: quieter, in the body face */
.marquee__group span {
  font-family: var(--font-body);
  font-size: .5em;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.marquee__group .mark { opacity: .7; }
@keyframes slide {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}

/* ═══ 9. About ═══ */
.about__grid {
  display: grid;
  grid-template-columns: minmax(0, .92fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 7vw, 8rem);
  align-items: center;
}
.about__media { position: relative; }
/* :not(.deco) — the objects hanging off the photo are also <img> in here, and
   this rule would otherwise force them back into the flow at the photo's ratio */
.about__media img:not(.deco) {
  position: relative;
  z-index: 2;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 28%;
  /* Black and white on purpose. :not(.deco) keeps it off the two 3D objects
     hanging over the photo, so they stay in full colour against it. If it reads
     flat, add contrast(1.05) here rather than lifting the grayscale. */
  filter: grayscale(1);
}
/* ...and back to colour on hover. Gated on (hover: hover) so it never runs on a
   touch device: there, :hover either does nothing or latches on after a tap and
   leaves the photo stuck in colour with no way to undo it. Phones keep the
   black and white, which is the intent.

   The objects are pointer-events: none, so hovering one passes straight through
   to the photo underneath and the whole picture still reacts as one thing.

   No cursor change: it isn't a link and shouldn't pretend to be. Under
   prefers-reduced-motion the global rule kills the duration, so the colour still
   arrives, just without the fade. */
@media (hover: hover) {
  .about__media img:not(.deco) { transition: filter .6s var(--ease); }
  .about__media img:not(.deco):hover { filter: grayscale(0); }
}


/* ═══ 10. Services ═══ */
/* no top rule: the blue marquee above it is already the divider */
.services { border-top: 0; }

.services__grid {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 6vw, 7rem);
}
.services__title { max-width: 15ch; margin-bottom: 0; color: var(--blue); }

.services__object {
  display: block;
  width: clamp(190px, 21vw, 330px);
  margin-top: clamp(2.5rem, 6vw, 5rem);
  /* the resting angle is repeated here on purpose: reduced motion kills the
     animation, and without this the object would snap flat */
  transform: rotate(-6deg);
  animation: float 7s ease-in-out infinite;
}
/* One keyframe for every floating object. The rotation has to live inside it —
   a transform on the element is overwritten while the animation plays — so each
   object passes its own angles and drift in through these variables. */
@keyframes float {
  0%, 100% { transform: translateY(0) rotate(var(--float-from, -6deg)); }
  50%      { transform: translateY(var(--float-y, -22px)) rotate(var(--float-to, -3deg)); }
}

/* each row: number + title on the left, the description on the right,
   separated by a full-strength rule. First row has no rule above it. */
.service {
  display: grid;
  grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr);
  align-items: start;
  gap: clamp(1.25rem, 3vw, 3rem);
  padding-block: clamp(1.75rem, 3vw, 2.5rem);
}
.service:first-child { padding-top: 0; }
.service:last-child { padding-bottom: 0; }
.service + .service { border-top: 1px solid var(--rule); }

.service__no,
.arc__no {
  display: block;
  margin-bottom: .5rem;
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--blue);
  opacity: .75;
}
.service__name {
  margin: 0;
  font-size: var(--step-h3);
  line-height: 1.05;
  color: var(--blue);
}
.service p { margin: 0; font-size: var(--step-body); }

/* ═══ 11. Work ═══ */
/* full viewport: the point of the carousel is seeing the mockup and its details
   at the same time, so the section is sized to hold both without scrolling */
.work {
  border-top: 1px solid var(--rule);
  min-height: 100svh;
  padding-block: clamp(2.5rem, 5vh, 4.5rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.work > .shell { width: 100%; }
.work .section__head { margin-bottom: clamp(1.5rem, 3vh, 2.5rem); }

.carousel {
  --slide-h: clamp(240px, 40vh, 460px);
  --slide-w: calc(var(--slide-h) * 4 / 3);
  position: relative;
}
/* full-bleed: the neighbours have to run off both screen edges, and inside the
   shell they'd be clipped at the gutter instead */
.carousel__stage {
  position: relative;
  width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

.carousel__track {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.6vw, 2.5rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* half a slide either side, so the first and last can reach the centre */
  padding-inline: calc(50% - var(--slide-w) / 2);
  padding-block: clamp(.5rem, 1.5vh, 1.25rem);
}
.carousel__track::-webkit-scrollbar { display: none; }
.carousel__track:focus-visible { outline: 1.5px solid var(--blue); outline-offset: 4px; }

/* neighbours are the same size as the centre and simply drop below it — they
   run off both edges of the screen, which is what makes the row feel endless */
.slide {
  flex: 0 0 auto;
  scroll-snap-align: center;
  opacity: .6;
  transform: translateY(7%);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.slide.is-active { opacity: 1; transform: none; }
.slide img {
  display: block;
  width: var(--slide-w);
  height: var(--slide-h);
  max-width: none;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.slide a { display: block; }

/* the details sit under the centre image and share its width */
.carousel__foot {
  width: var(--slide-w);
  max-width: 100%;
  margin: clamp(1.25rem, 2.5vh, 2rem) auto 0;
}
.carousel__meta { transition: opacity .35s var(--ease), transform .35s var(--ease); }
.carousel.is-swapping .carousel__meta { opacity: 0; transform: translateY(6px); }

.carousel__cat {
  margin: 0 0 .35rem;
  max-width: none;
  font-size: var(--step-label);
  letter-spacing: .06em;
  text-transform: uppercase;
  opacity: .55;
}
.carousel__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: clamp(1rem, 3vw, 2.5rem);
}
.carousel__row--title { align-items: center; margin-bottom: .6rem; }

.carousel__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.8rem, 3.4vw, 3.1rem);
  line-height: 1;
  letter-spacing: -.015em;
  color: var(--blue);
}
.carousel__title span {
  display: inline-block;
  transition: opacity .35s var(--ease), transform .35s var(--ease);
}
.carousel.is-swapping .carousel__title span { opacity: 0; transform: translateY(.18em); }

/* a step down from body copy: the title carries this block, and the description
   is support underneath it */
.carousel__desc { margin: 0; max-width: 46ch; font-size: clamp(.85rem, .92vw, .95rem); }
.carousel__cta { flex: none; }
.carousel__cta[hidden] { display: none; }

/* --- carousel arrows ---
   They flank the mockups instead of sitting under them, and they're a bare
   glyph: no box, no fill. The 44px button is still there for the tap target,
   it just isn't drawn. */
.carousel__btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 4;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  opacity: .45;
  cursor: pointer;
  transition: opacity .35s var(--ease), color .35s var(--ease);
}
.carousel__btn--prev { left: clamp(.5rem, 3vw, 2.5rem); }
.carousel__btn--next { right: clamp(.5rem, 3vw, 2.5rem); }
.carousel__btn svg { width: 22px; height: 22px; }
.carousel__btn:hover:not(:disabled) { opacity: 1; color: var(--blue); }
.carousel__btn:focus-visible { opacity: 1; outline: 1.5px solid var(--blue); outline-offset: 2px; }
/* still there, still reachable — just clearly at the end of the row */
.carousel__btn:disabled { opacity: .12; cursor: default; }

.carousel__count {
  flex: none;
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  opacity: .55;
  text-align: right;
}

/* ═══ 11b. Testimonials ═══
   Three, in a row, not a carousel. Three is exactly what fits, and a carousel
   would hide two thirds of the proof behind an arrow on a page that already has
   one. The quote is set in the display face so it reads as testimony rather than
   as more body copy, and the attribution is a real link to a real profile: that
   is the part that makes it checkable, which a screenshot never is. */
.quotes { border-top: 1px solid var(--rule); }
.quotes__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 4.5rem);
}
.quote {
  display: flex;
  flex-direction: column;
  margin: 0;
}
.quote__text {
  margin: 0 0 auto;
  max-width: none;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(1.1rem, 1.65vw, 1.45rem);
  line-height: 1.22;
}
/* the flower opens the quote instead of a typographic quote mark, so the section
   uses the same vocabulary as the marquee and the fit list */
.quote__mark {
  display: block;
  width: 1.1rem;
  height: 1.1rem;
  margin-bottom: clamp(1rem, 2vw, 1.5rem);
  color: var(--pink);
}
.quote__by {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  font-style: normal;
}
.quote__name { display: block; margin-bottom: .35rem; }
.quote__handle {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  opacity: .55;
  transition: color .3s var(--ease), opacity .3s var(--ease);
}
.quote__handle:hover { color: var(--blue); opacity: 1; }

/* ═══ 12. Working together ═══ */
.together {
  position: relative;
  overflow: hidden;
  background: var(--white);
  border-top: 1px solid var(--rule);
  padding-block: clamp(5rem, 12vh, 10rem);
}
/* the work-grid gradient, reused as a wash behind this section */
.blob--wash {
  position: absolute;
  width: 60vw; height: 42vw;
  left: 52%; top: 46%;
  transform: translate(-50%, -50%);
  background:
    radial-gradient(38% 44% at 28% 30%, var(--blue) 0%, transparent 62%),
    radial-gradient(46% 40% at 74% 68%, var(--pink) 0%, transparent 60%),
    var(--pink-pale);
  opacity: .32;
  filter: blur(110px);
  border-radius: 52% 48% 42% 58% / 46% 52% 48% 54%;
}
.together__inner { position: relative; z-index: 1; }
.together__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(2.4rem, 5.6vw, 5.2rem);
  line-height: 1;
  margin: 0 0 clamp(2.5rem, 5vw, 4rem);
  max-width: 16ch;
}
.together__title em { font-style: italic; color: var(--blue); }
.together__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: clamp(1.5rem, 4vw, 4rem);
  max-width: 92ch;
}
.together__cols > p { max-width: 46ch; }
.together__price {
  margin: 0;
  padding: clamp(1.4rem, 2.4vw, 2rem);
  border: 1px solid var(--line-strong);
  font-size: var(--step-lead);
  line-height: 1.5;
}
.together__inner .link-arrow { margin-top: clamp(2rem, 4vw, 3rem); }
.together__price strong {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.28em;
  color: var(--blue);
}

/* ═══ 13. The other half ═══ */
.other { border-top: 1px solid var(--rule); }
.other__grid {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 7rem);
}
.other__head .h2 { max-width: 13ch; }
.other__text p + p { margin-top: 1.1em; }
.other__links {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.25rem, 2.5vw, 2.5rem);
  margin-top: clamp(2rem, 3.5vw, 3rem);
}

/* --- latest uploads ---
   Facades, not live iframes: three YouTube embeds would pull megabytes of player
   JS on every page load. The thumbnail is swapped for the real iframe on click. */
.videos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: clamp(3rem, 6vw, 5rem);
}
.video__play {
  display: block;
  position: relative;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: var(--pink-pale);
  aspect-ratio: 16 / 9;
  overflow: hidden;
  cursor: pointer;
}
.video__play img,
.video__play iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
  transition: transform .7s var(--ease);
}
.video__play:hover img { transform: scale(1.04); }

.video__icon {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  width: clamp(48px, 4.5vw, 64px);
  aspect-ratio: 1;
  border: 1px solid var(--cream);
  background: rgba(34, 34, 34, .25);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--cream);
  transition: background .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease);
}
.video__icon svg { width: 55%; height: 55%; }
.video__play:hover .video__icon {
  background: var(--blue);
  border-color: var(--blue);
}

.video__title {
  margin: 1rem 0 .4rem;
  font-family: var(--font-body);
  font-size: var(--step-body);
  font-weight: 500;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.video__title a { transition: color .3s var(--ease); }
.video__title a:hover { color: var(--blue); }
.video__date {
  margin: 0;
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  opacity: .55;
}

/* ═══ 13b. Contact ═══ */
.contact {
  position: relative;
  overflow: hidden;
  background: var(--blue);
  color: var(--cream);
  padding-block: clamp(5.5rem, 13vh, 10rem);
}
.contact__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
}
.contact__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(2.6rem, 5.6vw, 5rem);
  line-height: .98;
  margin: 0 0 1.5rem;
  max-width: 12ch;
}
.contact__title em { font-style: italic; color: var(--pink); }
.contact__lead { font-size: var(--step-lead); max-width: 40ch; opacity: .85; }
.contact__details {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-light);
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 2.1;
}
.contact__details a {
  border-bottom: 1px solid var(--line-light);
  transition: border-color .3s var(--ease), color .3s var(--ease);
}
.contact__details a:hover { color: var(--pink); border-color: var(--pink); }
.contact__details span { opacity: .6; }

/* form: hairline underlines only — no boxes, no radius */
.field { display: block; margin: 0 0 clamp(1.5rem, 2.6vw, 2rem); max-width: none; }
.field label {
  display: block;
  margin-bottom: .55rem;
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  opacity: .7;
}
.field input,
.field textarea,
.field select {
  width: 100%;
  padding: .5rem 0 .7rem;
  border: 0;
  border-bottom: 1px solid var(--line-light);
  border-radius: 0;
  background: transparent;
  color: var(--cream);
  font-family: inherit;
  font-size: var(--step-lead);
  letter-spacing: var(--track-body);
  line-height: 1.5;
  transition: border-color .35s var(--ease);
}
.field textarea { resize: vertical; min-height: 5.5rem; }
.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-bottom-color: var(--pink);
}

/* the native select control is a rounded grey box on every platform, so it's
   stripped back to the same hairline as the inputs and given its own caret */
.field select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 1.75rem;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--cream) 50%),
                    linear-gradient(135deg, var(--cream) 50%, transparent 50%);
  background-position: right 8px center, right 2px center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
/* the dropdown itself is drawn by the OS, on its own light surface — cream text
   would be invisible in there */
.field select option { color: var(--ink); background: var(--cream); }
.field select:invalid { color: rgba(248, 245, 242, .5); }

/* --- consent checkboxes ---
   Fine print on purpose: these are terms, not part of the conversation, and at
   body size they carried the same weight as the questions above them. */
.field--check {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: .7rem;
  align-items: start;
  margin-top: clamp(1.75rem, 3vw, 2.25rem);
}
.field--check + .field--check { margin-top: .8rem; }
.field--check input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  display: grid;
  place-content: center;
  width: .95rem;
  height: .95rem;
  margin: .12rem 0 0;
  padding: 0;
  border: 1px solid var(--line-light);
  border-radius: 0;
  background: transparent;
  cursor: pointer;
  transition: background-color .25s var(--ease), border-color .25s var(--ease);
}
.field--check input[type="checkbox"]:checked {
  background: var(--pink);
  border-color: var(--pink);
}
/* the tick is two borders of an empty box, rotated — no icon font, no SVG.
   the negative top margin is the rotation: it drops the shape's optical centre
   below the box's geometric one */
.field--check input[type="checkbox"]:checked::after {
  content: "";
  width: .25rem;
  height: .47rem;
  margin-top: -.09rem;
  border: solid var(--blue);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(42deg);
}
.field--check input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 2px;
}
/* overrides the uppercase micro-label above: this one is a sentence to read */
.field--check label {
  margin: 0;
  font-size: var(--step-fine);
  font-weight: 400;
  letter-spacing: var(--track-body);
  text-transform: none;
  line-height: 1.55;
  opacity: .72;
  cursor: pointer;
}
.field--check label a {
  border-bottom: 1px solid var(--line-light);
  transition: border-color .3s var(--ease), color .3s var(--ease);
}
.field--check label a:hover { color: var(--pink); border-color: var(--pink); }
/* the collection notice above the send button — this is what replaced the
   required consent tick, so it has to be legible, not buried */
.form-consent {
  margin: clamp(1.5rem, 2.6vw, 2rem) 0 0;
  max-width: 62ch;
  font-size: var(--step-fine);
  line-height: 1.55;
  opacity: .62;
}
.form-consent a {
  border-bottom: 1px solid var(--line-light);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.form-consent a:hover { color: var(--pink); border-color: var(--pink); }

.contact__form .btn { margin-top: 1.25rem; }
.form-note {
  display: block;
  margin-top: 1rem;
  min-height: 1.2em;
  font-size: var(--step-label);
  letter-spacing: .06em;
  color: var(--pink);
}
.form-note a { border-bottom: 1px solid currentColor; }
/* WordPress only: the handler redirects back with a result, and a success reads
   as reassurance rather than as the error colour the note defaults to */
.form-note.is-ok { color: var(--cream); opacity: .85; }
/* WordPress only: shown to logged-in admins where a photo has not been chosen,
   so an empty figure is obvious in wp-admin and invisible to everyone else */
.mayara-missing-photo {
  display: block;
  padding: 1rem;
  border: 1px dashed var(--line-strong);
  font-size: var(--step-fine);
  opacity: .7;
}

/* ═══ 14. Footer ═══ */
.site-footer { padding-top: clamp(3.5rem, 7vw, 6rem); }
.site-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 4rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
}
.site-footer__logo { width: clamp(150px, 14vw, 190px); margin-bottom: 1.25rem; }
.site-footer__brand p { font-size: var(--step-body); max-width: 34ch; opacity: .75; }
.site-footer__col h3 { margin-bottom: 1.25rem; opacity: .55; }
.site-footer__col li + li { margin-top: .55rem; }
.site-footer__col a {
  position: relative;
  transition: color .3s var(--ease);
}
.site-footer__col a::after {
  content: "";
  position: absolute;
  left: 0; bottom: -3px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .4s var(--ease);
}
.site-footer__col a:hover { color: var(--blue); }
.site-footer__col a:hover::after { transform: scaleX(1); transform-origin: left; }

.site-footer__bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding-block: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  opacity: .6;
}
.site-footer__bar span { display: inline-flex; align-items: center; gap: .5rem; }
.site-footer__bar a {
  border-bottom: 1px solid var(--line);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.site-footer__bar a:hover { color: var(--blue); border-color: var(--blue); }

/* ═══ 14b. Consent ═══
   The cookie banner. Injected by js/consent.js, so there is no markup for it in
   any HTML file. Cream on a full-strength top rule rather than a floating card:
   no shadow and no radius, so it reads as another band of the page rather than
   something pasted over it.

   The one rule here that is legal rather than aesthetic: Accept all and Reject
   all are the SAME component at the SAME size, side by side. Do not restyle one
   of them into a quieter link. Under CNIL guidance, making refusal harder than
   acceptance invalidates the consent entirely. */
.consent {
  position: fixed;
  inset: auto 0 0;
  /* above the fixed header (100), below the paper grain (999) and the skip
     link (1000) — the grain is a page-wide multiply and should cover this too */
  z-index: 300;
  max-height: 100dvh;
  overflow-y: auto;
  background: rgba(248, 245, 242, .94);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border-top: 1px solid var(--rule);
  transform: translateY(101%);   /* 101% so the top border clears too */
  visibility: hidden;            /* keeps it out of the tab order until it opens */
  transition: transform .55s var(--ease), visibility .55s var(--ease);
}
.consent.is-open { transform: none; visibility: visible; }

.consent__inner { padding-block: clamp(1.5rem, 3vw, 2.25rem); }
.consent__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(1.4rem, 2.2vw, 2rem);
  line-height: 1.05;
  margin: 0 0 .6rem;
}
.consent__title:focus-visible { outline: 1.5px solid var(--blue); outline-offset: 4px; }
.consent__text {
  margin: 0;
  max-width: 74ch;
  font-size: var(--step-fine);
  line-height: 1.6;
  opacity: .78;
}
.consent__text a {
  border-bottom: 1px solid var(--line-strong);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.consent__text a:hover { color: var(--blue); border-color: var(--blue); }

/* --- the detail panel --- */
.consent__panel {
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 1px solid var(--line);
}
.consent__cats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
.consent__cat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .4rem;
}
.consent__cat-name {
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
.consent__always {
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  opacity: .45;
}
.consent__cat-desc {
  margin: 0;
  max-width: none;
  font-size: var(--step-fine);
  line-height: 1.55;
  opacity: .7;
}

/* the same square box as the contact form's consent lines — the site has one
   checkbox, not two that happen to look similar */
.consent__switch {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  cursor: pointer;
}
.consent__switch input {
  appearance: none;
  -webkit-appearance: none;
  display: grid;
  place-content: center;
  width: .95rem;
  height: .95rem;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 0;
  background: transparent;
  cursor: pointer;
  transition: background-color .25s var(--ease), border-color .25s var(--ease);
}
.consent__switch input:checked { background: var(--blue); border-color: var(--blue); }
.consent__switch input:checked::after {
  content: "";
  width: .25rem;
  height: .47rem;
  margin-top: -.09rem;
  border: solid var(--cream);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(42deg);
}
.consent__switch input:focus-visible { outline: 1.5px solid var(--blue); outline-offset: 3px; }

/* --- actions --- */
.consent__actions {
  display: flex;
  align-items: center;
  gap: .75rem 1.25rem;
  flex-wrap: wrap;
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
}
/* Accept and Reject are both .btn--solid and neither gets a modifier that would
   change its weight. See the note at the top of this section. */
.consent__toggle {
  padding: 0 0 .3rem;
  border: 0;
  border-bottom: 1px solid var(--line-strong);
  border-radius: 0;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  cursor: pointer;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.consent__toggle:hover { color: var(--blue); border-color: var(--blue); }

/* --- the footer re-open link ---
   A <button>, not an <a>: it opens a panel on this page, it doesn't navigate.
   Styled to sit invisibly among the footer bar's real links. */
.consent__reopen {
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.consent__reopen:hover { color: var(--blue); border-color: var(--blue); }

/* ═══ 15. Work with me ═══
   Second page (work-with-me.html). Everything above is shared: header, footer,
   buttons, links, blobs, decos, scribbles and the type scale all come from the
   sections above, so this only holds what the page adds. */

/* --- hero ---
   Shorter than the home hero on purpose: that one is a full-height composition
   with the headline crossing the portrait, and repeating it here would make the
   page feel like a second home page rather than the next step. */
.page-hero {
  position: relative;
  overflow: hidden;
  /* same one-screen treatment as Home and About — see the note on .about-hero */
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-top: calc(var(--header-h) + var(--bar-h) + clamp(3rem, 9vh, 7rem));
  padding-bottom: clamp(3.5rem, 9vh, 7rem);
}
.page-hero__inner { position: relative; z-index: 2; }
.page-hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(2.6rem, 6.4vw, 6rem);
  line-height: 1;
  margin: 0 0 clamp(1.75rem, 3.5vw, 2.75rem);
  max-width: 17ch;
}
.page-hero__title .line { display: block; }
.page-hero__title em { font-style: italic; color: var(--blue); }
.page-hero__lead { max-width: 52ch; }

/* --- who this is for ---
   The two columns are deliberately unequal, and the divider between them is a
   hairline: it separates two halves of one thought, not two sections. */
.fit { border-top: 1px solid var(--rule); }
.fit__grid {
  --fit-gap: clamp(2.5rem, 6vw, 6rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .88fr);
  gap: var(--fit-gap);
}
/* The divider sits in the true middle of the gap, and both columns give up half
   the gap to it. Pulling the right column across by the *whole* gap — which is
   what this did — put the hairline flush against the left column, so that
   column's row rules ran straight into it while the right column's floated a
   full gap clear. Same rules, two different relationships to the same line. */
.fit__col:not(.fit__col--not) { padding-right: calc(var(--fit-gap) / 2); }
.fit__col--not {
  padding-left: calc(var(--fit-gap) / 2);
  margin-left: calc(var(--fit-gap) / -2);
  border-left: 1px solid var(--rule);
}
.fit__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: var(--step-h3);
  line-height: 1.05;
  margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
}
.fit__title em { font-style: italic; color: var(--blue); }
.fit__col--not .fit__title em { color: var(--ink); opacity: .55; }

.fit__list li {
  display: flex;
  gap: .85rem;
  padding-block: clamp(.85rem, 1.6vw, 1.15rem);
}
.fit__list li + li { border-top: 1px solid var(--rule); }
.fit__mark {
  margin-top: .42em;          /* optically centres the mark on the first line */
  color: var(--blue);
}
.fit__col--not .fit__mark { color: var(--ink); opacity: .35; }

/* --- what you get --- */
.arc { position: relative; border-top: 1px solid var(--rule); }
.arc .section__head { margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.arc__item {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  align-items: start;
  gap: clamp(1rem, 3vw, 3rem);
  padding-block: clamp(1.5rem, 2.6vw, 2.1rem);
}
.arc__item:first-child { padding-top: 0; }
.arc__item:last-child { padding-bottom: 0; }
.arc__item + .arc__item { border-top: 1px solid var(--rule); }
.arc__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: var(--step-h3);
  line-height: 1.05;
  color: var(--blue);
}
.arc__item p { margin: 0; }

/* --- how it runs ---
   Heading left, steps right, with the numbers hanging in their own column so
   they line up as a spine down the page. */
.steps { border-top: 1px solid var(--rule); }
.steps__grid {
  display: grid;
  grid-template-columns: minmax(0, .7fr) minmax(0, 1.3fr);
  gap: clamp(2rem, 6vw, 7rem);
}
.steps__head .h2 { max-width: 9ch; }
.step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 2.25rem);
  padding-block: clamp(1.5rem, 2.8vw, 2.25rem);
}
.step:first-child { padding-top: 0; }
.step:last-child { padding-bottom: 0; }
.step + .step { border-top: 1px solid var(--rule); }
.step__no {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.6vw, 2.4rem);
  line-height: 1;
  color: var(--blue);
  opacity: .45;
}
.step__name {
  margin: 0 0 .5rem;
  font-family: var(--font-body);
  font-size: var(--step-body);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 1.3;
}
.step__body p { margin: 0; }

/* --- the details ---
   White, with the same blurred wash as Working together on the home page, so
   the two pages share one "this is the money section" treatment. */
.details {
  position: relative;
  overflow: hidden;
  background: var(--white);
  border-top: 1px solid var(--rule);
  padding-block: clamp(4.5rem, 11vh, 9rem);
}
.details__inner { position: relative; z-index: 1; }
.details__inner .h2 { margin-bottom: clamp(2rem, 4vw, 3rem); }
.details__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}
.detail {
  padding: clamp(1.4rem, 2.4vw, 2rem);
  border: 1px solid var(--line-strong);
}
.detail .eyebrow { margin-bottom: 1rem; color: var(--blue); }
.detail p { margin: 0; max-width: none; }
.detail strong {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.28em;
  color: var(--blue);
}

/* --- content work --- */
.content-work { position: relative; border-top: 1px solid var(--rule); }
.content-work__grid {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 6vw, 7rem);
  align-items: start;
}
.content-work__head .h2 { max-width: 12ch; margin-bottom: 0; }
.content-work__text .link-arrow { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }

/* --- final CTA ---
   Full-bleed blue, which is its own divider — no rule above it. Reuses
   the same full-bleed blue treatment. */
.cta {
  position: relative;
  overflow: hidden;
  background: var(--blue);
  color: var(--cream);
  padding-block: clamp(5rem, 12vh, 9rem);
}
.cta__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .92fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: end;
}
.cta__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(2.6rem, 5.6vw, 5rem);
  line-height: .98;
  margin: 0;
  max-width: 12ch;
}
.cta__title em { font-style: italic; color: var(--pink); }
.cta__body .lead { max-width: 44ch; opacity: .85; }
.cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
/* About's closing line is a sentence, not three words — it needs a wider
   measure and a smaller size than the one on Work with me */
.cta--wide .cta__title {
  max-width: 20ch;
  font-size: clamp(2.1rem, 4.3vw, 3.8rem);
  line-height: 1.02;
}
.cta__mail {
  margin: clamp(1.5rem, 3vw, 2rem) 0 0;
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
.cta__mail a {
  border-bottom: 1px solid var(--line-light);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.cta__mail a:hover { color: var(--pink); border-color: var(--pink); }

/* ═══ 16. About ═══
   Third page (about.html). Long-form, so the whole page is really two things:
   a portrait hero and a column of prose that has to stay readable. */
.about-hero {
  position: relative;
  overflow: hidden;
  /* one screen, matching Home. svh not vh: on mobile 100vh is measured as if the
     browser chrome were retracted, so it hides content behind the address bar on
     load. min-, not a fixed height, so a hero that genuinely needs more room
     (stacked layout, large text, short landscape window) grows instead of
     clipping. */
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-top: calc(var(--header-h) + var(--bar-h) + clamp(2.5rem, 7vh, 5.5rem));
  padding-bottom: clamp(3rem, 8vh, 6rem);
}
.about-hero__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .8fr);
  gap: clamp(2.5rem, 7vw, 7rem);
  align-items: center;
}
.about-hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(3rem, 7.4vw, 7rem);
  line-height: 1;
  margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
}
.about-hero__title .line { display: block; }
.about-hero__title em { font-style: italic; color: var(--blue); }

.about-hero__media { position: relative; }
/* the flat pale plate the portrait sits against — offset, not centred, so the
   two shapes overlap instead of framing each other */
.about-hero__media::before {
  content: "";
  position: absolute;
  inset: 8% -6% -6% 8%;
  background: var(--pink-pale);
  z-index: 0;
}
/* :not(.deco) is kept even though this page carries no 3D objects any more —
   the rule is about the portrait specifically, and Home's version of this figure
   still overlays them */
.about-hero__media img:not(.deco) {
  position: relative;
  z-index: 2;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 28%;
  filter: saturate(.92);
}

/* --- the story --- */
.story { border-top: 1px solid var(--rule); }
.story__intro { max-width: 62ch; margin-bottom: clamp(3rem, 6vw, 5rem); }
/* wider than the 46ch default: it's one long paragraph and at 46ch it becomes a
   very tall, narrow slab before the reader has any headings to hold on to */
.story__intro .lead { max-width: 58ch; margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem); }
/* the one typographic moment in the prose: her thesis line, set in the display
   face so the eye stops on it */
.story__pull {
  margin: 0;
  max-width: 22ch;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(1.5rem, 2.8vw, 2.4rem);
  line-height: 1.14;
}

.story__block {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, .62fr) minmax(0, 1.38fr);
  gap: clamp(1.5rem, 5vw, 5rem);
  padding-block: clamp(2rem, 4vw, 3.25rem);
}
.story__block + .story__block { border-top: 1px solid var(--rule); }
.story__block:last-child { padding-bottom: 0; }
.story__head {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: var(--step-h3);
  line-height: 1.05;
  max-width: 10ch;
}
.story__head em { font-style: italic; color: var(--blue); }
.story__text { max-width: 62ch; }
.story__text p + p { margin-top: 1.1em; }

/* ═══ 16b. Legal ═══
   privacy.html, and any policy page after it. Deliberately the plainest thing on
   the site: one column, no blobs, no objects, no display-face section headings,
   no reveal animation. A policy has to be read, quoted and trusted, and every
   device that makes the rest of the site feel designed works against that here.
   The only thing it keeps is the type system. */
.legal-hero {
  padding-top: calc(var(--header-h) + var(--bar-h) + clamp(2.5rem, 6vh, 4.5rem));
  padding-bottom: clamp(1.5rem, 3vh, 2.25rem);
}
.legal-hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -.015em;
  font-size: clamp(2.2rem, 4.6vw, 3.6rem);
  line-height: 1;
  margin: 0 0 .9rem;
}
.legal-hero__meta {
  margin: 0;
  max-width: none;
  font-size: var(--step-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  opacity: .55;
}

.legal { padding-bottom: clamp(4rem, 9vh, 7rem); }
.legal__body { max-width: 64ch; }
/* everything shares the container measure rather than the 60ch <p> default,
   so headings, prose and lists all hang off the same right edge */
.legal__body p,
.legal__body li { max-width: none; }
.legal__intro {
  padding-bottom: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--line);
}
/* section headings are body-face uppercase, not the display serif: they're
   signposts in a document, not titles competing for attention */
.legal__body h2 {
  margin: clamp(2.25rem, 4vw, 3rem) 0 .9rem;
  font-family: var(--font-body);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
.legal__body h3 {
  margin: 1.5rem 0 .35rem;
  font-size: var(--step-body);
  font-weight: 600;
}
.legal__body ul {
  margin: 0 0 1.1em;
  padding-left: 1.15rem;
  list-style: disc;
}
.legal__body li { margin-bottom: .45em; }
.legal__body li::marker { color: var(--line-strong); }
.legal__body a {
  border-bottom: 1px solid var(--line-strong);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.legal__body a:hover { color: var(--blue); border-color: var(--blue); }
.legal__note {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: var(--step-fine);
  line-height: 1.6;
  opacity: .6;
}

/* ═══ 17. Motion ═══ */
.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
}
.js .reveal.is-visible { opacity: 1; transform: none; }

.js [data-stagger] .line {
  opacity: 0;
  transform: translateY(.5em);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
}
.js [data-stagger].is-visible .line { opacity: 1; transform: none; }
.js [data-stagger].is-visible .line:nth-child(1) { transition-delay: .05s; }
.js [data-stagger].is-visible .line:nth-child(2) { transition-delay: .14s; }
.js [data-stagger].is-visible .line:nth-child(3) { transition-delay: .23s; }
.js [data-stagger].is-visible .line:nth-child(4) { transition-delay: .32s; }

/* ═══ 18. Responsive ═══ */
/* mid widths are the tight spot: the headline is still full size but the side
   notes have closed in. Shrink the type before the two can touch. */
@media (max-width: 1240px) {
  .hero__title { font-size: clamp(2.4rem, 5.1vw, 6.2rem); }
  .hero__note { max-width: 26ch; }
}

@media (max-width: 1080px) {
  .deco { width: clamp(100px, 13vw, 170px); }
  .about__grid { grid-template-columns: 1fr; gap: clamp(2.5rem, 6vw, 4rem); }
  .work { min-height: 0; padding-block: var(--section-y); }
  .carousel__foot { flex-direction: column; align-items: flex-start; }
  /* sized by width down here: a fixed height would make the 16:9 mockups
     wider than the screen and you'd only ever see a slice of them */
  .carousel__track { padding-inline: calc(50% - min(39vw, 215px)); }
  .slide img { width: min(78vw, 430px); height: auto; }
  .other__grid { grid-template-columns: 1fr; gap: clamp(1.5rem, 4vw, 2.5rem); }
  .contact__grid { grid-template-columns: 1fr; }
  .about__media { max-width: 520px; }
  .services__grid { grid-template-columns: 1fr; }
  .services__object { margin-inline: auto; }
  .service__no { margin-bottom: 1.5rem; }
  .hero__stage { --fig-w: clamp(170px, 22vw, 240px); }
  .hero__note { max-width: 24ch; }   /* now sits directly under 01 */

  /* work-with-me: everything two-up goes single column, and the negative
     margin pulling the "not a fit" divider into the gap has to go with it */
  .fit__grid, .steps__grid, .content-work__grid, .cta__grid { grid-template-columns: 1fr; }
  /* stacked: the half-gap each column gave to the divider goes back, and the
     divider itself becomes a rule between the two blocks */
  .fit__col:not(.fit__col--not) { padding-right: 0; }
  .fit__col--not {
    margin-left: 0;
    padding-left: 0;
    padding-top: clamp(2rem, 5vw, 3rem);
    border-left: 0;
    border-top: 1px solid var(--line);
  }
  .details__grid { grid-template-columns: 1fr; }
  .quotes__grid { grid-template-columns: 1fr; gap: 0; }
  .quote + .quote { margin-top: clamp(2rem, 4vw, 3rem); padding-top: clamp(2rem, 4vw, 3rem); border-top: 1px solid var(--rule); }
  .cta__grid { align-items: start; }

  /* about: portrait above the text, and the story blocks lose their heading
     column — the heading just sits on top of its own prose */
  .about-hero__grid { grid-template-columns: 1fr; }
  .about-hero__media { order: -1; max-width: 420px; }
  .story__block { grid-template-columns: 1fr; gap: 1rem; }
  .story__head { max-width: none; }
}

@media (max-width: 860px) {
  .deco { display: none; }   /* too little room to overlap without covering text */
  /* the two on the photo stay — pulled in so they don't clip off the edges */
  .deco--eiffel, .deco--cat { display: block; }
  .deco--eiffel { top: -7%; right: -4%; width: 38%; }
  .deco--cat    { bottom: -10%; left: -5%; width: 42%; }
  :root { --header-h: 66px; }

  .nav-toggle { display: flex; }
  .nav {
    position: fixed;
    inset: calc(var(--header-h) + var(--bar-h)) 0 auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.5rem;
    padding: 2rem var(--gutter) 2.5rem;
    background: rgba(248, 245, 242, .92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-bottom: 1px solid var(--line);
    clip-path: inset(0 0 100% 0);
    transition: clip-path .5s var(--ease);
  }
  .nav.is-open { clip-path: inset(0 0 0 0); }
  .nav__list { flex-direction: column; gap: 1.1rem; font-size: .8rem; }

  .hero { min-height: auto; padding-bottom: 4rem; }

  /* the crossing trick needs room — below this it stacks instead */
  .hero__stage { display: block; --title-shift: 0px; }
  .hero__title--back { transform: none; }
  .hero__title { width: 100%; }
  .hero__title--front { display: none; }
  .hero__figure {
    width: min(62%, 260px);
    margin: clamp(2rem, 5vw, 3rem) auto 0;
  }
  .hero__note {
    position: static;
    max-width: 46ch;
    margin: clamp(1.75rem, 4vw, 2.5rem) auto 0;
    text-align: center;
  }
  .hero__note--right { text-align: center; }

  .service { grid-template-columns: 1fr; gap: .75rem; }
  .together__cols { grid-template-columns: 1fr; }

  /* consent: the three categories stack, and the buttons go full width — but
     Accept and Reject stay identical to each other, which is the whole point */
  .consent__cats { grid-template-columns: 1fr; gap: 1.25rem; }
  .consent__cat + .consent__cat { padding-top: 1.25rem; border-top: 1px solid var(--line); }

  /* work-with-me */
  .arc__item { grid-template-columns: 1fr; gap: .75rem; }
  .step { gap: 1rem; }
  .step__no { font-size: 1.4rem; }

  .site-footer__grid { grid-template-columns: 1fr 1fr; }
  .site-footer__brand { grid-column: 1 / -1; }
  .blob { filter: blur(60px); }
}

@media (max-width: 520px) {
  .btn { width: 100%; justify-content: center; }
  .hero__actions { width: 100%; }
  .contact__form .btn { width: 100%; }
  /* .btn goes full width here, so the two consent buttons stack — equal width,
     equal weight, Accept first only because it is the affirmative */
  .consent__actions { flex-direction: column; align-items: stretch; }
  .consent__toggle { align-self: flex-start; margin-top: .35rem; }
  .site-footer__grid { grid-template-columns: 1fr; }
  .site-footer__bar { justify-content: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .js .reveal, .js [data-stagger] .line { opacity: 1; transform: none; }
  .js .reveal .doodle { stroke-dashoffset: 0; }   /* else they'd never draw */
}
