/* ---- Police system (sans dépendance externe) ---- */

/* ============================================================
   Skip link — a11y WCAG 2.4.1 (sprint-05 C3, refactor C3b).
   Pattern visually-hidden classique (gov.uk / Bootstrap) : clip-path
   cache vraiment l'élément hors-écran sans transition fragile.
   Apparaît au focus clavier (Tab depuis la barre d'URL).
   ============================================================ */
.skip-link {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    border: 0;
    white-space: nowrap;
}
.skip-link:focus,
.skip-link:focus-visible {
    position: fixed;
    top: 8px;
    left: 8px;
    width: auto;
    height: auto;
    margin: 0;
    padding: 10px 18px;
    overflow: visible;
    clip: auto;
    clip-path: none;
    white-space: normal;
    z-index: 10000;
    background: #009FCB;
    color: #fff;
    text-decoration: none;
    font-weight: 600;
    border-radius: 0;
    outline: 3px solid #f0e3a4;
    outline-offset: 2px;
}

/* Le <main> est target du skip link, doit pouvoir recevoir le focus
 * programmatique (tabindex="-1" côté PHP) sans afficher d'outline visuel. */
main:focus,
main:focus-visible {
    outline: none;
}

/* ============================================================
   Reduced motion — a11y (sprint-05 C14).
   Désactive l'animation backgroundZoom et fadeIn pour les utilisateurs
   qui ont activé prefers-reduced-motion sur leur OS.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.001s !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001s !important;
        scroll-behavior: auto !important;
    }
    body {
        animation: none !important;
    }
}

/* ===== Design tokens — source de vérité visuelle (style index) ===== */
:root {
    /* Cartes (landing-box, square-block layout-b, contact-info-box, contact-wrapper)
     * sprint-05 iter 3 : --card-radius 16px → 8px → 0 (carré pur, look
     * architecte brutaliste demandé Arnaud sur l'index et étendu partout
     * pour cohérence). Seul le CTA sticky garde son pill 999px. */
    --card-bg: rgba(0, 0, 0, 0.28);
    --card-bg-hover: rgba(255, 255, 255, 0.18);
    --card-border: 1px solid rgba(255, 255, 255, 0.15);
    --card-blur: blur(2px); /* sprint-24 (retour Arnaud) : blur réduit 3px→2px (fond photo moins « laiteux » derrière les boîtes) */
    --card-radius: 0;
    --card-transition: background 0.3s, transform 0.25s;

    /* CTA (cta-devis, cta-client-portal, send button) */
    --cta-primary-bg: #009FCB;
    --cta-primary-bg-hover: #61C452;
    --cta-primary-color: #fff;
    --cta-accent-bg: #f0e3a4;
    --cta-accent-color: #12202f;
    --cta-radius: 0;  /* sprint-06 itér. 15 : carré pur partout (CTA inclus). */
    --cta-transition: background 0.3s, transform 0.2s;

    /* Hero */
    --hero-text-shadow: 0 3px 15px rgba(0, 0, 0, 0.7);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* ---- BACKGROUND INDEX AVEC ZOOM ---- */

body {
    font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Arial, 'Noto Sans', 'Liberation Sans', sans-serif;
    color: #fff;
    min-height: 100vh;
    overflow-x: hidden;
    /* Clearance globale pour la bottombar fixée + safe-area iPhone à encoche */
    padding-bottom: calc(48px + env(safe-area-inset-bottom));

    /* fallback JPG */
    background-image:
        linear-gradient(rgba(0,0,0,0.25), rgba(0,0,0,0.25)),
        url('assets/img/background_index_light.jpg');
    background-position: center, center;
    background-repeat: no-repeat, no-repeat;
    background-attachment: fixed, fixed;
    background-size: auto, 105% 105%;
    animation: backgroundZoom 3s ease-out forwards;
}

/* WebP */
@supports (background-image: url('assets/img/background_index_light.webp')) {
    body {
        background-image:
            linear-gradient(rgba(0,0,0,0.25), rgba(0,0,0,0.25)),
            url('assets/img/background_index_light.webp');
    }
}

/* AVIF */
@supports (background-image: url('assets/img/background_index_light.avif')) {
    body {
        background-image:
            linear-gradient(rgba(0,0,0,0.25), rgba(0,0,0,0.25)),
            url('assets/img/background_index_light.avif');
    }
}

/* Zoom */
@keyframes backgroundZoom {
    from { background-size: auto, 110% 110%; }
    to   { background-size: auto, 100% 100%; }
}


/* --- TITRE PRINCIPAL --- */
.main-title {
    font-size: 5.6em;
    text-align: center;
    margin-top: 200px;
    margin-bottom: 0;
    line-height: 1;
    font-weight: bold;
    text-shadow: 0 3px 10px rgba(0,0,0,0.75);
    animation: fadeIn 1.2s ease-out;
}

/* --- SOUS-TEXTE --- */
.subtitle {
    text-align: center;
    margin-top: 5px;
    font-size: 1.6em;
    color: #fafafa;
    text-shadow: 0 2px 8px rgba(0,0,0,0.6);
    animation: fadeIn 1.6s ease-out;
}

/* === Animations manquantes === */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---- BLOCS ---- */
.content-blocks {
    display: flex;
    justify-content: center;
    gap: 50px;
    margin-top: 20px;
    flex-wrap: wrap;
    padding: 20px;
}

.square-block {
    width: 400px;
    height: 215px;
    color: #fff;
    background: var(--card-bg, rgba(0, 0, 0, 0.28));
    backdrop-filter: var(--card-blur, blur(2px));
    -webkit-backdrop-filter: var(--card-blur, blur(2px));
    border-radius: 0;  /* sprint-05 iter 3 : carré pur */
    padding: 25px;
    text-align: center;
    display: flex;
    justify-content: center;
    flex-direction: column;
    transition: 0.3s;
}

/* CANON sprint-26 (⛔ backdrop-filter interdit sous le mask) : ces boîtes à FOND UNI
   sont DANS le <main> masqué des pages construction. backdrop-filter y crée une couche
   que le mask ne découpe pas (Firefox/Edge) → elles NE se fondent PAS sous les barres
   (corps syndic, « Voir aussi », résumé KB, encadré Synila). On NEUTRALISE le
   backdrop-filter (canon global + .page-client + related-link + page-summary +
   kb-synila-box) → contenu normal qui se fond comme le titre, tous navigateurs.
   Le verre dépoli (::before flouté) reste réservé aux petites cartes FAQ/KB catégorie. */
body.construction-page .square-block,
body.construction-page .related-link,
body.construction-page .related-links,
body.construction-page .page-summary,
body.construction-page .kb-synila-box {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

.square-block:hover {
    background: rgba(0, 0, 0, 0.35);
    /* sprint-20 (retour Arnaud) : translateY au lieu de scale(1.02) — le scale
     * combiné au backdrop-filter rendait le texte FLOU au survol (ex. ?page=change).
     * translateY donne le même effet de « soulèvement » SANS flou (comme l'index). */
    transform: translateY(-4px);
}

/* Blog & FAQ: auto height, no white hover, title like layout-b */
.page-blog .main-title,
.page-faq .main-title,
.page-client .main-title {
    margin-top: 100px;
    margin-bottom: 17px;
    font-size: 4.2rem;
}

/* TD-24-2 (sprint-25) : l'espace client apparaissait trop haut vs les pages
   d'offre (référence) → on descend le titre. Override page-client UNIQUEMENT
   (blog/faq gardent 100px). Valeur à affiner à l'œil avec Arnaud. */
body.construction-page.page-client .main-title { margin-top: 140px; margin-bottom: 37px; }

/* CTA Espace client (beige accent, like topbar pill) */
.cta-client-portal {
    display: inline-block;
    padding: 18px 48px;
    background: var(--cta-accent-bg, #f0e3a4);
    color: var(--cta-accent-color, #12202f);
    font-size: 1.25em;
    font-weight: 700;
    border-radius: 0;
    text-decoration: none;
    transition: background 0.3s, transform 0.2s;
    letter-spacing: 0.02em;
}
.cta-client-portal:hover {
    background: #61C452;
    color: #fff;
    transform: translateY(-2px);
}
.page-blog .square-block,
.page-faq .square-block {
    height: auto;
    max-width: 800px;
    line-height: 1.4;
    background: rgba(0, 0, 0, 0.28);
}
.page-blog .square-block {
    text-align: center;
}
.page-faq .square-block {
    text-align: left;
}
.page-blog .square-block:hover,
.page-faq .square-block:hover {
    background: rgba(0, 0, 0, 0.28);
    transform: none;
}

/* ============================================================
   PAGE CLIENT — 3 cards en style canon landing/blog (migration 046)
   3 boîtes : Propriétaires occupants / Bailleurs / Entreprises
   ============================================================ */
/* Centrage vertical du contenu page-client (canon identique page-blog) :
 * topbar fixée en haut, puis tout le reste (titre + 3 cards + CTA) centré
 * verticalement dans le viewport restant. */
body.construction-page.page-client {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

/* TD-19-2 (sprint-20) : le <main> de la page client est un enfant flex de body
 * (align-items:center) — sans largeur définie, il se dimensionnait sur le
 * max-content de la grille auto-fit (3 colonnes ~920px), d'où un débordement
 * horizontal de +273px en 375px. On le contraint à la largeur du conteneur :
 * la grille auto-fit résout alors une largeur définie et retombe à 1 colonne. */
body.construction-page.page-client > main {
    width: 100%;
    max-width: 100%;
}

.page-client .content-blocks.construction-content {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 24px;
    max-width: 1200px;
    width: 92%;
    margin: 20px auto;
    padding: 0 16px;
}

.page-client .square-block {
    width: auto;
    height: auto;
    background: var(--card-bg, rgba(0, 0, 0, 0.28));  /* sprint-25 : canon unique .landing-box */
    backdrop-filter: var(--card-blur, blur(2px));
    -webkit-backdrop-filter: var(--card-blur, blur(2px));
    border: var(--card-border, 1px solid rgba(255, 255, 255, 0.15));
    border-radius: 0;  /* sprint-05 iter 3 : carré pur */
    padding: 28px 28px;
    color: #fff;
    text-align: center;
    line-height: 1.6;
    transition: background 0.3s, transform 0.25s;
    display: block;            /* override le flex column qui force la hauteur */
}

.page-client .square-block:hover {
    /* Survol qui ASSOMBRIT (jamais blanchir). Canon unique .landing-box. */
    background: rgba(0, 0, 0, 0.45);
    transform: translateY(-3px);
}

/* Premier <p> avec <strong> = équivalent du .box-title de l'index canon
 * (font-size 1.9em + bold + text-shadow). On stylise le strong directement
 * pour ne pas avoir à modifier le contenu BDD (migration 019 garde son
 * pattern <p><strong>Title</strong></p>). */
.page-client .square-block p:first-child {
    margin: 0 0 14px 0;
}

.page-client .square-block p:first-child strong {
    display: block;
    font-size: 1.5em;
    font-weight: 700;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
    margin: 0;
    color: #fff;
    line-height: 1.15;
}

/* Paragraphes suivants = équivalent .box-desc de l'index canon
 * (font-size 0.9em + opacity 0.85 + line-height 1.6). */
.page-client .square-block p:not(:first-child) {
    font-size: 0.92rem;
    line-height: 1.6;
    margin: 0;
    color: #fff;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
}

/* Fallback : si une box utilise <strong> hors <p>, on le style aussi */
.page-client .square-block > strong {
    display: block;
    font-size: 1.5em;
    font-weight: 700;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
    margin-bottom: 12px;
    color: #fff;
}

@media (max-width: 768px) {
    .page-blog .main-title,
    .page-faq .main-title,
    .page-client .main-title {
        margin-top: 70px;
        font-size: 1.8rem;
    }
}

.square-block a {
    color: #009FCB;
    text-decoration: underline;
    font-weight: 600;
}

/* L'ancienne popup #cookie-popup a été supprimée sprint-05 C5
 * (remplacée par #cookie-banner dans assets/css/cookie-banner.css sprint-03). */

/* ---- MOBILE ---- */
@media(max-width: 768px){

    body {
        background-attachment: scroll;
        background-size: auto, cover !important;
        animation: none !important;
    }

    .top-bar {
        justify-content: center;
        flex-wrap: wrap;
        padding: 8px;
    }

    .main-title {
        font-size: 2.8em;
        margin-top: 100px;
    }

    .subtitle { font-size: 1.2em; }

    .square-block {
        width: 90%;
        height: auto;
    }

    .bottom-bar { font-size: 0.8em; }
}

/* === Page-specific tweaks (no inline styles) === */
.main-title.main-title-legal {
  margin-top: 160px;
}

.content-blocks.legal-content {
  margin-top: 30px;
  margin-bottom: 120px;
}

.content-blocks.construction-content {
  margin-top: 30px;
  margin-bottom: 6px;
}

/* --- Per-page background override (construction pages) --- */
body.page-legal {
  background-image: url('assets/img/background_legal.jpg');
}
@supports (background-image: url('assets/img/background_legal.webp')) {
  body.page-legal { background-image: url('assets/img/background_legal.webp'); }
}
@supports (background-image: url('assets/img/background_legal.avif')) {
  body.page-legal { background-image: url('assets/img/background_legal.avif'); }
}

/* Immeubles de bureaux (sprint-23) — fond dédié (© Arnaud Colin). */
body.page-immeubles-bureaux {
  background-image: url('assets/img/background_immeubles-bureaux.jpg');
}
@supports (background-image: url('assets/img/background_immeubles-bureaux.webp')) {
  body.page-immeubles-bureaux { background-image: url('assets/img/background_immeubles-bureaux.webp'); }
}
@supports (background-image: url('assets/img/background_immeubles-bureaux.avif')) {
  body.page-immeubles-bureaux { background-image: url('assets/img/background_immeubles-bureaux.avif'); }
}

/* Note : les backgrounds des autres pages construction (faq, blog, syndic,
 * property, about, etc.) sont gérés par layout-a.css ou layout-b.css via
 * un pseudo-element ::before (pattern image-set). Ne pas ajouter de
 * body.page-* { background-image } ici — c'est inefficace, car layout-*.css
 * fait `body.construction-page { background: none !important }` puis sert
 * l'image via ::before. */

/* ---- LANDING BOXES ---- */
/* ---- LOGOS PARTENAIRES (sous la devise) ---- */
.partner-row {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 20px;
    margin: 8px auto 0;
    flex-wrap: wrap;
}

/* ---- LANDING LAYOUT (boîtes uniquement) ---- */
.landing-layout {
    display: flex;
    justify-content: center;
    max-width: 1200px;
    margin: 14px auto 0;
    padding: 0 24px 20px;
}

.partner-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    /* sprint-20 (retour Arnaud) : 3 boîtes de MÊME taille ; chaque logo REMPLIT sa
     * boîte (object-fit + padding minime). Hauteur 54 ≈ inchangée (le titre ne bouge
     * quasiment pas), mais les logos passent de 36→~46px = nettement plus grands. */
    box-sizing: border-box;
    width: 132px;
    height: 54px;
    padding: 4px 8px;
    /* sprint-20 (retour Arnaud) : au REPOS, les logos flottent sur la photo (fond
     * transparent, « le plus transparent possible »). Suppose des logos foncés/
     * colorés lisibles sur la photo claire (CC, GSPL maroon, Lux Confederation
     * version texte FONCÉ). */
    background: transparent;
    border: 1px solid transparent;
    box-shadow: none;
    border-radius: 0;  /* sprint-06 itér. 15 : carré pur (cf. D29). */
    transition: background 0.25s, backdrop-filter 0.25s, border-color 0.25s, box-shadow 0.25s;
    text-decoration: none;
}

/* ROLLOVER (retour Arnaud) : PAS de blanc plein — « le blanc casse tout ». On met
 * le logo en exergue avec un panneau TRANSLUCIDE dépoli (verre givré) : le flou
 * masque l'eau derrière → le logo ressort, tout en laissant transparaître le fond. */
.partner-logo:hover {
    background: rgba(255, 255, 255, 0.30);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-color: rgba(255, 255, 255, 0.45);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.28);
}

/* Chaque logo REMPLIT sa boîte (object-fit:contain garde les proportions).
 * Au REPOS : pas de carte, mais un léger HALO clair + ombre portée (filter sur
 * l'IMG → épouse la forme du logo, ce n'est PAS un carré) pour décoller les logos
 * de l'eau (retour Arnaud : « noyés dans l'eau »). */
.partner-logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    /* Halo RENFORCÉ — variante « B », choisie par Arnaud sur planche comparative
     * (sprint-21, 2026-07-27). Le halo de 2px du sprint-20 ne décollait pas assez
     * les logos des roseaux de la photo. Trois couches : un liseré net (4px) qui
     * détoure, une diffusion large (8px) qui crée le halo, une ombre portée qui
     * pose le logo. Valeurs consignées ici ET dans DECISIONS.md D86 — l'arbitrage
     * précédent n'avait été noté que par son intention, d'où sa perte. */
    filter:
        drop-shadow(0 0 4px rgba(255, 255, 255, 1))
        drop-shadow(0 0 8px rgba(255, 255, 255, 0.7))
        drop-shadow(0 2px 4px rgba(0, 0, 0, 0.55));
}

/* GSPL (retour Arnaud) : logo au MAX, jusqu'au bord de la ligne (padding réduit). */
.partner-logo-gspl { padding: 1px 4px; }

/* Deux boîtes côte à côte */
.landing-boxes {
    display: flex;
    gap: 32px;
    flex-wrap: wrap;
    justify-content: center;
    flex: 1;
    max-width: 1060px;
}

.landing-box {
    flex: 1 1 380px;
    max-width: 500px;
    background: var(--card-bg, rgba(0, 0, 0, 0.28));
    backdrop-filter: var(--card-blur, blur(2px));
    -webkit-backdrop-filter: var(--card-blur, blur(2px));
    border: var(--card-border, 1px solid rgba(255, 255, 255, 0.15));
    border-radius: 0;  /* sprint-05 iter 3 : carré pur Arnaud */
    padding: 18px 32px;
    color: #fff;
    text-decoration: none;
    display: flex;
    flex-direction: column;
    gap: 10px;
    text-align: center;
    transition: background 0.3s, transform 0.25s;
}

.landing-box:hover {
    background: rgba(0, 0, 0, 0.45);
    transform: translateY(-4px);
}

.box-title {
    /* sprint-06 retour Arnaud : harmonisation taille box-left / box-right.
     * Avant : box-left 1.9em + override box-right 1.5em (asymétrique).
     * Après : 1.5em uniforme sur toutes les .landing-box (index + blog
     * sprint-06 hérite naturellement). */
    font-size: 1.5em;
    font-weight: 700;
    margin: 0;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.box-desc {
    font-size: 0.9em;
    /* sprint-24 (retour Arnaud) : BLANC (plus de gris/opacity) + ombre pour ressortir. */
    line-height: 1.6;
    margin: 0;
    color: #fff;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
}

.box-more {
    align-self: flex-end;
    font-size: 0.82em;
    /* C15b sprint-05 — contraste a11y : rgba(255,255,255,0.60) était insuffisant
     * sur fond landing-box rgba(0,0,0,0.28-0.45) au-dessus du background photo
     * (Lighthouse mobile "Contrast insufficient"). Passage à 0.92 préserve la
     * discrétion visuelle tout en passant WCAG AA. */
    color: rgba(255, 255, 255, 0.92);
    margin-top: auto;
    padding-top: 10px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    width: 100%;
    text-align: right;
    transition: color 0.2s;
}

.landing-box:hover .box-more {
    color: #fff;
}

@media (max-width: 768px) {
    .landing-layout {
        flex-direction: column;
        align-items: center;
        padding: 0 16px 80px;
        gap: 16px;
    }

    .partner-row {
        gap: 12px;
    }

    .landing-boxes {
        flex-direction: column;
        align-items: stretch;
        gap: 16px;
    }

    .landing-box {
        max-width: 100%;
        flex: none;
        padding: 16px 20px;
    }

    .box-more {
        margin-top: 8px;
        padding-top: 8px;
    }

    .box-title {
        font-size: 1.5em;
    }

    .box-desc {
        font-size: 0.85em;
        line-height: 1.4;
    }
}

/* ============================================================
   PAGE BLOG — tuile style landing + centrage vertical du bloc
   ============================================================ */
/* Sprint-05 + sprint-06 itér. 8 : restauration du centring sur body
 * (le main n'est plus fixed sauf pour page-property — refonte limitée). */
body.construction-page.page-blog {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

body.construction-page.page-blog .main-title {
    margin-top: 0 !important;
    margin-bottom: 24px;
    text-align: center;
}

body.construction-page.page-blog .content-blocks.construction-content {
    width: 92%;
    max-width: 800px;
    margin: 0 auto;
    padding: 0;
}

/* Note : ces règles legacy sont override plus bas par la refonte Blog
 * sprint-05 (background: transparent + grille de cards landing-box style).
 * Conservées pour fallback si le bloc plus loin échoue, mais inactives
 * en pratique grâce aux !important plus loin. */
body.construction-page.page-blog .square-block {
    background: var(--card-bg, rgba(0, 0, 0, 0.28));
    backdrop-filter: var(--card-blur, blur(3px));
    -webkit-backdrop-filter: var(--card-blur, blur(3px));
    border: var(--card-border, 1px solid rgba(255, 255, 255, 0.15));
    border-radius: var(--card-radius, 0);  /* sprint-06 retour Arnaud : fallback 0 (cf. D29) */
    padding: 36px 48px;
    text-align: center;
    transition: var(--card-transition, background 0.3s, transform 0.25s);
}

body.construction-page.page-blog .square-block:hover {
    background: var(--card-bg-hover, rgba(255, 255, 255, 0.18)) !important;
    transform: translateY(-3px);
}

@media (max-width: 768px) {
    body.construction-page.page-blog .square-block {
        padding: 24px 24px !important;
    }
    body.construction-page.page-blog .main-title {
        font-size: 2rem;
    }
}

/* ============================================================
   PAGE BLOG — typographie alignée sur les tuiles landing index
   ============================================================ */
body.construction-page.page-blog .square-block,
body.construction-page.page-blog .square-block p,
body.construction-page.page-blog .square-block li {
    font-size: 0.95em;
    line-height: 1.6;
    opacity: 0.92;
    color: #fff;
}

body.construction-page.page-blog .square-block p {
    margin: 0 0 14px 0;
}

body.construction-page.page-blog .square-block strong {
    font-weight: 700;
    opacity: 1;
}

/* ============================================================
   FAQ + Blog — refonte "pro" sprint-05 C-PRO-FAQ-BLOG
   Tuiles individuelles aérées, border-radius 8px (subtil moderne),
   alignées sur le canon .landing-box index mais plus carrées.
   ============================================================ */

/* --- FAQ intro centrée au-dessus de la grille --- */
.faq-intro-wrap {
    max-width: 880px;
    margin: 0 auto 24px;
    padding: 16px 22px;
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 0;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    text-align: center;
    color: #fff;
    line-height: 1.5;
}
.faq-intro-wrap p { margin: 0; }

/* --- FAQ grille responsive de cards --- */
.faq-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 16px;
    max-width: 1100px;
    margin: 0 auto 32px;
    padding: 0 16px;
}

/* FAQ : boîte alignée sur le CANON de l'accueil (.landing-box) — fond 0.28,
   flou, bordure, survol 0.35 (assombrit, ne blanchit pas). Sprint-24. */
.faq-card {
    /* sprint-26 (TD-25-5, retour Arnaud ×2) : le `backdrop-filter` NE floute PAS ici —
       le <main> des pages construction porte un `mask` (fondu au scroll) qui BLOQUE
       backdrop-filter (la photo posée dans main::before n'y change rien). On repasse au
       VRAI verre dépoli DÉJÀ VALIDÉ sur les cartes KB (ab818dc) : une COPIE de la photo
       FAQ dans ::before, alignée sur le fond fixe (background-attachment:fixed), floutée
       par filter:blur (que le mask NE bloque PAS) ; teinte canon 0.28/0.45 via ::after.
       Le backdrop-filter (neutralisé) est conservé UNIQUEMENT pour créer le contexte
       d'empilement qui garde les pseudos z-index négatifs À L'INTÉRIEUR de la carte. */
    position: relative;
    background: transparent;   /* la teinte vient de ::after, pas du fond de carte */
    border: var(--card-border, 1px solid rgba(255, 255, 255, 0.15));
    border-radius: 0;
    overflow: hidden;
    transition: background 0.3s, transform 0.25s;
    backdrop-filter: var(--card-blur, blur(2px));
    -webkit-backdrop-filter: var(--card-blur, blur(2px));
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.9), 0 2px 12px rgba(0,0,0,.55);
}
.faq-card::before {   /* copie floutée de la photo FAQ, alignée sur body::before */
    content: "";
    position: absolute;
    inset: -24px;      /* déborde : le halo du flou reste hors du clip de la carte */
    z-index: -2;
    background-image: image-set(
        url("assets/img/background_faq.avif") type("image/avif"),
        url("assets/img/background_faq.webp") type("image/webp"),
        url("assets/img/background_faq.jpg")  type("image/jpeg"));
    background-attachment: fixed;
    background-position: center;
    background-size: cover;
    filter: blur(7px);
    pointer-events: none;
}
.faq-card::after {    /* teinte = canon .landing-box (0.28, survol 0.45) */
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: rgba(0, 0, 0, 0.28);
    transition: background 0.3s;
    pointer-events: none;
}
.faq-card:hover {
    transform: translateY(-3px);
}
.faq-card:hover::after {
    background: rgba(0, 0, 0, 0.45);
}

.faq-card summary {
    list-style: none;
    cursor: pointer;
    padding: 18px 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.faq-card summary::-webkit-details-marker { display: none; }
.faq-card summary::marker { display: none; }

.faq-card .faq-q-text {
    flex: 1;
    margin: 0;
    /* sprint-25 (retour Arnaud « le gras est insupportable ») : gras RETIRÉ →
       poids NORMAL (400), taille 1.05em. Les questions se lisent en texte courant. */
    font-size: 1.05em;
    font-weight: 400;
    line-height: 1.35;
    color: #fff;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.faq-card .faq-q-marker {
    flex-shrink: 0;
    font-size: 1.6em;
    color: #f0e3a4;  /* accent jaune marque */
    font-weight: 700;
    line-height: 1;
    transition: transform 0.2s ease-out;
    width: 24px;
    text-align: center;
}
.faq-card[open] .faq-q-marker {
    transform: rotate(45deg);  /* + devient × */
}

.faq-card .faq-answer {
    padding: 14px 20px 20px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    font-size: 0.95em;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.92);
}
.faq-card .faq-answer p { margin: 0 0 10px 0; }
.faq-card .faq-answer p:last-child { margin-bottom: 0; }

/* Liens dans la FAQ : forcer une couleur lisible sur fond sombre et la
 * conserver après visite — sinon le navigateur applique un :visited violet
 * presque illisible sur la card semi-transparente. */
.faq-card .faq-answer a,
.faq-card .faq-answer a:link,
.faq-card .faq-answer a:visited {
    color: #4FC3E5;
    text-decoration: underline;
    font-weight: 600;
}
.faq-card .faq-answer a:hover,
.faq-card .faq-answer a:focus {
    color: #ffffff;
    text-decoration: underline;
}

@media (max-width: 640px) {
    .faq-grid {
        grid-template-columns: 1fr;
        gap: 12px;
        padding: 0 12px;
    }
    .faq-card summary { padding: 14px 16px; }
    .faq-card .faq-answer { padding: 12px 16px 16px; }
}

/* --- BLOG : transforme la <ul> existante en grille de cards --- */
/* Override des styles legacy ligne 645-657 ci-dessus + 600 hover.
 * SPRINT-06 : sélecteur inactif (blog ne rend plus de .square-block depuis
 * refonte 4 landing-box), conservé pour fallback. */
body.construction-page.page-blog .square-block {
    border-radius: 0 !important;  /* sprint-06 retour Arnaud : coins carrés (cf. D29) */
}

body.construction-page.page-blog .square-block ul {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 16px;
    list-style: none !important;
    padding: 0 !important;
    margin: 24px 0;
    text-align: left;
}

body.construction-page.page-blog .square-block ul li {
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 0;
    padding: 20px;
    margin: 0 !important;
    line-height: 1.55;
    font-size: 0.95em;
    transition: background 0.3s, transform 0.25s;
}

body.construction-page.page-blog .square-block ul li:hover {
    background: rgba(0, 0, 0, 0.6);
    transform: translateY(-3px);
}

body.construction-page.page-blog .square-block ul li strong {
    display: block;
    margin-bottom: 8px;
    font-size: 1.08em;
    font-weight: 700;
    color: #f0e3a4;  /* accent jaune pour titre de card */
    opacity: 1;
}

/* ============================================================
   CTA Devis flottant (sticky bottom-right) — sprint-05
   Visible toujours sur les pages lead-gen (syndic/property/services/
   change/faq/blog). Ne scrolle pas avec la page.
   Iter 2 sprint-05 : taille réduite (retour Arnaud "trop large").
   ============================================================ */
.cta-wrapper.cta-sticky {
    position: fixed;
    bottom: 38px;   /* iter 6 Arnaud : plus bas encore, presque collé au bottombar */
    right: 16px;
    z-index: 999;
    margin: 0;
    padding: 0;
    max-width: none;
    width: auto;
}

.cta-wrapper.cta-sticky .cta-devis {
    display: inline-block;
    padding: 10px 18px;            /* iter 2 : compact (vs 13/22) */
    background: var(--cta-primary-bg, #009FCB);
    color: var(--cta-primary-color, #fff);
    font-size: 0.88em;             /* iter 2 : plus petit (vs 0.95) */
    font-weight: 600;              /* iter 2 : moins bold (vs 700) */
    border-radius: 0;  /* sprint-06 itér. 15 : carré pur (était pill 999px). */
    text-decoration: none;
    transition: background 0.3s, transform 0.2s, box-shadow 0.3s;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.30);
    border: 1px solid rgba(255, 255, 255, 0.15);
}

.cta-wrapper.cta-sticky .cta-devis:hover,
.cta-wrapper.cta-sticky .cta-devis:focus {
    background: var(--cta-primary-bg-hover, #61C452);
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.40);
}

.cta-wrapper.cta-sticky .cta-devis:focus-visible {
    outline: 3px solid #f0e3a4;
    outline-offset: 3px;
}

@media (min-width: 768px) {
    .cta-wrapper.cta-sticky {
        bottom: 44px;  /* iter 6 Arnaud : plus bas encore */
        right: 24px;
    }
    .cta-wrapper.cta-sticky .cta-devis {
        padding: 11px 20px;
        font-size: 0.92em;
        box-shadow: 0 5px 16px rgba(0, 0, 0, 0.35);
    }
}

/* TD-16-1 (sprint-20) : sur mobile, le bandeau cookies (#cookie-banner, bottom:0,
 * pleine largeur, z-index:1000) recouvre le CTA sticky (.cta-sticky, bottom:38px,
 * z-index:999) au premier passage — tant que l'utilisateur n'a pas choisi. On
 * masque le sticky pendant que le bandeau est affiché : rgpd.js pose l'attribut
 * [hidden] sur #cookie-banner dès qu'un consentement est enregistré, ce qui
 * réaffiche le CTA. Sélecteur :has() (dégradation propre si non supporté). */
@media (max-width: 768px) {
    body:has(#cookie-banner:not([hidden])) .cta-wrapper.cta-sticky {
        display: none;
    }
}

/* TD-19-2 (sprint-20) : césure des composés longs (DE/LB, ex.
 * « Wohnungseigentümergemeinschaft ») sur les titres des pages construction et
 * légale + les cartes .square-block — même idiome que kb.css (TD-19-1). Évite le
 * débordement horizontal mobile 375px sur ?page=syndic (+151px DE) et ?page=legal
 * (+10px). overflow-wrap et hyphens sont hérités → couvrent aussi le contenu. */
.main-title-construction,
.main-title-legal,
.square-block {
    overflow-wrap: break-word;
    hyphens: auto;
}

/* ============================================================
   BLOG — Option 3 (sprint-05 iter 5) : feature-list horizontale
   Pattern Apple/Wikipedia : 4 rows empilées, icône emoji à gauche +
   titre/desc à droite. Cohérent avec contenu placeholder court
   (vs cards landing-box qui demandaient des descriptions longues).
   Cause profonde : le contenu BDD est court (4 bullets de 3-4 mots),
   ne porte pas le pattern "grosse card landing-box". Feature-list
   marche très bien avec contenu court.
   ============================================================ */

/* Wrapper devient transparent : juste un container pour la liste */
body.construction-page.page-blog .square-block {
    background: transparent !important;
    border: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
    padding: 0 !important;
    max-width: 1060px;
}

/* Les <p> introductifs/conclusifs restent centrés et lisibles */
body.construction-page.page-blog .square-block > p {
    color: #fff;
    text-align: center;
    line-height: 1.55;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
    padding: 0 16px;
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
}

/* Liste = colonne unique, gap entre rows */
body.construction-page.page-blog .square-block ul {
    display: flex !important;
    flex-direction: column;
    gap: 14px;
    list-style: none !important;
    padding: 0 !important;
    margin: 28px auto !important;
    max-width: 720px;
    text-align: left;
}

/* Row simple inline-flow (vs grid iter 5 qui cassait textnode après <strong>).
 * Le HTML BDD natif est <li><strong>Titre</strong> description textnode</li>
 * — display:inline garde tout en flow naturel, wrap propre en fin de ligne. */
body.construction-page.page-blog .square-block ul li {
    background: rgba(0, 0, 0, 0.32);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 0;
    padding: 16px 22px;
    margin: 0 !important;
    color: #fff;
    line-height: 1.55;
    transition: background 0.3s, transform 0.2s;
    font-size: 1em;
    text-align: left;
}

body.construction-page.page-blog .square-block ul li:hover {
    background: rgba(0, 0, 0, 0.48);
    transform: translateX(4px);
}

/* Icône inline-block, large fixed width pour alignement vertical des titres */
body.construction-page.page-blog .square-block ul li::before {
    display: inline-block;
    vertical-align: middle;
    width: 40px;
    font-size: 1.8em;
    line-height: 1;
    margin-right: 12px;
    text-align: center;
    opacity: 0.9;
}

body.construction-page.page-blog .square-block ul li:nth-child(1)::before { content: "📜"; }
body.construction-page.page-blog .square-block ul li:nth-child(2)::before { content: "💡"; }
body.construction-page.page-blog .square-block ul li:nth-child(3)::before { content: "📚"; }
body.construction-page.page-blog .square-block ul li:nth-child(4)::before { content: "📰"; }

/* Titre <strong> inline (PAS block, sinon le textnode passe à la ligne suivante
 * et perd l'alignement avec l'icône). Le wrap naturel se fait en fin de phrase
 * si l'écran est étroit. */
body.construction-page.page-blog .square-block ul li strong {
    display: inline;
    font-size: 1.1em;
    font-weight: 700;
    color: #ffffff;
    line-height: 1.4;
    opacity: 1;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
    margin-right: 4px;
}

/* Mobile : icône plus petite, padding compressé */
@media (max-width: 500px) {
    body.construction-page.page-blog .square-block ul li {
        padding: 12px 14px;
    }
    body.construction-page.page-blog .square-block ul li::before {
        width: 32px;
        font-size: 1.4em;
        margin-right: 10px;
    }
    body.construction-page.page-blog .square-block ul li strong {
        font-size: 1em;
    }
}

/* ============================================================
   Body padding-bottom augmenté pour gérer bottombar wrap (3-4 items)
   ============================================================ */
body {
    /* Override du padding-bottom du body global (ligne 41 = 48px).
     * Le bottombar a maintenant 4 entries (legal · privacy · photo credit)
     * qui peuvent wrap sur 2 lignes en mobile → 80px sécurise. */
    padding-bottom: calc(80px + env(safe-area-inset-bottom));
}

/* ============================================================
   BLOG — sprint-06 retour Arnaud : 4 cards landing-box pattern
   Le contenu BDD long-form (under_blog_body avec <ul>) reste mais
   n'est plus rendu (construction.php cas blog réécrit avec 4
   landing-box hardcodées + intro/outro). Le CSS feature-list iter 5
   ci-dessus (sélecteur .page-blog .square-block) devient inactif.

   Layout : .landing-layout (wrapper centré 1200px max) + .landing-boxes
   (flex-wrap, 1060px max) + 4 × .landing-box (flex 380px+, max 500px).
   Sur desktop ≥ 768px : grid naturel 2x2. Sur mobile : 1 col × 4 rows.
   ============================================================ */

/* Sous-titre blog EN HAUT avec fond — retour Arnaud sprint-06 itér. 3.
 * Clone du pattern .construction-subtitle (layout-b.css ligne 17-31) car
 * blog charge layout-a.css et non layout-b.css. Style inliné ici pour
 * être disponible sur blog. */
.blog-subtitle {
    max-width: calc(980px - 36px);
    width: calc(100% - 36px);
    margin: 10px auto 18px auto;
    padding: 10px 16px;
    border-radius: 0;  /* coins carrés sprint-05 D29 */
    box-sizing: border-box;
    background: rgba(0, 0, 0, 0.58);
    text-align: center;
    color: #ffffff;
    font-size: 1.15rem;
    font-weight: 500;
    line-height: 1.4;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.70);
}

.blog-subtitle p {
    margin: 0;
    text-align: center;
}

/* Fix retour Arnaud sprint-06 itér. 3 : "le bouton est trop bas seulement
 * sur le blog". Cause = body.page-blog est en flex column min-height 100vh
 * (centring vertical demandé), le contenu blog tient en 1 viewport, donc le
 * bottombar est PILE en bas du viewport. Le CTA fixed bottom:44px chevauche
 * le bottombar.
 * Fix : remonter le CTA spécifiquement sur blog pour passer au-dessus du
 * bottombar (~50-60px de haut). */
body.construction-page.page-blog .cta-wrapper.cta-sticky {
    bottom: 88px;
}

@media (min-width: 768px) {
    body.construction-page.page-blog .cta-wrapper.cta-sticky {
        bottom: 92px;
    }
}

/* Centering vertical de .page-blog body conservé (legacy sprint-05 ligne 581
 * fait justify-content: center). Arnaud retour sprint-06 : "centre tout le
 * bloc en hauteur". On ne touche donc PAS au body display:flex column +
 * justify-content: center hérité.
 *
 * Le wrapper .landing-layout est centré horizontalement par défaut. */
.blog-landing-layout {
    margin-top: 0;
}

/* Les blog-landing-box partagent les styles .landing-box natifs.
 * On ajoute juste un text-align centré sur la desc (vs flex-end naturel). */
.blog-landing-box .box-desc {
    text-align: center;
}

/* ============================================================
   FADE-OUT DU CONTENT SOUS TOPBAR / BOTTOMBAR — sprint-06 retour Arnaud
   « la photo doit toujours être visible et les zones sous la top et
     bottom barres aussi, le texte doit disparaître qd il passe sous
     la top et bottom bar. »

   Itér. 8 : application LOCALISÉE sur body.page-property uniquement
   (Arnaud "essayer de finaliser Administration de biens en premier
   pour voir si on arrive à qqchose"). Les autres pages restent en
   layout standard (main dans le flow, pas de mask).

   Sur page-property uniquement :
   - <main> position:fixed plein viewport → scroll interne, le mask
     gradient s'applique alors viewport-relative.
   - 80px fade-out top + 72px fade-out bottom (zones plus larges que
     les bars 56/52 — Arnaud "le texte disparait derrière la top bar
     mais un peu trop tard", on commence le fade plus tôt).
   - padding-top:72px + padding-bottom:64px pour démarrer le content
     sous la topbar et finir au-dessus de la bottombar.

   Le CTA "Devis gratuit" est sorti de <main> dans construction.php
   (déjà fait itér. 7), donc pas masqué.
   ============================================================ */
body.construction-page main {
    position: fixed;
    top: 0;
    left: 0;
    /* Itér. 12 : explicit width/height + mask en % pour résoudre le bug
     * fade bottom (le mask ne se calait pas correctement avec top:0 bottom:0
     * + overflow-y:auto — la box scrollable interfère avec mask-size:auto).
     * Avec height:100vh fixe, le mask % = 100vh garantit. */
    width: 100%;
    height: 100vh;
    overflow-y: auto;
    overflow-x: hidden;

    /* sprint-25 : le fondu (mask) est REMIS (retour Arnaud). Le mask isole main
     * (« backdrop-root ») et empêcherait les boîtes de flouter body::before ; on
     * résout en posant la MÊME photo À L'INTÉRIEUR de main (main::before, dans
     * layout-b.css) → les boîtes floutent CE calque, et le fondu du texte au scroll
     * est conservé. Le fondu ET le blur cohabitent.
     * sprint-26 (retour Arnaud) : fondu HAUT et BAS désormais SYMÉTRIQUES (72px de
     * chaque côté) → le texte s'efface sous la top bar ET sous la bottom bar de la
     * même façon (le bas ne se déclenchait pas car padding-bottom:150px parquait le
     * contenu au-dessus de l'ancienne rampe basse ; on ramène le padding pour que le
     * contenu traverse bien la rampe et disparaisse sous la barre). Les barres
     * restent nettes (aucun scrim/dégradé) : c'est le TEXTE qui se fond, pas la barre. */
    /* sprint-26 (retour Arnaud) : ZONE PLATE totalement transparente = hauteur de la
       barre (≈44px), PUIS fondu sur 44px. Ainsi le texte est COMPLÈTEMENT effacé
       DERRIÈRE la barre (et non ~50% visible au ras de la barre comme avec un simple
       ramp depuis 0), puis réapparaît en fondu juste en dessous. Symétrique haut/bas. */
    -webkit-mask-image: linear-gradient(
        to bottom,
        transparent 0,
        transparent 44px,
        rgba(0, 0, 0, 1) 88px,
        rgba(0, 0, 0, 1) calc(100% - 88px),
        transparent calc(100% - 44px),
        transparent 100%
    );
    mask-image: linear-gradient(
        to bottom,
        transparent 0,
        transparent 44px,
        rgba(0, 0, 0, 1) 88px,
        rgba(0, 0, 0, 1) calc(100% - 88px),
        transparent calc(100% - 44px),
        transparent 100%
    );
    padding-top: 0;
    padding-bottom: 72px;
}

/* Itér. 10 : éclaircir la photo de fond des pages services (retour
 * Arnaud "on voit pas bien le texte"). Override de l'overlay assombri
 * body.construction-page::after rgba(0,0,0,0.25) → rgba(0,0,0,0.10)
 * sur page-property pour test (à étendre à page-syndic + page-services
 * si Arnaud valide — mêmes image pfaffenthal partagée).
 * Itér. 13 : Arnaud "garder pfaffenthal, juste plus claire". Push
 * encore plus : overlay 0.10 → 0.05 + brightness(1.18) sur la photo
 * elle-même via ::before.
 * Itér. 14 : retour Arnaud "ça va pas, quand on éclaircit on voit
 * encore moins bien". Diagnostic : photo claire + texte blanc =
 * contraste qui s'effondre sur les zones lumineuses (arbres dorés,
 * ciel). On inverse l'approche : photo modérément claire (overlay
 * 0.22, brightness retiré) + halo noir text-shadow derrière chaque
 * élément texte pour qu'il ressorte indépendamment de la zone de
 * la photo. */
body.construction-page.page-property::after {
    background: rgba(0, 0, 0, 0.22);
}

body.construction-page.page-property::before {
    filter: none;
}

body.construction-page.page-property .main-title,
body.construction-page.page-property h1,
body.construction-page.page-property h2,
body.construction-page.page-property h3,
body.construction-page.page-property h4,
body.construction-page.page-property p,
body.construction-page.page-property li,
body.construction-page.page-property strong,
body.construction-page.page-property em {
    text-shadow:
        0 2px 6px rgba(0, 0, 0, 0.95),
        0 0 14px rgba(0, 0, 0, 0.75),
        0 0 2px rgba(0, 0, 0, 1);
}

/* ============================================================================
 * Maillage interne « Voir aussi » (sprint-vitrine-17, Lot B)
 * Bloc de liens internes contextuels rendu par construction.php après le
 * contenu (pages layout-B + familles Synila). Réseau documentaire pour Google
 * + IA. Reprend la charte : cartes carrées (--card-radius 0), fond sombre
 * translucide, hover cyan CTA. Défini dans style.css (toujours chargé) pour un
 * rendu identique sur layout-b.css comme sur synila.css.
 * ==========================================================================*/
.related-links {
    max-width: 900px;
    margin: 2.5rem auto 0.5rem;
    padding: 1.6rem 1rem 0;
    /* sprint-20 (retour Arnaud) : « Voir aussi » pas assez visible → séparateur
     * plus marqué (2px accent cyan translucide) au lieu du filet discret. */
    border-top: 2px solid rgba(56, 189, 214, 0.45);
}
.related-links-title {
    /* sprint-20 (retour Arnaud) : titre plus grand + pleine opacité pour que la
     * section « Voir aussi » ressorte (avant : 0.8rem / opacity 0.72 → noyée). */
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    opacity: 0.96;
    margin-bottom: 1.05rem;
    text-align: center;
    /* Le titre est posé sur la photo (section sans fond) → ombre pour rester
     * lisible sur les zones claires du visuel (retour Arnaud : « pas assez visible »). */
    text-shadow: 0 1px 8px rgba(0, 0, 0, 0.75);
}
.related-links-list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem;
    padding: 0;
    margin: 0;
}
.related-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 0.9rem;
    color: #fff;
    text-decoration: none;
    background: var(--card-bg);
    border: var(--card-border);
    border-radius: var(--card-radius);
    backdrop-filter: var(--card-blur);
    -webkit-backdrop-filter: var(--card-blur);
    transition: var(--card-transition), color 0.25s, border-color 0.25s;
    font-size: 0.95rem;
    line-height: 1.2;
}
.related-link:hover,
.related-link:focus-visible {
    background: var(--card-bg-hover);
    border-color: var(--cta-primary-bg);
    color: #fff;
    transform: translateY(-2px);
}
.related-link-arrow {
    color: var(--cta-primary-bg);
    font-weight: 700;
    transition: transform 0.2s;
}
.related-link:hover .related-link-arrow,
.related-link:focus-visible .related-link-arrow {
    transform: translateX(3px);
}
@media (max-width: 480px) {
    .related-links-list { flex-direction: column; align-items: stretch; }
    .related-link { justify-content: space-between; }
}

/* ============================================================================
 * Bloc « En résumé » (sprint-vitrine-17, Lot E)
 * Sommaire extractif en tête des guides longs (pilote : ?page=change). Reprend
 * la charte carrée/sombre. Encadré discret (accent gauche cyan) au-dessus du
 * corps de l'article — n'ajoute aucune information, surface les étapes visibles.
 * ==========================================================================*/
.page-summary {
    background: var(--card-bg);
    border: var(--card-border);
    border-left: 3px solid var(--cta-primary-bg);
    border-radius: var(--card-radius);
    backdrop-filter: var(--card-blur);
    -webkit-backdrop-filter: var(--card-blur);
    padding: 1rem 1.25rem;
    margin: 0 0 1.75rem;
}
.page-summary-title {
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.85;
    margin: 0 0 0.6rem;
}
.page-summary-list {
    margin: 0;
    padding-left: 1.2rem;
}
.page-summary-list li {
    margin: 0.3rem 0;
    line-height: 1.4;
}
/* « En bref » (sprint-27, Lot A) — étapes clés visibles/extractibles en tête d'article.
   Réutilise la boîte .page-summary (fond + override canon anti-backdrop-filter). Le chip
   reprend .page-summary-title ; le titre = intitulé HowTo (contient la requête reine) ;
   la liste ordonnée porte des numéros visibles (sémantique « les 5 étapes »). */
.kb-inbrief-label {
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.85;
    margin: 0 0 0.4rem;
}
.kb-inbrief-title {
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.3;
    margin: 0 0 0.7rem;
}
.kb-inbrief-steps {
    margin: 0;
    padding-left: 1.4rem;
    list-style: decimal;
}
.kb-inbrief-steps li {
    margin: 0.35rem 0;
    line-height: 1.4;
    padding-left: 0.2rem;
}
