/* ==========================================================================
   SADICOM, site vitrine
   Société Africaine d'Industrie et du Commerce, Conakry

   MONDE : le dépôt. Les marchandises de Sadicom arrivent par conteneur et
   repartent en piles. La page est un empilement de blocs de couleur pleine,
   comme une cour de stockage. La profondeur vient d'abord du recouvrement
   d'un bloc par un autre, jamais d'un ombrage.

   Les champs de couleur portent depuis le 4 septembre 2026 un dégradé de
   ton, à la demande du client, qui avait d'abord demandé le contraire. La
   discipline qui l'encadre : une seule teinte par dégradé, jamais deux
   couleurs qui se croisent, et la course va toujours du clair vers le
   sombre en descendant, comme une lumière qui tombe du toit du dépôt.
   Aucun dégradé sur le fond kraft de la page, aucun derrière un titre.

   Trois disciplines tenues d'un bout à l'autre :
     1. le bleu tient au moins un tiers de chaque écran, en champ plein et non
        en accent ;
     2. une seule grille modulaire porte toute la composition, les légendes
        vivent dans la même grille ;
     3. la profondeur se fait par superposition d'aplats, jamais par ombrage.

   Les blocs sont arrondis à la demande du client : la matière reste plate,
   seuls les angles s'adoucissent.

   Couleurs relevées sur les pièces réelles de la marque : le bleu du disque
   de l'emblème, l'orange du sigle imprimé sur les sacs.
   ========================================================================== */

/* --- 0. Les polices, hebergees ici ---------------------------------------
   Elles venaient de Google Fonts. Sur une connexion guineenne, cela coutait
   deux resolutions DNS et deux poignees de main TLS supplementaires avant
   qu'une seule lettre ne s'affiche, et la feuille de Google bloque le rendu.
   Les deux fichiers sont maintenant servis par le meme domaine que la page,
   sur la connexion deja ouverte.

   Un seul fichier par famille : ce sont des polices variables, donc les
   graisses 600, 700 et 800 d'Archivo sortent du meme fichier. Seul le
   sous-ensemble latin est embarque, il contient tous les accents francais ;
   le latin etendu ne sert qu'aux langues d'Europe de l'Est.

   font-display: swap, comme avant : le texte s'affiche tout de suite dans la
   police de secours, puis change. Sur une page ou l'on vient chercher un
   numero de telephone, attendre une police pour lire est inacceptable. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 600 800;
  font-display: swap;
  src: url("../polices/archivo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../polices/source-sans-3-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- 1. Jetons ----------------------------------------------------------- */
:root {
  /* Relevés sur l'emblème et le packaging */
  --bleu:       #185289;
  --bleu-nuit:  #071c33;
  --bleu-fonce: #10365c;
  --orange:     #d2622f;

  /* Les neutres : de l'acier et du papier kraft, pas du gris pur */
  --acier:      #eef1f4;
  --acier-2:    #dde3e9;
  --kraft:      #f4f1ec;
  --encre:      #0d1620;
  --encre-2:    #33414f;
  --gris:       #61707f;

  --titre: "Archivo", ui-sans-serif, system-ui, sans-serif;
  --texte: "Source Sans 3", ui-sans-serif, system-ui, sans-serif;

  --t-sm:   .94rem;
  --t-lede: clamp(1.04rem, 1.35vw, 1.2rem);

  /* Les angles. Un seul rayon pour les blocs, un plus court pour les
     commandes, de sorte que rien ne paraisse arrondi par hasard. */
  --r:      20px;
  --r-sm:   12px;

  /* La grille */
  --page:   1320px;
  --marge:  clamp(1.1rem, 3.4vw, 2.4rem);
  --pile:   clamp(3.4rem, 5.6vw, 5.6rem);
  --jeu:    14px;

  /* Les champs de couleur. Une seule teinte par degrade, la course va du
     clair vers le sombre en descendant. Le point de depart est la couleur
     pleine, donc le contraste du texte blanc ne baisse jamais : il monte. */
  --fond-bleu:   linear-gradient(168deg, var(--bleu) 0%, #123f6b 100%);
  --fond-nuit:   linear-gradient(168deg, var(--bleu-nuit) 0%, #030c17 100%);
  --fond-orange: linear-gradient(168deg, var(--orange) 0%, #b8511f 100%);

  --sortie: cubic-bezier(.16, 1, .3, 1);
}

/* --- 2. Base ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--kraft);
  color: var(--encre-2);
  font-family: var(--texte);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, svg { display: block; max-width: 100%; }
/* Les images sont enveloppees dans un <picture> par tools/webp.mjs, qui
   propose le WebP et garde le JPEG en repli. Sans cette ligne, l'enveloppe
   deviendrait une boite intermediaire : toutes les regles qui posent l'image
   comme enfant direct de son cadre, et les grilles qui la comptent comme
   element, tomberaient a cote. */
picture { display: contents; }
/* Et la source doit sortir de la mise en page, sinon elle y entre. Avec
   display: contents sur l'enveloppe, ses deux enfants deviennent des elements
   de la grille parente : la source, qui n'affiche rien, prenait une cellule
   sur deux et poussait chaque image dans la colonne suivante. La galerie du
   conteneur au chantier se retrouvait sur une seule colonne, l'autre vide.
   Le rendu d'une source ne joue aucun role dans le choix du fichier, la
   masquer ne coute donc rien. */
picture > source { display: none; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1, h2, h3 { margin: 0; font-family: var(--titre); color: var(--encre); font-weight: 800; line-height: 1.04; letter-spacing: -.035em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

/* Les surfaces que le navigateur dessine à notre place appartiennent aussi
   au monde : sélection, curseur, ascenseur, anneau de focus. */
::selection { background: var(--orange); color: #fff; }
:root { accent-color: var(--bleu); caret-color: var(--orange); }
:focus-visible { outline: 3px solid var(--orange); outline-offset: 3px; border-radius: 4px; }
@supports (scrollbar-color: red blue) {
  html { scrollbar-color: var(--bleu) var(--acier-2); scrollbar-width: thin; }
}

.saut { position: absolute; left: -100%; top: 0; z-index: 100; background: var(--orange); color: #fff; padding: .8rem 1.2rem; font-weight: 700; border-radius: 0 0 var(--r-sm) 0; }
.saut:focus { left: 0; }

/* --- 3. Le pochoir ------------------------------------------------------
   Le lettrage du dépôt : capitales serrées, comme un marquage au pochoir sur
   une caisse. C'est la voix des étiquettes, jamais celle d'un titre. */
.pochoir {
  font-family: var(--titre); font-weight: 700;
  font-size: .74rem; letter-spacing: .19em; text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

/* --- 4. Trame ------------------------------------------------------------ */
.page { width: 100%; max-width: var(--page); margin-inline: auto; padding-inline: var(--marge); }
.pile { padding-block: var(--pile); }

/* Deux sections a rembourrage qui se suivent doublent l'ecart : on voyait
   deux fois plus d'espace au-dessus d'un titre qu'en dessous. La seconde
   perd donc son rembourrage haut.

   Exception pour les sections qui portent leur propre fond : la, le
   rembourrage haut est ce qui separe le titre du bord de la bande, et celui
   de la section suivante est le seul espace entre cette bande et elle. Ces
   sections se declarent avec .pile--fond, faute de pouvoir demander en CSS
   si le voisin precedent a un fond. */
.pile + .pile { padding-top: 0; }
.pile.pile--fond,
.pile--fond + .pile { padding-top: var(--pile); }

/* Le titre de section. Pas de sur-titre : le titre porte seul, centré, et
   la ligne dessous dit la chose concrète. */
.titre-pile { max-width: 46rem; margin-inline: auto; text-align: center; }
.titre-pile h2 { font-size: clamp(2rem, 4.6vw, 3.2rem); text-wrap: balance; }
.titre-pile p { margin: 1.1rem auto 0; font-size: var(--t-lede); color: var(--gris); max-width: 46ch; text-wrap: pretty; }

/* --- 5. Le bandeau de quai ----------------------------------------------
   Les faits qu'on veut lire avant meme d'ouvrir la page. Il defile, parce
   qu'en statique il fallait masquer trois items sur quatre des qu'on passait
   sur telephone : le visiteur mobile, qui est le plus nombreux, ne voyait
   que le numero.

   Trois pistes identiques et non deux : avec deux, une seule copie doit etre
   plus large que l'ecran, sinon un vide apparait a droite sur un grand
   moniteur. Avec trois, la fenetre visible reste toujours couverte.

   La bande est decorative au sens strict : le numero s'y lit mais ne s'y
   clique pas, car viser une cible qui bouge est un mauvais geste. L'appel se
   fait par le bouton de l'en-tete, par celui de l'ouverture, et par le
   pave WhatsApp. Toutes ces coordonnees sont par ailleurs reprises dans le
   pied de page et sur la page Contact. */
.quai {
  background: var(--bleu-nuit); color: rgba(255,255,255,.78);
  font-family: var(--titre); font-weight: 600;
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  overflow: hidden; padding-block: .78rem;
}
.quai__piste { display: flex; width: max-content; animation: defileQuai 32s linear infinite; }
.quai:hover .quai__piste { animation-play-state: paused; }
.quai ul { display: flex; align-items: center; }
.quai li { display: inline-flex; align-items: center; gap: .45rem; white-space: nowrap; }
.quai li::after {
  content: ""; flex: none;
  width: 6px; height: 6px; margin-inline: 1.5rem;
  background: var(--orange); transform: rotate(45deg);
}
.quai svg { width: 14px; height: 14px; color: var(--orange); flex: none; }
@keyframes defileQuai { from { transform: translateX(0); } to { transform: translateX(-33.3333%); } }
@media (prefers-reduced-motion: reduce) {
  .quai__piste { animation: none; }
  .quai { overflow-x: auto; }
}

/* --- 6. En-tête ---------------------------------------------------------- */
.entete { position: sticky; top: 0; z-index: 50; background: var(--kraft); transition: box-shadow .2s; }
.entete.est-collee { box-shadow: 0 1px 0 var(--acier-2); }
.entete__in { display: flex; align-items: center; gap: 1.2rem; min-height: 76px; }

.sceau { display: inline-flex; align-items: center; gap: .7rem; flex: none; }
.sceau img { width: 46px; height: 46px; border-radius: 50%; flex: none; }
.sceau b { display: block; font-family: var(--titre); font-weight: 800; font-size: 1.32rem; letter-spacing: -.05em; color: var(--encre); line-height: 1; }
/* Le sous-titre seul est au pochoir. On cible le second span et non le
   conteneur, sinon la capitalisation retombe sur le nom de la marque. */
.sceau b + span { display: block; margin-top: 4px; font-family: var(--titre); font-weight: 600; font-size: .56rem; letter-spacing: .2em; text-transform: uppercase; color: var(--gris); line-height: 1.2; }

.nav { display: flex; margin-left: auto; }
.nav a {
  position: relative; padding: .6rem 1rem; border-radius: var(--r-sm);
  font-family: var(--titre); font-weight: 600; font-size: .92rem; color: var(--encre-2);
  transition: color .2s, background-color .2s;
}
.nav a:hover { color: var(--bleu); background: var(--acier); }
.nav a[aria-current="page"] { color: var(--encre); }
.nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 1rem; right: 1rem; bottom: .1rem;
  height: 3px; border-radius: 3px; background: var(--orange);
}

.entete__bout { display: flex; align-items: center; gap: .5rem; flex: none; }
.burger { display: none; width: 46px; height: 46px; border-radius: var(--r-sm); align-items: center; justify-content: center; color: var(--encre); }
.burger svg { width: 26px; height: 26px; }
.burger:hover { background: var(--acier); }

@media (max-width: 1000px) {
  .burger { display: inline-flex; }
  .entete__bout { margin-left: auto; }
  .entete__bout .bloc-lien { display: none; }
  .nav {
    position: fixed; inset: 116px var(--marge) auto; z-index: 49;
    flex-direction: column; background: var(--kraft);
    border: 1px solid var(--acier-2); border-radius: var(--r);
    padding: .6rem; overflow: hidden;
    transform: translateY(-8px); opacity: 0; visibility: hidden;
    transition: opacity .22s, transform .22s var(--sortie), visibility .22s;
  }
  .nav.est-ouvert { transform: none; opacity: 1; visibility: visible; }
  .nav a { padding: 1rem; font-size: 1.05rem; }
  .nav a[aria-current="page"]::after { display: none; }
  .nav a[aria-current="page"] { background: var(--acier); }
}

/* --- 7. Le lien-bloc -----------------------------------------------------
   Une plaque de couleur pleine. Aucun dégradé, aucune ombre : la commande se
   distingue par la couleur et la taille de la cible, pas par du relief. */
.bloc-lien {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  padding: .95rem 1.6rem; border-radius: var(--r-sm);
  font-family: var(--titre); font-weight: 700; font-size: .95rem; letter-spacing: -.01em;
  transition: background-color .2s, color .2s, border-color .2s;
}
.bloc-lien svg { width: 1.15em; height: 1.15em; flex: none; }
/* Le numero s'ecrit en entier tant qu'il y a la place ; sur telephone il
   cede a un verbe, sans quoi les deux commandes ne tiennent pas sur une
   ligne. Les deux libelles sont dans le HTML : le lien reste lisible meme
   sans feuille de style. */
.num-court { display: none; }
.bloc-lien--orange { background: var(--orange); color: #fff; }
.bloc-lien--orange:hover { background: #b8511f; }
.bloc-lien--bleu { background: var(--bleu); color: #fff; }
.bloc-lien--bleu:hover { background: var(--bleu-fonce); }
.bloc-lien--encre { background: var(--encre); color: #fff; }
.bloc-lien--encre:hover { background: var(--bleu); }
.bloc-lien--vide { border: 2px solid var(--encre); color: var(--encre); }
.bloc-lien--vide:hover { background: var(--encre); color: #fff; }
.bloc-lien--clair { background: rgba(255,255,255,.12); border: 2px solid rgba(255,255,255,.55); color: #fff; }
.bloc-lien--clair:hover { background: #fff; color: var(--bleu-nuit); border-color: #fff; }

/* --- 8. L'ouverture ------------------------------------------------------
   Une seule photographie, plein cadre, cadree expres pour cet usage : le mur
   dans l'ombre a gauche sur ecran large, le sol vide en bas sur telephone.
   Le texte se pose directement dessus, sans cadre ni voile. Aucun bloc a
   traverser, aucune boite : la lisibilite vient du cadrage, ce qui est la
   seule facon de ne pas avoir l'air d'un gabarit. */
.cour { position: relative; overflow: hidden; background: var(--bleu-nuit); }
.cour__vue { position: absolute; inset: 0; }
.cour__vue img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; }

.cour__in {
  position: relative; z-index: 1;
  min-height: clamp(32rem, 84vh, 48rem);
  display: flex; align-items: flex-end;
  padding-block: clamp(3.4rem, 7vw, 6rem);
}
@media (min-width: 940px) {
  .cour__in { align-items: center; }
  .cour__vue img { object-position: 50% 50%; }
}

.cour__mot { color: #fff; max-width: min(34rem, 88%); }
@media (min-width: 940px) { .cour__mot { max-width: min(32rem, 44vw); } }
.cour__titre { color: #fff; font-size: clamp(2.3rem, 5.4vw, 4rem); text-wrap: balance; }
.cour__dit { margin-top: 1.2rem; max-width: 34ch; font-size: var(--t-lede); color: rgba(255,255,255,.88); text-wrap: pretty; }
.cour__actes { margin-top: 2rem; display: flex; flex-wrap: wrap; gap: .7rem; }

/* --- 9. Le manifeste -----------------------------------------------------
   Quatre faits en champ plein sous l'ouverture. C'est ici que le bleu prend
   son tiers d'ecran, et c'est pour cela qu'il n'y a ni vignette, ni carte,
   ni pastille : le fond est deja le bloc. Quatre colonnes separees par des
   filets, comme un marquage peint au fond du depot.

   Une version en cartes grises a icone blanche a ete essayee et jetee le
   meme jour : elle ressemblait a n'importe quel site, et le client l'a dit
   avant meme d'avoir fini de lire. Sur ce site, un bloc est un aplat de
   couleur, jamais une boite posee sur un fond clair. */
.manifeste { background: var(--fond-bleu); color: #fff; padding-block: clamp(2.6rem, 4.6vw, 4.2rem); }
.manifeste ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(2rem, 3.4vw, 2.8rem) 0; }
@media (min-width: 900px) { .manifeste ul { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; } }

.manifeste li {
  padding-inline: clamp(1rem, 2.4vw, 2.2rem);
  border-inline-start: 1px solid rgba(255, 255, 255, .2);
}
.manifeste li:first-child { border-inline-start: 0; padding-inline-start: 0; }
@media (max-width: 899px) {
  .manifeste li:nth-child(odd) { border-inline-start: 0; padding-inline-start: 0; }
}

.fait__ico { display: block; color: #fff; }
.fait__ico svg { width: clamp(40px, 4.4vw, 54px); height: auto; aspect-ratio: 1; }
.manifeste b {
  display: block; margin-top: clamp(1rem, 1.8vw, 1.5rem);
  font-family: var(--titre); font-weight: 800;
  font-size: clamp(1.06rem, 1.7vw, 1.3rem); letter-spacing: -.025em; color: #fff;
}
.fait__dit {
  display: block; margin-top: .42rem;
  font-size: var(--t-sm); line-height: 1.55; color: rgba(255, 255, 255, .8);
  max-width: 26ch;
}

/* --- 10. L'empilement des gammes -----------------------------------------
   Pas une grille de vignettes identiques : le platre, seul produit a la
   marque, tient quatre cellules ; les autres se rangent autour.

   La legende est SOUS la photographie, jamais dessus. Un cartouche pose sur
   une image en masque toujours une part, et sur une vignette de trois cents
   pixels il en masque le sujet. Le nom se lit sur le fond de page, la
   photographie reste entiere. */
/* Six colonnes : deux grandes cellules en haut, trois moyennes en dessous.
   Toutes gardent le meme rapport 4/3, de sorte qu'aucune photographie n'est
   etiree pour remplir une case plus haute que les autres. */
.empilement { display: grid; gap: var(--jeu); grid-template-columns: minmax(0, 1fr); margin-top: 2.8rem; }
@media (min-width: 820px) {
  .empilement { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .caisse--demi { grid-column: span 3; }
  .caisse--tiers { grid-column: span 2; }
}

.caisse {
  display: flex; flex-direction: column;
  background: var(--acier); border-radius: var(--r); overflow: hidden;
}
.caisse__vue { position: relative; background: var(--acier-2); aspect-ratio: 4 / 3; overflow: hidden; }
.caisse__vue img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--sortie); }
.caisse:hover .caisse__vue img { transform: scale(1.04); }

/* La legende vit dans le meme bloc que la photographie, sur une surface
   propre : ni posee sur l'image, ou elle en masque le sujet, ni flottant
   sur le fond de page, ou elle a l'air orpheline. */
.caisse__mot { padding: 1.15rem 1.3rem 1.4rem; }
.caisse__mot b { display: block; font-family: var(--titre); font-weight: 800; font-size: 1.16rem; color: var(--encre); letter-spacing: -.03em; line-height: 1.15; transition: color .2s; }
.caisse:hover .caisse__mot b { color: var(--bleu); }
.caisse__mot span { display: block; margin-top: .28rem; font-size: .9rem; color: var(--gris); line-height: 1.4; }

/* Le cachet de marque : une pastille blanche a lettrage orange, posee dans
   un coin de la photographie. On y a mis l'embleme, mais a cette taille il
   se reduit a une tache : le mot se lit, le dessin non. */
.caisse__sceau {
  position: absolute; left: 12px; top: 12px; z-index: 1;
  background: #fff; color: var(--orange);
  padding: .42rem .85rem; border-radius: 999px;
  font-size: .64rem; letter-spacing: .13em;
}

/* --- 11. Le pesage -------------------------------------------------------
   Les trois questions posées au téléphone, dans l'ordre où elles arrivent.
   L'ordre est une information : il vient du dirigeant lui-même. */
.pesage { display: grid; gap: var(--jeu); }
@media (min-width: 940px) { .pesage { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); } }
.pesage__mot { background: var(--bleu); color: #fff; border-radius: var(--r); padding: clamp(1.8rem, 3.6vw, 3.2rem); }
.pesage__mot h2 { color: #fff; font-size: clamp(1.7rem, 3.4vw, 2.5rem); text-wrap: balance; }
.pesage__vue { position: relative; overflow: hidden; border-radius: var(--r); min-height: 20rem; background: var(--bleu-fonce); }
.pesage__vue img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.releve { margin-top: 1.8rem; }
.releve li { padding: 1.2rem 0; border-top: 1px solid rgba(255,255,255,.22); }
.releve li:last-child { border-bottom: 1px solid rgba(255,255,255,.22); }
.releve .pochoir { display: block; color: #ffc9ac; margin-bottom: .35rem; }
.releve b { display: block; font-family: var(--titre); font-weight: 700; font-size: 1.1rem; color: #fff; letter-spacing: -.02em; }
.releve p { margin-top: .3rem; font-size: var(--t-sm); color: rgba(255,255,255,.78); line-height: 1.5; }

/* --- 12. Les trois clientèles --------------------------------------------
   Chacune est montrée avant d'être nommée : une part importante des clients
   lit peu, l'image doit porter l'information la première. */
.clients { display: grid; gap: var(--jeu); margin-top: 2.8rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 860px) { .clients { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.client { background: var(--acier); border-radius: var(--r); overflow: hidden; display: flex; flex-direction: column; }
.client__vue { position: relative; aspect-ratio: 4 / 3; background: var(--acier-2); }
.client__vue img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.client__mot { padding: 1.5rem 1.5rem 1.8rem; }
.client h3 { font-size: 1.28rem; }
.client p { margin-top: .6rem; font-size: var(--t-sm); color: var(--gris); line-height: 1.55; }

/* --- 13. Le plan ---------------------------------------------------------
   La carte vit dans la page. Personne ne doit ouvrir une autre application
   pour savoir où est le dépôt. */
.plan { display: grid; gap: var(--jeu); }
@media (min-width: 940px) { .plan { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); } }
.plan__mot { background: var(--encre); color: #fff; border-radius: var(--r); padding: clamp(1.8rem, 3.4vw, 2.8rem); }
.plan__mot h2 { color: #fff; font-size: clamp(1.7rem, 3.2vw, 2.3rem); }
.plan__adresse { margin-top: 1.6rem; }
.plan__adresse li { padding: 1rem 0; border-bottom: 1px solid rgba(255,255,255,.14); }
.plan__adresse li:last-child { border-bottom: 0; padding-bottom: 0; }
.plan__adresse .pochoir { color: var(--orange); display: block; margin-bottom: .35rem; }
.plan__adresse strong { font-family: var(--titre); font-weight: 700; font-size: 1.05rem; color: #fff; }
.plan__adresse a:hover { color: var(--orange); }

.plan__carte { position: relative; overflow: hidden; border-radius: var(--r); min-height: 24rem; background: var(--acier-2); }
.plan__carte iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; filter: grayscale(.3) contrast(1.04); }

/* --- 14. L'appel --------------------------------------------------------- */
/* Le bloc d'appel porte sa propre trame, un appareillage de blocs, et non
   la geometrie de l'embleme : deux fonds pleins qui se suivent avec le meme
   motif finiraient par le rendre invisible a force de le repeter. Celle-ci
   parle du chantier, l'autre parlait de la marque. */
.appel { position: relative; overflow: hidden; background: var(--fond-orange); color: #fff; border-radius: var(--r); padding: clamp(2.2rem, 4.6vw, 3.6rem); display: grid; gap: 1.8rem; align-items: center; }
.appel::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: url("../img/marque/motif-bloc.jpg");
  background-size: 420px; background-repeat: repeat;
  opacity: .45;
}
.appel > * { position: relative; z-index: 1; }
@media (min-width: 900px) { .appel { grid-template-columns: minmax(0, 1fr) auto; gap: 2.8rem; } }
.appel h2 { color: #fff; font-size: clamp(1.8rem, 3.8vw, 2.8rem); max-width: 20ch; text-wrap: balance; }
.appel p { margin-top: .9rem; font-size: var(--t-lede); color: #fff; max-width: 44ch; }
.appel__actes { display: flex; flex-wrap: wrap; gap: .7rem; }

/* --- 15. Pied ------------------------------------------------------------ */
.pied { background: var(--bleu-nuit); color: rgba(255,255,255,.62); padding-block: clamp(2.8rem, 5vw, 4rem) 1.5rem; }
.pied__grille { display: grid; gap: 2.4rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.pied h3 { font-family: var(--titre); font-size: .72rem; font-weight: 700; letter-spacing: .17em; text-transform: uppercase; color: #fff; margin-bottom: 1rem; }
.pied li + li { margin-top: .58rem; }
.pied a:hover { color: var(--orange); }
.pied .sceau b { color: #fff; }
.pied .sceau b + span { color: rgba(255,255,255,.42); }
.pied__devise { margin-top: 1.3rem; font-size: var(--t-sm); font-style: italic; color: rgba(255,255,255,.5); max-width: 28ch; }
/* Sans min-width, un element de boite flexible ne se replie pas sous la
   largeur de son texte : la raison sociale sortait du cadre sur telephone. */
.pied__bas { margin-top: 2.6rem; padding-top: 1.4rem; border-top: 1px solid rgba(255,255,255,.12); display: flex; flex-wrap: wrap; gap: .5rem 1.4rem; justify-content: space-between; font-size: .78rem; color: rgba(255,255,255,.42); }
.pied__bas span { min-width: 0; }

/* --- 16. WhatsApp --------------------------------------------------------
   Le vrai logo de WhatsApp, pas une icône maison : c'est un repère que le
   client reconnaît avant de lire quoi que ce soit. */
.wa {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 45;
  width: 56px; height: 56px; border-radius: 50%;
  display: grid; place-items: center;
  background: #25d366; color: #fff;
  transition: transform .2s var(--sortie);
}
.wa:hover { transform: translateY(-3px); }
.wa svg { width: 30px; height: 30px; }

/* --- 17. Le jeu d'icônes -------------------------------------------------
   Un seul système pour tout le site, posé comme élément de charte : grille
   24, trait 1.6, extrémités arrondies, aucun remplissage, et dans chaque
   icône un seul trait passe à l'orange. Le pictogramme est dessiné grand :
   une part des clients lit peu, l'icône porte l'information avant le mot.
   Le logo WhatsApp est la seule exception : c'est une marque tierce, on la
   reproduit telle quelle. */
.ico { width: 32px; height: 32px; flex: none; }
/* Sur un fond deja colore, le second trait rejoint la couleur du texte :
   un trait orange sur un bouton orange devient invisible et une fleche se
   reduit alors a une barre, qui se lit comme un tiret. */
.bloc-lien svg, .wa svg, .quai svg { --trait2: currentColor; }
.ico--sm { width: 20px; height: 20px; }

/* --- 18. Le mouvement ----------------------------------------------------
   Un seul geste, celui du monde : un bloc se pose. Il monte de sa hauteur et
   se cale, comme une caisse déposée sur la pile. Rien d'autre ne bouge.
   Le voile de départ n'existe que si le script tourne : sans lui, tout reste
   visible. Une page dont le contenu dépend d'un fichier JS qui n'a pas
   chargé est une page vide, et la 3G ne pardonne pas. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-pose] { opacity: 0; transform: translateY(24px); }
  .js [data-pose].est-pose {
    opacity: 1; transform: none;
    transition: opacity .5s var(--sortie), transform .62s var(--sortie);
  }
}

/* --- 19. Les pages interieures -------------------------------------------
   Meme monde, meme grille. La tete de page est un champ bleu plein, comme
   l'ouverture de l'accueil : le bleu tient toujours son tiers d'ecran.
   Les gammes s'alternent gauche et droite. Le texte n'est pas mis en boite :
   il se pose sur le fond de la page, et seule la photographie est un bloc. */
/* La tete des pages interieures porte le motif de marque, comme la galerie
   et le volet sombre : c'est le troisieme et dernier endroit ou la trame
   apparait, ce qui suffit a la faire reconnaitre sans qu'elle devienne un
   tic. Elle reste tres basse en contraste pour ne pas manger le titre. */
.tete-page { position: relative; overflow: hidden; background: var(--fond-bleu); color: #fff; padding-block: clamp(2.8rem, 6vw, 5rem); }
.tete-page::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: url("../img/marque/motif.jpg");
  background-size: 460px; background-repeat: repeat;
  opacity: .17;
}
.tete-page > .page { position: relative; z-index: 1; }
.tete-page h1 { color: #fff; font-size: clamp(2.2rem, 5.4vw, 3.8rem); max-width: 18ch; text-wrap: balance; }
.tete-page p { margin-top: 1.2rem; max-width: 52ch; font-size: var(--t-lede); color: rgba(255,255,255,.86); text-wrap: pretty; }

.gamme { display: grid; gap: clamp(1.4rem, 3vw, 3rem); align-items: center; }
.gamme + .gamme { margin-top: clamp(2.6rem, 5vw, 4.4rem); padding-top: clamp(2.6rem, 5vw, 4.4rem); border-top: 1px solid var(--acier-2); }
@media (min-width: 860px) {
  .gamme { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); }
  .gamme--inverse .gamme__vue { order: 2; }
}
.gamme__vue { position: relative; overflow: hidden; border-radius: var(--r); background: var(--acier-2); aspect-ratio: 4 / 3; }
.gamme__vue img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.gamme__mot h2 { font-size: clamp(1.7rem, 3.4vw, 2.6rem); }
.gamme__mot p { margin-top: 1rem; font-size: var(--t-lede); color: var(--gris); max-width: 46ch; text-wrap: pretty; }

/* L'etiquette de marque : une pastille orange, la meme que sur l'accueil. */
.etiquette { display: inline-block; margin-bottom: .9rem; background: var(--orange); color: #fff; padding: .4rem .8rem; border-radius: 999px; }

/* Les faits : trois mots par gamme, lisibles sans lire la phrase. */
.faits { margin-top: 1.4rem; display: flex; flex-wrap: wrap; gap: .5rem; }
.faits li {
  font-family: var(--titre); font-weight: 600; font-size: .86rem; color: var(--encre);
  border: 1px solid var(--acier-2); background: #fff;
  padding: .45rem .85rem; border-radius: 999px;
}

/* --- 20. Le contact ------------------------------------------------------ */
.fiches { display: grid; gap: var(--jeu); grid-template-columns: minmax(0, 1fr); margin-top: 2.6rem; }
@media (min-width: 820px) { .fiches { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.fiche { background: var(--acier); border-radius: var(--r); padding: 1.7rem 1.5rem 1.9rem; }
.fiche .ico { color: var(--bleu); margin-bottom: 1rem; }
.fiche h2 { font-size: 1.2rem; }
.fiche p { margin-top: .5rem; font-size: var(--t-sm); color: var(--gris); }
.fiche strong { display: block; margin-top: .8rem; font-family: var(--titre); font-weight: 700; font-size: 1.12rem; color: var(--encre); letter-spacing: -.02em; }
.fiche a strong:hover { color: var(--bleu); }

/* --- 21. Le recit d'entreprise -------------------------------------------
   Deux colonnes : le texte a lire, et les faits a verifier. Rien d'invente :
   ce qui n'a pas ete confirme par le dirigeant ne figure pas ici. */
.recit { display: grid; gap: clamp(1.8rem, 4vw, 3.4rem); }
@media (min-width: 900px) { .recit { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); } }
.recit__texte p + p { margin-top: 1.1rem; }
.recit__texte p { font-size: var(--t-lede); color: var(--encre-2); max-width: 60ch; text-wrap: pretty; }
.recit__vue { position: relative; overflow: hidden; border-radius: var(--r); background: var(--acier-2); aspect-ratio: 3 / 2; }
.recit__vue img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.chiffres { display: grid; gap: var(--jeu); grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 2.6rem; }
@media (min-width: 900px) { .chiffres { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.chiffres li { background: var(--bleu); color: #fff; border-radius: var(--r); padding: 1.5rem 1.4rem; }
.chiffres b { display: block; font-family: var(--titre); font-weight: 800; font-size: clamp(1.3rem, 2.4vw, 1.7rem); letter-spacing: -.03em; }
.chiffres span { display: block; margin-top: .35rem; font-size: var(--t-sm); color: rgba(255,255,255,.76); line-height: 1.45; }


/* --- 22. Le bandeau defilant ---------------------------------------------
   La liste des gammes passe en continu, comme le marquage sur le flanc d'un
   camion qui sort du depot. Deux pistes identiques se suivent, la seconde
   prenant le relais quand la premiere sort du cadre : c'est ce qui rend la
   boucle invisible. Le separateur est un losange orange, jamais un point
   median ni un tiret.
   L'animation s'arrete si le visiteur a demande moins de mouvement. */
.bandeau { background: var(--bleu-nuit); color: #fff; overflow: hidden; padding-block: 1.05rem; }
.bandeau__piste { display: flex; width: max-content; animation: defile 34s linear infinite; }
.bandeau:hover .bandeau__piste { animation-play-state: paused; }
.bandeau ul { display: flex; align-items: center; }
.bandeau li {
  display: inline-flex; align-items: center;
  font-family: var(--titre); font-weight: 700;
  font-size: clamp(.82rem, 1.3vw, .96rem); letter-spacing: .16em; text-transform: uppercase;
  white-space: nowrap;
}
.bandeau li::after {
  content: ""; flex: none;
  width: 6px; height: 6px; margin-inline: 1.4rem;
  background: var(--orange); transform: rotate(45deg);
}
@keyframes defile { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .bandeau__piste { animation: none; }
  .bandeau { overflow-x: auto; }
}

/* --- 23. Les coutures ----------------------------------------------------
   Entre deux bandes pleine largeur, le bord d'un bloc tombe parfois sur un
   demi-pixel selon le zoom et la densite de l'ecran, et le navigateur laisse
   alors apparaitre un filet du fond de page. Mesure a zero dans le calcul,
   visible a l'oeil. On fait donc chevaucher d'un pixel plutot que de compter
   sur l'arrondi : l'en-tete etant au-dessus dans l'empilement, c'est lui qui
   recouvre. */
.cour, .tete-page { margin-top: -1px; }
.bandeau { margin-top: -1px; }

/* --- 24. Le telephone ---------------------------------------------------
   Le petit ecran n'est pas une reduction du grand : c'est la ou la plupart
   des visiteurs arrivent, et chaque section doit y tenir sans qu'on ait
   l'impression de derouler un rouleau. Tout ce bloc est verifie a 390 px.

   1. Le nom de la societe en toutes lettres ne tient pas a cote du menu : il
      poussait le bouton d'ouverture hors du cadre et faisait defiler la page
      lateralement. On ne garde que la marque.
   2. L'ouverture se centre, le titre tient sur deux lignes, la phrase sur
      trois, et les deux commandes sur une seule.
   3. Le bandeau de quai se reduit au numero : c'est la seule ligne qu'on
      veut voir avant le titre.
   4. Les gammes deviennent une rangee qu'on fait glisser du pouce. Empilees,
      elles demandaient cinq ecrans de defilement pour etre vues ; en rangee,
      la section tient sur un ecran et la vignette suivante depasse, ce qui
      dit au visiteur qu'il y a une suite sans avoir a l'ecrire.
   5. Le pied passe sur deux colonnes : en une seule, il laissait la moitie
      droite vide sur toute sa hauteur. */
@media (max-width: 700px) {
  .sceau b + span { display: none; }
  .sceau img { width: 42px; height: 42px; }

  /* La hauteur du heros suit le rapport de la photographie mobile, qui a
     ete recadree pour ne garder que le sol necessaire au texte. Sans cela,
     l'image se recadrait toute seule et mangeait le haut des sacs, ou bien
     laissait cent soixante-dix pixels de sol vide entre la palette et le
     titre. Le plafond en vh evite un heros demesure sur les grands
     telephones. */
  .cour__in { padding-block: 2.4rem 3rem; min-height: min(calc(100vw * 1.551), 86vh); }
  /* Le cadrage part du haut : le sommet des sacs n'est jamais coupe. */
  .cour__vue img { object-position: 50% 0%; }
  .cour__mot { text-align: center; margin-inline: auto; max-width: 100%; }
  /* Le titre tient sur deux lignes, jamais trois. La coupure voulue est
     « Materiaux de construction » puis « a Conakry » : la categorie, puis le
     lieu. Deux reglages pour l'obtenir, et il faut les deux.

     La taille suit la largeur de l'ecran plutot qu'une valeur fixe, sinon
     elle passe a trois lignes des qu'on descend sous 390 px. Et l'equilibrage
     automatique est desactive ici : il minimise la ligne la plus longue,
     donc il coupait « Materiaux de » tout seul sur la premiere ligne. Le
     debordement de huit pixels de chaque cote rend la largeur qui manquait
     pour garder le titre lisible. */
  .cour__titre {
    font-size: clamp(1.4rem, 7.55vw, 2.05rem);
    margin-inline: -.5rem;
    text-wrap: normal;
  }
  .cour__dit { margin-inline: auto; max-width: 100%; font-size: 1rem; }
  .cour__actes { justify-content: center; flex-wrap: nowrap; }
  .cour__actes .bloc-lien { flex: 1 1 0; min-width: 0; padding-inline: .8rem; font-size: .88rem; }

  .appel p { max-width: 100%; font-size: 1rem; }
  .appel__actes { flex-wrap: nowrap; }
  .appel__actes .bloc-lien { flex: 1 1 0; min-width: 0; padding-inline: .7rem; font-size: .88rem; }
  .num-long { display: none; }
  .num-court { display: inline; }

  .pied__grille { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.9rem 1.2rem; }
  .pied__grille > :first-child { grid-column: 1 / -1; }
  .pied__grille > :last-child { grid-column: 1 / -1; }
  .pied__grille > :last-child ul { columns: 2; column-gap: 1.2rem; }
  .pied__grille > :last-child li { break-inside: avoid; }
  .pied__devise { margin-top: 1rem; }
}

/* --- 25. Les gammes sur telephone : le jeu de cartes ---------------------
   Empilees, les cinq gammes demandaient cinq ecrans de defilement. Ici
   chacune se colle en haut de l'ecran et la suivante monte par-dessus : on
   reste sur un ecran, et le defilement sert de bouton de passage.

   Tout tient en CSS, avec position: sticky. Pas de bibliotheque, pas de
   script, rien a telecharger : sur une 3G guineenne c'est la difference
   entre une animation gratuite et une animation a cent kilo-octets. Sans
   prise en charge de sticky, les cartes redeviennent une simple pile, ce
   qui reste parfaitement lisible.

   Le decalage de quelques pixels d'une carte a l'autre laisse voir la
   tranche de celle du dessous : c'est ce qui fait lire un paquet plutot
   qu'une seule carte qui change. */
@media (max-width: 820px) {
  .empilement { display: block; margin-top: 2rem; }
  .caisse {
    position: sticky;
    top: calc(var(--haut-entete, 76px) + 1.1rem);
  }
  /* L'ecart entre deux cartes est la course de defilement pendant laquelle
     la carte du dessus tient l'ecran. */
  .caisse + .caisse { margin-top: clamp(17rem, 44vh, 24rem); }
  .caisse:nth-child(2) { top: calc(var(--haut-entete, 76px) + 1.6rem); }
  .caisse:nth-child(3) { top: calc(var(--haut-entete, 76px) + 2.1rem); }
  .caisse:nth-child(4) { top: calc(var(--haut-entete, 76px) + 2.6rem); }
  .caisse:nth-child(5) { top: calc(var(--haut-entete, 76px) + 3.1rem); }
}

/* --- 25b. Du conteneur au chantier ---------------------------------------
   Une grille de vues du travail, basculee en arriere puis redressee au
   defilement, les colonnes ne montant pas a la meme vitesse. Le mouvement
   ne decore pas : il fait passer d'un plan a plat, celui du catalogue, a un
   plan en perspective, celui de l'entrepot ou l'on marche entre les piles.

   La scene est une fenetre de hauteur fixe qui coupe ce qui depasse. Sans
   elle, le decalage des colonnes et la parallaxe laissaient des trous de
   fond en bas de section et la grille mordait sur le titre. Avec elle, la
   fenetre est toujours pleine, quelle que soit la position de defilement.

   GSAP n'est demande qu'a l'approche de cette section, jamais au
   chargement. Sans lui, la grille reste droite et lisible : le basculement
   est un supplement, pas la fondation. */
.chaine { position: relative; background: var(--fond-nuit); color: #fff; overflow: hidden; }
.chaine .titre-pile h2 { color: #fff; }
.chaine .titre-pile p { color: rgba(255,255,255,.72); }

/* Le motif de marque, tire de la geometrie des ailes de l'embleme, pose tres
   bas en contraste : une texture de fond, pas un decor qu'on remarque. */
.chaine > .page { position: relative; z-index: 1; }
.chaine__scene::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: url("../img/marque/motif.jpg");
  background-size: 460px; background-repeat: repeat;
  opacity: .16;
}
.chaine__grille { position: relative; z-index: 1; }

.chaine__scene {
  position: relative;
  perspective: 1200px; perspective-origin: 50% 0%;
  margin-top: 3rem;
  /* La fenetre coupe ce qui depasse, et le rembourrage interieur absorbe la
     course de la parallaxe : les colonnes peuvent glisser sans jamais
     laisser voir le fond entre deux vues. */
  overflow: hidden;
  padding-block: 2.4rem;
}
.chaine__grille {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--jeu);
  transform-style: preserve-3d;
  /* Le pivot est au bord haut : la bascule et l'agrandissement poussent la
     grille vers le bas et jamais vers le titre, qu'elle recouvrait. */
  transform-origin: 50% 0%;
  position: relative; z-index: 1;
}
/* Sur petit ecran, les colonnes s'effacent et leurs vues deviennent les
   enfants directs de la grille : les huit se repartissent alors d'elles
   memes sur deux colonnes pleines, quatre et quatre. */
.chaine__col { display: contents; }
.chaine__col img {
  width: 100%; height: auto; display: block;
  border-radius: var(--r-sm);
  aspect-ratio: 4 / 3; object-fit: cover;
}

@media (min-width: 820px) {
  /* Quatre colonnes de deux vues. Huit se divise par quatre comme par deux :
     la grille est pleine sur les deux dispositions, et aucune vue n'est
     etiree ni rognee pour combler un vide. */
  .chaine__grille { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .chaine__col { display: flex; flex-direction: column; gap: var(--jeu); }
}

/* L'etat de depart n'est pose que si le script a pu prendre la main. */
.chaine.est-armee .chaine__grille { transform: rotateX(58deg) scale(1.16); }

/* --- 26. L'enchainement sur telephone ------------------------------------
   En colonne, la photographie du comptoir se retrouvait sous le bloc bleu,
   entre deux sections, et se lisait comme une image orpheline appartenant a
   la suivante. On la remonte en tete de sa propre section : le bloc se lit
   alors d'un seul tenant, image puis reponses, et la coupure avec la section
   suivante redevient nette. */
@media (max-width: 939px) {
  .pesage__vue { order: -1; min-height: 0; aspect-ratio: 3 / 2; }
}

/* --- 27. Le récit en volets ----------------------------------------------
   Les trois volets restent en aplat, seuls champs de couleur du site à ne pas
   porter de dégradé de ton. Deux raisons. Sur un panneau pleine hauteur la
   course du dégradé s'étale sur cent pour cent de la fenêtre et ne se voit
   plus. Et surtout, un dégradé repart à zéro à chaque raccord : entre la
   bande de titre et le premier volet, la couleur faisait une marche que le
   client a vue immédiatement. Un aplat qui touche le même aplat ne fait
   jamais de couture.

   Les trois étapes deviennent trois panneaux pleine hauteur, chacun d'une
   couleur de la marque. Chaque panneau arrive incliné depuis son coin
   inférieur gauche et se redresse au défilement, le précédent restant
   accroché derrière lui. On ne lit plus une liste : on tourne trois pages.

   Le pivot est un supplément. Sans script ou sans GSAP, les trois panneaux
   restent trois blocs pleins empilés, droits et lisibles. Chaque volet coupe
   ce qui dépasse de son cadre, sinon l'inclinaison ferait défiler la page
   latéralement.

   Le conteneur porte le bleu plein du premier volet : pendant que celui-ci
   pivote pour arriver, la rotation découvre ce qu'il y a derrière lui, et
   sans ce fond c'est le kraft de la page qui apparaît. */
.volets { background: var(--bleu); }
.volet { position: relative; min-height: 100vh; width: 100%; overflow: hidden; }
.volet__in {
  min-height: 100vh; width: 100%;
  display: flex; flex-direction: column; justify-content: space-between;
  gap: clamp(.8rem, 2vw, 1.6rem);
  padding: clamp(2rem, 6vw, 4rem) var(--marge) clamp(2.4rem, 5vw, 4rem);
  transform-origin: bottom left;
  will-change: transform;
}
.volet--bleu   .volet__in { background: var(--bleu);      color: #fff; }
.volet--encre  .volet__in { background: var(--bleu-nuit); color: #fff; }
/* Le motif de marque en couche separee et tres bas en contraste : une trame
   qu'on sent, pas un tissu qu'on lit. Pose a pleine force, il rendait le
   texte blanc illisible. */
.volet--encre .volet__in::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: url("../img/marque/motif.jpg");
  background-size: 460px; background-repeat: repeat;
  opacity: .10;
}
.volet__in { position: relative; }
.volet__in > * { position: relative; z-index: 1; }
.volet--orange .volet__in { background: var(--orange);    color: #fff; }

.volet__rang { color: rgba(255,255,255,.72); }
.volet__filet { border: 0; border-top: 1px solid rgba(255,255,255,.45); margin: clamp(1rem, 2.4vw, 2rem) 0; width: 100%; }
.volet h2 {
  color: #fff; text-transform: uppercase;
  font-size: clamp(2.8rem, 11vw, 9rem);
  line-height: .86; letter-spacing: -.045em;
}
.volet p {
  max-width: 46ch; margin-left: auto;
  font-size: clamp(1.05rem, 2.1vw, 1.75rem); line-height: 1.4;
  color: rgba(255,255,255,.9); text-wrap: pretty;
}
.volet--encre p { margin-left: 0; }

/* --- 28. Le rideau de pied de page ---------------------------------------
   Le dernier appel et le pied ne défilent pas avec la page : ils sont fixés
   au bas de la fenêtre et la page se retire par-dessus, comme un rideau
   qu'on lève. Le découpage du conteneur suffit à les enfermer, sans script
   pour la mécanique elle-même.

   Le script ne fait qu'une chose : vérifier que le contenu tient dans la
   hauteur de la fenêtre. S'il n'y tient pas, le rideau n'est pas posé et
   tout reprend sa place dans le flux. Un pied coupé vaut moins qu'un pied
   qui défile. */
.rideau { position: relative; }
.rideau.est-levee {
  height: 100vh;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
.rideau.est-levee > .rideau__in {
  position: fixed; bottom: 0; left: 0; width: 100%; height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(1.5rem, 3vw, 3rem);
  overflow: hidden;
  background: var(--kraft);
}

/* Le rideau ne se pose que si son contenu tient dans la hauteur de la
   fenetre, et la marge etait de deux pixels. Une phrase de l'appel passee de
   deux lignes a trois a suffi a le desarmer, sans erreur ni message : le
   pied s'est simplement remis a defiler. A l'interieur du rideau, et
   seulement la, l'appel et le pied se resserrent pour garder une reserve
   d'une soixantaine de pixels.

   Le resserrement n'est surtout pas conditionne a .est-levee : le script
   mesure justement apres avoir retire cette classe, il ne verrait donc pas
   le gain et n'armerait jamais le rideau. */
@media (min-width: 900px) {
  .rideau .appel { padding: clamp(1.8rem, 3.2vw, 2.6rem) clamp(2.2rem, 4.6vw, 3.4rem); }
  .rideau .pied { padding-block: clamp(2rem, 3.4vw, 2.8rem) 1.2rem; }
  .rideau .pied__grille { gap: 1.8rem; }
  .rideau .pied__bas { margin-top: 1.8rem; padding-top: 1.1rem; }
}

/* Le nom en très grand derrière le pied : une enseigne peinte au fond du
   dépôt, pas un titre. Aucun dégradé, un aplat très clair. */
.pied__geant {
  position: absolute; left: 50%; bottom: -.08em; z-index: 0;
  transform: translateX(-50%);
  font-family: var(--titre); font-weight: 800;
  font-size: 25vw; line-height: .74; letter-spacing: -.05em;
  color: rgba(255,255,255,.055);
  white-space: nowrap; pointer-events: none; user-select: none;
}
.rideau .pied { position: relative; z-index: 1; }
.rideau .pied__geant { display: none; }
.rideau.est-levee .pied__geant { display: block; }

/* Le bandeau reprend en oblique dans le rideau : le même marquage que sous
   l'ouverture, revu de biais, ferme la page comme il l'avait ouverte. */
.bandeau--oblique { transform: rotate(-2deg) scale(1.06); }
.rideau .bandeau--oblique { display: none; }
.rideau.est-levee .bandeau--oblique { display: block; }

/* Le retour en haut. */
.haut {
  width: 48px; height: 48px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  border: 2px solid rgba(255,255,255,.35); color: #fff;
  transition: background-color .2s, border-color .2s, color .2s;
}
.haut:hover { background: #fff; color: var(--bleu-nuit); border-color: #fff; }
.haut svg { width: 20px; height: 20px; transition: transform .3s var(--sortie); }
.haut:hover svg { transform: translateY(-3px); }
.pied__bas .haut { margin-left: auto; }

/* Les commandes aimantées suivent le curseur de quelques pixels. Uniquement
   là où il y a un curseur : sur un écran tactile, cela ne veut rien dire. */
.aimante { will-change: transform; }

/* --- 29. Les volets sur téléphone ----------------------------------------
   Sur grand écran, le volet répartit son contenu sur toute la hauteur : le
   rang en haut, le titre au centre, la phrase en bas. Sur téléphone cette
   répartition envoie la dernière ligne sous le bouton WhatsApp flottant,
   qui en cache une partie, et laisse le titre isolé au milieu d'un grand
   vide.

   On regroupe donc tout au centre de l'écran, et on réserve en bas la place
   du bouton flottant. Une commande fixe qui recouvre du texte est un défaut
   de mise en page, pas un détail : elle est toujours là, sur toutes les
   sections, et c'est au contenu de lui laisser sa place. */
@media (max-width: 820px) {
  .volet__in {
    justify-content: center;
    gap: .6rem;
    padding-bottom: clamp(6rem, 16vw, 8rem);
  }

  /* Le premier volet porte le titre de la section juste au-dessus de lui, et
     sur le meme bleu : les deux se lisent comme un seul ecran. Lui imposer
     cent pour cent de la hauteur en plus de la bande de titre faisait deux
     cent vingt pixels de bleu vide entre le sous-titre et « d'abord ». Il
     prend donc la hauteur de son contenu, et la bande de titre rend son
     rembourrage bas, qui ne separait rien puisque la couleur ne change pas.
     Le centrage reste : c'est la hauteur imposee qui etait de trop, pas
     l'alignement. Les deux volets suivants gardent leur pleine hauteur, eux
     arrivent seuls dans l'ecran.

     On ne touche pas a la hauteur, seulement a l'alignement. Essayee et
     jetee le meme jour : reduire la hauteur du premier volet casse
     l'epinglage. GSAP l'epingle quand son bas atteint le bas de la fenetre
     et lui fige sa hauteur en ligne, avec pinSpacing a false ; un volet plus
     court s'epingle trop tot et laisse reapparaitre le fond kraft de la page
     entre la bande de titre et lui. Le defaut corrige revenait en pire.

     L'ecart vise entre le sous-titre et « d'abord » est d'une cinquantaine
     de pixels : coller les deux textes serait aussi mauvais que les separer
     de deux cents. */
  .pile--bleu { padding-bottom: clamp(1.1rem, 3.5vw, 1.7rem); }
  .volet:first-child .volet__in {
    justify-content: flex-start;
    padding-top: clamp(1.9rem, 6vw, 2.8rem);
  }
  .volet__filet { margin: 1.1rem 0; }
  .volet h2 { font-size: clamp(2.6rem, 13vw, 4rem); }
  .volet p,
  .volet--encre p { margin-left: 0; max-width: 100%; font-size: 1.05rem; }
}

/* --- 30. Le paquet de cartes doit rester lisse ---------------------------
   Une carte collante à laquelle on applique un transform cesse un instant
   d'être collante : le transform crée un nouveau bloc conteneur et la carte
   retombe dans le flux avant de reprendre sa place. C'est le petit rebond
   qu'on voyait au moment où une gamme passait sur la précédente.

   L'apparition au défilement est donc coupée sur ces cartes, et seulement
   sur elles : le mouvement du paquet, lui, vaut mieux que le mouvement
   d'arrivée. */
@media (max-width: 820px) {
  /* Les caisses n'ont plus d'attribut data-pose : leur apparition est passee
     a GSAP, qui ne transforme que la vue et le texte, jamais la caisse
     elle-meme. C'est ce qui permet de garder le meme geste sur telephone
     sans decrocher le paquet de cartes collantes. */
}

/* Le bouton du menu garde une seule couleur : les trois traits sont un
   symbole, pas une icône de la famille à deux tons. Un trait orange au
   milieu se lisait comme un état actif. */
.burger svg { --trait2: currentColor; }

/* --- 32. Devenir revendeur -----------------------------------------------
   Les magasins et les revendeurs sont le segment sur lequel le client veut
   croître, et le site ne leur ouvrait aucune porte. Bloc clair entre deux
   sections sur fond de page, pour ne pas enchaîner deux champs sombres. */
.revendeur {
  background: var(--acier); border-radius: var(--r);
  padding: clamp(1.8rem, 4vw, 3rem);
  display: grid; gap: clamp(1.4rem, 3vw, 2.6rem); align-items: center;
}
@media (min-width: 900px) { .revendeur { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.revendeur h2 { font-size: clamp(1.7rem, 3.4vw, 2.4rem); text-wrap: balance; }
.revendeur h2::before {
  content: ""; display: block; width: 34px; height: 3px; border-radius: 3px;
  background: var(--orange); margin-bottom: .9rem;
}
.revendeur > div > p { margin-top: 1rem; font-size: var(--t-lede); color: var(--gris); max-width: 42ch; }
.revendeur__actes { margin-top: 1.6rem; display: flex; flex-wrap: wrap; gap: .7rem; }

.conditions li { padding: .95rem 0; border-bottom: 1px solid var(--acier-2); display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: .9rem; align-items: start; }
.conditions li:first-child { padding-top: 0; }
.conditions li:last-child { border-bottom: 0; }
.conditions .ico { width: 26px; height: 26px; color: var(--bleu); }
.conditions b { display: block; font-family: var(--titre); font-weight: 700; font-size: 1rem; color: var(--encre); letter-spacing: -.02em; }
.conditions p { margin-top: .2rem; font-size: var(--t-sm); color: var(--gris); line-height: 1.5; }

/* --- 33a. Pourquoi nous choisir, le coverflow ----------------------------
   Quatre raisons, chacune avec sa photographie. La carte du milieu se tient
   droite et pleine, ses voisines s'effacent en tournant sur l'axe vertical.
   Porte par 21st.dev, ramene dans le monde du depot : ni or, ni halo, ni
   verre depoli, ni ombre coloree. Un champ sombre, des blocs, des filets.

   Le texte ne se pose jamais sur la photographie. Chaque carte est une image
   plus un bloc de texte dessous, comme les caisses des gammes : une legende
   posee sur une image en masque le sujet a la taille ou on la regarde.

   Aucune bibliotheque. Le script pose un attribut data-cf qui vaut l'ecart
   signe a la carte active, et tout le reste est ici. Sans script les quatre
   cartes se lisent en colonne, dans l'ordre. */
.pourquoi { background: var(--fond-nuit); color: #fff; overflow: hidden; }
.pourquoi .titre-pile h2 { color: #fff; }
/* Le chapeau tient sur une ligne sur un ecran large. La mesure commune des
   sections est de 46 caracteres, taillee pour des sous-titres de deux lignes ;
   celui-ci est court et se casserait en deux pour rien. */
.pourquoi .titre-pile p { color: rgba(255, 255, 255, .72); max-width: 54ch; }

.cf { margin-top: clamp(2.2rem, 3.6vw, 3.4rem); }

/* Sans script : une colonne lisible, rien de cache. */
.cf__scene { display: grid; gap: var(--jeu); }
.cf__carte { background: var(--kraft); border-radius: var(--r); overflow: hidden; color: var(--encre-2); }
.cf__vue { display: block; aspect-ratio: 3 / 2; background: var(--acier-2); }
.cf__vue img { width: 100%; height: 100%; object-fit: cover; }
.cf__mot { display: block; padding: clamp(1.1rem, 2vw, 1.5rem) clamp(1.2rem, 2.2vw, 1.7rem) clamp(1.3rem, 2.4vw, 1.8rem); }
.cf__rang { display: block; color: var(--orange); }
.cf__carte h3 { margin-top: .6rem; font-size: clamp(1.14rem, 1.9vw, 1.4rem); letter-spacing: -.025em; }
.cf__carte p { margin-top: .5rem; font-size: var(--t-sm); line-height: 1.55; color: var(--gris); }

.cf__barre { display: none; }

/* Avec script : la scene devient un plateau en perspective et les cartes s'y
   posent les unes derriere les autres. */
.js .cf[data-arme] .cf__scene {
  display: block; position: relative;
  height: clamp(430px, 52vw, 560px);
  perspective: 1500px;
}
.js .cf[data-arme] .cf__carte {
  position: absolute; top: 0; left: 50%;
  width: min(84vw, 30rem);
  margin-left: calc(min(84vw, 30rem) / -2);
  transform-origin: center center;
  transition: transform .8s var(--sortie), opacity .8s var(--sortie);
  will-change: transform;
}
@media (min-width: 900px) {
  .js .cf[data-arme] .cf__carte { width: 32rem; margin-left: -16rem; }
}

/* La carte tenue, ses deux voisines, puis le reste hors champ. Les valeurs
   sont volontairement courtes : au-dela, les voisines sortent du cadre sur un
   ecran de portable et la scene se vide. */
.js .cf[data-arme] .cf__carte            { opacity: 0; pointer-events: none; z-index: 1; transform: translateX(0) scale(.6); }
.js .cf[data-arme] [data-cf="0"]         { opacity: 1; pointer-events: auto; z-index: 30; transform: translateX(0) scale(1) rotateY(0); }
.js .cf[data-arme] [data-cf="-1"]        { opacity: .34; pointer-events: auto; z-index: 20; transform: translateX(-46%) scale(.82) rotateY(26deg); cursor: pointer; }
.js .cf[data-arme] [data-cf="1"]         { opacity: .34; pointer-events: auto; z-index: 20; transform: translateX(46%) scale(.82) rotateY(-26deg); cursor: pointer; }
.js .cf[data-arme] [data-cf="-2"]        { opacity: .12; z-index: 10; transform: translateX(-78%) scale(.68) rotateY(34deg); }
.js .cf[data-arme] [data-cf="2"]         { opacity: .12; z-index: 10; transform: translateX(78%) scale(.68) rotateY(-34deg); }

@media (max-width: 620px) {
  .js .cf[data-arme] [data-cf="-1"],
  .js .cf[data-arme] [data-cf="1"]  { opacity: .28; transform: translateX(-62%) scale(.8) rotateY(22deg); }
  .js .cf[data-arme] [data-cf="1"]  { transform: translateX(62%) scale(.8) rotateY(-22deg); }
  .js .cf[data-arme] [data-cf="-2"],
  .js .cf[data-arme] [data-cf="2"]  { opacity: 0; }
}

/* La barre de commande. Elle n'existe que si le script tourne : sans lui il
   n'y a rien a commander, les quatre cartes sont deja toutes lisibles. */
.js .cf[data-arme] .cf__barre {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(1rem, 2.4vw, 1.8rem);
  margin-top: clamp(1.6rem, 2.6vw, 2.4rem);
}
.cf__fleche {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; flex: none;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .26);
  color: #fff;
  transition: background-color .2s, border-color .2s;
}
.cf__fleche svg { width: 20px; height: 20px; }
.cf__fleche:hover { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .5); }
.cf__fleche:focus-visible { outline: 3px solid var(--orange); outline-offset: 3px; }

.cf__pastilles { display: flex; align-items: center; gap: .5rem; }
.cf__pastilles button {
  height: 8px; width: 8px; padding: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, .3);
  transition: width .3s var(--sortie), background-color .3s;
}
.cf__pastilles button[aria-selected="true"] { width: 30px; background: var(--orange); }
.cf__pastilles button:focus-visible { outline: 3px solid var(--orange); outline-offset: 4px; }

@media (prefers-reduced-motion: reduce) {
  .js .cf[data-arme] .cf__carte { transition: none; }
  .cf__pastilles button { transition: none; }
}

/* --- 33b. Les etats de depart des gestes GSAP ----------------------------
   Aucun de ces etats n'existe sans script : la page sans JavaScript, ou avec
   un GSAP qui n'arrive jamais, est entierement lisible. Le script pose
   .est-armee au moment ou la bibliotheque a repondu, deux ecrans avant que
   la section n'entre dans le cadre, et c'est cette classe qui cache. */

/* Le masque d'une ligne : elle monte de dessous un filet invisible. C'est le
   seul moyen de faire apparaitre du texte sans fondu. Le fondu dit « je
   charge », le masque dit « je me pose ». */
.masque { display: block; overflow: hidden; }
.masque--mot { display: inline-block; vertical-align: top; }
.masque__in { display: block; will-change: transform; }
.est-armee .masque__in { transform: translateY(115%); }

/* Les caisses : le volet monte sur la photographie pendant que l'image
   revient a sa taille. Rien ne s'estompe, tout se decouvre. */
.empilement.est-armee .caisse__vue { clip-path: inset(0 0 100% 0); }
.empilement.est-armee .caisse__vue img { transform: scale(1.16); }
.empilement.est-armee .caisse__sceau { transform: scale(.4); opacity: 0; }

/* Les faits : le trace de l'icone se dessine d'un bout a l'autre. La valeur
   200 est plus longue que le plus long trace de la grille 24, donc le trait
   est integralement cache avant que le script ne mesure sa longueur. */
.manifeste.est-armee .fait__ico svg > * { stroke-dasharray: 200; stroke-dashoffset: 200; }

@media (prefers-reduced-motion: reduce) {
  .est-armee .masque__in { transform: none; }
  .empilement.est-armee .caisse__vue { clip-path: none; }
  .empilement.est-armee .caisse__vue img { transform: none; }
  .empilement.est-armee .caisse__sceau { transform: none; opacity: 1; }
  .manifeste.est-armee .fait__ico svg > * { stroke-dasharray: none; stroke-dashoffset: 0; }
}

/* --- 34. Les questions pratiques -----------------------------------------
   Une liste depliable sans une ligne de script : <details> fait tout le
   travail, et la page reste utilisable quand le JavaScript ne se charge pas,
   ce qui arrive souvent sur une connexion faible.

   Filets plutot que cartes, comme le manifeste : c'est de l'information, pas
   une vitrine. Le repere d'ouverture est un chevron dessine en deux bordures.
   Surtout pas un signe plus qui devient un signe moins : sur cette page, un
   trait horizontal isole se lit comme un tiret cadratin. */
/* La bande d'acier : le seul fond de section qui ne soit ni le kraft de la
   page ni un champ de couleur pleine. Elle existe pour separer la carte du
   dernier appel, qui sans elle se suivaient sur le meme fond. */
.pile--acier { background: var(--acier); }

/* Le titre de la marche a suivre se pose sur le meme bleu que le premier
   volet, et sur le bleu plein, pas sur le degrade. Sinon le degrade se
   relance au raccord et fabrique une marche visible entre les deux. Pose sur
   le fond kraft de la page, comme il l'etait, ce titre laissait une bande
   claire coincee entre le champ sombre des cartes et le bleu du volet : le
   client l'a vue tout de suite, et c'etait bien un defaut de montage. */
.pile--bleu { background: var(--bleu); color: #fff; margin-bottom: -1px; }
.pile--bleu .titre-pile h2 { color: #fff; }
.pile--bleu .titre-pile p { color: rgba(255, 255, 255, .78); }

.questions { max-width: 46rem; margin: clamp(2.2rem, 3.6vw, 3.2rem) auto 0; border-top: 1px solid var(--acier-2); }
.questions details { border-bottom: 1px solid var(--acier-2); }

.questions summary {
  display: flex; align-items: center; gap: 1.2rem;
  padding-block: 1.15rem;
  list-style: none; cursor: pointer;
  font-family: var(--titre); font-weight: 600;
  font-size: clamp(1.02rem, 1.5vw, 1.16rem); line-height: 1.35;
  color: var(--encre); text-wrap: pretty;
}
.questions summary::-webkit-details-marker { display: none; }
.questions summary:hover { color: var(--bleu); }
.questions summary:focus-visible { outline: 2px solid var(--bleu); outline-offset: 4px; border-radius: var(--r-sm); }

.questions summary::after {
  content: ""; flex: none; margin-inline-start: auto;
  width: .52rem; height: .52rem;
  border-right: 2px solid var(--bleu); border-bottom: 2px solid var(--bleu);
  transform: translateY(-.16rem) rotate(45deg);
  transition: transform .28s var(--sortie);
}
.questions details[open] summary::after { transform: translateY(.1rem) rotate(-135deg); }
@media (prefers-reduced-motion: reduce) { .questions summary::after { transition: none; } }

.questions details > p {
  margin: 0; padding: 0 2rem 1.35rem 0;
  max-width: 62ch;
  font-size: var(--t-sm); line-height: 1.6; color: var(--encre-2);
}

/* --- 33. Les canaux officiels --------------------------------------------
   Sur un marché où l'acheteur craint d'abord de se faire avoir, nommer ses
   seuls numéros vaut plus qu'une promesse de qualité. Le bloc est encadré
   et non coloré : c'est une mise en garde, pas une réclame. */
.canaux {
  margin-top: var(--jeu);
  border: 2px solid var(--encre); border-radius: var(--r);
  padding: clamp(1.4rem, 3vw, 2rem);
  display: grid; gap: 1.2rem;
}
@media (min-width: 780px) { .canaux { grid-template-columns: auto minmax(0, 1fr); align-items: start; } }
.canaux .ico { width: 34px; height: 34px; color: var(--orange); }
.canaux h2 { font-size: 1.25rem; }
.canaux p { margin-top: .6rem; font-size: var(--t-sm); color: var(--gris); max-width: 60ch; }
.canaux ul { margin-top: 1rem; display: flex; flex-wrap: wrap; gap: .5rem; }
.canaux ul li {
  font-family: var(--titre); font-weight: 700; font-size: .95rem; color: var(--encre);
  background: var(--acier); border-radius: 999px; padding: .5rem 1rem;
  font-variant-numeric: tabular-nums;
}
