/* ============================================================================
   Sections : en-tete, hero, preuve, points forts, cas, contact, pied de page
   Mobile-first. Chaque bloc ne monte en complexite qu'a partir de 720px.
   ========================================================================= */

/* ── EN-TETE ─────────────────────────────────────────────────────────────── */
.masthead {
  position: fixed; inset: 0 0 auto 0;
  z-index: 60;
  padding-block: var(--space-md);
  transition: background var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease),
              padding var(--t-base) var(--ease);
  border-bottom: 1px solid transparent;
}
.masthead.is-stuck {
  background: rgba(7, 11, 20, .82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--border);
  padding-block: var(--space-sm);
}
.masthead__inner { display: flex; align-items: center; gap: var(--space-lg); }
.masthead__logo { flex: none; display: block; }
.masthead__logo img { height: 30px; width: auto; }

.masthead__nav { display: none; margin-inline: auto; }
.masthead__nav ul { display: flex; gap: var(--space-lg); list-style: none; margin: 0; padding: 0; }
.masthead__nav a {
  color: var(--text-soft); text-decoration: none; font-weight: 500;
  font-size: var(--step--1); letter-spacing: .02em;
  transition: color var(--t-fast) var(--ease);
}
.masthead__nav a:hover { color: var(--text); }

.masthead__end { display: flex; align-items: center; gap: var(--space-sm); margin-left: auto; }
.masthead__cta { display: none; }

.langs { display: flex; gap: 2px; list-style: none; margin: 0; padding: 0; }
.langs a {
  display: block; padding: .45em .6em;
  font-size: var(--step--1); font-weight: 600; letter-spacing: .06em;
  color: var(--text-faint); text-decoration: none; border-radius: var(--radius-sm);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.langs a:hover { color: var(--text); background: var(--surface); }
.langs a.is-current { color: var(--accent); }

.burger {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--border-strong);
  border-radius: var(--radius-full); cursor: pointer;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.burger:hover { border-color: var(--accent); background: var(--surface); }
.burger span, .burger span::before, .burger span::after {
  content: ''; display: block;
  width: 17px; height: 2px; border-radius: 2px;
  background: var(--text);
  transition: transform var(--t-base) var(--ease), opacity var(--t-fast) var(--ease);
}
.burger span::before { transform: translateY(-6px); }
.burger span::after  { transform: translateY(4px); }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { transform: rotate(45deg); }
.burger[aria-expanded="true"] span::after  { transform: rotate(-45deg) translateY(-1px); }

/* ── TIROIR DE NAVIGATION ────────────────────────────────────────────────── */
.drawer { position: fixed; inset: 0; z-index: 80; }
.drawer[hidden] { display: none; }
.drawer__backdrop {
  position: absolute; inset: 0;
  background: rgba(4, 7, 13, .72);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; transition: opacity var(--t-base) var(--ease);
}
.drawer__panel {
  position: absolute; inset: 0 0 0 auto;
  width: min(420px, 100%);
  background: var(--bg-raised);
  border-left: 1px solid var(--border);
  padding: var(--space-2xl) var(--gutter);
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform var(--t-base) var(--ease-out);
  display: flex; flex-direction: column; gap: var(--space-xl);
}
.drawer.is-open .drawer__backdrop { opacity: 1; }
.drawer.is-open .drawer__panel { transform: none; }

.drawer__close {
  position: absolute; top: var(--space-lg); right: var(--gutter);
  width: 44px; height: 44px; display: grid; place-items: center;
  background: transparent; border: 1px solid var(--border); border-radius: var(--radius-full);
  color: var(--text); cursor: pointer;
}
.drawer__close svg { width: 18px; height: 18px; }
.drawer__close:hover { border-color: var(--accent); }

.drawer__main { list-style: none; margin: var(--space-xl) 0 0; padding: 0; }
.drawer__main a {
  display: block; padding: .5em 0;
  font-family: var(--font-display); font-size: var(--step-2); font-weight: 600;
  color: var(--text); text-decoration: none;
}
.drawer__main a:hover { color: var(--accent); }

.drawer__group + .drawer__group { margin-top: var(--space-lg); }
.drawer__group-title {
  font-size: var(--step--1); font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 var(--space-xs);
}
.drawer__group-title--industry     { color: var(--cyan); }
.drawer__group-title--serious-game { color: #A78BFA; }
.drawer__group ul { list-style: none; margin: 0; padding: 0; }
.drawer__group a {
  display: block; padding: .32em 0;
  color: var(--text-soft); text-decoration: none; font-size: var(--step-0);
}
.drawer__group a:hover { color: var(--text); }

.drawer__foot {
  margin-top: auto; padding-top: var(--space-lg);
  border-top: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-md);
}

/* ── PREUVE ──────────────────────────────────────────────────────────────── */
.stats {
  list-style: none; margin: 0 0 var(--space-3xl); padding: 0;
  display: grid; gap: var(--space-xl);
}
.stats__item { border-left: 2px solid var(--accent); padding-left: var(--space-lg); }
.stats__value {
  font-family: var(--font-display); font-size: var(--step-5); font-weight: 700;
  line-height: 1; letter-spacing: -.04em; color: var(--text); margin: 0 0 .25em;
}
.stats__unit { font-size: .38em; color: var(--accent); margin-left: .35em; letter-spacing: 0; }
.stats__label { color: var(--text-soft); font-size: var(--step-0); margin: 0; max-width: 34ch; }

.trust { border-top: 1px solid var(--border); padding-top: var(--space-xl); }

/* Grille de logos ──────────────────────────────────────────────────────
   Les fichiers sont deja en blanc detoure : aucun filtre CSS, donc aucune
   alteration au rendu. Un logo officiel en version inversee peut remplacer
   le fichier correspondant sans toucher au style.                        */
.trust__grid {
  --mark: rgba(147, 164, 190, .45);
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0;
}
.trust__grid li { margin-bottom: 0; }

.trust__cell {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 112px;
  padding: 1.4rem 1.1rem;
  background: rgba(255, 255, 255, .022);
}

/* Une croix aux intersections internes seulement : ni premiere rangee,
   ni premiere colonne. */
.trust__cell::before {
  content: '';
  display: none;
  position: absolute;
  top: 0; left: 0;
  width: 9px; height: 9px;
  translate: -50% -50%;
  color: var(--mark);
  background:
    linear-gradient(currentColor, currentColor) center / 100% 1px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1px 100% no-repeat;
  z-index: 1;
}

.trust__cell img {
  max-height: 34px;
  max-width: 124px;
  width: auto; height: auto;
  object-fit: contain;
  opacity: .78;
  transition: opacity var(--t-base) var(--ease);
}
.trust__cell:hover img { opacity: 1; }

/* 2 colonnes : damier de periode 4, croix au seul centre */
@media (max-width: 759.98px) {
  .trust__grid > :nth-child(4n+2),
  .trust__grid > :nth-child(4n+3) { background: rgba(255, 255, 255, .055); }
  .trust__grid > :nth-child(n+3):not(:nth-child(2n+1))::before { display: block; }
}

/* 4 colonnes : damier de periode 8 */
@media (min-width: 760px) {
  .trust__grid { grid-template-columns: repeat(4, 1fr); }
  .trust__grid > :nth-child(8n+2),
  .trust__grid > :nth-child(8n+4),
  .trust__grid > :nth-child(8n+5),
  .trust__grid > :nth-child(8n+7) { background: rgba(255, 255, 255, .055); }
  .trust__grid > :nth-child(n+5):not(:nth-child(4n+1))::before { display: block; }
}

/* ── EN-TETE DE SECTION ──────────────────────────────────────────────────── */
.section__head { max-width: 60ch; margin-bottom: var(--space-2xl); }

/* ── POINTS FORTS ────────────────────────────────────────────────────────── */
.strengths {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--space-lg);
}
.strength { position: relative; overflow: hidden; }
.strength::after {
  content: ''; position: absolute; inset: auto auto 0 0;
  width: 100%; height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t-slow) var(--ease-out);
}
.strength:hover { border-color: var(--border-strong); background: var(--surface-hover); }
.strength:hover::after { transform: scaleX(1); }
.strength__icon {
  display: grid; place-items: center;
  width: 46px; height: 46px; margin-bottom: var(--space-lg);
  border-radius: var(--radius-md);
  background: rgba(255, 122, 47, .1);
  border: 1px solid rgba(255, 122, 47, .25);
  color: var(--accent);
}
.strength__icon svg { width: 22px; height: 22px; }
.strength__title { font-size: var(--step-1); margin-bottom: var(--space-xs); }
.strength__text { color: var(--text-soft); font-size: var(--step-0); margin: 0; }

/* ── CAS CLIENTS ─────────────────────────────────────────────────────────── */
.cases { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-lg); }
.case__link {
  display: grid; height: 100%;
  grid-template-rows: auto 1fr;      /* media, puis le corps prend le reste */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none; color: inherit;
  transition: border-color var(--t-base) var(--ease),
              transform var(--t-base) var(--ease-out);
}
.case__link:hover { border-color: var(--accent); transform: translateY(-4px); }
.case__media { display: block; aspect-ratio: 16 / 10; overflow: hidden; background: var(--bg); }
.case__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform var(--t-slow) var(--ease-out), opacity var(--t-base) var(--ease);
  opacity: .82;
}
.case__link:hover .case__media img { transform: scale(1.05); opacity: 1; }
.case__body {
  display: flex;
  flex-direction: column;
  padding: var(--space-xl);
}
.case__label {
  display: inline-block;
  font-size: var(--step--1); font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent); margin-bottom: var(--space-sm);
}
.case__label--industry     { color: var(--cyan); }
.case__label--serious-game { color: #A78BFA; }
.case__title {
  display: block; font-family: var(--font-display);
  font-size: var(--step-2); font-weight: 600; line-height: 1.15;
  margin-bottom: var(--space-sm);
}
.case__summary { display: block; color: var(--text-soft); font-size: var(--step-0); margin-bottom: var(--space-lg); }
.case__more {
  margin-top: auto;                  /* colle le lien au bas de la carte */
  display: inline-flex; align-items: center; align-self: flex-start; gap: .5em;
  color: var(--accent); font-weight: 600; font-size: var(--step--1);
}
.case__more svg { width: 1.05em; height: 1.05em; transition: transform var(--t-base) var(--ease); }
.case__link:hover .case__more svg { transform: translateX(4px); }

/* ── CONTACT ─────────────────────────────────────────────────────────────── */
.contact { border-top: 1px solid var(--border); }
.contact__inner { display: grid; gap: var(--space-2xl); }
.contact__links { list-style: none; margin: var(--space-xl) 0; padding: 0; display: grid; gap: var(--space-sm); }
.contact__links li { display: flex; align-items: center; gap: .7em; margin: 0; }
.contact__links svg { width: 19px; height: 19px; color: var(--accent); flex: none; }
.contact__links a { color: var(--text); text-decoration: none; font-weight: 500; }
.contact__links a:hover { color: var(--accent); }


/* ── PAGES INTERIEURES ───────────────────────────────────────────────────── */
.phero { position: relative; padding-block: 9rem 3rem; overflow: hidden; }
.phero--plain { border-bottom: 1px solid var(--border); }
.phero__media { position: absolute; inset: 0; z-index: 0; }
.phero__media img { width: 100%; height: 100%; object-fit: cover; }
.phero__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(7,11,20,.9) 0%, rgba(7,11,20,.6) 45%, rgba(7,11,20,.97) 100%);
}
.phero__inner { position: relative; z-index: 1; }
.phero h1 { max-width: 20ch; margin: 0; }

.crumbs {
  display: flex; gap: .6em; align-items: center;
  font-size: var(--step--1); color: var(--text-faint); margin-bottom: var(--space-lg);
}
.crumbs a { color: var(--text-soft); text-decoration: none; }
.crumbs a:hover { color: var(--accent); }

.kicker--industry     { color: var(--cyan); }
.kicker--serious-game { color: #A78BFA; }

.prose h2 { font-size: var(--step-3); margin-top: var(--space-2xl); }
.prose h3 { font-size: var(--step-1); margin-top: var(--space-xl); }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose p, .prose li { color: var(--text-soft); }
.prose figure { margin: var(--space-2xl) 0; }
.prose iframe, .prose video {
  width: 100%; aspect-ratio: 16 / 9; height: auto;
  border-radius: var(--radius-md); border: 1px solid var(--border); background: #000;
}
.prose .wp-block-embed__wrapper { margin: 0; }

/* ── PIED DE PAGE ────────────────────────────────────────────────────────── */
.foot { border-top: 1px solid var(--border); padding-top: var(--space-3xl); background: var(--bg-raised); }
.foot__inner { display: grid; gap: var(--space-2xl); padding-bottom: var(--space-2xl); }
.foot__brand img { height: 30px; width: auto; margin-bottom: var(--space-md); }
.foot__brand p { color: var(--text-soft); font-size: var(--step--1); }
.foot__col h3 { font-size: var(--step--1); letter-spacing: .12em; text-transform: uppercase; color: var(--text-faint); margin-bottom: var(--space-md); }
.foot__col p { color: var(--text-soft); font-size: var(--step--1); margin-bottom: .5em; }
.foot__col a { color: var(--text-soft); text-decoration: none; }
.foot__col a:hover { color: var(--accent); }
.foot__links { list-style: none; margin: 0; padding: 0; }
.foot__links li { margin-bottom: .35em; }
.foot__links a { font-size: var(--step--1); }
.foot__legal { border-top: 1px solid var(--border); padding-block: var(--space-lg); }
.foot__legal p { color: var(--text-faint); font-size: .78rem; line-height: 1.6; margin: 0; }

/* ── PALIERS RESPONSIVE ──────────────────────────────────────────────────── */
@media (min-width: 600px) {
  .stats { grid-template-columns: repeat(3, 1fr); gap: var(--space-lg); }
  .strengths { grid-template-columns: repeat(2, 1fr); }
  .cases { grid-template-columns: repeat(2, 1fr); }
  .foot__inner { grid-template-columns: 1.4fr 1fr 1fr; }
}

@media (min-width: 900px) {
  .masthead__nav { display: block; }
  .masthead__cta { display: inline-flex; }
  .burger { display: none; }
  .hero__title { max-width: 14ch; }
  .contact__inner { grid-template-columns: 1.6fr 1fr; align-items: center; }
}

/* Toutes les cartes ont le meme poids : aucune n'est mise en avant.
   2 colonnes des 600px, 3 a partir de 1000px — meme grille sur l'accueil
   et sur la rubrique. */

/* ============================================================================
   HERO — « chausser le casque »
   La page reste en place via position:sticky (aucun scroll-jacking : le scroll
   natif n'est jamais intercepte). Le JS n'ecrit qu'une variable, --open.
   --w est la taille commune du cache et du casque : les deux grandissent
   exactement au meme rythme, donc les optiques restent alignees.
   ========================================================================= */
.hero {
  position: relative;
  /* 340vh : ~140vh pour la sequence, puis ~100vh de maintien pendant
     lesquels la page reste epinglee sur la video grande ouverte. */
  height: 340vh;
  --open: 0;
  /* --s : l'echelle commune. Casque, optiques ET video la partagent, donc on
     voit toujours le meme contenu a travers les lentilles.
     Elle s'arrete a 1.15 : au-dela, la video serait visiblement upscalee. */
  --s: calc(0.36 + var(--open) * 0.79);
  /* --w et --cx sont des LONGUEURS, pas des pourcentages : en pourcentage,
     mask-position aligne le point X% de l'image sur le point X% du
     conteneur, ce qui ne place PAS le centre de l'image sur --cx. */
  --w: calc(var(--s) * 100vw);
  --cx: 50vw;
}
.hero__pin {
  position: sticky; top: 0;
  height: 100svh;
  overflow: hidden;
  display: grid; align-items: center;
  background: var(--bg);
}

/* couche 0 — la video, toujours plein cadre */
.visor__video {
  position: absolute; z-index: 0;
  width: 100%; height: 100%; object-fit: cover;
  /* meme echelle et meme centre que le casque : les optiques cadrent
     toujours la meme portion d'image, quelle que soit la taille.        */
  left: var(--cx); top: 50%;
  translate: -50% -50%;
  transform: scale(var(--s));
  transform-origin: center;
  will-change: transform;
}

/* couche 1 — le cache : plein ecran MOINS les deux optiques.
   mask-composite:exclude soustrait le masque des optiques d'un aplat.
   C'est ce qui garantit que l'exterieur du casque reste opaque a toute
   echelle, contrairement a un simple masque qui ne couvrirait que sa
   propre surface.                                                        */
.visor__cover {
  position: absolute; inset: 0; z-index: 1;
  background: var(--bg);
  -webkit-mask-image: linear-gradient(#000, #000), url('/assets/images/masks/lens.webp');
          mask-image: linear-gradient(#000, #000), url('/assets/images/masks/lens.webp');
  -webkit-mask-size: 100% 100%, var(--w) auto;
          mask-size: 100% 100%, var(--w) auto;
  -webkit-mask-position: 0 0, calc(var(--cx) - var(--w) / 2) center;
          mask-position: 0 0, calc(var(--cx) - var(--w) / 2) center;
  -webkit-mask-repeat: no-repeat, no-repeat;
          mask-repeat: no-repeat, no-repeat;
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  /* disparait completement sur la toute fin, pour eviter le pont de nez
     residuel au centre quand les optiques sont enormes */
  opacity: clamp(0, calc((1 - var(--open)) * 3.4), 1);
}

/* couche 2 — le casque lui-meme, cale sur la meme largeur que le cache */
.visor__frame {
  position: absolute; z-index: 2;
  left: var(--cx); top: 50%;
  width: var(--w); height: auto;
  translate: -50% -50%;
  pointer-events: none;
  opacity: clamp(0, calc((1 - var(--open)) * 3.1), 1);
}

/* couche 3 — le voile, uniquement quand le texte arrive */
.hero__scrim {
  position: absolute; inset: 0; z-index: 3;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(7,11,20,.84) 0%, rgba(7,11,20,.42) 38%, rgba(7,11,20,.95) 100%),
    radial-gradient(120% 80% at 15% 45%, rgba(7,11,20,.45), transparent 70%);
  /* le voile suit l'ouverture : au depart le fond est deja sombre, il ne
     sert qu'a garder le texte lisible quand la video envahit l'ecran */
  opacity: clamp(0, calc(var(--open) * 1.7), 1);
}

/* Le texte est present du debut a la fin : il ne depend pas de --open.
   Seule la video est masquee par le calque, jamais le contenu.          */
.hero__inner { position: relative; z-index: 4; }
.hero__title { max-width: 16ch; margin-bottom: var(--space-lg); }
.hero__title em { font-style: normal; color: var(--accent); text-shadow: var(--glow-accent); }
.hero__lead { margin-bottom: var(--space-xl); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); }

.hero__scroll {
  position: absolute; left: 50%; bottom: 2rem; z-index: 4;
  translate: -50% 0;
  width: 26px; height: 42px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-full);
  display: grid; justify-items: center; padding-top: 8px;
  opacity: clamp(0, calc(1 - var(--open) * 8), 1);
}
.hero__scroll span {
  width: 3px; height: 7px; border-radius: 2px; background: var(--accent);
  animation: scroll-hint 1.8s var(--ease) infinite;
}
@keyframes scroll-hint {
  0%, 100% { opacity: 0; transform: translateY(0); }
  35%      { opacity: 1; }
  70%      { opacity: 0; transform: translateY(12px); }
}

@media (min-width: 900px) {
  .hero__title { max-width: 14ch; }
  /* 70% au repos -> 50% une fois grand ouvert */
  .hero { --cx: calc(70vw - var(--open) * 20vw); }
}

/* Sans mask-composite, le cache serait l'inverse de ce qu'on veut :
   on prefere alors ne rien masquer du tout plutot qu'afficher un cache
   perce a l'envers.                                                      */
@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .visor__cover, .visor__frame { display: none; }
  .hero { height: 100svh; --open: 1; }
  .hero__pin { position: relative; }
}

/* Sans JS ou en mouvement reduit : etat final, immediatement lisible. */
.no-js .hero { height: auto; --open: 1; }
.no-js .hero__pin { position: relative; }
.no-js .visor__cover, .no-js .visor__frame { display: none; }

@media (prefers-reduced-motion: reduce) {
  .hero { height: auto; --open: 1; }
  .hero__pin { position: relative; }
  .visor__cover, .visor__frame, .hero__scroll { display: none; }
}

/* ── SCENE 3D a cote du titre ────────────────────────────────────────────
   400x300, en vis-a-vis du titre sur grand ecran. Le texte n'est plus
   au-dessus du nuage : le probleme de contraste disparait, on peut donc
   rendre la scene a pleine opacite.                                       */
.forces__head {
  display: grid;
  gap: var(--space-xl);
  margin-bottom: var(--space-2xl);
}
.forces__intro { max-width: 60ch; }

.cloud {
  width: 400px;
  height: 300px;
  max-width: 100%;
  justify-self: center;
  opacity: 0;
  transition: opacity 1100ms var(--ease-out);
  /* le nuage s'eteint sur les bords plutot que de finir en carre net */
  -webkit-mask-image: radial-gradient(closest-side, #000 55%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 55%, transparent 100%);
}
.cloud.is-ready { opacity: 1; }
.cloud[hidden]  { display: none; }
.cloud__canvas  { width: 100%; height: 100%; display: block; }

/* MOBILE : la scene est masquee. Un element en display:none n'entre jamais
   en intersection, donc le JS ne declenche pas l'import : les 166 Ko de
   Three.js et les 65 Ko du nuage ne sont PAS telecharges sur telephone.
   Pour l'afficher malgre tout, sous les cartes : remplacer ce bloc par
   .cloud { order: 2 } et deplacer l'element apres <ul class="strengths">. */
@media (max-width: 899px) {
  .cloud { display: none; }
}

@media (min-width: 900px) {
  .forces__head {
    grid-template-columns: 1fr 400px;
    align-items: center;
    gap: var(--space-2xl);
  }
  .forces__intro { margin: 0; }
}

/* ── FORMULAIRE DE CONTACT ───────────────────────────────────────────────
   Labels toujours visibles (jamais de placeholder en guise d'etiquette),
   erreurs affichees AU PIED DU CHAMP concerne, jamais seulement en tete.  */
.cform { display: grid; gap: var(--space-lg); }

/* piege a robots : sorti du flux sans display:none, que certains bots detectent */
.cform__trap {
  position: absolute; left: -9999px;
  width: 1px; height: 1px; overflow: hidden;
}

.cform__row { display: grid; gap: var(--space-lg); }
.cform__field { display: grid; gap: .4rem; }

.cform label {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--text-soft);
  letter-spacing: .02em;
}
.cform label span { color: var(--accent); }

.cform input[type="text"],
.cform input[type="email"],
.cform textarea {
  width: 100%;
  font: inherit;
  font-size: var(--step-0);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: .72em .9em;
  min-height: 48px;                    /* cible tactile confortable */
  transition: border-color var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease);
}
.cform textarea { resize: vertical; min-height: 130px; line-height: 1.6; }

.cform input:hover, .cform textarea:hover { border-color: var(--text-faint); }
.cform input:focus-visible, .cform textarea:focus-visible {
  border-color: var(--cyan);
  background: var(--surface);
}

/* champ en erreur : la couleur ne porte pas seule l'information,
   le message texte sous le champ la double toujours */
.cform [aria-invalid="true"] { border-color: #FF6B6B; }

.cform__hint { font-size: var(--step--1); color: var(--text-faint); margin: 0; }
.cform__err  { font-size: var(--step--1); color: #FF8A8A; margin: 0; display: none; }
.cform__err.is-on { display: block; }

/* consentement : la case doit rester alignee sur la premiere ligne du label */
.cform__consent {
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: .7rem;
}
.cform__consent input {
  width: 20px; height: 20px; margin-top: .18em;
  accent-color: var(--accent); cursor: pointer;
}
.cform__consent label { font-weight: 400; line-height: 1.55; cursor: pointer; }
.cform__consent .cform__err { grid-column: 1 / -1; }

.cform__foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-md); }
.cform__sending { display: none; }
.cform.is-sending .cform__label   { display: none; }
.cform.is-sending .cform__sending { display: inline; }
.cform.is-sending .cform__submit  { opacity: .75; pointer-events: none; }

.cform__status { margin: 0; font-size: var(--step--1); color: var(--text-soft); }
.cform__status.is-ok { color: #6EE7A8; }
.cform__status.is-ko { color: #FF8A8A; }

@media (min-width: 600px) {
  .cform__row { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 900px) {
  .contact__inner { grid-template-columns: 1fr 1.1fr; align-items: start; gap: var(--space-3xl); }
}

.foot__privacy { margin: .6rem 0 0; }
.foot__privacy a { color: var(--text-soft); font-size: .78rem; text-decoration: underline; }
.foot__privacy a:hover { color: var(--accent); }
.cform__consent label a { color: var(--cyan); }

/* ── ACTUALITES ──────────────────────────────────────────────────────────
   Meme grammaire visuelle que les cas clients, mais en plus sobre : une
   actualite se lit vite, elle ne doit pas concurrencer les cas.          */
.head-row,
.news__head {
  display: flex; flex-wrap: wrap; align-items: end;
  justify-content: space-between; gap: var(--space-lg);
  margin-bottom: var(--space-2xl);
}
.head-row h2,
.news__head h2 { margin: 0; }

.posts { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-lg); }

.post-card__link {
  display: grid; height: 100%;
  grid-template-rows: auto 1fr;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none; color: inherit;
  transition: border-color var(--t-base) var(--ease),
              transform var(--t-base) var(--ease-out);
}
.post-card__link:hover { border-color: var(--accent); transform: translateY(-4px); }

.post-card__media { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--bg); }
.post-card__media img {
  width: 100%; height: 100%; object-fit: cover; opacity: .82;
  transition: transform var(--t-slow) var(--ease-out), opacity var(--t-base) var(--ease);
}
.post-card__link:hover .post-card__media img { transform: scale(1.05); opacity: 1; }

.post-card__body { display: flex; flex-direction: column; padding: var(--space-lg); }
.post-card__date {
  font-size: var(--step--1); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); margin-bottom: var(--space-xs);
}
.post-card__title {
  display: block; font-family: var(--font-display);
  font-size: var(--step-1); font-weight: 600; line-height: 1.2;
  margin-bottom: var(--space-xs);
}
.post-card__excerpt { display: block; color: var(--text-soft); font-size: var(--step--1); }

.post__date {
  display: block; font-size: var(--step--1); font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); margin-bottom: var(--space-sm);
}
.post__back { margin-top: var(--space-2xl); padding-top: var(--space-lg); border-top: 1px solid var(--border); }

@media (min-width: 700px)  { .posts { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .posts--compact { grid-template-columns: repeat(3, 1fr); } }

/* Variante sur fond sombre — à activer le jour où les versions blanches
   OFFICIELLES des logos seront disponibles. Il suffit alors d'ajouter
   « trust__grid--dark » sur le <ul> et de remplacer les fichiers.
   À n'utiliser qu'avec de vraies déclinaisons inversées fournies par les
   marques : un filtre CSS appliqué à une version couleur reste une
   altération, et les chartes l'interdisent presque toujours.             */
.trust__grid--dark {
  --line: var(--border);
  --mark: var(--border-strong);
}
.trust__grid--dark .trust__cell { background: var(--bg-raised); }

/* ── HERO : deux dispositions ────────────────────────────────────────────
   Desktop  — .visor est un calque plein cadre, le texte passe par-dessus.
   Mobile   — .visor descend dans le flux, sous le titre, et s'ouvre en
              pleine LARGEUR (16/9) plutot qu'en plein ecran : un hero
              video pleine hauteur sur telephone rend le texte illisible
              et pousse tout le contenu hors de l'ecran.                  */

/* --- calque plein cadre (defaut, desktop) --- */
.visor { position: absolute; inset: 0; z-index: 0; }

/* --- mobile : le casque suit le titre --- */
@media (max-width: 899px) {
  .hero__pin {
    display: grid;
    grid-template-rows: auto auto;
    align-content: center;
    gap: clamp(1.5rem, 5vw, 2.5rem);
    padding-block: 6rem 3rem;
  }

  .visor {
    position: relative;
    inset: auto;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
  }

  /* le texte n'est plus au-dessus de la video : le voile n'a plus lieu d'etre */
  .hero__scrim { display: none; }

  /* la video remplit la boite, pas la fenetre */
  .visor__video { border-radius: var(--radius-md); }

  .hero__inner { text-align: left; }
  .hero__scroll { display: none; }   /* le geste est evident au doigt */
}

/* ── Etiquettes des realisations ─────────────────────────────────────────
   Deux informations distinctes : le DOMAINE (Marketing, Industrie…) et la
   NATURE du projet (commande client ou production propre). Les separer
   evite de faire passer une production interne pour une reference client.  */
.case__tags {
  /* Empilees, jamais cote a cote : en flex-wrap, deux etiquettes courtes
     tenaient sur une ligne et deux longues passaient a la ligne — les cartes
     dune meme grille navaient donc pas la meme hauteur de bloc. */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .4rem;
  margin-bottom: var(--space-sm);
}

.case__tags__page {
  display: block;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .8rem;
  margin-bottom: var(--space-sm);
}
.case__label { margin-bottom: 0; }

.case__kind__page {
  display: inline-block;
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-faint);
  border: 2px solid var(--border-strong);
  border-radius: var(--radius-full);
  padding: .18em .7em;
  white-space: nowrap;
}

.case__kind {
  display: inline-block;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-faint);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  padding: .18em .7em;
  white-space: nowrap;
}
/* La production interne est signalee plus nettement : cest linformation
   qui pourrait autrement induire en erreur. */
.case__kind--interne {
  color: var(--cyan);
  border-color: color-mix(in srgb, var(--cyan) 45%, transparent);
}

.case__kind--client {
  color: var(--orange);
  border-color: color-mix(in srgb, var(--cyan) 45%, transparent);
}

/* ── Video auto-hebergee dans un article ─────────────────────────────────
   Pas d'aspect-ratio impose : les attributs width/height portent le vrai
   rapport du fichier, le navigateur reserve donc la bonne place avant meme
   d'avoir telecharge quoi que ce soit.                                    */
.prose .video { margin: var(--space-2xl) 0; }

.prose .video video {
  width: 100%;
  height: auto;
  aspect-ratio: auto;              /* annule la regle generique .prose video */
  display: block;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: #000;
}

.prose .video figcaption {
  margin-top: var(--space-sm);
  font-size: var(--step--1);
  color: var(--text-faint);
  line-height: 1.5;
}

/* ── Renvoi vers une autre realisation ───────────────────────────────────
   En fin d'article : garde le lecteur sur le site plutot que de le laisser
   au bout d'une impasse.                                                  */
.prose .next-case {
  margin-top: var(--space-3xl);
  padding: var(--space-lg) var(--space-xl);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
}
.prose .next-case__label {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 0 0 .35rem;
}
.prose .next-case__link {
  display: inline-flex;
  align-items: center;
  gap: .6em;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  line-height: 1.25;
}
.prose .next-case__link:hover { color: var(--accent); }
.prose .next-case__link svg {
  width: .85em; height: .85em; flex: none;
  transition: transform var(--t-base) var(--ease);
}
.prose .next-case__link:hover svg { transform: translateX(4px); }

/* ── Photo paysage dans un article ──────────────────────────────────────
   Occupe toute la colonne de texte. Meme habillage que .shot — cadre,
   arrondi, legende centree — mais sans la bride de largeur.             */
.prose .photo { margin: var(--space-2xl) 0; }
.prose .photo img {
  width: 100%; height: auto;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
}
.prose .photo figcaption {
  margin-top: var(--space-sm);
  font-size: var(--step--1);
  color: var(--text-faint);
  text-align: center;
}

/* ── Capture d'ecran dans un article ─────────────────────────────────────
   Format portrait : sans bride, une capture de 562 px de large occuperait
   toute la colonne et ecraserait le texte autour.                        */
.prose .shot { margin: var(--space-2xl) auto; max-width: 400px; }
.prose .shot img {
  width: 100%; height: auto;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
}
.prose .shot figcaption {
  margin-top: var(--space-sm);
  font-size: var(--step--1);
  color: var(--text-faint);
  text-align: center;
}

/* ── Rubrique Realisations : grille groupee par domaine ──────────────────
   Chaque groupe reprend la couleur de son domaine, la meme que sur les
   kickers des pages de cas — le lecteur retrouve le meme code partout.   */
.section--tight { padding-block: clamp(2rem, 5vw, 3.5rem); }

.group__title {
  font-family: var(--font-body);
  font-size: var(--step--1);
  margin-bottom: var(--space-xl);
}

/* Sur la rubrique, aucune realisation n'est mise en avant : toutes les
   cartes ont le meme poids, contrairement au bento de l'accueil.        */
@media (min-width: 1000px) {
  .cases { grid-template-columns: repeat(3, 1fr); }
}

/* Seconde pastille : le domaine. Elle reprend la couleur deja utilisee
   pour les kickers du meme domaine, donc le code couleur reste constant
   d'une page a l'autre.                                                  */
.case__kind--topic { border-color: currentColor; opacity: .9; }
.case__kind--marketing     { color: var(--accent); }
.case__kind--industry      { color: var(--cyan); }
.case__kind--serious-game  { color: #A78BFA; }

/* Decision & Strategie : quatrieme domaine. Teinte or, distincte des trois
   autres (orange marketing, cyan industrie, violet ludique) et a 11.7:1 sur
   le fond — largement au-dessus du seuil AA. */
.case__kind--decision { color: #E8C468; }
.kicker--decision     { color: #E8C468; }

/* Sante : vert. Choisi pour son ecart de teinte — 58 degres du cyan de
   l'industrie, le plus proche des quatre autres domaines. Un vert plus
   bleute se serait confondu avec lui sur une petite etiquette. 11.3:1. */
.case__kind--health { color: #4ADE80; }
.kicker--health     { color: #4ADE80; }

/* ─────────────────────────────────────────────────────────────────────────
   BANDEAU DE CONSENTEMENT

   Pose en bas de fenetre, jamais en plein ecran : il ne masque pas le
   contenu et ne piege pas le clavier. Un visiteur qui l'ignore peut lire
   tout le site — rien n'est charge tant qu'il n'a pas repondu, donc rien
   ne justifie de lui barrer la route.

   Les deux boutons ont EXACTEMENT la meme taille et le meme poids visuel.
   La CNIL demande que refuser soit aussi simple qu'accepter : meme nombre
   de clics, meme visibilite. Seule la couleur de fond les distingue, et
   c'est deja a la limite de ce qui se defend.
   ───────────────────────────────────────────────────────────────────────── */
.consent {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 60;                       /* au-dessus du contenu, sous le tiroir */
  background: var(--surface);
  border-top: 1px solid var(--border-strong);
  box-shadow: 0 -12px 40px -20px rgb(0 0 0 / .8);
  padding: var(--space-md) var(--space-lg);
}
.consent:focus { outline: none; }
.consent:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.consent__inner {
  max-width: var(--wrap);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  flex-wrap: wrap;
}
.consent__text  { flex: 1 1 22rem; }
.consent__title { font-weight: 600; color: var(--text); margin: 0 0 .2em; }
.consent__text p {
  margin: 0;
  font-size: var(--step--1);
  color: var(--text-soft);
  max-width: 62ch;
}
.consent__text a { color: var(--cyan); }

.consent__actions { display: flex; gap: var(--space-sm); flex: none; }

/* Largeur commune : les deux boutons font la meme taille quel que soit le
   libelle, en francais comme en anglais. */
.btn--consent {
  min-width: 10rem;
  background: var(--bg-raised);
  color: var(--text);
  border-color: var(--border-strong);
}
.btn--consent:hover { background: var(--surface-hover); border-color: var(--accent); }
.btn--consent-ok    { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn--consent-ok:hover { background: var(--accent-hot); color: var(--accent-ink); }

@media (max-width: 40rem) {
  .consent { padding: var(--space-md); }
  .consent__actions { width: 100%; }
  .consent__actions .btn { flex: 1 1 0; min-width: 0; }
}
