@charset "UTF-8";
/* ═══════════════════════════════════════════════════════════════════════════
   CréaByte — feuille de la refonte
   ---------------------------------------------------------------------------
   Elle remplace index.css, style.css et projets.css d'un seul tenant. De
   Bootstrap on ne prend que la MÉCANIQUE — tiroir, onglets, modale, quelques
   utilitaires d'affichage — et pas une ligne de son allure : ce site a une
   identité (circuit imprimé, plaque noire vitrée, matrice binaire) et un
   gabarit reconnaissable l'aurait mangée.

   Ce qui a disparu avec les iframes :
     · les onze translations de 648 px du diaporama, écrites douze fois ;
     · les hauteurs de 780 px répétées dans une vingtaine de règles ;
     · la question « qui peut couvrir quoi », puisqu'il n'y a plus qu'un
       document — c'est elle qui laissait les flèches par-dessus
       l'agrandissement.

   Ce qui a été conservé sciemment :
     · le fond cadetblue, la violette des liens, le rouge et le vert du texte ;
     · les 720 ms de l'éclair, et sa simultanéité avec la planche illuminée ;
     · le survol des vignettes en `translateY(-2px) scale(1.04)` ;
     · le dépassement en fin de course de l'agrandissement, cubic-bezier
       (0.2, 0.9, 0.3, 1.18) — le 1,18 final EST le rebond.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Le bus de la planche ──────────────────────────────────────────────────
 * Ce bloc est ÉCRIT ICI par tools/injecter-decor.py — ne pas le modifier à la
 * main, il sera réécrit.
 *
 * Il était jusqu'au 14 août dans un fichier à part, appelé par `@import`. Un
 * envoi FTP incomplet l'a laissé sur le carreau, et le navigateur a signalé
 * « failed to load a stylesheet » sans que rien n'indique lequel ni pourquoi.
 * Une dépendance de moins est une panne de moins : le dégradé fait 800 octets,
 * il n'a rien à faire dans un second fichier.
 */
/* bus:début */
.cb-bus{background-image:linear-gradient(to bottom, transparent 0px, transparent 8px, currentColor 8px, currentColor 12px, transparent 12px, transparent 13px, currentColor 13px, currentColor 17px, transparent 17px, transparent 18px, currentColor 18px, currentColor 22px, transparent 22px, transparent 23px, currentColor 23px, currentColor 27px, transparent 27px, transparent 28px, currentColor 28px, currentColor 32px, transparent 32px, transparent 33px, currentColor 33px, currentColor 37px, transparent 37px, transparent 38px, currentColor 38px, currentColor 42px, transparent 42px, transparent 44px, currentColor 44px, currentColor 48px, transparent 48px, transparent 50px, currentColor 50px, currentColor 54px, transparent 54px, transparent 60px)}
/* bus:fin */

:root {
  --cb-fond:          #5f9ea0;          /* cadetblue, la couleur du site */
  --cb-fond-barre:    #3f6d6f;
  --cb-encre:         #24313a;
  --cb-rouge:         #c61800;
  --cb-vert:          #18a600;
  --cb-violet:        hsl(260 100% 78%);

  --cb-barre:         196px;            /* barre repliée */
  --cb-barre-deplie:  304px;            /* barre dépliée, en recouvrement */
  --cb-plaque:        146px;            /* largeur d'affichage de la plaque */

  --cb-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, sans-serif;
  --cb-mono: ui-monospace, SFMono-Regular, Menlo, Consolas,
             "Droid Sans Mono", monospace;
}

/* ── Fond de page ───────────────────────────────────────────────────────── */

html, body { height: 100%; }

.cb-corps {
  margin: 0;
  background: var(--cb-fond);
  color: var(--cb-encre);
  font-family: var(--cb-sans);
  overscroll-behavior-y: none;
}

/* ═══ LA BARRE ══════════════════════════════════════════════════════════════
 * Sous 768 px, `offcanvas-md` en fait un tiroir : ouverture à l'appui, bouton
 * de fermeture, piège de focus, arrière-plan verrouillé. Au-delà, Bootstrap la
 * rend statique et transparente — on la reprend en colonne fixe, d'où les
 * quelques `!important` qui suivent : ils ne servent qu'à défaire ça.
 * ═══════════════════════════════════════════════════════════════════════════ */

.cb-barre {
  --bs-offcanvas-width: 304px;
  --bs-offcanvas-bg: var(--cb-fond-barre);
  --bs-offcanvas-color: #fff;
}

.cb-barre .cb-barre__corps { position: relative; flex: 1 1 auto; padding: 0; overflow: hidden; }

.cb-poignee {                            /* le bandeau du haut, sur mobile */
  position: sticky;
  top: 0;
  z-index: 1030;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 52px;
  padding: 8px 16px;
  border: 0;
  border-bottom: 1px solid rgb(0 0 0 / 0.18);
  background: var(--cb-fond-barre);
  color: #fff;
}
.cb-poignee__traits { position: relative; width: 22px; height: 2px; background: currentColor; }
.cb-poignee__traits::before,
.cb-poignee__traits::after {
  content: ""; position: absolute; left: 0; width: 22px; height: 2px; background: currentColor;
}
.cb-poignee__traits::before { top: -7px; }
.cb-poignee__traits::after  { top:  7px; }
.cb-poignee__mot { font-weight: 600; letter-spacing: 0.06em; }

/* ── Le décor de la barre ──────────────────────────────────────────────────
 * Trois calques superposés : la matrice au fond, la plaque par-dessus,
 * l'éclair par-dessus tout. C'est l'ordre d'origine (z-index 1, 2, 3), et
 * c'est lui qui fait l'effet : l'éclair passe DEVANT la plaque.
 */

.cb-matrice {
  position: absolute;
  inset: 2% auto 2% 0;
  width: 100%;
  height: 96%;
  object-fit: contain;
  object-position: left center;
  opacity: 0.9;
  pointer-events: none;
  z-index: 1;
}

.cb-plaque {
  position: absolute;
  top: 50%;
  left: 2px;
  height: min(86%, 520px);
  width: auto;
  transform: translateY(-50%);
  pointer-events: none;
  z-index: 2;
}

.cb-eclair-boite {
  position: absolute;
  inset: 0 auto 0 -6%;
  width: 118%;
  z-index: 3;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease-in-out;
}
.cb-eclair-boite.est-visible { opacity: 1; }

/* L'état « plein » n'est plus une seconde image : c'est le même tracé, plus
   lumineux et nimbé. Il peut donc s'allumer À LA MILLISECONDE en même temps
   que la planche — c'est cette simultanéité qui fait l'effet, pas l'éclair. */
.cb-eclair-boite.est-pleine {
  opacity: 1;
  filter: drop-shadow(0 0 14px rgb(255 255 255 / 0.95))
          drop-shadow(0 0 34px rgb(200 230 255 / 0.75))
          brightness(1.35);
  transition: opacity 0.2s ease-in-out, filter 0.2s ease-in-out;
}
.cb-eclair { display: block; width: 100%; height: 100%; }

/* ── Les trois rubriques ───────────────────────────────────────────────── */

.cb-liens {
  position: absolute;
  inset: 0 0 0 auto;
  left: calc(var(--cb-plaque) + 4px);
  z-index: 4;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: flex-start;
  padding: 24px 0;
}

.cb-lien {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;                      /* cible tactile : 44 px, pas 34 */
  padding: 5px 6px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: hsl(260 100% 78% / 0.72);
  font: 600 17px/1.1 var(--cb-sans);
  white-space: nowrap;
  cursor: pointer;
  -webkit-text-stroke: 1px hsl(0 0% 78% / 0.7);
  transition: color 0.5s ease-in-out, -webkit-text-stroke-color 0.4s ease-in-out;
}
.cb-lien img { width: 34px; height: 34px; flex: 0 0 34px; transition: transform 0.2s ease-out; }
.cb-lien:hover, .cb-lien:focus-visible { color: hsl(260 100% 100%); -webkit-text-stroke-color: hsl(0 0% 0%); }
.cb-lien:hover img { transform: scale(1.12); }
.cb-lien.active { color: #fff; -webkit-text-stroke-color: hsl(0 0% 0% / 0.85); }
.cb-lien:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* Le mot n'apparaît qu'au dépli. `visibility` en plus de l'opacité : un
   libellé transparent resterait cliquable et lisible par un lecteur d'écran
   alors qu'il est, pour tout le monde, absent. */
.cb-lien span { opacity: 1; visibility: visible; transition: opacity 0.18s ease-out, visibility 0.18s; }

.cb-son {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgb(0 0 0 / 0.18);
  cursor: pointer;
  transition: background 0.15s ease;
}
.cb-son:hover { background: rgb(0 0 0 / 0.32); }
.cb-son img { width: 24px; height: 24px; opacity: 0.85; }

/* ═══ LA SCÈNE ══════════════════════════════════════════════════════════════ */

.cb-scene { position: relative; }

/* ── La planche du circuit ─────────────────────────────────────────────────
 * Quatre morceaux ancrés aux quatre coins, et entre les deux du bas un bus
 * tracé au dégradé. La tranche de 4 px répétée a disparu, et avec elle sa
 * couture : une ligne horizontale étirée horizontalement reste la même ligne.
 *
 * Les couleurs sont des variables. La planche illuminée n'est donc PAS un
 * second jeu d'images à charger et à garder synchronisé : c'est le même
 * dessin, une classe plus loin. Et comme `color` est animable, le dégradé du
 * bus — qui s'y réfère par `currentColor` — s'illumine avec le reste.
 */

.cb-planche {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;

  --cb-piste:  #2e2e2e;
  --cb-puce:   #767676;
  --cb-ombre:  #141414;
  --cb-broche: #c3c3c3;
}
.cb-planche.est-illuminee {
  --cb-piste:  #eef5f6;
  --cb-puce:   #e6eff0;
  --cb-ombre:  #cfdedf;
  --cb-broche: #ffffff;
}

.cb-coin { position: absolute; }
.cb-coin--hg { top: 0;    left: 0;  }
.cb-coin--hd { top: 0;    right: 0; }
.cb-coin--bg { bottom: 0; left: 0;  }
.cb-coin--bd { bottom: 0; right: 0; }

.cb-piste           { stroke: var(--cb-piste);  transition: stroke 0.2s ease-in-out; }
.cb-puce, .cb-boitier { fill: var(--cb-puce);   transition: fill 0.2s ease-in-out; }
.cb-ombre           { fill: var(--cb-ombre);    transition: fill 0.2s ease-in-out; }
.cb-broche rect     { fill: var(--cb-broche);   transition: fill 0.2s ease-in-out; }

.cb-bus {
  position: absolute;
  left: 115px;
  right: 160px;
  bottom: 0;
  height: 60px;
  display: block;
  color: var(--cb-piste);
  transition: color 0.2s ease-in-out;
}

/* ── Le cadre de contenu ───────────────────────────────────────────────── */

.cb-cadre { position: relative; z-index: 1; }
.cb-cadre > .tab-content { height: 100%; }

.cb-page { padding: 26px 22px 34px; }
.cb-page:focus-visible { outline: none; }

.cb-titre-maison {
  margin: 0 0 22px;
  font: 400 clamp(21px, 3.4vw, 30px)/1.28 var(--cb-sans);
  letter-spacing: -0.01em;
  text-align: center;
  color: #12222b;
  text-shadow: 0 2px 6px rgb(0 0 0 / 0.18);
}

/* Le cartouche de texte : monospace, fond et filet rouge très pâles. C'est le
   `.description` d'origine, au pixel de padding près. */
.cb-texte {
  padding: 14px 20px;
  border: 1px solid rgb(198 24 0 / 0.2);
  border-radius: 8px;
  background: rgb(255 0 0 / 0.05);
  font: 13px/1.5 var(--cb-mono);
  text-align: left;
}
.cb-texte p { margin: 0 0 0.95em; }
.cb-texte p:last-child { margin-bottom: 0; }
.cb-texte b { font-weight: 700; color: var(--cb-rouge); }
.cb-signature { margin-top: 1.4em; color: #55606a; }

/* ── La rubrique « contact » ───────────────────────────────────────────────
 * Elle ne contenait qu'une adresse, centrée dans le vide. Une adresse seule ne
 * dit ni à quoi elle sert ni ce qu'on peut en attendre. La page a maintenant
 * du contenu : le centrage vertical saute, sinon il se battrait avec lui.
 */

/* De la garde en bas : la dernière ligne ne doit jamais tomber pile sur le bus
   du circuit, qui passe derrière. */
.cb-page--contact { padding-bottom: 48px; }

.cb-chapeau {
  max-width: 44em;
  margin: 0 0 22px;
  font-size: 16px;
  line-height: 1.55;
  color: #1c3b44;
}

.cb-adresse {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 26px;
  padding: 16px 18px;
  border: 1px solid rgb(198 24 0 / 0.25);
  border-radius: 10px;
  background: rgb(255 255 255 / 0.55);
}
.cb-adresse__lien {
  flex: 1 1 auto;
  color: var(--cb-rouge);
  font: 600 clamp(16px, 2.4vw, 22px) var(--cb-mono);
  text-decoration: none;
  word-break: break-all;
  transition: color 0.15s ease;
}
.cb-adresse__lien:hover { color: var(--cb-vert); }
.cb-adresse__copier {
  flex: 0 0 auto;
  min-height: 40px;
  padding: 9px 16px;
  border: 1px solid rgb(0 0 0 / 0.18);
  border-radius: 8px;
  background: #fff;
  color: #33474f;
  font: 600 13px var(--cb-sans);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.cb-adresse__copier:hover { background: #f2f6f7; }
/* Le bouton dit ce qui s'est passé plutôt que de faire apparaître une bulle
   ailleurs : c'est là qu'on regarde au moment du clic. */
.cb-adresse__copier.est-copiee {
  background: rgb(24 166 0 / 0.12);
  border-color: rgb(24 166 0 / 0.45);
  color: var(--cb-vert);
}

.cb-motifs { margin: 0 0 26px; }
.cb-motifs dt {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid rgb(0 0 0 / 0.12);
  font: 600 15px var(--cb-sans);
  color: #12222b;
}
.cb-motifs dt:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.cb-motifs dd {
  margin: 5px 0 0;
  font-size: 14px;
  line-height: 1.55;
  color: #2c4149;
}
.cb-motifs a {
  color: var(--cb-rouge);
  text-decoration: none;
  border-bottom: 1px solid rgb(198 24 0 / 0.35);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.cb-motifs a:hover { color: var(--cb-vert); border-bottom-color: rgb(24 166 0 / 0.5); }

.cb-texte--serre { font-size: 12.5px; }

/* ── Mentions légales ─────────────────────────────────────────────────────
 * Repliées : elles sont obligatoires, pas intéressantes. Mais elles restent
 * DANS le document, ouvertes ou non — un lecteur d'écran et un moteur de
 * recherche les trouvent quand même.
 */

/* Ouvertes, les mentions descendent jusqu'au bas du cadre — c'est-à-dire
   par-dessus le bus de la planche, et un texte sombre sur des traits sombres ne
   se lit plus. Elles prennent donc un fond dès qu'on les déplie, comme les
   fiches produit et le cartouche de « à propos ». Repliées, elles restent une
   simple pastille. */
.cb-legal { margin-top: 28px; }
.cb-legal[open] {
  padding: 14px 16px 16px;
  border: 1px solid rgb(0 0 0 / 0.12);
  border-radius: 10px;
  background: rgb(255 255 255 / 0.5);
}
.cb-legal > summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 10px 14px;
  border: 1px solid rgb(0 0 0 / 0.16);
  border-radius: 8px;
  background: rgb(255 255 255 / 0.35);
  font: 600 13px var(--cb-sans);
  color: #2c4149;
  cursor: pointer;
  list-style: none;
}
.cb-legal > summary::-webkit-details-marker { display: none; }
.cb-legal > summary::before { content: "▸"; font-size: 11px; }
.cb-legal[open] > summary::before { content: "▾"; }
.cb-legal > summary:hover { background: rgb(255 255 255 / 0.6); }
.cb-legal[open] > summary { margin-bottom: 14px; }
.cb-legal h2 {
  margin: 18px 0 6px;
  font: 600 13px var(--cb-sans);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #1c3b44;
}
.cb-legal h2:first-of-type { margin-top: 0; }
.cb-legal p { margin: 0 0 10px; font-size: 13px; line-height: 1.6; color: #2c4149; }
.cb-legal a { color: var(--cb-rouge); }

/* Impossible à rater, et c'est le but : tant qu'il en reste une, les mentions
   ne sont pas valables. */
.cb-a-remplir {
  padding: 1px 6px;
  border-radius: 4px;
  background: #ffe89a;
  color: #6b4b00;
  font-weight: 600;
}

/* ═══ LES PROJETS ═══════════════════════════════════════════════════════════
 * Un conteneur en défilement par accroche. Aucune arithmétique : le pas du
 * diaporama EST la largeur d'une fiche, quelle qu'elle soit, et le doigt est
 * géré par le navigateur. Sous 768 px la même liste devient une colonne — on
 * lit un catalogue au lieu de balayer onze diapositives.
 * ═══════════════════════════════════════════════════════════════════════════ */

.cb-page--projets { position: relative; padding: 0; }

.cb-diapo {
  display: flex;
  height: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.cb-diapo::-webkit-scrollbar { display: none; }
.cb-diapo:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }

.cb-fiche {
  flex: 0 0 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  overflow-y: auto;
  padding: 24px 20px 34px;
  overscroll-behavior: contain;
}

.cb-fiche__contenu {
  max-width: 560px;
  margin: 0 auto;
  padding: 22px 24px 26px;
  background: linear-gradient(to top, #bbd, #fff);
  box-shadow: 0 6px 22px rgb(0 0 0 / 0.22);
}
/* L'alternance des coins arrondis d'une fiche à l'autre : c'était déjà là, et
   ça se remarque quand on fait défiler. */
.cb-fiche:nth-child(odd)  .cb-fiche__contenu { border-radius: 0 20px; }
.cb-fiche:nth-child(even) .cb-fiche__contenu { border-radius: 20px 0; }

.cb-fiche__titre {
  margin: 0;
  font: 400 clamp(26px, 4.4vw, 38px)/1.1 var(--cb-sans);
  letter-spacing: -0.04em;
  color: #000;
  text-shadow: 0 2px 5px rgb(0 0 0 / 0.2);
}
.cb-fiche__plateforme { margin: 6px 0 16px; font-size: 15px; color: #3f3f3f; }
.cb-fiche__note { color: #6b6b70; font-size: 13px; }

.cb-fiche__liens { margin: 14px 0 0; font-size: 12px; }
.cb-fiche__liens a {
  margin-right: 16px;
  padding-bottom: 1px;
  border-bottom: 1px solid rgb(198 24 0 / 0.35);
  color: var(--cb-rouge);
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.cb-fiche__liens a:hover { color: var(--cb-vert); border-bottom-color: rgb(24 166 0 / 0.5); }

.cb-fiche__etat { margin: 16px 0 0; text-align: right; }
.cb-fiche__etat img { width: 180px; height: 54px; }

/* ── Les vignettes ─────────────────────────────────────────────────────────
 * Bornées en hauteur ET en largeur : le catalogue va du jeu en paysage
 * (422 × 317) au téléphone très allongé (416 × 900), et une seule contrainte
 * laisserait les seconds en fils à couper le beurre. L'écart passe de 8 à
 * 12 px : à 8, au doigt, on ouvrait la mauvaise.
 */

.cb-vignettes { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin-top: 16px; }
.cb-vignettes__aide { flex-basis: 100%; margin: 0; font-size: 11px; color: #6b6b70; }

.cb-vignette {
  max-height: 88px;
  max-width: 104px;
  min-width: 44px;
  min-height: 44px;
  width: auto;
  height: auto;
  display: block;
  border: 1px solid rgb(0 0 0 / 0.18);
  border-radius: 4px;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.18);
  cursor: zoom-in;
  transition: transform 0.18s ease-out, box-shadow 0.18s ease-out;
}
/* Le `transform` plutôt qu'une largeur : composité par le GPU, aucun recalcul
   de mise en page. `:active` en plus de `:hover`, le survol n'existant pas au
   doigt. */
.cb-vignette:hover, .cb-vignette:focus-visible, .cb-vignette:active {
  transform: translateY(-2px) scale(1.04);
  box-shadow: 0 5px 14px rgb(0 0 0 / 0.3);
  outline: none;
}
.cb-vignette:focus-visible { box-shadow: 0 0 0 3px var(--cb-violet); }

/* ── Flèches et pastilles du diaporama ─────────────────────────────────── */

.cb-fleche {
  position: absolute;
  top: 50%;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-top: -22px;
  padding: 0;
  border: 1px solid rgb(255 255 255 / 0.3);
  border-radius: 50%;
  background: rgb(0 0 0 / 0.22);
  cursor: pointer;
  transition: background 0.15s ease, opacity 0.15s ease;
}
.cb-fleche svg path { fill: #fff; }
.cb-fleche:hover { background: rgb(0 0 0 / 0.4); }
.cb-fleche[disabled] { opacity: 0.2; cursor: default; }
.cb-fleche--prec { left: 6px; }
.cb-fleche--suiv { right: 6px; }

.cb-pastilles {
  position: absolute;
  left: 0; right: 0; bottom: 8px;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: 7px;
  pointer-events: none;
}
.cb-pastille {
  width: 8px; height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.4);
  pointer-events: auto;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}
.cb-pastille[aria-selected="true"] { background: #fff; transform: scale(1.35); }

/* ═══ L'AGRANDISSEMENT ══════════════════════════════════════════════════════
 * Modale Bootstrap pour la mécanique (piège de focus, Échap, défilement
 * verrouillé), CSS maison pour le mouvement. Les deux morceaux du rebond :
 *   1. la carte NAÎT du rectangle de la vignette — le JS pose la
 *      transformation de départ ; comme la vignette et la grande version sont
 *      le même fichier, il est déjà décodé et rien ne saute ;
 *   2. le dépassement en fin de course : 1,18 au bout de la courbe. Un
 *      `ease-out` ordinaire donnerait une boîte qui apparaît, pas un zoom.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Le fond appartient au voile de Bootstrap, pas à la modale : c'est lui qui
   ferme au clic à côté, et lui donner NOTRE couleur évite d'en superposer
   deux. Il couvre tout, flèches du diaporama comprises — la question « qui
   peut couvrir quoi » ne se pose plus, il n'y a qu'un document. */
.modal-backdrop.show {
  --bs-backdrop-opacity: 1;
  background-color: rgb(18 18 22 / 0.82);
  backdrop-filter: blur(3px);
}
.cb-loupe { --bs-modal-width: auto; }
.cb-loupe .modal-dialog {
  max-width: none;
  width: fit-content;
  margin: 0 auto;
  transform-origin: center center;
  will-change: transform;
  transition: transform 0.32s cubic-bezier(0.2, 0.9, 0.3, 1.18), opacity 0.22s ease-out;
}
.cb-loupe__cadre {
  padding: 10px;
  border: 1px solid rgb(0 0 0 / 0.15);
  border-radius: 10px;
  background: #fbfbfd;
  box-shadow: 0 18px 45px rgb(0 0 0 / 0.55);
}
.cb-loupe__image {
  display: block;
  margin: 0 auto;
  max-width: min(1100px, calc(100vw - 96px));
  max-height: calc(100dvh - 150px);
  width: auto; height: auto;
  border-radius: 5px;
  background: #000;
}
/* `width: 0` retire la légende du calcul de largeur intrinsèque de la carte,
   `min-width: 100%` la fait ensuite se replier sur la largeur retenue. Sans
   cela une légende d'une ligne élargit le cadre — mesuré à 493 px pour une
   image de 416 — et la carte paraît décentrée autour de sa propre image. */
.cb-loupe__legende {
  width: 0; min-width: 100%;
  margin: 0;
  padding: 8px 4px 2px;
  box-sizing: border-box;
  font: 11px/1.45 var(--cb-sans);
  color: #3f3f3f;
  text-align: center;
}
.cb-loupe__legende:empty { display: none; }

.cb-loupe__nav, .cb-loupe__fermer {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid rgb(255 255 255 / 0.22);
  border-radius: 50%;
  background: rgb(255 255 255 / 0.1);
  color: #fff;
  cursor: pointer;
  transition: background 0.15s ease, opacity 0.15s ease;
}
.cb-loupe__nav { top: 50%; width: 44px; height: 44px; margin-top: -22px; }
.cb-loupe__nav svg path { fill: var(--cb-violet); }
.cb-loupe__nav--prec { left: 12px; }
.cb-loupe__nav--suiv { right: 12px; }
.cb-loupe__nav:hover, .cb-loupe__fermer:hover { background: rgb(255 255 255 / 0.26); }
.cb-loupe__nav[disabled] { opacity: 0.22; cursor: default; }
.cb-loupe__nav[hidden] { display: none; }
.cb-loupe__fermer { top: 12px; right: 14px; width: 34px; height: 34px; font-size: 22px; line-height: 1; }
.cb-loupe__compteur {
  position: absolute;
  left: 0; right: 0; bottom: 14px;
  margin: 0;
  font: 11px var(--cb-sans);
  letter-spacing: 0.08em;
  color: rgb(255 255 255 / 0.65);
  text-align: center;
  pointer-events: none;
}

/* ═══ SOUS 768 PX ═══════════════════════════════════════════════════════════
 * Une colonne. Le décor de 1024 px disparaît : réduit, il devient du bruit
 * gris qui coûte 200 Ko, et il raconte un poste de travail — un téléphone n'en
 * est pas un. La plaque reste : c'est la marque.
 * ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767.98px) {
  .cb-planche { display: none; }

  .cb-barre__corps { display: flex; flex-direction: column; padding: 8px 0 16px; }
  .cb-matrice { display: none; }
  .cb-plaque {
    position: static;
    transform: none;
    align-self: center;
    height: 240px;
    margin: 6px 0 16px;
  }
  .cb-eclair-boite { display: none; }
  .cb-liens { position: static; padding: 0 12px; gap: 6px; }
  .cb-lien { width: 100%; min-height: 52px; font-size: 19px; }
  .cb-son { position: static; align-self: flex-start; margin: 16px 0 0 14px; }

  .cb-cadre { padding-bottom: 24px; }

  /* Le diaporama redevient une liste : sur un écran de 390 px, onze fiches
     empilées se lisent, onze diapositives à balayer non. */
  .cb-diapo {
    display: block;
    height: auto;
    overflow: visible;
    scroll-snap-type: none;
  }
  .cb-fiche { overflow: visible; padding: 0 14px; margin-bottom: 18px; }
  .cb-fiche__contenu { padding: 18px 16px 22px; }
  .cb-page { padding: 18px 14px 28px; }
  .cb-page--projets { padding: 14px 0 8px; }

  /* Cibles tactiles : les vignettes montent à 96 px de haut, largement
     au-dessus du minimum de 44. */
  .cb-vignette { max-height: 96px; max-width: 120px; }
}

/* ═══ À PARTIR DE 768 PX ════════════════════════════════════════════════════
 * La scène occupe la fenêtre, et c'est le CADRE qui défile — pas la page. On
 * retrouve le poste de travail d'origine, mais sans une seule hauteur en dur :
 * `100dvh` suit la barre d'adresse au lieu de la subir.
 * ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 768px) {
  .cb-corps { overflow: hidden; }

  .cb-barre.offcanvas-md {
    position: fixed !important;
    inset: 0 auto 0 0;
    width: var(--cb-barre);
    height: 100dvh;
    overflow: hidden;
    background: var(--cb-fond-barre) !important;
    box-shadow: 2px 0 14px rgb(0 0 0 / 0.22);
    z-index: 10;
    transition: width 0.28s cubic-bezier(0.25, 0.8, 0.3, 1);
  }

  .cb-barre .cb-barre__corps { height: 100%; }

  /* Le cadre est centré dans la scène, franchement, sans réserve d'aucune
     sorte. La première version en gardait une à gauche, large du dépli de la
     barre, pour qu'elle ne puisse jamais recouvrir le contenu — mais le remède
     se voyait plus que le mal : tout le site penchait de 108 px vers la
     droite. C'est le dépli qui s'adapte maintenant (voir plus bas), pas le
     centrage qui recule devant lui. */
  .cb-scene {
    margin-left: var(--cb-barre);
    height: 100dvh;
    overflow: hidden;
  }

  .cb-cadre {
    height: 100%;
    max-width: 680px;
    margin: 0 auto;
  }
  .cb-page { height: 100%; overflow-y: auto; }
  .cb-page--projets { overflow: hidden; }

  /* ── Les libellés quand la barre ne peut pas se déplier ─────────────────
   * Entre 768 et 1120 px, le dépli est désactivé (voir le bloc suivant) :
   * il passerait par-dessus le cadre. Les mots ne disparaissent pas pour
   * autant — ils passent SOUS les icônes, et la plaque se resserre juste ce
   * qu'il faut pour leur laisser la place. La barre garde sa largeur, le
   * contenu son centrage, et personne ne perd la lecture des rubriques.
   */
  .cb-lien {
    flex-direction: column;
    gap: 3px;
    width: 100%;
    padding: 6px 2px;
    font-size: 12px;
    background: rgb(10 22 24 / 0.82);
    /* Le contour de 1 px, dessiné pour du 17 px, mangeait la moitié d'une
       lettre de 12. Ici c'est le fond sombre qui détache le mot du champ de
       points, pas un liseré. */
    -webkit-text-stroke: 0;
    text-shadow: 0 1px 2px rgb(0 0 0 / 0.6);
  }
  .cb-lien:hover, .cb-lien.active { background: rgb(10 22 24 / 0.94); -webkit-text-stroke: 0; }
  .cb-lien img { width: 30px; height: 30px; flex: 0 0 30px; }
  .cb-liens { left: 108px; align-items: center; gap: 10px; padding: 20px 4px; }
  .cb-plaque { height: min(80%, 470px); }
}

/* ── Au-delà de 1120 px : le dépli au survol ─────────────────────────────────
 *
 * Le seuil n'est pas choisi au jugé, il se calcule. Le cadre fait 680 px et se
 * centre dans (largeur − 196) ; son bord gauche tombe donc à
 * 196 + (largeur − 876) / 2, et il faut qu'il dépasse les 304 px de la barre
 * ouverte. L'égalité se produit à 1092 px ; on prend 1120 pour garder une
 * marge de manœuvre au-dessus des flèches du diaporama.
 *
 * En dessous, la barre reste repliée : elle passerait sinon par-dessus le
 * cadre, et c'est exactement ce qu'on refuse de laisser arriver.
 */
@media (min-width: 1120px) and (hover: hover) {
  .cb-lien { flex-direction: row; gap: 12px; width: auto; font-size: 17px; padding: 5px 6px; }
  .cb-lien img { width: 34px; height: 34px; flex: 0 0 34px; }
  .cb-liens { left: calc(var(--cb-plaque) + 4px); align-items: flex-start; }
  .cb-plaque { height: min(86%, 520px); }

  .cb-lien span { opacity: 0; visibility: hidden; }
  .cb-barre.offcanvas-md:hover { width: var(--cb-barre-deplie); }
  .cb-barre.offcanvas-md:hover .cb-lien span {
    opacity: 1; visibility: visible; transition-delay: 0.1s;
  }
  /* `:has(:focus-visible)` et non `:focus-within` : au clic à la souris, le
     bouton garde le focus, et la barre serait restée ouverte en travers de la
     planche jusqu'au clic suivant. Au clavier, elle s'ouvre. Règle à part,
     pour qu'un navigateur sans `:has` ignore celle-ci seule. */
  .cb-barre.offcanvas-md:has(.cb-lien:focus-visible) { width: var(--cb-barre-deplie); }
  .cb-barre.offcanvas-md:has(.cb-lien:focus-visible) .cb-lien span {
    opacity: 1; visibility: visible; transition-delay: 0.1s;
  }
}

/* Sous 1024 px, la scène n'est plus assez large pour que les boîtiers du
   haut-droite restent visibles à côté du cadre : ils passeraient derrière lui.
   On les retire plutôt que de les laisser dépasser à moitié. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .cb-coin--hd { display: none; }
}

/* Au-delà de 1400 px la colonne ne s'élargit pas — une ligne de texte trop
   longue se lit mal — mais la planche, elle, occupe toute la scène. */
@media (min-width: 1400px) {
  .cb-cadre { max-width: 740px; }
}

/* ═══ MOUVEMENT RÉDUIT ═════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .cb-loupe .modal-dialog,
  .cb-vignette,
  .cb-eclair-boite,
  .cb-barre.offcanvas-md,
  .cb-lien, .cb-lien img { transition-duration: 0.01ms !important; }
  .cb-diapo { scroll-behavior: auto; }
}
