/* ============================================================
   04 — SECTIONS DE CONTENU (pages dédiées)
   Studio, Services, Méthode, Réalisations, Contact — le contenu
   complet de chaque page dédiée (studio.html, services.html,
   realisations.html, contact.html). Le hero plein écran et les
   teasers condensés de l'accueil sont dans 06-home.css.
   ============================================================ */

/* ---------- STUDIO / MANIFESTE ---------- */
.studio{ background:var(--paper); }
.studio-side .eyebrow{ margin-bottom:24px; }
.studio-grid{
  display:grid;
  grid-template-columns:0.9fr 1.1fr;
  gap:80px;
  align-items:start;
}
.pull{
  font-family:var(--display);
  font-size:clamp(26px, 2.6vw, 34px);
  line-height:1.32;
  font-weight:400;
  color:var(--text-dark);
}
.pull em{ font-style:italic; color:var(--indigo); font-weight:500; }
.pull.on-dark{ color:var(--text-light); }
.pull.on-dark em{ color:var(--indigo-lt); }
.studio-side p{
  color:var(--text-dim);
  font-size:15.5px;
  margin:0 0 22px;
}
.studio-side .divider{
  width:100%; height:1px; background:var(--paper-line);
  margin:32px 0;
}
.studio-values{
  display:grid; grid-template-columns:1fr 1fr; gap:24px 32px;
}
.studio-values div span.n{
  font-family:var(--body); font-size:11px; color:var(--indigo); letter-spacing:0.1em;
}
.studio-values div p{
  margin:8px 0 0; font-size:14.5px; color:var(--text-dark); font-weight:500;
}

/* ---------- SERVICES ---------- */
/* Même correctif que .hero .hero-content ailleurs sur le site : ignore
   le plafond de 1180px du .container partagé, pour que le contenu
   parte des vrais bords plutôt que de flotter dans une colonne
   centrée avec une grande marge vide de chaque côté. */
.page-header > .container,
.services > .container,
#process > .container,
.why > .container,
.contact > .container{
  max-width:none;
  width:100%;
  margin-left:0;
  margin-right:0;
  padding-left:var(--edge);
  padding-right:var(--edge);
  box-sizing:border-box;
}
.services{ background:var(--paper); color:var(--text-dark); }
.service-grid{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:1px;
  background:var(--paper-line);
  border:1px solid var(--paper-line);
  border-radius:14px;
  overflow:hidden;
}
.service-card{
  background:var(--paper);
  padding:40px 32px 34px;
  position:relative;
  display:flex;
  flex-direction:column;
  min-height:280px;
  transition:background .25s ease;
}
.service-card:hover{ background:var(--paper-dim); }
.service-card .idx{
  font-family:var(--body); font-size:11px; font-weight:700; color:var(--indigo);
  letter-spacing:0.14em; text-transform:uppercase;
  margin-bottom:8px;
  position:relative; z-index:1;
}
.service-card h3{
  margin-top:0;
  margin-bottom:10px;
  font-size:19px;
  font-weight:500;
  position:relative; z-index:1;
}
.service-card p{
  color:var(--text-dim);
  font-size:14px;
  line-height:1.55;
  max-width:38ch;
  margin-bottom:18px;
  position:relative; z-index:1;
}
.service-card .tag-row{ margin-top:auto; position:relative; z-index:1; }
.service-card .tag{
  border:1px solid var(--paper-line);
  color:var(--text-dim);
}
.service-icon{
  width:44px; height:44px;
  border-radius:10px;
  background:var(--indigo);
  display:flex; align-items:center; justify-content:center;
  margin-bottom:22px;
  position:relative; z-index:1;
}
.service-icon svg{ width:22px; height:22px; stroke:var(--text-light); fill:none; stroke-width:1.7; }

/* Numéro en filigrane — comble le vide des cartes texte-seul
   (pilier Identité, sans photo) ; les cartes .has-photo n'en ont pas
   besoin, déjà pleines. Même principe que .pillar-bg-num/.work-bg-num
   ailleurs sur le site, dont il reprend exactement la teinte. */
.card-bg-num{
  position:absolute;
  top:8px; right:18px;
  font-family:var(--display);
  font-size:88px;
  line-height:1;
  color:rgba(0,15,159,0.08);
  z-index:0;
  pointer-events:none;
  user-select:none;
  transition:color .25s ease;
}
.service-card:hover .card-bg-num{ color:rgba(0,15,159,0.14); }

/* Cartes avec photo (mockups des supports Indigo Space eux-mêmes,
   voir assets/img/services/) — la photo se déploie en bandeau plein
   cadre en haut de carte (marges négatives = même valeur que le
   padding de .service-card), l'icône reste à sa position d'origine
   mais se retrouve de fait "posée" sur la photo plutôt qu'au-dessus
   du texte : d'où le fond + le contour, pour rester lisible sur une
   image chargée plutôt que sur l'aplat indigo uni. */
.service-card.has-photo{ padding-top:0; overflow:hidden; }
.service-photo{
  position:relative;
  margin:0 -24px 10px;
  aspect-ratio:4/3;
  overflow:hidden;
  background:var(--ink-soft);
}
/* Voile de teinte commun à toutes les photos — les 6 sources
   (studio très clair, packaging plus saturé, scène véhicule en
   extérieur...) n'ont pas la même direction artistique ; ce voile
   les rapproche d'une même température plutôt que de les laisser
   se lire comme une banque d'images assemblée. Un vrai retraitement
   des photos irait plus loin, mais n'est pas possible ici. */
.service-photo::after{
  content:"";
  position:absolute; inset:0;
  z-index:1;
  background:linear-gradient(165deg, rgba(0,15,159,0.16), rgba(0,15,159,0.04) 55%);
  mix-blend-mode:multiply;
  pointer-events:none;
}
.service-photo img{
  width:100%; height:100%;
  object-fit:cover;
  display:block;
  filter:saturate(0.94) contrast(1.04) brightness(1.01);
  transition:transform .35s cubic-bezier(.2,.8,.2,1);
}
.service-card.has-photo:hover .service-photo img{ transform:scale(1.05); }
.service-card.has-photo .service-icon{
  position:absolute;
  top:14px; right:14px;
  z-index:2;
  opacity:1;
  width:34px; height:34px;
  padding:9px;
  background:rgba(255,255,255,0.16);
  backdrop-filter:blur(6px);
  border-radius:9px;
}
.service-card.has-photo .service-icon svg{ stroke:var(--text-light); }

/* Légende posée sur la photo (idx + titre), plutôt qu'en dessous —
   même idiome que .work-card .info (Réalisations) : dégradé sombre
   au ras du bord pour porter le texte clair directement sur l'image,
   la carte n'a donc plus qu'une seule ligne de texte (teaser) sous
   la photo. */
.photo-caption{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:20px 16px 14px;
  background:linear-gradient(to top, rgba(11,11,54,0.85), rgba(11,11,54,0.18) 65%, transparent);
}
.photo-caption .idx{ font-size:11px; color:var(--indigo-lt); }
.photo-caption h3{
  margin-top:4px;
  font-size:19px;
  color:var(--text-light);
  display:flex; align-items:center; gap:8px;
}

/* Grille uniforme (pilier Impression) — 3 colonnes / 2 rangées, les 6
   cartes à l'identique (plus de bento asymétrique). */
.service-grid-3{
  grid-template-columns:repeat(3, 1fr);
  gap:22px;
  background:transparent;
  border:none;
  border-radius:0;
  overflow:visible;
}
#impression{
  position:relative;
  overflow:hidden;
}
#impression .section-head p{
  font-size:17.5px;
  line-height:1.55;
  max-width:56ch;
}
/* Comble le vide à droite du chapô sur très grand écran (le bloc
   texte est plafonné à 64ch) : un stat lisible plutôt qu'un texte
   étiré artificiellement ou un filigrane redondant avec celui déjà
   présent dans la section. Masqué sous 1100px : pas de vide à combler
   à cette largeur, et pas de place pour l'accueillir proprement. */
#impression .section-head-split{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:48px;
}
#impression .section-head-text{ max-width:64ch; }
#impression .section-head-stat{
  display:none;
  flex-direction:column;
  align-items:flex-start;
  gap:2px;
  flex-shrink:0;
  min-width:200px;
  padding:20px 26px;
  background:var(--paper-dim);
  border:1px solid var(--paper-line);
  border-radius:14px;
}
#impression .section-head-stat .stat-num{
  font-family:var(--display);
  font-size:44px;
  line-height:1;
  color:var(--indigo);
}
#impression .section-head-stat .stat-label{
  margin-top:6px;
  font-size:13px;
  line-height:1.35;
  color:var(--text-dim);
  text-transform:uppercase;
  letter-spacing:0.04em;
}
@media (min-width:1100px){
  #impression .section-head-stat{ display:flex; }
}
/* Empreinte en filigrane — même motif que le page-header/footer,
   teinte indigo très pâle (pas blanche : fond clair ici) pour ancrer
   la section dans l'identité de marque au-delà du seul logo. */
#impression .fp-watermark{
  width:420px; height:420px;
  top:0; right:-100px;
  opacity:0.05;
  color:var(--indigo); /* voir 03-components.css — color, jamais fill */
}

/* Cartes cliquables (pilier Impression) — photo + titre seulement,
   le reste (description détaillée, tags) s'ouvre dans la popup
   .service-modal au clic (voir js/main.js). */
.service-card.has-photo{
  padding:0 24px 10px;
  border-radius:14px;
  overflow:hidden;
  background:var(--paper);
  border:1px solid var(--paper-line);
  box-shadow:0 1px 2px rgba(10,10,20,0.04);
  cursor:pointer;
}
/* Micro-description — une ligne, toujours visible mais discrète (le
   détail complet reste réservé à la popup). Comble le "juste un
   label + un titre" qui rendait les cartes un peu sèches. */
.service-card.has-photo .teaser{
  margin-top:0;
  font-size:13px;
  color:var(--text-dim);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
/* Flèche qui glisse depuis le titre au survol — même geste que
   .link-arrow ailleurs sur le site, ici sans lien propre puisque
   toute la carte est déjà cliquable. Couleur claire (indigo-lt) :
   la légende est posée sur la photo, pas sur le fond papier. */
.photo-caption h3 .arrow{
  opacity:0;
  transform:translateX(-4px);
  transition:opacity .25s ease, transform .25s ease;
  color:var(--indigo-lt);
}
.service-card.has-photo:hover .photo-caption h3 .arrow{ opacity:1; transform:translateX(0); }
.service-card.has-photo:focus-visible{
  outline:2px solid var(--indigo);
  outline-offset:-2px;
}

/* Clôture de section — la grille ne s'arrête plus net : un lien
   discret referme le pilier avant de passer à la suite. */
.service-section-foot{
  margin-top:40px;
  display:flex; justify-content:center;
}

/* ---------- POPUP DE DÉTAIL SERVICE ---------- */
.service-modal{
  position:fixed; inset:0; z-index:300;
  display:flex; align-items:center; justify-content:center;
  padding:24px;
  visibility:hidden;
  pointer-events:none;
}
.service-modal.open{ visibility:visible; pointer-events:auto; }
.service-modal-backdrop{
  position:absolute; inset:0;
  background:rgba(10,9,30,0.72);
  backdrop-filter:blur(4px);
  opacity:0;
  transition:opacity .35s ease;
}
.service-modal.open .service-modal-backdrop{ opacity:1; }
.service-modal-panel{
  position:relative;
  z-index:1;
  width:min(880px, 100%);
  max-height:min(720px, 90vh);
  overflow-y:auto;
  background:var(--paper);
  display:grid;
  grid-template-columns:1.1fr 1fr;
  opacity:0;
  transform:scale(0.94) translateY(18px);
  transition:opacity .4s cubic-bezier(.16,.7,.2,1), transform .4s cubic-bezier(.16,.7,.2,1);
}
.service-modal.open .service-modal-panel{ opacity:1; transform:scale(1) translateY(0); }
.service-modal-media{ background:var(--ink-soft); }
.service-modal-media img{ width:100%; height:100%; object-fit:cover; display:block; }
/* Popup Réalisations : pas de photo (portfolio en cours de
   constitution), le media reprend le duo teinte + monogramme de la
   carte plutôt qu'une image absente. */
.service-modal-media .swatch{
  width:100%; height:100%;
  display:flex; align-items:center; justify-content:center;
}
.service-modal-media .work-monogram{ font-size:clamp(72px, 12vw, 110px); }
.service-modal-body{
  padding:44px 40px;
  display:flex; flex-direction:column;
  align-self:start;
}
.service-modal-body .idx{
  font-family:var(--body); font-size:12px; color:var(--indigo); letter-spacing:0.1em;
}
.service-modal-body h3{ margin-top:14px; font-size:26px; font-weight:500; }
.service-modal-body p{
  margin-top:16px; color:var(--text-dim); font-size:15px; line-height:1.7;
}
.service-modal-body .tag-row{ margin-top:22px; margin-bottom:32px; }
.service-modal-close{
  position:absolute; top:16px; right:16px; z-index:2;
  width:38px; height:38px;
  display:flex; align-items:center; justify-content:center;
  background:rgba(10,9,30,0.6);
  backdrop-filter:blur(6px);
  border:none; border-radius:50%;
  color:var(--text-light);
  font-size:22px; line-height:1;
  cursor:pointer;
  transition:background .25s ease, transform .25s ease;
}
.service-modal-close:hover{ background:rgba(10,9,30,0.85); transform:scale(1.08); }

/* Bande de transition entre les deux piliers — écho des eyebrows
   "01 — Construire" / "02 — Imprimer" en tête de chaque section, pour
   que la page se lise comme un seul récit ("deux métiers, un seul
   geste") plutôt que deux blocs juxtaposés sans lien. */
.pilier-link{
  background:var(--paper-dim);
  border-top:1px solid var(--paper-line);
  border-bottom:1px solid var(--paper-line);
  padding:26px 0;
}
.pilier-link .container{
  display:flex; align-items:center; justify-content:center;
  gap:16px; flex-wrap:wrap;
  font-family:var(--body); font-weight:600; font-size:11px;
  letter-spacing:0.13em; text-transform:uppercase;
  color:var(--text-dim);
}
.pilier-link-arrow{ color:var(--indigo); font-size:14px; }

/* Puces "01 Construire / 02 Imprimer" dans l'en-tête — sommaire
   cliquable qui donne le ton avant même de scroller, plutôt qu'un
   simple bloc de texte statique. */
.page-header-jump{
  margin-top:44px;
  display:flex; gap:14px; flex-wrap:wrap;
}
.page-header-jump-item{
  display:flex; align-items:center; gap:10px;
  padding:10px 18px 10px 10px;
  border:1px solid var(--ink-line);
  border-radius:100px;
  font-family:var(--body); font-weight:600; font-size:12.5px;
  letter-spacing:0.04em; color:var(--text-light);
  transition:border-color .25s ease, background .25s ease, transform .25s ease;
}
.page-header-jump-item .n{
  display:flex; align-items:center; justify-content:center;
  width:24px; height:24px; border-radius:50%;
  background:var(--indigo-lt); color:var(--ink);
  font-size:10.5px;
}
.page-header-jump-item:hover{
  border-color:var(--indigo-lt);
  background:rgba(255,255,255,0.06);
  transform:translateY(-2px);
}

/* Fil de process compact (pilier Identité, pas de photo pour porter
   la section) — pas le composant .steps réutilisé plus bas pour
   "De l'idée au tirage" : ici juste une ligne de repères, en écho
   discret plutôt qu'une deuxième vraie section d'étapes. */
.process-thread{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:10px;
  margin-top:28px;
  padding-top:28px;
  border-top:1px solid var(--paper-line);
}
.process-thread-item{
  font-family:var(--body); font-weight:600; font-size:11px;
  letter-spacing:0.1em; text-transform:uppercase;
  color:var(--text-dim);
}
.process-thread-item::after{
  content:"—"; margin-left:10px; color:var(--paper-line);
}
.process-thread-item:last-child::after{ content:none; }

/* Cascade d'entrée carte par carte — la grille entière porte le
   .reveal observé (pas chaque carte : un élément réduit à une hauteur
   visible nulle par son propre clip-path n'est jamais considéré
   "intersecting" par IntersectionObserver, la révélation ne se
   déclenche donc jamais — vérifié). Chaque carte se révèle en rideau,
   décalée par nth-child, une fois .in posé sur le conteneur. */
.service-card{
  clip-path:inset(0 0 100% 0);
  transition:clip-path .7s cubic-bezier(.16,.7,.2,1);
}
.service-grid.reveal.in .service-card{ clip-path:inset(0 0 0 0); }
.service-grid.reveal.in .service-card:nth-child(1){ transition-delay:0s; }
.service-grid.reveal.in .service-card:nth-child(2){ transition-delay:.12s; }
.service-grid.reveal.in .service-card:nth-child(3){ transition-delay:.24s; }
.service-grid.reveal.in .service-card:nth-child(4){ transition-delay:.36s; }
.service-grid.reveal.in .service-card:nth-child(5){ transition-delay:.48s; }
.service-grid.reveal.in .service-card:nth-child(6){ transition-delay:.6s; }
/* Le délai ci-dessus (posé sur l'élément) s'appliquerait sinon aussi
   au survol (fond) une fois la révélation jouée — neutralisé
   explicitement pour que le hover reste instantané. */
.service-card:hover{ transition-delay:0s; }

/* Icônes qui se dessinent au trait (voir js/main.js) — stroke-dasharray
   animé plutôt qu'un fondu, pour un geste "tracé" cohérent avec
   l'esprit signature/empreinte de la marque. */
.service-icon svg.draw-ready path,
.service-icon svg.draw-ready circle,
.service-icon svg.draw-ready line,
.service-icon svg.draw-ready rect{
  transition:stroke-dashoffset 1s cubic-bezier(.16,.7,.2,1);
}
.service-icon svg.draw-in path,
.service-icon svg.draw-in circle,
.service-icon svg.draw-in line,
.service-icon svg.draw-in rect{
  stroke-dashoffset:0 !important;
}

/* Tilt léger au survol des photos (pilier Impression) — même
   mécanique que les cartes Réalisations (voir js/main.js), suit le
   curseur plutôt qu'un simple zoom. */
.service-photo img{ transform-style:preserve-3d; }
.service-card.has-photo:hover .service-photo img{
  transform:scale(1.05) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
}

/* ---------- MÉTHODE ---------- */
.methode{ background:var(--paper-dim); position:relative; }
/* Fondu haut/bas : la section grise s'arrêtait net contre les deux
   sections blanches qui l'entourent (#impression, .why) — un bord dur
   plutôt qu'une transition. */
.methode::before, .methode::after{
  content:"";
  position:absolute; left:0; right:0; height:64px;
  pointer-events:none; z-index:0;
}
.methode::before{ top:0; background:linear-gradient(to bottom, var(--paper), transparent); }
.methode::after{ bottom:0; background:linear-gradient(to top, var(--paper), transparent); }
.methode > .container{ position:relative; z-index:1; }
.steps{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  gap:0;
  position:relative;
}
/* Rail statique (toujours visible), le tracé indigo est désormais un
   segment par étape (voir .step::after) plutôt qu'un trait unique :
   chaque tronçon se remplit juste après l'étape qui le précède,
   effet "chemin qui avance" plutôt qu'un trait qui se dessine seul,
   sans rapport avec l'apparition des étapes. */
.steps::before{
  content:"";
  position:absolute; top:15px; left:0; right:0; height:1px;
  background:var(--paper-line);
}
.step{
  padding-right:28px;
  position:relative;
  opacity:0;
  transform:translateY(16px);
  transition:opacity .6s cubic-bezier(.16,.7,.2,1), transform .6s cubic-bezier(.16,.7,.2,1);
}
/* Carte de survol (desktop) — fond + ombre qui apparaissent derrière
   tout le bloc (node/icône/titre/texte) au survol, sous la ligne/le
   node (z-index:-1) pour ne rien masquer du tracé. */
.step::before{
  content:"";
  position:absolute; top:-14px; right:-16px; bottom:-16px; left:-16px;
  background:var(--paper);
  border-radius:14px;
  opacity:0;
  transform:scale(.97);
  transition:opacity .3s cubic-bezier(.16,.7,.2,1), transform .3s cubic-bezier(.16,.7,.2,1);
  box-shadow:0 24px 40px -22px rgba(0,15,159,.22);
  pointer-events:none;
  z-index:-1;
}
.steps.in .step{ opacity:1; transform:translateY(0); }
.steps.in .step:nth-child(1){ transition-delay:.15s; }
.steps.in .step:nth-child(2){ transition-delay:.35s; }
.steps.in .step:nth-child(3){ transition-delay:.55s; }
.steps.in .step:nth-child(4){ transition-delay:.75s; }
.step:not(:last-child)::after{
  content:"";
  position:absolute; top:14px; left:15px; width:100%; height:2px;
  background:var(--indigo);
  transform:scaleX(0); transform-origin:left;
  transition:transform .55s cubic-bezier(.4,0,.2,1);
}
.steps.in .step:nth-child(1)::after{ transition-delay:.45s; }
.steps.in .step:nth-child(2)::after{ transition-delay:.65s; }
.steps.in .step:nth-child(3)::after{ transition-delay:.85s; }
.steps.in .step::after{ transform:scaleX(1); }
/* Point lumineux qui parcourt chaque segment en même temps qu'il se
   remplit — accompagne l'œil d'un node à l'autre plutôt qu'un simple
   remplissage silencieux. Timing calé sur le segment correspondant. */
.step-dot{
  position:absolute; top:11.5px; left:15px;
  width:7px; height:7px; border-radius:50%;
  background:var(--indigo);
  box-shadow:0 0 8px 2px rgba(0,15,159,.55);
  opacity:0;
  pointer-events:none;
}
@keyframes step-dot-travel{
  0%{ left:15px; opacity:0; }
  10%{ opacity:1; }
  85%{ opacity:1; }
  100%{ left:calc(100% + 15px); opacity:0; }
}
.steps.in .step:nth-child(1) .step-dot{ animation:step-dot-travel .55s cubic-bezier(.4,0,.2,1) .45s both; }
.steps.in .step:nth-child(2) .step-dot{ animation:step-dot-travel .55s cubic-bezier(.4,0,.2,1) .65s both; }
.steps.in .step:nth-child(3) .step-dot{ animation:step-dot-travel .55s cubic-bezier(.4,0,.2,1) .85s both; }
.step .node{
  width:30px; height:30px;
  border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--indigo);
  font-family:var(--body); font-size:11px; font-weight:600; color:var(--text-light);
  position:relative; z-index:1;
  /* halo = fond de section : masque le rail/tracé derrière le disque
     plein pour qu'il n'affleure pas visuellement sur le chiffre */
  box-shadow:0 0 0 5px var(--paper-dim);
  transform:scale(.3);
  transition:transform .5s cubic-bezier(.34,1.56,.64,1);
}
.steps.in .step:nth-child(1) .node{ transition-delay:.15s; }
.steps.in .step:nth-child(2) .node{ transition-delay:.35s; }
.steps.in .step:nth-child(3) .node{ transition-delay:.55s; }
.steps.in .step:nth-child(4) .node{ transition-delay:.75s; }
.steps.in .step .node{ transform:scale(1); }
.step-icon{
  width:26px; height:26px;
  margin-top:22px;
  color:var(--indigo);
  opacity:0;
  transform:translateY(6px) scale(.7);
  transition:opacity .45s cubic-bezier(.16,.7,.2,1), transform .45s cubic-bezier(.16,.7,.2,1);
}
.step-icon svg{ width:100%; height:100%; stroke:currentColor; fill:none; stroke-width:1.3; }
.step-icon + h4{ margin-top:12px; }
.steps.in .step:nth-child(1) .step-icon{ transition-delay:.32s; }
.steps.in .step:nth-child(2) .step-icon{ transition-delay:.52s; }
.steps.in .step:nth-child(3) .step-icon{ transition-delay:.72s; }
.steps.in .step:nth-child(4) .step-icon{ transition-delay:.92s; }
.steps.in .step-icon{ opacity:1; transform:translateY(0) scale(1); }
.step h4{
  margin-top:26px;
  font-size:18px;
  color:var(--text-dark);
  font-weight:500;
}
.step p{
  margin-top:10px;
  font-size:14px;
  color:var(--text-dim);
  line-height:1.6;
  max-width:26ch;
}
/* Micro-interaction desktop : léger décollement du duo node/icône au
   survol, écho du système de tilt/hover déjà en place sur les cartes
   Impression, plutôt qu'un simple changement de couleur. */
@media (hover:hover) and (pointer:fine){
  /* .steps.in .step(:nth-child) fait déjà autorité en spécificité et
     porte un transition-delay d'entrée (.15s à .75s) — il faut égaler
     la spécificité et remettre le délai à 0 pour que le survol
     réagisse immédiatement une fois l'entrée terminée. */
  .steps.in .step:hover{ transition-delay:0s; transform:translateY(-6px); }
  .steps.in .step:hover::before{ opacity:1; transform:scale(1); }
  .steps.in .step:hover .node{ transform:scale(1.08); }
  .step:hover .step-icon{ transform:translateY(-3px) scale(1); }
}

/* ---------- POURQUOI INDIGO (réassurance) ---------- */
.why{ background:var(--paper); }
/* Titre centré : casse la répétition visuelle avec le section-head
   (label + titre + sous-titre, aligné à gauche) du pilier juste
   au-dessus et de la section process. */
.why .section-head{
  max-width:480px;
  margin-left:auto;
  margin-right:auto;
  text-align:center;
}
.why-grid{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  gap:40px;
  margin-top:16px;
}
.why-item{
  opacity:0;
  transform:translateY(16px);
  transition:opacity .6s cubic-bezier(.16,.7,.2,1), transform .6s cubic-bezier(.16,.7,.2,1);
  text-align:center;
}
.why-grid.in .why-item{ opacity:1; transform:translateY(0); }
.why-grid.in .why-item:nth-child(1){ transition-delay:0s; }
.why-grid.in .why-item:nth-child(2){ transition-delay:.12s; }
.why-grid.in .why-item:nth-child(3){ transition-delay:.24s; }
.why-grid.in .why-item:nth-child(4){ transition-delay:.36s; }
.why-icon{
  width:34px; height:34px;
  color:var(--indigo);
  margin:0 auto 20px;
  transform:scale(.3);
  transition:transform .5s cubic-bezier(.34,1.56,.64,1);
}
.why-icon svg{ width:100%; height:100%; stroke:currentColor; fill:none; stroke-width:1.3; }
/* Rebond en entrée — même geste que les cercles du process juste
   au-dessus, sur le même tempo que le fondu de la carte (.why-item). */
.why-grid.in .why-item:nth-child(1) .why-icon{ transition-delay:0s; }
.why-grid.in .why-item:nth-child(2) .why-icon{ transition-delay:.12s; }
.why-grid.in .why-item:nth-child(3) .why-icon{ transition-delay:.24s; }
.why-grid.in .why-item:nth-child(4) .why-icon{ transition-delay:.36s; }
.why-grid.in .why-icon{ transform:scale(1); }
.why-item h4{
  font-size:17px;
  font-weight:500;
  color:var(--text-dark);
}
.why-item p{
  margin-top:10px;
  font-size:14px;
  color:var(--text-dim);
  line-height:1.6;
}
/* Survol "intelligent" (desktop) — chaque icône réagit selon le sens
   de sa valeur plutôt qu'un hover générique identique partout :
   le check pulse (validation), le losange tourne légèrement (reflet),
   la boucle fait un tour complet (continuité), la loupe zoome (détail). */
@media (hover:hover) and (pointer:fine){
  .why-grid.in .why-item:hover .why-icon{
    transition-delay:0s;
    transition-duration:.45s;
    transition-timing-function:cubic-bezier(.34,1.56,.64,1);
  }
  .why-grid.in .why-item:nth-child(1):hover .why-icon{ transform:scale(1.18); }
  .why-grid.in .why-item:nth-child(2):hover .why-icon{ transform:rotate(24deg) scale(1.1); }
  /* rotate(360deg) en transition est un no-op : la matrice calculée
     est identique à 0deg (mêmes cos/sin), le navigateur ne détecte
     aucun changement et n'anime rien — d'où la vraie @keyframes ici. */
  .why-grid.in .why-item:nth-child(3):hover .why-icon{
    animation:why-icon-spin .6s cubic-bezier(.4,0,.2,1);
  }
  .why-grid.in .why-item:nth-child(4):hover .why-icon{ transform:scale(1.3); }
}
@keyframes why-icon-spin{
  from{ transform:rotate(0deg); }
  to{ transform:rotate(360deg); }
}

/* ---------- RÉALISATIONS ---------- */
.work{ background:var(--paper); }
.work-grid{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:2px;
  background:var(--paper-line);
  border:1px solid var(--paper-line);
}
.work-card{
  background:var(--paper);
  aspect-ratio:4/5;
  position:relative;
  overflow:hidden;
  cursor:default;
  perspective:800px; /* profondeur pour le tilt 3D de .swatch au survol */
}
/* Cliquable uniquement sur le catalogue complet (voir js/main.js) —
   le teaser accueil (grid limitée) reste une simple vitrine. */
.work-card[role="button"]{ cursor:pointer; }
.work-card[role="button"]:focus-visible{ outline:2px solid var(--indigo); outline-offset:-2px; }
.work-card .swatch{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  transform-style:preserve-3d;
  transform:rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) scale(1);
  transition:transform .5s cubic-bezier(.2,.8,.2,1);
}
.work-card:hover .swatch{ transform:rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) scale(1.04); }

/* Monogramme — tient lieu de vraie photo tant qu'elle n'est pas
   disponible : plus habillé que les deux cercles concentriques
   précédents, et utilise la police de marque plutôt qu'un motif
   générique. */
.work-monogram{
  font-family:var(--display);
  font-size:clamp(48px, 8vw, 72px);
  font-weight:400;
  line-height:1;
  opacity:0.9;
  display:inline-block;
  transform:scale(.4);
  transition:transform .55s cubic-bezier(.34,1.56,.64,1);
}
.work-card.in .work-monogram{ transform:scale(1); }
@media (hover:hover) and (pointer:fine){
  .work-card[role="button"]:hover .work-monogram{ transform:scale(1.08); }
}

/* Numéro de catalogue en filigrane — même esprit que celui des
   Piliers, à une échelle adaptée à une carte plus petite. */
.work-bg-num{
  position:absolute;
  bottom:-0.1em; left:-0.03em;
  font-family:var(--display);
  font-size:110px;
  line-height:1;
  color:rgba(0,15,159,0.08);
  z-index:1;
  pointer-events:none;
  user-select:none;
}
/* ...et sa version lisible, toujours visible (pas seulement au survol)
   — le filigrane est une texture de fond, celui-ci un vrai repère de
   catalogue qu'on peut lire sans interagir. */
.work-cat-num{
  position:absolute;
  top:14px; right:14px; /* coin libre : le repère de calage occupe le haut-gauche, l'autre le bas-droit */
  z-index:2;
  font-family:var(--body); font-weight:600; font-size:10.5px;
  letter-spacing:0.1em;
  color:var(--text-dim);
  background:rgba(255,255,255,0.82);
  padding:4px 8px;
  pointer-events:none;
}

/* Repères de calage au survol — diagonale classique (comme boutons/
   cartes Piliers). Le bas bascule maintenant en overlay sombre en
   permanence (le titre y est toujours affiché, plus seulement au
   survol — voir .info plus bas), donc le repère bas-droit peut être
   clair sans jamais perdre son contraste. */
.work-card::before,
.work-card::after{
  content:"";
  position:absolute;
  width:12px; height:12px;
  opacity:0;
  z-index:3;
  transition:opacity .3s ease, transform .3s ease;
  pointer-events:none;
}
.work-card::before{
  top:12px; left:12px;
  border-top:1.5px solid var(--indigo);
  border-left:1.5px solid var(--indigo);
  transform:translate(5px, 5px);
}
.work-card::after{
  bottom:12px; right:12px;
  border-bottom:1.5px solid var(--text-light);
  border-right:1.5px solid var(--text-light);
  transform:translate(-5px, -5px);
}
.work-card:hover::before,
.work-card:hover::after{ opacity:0.8; transform:translate(0, 0); }

/* Légende toujours visible (titre) — avant, tout .info était caché
   jusqu'au survol, donc la grille ne racontait rien sans interaction.
   Seul le tag de catégorie reste réservé au survol, en éditorial
   "détail qui se révèle". */
.work-card .info{
  position:absolute; left:0; right:0; bottom:0;
  z-index:2;
  padding:22px 24px;
  background:linear-gradient(to top, rgba(23,22,42,0.85), transparent);
  color:var(--text-light);
}
.work-card .info .tag{
  padding:0;
  color:var(--indigo-lt);
  opacity:0;
  transform:translateY(6px);
  transition:opacity .3s ease, transform .3s ease;
}
.work-card:hover .info .tag,
.work-card:focus-within .info .tag{ opacity:1; transform:translateY(0); }
.work-card .info h4{
  margin-top:8px; font-size:16px; color:var(--text-light); font-weight:500;
}
/* Indice de clic — seules les cartes du catalogue complet (voir
   js/main.js) sont interactives ; sans lui, rien ne signale que la
   carte mène à un popup de détail. */
.work-card[role="button"] .info::after{
  content:"Voir le concept →";
  display:block;
  margin-top:10px;
  font-family:var(--body); font-size:12.5px; font-weight:600;
  color:var(--indigo-lt);
  opacity:0;
  transform:translateY(6px);
  transition:opacity .3s ease, transform .3s ease;
}
.work-card:hover .info::after,
.work-card:focus-visible .info::after{ opacity:1; transform:translateY(0); }
.work-note{
  margin-top:28px;
  font-size:13.5px;
  color:var(--text-dim);
  font-style:italic;
}

/* Révélation en cascade des cartes (voir js/main.js) */
.work-card.work-reveal{
  opacity:0;
  transform:translateY(18px);
  transition:opacity .6s cubic-bezier(.16,.7,.2,1), transform .6s cubic-bezier(.16,.7,.2,1);
}
.work-card.work-reveal.in{ opacity:1; transform:translateY(0); }

/* ---------- INDEX ÉDITORIAL (page Réalisations) ----------
   Catalogue complet : plus de grille de vignettes, une liste de
   titres façon sommaire de magazine. Survol desktop -> aperçu fixe à
   droite (voir .index-preview) ; tap mobile -> la ligne se déplie
   (voir .index-row-expand). Le teaser accueil garde .work-grid/
   .work-card, inchangés au-dessus. */
.index-wrap{
  display:grid;
  grid-template-columns:1.3fr 1fr;
  gap:64px;
  align-items:start;
}
.index-list{ min-width:0; }
.index-row{
  position:relative;
  padding:26px 4px;
  border-top:1px solid var(--paper-line);
  cursor:pointer;
}
.index-list > .index-row:last-child{ border-bottom:1px solid var(--paper-line); }
.index-row-main{
  display:flex;
  align-items:baseline;
  gap:24px;
}
.index-row-num{
  font-family:var(--body); font-size:13px; color:var(--text-dim);
  flex-shrink:0;
  width:28px;
}
.index-row-title{
  font-family:var(--display); font-weight:400;
  font-size:clamp(28px, 4.2vw, 52px);
  line-height:1.05;
  color:var(--text-dark);
  transition:color .3s ease, transform .3s cubic-bezier(.2,.8,.2,1);
  flex:1; min-width:0;
}
.index-row-tag{
  font-family:var(--body); font-size:11px; font-weight:600; letter-spacing:0.1em;
  text-transform:uppercase;
  color:var(--text-dim);
  flex-shrink:0;
  align-self:center;
}
@media (hover:hover) and (pointer:fine){
  .index-row:hover .index-row-title, .index-row:focus-visible .index-row-title{
    color:var(--indigo);
    transform:translateX(10px);
  }
}
.index-row:focus-visible{ outline:2px solid var(--indigo); outline-offset:-2px; }

/* Aperçu fixe à droite (desktop) — même duo teinte + monogramme que
   les lignes, mis à jour en JS au survol. */
.index-preview{
  position:sticky;
  top:132px;
  aspect-ratio:4/5;
  background:var(--paper-dim);
  overflow:hidden;
}
.index-preview-swatch{
  width:100%; height:100%;
  display:flex; align-items:center; justify-content:center;
  transition:background .35s ease;
}
.index-preview-swatch .work-monogram{
  font-size:clamp(64px, 8vw, 100px);
  transition:color .35s ease;
}

/* Dépliant mobile — masqué/inerte tant que .is-expanded n'est pas
   posé (voir js/main.js, tap sur la ligne) ; grid-template-rows plutôt
   que max-height pour une hauteur "auto" proprement animée. */
.index-row-expand-wrap{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .4s cubic-bezier(.16,.7,.2,1);
}
.index-row-expand{
  overflow:hidden;
  min-height:0;
}
.index-row.is-expanded .index-row-expand-wrap{ grid-template-rows:1fr; }
.index-row-expand-swatch{
  margin-top:20px;
  aspect-ratio:16/10;
  display:flex; align-items:center; justify-content:center;
}
.index-row-expand-swatch .work-monogram{ font-size:56px; }
.index-row-detail-btn{
  margin-top:16px;
  background:none; border:none; padding:0;
  cursor:pointer;
}

/* ---------- CONTACT ---------- */
.contact{
  background:var(--ink);
  color:var(--text-light);
  overflow:hidden;
  position:relative;
  isolation:isolate;
}
/* Plein écran comme .page-header (Services/Studio/Réalisations) —
   la page ne faisait pas "à part" du reste du site sans ce traitement :
   même dégagement sous le header fixe, mêmes repères de calage. */
.contact.page-top{
  min-height:100vh;
  min-height:100svh;
  min-height:100dvh;
  display:flex;
  flex-direction:column;
  justify-content:center;
  padding:132px 0 96px;
}
.contact-grid{
  display:grid;
  grid-template-columns:1.1fr 0.9fr;
  gap:64px;
  align-items:end;
}
.contact h1{
  font-size:clamp(34px, 4.4vw, 54px);
  line-height:1.12;
  color:var(--text-light);
  max-width:12ch;
}
.contact h1 em{ font-style:italic; color:var(--indigo-lt); font-weight:500; }
.contact .eyebrow{ margin-bottom:24px; }
.contact .intro-text{
  margin-top:24px; color:var(--text-light-dim); max-width:42ch; font-size:16px;
}
.contact-cta{ margin-top:40px; display:flex; flex-wrap:wrap; gap:14px; }
.btn-icon{ width:16px; height:16px; flex-shrink:0; stroke:currentColor; fill:none; stroke-width:1.5; }
/* Réassurance juste avant l'action — lève les dernières hésitations
   au moment précis où on regarde encore les boutons. */
.contact-reassure{
  margin-top:18px;
  font-size:13px;
  color:var(--text-light-dim);
}
.contact-details{
  display:grid; gap:8px;
}
.contact-details .row{
  display:flex; align-items:center; gap:16px;
  border-top:1px solid var(--ink-line);
  padding:18px 10px 18px 0;
  margin:0 -10px;
  border-radius:8px;
  transition:background .3s ease;
}
.contact-details .row-icon{
  width:34px; height:34px; flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
  color:var(--indigo-lt);
  transform:scale(.3);
  transition:transform .5s cubic-bezier(.34,1.56,.64,1);
}
.contact-details .row-icon svg{ width:19px; height:19px; stroke:currentColor; fill:none; stroke-width:1.3; }
.contact-details.in .row:nth-child(1) .row-icon{ transition-delay:.1s; }
.contact-details.in .row:nth-child(2) .row-icon{ transition-delay:.22s; }
.contact-details.in .row:nth-child(3) .row-icon{ transition-delay:.34s; }
.contact-details.in .row-icon{ transform:scale(1); }
.contact-details .m-label{
  font-family:var(--body); font-size:10.5px; letter-spacing:0.14em;
  color:var(--text-light-dim); text-transform:uppercase;
}
.contact-details .m-value{
  margin-top:8px; font-size:18px; font-family:var(--display); color:var(--text-light);
}
.contact-details a.m-value:hover{ color:var(--indigo-lt); }
@media (hover:hover) and (pointer:fine){
  .contact-details .row:hover{ background:rgba(246,242,233,0.05); padding-left:10px; padding-right:20px; margin-left:-20px; }
  .contact-details.in .row:hover .row-icon{ transition-delay:0s; transform:scale(1.12); color:var(--text-light); }
}

/* ---------- RESPONSIVE ---------- */
@media (max-width: 980px){
  .studio-grid{ grid-template-columns:1fr; gap:40px; }
  .studio-values{ grid-template-columns:1fr 1fr; }

  .service-grid,
  .service-grid-3{ grid-template-columns:1fr; }
  .card-bg-num{ font-size:64px; }
  .pilier-link .container{ font-size:10px; gap:10px; }

  .service-modal-panel{ grid-template-columns:1fr; max-height:92vh; }
  .service-modal-media{ aspect-ratio:16/10; }

  .steps{ grid-template-columns:1fr; gap:40px; }
  .steps::before{ display:none; }
  .step::after{ display:none; }
  .step-dot{ display:none; }
  .step{ padding-right:0; }

  .why-grid{ grid-template-columns:1fr 1fr; gap:32px; }

  .work-grid{ grid-template-columns:1fr 1fr; }
  .contact-grid{ grid-template-columns:1fr; gap:48px; }

  /* Index éditorial : pas d'aperçu fixe sans survol réel (voir aussi
     canHover en JS) — la ligne se déplie sur place à la place. */
  .index-wrap{ grid-template-columns:1fr; gap:0; }
  .index-preview{ display:none; }
  .index-row-main{ flex-wrap:wrap; gap:6px 24px; }
  .index-row-tag{ order:1; width:100%; }
}

@media (max-width: 560px){
  .work-grid{ grid-template-columns:1fr; }
  .why-grid{ grid-template-columns:1fr; gap:28px; }
}
