@charset "UTF-8";
/* ==========================================================================
   DPH Net — feuille de style du site

   Cette feuille porte la MÉCANIQUE du moteur de Spin’Info — grille, en-tête
   « A » et son en-tête collant, barre et tiroir mobiles, boutons de
   révélation, visionneuse, contours de focus, impression — avec les valeurs
   de DPH Net que donne l'inventaire (dphwork/rapport_base.md,
   db/plans/*.txt, live/pages/*.json). L'en-tête (§ 4), le pied (§ 5) et la
   barre mobile (§ 9) sont mesurés sur l'original à 1440, 600 et 390 px, et
   leurs cotes sont écrites à côté des règles. Les cotes de blocs qui n'ont
   pas encore été relevées sont marquées « provisoire ».

   Aucune règle en ligne, aucun style tiers : la CSP n'autorise que ce
   fichier et fonts.css (style-src 'self').

   Sommaire
     1. Jetons
     2. Base
     3. Enveloppe et grille
     4. En-tête (ordinateur, collant, sous 981 px)
     5. Pied de page
     6. Blocs de contenu
     7. Page Coordonnées
     8. Utilitaires
     9. Mobile, mouvement réduit, impression
   ========================================================================== */

/* ==========================================================================
   1. Jetons
   ========================================================================== */

:root {
    /* Le site s'affiche sur fond clair et le déclare : sans cette ligne,
       Chrome sur Android peut recalculer les couleurs quand l'assombrissement
       automatique des pages est coché (mesuré sur le site Raon). */
    color-scheme: only light;

    /* Couleurs relevées : accent Divi #283851 (et_divi.accent_color), texte
       et liens #000000, fond des pages simples et des sections de texte
       #f4f4f4 (rapport_base.md § 1 et § 3). */
    --navy: #283851;
    --ink: #000000;
    --white: #ffffff;
    --grey-bg: #f4f4f4;
    /* Barre de contact de l'en-tête d'ordinateur (decisions.md § 2.4). */
    --head-deep: #1d2939;
    /* Barre mobile et liens du tiroir : défauts de WP Mobile Menu
       (rgb(17, 17, 17) relevé à 390 px). */
    --mobile-bar: #111111;
    --mobile-link: #666666;
    --drawer-bg: #f7f7f7;

    /* Fonds translucides : bouton du diaporama rgba(40,56,81,.5)
       (button_bg_color), panneau du bandeau d'appel rgba(40,56,81,.7)
       (db/plans/2.txt), tiroir mobile ouvert. La photo du diaporama, elle,
       n'a AUCUN voile (§ 6). */
    --veil-slide: rgba(40, 56, 81, 0.5);
    --veil-bandeau: rgba(40, 56, 81, 0.7);
    --veil-menu: rgba(0, 0, 0, 0.83);

    /* Ombre « preset3 » de Divi (box_shadow_style=preset3 de l'accordéon,
       db/plans/2.txt s6) : relevée « rgba(0,0,0,.3) 0 12px 18px -6px »
       (accordéon de l'original à 390 px, 21 septembre 2026). ABANDONNÉ le
       même jour : « 0 2px 18px 0 rgba(0, 0, 0, 0.3) », provisoire. */
    --box-shadow: 0 12px 18px -6px rgba(0, 0, 0, 0.3);
    /* Filet des éléments d'accordéon (1 px #d9d9d9, relevé). */
    --toggle-border: #d9d9d9;
    --text-shadow: 0 0 0.3em #000;

    /* Open Sans, puis Arial ; Dosis pour le tiroir mobile seulement. */
    --sans: "Open Sans", Arial, Helvetica, sans-serif;
    --dosis: "Dosis", "Trebuchet MS", Arial, sans-serif;

    /* Défaut de Divi, que l'original ne redéfinit pas : rangée à 80 % de la
       page, au plus 1080 px ; gouttière « 3 » de 5,5 %. */
    --row: 1080px;
    --gutter: 5.5%;

    --transition: 0.3s ease;
    --btn-transition: 0.2s;
}

/* ==========================================================================
   2. Base
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    margin: 0;
    background: var(--white);
    color: var(--ink);
    font-family: var(--sans);
    font-size: 14px;
    line-height: 1.7em;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    /* body{overflow-x:hidden} : règle du CSS personnalisé de l'original
       (dph_posts 2750). */
    overflow-x: hidden;
}

/* Titres : graisse 600 et #283851 dans les modules de l'original
   (rapport_base.md § 3, « Divi »). Interligne égal à la taille, 10 px de
   retombée : la règle de Divi (h1 à h6 : line-height 1em, padding-bottom
   10px), relevée sur l'accueil de l'original le 21 septembre 2026 — h1
   32/32 px, h2 26/26, h3 16/16, h4 18/18 (live/pages/accueil_1440.json,
   headings) — et celle du site Spin’Info. ABANDONNÉ le même jour :
   « line-height: 1.2em », provisoire des fondations (6,4 px de trop par
   ligne de h1). */
h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 0;
    padding-bottom: 10px;
    color: var(--navy);
    font-family: var(--sans);
    font-weight: 600;
    line-height: 1em;
    text-wrap: pretty;
}

h1 {
    font-size: 32px;
}

h2 {
    font-size: 26px;
}

h3 {
    font-size: 22px;
}

h4 {
    font-size: 18px;
}

p {
    margin: 0;
    padding-bottom: 1em;
}

p:last-child {
    padding-bottom: 0;
}

a {
    color: var(--ink);
    text-decoration: none;
    transition: color var(--transition), opacity var(--transition);
}

a:hover {
    color: var(--navy);
}

img {
    max-width: 100%;
    height: auto;
    border: 0;
    vertical-align: middle;
}

picture {
    display: contents;
}

ul,
ol {
    margin: 0 0 1em;
    padding-left: 1em;
}

strong,
b {
    font-weight: 700;
}

button {
    font: inherit;
    color: inherit;
    padding: 0;
}

/* Contour de focus double, lisible sur fond clair comme sur fond sombre. */
:focus-visible {
    outline: 2px solid var(--white);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px var(--navy);
    border-radius: 1px;
}

.section :focus-visible,
.prose :focus-visible,
.sitemap :focus-visible,
.legal :focus-visible,
.gallery :focus-visible,
.mobile-panel :focus-visible,
.masthead__mobile :focus-visible {
    outline-color: var(--navy);
    box-shadow: 0 0 0 4px var(--white);
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    padding: 12px 20px;
    background: var(--white);
    color: var(--navy);
    font-weight: 700;
}

.skip-link:focus {
    left: 0;
    z-index: 10001;
}

[hidden] {
    display: none !important;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ==========================================================================
   3. Enveloppe et grille
   ========================================================================== */

/* Rythme vertical de Divi : sections à 4 % de respiration haute et basse,
   rangées à 2 %, fixées à 54 et 27 px au-delà de 1350 px ; sous 981 px,
   50 et 30 px (§ 9). */
.section {
    position: relative;
    padding: 4% 0;
    background: var(--white);
}

.section > .row {
    padding: 2% 0;
}

@media (min-width: 1350px) {
    .section {
        padding: 54px 0;
    }

    .section > .row {
        padding: 27px 0;
    }
}

.section--gris {
    background: var(--grey-bg);
}

.row {
    width: 80%;
    max-width: var(--row);
    margin: 0 auto;
    position: relative;
}

/* Rangée « pleine largeur » de Divi : 80 %, sans plafond. */
.row--wide {
    max-width: none;
}

.cols {
    display: flex;
    flex-wrap: wrap;
}

.cols > * {
    margin-right: var(--gutter);
}

.cols > *:last-child {
    margin-right: 0;
}

.cols--2 > * {
    width: 47.25%;
}

.cols--3 > * {
    width: 29.6667%;
}

/* Photo posée en fond d'une section : une balise <img> et non un fond CSS
   (style en ligne interdit par la CSP). */
.bg-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}

@media (max-width: 980px) {
    .section {
        padding: 50px 0;
    }

    .section > .row {
        padding: 30px 0;
    }

    .cols > *,
    .cols--2 > *,
    .cols--3 > * {
        width: 100%;
        margin-right: 0;
        margin-bottom: 30px;
    }

    .cols > *:last-child {
        margin-bottom: 0;
    }
}

/* ==========================================================================
   4. En-tête
   ========================================================================== */

/* Deux régimes, une seule bascule à 981 px (§ 9) :

   AU-DESSUS DE 980 px — l'en-tête « A » de Spin’Info, adapté à DPH Net
   (decisions.md § 2.4 et § 2.8 ; templates/partials/masthead.php et
   topbar.php) :
     .masthead__top    barre de contact #1d2939, 40 px ;
     .masthead__main   barre principale #283851, 88 px ;
                       = 128 px, premier contenu à 128 px à toutes les
                       largeurs d'ordinateur (127 px dans l'original) ;
     .sticky-header    après 250 px de défilement : la barre principale
                       seule, en 64 px (118 px dans l'original).
   Règles, couleurs et paliers sont ceux de la feuille de Spin’Info, moins
   ce qui tient à sa boutique sœur (carte « Aussi à », horaires, lien
   DPH Net). À montrer au client sur captures avant de le tenir pour
   définitif.

   SOUS 981 px — l'original, mesuré : la rangée bleue (.topbar), puis le
   logo et trois lignes à icône (.masthead__mobile). La barre noire du menu
   mobile est au § 9.

   COULEURS — contrastes calculés selon la formule WCAG 2 (luminance
   relative) :
     texte du menu            #dfe5ee sur #283851   9,34:1
     texte de la barre haute  #c7d0dc sur #1d2939   9,44:1
     blanc                    sur #283851 11,83:1 ; sur #1d2939 14,70:1
     bouton Nous contacter    #283851 sur blanc 11,83:1 ; sur #e6edf5 10,03:1
     trait de page courante   #6fb3dc sur #283851 5,16:1 (seuil 3:1)
     contour des pastilles    #8795ab sur #1d2939 4,84:1 (seuil 3:1)
     icônes de la barre haute #8fbbd9 sur #1d2939 7,19:1
     survols                  pastille : blanc sur #2f3a49 11,52:1 ; trait
                              blanc à 45 % (#89929f) sur #283851 3,76:1
     focus                    contour blanc, anneau #1d2939               */

/* --- Rangée bleue de contact (.topbar), SOUS 981 px ---------------------
   Module global 2284, rangée #secondary_line : fond #283851, 100 % de la
   page avec 50 px de côtés (custom_padding 8px|50px|4px|50px, aucune
   variante responsive), texte blanc de 14 px sur 23,8 px.
   Relevé à 390 px (live/pages/accueil_390.json, capture
   accueil_390_bandeau.png) : 65,8 px de haut =
       8      respiration haute
     + 23,8   la ligne : icône, numéro, icône, adresse e-mail
     + 30     marge basse de la colonne : Divi empile les colonnes sous
              981 px avec 30 px de marge, sauf la dernière — ici la colonne
              du menu secondaire, masquée (disabled_on="on|on|off") mais
              toujours dernière du document
     + 4      respiration basse.
   Même hauteur relevée sur l'original en ligne à 600 px.
   Encre relevée à 390 px : combiné 14 × 14 px à x 50, texte à 2 px ;
   enveloppe 15 × 12 px, texte à 4 px ; 17 px entre la fin du numéro et
   l'enveloppe (#et-info-phone { margin-right: 13px } et une espace). Les
   boîtes des SVG sont calculées pour ces encres : le combiné remplit
   19,6 / 24 de la sienne (16 px → 13,1 plus l'anticrénelage), l'enveloppe
   20 / 24 en largeur (17 px → 14,2). */

.topbar {
    background: var(--navy);
    color: var(--white);
}

.topbar__inner {
    padding: 8px 50px 4px;
}

.topbar__info {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 14px;
    margin: 0 0 30px;
    padding: 0;
    color: var(--white);
    line-height: 23.8px;
}

/* Les libellés d'avant le clic sont plus longs que les valeurs de l'original
   (Open Sans 14 px mesurée dans Chrome : « Voir le numéro » 96,8 px contre
   94,6 pour le numéro, « Voir l’adresse e-mail » 130,5 contre 122 pour
   l'adresse) : la ligne fait 277,3 px, et l'original, 268,6. À 375 px de
   large, 275 px de contenu : l'écart passe de 14 à 10 px, et la rangée garde
   une seule ligne comme l'original (273,3 px). Sous 369 px, l'original
   lui-même passait sur deux lignes. */
@media (max-width: 389px) {
    .topbar__info {
        column-gap: 10px;
    }
}

.topbar__item {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}

.topbar__icon {
    flex: 0 0 auto;
    fill: currentColor;
    color: var(--white);
}

/* Boîtes et marges ajustées sur le rendu à 390 px, pour retrouver les encres
   de l'original : combiné x 50..63 et texte à x 66, comme l'original (le
   combiné laisse 1,7 px de boîte vide à gauche de son encre, d'où la marge
   négative) ; enveloppe de 15 px de large à x 178..192, texte à 5 px — elle
   suit « Voir le numéro », plus long que le numéro de l'original (x 177). */
.topbar__item--tel .topbar__icon {
    width: 16px;
    height: 16px;
    margin: 0 1px 0 -1px;
}

.topbar__item--email .topbar__icon {
    width: 17px;
    height: 17px;
    margin-right: 3px;
}

.topbar .reveal,
.topbar a {
    color: var(--white);
}

.topbar a:hover,
.topbar .reveal:hover {
    color: rgba(255, 255, 255, 0.7);
}

/* --- Jetons de l'en-tête d'ordinateur ----------------------------------- */

.masthead,
.sticky-header {
    --head-text: #dfe5ee;
    --head-muted: #c7d0dc;
    --head-icon: #8fbbd9;
    --head-accent: #6fb3dc;
    --head-line: #8795ab;
    --head-cta-hover: #e6edf5;
    /* Largeur utile : 1 680 px au plus, marges de 40 px (Spin’Info). */
    --head-max: 1680px;
    --head-pad: 40px;
}

.masthead {
    position: relative;
    z-index: 50;
    background: var(--white);
}

.masthead__wrap {
    width: 100%;
    max-width: var(--head-max);
    margin: 0 auto;
    padding: 0 var(--head-pad);
}

/* --- Barre de contact (.masthead__top) ---------------------------------
   40 px, texte de 13 px sur 20 px, une seule ligne à toutes les largeurs
   d'ordinateur avec les réglages de police par défaut du navigateur. À
   gauche, la liste des coordonnées (secteur, pastilles du numéro et de
   l'e-mail) ; à droite, depuis le 23 septembre 2026, le lien « Support à
   Distance » (decisions.md § 2.13 ; partials/masthead.php), au bord droit
   de la largeur utile, à l'aplomb du bouton « Nous contacter », poussé là
   par sa marge gauche automatique, à 24 px au moins de la liste (l'écart
   de la barre de Spin’Info).
   PASSAGE À LA LIGNE : quand la liste et le lien ne tiennent pas côte à
   côte, le lien passe sous la liste, toujours à droite, et la barre
   grandit — 7 px au-dessus, entre les deux lignes et au-dessous : 40 px
   pour une ligne, 73 pour deux. Cela n'arrive qu'avec une taille de police
   MINIMALE imposée par le visiteur (Chrome, « Taille de police
   minimale ») : mesuré le 23 septembre 2026 au maximum du réglage, 24 px,
   où la liste mesure 812 px et le lien 263,6 : deux lignes jusqu'à
   1 139 px de fenêtre, une au-delà (la révélation raccourcit la liste de
   18 px : de 1 122 à 1 139 px, elle ramène la barre à une ligne). Sans ce
   passage, la liste, qui peut rétrécir, glissait SOUS le lien, qui ne
   rétrécit pas : jusqu'à 134,6 px de la pastille de l'e-mail recouverts,
   de 981 à 1 100 px. Avec les réglages par défaut, rien ne change : une
   ligne de 40 px, la liste et le lien au pixel près où ils étaient
   (mesuré avant et après, 981 à 1 920 px).
   ABANDONNÉ le 23 septembre 2026 : « une seule ligne à toutes les largeurs
   d'ordinateur. », sans réserve ; et « `space-between` et l'écart minimal de
   24 px (celui de la barre de Spin’Info) n'ont aucun effet sur la liste
   seule : elle reste où elle était, au pixel près (mesuré avant et après,
   981 à 1 920 px). », avec « justify-content: space-between; gap: 24px;
   height: 40px; » : une seule ligne de 40 px imposée, dont la liste
   débordait sous le lien avec la police minimale de 24 px. */

.masthead__top {
    background: var(--head-deep);
    color: var(--head-muted);
    font-size: 13px;
    line-height: 20px;
}

.masthead__top-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 7px 24px;
    min-height: 40px;
    padding-top: 7px;
    padding-bottom: 7px;
}

.masthead__address {
    display: flex;
    align-items: center;
    min-width: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    line-height: 20px;
    white-space: nowrap;
}

.masthead__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 7px;
}

/* Séparateur : filet de 16 px au milieu des 37 px qui séparent deux
   éléments, en position absolue pour ne pas compter dans l'écart de 7 px
   entre l'icône et son texte. */
.masthead__item + .masthead__item {
    margin-left: 37px;
}

.masthead__item + .masthead__item::before {
    content: "";
    position: absolute;
    left: -19px;
    top: 50%;
    width: 1px;
    height: 16px;
    margin-top: -8px;
    background: rgba(255, 255, 255, 0.18);
}

.masthead__icon {
    width: 14px;
    height: 14px;
    flex: 0 0 14px;
    fill: var(--head-icon);
}

/* Boutons de révélation de la barre : pastilles à contour de 26 px de haut
   (cible au-dessus des 24 × 24 px requis), blanches sur le bleu profond.
   Les deux états ont la même boîte : le script remplace le <button> par un
   <a class="reveal" data-state="done">, que ces règles visent aussi. Largeur
   minimale = le plus long des deux textes, mesuré en Open Sans 13 px dans
   Chrome, plus 22 px de remplissage et de contour :
     tel    « Voir le numéro » 89,9 px / « 03 29 52 89 93 » 87,8 px → 114
     email  « Voir l’adresse e-mail » 121,2 / « contact@dphnet.fr » 113,3 → 146
   Rien ne bouge autour au clic. */
.masthead__slot .reveal {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 26px;
    padding: 0 10px;
    border: 1px solid var(--head-line);
    border-radius: 13px;
    background: transparent;
    color: var(--white);
    font-size: 13px;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.masthead__slot .reveal:hover {
    color: var(--white);
    opacity: 1;
    text-decoration: none;
    border-color: var(--white);
    background: rgba(255, 255, 255, 0.08);
}

/* Une fois révélé, c'est un lien tel: ou mailto: : il reste une action. */
.masthead__slot .reveal[data-state="done"] {
    cursor: pointer;
}

.masthead__slot--tel .reveal {
    min-width: 114px;
}

.masthead__slot--email .reveal {
    min-width: 146px;
}

/* Lien « Support à Distance » : même pastille que les boutons de
   révélation — 26 px de haut, contour #8795ab, coins ronds, blanc sur le
   bleu profond, même survol —, l'icône d'écran DANS la pastille, à 7 px du
   texte comme dans la liste. Graisse 600 : la seule action de la barre qui
   mène ailleurs, comme la pastille « Aussi à » de l'en-tête « A » de
   Spin’Info, que ces cotes reprennent (remplissage 10 px à gauche, 11 à
   droite). Il ne rétrécit jamais (flex: none) ; sa marge gauche
   automatique le tient au bord droit, sur la ligne de la liste ou, s'il
   passe à la ligne (police minimale, voir la barre ci-dessus), sous
   elle. Le `color` du survol
   remplace le `a:hover` du § 2, qui le passerait en bleu nuit sur le bleu
   profond. Focus clavier : la règle « .masthead :focus-visible » plus bas.
   Masqué sous 981 px et à l'impression avec toute la barre (§ 9).
   Mesuré dans Chrome le 23 septembre 2026 : 162,9 px de large en 13 px
   (texte 118,95 px), 153,8 px en 12 px de 981 à 1 199 px (texte
   109,8 px), bord droit à l'aplomb de celui du bouton « Nous contacter » ;
   à 981 px, 287,6 px le séparent encore de la pastille de l'e-mail révélé.
   Sur 198 rendus (9 pages, 11 largeurs de 981 à 1 920 px, avant et après
   révélation) : une ligne, 26 px de haut, centré dans la barre de 40 px,
   rien au-delà de la largeur utile ; tous les autres rectangles de
   l'en-tête inchangés. */
.masthead__support {
    display: inline-flex;
    flex: none;
    align-items: center;
    margin-left: auto;
    gap: 7px;
    height: 26px;
    padding: 0 11px 0 10px;
    border: 1px solid var(--head-line);
    border-radius: 13px;
    background: transparent;
    color: var(--white);
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.masthead__support:hover {
    color: var(--white);
    text-decoration: none;
    border-color: var(--white);
    background: rgba(255, 255, 255, 0.08);
}

/* --- Barre principale (.masthead__main) --------------------------------
   88 px : le logo à gauche, la navigation poussée à droite. */

.masthead__main {
    background: var(--navy);
}

.masthead__main-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
    height: 88px;
}

/* --logo-h : la hauteur du logo, seule cote que changent l'en-tête collant
   et les largeurs étroites ; les deux décalages en sont des proportions. */
.masthead__logo {
    --logo-h: 72px;
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    line-height: 0;
}

/* Le logo, 72 px de haut (178,1 px de large). Son rectangle ne se voit plus
   (mélange `lighten`, voir partials/masthead.php) : ce qui compte est son
   ENCRE, le texte « D.P.H.Net » et le trait dessous, relevée au pixel sur
   les colonnes 19 à 218 et les lignes 32 à 83 du fichier (240 × 97). D'où
   deux décalages proportionnels à la hauteur affichée :
     - vers le haut, (58 − 48,5) / 97 = 0,098 × hauteur (7,1 px à 72 px) :
       on centre l'encre, et non le rectangle invisible, dans la barre ;
     - vers la gauche, 19 / 97 = 0,196 × hauteur (14,1 px) : l'encre
       commence au bord de la largeur utile, à l'aplomb de l'icône de la
       barre de contact.
   `position: relative` ne crée pas de contexte d'empilement : le mélange
   voit toujours le bleu de la barre. `max-width: none` : sans lui, le
   `max-width: 100%` des images (§ 2) se calcule sur la largeur du lien,
   plus étroite que l'image de son décalage, et comprime le logo (piège
   relevé sur Spin’Info). Aucun ancêtre du logo ne doit créer de groupe
   isolé transparent (opacité < 1, transform, filter) : il n'y aurait plus
   de bleu à mélanger. */
.masthead__logo img {
    position: relative;
    top: calc(var(--logo-h) * -0.098);
    display: block;
    width: auto;
    max-width: none;
    height: var(--logo-h);
    margin-left: calc(var(--logo-h) * -0.196);
    mix-blend-mode: lighten;
}

/* Couleurs forcées (thèmes de contraste de Windows) : le fond des barres
   devient la couleur système, le mélange n'a plus de bleu à garder et, sur
   un thème clair, le logo disparaîtrait (relevé sur Spin’Info). Le JPEG
   s'affiche alors tel quel, rectangle noir compris. */
@media (forced-colors: active) {
    .masthead__logo img {
        mix-blend-mode: normal;
    }
}

/* --- Navigation ---------------------------------------------------------
   Une ligne poussée à droite : cinq entrées en capitales (Open Sans 13 px,
   graisse 600, interlettrage 0,06 em), puis le bouton d'appel. Page
   courante : texte blanc et trait de 2 px #6fb3dc sous le mot. Survol :
   texte blanc et trait blanc à 45 %. Chaque lien fait 40 px de haut
   (12 + 16 + 12). */

.nav {
    flex: 1 1 auto;
    min-width: 0;
}

.nav__list {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin: 0;
    padding: 0;
    list-style: none;
    line-height: normal;
}

.nav__item {
    position: relative;
    margin: 0;
}

.nav__link {
    position: relative;
    display: inline-flex;
    align-items: center;
    padding: 12px 13px;
    color: var(--head-text);
    font-size: 13px;
    font-weight: 600;
    line-height: 16px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
    transition: color 0.2s ease;
}

.nav__link::after {
    content: "";
    position: absolute;
    left: 13px;
    right: 13px;
    bottom: 5px;
    height: 2px;
    background: transparent;
    transition: background-color 0.2s ease;
}

.nav__link:hover {
    color: var(--white);
}

.nav__link:hover::after {
    background: rgba(255, 255, 255, 0.45);
}

.nav__link[aria-current="page"] {
    color: var(--white);
}

.nav__link[aria-current="page"]::after {
    background: var(--head-accent);
}

/* Bouton d'appel : l'entrée Coordonnées, en blanc plein — le seul aplat
   clair de l'en-tête. Deux lignes : « NOUS CONTACTER », puis « Devis
   gratuit » (decisions.md § 2.8). Sur la page Coordonnées, il porte
   aria-current et passe en contour blanc. */
.nav__item--cta {
    margin-left: 12px;
}

.nav__cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 46px;
    padding: 5px 18px;
    border-radius: 3px;
    background: var(--white);
    color: var(--navy);
    text-align: center;
    white-space: nowrap;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.nav__cta:hover {
    color: var(--navy);
    background: var(--head-cta-hover);
}

.nav__cta-main {
    font-size: 13px;
    font-weight: 700;
    line-height: 17px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.nav__cta-detail {
    font-size: 11.5px;
    font-weight: 400;
    line-height: 16px;
}

.nav__cta[aria-current="page"],
.nav__cta[aria-current="page"]:hover {
    color: var(--white);
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--white);
}

/* --- En-tête collant (.sticky-header) -----------------------------------
   Sous 981 px, il reste dans le flux, réduit à la rangée bleue ; au-dessus,
   il quitte le flux, se fixe en haut et attend le défilement. */

.sticky-header__main {
    display: none;
}

@media (min-width: 981px) {
    /* z-index 99999, celui que le thème enfant de l'original lui donnait. */
    .sticky-header {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 99999;
        background: var(--navy);
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
        /* Masqué en haut de page. visibility et non display : la transition
           reste possible, et un élément en visibility: hidden sort de la
           tabulation et de l'arbre d'accessibilité. 0,4 s : le fadeIn de
           jQuery qu'employait le thème enfant. pointer-events bascule tout
           de suite : pendant le fondu de sortie, le collant presque
           transparent recevait encore les clics (relevé sur Spin’Info). */
        opacity: 0;
        visibility: hidden;
        transition: opacity 0.4s ease, visibility 0.4s ease;
        pointer-events: none;
    }

    .sticky-header[data-shown="true"] {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
    }

    .sticky-header .topbar {
        display: none;
    }

    /* Filet clair de 1 px en bas, en ombre intérieure pour ne pas ajouter de
       hauteur : les sections bleu nuit de l'accueil et des pages de service
       se confondraient sinon avec la barre. */
    .sticky-header__main {
        display: block;
        box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.12);
    }

    /* 64 px au lieu de 88 : logo de 54 px, liens de 36 px. */
    .sticky-header__inner {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 32px;
        height: 64px;
    }

    .sticky-header .masthead__logo {
        --logo-h: 54px;
    }

    .sticky-header .nav__link {
        padding-top: 10px;
        padding-bottom: 10px;
    }

    .sticky-header .nav__link::after {
        bottom: 4px;
    }

    /* Le bouton garde ses deux lignes, « NOUS CONTACTER » et « Devis
       gratuit » (decisions.md § 2.8), resserrées : 42 px dans la barre de
       64. */
    .sticky-header .nav__cta {
        min-height: 42px;
        padding-top: 3px;
        padding-bottom: 3px;
    }

    .sticky-header .nav__cta-main {
        line-height: 16px;
    }

    .sticky-header .nav__cta-detail {
        line-height: 15px;
    }

    /* Focus clavier sur fond sombre : contour blanc, puis un anneau du bleu
       profond entre le contour et l'élément, qui sépare aussi le contour du
       bouton d'appel blanc. */
    .masthead :focus-visible,
    .sticky-header :focus-visible {
        outline: 2px solid var(--white);
        outline-offset: 2px;
        box-shadow: 0 0 0 4px var(--head-deep);
    }

    .masthead__mobile {
        display: none;
    }
}

/* --- De 981 à 1 279 px : on resserre -----------------------------------
   Rien ne se retire : les marges se resserrent — 28 px de côtés, 10 px
   autour des entrées du menu —, et le logo passe à 64 px. « Devis gratuit »
   reste sous « NOUS CONTACTER » à toutes les largeurs du grand en-tête :
   plus court que la première ligne, il n'élargit pas le bouton (Spin’Info
   retire sa seconde ligne, « Devis et diagnostic gratuits », plus large).
   Balayage de 981 à 1 440 px, pixel par pixel, le 21 septembre 2026 : aucun
   débordement, aucun lien replié, barres de 40 et 88 px partout ; plus petit
   écart entre l'encre du logo et le texte du premier lien, 58,5 px à 981 px
   (41,5 px avec une barre de défilement classique de 17 px). */

@media (min-width: 981px) and (max-width: 1279px) {
    .masthead,
    .sticky-header {
        --head-pad: 28px;
    }

    .masthead__main-inner,
    .sticky-header__inner {
        gap: 24px;
    }

    .masthead .masthead__logo {
        --logo-h: 64px;
    }

    .nav__link {
        padding-left: 10px;
        padding-right: 10px;
        letter-spacing: 0.04em;
    }

    .nav__link::after {
        left: 10px;
        right: 10px;
    }

    .nav__item--cta {
        margin-left: 10px;
    }
}

/* --- De 981 à 1 199 px : texte de 12 px --------------------------------
   Le menu et la barre de contact passent en 12 px ; les pastilles suivent,
   mesurées en 12 px dans Chrome plus 22 px : « Voir le numéro » 83,0 px et
   « 03 29 52 89 93 » 81,1 → 106 ; « Voir l’adresse e-mail » 111,9 px et
   « contact@dphnet.fr » 104,6 → 136. Le lien « Support à Distance » aussi
   (23 septembre 2026) : 153,8 px. */

@media (min-width: 981px) and (max-width: 1199px) {
    .masthead,
    .sticky-header {
        --head-pad: 20px;
    }

    .masthead__top,
    .masthead__address .reveal,
    .masthead__support {
        font-size: 12px;
    }

    .masthead__address .masthead__slot--tel .reveal {
        min-width: 106px;
    }

    .masthead__address .masthead__slot--email .reveal {
        min-width: 136px;
    }

    .masthead__main-inner,
    .sticky-header__inner {
        gap: 16px;
    }

    .masthead .masthead__logo {
        --logo-h: 56px;
    }

    .nav__link {
        padding-left: 8px;
        padding-right: 8px;
        font-size: 12px;
        letter-spacing: 0.03em;
    }

    .nav__link::after {
        left: 8px;
        right: 8px;
    }

    .nav__item--cta {
        margin-left: 8px;
    }

    .nav__cta {
        padding-left: 12px;
        padding-right: 12px;
    }

    .nav__cta-main {
        font-size: 12px;
        letter-spacing: 0.04em;
    }
}

/* --- Sous 981 px : le logo et les trois lignes à icône -----------------
   Section 2 du Theme Builder 2729 : respiration haute de 5 px, rangée de
   80 % sans remplissage, quatre colonnes 1/4 à hauteurs égales, contenu
   centré verticalement (classe ds-vertical-align du thème enfant). Divi
   les dispose ainsi sous 981 px (style-static.min.css) :
     480 à 980 px  deux par deux, 47,25 % de large, 5,5 % entre elles,
                   30 px sous la première ligne ;
     sous 480 px   une par ligne, 30 px entre elles.
   Relevés : 228,8 px à 390 px (5 + 37,8 + 3 × (30 + 32)) ; 99 px à 600 px
   sur l'original en ligne (5 + 32 + 30 + 32 ; colonnes de 226,8 px à x = 60
   et 313,2).
   Le logo : l'image à 30 % de sa colonne, centrée — 93,6 × 37,8 px à
   390 px —, le JPEG tel quel sur ce fond blanc, comme l'original.
   Les lignes (modules « blurb ») : disque #283851 de 32 px (icône de 16 px
   et 8 px de remplissage), texte noir de 16 px sur 23,8 px à 15 px du disque,
   calé en haut. Encres relevées à 390 px dans le disque de 32 px : combiné
   15 × 15, repère 12 × 16, écran 16 × 14, toutes centrées ; boîtes des SVG
   calculées pour elles. Mesuré sur le site neuf le 21 septembre 2026 :
   section de 228,8 px à 390 px et de 99 px à 600 px, colonnes aux mêmes
   positions ; encres du combiné (x 48..62, y 197..211) et de l'écran
   identiques à l'original, repère 11 × 17 px. */

.masthead__mobile {
    padding: 5px 0 0;
    background: var(--white);
}

.masthead__mobile-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 30px 5.5%;
    width: 80%;
    margin: 0 auto;
}

.masthead__mobile-col {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
}

.masthead__mobile-logo {
    display: block;
    width: 30%;
    margin: 0 auto;
    line-height: 0;
}

.masthead__mobile-logo img {
    display: block;
    width: 100%;
    height: auto;
}

.blurb {
    display: flex;
    align-items: flex-start;
    margin: 0;
    padding: 0;
    color: var(--ink);
    font-size: 16px;
    line-height: 23.8px;
}

.blurb__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--navy);
    color: var(--white);
}

.blurb__icon svg {
    width: 16px;
    height: 16px;
    fill: currentColor;
}

.blurb__icon--tel svg {
    width: 17px;
    height: 17px;
}

.blurb__icon--pin svg {
    width: 17px;
    height: 17px;
}

.blurb__text {
    min-width: 0;
    padding-left: 15px;
}

@media (max-width: 479px) {
    .masthead__mobile-row {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ==========================================================================
   5. Pied de page
   ========================================================================== */

/* Mise en page « et_footer_layout » 2744 (db/plans/2744.txt), relevée à
   1440 et 390 px (live/pages/accueil_1440.json et _390.json, sections
   kind=footer) et sur l'original en ligne à 600 px.

   BANDE 1 — section #283851, 10 px de respiration haute et basse (sans
   variante responsive). Rangée de 80 % sans plafond (max_width=100 %) :
   1 152 px à 1440 px ; remplissage de rangée par défaut de Divi, 27 px
   au-delà de 1 350 px, 2 % en dessous, 30 px sous 981 px. Quatre colonnes
   1/4 sans gouttière (gutter_width=1) à hauteurs égales (make_equal), leur
   contenu centré verticalement (ds-vertical-align) : c'est ce qui descend
   Téléphone et E-mail de 11,9 px à 1440 px, colonnes plus courtes d'une
   ligne. Hauteurs reconstituées au dixième :
       1440 px  10 + 27 + 122,4 + 27 + 10 = 196,4 (relevé 196,4)
                122,4 = 23,8 titre + 9 + 10 + 23 filet + 47,6 texte + 9
        600 px  10 + 30 + 171,2 + 123,6 + 30 + 10 = 374,8 (relevé 374,8)
        390 px  10 + 30 + 147,4 + 147,4 + 123,6 + 98,6 + 30 + 10 = 597
                (relevé 597)
   Le site neuf mesure les mêmes trois hauteurs (21 septembre 2026).
   Sous 981 px, les trois premières colonnes ont 25 px de remplissage bas
   (custom_padding_tablet, repris sur téléphone) ; Divi les dispose deux par
   deux de 480 à 980 px (50 % chacune, gouttière 1), une par ligne en
   dessous.

   Les marges de la colonne ne fusionnent pas (colonne en flex) : 9 px sous
   le titre + 10 px au-dessus du filet = 19 px ; le filet est un module
   « séparateur » de 23 px dont le trait de 4 px est en haut, sur 9 % de la
   colonne (25,9 px à 1440 px, 28,1 à 390). Ici le filet est un ::after du
   titre, et le compte est le même : 23,8 + 19 + 4 + 19 = 65,8 px du haut de
   la colonne au texte (relevé : 3 866,5 − 3 800,7 = 65,8).

   Interligne : 23,8 px partout (1,7 em calculé sur le corps de 14 px,
   hérité tel quel par le titre de 22 px et le texte de 18 px).

   DÉFAUTS CORRIGÉS (decisions.md § 4) :
     - la rangée de l'original commençait à x = 288 à 1440 px (x = 78 à
       390 px) : module_alignment=right sur une rangée de 80 %. Elle est
       centrée ici, à x = 144 (39 à 390 px) ;
     - la barre noire portait 30 px de marge basse (custom_margin
       ||30px, relevé margin 0 0 30px) : 30 px blancs sous le pied de
       toutes les pages. Aucune marge ici : la page se termine sur la
       barre noire. */

.footer__main {
    background: var(--navy);
    color: var(--white);
    padding: 10px 0;
}

.footer__main > .row {
    padding: 2% 0;
}

@media (min-width: 1350px) {
    .footer__main > .row {
        padding: 27px 0;
    }
}

.footer a,
.footer .reveal {
    color: var(--white);
}

.footer a:hover,
.footer .reveal:hover {
    color: rgba(255, 255, 255, 0.7);
}

/* Grille et non flex : les colonnes changent de nombre aux paliers de
   Divi. `gap: 0` : l'original n'a ni gouttière ni écart de ligne. */
.footer__cols {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0;
}

.footer__col {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
}

/* Titre : 22 px, graisse 600, italique, blanc (text_font |600|on) ; pas de
   capitales. */
.footer h2 {
    margin: 0 0 19px;
    padding-bottom: 0;
    color: var(--white);
    font-size: 22px;
    font-weight: 600;
    font-style: italic;
    line-height: 23.8px;
}

.footer h2::after {
    content: "";
    display: block;
    width: 9%;
    height: 4px;
    margin-top: 19px;
    background: var(--white);
}

/* Texte : 18 px, 600, italique, 9 px de marge basse (custom_margin ||9px). */
.footer__text {
    margin: 0 0 9px;
    padding: 0;
    font-size: 18px;
    font-weight: 600;
    font-style: italic;
    line-height: 23.8px;
}

.footer__noscript {
    padding: 0 0 9px;
    font-size: 14px;
    font-weight: 400;
    font-style: normal;
    line-height: 23.8px;
}

.footer__fallback {
    margin: 0 0 9px;
    padding: 0;
    list-style: none;
    font-size: 18px;
    font-weight: 600;
    font-style: italic;
}

/* BANDE 2 — barre noire (module global 2270) : rangée de contenu
   ordinaire (80 %, 1 080 px au plus : x = 180 à 1440 px), même remplissage
   de rangée que la bande 1 ; texte blanc de 14 px sur 23,8 px, liens en
   gras. Relevé : 101,6 px à 1440 px (27 + 2 lignes + 27), 107,6 à 600 px,
   155,2 à 390 px (30 + 4 lignes + 30).
   La ligne « Particuliers » (decisions.md § 2.2) se range à droite de la
   même rangée au-dessus de 980 px, sur la première ligne : la barre garde
   ses 101,6 px. En dessous, elle passe sous le crédit. Gris #bfbfbf sur noir
   (11,42:1), liens blancs de graisse normale, soulignés : discrète à côté
   des liens légaux en gras. */

.footer__bar {
    background: var(--ink);
    color: var(--white);
}

.footer__bar > .row {
    padding: 2% 0;
}

@media (min-width: 1350px) {
    .footer__bar > .row {
        padding: 27px 0;
    }
}

.footer__bar-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 30px;
    align-items: start;
}

.footer__legal {
    margin: 0;
    padding: 0;
    font-size: 14px;
    line-height: 23.8px;
}

.footer__legal a {
    font-weight: 700;
}

.footer__boutiques {
    margin: 0;
    padding: 0;
    color: #bfbfbf;
    font-size: 14px;
    line-height: 23.8px;
    text-align: right;
    white-space: nowrap;
}

.footer__boutiques a {
    font-weight: 400;
    text-decoration: underline;
    text-decoration-color: rgba(255, 255, 255, 0.5);
    text-underline-offset: 3px;
}

.footer__boutiques a:hover {
    text-decoration-color: currentColor;
}

@media (max-width: 980px) {
    .footer__main > .row,
    .footer__bar > .row {
        padding: 30px 0;
    }

    .footer__cols {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .footer__col:not(:last-child) {
        padding-bottom: 25px;
    }

    .footer__bar-inner {
        grid-template-columns: minmax(0, 1fr);
    }

    .footer__boutiques {
        margin-top: 10px;
        text-align: left;
        white-space: normal;
    }
}

@media (max-width: 479px) {
    .footer__cols {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ==========================================================================
   6. Blocs de contenu
   ========================================================================== */

/* --- Texte courant — 15 px sur 1,8 em dans les modules de texte de
   l'original (db/plans/2.txt). --------------------------------------------- */
.prose {
    color: var(--ink);
    font-size: 15px;
    line-height: 1.8em;
}

.prose a {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.prose ul {
    padding-left: 1.2em;
}

.block-image .row {
    padding-bottom: 27px;
}

.block-image img {
    display: block;
    width: 100%;
    height: auto;
}

/* --- Titre de page (blocks/page_title.php) — Galerie et Coordonnées -----
   Dans l'original, le module « titre » et le contenu vivent dans la même
   section (db/plans/2934.txt, 2869.txt). Relevé à 1440 px
   (live/pages/galerie_1440.json et coordonnees_1440.json, 21 septembre
   2026) : section à 127, h1 à 208 (= 127 + 54 de section + 27 de rangée),
   module titre de 42 px (32 d'interligne + 10 de retombée, § 2), module
   suivant à 279,7 : 29,7 px d'écart, les 2,75 % de marge basse d'un module
   dans une colonne pleine de Divi en gouttière 3 (2,75 % × 1080 = 29,7 ;
   gutters3.css de la sauvegarde). À 390 px : h1 à 424,6 (= 344,6 + 50 + 30),
   module suivant à 496,6, soit 30 px (.et_pb_column .et_pb_module
   {margin-bottom: 30px} de Divi sous 981 px).
   Ici titre et contenu sont deux sections : la respiration basse de la
   première et la respiration haute de la seconde sont retirées, et l'écart
   de module devient la marge basse du titre. En POURCENTAGE, pour qu'il
   suive la rangée entre 981 et 1349 px comme chez Divi : une marge se
   calcule sur la largeur du bloc conteneur, ici la rangée — une
   respiration de .row, elle, se calculerait sur la section.
   `display: flow-root` garde cette marge DANS la rangée : sans lui, elle
   traverserait la rangée et la section, toutes deux sans respiration basse,
   et laisserait paraître le fond de la page entre deux sections grises.
   ABANDONNÉ le 21 septembre 2026 : aucun écart entre le titre et le
   contenu (galerie collée au titre, 29,7 px de moins que l'original). */
.page-title {
    padding-bottom: 0;
}

.page-title > .row {
    display: flow-root;
    padding-bottom: 0;
}

.page-title__heading {
    margin-bottom: 2.75%;
}

.page-title + .section,
.page-title + .section > .row {
    padding-top: 0;
}

/* Coordonnées : le titre et son filet forment la PREMIÈRE rangée de
   l'original, qui garde sa respiration basse (rangée relevée de 181 à
   329,7 px, dont 27 de respiration sous le filet ; 30 à 390 px) ; les deux
   colonnes sont dans une seconde rangée (§ 7). */
.page-title--filet > .row {
    padding-bottom: 2%;
}

@media (min-width: 1350px) {
    .page-title--filet > .row {
        padding-bottom: 27px;
    }
}

/* Le filet : module séparateur de Divi (s1.r1.c1.m2 de db/plans/2869.txt :
   divider_weight=2px, width=6 %, marges et respirations à 0). Relevé : un
   module de 23 px de haut (.et_pb_space de Divi : height 23px), à 279,7 px
   à 1440 et 496,6 à 390, large de 64,8 px (6 % de 1080) et 18,7 px (6 % de
   312) ; sur la capture, un trait #283851 de 2 px, lignes 280 et 281
   (coordonnees_1440.png), 497 et 498 à 390 px, colonnes 180 à 244.
   ABANDONNÉ le 21 septembre 2026 : « height: 3px; margin-top: 10px;
   background » (provisoire, un trait de 3 px collé au titre). */
.page-title__rule {
    display: block;
    width: 6%;
    height: 23px;
    border-top: 2px solid var(--navy);
}

@media (max-width: 980px) {
    .page-title__heading {
        margin-bottom: 30px;
    }

    .page-title--filet > .row {
        padding-bottom: 30px;
    }
}

/* --- Diaporama figé (hero_slide) ----------------------------------------
   Décomposition des 577,5 px relevés à 1440 px (live/pages/accueil_1440.json :
   mainSections[0], sliders ; accueil_1440.textes.json) :

     202,75  remplissage haut de la description : 16 % de la largeur de son
             conteneur, 1 267,2 px (0,16 × 1 267,2 = 202,75 ; aucun
             remplissage latéral : slogan et bouton relevés au bord gauche
             de la description, x 754,9)
      92     le slogan, sur DEUX lignes de 46 px
      10     sa retombée (padding-bottom des titres Divi)
      20     l'écart avant le bouton
      50     le bouton (34 d'interligne + 2 × 6 + 2 × 2)
     202,75  remplissage bas
     ------
     577,5   pour 577,5 relevés (section de y 127 à 704,5).
   Mesuré sur le neuf le 21 septembre 2026 : 577,5 ; slogan 202,8 px sous
   le haut de la section, à x 754,9 ; badge 253,4 × 155,2 à x 86,4 ; bouton
   189 × 50.

   Largeurs : la diapositive a 6 % de remplissage de chaque côté (86,4 px
   relevés), d'où un conteneur de 88 % (1 267,2 px). Le badge y prend 20 %
   (custom_css_slide_image « width:20% » : 253,4 × 155 relevés, à x 86,4),
   collé à gauche et CENTRÉ en hauteur (milieu relevé 415,8, milieu de la
   section 415,75) ; la description 47,25 %, collée à droite (598,8 px,
   slogan relevé à x 754,9 et y 329,8).

   Photo : `cover` centrée (bgSize cover, bgPos 50% 50%), sans voile — voir
   templates/blocks/hero_slide.php. ABANDONNÉ le 21 septembre 2026 : la règle
   « .veil » (§ 3) et son élément, un voile rgba(40,56,81,.5) repris de
   Spin’Info, ainsi que « align-items: center ; gap: 5% ; width: 80% ;
   min-height: 560px » et un badge à 25 %, provisoires.

   Masqué sous 981 px, comme la section d'origine (disabled_on="on|on|off" :
   ni téléphone ni tablette ; relevé à 390 px : hauteur 0). */
.hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    /* Fond sous la photo (couleur de la diapositive, rgb(40,56,81) relevé) :
       la section n'est jamais blanche, même le temps du chargement. */
    background: var(--navy);
}

.hero__container {
    position: relative;
    z-index: 1;
    display: flex;
    width: 88%;
    margin: 0 auto;
}

.hero__media {
    flex: 0 0 20%;
    width: 20%;
    align-self: center;
}

.hero__media img {
    display: block;
    width: 100%;
    height: auto;
}

/* Sur un élément flexible, un pourcentage de remplissage se calcule sur la
   largeur du CONTENEUR (1 267,2 px) : 16 % = 202,75 px, la cote relevée. */
.hero__body {
    flex: 0 0 47.25%;
    width: 47.25%;
    margin-left: auto;
    padding: 16% 0;
}

/* Slogan : 46 px, graisse 600 (header_font |600|, face chargée), interligne
   46 px, blanc, ombre « preset3 » 0 0 .3em #000 (13,8 px relevés). C'était un
   h4 (défaut corrigé, decisions.md § 4) : sa retombée de 10 px est gardée. */
.hero__title {
    margin: 0;
    padding: 0 0 10px;
    color: var(--white);
    font-size: 46px;
    font-weight: 600;
    line-height: 46px;
    text-shadow: var(--text-shadow);
}

.hero__actions {
    margin-top: 20px;
}

.hero__actions .btn {
    vertical-align: top;
}

@media (max-width: 980px) {
    .hero {
        display: none;
    }
}

/* --- Image et texte (media_text) ----------------------------------------
   Rangée Divi en deux moitiés (s3.r1 de l'accueil ; s1 des trois pages de
   services) : colonnes de 47,25 % (510,3 px à 1440), écart 5,5 %, alignées
   EN HAUT — image et titre relevés tous deux à y 785,5. Colonne de droite,
   relevé à 1440 :
      74     titre h1, deux lignes de 32 + 10 de retombée
      29,7   écart entre modules : 5,82 % de la colonne (marge basse des
             modules d'une colonne 1/2, gouttière 3)
     162     texte, six lignes de 27 (15 px / 1,8 em)
      29,7
      45,4   bouton « Voir nos services » (18 px : 30,6 + 2 × 5,4 + 2 × 2)
     ------
     340,8   pour 340,8 relevés.
   Mesuré sur le neuf le 21 septembre 2026 : cette section 448,8 + celle
   des chiffres 247 = 695,8, pour les 695,8 de la section d'origine ; à
   390 : 801,9 + 595 = 1 396,9 pour 1 396,9.
   Image : 480 × 270 étirée à la colonne (force_fullwidth) : 510,3 × 287.
   Sous 981 px (relevé à 390) : colonnes empilées, 30 px entre modules et
   sous l'image ; titre 138 (quatre lignes), texte 243, bouton 45,4.
   ABANDONNÉ le 21 septembre 2026 : « align-items: center » et
   « .media-text__actions { padding-top: 20px } », provisoires. */
.media-text__cols {
    align-items: flex-start;
}

.media-text__media img {
    display: block;
    width: 100%;
    height: auto;
}

.media-text__heading {
    font-size: 32px;
}

/* Coupure des titres de ces blocs : celle de l'original, gloutonne. La
   règle de base (§ 2) équilibre les lignes (text-wrap: pretty) ; à 390 px,
   elle coupait le h1 en « Votre magasin / informatique / à Raon-l’Étape /
   et Épinal », là où l'original écrit « Votre magasin / informatique à /
   Raon-l’Étape et / Épinal » (live/pages/accueil_390.png), à hauteur égale
   mais avec d'autres lignes. */
.media-text__heading,
.services__title,
.service-item__title,
.colonnes .prose h2,
.colonnes .prose h3,
.colonnes .prose h4 {
    text-wrap: wrap;
}

/* Un pourcentage de marge se calcule sur la largeur du bloc parent : la
   colonne, 510,3 px, d'où 29,7 px. */
.media-text__body > * + * {
    margin-top: 5.82%;
}

.media-text__actions .btn {
    font-size: 18px;
    vertical-align: top;
}

/* Le bloc « chiffres » qui suit est la seconde rangée de la MÊME section
   d'origine : la section s'arrête sans respiration basse, la rangée garde
   la sienne (27 px à 1440, 30 à 390), et la section des chiffres reprend
   avec les 30 px de marge de sa rangée. ABANDONNÉ le 21 septembre 2026 :
   la respiration basse de la rangée, retirée elle aussi (27 px de moins
   que l'original). */
.media-text--suite {
    padding-bottom: 0;
}

@media (max-width: 980px) {
    .media-text__body > * + * {
        margin-top: 30px;
    }
}

/* --- Chiffres (s3.r2 de l'accueil) --------------------------------------
   Rangée de trois tiers (29,6667 %, écart 5,5 % : colonnes relevées à
   x 180, 559,8 et 939,6, larges de 320,4), 30 px sous la rangée précédente
   (custom_margin 30px), sans remplissage (custom_padding 0), colonnes de
   même hauteur (make_equal) : 163 px, la plus haute. Relevé à 1440 :
     compteur : 15 de colonne + 0 de module, nombre 72 (52 px sur 72
       d'interligne), 20 de marge, titre 26 (16 px + 10 de retombée),
       15 de module + 15 de colonne = 163 ; nombre à y 1198,3, titre à
       1290,3 ;
     blurbs : 15 + icône 60 + 30 + titre 26 + 15 = 146, étirés à 163 ;
       icône à y 1198,3, titre à 1288,3.
   Sous 981 px (relevé à 390) : empilés, 30 px entre eux, 163, 146 et 146 px.

   GRAISSE, vérifiée le 21 septembre 2026 à la demande du lot en-tête (« 600
   contre 400 apparent ») : l'original DÉCLARE 500 sur le nombre et les
   trois titres (live/pages/accueil_1440.json, styles : p, h3 et h4 à 500),
   mais ne chargeait aucune face 500 (fontsLoaded : Open Sans 300, 400, 600
   et 700) ; pour 500, le navigateur prend alors la face 400. Notre Open Sans
   est variable : écrire 500 épaissirait le trait, et 600 plus encore. On
   écrit la graisse RENDUE, 400 (même raisonnement que le corps de page,
   fonts.css). Preuve à l'encre, libellés du neuf comparés à la capture de
   l'original (live/pages/accueil_1440.png), écart moyen par pixel sur 255 :
   en 400, 0 pour « Certification Microsoft » (identique au pixel), 1,2 et
   1,4 pour les deux autres ; en 500, 16 à 27 et 17 à 19 % d'encre en trop ;
   en 600, 30 à 42 et 37 à 40 % d'encre en trop. Largeurs de texte égales
   au dixième de pixel en 400 (229,4 et 165,3 px des deux côtés).
   ABANDONNÉ le même jour : « font-weight: 600 » sur le nombre et les
   libellés.
   ABANDONNÉ aussi : « gap: 10px ; padding: 15px » sur chaque élément et
   « row-gap: 20px » sous 981 px, provisoires. */
.chiffres {
    padding-top: 30px;
}

.chiffres > .row {
    padding: 0;
}

.chiffres__list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    column-gap: var(--gutter);
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: center;
}

.chiffres__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 15px;
}

/* 15 px de colonne, puis le remplissage du compteur (custom_padding
   0|15px|15px|15px). */
.chiffres__item--nombre {
    padding: 15px 30px 30px;
}

.chiffres__nombre {
    display: block;
    margin-bottom: 20px;
    color: var(--navy);
    font-size: 52px;
    font-weight: 400;
    line-height: 72px;
}

/* color : la caisse à outils ('toolbox', src/icons.php) est tracée au
   trait, en currentColor ; l'écran est plein, en fill. 30 px sous l'icône
   (marge basse de l'image d'un blurb). */
.chiffres__icone {
    flex: none;
    width: 60px;
    height: 60px;
    margin-bottom: 30px;
    fill: var(--navy);
    color: var(--navy);
}

.chiffres__label {
    display: block;
    padding-bottom: 10px;
    color: var(--ink);
    font-size: 16px;
    font-weight: 400;
    line-height: 16px;
}

@media (max-width: 980px) {
    .chiffres__list {
        grid-template-columns: 1fr;
        row-gap: 30px;
    }
}

/* --- Bandeau d'appel sur photo ------------------------------------------
   Module et_pb_cta : panneau rgba(40,56,81,.7), coins de 25 px, remplissage
   40 px 60 px (40 px sous 981 px), texte 18 px sur 23,8 px d'interligne
   (celui du corps, que le module ne redéfinit pas), 20 px sous le texte,
   bouton de 50 px (db/plans/2.txt s4 ; relevé à 390 px le 21 septembre
   2026). Relevé à 1440 : 54 + 27 + (40 + 23,8 + 20 + 50 + 40) + 27 + 54
   = 335,8 pour 335,8 ; à 390 : 50 + 30 + (40 + 95,2 + 20 + 50 + 40) + 30
   + 50 = 405,2 pour 405,2 (texte sur quatre lignes). Neuf, mesuré le
   21 septembre 2026 : 335,8 et 405,2. ABANDONNÉ le
   21 septembre 2026 : « padding: 40px » à toutes les largeurs et
   « line-height: 1.5em », provisoires. */
.bandeau {
    isolation: isolate;
    overflow: hidden;
    background: var(--navy);
}

.bandeau > .row {
    z-index: 1;
}

.bandeau__panel {
    padding: 40px 60px;
    border-radius: 25px;
    background: var(--veil-bandeau);
    color: var(--white);
    text-align: center;
}

.bandeau__text {
    font-size: 18px;
    line-height: 23.8px;
}

.bandeau__actions {
    padding-top: 20px;
}

.bandeau__actions .btn {
    vertical-align: top;
}

/* Parallaxe des quatre bandeaux — accueil et trois pages de services —,
   FIGÉE (templates/blocks/bandeau.php). Relevé et calculs faits d'abord sur
   l'accueil. Dans
   l'original, la photo était un fond `fixed` : cadrée `cover` sur la
   FENÊTRE (1440 × 900 → 1 600 × 900, calée en haut : bgPos « 50% 0% »
   relevé) et immobile pendant que la section défilait devant elle. La
   section laissait donc voir la bande de photo qui se trouvait derrière elle
   à l'écran. On fige cette bande au milieu de la course, quand le milieu de
   la section passe au milieu de l'écran — le choix du site Raon
   Informatique pour sa propre parallaxe : la photo reçoit la taille de la
   fenêtre (100 % × 100vh, `cover`, calée en haut) et son haut est placé une
   demi-fenêtre au-dessus du milieu de la section. À 1440 × 900 : section de
   335,8 px, photo de 1 600 × 900 débordant de 80 px de chaque côté, haut à
   −282,1 px ; la section montre les lignes 282,1 à 617,9 de la photo
   affichée, soit 338,5 à 741,5 du fichier de 1 080 px. Un simple `cover` sur
   la section aurait montré la photo à 75 % au lieu de 83,3 %, sur une bande
   que l'original ne montre à aucun moment de la course.
   Pages de services (même parallaxe dans l'original, même règle ici) : les
   photos en 3:2 (DSC1468 et D810631, 960 × 640) sont affichées à 1 440 × 960
   (× 1,5), celle en 4:3 (Fontainebleau, 720 × 540) à 1 440 × 1 080 (× 2) ;
   la section montre les lignes 282,1 à 617,9 de la photo affichée, soit
   188 à 412 du fichier en 3:2 et 141 à 309 du 4:3. Vérifié le 21 septembre
   2026 en cherchant, ligne à ligne, la bande de photo qui ressemble le plus
   à la capture du neuf : lignes 282 à 283 trouvées sur les trois pages.
   La même recherche sur la capture de l'ORIGINAL (live/pages/*_1440.png)
   trouve le même agrandissement (× 1,5 et × 2 : `cover` sur la fenêtre,
   calé en haut, confirmé) mais les lignes 574 à 576 : la capture a été prise
   page en haut, quand le bandeau, à y 576, entrait par le bas de l'écran.
   C'est un autre instant de la même course ; l'écart pixel du bandeau à
   1440 contre cette capture (39 à 44 sur 255) ne mesure donc que ce choix
   d'instant. */
@media (min-width: 981px) {
    .bandeau--parallaxe .bandeau__photo {
        top: calc(50% - 50vh);
        bottom: auto;
        height: 100vh;
        object-position: 50% 0;
    }
}

/* Sous 981 px, Divi rend le fond défilant (background-attachment « scroll »
   relevé à 390 px) : `cover` sur la section, calé en haut. */
@media (max-width: 980px) {
    .bandeau__panel {
        padding: 40px;
    }

    .bandeau--parallaxe .bandeau__photo {
        object-position: 50% 0;
    }
}

/* --- Nos services (global 2899) -----------------------------------------
   Relevé à 1440 : section de 446,2 px = 24 (custom_padding) + rangée du
   titre 77,8 (27 + 23,8 + 27) + rangée des cartes 290,4 (27 + 261,4 + 2,
   custom_padding ||2px) + 54.
   Titre : 26 px, graisse 600, #283851, centré, sur 23,8 px d'interligne
   (celui du corps : c'était un module de texte, pas un titre), sans retombée.
   Cartes : rangée à 80 % sans plafond (max_width 100% : 1 152 px à x 144),
   cinq colonnes de 15,6 % (179,7 px) à 5,5 % d'écart (63,4 px : colonnes
   relevées à x 144, 387,1, 630,1, 873,2 et 1 116,3), de même hauteur
   (make_equal) ; 261,4 = image 119,8 + 30 + titre 64 (trois lignes de
   18 px + 10) + texte 47,6 (deux lignes de 23,8).
   Image : 300 × 200 réduite à la colonne, coins de 10 px (border_radii_image),
   30 px dessous. Titre : 18 px, #283851, centré, interligne 18 px, 10 px de
   retombée. Texte : 14 px sur 23,8, noir, ALIGNÉ À GAUCHE (relevé : x égal
   au bord de la colonne). Graisse 400 pour les deux : l'original déclarait
   500 sans charger la face (voir « Chiffres »).
   Survol : la colonne grossit de 10 % (transform_scale__hover 110%), en
   0,3 s (transition de Divi) ; ici aussi au focus clavier.
   Sous 981 px (relevé à 390) : 24 + 83,8 (30 + 23,8 + 30) + rangée de
   1 579 (30 + cinq cartes de 281,8, la quatrième 299,8, 30 px entre elles,
   + 2) + 50 = 1 736,8 ; images à leur taille, 300 × 200, centrées.
   Neuf, mesuré le 21 septembre 2026 : 446,2 et 1 736,8 ; images, titres et
   textes aux positions relevées, au dixième de pixel près (décalés du 1 px
   de l'en-tête à 1440).
   ABANDONNÉ le 21 septembre 2026 : grille de cinq colonnes égales à 3 %
   d'écart, titre 18 px en graisse 600 avec 18 px de marge haute, texte
   15 px centré, soulignement du titre au survol — provisoires. */
.services {
    padding-top: 24px;
}

.services__title {
    padding: 0;
    font-size: 26px;
    line-height: 23.8px;
    text-align: center;
}

.section > .services__cards {
    padding-bottom: 2px;
}

.services__list {
    display: flex;
    margin: 0;
    padding: 0;
    list-style: none;
}

.services__cell {
    display: flex;
    flex: 0 0 15.6%;
    width: 15.6%;
    margin-right: var(--gutter);
    transition: transform var(--transition);
}

.services__cell:last-child {
    margin-right: 0;
}

@media (hover: hover) {
    .services__cell:hover {
        transform: scale(1.1);
    }
}

.services__cell:has(.service-item:focus-visible) {
    transform: scale(1.1);
}

/* Au focus clavier, la carte grandit de 10 % (5 % de sa hauteur au-dessus
   et au-dessous), mais le navigateur la fait défiler en vue d'après sa
   taille normale : il faut lui réserver cette marge, sans quoi son bord et
   son anneau de focus passaient sous l'en-tête collant (981 px et plus),
   sous la barre noire (sous 981 px) ou sous « Nous appeler » (sous
   768 px) — 13 à 15 px, mesurés (relecture de fidélité du 22 septembre
   2026). 24 px couvrent une carte jusqu'à 480 px de haut ; aucun effet sur
   la mise en page. ABANDONNÉ le 22 septembre 2026 : aucune marge de
   défilement sur .service-item. */
.service-item {
    display: flex;
    flex-direction: column;
    width: 100%;
    color: var(--ink);
    scroll-margin-block: 24px;
}

.service-item:hover {
    color: var(--ink);
}

.service-item__media {
    display: block;
    margin-bottom: 30px;
    line-height: 0;
    text-align: center;
}

/* Proportion 3:2 imposée : les photos des cartes sont des 3:2, mais une
   variante arrondie au pixel (320 × 213 pour 320 × 213,3) donnait sinon sa
   propre proportion à la carte — 199,7 px de haut au lieu de 200 à 390 px,
   mesuré le 22 septembre 2026 après le passage à des fichiers plus grands
   (content/pages/_nos_services.php). « cover » rogne le tiers de pixel au
   lieu de l'étirer. ABANDONNÉ le 22 septembre 2026 : la hauteur tirée de la
   seule proportion du fichier servi. */
.service-item__media img {
    border-radius: 10px;
    aspect-ratio: 3 / 2;
    object-fit: cover;
}

.service-item__title {
    padding: 0 0 10px;
    color: var(--navy);
    font-size: 18px;
    font-weight: 400;
    line-height: 18px;
    text-align: center;
}

.service-item__text {
    display: block;
    font-size: 14px;
    line-height: 23.8px;
    text-align: left;
}

@media (max-width: 980px) {
    .services__list {
        flex-direction: column;
    }

    .services__cell {
        flex: none;
        width: 100%;
        margin: 0 0 30px;
    }

    .services__cell:last-child {
        margin-bottom: 0;
    }
}

/* --- Colonnes et accordéon (<details> natifs) ---------------------------
   Relevé à 1440 (« L’entreprise », s6 de l'accueil) : section de 678,6 px =
   54 + 27 + colonne de gauche 516,6 + 27 + 54. Colonne de gauche :
   texte 240 (titre 36 + paragraphes de 150, retombée de 15 comprise, et
   54) + 29,7
   + image 109,2 + 29,7 + texte 108 = 516,6 pour 516,6 — 29,7 = 5,82 % de
   la colonne de 510,3 px, la marge basse des modules d'une colonne 1/2 ;
   9,27 % pour une colonne 1/3 (gouttière 3 de Divi). Sous 981 px (relevé à
   390) : 30 px. Neuf, mesuré le 21 septembre 2026 : 678,8 (image de
   109,4 au lieu de 109,2 : la variante de 320 px du badge, 320 × 196, n'a
   pas tout à fait les proportions du fichier de 497 × 304) ; 1 314,9 à 390,
   pour 1 314,9. ABANDONNÉ le 21 septembre 2026 : « margin-top: 30px » à
   toutes les largeurs, provisoire.
   Pages de services (s4, mêmes règles ; live/pages/*_1440.json et _390),
   hauteur de section relevée → mesurée sur le neuf le 21 septembre 2026 :
     Revendeur HP, trois tiers         642    → 642     1 604 → 1 604
       (colonnes 480, 457 et 420 : 54 + 27 + 480 + 27 + 54) ;
     Services informatiques, moitiés   607,7  → 607,7   1 387 → 1 387
       (textes 252 + 29,7 + 144 = 425,7 ; accordéon 348 + 29,7 + 68 = 445,7) ;
     Maintenance informatique          737,7  → 737,7   1 240 → 1 240
       (texte 198 ; accordéon 478 + 29,7 + 68 = 575,7).
   Chaque titre, paragraphe et puce y tombe à la position relevée (décalé du
   pixel de l'en-tête à 1440) ; écart pixel des captures, section entière :
   0,00 à 0,01 sur 255 à 1440, 0,00 à 0,10 à 390.
   Avant ce relevé : 673, 620,7 et 689,7 à 1440 ; 1 661, 1 389 et 1 193 à
   390 (listes, titres d'un tiers et second texte des Services
   informatiques : voir plus bas). */
.colonnes__col > * + * {
    margin-top: 5.82%;
}

.cols--3 > .colonnes__col > * + * {
    margin-top: 9.27%;
}

/* --- Textes des colonnes : les règles de Divi 4.27, lues dans la feuille
   du thème de la sauvegarde (wp-content/themes/Divi/style-static.min.css)
   et vérifiées sur les pages de services de l'original
   (live/pages/*_1440.textes.json), le 21 septembre 2026 :
   - « p:not(.has-background):last-of-type{padding-bottom:0} » : le DERNIER
     paragraphe d'un module perd sa retombée même quand une liste le suit.
     Revendeur HP, colonne du milieu : « Chez D.P.H. Net, vous pourrez vous
     fournir en : » 54 px (deux lignes, sans retombée), puis la liste à
     y 1 699 = 1 645 + 54 ;
   - listes : « .entry-content ul{padding:0 0 23px 1em;line-height:26px} »
     et, dans un module de texte, « .et_pb_text ul{padding-bottom:1em} ».
     Puces à 15 px du texte (li relevés à x 574,8 pour une colonne à 559,8),
     lignes de 26 px (li relevés de 26 en 26 : 1 699, 1 725 … 1 855), 15 px
     sous la dernière (module de 457 px = 1 896 − 1 439, dernière puce
     finie à 1 881) ; 23 px dans le corps d'un accordéon (Services
     informatiques, « Installation » : dernière puce finie à 1 743, corps
     fini à 1 766).
   Les colonnes de l'accueil n'ont ni liste ni paragraphe suivi d'autre
   chose qu'un paragraphe : rien n'y bouge (mesuré). ABANDONNÉ le
   21 septembre 2026, pour ces colonnes : les listes de la base (§ 2 :
   « margin: 0 0 1em ; padding-left: 1em ») et de .prose (« padding-left:
   1.2em »), avec des lignes de 27 px — 13 px de trop sous « Installation »
   et 22 sous la liste du Revendeur HP. */
.colonnes .prose p:last-of-type {
    padding-bottom: 0;
}

.colonnes .prose ul {
    margin: 0;
    padding: 0 0 1em 1em;
    line-height: 26px;
}

.colonnes .accordeon__corps ul {
    padding-bottom: 23px;
}

/* Ligne blanche de l'original, gardée à sa hauteur : dans « Réactivité »
   (Maintenance informatique), un paragraphe vide « <p>&nbsp;</p> » sépare
   la liste du dernier paragraphe — 27 px de ligne et 15 de retombée, soit
   42 px (paragraphe final relevé à y 1 842 = 1 800 + 42, la liste et sa
   retombée de 23 px finissant à 1 800). Le paragraphe vide n'est pas repris,
   son blanc l'est, porté par le paragraphe qui suit
   (content/pages/maintenance-informatique.php). */
.colonnes .prose .apres-ligne-blanche {
    margin-top: 42px;
}

/* Titres des colonnes d'un tiers : 23 px, règle de Divi
   « .et_pb_column_1_3 h2{font-size:23px} », à toutes les largeurs —
   relevés 23/23 px à 1440 et à 390 sur le Revendeur HP (« HP Pro » 33 px de
   haut, retombée comprise ; « Quel matériel informatique pour mon
   entreprise ? » 56 px, deux lignes). ABANDONNÉ le 21 septembre 2026 :
   26 px, trois lignes et 32 px de trop sur le second. */
.cols--3 .prose h2 {
    font-size: 23px;
}

/* Image : 35 % de la colonne (width=35%, module_alignment=left), 178,6 ×
   109,2 relevés à 1440, 109,2 × 66,9 à 390. */
.colonnes__media img {
    display: block;
    width: 35%;
    height: auto;
}

/* Séparateur haut « arrow3 » (top_divider_height=41px) : posé sur le
   remplissage haut de la section, étiré sur toute la largeur (relevé :
   background-size « 100% 41px »). */
.separateur {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    height: 41px;
    pointer-events: none;
}

/* Accordéon, relevé à 390 px le 21 septembre 2026 (module et_pb_accordion ;
   à 1440, positions de live/pages/accueil_1440.textes.json) :
   - élément : filet 1 px #d9d9d9, remplissage 20 px, ombre preset3 ; fond
     blanc ouvert, #f4f4f4 fermé (règles de Divi) ;
   - titre : 26 px, graisse 600, interligne 26 px, #283851 (le second, fermé :
     noir, voir templates/blocks/colonnes.php), 50 px réservés à droite pour
     l'icône ; icône de 16 px, centrée sur le titre (top 50 %, −8 px),
     #283851, masquée quand l'élément est ouvert ;
   - corps : 20 px sous le titre, 15 px / 27 px ;
   - entre deux éléments : la marge des modules, 5,82 % de la colonne à
     1440 (29,7 px : titres relevés à y 2 284,2 et 2 563,9, premier élément
     de 250 px), 10 px sous 981 px (relevé à 390).
   Hauteurs : ouvert à 1440, 1 + 20 + 26 + 20 + 162 + 20 + 1 = 250 ; fermé,
   68. Pages de services : « Installation » ouvert 348 (corps de 280 = 20 +
   81 + quatre puces sur 156 + 23), « Réactivité » 478 (corps de 410),
   relevés et mesurés ; le second élément, fermé, en noir comme sur
   l'accueil (toggle_text_color=#000000 dans les deux arbres, rgb(0, 0, 0)
   relevé). ABANDONNÉ le 21 septembre 2026 : l'ombre « 0 2px 18px 0 », 18 px entre
   les éléments, 15 px sous le titre, fond blanc fermé et le triangle natif
   du navigateur, provisoires. */
.accordeon__item {
    padding: 20px;
    border: 1px solid var(--toggle-border);
    background: var(--grey-bg);
    box-shadow: var(--box-shadow);
}

.accordeon__item[open] {
    background: var(--white);
}

.accordeon__item + .accordeon__item {
    margin-top: 5.82%;
}

.cols--3 .accordeon__item + .accordeon__item {
    margin-top: 9.27%;
}

.accordeon__titre {
    position: relative;
    display: block;
    padding-right: 50px;
    color: var(--navy);
    font-size: 26px;
    font-weight: 600;
    line-height: 26px;
    list-style: none;
    cursor: pointer;
}

/* Triangle de <summary> dans Safari (display: block suffit ailleurs). */
.accordeon__titre::-webkit-details-marker {
    display: none;
}

.accordeon__item--titre-noir:not([open]) .accordeon__titre {
    color: var(--ink);
}

.accordeon__icone {
    position: absolute;
    top: 50%;
    right: 0;
    width: 16px;
    height: 16px;
    margin-top: -8px;
    fill: var(--navy);
}

.accordeon__item[open] .accordeon__icone {
    display: none;
}

.accordeon__corps {
    padding-top: 20px;
}

@media (max-width: 980px) {
    .colonnes__col > * + *,
    .cols--3 > .colonnes__col > * + * {
        margin-top: 30px;
    }

    .accordeon__item + .accordeon__item,
    .cols--3 .accordeon__item + .accordeon__item {
        margin-top: 10px;
    }
}

/* --- Galerie, pagination et visionneuse (blocks/gallery.php) -----------
   L'original : module de galerie Divi en grille, gouttière 3 (db/plans/
   2934.txt). Relevé à 1440 px, script de Divi actif, page 1 de 2
   (live/pages/galerie_1440.json et galerie_1440.textes.json, 21 septembre
   2026) :
     h1 à 208, grille à 279,7 (écart de module, § 6 « Titre de page ») ;
     rangées de vignettes à 279,7, 499,1, 718,6 et 938 : pas de 219,4 =
       160 (la plus haute vignette de la rangée) + 59,4 (5,5 % de 1080) ;
     vignettes de 225,4 px de large, 160 de haut pour les recadrages
       400 × 284, 126,8 pour les cinq photos de 480 × 270 ;
     filet de la pagination à 1157,4 (= 938 + 160 + 59,4 : la dernière
       rangée GARDE sa marge quand la pagination est affichée) ;
     pagination de 73 px, puis 27 + 54 : section de 1184,4 px.
   Soit 54 + 27 + 42 + 29,7 + 4 × 219,4 + 73,1 + 27 + 54 = 1184,4.
   À 390 px, une colonne de 312 px : photos entières (gallery.php), 35,9 px
   entre elles et sous la dernière (11,5 % de 312), pagination de 72,9 px ;
   section de 4238,8 px.

   POURQUOI UNE BOÎTE FLEXIBLE. Les gouttières de Divi sont en POURCENTAGE
   de la rangée. Dans une grille CSS, une marge en pourcentage se calcule
   sur l'aire de grille de la vignette, et un row-gap en pourcentage sur une
   hauteur indéfinie, donc sur zéro (constat du site Spin’Info, qui a pris
   des flottants). Dans une boîte flexible, marges et column-gap se
   calculent sur la largeur de la boîte, comme chez Divi — et, à la
   différence des flottants de Spin’Info, une vignette masquée par la
   pagination ne compte plus : la 17e photo ouvre la rangée de la page 2
   sans règle :nth-child. `align-items: flex-start` : chaque vignette garde
   sa hauteur, la rangée prend celle de la plus haute, comme les flottants
   de Divi (clear: both en tête de rangée).
   ABANDONNÉ le 21 septembre 2026 : « display: grid; grid-template-columns:
   repeat(4, 1fr); gap: 5.5% » (provisoire : 16,5 px entre les rangées au
   lieu de 59,4, et une colonne sous 981 px). */
.gallery {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    column-gap: 5.5%;
    /* Sans pagination (sans script, ou une seule page), Divi retire la marge
       de la dernière rangée au-dessus de 980 px (.on_last_row
       {margin-bottom: 0}, gutters3_grid_items.css) : la marge négative de
       la boîte l'annule, en pourcentage de la même rangée. */
    margin-bottom: -5.5%;
}

/* Pagination affichée par le script : la dernière rangée garde sa marge
   (relevé ci-dessus ; « keep gutter margin if gallery has pagination »
   dans le script de Divi). */
.gallery--paginee {
    margin-bottom: 0;
}

/* Quatre colonnes de 20,875 % et trois gouttières de 5,5 % : 100 %
   (.et_pb_gutters3 .et_pb_column_4_4 .et_pb_grid_item, gutters3_grid_items
   .css de la sauvegarde). */
.gallery__item {
    position: relative;
    display: block;
    width: 20.875%;
    margin-bottom: 5.5%;
    line-height: 0;
    overflow: hidden;
}

/* Le format est ÉCRIT, d'après la classe que pose gallery.php, et non laissé
   à la variante servie, dont les pixels sont arrondis (voir gallery.php).
   object-fit: cover absorbe le millième de différence. ABANDONNÉ le
   21 septembre 2026 : « aspect-ratio: 400 / 284 » pour toutes les vignettes
   (les cinq photos de 480 × 270 étaient rognées et leurs rangées trop
   hautes de 33,2 px). */
.gallery__item img {
    display: block;
    width: 100%;
    height: auto;
    object-fit: cover;
}

@media (min-width: 480px) {
    .gallery__item--v100x71 img {
        aspect-ratio: 100 / 71;
    }

    .gallery__item--v16x9 img {
        aspect-ratio: 16 / 9;
    }
}

/* Sous 480 px, la photo entière (gallery.php) : 312 × 175,5 (16:9),
   312 × 208 (3:2), 312 × 467,3 (DSC1574, 960 × 1438) relevés à 390 px ;
   DSC1451 (960 × 960) est en page 2, que le relevé ne montre pas. */
@media (max-width: 479px) {
    .gallery__item--p16x9 img {
        aspect-ratio: 16 / 9;
    }

    .gallery__item--p3x2 img {
        aspect-ratio: 3 / 2;
    }

    .gallery__item--p1x1 img {
        aspect-ratio: 1 / 1;
    }

    .gallery__item--p480x719 img {
        aspect-ratio: 480 / 719;
    }
}

/* Voile du survol : #283851 plein (hover_overlay_color=#283851, sans
   transparence) et icône blanche au centre (zoom_icon_color=#ffffff,
   hover_icon=%%13%% : U+002E « arrow_expand_alt », tracé 'expand' de
   src/icons.php). Divi : .et_overlay, opacité 0 → 1 en 0,3 s, icône de
   32 px centrée (style-static.min.css). Le survol n'a pas été capturé sur
   l'original : cotes de la feuille de Divi, non mesurées.
   Réservé aux appareils à survol : sur écran tactile, le survol « collait »
   à la vignette touchée après la fermeture de la visionneuse. ABANDONNÉ le
   21 septembre 2026 : « .gallery__item:hover img { opacity: 0.4 } » (le
   voile à 60 % de Spin’Info, dont la galerie était réglée ainsi). */
.gallery__voile {
    position: absolute;
    inset: 0;
    background: var(--navy);
    color: var(--white);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition);
}

.gallery__voile svg {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 32px;
    height: 32px;
    transform: translate(-50%, -50%);
}

@media (hover: hover) {
    .gallery__item:hover .gallery__voile {
        opacity: 1;
    }
}

/* Paliers de Divi sous 981 px (grid_items.css de la sauvegarde) : trois
   colonnes de 29,666 % de 768 à 980 px, marge basse 7,5 % ; deux de
   47,25 % de 480 à 767, marge basse 9,5 % ; une seule en dessous, marge
   basse 11,5 %. Sous 981 px, Divi garde la marge de la dernière rangée
   (ses règles .on_last_row n'agissent qu'au-dessus de 980 px, et celle de
   479 px vise un descendant qui n'existe pas) : 35,9 px relevés sous la
   dernière photo à 390 px. Seuls 1440 et 390 px ont été relevés ; 768 à
   980 et 480 à 767 suivent la feuille de Divi. ABANDONNÉ le 21 septembre
   2026 : une colonne dès 980 px et « row-gap: 30px » (provisoire). */
@media (max-width: 980px) {
    .gallery {
        margin-bottom: 0;
    }

    .gallery__item {
        width: 29.666%;
        margin-bottom: 7.5%;
    }
}

@media (max-width: 767px) {
    .gallery__item {
        width: 47.25%;
        margin-bottom: 9.5%;
    }
}

@media (max-width: 479px) {
    .gallery__item {
        width: 100%;
        margin-bottom: 11.5%;
    }
}

/* Pagination — .et_pb_gallery_pagination de Divi (gallery.css de la
   sauvegarde) : filet 1 px #e2e2e2, liste alignée à droite, cases en ligne
   de 10 px de remplissage, liens de 16 px sur 16 px, en #283851
   (pagination_text_color). Relevé à 1440 : « 1 » à x 1116,7, « 2 » à
   1145,8, « Prochaine » à 1175, large de 75 px et terminé à 1250 = 1260 −
   10 ; textes à 11 px sous le haut de leur case (1169,4 − 1158,4).
   Hauteur de 73 px = 1 (filet) + 46 (une case : 10 + 26 + 10, la ligne de
   26 px du thème, corps 14 px) + 26 (la ligne vide que crée
   « ul:after {display: inline-block; width: 100%} », reproduite ici par la
   respiration basse de la liste).
   Graisse : l'original demande 500, que ses polices chargées n'ont pas
   (relevé fontsLoaded : 300, 400, 600, 700) ; le navigateur rend donc du
   400, et c'est la graisse écrite ici (la fonte variable du site, elle,
   rendrait un vrai 500). */
.gallery-pager {
    border-top: 1px solid #e2e2e2;
}

/* Boîte flexible et non cases en ligne : le gabarit sépare les <li> par des
   retours à la ligne, qui feraient des espaces entre les cases ; le script
   de Divi les écrivait bout à bout. */
.gallery-pager ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    margin: 0;
    padding: 0 0 26px;
    list-style: none;
    font-size: 14px;
    line-height: 26px;
}

.gallery-pager li {
    padding: 10px;
}

.gallery-pager button {
    position: relative;
    display: inline-block;
    padding: 0;
    border: 0;
    background: none;
    color: var(--navy);
    font-size: 16px;
    font-weight: 400;
    line-height: 16px;
    cursor: pointer;
}

/* Zone de clic agrandie aux 10 px de la case, sans rien déplacer : « 1 » et
   « 2 » ne font que 9,2 px de large, sous les 24 × 24 px du critère 2.5.8
   des WCAG 2.2 ; avec la case, 29,2 × 36 px. */
.gallery-pager button::after {
    content: "";
    position: absolute;
    inset: -10px;
}

/* ÉCART : la page affichée est soulignée. Dans l'original, « 1 », « 2 » et
   « Prochaine » avaient la même couleur, active ou non (a.active relevé en
   #283851, comme les autres) : rien ne disait sur quelle page on était. Le
   soulignement ne déplace aucun pixel ; le retirer suffit à revenir à
   l'original. */
.gallery-pager [aria-current="page"] {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

/* La visionneuse est un <dialog> natif piloté par assets/js/site.js, celle
   du site Spin’Info (cotes et règles reprises telles quelles). Elle
   remplace la lightbox de Divi (magnific popup) : même service, sans
   dépendance. Comme celle de Divi, elle parcourt les 23 photos, quelle que
   soit la page affichée. */
.lightbox {
    border: 0;
    padding: 0;
    max-width: 100vw;
    max-height: 100vh;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.92);
}

.lightbox::backdrop {
    background: rgba(0, 0, 0, 0.92);
}

.lightbox__figure {
    margin: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    padding: 40px 60px;
}

.lightbox__figure img {
    max-width: 100%;
    max-height: calc(100vh - 140px);
    width: auto;
    object-fit: contain;
}

.lightbox__figure figcaption {
    color: var(--white);
    font-size: 14px;
    text-align: center;
}

.lightbox__close,
.lightbox__prev,
.lightbox__next {
    position: absolute;
    background: none;
    border: 0;
    color: var(--white);
    cursor: pointer;
    padding: 12px;
    line-height: 0;
}

.lightbox__close {
    top: 12px;
    right: 16px;
}

.lightbox__prev {
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
}

.lightbox__next {
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
}

.lightbox svg {
    width: 26px;
    height: 26px;
    fill: currentColor;
}

@media (max-width: 767px) {
    /* La photo prend presque toute la largeur : les boutons de navigation,
       au bord de l'écran, passent DESSUS. Leurs chevrons blancs sont donc
       posés sur une pastille sombre, qui les garde lisibles sur une zone
       claire de la photo : blanc sur noir à 60 % posé sur du blanc, 5,7:1
       au pire (critère 1.4.11 : 3:1).
       ABANDONNÉ le 22 septembre 2026 : « Les boutons de navigation sont au
       bord de l'écran : la photo leur laisse la place plutôt que de passer
       dessous. », que le code ne faisait pas — 16 px de marge pour des
       boutons de 58 px. Mesuré (relecture de fidélité du 22 septembre 2026) :
       flèches sur la photo pour 23 photos sur 23 à 480, 390 et 360 px, et
       jusqu'à 15 % des pixels du tracé sous 3:1 (1,19:1 au pire). */
    .lightbox__figure {
        padding: 60px 16px 30px;
    }

    .lightbox__prev,
    .lightbox__next {
        background: rgba(0, 0, 0, 0.6);
        border-radius: 4px;
    }
}

/* --- Plan du site (blocks/sitemap.php) ----------------------------------
   L'original (db/plans/2959.txt ; live/pages/plan-du-site_1440.json et
   .textes.json, 21 septembre 2026) : section #f4f4f4, h1 à 208, h2
   « Pages » à 279,7 (écart de module de 29,7 px, comme § 6 « Titre de
   page »), 36 px de haut (26 + 10), liste à 315,7, une page tous les
   26 px, liens de 15 px en #283851 à 15 px du bord (retrait de 1 em).
   Notre plan ne liste que les neuf pages servies, et plus les titres
   « Actualités », « Avis clients », « Login Designer » ni les articles
   (content/pages/plan-du-site.php). Section attendue :
     à 1440 : 54 + 27 + 42 + 29,7 + 36 + 9 × 26 + 23 + 27 + 54 = 526,7 px ;
     à 390  : 50 + 30 + 42 + 30 + 36 + 13 × 26 + 23 + 30 + 50 = 629 px —
              quatre titres passent sur deux lignes dans les 297 px de la
              colonne, comme dans l'original (« Matériel informatique… »,
              « Un service de maintenance… », « Votre administrateur… »,
              « Votre magasin… », relevés à 46 px de haut).
   ABANDONNÉ le 21 septembre 2026 : « padding: 4% 0 » et « 2% 0 » sans
   plafond (57,6 et 28,8 px à 1440 au lieu de 54 et 27, 15,6 et 7,8 à 390
   au lieu de 50 et 30), titres « Pages » et liens à leur corps par défaut. */

/* `.sitemap-section` n'est pas un `.section` : elle reçoit ici les
   respirations du § 3. */
.sitemap-section {
    padding: 4% 0;
    background: var(--grey-bg);
}

.sitemap-section > .row {
    padding: 2% 0;
}

@media (min-width: 1350px) {
    .sitemap-section {
        padding: 54px 0;
    }

    .sitemap-section > .row {
        padding: 27px 0;
    }
}

/* Le h1 garde les cotes du § 2 (32 px sur 32, graisse 600, 10 px de
   retombée) ; sa marge basse est l'écart de module de Divi. */
.sitemap__title {
    margin-bottom: 2.75%;
}

/* « Pages » : h2 de 26 px sur 26, NOIR (relevé rgb(0, 0, 0) : le module ne
   règle que la couleur du texte et des liens), en graisse 500 demandée,
   donc 400 rendue (voir la pagination de la galerie ci-dessus). */
.sitemap h2 {
    color: var(--ink);
    font-size: 26px;
    font-weight: 400;
    line-height: 26px;
}

/* Liste du thème (padding: 0 0 23px 1em ; line-height: 26px ; puces), texte
   de 15 px (text_font_size=15px), puces et liens #283851 (text_text_color,
   link_text_color). */
.sitemap ul {
    margin: 0;
    padding: 0 0 23px 1em;
    list-style: disc;
    color: var(--navy);
    font-size: 15px;
    line-height: 26px;
}

.sitemap a {
    color: var(--navy);
}

@media (max-width: 980px) {
    .sitemap-section {
        padding: 50px 0;
    }

    .sitemap-section > .row {
        padding: 30px 0;
    }

    .sitemap__title {
        margin-bottom: 30px;
    }
}

/* --- Pages légales (blocks/legal.php) — Mentions légales et Politique de
   confidentialité -------------------------------------------------------
   Mise en page de l'original, la même sur les deux pages (dph_posts 2950 et
   2955 ; db/plans/2950.txt et 2955.txt) : UNE section à fond #f4f4f4
   (background_color), une rangée, une colonne pleine, un module « titre »
   (h1 32 px, graisse 600, #283851) puis un module de texte
   (text_font_size=15px, text_line_height=1.8em).
   Relevé à 1440 px (live/pages/mentions-legales_1440.json et .textes.json,
   politique-de-confidentialite_1440.*, 21 septembre 2026) :
     - section à 127, fond rgb(244, 244, 244), 54 px de respiration, rangée
       à 27 : h1 à 208 (= 127 + 54 + 27), 42 px de haut (32 + 10 de
       retombée, § 2) ;
     - module de texte à 279,7 : 29,7 px sous le titre, l'écart de module de
       Divi (2,75 % de la rangée, voir « Titre de page ») ;
     - paragraphes 15 px sur 27, NOIRS, 15 px dessous (1 em) — la base
       .prose et le § 2 les donnent déjà ;
     - h2 26 px sur 26 et h3 22 sur 22, NOIRS, graisse 500 demandée mais
       rendue 400 (aucune face 500 chargée : même constat que pour « Pages »
       du plan du site et les chiffres de l'accueil), 10 px de retombée et
       AUCUN écart au-dessus : le h2 « Administrateur du site internet »
       tombe à 486,7, juste sous le paragraphe commencé à 417,7 (54 + 15) ;
       h2 de 36 px de haut, h3 de 32 ;
     - listes (politique) : lignes de 26 px, texte à x 195 pour une colonne
       à 180 (retrait de 15 px, 1 em), aucun écart au-dessus, 15 px dessous
       (dernier point fini à 3 062,7, h2 suivant à 3 077,7) ;
     - dernier paragraphe → bas de section : 27 + 54 px (rangée puis
       section), la base retire la marge du dernier paragraphe.
   À 390 px (…_390.json) : section à 344,6, 50 px puis 30 de rangée, h1 à
   424,6, module de texte à 496,6 — 30 px, l'écart de module sous 981 px.
   ÉPROUVÉ le 22 septembre 2026 sur un banc (copie du site servie à part,
   dphwork/legales/) : le texte et les balises de l'ORIGINAL (module de
   texte de live/pages/*_1440.html) sous ces règles redonnent la section des
   mentions au dixième de pixel — 2 149,7 px à 1440, 3 939 à 390, comme
   relevé —, les 23 boîtes des mentions et les 48 de la politique (tableaux
   retirés) à moins de 0,5 px, et un écart pixel moyen de 0,06 à 0,15 sur
   255 : les seules lignes qui diffèrent sont les soulignements de liens
   (ci-dessous).
   ABANDONNÉ le 21 septembre 2026 (premier jet des fondations, sans
   relevé) : section BLANCHE, texte collé au titre (aucun écart), et
   « .legal h2, .legal h3 { padding-top: 10px; color: var(--ink);
   font-weight: 600; } ». */
.legal-section {
    background: var(--grey-bg);
}

/* L'écart de module en POURCENTAGE de la rangée, comme chez Divi : une
   marge se calcule sur la largeur du bloc conteneur, ici .legal, large
   comme la rangée (29,7 px à 1440, 2,75 % de 1080). */
.legal > h1 {
    margin-bottom: 2.75%;
}

/* Coupure gloutonne (text-wrap: wrap) et non « pretty » (§ 2) : celle de
   l'original, que suivent les titres des autres blocs (§ « Image et
   texte »). */
.legal h1,
.legal h2,
.legal h3,
.legal h4 {
    text-wrap: wrap;
}

/* h4 : 18 px sur 18, noir, 400 rendu, 28 px de haut (quatre h4 dans la
   politique d'origine, « Cookie nécessaire au fonctionnement du site »…).
   Aucune des deux pages n'en porte aujourd'hui ; la règle est là pour
   qu'un h4 ajouté un jour ne prenne pas le bleu nuit en 600 des titres du
   site (§ 2). */
.legal h2,
.legal h3,
.legal h4 {
    padding: 0 0 10px;
    color: var(--ink);
    font-weight: 400;
}

.legal ul {
    margin: 0 0 15px;
    padding-left: 1em;
}

.legal li {
    line-height: 26px;
}

.legal__strong {
    font-weight: 700;
}

/* Liens : SOULIGNÉS (.prose a), alors que l'original les écrivait noirs et
   sans soulignement (decoration « none », couleur rgb(0, 0, 0), relevés) —
   dans un texte noir, rien ne les distinguait (critère 1.4.1 des WCAG :
   l'information ne passe pas par la seule couleur, ici pas même par elle).
   Défaut de l'original corrigé ; aucune cote ne change, le soulignement
   tient dans la ligne. */
.legal a {
    word-break: break-word;
}

@media (max-width: 980px) {
    .legal > h1 {
        margin-bottom: 30px;
    }
}

.legal .table-scroll {
    overflow-x: auto;
    margin: 0 0 1.4em;
}

.legal table {
    width: 100%;
    border-collapse: collapse;
    min-width: 560px;
    font-size: 13px;
}

.legal table td,
.legal table th {
    padding: 6px;
    border: 1px solid var(--ink);
    text-align: left;
    vertical-align: top;
}

/* --- Encadré de fin des pages de services (cta) -------------------------
   AJOUT (decisions.md § 3, comme Spin’Info et Raon Informatique) : les trois
   pages de services de l'original finissaient sur leurs colonnes grises, sans
   appel ni renvoi de l'une à l'autre (live/pages/*_1440.json : quatre
   sections de contenu, puis le pied). Aucun relevé ne contraint donc cet
   encadré ; ses cotes sont EMPRUNTÉES au seul appel à l'action de
   l'original, le bandeau « Contacter » (module et_pb_cta, § « Bandeau
   d'appel » ci-dessus), pour que le site n'ait qu'une manière de dire
   « contactez-nous » :
   - section blanche au rythme de Divi (54 et 27 px à 1440, 50 et 30 sous
     981 px), entre les colonnes grises et le bleu nuit du pied ;
   - panneau aux coins de 25 px (border_radii), 40 px 60 px de remplissage
     (40 px sous 981 px ; 24 px de côté sous 480 px, voir la dernière règle
     de ce bloc), texte blanc centré, 20 px avant le bouton,
     bouton évidé blanc de 50 px (btn--light, celui de « Contacter ») ;
   - fond #283851 PLEIN et non rgba(40,56,81,.7) : le voile du bandeau
     assombrit une photo ; posé sur du blanc, il donnerait un gris-bleu
     #687485, où le texte blanc tomberait à 4,7:1 (calculé) ; en plein,
     11,8:1 ;
   - titre h2 de 26 px, graisse 600, interligne 26 px et 10 px de retombée,
     ceux des titres de colonnes de ces pages (relevés 26/26, 600) ;
   - phrase en 18 px sur 23,8 px, celles du bandeau (body_font_size=18px,
     interligne du corps) ;
   - renvoi vers une autre page de services 14 px sous le bouton, en 15 px
     sur 27 (le texte courant des colonnes), lien souligné en graisse 600.
   Hauteur calculée à 1440 : 54 + 27 + (40 + 36 + 23,8 + 20 + 50 + 14 + 27
   + 40) + 27 + 54 = 412,8 px ; mesurée le 21 septembre 2026 : 412,8 sur les
   trois pages (autres mesures dans templates/blocks/cta.php).
   ABANDONNÉ le 21 septembre 2026 : « .cta { background: var(--navy) } »,
   « .cta__panel { padding: 40px ; border: 2px solid var(--white) } »,
   « .cta h2 { font-size: 18px ; font-style: italic ; text-transform:
   uppercase ; text-shadow: var(--text-shadow) } », « .cta__text {
   font-size: 16px } » et « margin-top: 16px » avant le bouton — l'encadré de
   l'accueil de Spin’Info, repris tel quel par les fondations. Collé au pied
   bleu nuit, il s'y confondait (captures de l'état d'avant :
   dphwork/services/avant_*.png). */
.cta {
    color: var(--white);
}

.cta__panel {
    padding: 40px 60px;
    border-radius: 25px;
    background: var(--navy);
    text-align: center;
}

.cta h2 {
    color: var(--white);
    font-size: 26px;
    line-height: 26px;
}

.cta__text {
    font-size: 18px;
    line-height: 23.8px;
}

.cta__actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    margin-top: 20px;
}

.cta__link {
    margin: 0;
    padding: 0;
    font-size: 15px;
    line-height: 27px;
}

/* inline-block : quand la ligne ne tient pas (téléphone), le lien passe
   ENTIER à la ligne au lieu de se couper après « Voir le ». */
.cta__link a,
.cta__link a:hover {
    display: inline-block;
    color: var(--white);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.cta__link a:hover {
    text-decoration-thickness: 2px;
}

@media (max-width: 980px) {
    .cta__panel {
        padding: 40px;
    }
}

/* Focus au clavier sur les panneaux bleu nuit (cet encadré et le bandeau
   « Contacter ») : le contour des fonds sombres (§ 2 — filet blanc, anneau
   bleu nuit), et non celui des sections claires, que .section impose
   (filet bleu nuit, invisible sur ce fond, et anneau blanc qui se fondait
   dans la bordure blanche du bouton : une bordure de 2 px devenait 6 px,
   seul signe du focus). Le bouton focalisé porte ainsi sa bordure blanche,
   2 px de bleu nuit, puis le filet blanc. Aucune cote ne bouge (contour et
   ombre ne prennent pas de place). */
.cta__panel :focus-visible,
.bandeau__panel :focus-visible {
    outline-color: var(--white);
    box-shadow: 0 0 0 4px var(--navy);
}

/* Sous 480 px, 24 px de côté (les 40 px du haut et du bas restent) : avec
   40 px, la place intérieure tombait à 176 px à 320 px de fenêtre, et le
   bouton « Nous contacter », qui en demande 186,3, passait sur deux lignes
   (84 px au lieu de 50, mesuré le 21 septembre 2026). Avec 24 px : 208 px à
   320, 264 à 390 — où « Voir la maintenance informatique » (244,3 px) tient
   enfin sur une ligne. Le bandeau « Contacter », lui, garde les 40 px
   relevés sur l'original : son libellé tient à toutes les largeurs. */
@media (max-width: 479px) {
    .cta__panel {
        padding: 40px 24px;
    }
}

/* ==========================================================================
   7. Page Coordonnées
   ========================================================================== */

/* La seconde rangée de l'original, celle des deux colonnes : aucune
   respiration (custom_padding=0px||0px de s1.r2, db/plans/2869.txt). Relevé
   à 1440 px (live/pages/coordonnees_1440.json) : rangée de 329,7 à 416,1,
   collée à la première (titre et filet, § 6 « Titre de page ») ; puis les
   54 px de la section, et le pied à 470,1. Section de 343,1 px =
       54 + 27 (section, rangée) + 42 (h1) + 29,7 + 23 (filet) + 27
     + 86,4 (la plus haute colonne, trois lignes de 28,8) + 54.
   À 390 px, l'original : 429 px = 50 + 30 + 42 + 30 + 23 + 30 + 57,6 + 30
   + 86,4 + 50 (colonnes empilées, 30 px entre elles) ; ici 477 px, les
   48 px des cibles tactiles en plus (plus bas). ABANDONNÉ le 21 septembre
   2026 : « padding-top: 40px » (provisoire). */
.page-title + .coordonnees > .row {
    padding-top: 0;
    padding-bottom: 0;
}

/* Deux colonnes 1_2 de Divi en gouttière 3 : 510,3 px chacune et 59,4 px
   entre elles (5,5 % de 1080), relevées à x 180 et 749,7. */
.coordonnees__grille {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--gutter);
}

/* Le texte des deux modules de l'original : 16 px, graisse 600, #283851,
   interligne 1,8 em, soit des lignes de 28,8 px (text_font=|600|,
   text_font_size=16px, text_line_height=1.8em, db/plans/2869.txt ; relevé :
   57,6 et 86,4 px de haut). */
.coordonnees__col {
    color: var(--navy);
    font-size: 16px;
    font-weight: 600;
    line-height: 1.8em;
}

/* Le nom, un h2 ici, une simple ligne du même texte dans l'original : même
   corps, même graisse, même ligne, sans la retombée de 10 px des titres
   (§ 2). Capitales par la feuille, le texte reste « M. Romary ». ABANDONNÉ
   le 21 septembre 2026 : « padding-bottom: 6px; font-weight: 700 »
   (provisoire : un nom plus gras et 6 px plus bas que l'original). */
.coordonnees__titre {
    padding-bottom: 0;
    color: inherit;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.8em;
    text-transform: uppercase;
}

.coordonnees__fiche {
    font-style: normal;
}

.coordonnees__col p {
    padding-bottom: 0;
}

/* Numéros et adresse EN LIENS (decisions.md § 2.3) : dans l'original, ils
   n'étaient que du texte. Le soulignement dit qu'on peut les toucher ; la
   couleur et la graisse restent celles du texte (règles du site Spin’Info,
   § 7 de sa feuille). Sur une seule ligne : un numéro ne se coupe pas entre
   deux groupes de chiffres.
   `inline-block` donne à chaque lien, à la souris, la hauteur de sa ligne,
   28,8 px, comme zone de clic, sans rien déplacer : le bloc a l'interligne
   de la colonne et sa ligne de base est celle de son texte. */
.coordonnees__lien {
    display: inline-block;
    color: inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
    white-space: nowrap;
}

.coordonnees__lien:hover {
    color: inherit;
    text-decoration-thickness: 2px;
}

/* Cibles tactiles — règle du site Spin’Info, que contrôle
   outils/audit_interact.mjs (« cibles d'au moins 44 × 44 px » à 390 px) :
   sur téléphone, et partout où un doigt peut servir de pointeur, chaque lien
   fait 44,8 px de haut (8 + 28,8 + 8), au-dessus des 44 px du critère 2.5.5
   des WCAG. Le remplissage est vertical seulement : la ligne s'allonge
   d'autant, sans que deux cibles se recouvrent. ÉCART À L'ORIGINAL, voulu :
   à 390 px, les trois lignes à lien prennent 16 px de plus chacune, la
   section 477 px au lieu de 429. À la souris seule (relevé à 1440), les
   lignes gardent l'interligne de l'original. */
@media (max-width: 767px), (any-pointer: coarse) {
    .coordonnees__lien {
        padding: 8px 0;
    }
}

/* Sous 981 px, les colonnes s'empilent, 30 px entre elles : règle de Divi
   (.et_pb_column {width: 100%; margin-bottom: 30px} sous 981 px,
   style-static.min.css de la sauvegarde), relevée à 390 px (colonnes à
   549,6 et 637,2 = 549,6 + 57,6 + 30). ABANDONNÉ le 21 septembre 2026 : la
   bascule à 767 px (deux colonnes jusqu'à 768 px, où Divi en montre une). */
@media (max-width: 980px) {
    .coordonnees__grille {
        grid-template-columns: 1fr;
        row-gap: 30px;
    }
}

/* ==========================================================================
   8. Utilitaires
   ========================================================================== */

/* Bouton de révélation : il ne se distingue pas du texte qui l'entoure,
   puisqu'il prendra la place d'un numéro ou d'une adresse. Le script le
   remplace par un <a> qui garde la classe `reveal`. */
.reveal {
    display: inline;
    padding: 0;
    background: none;
    border: 0;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: opacity var(--transition);
}

.reveal:hover {
    opacity: 0.75;
    text-decoration: underline;
}

.reveal[data-state="loading"] {
    opacity: 0.6;
    cursor: progress;
}

.reveal[data-state="done"] {
    cursor: default;
    text-decoration: none;
}

.reveal[data-state="done"]:hover {
    opacity: 1;
}

/* Boutons Divi : 20 px, bordure de 2 px, coins de 3 px ; remplissage de
   .3em 1em, interligne 1,7 em — d'où 50 px de haut à 20 px, et 45,4 px pour
   « Voir nos services » en 18 px (5,4 px 18 px relevés à 390 px le
   21 septembre 2026). ABANDONNÉ le même jour : « padding: 6px 20px », juste
   à 20 px seulement. */
.btn {
    display: inline-block;
    padding: 0.3em 1em;
    border: 2px solid currentColor;
    border-radius: 3px;
    background: transparent;
    color: var(--ink);
    font-family: var(--sans);
    font-size: 20px;
    font-weight: 400;
    line-height: 1.7em;
    text-align: center;
    cursor: pointer;
    transition: all var(--btn-transition);
}

.btn:hover {
    background: rgba(0, 0, 0, 0.05);
}

.btn--light {
    color: var(--white);
}

.btn--light:hover {
    background: rgba(255, 255, 255, 0.2);
    color: var(--white);
}

/* Bouton du diaporama : fond rgba(40,56,81,.5) (button_bg_color,
   db/plans/2.txt). */
.btn--veil {
    background: var(--veil-slide);
}

/* « Voir nos services » : texte #283851 (button_text_color). */
.btn--navy-text {
    color: var(--navy);
}

.btn--navy-text:hover {
    color: var(--navy);
}

.error-page {
    text-align: center;
}

.error-page h1 {
    padding-bottom: 18px;
}

.error-page p {
    max-width: 52ch;
    margin: 0 auto;
    padding-bottom: 1.4em;
}

.error-page__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: center;
    padding-top: 10px;
}

.btn--navy {
    background: var(--navy);
    border-color: var(--navy);
    color: var(--white);
}

.btn--navy:hover {
    background: var(--navy);
    color: var(--white);
}

/* Ni une ancre ni un élément qui reçoit le focus ne se cachent sous
   l'en-tête collant (64 px, au-dessus de 980 px ; WCAG 2.4.11) : le
   navigateur réserve cette hauteur quand il amène un élément à l'écran.
   Mesuré le 21 septembre 2026 à 1440 px, en remontant au clavier (Maj+Tab)
   depuis le bas de la page : sans cette réserve, 4 arrêts sur l'accueil et
   10 sur Services informatiques tombaient sous l'en-tête collant (haut du
   lien entre 0 et 19 px) ; avec elle, aucun. En dessous de 981 px, c'est la
   réserve de 50 px de la barre noire (§ 9). ABANDONNÉ le même jour :
   « .section[id] { scroll-margin-top: 64px } », qui ne couvrait que les
   ancres et se serait ajouté à cette réserve. */
@media (min-width: 981px) {
    html {
        scroll-padding-top: 64px;
    }
}

/* ==========================================================================
   9. Mobile, mouvement réduit, impression
   ========================================================================== */

/* Trois composants qui n'existent que sous 981 px — barre du haut, tiroir,
   bouton d'appel — et la bascule entre les deux en-têtes. Sous 981 px, rien
   ne change par rapport à l'original (decisions.md § 2.4). Sources, toutes
   mesurées : live/pages/accueil_390.json (mobmenu, stickyFooter), captures
   accueil_390_bandeau.png et accueil_390_menu.png, capture de l'original en
   ligne à 600 px (21 septembre 2026), et les feuilles de l'extension dans la
   sauvegarde (wp-content/uploads/dynamic-mobmenu.css,
   plugins/mobile-menu/includes/css/mobmenu.css). Les cotes fines de ces
   trois composants sont celles que Spin’Info a relevées sur la même
   extension, jamais configurée non plus ; elles ont été recomparées ici aux
   captures de DPH Net.

   DÉFAUT DE L'ORIGINAL CORRIGÉ (decisions.md § 4) : l'extension affichait
   sa barre jusqu'à 1 024 px (dynamic-mobmenu.css : max-width 1024px) quand
   l'en-tête de Divi basculait à 981 px ; entre les deux, deux en-têtes
   empilés. Ici, une seule bascule, à 981 px, la rupture de Divi que suit
   tout le reste de la page. */

/* --- Barre du haut ------------------------------------------------------
   Barre de 50 px, fond #111, z-index 10000 ; au centre, le TEXTE « DPH Net »
   en Dosis 20 px blanc, graisse héritée 700 de la barre alors que seule la
   Dosis 400 est chargée — le navigateur la graisse lui-même, comme sur
   l'original (encre relevée à 390 px : x 164..226, y 18..33). Hamburger :
   encre 22 × 15 px à x 15..36, trois barres de 3 px (y 18, 24, 30).
   L'original fixait la barre et donnait 50 px de marge haute au <body> ;
   ici elle est `sticky` et occupe ses 50 px dans le flux : même rendu. */

.mobile-bar {
    display: none;
    position: sticky;
    top: 0;
    z-index: 10000;
    height: 50px;
    background: var(--mobile-bar);
}

.mobile-bar__inner {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
}

.mobile-bar__title {
    color: var(--white);
    font-family: var(--dosis);
    font-size: 20px;
    font-weight: 700;
    line-height: 50px;
}

.mobile-bar__title:hover {
    color: var(--white);
}

.mobile-bar__toggle {
    position: absolute;
    left: 0;
    top: 0;
    width: 51px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 0;
    cursor: pointer;
    color: var(--white);
}

.mobile-bar__toggle svg {
    width: 28px;
    height: 28px;
    fill: currentColor;
}

/* --- Tiroir -------------------------------------------------------------
   270 px depuis la GAUCHE, fond #f7f7f7, voile rgba(0,0,0,.83) qui couvre
   aussi la barre noire. Premier lien à 55 px du haut (.mobmenu-content :
   margin-top 45px, padding-top 10px). Liens en Dosis 14 px, interligne
   21 px, #666, remplissage 10 px 20 px : un lien tous les 41 px (relevé sur
   accueil_390_menu.png : 76, 117, 158…). Graisse déclarée 500, rendue en
   400 — seule la Dosis 400 est chargée, ici comme sur l'original.
   Croix de 30 px en #666 au coin haut droit ; cible de 44 × 44 px. */

.mobile-panel {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10010;
    width: 270px;
    max-width: 85vw;
    height: 100%;
    padding: 55px 0 120px;
    background: var(--drawer-bg);
    overflow-y: auto;
    transform: translateX(-100%);
    transition: transform var(--transition);
    visibility: hidden;
}

.mobile-panel[data-open="true"] {
    transform: translateX(0);
    visibility: visible;
}

.mobile-panel__close {
    position: absolute;
    top: 0;
    right: 3.5px;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    background: none;
    border: 0;
    color: var(--mobile-link);
    cursor: pointer;
}

/* L'anneau de focus de la croix est tracé À L'INTÉRIEUR du bouton : placé
   dehors (2 px d'écart, 4 px de halo), son haut tombait au-dessus du bord du
   tiroir et le défilement du panneau (overflow-y: auto) le coupait
   (relecture de fidélité du 22 septembre 2026). Même tracé, bleu nuit sur
   halo blanc ; la croix ne bouge pas. ABANDONNÉ le 22 septembre 2026 : la
   règle générale « .mobile-panel :focus-visible » seule pour ce bouton. */
.mobile-panel__close:focus-visible {
    outline-offset: -2px;
    box-shadow: inset 0 0 0 6px var(--white);
}

.mobile-panel__close svg {
    width: 36px;
    height: 36px;
    margin-top: -4px;
    fill: currentColor;
}

.mobile-panel ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.mobile-panel a {
    display: block;
    padding: 10px 20px;
    color: var(--mobile-link);
    font-family: var(--dosis);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5em;
}

.mobile-panel a:hover {
    background: var(--mobile-link);
    color: var(--white);
}

.mobile-overlay {
    position: fixed;
    inset: 0;
    z-index: 10005;
    background: var(--veil-menu);
    opacity: 0;
    transition: opacity var(--transition);
    border: 0;
    padding: 0;
    cursor: pointer;
}

.mobile-overlay[data-open="true"] {
    opacity: 1;
}

body[data-menu-open="true"] {
    overflow: hidden;
}

@media (min-width: 981px) {
    .mobile-panel,
    .mobile-overlay {
        display: none;
    }
}

/* --- Bouton « Nous appeler » (module global 2259) -----------------------
   Sous 768 px, fixé en bas de l'écran, pleine largeur, 50 px : fond noir,
   bordure blanche de 2 px sur les quatre côtés, coins de 3 px, Open Sans
   20 px sur 34 px en capitales blanches (2 + 6 + 34 + 6 + 2 = 50). Graisse
   déclarée 500, rendue en 400 : l'original ne chargeait pas l'Open Sans 500
   (live/pages/accueil_390.json, fontsLoaded : 300, 400, 600, 700).
   Icône du combiné plein à gauche, toujours visible, sans animation au
   survol (button_on_hover=off).
   Relevé sur l'original en ligne à 600 px : encre de l'icône 18 × 18 px à
   x 217..234, 9 px avant l'encre du texte (x 244..384), le groupe centré
   sur la barre. Le combiné remplit 19,6 / 24 de sa boîte : 22 px donnent
   18 px d'encre ; il laisse 1,8 px vides à droite, d'où l'écart de 6 px.
   Mesuré sur le rendu à 600 px : icône x 216..233, texte x 244..384.  */

.mobile-call {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9990;
}

.mobile-call .reveal {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    min-height: 50px;
    padding: 6px 14px;
    background: var(--ink);
    border: 2px solid var(--white);
    border-radius: 3px;
    color: var(--white);
    font-family: var(--sans);
    font-size: 20px;
    font-weight: 400;
    line-height: 34px;
    text-transform: uppercase;
    text-decoration: none;
}

.mobile-call .reveal:hover {
    opacity: 1;
    text-decoration: none;
}

.mobile-call .reveal svg {
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
    fill: currentColor;
    color: var(--white);
}

/* --- La bascule entre les deux en-têtes ---------------------------------
   Écrite APRÈS les composants ci-dessus : `.mobile-bar` est livrée en
   `display: none` et cette règle la rallume à la même spécificité. La
   rangée bleue n'est pas concernée : c'est l'en-tête collant qui décide de
   sa visibilité (§ 4). */

@media (max-width: 980px) {
    .masthead__top,
    .masthead__main {
        display: none;
    }

    .mobile-bar {
        display: block;
    }

    /* Le focus clavier ne se cache pas sous la barre noire (WCAG 2.4.11). */
    html {
        scroll-padding-top: 50px;
    }
}

/* --- 767 px : le bouton d'appel apparaît --------------------------------
   Il couvre le bas de l'écran : sans réserve, le crédit du pied passerait
   dessous. La réserve est posée DANS la barre noire, et seulement quand le
   script a démasqué le bouton (data-call-bar sur <html>, assets/js/site.js) :
   la page se termine toujours sur du noir, sans bande blanche (défaut des
   30 px corrigé, decisions.md § 4), et sans JavaScript il n'y a ni bouton ni
   réserve. scroll-padding-bottom garde le focus hors de dessous le bouton. */

@media (max-width: 767px) {
    .mobile-call {
        display: block;
    }

    html[data-call-bar] {
        scroll-padding-bottom: 50px;
    }

    html[data-call-bar] .footer__bar {
        padding-bottom: 50px;
    }
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

@media print {
    .sticky-header,
    .masthead,
    .mobile-bar,
    .mobile-panel,
    .mobile-overlay,
    .mobile-call,
    .lightbox {
        display: none !important;
    }

    body {
        color: #000;
        background: #fff;
        padding-bottom: 0;
    }

    a {
        text-decoration: underline;
    }
}
