/* ==========================================================================
   Antonin Renard — Graphiste indépendant
   Feuille de style unique.

   Sommaire
   1. Variables (charte)        6. Sections : hero, showcase, problème
   2. Base                     7. Sections : projets, méthode
   3. Structure                8. Sections : offres, à propos, contact
   4. Composants communs      8b. Pages légales (mentions, confidentialité)
   5. En-tête & navigation     9. Pied de page
                               10. Mouvement (apparitions, survols, aimantation)
   ========================================================================== */


/* Inclusive Sans (police variable, licence SIL OFL 1.1) — hébergée avec le site :
   aucune requête vers un service tiers au chargement. */
@font-face {
  font-family: "Inclusive Sans";
  src: url("../assets/fonts/InclusiveSans-Variable.woff") format("woff");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}


/* ==========================================================================
   1. Variables
   ========================================================================== */
:root {
  /* Couleurs de marque (charte : orange #ef781a, beige #fceadb) */
  --orange: #ef781a;
  --beige: #fceadb;

  /* Dérivées de l'orange */
  --orange-deep: #c25d0d;   /* ombre des boutons « 3D » */
  --orange-text: #b8520a;   /* orange lisible en texte sur fond clair */
  --orange-ink: #8f3f05;    /* texte des pastilles teintées orange */
  --orange-brown: #5a2c05;  /* texte posé sur fond orange */

  /* Surfaces */
  --cream: #fff8f1;
  --sand: #fbe0c4;
  --sage: #e6e9d8;
  --backdrop: #ded2c6;      /* fond autour de la page « carte » */

  /* Encre & textes */
  --ink: #1c1614;
  --text: #453b35;
  --muted: #6b5d55;
  --on-dark: #e0d3c7;
  --on-dark-soft: #cbbdb1;
  --on-dark-faint: #8c7d73;

  /* Filets & ombres */
  --line: rgba(28, 22, 20, .22);
  --line-soft: rgba(28, 22, 20, .1);
  --dash: rgba(28, 22, 20, .24);
  --shadow-media: 0 20px 50px rgba(28, 22, 20, .16);

  /* Formes */
  --blob: .16em; /* les 4 coins du surlignage : une seule valeur, relative à la taille du titre */

  --font: "Inclusive Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Mouvement : une seule famille de courbes pour tout le site */
  --ease-out: cubic-bezier(.22, 1, .36, 1);       /* départ vif, arrivée douce : apparitions, survols */
  --ease-spring: cubic-bezier(.34, 1.4, .64, 1);  /* léger rebond : objets « physiques » (post-it) */
  --ease-sweep: cubic-bezier(.45, 0, .2, 1);      /* plus régulière : on voit l'arête du remplissage traverser le bouton */

  /* Ancrages et aimantation du défilement : une section se cale juste sous l'en-tête collant.
     Sa hauteur réelle est mesurée par js/motion.js (--header-h) ; valeur de repli sans JS. */
  --snap-top: calc(var(--header-h, 64px) + 8px);
}


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

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--snap-top); /* les ancres se posent juste sous l'en-tête collant */
  background: var(--beige);
  -webkit-text-size-adjust: 100%;
          text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--beige);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a { color: inherit; text-decoration: none; }
img { max-width: 100%; }
button, input, textarea { font: inherit; }

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

:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
/* Sur fond orange, l'anneau orange serait invisible : on passe à l'encre */
.on-orange :focus-visible { outline-color: var(--ink); }

.link { color: var(--orange-text); }
.link:hover { color: var(--orange); }

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

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

/* Empêche un mot composé de se couper au trait d'union en fin de ligne (ex. « Auto-entreprise » du pied de page) */
.nowrap { white-space: nowrap; }

.skip-link {
  position: fixed;
  top: 12px; left: 12px;
  z-index: 100;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--beige);
  font-weight: 700;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

/* Astérisque de la marque : défini une fois (<symbol id="asterisk">), coloré par currentColor */
.ast { display: block; width: 100%; height: 100%; }


/* ==========================================================================
   3. Structure
   ========================================================================== */
/* Le site occupe toute la largeur de l'écran, sans bande latérale ni marge :
   .page/.frame ne sont plus une « carte » centrée avec un fond visible autour —
   juste un conteneur plein cadre. .frame garde overflow:clip pour empêcher les
   éléments décoratifs (astérisques, grilles) de créer un débordement horizontal,
   sans casser le position:sticky de l'en-tête. */
.page { background: var(--beige); }

.frame {
  background: var(--beige);
  overflow: clip;
}

/* Grille de repérage décorative (sections orange) */
.grid-lines {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(28, 22, 20, .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(28, 22, 20, .07) 1px, transparent 1px);
  background-size: 56px 56px;
}

/* Astérisque décoratif qui tourne lentement */
.spinner {
  position: absolute;
  pointer-events: none;
  animation: spinSlow 80s linear infinite;
}


/* ==========================================================================
   4. Composants communs
   ========================================================================== */

/* — Boutons — */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid transparent;
  border-radius: 999px;
  font-family: inherit;
  font-weight: 700;
  line-height: normal;
  text-align: center;
  cursor: pointer;
  /* Au survol, une couleur « coule » dans le bouton en diagonale : chaque variante déclare la sienne (--sweep) */
  --sweep: transparent;
  background-image: linear-gradient(100deg, var(--sweep) 50%, transparent 50%);
  background-repeat: no-repeat;
  background-origin: border-box;
  background-size: 260% 100%;
  background-position: 100% 0;
  transition:
    background-position .5s var(--ease-sweep),
    color .3s var(--ease-out) .06s,
    border-color .2s var(--ease-out),
    box-shadow .22s var(--ease-out),
    transform .22s var(--ease-out);
}
.btn:not(:disabled):hover { background-position: 0 0; }

/* tailles (le padding inclut le liseré de 1,5 px) */
.btn--sm { padding: 10.5px 18.5px; font-size: 15px; }
.btn--md { padding: 12.5px 26.5px; font-size: 16.5px; }
.btn--lg { padding: 15px 30px; font-size: 17px; }

/* variantes : couleur de fond, et couleur qui « coule » au survol (--sweep) */
.btn--dark { background-color: var(--ink); --sweep: var(--orange); color: var(--beige); }
.btn--dark:hover { color: var(--cream); }

.btn--outline { --sweep: var(--cream); border-color: var(--line); color: var(--ink); }
.btn--sm.btn--outline { padding: 11px 18px; }
.btn--outline:hover { border-color: var(--ink); }

.btn--cream { background-color: var(--cream); --sweep: var(--sand); border-color: rgba(28, 22, 20, .2); color: var(--ink); }
.btn--cream:hover { border-color: var(--ink); }

/* Gros bouton orange « 3D » (hero) : libellé + sous-libellé */
.btn--cta {
  flex-direction: column;
  padding: 13.5px 30.5px;
  background-color: var(--orange);
  --sweep: var(--ink);
  color: var(--cream);
  font-size: 18px;
  line-height: 1.2;
  box-shadow: 0 8px 0 var(--orange-deep);
}
.btn--cta small { margin-top: 2px; font-size: 13px; font-weight: 400; opacity: .88; }
.btn--cta:hover { box-shadow: 0 8px 0 #000; }
.btn--cta:active { transform: translateY(4px); box-shadow: 0 4px 0 #000; }

/* — Pastilles de rubrique (kickers) — */
.kicker {
  display: inline-block;
  padding: 6px 15px;
  border-radius: 999px;
  background: rgba(239, 120, 26, .16);
  color: var(--orange-ink);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.kicker--dark { background: var(--ink); color: var(--beige); }
.kicker--orange { background: rgba(239, 120, 26, .2); color: var(--orange); }

/* — Titres de section — */
.section-head { max-width: 940px; margin: 0 auto; text-align: center; }

.display {
  margin-top: clamp(18px, 2.4vw, 30px);
  font-size: clamp(40px, 7.4vw, 96px);
  line-height: .95;
  font-weight: 700;
  letter-spacing: -.045em;
  text-transform: uppercase;
}

.section-lead {
  margin: clamp(24px, 3vw, 36px) auto 0;
  font-size: clamp(16.5px, 1.5vw, 19px);
  line-height: 1.65;
}

/* — Surlignage penché (motif signature) — */
.hl {
  display: inline-block;
  margin-top: .08em;
  padding: .02em .26em .08em;
  border-radius: var(--blob);
  transform: rotate(-1.4deg);
}
.hl--orange { background: var(--orange); color: var(--cream); }
.hl--orange-ink { background: var(--orange); color: var(--ink); }
.hl--beige { background: var(--beige); color: var(--ink); }

/* — Mot mis en couleur dans un titre — */
.accent { color: var(--orange); }

/* — Étiquettes (tags) — */
.tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.tags li {
  padding: 7px 15px;
  border-radius: 999px;
  background: var(--cream);
  border: 1px solid rgba(28, 22, 20, .14);
  font-size: 14px;
  color: var(--text);
}


/* ==========================================================================
   5. En-tête & navigation
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  padding: clamp(12px, 1.6vw, 20px) clamp(12px, 2.4vw, 28px);
  background: rgba(252, 234, 219, .9);
  -webkit-backdrop-filter: blur(16px);
          backdrop-filter: blur(16px);
}

.nav {
  position: relative;
  max-width: 1300px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 20px;
  padding: 9px 10px 9px 14px;
  border: 1.5px dashed var(--dash);
  border-radius: 999px;
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: 11px;
  flex-shrink: 0;
  color: var(--ink);
}
.nav__mark { width: 30px; height: 30px; flex-shrink: 0; color: var(--orange); }
.nav__name { font-weight: 700; font-size: 17.5px; letter-spacing: -.015em; }

.nav__menu {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 20px;
}

.nav__links {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px clamp(10px, 1.6vw, 26px);
  font-size: 15.5px;
}
.nav__links a { display: block; padding: 6px 4px; color: var(--ink); transition: color .18s; }
.nav__links a:hover { color: var(--orange-text); }

.nav__actions { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }

/* Bouton du menu mobile (masqué sur grand écran) */
.nav__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  padding: 0;
  border: 1.5px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color .18s, border-color .18s;
}
.nav__toggle:hover { border-color: var(--ink); background: var(--cream); }
.nav__toggle svg { width: 20px; height: 20px; overflow: visible; }
.nav__toggle line { stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; transform-origin: 12px 12px; transition: transform .22s, opacity .18s; }
.nav__toggle[aria-expanded="true"] .bar-top { transform: translateY(6px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .bar-mid { opacity: 0; }
.nav__toggle[aria-expanded="true"] .bar-bot { transform: translateY(-6px) rotate(-45deg); }

/* Menu mobile : actif seulement si le JS est chargé (sinon la barre reste visible et s'enroule) */
@media (max-width: 899.98px) {
  .js .nav { flex-wrap: nowrap; }
  .js .nav__toggle { display: inline-flex; }

  .js .nav__menu {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    left: 0; right: 0;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 10px;
    padding: 12px;
    border: 1.5px dashed var(--dash);
    border-radius: 28px;
    background: var(--cream);
    box-shadow: 0 24px 48px rgba(28, 22, 20, .18);
  }
  .js .nav__menu.is-open { display: flex; animation: riseIn .22s ease-out both; }

  .js .nav__links { flex-direction: column; align-items: stretch; gap: 2px; font-size: 18px; }
  .js .nav__links a { padding: 12px 16px; border-radius: 16px; }
  .js .nav__links a:hover { background: var(--beige); }

  .js .nav__actions { flex-direction: column; align-items: stretch; }
  .js .nav__actions .btn { padding-top: 14px; padding-bottom: 14px; font-size: 16.5px; }
}


/* ==========================================================================
   6. Sections : hero, showcase, problème
   ========================================================================== */

/* — Hero — */
.hero {
  position: relative;
  padding: clamp(52px, 8vw, 132px) clamp(20px, 5vw, 56px) clamp(40px, 5vw, 72px);
  text-align: center;
  overflow: hidden;
}

.hero__grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(28, 22, 20, .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(28, 22, 20, .05) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(90% 60% at 50% 22%, #000 0%, transparent 78%);
          mask-image: radial-gradient(90% 60% at 50% 22%, #000 0%, transparent 78%);
}

.hero__ast--left {
  left: clamp(-40px, 2vw, 60px);
  top: clamp(120px, 18vw, 220px);
  width: clamp(52px, 7vw, 104px);
  height: clamp(52px, 7vw, 104px);
  opacity: .22;
  color: var(--orange);
  animation-duration: 80s;
}
.hero__ast--right {
  right: clamp(-30px, 3vw, 80px);
  top: clamp(210px, 24vw, 300px);
  width: clamp(34px, 4.4vw, 64px);
  height: clamp(34px, 4.4vw, 64px);
  opacity: .3;
  color: var(--ink);
  animation-duration: 50s;
  animation-direction: reverse;
}

.hero__inner { position: relative; max-width: 1000px; margin: 0 auto; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 16px 6px 8px;
  border-radius: 999px;
  background: var(--cream);
  border: 1px solid rgba(239, 120, 26, .4);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--orange-text);
  animation: riseIn .5s ease-out both;
}
.badge__mark { width: 20px; height: 20px; flex-shrink: 0; color: var(--orange); }

.hero__title {
  margin-top: clamp(18px, 2.4vw, 30px);
  font-size: clamp(38px, 6.6vw, 86px);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -.04em;
  text-transform: uppercase;
  animation: riseIn .6s .06s ease-out both;
}
.hero__title .hl { margin-top: .1em; padding: .04em .3em .1em; }

/* Le line-height de .display (.95) est pensé pour du texte seul ; avec le surlignage orange sur
   sa propre ligne juste en dessous, « zéro » touchait presque « mauvaise surprise. ». Écart calé
   sur celui, déjà propre, du hero (« … impression / deux fois. ») : ~-6px de chevauchement des
   boîtes de texte, imperceptible à l'oeil une fois les fonds de surlignage en place. */
#methode-title { line-height: 1.15; }

/* « mauvaise surprise. » : un <br> dans le HTML garde « zéro » sur sa propre ligne (blanche,
   au-dessus). En inline-block (comme les autres surlignages), la boîte du surlignage aurait pris
   toute la largeur du titre dès qu'elle doit revenir à la ligne — même sur des mots courts —
   d'où un grand vide de chaque côté si le texte wrappait. En inline + box-decoration-break: clone,
   le fond épouse chaque ligne de texte séparément, comme un vrai coup de surligneur ; ça reste le
   filet de sécurité sur petit écran (2 lignes, wrap naturel, plus de vide).
   À partir du format ordinateur (≥ 900px, le même seuil que le menu), « mauvaise surprise. » tient
   sur une seule ligne : le titre peut alors déborder légèrement de la colonne de 940px du bloc de
   section (~20px de chaque côté au plus large), sans risque de rognage — rien ne clippe ici.
   display:inline n'est nécessaire QUE tant qu'un wrap sur 2 lignes reste possible (< 900px) : Safari
   n'applique pas fiablement clip-path (utilisé par l'animation « wipe » au scroll, plus bas dans ce
   fichier) sur un élément inline, ce qui coupait l'animation sur ce titre alors que tous les autres
   surlignages (restés en inline-block) l'ont. À partir de 900px, une seule ligne garantie par
   white-space:nowrap rend box-decoration-break sans objet (rien à fragmenter) : repasser en
   inline-block à ce seuil ne change rien au rendu et refait fonctionner l'animation partout. */
.method .hl {
  display: inline;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
@media (min-width: 900px) {
  .method .hl { display: inline-block; white-space: nowrap; }
}

.hero__lead {
  max-width: 52ch;
  margin: clamp(24px, 3vw, 38px) auto 0;
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.6;
  color: var(--text);
  animation: riseIn .6s .14s ease-out both;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: clamp(28px, 3.4vw, 44px);
  animation: riseIn .6s .22s ease-out both;
}

.trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px clamp(20px, 3vw, 40px);
  margin-top: clamp(40px, 5vw, 70px);
  animation: riseIn .6s .3s ease-out both;
}
.trust__label { font-size: 13.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.trust__name { font-size: clamp(17px, 1.8vw, 22px); font-weight: 700; letter-spacing: -.02em; color: var(--text); }

/* — Showcase : logo animé — */
.showcase { padding: 0 clamp(16px, 4vw, 56px) clamp(56px, 7vw, 110px); }

/* perspective : donne de la profondeur à l'inclinaison de .showcase__media au survol (motion.js) */
.showcase__frame { position: relative; max-width: 1120px; margin: 0 auto; perspective:3000px; }

/* Le fond reprend la 1re image du GIF : rien de vide pendant le chargement */
.media {
  position: relative;
  overflow: hidden;
  background: #1636d8 center / cover no-repeat;
}
.media .cover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.media--logo { background-image: url("../assets/img/clean-inspector-logo-poster.jpg"); }

/* Le halo orange entoure l'image elle-même (la légende peut ainsi passer dessous sur mobile) —
   il respire en continu (voir @keyframes showcaseGlow) : la pièce maîtresse de la page reste
   vivante même sans interaction. Au survol (souris fine), motion.js incline la carte pour suivre
   le curseur ; « perspective » vient du parent .showcase__frame, will-change prépare la couche
   composée pour que l'inclinaison reste fluide. */
.showcase__media {
  aspect-ratio: 16 / 9;
  border-radius: clamp(20px, 2.6vw, 32px);
  will-change: transform;
  animation: showcaseGlow 4.5s ease-in-out infinite;
}

@keyframes showcaseGlow {
  0%, 100% {
    box-shadow:
      0 0 0 1px rgba(239, 120, 26, .25),
      0 10px 40px rgba(239, 120, 26, .42),
      0 26px 90px rgba(239, 120, 26, .32);
  }
  50% {
    box-shadow:
      0 0 0 1px rgba(239, 120, 26, .4),
      0 16px 56px rgba(239, 120, 26, .6),
      0 38px 130px rgba(239, 120, 26, .48);
  }
}

.showcase__caption {
  position: absolute;
  left: clamp(12px, 2.2vw, 30px);
  bottom: clamp(12px, 2.2vw, 30px);
  padding: clamp(12px, 1.4vw, 18px) clamp(20px, 2.4vw, 30px);
  border-radius: clamp(18px, 2.2vw, 26px);
  background: var(--beige);
  box-shadow: 0 16px 40px rgba(28, 22, 20, .34);
}
.showcase__caption strong {
  display: block;
  margin-bottom: 2px;
  font-size: clamp(16px, 1.6vw, 21px);
  letter-spacing: -.02em;
  color: var(--ink);
}
.showcase__caption span { font-size: clamp(13.5px, 1.2vw, 15.5px); line-height: 1.4; color: var(--text); }

/* Petit écran : la légende recouvrirait la moitié du logo, on la place sous l'image */
@media (max-width: 600px) {
  /* Sur petit écran, toute la légende (titre + description) est retirée à la demande
     d'Antonin : le nom du logo animé se voit déjà à l'écran, et la fiche du projet plus
     bas sur la page reprend cette même information. Le nom reste néanmoins accessible
     aux lecteurs d'écran via l'aria-label posé sur la vidéo elle-même. */
  .showcase__caption { display: none; }
}

/* — Problème — */
.problem {
  position: relative;
  padding: clamp(60px, 8vw, 130px) clamp(20px, 5vw, 56px) clamp(70px, 9vw, 150px);
  background: var(--orange);
  overflow: hidden;
}
.problem__inner { position: relative; max-width: 1120px; margin: 0 auto; }
.problem .display { color: var(--ink); }
.problem .section-lead { max-width: 42ch; color: var(--orange-brown); }

.problem__cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: clamp(20px, 3vw, 34px);
  margin-top: clamp(44px, 6vw, 86px);
}

.note {
  position: relative;
  padding: clamp(26px, 2.6vw, 34px) clamp(24px, 2.4vw, 30px) clamp(28px, 2.8vw, 36px);
  border-radius: 6px;
  background: var(--cream);
  box-shadow: 0 14px 30px rgba(92, 42, 4, .22);
  transform: rotate(-2deg);
}
.note:nth-child(2) { background: var(--sand); transform: rotate(1.6deg); margin-top: clamp(0px, 2vw, 26px); }
.note:nth-child(3) { background: var(--sage); transform: rotate(-1.2deg); }

.note__num {
  position: absolute;
  top: -11px; left: 24px;
  padding: 3px 12px;
  border-radius: 4px;
  background: var(--ink);
  color: var(--beige);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.note h3 { margin: 8px 0 12px; font-size: 21px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
.note p { font-size: 15.5px; line-height: 1.65; color: var(--text); }

.problem__outro {
  max-width: 34ch;
  margin: clamp(44px, 5vw, 72px) auto 0;
  text-align: center;
  font-size: clamp(19px, 2.2vw, 26px);
  line-height: 1.35;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--ink);
}
.problem__cta { display: flex; justify-content: center; margin-top: 26px; }
.problem__cta .btn--dark { --sweep: var(--cream); }
.problem__cta .btn--dark:hover { color: var(--ink); }


/* ==========================================================================
   7. Sections : projets, méthode
   ========================================================================== */

/* — Projets — */
.projects { padding: clamp(60px, 8vw, 140px) clamp(20px, 5vw, 56px); }
.projects__inner { max-width: 1200px; margin: 0 auto; }

.projects__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px 32px;
}
.projects__intro { flex: 1 1 400px; }
.projects__title {
  max-width: 18ch;
  margin-top: 20px;
  font-size: clamp(30px, 4.6vw, 58px);
  line-height: 1.04;
  font-weight: 700;
  letter-spacing: -.035em;
  text-transform: uppercase;
}
.projects__more { flex-shrink: 0; padding: 13px 24px; font-size: 16px; }
.projects__more:hover { border-color: var(--orange); color: var(--orange-text); }

.project {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(24px, 4vw, 64px);
  align-items: center;
  margin-top: clamp(48px, 7vw, 110px);
}
.projects__head + .project { margin-top: clamp(48px, 6vw, 96px); }
.project__text, .project__media { min-width: 0; }
.project--flip .project__text { order: 2; }
.project--flip .project__media { order: 1; }
/* En dessous de ~700px (mesuré : la grille auto-fit empile les colonnes entre 680 et 700px),
   l'inversion desktop de Quad Life plaçait son image avant son texte, contrairement aux 2 autres
   projets : on annule l'ordre pour retrouver la même lecture texte -> image partout. */
@media (max-width: 699.98px) {
  .project--flip .project__text, .project--flip .project__media { order: 0; }
}

.project__meta { font-size: 14px; font-weight: 700; letter-spacing: .12em; color: var(--orange-text); }
.project__title {
  margin-top: 14px;
  font-size: clamp(28px, 3.4vw, 44px);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.03;
}
.project__desc { max-width: 46ch; margin-top: 18px; font-size: 17px; line-height: 1.65; color: var(--text); }
.project__cta { margin-top: 28px; padding: 12px 22px; font-size: 15.5px; }

.project__media {
  position: relative;
  overflow: hidden;
  border-radius: clamp(20px, 2.6vw, 34px);
  box-shadow: var(--shadow-media);
}
/* Ratio aligné sur celui, natif, de la vidéo (1920×1080) : un cadre 4/3 forçait un zoom qui
   rognait le texte « Clean inspector » sur les bords, comme au showcase et pour Quad Life. */
.project__media--ci { aspect-ratio: 16 / 9; }
.project__media--quad { aspect-ratio: 16 / 9; background-color: #f5ece0; }
.project__media--quad .cover { object-position: center top; }
.project__media--ofqj { aspect-ratio: 4 / 3; background-color: #26307a; }
.project__media--ofqj .cover { object-position: top center; }

.project__chip {
  position: absolute;
  left: 16px; top: 16px;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(252, 234, 219, .94);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
}
/* — Méthode — */
.method {
  position: relative;
  padding: clamp(60px, 8vw, 140px) clamp(20px, 5vw, 56px);
  background: var(--ink);
  color: var(--beige);
  overflow: hidden;
}
.method__bg {
  right: clamp(-60px, -2vw, 0px);
  bottom: clamp(-70px, -3vw, 0px);
  width: clamp(180px, 26vw, 400px);
  height: clamp(180px, 26vw, 400px);
  opacity: .09;
  color: var(--orange);
  animation-duration: 85s;
}
.method__inner { position: relative; max-width: 1200px; margin: 0 auto; }
.method .section-lead { max-width: 44ch; color: var(--on-dark-soft); }

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: clamp(10px, 1.4vw, 20px);
  margin-top: clamp(44px, 5.5vw, 84px);
}
.step {
  padding: clamp(16px, 1.8vw, 28px);
  border-radius: 22px;
  background: rgba(252, 234, 219, .05);
  border: 1px solid rgba(252, 234, 219, .14);
}
.step__num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(38px, 3.4vw, 48px);
  height: clamp(38px, 3.4vw, 48px);
  border-radius: 999px;
  border: 1.5px solid rgba(252, 234, 219, .32);
  color: var(--beige);
  font-size: clamp(16px, 1.5vw, 20px);
  font-weight: 700;
}
.step h3 {
  margin: clamp(14px, 1.6vw, 20px) 0 8px;
  font-size: clamp(15.5px, 1.5vw, 20px);
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: 1.15;
}
.step p { font-size: clamp(13px, 1.15vw, 15.5px); line-height: 1.6; color: var(--on-dark-soft); }

/* Première étape mise en avant */
.step:first-child { background: rgba(239, 120, 26, .12); border-color: rgba(239, 120, 26, .35); }
.step:first-child .step__num { background: var(--orange); border-color: var(--orange); color: var(--ink); }


/* ==========================================================================
   8. Sections : offres, à propos, contact
   ========================================================================== */

/* — Offres — */
.pricing { padding: clamp(60px, 8vw, 140px) clamp(20px, 5vw, 56px); }
.pricing__inner { max-width: 1200px; margin: 0 auto; }
.pricing .display { font-size: clamp(42px, 8vw, 104px); }
.pricing .hl { margin-top: 0; }
.pricing .section-lead { max-width: 44ch; color: var(--text); }

.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 258px), 1fr));
  gap: clamp(18px, 2.2vw, 28px);
  margin-top: clamp(48px, 6vw, 90px);
  align-items: center;
}

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(26px, 2.8vw, 36px);
  border-radius: 28px;
  background: var(--cream);
  border: 1px solid var(--line-soft);
}
.plan__name { font-size: 12.5px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--muted); }
.plan__price { display: flex; align-items: baseline; gap: 6px; margin: 14px 0 20px; }
.plan__amount { font-size: clamp(36px, 4vw, 48px); font-weight: 700; letter-spacing: -.04em; line-height: 1; }
.plan__currency { font-size: 22px; font-weight: 700; color: var(--orange); }

.plan__features {
  flex: 1;
  display: grid;
  gap: 12px;
  padding-top: 22px;
  border-top: 1px solid var(--line-soft);
  font-size: 16px;
  color: var(--text);
}
.plan__features li { display: flex; gap: 10px; }
.plan__features li::before { content: "✓"; color: var(--orange); font-weight: 700; }

.plan .btn { margin-top: 28px; font-size: 16px; }
.plan .btn--outline { padding: 13px 22px; }
.plan .btn--outline { --sweep: var(--ink); }
.plan .btn--outline:hover { color: var(--beige); border-color: var(--ink); }

/* Offre mise en avant */
.plan--featured {
  padding: clamp(30px, 3.2vw, 42px) clamp(26px, 2.8vw, 36px);
  border-radius: 32px;
  background: var(--ink);
  border: 0;
  color: var(--beige);
  box-shadow: 0 26px 54px rgba(28, 22, 20, .28);
}
.plan--featured .plan__name { color: var(--orange); }
.plan--featured .plan__amount { font-size: clamp(40px, 4.6vw, 56px); }
.plan--featured .plan__currency { font-size: 24px; }
.plan--featured .plan__features { border-top-color: rgba(252, 234, 219, .18); color: var(--on-dark); }
.plan--featured .btn {
  padding: 13.5px 20.5px;
  background-color: var(--orange);
  --sweep: var(--beige);
  color: var(--ink);
  font-size: 17px;
  box-shadow: 0 6px 0 var(--orange-deep);
}
.plan--featured .btn:active { transform: translateY(3px); box-shadow: 0 3px 0 var(--orange-deep); }

.plan__badge {
  position: absolute;
  top: -14px; left: 50%;
  transform: translateX(-50%);
  padding: 6px 16px;
  border-radius: 999px;
  background: var(--orange);
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Supports print */
.print {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(20px, 3vw, 44px);
  margin-top: clamp(28px, 3.4vw, 44px);
  padding: clamp(26px, 3vw, 40px);
  border-radius: 28px;
  border: 1.5px dashed rgba(28, 22, 20, .26);
}
.print__intro { flex: 1 1 220px; min-width: 0; }
.print__intro h3 { font-size: clamp(20px, 2.2vw, 26px); font-weight: 700; letter-spacing: -.025em; text-transform: uppercase; }
.print__intro p { margin-top: 8px; font-size: 15.5px; color: var(--muted); }
.print__list {
  flex: 2 1 420px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
  gap: 10px;
}
.print__list li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 14px 18px;
  border-radius: 18px;
  background: var(--cream);
}
.print__list span:first-child { font-size: 16px; color: var(--text); }
.print__list strong { font-size: 19px; font-weight: 700; letter-spacing: -.02em; white-space: nowrap; }
.print__list .on-quote { font-size: 15.5px; color: var(--muted); letter-spacing: 0; }

/* — À propos — */
.about { padding: clamp(60px, 8vw, 140px) clamp(20px, 5vw, 56px); background: var(--cream); }
.about__inner {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr));
  gap: clamp(32px, 5vw, 80px);
  align-items: center;
}
.about__inner > * { min-width: 0; }

/* La figure a la même largeur max que la photo : l'astérisque (.about__spin) s'accroche ainsi au
   coin de la photo, et non au bord de la colonne de la grille, plus large sur ordinateur. */
.about__photo { position: relative; max-width: 440px; }
.about__frame {
  position: relative;
  aspect-ratio: 3 / 4;                /* format natif de la photo : rien n'est rogné */
  border-radius: clamp(24px, 3vw, 40px);
  overflow: hidden;
  background-color: #c95a22;          /* orange du fond de la photo : pas de flash clair avant son chargement différé */
}
.about__frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.about__spin {
  right: clamp(-10px, 2vw, 40px);
  bottom: -18px;
  width: clamp(62px, 8vw, 104px);
  height: clamp(62px, 8vw, 104px);
  color: var(--orange);
  animation-duration: 70s;
}

.about__title {
  margin-top: 22px;
  font-size: clamp(28px, 4vw, 50px);
  line-height: 1.04;
  font-weight: 700;
  letter-spacing: -.035em;
  text-transform: uppercase;
}
.about__text { max-width: 46ch; margin-top: 24px; font-size: 17.5px; line-height: 1.7; color: var(--text); }
.about__text + .about__text { margin-top: 16px; }
.about__actions { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 32px; }
.about__actions .btn { font-size: 16.5px; }
.about__actions .btn--dark { padding: 12.5px 24.5px; }
.about__actions .btn--outline { padding: 14px 26px; }
.about__actions .btn--outline { --sweep: transparent; }
.about__actions .btn--outline:hover { border-color: var(--orange); color: var(--orange-text); }

/* — Contact — */
.contact { padding: clamp(40px, 5vw, 80px) clamp(20px, 5vw, 56px) clamp(60px, 7vw, 110px); }
.contact__panel {
  position: relative;
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(34px, 5vw, 80px) clamp(24px, 4vw, 64px);
  border-radius: clamp(26px, 3vw, 44px);
  background: var(--orange);
  overflow: hidden;
}
.contact__spin {
  right: -70px; top: -70px;
  width: clamp(180px, 26vw, 320px);
  height: clamp(180px, 26vw, 320px);
  opacity: .2;
  color: var(--cream);
  animation-duration: 70s;
}
.contact__grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(30px, 4vw, 64px);
  align-items: center;
}
.contact__grid > * { min-width: 0; }

.contact__title {
  max-width: 15ch;
  font-size: clamp(30px, 4.8vw, 62px);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -.04em;
  text-transform: uppercase;
  color: var(--ink);
}
.contact__lead { max-width: 42ch; margin-top: 24px; font-size: clamp(16.5px, 1.6vw, 19px); line-height: 1.6; color: var(--orange-brown); }

.contact__cta {
  flex-direction: column;
  margin-top: 32px;
  padding: 15.5px 34.5px;
  align-items: stretch;
  text-align: left;
  font-size: 19px;
  line-height: 1.2;
  box-shadow: 0 8px 0 rgba(0, 0, 0, .35);
}
.contact__cta small { margin-top: 3px; font-size: 13px; font-weight: 400; opacity: .85; }
.contact__cta { --sweep: var(--cream); }
.contact__cta:hover { color: var(--ink); }
.contact__cta:active { transform: translateY(4px); box-shadow: 0 4px 0 rgba(0, 0, 0, .35); }

.form-card {
  padding: clamp(24px, 3vw, 38px);
  border-radius: clamp(22px, 2.6vw, 32px);
  background: var(--beige);
  box-shadow: 0 20px 44px rgba(92, 42, 4, .24);
}
.form-card h3 { margin-bottom: 20px; font-size: 19px; font-weight: 700; letter-spacing: -.02em; }
.form { display: grid; gap: 14px; }
.field { display: grid; gap: 7px; font-size: 14.5px; font-weight: 700; }
/* Piège à robots (anti-spam) : contrairement à .sr-only, doit rester invisible des lecteurs
   d'écran aussi (aria-hidden + tabindex="-1" sur le champ, cf. HTML) — un vrai visiteur ne doit
   jamais savoir que ce champ existe. */
.field--trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.field input, .field textarea {
  width: 100%;
  padding: 13px 18px;
  border: 1.5px solid rgba(28, 22, 20, .2);
  border-radius: 999px;
  background: var(--cream);
  color: var(--ink);
  font-size: 16px;
  font-weight: 400;
  transition: border-color .2s var(--ease-out), background-color .25s var(--ease-out);
}
.field textarea { padding: 14px 18px; border-radius: 22px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: #8c7d73; }
.field input:hover, .field textarea:hover { border-color: rgba(28, 22, 20, .4); }
.field input:focus-visible, .field textarea:focus-visible { border-color: var(--orange); background-color: #fff; outline-offset: 2px; }

.form .btn { margin-top: 4px; padding: 13.5px 24.5px; font-size: 17px; }
.form .btn:disabled { opacity: .6; cursor: progress; }
.form__status { min-height: 0; margin-top: 14px; font-size: 14.5px; line-height: 1.5; color: var(--text); }
.form__status:empty { display: none; }
.form__status[data-state="success"] { font-weight: 700; color: #2f6b2c; }
.form__status[data-state="error"] { font-weight: 700; color: #a3200f; }
.form-card__direct { margin-top: 18px; font-size: 14.5px; color: var(--muted); }


/* ==========================================================================
   8b. Pages légales (mentions, confidentialité)
   Pages secondaires, sans les animations du site principal (motion.js n'y est
   pas chargé) : juste le header/footer partagés autour d'un contenu texte.
   ========================================================================== */
.legal { padding: clamp(48px, 7vw, 96px) clamp(20px, 5vw, 56px) clamp(80px, 9vw, 130px); }
.legal__inner { max-width: 760px; margin: 0 auto; }
.legal__title {
  margin-top: clamp(14px, 2vw, 20px);
  font-size: clamp(34px, 5.4vw, 58px);
  line-height: 1.05;
  font-weight: 700;
  letter-spacing: -.03em;
  text-transform: uppercase;
}
.legal__updated { margin-top: 12px; font-size: 14.5px; color: var(--muted); }

.legal__body { margin-top: clamp(36px, 5vw, 52px); }
.legal__body h2 {
  margin-top: clamp(30px, 4vw, 46px);
  font-size: clamp(19px, 2.2vw, 24px);
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--ink);
}
.legal__body h2:first-child { margin-top: 0; }
.legal__body p { margin-top: 12px; font-size: 16.5px; line-height: 1.7; color: var(--text); }
.legal__body ul { margin-top: 12px; padding-left: 22px; list-style: disc; font-size: 16.5px; line-height: 1.7; color: var(--text); }
.legal__body li + li { margin-top: 4px; }
.legal__body a { color: var(--orange-text); text-decoration: underline; text-underline-offset: 3px; }
.legal__body a:hover { color: var(--orange); }
.legal__body strong { font-weight: 700; color: var(--ink); }


/* ==========================================================================
   9. Pied de page
   ========================================================================== */
.site-footer {
  padding: clamp(44px, 5vw, 72px) clamp(20px, 5vw, 56px) 0;
  background: var(--ink);
  color: var(--beige);
  overflow: hidden;
}
.footer__cols {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 32px 48px;
  align-items: flex-start;
}
.footer__brand { flex: 1 1 280px; min-width: 0; }
.footer__logo { display: flex; align-items: center; gap: 11px; font-weight: 700; font-size: 17.5px; }
.footer__logo .nav__mark { display: flex; align-items: center; justify-content: center; }
.footer__blurb { max-width: 32ch; margin-top: 16px; font-size: 15.5px; line-height: 1.65; color: #a3948a; }

.footer__col { flex: 0 1 auto; display: grid; gap: 10px; font-size: 15.5px; }
.footer__heading {
  margin-bottom: 4px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--on-dark-faint);
}
.footer__col a { color: var(--on-dark); transition: color .18s; }
.footer__col a:hover { color: var(--orange); }

.footer__legal {
  max-width: 1200px;
  margin: clamp(36px, 4vw, 56px) auto 0;
  padding-top: 20px;
  border-top: 1px solid rgba(252, 234, 219, .14);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  justify-content: space-between;
  font-size: 13.5px;
  color: var(--on-dark-faint);
}

.footer__wordmark {
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(20px, 3vw, 40px) 0 .12em;
  font-size: clamp(52px, 14.5vw, 224px);
  line-height: .82;
  font-weight: 700;
  letter-spacing: -.05em;
  text-transform: uppercase;
  text-align: center;
  color: #2a221e;
  white-space: nowrap;
  overflow-x: clip;
  user-select: none;
}


/* ==========================================================================
   10. Mouvement
   Règle du site : un mouvement sert soit à GUIDER (où regarder, où l'on est),
   soit à RÉPONDRE (ce que l'on pointe, ce qui est cliquable). Jamais à décorer seul.

   Langage de survol, le même partout : ce que l'on pointe « se réveille » —
   accent orange (encre ou crème sur les fonds orange), petit relief, léger rebond.

   Répartition des propriétés, pour que les effets ne se marchent pas dessus :
     opacity + translate  → apparition au défilement (une seule fois)
     transform            → survols
     translate / rotate   → parallaxe et effets pilotés par js/motion.js
   Tout est coupé pour les visiteurs qui demandent moins d'animations (fin du fichier).
   ========================================================================== */
@keyframes spinSlow { to { transform: rotate(360deg); } }
@keyframes riseIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fadeUp { from { opacity: 0; translate: 0 6px; } }


/* — 10.1 Apparition au défilement —
   Les éléments à révéler portent data-reveal. Ils ne sont masqués que si le JS a démarré
   (html.reveal-on) et seulement s'ils sont sous la ligne de flottaison : sans JS, ou en
   mouvement réduit, tout est visible d'emblée. Seul « opacity » est masqué (pas de translate) :
   la position de l'élément ne change donc pas avant son apparition. */
@keyframes reveal      { from { opacity: 0; translate: var(--rx, 0px) 40px; } }
@keyframes revealNote  { from { opacity: 0; translate: 0 64px; rotate: 8deg; } }
@keyframes revealMedia { from { opacity: 0; translate: var(--rx, 0px) 48px; scale: .94; } }
@keyframes revealStage { from { opacity: 0; translate: 0 72px; scale: .9; } }
@keyframes revealBase  { from { translate: 0 45%; } }

/* Côté d'où arrive un élément : celui où il se trouve dans la mise en page (sur mobile, tout arrive du bas) */
[data-side="left"]  { --rx: -84px; }
[data-side="right"] { --rx: 84px; }
@media (max-width: 899.98px) { [data-side] { --rx: 0px; } }

.reveal-on [data-reveal]:not(.is-visible) { opacity: 0; }
.reveal-on [data-reveal].is-visible {
  /* « backwards » : rien ne reste appliqué après l'animation, les survols reprennent la main */
  animation: reveal .85s var(--ease-out) var(--d, 0s) backwards;
}

/* variantes */
.reveal-on [data-reveal="note"].is-visible {        /* les post-it se posent, avec un petit rebond */
  animation-name: revealNote;
  animation-duration: 1.05s;
  animation-timing-function: var(--ease-spring);
}
.reveal-on [data-reveal="media"].is-visible {       /* les grands visuels prennent leur place */
  animation-name: revealMedia;
  animation-duration: 1.05s;
}
.reveal-on [data-reveal="stage"].is-visible {       /* le logo animé : entrée plus appuyée, c'est la pièce maîtresse */
  animation-name: revealStage;
  animation-duration: 1.2s;
}
.reveal-on [data-reveal="wordmark"]:not(.is-visible) { opacity: 1; translate: 0 45%; }
.reveal-on [data-reveal="wordmark"].is-visible {    /* le grand nom du pied de page remonte depuis le bord */
  animation: revealBase 1.1s var(--ease-out) backwards;
}


/* — 10.2 Surlignage « marqueur » —
   Le bloc coloré des mots clés se trace de gauche à droite : l'œil est attiré sur la
   promesse au moment précis où le titre apparaît. */
@keyframes wipe {
  from { clip-path: inset(0 100% 0 0 round var(--blob)); }
  to   { clip-path: inset(0 0 0 0 round var(--blob)); }
}
.hero__title .hl { animation: wipe .9s var(--ease-out) .55s backwards; }
.reveal-on [data-reveal].is-visible .hl {
  animation: wipe .9s var(--ease-out) calc(var(--d, 0s) + .3s) backwards;
}


/* — 10.3 Profondeur —
   Positions pilotées par js/motion.js : astérisques décoratifs qui dérivent avec le défilement,
   et boutons « Réserver mon appel » légèrement attirés par le curseur.
   (Pas de will-change sur les boutons : une couche permanente n'apporte rien et peut adoucir le texte.) */
.js [data-parallax] { will-change: translate; }

/* Grille « lampe torche » : sous le curseur, les traits de la grille de fond s'allument. */
.glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background-image:
    radial-gradient(circle 220px at var(--gx, 50%) var(--gy, 50%), var(--glow-halo), transparent),
    linear-gradient(var(--glow-line) 1.5px, transparent 1.5px),
    linear-gradient(90deg, var(--glow-line) 1.5px, transparent 1.5px);
  background-size: 100% 100%, var(--glow-size) var(--glow-size), var(--glow-size) var(--glow-size);
  -webkit-mask-image: radial-gradient(circle 260px at var(--gx, 50%) var(--gy, 50%), #000 0%, transparent 100%);
          mask-image: radial-gradient(circle 260px at var(--gx, 50%) var(--gy, 50%), #000 0%, transparent 100%);
  transition: opacity .5s ease;
}
.glow.is-on { opacity: 1; }
.hero .glow { --glow-line: rgba(239, 120, 26, .8); --glow-halo: rgba(239, 120, 26, .13); --glow-size: 64px; }
.on-orange .glow { --glow-line: rgba(255, 248, 241, .7); --glow-halo: rgba(255, 248, 241, .14); --glow-size: 56px; }


/* — 10.4 Survols —
   Le remplissage diagonal des boutons est défini avec les boutons (voir --sweep, plus haut).
   Le reste est réservé aux appareils à souris : pas de « survol collé » sur écran tactile. */
.arrow { display: inline-block; }   /* nécessaire pour pouvoir le déplacer */

@media (hover: hover) and (pointer: fine) {
  /* Touches « 3D » : elles se soulèvent au survol, s'enfoncent au clic */
  .btn--cta:hover { transform: translateY(-2px); box-shadow: 0 10px 0 #000; }
  .btn--cta:active { transform: translateY(4px); box-shadow: 0 4px 0 #000; }
  .contact__cta:hover { transform: translateY(-2px); box-shadow: 0 10px 0 rgba(0, 0, 0, .35); }
  .contact__cta:active { transform: translateY(4px); box-shadow: 0 4px 0 rgba(0, 0, 0, .35); }
  .plan--featured .btn:hover { transform: translateY(-2px); box-shadow: 0 8px 0 var(--orange-deep); }
  .plan--featured .btn:active { transform: translateY(3px); box-shadow: 0 3px 0 var(--orange-deep); }

  /* Lien externe : la flèche indique la direction */
  .arrow { transition: transform .28s var(--ease-out); }
  .projects__more:hover .arrow, .project__cta:hover .arrow { transform: translate(3px, -3px); }

  /* Pastilles de rubrique : elles s'allument et se redressent d'un côté */
  .kicker { transition: background-color .25s var(--ease-out), color .25s var(--ease-out), transform .4s var(--ease-spring); }
  .kicker:hover { background: var(--orange); color: var(--ink); transform: rotate(-3deg) scale(1.07); }
  .kicker--dark:hover { background: var(--cream); color: var(--ink); }   /* sur fond orange */

  /* Mots surlignés : les couleurs s'inversent, le bloc se penche de l'autre côté */
  .hl { transition: background-color .3s var(--ease-out), color .3s var(--ease-out), transform .45s var(--ease-spring); }
  .hl:hover { transform: rotate(1.4deg) scale(1.03); }
  .hl--orange:hover { background: var(--ink); color: var(--cream); }
  .hl--beige:hover { background: var(--ink); color: var(--beige); }
  .hl--orange-ink:hover { background: var(--beige); color: var(--ink); }

  /* Clients cités */
  .trust__name { cursor: default; transition: color .25s var(--ease-out), transform .4s var(--ease-spring); }
  .trust__name:hover { color: var(--orange-text); transform: translateY(-3px) rotate(-2deg); }

  /* Étiquettes des projets */
  .tags li { cursor: default; transition: background-color .25s var(--ease-out), border-color .25s var(--ease-out), color .25s var(--ease-out), transform .4s var(--ease-spring); }
  .tags li:hover { background: var(--orange); border-color: var(--orange); color: var(--ink); transform: translateY(-3px) rotate(-2.5deg); }
  .tags li:nth-child(even):hover { transform: translateY(-3px) rotate(2.5deg); }

  /* Post-it : on le soulève et on le redresse, son numéro s'allume */
  .note { transition: transform .4s var(--ease-spring), box-shadow .4s var(--ease-out); }
  .note:hover { transform: rotate(0deg) translateY(-8px); box-shadow: 0 24px 44px rgba(92, 42, 4, .3); }
  .note__num { transition: background-color .3s var(--ease-out), color .3s var(--ease-out), transform .4s var(--ease-spring); }
  .note:hover .note__num { background: var(--orange); color: var(--ink); transform: rotate(-6deg) scale(1.15); }

  /* Projets : le visuel se soulève, l'image respire, le titre prend la couleur de la marque */
  .project__media { transition: transform .5s var(--ease-out), box-shadow .5s var(--ease-out); }
  .project__media:hover { transform: translateY(-6px); box-shadow: 0 32px 64px rgba(28, 22, 20, .22); }
  .project__media .cover { transition: scale 1.1s var(--ease-out); }
  .project__media:hover .cover { scale: 1.05; }
  .project__title { transition: color .3s var(--ease-out); }
  .project:hover .project__title { color: var(--orange-text); }

  /* Méthode : la mise en avant de l'étape 1 passe à l'étape survolée */
  .step { transition: transform .4s var(--ease-out), background-color .3s var(--ease-out), border-color .3s var(--ease-out); }
  .step__num { transition: transform .45s var(--ease-spring), background-color .3s var(--ease-out), border-color .3s var(--ease-out), color .3s var(--ease-out); }
  .step:hover { transform: translateY(-8px); background: rgba(239, 120, 26, .12); border-color: rgba(239, 120, 26, .35); }
  .step:hover .step__num { background: var(--orange); border-color: var(--orange); color: var(--ink); transform: rotate(-10deg) scale(1.12); }
  .steps:hover .step:first-child:not(:hover) { background: rgba(252, 234, 219, .05); border-color: rgba(252, 234, 219, .14); }
  .steps:hover .step:first-child:not(:hover) .step__num { background: transparent; border-color: rgba(252, 234, 219, .32); color: var(--beige); }

  /* Offres : celle qu'on regarde se détache, son € fait un petit tour */
  .plan { transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out), border-color .3s var(--ease-out); }
  .plan:hover { transform: translateY(-6px); box-shadow: 0 20px 40px rgba(28, 22, 20, .12); }
  .plan:not(.plan--featured):hover { border-color: var(--orange); }
  .plan--featured:hover { box-shadow: 0 34px 68px rgba(28, 22, 20, .36); }
  .plan__currency { transition: transform .45s var(--ease-spring); }
  .plan:hover .plan__currency { transform: rotate(-14deg) scale(1.25); }

  /* Supports print : la tuile s'allume */
  .print__list li { transition: background-color .25s var(--ease-out), transform .4s var(--ease-spring); }
  .print__list li:hover { background: var(--orange); transform: translateY(-4px) rotate(-1.2deg); }
  .print__list li:hover span:first-child, .print__list li:hover .on-quote { color: var(--ink); }

  /* Logo de l'en-tête : un demi-tour au passage du curseur */
  .nav__brand:hover .nav__mark { rotate: 180deg; }

  /* Pied de page : le lien se souligne en glissant et avance d'un cran */
  .footer__col a:hover { background-size: 100% 1.5px; translate: 5px 0; }

  /* Grand nom : chaque lettre s'allume et se lève au passage, puis retombe lentement (effet de vague) */
  .wm-letter:hover { color: var(--orange); transform: translateY(-9%) rotate(-3deg); transition-duration: .12s, .25s; }
}

.nav__mark { transition: rotate .8s var(--ease-spring); }
.footer__col a {
  justify-self: start;                     /* le soulignement épouse le texte, pas la colonne */
  background: linear-gradient(currentColor, currentColor) 0 calc(100% - 1px) / 0 1.5px no-repeat;
  transition: color .2s var(--ease-out), background-size .4s var(--ease-out), translate .35s var(--ease-out);
}
.wm-letter { display: inline-block; transition: color 1.1s ease, transform 1.1s var(--ease-spring); }


/* — 10.5 Navigation : section active et indicateur glissant —
   L'indicateur est ajouté par js/motion.js ; il suit le survol, puis revient sous la section
   en cours de lecture. Sur mobile (menu déroulant), il n'est pas affiché. */
.nav__links { position: relative; }
.nav__links a[aria-current="true"] { color: var(--orange-text); }
.nav__indicator {
  position: absolute;
  left: 0; bottom: 1px;
  width: 1px; height: 2px;          /* la largeur réelle passe par scaleX(), calculée en JS */
  border-radius: 2px;
  background: var(--orange);
  transform-origin: 0 50%;
  opacity: 0;
  pointer-events: none;
  transition: transform .42s var(--ease-out), opacity .2s ease;
}
.nav__indicator.is-instant { transition: opacity .2s ease; }   /* 1re apparition : pas de glissade depuis la gauche */

@media (max-width: 899.98px) {
  .js .nav__indicator { display: none; }
}


/* — 10.6 Formulaire —
   Le message de retour apparaît en douceur (il est aussi annoncé aux lecteurs d'écran),
   et le libellé du champ actif prend la couleur de la marque. */
.form__status:not(:empty) { animation: fadeUp .3s var(--ease-out); }
.field { transition: color .18s var(--ease-out); }
.field:focus-within { color: var(--orange-text); }


/* — 10.7 Attention : l'offre recommandée —
   Le badge « Le plus choisi » fait un petit saut toutes les 7 secondes : l'œil est ramené
   sur l'offre que l'on recommande, sans clignoter en continu. */
@keyframes wiggle {
  0%, 72%, 100% { rotate: 0deg; translate: 0 0; }
  77% { rotate: -6deg; translate: 0 -4px; }
  82% { rotate: 5deg;  translate: 0 -3px; }
  87% { rotate: -3deg; translate: 0 -1px; }
  92% { rotate: 2deg;  translate: 0 0; }
}
.plan__badge { animation: wiggle 7s ease-in-out 2.5s infinite; }


/* — 10.8 Aimantation du défilement (scroll snap) —
   Un seul point de calage sur tout le site, sur le logo animé Clean Inspector : c'est la pièce
   maîtresse de la page, celle qu'on veut mettre en scène. Multiplier les points de calage sur une
   page aussi longue rendait le défilement saccadé section après section ; un seul point, bien
   réglé, reste fluide partout ailleurs (défilement libre) et attire l'œil au bon endroit.
   « proximity » : le calage n'a lieu qu'à l'approche du point, jamais de blocage forcé ; la
   navigation au clavier (Tab, flèches) n'est pas contrariée. « scroll-snap-stop: always » évite
   qu'un défilement rapide saute par-dessus ce point unique. Désactivé en mouvement réduit et sur
   les écrans très peu hauts. */
@media (prefers-reduced-motion: no-preference) and (min-height: 520px) {
  html { scroll-snap-type: y proximity; }

  .showcase {
    scroll-margin-top: 28px;   /* pas de marge haute dans cette section : on laisse respirer le visuel */
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
}


/* — 10.9 Impression et mouvement réduit — */
@media print {
  [data-reveal] { opacity: 1 !important; translate: none !important; animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
  }
}
