/* =====================================================================
   WebApp — presentations de sections

   Chargee apres identity.css. Un traitement DIFFERENT par section, a
   dessein : quatre grilles de cartes identiques empilees se lisent comme un
   tableau, pas comme un discours. Chaque section a donc sa forme propre.

     .statband   bandeau de chiffres, separes par un filet
     .bento      mosaique, la premiere cellule pese deux colonnes
     .tilerail   tuiles a numero en filigrane, rail defilant sur telephone
     .quoterail  rail de citations

   Tout est ecrit en proprietes LOGIQUES : l'arabe se retourne sans regle
   dediee.
   ===================================================================== */

/* ------------------------------------------------- bandeau de chiffres */
.statband {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0;
    border: 1px solid var(--line);
    border-radius: var(--r-lg, 14px);
    background: var(--surface);
    overflow: hidden;
}
.statband__item {
    padding: 22px 20px;
    border-inline-start: 1px solid var(--line);
}
/* Le premier n'a pas de filet : un filet contre la bordure du cadre fait
   une double ligne de 2 px, visible et sale. */
.statband__item:first-child { border-inline-start: 0; }

/* --- L'ICONE DE CHAQUE CASE ------------------------------------------
   Quatre cases identiques separees par un filet se parcourent sans que
   l'oeil s'arrete : rien ne distinguait « ce que ca coute » de « ce qui
   vous appartient ». Le pictogramme donne un point d'entree a chacune.

   POURQUOI SI DISCRET. Le heros de la case est le chiffre, en trente
   pixels. Une pastille pleine et coloree lui disputerait le regard ; un
   trace fin sur un fond tres clair le precede sans le concurrencer.

   La couleur vient de la marque et non de l'ambre du chiffre : deux
   accents dans un carre de deux centimetres se neutralisent. */
.statband__ic {
    display: inline-grid;
    place-items: center;
    width: 38px;
    height: 38px;
    margin-bottom: 14px;
    border-radius: var(--r-md, 10px);
    background: var(--brand-050);
    color: var(--brand);
    /* Le degrade du chiffre passe par background-clip sur le texte ; sur
       une icone SVG il faut le trait, pas le fond. */
    -webkit-background-clip: border-box;
            background-clip: border-box;
}
.statband__ic .icon { width: 20px; height: 20px; }

/* Au survol de la case, l'icone s'affirme : le seul retour visuel que la
   bande offrait etait... aucun. */
.statband__item { transition: background .18s ease; }
.statband__item:hover { background: var(--bg-soft); }
.statband__item:hover .statband__ic {
    background: var(--brand);
    color: #fff;
}
@media (prefers-reduced-motion: reduce) {
    .statband__item, .statband__ic { transition: none; }
}

.statband__num {
    font-size: var(--t-2xl);
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    background: var(--grad-amber);
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .statband__num { color: var(--accent); }
}
.statband__lbl {
    margin-top: 6px;
    font-weight: 600;
    font-size: var(--t-sm);
    color: var(--ink);
}
.statband__ctx {
    margin: 8px 0 0;
    font-size: var(--t-sm);
    line-height: 1.5;
    color: var(--muted);
}

/* ---------------------------------------------------------- mosaique */
.bento {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
}
.bento__item {
    position: relative;
    overflow: hidden;            /* borne le filigrane */
    display: flex;
    flex-direction: column;
    padding: 22px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg, 14px);
    color: inherit;
    text-decoration: none;
    transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
/* Lisere de tete, revele au survol. Un pseudo-element plutot qu'une bordure :
   une bordure qui apparait decale le contenu de trois pixels. */
.bento__item::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    height: 3px;
    /* PAS --grad-brand. Ce degrade est fige en vert sombre (0,56,43 vers
       0,105,75) : mesure sur la carte du theme sombre, il plafonne a 2,4:1 et
       demarre a 1,2:1 — autant dire invisible, alors que c'est le seul signal
       de survol de la carte. --brand et --accent, eux, sont redefinis par
       theme et restent lisibles des deux cotes. */
    background: linear-gradient(90deg, var(--brand), var(--accent));
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .28s ease;
}
[dir="rtl"] .bento__item::before { transform-origin: right center; }
.bento__item:hover::before { transform: scaleX(1); }
.bento__item:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
    border-color: var(--accent);
}
/* La cellule de tete : deux colonnes, texte plus grand. */
.bento__item--lead { grid-column: span 2; }
.bento__item--lead .bento__title { font-size: var(--t-xl); }
.bento__item--lead .bento__text  { font-size: var(--t-base); max-width: 46ch; }

/* Le filigrane. C'est l'illustration de la carte : son icone, agrandie et
   attenuee, ancree dans l'angle bas. Elle occupe le vide sans disputer le
   regard au titre, et elle change avec le service puisqu'elle vient du meme
   champ. aria-hidden dans le gabarit. */
/* LE TRACE EST ENTIER, ET C'EST LA REGLE.
   Premiere version : un grand dessin debordant de la carte, borne par
   overflow. A l'ecran, chaque coin montrait un fragment — une moitie de
   panier, deux chevrons coupes en biais — qui se lit comme un defaut
   d'affichage et non comme un ornement. Le numero « 04 » des tuiles
   Solutions, lui, supporte tres bien d'etre rogne : un chiffre tronque reste
   un chiffre, et l'oeil complete. Un dessin, non : il n'a pas de forme
   attendue a laquelle se raccrocher.

   Le trace se pose donc ENTIER dans la bande basse que « en savoir plus »
   laisse libre a sa droite, et il est dimensionne pour cette bande. Plus
   petit, donc moins pale : a 7 % d'opacite il aurait simplement disparu.

   La cellule de tete est un cas a part. Deux fois plus large, avec un texte
   borne a 46 caracteres, elle dispose d'une vraie reserve d'espace et recoit
   le grand format — entier lui aussi. */
.bento__ghost {
    position: absolute;
    inset-block-end: 14px;
    inset-inline-end: 16px;
    color: var(--brand);
    opacity: .14;
    pointer-events: none;
    user-select: none;
    transition: opacity .28s ease, transform .28s ease;
}
.bento__ghost .icon {
    width: 42px; height: 42px;
    /* 1,1 convenait a 116 px ; a 42 px le trait devient un fil et s'efface. */
    stroke-width: 1.4;
}
.bento__item--lead .bento__ghost { inset-block-end: 20px; inset-inline-end: 24px; }
.bento__item--lead .bento__ghost .icon { width: 96px; height: 96px; stroke-width: 1.15; }
.bento__item:hover .bento__ghost { opacity: .22; transform: translateY(-3px); }
[dir="rtl"] .bento__ghost .icon { transform: scaleX(-1); }

.bento__icon {
    position: relative;          /* au-dessus du filigrane */
    display: grid;
    place-items: center;
    width: 46px; height: 46px;
    margin-bottom: 14px;
    border-radius: var(--r-md, 10px);
    background: var(--brand-050);
    color: var(--brand);
    transition: background .22s ease, color .22s ease;
}
.bento__item:hover .bento__icon { background: var(--brand); color: #fff; }
.bento__icon .icon { width: 23px; height: 23px; }
.bento__title { position: relative; font-size: var(--t-lg); margin: 0 0 .35em; line-height: 1.3; }
.bento__text  { position: relative; margin: 0; color: var(--muted); font-size: var(--t-sm); line-height: 1.6; }

/* « En savoir plus ». margin-block-start:auto le colle en bas : c'est ce qui
   remplit la cellule de tete, dont le texte court laissait un grand blanc. Il
   dit aussi que la carte est cliquable, ce que rien n'indiquait. */
.bento__more {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    /* inline-flex ne suffit PAS : dans un conteneur flex en colonne, l'element
       est etire sur toute la largeur par align-items:stretch. Son cadre
       traversait donc la carte de bord a bord et croisait le filigrane. */
    align-self: flex-start;
    margin-block-start: auto;
    /* 24 et non 16 : cette respiration est aussi la bande dans laquelle le
       filigrane se pose, a droite. A 16 px la bande faisait 33 px de haut et
       un trace de 42 mordait la derniere ligne de texte sur les cartes
       courtes. Elargir la respiration coute quelques pixels de hauteur et
       evite de rapetisser le dessin jusqu'a l'insignifiance. */
    padding-block-start: 24px;
    font-family: var(--font-head);
    font-size: var(--t-sm);
    font-weight: 600;
    color: var(--brand);
}
.bento__more .icon {
    width: 15px; height: 15px;
    transition: transform .22s ease;
}
[dir="rtl"] .bento__more .icon { transform: scaleX(-1); }
.bento__item:hover .bento__more .icon { transform: translateX(4px); }
[dir="rtl"] .bento__item:hover .bento__more .icon { transform: scaleX(-1) translateX(4px); }

/* ----------------------------------------------- tuiles a filigrane */
.tilerail {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
}
.tile {
    position: relative;
    overflow: hidden;
    /* flex colonne, et non block : c'est ce qui permet a « en savoir plus »
       d'etre pousse en bas par margin-block-start:auto. */
    display: flex;
    flex-direction: column;
    padding: 24px 22px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg, 14px);
    color: inherit;
    text-decoration: none;
    transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
.tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--accent); }

/* Meme lisere que la mosaique, aux couleurs de la tuile : accent d'abord,
   marque ensuite — l'inverse des services, dont la pastille est verte. */
.tile::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--accent), var(--brand));
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .28s ease;
}
[dir="rtl"] .tile::before { transform-origin: right center; }
.tile:hover::before { transform: scaleX(1); }

/* Le numero en filigrane. aria-hidden dans le HTML : il ne doit pas etre lu,
   c'est un reperage, pas une information.
   Reduit de 5,2 a 4,2 rem : il partage maintenant la carte avec le filigrane
   de l'icone, dans l'angle oppose. A sa taille d'origine les deux se
   rejoignaient au milieu. */
.tile__ghost {
    position: absolute;
    inset-block-start: -4px;
    inset-inline-end: 10px;
    font-size: var(--t-numeral);
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--brand);
    opacity: .07;
    pointer-events: none;
    user-select: none;
}
/* L'illustration : l'icone de la tuile en grand, dans l'angle BAS-FIN.
   Premiere tentative : angle bas-DEBUT, a l'oppose du numero. Mesure a
   l'ecran : elle passait derriere le texte ET derriere « en savoir plus » sur
   les sept tuiles — c'est le bord ou le texte commence. Cote fin, le texte
   n'atteint le bord qu'au milieu des lignes, jamais en bas.
   Le numero reste en haut-fin : meme colonne, mais 140 px plus haut, les deux
   ne se rencontrent pas. */
/* Entier, comme celui des services — voir la note sur .bento__ghost. Le
   numero au-dessus reste rogne, et c'est voulu : les deux ne suivent pas la
   meme regle parce qu'ils ne sont pas de meme nature. */
.tile__art {
    position: absolute;
    inset-block-end: 16px;
    inset-inline-end: 18px;
    color: var(--accent);
    opacity: .16;
    pointer-events: none;
    user-select: none;
    transition: opacity .28s ease, transform .28s ease;
}
.tile__art .icon { width: 42px; height: 42px; stroke-width: 1.4; }
.tile:hover .tile__art { opacity: .26; transform: translateY(-3px); }
[dir="rtl"] .tile__art .icon { transform: scaleX(-1); }

.tile__icon {
    position: relative;
    display: grid;
    place-items: center;
    width: 44px; height: 44px;
    margin-bottom: 14px;
    border-radius: var(--r-md, 10px);
    background: var(--accent-050);
    color: var(--accent);
    transition: background .22s ease, color .22s ease;
}
.tile:hover .tile__icon { background: var(--accent); color: #fff; }
.tile__icon .icon { width: 22px; height: 22px; }

/* Mention cliquable, calee en bas. Meme role que sur la mosaique : dire que
   la tuile est un lien, ce que rien n'indiquait. */
.tile__more {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    align-self: flex-start;      /* voir .bento__more */
    margin-block-start: auto;
    padding-block-start: 24px;   /* voir .bento__more : c'est la bande du filigrane */
    font-family: var(--font-head);
    font-size: var(--t-sm);
    font-weight: 600;
    color: var(--accent);
}
.tile__more .icon { width: 15px; height: 15px; transition: transform .22s ease; }
[dir="rtl"] .tile__more .icon { transform: scaleX(-1); }
.tile:hover .tile__more .icon { transform: translateX(4px); }
[dir="rtl"] .tile:hover .tile__more .icon { transform: scaleX(-1) translateX(4px); }
.tile__title { position: relative; font-size: var(--t-lg); margin: 0 0 .35em; line-height: 1.3; }
.tile__text  { position: relative; margin: 0; color: var(--muted); font-size: var(--t-sm); line-height: 1.6; }

/* -------------------------------------------------- rail de citations */
.quoterail {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
}
.quote {
    position: relative;
    margin: 0;
    padding: 26px 22px 20px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg, 14px);
    display: flex;
    flex-direction: column;
}
.quote__mark {
    font-family: Georgia, "Times New Roman", serif;
    font-size: calc(var(--t-numeral) * .857);
    line-height: .8;
    color: var(--accent);
    opacity: .3;
    margin-bottom: 4px;
}
.quote__text {
    margin: 0 0 16px;
    padding: 0;
    border: 0;
    font-size: var(--t-base);
    line-height: 1.7;
    color: var(--ink);
    flex: 1;
}
.quote__by {
    padding-top: 14px;
    border-top: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.quote__author  { font-weight: 600; color: var(--ink); font-size: var(--t-base); }
.quote__company { color: var(--muted); font-size: var(--t-sm); }

/* ===================================================== tablette */
@media (max-width: 900px) {
    .statband { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* En deux colonnes, le filet gauche doit repartir a chaque debut de
       ligne, et un filet horizontal separe les deux rangees. */
    .statband__item:nth-child(odd)  { border-inline-start: 0; }
    .statband__item:nth-child(n+3)  { border-block-start: 1px solid var(--line); }

    .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .bento__item--lead { grid-column: span 2; }
    .tilerail, .quoterail { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ===================================================== telephone */
@media (max-width: 620px) {
    .statband { grid-template-columns: 1fr; }
    .statband__item { border-inline-start: 0; }
    .statband__item + .statband__item { border-block-start: 1px solid var(--line); }
    .statband__item:nth-child(n+3) { border-block-start: 1px solid var(--line); }

    .bento { grid-template-columns: 1fr; gap: 14px; }
    .bento__item--lead { grid-column: auto; }
    .bento__item--lead .bento__title { font-size: var(--t-lg); }
    .bento__item--lead .bento__text  { font-size: var(--t-sm); }
    /* Sur une colonne, la cellule de tete a la meme largeur que les autres :
       elle perd son traitement particulier et reprend le format commun. */
    .bento__item--lead .bento__ghost { inset-block-end: 14px; inset-inline-end: 16px; }
    .bento__item--lead .bento__ghost .icon { width: 42px; height: 42px; stroke-width: 1.4; }
    .bento__more { padding-block-start: 20px; }   /* bande du filigrane, voir plus haut */

    /*
      Solutions et temoignages passent en RAIL horizontal a defilement par
      crans, au lieu d'une colonne de six blocs empiles. Deux raisons : la
      page devenait tres longue, et un rail signale qu'il y a une suite,
      ce qu'une pile ne fait pas.
      scroll-padding-inline garde la premiere tuile alignee sur la marge du
      conteneur ; sans lui elle colle au bord de l'ecran.
    */
    .tilerail, .quoterail {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 82%;
        grid-template-columns: none;
        gap: 12px;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        scroll-padding-inline-start: 4px;
        padding-bottom: 10px;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-inline: contain;
    }
    .tile, .quote { scroll-snap-align: start; }
    .tile__ghost { font-size: calc(var(--t-numeral) * .857); }
    .tile__more { padding-block-start: 20px; }    /* bande du filigrane, voir plus haut */
}

@media (prefers-reduced-motion: reduce) {
    .bento__item, .tile,
    .bento__item::before, .bento__ghost, .bento__icon, .bento__more .icon,
    .tile::before, .tile__art, .tile__icon, .tile__more .icon { transition: none; }
    .bento__item:hover, .tile:hover { transform: none; }
    /* Le deplacement est retire, pas le signal : le lisere et la pastille
       pleine restent, ils ne bougent simplement plus. */
    .bento__item:hover .bento__ghost,
    .bento__item:hover .bento__more .icon,
    .tile:hover .tile__art { transform: none; }
    .tile:hover .tile__more .icon { transform: none; }
    [dir="rtl"] .bento__item:hover .bento__more .icon,
    [dir="rtl"] .tile:hover .tile__more .icon { transform: scaleX(-1); }
}

/* ------------------------------------- liste d'arguments (« Pourquoi nous »)
   Deux colonnes de lignes, l'icone a gauche, un filet entre les lignes.
   Aucun cadre : cette section est prise en sandwich entre le bandeau de
   chiffres et la mosaique des services, tous deux encadres. */
.argues {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 40px;
}
.argues__item {
    display: flex;
    gap: 16px;
    padding: 20px 0;
    border-block-start: 1px solid var(--line);
}
/* Les deux premieres lignes n'ont pas de filet superieur : il ferait une
   barre flottante juste sous le titre de section. */
.argues__item:nth-child(1),
.argues__item:nth-child(2) { border-block-start: 0; padding-block-start: 0; }

.argues__icon {
    flex: 0 0 44px;
    display: grid;
    place-items: center;
    width: 44px; height: 44px;
    border-radius: var(--r-md, 10px);
    background: var(--accent-050);
    color: var(--accent);
}
.argues__icon .icon { width: 22px; height: 22px; }
.argues__body { min-width: 0; }
.argues__title { font-size: var(--t-base); margin: 0 0 .3em; line-height: 1.3; }
.argues__text  { margin: 0; color: var(--muted); font-size: var(--t-sm); line-height: 1.6; }

@media (max-width: 760px) {
    .argues { grid-template-columns: 1fr; gap: 0; }
    /* En une colonne, seule la premiere ligne perd son filet. */
    .argues__item:nth-child(2) { border-block-start: 1px solid var(--line); padding-block-start: 20px; }
}

/* =====================================================================
   Tableaux dans le contenu editorial

   La politique de confidentialite contient un tableau de quatre colonnes
   (donnees / origine / finalite / conservation). Mesure a 375 px : le tableau
   faisait 381 px et poussait le document a 397 px, soit un defilement
   horizontal de TOUTE la page. Un tableau de donnees ne se compresse pas
   au-dela d'un point : on le rend defilant DANS son cadre, ce qui contient
   le probleme au lieu de le repandre sur la page.
   ===================================================================== */
.prose__scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-inline: contain;
    margin-block: 18px;
}
.prose table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--t-sm);
}
.prose th,
.prose td {
    padding: 9px 12px;
    text-align: start;
    border-block-end: 1px solid var(--line);
    vertical-align: top;
}
.prose thead th {
    background: var(--brand-050);
    color: var(--brand);
    font-size: var(--t-xs);
    text-transform: uppercase;
    letter-spacing: .04em;
    white-space: nowrap;
}

@media (max-width: 620px) {
    /* min-width : sans elle, le navigateur ecrase les colonnes a deux ou
       trois caracteres par ligne, ce qui est illisible. Mieux vaut defiler. */
    .prose table { min-width: 560px; font-size: var(--t-sm); }
    .prose th, .prose td { padding: 8px 10px; }
    /* Indice visuel qu'il y a une suite a droite. */
    .prose__scroll {
        border: 1px solid var(--line);
        border-radius: var(--r-md, 10px);
    }
}

/* ------------------------------------------- fil d'Ariane tactile
   Mesure : le lien « Accueil » faisait 50 x 17 px. Sous le doigt, 17 px de
   haut n'est pas atteignable de facon fiable. */
@media (max-width: 940px) {
    .crumbs a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }
}

/* ------------------------------------------------- grille des tarifs
   Elle etait figee a 3 colonnes. L'ajout d'une 4e formule laissait donc une
   carte orpheline sur une deuxieme ligne. auto-fit s'adapte au nombre reel
   de formules : 4 de front sur grand ecran, 2 x 2 sur tablette, une colonne
   sur telephone — sans qu'il faille retoucher le CSS a chaque ajout. */
.pricing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    gap: 18px;
    /* « start » laissait chaque carte à la hauteur de son contenu. Les quatre
       boutons se retrouvaient à quatre hauteurs différentes — jusqu'à 109 px
       d'écart mesurés. « stretch » leur donne la hauteur de la rangée ; le
       bouton est ensuite poussé en bas par .plan__cta. */
    align-items: stretch;
}

/* ================================================================
   DÉMONSTRATIONS — captures d'écran des applications livrées
   ================================================================
   Les vignettes sont larges à dessein : une capture d'écran de logiciel
   de gestion est dense, et réduite à la taille d'une carte elle ne montre
   plus rien. Deux par ligne sur grand écran, une sur téléphone.
   ================================================================ */
.demo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
    gap: 22px;
    margin-bottom: 34px;
}
.demo-shot {
    margin: 0;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: box-shadow .2s ease, border-color .2s ease;
}
.demo-shot:hover { box-shadow: var(--shadow-md); border-color: var(--brand); }
.demo-shot img {
    display: block;
    width: 100%;
    height: auto;
    /* Le haut de la capture porte l'information utile — barre d'outils,
       en-têtes de colonnes. Si le format doit être rogné, ce n'est jamais
       par le haut. */
    object-fit: cover;
    object-position: top center;
    border-block-end: 1px solid var(--line);
    background: var(--bg-soft);
}
/* CADRAGE À L'AFFICHAGE. Le cadre impose les proportions de la bande à
   montrer ; `object-position` fait glisser la capture derrière, si bien
   qu'on n'en voit que la partie utile. Le fichier reste entier — le lien
   ouvre la capture complète, et un cadrage mal réglé se corrige en base
   sans reprendre l'image.

   Les deux variables sont posées en ligne, calculées par cadrage() à
   partir des proportions réelles du fichier. Leurs valeurs de repli
   montrent la capture entière : si le fichier manque, on retombe sur le
   comportement d'origine plutôt que sur une bande vide. */
.demo-shot__cadre { display: block; }
.demo-shot__cadre.is-cadree {
    aspect-ratio: var(--vue-ratio, 16 / 9);
    overflow: hidden;
}
.demo-shot__cadre.is-cadree img {
    height: 100%;
    object-position: center var(--vue-pos, 0%);
}
.demo-shot figcaption { padding: 14px 16px 16px; }
.demo-shot figcaption strong { display: block; font-size: var(--t-base); color: var(--ink); margin-bottom: 4px; }
.demo-shot figcaption span { display: block; font-size: var(--t-sm); line-height: 1.5; color: var(--muted); }

/* MODULE DÉCRIT — une fonctionnalité présentée sans capture.
   Trois par ligne : assez large pour deux lignes de texte utile, assez
   étroit pour qu'on embrasse un thème entier d'un regard. */
.module-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: 16px;
    margin-bottom: 34px;
}
.module {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 14px;
    align-items: start;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: 18px 18px 20px;
    transition: border-color .2s ease, box-shadow .2s ease;
}
.module:hover { border-color: var(--brand); box-shadow: var(--shadow-sm); }
.module__icon {
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border-radius: var(--r-md);
    background: var(--surface-2);
    color: var(--brand);
}
.module__icon .icon { width: 21px; height: 21px; }
/* La taille est fixée ici, pas héritée du niveau de titre : ces h3 suivent
   un h2 de thème, et doivent rester des intitulés de carte. */
.module h3 { font-size: var(--t-base); margin: 2px 0 6px; color: var(--ink); }
.module p  { font-size: var(--t-sm); line-height: 1.55; color: var(--muted); margin: 0; }

.demo-cover {
    display: block; width: 100%; height: auto;
    border-radius: var(--r-md);
    border: 1px solid var(--line);
    margin-bottom: 14px;
}
.demo-meta { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 12px; }
.demo-count { font-size: var(--t-sm); color: var(--muted); }

/* ================================================================
   FORMULE — la carte d'une offre sur la page Tarifs
   ================================================================
   CE QUI N'ALLAIT PAS, constaté sur la page en ligne :

   1. Les caractéristiques utilisaient `.aside-list`, un composant de
      navigation LATÉRALE dont tout le style porte sur ses `<a>`. Avec de
      simples `<li>` de texte, il n'apportait donc RIEN : pas de puce
      (`ul { list-style: none }` s'applique partout), pas d'espacement,
      pas de séparateur. Mesuré : marge 0, padding 0, aucune bordure.
      Résultat, huit caractéristiques formaient un pavé de texte continu
      où l'on ne voyait pas où finissait une ligne.

   2. La pastille « populaire » était dans le flux : elle décalait vers le
      bas TOUT le contenu de la seule carte qui la porte. D'où des titres,
      des prix et des listes qui ne s'alignaient pas d'une carte à l'autre.

   3. La carte mise en avant n'avait aucune distinction visuelle
      (`.card--module { display: block }` et rien d'autre).
   ================================================================ */

.plan {
    position: relative;
    display: flex;
    flex-direction: column;
    /* 28 px de chaque côté sur une colonne de 275 px ne laissaient que
       219 px au texte, d'où les coupures de mots des captures. */
    padding: 26px 20px 22px;
}

/* La pastille sort du flux : les quatre cartes commencent à la même
   hauteur, qu'elles la portent ou non. */
.plan__badge {
    position: absolute;
    top: 14px;
    inset-inline-end: 14px;
}

/* La formule mise en avant se voit enfin — liseré à la couleur de marque
   et ombre portée, sans changer sa taille : une carte plus grande casserait
   l'alignement de la rangée. */
.plan--phare {
    border-color: var(--brand);
    box-shadow: var(--shadow-md);
}

/* `.plan .plan__name` et non `.plan__name` seul : la règle `.card h2`
   (0,1,1) l'emportait sur une simple classe (0,1,0), et le titre restait à
   1,25 rem. Mesuré à 20 px alors qu'on en demandait 18,4. */
.plan .plan__name { font-size: var(--t-lg); line-height: 1.25; margin: 0 0 .35em; }
.plan__price { font-size: var(--t-2xl); font-weight: 800; color: var(--brand); line-height: 1.05; margin: 0; }
.plan__note  { font-size: var(--t-sm); line-height: 1.5; color: var(--muted); margin: .35em 0 0; }
.plan__pitch { font-size: var(--t-sm); line-height: 1.55; margin: 14px 0 0; color: var(--body); }

/* ALIGNEMENT DES BLOCS À LONGUEUR VARIABLE.
   Mesuré sur les quatre formules : la note tient sur 1 ou 2 lignes, le
   chapeau sur 8 à 11. Ces écarts faisaient démarrer les quatre listes de
   caractéristiques à quatre hauteurs différentes — jusqu'à 91 px — ce qui
   est précisément ce qui donne l'impression d'une page non homogène.
   On réserve donc la hauteur du plus long.

   RÉSERVE ASSUMÉE : ces deux valeurs dépendent du texte. Si une formule
   reçoit un chapeau nettement plus long depuis l'administration, il faudra
   les relever. C'est le prix d'un alignement sans JavaScript ; la marge
   prise ici absorbe environ deux lignes de rédaction supplémentaires.
   Appliqué seulement quand les cartes sont côte à côte : sur une colonne,
   réserver de la hauteur n'alignerait rien et ajouterait du vide. */
@media (min-width: 561px) {
    /* « Application sur mesure » passe sur deux lignes dans une colonne de
       267 px, les trois autres tiennent sur une : le prix de cette carte
       descendait de 24 px, et tout le reste avec. On réserve deux lignes
       partout — le titre le plus long les occupera de toute façon. */
    .plan .plan__name { min-height: 2.5em; }
    .plan__note  { min-height: 3em; }
    .plan__pitch { min-height: 17.1em; }
}

/* La liste des caractéristiques — le cœur du correctif. */
.plan__features {
    flex: 1 1 auto;          /* occupe la place restante : le bouton descend */
    list-style: none;
    margin: 16px 0 18px;
    padding: 15px 16px;
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    display: grid;
    gap: 11px;               /* c'est cet écart qui manquait entièrement */
    align-content: start;
}
.plan__features li {
    position: relative;
    padding-inline-start: 22px;
    font-size: var(--t-sm);
    line-height: 1.45;
    color: var(--body);
}
/* Coche dessinée en CSS plutôt qu'en image : elle suit la couleur de la
   palette, que le client peut changer depuis les réglages. Une image
   figerait le vert. */
.plan__features li::before {
    content: "";
    position: absolute;
    inset-inline-start: 3px;
    top: .3em;
    width: 5px;
    height: 10px;
    border: solid var(--brand);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.plan__cta { margin-top: auto; }   /* colle le bouton au bas de la carte */

/* Sur une seule colonne, la carte n'a plus de voisine avec qui s'aligner :
   on rend la respiration et la largeur de lecture. */
@media (max-width: 560px) {
    .plan { padding: 24px 18px 20px; }
    .plan__features { gap: 12px; }
    .plan__features li { font-size: var(--t-sm); }
}

/* ------------------------------------------- bloc editorial lisible
   Largeur de ligne bornee, respiration entre les sections, et un filet
   discret avant chaque titre de niveau 2 pour que la page se parcoure en
   diagonale au lieu de se lire d'un bloc. */
.prose--lisible {
    max-width: 72ch;
    margin-inline: auto;
    margin-block-end: 40px;
}
.prose--lisible .lead {
    font-size: var(--t-lg);
    line-height: 1.7;
    color: var(--ink);
    padding-block-end: 22px;
    border-block-end: 1px solid var(--line);
    margin-block-end: 30px;
}
.prose--lisible h2 {
    font-size: var(--t-xl);
    margin-block: 36px 12px;
    padding-block-start: 22px;
    border-block-start: 2px solid var(--accent-050);
}
.prose--lisible h2:first-of-type { border-block-start: 0; padding-block-start: 0; margin-block-start: 0; }
.prose--lisible h3 {
    font-size: var(--t-base);
    margin-block: 24px 6px;
    color: var(--brand);
}
.prose--lisible p  { line-height: 1.75; margin-block-end: 14px; }
.prose--lisible ul { margin-block: 14px 0; padding-inline-start: 0; list-style: none; }
.prose--lisible li {
    position: relative;
    padding-inline-start: 26px;
    margin-block-end: 12px;
    line-height: 1.7;
}
/* Puce dessinee plutot que list-style : elle suit la couleur d'accent et se
   retourne seule en arabe grace a inset-inline-start. */
.prose--lisible li::before {
    content: "";
    position: absolute;
    inset-inline-start: 6px;
    inset-block-start: .62em;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--accent);
}
@media (max-width: 620px) {
    .prose--lisible h2 { font-size: var(--t-lg); margin-block-start: 28px; }
    .prose--lisible .lead { font-size: var(--t-base); }
}

/* Les domaines couverts, sur la vignette d'une application. */
.demo-themes { font-size: var(--t-sm); line-height: 1.5; color: var(--brand); margin: 8px 0 0; font-weight: 600; }

/* Visuel de tête d'une fiche de démonstration. Large, avec une ombre
   portée : une maquette d'interface plaquée sans relief se lit comme une
   illustration décorative, pas comme un logiciel. */
.demo-hero { margin: 0 0 34px; }
.demo-hero img {
    display: block; width: 100%; height: auto;
    border-radius: var(--r-lg);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-md);
}
/* La couverture est une capture : même cadrage que les vignettes, sinon la
   fiche s'ouvre sur une barre d'adresse de navigateur. */
.demo-hero.is-cadree {
    aspect-ratio: var(--vue-ratio, 16 / 9);
    overflow: hidden;
    border-radius: var(--r-lg);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-md);
}
.demo-hero.is-cadree img {
    height: 100%;
    object-fit: cover;
    object-position: center var(--vue-pos, 0%);
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

/* =====================================================================
   ÉTAPES NUMÉROTÉES — « ce qui se passe après votre envoi »
   =====================================================================
   Une liste ORDONNÉE, et c'est voulu : l'ordre porte le sens, et un
   lecteur d'écran doit l'annoncer comme une séquence. Le numéro visible
   vient du balisage, pas d'un ::before décoratif — pour la même raison. */
.etapes {
    list-style: none;
    counter-reset: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 2px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    overflow: hidden;
}
.etape {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 18px;
    align-items: start;
    background: var(--surface);
    padding: clamp(20px, 2.6vw, 30px);
}
.etape__n {
    width: 34px; height: 34px;
    flex: 0 0 34px;
    display: grid; place-items: center;
    border-radius: var(--r-full);
    background: var(--brand-050);
    color: var(--brand);
    font-family: var(--font-head);
    font-weight: 750;
    font-size: var(--t-base);
    font-variant-numeric: tabular-nums;
}
.etape h3 { margin: 2px 0 6px; font-size: var(--t-base); }
.etape p  { margin: 0; color: var(--body); line-height: 1.6; max-width: 68ch; }

/* --- ENCART : une proposition secondaire, sans concurrencer le formulaire */
.encart {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
    padding: clamp(24px, 3.4vw, 40px);
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
}
.encart h2 { margin: 0 0 8px; font-size: var(--t-xl); }
.encart p  { margin: 0; color: var(--body); max-width: 58ch; }
.encart__actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* --- LISTE COCHÉE : coche dessinée, pas image ------------------------
   Une image de coche resterait de la même couleur en thème sombre et
   demanderait un second fichier. Dessinée, elle suit le texte. */
.liste-cochee { list-style: none; padding: 0; margin: 10px 0 0; display: grid; gap: 10px; }
.liste-cochee li { position: relative; padding-inline-start: 28px; line-height: 1.55; color: var(--body); }
.liste-cochee li::before {
    content: "";
    position: absolute;
    inset-inline-start: 2px;
    top: .42em;
    width: 12px; height: 6px;
    border-inline-start: 2px solid var(--brand);
    border-block-end: 2px solid var(--brand);
    transform: rotate(-45deg);
}

/* =====================================================================
   OBJET DE LA DEMANDE — le contexte repris en tete de formulaire
   =====================================================================
   Volontairement PAS un champ de saisie. Un input pre-rempli invite a
   corriger, et l'on recolte des variantes libres du meme intitule, qu'on
   ne peut plus regrouper. C'est un constat, avec une porte de sortie. */
.objet-demande {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    margin-bottom: 22px;
    padding: 14px 16px;
    background: var(--brand-050);
    border-inline-start: 3px solid var(--brand);
    border-radius: var(--r-sm);
}
.objet-demande__label {
    font-size: var(--t-xs);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
}
.objet-demande__valeur { color: var(--ink); font-size: var(--t-base); }
.objet-demande__changer {
    margin-inline-start: auto;
    font-size: var(--t-sm);
    color: var(--brand);
    text-decoration: underline;
}
@media (max-width: 520px) {
    /* Sur telephone, le lien passe a la ligne plutot que de comprimer le
       libelle, qui est l'information utile. */
    .objet-demande__changer { margin-inline-start: 0; flex-basis: 100%; }
}

/* --- MENTION SOUS UN BOUTON D'ENVOI ---------------------------------- */
.form-note {
    margin: 14px 0 0;
    font-size: var(--t-sm);
    line-height: 1.55;
    color: var(--muted);
    max-width: 56ch;
}
