/* ---------- Tokens ---------- */
:root {
  --bg: #f5f1ea;
  --bg-alt: #ece6dc;
  --bg-deep: #e3dbce;
  --ink: #1d1b18;
  --ink-soft: #57524a;
  --line: #d6cfc3;
  --accent: #8b6b4e;

  --display: "Tenor Sans", "Gill Sans", "Optima", sans-serif;
  --sans: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;

  --gutter: clamp(1.25rem, 4vw, 3rem);
  /* Page edge for every section, matched to the hero text's inset */
  --page-x: clamp(1.25rem, 9vw, 10rem);
  --section: clamp(5rem, 11vw, 9rem);
  --header-h: 4.5rem;
  --nav-gap: clamp(1rem, 3vw, 2.5rem);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-h);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
ul, dl { margin: 0; padding: 0; list-style: none; }
figure { margin: 0; }
h1, h2, h3 { margin: 0; font-weight: 400; }
p { margin: 0 0 1.25em; }
p:last-child { margin-bottom: 0; }

:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }

.container {
  width: 100%;
  padding-inline: var(--page-x);
}

.skip-link {
  position: absolute;
  left: 1rem;
  top: -3rem;
  padding: .5rem 1rem;
  background: var(--ink);
  color: var(--bg);
  z-index: 100;
}
.skip-link:focus { top: 1rem; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Type helpers ---------- */
.eyebrow,
.section-label,
.cv-heading,
.contact-kind {
  font-family: var(--sans);
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
}

.section-label { color: var(--accent); margin-bottom: 1.25rem; }

.section-title {
  font-family: var(--display);
  font-size: clamp(1.75rem, 3.2vw, 2.6rem);
  line-height: 1.2;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.text-link {
  display: inline-block;
  font-size: .8125rem;
  font-weight: 400;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;
  padding-bottom: .3rem;
  background: linear-gradient(currentColor, currentColor) left bottom / 100% 1px no-repeat;
  transition: background-size .4s ease;
}
.text-link:hover { background-size: 30% 1px; }

/* ---------- Header ---------- */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  padding-top: env(safe-area-inset-top, 0px);
  color: #fff;
  background: transparent;
  transition: background-color .35s ease, color .35s ease, box-shadow .35s ease;
}
.site-header.is-solid {
  color: var(--ink);
  background: var(--bg);
  box-shadow: 0 1px 0 var(--line);
}
/* Only the ink changes when the menu opens: the menu panel itself covers the bar, so the
   whole screen fades to cream as one layer */
.site-header.is-menu-open { color: var(--ink); }

.header-inner {
  padding-inline: var(--gutter);
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nav-gap);
}

.wordmark {
  font-family: var(--display);
  font-size: 1.15rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}
.wordmark svg { height: 14px; width: auto; display: block; }

.site-nav { display: flex; align-items: center; gap: var(--nav-gap); margin-left: auto; }
.site-nav a {
  font-size: .875rem;
  font-weight: 400;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
  opacity: .78;
  transition: opacity .2s ease;
}
.site-nav a:hover { opacity: 1; }

/* EN / FR, last item in the nav, divided by a short rule; the current language is full strength */
.lang-toggle { display: flex; align-items: center; }
.lang-toggle button {
  padding: .25rem 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: .8125rem;
  letter-spacing: .14em;
  cursor: pointer;
  opacity: .55;
  transition: opacity .2s ease;
}
.lang-toggle button + button::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: .9em;
  margin-inline: .7rem;
  vertical-align: -.1em;
  background: currentColor;
  opacity: .5;
}
.lang-toggle button:hover,
.lang-toggle button[aria-pressed="true"] { opacity: 1; }

/* Menu button: hidden on wide screens, two lines that cross into an X when open */
.nav-toggle {
  display: none;
  position: relative;
  width: 2.25rem;
  height: 2.25rem;
  margin-right: -.5rem;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}
.nav-toggle-bars,
.nav-toggle-bars::before {
  position: absolute;
  left: .5rem;
  right: .5rem;
  height: 1px;
  background: currentColor;
  transition: transform .3s ease, top .3s ease;
}
.nav-toggle-bars { top: calc(50% - 3px); }
.nav-toggle-bars::before { content: ""; left: 0; right: 0; top: 6px; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars { top: 50%; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { top: 0; transform: rotate(-90deg); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 100vh;
  min-height: 100svh;
  /* On touch screens main.js pins this to a pixel height, so a mobile address bar
     sliding in or out never resizes the hero */
  min-height: var(--hero-h, 100svh);
  color: #fff;
  background: #2a2420;
  overflow: hidden;
}

.hero-media { position: absolute; inset: 0; }
.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 60% 45%;
}
/* Darken the lower left so the type always reads */
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(18, 15, 12, .78) 0%, rgba(18, 15, 12, .35) 38%, rgba(18, 15, 12, 0) 62%),
    linear-gradient(to right, rgba(18, 15, 12, .35) 0%, rgba(18, 15, 12, 0) 55%),
    linear-gradient(to bottom, rgba(18, 15, 12, .35) 0%, rgba(18, 15, 12, 0) 18%);
}
/* Hover swaps: one stacked image per letter of the name, faded in on hover (see main.js) */
.hero-media .hero-swap {
  position: absolute;
  inset: 0;
  object-position: 50% 50%;
  opacity: 0;
  transition: opacity .6s ease;
}
.hero-media .hero-swap.is-active { opacity: 1; transition-duration: .3s; }
/* Slower crossfades when the name is stepping through on its own */
.hero-media.is-autoplay .hero-swap,
.hero-media.is-autoplay .hero-swap.is-active { transition-duration: 1.2s; }

.hero-letter { transition: opacity .3s ease; }
.hero-name.is-swapping .hero-letter { opacity: .45; }
.hero-name.is-swapping .hero-letter.is-active { opacity: 1; }

/* On load the photo is already in place; the text fades up in turn: name (letter by letter,
   left to right), eyebrow, links. main.js starts the autoplay once all of it is in. */
.hero-name .hero-letter {
  /* backwards, not both: a held opacity would override the hover dimming above */
  animation: hero-letter-in 1.3s cubic-bezier(.25, .1, .25, 1) backwards;
}
/* Start times spread out letter by letter: the sweep moves off quickly and slows into the end */
.hero-letter:nth-child(1) { animation-delay: 0.2s; }
.hero-letter:nth-child(2) { animation-delay: 0.29s; }
.hero-letter:nth-child(3) { animation-delay: 0.4s; }
.hero-letter:nth-child(4) { animation-delay: 0.53s; }
.hero-letter:nth-child(5) { animation-delay: 0.68s; }
.hero-letter:nth-child(6) { animation-delay: 0.85s; }
.hero-letter:nth-child(7) { animation-delay: 1.03s; }
.hero-letter:nth-child(8) { animation-delay: 1.24s; }
.hero-letter:nth-child(9) { animation-delay: 1.46s; }
.hero-letter:nth-child(10) { animation-delay: 1.7s; }
@keyframes hero-letter-in { from { opacity: 0; } to { opacity: 1; } }

.hero .eyebrow, .hero-links { animation: hero-text-in 1.4s cubic-bezier(.2, .7, .2, 1) both; }
.hero .eyebrow { animation-delay: 2.2s; }
.hero-links { animation-delay: 2.6s; }
@keyframes hero-text-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

.hero-content {
  position: relative;
  padding-left: var(--page-x);
  padding-bottom: clamp(3rem, 8vh, 6rem);
}

.hero .eyebrow { font-size: .9375rem; letter-spacing: .18em; color: rgba(255, 255, 255, .85); margin-bottom: 1.5rem; }
.hero .eyebrow .sep { white-space: pre; margin-inline: .3em; opacity: .6; }

.hero-name {
  font-family: var(--display);
  font-size: clamp(2.6rem, 7vw, 6.75rem);
  line-height: 1;
  letter-spacing: .05em;
  text-transform: uppercase;
  margin-bottom: 2.25rem;
}
/* Wordmark SVG: about the same width as the old text name, shrunk to fit narrow screens */
.hero-name svg {
  display: block;
  width: min(8.35em, calc(100vw - 2 * var(--page-x)));
  height: auto;
}


.hero-links { display: flex; flex-wrap: wrap; gap: 2.5rem; }

/* ---------- Sections ---------- */
.section { padding-block: var(--section); }

.section-head { margin-bottom: clamp(2.5rem, 5vw, 4rem); }

/* About */
/* The photo bleeds to the left edge of the viewport; the text keeps the container's right edge. */
.about-grid {
  display: grid;
  grid-template-columns: 50vw minmax(0, 1fr);
  gap: clamp(3rem, 6vw, 6rem);
  align-items: center;
  padding-right: var(--page-x);
}
.about-image { aspect-ratio: 4 / 5; max-height: 92vh; overflow: hidden; background: var(--bg-alt); }
.about-image img { width: 100%; height: 100%; object-fit: cover; }
.about-text .section-title { margin-bottom: 2rem; }
.about-text p:not(.section-label) { color: var(--ink-soft); max-width: 36rem; }

/* Gallery */

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(.5rem, 1.5vw, 1.25rem);
}

.gallery-item {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: var(--line);
  cursor: zoom-in;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1s cubic-bezier(.2, .7, .2, 1), opacity .4s ease;
}
.gallery-item:hover img { transform: scale(1.04); }

.work-more {
  margin-top: 3rem;
  text-align: center;
  color: var(--ink-soft);
  font-size: .8125rem;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.work-more .text-link { margin-left: .75rem; color: var(--ink); }

/* Experience & skills: two bands sharing the #experience anchor */
.cv-band {
  padding-block: var(--section);
  background: var(--bg-alt);
}
.cv-band--skills { background: var(--bg-deep); }

.cv-heading { color: var(--accent); margin-bottom: 1.25rem; }

/* Experience: title on the left, entries on the right */
.cv-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
}
.cv-group + .cv-group { margin-top: clamp(3rem, 6vw, 4.5rem); }

.cv-roles { border-top: 1px solid var(--line); }
.cv-roles > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  gap: .5rem 2rem;
  padding-block: 1.5rem;
  border-bottom: 1px solid var(--line);
}
.cv-roles dt {
  font-family: var(--display);
  font-size: 1.15rem;
  line-height: 1.4;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.cv-roles dd { margin: 0; color: var(--ink-soft); }
.cv-roles li + li { margin-top: .2rem; }

/* Skills: three numbered columns, then a row of tools */
.cv-band--skills .cv-title { margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.skills {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
}
.skill-col { border-top: 1px solid var(--ink); padding-top: 1.5rem; }
.skill-num {
  font-family: var(--display);
  font-size: 2rem;
  line-height: 1;
  color: var(--accent);
  margin-bottom: 1.25rem;
}
.skill-col .cv-heading { color: var(--ink); }
.skill-list li {
  padding-block: .7rem;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
  line-height: 1.5;
}
.skill-list li:first-child { padding-top: 0; }
.skill-list li:last-child { border-bottom: 0; }

.tools {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 1rem 2.5rem;
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}
.tools .cv-heading { margin: 0; }
.tool-list {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 0;
  color: var(--ink-soft);
}
/* Vertical rule between items */
.tool-list li:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 1px;
  height: .95em;
  margin-inline: 1rem;
  vertical-align: -.12em;
  background: var(--ink-soft);
  opacity: .55;
}

/* Clients */
.clients {
  background: var(--bg-alt);
  padding-block: clamp(4rem, 8vw, 6rem);
  text-align: center;
}
.clients .section-label { margin-bottom: 2.5rem; }

.logos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}
.logos img {
  height: clamp(2.5rem, 5vw, 3.5rem);
  width: auto;
  max-width: 11rem;
  object-fit: contain;
  opacity: .75;
  transition: opacity .3s ease;
}
.logos img:hover { opacity: 1; }
/* Optical balance: the logos differ a lot in visual weight */
.logo--meta img { height: clamp(1.5rem, 3vw, 2.1rem); }
.logo--collective img { height: clamp(2.2rem, 4.4vw, 3.1rem); }
.logo--perle img { height: clamp(2.9rem, 5.8vw, 4.1rem); opacity: .9; }

/* Contact */
.contact { background: var(--ink); color: var(--bg); }
.contact .section-label { color: #c7a98c; }
.contact-inner { text-align: center; }
.contact-title {
  font-family: var(--display);
  font-size: clamp(1.6rem, 3.6vw, 2.75rem);
  line-height: 1.25;
  letter-spacing: .05em;
  text-transform: uppercase;
  max-width: 26ch;
  margin: 0 auto clamp(3rem, 6vw, 4.5rem);
}
.contact-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(2.5rem, 8vw, 7rem);
}
.contact-links li { display: flex; flex-direction: column; gap: .6rem; }
.contact-kind { color: rgba(245, 241, 234, .55); }
.contact-links a {
  font-family: var(--display);
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  letter-spacing: -.02em;
  text-decoration: none;
  overflow-wrap: anywhere;
  background: linear-gradient(currentColor, currentColor) center bottom / 0 1px no-repeat;
  transition: background-size .4s ease;
}
.contact-links a:hover { background-size: 100% 1px; }

/* Footer */
.site-footer {
  background: var(--ink);
  color: rgba(245, 241, 234, .55);
  font-size: .8125rem;
  letter-spacing: .06em;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.footer-inner {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 2rem;
  border-top: 1px solid rgba(245, 241, 234, .12);
}
.footer-inner a { text-decoration: none; text-transform: uppercase; letter-spacing: .14em; font-size: .75rem; }
.footer-inner a:hover { color: var(--bg); }

/* ---------- Lightbox ---------- */
.lightbox {
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: rgba(20, 18, 16, .96);
}
.lightbox[open] { display: flex; align-items: center; justify-content: center; }
.lightbox::backdrop { background: transparent; }
.lightbox img {
  max-width: calc(100vw - 8rem);
  max-height: calc(100vh - 6rem);
  width: auto;
  height: auto;
  object-fit: contain;
}
.lightbox-btn {
  position: absolute;
  background: none;
  border: 0;
  color: #f5f1ea;
  font-family: var(--display);
  font-size: 2.75rem;
  line-height: 1;
  width: 3.5rem;
  height: 3.5rem;
  cursor: pointer;
  opacity: .7;
  transition: opacity .2s ease;
}
.lightbox-btn:hover { opacity: 1; }
.lightbox-close { top: 1rem; right: 1rem; }
.lightbox-prev { left: 1rem; top: 50%; transform: translateY(-50%); }
.lightbox-next { right: 1rem; top: 50%; transform: translateY(-50%); }

/* ---------- Reveal on scroll ---------- */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .9s ease, transform .9s cubic-bezier(.2, .7, .2, 1);
}
.js .reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .gallery-item img, .text-link { transition: none; }
  .hero-name .hero-letter, .hero .eyebrow, .hero-links { animation: none; }
  .hero-media .hero-swap, .hero-letter { transition: none; }
}

/* ---------- Responsive ---------- */
/* Portrait phones: the 3:2 hero photos lose their sides to the crop, so each one is shown at
   full height and natural width and drifts slowly rightward across the middle of the picture
   while it's up (main.js adds .is-panning). A transform keeps the movement smooth.
   The factors (.32 → .68) are how far across the cropped-off width the view sits:
   0 = the photo's left edge, .5 = centered, 1 = its right edge. */
@media (max-width: 760px) and (max-aspect-ratio: 1/1) and (prefers-reduced-motion: no-preference) {
  .hero-media img,
  .hero-media .hero-swap {
    position: absolute;
    inset: 0 auto 0 0;
    width: auto;
    max-width: none;
    height: 100%;
    aspect-ratio: 3 / 2;
    transform: translateX(calc((100vw - 100%) * .32));
    will-change: transform; /* own layer: the slide is composited, not repainted */
  }
  .hero-media img.is-panning { animation: hero-pan 16s linear both; }
  @keyframes hero-pan {
    from { transform: translateX(calc((100vw - 100%) * .32)); }
    to   { transform: translateX(calc((100vw - 100%) * .68)); }
  }
}

@media (max-width: 900px) {
  .hero-media img { object-position: 62% 50%; }

  .about-grid { grid-template-columns: 1fr; padding-right: 0; }
  .about-image { max-height: none; margin-inline: var(--page-x); }
  .about-text { padding-inline: var(--page-x); }

  .cv-layout { grid-template-columns: 1fr; }
  .skills { grid-template-columns: 1fr 1fr; }
}

/* Narrow screens: the nav becomes a full-screen menu behind the header bar */
@media (max-width: 760px) {
  .nav-toggle { display: block; margin-left: auto; }
  .site-nav {
    position: fixed;
    inset: 0;
    z-index: -1; /* above the header's background, below its wordmark and buttons */
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 1.75rem;
    margin: 0;
    padding: var(--header-h) var(--page-x) 4rem;
    background: var(--bg);
    color: var(--ink);
    opacity: 0;
    visibility: hidden;
    transition: opacity .35s ease, visibility 0s .35s;
  }
  .site-header.is-menu-open .site-nav { opacity: 1; visibility: visible; transition: opacity .35s ease; }
  .site-nav a {
    font-family: var(--display);
    font-size: 1.75rem;
    letter-spacing: .1em;
    opacity: 1;
  }
  .site-nav .lang-toggle { margin-top: 1rem; }
  .site-nav .lang-toggle button { font-size: 1rem; }
  .menu-open { overflow: hidden; }
}

@media (max-width: 640px) {
  body { font-size: 1rem; }
  .wordmark { font-size: .95rem; letter-spacing: .1em; }
  .wordmark svg { height: 12px; }
  .hero .eyebrow { font-size: .8125rem; letter-spacing: .16em; line-height: 2.3; margin-bottom: 1.25rem; }
  .hero-name { margin-bottom: 1.5rem; }
  .hero .eyebrow span { display: block; }
  .hero .eyebrow .sep { display: none; }

  .gallery { grid-template-columns: 1fr 1fr; }
  .gallery li:nth-child(9) { display: none; } /* 9 photos leave a gap in two columns */
  .skills { grid-template-columns: 1fr; }
  .cv-roles > div { grid-template-columns: 1fr; }

  .lightbox img { max-width: 100vw; max-height: calc(100vh - 9rem); }
  .lightbox-prev, .lightbox-next { top: auto; bottom: 1.5rem; transform: none; }
}
