/* ---------- Reset & variables ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --paper: #fbfafd;
  --paper-soft: #f5f3fa;
  --surface: #ffffff;
  --line: #e4ebf2;
  --ink: #23282f;
  --ink-dim: #5a6472;
  --accent: #abc2dd;
  --accent-deep: #8aa6c8;
  --accent-text: #4a6a8f;
  --accent-pale: #eef3f9;
  --rose: #dbade3;
  --rose-deep: #c48bd0;
  --rose-text: #93549e;
  --rose-pale: #f8f0f9;
  --gradient: linear-gradient(120deg, var(--accent), var(--rose) 65%, var(--accent-deep));
  --radius: 20px;
  --radius-sm: 12px;
  --shadow: 0 30px 70px -30px rgba(35, 40, 47, 0.16);
  --ff-display: 'Playfair Display', 'Georgia', serif;
  --ff-body: 'Inter', system-ui, sans-serif;
  --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
}

/* ---------- Thème sombre ----------
   Activé par un choix explicite (bouton lune/soleil, persisté en
   localStorage) et posé sur <html data-theme="dark">. Un petit script
   inline dans le <head> applique l'attribut avant le premier rendu
   pour éviter un flash du thème clair. */
:root[data-theme="dark"] {
  --paper: #17181c;
  --paper-soft: #1e2025;
  --surface: #202329;
  --line: rgba(255, 255, 255, 0.09);
  --ink: #f2f1f4;
  --ink-dim: #a7adb8;
  --accent-text: #abc2dd;
  --accent-pale: rgba(171, 194, 221, 0.12);
  --rose-text: #dbade3;
  --rose-pale: rgba(219, 173, 227, 0.12);
  --shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.6);
}
:root[data-theme="dark"] body::before {
  background:
    radial-gradient(1000px circle at 12% -8%, rgba(171,194,221,0.14), transparent 60%),
    radial-gradient(900px circle at 92% 26%, rgba(219,173,227,0.1), transparent 60%),
    radial-gradient(850px circle at 45% 115%, rgba(171,194,221,0.08), transparent 60%);
}
:root[data-theme="dark"] .cursor-glow { mix-blend-mode: screen; opacity: 0.5; }
:root[data-theme="dark"] .header.scrolled { background: rgba(23, 24, 28, 0.82); }
:root[data-theme="dark"] .logo-horizontal { filter: invert(1) brightness(1.6); }
:root[data-theme="dark"] .hero-photo { filter: grayscale(1) contrast(1.05) brightness(0.92); }

html { scroll-behavior: smooth; }

body {
  font-family: var(--ff-body);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.65;
  overflow-x: hidden;
  font-weight: 400;
  position: relative;
}
/* Fond décoratif en position fixe : un calque dédié se compose sur le GPU
   sans être redessiné à chaque frame de scroll, contrairement à
   background-attachment: fixed sur le body. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(1000px circle at 12% -8%, rgba(171,194,221,0.4), transparent 60%),
    radial-gradient(900px circle at 92% 26%, rgba(219,173,227,0.32), transparent 60%),
    radial-gradient(850px circle at 45% 115%, rgba(171,194,221,0.28), transparent 60%);
  pointer-events: none;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, textarea, select { font: inherit; color: inherit; }

.container {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 24px;
}

.gradient-text {
  background: var(--gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-style: italic;
}

.section-tag {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 16px;
}
.section-tag--rose { color: var(--rose-text); }

.section-title {
  font-family: var(--ff-display);
  font-size: clamp(1.9rem, 3.4vw, 2.8rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin-bottom: 20px;
  color: var(--ink);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 15px 30px;
  border-radius: 999px;
  font-weight: 500;
  font-size: 0.92rem;
  letter-spacing: 0.01em;
  transition: box-shadow 0.25s ease, background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
  white-space: nowrap;
}

.btn-primary {
  background: rgba(138, 166, 200, 0.78);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(111, 143, 181, 0.9);
  color: var(--paper);
  box-shadow: 0 14px 30px -12px rgba(138, 166, 200, 0.55);
}
.btn-primary:hover {
  background: rgba(121, 154, 192, 0.88);
  border-color: rgba(98, 132, 171, 0.95);
  box-shadow: 0 18px 36px -12px rgba(138, 166, 200, 0.65);
}

.btn-ghost {
  border: 1px solid var(--line);
  color: var(--ink);
  background: var(--paper);
}
.btn-ghost:hover { border-color: var(--accent-deep); background: var(--accent-pale); }

.btn-accent {
  background: rgba(138, 166, 200, 0.78);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(111, 143, 181, 0.9);
  color: var(--paper);
  box-shadow: 0 14px 30px -12px rgba(138, 166, 200, 0.55);
}
.btn-accent:hover {
  background: rgba(121, 154, 192, 0.88);
  border-color: rgba(98, 132, 171, 0.95);
  box-shadow: 0 18px 36px -12px rgba(138, 166, 200, 0.65);
}

.btn-small { padding: 11px 22px; font-size: 0.82rem; }

/* ---------- Cursor glow ---------- */
/* Fixed-size layer moved with transform (GPU compositing only) instead of
   resizing a full-viewport blurred background every frame. */
.cursor-glow {
  position: fixed;
  top: 0;
  left: 0;
  width: 900px;
  height: 700px;
  margin: -350px 0 0 -450px;
  pointer-events: none;
  z-index: -1;
  background: radial-gradient(520px 400px ellipse at center, rgba(171,194,221,0.42), transparent 60%);
  filter: blur(100px);
  mix-blend-mode: multiply;
  transform: translate3d(var(--x, 50vw), var(--y, 30vh), 0);
  will-change: transform;
}

/* ---------- Header ---------- */
.header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  padding: 22px 0;
  transition: background 0.3s ease, padding 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
  border-bottom: 1px solid transparent;
}
.header.scrolled {
  background: rgba(255,255,255,0.85);
  backdrop-filter: blur(14px);
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
  box-shadow: 0 8px 30px -20px rgba(35,40,47,0.25);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.logo {
  display: flex;
  align-items: center;
}
.logo-horizontal {
  height: 60px;
  width: auto;
}

.nav {
  display: flex;
  gap: 34px;
  margin-left: auto;
}
.nav-link {
  font-size: 0.92rem;
  color: var(--ink-dim);
  position: relative;
  transition: color 0.2s ease;
}
.nav-link::after {
  content: '';
  position: absolute;
  left: 0; bottom: -6px;
  width: 0; height: 1.5px;
  background: var(--accent-deep);
  transition: width 0.25s ease;
}
.nav-link:hover { color: var(--ink); }
.nav-link:hover::after { width: 100%; }

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--ink-dim);
  transition: background 0.25s var(--ease-smooth), color 0.25s var(--ease-smooth),
    border-color 0.25s var(--ease-smooth), transform 0.2s var(--ease-smooth);
}
.theme-toggle:hover { border-color: var(--accent-deep); color: var(--ink); }
.theme-toggle:active { transform: scale(0.9); }
.theme-toggle svg { width: 19px; height: 19px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

.burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 34px;
  height: 34px;
  z-index: 200;
}
.burger span {
  display: block;
  width: 100%;
  height: 1.5px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 0.3s ease, opacity 0.3s ease;
}
.burger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger.open span:nth-child(2) { opacity: 0; }
.burger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  padding: 140px 0 80px;
  overflow: hidden;
}
.hero-bg {
  position: absolute;
  inset: -20% -10%;
  z-index: -1;
  background:
    radial-gradient(560px circle at 12% 18%, rgba(171,194,221,0.3), transparent 60%),
    radial-gradient(500px circle at 60% 95%, rgba(219,173,227,0.22), transparent 60%);
  filter: blur(20px);
}

.hero-columns {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 64px;
  align-items: center;
}

.hero-photo-frame {
  position: relative;
  aspect-ratio: 4 / 5;
  max-width: 420px;
  margin: 0 auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.hero-photo-blob {
  position: absolute;
  inset: -30%;
  background: var(--gradient);
  opacity: 0.5;
  filter: blur(60px);
  animation: blobMove 12s ease-in-out infinite alternate;
}
@keyframes blobMove {
  0% { transform: translate(-5%, -5%) scale(1); }
  100% { transform: translate(5%, 5%) scale(1.15); }
}
.hero-photo {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  filter: grayscale(1) contrast(1.05) brightness(1.03);
}
.hero-photo-frame::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  mix-blend-mode: multiply;
  opacity: 0.16;
  pointer-events: none;
}

.hero-brand {
  text-align: center;
  margin-bottom: 56px;
}
.hero-brand-sub {
  display: inline-block;
  font-family: var(--ff-display);
  font-size: clamp(2.3rem, 5.6vw, 4rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--ink);
  white-space: nowrap;
}

.hero-title {
  font-family: var(--ff-display);
  font-size: clamp(1.3rem, 2.8vw, 2.4rem);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -0.01em;
  margin-bottom: 26px;
  color: var(--ink);
}

.hero-text {
  font-size: 1.08rem;
  font-weight: 300;
  color: var(--ink-dim);
  max-width: 560px;
  margin-bottom: 38px;
}
.hero-text + .hero-text {
  margin-top: -20px;
}

.hero-actions {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 68px;
}

.scroll-hint {
  position: absolute;
  bottom: 36px;
  left: 50%;
  transform: translateX(-50%);
  width: 26px;
  height: 42px;
  border: 1px solid var(--line);
  border-radius: 20px;
}
.scroll-hint span {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 8px;
  border-radius: 2px;
  background: var(--rose-deep);
  animation: scrollDot 1.8s ease infinite;
}
@keyframes scrollDot {
  0% { transform: translate(-50%, 0); opacity: 1; }
  70% { transform: translate(-50%, 16px); opacity: 0; }
  100% { opacity: 0; }
}

/* ---------- Services ---------- */
.services { padding: 130px 0; position: relative; }

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin-top: 50px;
}

.card {
  position: relative;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 38px 32px;
  transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 30%), rgba(171,194,221,0.22), transparent 70%);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}
.card:hover::before { opacity: 1; }
.card--rose::before {
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 30%), rgba(219,173,227,0.26), transparent 70%);
}
.card:hover {
  transform: translateY(-6px);
  border-color: var(--accent);
  box-shadow: var(--shadow);
}
.card--rose:hover { border-color: var(--rose); }
.card--rose .card-list li::before { background: var(--rose); }

.services-cta {
  text-align: center;
  margin-top: 50px;
}

.card-icon {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-pale);
  color: var(--accent-text);
  margin-bottom: 24px;
}
.card-icon svg { width: 24px; height: 24px; }
.card-icon--rose { background: var(--rose-pale); color: var(--rose-text); }

.card h3 {
  font-family: var(--ff-display);
  font-size: 1.3rem;
  font-weight: 600;
  margin-bottom: 12px;
  color: var(--ink);
}
.card p {
  color: var(--ink-dim);
  font-size: 0.95rem;
  margin-bottom: 20px;
}
.card-list li {
  position: relative;
  padding-left: 20px;
  font-size: 0.89rem;
  color: var(--ink-dim);
  margin-bottom: 9px;
}
.card-list li::before {
  content: '';
  position: absolute;
  left: 0; top: 8px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* ---------- Portfolio ---------- */
.portfolio { padding: 130px 0; }

.portfolio-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 8px;
}
.filter-btn {
  padding: 9px 22px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-dim);
  font-size: 0.85rem;
  font-weight: 500;
  transition: background 0.3s var(--ease-smooth), color 0.3s var(--ease-smooth),
    border-color 0.3s var(--ease-smooth), transform 0.2s var(--ease-smooth);
}
.filter-btn:hover { border-color: var(--accent-deep); color: var(--ink); }
.filter-btn:active { transform: scale(0.94); }
.filter-btn.active {
  background: rgba(138, 166, 200, 0.85);
  border-color: rgba(111, 143, 181, 0.9);
  color: #fff;
}

/* Mosaïque en colonnes : chaque visuel garde son ratio naturel plutôt
   que d'être recadré dans une cellule de grille de taille fixe. */
.portfolio-grid {
  columns: 3 320px;
  column-gap: 22px;
  margin-top: 30px;
}

.portfolio-card {
  position: relative;
  display: block;
  width: 100%;
  text-align: left;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  /* Calque de composition dédié : sans lui, Safari/Chrome oublient parfois
     de peindre une carte située en haut d'une colonne (après le fondu
     .reveal) tant qu'on ne la survole pas. */
  will-change: transform;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  isolation: isolate;
  margin-bottom: 22px;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 20px 45px -30px rgba(35, 40, 47, 0.25);
  transition: transform 0.4s var(--ease-smooth), box-shadow 0.4s var(--ease-smooth),
    opacity 0.3s var(--ease-smooth);
}
.portfolio-card:hover,
.portfolio-card:focus-visible {
  transform: translateY(-6px);
  box-shadow: var(--shadow);
}
.portfolio-card:active { transform: translateY(-2px) scale(0.98); }

/* État transitoire pendant un changement de filtre : la carte s'efface
   en douceur avant d'être retirée du flux (voir script.js). */
.portfolio-card--hidden {
  opacity: 0;
  transform: scale(0.92);
  pointer-events: none;
}

.portfolio-media {
  display: block;
  width: 100%;
  overflow: hidden;
}
.portfolio-media img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.6s var(--ease-smooth);
}
.portfolio-card:hover .portfolio-media img,
.portfolio-card:focus-visible .portfolio-media img { transform: scale(1.06); }

.portfolio-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(20, 18, 24, 0.35);
  opacity: 0;
  transition: opacity 0.35s var(--ease-smooth);
}
.portfolio-card:hover .portfolio-overlay,
.portfolio-card:focus-visible .portfolio-overlay { opacity: 1; }

/* Icône loupe/agrandir en pur CSS : un cercle + une poignée, en ::before/::after. */
.portfolio-zoom {
  position: relative;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 10px 24px -8px rgba(20, 18, 24, 0.5);
  transform: scale(0.8);
  transition: transform 0.35s var(--ease-smooth);
}
.portfolio-card:hover .portfolio-zoom,
.portfolio-card:focus-visible .portfolio-zoom { transform: scale(1); }
.portfolio-zoom::before,
.portfolio-zoom::after {
  content: '';
  position: absolute;
  /* Couleur fixe (pas var(--ink)) : le cercle reste blanc quel que soit
     le thème, l'icône doit donc rester sombre pour rester visible. */
  background: #23282f;
}
.portfolio-zoom::before {
  top: 50%; left: 50%;
  width: 15px; height: 2px;
  transform: translate(-50%, -50%);
}
.portfolio-zoom::after {
  top: 50%; left: 50%;
  width: 2px; height: 15px;
  transform: translate(-50%, -50%);
}

/* ---------- Portfolio : lightbox ---------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--ease-smooth);
}
.lightbox.show { opacity: 1; pointer-events: auto; }
.lightbox-overlay {
  position: absolute;
  inset: 0;
  background: rgba(15, 14, 18, 0.88);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lightbox-figure {
  position: relative;
  z-index: 1;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  transform: scale(0.96);
  transition: transform 0.4s var(--ease-smooth);
}
.lightbox.show .lightbox-figure { transform: scale(1); }
.lightbox-img {
  max-width: 100%;
  max-height: 78vh;
  border-radius: var(--radius-sm);
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, 0.6);
  opacity: 1;
  transition: opacity 0.25s var(--ease-smooth);
}
.lightbox-img.is-switching { opacity: 0; }
.lightbox-caption {
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.92rem;
  text-align: center;
  max-width: 60ch;
}
.lightbox-close {
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 2;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  transition: transform 0.2s var(--ease-smooth), background 0.2s var(--ease-smooth);
}
.lightbox-close:hover { background: rgba(255, 255, 255, 0.22); transform: rotate(90deg); }
.lightbox-close:active { transform: rotate(90deg) scale(0.88); }
.lightbox-nav {
  position: absolute;
  top: 50%;
  z-index: 2;
  transform: translateY(-50%);
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  transition: background 0.2s var(--ease-smooth);
}
.lightbox-nav:hover { background: rgba(255, 255, 255, 0.22); }
.lightbox-prev { left: 16px; }
.lightbox-next { right: 16px; }
body.modal-open { overflow: hidden; }

/* ---------- Contact ---------- */
.contact { padding: 130px 0; }

.contact-inner {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 60px;
}

.contact-text { color: var(--ink-dim); font-weight: 300; margin-bottom: 36px; max-width: 440px; }

.contact-details { display: flex; flex-direction: column; gap: 16px; margin-bottom: 34px; }
.contact-item {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 0.96rem;
  color: var(--ink-dim);
  transition: color 0.2s ease;
}
a.contact-item:hover { color: var(--ink); }
.contact-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--accent-pale);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.socials { display: flex; gap: 12px; }
.social-link {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-dim);
  transition: background 0.25s ease, border-color 0.25s ease, transform 0.25s ease, color 0.25s ease;
}
.social-link svg { width: 18px; height: 18px; }
.social-link:hover {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
  transform: translateY(-3px);
}

.contact-visual-media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.contact-visual-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05) brightness(1.05);
}
.contact-visual-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  mix-blend-mode: multiply;
  opacity: 0.14;
  pointer-events: none;
}
.contact-visual-panel {
  margin-top: 28px;
  text-align: center;
}

/* ---------- Footer ---------- */
.footer {
  border-top: 1px solid var(--line);
  padding: 34px 0;
}
.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.footer-inner p { color: var(--ink-dim); font-size: 0.84rem; }
.footer-links { display: flex; gap: 18px; }
.footer-links a { color: var(--ink-dim); font-size: 0.84rem; transition: color 0.2s ease; }
.footer-links a:hover { color: var(--ink); }
.back-top {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-dim);
  transition: background 0.25s ease, color 0.25s ease;
}
.back-top:hover { background: var(--ink); color: var(--paper); }

/* ---------- Reveal animation ---------- */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveal.visible { opacity: 1; transform: translateY(0); }

/* ---------- Motion design ---------- */

/* Titres découpés en mots (data-split, voir script.js) : chaque mot monte
   depuis un masque, en cascade, au lieu d'un fondu global du bloc. */
.reveal[data-split] { opacity: 1; transform: none; }
.split-word {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  /* Marge de sécurité pour ne pas rogner jambages et italiques. */
  padding: 0 0.08em 0.14em;
  margin: 0 -0.08em -0.14em;
}
.split-inner {
  display: inline-block;
  transform: translateY(110%) rotate(4deg);
  transform-origin: left bottom;
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.split-ready.is-in .split-inner { transform: none; }

/* Dégradé des mots-clés qui ondule lentement. */
.gradient-text {
  background-size: 220% 100%;
  animation: gradientShift 7s ease-in-out infinite alternate;
}
@keyframes gradientShift {
  from { background-position: 0% 50%; }
  to { background-position: 100% 50%; }
}

/* Barre de progression de lecture en haut de page. */
.scroll-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 300;
  background: var(--gradient);
  transform: scaleX(var(--progress, 0));
  transform-origin: left center;
  pointer-events: none;
}

/* Portrait : dévoilement par volet + léger dézoom, puis parallaxe au
   scroll (propriété translate, indépendante du transform du .reveal). */
.hero-media { translate: 0 var(--parallax, 0px); }
.hero-media.reveal { opacity: 1; transform: none; }
.hero-media .hero-photo-frame {
  clip-path: inset(100% 0 0 0 round var(--radius));
  transition: clip-path 1.3s cubic-bezier(0.77, 0, 0.18, 1) 0.15s;
}
.hero-media .hero-photo {
  transform: scale(1.18);
  transition: transform 1.8s cubic-bezier(0.22, 1, 0.36, 1) 0.15s;
}
.hero-media.visible .hero-photo-frame { clip-path: inset(0 0 0 0 round var(--radius)); }
.hero-media.visible .hero-photo { transform: scale(1); }

/* Icônes de services qui se dessinent trait par trait. */
.card-icon svg [pathLength] {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.4s cubic-bezier(0.65, 0, 0.35, 1) 0.3s;
}
.card.visible .card-icon svg [pathLength] { stroke-dashoffset: 0; }

/* Portfolio : chaque carte flotte vers sa place en apparaissant, en
   cascade, et l'image se pose par un léger dézoom. On anime la propriété
   translate de la carte et l'opacité du média, jamais l'opacité ni le
   transform de la carte (voir le bug de peinture noté sur
   .portfolio-card, et transform sert au survol). Classe posée par
   script.js seulement. */
.portfolio-grid.motion-ready .portfolio-card {
  translate: 0 16px;
  transition: transform 0.4s var(--ease-smooth), box-shadow 1.4s ease var(--d, 0ms),
    opacity 0.3s var(--ease-smooth), translate 1.4s cubic-bezier(0.25, 1, 0.5, 1) var(--d, 0ms);
}
.portfolio-grid.motion-ready .portfolio-media {
  opacity: 0;
  transition: opacity 1.4s cubic-bezier(0.4, 0, 0.2, 1) var(--d, 0ms);
}
.portfolio-grid.motion-ready .portfolio-media img {
  scale: 1.03;
  transition: transform 0.6s var(--ease-smooth), scale 2s cubic-bezier(0.25, 1, 0.5, 1) var(--d, 0ms);
}
.portfolio-grid.motion-ready .portfolio-card:not(.is-in) { box-shadow: none; }
.portfolio-grid.motion-ready .portfolio-card.is-in { translate: 0 0; }
.portfolio-grid.motion-ready .is-in .portfolio-media { opacity: 1; }
.portfolio-grid.motion-ready .is-in .portfolio-media img { scale: 1; }
.card-icon { transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }
.card:hover .card-icon { transform: rotate(-8deg) scale(1.08); }

/* Accessibilité : aucune animation de mouvement si le visiteur l'a
   demandé au niveau du système. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { transform: none; transition: opacity 0.4s ease; }
  .split-inner { transform: none; transition: none; }
  .gradient-text, .hero-photo-blob, .scroll-hint span { animation: none; }
  .hero-media { translate: none; }
  .hero-media .hero-photo-frame { clip-path: none; transition: none; }
  .hero-media .hero-photo { transform: none; transition: none; }
  .card-icon svg [pathLength] { stroke-dashoffset: 0; transition: none; }
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .cards { grid-template-columns: 1fr; }
  .portfolio-grid { columns: 2 260px; }
  .lightbox { padding: 90px 16px 24px; }
  .lightbox-img { max-height: 62vh; }
  .contact-inner { grid-template-columns: 1fr; }

  .hero-columns { grid-template-columns: 1fr; gap: 40px; text-align: center; }
  .hero-photo-frame { max-width: 300px; }
  .hero-text { margin-left: auto; margin-right: auto; }
  .hero-actions { justify-content: center; }
}

@media (max-width: 760px) {
  .nav { display: none; }
  .burger { display: flex; }

  .nav.mobile-open {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0; right: 0;
    height: 100vh;
    width: 78%;
    max-width: 320px;
    background: var(--paper);
    border-left: 1px solid var(--line);
    padding: 100px 32px 40px;
    gap: 26px;
    z-index: 150;
    box-shadow: -20px 0 60px rgba(35,40,47,0.12);
  }
  .nav.mobile-open .nav-link { font-size: 1.1rem; }

  .portfolio-grid { columns: 1; }
  .hero-brand-sub { white-space: normal; }

  .contact-visual-media { aspect-ratio: 3 / 4; }
}

@media (max-width: 480px) {
  .container { padding: 0 18px; }
  .hero { padding-top: 120px; }
  .card { padding: 28px 22px; }
}

/* Overlay behind mobile menu */
.nav-overlay {
  position: fixed;
  inset: 0;
  background: rgba(35,40,47,0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  z-index: 140;
}
.nav-overlay.show { opacity: 1; pointer-events: auto; }

/* ---------- Bannière cookies ---------- */
.cookie-banner {
  position: fixed;
  left: 20px;
  right: 20px;
  bottom: 20px;
  z-index: 250;
  max-width: 620px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  padding: 22px 26px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: 0 30px 70px -30px rgba(20, 18, 24, 0.35);
  animation: cookieIn 0.5s var(--ease-smooth);
}
/* Une règle de classe qui fixe display:flex l'emporte sur le [hidden]
   natif (même spécificité, mais les styles auteur passent après la
   feuille de style du navigateur) : ce sélecteur plus spécifique
   rétablit le masquage quand l'attribut est posé en JS. */
.cookie-banner[hidden] { display: none; }
@keyframes cookieIn {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}
.cookie-banner p { font-size: 0.86rem; color: var(--ink-dim); flex: 1 1 320px; }
.cookie-banner p a { color: var(--accent-text); text-decoration: underline; }
.cookie-banner-actions { display: flex; gap: 10px; flex: 0 0 auto; }

@media (max-width: 480px) {
  .cookie-banner { left: 12px; right: 12px; bottom: 12px; padding: 20px; }
  .cookie-banner-actions { width: 100%; }
  .cookie-banner-actions .btn { flex: 1; }
}

/* ---------- Pages de contenu (RGPD, CGU, 404) ---------- */
.legal {
  padding: 160px 0 120px;
  min-height: 60vh;
}
.legal-content {
  max-width: 760px;
  margin: 0 auto;
}
.legal-updated { color: var(--ink-dim); font-size: 0.88rem; margin-bottom: 48px; }
.legal-content h2 {
  font-family: var(--ff-display);
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--ink);
  margin: 44px 0 16px;
}
.legal-content h2:first-of-type { margin-top: 0; }
.legal-content p { color: var(--ink-dim); margin-bottom: 16px; }
.legal-content p strong { color: var(--ink); font-weight: 600; }
.legal-content ul { margin: 0 0 16px; }
.legal-content li {
  position: relative;
  padding-left: 20px;
  color: var(--ink-dim);
  margin-bottom: 10px;
}
.legal-content li::before {
  content: '';
  position: absolute;
  left: 0; top: 9px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
.legal-content a { color: var(--accent-text); text-decoration: underline; }

.not-found {
  padding: 200px 0 140px;
  text-align: center;
  min-height: 70vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.not-found-inner { max-width: 480px; margin: 0 auto; }
.not-found-mark { width: 64px; height: auto; margin: 0 auto 28px; opacity: 0.85; }
.not-found h1 {
  font-family: var(--ff-display);
  font-size: clamp(2.4rem, 6vw, 3.4rem);
  color: var(--ink);
  margin-bottom: 16px;
}
.not-found p { color: var(--ink-dim); margin-bottom: 32px; }

@media (max-width: 600px) {
  .legal { padding: 130px 0 80px; }
}
