/* ============================================================================
   CLOUD QUARRY — le monde visuel de la home MonsieurWeb.
   Monde choisi par Yvon dans le catalogue Impeccable
   (dream-surreal-impossible-worlds-cloud-quarry). Références :
   .impeccable/monde-cloud-quarry/{board-systeme,demo-page-reference}.webp

   SCOPE : tout est préfixé « body.cq ». Aucune règle de ce fichier ne
   peut atteindre les 34 autres pages, même s'il est chargé partout. Retirer
   son <link> dans partials/head.html ramène le monde « Grille Suisse » intact.

   Les images sont les VRAIES images de la démo, recadrées sur leurs régions
   propres (images/cq/). Aucune n'est générée ni inventée.
   ========================================================================== */

body.cq {
  /* Palette relevée sur la planche système, aux valeurs qu'elle affiche */
  --cq-cumulus:  #F4F6F8;   /* le blanc de pierre, fond clair du monde */
  --cq-void:     #4EA6FF;   /* VOID BLUE : l'accent, porte l'ENCRE, jamais du blanc */
  --cq-cobalt:   #1668C9;   /* le bleu profond : seule surface bleue qui porte du blanc */
  --cq-thunder:  #47535F;   /* l'ardoise */
  --cq-silver:   #C7CDD3;
  --cq-fog:      #E4E7EA;
  --cq-haze:     #D7EAF7;
  --cq-nuit:     #23272C;   /* mesuré sur le panneau de données du hero */
  --cq-encre:    #1B2228;   /* le texte sur clair */
  --cq-encre-2:  #5A656E;
  --cq-signal:   #D9483B;   /* signalisation de chantier : l'urgence, et rien d'autre */
  --cq-filet:    rgba(27, 34, 40, .22);
  --cq-filet-clair: rgba(244, 246, 248, .28);

  --cq-plaque:   url("../images/cq/plaque.webp");
  --cq-pierre:   url("../images/cq/pierre.webp");

  /* LA recette de rivets, une seule fois. Deux porteurs la réclament : la classe
     .cq-rivets (posée dans le markup) et le pseudo-élément qui dessine le cadre
     de la plaque de section, qui ne peut pas porter de classe. Une recette de
     rivets recopiée diverge : elle vit ici, elle est référencée deux fois.
     ⚠ L'arrêt transparent n'est pas cosmétique : un radial-gradient sans lui
     étend sa DERNIÈRE couleur à tout l'élément, et les quatre têtes de rivet
     deviennent quatre voiles gris qui noient la plaque (vu le 2026-08-06). */
  --cq-rivets:
    radial-gradient(circle 4px at 15px 15px, #fdfdfd 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%),
    radial-gradient(circle 4px at calc(100% - 15px) 15px, #fdfdfd 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%),
    radial-gradient(circle 4px at 15px calc(100% - 15px), #fdfdfd 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%),
    radial-gradient(circle 4px at calc(100% - 15px) calc(100% - 15px), #fdfdfd 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%);

  /* Exo 2 (choix d'Yvon, 2026-08-06) remplace la stencil de carrière. Pas de
     face système dans la chaîne de repli. Exo 2 porte une chasse NORMALE :
     toutes les tailles de titre du monde sont recalibrées en conséquence. */
  --cq-stencil: "Exo 2", "Archivo", "Helvetica Neue", sans-serif;
  --cq-mono: "JetBrains Mono", ui-monospace, monospace;
  --cq-sans: "Archivo", "Helvetica Neue", Arial, sans-serif;

  background: var(--cq-cumulus);
  color: var(--cq-encre);
  font-family: var(--cq-sans);
}

/* Les rivets : 4 têtes de rivet posées aux coins d'une plaque, en pur CSS.
   Une plaque rivetée est le composant de base du monde ; elle n'a donc pas
   le droit de coûter un élément de markup par coin. */
body.cq .cq-rivets {
  background-image: var(--cq-rivets);
  background-repeat: no-repeat;
}

/* ── Typographie du monde ────────────────────────────────────────────────── */
body.cq h1,
body.cq h2,
body.cq h3,
body.cq .cq-display {
  font-family: var(--cq-stencil);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: -.015em;
  /* .84 sur deux lignes de capitales accentuées fait toucher l'accent
     circonflexe de COÛTE à la ligne du dessous : les h2 respirent à .92. */
  line-height: 1.12;
  color: var(--cq-encre);
  font-variation-settings: normal;
}
body.cq .cq-hero h1 { line-height: 1; letter-spacing: -.025em; }
body.cq .cq-mono,
body.cq .cq-kicker,
body.cq .cq-cote,
body.cq .cq-tab th,
body.cq .cq-tab td {
  font-family: var(--cq-mono);
  font-size: .74rem;
  letter-spacing: .16em;
  text-transform: uppercase;
}
body.cq p { line-height: 1.62; }
/* Une ligne qu'on veut d'un seul tenant... quand il y a la place. À 375 le
   nowrap faisait déborder de 223 px (contact, 2026-08-07). */
@media (min-width: 760px) { body.cq .cq-nowrap-large { white-space: nowrap; } }
/* `overflow-wrap: break-word` sur TOUS les titres du monde : c'est le filet qui
   garantit qu'aucun titre ne peut sortir de sa boîte, quel que soit le texte que
   verite.py ou une page neuve y mettra demain. Il ne se déclenche que si un mot
   ne rentre PAS : les titres qui vont bien ne changent pas d'un pixel. */
body.cq h1, body.cq h2, body.cq h3 { text-wrap: balance; overflow-wrap: break-word; }

/* ══ NAV ═══════════════════════════════════════════════════════════════════
   Le comp pose la barre PAR-DESSUS la carrière : ardoise translucide, filet
   clair en bas, et le bouton de droite en plaque de métal collée au bord. */
body.cq .nav {
  position: absolute;
  top: 0; left: 0; right: 0;
  background: rgba(35, 39, 44, .52);
  backdrop-filter: blur(3px) saturate(.9);
  -webkit-backdrop-filter: blur(3px) saturate(.9);
  border-bottom: 1px solid var(--cq-filet-clair);
  box-shadow: none;
  z-index: 40;
}
body.cq .nav__inner {
  max-width: none;
  padding: 0 0 0 40px;
  align-items: stretch;
  min-height: 64px;
}
body.cq .nav__logo,
body.cq .nav__logo:hover {
  font-family: var(--cq-stencil);
  font-weight: 800;
  font-size: 1.46rem;
  letter-spacing: -.005em;
  word-spacing: .16em;
  text-transform: uppercase;
  color: var(--cq-cumulus);
  display: flex;
  align-items: center;
  padding-right: 26px;
  border-right: 1px solid var(--cq-filet-clair);
}
body.cq .nav__logo span { color: var(--cq-void); }
body.cq .nav__links { align-items: center; }
body.cq .nav__links a {
  font-family: var(--cq-mono);
  font-size: 14px;
  letter-spacing: .04em;
  text-transform: uppercase;
  font-weight: 400;
  color: rgba(244, 246, 248, .84);
}
body.cq .nav__links a:hover,
body.cq .nav__links a.is-active { color: var(--cq-void); }
body.cq .nav__end { align-items: stretch; }
body.cq .nav .btn {
  display: flex;
  align-items: center;
  gap: 10px;
  background-color: #cdd1d4;
  background-image: var(--cq-plaque);
  background-size: 170px auto;
  background-blend-mode: luminosity;
  color: var(--cq-encre);
  border: 0;
  border-left: 1px solid var(--cq-filet-clair);
  border-radius: 0;
  font-family: var(--cq-mono);
  font-size: 14px;
  letter-spacing: .04em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 0 26px;
  margin: 0;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .35);
}
body.cq .nav .btn::after {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--cq-signal);
  box-shadow: 0 0 0 2px rgba(217, 72, 59, .28);
}
body.cq .nav .btn:hover { background-color: #e2e5e7; transform: none; }
body.cq .nav__burger span { background: var(--cq-cumulus); }

/* ══ LE MÉGA-MENU ═════════════════════════════════════════════════════════
   Il tombait en beige pâle sur beige pâle : les items n'existaient qu'au
   survol. Ici il porte les couleurs du monde, et le cube filaire remplace
   l'animation « réseau » en or de l'ère Docteur Web. */
body.cq .nav__menu {
  background: var(--cq-cumulus);
  border: 1px solid var(--cq-filet);
  border-radius: 0;
  box-shadow: 0 18px 40px rgba(27, 34, 40, .16);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 110' fill='none' stroke='%231B2228' stroke-opacity='.30' stroke-width='1.3'%3E%3Cpath d='M20 30 L60 10 L100 30 L100 78 L60 98 L20 78 Z'/%3E%3Cpath d='M20 30 L60 50 L100 30M60 50 L60 98'/%3E%3Cpath d='M40 40 L40 88M80 40 L80 88M20 54 L60 74 L100 54' stroke-opacity='.17'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  /* le vide sous la 3e colonne : plus haut, le cube mord sur les liens */
  background-position: right 44px top 236px;
  background-size: 205px auto;
}
body.cq .nav__menu a {
  color: var(--cq-encre);
  font-family: var(--cq-sans);
  letter-spacing: 0;
  text-transform: none;
  font-size: .95rem;
}
body.cq .nav__menu a:hover { color: var(--cq-cobalt); }
body.cq .nav__menu-head {
  color: var(--cq-encre-2);
  font-family: var(--cq-mono);
  font-size: .7rem; letter-spacing: .16em; text-transform: uppercase;
}
body.cq .nav__menu-all {
  background: var(--cq-fog);
  color: var(--cq-encre);
  font-family: var(--cq-mono); font-size: .72rem; letter-spacing: .14em;
  text-transform: uppercase;
  border-top: 1px solid var(--cq-filet);
  /* le libellé pendait au fond de sa barre : on le recentre optiquement */
  padding: 15px 22px 13px 24px;
  line-height: 1.1;
}
/* Le SVG « réseau » hérité est remplacé, pas empilé. */
body.cq .nav__menu-art svg { display: none; }
/* Ce menu a sa propre cellule d'art : sans ça, il porte DEUX cubes, celui du
   conteneur et le sien (vu le 2026-08-06). */
body.cq .nav__menu--prof { background-image: none; }
body.cq .nav__menu-art {
  align-self: start;
  align-items: flex-start;
  min-height: 232px;
  background-position-y: top;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 110' fill='none' stroke='%231B2228' stroke-opacity='.30' stroke-width='1.3'%3E%3Cpath d='M20 30 L60 10 L100 30 L100 78 L60 98 L20 78 Z'/%3E%3Cpath d='M20 30 L60 50 L100 30M60 50 L60 98'/%3E%3Cpath d='M40 40 L40 88M80 40 L80 88M20 54 L60 74 L100 54' stroke-opacity='.17'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center top 4px;
  background-size: 240px auto;
}

/* ══ HERO ══════════════════════════════════════════════════════════════════
   La carrière de nuages en fond (image originale de la démo, région propre),
   voilée d'ardoise à gauche pour que la colonne de texte tienne dessus. */
body.cq .cq-hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 116px 0 236px;
  /* Chaque page pose la sienne : style="--cq-img:url('images/cq/xxx.webp')"
     sur la section. Le chemin est alors relatif au DOCUMENT, pas au CSS. */
  background: #2c3540 var(--cq-img, url("../images/cq/hero.webp")) center right / cover no-repeat;
  overflow: hidden;
}
body.cq .cq-hero::before {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(100deg,
      rgba(28, 35, 42, .96) 0%,
      rgba(28, 35, 42, .90) 26%,
      rgba(28, 35, 42, .62) 46%,
      rgba(28, 35, 42, .12) 66%,
      rgba(28, 35, 42, 0) 82%),
    linear-gradient(to top, rgba(24, 30, 36, .70) 0%, rgba(24, 30, 36, 0) 34%);
}
body.cq .cq-hero > * { position: relative; z-index: 2; }
body.cq .cq-hero__inner { max-width: 1280px; margin: 0 auto; padding: 0 40px; width: 100%; }
body.cq .cq-kicker {
  color: rgba(244, 246, 248, .72);
  margin: 0 0 26px;
  display: flex; align-items: center; gap: 14px;
}
body.cq .cq-kicker::before {
  content: ""; width: 34px; height: 1px; background: var(--cq-void);
}
body.cq .cq-hero h1 {
  margin: 0;
  font-size: clamp(2.4rem, 5.4vw, 4.8rem);
  /* 15ch était plus étroit que le plus large pavé insécable que la passe
     anti-veuve fabrique (budget h1 = 18 caractères : « saigne&nbsp;maintenant. »
     sur urgence). Le titre sortait de 57 px à 375 et de 34 px à 1440. */
  max-width: 17ch;
  /* Pas de `hyphens: auto` ici : une césure dans un display de 77 px se voit de
     l'autre bout de la pièce. La largeur fait le travail, break-word n'est que
     le dernier recours. */
  overflow-wrap: break-word;
  color: var(--cq-cumulus);
  /* Les lettres du comp sont TAILLÉES DANS LA PIERRE : la vraie texture de
     cumulus-stone de la démo remplit les glyphes. Le voile clair par-dessus
     empêche la texture de creuser des trous sombres dans les lettres. */
  background-image:
    linear-gradient(rgba(246, 248, 250, .30), rgba(246, 248, 250, .30)),
    var(--cq-pierre);
  background-size: auto, 300px auto;
  background-position: center;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: brightness(1.58) contrast(1.04) saturate(.42);
  text-shadow: none;
}
body.cq .cq-hero h1 em { font-style: normal; color: inherit; }
body.cq .cq-filet {
  border: 0;
  height: 1px;
  background: rgba(244, 246, 248, .55);
  margin: 34px 0 26px;
  max-width: 620px;
}
body.cq .cq-lede {
  font-family: var(--cq-mono);
  font-size: .85rem;
  line-height: 1.74;
  letter-spacing: .01em;
  color: rgba(244, 246, 248, .88);
  max-width: 50ch;
  margin: 0 0 32px;
}
body.cq .cq-lede strong { color: #fff; font-weight: 500; }

/* ── Le bouton-plaque : plaque de métal rivetée à coin coupé, bloc bleu « // »
      (composant PRIMARY BUTTON de la planche système) ───────────────────── */
body.cq .cq-plaque-btn {
  display: inline-flex;
  align-items: stretch;
  text-decoration: none;
  border: 0;
  font-family: var(--cq-mono);
  font-size: .78rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  font-weight: 500;
  transition: transform .16s ease, filter .16s ease;
}
/* ⚠ `.btn-row .btn` EST DANS CETTE RÈGLE, et ce n'est pas une commodité. Les bandes
   rendues par build.py ({{PRIX_BANDE}}) posent un `<a class="btn">` nu, sans les deux
   `<span>` du bouton-plaque : sans règle « body.cq », ces boutons sortaient en bleu
   #2b57d6 de l'ancien monde sur 5 pages. On leur donne LA MÊME matière plutôt qu'une
   imitation approchante — une recette de rivets recopiée est une recette qui divergera. */
body.cq .cq-plaque-btn > span:first-child,
body.cq .btn-row .btn {
  position: relative;
  background-color: #d7dade;
  /* Le bouton du comp est une plaque RIVETÉE : ses quatre têtes de rivet
     viennent avant la matière, sinon c'est un rectangle gris avec du texte. */
  background-image:
    radial-gradient(circle 3px at 12px 12px, #fff 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%),
    radial-gradient(circle 3px at calc(100% - 12px) 12px, #fff 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%),
    radial-gradient(circle 3px at 12px calc(100% - 12px), #fff 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%),
    radial-gradient(circle 3px at calc(100% - 12px) calc(100% - 12px), #fff 0%, #c9ced3 40%, #7d858c 76%, rgba(60,68,75,.5) 92%, transparent 94%),
    var(--cq-plaque);
  background-size: auto, auto, auto, auto, 190px auto;
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, repeat;
  background-blend-mode: normal, normal, normal, normal, luminosity;
  color: var(--cq-encre);
  padding: 19px 30px 19px 26px;
  clip-path: polygon(11px 0, 100% 0, 100% 100%, 0 100%, 0 11px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .45);
  display: flex; align-items: center;
}
/* La barre d'appui du comp, sous le libellé, à gauche. */
body.cq .cq-plaque-btn > span:first-child::after,
body.cq .btn-row .btn::after {
  content: "";
  position: absolute; left: 26px; right: 30px; bottom: 11px;
  height: 2px; background: var(--cq-encre); opacity: .82;
}
/* Le `<a class="btn">` nu n'hérite pas de la typographie du bouton-plaque (elle
   vit sur le parent .cq-plaque-btn) : il la reçoit ici, plus le chanfrein. */
body.cq .btn-row .btn {
  text-decoration: none; border: 0; border-radius: 0;
  font-family: var(--cq-mono);
  font-size: .78rem; letter-spacing: .18em; text-transform: uppercase;
  font-weight: 500;
  transition: filter .16s ease, transform .16s ease;
}
body.cq .btn-row .btn:hover {
  filter: brightness(1.06); transform: translateY(-1px);
  background-color: #d7dade; color: var(--cq-encre);
}
/* Le secondaire : contour d'encre, pas de plaque, comme `--sombre`. */
body.cq .btn-row .btn--ghost {
  background: transparent;
  background-image: none;
  color: var(--cq-encre);
  box-shadow: inset 0 0 0 1px rgba(27, 34, 40, .55);
}
body.cq .btn-row .btn--ghost::after { background: var(--cq-encre); opacity: .5; }
body.cq .btn-row .btn--ghost:hover {
  background: transparent; color: var(--cq-cobalt);
  box-shadow: inset 0 0 0 1px var(--cq-cobalt);
}
body.cq .btn-row {
  display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px;
}
body.cq .cq-plaque-btn > span:last-child {
  background: var(--cq-void);
  color: var(--cq-encre);
  display: flex; align-items: center;
  padding: 0 15px;
  font-weight: 700;
  letter-spacing: 0;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 11px), calc(100% - 11px) 100%, 0 100%);
}
body.cq .cq-plaque-btn:hover { filter: brightness(1.06); transform: translateY(-1px); }
body.cq .cq-plaque-btn--ghost > span:first-child {
  background: transparent;
  background-image: none;
  color: var(--cq-cumulus);
  box-shadow: inset 0 0 0 1px rgba(244, 246, 248, .55);
}
/* Le secondaire posé SUR une plaque claire : contour d'encre, bloc en ardoise. */
body.cq .cq-plaque-btn--sombre > span:first-child {
  background: transparent;
  background-image: none;
  color: var(--cq-encre);
  box-shadow: inset 0 0 0 1px rgba(27, 34, 40, .55);
}
body.cq .cq-plaque-btn--sombre > span:last-child {
  background: var(--cq-thunder);
  color: var(--cq-cumulus);
}

/* ── Le panneau de données du hero : le gabarit SITE 07 / CUMULUS STRATUM,
      devenu le relevé des coûts. Chaque ligne est une ancre. ───────────── */
body.cq .cq-panneau {
  position: absolute;
  left: max(40px, calc(50vw - 640px + 40px));
  bottom: 46px;
  z-index: 3;
  width: min(560px, calc(100vw - 80px));
  background: rgba(35, 39, 44, .93);
  box-shadow: inset 0 0 0 1px rgba(199, 205, 211, .30);
  display: grid;
  grid-template-columns: 1fr 132px;
}
body.cq .cq-panneau__head {
  grid-column: 1 / -1;
  padding: 12px 16px 11px;
  border-bottom: 1px solid rgba(199, 205, 211, .26);
  color: rgba(244, 246, 248, .88);
  display: flex; justify-content: space-between; gap: 12px;
}
body.cq .cq-panneau__lignes { padding: 6px 0 8px; }
body.cq .cq-panneau a {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 7px 16px;
  text-decoration: none;
  color: rgba(244, 246, 248, .78);
  border-left: 2px solid transparent;
}
body.cq .cq-panneau a:hover {
  background: rgba(78, 166, 255, .10);
  border-left-color: var(--cq-void);
  color: #fff;
}
body.cq .cq-panneau a b {
  font-weight: 500;
  color: var(--cq-cumulus);
  font-variant-numeric: tabular-nums;
  letter-spacing: .08em;
}
body.cq .cq-panneau a b.cq-gratuit { color: var(--cq-void); font-weight: 700; }
body.cq .cq-panneau__profil {
  border-left: 1px solid rgba(199, 205, 211, .26);
  display: flex; align-items: flex-end; justify-content: center;
  padding: 10px;
}
body.cq .cq-panneau__profil svg { width: 100%; height: auto; opacity: .62; }

/* ══ PLAQUES DE SECTION ════════════════════════════════════════════════════
   « CARVE WITH PRECISION » : la plaque de métal rivetée, sa cellule de titre
   bordée à gauche, le corps au centre, et la machine à câble à droite. */
/* ══ L'ALTERNANCE (règle d'Yvon, 2026-08-07) ═══════════════════════════════
   Texte à gauche et image à droite, puis l'inverse sur la plaque suivante.
   Une page qui empile trois fois le même sens se lit comme un formulaire. */
body.cq .cq-plate--miroir .cq-plate__img { grid-column: 1; grid-row: 1 / 3; }
body.cq .cq-plate--miroir .cq-plate__head,
body.cq .cq-plate--miroir .cq-plate__body { grid-column: 2; }
body.cq .cq-plate--miroir .cq-plate__grid::before { grid-area: 1 / 2 / 3 / 3; }
body.cq .cq-plate--image.cq-plate--miroir .cq-plate__grid {
  grid-template-columns: 34% 1fr;
}
body.cq .cq-plate--miroir .cq-plate__img { border-left: 0; border-right: 1px solid rgba(27, 34, 40, .22); }

body.cq .cq-plate {
  position: relative;
  background-color: #e7e9ea;
  /* La plaque du comp n'est pas un aplat : c'est du béton clair sur lequel un
     plan technique est tracé. La tuile porte la matière, les gradients portent
     le tracé (verticales de cote + horizontale de niveau). */
  background-image:
    repeating-linear-gradient(90deg,
      rgba(27, 34, 40, .085) 0 1px, transparent 1px 118px),
    linear-gradient(0deg, rgba(27, 34, 40, .07) 0 1px, transparent 1px),
    var(--cq-plaque);
  background-size: auto, 100% 62%, 660px auto;
  background-position: 0 0, 0 0, center;
  background-blend-mode: normal, normal, luminosity;
  border-top: 1px solid rgba(27, 34, 40, .34);
  border-bottom: 1px solid rgba(27, 34, 40, .34);
  padding: 18px 0;
}
/* ⚠ DEUX RANGÉES, PAS TROIS COLONNES (regabarit du 2026-08-07, gabarit d'Yvon).
   L'ancien gabarit `400px 1fr 34%` posait le titre SEUL dans une cellule rivetée
   qui, elle, s'étirait sur toute la hauteur de la plaque : mesuré à 1440, le cadre
   de boutique.html faisait 549 px pour 210 px de contenu — 62 % de vide sous le
   titre — pendant que le corps s'étranglait à 36 caractères par ligne à côté.
   Pire cas du site : contact.html §02, cadre de 1357 px pour 129 px de contenu
   (90 % de vide), parce que le formulaire tenait la hauteur dans la colonne d'à
   côté. La cellule rivetée prend maintenant les DEUX TIERS de la largeur et le
   corps descend SOUS le titre, dans le même cadre : le cadre ne peut plus être
   plus haut que ce qu'il contient.
   Le cadre n'est plus porté par `.cq-plate__head` (il ne tiendrait que le titre)
   mais par un pseudo-élément de la grille posé sur les deux rangées : c'est ce
   qui permet de regabariter les 33 pages sans toucher à une ligne de leur HTML. */
/* Deux plaques qui se suivent partageaient DEUX traits collés : la ligne
   horizontale qu'Yvon a relevée entre les cartes (2026-08-07). Une seule. */
body.cq .cq-plate + .cq-plate { border-top: 0; }
body.cq .cq-plate__grid {
  max-width: 1280px; margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  align-items: stretch;
  min-height: 250px;
}
/* Le cadre riveté : il englobe le titre ET le corps. Sans contenu propre, il ne
   peut pas grandir tout seul — sa hauteur est celle des deux rangées. */
body.cq .cq-plate__grid::before {
  content: "";
  grid-column: 1; grid-row: 1 / 3;
  margin: 16px;
  box-shadow: inset 0 0 0 1px rgba(27, 34, 40, .34);
  background-image: var(--cq-rivets);
  background-repeat: no-repeat;
  pointer-events: none;
}
body.cq .cq-plate--image .cq-plate__grid { grid-template-columns: 1fr 34%; }
body.cq .cq-plate__img { grid-column: 2; grid-row: 1 / 3; }
/* Les marges de `head` et `body` répliquent celle du cadre : leurs bords sont
   donc exactement ceux du pseudo-élément, et la mesure du vide est vérifiable
   depuis le DOM (union head+body = cadre). */
body.cq .cq-plate__head {
  grid-column: 1; grid-row: 1;
  padding: 30px 40px 0;
  margin: 16px 16px 0;
  display: flex; flex-direction: column; justify-content: flex-start;
}
/* Le cadre a quitté la cellule de titre : elle ne le porte plus, ni ses rivets. */
body.cq .cq-plate__head.cq-rivets {
  box-shadow: none;
  background-image: none;
}
body.cq .cq-plate__head .cq-mono {
  display: flex; justify-content: space-between; gap: 12px;
  color: #4A555E;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--cq-filet);
  margin: 0 0 20px;
}
body.cq .cq-plate__head h2 {
  margin: 0;
  /* ⚠ LA TAILLE SUIT LA CELLULE, PAS LA FENÊTRE. La cellule fait maintenant les
     deux tiers de la grille : 845 px à 1280 et au-delà, soit 733 px de texte une
     fois la marge (2 × 16) et le padding (2 × 40) retirés — contre 268 px du
     temps de la colonne fixe de 400. Le plafond monte donc de 1,72rem à 2,35rem,
     et pas plus : à 37,6 px le plus long pavé insécable de la passe anti-veuve
     (22 caractères) demande ≈ 524 px, il reste 209 px de garde. Le plancher reste
     à 1,5rem : sous 980 px la cellule redevient étroite et c'est la césure qui
     tient le titre, exactement comme avant. */
  font-size: clamp(1.5rem, 2.9vw, 2.35rem);
  /* Filet de sécurité, et il n'est pas décoratif : la passe anti-veuve de build.py
     (TYPO_BUDGET_ATOME, h2 = 22 caractères) fabrique des pavés INSÉCABLES de 21
     caractères — « au&nbsp;strict&nbsp;nécessaire, », « la&nbsp;technique,&nbsp;réunie. ».
     Aucune taille lisible ne les fait tenir dans 328 px. Les pages sont en
     `lang="fr"` : la césure automatique coupe au bon endroit, et `break-word`
     attrape ce que le dictionnaire ne sait pas couper. Sans les deux, un mot
     unique suffit à faire ressortir le titre de sa plaque. */
  overflow-wrap: break-word;
  hyphens: auto;
}
body.cq .cq-plate__head .cq-souligne {
  margin-top: 20px; width: 74px; height: 2px; background: var(--cq-encre);
}
body.cq .cq-plate__body {
  grid-column: 1; grid-row: 2;
  padding: 26px 40px 34px;
  margin: 0 16px 16px;
  display: flex; flex-direction: column; justify-content: flex-start;
}
/* Une plaque sans colonne d'image a un cadre pleine largeur : le texte DOIT
   l'être aussi. Sur une seule colonne, le tiers droit du cadre restait vide,
   le défaut qu'Yvon a relevé sur boutique, protection-renseignements et
   a-propos (2026-08-07). Deux colonnes de spécification : la mesure de lecture
   reste bonne et le cadre est plein. Les boutons et les liens traversent. */
@media (min-width: 1060px) {
  body.cq .cq-plate:not(.cq-plate--image):not(.cq-close) .cq-plate__body {
    display: block;
    columns: 2;
    column-gap: 52px;
  }
  /* ⚠ PAS de break-inside: avoid ici. Avec un seul paragraphe, il l'empêche de
     se scinder : le texte reste entier dans la colonne 1 et la colonne 2 sort
     VIDE. C'est le vide qu'Yvon a repris sur a-propos (2026-08-07 05:01), alors
     que la règle des deux colonnes était bien active. Le texte coule d'une
     colonne à l'autre, comme dans un journal. */
  body.cq .cq-plate:not(.cq-plate--image):not(.cq-close) .cq-plate__body .cq-btnrow,
  body.cq .cq-plate:not(.cq-plate--image):not(.cq-close) .cq-plate__body .cq-lien {
    column-span: all;
    margin-top: 12px;
  }
}
/* Le corps de plaque parle en mono, comme la fiche technique du comp. */
body.cq .cq-plate__body p {
  margin: 0 0 26px;
  color: #2c353c;
  font-family: var(--cq-mono);
  font-size: .82rem;
  line-height: 1.9;
  /* ⚠ LA MESURE SE PLAFONNE SUR LE PARAGRAPHE, PAS SUR LA CELLULE. Le corps a
     hérité des deux tiers de la grille : sans borne il filerait à 93 caractères
     par ligne (733 px de mono à .82rem), et l'œil perd la ligne suivante. 78ch
     ≈ 614 px. Le `ch` est posé ICI, sur le <p>, parce que c'est LUI qui porte la
     mono : sur `.cq-plate__body`, qui hérite de l'Archivo du corps de page, le
     même 78ch aurait mesuré une autre police que celle qu'il borne. */
  max-width: 78ch;
}
body.cq .cq-plate__body p:last-of-type { margin-bottom: 28px; }
body.cq .cq-lien {
  font-family: var(--cq-mono);
  font-size: .74rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--cq-encre); text-decoration: none;
  display: inline-flex; align-items: center; gap: 16px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--cq-encre);
  align-self: flex-start;
}
body.cq .cq-lien:hover { color: var(--cq-cobalt); border-bottom-color: var(--cq-cobalt); }
body.cq .cq-plate__img {
  background: var(--cq-img, url("../images/cq/machine.webp")) center left / cover no-repeat;
  border-left: 1px solid rgba(27, 34, 40, .22);
  min-height: 260px;
}

/* ══ CARTES DE DONNÉES ═════════════════════════════════════════════════════
   Le composant CARD de la planche : bloc bleu à gauche (code + cube filaire
   + masse), tableau de mesures à droite, barre d'action en bas. */
/* Le champ des paliers garde le tracé du plan sous les fiches : sans lui,
   la page tombe dans un blanc de gabarit entre deux régions de matière. */
body.cq .cq-champ {
  background-color: var(--cq-cumulus);
  /* Les lignes de COTE du comp, verticales seulement : le mur de la démo porte
     des verticales et une cote, pas un quadrillage. Un quadrillage deux axes
     est un tic d'interface générée, et il n'est pas dans le monde. */
  background-image:
    repeating-linear-gradient(90deg, rgba(27, 34, 40, .06) 0 1px, transparent 1px 132px);
  border-bottom: 1px solid var(--cq-filet);
}
body.cq .cq-paliers {
  max-width: 1280px; margin: 0 auto;
  padding: 96px 40px 104px;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 34px;
}
/* ⚠ Le titre à gauche et le texte à droite avec `space-between` creusaient un
   vide au milieu : le défaut qu'Yvon a repris deux fois (ia-securite, ia,
   le-bilan, securite). Une grille 1/3 - 2/3 : le titre garde son tiers, le
   texte prend TOUT le reste. */
body.cq .cq-sechead {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: 1fr 2fr;
  align-items: end;
  gap: 48px;
  padding-bottom: 22px; margin-bottom: 12px;
  border-bottom: 1px solid var(--cq-filet);
}
/* Quand le sous-titre appartient au titre, il passe DESSOUS et le titre prend
   toute la largeur : rien ne pend plus à droite (securite, 2026-08-07). */
body.cq .cq-sechead--plein { grid-template-columns: 1fr; }
body.cq .cq-sechead--plein h2 { max-width: 26ch; }
body.cq .cq-sechead h2 { margin: 0; font-size: clamp(1.8rem, 3.1vw, 2.9rem); max-width: 20ch; }
body.cq .cq-sechead p { margin: 0; color: var(--cq-encre-2); max-width: none; font-size: .98rem; }
body.cq .cq-card {
  min-width: 0;
  display: grid;
  grid-template-columns: 148px 1fr;
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(27, 34, 40, .26);
}
body.cq .cq-card__id {
  background: var(--cq-void);
  color: var(--cq-encre);
  padding: 18px 14px 16px;
  display: flex; flex-direction: column; justify-content: space-between; gap: 12px;
}
body.cq .cq-card__id strong {
  font-family: var(--cq-stencil);
  font-size: 1.85rem; font-weight: 600; letter-spacing: -.01em;
  text-transform: uppercase; line-height: .9;
}
body.cq .cq-card__id span { font-family: var(--cq-mono); font-size: .68rem; letter-spacing: .12em; }
body.cq .cq-card__id svg { width: 100%; height: auto; }
body.cq .cq-card__data { padding: 18px 22px 0; min-width: 0; }
body.cq .cq-card__data h3 {
  margin: 0 0 4px; font-size: 1.5rem;
  display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  hyphens: auto;
}
body.cq .cq-card__data h3 span {
  font-family: var(--cq-mono); font-size: .68rem; letter-spacing: .14em;
  color: var(--cq-encre-2); font-weight: 400;
}
body.cq .cq-card__note {
  margin: 0 0 14px; font-size: .95rem; color: #39424a; line-height: 1.55;
}
body.cq .cq-tab { width: 100%; border-collapse: collapse; }
body.cq .cq-tab th, body.cq .cq-tab td {
  text-align: left; padding: 8px 0; border-top: 1px solid var(--cq-filet);
  font-size: .71rem;
}
body.cq .cq-tab th {
  color: var(--cq-encre-2); font-weight: 400;
  padding-right: 16px; white-space: nowrap;
}
body.cq .cq-tab td {
  text-align: right; color: var(--cq-encre); font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: .06em;
}
body.cq .cq-tab td.cq-etat { color: var(--cq-cobalt); }
body.cq .cq-card__cta {
  grid-column: 1 / -1;
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 22px;
  border-top: 1px solid rgba(27, 34, 40, .26);
  font-family: var(--cq-mono); font-size: .72rem; letter-spacing: .18em;
  text-transform: uppercase; text-decoration: none; color: var(--cq-encre);
}
body.cq .cq-card__cta:hover { background: var(--cq-haze); color: var(--cq-cobalt); }

/* ══ LA BANDE « COMMENT JE FACTURE » ═══════════════════════════════════════
   Ce bloc est RENDU PAR build.py (tokens de verite.py) avec le vocabulaire de
   classes de l'ancien monde : on ne réécrit pas son contenu, on l'habille.
   Le reveal est neutralisé : Cloud Quarry n'anime rien à l'entrée, et un texte
   qui dépend du JS pour devenir visible est un texte qui peut disparaître. */
body.cq .reveal { opacity: 1 !important; transform: none !important; }
body.cq .section--soft {
  background: var(--cq-fog);
  border-top: 1px solid var(--cq-filet);
  border-bottom: 1px solid var(--cq-filet);
  padding: 84px 0 90px;
}
body.cq .section--soft .container { max-width: 1280px; padding: 0 40px; }
/* ⚠ LE TITRE SE PORTE SEUL (règle du monde, DESIGN.md « Don't »). L'étiquette ne
   se jette pas pour autant : build.py la rend maintenant APRÈS le h2, et elle se
   pose À CÔTÉ du titre, sur sa ligne de base, en cote mono — exactement la
   grammaire de `.cq-sechead` (titre à gauche, donnée à droite). */
body.cq .section--soft .sechead,
body.cq .section--paper .sechead {
  display: flex; flex-direction: row;
  align-items: flex-end; justify-content: space-between;
  gap: 12px 30px; flex-wrap: wrap;
  padding-bottom: 22px; margin-bottom: 40px;
  border-bottom: 1px solid var(--cq-filet);
  /* style.css borne la .sechead à 900 px : son filet s'arrêtait 300 px avant les
     fiches posées dessous, et la cote n'avait pas la place d'aller au bout.
     Dans ce monde-ci l'en-tête tient la MÊME largeur que ce qu'il annonce. */
  max-width: none;
}
body.cq .section--soft .sechead > div,
body.cq .section--paper .sechead > div {
  display: flex; gap: 18px; align-items: baseline;
  flex: 0 0 auto; padding-bottom: 5px;
}
body.cq .section--soft .sechead h2,
body.cq .section--paper .sechead h2 { flex: 1 1 18ch; }
body.cq .section--soft .secnum,
body.cq .section--paper .secnum { display: none; }
/* ⚠ L'étiquette était `display: none` (monsieurweb.css : « eyebrow banni du
   monde »). Bannir la POSITION est juste ; jeter l'INFORMATION ne l'est pas :
   « Le prix, affiché », « Comment je facture », c'est la cote de la section.
   Elle revient donc, en mono, à droite du titre, sur sa ligne de base. */
body.cq .section--soft .label,
body.cq .section--paper .label {
  display: block;
  margin: 0;
  font-family: var(--cq-mono); font-size: .72rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--cq-encre-2);
}
body.cq .section--soft h2,
body.cq .section--paper h2 { margin: 0; font-size: clamp(1.7rem, 2.6vw, 2.4rem); max-width: 32ch; }
body.cq .section--soft h2 em,
body.cq .section--paper h2 em { font-style: normal; color: var(--cq-cobalt); }

/* ══ LA BANDE DES PRIX ({{PRIX_BANDE}}, rendue par build.py) ════════════════
   Dernier bloc encore habillé par l'ancien monde : ses chiffres sortaient en
   Inter Tight CONDENSÉE (`font-variation-settings: "wdth" 72`), une chasse qui
   n'existe pas dans Cloud Quarry, et sa grille n'avait aucune règle « body.cq ».
   Vu sur wordpress, boutique, courriel, serveur et fuite-donnees.
   Le vocabulaire de classes reste celui de l'ancien monde : on l'HABILLE. */
body.cq .stats__grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0;
  border-top: 1px solid var(--cq-filet);
  border-bottom: 1px solid var(--cq-filet);
}
body.cq .stat {
  padding: 30px 28px 28px;
  border-right: 1px solid var(--cq-filet);
  min-width: 0;
}
body.cq .stat:last-child { border-right: 0; }
body.cq .stat__num {
  font-family: var(--cq-stencil);
  /* la chasse condensée de l'ancien monde n'a pas cours ici */
  font-variation-settings: normal;
  font-weight: 600;
  font-size: clamp(2.3rem, 4.4vw, 3.5rem);
  line-height: 1.04; letter-spacing: -.015em;
  color: var(--cq-encre);
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
}
body.cq .stat__cap {
  margin-top: 14px;
  font-family: var(--cq-mono); font-size: .72rem; letter-spacing: .15em;
  text-transform: uppercase; color: var(--cq-encre-2); line-height: 1.7;
}
@media (max-width: 980px) {
  body.cq .stats__grid { grid-template-columns: 1fr; }
  body.cq .stat {
    border-right: 0; border-bottom: 1px solid var(--cq-filet);
    padding: 24px 0 22px;
  }
  body.cq .stat:last-child { border-bottom: 0; }
}
/* L'ancien monde encadrait le GROUPE et collait les deux cartes (gouttière
   nulle, cadre partagé). Cloud Quarry pose des fiches autonomes : le cadre du
   conteneur devient un double trait qui relie les rectangles. Il saute. */
body.cq .cards2 {
  display: grid; grid-template-columns: 1fr 1fr; gap: 28px;
  border: 0; margin-top: 0;
}
body.cq .cards2 .card {
  background: var(--cq-cumulus);
  box-shadow: inset 0 0 0 1px rgba(27, 34, 40, .26);
  border: 0; border-radius: 0;
  padding: 0; display: flex; flex-direction: column;
}
body.cq .cards2 .card__title {
  font-family: var(--cq-stencil); font-weight: 600; text-transform: uppercase;
  font-size: 1.4rem; letter-spacing: -.01em; color: var(--cq-encre);
  padding: 20px 24px 16px; border-bottom: 1px solid var(--cq-filet);
}
body.cq .cards2 .card__body {
  padding: 20px 24px 24px; color: #39424a; font-size: .96rem; line-height: 1.62; flex: 1;
}
body.cq .cards2 .card__take {
  border-top: 1px solid var(--cq-filet); padding: 13px 24px;
}
body.cq .cards2 .card__take a {
  font-family: var(--cq-mono); font-size: .72rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--cq-encre);
  /* l'ancien monde mettait ces liens en italique souligné */
  text-decoration: none; font-style: normal;
}
body.cq .cards2 .card__take a:hover { color: var(--cq-cobalt); }
@media (max-width: 980px) {
  body.cq .section--soft { padding: 60px 0 64px; }
  body.cq .section--soft .container { padding: 0 22px; }
  body.cq .cards2 { grid-template-columns: 1fr; gap: 20px; }
}

/* ══ LA GRILLE DES CADENCES (bloc {{FORFAIT}}, rendu par build.py) ═════════
   Dernier bloc encore habillé par l'ancien monde : ses prix sortaient en or
   #b57a0a, couleur qui n'existe pas dans Cloud Quarry. */
body.cq .rhythms {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px;
  border: 0; margin-top: 36px;
}
/* ⚠ LE NOMBRE DE COLONNES SUIT LE NOMBRE DE FICHES. Deux colonnes en dur, c'était
   la valeur qui convient au forfait (2 paliers) imposée à tout le monde : urgence
   porte TROIS paliers et sortait 2 fiches + 1 orpheline sur une deuxième rangée,
   à côté d'un trou. Un trou dans une grille se lit comme une erreur, pas comme du
   souffle. La variante se prend sur les enfants réels (:has), pas sur une classe
   qu'une page neuve oublierait de poser. */
body.cq .rhythms:has(> .rhythm:nth-child(3)) { grid-template-columns: repeat(3, 1fr); }
/* 4 fiches : 2 × 2, jamais 3 + 1. */
body.cq .rhythms:has(> .rhythm:nth-child(4)) { grid-template-columns: repeat(2, 1fr); }
/* 5 et plus : on laisse la grille se remplir d'elle-même. */
body.cq .rhythms:has(> .rhythm:nth-child(5)) {
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
}
body.cq .rhythm {
  background: var(--cq-cumulus);
  box-shadow: inset 0 0 0 1px rgba(27, 34, 40, .26);
  border: 0; border-radius: 0; padding: 22px 24px 26px;
}
body.cq .rhythm__price {
  font-family: var(--cq-stencil); font-weight: 600; font-size: 2.1rem;
  letter-spacing: -.01em; color: var(--cq-encre);
  font-variant-numeric: tabular-nums; font-style: normal;
  display: block; margin-bottom: 4px;
}
body.cq .rhythm__title {
  font-family: var(--cq-stencil); font-weight: 600; text-transform: uppercase;
  font-size: 1.15rem; letter-spacing: -.005em; color: var(--cq-encre);
  padding-bottom: 12px; margin-bottom: 14px;
  border-bottom: 1px solid var(--cq-filet);
}
body.cq .rhythm__body { color: #39424a; font-size: .95rem; line-height: 1.6; }
body.cq .rhythms__note {
  font-family: var(--cq-mono); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--cq-encre-2); font-style: normal;
  margin-top: 22px;
}
/* ⚠ LE REPLI MOBILE DOIT RÉ-ÉNUMÉRER LES VARIANTES :has(). Un `:has()` prend la
   spécificité de son argument : `body.cq .rhythms:has(> .rhythm:nth-child(3))`
   pèse (0,4,1) et BAT `body.cq .rhythms` (0,2,1) même à l'intérieur d'une media
   query — une media query ne change pas la spécificité, seulement l'ordre.
   Sans ces trois lignes, urgence gardait 3 colonnes à 375 px et le document
   débordait de 99 px (mesuré juste après avoir posé la variante, 2026-08-06). */
@media (max-width: 980px) {
  body.cq .rhythms,
  body.cq .rhythms:has(> .rhythm:nth-child(3)),
  body.cq .rhythms:has(> .rhythm:nth-child(4)),
  body.cq .rhythms:has(> .rhythm:nth-child(5)) {
    grid-template-columns: 1fr; gap: 20px;
  }
}

/* ══ LES IMAGES PAR PAGE ═══════════════════════════════════════════════════
   Le monde a plusieurs vues de la même carrière : chaque page porte la sienne,
   sinon les 25 pages servent la même photo et ça se voit. */
body.p-forfait .cq-hero { background-image: url("../images/cq/hero-forfait.webp"); }
/* Les QUATRE landings « modèle » (rendez-vous, soumission, boutique-en-ligne,
   magasin) sont rendues par build_landings() : elles n'ont pas de style en ligne,
   c'est ici qu'elles prennent leur image. Sans ces règles, les trois dernières
   tombaient sur l'image PAR DÉFAUT du monde et servaient la même photo que
   l'accueil : quatre pages sur cinq avec le même hero, ça se voit tout de suite. */
body.p-rendez-vous .cq-hero { background-image: url("../images/cq/hero-modele.webp"); }
body.p-soumission .cq-hero { background-image: url("../images/cq/hero-soumission.webp"); }
body.p-soumission .cq-plate__img { background-image: url("../images/cq/machine-soumission.webp"); background-position: center; }
body.p-boutique-en-ligne .cq-hero { background-image: url("../images/cq/hero-boutique-en-ligne.webp"); }
body.p-boutique-en-ligne .cq-plate__img { background-image: url("../images/cq/machine-boutique-en-ligne.webp"); background-position: center; }
body.p-magasin .cq-hero { background-image: url("../images/cq/hero-magasin.webp"); }
body.p-magasin .cq-plate__img { background-image: url("../images/cq/machine-magasin.webp"); background-position: center; }

/* ══ LES MESURES (preuves) ═════════════════════════════════════════════════ */
body.cq .cq-mesures {
  background: var(--cq-nuit);
  color: var(--cq-cumulus);
  border-top: 1px solid rgba(199, 205, 211, .22);
}
body.cq .cq-mesures__grid {
  max-width: 1280px; margin: 0 auto; padding: 92px 40px 96px;
}
body.cq .cq-mesures .cq-sechead { border-bottom-color: rgba(199, 205, 211, .26); }
body.cq .cq-mesures h2 { color: var(--cq-cumulus); }
body.cq .cq-mesures .cq-sechead p { color: rgba(244, 246, 248, .68); }
/* Une bande de mesures peut porter son visuel à droite : sans lui, un texte
   court laisse la moitié de la bande vide (securite, 2026-08-07). */
body.cq .cq-mesures--image .cq-mesures__grid {
  display: grid; grid-template-columns: 1fr 30%; gap: 48px; align-items: start;
}
body.cq .cq-mesures--image .cq-sechead,
body.cq .cq-mesures--image .cq-mesures__rangee,
body.cq .cq-mesures--image .cq-mesures__pied { grid-column: 1; }
body.cq .cq-mesures__img {
  grid-column: 2; grid-row: 1 / 4;
  background: var(--cq-img) center / cover no-repeat;
  box-shadow: inset 0 0 0 1px rgba(199, 205, 211, .26);
  min-height: 260px; align-self: stretch;
}
@media (max-width: 980px) {
  body.cq .cq-mesures--image .cq-mesures__grid { grid-template-columns: 1fr; }
  body.cq .cq-mesures__img { grid-column: 1; grid-row: auto; min-height: 190px; }
}
body.cq .cq-mesures__rangee {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid rgba(199, 205, 211, .26);
}
/* Trois colonnes en dur, c'était la rangée de l'accueil imposée à toutes les
   autres. Une rangée de 1, 2 ou 4 mesures a droit à sa propre découpe : sinon
   une mesure seule occupe un tiers de la bande et laisse deux tiers de vide. */
body.cq .cq-mesures__rangee:has(> .cq-mesure:nth-child(4)) {
  grid-template-columns: repeat(4, 1fr);
}
body.cq .cq-mesures__rangee:not(:has(> .cq-mesure:nth-child(2))) {
  grid-template-columns: 1fr;
}
body.cq .cq-mesures__rangee:has(> .cq-mesure:nth-child(2)):not(:has(> .cq-mesure:nth-child(3))) {
  grid-template-columns: repeat(2, 1fr);
}
body.cq .cq-mesure { padding: 40px 30px 34px; border-right: 1px solid rgba(199, 205, 211, .26); }
body.cq .cq-mesure:last-child { border-right: 0; }
/* À 4 mesures le chiffre doit rentrer dans un quart de bande, pas dans un tiers. */
body.cq .cq-mesures__rangee:has(> .cq-mesure:nth-child(4)) .cq-mesure strong {
  font-size: clamp(2.6rem, 4.6vw, 4.2rem);
}
body.cq .cq-mesure strong {
  display: block;
  font-family: var(--cq-stencil); font-weight: 600; text-transform: uppercase;
  font-size: clamp(3rem, 6.4vw, 5.6rem); line-height: 1.04;
  color: var(--cq-cumulus);
  font-variant-numeric: tabular-nums;
}
body.cq .cq-mesure span {
  display: block; margin-top: 18px;
  font-family: var(--cq-mono); font-size: .72rem; letter-spacing: .15em;
  text-transform: uppercase; color: rgba(244, 246, 248, .70); line-height: 1.7;
}
body.cq .cq-mesures__pied {
  margin: 46px 0 0; max-width: 66ch;
  color: rgba(244, 246, 248, .82); font-size: 1.02rem;
}

/* ══ CLOSE ════════════════════════════════════════════════════════════════ */
body.cq .cq-close .cq-plate__grid {
  grid-template-columns: 1.55fr 1fr;
  min-height: 250px;
}
body.cq .cq-btnrow { display: flex; flex-wrap: wrap; gap: 14px; }
/* La fiche de l'opérateur : la photo tenue dans une plaque rivetée. */
body.cq .cq-operateur {
  grid-column: 2; grid-row: 1 / 3;
  margin: 16px 16px 16px 0;
  box-shadow: inset 0 0 0 1px rgba(27, 34, 40, .34);
  padding: 14px 14px 0;
  display: flex; flex-direction: column;
  align-self: stretch;
  background: rgba(255, 255, 255, .34);
}
body.cq .cq-operateur img {
  width: 100%; height: auto; aspect-ratio: 4 / 5;
  object-fit: cover; object-position: center 12%;
  display: block; filter: grayscale(1) contrast(1.06) brightness(1.02);
}
/* Le portrait court : quand le texte de la plaque est bref, un cadre en 4/5
   creuse un vide sous lui. Le carré cadré sur le visage rend la hauteur. */
body.cq .cq-operateur--tete img { aspect-ratio: 1 / 1; object-position: center 4%; }
body.cq .cq-operateur--tete { align-self: start; }
body.cq .cq-operateur figcaption {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 11px 0 12px; color: var(--cq-encre-2);
  font-size: .68rem; letter-spacing: .12em;
}
/* Le burger hérite d'un contour doré de l'ancien monde : il n'existe pas ici. */
body.cq .nav__burger {
  background: transparent;
  border: 1px solid var(--cq-filet-clair);
  border-radius: 0;
}

/* ══ FOOTER ═══════════════════════════════════════════════════════════════ */
body.cq .footer {
  background: var(--cq-nuit);
  color: rgba(244, 246, 248, .78);
  border-top: 1px solid rgba(199, 205, 211, .26);
}
body.cq .footer a { color: rgba(244, 246, 248, .78); }
body.cq .footer a:hover { color: var(--cq-void); }
body.cq .footer .nav__logo {
  color: var(--cq-cumulus);
  font-family: var(--cq-stencil); font-weight: 800; font-size: 1.6rem;
  text-transform: uppercase; letter-spacing: .01em; word-spacing: .16em;
  border-right: 0; padding-right: 0;
}
body.cq .footer .nav__logo span { color: var(--cq-void); }
body.cq .footer__col-head {
  font-family: var(--cq-mono); font-size: .7rem; letter-spacing: .16em;
  text-transform: uppercase; color: rgba(244, 246, 248, .56);
}
body.cq .footer__mission { color: rgba(244, 246, 248, .62); }
body.cq .footer__bottom { border-top: 1px solid rgba(199, 205, 211, .20); }
body.cq .footer__copy,
body.cq .footer__legal a {
  font-family: var(--cq-mono); font-size: .7rem; letter-spacing: .12em;
  color: rgba(244, 246, 248, .68);
}

/* ══ RESPONSIVE ═══════════════════════════════════════════════════════════ */
@media (max-width: 1180px) {
  body.cq .cq-plate--image .cq-plate__grid { grid-template-columns: 1fr 30%; }
  body.cq .cq-close .cq-plate__grid { grid-template-columns: 1fr 240px; }
}
@media (max-width: 980px) {
  body.cq .cq-sechead { grid-template-columns: 1fr; gap: 20px; }
  body.cq .cq-hero { padding: 118px 0 220px; }
  body.cq .cq-hero::before {
    background:
      linear-gradient(100deg, rgba(28,35,42,.96) 0%, rgba(28,35,42,.88) 46%, rgba(28,35,42,.54) 74%, rgba(28,35,42,.30) 100%),
      linear-gradient(to top, rgba(24,30,36,.76) 0%, rgba(24,30,36,0) 40%);
  }
  /* Une colonne : le cadre riveté tient toujours titre + corps (rangées 1-2),
     et ce qui vivait à droite (image, opérateur) passe en rangée 3, DEHORS. */
  body.cq .cq-plate__grid,
  body.cq .cq-plate--image .cq-plate__grid,
  body.cq .cq-close .cq-plate__grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
  }
  body.cq .cq-plate__grid::before { margin: 14px; }
  body.cq .cq-plate__img,
  body.cq .cq-operateur { grid-column: 1; grid-row: 3; }
  /* Le miroir n'existe qu'à deux colonnes : en une seule, `grid-column: 2`
     fabrique une colonne implicite et le titre sort de l'écran (87 px mesurés
     à 375, 2026-08-07). */
  body.cq .cq-plate--miroir .cq-plate__head,
  body.cq .cq-plate--miroir .cq-plate__body,
  body.cq .cq-plate--miroir .cq-plate__img { grid-column: 1; }
  body.cq .cq-plate--miroir .cq-plate__img { grid-row: 3; border-right: 0; }
  body.cq .cq-plate--miroir .cq-plate__grid::before { grid-area: 1 / 1 / 3 / 2; }
  body.cq .cq-operateur { margin: 0 14px 16px; align-self: stretch; }
  body.cq .cq-operateur img { height: 210px; }
  body.cq .cq-plate__head { margin: 14px 14px 0; padding: 26px 28px 0; }
  body.cq .cq-plate__body { margin: 0 14px 14px; padding: 22px 28px 30px; }
  body.cq .cq-plate__img { min-height: 190px; border-left: 0; border-top: 1px solid rgba(27,34,40,.22); }
  body.cq .cq-paliers { grid-template-columns: 1fr; padding: 64px 22px 72px; gap: 26px; }
  body.cq .cq-mesures__grid { padding: 64px 22px 70px; }
  /* même piège de spécificité que .rhythms : les variantes :has() se ré-énumèrent */
  body.cq .cq-mesures__rangee,
  body.cq .cq-mesures__rangee:has(> .cq-mesure:nth-child(4)),
  body.cq .cq-mesures__rangee:has(> .cq-mesure:nth-child(2)):not(:has(> .cq-mesure:nth-child(3))) {
    grid-template-columns: 1fr;
  }
  body.cq .cq-mesure { border-right: 0; border-bottom: 1px solid rgba(199,205,211,.26); padding: 30px 0 26px; }
  body.cq .cq-mesure:last-child { border-bottom: 0; }
  /* Le menu déroulant se pose sur l'image : il lui faut un fond opaque. */
  body.cq .nav__links {
    background: var(--cq-nuit);
    border-bottom: 1px solid var(--cq-filet-clair);
  }
  body.cq .nav__inner { padding-left: 22px; }
  body.cq .nav__logo { font-size: 1.36rem; padding-right: 16px; }
}
@media (max-width: 720px) {
  body.cq .cq-hero__inner { padding: 0 22px; }
  body.cq .cq-hero h1 { font-size: clamp(2.1rem, 8.6vw, 3.4rem); max-width: 13ch; }
  body.cq .cq-panneau {
    left: 22px; right: 22px; width: auto; bottom: 34px;
    grid-template-columns: 1fr;
  }
  body.cq .cq-panneau__profil { display: none; }
  body.cq .cq-card { grid-template-columns: 84px 1fr; }
  /* sous 720px le libellé se replie : nowrap ferait déborder la fiche */
  body.cq .cq-tab th { white-space: normal; padding-right: 10px; }
  body.cq .cq-card__id strong { font-size: 1.5rem; }
  /* ⚠ Le bloc d'identifiant prend 84 px et le padding de la fiche 44 : il ne
     reste que 203 px pour le titre ET sa cote côte à côte. « HÉBERGEMENT » +
     « MENSUEL » demandaient 236 px et sortaient de 33 px (mesuré sur l'accueil,
     2026-08-06 ; même défaut sur 6 pages). La cote passe DESSOUS le titre : une
     cote qu'on serre jusqu'à la casser ne dit plus rien. */
  body.cq .cq-card__data h3 {
    display: block;
    font-size: 1.24rem;
  }
  body.cq .cq-card__data h3 span { display: block; margin-top: 5px; }
  body.cq .cq-plate__head { padding: 24px 22px 0; }
  body.cq .cq-plate__body { padding: 20px 22px 26px; }
  body.cq .nav .btn { padding: 0 16px; font-size: .68rem; letter-spacing: .12em; }
}
@media (max-width: 420px) {
  body.cq .nav__logo { font-size: 1.14rem; }
  body.cq .nav .btn { padding: 0 12px; }
  body.cq .cq-lede { font-size: .86rem; }
  body.cq .cq-panneau a { padding: 7px 12px; }
  body.cq .cq-mono, body.cq .cq-kicker, body.cq .cq-panneau a { font-size: .68rem; }
}
/* ══ LES SURFACES DU NAVIGATEUR ═══════════════════════════════════════════
   Sélection, curseur, anneau de focus, barre de défilement : ce que je n'ai
   pas dessiné porte quand même le monde. Par défaut, ça porte celui de
   personne. */
body.cq ::selection { background: var(--cq-void); color: var(--cq-encre); }
body.cq { accent-color: var(--cq-cobalt); caret-color: var(--cq-cobalt); scrollbar-color: var(--cq-thunder) var(--cq-fog); }
body.cq a:focus-visible,
body.cq button:focus-visible,
body.cq .nav .btn:focus-visible {
  outline: 2px solid var(--cq-void);
  outline-offset: 2px;
}
body.cq .cq-hero a:focus-visible,
body.cq .cq-panneau a:focus-visible,
body.cq .cq-mesures a:focus-visible,
body.cq .footer a:focus-visible { outline-color: var(--cq-void); }

/* ══ LE MOMENT ════════════════════════════════════════════════════════════
   Un seul mouvement, celui du monde : la charge qui se pose. Le titre, puis
   le relevé qui vient s'appuyer dessous. Rien d'autre ne bouge sur la page. */
@keyframes cq-pose {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
body.cq .cq-hero__inner > * { animation: cq-pose .72s cubic-bezier(.16,.84,.3,1) both; }
body.cq .cq-hero__inner > *:nth-child(2) { animation-delay: .07s; }
body.cq .cq-hero__inner > *:nth-child(3) { animation-delay: .13s; }
body.cq .cq-hero__inner > *:nth-child(4) { animation-delay: .19s; }
body.cq .cq-panneau { animation: cq-pose .8s cubic-bezier(.16,.84,.3,1) .3s both; }

@media (prefers-reduced-motion: reduce) {
  body.cq * { transition: none !important; animation: none !important; }
}
