/* La modal « Être rappelé » — reprise des valeurs RÉELLES de la modal « Aide & Contact » du site
   (gf-cms/public/theme/css/app.css, blocs 739-744 et 776-779 ; source gf-wp _help.scss) :
   fond #fafafa, rayon 20, padding 40, boutons BLANCS sans bordure à `box-shadow: 0 0 15px
   rgba(0,0,0,.08)`, rayon 10, intertitres gris centrés. C'est ce contraste blanc-sur-#fafafa,
   et non une bordure, qui détache les portes : un fond blanc les ferait disparaître.

   Polices : Barlow (corps) et IvyPresto Headline (les titres et la promesse finale — le registre
   d'affichage, celui des questions du tunnel), les deux familles du site, servies ici en woff2
   sous-jeu latin : aucune requête tierce dans l'iframe.

   ⚠ Le JS ne pose AUCUNE classe d'état : tout se lit sur [data-vue], [data-champ], [data-sens],
   [hidden], :disabled, :focus-visible. Les animations d'entrée se rejouent parce que le passage
   de `display:none` à `display:block` redémarre une animation CSS — pas parce qu'on pose une classe.
   ⚠ Cette règle doit rester la première : la feuille pose du flex et du grid sur des éléments masqués. */

@font-face { font-family: "Barlow GF"; src: url("/assets/font/Barlow-400-GF.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Barlow GF"; src: url("/assets/font/Barlow-500-GF.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Barlow GF"; src: url("/assets/font/Barlow-600-GF.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Barlow GF"; src: url("/assets/font/Barlow-700-GF.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "IvyPresto GF"; src: url("/assets/font/IvyPresto-Headline-GF.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }

:root {
    color-scheme: light;

    /* Les jetons du site, à la valeur exacte (gf-wp _variables.scss:8-32 → --bs-* de app.css). */
    --gf-encre: #18152f;           /* --bs-body-color / --bs-heading-color */
    --gf-fond: #fafafa;            /* --bs-body-bg, et donc --bs-modal-bg */
    --gf-blanc: #fff;
    --gf-corail: #ff6666;          /* --bs-primary */
    --gf-corail-survol: #ff7d7d;   /* .btn-primary:hover */
    --gf-corail-survol-bord: #ff7575;    /* .btn-primary:hover border-color — la paire du site, pas une nuance inventée */
    --gf-corail-clair: #ffb3b3;    /* --bs-primary-light, bordure de champ au focus */
    --gf-corail-pale: #ffd9d9;     /* --bs-primary-ultra-light, l'ombre corail des icônes `card-ico` du site */
    --gf-halo: hsla(0, 100%, 70%, .25);  /* --bs-focus-ring-color */

    /* rgba(24,21,47,.6) est le gris du site ; monté à .68 pour passer 4,5:1 sur #fafafa en 14 px. */
    --gf-gris: rgba(24, 21, 47, .68);
    --gf-gris-fort: rgba(24, 21, 47, .78);
    --gf-trait: #dee2e6;           /* --bs-gray-300, le filet du site */
    --gf-trait-fin: #e9ecef;       /* --bs-gray-200 */
    --gf-gris-libelle: #838098;    /* le libellé « Devis / Tarifs assurance » du bandeau du tunnel */
    --gf-rail: #d3d5ea;            /* le rail de la barre d'avancement du tunnel (#header .avancement::before) */

    --gf-vert: #297a29;            /* la coche et le liseré de la quittance — 5,4:1 sur son fond */
    --gf-vert-fond: #eef8ee;
    --gf-alerte: #b83c3d;
    --gf-alerte-fond: #fff1f1;

    --gf-r-porte: 10px;            /* --bs-btn-border-radius */
    --gf-r-bloc: 10px;
    --gf-r-modal: 20px;            /* --bs-modal-border-radius */
    --gf-r-rond: 50rem;            /* --bs-border-radius-pill */

    --gf-ombre-porte: 0 0 15px 0 rgba(0, 0, 0, .08);   /* .btn-white du site */
    --gf-ombre-porte-survol: 0 4px 18px 0 rgba(0, 0, 0, .13);

    /* Quatre intervalles, quatre sens — jamais réemployés pour autre chose. */
    --gf-lie: 8px;                 /* deux parties d'un même objet */
    --gf-frere: 12px;              /* deux éléments de même nature */
    --gf-bloc: 30px;               /* deux blocs de natures différentes — .help-content-wrapper du site */
    --gf-souffle: 40px;            /* --bs-modal-padding */

    /* Les courbes du site : .15s pour un survol, .3s pour une entrée. Rien d'autre. */
    --gf-t-court: .15s ease-in-out;
    --gf-t-entree: .3s ease-out;

    --gf-sans: "Barlow GF", Barlow, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --gf-serif: "IvyPresto GF", Georgia, "Times New Roman", serif;
}

* { box-sizing: border-box; }
.rappel [hidden], .rappel-vue[hidden] { display: none !important; }

html, body {
    margin: 0; padding: 0; background: var(--gf-fond); color: var(--gf-encre);
    font-family: var(--gf-sans); font-size: 16px; line-height: 1.5;
    -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
    overscroll-behavior: contain;  /* sans quoi le défilement de l'iframe fait bouger la page hôte */
    overflow-x: hidden;            /* un débordement en travers ferait défiler la modal latéralement */
}
::selection { background: var(--gf-corail-pale); color: var(--gf-encre); }

.rappel { max-width: 30rem; margin: 0 auto; text-align: center; }
body.rappel-mode-modal .rappel { padding: 2.5rem 1.25rem 1.5rem; }
body.rappel-mode-lien .rappel { padding: 1.75rem 1.25rem 1.5rem; }
@media (min-width: 480px) {
    body.rappel-mode-modal .rappel { padding: 2.75rem var(--gf-souffle) 1.75rem; }
    body.rappel-mode-lien .rappel { padding: 2rem var(--gf-souffle) 1.75rem; }
}
/* La page du lien SMS est autonome : c'est ELLE qui porte la carte, l'iframe n'en a pas besoin. */
body.rappel-mode-lien { background: #f2f3f7; padding: 1rem; }
/* ——— La page de rendez-vous (mode rdv) : la mise en page du tunnel de devis, aux mêmes proportions
   (`#header` de base.css) — le logo à gauche, le libellé du service, une croix à droite à la place du
   « Rappelez-moi », la barre d'avancement en dessous ; puis la conseillère et les écrans sur le fond
   de page, sans carte. Bureau : gouttières de 40 px, logo 176 × 40, libellé 16 px ; mobile : 20 px,
   logo 132 px, libellé masqué — comme le tunnel. ——— */
body.rappel-mode-rdv { background: var(--gf-fond); }
.rappel-entete { background: var(--gf-fond); }
/* Mobile, comme le tunnel : le logo est CENTRÉ entre une case vide (la place du retour) et la croix,
   la barre va d'un bord à l'autre. Mesuré sur dev-rappel à 375 px : logo 132 × 30 à y = 27, bouton
   38 × 37 à y = 20, barre à y = 79, avatar à y = 105. */
.rappel-entete-haut { display: grid; grid-template-columns: 38px 1fr 38px; align-items: center; padding: 20px 20px 0; }
.rappel-entete-marque { grid-column: 2; display: flex; align-items: center; justify-content: center; gap: 20px; }
.rappel-entete-marque a { display: block; line-height: 0; }
.rappel-entete-marque img { display: block; width: 132px; height: 30px; margin-top: 5px; }
.rappel-entete-libelle { display: none; color: var(--gf-gris-libelle); font-size: 1rem; line-height: 1.2; }
/* La croix : la pastille du « Rappelez-moi » du tunnel (corail pâle, coins 10 px), sans texte. */
.rappel-entete-fermer { grid-column: 3; display: flex; align-items: center; justify-content: center; width: 38px; height: 38px; border-radius: var(--gf-r-porte); background: var(--gf-corail-pale); color: var(--gf-encre); transition: background-color var(--gf-t-court); }
.rappel-entete-fermer:hover, .rappel-entete-fermer:focus-visible { background: var(--gf-corail-clair); outline: none; }
.rappel-entete-fermer svg { width: 18px; height: 18px; }
/* L'avancement : le trait corail du tunnel (3 px) sur son rail d'1 px ; la largeur suit l'étape
   (1/3, 2/3, 3/3), posée par le JS. */
.rappel-avancement { position: relative; height: 3px; margin: 18px 0 25px; }
.rappel-avancement::before { content: ""; position: absolute; left: 0; right: 0; top: 1px; height: 1px; background: var(--gf-rail); }
.rappel-avancement-barre { position: relative; height: 3px; width: 33.333%; background: var(--gf-corail); transition: width var(--gf-t-entree); }
.rappel-rdv { max-width: 30rem; margin: 0 auto; padding: 0; }
body.rappel-mode-rdv .rappel { padding: .25rem 1.25rem 2.5rem; }
@media (min-width: 480px) { body.rappel-mode-rdv .rappel { padding: .25rem var(--gf-souffle) 3rem; } }
/* Bureau, mesuré sur dev-rappel à 1392 px : logo 176 × 40 à (40, 34), libellé à x = 236, bouton
   collé à la gouttière droite, barre à y = 107 dans les gouttières, avatar à y = 157. */
@media (min-width: 768px) {
    .rappel-entete-haut { display: flex; justify-content: space-between; padding: 34px 40px 0; }
    .rappel-entete-marque { justify-content: flex-start; }
    .rappel-entete-marque img { width: 176px; height: 40px; margin-top: 0; }
    .rappel-entete-libelle { display: inline-block; }
    .rappel-entete-fermer { width: 40px; height: 40px; }
    .rappel-avancement { margin: 33px 40px 31px; }
    .rappel-rdv { padding: 1rem 0 0; }
}
body.rappel-mode-lien .rappel { background: var(--gf-fond); border-radius: var(--gf-r-modal); box-shadow: 0 30px 60px 0 rgba(0, 0, 0, .1); margin: 1.5rem auto; }
/* La page de reprise du tchat (`/tchat/{jeton}`, mode page) : la carte de la page du lien SMS, le comportement de la modal. */
body.rappel-mode-page { background: #f2f3f7; padding: 1rem; }
body.rappel-mode-page .rappel { background: var(--gf-fond); border-radius: var(--gf-r-modal); box-shadow: 0 30px 60px 0 rgba(0, 0, 0, .1); margin: 1.5rem auto; padding: 1.75rem 1.25rem 1.5rem; }
@media (min-width: 480px) { body.rappel-mode-page .rappel { padding: 2rem var(--gf-souffle) 1.75rem; } }

/* ——————————————————————— L'entrée des écrans ———————————————————————
   Le passage de display:none à display:block redémarre l'animation : c'est ce qui la rejoue à
   chaque changement d'écran, sans qu'aucune classe ne soit posée. Le sens vient de [data-sens]. */
@keyframes rappel-entre-avant { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }
@keyframes rappel-entre-arriere { from { opacity: 0; transform: translateX(-14px); } to { opacity: 1; transform: none; } }
@keyframes rappel-coche-fond { from { transform: scale(.5); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes rappel-coche-trait { from { stroke-dashoffset: 30; } to { stroke-dashoffset: 0; } }
@keyframes rappel-lueur { from { background-position: 100% 0; } to { background-position: -100% 0; } }

[data-sens] .rappel-vue:not([hidden]) { animation: rappel-entre-avant var(--gf-t-entree) both; }
[data-sens="arriere"] .rappel-vue:not([hidden]) { animation-name: rappel-entre-arriere; }

/* ——————————————————————— Typographie ——————————————————————— */
/* La phrase de disponibilité, en registre d'affichage : c'est la VOIX de la marque, celle que le
   tunnel emploie pour toutes ses questions. En Barlow 700 à 17 px, elle était à 2 px d'un libellé
   de bouton — aucune hiérarchie. */
/* L'avatar du tunnel (femme.png, 79 px) : la conseillère qui parle. Pas de `border-radius` : le PNG
   est déjà un disque sur fond transparent, et sa pastille verte « en ligne » DÉPASSE du disque en
   haut à droite — arrondir l'image la coupait en deux (vu par le CTO sur dev-rappel, 03/09). */
.rappel-avatar { display: block; width: 79px; height: 79px; margin: 0 auto .9rem; }
/* Le signe final d'un titre en IvyPresto (« ? », « ! ») : la fonte donne à l'espace, insécable
   compris, 0,176 em de chasse — 4 px à 24 px, invisibles devant le signe. Pas d'espace dans le
   texte : l'écart est ici, et le signe ne peut pas passer seul à la ligne. */
.rappel-ponct { margin-left: .22em; }
.rappel-accroche { margin: 0 auto; max-width: 25rem; font-family: var(--gf-serif); font-weight: 700; font-size: clamp(1.25rem, 6vw, 1.5rem); line-height: 1.2; text-wrap: balance; }
/* L'échelle de l'écran 1. Le conseil de créa du 02/09 avait posé un plancher à 14 px et trois corps
   (17 · 15 · 14) ; sur dev-rappel, le CTO a trouvé l'ensemble encore petit — un cran de plus,
   partout : 18 (nom d'une porte) · 16 (intertitre, parole de l'assistant) · 15 (tout le gris,
   dont les horaires : fermé, c'est le fait le plus utile de l'écran). Le contraste n'a jamais été
   le point limitant (--gf-gris : 6,0:1 sur le fond, --gf-gris-fort : 8,5:1) ; c'est la hauteur
   d'x de Barlow, 6,6 px à 13 px, qui rendait les lignes grises « petites ». Rien sous 14 px, sur
   aucun écran : les mentions des écrans 3 à 5 (titres de jour, créneaux, libellés en capitales,
   étiquettes de champ, consentement, liens, alertes) ont rejoint le plancher le 03/09. */
.rappel-horaires { max-width: 24rem; margin: .5rem auto 0; font-size: .9375rem; line-height: 1.45; color: var(--gf-gris); }
/* Le titre d'un écran de question : même registre que l'accroche, un cran au-dessus. */
.rappel-q-titre { flex: none; max-width: 25rem; margin: 0 auto; font-family: var(--gf-serif); font-weight: 700; font-size: clamp(1.25rem, 6vw, 1.5rem); line-height: 1.2; text-wrap: balance; scroll-margin-top: 1rem; }
.rappel-q-pourquoi { max-width: 24rem; margin: .4rem auto 1.5rem; font-size: .9375rem; line-height: 1.45; color: var(--gf-gris); text-wrap: pretty; }
.rappel-q-pourquoi-serre { margin: 0; }
/* Le titre reçoit le focus par programme au changement d'écran, pour que le lecteur d'écran
   annonce la nouvelle étape. Ce n'est pas une cible clavier : pas d'anneau. Les vraies cibles
   (portes, créneaux, champs, boutons) gardent le leur, en :focus-visible. */
.rappel-vue h1:focus, .rappel-accroche:focus { outline: 0; }
/* L'intertitre d'un groupe de portes. .header-title du site (14/500/gris) surplombe des boutons à
   14 px ; ici il annonce des portes à 17/700 : à 14/500 il légendait la carte du dessus au lieu de
   titrer celles du dessous. 16/600, gris fort. */
.rappel-groupe { display: block; margin: var(--gf-bloc) auto 1rem; font-size: 1rem; font-weight: 600; line-height: 1.25; color: var(--gf-gris-fort); }

/* ——————————————————————— Les portes ——————————————————————— */
.rappel-portes { display: flex; flex-direction: column; gap: var(--gf-frere); }
.rappel-porte {
    position: relative; display: block; width: 100%; min-height: 3.5rem;
    /* Symétrique : l'icône est posée par-dessus, en absolu. Un padding asymétrique centrerait
       le texte dans l'espace RESTANT — c'est ce décalage de 18 px que le premier comité a vu.
       48 px : l'icône occupe 16 → 44 px ; le texte étant centré, il ne l'atteint jamais. */
    padding: .85rem 3rem;
    border: 0; border-radius: var(--gf-r-porte); background: var(--gf-blanc);
    box-shadow: var(--gf-ombre-porte);
    color: var(--gf-encre); font-family: inherit; text-align: center; text-decoration: none;
    cursor: pointer;
    transition: box-shadow var(--gf-t-court), transform var(--gf-t-court), background-color var(--gf-t-court);
}
.rappel-porte-double { min-height: 4rem; }
.rappel-porte:hover { box-shadow: var(--gf-ombre-porte-survol); transform: translateY(-1px); }
.rappel-porte:active { transform: translateY(0); box-shadow: var(--gf-ombre-porte); }
.rappel-porte:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; box-shadow: var(--gf-ombre-porte), 0 0 0 .25rem var(--gf-halo); }
.rappel-porte[disabled] { opacity: .55; cursor: default; transform: none; }

/* Les icônes `card-ico` du site : gabarit 36 servi à 28 px, le trait de 2 rend alors 1,55 px.
   Tous les gabarits partagent le même axe vertical (30 px du bord). La largeur du trait est portée
   par le SVG racine — elle se transmet aux tracés, et un gabarit rapporté à une autre échelle (le
   bouclier) la corrige sur son groupe. */
.rappel-porte-ic { position: absolute; left: 1rem; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; stroke-width: 2; }
.rappel-ic-trait { fill: none; stroke: var(--gf-encre); stroke-linecap: round; stroke-linejoin: round; }
.rappel-ic-fond { fill: var(--gf-corail-pale); }
.rappel-ic-plein { fill: var(--gf-encre); }
/* Le glyphe WhatsApp est plein : à surface égale il paraît plus gros qu'un tracé, d'où 26 px. */
.rappel-ic-whatsapp { width: 26px; height: 26px; left: 1.0625rem; }
.rappel-porte-t { display: block; font-size: 1.125rem; font-weight: 700; line-height: 1.25; letter-spacing: -.006em; }
/* 18/15 : une voix, deux lignes — la hiérarchie tient par le poids (700/400) et la couleur, pas
   par l'écart de corps. `balance` : quand la sous-ligne passe à deux lignes (dès 375 px pour
   « Choisissez le moment qui vous arrange. »), pas de veuve « 9 / h. ». */
.rappel-porte-s { display: block; margin-top: .15rem; font-size: .9375rem; font-weight: 400; line-height: 1.4; color: var(--gf-gris); text-wrap: balance; }

/* ——————————————————————— Le bandeau « c'est déjà noté » ——————————————————————— */
.rappel-en-cours { margin: 1.25rem 0 0; padding: .8rem 1rem; border-radius: var(--gf-r-bloc); background: var(--gf-vert-fond); border-left: 3px solid var(--gf-vert); text-align: left; font-size: .9375rem; line-height: 1.45; }
.rappel-en-cours b { display: block; }
.rappel-en-cours span { color: var(--gf-gris-fort); }

/* Hors horaires : ce que fait l'assistant, dit AVANT de proposer d'écrire. */
/* Hors horaires, c'est l'assistant qui parle : un PARAGRAPHE sous « Nous écrire : », sur le fond de
   la modal, sans boîte. Trois formes ont été essayées le 02/09 au soir — une bulle grise (« une
   porte éteinte »), une bulle crème décalée puis pleine largeur (« trop de rectangles entre les
   CTA, on s'y perd ») : le CTO a tranché pour le texte nu, en 15 px, la première phrase en gras
   et en encre dans le fil du paragraphe. Ce qui le fait lire, c'est le corps et la place, pas un
   fond. Marges latérales : la même mesure que les horaires (24 rem centrés). */
.rappel-rassurance { max-width: 24rem; margin: -.25rem auto var(--gf-frere); padding: 0 .25rem; font-size: .9375rem; line-height: 1.5; color: var(--gf-gris-fort); text-wrap: pretty; }
.rappel-rassurance b { font-weight: 700; color: var(--gf-encre); }

/* ——————————————————————— Les créneaux ——————————————————————— */
.rappel-sep { margin-top: var(--gf-bloc); }
.rappel-jour-titre { margin: 1.25rem 0 .6rem; font-size: .875rem; font-weight: 700; color: var(--gf-encre); }
/* Flex plutôt que grid : la dernière ligne se centre au lieu de laisser une pilule orpheline à gauche. */
.rappel-jour-heures { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; }
.rappel-creneau {
    flex: 0 1 auto; min-width: 5.25rem;
    min-height: 2.75rem; display: grid; place-items: center; padding: 0 .75rem;
    border: 0; border-radius: var(--gf-r-porte); background: var(--gf-blanc);
    /* Une ombre de porte de 68 px posée sur une pilule de 44 px est proportionnellement 3× trop présente. */
    box-shadow: 0 0 8px 0 rgba(0, 0, 0, .06);
    color: var(--gf-encre); font-family: inherit; font-size: .875rem; font-weight: 600;
    white-space: nowrap; cursor: pointer;
    transition: box-shadow var(--gf-t-court), transform var(--gf-t-court), color var(--gf-t-court);
}
.rappel-creneau:hover { box-shadow: var(--gf-ombre-porte-survol); transform: translateY(-1px); color: var(--gf-corail); }
.rappel-creneau:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; box-shadow: var(--gf-ombre-porte), 0 0 0 .25rem var(--gf-halo); }
.rappel-creneau[disabled] { opacity: .5; cursor: progress; transform: none; }
.rappel-plus {
    display: flex; align-items: center; justify-content: center; gap: .4rem;
    width: 100%; min-height: 2.75rem; margin-top: 1rem;
    border: 1px solid var(--gf-trait); border-radius: var(--gf-r-bloc); background: transparent;
    color: var(--gf-gris); font-family: inherit; font-size: .875rem; font-weight: 600; cursor: pointer;
    transition: border-color var(--gf-t-court), color var(--gf-t-court);
}
.rappel-plus:hover { border-color: var(--gf-corail-clair); color: var(--gf-encre); }
.rappel-plus:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; border-color: var(--gf-corail-clair); box-shadow: 0 0 0 .25rem var(--gf-halo); }

/* Le cul-de-sac assumé : la file ne peut rien tenir, on donne le numéro plutôt qu'un écran vide. */
.rappel-secours { margin-top: 0; }
.rappel-secours p { max-width: 24rem; margin: 0 auto 1rem; font-size: .9375rem; line-height: 1.5; color: var(--gf-gris-fort); text-wrap: pretty; }

.rappel-fini { margin: 1rem 0 0; font-size: .875rem; color: var(--gf-gris); }
.rappel-connu { margin: 0 0 .25rem; text-align: center; }
.rappel-connu span { display: block; font-size: .875rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--gf-gris); }
.rappel-connu strong { display: block; margin-top: .15rem; font-size: 1.25rem; font-variant-numeric: tabular-nums; letter-spacing: .02em; }

/* ——————————————————————— Le formulaire ——————————————————————— */
.rappel-form { text-align: left; }
.rappel-champ { position: relative; display: block; margin-top: var(--gf-frere); }
.rappel-champ i { position: absolute; top: 8px; left: .9rem; z-index: 1; font-style: normal; font-size: .875rem; font-weight: 600; letter-spacing: .01em; color: var(--gf-gris); pointer-events: none; }
.rappel-champ input {
    width: 100%; height: 3.75rem; padding: 1.7rem .9rem .35rem;
    border: 1px solid var(--gf-trait); border-radius: var(--gf-r-bloc); background: var(--gf-blanc);
    color: var(--gf-encre); font-family: inherit; font-size: 1rem; font-weight: 500;
    transition: border-color var(--gf-t-court), box-shadow var(--gf-t-court);
}
#rappel-telephone { font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.rappel-champ input::placeholder { color: var(--gf-gris); font-weight: 400; letter-spacing: normal; }
.rappel-champ input:focus { outline: 0; border-color: var(--gf-corail-clair); box-shadow: 0 0 0 .25rem var(--gf-halo); }
.rappel-champ input:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; }
.rappel-erreur { margin: .6rem 0 0; padding: .6rem .8rem; border-radius: var(--gf-r-bloc); background: var(--gf-alerte-fond); color: var(--gf-alerte); font-size: .875rem; line-height: 1.4; }

.rappel-ajouter { display: block; width: 100%; margin-top: .9rem; padding: 0; border: 0; background: none; color: var(--gf-encre); font-family: inherit; font-size: .875rem; font-weight: 600; text-align: center; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.rappel-ajouter:hover { color: var(--gf-corail); }
.rappel-ajouter:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 3px; border-radius: 4px; }

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

/* Le bouton corail du site : 56 px, rayon 10, poids 700, flèche à droite, `gap: .5rem`. */
.rappel-cta {
    display: flex; align-items: center; justify-content: center; gap: .5rem;
    width: 100%; min-height: 3.5rem; margin-top: 1.25rem; padding: 0 1.875rem;
    border: 1px solid var(--gf-corail); border-radius: var(--gf-r-porte); background: var(--gf-corail);
    color: #fff; font-family: inherit; font-size: 1rem; font-weight: 700; line-height: 1.5;
    text-decoration: none; cursor: pointer;
    transition: background-color var(--gf-t-court), border-color var(--gf-t-court), box-shadow var(--gf-t-court);
}
.rappel-cta:hover { background: var(--gf-corail-survol); border-color: var(--gf-corail-survol-bord); }
.rappel-cta:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; box-shadow: 0 0 0 .25rem var(--gf-halo); }
.rappel-cta[disabled] { opacity: .6; cursor: default; }
.rappel-cta[aria-busy="true"] { cursor: progress; }
.rappel-cta-fleche { width: 15px; height: 11px; margin-top: -1px; flex: none; }
.rappel-consent { max-width: 24rem; margin: .75rem auto 0; text-align: center; font-size: .875rem; line-height: 1.45; color: var(--gf-gris); text-wrap: pretty; }

/* ——————————————————————— Revenir ——————————————————————— */
.rappel-vue { display: flex; flex-direction: column; justify-content: center; min-height: 24rem; }
.rappel-vue:focus { outline: 0; }
.rappel-retour {
    align-self: flex-start;
    display: inline-flex; align-items: center; height: 2rem; margin: 0 0 1.1rem; padding: 0 .8rem;
    border: 1px solid var(--gf-trait); border-radius: var(--gf-r-rond); background: var(--gf-blanc);
    color: var(--gf-gris); font-family: inherit; font-size: .875rem; font-weight: 500; cursor: pointer;
    transition: border-color var(--gf-t-court), color var(--gf-t-court);
}
.rappel-retour:hover { border-color: var(--gf-gris); color: var(--gf-encre); }
.rappel-retour:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; }
.rappel-lien { display: block; width: 100%; margin: 1rem 0 0; padding: 0; border: 0; background: none; color: var(--gf-gris); font-family: inherit; font-size: .875rem; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.rappel-lien-haut { margin: .25rem 0 .5rem; color: var(--gf-encre); }
.rappel-lien:hover { color: var(--gf-encre); }
/* Le QR de la porte WhatsApp (écran `whatsapp`, ordinateur seulement) : sur une carte blanche, dont le rembourrage fait la marge de silence. */
.rappel-qr { display: block; box-sizing: content-box; width: 11rem; max-width: calc(100% - 2rem); height: auto; margin: 0 auto; padding: 1rem; background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0, 0, 0, .08); }
a.rappel-lien { margin-top: 1.25rem; text-align: center; }

/* ——————————————————————— La quittance ——————————————————————— */
/* La coche du site (`check-corail-clair`) à 64 px : le disque entre en s'agrandissant, puis le trait
   se dessine (sa longueur vaut 28,3 sur le gabarit 48 ; dasharray 30). Trait de 3,5 sur 48, soit
   4,7 px rendus — celui du fichier (4) donnerait 5,3, un poil lourd sous un titre serif. */
.rappel-coche { display: block; width: 64px; height: 64px; margin: 0 auto 1.5rem; animation: rappel-coche-fond var(--gf-t-entree) both; }
.rappel-coche-ic { display: block; width: 100%; height: 100%; }
.rappel-coche-trait { fill: none; stroke: var(--gf-encre); stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 30; animation: rappel-coche-trait var(--gf-t-entree) .15s both; }
/* L'écran de fin respire : plus d'air sous la coche, entre les lignes, et avant le bouton (le CTO, 03/09). */
[data-vue="quittance"] .rappel-cta { margin-top: 1.75rem; }
/* « C'est noté » est le titre : c'est lui qu'on lit en premier, dans la voix des autres écrans. */
.rappel-fin-titre { margin: 0 0 .85rem; font-family: var(--gf-serif); font-weight: 700; font-size: clamp(1.5rem, 7vw, 1.75rem); line-height: 1.15; color: var(--gf-encre); }
/* Le seul endroit où la formulation du serveur se lit. Un cran AU-DESSUS des titres de question :
   c'est la phrase qui engage le service, elle ne peut pas être réglée comme un message d'erreur. */
/* La promesse : le seul endroit où l'horaire retenu se lit — 17 px gras, sur une ou deux lignes. */
.rappel-fin-promesse { max-width: 24rem; margin: 0 auto 1rem; font-size: 1.0625rem; font-weight: 700; line-height: 1.5; color: var(--gf-encre); text-wrap: balance; }
.rappel-fin-canal { max-width: 24rem; margin: 0 auto 1rem; font-size: .9375rem; line-height: 1.6; color: var(--gf-gris-fort); text-wrap: balance; }
.rappel-alerte { margin: 0 0 1rem; padding: .7rem .9rem; border-radius: var(--gf-r-bloc); background: var(--gf-alerte-fond); color: var(--gf-alerte); font-size: .875rem; line-height: 1.45; }

/* ——————————————————————— Le tchat ———————————————————————
   Le fil (docs/tchat.md, étape 6) : en mode modal il prend toute la place du panneau et défile en interne
   (règles `body.rappel-mode-modal` plus bas) ; sur la page de reprise, il garde une hauteur de 17 rem. */
.rappel-vue-tchat { justify-content: flex-start; text-align: left; }
.tchat-bandeau { margin: 0 0 .75rem; font-size: .9375rem; font-weight: 600; line-height: 1.45; color: var(--gf-gris-fort); text-align: center; text-wrap: balance; }
/* « Passer à un conseiller » : un simple lien gris, en petits caractères, sur la ligne du nom de l'assistant, aligné à droite
   du fil (essai du CTO, 08/09) — le premier message de l'assistant prend alors toute la largeur, ses bulles gardent leur
   mesure ; la ligne de « Revenir » garde un demi-rem d'air sous la croix du panneau. */
.rappel-vue-tchat .rappel-retour { margin-top: .5rem; }
.tchat-msg.tchat-msg-large { width: 100%; max-width: 100%; }   /* deux classes : la règle `.tchat-msg { max-width: 85% }` vient après dans la feuille */
.tchat-msg-large .tchat-entete { width: 100%; }
.tchat-msg-large .tchat-bulle { max-width: calc(85% - 28px - .5rem); }
.tchat-vers-conseiller { margin: 0 0 0 auto; padding: .1rem .25rem; border: 0; background: none; color: var(--gf-gris); font-family: inherit; font-size: .8125rem; font-weight: 400; line-height: 1.45; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; cursor: pointer; transition: color var(--gf-t-court); }
@keyframes tchat-fondu { from { opacity: 0; } to { opacity: 1; } }
/* Les pattes au bout d'une phrase de l'assistant qui cherche : trois empreintes qui s'allument l'une après l'autre. */
.tchat-pattes { display: inline-flex; gap: .15rem; margin-left: .35rem; vertical-align: -.15em; }
.tchat-pattes svg { width: .95em; height: .95em; fill: var(--gf-corail); opacity: .2; animation: tchat-patte 1.5s ease-in-out infinite; }
.tchat-pattes svg:nth-child(2) { animation-delay: .25s; transform: rotate(12deg); }
.tchat-pattes svg:nth-child(3) { animation-delay: .5s; }
.tchat-pattes svg:nth-child(1) { transform: rotate(-12deg); }
@keyframes tchat-patte { 0%, 60%, 100% { opacity: .2; } 30% { opacity: 1; } }
/* Les trois suites proposées par l'assistant (« Passer à un conseiller », proposition 2) : les cartes des portes, avec leurs
   icônes, en retrait comme ses bulles ; dans le fil le texte est calé à gauche de l'icône, en corps un peu plus petit. */
.tchat-choix { width: calc(100% - 28px - .5rem); max-width: none; margin: .25rem 0 .25rem calc(28px + .5rem); padding: 0; }
.tchat-choix .rappel-porte { padding: .7rem 1rem .7rem 3.25rem; text-align: left; }
.tchat-choix .rappel-porte-t { font-size: 1rem; }
.tchat-choix .rappel-porte-s { font-size: .875rem; text-wrap: pretty; }
/* La carte qui demande l'adresse, dans le fil : un champ (16 px, sinon Safari iOS zoome), « Valider », l'erreur dessous. */
.tchat-carte-email { display: flex; flex-direction: column; gap: .5rem; padding: .75rem .85rem; border-radius: var(--gf-r-porte); background: var(--gf-blanc); box-shadow: var(--gf-ombre-porte); }
.tchat-carte-email input { width: 100%; min-height: 2.75rem; padding: .5rem .75rem; border: 1.5px solid var(--gf-trait); border-radius: 10px; background: var(--gf-blanc); color: var(--gf-encre); font-family: inherit; font-size: 1rem; }
.tchat-carte-email input:focus { outline: 0; border-color: var(--gf-corail-clair); box-shadow: 0 0 0 .25rem var(--gf-halo); }
.tchat-carte-email .rappel-cta { min-height: 2.75rem; margin-top: 0; }
.tchat-carte-erreur { margin: 0; font-size: .8125rem; color: var(--gf-alerte); }
/* « Pour le finaliser, j'ai besoin de connaître… » : le formulaire du devis dans le fil, même habit que la carte e-mail. */
.tchat-carte-devis { display: flex; flex-direction: column; gap: .6rem; padding: .75rem .85rem; border-radius: var(--gf-r-porte); background: var(--gf-blanc); box-shadow: var(--gf-ombre-porte); }
.tchat-carte-devis-titre { margin: 0; font-weight: 600; color: var(--gf-encre); }
.tchat-carte-devis-champ { display: flex; flex-direction: column; gap: .3rem; font-size: .875rem; color: var(--gf-encre); }
.tchat-carte-devis input[type="text"], .tchat-carte-devis select { min-height: 2.75rem; padding: .5rem .75rem; border: 1.5px solid var(--gf-trait); border-radius: 10px; background: var(--gf-blanc); color: var(--gf-encre); font-family: inherit; font-size: 1rem; }
.tchat-carte-devis input[type="text"]:focus, .tchat-carte-devis select:focus { outline: 0; border-color: var(--gf-corail-clair); box-shadow: 0 0 0 .25rem var(--gf-halo); }
.tchat-carte-devis-naissance { display: flex; gap: .5rem; }
.tchat-carte-devis-naissance select { flex: 1 1 0; min-width: 0; }
.tchat-carte-devis-choix { display: flex; flex-wrap: wrap; gap: .5rem 1rem; margin: 0; padding: 0; border: 0; font-size: .875rem; color: var(--gf-encre); }
.tchat-carte-devis-choix legend { padding: 0; margin-bottom: .3rem; }
.tchat-carte-devis-choix label { display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; }
.tchat-carte-devis .rappel-cta { min-height: 2.75rem; margin-top: 0; }
.tchat-carte-devis-plus-tard { align-self: center; padding: .25rem; border: 0; background: none; color: var(--gf-encre); font: inherit; font-size: .8125rem; text-decoration: underline; cursor: pointer; }
.tchat-fondu { animation: tchat-fondu .35s ease-out both; }
.tchat-vers-conseiller:hover { color: var(--gf-encre); }
.tchat-vers-conseiller:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; border-radius: 3px; }
/* L'écran de bascule, fermé : la ligne d'urgence, sobre, sous les deux options. */
.rappel-urgence { max-width: 24rem; margin: 1.25rem auto 0; font-size: .875rem; line-height: 1.45; color: var(--gf-gris); text-align: center; text-wrap: pretty; }
.tchat-fil { display: flex; flex-direction: column; gap: .5rem; height: 17rem; margin: 0; padding: .25rem .15rem; overflow-y: auto; list-style: none; scroll-behavior: smooth; overscroll-behavior: contain; }
.tchat-fil:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; border-radius: 6px; }
/* Un message (le CTO, 08/09, d'après Crisp) : à gauche, une ligne d'en-tête — l'avatar rond de Goodflair (28 px) et le nom
   en petit — puis les bulles en retrait sous le nom. Le visiteur, à droite, n'a ni avatar ni nom. Aucune heure (le CTO, 08/09).
   Deux messages de suite du même auteur : l'en-tête ne vit que sur le premier (`tchat-msg-suite` sur les autres). */
.tchat-msg { display: flex; flex-direction: column; align-items: flex-start; gap: .3rem; max-width: 85%; font-size: .9375rem; line-height: 1.45; }
.tchat-entete { display: flex; align-items: center; gap: .5rem; font-size: .8125rem; font-weight: 600; color: var(--gf-gris-fort); }
.tchat-avatar { flex: none; width: 28px; height: 28px; border-radius: 50%; object-fit: cover; background: var(--gf-blanc); }
.tchat-bulle { padding: .6rem .85rem; border-radius: 14px; white-space: pre-wrap; overflow-wrap: anywhere; }
.tchat-msg-visiteur { align-self: flex-end; align-items: flex-end; }
.tchat-msg-visiteur .tchat-bulle { background: var(--gf-blanc); box-shadow: var(--gf-ombre-porte); border-bottom-right-radius: 4px; }
.tchat-msg-staffer, .tchat-msg-assistant { align-self: flex-start; }
.tchat-msg-staffer .tchat-bulle, .tchat-msg-assistant .tchat-bulle { margin-left: calc(28px + .5rem); background: var(--gf-corail-pale); border-top-left-radius: 4px; }
.tchat-msg-systeme { display: block; align-self: center; max-width: 100%; padding: .2rem .5rem; font-size: .875rem; color: var(--gf-gris); text-align: center; white-space: pre-wrap; overflow-wrap: anywhere; }
.tchat-msg-meta { display: block; padding: 0 .25rem; font-size: .8125rem; color: var(--gf-gris); }
.tchat-msg-suite { margin-top: -.2rem; }
/* L'entrée des bulles de l'assistant, l'une après l'autre, depuis la gauche (le CTO, 08/09) ; le délai est posé par le JS. */
@keyframes tchat-entree { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }
.tchat-msg-entree { animation: tchat-entree .35s ease-out both; }
.tchat-msg-suite .tchat-entete { display: none; }
.tchat-msg-suite .tchat-bulle { border-top-left-radius: 14px; }
/* ——— La zone de saisie (le CTO, 08/09/2026, d'après Crisp) ———
   Un cadre arrondi, blanc, dont le trait prend la couleur active au survol puis au focus ; le message en haut ; en bas la
   ligne des outils (émoji, pièce, dictée) et, à droite, l'envoi — une flèche pâle tant que le message n'a pas deux
   caractères, un bouton corail plein ensuite. Mêmes proportions que Crisp : cadre 12 px, outils 18 px, envoi 32 px. */
.tchat-composeur { position: relative; display: flex; flex-direction: column; margin-top: .75rem; padding: .7rem .8rem .55rem; border: 1.5px solid var(--gf-trait); border-radius: 12px; background: var(--gf-blanc); transition: border-color var(--gf-t-court), box-shadow var(--gf-t-court); }
.tchat-composeur:hover, .tchat-composeur:focus-within { border-color: var(--gf-corail); }
/* 16 px et pas un de moins : sous 16 px, Safari iOS zoome la PAGE HÔTE au focus du champ. */
.tchat-composeur textarea { display: block; width: 100%; min-height: 1.5rem; max-height: 8rem; padding: 0; border: 0; background: transparent; color: var(--gf-encre); font: inherit; font-size: 1rem; line-height: 1.45; resize: none; }
.tchat-composeur textarea::placeholder { color: var(--gf-gris); }
.tchat-composeur textarea:focus { outline: 0; }
.tchat-outils { display: flex; align-items: center; gap: .6rem; margin-top: .45rem; }
.tchat-outil { display: grid; place-items: center; width: 1.5rem; height: 1.5rem; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--gf-gris-fort); cursor: pointer; transition: color var(--gf-t-court), background-color var(--gf-t-court); }
.tchat-outil svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tchat-outil:hover { color: var(--gf-encre); }
.tchat-outil:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; }
.tchat-outil[aria-expanded="true"], .tchat-outil[aria-pressed="true"] { color: var(--gf-corail); background: var(--gf-corail-pale); }
.tchat-outil[aria-pressed="true"] svg { animation: tchat-dictee 1s infinite ease-in-out; }
@keyframes tchat-dictee { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
.tchat-trombone input { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); }
.tchat-trombone:focus-within { outline: 2px solid var(--gf-encre); outline-offset: 2px; }
.tchat-trombone[aria-busy="true"] { opacity: .6; cursor: progress; }
/* L'envoi : pâle et nu tant qu'il n'y a rien à envoyer, un bouton corail plein dès deux caractères. */
.tchat-envoyer { flex: none; display: grid; place-items: center; width: 2rem; height: 2rem; margin-left: auto; padding: 0; border: 0; border-radius: 8px; background: var(--gf-corail); color: var(--gf-blanc); box-shadow: 0 2px 8px rgba(255, 102, 102, .35); cursor: pointer; transition: background-color var(--gf-t-court), color var(--gf-t-court), box-shadow var(--gf-t-court); }
.tchat-envoyer svg { width: 18px; height: 18px; }
.tchat-envoyer:hover { background: var(--gf-corail-survol); }
.tchat-envoyer:focus-visible { outline: 2px solid var(--gf-encre); outline-offset: 2px; }
.tchat-envoyer[disabled] { background: transparent; color: var(--gf-corail-clair); box-shadow: none; cursor: default; }
.tchat-envoyer[disabled] svg path[stroke] { stroke: var(--gf-blanc); }
.tchat-envoyer[aria-busy="true"] { cursor: progress; }
/* Le sélecteur d'émojis : une carte au-dessus de la zone de saisie, la recherche en tête, les grilles par famille. */
.tchat-emojis { position: absolute; left: 0; right: 0; bottom: 100%; z-index: 2; display: flex; flex-direction: column; max-height: 19rem; margin-bottom: .5rem; padding: .6rem .6rem .4rem; border-radius: 14px; background: var(--gf-blanc); box-shadow: 0 8px 28px rgba(24, 21, 47, .18); }
.tchat-emojis-recherche { display: flex; align-items: center; gap: .5rem; padding: 0 .75rem; border: 1.5px solid var(--gf-trait); border-radius: 10px; background: var(--gf-fond); color: var(--gf-gris); }
.tchat-emojis-recherche:focus-within { border-color: var(--gf-corail); }
.tchat-emojis-recherche svg { flex: none; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.tchat-emojis-recherche input { flex: 1; min-width: 0; height: 2.25rem; border: 0; background: transparent; color: var(--gf-encre); font: inherit; font-size: 1rem; }
.tchat-emojis-recherche input:focus { outline: 0; }
.tchat-emojis-liste { flex: 1 1 auto; min-height: 0; margin-top: .5rem; overflow-y: auto; overscroll-behavior: contain; text-align: left; }
.tchat-emojis-famille { margin: .5rem 0 .25rem .25rem; font-size: .8125rem; font-weight: 600; color: var(--gf-gris-fort); }
.tchat-emojis-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(2rem, 1fr)); gap: 2px; }
.tchat-emoji { display: grid; place-items: center; height: 2rem; padding: 0; border: 0; border-radius: 6px; background: transparent; font-size: 1.375rem; line-height: 1; cursor: pointer; }
.tchat-emoji:hover, .tchat-emoji:focus-visible { background: var(--gf-fond); outline: 0; }
.tchat-emojis-rien { margin: 1rem 0; text-align: center; font-size: .9375rem; color: var(--gf-gris); }
/* Le composeur est le repère du sélecteur : la vue doit l'accepter au-dessus du fil. */
.rappel-vue-tchat { position: relative; }
.tchat-msg a { color: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.tchat-vignette { display: block; max-width: 100%; max-height: 12rem; margin: 0 0 .25rem; border-radius: 10px; object-fit: cover; }
.tchat-email { margin-top: .75rem; }
.tchat-email .rappel-champ { margin-top: 0; }
.tchat-email .rappel-consent { margin-top: .4rem; text-align: left; }
.tchat-rappel { margin: .75rem 0 0; text-align: center; }
.tchat-rappel .rappel-cta { margin-top: .6rem; }
/* Ce que seul le lecteur d'écran lit : l'auteur en tête de chaque message, « (nouvel onglet) », le titre du fil. */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* « Mégane écrit… » : une bulle de conseiller à trois points, SŒUR du fil (hors de sa région live), effacée seule. */
.tchat-ecrit { display: inline-flex; align-items: center; gap: .3rem; align-self: flex-start; margin: .5rem 0 0 calc(28px + .5rem); padding: .7rem .85rem; border-radius: 14px; border-bottom-left-radius: 4px; background: var(--gf-corail-pale); }
.tchat-ecrit span { display: block; width: 6px; height: 6px; border-radius: 50%; background: var(--gf-gris-fort); animation: tchat-point 1.2s infinite ease-in-out; }
.tchat-ecrit span:nth-child(2) { animation-delay: .2s; }
.tchat-ecrit span:nth-child(3) { animation-delay: .4s; }
@keyframes tchat-point { 0%, 60%, 100% { opacity: .3; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }
/* L'e-mail au moment qui compte : le champ se signale tant qu'il manque. */
.tchat-email-avant { border-color: var(--gf-corail-clair) !important; box-shadow: 0 0 0 .25rem var(--gf-halo); }
.rappel-squelette-tchat { align-items: stretch; }
.rappel-sq-bulle { width: 70%; height: 2.75rem; border-radius: 14px; }
.rappel-sq-droite { align-self: flex-end; }
.rappel-sq-composeur { width: 100%; height: 3rem; margin-top: .5rem; }
/* ——— Mode modal : la modal annonce la hauteur de son contenu, le panneau la prend (bornée à l'écran) ———
   Chaque écran a sa hauteur naturelle, alignée en haut (le CTO, 08/09). La vue TCHAT seule demande « tout »
   (`body.rappel-plein`, posée par le JS) : le corps prend la hauteur du panneau et le fil, en flex, remplit la
   place et défile en interne — plus de hauteur figée à 17 rem. Rien de ceci ne touche les pages autonomes. */
body.rappel-mode-modal .rappel-vue { min-height: 0; justify-content: flex-start; }
/* Dans le panneau, l'écran des portes doit tenir dans 660 px (Chromebook 1366 × 768 moins la marge) sans défiler :
   l'avatar s'efface (la page hôte l'affiche déjà en tête du tunnel), l'air du haut et les intertitres se resserrent —
   737 px → 615 mesurés. Les pages autonomes gardent l'avatar. */
body.rappel-mode-modal .rappel { padding-top: 2rem; }
body.rappel-mode-modal .rappel-avatar { display: none; }
body.rappel-mode-modal .rappel-groupe { margin-top: 1.25rem; }
html.rappel-plein, body.rappel-plein { height: 100%; }
body.rappel-plein .rappel { display: flex; flex-direction: column; height: 100%; }
body.rappel-plein .rappel-vue-tchat { flex: 1 1 auto; min-height: 0; }
body.rappel-plein .tchat-fil { flex: 1 1 0; min-height: 6rem; height: auto; }
/* Le clavier du téléphone réduit l'iframe (la page hôte la cale sur le viewport visuel) : légitime ici, la
   hauteur vient de l'hôte. Le champ e-mail se replie, le composeur reste au-dessus du clavier. */
@media (max-height: 420px) {
    body.rappel-plein .tchat-email { display: none; }
    body.rappel-plein .rappel { padding-top: 1.25rem; }
}

/* ——————————————————————— Le squelette ——————————————————————— */
.rappel-squelette { display: flex; flex-direction: column; align-items: center; gap: var(--gf-frere); }
.rappel-sq { display: block; border-radius: var(--gf-r-bloc); background: linear-gradient(90deg, var(--gf-trait-fin) 25%, #f6f7f9 50%, var(--gf-trait-fin) 75%) 0 0 / 200% 100%; animation: rappel-lueur 1.4s linear infinite; }
.rappel-sq-avatar { width: 79px; height: 79px; border-radius: 50%; margin-bottom: .4rem; }
.rappel-sq-titre { width: 78%; height: 1rem; border-radius: 4px; }
.rappel-sq-titre.rappel-sq-court { width: 45%; margin-bottom: 1rem; }
.rappel-sq-groupe { width: 40%; height: .75rem; border-radius: 4px; margin: .75rem 0 .25rem; }
.rappel-sq-porte { width: 100%; height: 4rem; }

/* ——————————————————————— La page du lien SMS ———————————————————————
   Un en-tête au-dessus de la modal : la promesse en cours, puis les mêmes écrans. */
body.rappel-mode-lien .rappel-lien-entete { max-width: 30rem; margin: 0 auto; padding: 0 1.25rem; background: none; border-radius: 0; box-shadow: none; text-align: center; }
.rappel-titre { max-width: 25rem; margin: 0 auto var(--gf-lie); font-family: var(--gf-serif); font-weight: 700; font-size: clamp(1.25rem, 6vw, 1.5rem); line-height: 1.2; text-wrap: balance; }
.rappel-muted { margin: 0; font-size: .875rem; line-height: 1.5; color: var(--gf-gris); text-wrap: pretty; }
.rappel-promesse { margin: 0 0 .5rem; padding: .8rem 1rem; border-radius: var(--gf-r-bloc); background: var(--gf-vert-fond); border-left: 3px solid var(--gf-vert); text-align: left; }
.rappel-promesse-finale { font-family: var(--gf-serif); font-weight: 700; font-size: clamp(1.375rem, 7vw, 1.75rem); line-height: 1.15; }

/* La page hôte annonce la hauteur dont elle dispose (`?h=`) : dans l'iframe, une media query de
   hauteur mesurerait l'iframe, dont la hauteur vient du contenu — la règle serait circulaire. */
body.rappel-h-court.rappel-mode-modal .rappel { padding-top: 1.75rem; }
body.rappel-h-court .rappel-groupe { margin-top: 1.5rem; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .001ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
    .rappel-porte:hover, .rappel-creneau:hover { transform: none; }
    .tchat-fil { scroll-behavior: auto; }
    .tchat-msg-entree, .tchat-fondu { animation: none; }
    .tchat-pattes svg { animation: none; opacity: .7; }
}

/* ——————————————————————— ESSAI (le CTO, 09/09/2026) : la porte « chat » se signale ———————————————————————
   La bulle vient d'être cliquée : il y a de fortes chances que la personne veuille écrire — les autres portes restent,
   elle ne les connaissait peut-être pas. La carte prend une ombre rose pâle (la couleur des icônes du site), très
   légère, qui monte en un demi-seconde, tient deux secondes et s'efface — comme si la carte était un peu édulcorée.
   Joué une fois, rejouable (la classe tombe à la fin de l'animation). Rien d'autre ne bouge. */
.rappel-porte-accent { animation: gf-accent-tchat 2.4s ease-in-out forwards; }
@keyframes gf-accent-tchat {
    0%   { box-shadow: var(--gf-ombre-porte); }
    16%  { box-shadow: var(--gf-ombre-porte), 0 0 0 2px var(--gf-corail-pale), 0 4px 12px 0 var(--gf-corail-pale); }
    66%  { box-shadow: var(--gf-ombre-porte), 0 0 0 2px var(--gf-corail-pale), 0 4px 12px 0 var(--gf-corail-pale); }
    100% { box-shadow: var(--gf-ombre-porte); }
}
@media (prefers-reduced-motion: reduce) {
    .rappel-porte-accent { animation-timing-function: linear; }
}
