/*
 * Feuille de style unique du site.
 *
 * Aucun framework, aucun build : ce fichier est servi tel qu'il est ecrit.
 *
 * SOURCE — la maquette 6a, dans docs/charte/design_handoff_site_hypnose/ : son
 * README porte les tokens, les espacements et les rayons, et fait foi. Ce qui
 * suit les recopie ; ce qui s'en ecarte est signale sur place, avec sa raison.
 *
 * Trois regles de la charte ne se contournent pas :
 *   - l'ORANGE n'est jamais cliquable et n'ecrit jamais : 2,20:1 sur le creme.
 *     Il ponctue — pastille du heros, soulignement de la page courante, puce du
 *     sur-titre, initiale « O ». Trois a quatre touches par page, pas davantage.
 *     L'action, elle, est toujours bleue ;
 *   - le focus clavier est ORANGE et visible partout : le tunnel de reservation
 *     se parcourt entierement au clavier ;
 *   - aucune police distante. Caprasimo et Figtree sont auto-hebergees ci-dessous
 *     (spec §9 : RGPD et performance).
 *
 * UN ECART ASSUME SUR LA PALETTE : le README donne #7a6e60 en « texte discret ».
 * Pose sur le sable de la carte « Le cabinet », il ne fait que 3,94:1 — sous le
 * minimum WCAG de 4,5:1 pour du texte de 12 a 15 px. Il est remplace partout par
 * #6b6055, de teinte indiscernable : 4,86:1 sur le sable, 5,88:1 sur le creme.
 * Un seul token, et non deux, pour qu'on ne puisse pas choisir le mauvais.
 */

/* --- Polices auto-hebergees -------------------------------------------------
 *
 * Figtree est une VARIABLE FONT : un seul fichier de 20 Ko couvre 400 a 700.
 * Ne pas y ajouter de fichier par graisse, il n'en existe pas.
 * Le latin-ext n'est telecharge que si un caractere de sa plage apparait :
 * sur un site francais, il ne part quasiment jamais.
 */

@font-face {
    font-family: "Caprasimo";
    src: url("polices/caprasimo-400-latin.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
        U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
        U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Figtree";
    src: url("polices/figtree-var-latin.woff2") format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
        U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
        U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Figtree";
    src: url("polices/figtree-var-latin-ext.woff2") format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
        U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
        U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
        U+A720-A7FF;
}

/* --- Tokens ----------------------------------------------------------------- */

:root {
    /* Surfaces */
    --creme: #fdfaf5;        /* fond de page                                   */
    --sable: #f2e3ce;        /* cercle du heros, carte « Le cabinet »          */
    --sauge: #e8eedc;        /* panneau « Pourquoi l'hypnose ? »               */
    /* Le titre DANS le panneau. Egal a --encre aujourd'hui, et distinct de lui
       parce que le handoff le nomme `panelHeading` : le jour ou le panneau
       s'assombrit, son H2 se reprend ici et nulle part ailleurs. */
    --panneau-titre: #1b2740;
    --champ: #fdf7ef;        /* fond des champs de saisie                      */
    --photo: #e3cfb4;        /* emplacement d'image, avant chargement          */

    /* Encres — contrastes mesures sur le creme #fdfaf5 */
    --encre: #1b2740;        /* 14,30:1 — titres                               */
    --texte: #4a4239;        /*  9,47:1 — texte courant                        */
    --discret: #6b6055;      /*  5,88:1 — mentions, sur-titres discrets        */
    --bleu: #14509b;         /*  7,61:1 — action, liens                        */
    --bleu-fonce: #0f3d78;   /* survol de l'action                             */
    --vert: #4f8a3a;         /*  4,01:1 — initiales P, R, G (gros texte seul)   */
    --brique: #b8620d;       /*  4,21:1 — initiale O (gros texte seul)         */
    --roux: #864200;         /*  7,22:1 — « PRATICIENNE EN HYPNOSE »           */
    --orange: #f0972a;       /*  2,20:1 — APLATS ET FOCUS SEULEMENT, jamais du texte */

    /* Filets */
    --trait: rgba(62, 44, 30, .16);
    --trait-champ: rgba(62, 44, 30, .24);
    --trait-fort: rgba(62, 44, 30, .32);
    --trait-doux: rgba(62, 44, 30, .18);

    /* Les quatre teintes d'occupation du calendrier de reservation. Ce n'est pas
       une palette de plus : c'est la sauge, le sable et l'orange du handoff,
       eclaircis sur le creme, plus un gris chaud pour « complet ». L'encre y garde
       partout plus de 10:1 — obligatoire, le chiffre d'une case est petit. */
    --case-libre: #dfead0;
    --case-partiel: #f7ead3;
    --case-presque: #f9dcb4;
    --case-complet: #e9e0d7;

    /* Les boutons secondaires de l'admin (21/08/2026, adoucis le soir meme).
       **En contour, jamais en aplat** : deux pastilles saturees posees dans chaque
       creneau ecrasaient une page dont tout le reste est creme et sable, et volaient
       la hierarchie au bleu de l'action principale. Le fond pale, la bordure teintee
       et le texte fonce disent la meme chose sans crier.

       Le vert pale est **deja un jeton de la charte** — c'est la teinte « libre » du
       calendrier —, et le brique pale est son pendant chaud. Contrastes du texte sur
       son propre fond : 5,91:1 pour le vert, 6,02:1 pour la brique ; les bordures
       tiennent 3,3:1, le minimum d'un element non textuel. */
    --geste-vert-fond: #dfead0;      /* identique a --case-libre                  */
    --geste-vert-trait: #4f8a3a;     /* --vert                                    */
    --geste-vert-texte: #35601f;     /*  5,91:1 sur son fond                      */
    --geste-vert-survol: #d3e2be;    /* le fond, d'un cran                        */
    --geste-rouge-fond: #f7ddd0;
    --geste-rouge-trait: #b8620d;    /* --brique                                  */
    --geste-rouge-texte: #8a3a0a;    /*  6,02:1 sur son fond                      */
    --geste-rouge-survol: #f0cdba;

    /* L'aplat du seul bouton qui **acte** une annulation. Il reste plein, et c'est
       voulu : c'est le point de non-retour, pas un bouton qui ouvre. */
    /* Le fond d'un creneau **pris**, dans l'agenda de l'admin (25/08/2026). Chacun
       reprend la teinte du filet de gauche, delavee jusqu'a porter le texte courant
       sans le gener : sur les quatre, --texte tient au-dela de 7,9:1, --discret
       au-dela de 4,9:1 et --encre au-dela de 11,9:1. */
    --creneau-confirme-fond:  #e9eff8;   /* --bleu    */
    --creneau-attente-fond:   #fdeed6;   /* --orange  */
    --creneau-a-confirmer-fond: #f1ece6; /* --discret */
    --creneau-proposee-fond:  #f7e3d3;   /* --brique  */

    --rouge-geste: #a4300f;
    --rouge-geste-survol: #8a2709;

    /* Le message d'erreur d'un formulaire et l'avis de l'admin. Ils vivaient en
       dur sur leurs selecteurs jusqu'au 26/08/2026 ; les remonter ici est ce qui
       permet de reprendre une teinte sans ouvrir le selecteur qui la porte. */
    --erreur-fond: #fdf0ec;
    --erreur-trait: #c4462a;
    --erreur-texte: #7a2612;
    --avis-trait: rgba(79, 138, 58, .45);
    --avis-texte: #2f5222;

    /* Le bandeau de l'admin : son fond est l'encre, ses liens doivent donc etre
       clairs — ce ne sont ni --bleu ni --texte, qui y disparaitraient. */
    --admin-lien: #cfd8e6;
    --admin-lien-vif: #ffffff;
    --bandeau-trait: rgba(255, 255, 255, .45);
    --bandeau-survol: rgba(255, 255, 255, .12);

    /* Le voile d'un bouton en contour au survol : le texte courant, dilue dans le
       fond de page — et non un gris fixe, qui jurerait sur le creme. */
    --voile-survol: rgba(62, 44, 30, .05);

    /* Les initiales P.R.O.G. **sur mobile**. Sous 24 px, une initiale n'est plus
       du « gros texte » au sens WCAG : il lui faut 4,5:1 et non 3:1, et --vert
       comme --brique n'y suffisent plus (4,01 et 4,21). */
    --vert-fonce: #3d6b28;           /*  6,05:1 sur le creme                     */
    --brique-fonce: #8a3a0a;         /*  7,50:1 sur le creme                     */

    --ombre-carte: 0 10px 24px rgba(60, 40, 24, .07);

    /* --- Typographie ---------------------------------------------------------
     *
     * Les valeurs ci-dessous sont le jeu « 10a — Caprasimo allegee » de
     * docs/charte/design_handoff_typo/typography.json, **retenu par la cliente le
     * 31/08/2026** : c'est desormais le jeu du site, et il n'y en a plus d'autre.
     *
     * Ce sont des TOKENS et non des valeurs ecrites sur les selecteurs, pour la
     * meme raison que les couleurs — un role typographique se change ici, en un
     * endroit, sans ouvrir un seul selecteur.
     *
     * ⚠️ **Le jeu du handoff etait « 6a »** — H1 a 62 px —, et la lourdeur qu'on
     * lui reprochait venait de la taille des titres, pas de la graisse. Caprasimo
     * n'a qu'une graisse : la retoucher par un `font-weight` donnerait un faux
     * gras baveux, jamais un titre plus leger.
     *
     * Les tailles interpolent entre les deux seules largeurs maquettees, 390 px
     * et 1180 px, par un `clamp()` dont la borne haute est la valeur du JSON et
     * la borne basse son rapport mobile (0,613 pour H1, 0,778 pour H2, 0,9 pour
     * H3 et la marque — les rapports du README principal). Aux deux bornes, la
     * valeur est exacte.
     */
    --titre-police: "Caprasimo", Georgia, "Times New Roman", serif;
    --texte-police: "Figtree", system-ui, -apple-system, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;

    --h1-taille: clamp(2.1452rem, 1.4763rem + 2.744vw, 3.5rem); /* 34,3 → 56 px */
    --h1-interligne: 1.12;
    --h1-espacement: -.005em;
    --h2-taille: clamp(1.5069rem, 1.2944rem + 0.872vw, 1.9375rem); /* 24,1 → 31 px */
    --h2-interligne: 1.2;
    --h2-espacement: 0;
    --h3-taille: 1.1562rem;                                     /* 18,5 px    */
    --h3-interligne: 1.2;
    --marque-taille: 1.375rem;                                  /* 22 px      */
    --marque-interligne: 1.08;
    --marque-espacement: 0;
    /* La graisse des titres. **Caprasimo n'existe qu'en 400** : c'est le jeu
       typographique qui a le droit de monter, jamais un selecteur. Une graisse
       plus haute demandee a une police qui ne l'a pas donne un faux gras baveux,
       synthetise par le navigateur. */
    --titre-graisse: 400;

    /* Le mot des cartes P.R.O.G. — « Prendre », « Retrouver »… — est un H3
       agrandi, et il suit donc le jeu typographique. Le rapport 1,4 est celui de
       la maquette 6a : H3 a 20 px, mot a 28 px. Le role `initial` du JSON, lui,
       n'a plus de cible : la lettre isolee a disparu le 26/08/2026. */
    --prog-taille: calc(var(--h3-taille) * 1.4);

    --page: 1180px;
    --marge: 3rem;           /* 48 px — 24 px en dessous de 720 px             */
}

/* --- Base -------------------------------------------------------------------- */

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

body {
    margin: 0;
    font-family: var(--texte-police);
    font-size: 1.0625rem;    /* 17 px */
    line-height: 1.7;
    color: var(--texte);
    background: var(--creme);
    -webkit-text-size-adjust: 100%;
}

h1, h2, h3 {
    font-family: var(--titre-police);
    font-weight: var(--titre-graisse);
    color: var(--encre);
    margin: 0 0 0.5em;
}

/* Tailles, interlignes et interlettrages : des tokens, jamais des valeurs ecrites
   ici. C'est ce qui permet de reprendre un role typographique en un seul endroit,
   sans toucher a un selecteur. */
h1 { font-size: var(--h1-taille); line-height: var(--h1-interligne); letter-spacing: var(--h1-espacement); }
h2 { font-size: var(--h2-taille); line-height: var(--h2-interligne); letter-spacing: var(--h2-espacement); }
h3 { font-size: var(--h3-taille); line-height: var(--h3-interligne); }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--bleu); }
a:hover { color: var(--bleu-fonce); }

img { max-width: 100%; }

/* Le focus visible est une exigence d'accessibilite, pas une decoration.
   C'est le seul emploi de l'orange sur un element interactif : il ne le rend
   pas cliquable, il montre ou l'on est. */
:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 2px;
}

/* Visible des qu'on l'atteint au clavier, invisible sinon. */
.evitement {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--bleu);
    color: var(--creme);
    padding: 0.75rem 1.25rem;
    border-radius: 0 0 999px 999px;
    text-decoration: none;
    z-index: 10;
}

.evitement:focus {
    left: 1rem;
    color: var(--creme);
}

/* --- Structure ---------------------------------------------------------------- */

.contenu {
    max-width: var(--page);
    margin: 0 auto;
    padding-left: var(--marge);
    padding-right: var(--marge);
}

/* Les sections de l'accueil portent leur propre respiration : les valeurs du
   README sont des paddings de section, pas une regle uniforme. */
.section { padding-bottom: 4.75rem; }  /* 76 px */

/* De l'air entre le bandeau et le premier titre d'une page en mise en page
   « large » (26/08/2026). Les sections n'ont qu'un padding **bas** : sur l'accueil
   le heros pose le sien, mais sur les pages de contenu le premier titre venait
   coller la bordure du menu.
 *
 * ⚠️ Elle ne touche pas l'accueil, dont le premier enfant est `.heros` et non
 * `.section` : `:first-child` echoue alors, ce qui est exactement voulu. */
main > .section:first-child { padding-top: 3.25rem; }   /* 52 px, comme .page-texte */

/* ⚠️ **La bande du heros n'est plus le fond de la page** (26/08/2026) : les 4,5 rem
   qu'elle porte en bas sont *dedans*, en sable. Sans cette regle, le titre de la
   section suivante viendrait coller la bande de couleur. */
.heros + .section { padding-top: 4.5rem; }   /* 72 px */

/* Toute page qui n'est pas l'accueil : une colonne, et de l'air au dessus comme
   en dessous. Le tunnel de reservation et les pages a jeton passent par la. */
.page-texte {
    padding-top: 3.25rem;
    padding-bottom: 4.5rem;
}

/* --- Bandeau ------------------------------------------------------------------- */

/* La bordure court sur toute la largeur de l'ecran, alors que la maquette
   l'arretait a 1180 px : au dela, un filet suspendu au milieu du vide se lit
   comme un defaut. Le contenu, lui, reste contenu. */
.entete {
    border-bottom: 1px solid var(--trait);
    background: var(--creme);
}

.entete .contenu {
    display: flex;
    align-items: center;
    gap: 1.625rem;           /* 26 px */
    flex-wrap: wrap;
    padding-top: 1.125rem;   /* 18 px */
    padding-bottom: 1.125rem;
}

.identite {
    display: flex;
    align-items: center;
    gap: 0.875rem;           /* 14 px */
    text-decoration: none;
}

/* Dimensions declarees : le navigateur reserve la place et la page ne saute pas
   au chargement du logo. Le fichier fait 156 px, soit deux fois sa taille
   d'affichage — la densite x2 est servie sans srcset. */
.identite img {
    display: block;
    width: 4.875rem;         /* 78 px */
    height: 4.875rem;
}

.identite-nom {
    display: block;
    font-family: var(--titre-police);
    font-size: var(--marque-taille);
    font-weight: var(--titre-graisse);
    line-height: var(--marque-interligne);
    letter-spacing: var(--marque-espacement);
    color: var(--encre);
}

.identite-role {
    display: block;
    font-size: 0.78125rem;   /* 12,5 px */
    letter-spacing: .1em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--roux);
    margin-top: 5px;
    text-align: center;
}

.navigation {
    display: flex;
    align-items: center;
    gap: 1.625rem;
    margin-left: auto;
}

.navigation ul {
    display: flex;
    gap: 1.375rem;           /* 22 px */
    margin: 0;
    padding: 0;
    list-style: none;
}

/* ⚠️ Ces trois regles visent « ul a » et non « a » : le bouton « Prendre
   rendez-vous » vit dans la meme <nav>, et « .navigation a » l'emportait sur
   « .bouton-principal » — un bouton bleu a texte sombre, illisible. */
.navigation ul a {
    font-size: 0.90625rem;   /* 14,5 px */
    font-weight: 600;
    color: var(--encre);
    text-decoration: none;
}

.navigation ul a:hover { color: var(--bleu); }

/* Le soulignement orange de l'entree courante : deuxieme des trois touches de
   la page, et la seule qui ne soit pas decorative. */
.navigation ul a.courante {
    border-bottom: 2px solid var(--orange);
    padding-bottom: 3px;
}

/* Le menu deroulant de mobile, SANS JavaScript.
 *
 * La bascule est une vraie case a cocher : elle reste focalisable et s'active a
 * la barre d'espace. Un <label tabindex="0"> aurait l'air de marcher a la
 * souris et serait mort au clavier — c'est le piege classique de ce motif.
 * En bureau, la case et son bouton n'existent pas.
 */
.menu-bascule { display: none; }
.menu-bouton { display: none; }

/* --- Boutons --------------------------------------------------------------------- */

.bouton {
    display: inline-block;
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 0.9375rem 1.75rem;   /* 15 / 28 px */
    font-family: var(--texte-police);
    font-size: 0.96875rem;        /* 15,5 px */
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 140ms ease, color 140ms ease;
}

.bouton-principal {
    background: var(--bleu);
    color: var(--creme);
}

.bouton-principal:hover {
    background: var(--bleu-fonce);
    color: var(--creme);
}

.bouton-second {
    background: transparent;
    color: var(--encre);
    border-color: var(--trait-fort);
}

.bouton-second:hover {
    background: var(--voile-survol);
    color: var(--encre);
}

/* Le bouton du bandeau est plus petit que ceux du heros. */
.entete .bouton {
    font-size: 0.90625rem;        /* 14,5 px */
    padding: 0.75rem 1.375rem;    /* 12 / 22 px */
}

/* --- Heros ------------------------------------------------------------------------
 *
 * Une **bande de couleur pleine largeur** (26/08/2026, Bjorn), et le portrait qui en
 * occupe toute la hauteur, coupe a vif par le bord de la page. ⛔ **Plus aucune forme
 * decorative** : les trois cercles de la maquette 6a — sable, sauge, pastille orange —
 * ont ete retires, Bjorn y lisant « une signature trop evidente de vibe coding ». Ne
 * pas les faire revenir en relisant le handoff, qui les decrit toujours.
 *
 * ⚠️ **Le fond est porte par `.heros`, pas par `.contenu`** : celui-ci est borne a
 * 1180 px et centre, donc une bande posee sur lui s'arreterait a sa marge. Meme
 * raison pour le portrait, qui vit **hors** du `.contenu`.
 */
.heros {
    position: relative;
    background: var(--sable);
    overflow: hidden;             /* c'est ce qui coupe le portrait a vif */
}

.heros .contenu {
    position: relative;
    z-index: 1;                   /* le texte passe devant l'image, jamais dessous */
    padding-top: 4rem;            /* 64 px — voir la marge de .heros-surtitre */
    padding-bottom: 4.5rem;       /* 72 px */
}

/* ⚠️ **Cette largeur est ce qui empeche le texte de passer sous le portrait.** Le
   portrait occupe au plus 30 rem a droite de l'ecran ; au point d'arret de 1024 px, le
   texte finit encore 80 px avant lui. L'elargir sans toucher au point d'arret les
   ferait se chevaucher sur les largeurs intermediaires. */
.heros-texte { max-width: 32rem; }   /* 512 px */

/* Le surtitre : un trait orange, puis la specialite et le lieu en petites capitales.
 *
 * ⚠️ **C'est la seule touche d'orange qui reste sur l'accueil** depuis que les formes
 * decoratives ont disparu, et elle est **decorative** : ce que le trait dirait, le
 * texte a cote le dit deja. L'orange ne porte jamais de texte (charte) — d'ou le roux
 * pour les mots, qui tient 5,96:1 sur le sable. */
.heros-surtitre {
    display: flex;
    align-items: center;
    gap: 0.75rem;                 /* 12 px */
    font-size: 0.6875rem;         /* 11 px */
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--roux);
    /* ⚠️ **Cette marge et le `padding-top` du heros se lisent ensemble** (Bjorn,
       26/08/2026, « un peu plus haut ») : le premier a ete raccourci de 16 px pour
       remonter le surtitre, la seconde allongee d'autant pour que le titre, lui, ne
       bouge pas. Ne pas toucher a l'une sans l'autre. */
    margin: 0 0 1.75rem;
}

.heros-surtitre::before {
    content: "";
    width: 1.5rem;                /* 24 px */
    height: 2px;
    background: var(--orange);
    flex: none;
}

/* ⛔ **Ce style vise le paragraphe d'introduction, et lui seul.** Il s'ecrivait
   `.heros p` jusqu'au 26/08/2026, et cette regle d'element a mange le surtitre le jour
   ou celui-ci est arrive : `.heros p` (0,1,1) l'emporte sur `.heros-surtitre` (0,1,0),
   si bien que le surtitre heritait de la taille du paragraphe **et** de sa marge en
   haut — donc aucune marge en bas, collant le titre. Ne pas revenir a un selecteur
   d'element ici : le heros porte plusieurs `<p>`. */
.heros-intro {
    font-size: 1.125rem;          /* 18 px */
    line-height: 1.65;
    max-width: 46ch;
    margin: 1.75rem 0 0;
}

.heros-actions {
    display: flex;
    gap: 0.875rem;                /* 14 px */
    flex-wrap: wrap;
    margin-top: 2.125rem;         /* 34 px */
}

/* Le portrait du heros : colle en haut, en bas et a droite de la bande, donc coupe
   par le bord de la page. Sa largeur suit l'ecran sans jamais depasser 30 rem — au
   dela, il mangerait la moitie d'un grand ecran. */
.heros-portrait {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: clamp(18rem, 34vw, 30rem);
    background: var(--photo);     /* la place est tenue avant le chargement */
}

/* ⚠️ **`object-fit` decide seul du cadrage** : le fichier est carre (680 x 680) et la
   bande ne l'est pas. `object-position` remonte le cadre a 30 % de la hauteur, la ou
   se trouve le visage — au centre, un format haut coupe le front.
 *
 * Les attributs width et height de la balise restent : ils reservent la place au
 * chargement. Ils ne font pas loi ici, le CSS surchargeant les deux. */
/* ⛔ **Aucun filtre ici** (Bjorn, 26/08/2026) : le « washed » du design system —
   `saturate(.6) contrast(.85) brightness(1.1) opacity(.94)` — posait un voile qui
   mangeait le contraste du visage. Il n'a de sens que sur le medaillon de
   `/a-propos/`, ou l'image est petite et ronde. Ne pas le remettre « pour aligner ». */
.heros-portrait img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 30%;
}

/* La grille « texte a gauche, portrait a droite ». Elle s'appelait `heros-grille`
   jusqu'au 26/08/2026, date a laquelle le heros a cesse d'etre une grille : le nom
   ne decrivait plus que sa seule page restante, `/a-propos/`. */
.presentation {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 21.25rem;   /* 340 px */
    gap: 3.5rem;                                      /* 56 px */
    align-items: center;
}

/* --- Le medaillon rond -------------------------------------------------------------
 *
 * Il ne sert plus qu'a `/a-propos/` : le heros a pris une bande pleine largeur le
 * 26/08/2026, et son portrait n'est plus un medaillon.
 *
 * ⚠️ C'est le CONTENEUR qui impose le carre, et l'image qui le remplit. L'image porte
 * des attributs width et height — necessaires pour que le navigateur reserve la place —
 * et ces attributs font loi tant que le CSS ne les surcharge pas tous les deux : une
 * image de 680 px de haut dans une colonne de 340 donnait un ovale de 340 x 680, qui
 * allongeait toute la section de 272 px.
 */
.portrait {
    width: 100%;
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: hidden;
    background: var(--photo);
}

/* Le « washed » du design system, et il ne s'applique qu'une fois : ne pas le
   reappliquer au fichier. */
.portrait img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: saturate(0.6) contrast(0.85) brightness(1.1) opacity(0.94);
}

/* --- Bloc a deux colonnes : titre a gauche, texte a droite -------------------------- */

.duo {
    display: grid;
    grid-template-columns: minmax(0, 21.25rem) minmax(0, 1fr);
    gap: 3.5rem;
    align-items: start;
}

.duo p {
    max-width: 62ch;
    margin-bottom: 1.125rem;      /* 18 px */
}

/* ⛔ Le titre d'une page vit dans une colonne de 340 px, et Caprasimo est large :
 * « Accompagnements » y mesure 593 px a la taille de bureau. Il debordait sur la
 * colonne de texte (Bjorn, 26/08/2026). Le filet ci-dessous empeche un titre qu'on
 * n'aurait pas traite de sortir de sa colonne, au prix d'une coupure sans trait
 * d'union — c'est un garde-fou, pas une mise en page.
 *
 * Regle pratique : dans un titre de page, tout mot de plus de onze lettres deborde. */
.duo > h1, .duo > h2 { overflow-wrap: break-word; }

/* La variante pour un titre qu'aucune colonne de 340 px ne peut tenir : il enjambe
 * les deux colonnes, le texte reste dans celle de droite (Bjorn, 26/08/2026, sur
 * « Accompagnements »). Deux essais ecartes avant celui-la : le couper par un `&shy;`
 * — le mot s'affichait en deux morceaux sur un ecran large —, et elargir la colonne
 * du titre a son contenu, qui donnait a cette page-la un titre de 593 px, plus lourd
 * que ceux des trois autres.
 *
 * ⚠️ **Les deux `grid-column` vont ensemble** : sans celui du `div`, le texte
 * repartirait dans la colonne de gauche, sous le titre. Et `row-gap` retombe a zero,
 * la marge basse du `h1` — 0,5 em — suffisant a l'ecart ; les 3,5 rem de `gap`
 * s'y ajouteraient. */
.duo-titre-large { row-gap: 0; }
.duo-titre-large > h1 { grid-column: 1 / -1; }
.duo-titre-large > div { grid-column: 2; }

/* --- Panneau sauge et cartes P.R.O.G. ----------------------------------------------- */

.panneau {
    background: var(--sauge);
    border-radius: 4rem;          /* 64 px */
    padding: 3.75rem;             /* 60 px */
}

.panneau > h2 { margin-bottom: 2.25rem; color: var(--panneau-titre); }

.atouts {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1.125rem;                /* 18 px */
    margin: 0;
    padding: 0;
    list-style: none;
}

.atout {
    background: var(--creme);
    border-radius: 2.125rem;      /* 34 px */
    padding: 1.75rem;             /* 28 px */
    box-shadow: var(--ombre-carte);
}

.atout h3 { margin: 0 0 0.5rem; }

/* Les quatre cartes P.R.O.G. de l'accueil, et elles seules (26/08/2026).
 *
 * La maquette 6a posait la lettre seule au dessus du mot — « P » puis « Preparer ».
 * Bjorn l'a retiree : c'est la premiere lettre du mot qui porte la couleur, et le mot
 * grossit d'autant. La lettre isolee etait `aria-hidden`, donc lue nulle part, et
 * repetait a l'ecran ce que le titre disait juste en dessous.
 *
 * ⚠️ La classe existe pour que les autres grilles de cartes — celles des pages de
 * contenu, qui portent une phrase et non un mot — gardent leur h3 de 20 px. Ne pas
 * remonter ces regles sur `.atout` tout court. */
.atouts-prog .atout h3 {
    font-size: var(--prog-taille);   /* 28 px en 6a — « Retrouver » tient dans la carte */
    line-height: 1.15;
    margin: 0 0 0.5rem;
}

/* L'initiale coloree. Le « O » d'Organiser passe au brique : deuxieme touche
   d'orange de la page, et le decalage est voulu — ne pas l'uniformiser. */
.atouts-prog .initiale { color: var(--vert); }
.atouts-prog .initiale-brique { color: var(--brique); }

.atout p {
    font-size: 0.9375rem;         /* 15 px */
    line-height: 1.6;
    margin: 0;
}

/* Trois colonnes plutot que quatre : les cartes des pages de contenu portent une
   phrase, pas quatre mots. Deux quand la page n'a que deux cartes — « L'hypnose »
   depuis que la cliente a fait retirer l'hypnose regressive (26/08/2026) : sans
   cette classe, ses deux cartes se serreraient sur une grille de quatre. */
.atouts-trois { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.atouts-deux { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Un paragraphe qui annonce un contenu a venir. Il porte sa classe pour qu'on
   puisse tous les retrouver — et verifier qu'il n'en reste aucun avant la mise
   en ligne :  grep -rn 'a-ecrire' site/gabarits/ */
.a-ecrire {
    font-style: italic;
    color: var(--discret);
    border-left: 3px solid var(--sable);
    padding-left: 0.875rem;
}

/* --- Tableaux ------------------------------------------------------------------------
 *
 * Le conteneur defile horizontalement plutot que de faire deborder la page : sur
 * un telephone, c'est la seule facon de garder un tableau lisible sans le casser.
 */

.tableau {
    overflow-x: auto;
    border: 1px solid var(--trait);
    border-radius: 2rem;
    background: var(--champ);
}

.tableau table {
    width: 100%;
    border-collapse: collapse;
    text-align: left;
}

.tableau caption { text-align: left; }

.tableau th, .tableau td {
    padding: 1rem 1.75rem;
    vertical-align: top;
    border-bottom: 1px solid var(--trait);
}

.tableau thead th {
    font-family: var(--titre-police);
    font-weight: 400;
    font-size: 1.0625rem;
    color: var(--encre);
    background: var(--sable);
}

.tableau tbody th {
    font-weight: 600;
    color: var(--encre);
}

/* ⛔ **La valeur d'un tableau est une classe, pas un `td`.** Ces trois declarations
   ont ete ecrites pour la grille tarifaire, ou une cellule porte « 70 € » : posees sur
   tout `td`, elles mettaient en bleu gras — et sur une seule ligne, donc en debordement
   — les phrases entieres du tableau de la page de confidentialite (26/08/2026). */
.tableau td.valeur {
    white-space: nowrap;
    font-weight: 600;
    color: var(--bleu);
}

/* Un tableau de trois colonnes de **texte**. Le dimensionnement automatique les
   repartit mal — la colonne des durees, la plus courte, ressortait la plus large —,
   d'ou des largeurs declarees. Sa largeur minimale le fait defiler dans son conteneur
   sur un telephone plutot que de se tasser en trois colonnes illisibles. */
.tableau-trois table {
    table-layout: fixed;
    min-width: 40rem;             /* 640 px */
}

.tableau-trois thead th:nth-child(1) { width: 34%; }
.tableau-trois thead th:nth-child(2) { width: 40%; }
.tableau-trois thead th:nth-child(3) { width: 26%; }

/* Trois colonnes ne supportent pas les 28 px de marge laterale de la grille
   tarifaire, qui n'en a que deux. */
.tableau-trois th, .tableau-trois td {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
}

.tableau tr:last-child th, .tableau tr:last-child td { border-bottom: 0; }

.tableau .aide { font-weight: 400; margin-top: 0.25rem; }

/* --- Bloc d'appel, en bas des pages de contenu ---------------------------------------- */

.appel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 3.5rem;
    align-items: center;
    background: var(--sable);
    border-radius: 4rem;
    padding: 3rem 3.75rem;
}

.appel h2 { margin-bottom: 0.5rem; }
.appel p:last-child { max-width: 52ch; }

.appel-actions {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}

/* Visible des lecteurs d'ecran, invisible a l'oeil : un titre de tableau qui n'a
   pas sa place dans la mise en page mais qui manquerait a qui ne la voit pas. */
.invisible {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --- Blog (14/09/2026) --------------------------------------------------------------
 *
 * Un article se lit dans une colonne de 42 rem, comme le tunnel : il ne se met pas
 * en deux colonnes. Le corps vient de l'editeur de l'admin, nettoye au stockage
 * par liste blanche de balises — rien ici ne suppose une classe dedans, seulement
 * `p`, `h2`, `h3`, `ul`, `ol`, `blockquote`, `a`, `strong`, `em`.
 */

/* La colonne de lecture se centre : calee a gauche, le vide a sa droite se lisait
   comme une place manquante — pour des photos, croyait-on — et non comme une largeur
   de lecture (Bjorn, 14/09/2026). Le texte reste aligne a gauche dans la colonne. */
.article { max-width: 42rem; margin: 0 auto; }

.article .surtitre a { color: inherit; text-decoration: none; }
.article .surtitre a:hover { text-decoration: underline; }

.article .chapo {
    font-size: 1.1875rem;         /* 19 px */
    line-height: 1.6;
    color: var(--encre);
    margin-bottom: 1.75rem;
}

.article-corps h2 { margin-top: 2.25rem; }
.article-corps h3 { margin-top: 1.5rem; }

.article-corps blockquote {
    margin: 1.5rem 0;
    padding-left: 1.25rem;
    border-left: 3px solid var(--sable);
    color: var(--discret);
}

/* La liste des articles, sur /blog/ comme en pied d'article : un titre, un chapo. */
.blog-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    max-width: 42rem;
    display: grid;
    gap: 2.25rem;
}

.blog-liste h2, .blog-liste h3 {
    font-size: var(--h3-taille);
    line-height: var(--h3-interligne);
    margin-bottom: 0.375rem;
}

.blog-liste a { color: var(--encre); text-decoration: none; }
.blog-liste a:hover { color: var(--bleu); text-decoration: underline; }

.blog-liste p { max-width: 62ch; }

/* Le lien de suite, sous le chapo (21/09/2026) — la liste du blog et le « A lire
   aussi » d'un article le partagent. Il porte le bleu d'action alors que
   le titre garde l'encre : c'est lui, et non le titre, qui se lit comme une invitation
   a ouvrir. En texte et non en bouton — une pastille par article ecraserait une liste
   qui doit rester calme. La fleche avance au survol ; la regle `prefers-reduced-motion`
   de fin de fichier la retient pour qui n'en veut pas.

   ⚠️ Ce bloc doit rester APRES `.blog-liste a:hover` : les deux ont la meme
   specificite, seul l'ordre les departage. */
.blog-liste .lire {
    margin-top: 0.6875rem;   /* 11 px */
    margin-bottom: 0;
}

.blog-liste .lire a {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    color: var(--bleu);
    font-weight: 600;
    font-size: 0.96875rem;   /* 15,5 px, comme les boutons */
    text-decoration: none;
}

.blog-liste .lire a::after {
    content: "\2192";        /* fleche vers la droite */
    transition: transform 140ms ease;
}

.blog-liste .lire a:hover { color: var(--bleu-fonce); text-decoration: underline; }
.blog-liste .lire a:hover::after { transform: translateX(3px); }

.a-lire-aussi > h2 { margin-bottom: 1.5rem; }

/* La photo de tete ouvre l'article ; la galerie, en bas, ne s'affiche qu'au-dela
   d'une photo. Les dimensions sont declarees dans le HTML : rien ne saute au
   chargement. Sans script, un clic sur une vignette ouvre la grande image seule. */
.article-tete {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 1.5rem;
    margin: 0 0 1.75rem;
    background: var(--photo);
}

/* La signature sous le corps : un cran plus discret que le texte, comme une note. */
.article-signature {
    margin-top: 2rem;
    color: var(--discret);
}
.article-signature a { color: inherit; }

.galerie {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 0.75rem;
    list-style: none;
    margin: 2.25rem 0 0;
    padding: 0;
}

.galerie a { display: block; border-radius: 1rem; overflow: hidden; background: var(--photo); }
.galerie img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }

/* Une vignette a gauche du titre, dans la liste, quand l'article en a une. */
.blog-liste .avec-vignette {
    display: grid;
    grid-template-columns: 8rem minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
}

.blog-liste .vignette { display: block; width: 100%; height: auto; border-radius: 1rem; background: var(--photo); }

/* --- La visionneuse (assets/galerie.js) ---------------------------------------------
 *
 * Construite par le script au premier clic, jamais dans le gabarit : une page sans
 * script n'en porte pas, et les liens des vignettes suffisent. **Tout se dimensionne
 * ici**, rien en ligne — la page du blog sert `style-src 'self'`.
 */
.visionneuse {
    position: fixed;
    inset: 0;
    z-index: 20;
    display: grid;
    place-items: center;
    padding: 3.5rem 4rem;
    background: rgba(27, 39, 64, .94);   /* l'encre, presque opaque */
}

.visionneuse[hidden] { display: none; }

.visionneuse figure { margin: 0; max-width: 100%; max-height: 100%; text-align: center; }

.visionneuse img {
    display: block;
    margin: 0 auto;
    max-width: calc(100vw - 8rem);
    max-height: calc(100vh - 9rem);
    width: auto;
    height: auto;
    border-radius: 1rem;
    background: var(--photo);
}

.visionneuse figcaption { color: var(--creme); margin-top: 0.75rem; font-size: 0.9375rem; }

.visionneuse button {
    position: absolute;
    background: transparent;
    color: var(--creme);
    border: 0;
    padding: 0.5rem 1rem;
    font-size: 2.5rem;
    line-height: 1;
    cursor: pointer;
}

.visionneuse button:hover { color: var(--orange); background: transparent; }
.visionneuse-fermer { top: 0.75rem; right: 1rem; }
.visionneuse-precedente { left: 0.5rem; top: 50%; transform: translateY(-50%); }
.visionneuse-suivante { right: 0.5rem; top: 50%; transform: translateY(-50%); }

/* La page ne defile plus derriere la boite ouverte. */
body.visionneuse-ouverte { overflow: hidden; }

/* --- Sur-titre --------------------------------------------------------------------- */

/* Sa puce ronde est la troisieme et derniere touche d'orange de la page. */
.surtitre {
    display: flex;
    align-items: center;
    gap: 0.5625rem;               /* 9 px */
    font-size: 0.8125rem;         /* 13 px */
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--bleu);
    margin: 0 0 0.75rem;
}

.surtitre::before {
    content: "";
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--orange);
    flex: none;
}

/* --- Contact ------------------------------------------------------------------------ */

.contact {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 25rem;   /* 400 px */
    gap: 3.5rem;
    align-items: start;
}

.contact > div > p { max-width: 48ch; }

.cabinet {
    background: var(--sable);
    border-radius: 2.5rem;        /* 40 px */
    padding: 2.125rem;            /* 34 px */
}

.cabinet-titre {
    font-size: 0.75rem;           /* 12 px */
    letter-spacing: .06em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--discret);
    margin: 0 0 0.875rem;
}

.cabinet address {
    font-style: normal;
    font-size: 1rem;              /* 16 px */
}

.cabinet hr {
    border: 0;
    border-top: 1px solid var(--trait-doux);
    margin: 1.5rem 0;
}

.cabinet .mention-legale { margin: 0; }

/* --- Formulaires ---------------------------------------------------------------------
 *
 * Ces regles portent sur les ELEMENTS, pas sur des classes : les gabarits du
 * tunnel de reservation et de l'espace admin sont en HTML nu, et heritent donc
 * de la charte sans qu'on les rouvre.
 */

.champs {
    display: grid;
    gap: 0.875rem;                /* 14 px */
}

.champs-paire {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

label {
    display: block;
    font-size: 0.84375rem;        /* 13,5 px */
    font-weight: 600;
    color: var(--texte);
    margin-bottom: 0.4375rem;
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="date"],
input[type="number"],
select,
textarea {
    display: block;
    width: 100%;
    min-height: 2.875rem;         /* 46 px */
    padding: 0.6875rem 1.125rem;
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.4;
    color: var(--encre);
    background: var(--champ);
    border: 1px solid var(--trait-champ);
    border-radius: 999px;
    transition: border-color 140ms ease;
}

input::placeholder, textarea::placeholder { color: var(--discret); opacity: 1; }

input:hover, select:hover, textarea:hover { border-color: var(--trait-fort); }

textarea {
    min-height: 6.875rem;         /* 110 px */
    border-radius: 1.75rem;       /* 28 px */
    resize: vertical;
}

/* Une case a cocher garde sa taille native et son libelle en graisse normale :
   c'est une phrase que l'on lit, pas l'intitule d'un champ. */
.champ-case {
    display: flex;
    gap: 0.625rem;
    align-items: flex-start;
}

.champ-case input {
    width: auto;
    min-height: 0;
    margin-top: 0.35rem;
    flex: none;
}

.champ-case label {
    font-weight: 400;
    font-size: 0.9375rem;
    margin-bottom: 0;
}

.aide {
    display: block;
    font-size: 0.875rem;
    color: var(--discret);
    margin-top: 0.35rem;
}

/* Un bouton sans classe — le tunnel et l'admin n'en portent pas — prend
   l'apparence de l'action principale. */
button, input[type="submit"] {
    display: inline-block;
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 0.9375rem 1.875rem;
    font-family: var(--texte-police);
    font-size: 0.96875rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--creme);
    background: var(--bleu);
    cursor: pointer;
    transition: background-color 140ms ease;
}

button:hover, input[type="submit"]:hover { background: var(--bleu-fonce); }

/* Le piege a robots : invisible a l'oeil, present pour un automate.
   Ni display:none ni hidden — les deux sont detectes. */
.piege {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* --- Messages ------------------------------------------------------------------------ */

.erreur, .avis, .bandeau-purge {
    border-radius: 1.25rem;
    padding: 0.9375rem 1.25rem;
    margin-bottom: 1.5rem;
}

.erreur {
    background: var(--erreur-fond);
    border: 1px solid var(--erreur-trait);
    color: var(--erreur-texte);
}

.avis {
    background: var(--sauge);
    border: 1px solid var(--avis-trait);
    color: var(--avis-texte);
}

.bandeau-purge {
    background: var(--sable);
    border: 1px solid var(--trait-doux);
    color: var(--texte);
}

/* --- Tunnel de reservation ------------------------------------------------------------
 *
 * Aucune de ces regles ne suppose une classe : les gabarits de rendez-vous/ et
 * de rdv/ sont en HTML nu, et le resteront.
 */

.tunnel { max-width: 42rem; }

/* Les creneaux et les lieux sont des listes de boutons : la puce n'a pas de
   sens, et ils se posent en grille des qu'il y en a plusieurs. */
.tunnel form ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
    margin: 0 0 1.75rem;
    padding: 0;
    list-style: none;
}

.tunnel form ul button {
    background: var(--creme);
    color: var(--encre);
    border-color: var(--trait-champ);
    padding: 0.75rem 1.375rem;
}

.tunnel form ul button:hover {
    background: var(--champ);
    border-color: var(--bleu);
    color: var(--bleu);
}

.tunnel h2 {
    font-size: 1.375rem;
    text-transform: capitalize;
    margin: 1.75rem 0 0.75rem;
}

.tunnel dl {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.4rem 1.5rem;
    background: var(--champ);
    border: 1px solid var(--trait);
    border-radius: 1.75rem;
    padding: 1.5rem 1.75rem;
    margin: 0 0 1.5rem;
}

.tunnel dt { color: var(--discret); }
.tunnel dd { margin: 0; font-weight: 600; color: var(--encre); }

.tunnel p > label { display: inline-block; }

/* --- Calendrier de reservation ----------------------------------------------------------
 *
 * Les deux premieres pages du tunnel depuis le 21/08/2026 : trois mois de cases,
 * puis le detail d'un jour. **Aucune de ces regles ne suppose du JavaScript** — une
 * case est un lien, un creneau est un bouton de formulaire.
 *
 * ⚠️ La couleur d'une case ne porte jamais seule son information : le chiffre inscrit
 * dedans dit le nombre de creneaux libres, et le lien d'un jour consultable porte la
 * phrase entiere en `aria-label`. Retirer l'un des deux rendrait le calendrier
 * illisible a qui ne distingue pas ces teintes.
 */

/* Le calendrier ne tient pas dans la largeur de lecture du tunnel. Seule cette page
   demande la colonne large, par la variable « colonne » de page.php. */
.tunnel.colonne-large { max-width: 64rem; }

.calendrier {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.75rem 1.5rem;
    margin: 1.5rem 0 2rem;
}

/* La bande de semaines (21/08/2026) est **un seul tableau**, la ou trois mois en
   faisaient trois : une colonne suffit, et elle se lit de haut en bas comme un
   agenda. Elle ne depasse pas la largeur d'une main sur un ecran large — un
   calendrier etale sur 64 rem oblige a balayer la page pour comparer deux jours. */
.calendrier:has(.bande-semaines) { grid-template-columns: minmax(0, 30rem); }

/* Le nom du mois, pose sur la semaine ou il commence. Il porte la fonction du
   `caption` d'un calendrier mensuel, sans decouper la bande en morceaux. */
.bandeau-mois th {
    font-family: var(--titre-police);
    font-size: 1.0625rem;
    font-weight: 400;
    color: var(--encre);
    text-align: left;
    text-transform: none;
    letter-spacing: 0;
    padding: 1rem 0 0.35rem;
    border-bottom: 1px solid var(--trait);
}

.mois { width: 100%; border-collapse: collapse; }

.mois caption {
    font-family: var(--titre-police);
    font-size: 1.125rem;
    color: var(--encre);
    text-align: left;
    text-transform: capitalize;
    padding-bottom: 0.5rem;
}

.mois th {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--discret);
    padding-bottom: 0.35rem;
}

/* Le pointille que les navigateurs posent sous une abreviation ferait sale sur sept
   colonnes ; l'infobulle du `title`, elle, reste. */
.mois abbr { text-decoration: none; cursor: help; }

.mois td { padding: 2px; }

.case-boite {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    border-radius: 0.7rem;
    text-decoration: none;
    color: var(--discret);
}

a.case-boite {
    color: var(--encre);
    border: 1px solid transparent;
}

a.case-boite:hover, a.case-boite:focus-visible {
    border-color: var(--bleu);
    color: var(--bleu);
}

.case-jour { font-weight: 600; line-height: 1; font-size: 0.9375rem; }
.case-compte { font-size: 0.6875rem; line-height: 1; margin-top: 2px; }

/* Les teintes valent pour la case et pour la pastille de la legende : ecrites deux
   fois, elles auraient fini par ne plus dire la meme chose. */
.case-libre .case-boite,           .pastille.case-libre           { background: var(--case-libre); }
.case-partiel .case-boite,         .pastille.case-partiel         { background: var(--case-partiel); }
.case-presque_complet .case-boite, .pastille.case-presque_complet { background: var(--case-presque); }
.case-complet .case-boite,         .pastille.case-complet         { background: var(--case-complet); }

/* Ce qui n'est pas consultable : ni fond, ni relief, et un chiffre efface. Le jour
   passe s'efface plus encore — il ne reviendra pas. */
.case-ferme .case-boite,
.case-hors_fenetre .case-boite,
.pastille.case-ferme { background: transparent; border: 1px dashed var(--trait); }

/* Un jour que la semaine type ouvre et qu'une derogation ferme d'un bout a l'autre
   (21/08/2026). ⚠️ **Il ne se lit pas comme un dimanche** : le premier est une
   decision de Gentiane, le second n'a jamais ete ouvert. Les deux se confondaient, si
   bien qu'une semaine de conges posee dans l'ecran de gestion ne se voyait nulle part
   dans l'agenda. Le trait plein, teinte brique, dit qu'il s'y est passe quelque chose. */
.case-ferme_exception .case-boite,
.pastille.case-ferme_exception {
    background: var(--geste-rouge-fond);
    border: 1px solid var(--geste-rouge-trait);
}

.case-passe .case-jour { opacity: .45; }

/* « Trop proche » se consulte encore — la page du jour y explique quoi faire — mais
   n'affiche aucun compte : un « 0 » s'y lirait « complet ». Il partage la teinte de
   « complet », que la legende nomme pour les deux : rien n'y est reservable, et la
   difference se lit sur la page du jour, pas dans une sixieme couleur. */
.case-trop_tot .case-boite { background: var(--case-complet); }

.legende {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.25rem;
    list-style: none;
    margin: 1.5rem 0 0.5rem;
    padding: 0;
    font-size: 0.875rem;
}

.legende li { display: flex; align-items: center; gap: 0.45rem; }

.pastille {
    display: inline-block;
    width: 0.95rem;
    height: 0.95rem;
    border-radius: 0.3rem;
    border: 1px solid var(--trait);
    flex: none;
}

/* --- Le detail d'un jour ---------------------------------------------------------- */

.navigation-jour {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    margin: 0 0 1.5rem;
    font-size: 0.9375rem;
}

/* Une direction hors des trois mois reste ecrite et grisee : une barre dont les
   elements disparaissent se relit a chaque fois. */
.saut-inerte { color: var(--discret); }

/* ⚠️ Le selecteur porte « ul.creneaux-du-jour » et non la seule classe : cette liste
   vit dans un formulaire, et « .tunnel form ul » l'aurait sinon mise en ligne. */
.tunnel form ul.creneaux-du-jour {
    display: grid;
    gap: 0.6rem;
    margin: 1.25rem 0 1.5rem;
    padding: 0;
    list-style: none;
}

/* Ces classes sont **distinctes de celles de l'agenda admin** (« .creneau »), qui
   n'est pas scope et deteindrait ici. */
.creneau-jour {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    background: var(--creme);
    border: 1px solid var(--trait);
    border-left: 4px solid var(--trait-fort);
    border-radius: 1rem;
    padding: 0.85rem 1.25rem;
    margin: 0;
}

.creneau-jour .heure { font-weight: 700; color: var(--encre); }
.creneau-jour .etat { color: var(--discret); }

/* L'etat se lit au filet de gauche avant meme le texte : c'est ce qui distingue d'un
   coup d'oeil le libre du reserve, la demande du 21/08/2026. */
.creneau-jour-libre { border-left-color: var(--vert); }

.creneau-jour-reserve {
    border-left-color: var(--brique);
    background: var(--champ);
}

.creneau-jour:not(.creneau-jour-libre) .heure { color: var(--discret); font-weight: 600; }

/* --- Pied de page ---------------------------------------------------------------------- */

.pied {
    border-top: 1px solid var(--trait);
    margin-top: 1.5rem;
}

.pied .contenu {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding-top: 2.125rem;        /* 34 px */
    padding-bottom: 2.625rem;     /* 42 px */
    font-size: 0.84375rem;        /* 13,5 px */
    color: var(--discret);
}

.pied p { margin: 0; }

.pied ul {
    display: flex;
    gap: 1.5rem;
    margin: 0 0 0 auto;
    padding: 0;
    list-style: none;
}

.mention-legale { color: var(--discret); }

/* --- Espace admin -----------------------------------------------------------------------
 *
 * Meme charte, densite plus forte : c'est un outil de travail, pas une vitrine.
 */

.entete-admin {
    background: var(--encre);
    color: var(--creme);
}

.entete-admin .contenu {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding-top: 1rem;
    padding-bottom: 1rem;
}

.entete-admin .marque {
    margin: 0;
    font-family: var(--titre-police);
    font-size: 1.125rem;
    color: var(--creme);
}

.entete-admin a { color: var(--admin-lien); text-decoration: none; font-weight: 600; font-size: 0.9375rem; }
.entete-admin a:hover { color: var(--admin-lien-vif); }
.entete-admin a[aria-current="page"] { color: var(--admin-lien-vif); border-bottom: 2px solid var(--orange); padding-bottom: 3px; }

.entete-admin nav ul {
    display: flex;
    gap: 1.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.entete-admin .deconnexion {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-left: auto;
    font-size: 0.875rem;
}

.entete-admin .deconnexion button {
    background: transparent;
    border-color: var(--bandeau-trait);
    color: var(--creme);
    padding: 0.5rem 1rem;
    font-size: 0.84375rem;
}

.entete-admin .deconnexion button:hover { background: var(--bandeau-survol); }

.admin main { padding-top: 2rem; }

/* La respiration entre deux zones d'un ecran d'administration. Sans elle, le bouton
   qui finit un formulaire touche le titre de la zone suivante : « Enregistrer ces
   horaires » collait a « Fermetures exceptionnelles », et le dernier `<p>` d'un
   formulaire a une marge basse nulle (`p:last-child`), donc rien ne les separait.
   Meme cause, meme remede pour un sous-titre qui suit un formulaire. */
.admin .contenu > section + section { margin-top: 3rem; }
.admin form + h3 { margin-top: 2.5rem; }

.demande, .creneau, .liste-rdv > li, .liste-conges > li {
    background: var(--creme);
    border: 1px solid var(--trait);
    border-radius: 1.5rem;
    padding: 1.25rem 1.5rem;
    margin-bottom: 0.875rem;
}

.demande dl, .creneau dl {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.2rem 0.9rem;
    margin: 0.5rem 0;
}

.demande dt, .creneau dt { font-weight: 600; color: var(--discret); }
.demande dd, .creneau dd { margin: 0; }
.demande .echeance { font-weight: 700; color: var(--brique); }

.liste-rdv, .liste-conges { margin: 0; padding: 0; list-style: none; }

/* L'historique des demandes : une ligne de tete qui dit quoi et pourquoi, puis les
   coordonnees et les dates en retrait. Le `.note` est un bloc pour que le second
   niveau parte a la ligne — inline, il collait a la raison sur un ecran large. */
.liste-rdv .statut { font-weight: 600; }
.liste-rdv .note { display: block; margin-top: 0.35rem; line-height: 1.5; }

.navigation-semaine { display: flex; gap: 1.25rem; margin-bottom: 0.75rem; }

/* L'etat d'un creneau se lit a son filet de gauche, avant meme le texte. */
.creneau { border-left: 4px solid var(--trait); }
.creneau .heure { font-weight: 700; margin-right: 0.6rem; color: var(--encre); }
.creneau .etat { color: var(--discret); }
.creneau-libre      { border-left-color: var(--vert); }
.creneau-ferme      { border-left-color: var(--discret); }
.creneau-en_attente { border-left-color: var(--orange); }
.creneau-confirme   { border-left-color: var(--bleu); }

/* --- Ce qui est pris doit se voir avant ce qui est libre (25/08/2026) ---------------
 *
 * ⚠️ **Le defaut corrige** : un creneau libre portait les deux seuls aplats colores de
 * la liste — « Fermer ce creneau » en rouge, « Inscrire un rendez-vous » en vert —,
 * tandis qu'un rendez-vous confirme n'avait qu'un filet et un `summary` en texte nu.
 * L'oeil tombait sur les trous de l'agenda, alors que ce qu'on vient y lire, ce sont
 * les rendez-vous.
 *
 * Le filet seul ne pouvait pas suffire : la carte a le **meme fond que la page**, si
 * bien que 4 px de couleur sur un bord arrondi de 1,5 rem se perdent. Ce qui est pris
 * prend donc un aplat, et le nom de la personne passe en gras encre.
 *
 * ⛔ **Ne pas colorer le libre pour « equilibrer »** : c'est le contraste entre les deux
 * qui porte l'information. Un agenda ou tout est teinte ne dit plus rien.
 */
.creneau-confirme, .creneau-en_attente, .creneau-a_confirmer, .creneau-proposee {
    border-left-width: 6px;
}

.creneau-confirme    { background: var(--creneau-confirme-fond); }
.creneau-en_attente  { background: var(--creneau-attente-fond); }
.creneau-a_confirmer { background: var(--creneau-a-confirmer-fond); }
.creneau-proposee    { background: var(--creneau-proposee-fond); }

/* --- La frequentation, ecran « Fréquentation » (07/09/2026, resserre le 09/09) -------
 *
 * Un ecran qui se lit sans defiler : une phrase de resume, les pages et les provenances
 * cote a cote des que la place le permet, puis les trente jours ranges en semaines —
 * cinq lignes de sept cases au lieu de trente lignes. Les jours a zero sont la — c'est
 * le trou qu'on vient voir — et leur chiffre s'efface au lieu de disparaitre.
 */
.resume-frequentation { font-size: 1.125rem; margin-bottom: 0.5rem; }

.frequentation-colonnes { display: grid; gap: 2rem; }

.frequentation-colonnes > section > .note { margin-top: 0.75rem; }

@media (min-width: 900px) {
    .frequentation-colonnes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.5rem; }
    .frequentation-colonnes > section { min-width: 0; }
}

/* Le `.tableau` du site a la geometrie de la grille tarifaire — 28 px de marge, coins
   a 2 rem. Pour douze lignes de chiffres, la moitie suffit. */
.tableau-compact { border-radius: 1rem; }
.tableau-compact th, .tableau-compact td { padding: 0.5rem 1rem; }
.tableau-compact tbody th { font-weight: 500; color: var(--texte); word-break: break-all; }
.tableau-compact td.valeur { text-align: right; color: var(--encre); font-variant-numeric: tabular-nums; }
.tableau-compact thead th { font-family: var(--texte-police); font-size: 0.875rem; font-weight: 600; }

/* Les semaines : le numero du jour en petit au-dessus du nombre de vues, une colonne de
   total a droite, et les cases hors periode vides plutot qu'a zero. */
.semaines table { min-width: 34rem; }
.semaines th, .semaines td { text-align: center; white-space: nowrap; }
.semaines tbody th { text-align: left; font-size: 0.875rem; }
.semaines .numero { display: block; font-size: 0.75rem; line-height: 1.2; color: var(--discret); }
.semaines .vues { font-weight: 700; color: var(--encre); font-variant-numeric: tabular-nums; }
.semaines .zero .vues { font-weight: 400; color: var(--discret); }
.semaines .aujourdhui { background: var(--sable); }
.semaines .vide { background: var(--voile-survol); }
.semaines td.total { font-weight: 700; color: var(--encre); font-variant-numeric: tabular-nums; border-left: 1px solid var(--trait); }
.semaines thead th.total { border-left: 1px solid var(--trait); }

/* --- Le creneau vise par un lien (07/09/2026) ---------------------------------------
 *
 * L'ecran des demandes renvoie a un rendez-vous precis de l'agenda, par une ancre. Le
 * navigateur y fait defiler la page et **c'est tout** : sur une journee de six lignes
 * qui se ressemblent, rien ne dit laquelle on vient d'ouvrir. Ce cerne le dit.
 *
 * ⚠️ Il ne remplace pas le fond d'etat, il s'y ajoute : la ligne doit rester lisible
 * comme « confirmee » ou « en attente ». D'ou un contour, et non un aplat de plus.
 */
.creneau:target {
    outline: 3px solid var(--orange);
    outline-offset: 2px;
    scroll-margin-top: 1rem;
}

/* Le prenom porte par le repli d'un rendez-vous : c'est l'information de la ligne, et
   elle etait au meme poids qu'une mention. ⛔ Le `:not()` epargne les `summary` qui
   sont des boutons — « Inscrire un rendez-vous », « Modifier ? » —, deja habilles. */
.creneau .repli > summary:not(.bouton-menu) {
    font-weight: 600;
    color: var(--encre);
}

/* Un creneau **libre** n'a rien a montrer : il s'efface d'un cran pour laisser la
   place a ce qui est pris. Son filet vert et ses deux boutons restent, eux, intacts. */
.creneau-libre .etat { font-size: 0.90625rem; }

.note { color: var(--discret); font-size: 0.9375rem; }

/* La balise d'audience (`Audience\Balise`) : hors de l'ecran, pas invisible. ⛔ Ni
   `display: none` ni `visibility: hidden` : un navigateur peut ne pas demander une
   image qu'il n'a pas a peindre, et la page ne se compterait pas. */
.balise-audience { position: absolute; left: -9999px; top: 0; width: 1px; height: 1px; }

/* --- L'agenda de l'admin ------------------------------------------------------------
 *
 * Le mois d'ensemble reprend **les memes classes que le calendrier public** — `.mois`,
 * `.case`, `.case-boite`, `.pastille` — pour que les deux se lisent de la meme facon.
 * Ne dupliquer ni les teintes ni la geometrie ici : ce qui suit ne fait qu'ajuster ce
 * qui differe, un calendrier unique dans une colonne large.
 */

.calendrier-admin { grid-template-columns: minmax(0, 26rem); }

/* --- L'agenda en deux colonnes (30/08/2026) -------------------------------------------
 *
 * La bande de semaines a gauche, la journee choisie a droite, **des que l'ecran le
 * permet**. Le motif tient a ce que la bande est passee de neuf semaines a seize : la
 * journee s'en trouvait rejetee sous un calendrier de plus de huit cents pixels, et il
 * fallait redescendre apres chaque changement de jour. Cote a cote, les deux hauteurs
 * se repondent — seize semaines a gauche, six creneaux detailles a droite.
 *
 * ⚠️ **En `min-width`, contrairement au reste de cette feuille**, qui degrade en
 * `max-width` depuis une mise en page large. Ici la mise en page de base est la colonne
 * unique — celle qui a toujours existe — et les deux colonnes sont ce qu'on ajoute
 * quand la place est la. Un ecran etroit ne « perd » donc rien.
 *
 * Le seuil est celui ou la colonne de droite atteint ~34 rem, en dessous de quoi les
 * cartes de creneau et leurs formulaires deviennent illisibles.
 */
.agenda-colonnes { display: grid; gap: 2.5rem; }

@media (min-width: 1100px) {
    .agenda-colonnes {
        grid-template-columns: 26rem minmax(0, 1fr);
        gap: 3rem;
        /* Les deux colonnes commencent en haut : sans cela, une journee courte se
           centrerait sur la hauteur de la bande. */
        align-items: start;
    }

    /* ⛔ Matin et apres-midi s'empilent dans la colonne de droite. Cote a cote, ils y
       feraient deux colonnes d'environ 300 px — la largeur meme que la regle mobile
       ci-dessous ecarte comme illisible. La journee reste donc lue de haut en bas, ce
       qui est son ordre naturel. */
    .agenda-journee .demi-journees { grid-template-columns: minmax(0, 1fr); }

    /* Le titre de la journee s'aligne sur le premier lien de la colonne de gauche.
       ⚠️ Le `.admin` de tete n'est pas decoratif : `.admin .jour { margin-top: 2rem }`
       est declare **plus bas** a specificite egale, et l'emporterait sans lui. */
    .admin .agenda-journee .jour { margin-top: 0; }
}

/* La journee ouverte, pour qu'on retrouve d'un coup d'oeil ou l'on est. */
.case-ouverte .case-boite {
    outline: 2px solid var(--bleu);
    outline-offset: -2px;
}

.admin .jour { margin-top: 2rem; }

.admin .creneaux { margin: 0; padding: 0; list-style: none; }

/* Les etats de l'agenda admin, en plus de ceux que porte deja `.creneau-*`. Un creneau
   retenu par une demande que la personne n'a pas encore confirmee se lit a part : la
   place n'est pas libre, et Gentiane n'a pourtant rien a en faire. */
.creneau-a_confirmer { border-left-color: var(--discret); }
.creneau-proposee    { border-left-color: var(--brique); }

/* Les deux champs d'une date proposee tiennent sur une ligne. */
.admin .champs-paire { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }

/* --- Les creneaux libres de « proposer une autre date » (25/08/2026) -----------------
 *
 * ⚠️ **Ils remplacent deux champs `date` + `heure` a remplir a l'aveugle** : rien n'y
 * disait si l'heure existait, ni si elle etait deja prise. Un `fieldset` par jour, ses
 * heures en pastilles sur une ligne qui se replie — c'est ce qui tient sur un telephone
 * sans devenir une colonne de cent lignes.
 *
 * La radio reste **visible** plutot que masquee : c'est elle que le clavier atteint et
 * que le lecteur d'ecran annonce, et la pastille ne fait que l'habiller.
 */
.creneaux-libres {
    margin: 0 0 0.75rem;
    padding: 0.5rem 0.75rem 0.65rem;
    border: 1px solid var(--trait);
    border-radius: 0.7rem;
}

.creneaux-libres legend {
    padding: 0 0.35rem;
    font-size: 0.84375rem;
    font-weight: 600;
    color: var(--discret);
}

.creneaux-libres label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0.2rem 0.4rem 0.2rem 0;
    padding: 0.35rem 0.75rem;
    font-size: 0.9375rem;
    line-height: 1.2;
    color: var(--encre);
    background: var(--champ);
    border: 1px solid var(--trait-fort);
    border-radius: 999px;
    cursor: pointer;
}

.creneaux-libres label:hover { background: var(--sable); }

/* L'heure retenue doit se lire sans avoir a chercher lequel des ronds est plein :
   c'est elle qui partira dans le courriel de la personne. */
.creneaux-libres label:has(input:checked) {
    font-weight: 600;
    color: var(--geste-vert-texte);
    background: var(--geste-vert-fond);
    border-color: var(--geste-vert-trait);
}

/* --- La journee ouverte, en deux colonnes -------------------------------------------
 *
 * Matin a gauche, apres-midi a droite (21/08/2026) : une seule liste de sept creneaux
 * poussait le calendrier hors de l'ecran, et il fallait remonter pour changer de jour.
 * Le partage se fait dans `Admin\Agenda`, jamais ici — c'est une regle de lecture d'une
 * journee, pas une question de mise en page.
 */
.demi-journees {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.25rem 2rem;
    align-items: start;
}

.demi-journee h3 {
    font-size: 1.0625rem;
    margin: 0 0 0.5rem;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid var(--trait);
}

.admin .creneau {
    padding: 0.6rem 0 0.6rem 0.75rem;
    margin-bottom: 0.5rem;
}

.admin .creneau .heure { display: inline-block; }

/* --- Les boutons secondaires de l'admin ----------------------------------------------
 *
 * ⚠️ **Un bouton sans classe reste l'action principale**, bleu et rond : c'est ce qui
 * habille tout le tunnel et tous les formulaires. Ce qui suit ne concerne que les
 * gestes **inline** d'un creneau — plus petits, moins hauts, et colores par ce qu'ils
 * font : rouge pour ce qui retire, vert pour ce qui pose.
 */
/* Le bouton secondaire : petit, en contour, sur fond clair. Il **ouvre** ou il agit
   sur un detail ; le bleu plein reste reserve a l'action principale d'un formulaire. */
.bouton-menu {
    padding: 0.4rem 0.85rem;
    font-size: 0.84375rem;
    border-radius: 999px;
    color: var(--encre);
    background: var(--champ);
    border: 1px solid var(--trait-fort);
}

.bouton-menu:hover { background: var(--sable); border-color: var(--trait-fort); }

/* Un `summary` n'est pas un bouton : il faut lui rendre l'apparence a la main, et
   surtout lui retirer le triangle par defaut — sans quoi la pilule porte une fleche. */
summary.bouton-menu {
    display: inline-block;
    list-style: none;
    font-family: var(--texte-police);
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color 140ms ease, border-color 140ms ease;
}

summary.bouton-menu::-webkit-details-marker { display: none; }
summary.bouton-menu::marker { content: ''; }

/* Les deux gestes qui se distinguent d'un coup d'oeil : celui qui retire, celui qui
   pose. La couleur qualifie, elle ne hurle pas. */
.bouton-menu.bouton-vert {
    color: var(--geste-vert-texte);
    background: var(--geste-vert-fond);
    border-color: var(--geste-vert-trait);
}

.bouton-menu.bouton-vert:hover { background: var(--geste-vert-survol); }

.bouton-menu.bouton-rouge {
    color: var(--geste-rouge-texte);
    background: var(--geste-rouge-fond);
    border-color: var(--geste-rouge-trait);
}

.bouton-menu.bouton-rouge:hover { background: var(--geste-rouge-survol); }

/* ⚠️ **Le seul aplat plein reste celui qui acte une annulation** — le bouton de
   confirmation, qui n'a pas `.bouton-menu`. Un point de non-retour ne se signale pas
   avec la meme discretion qu'un bouton qui ouvre. */
button.bouton-rouge:not(.bouton-menu) { background: var(--rouge-geste); }
button.bouton-rouge:not(.bouton-menu):hover { background: var(--rouge-geste-survol); }

/* --- L'echelle des boutons qui **agissent**, dans un repli ---------------------------
 *
 * « Inscrire », « Deplacer », « Envoyer la proposition », « Confirmer l'annulation » :
 * ils gardent leur aplat, c'est ce qui les distingue des pilules en contour qui, elles,
 * ne font qu'ouvrir. **Mais ils prenaient la taille d'un bouton de page publique** —
 * 15 px de haut, 30 px de large —, posee au fond d'un repli de creneau a cote de
 * pastilles de 6 px. La hierarchie ne se lisait plus : elle criait.
 *
 * Ils descendent donc a une taille intermediaire, entre la pilule et le bouton de
 * page. ⛔ Ne pas les passer en contour pour « harmoniser » : ils seraient alors
 * indiscernables du bouton qui ouvre, et rien ne dirait plus lequel engage.
 *
 * Les boutons pleine page de l'admin — connexion, purge, « Enregistrer ces horaires »,
 * « Fermer cette periode » — ne sont pas concernes : ils sont l'action d'un formulaire
 * qui occupe sa section, et leur taille y est juste.
 */
.admin .repli button,
.admin .geste button {
    padding: 0.55rem 1.25rem;
    font-size: 0.90625rem;
}

/* Le formulaire d'un repli respire moins qu'une page : ses champs et son bouton se
   resserrent, sans quoi le repli deplie fait deux ecrans de haut. */
.admin .repli form p { margin: 0.6rem 0; }
.admin .repli label { font-size: 0.90625rem; }

/* Le repli reste attache a son creneau : sans cette marge, le formulaire deplie
   colle a la ligne suivante et on ne sait plus a quel creneau il appartient. */
.admin .repli > summary { margin: 0.35rem 0; }
.admin .repli[open] { padding-bottom: 0.5rem; }

/* Les trois gestes du repli « Modifier ? », separes pour qu'on ne remplisse pas le
   formulaire de l'un en croyant remplir celui de l'autre. */
.geste {
    margin: 0.75rem 0;
    padding: 0.75rem 0 0.25rem;
    border-top: 1px solid var(--trait);
}

.geste h4 { font-size: 0.96875rem; margin: 0 0 0.35rem; }

/* --- Le blog dans l'admin (14/09/2026) ---------------------------------------------------
 *
 * La liste des articles reprend la carte des demandes ; le formulaire d'edition
 * prend la largeur d'une colonne de lecture, TinyMCE s'y installe a la place du
 * textarea du corps.
 */
.liste-articles { margin: 0; padding: 0; list-style: none; }

.liste-articles > li {
    background: var(--creme);
    border: 1px solid var(--trait);
    border-radius: 1.5rem;
    padding: 1.25rem 1.5rem;
    margin-bottom: 0.875rem;
}

.liste-articles .titre a { font-weight: 600; }
.liste-articles .note { display: block; margin-top: 0.35rem; }

.formulaire-article { max-width: 52rem; }
.formulaire-article input[type="text"], .formulaire-article textarea { width: 100%; }

.actions-article { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }

/* Les photos d'un article dans l'admin : une vignette, sa description, ses gestes. */
.liste-photos { margin: 0; padding: 0; list-style: none; }

.liste-photos > li {
    display: grid;
    grid-template-columns: 8rem minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
    background: var(--creme);
    border: 1px solid var(--trait);
    border-radius: 1.5rem;
    padding: 1rem 1.25rem;
    margin-bottom: 0.875rem;
}

.liste-photos img { display: block; width: 100%; height: auto; border-radius: 0.75rem; background: var(--photo); }
.liste-photos .gestes { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }
.liste-photos .gestes form { display: inline; }
.liste-photos .de-tete { font-weight: 600; color: var(--vert-fonce); }

/* --- L'ecran de gestion ---------------------------------------------------------------
 *
 * L'apercu de quatre mois reprend les classes du calendrier, avec ses propres teintes :
 * il ne dit pas ce qui **reste**, il dit ce qui est **ouvert**.
 */
.calendrier-apercu { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.apercu-ouvert .case-boite,          .pastille.apercu-ouvert          { background: var(--case-libre); }
.apercu-ferme_exception .case-boite, .pastille.apercu-ferme_exception { background: var(--case-presque); }
.apercu-ferme .case-boite,
.pastille.apercu-ferme { background: transparent; border: 1px dashed var(--trait); }

/* La puce d'un jour qui porte au moins un rendez-vous. Elle se pose **en plus** de la
   couleur, jamais a sa place : deux informations distinctes — ce qui est ouvert, et ce
   qui est deja pris. */
.apercu-ouvert .case-boite, .apercu-ferme_exception .case-boite { position: relative; }

.puce-rdv, .pastille.puce-legende {
    display: block;
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: var(--bleu);
}

.puce-rdv { position: absolute; top: 3px; right: 3px; }

/* La semaine type : sept colonnes de cases a cocher. */
.semaine-type {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.75rem;
    margin: 1rem 0 1.5rem;
}

.jour-type {
    border: 1px solid var(--trait);
    border-radius: 0.5rem;
    padding: 0.5rem 0.6rem 0.65rem;
    margin: 0;
}

.jour-type legend {
    font-weight: 700;
    font-size: 0.90625rem;
    padding: 0 0.35rem;
}

/* La case et son heure forment une seule cible : viser une case a cocher de 13 px au
   doigt est impossible, viser sa ligne entiere ne l'est pas. */
.case-creneau {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0;
    font-size: 0.8125rem;
    cursor: pointer;
}

.case-creneau input { margin: 0; flex: none; }
.case-creneau:hover span { color: var(--encre); }

/* Le bouton qui coche ou decoche une journee entiere. **Il n'existe que si
   `gestion.js` s'execute** : c'est lui qui le cree, pour qu'un navigateur sans script
   n'affiche pas un bouton mort (voir ce fichier-la). D'ou son absence du gabarit.

   Pleine largeur de la colonne : il commande les sept cases qui le suivent, et un
   bouton flottant a gauche ne l'aurait pas dit. */
.bascule-jour {
    display: block;
    width: 100%;
    margin: 0.15rem 0 0.4rem;
    padding: 0.25rem 0.4rem;
    font-size: 0.75rem;
    font-weight: 600;
    border-radius: 0.35rem;
    color: var(--discret);
    background: transparent;
    border: 1px solid var(--trait);
}

.bascule-jour:hover { color: var(--encre); background: var(--sable); border-color: var(--trait-fort); }

/* --- Responsive -------------------------------------------------------------------------
 *
 * Deux points d'arret, ceux du handoff : sous 1024 px les grilles tombent a une
 * colonne ou deux, sous 720 px la maquette mobile s'applique.
 */

@media (max-width: 1024px) {
    /* Le heros s'empile : le portrait devient une bande horizontale **au-dessus** du
       texte, comme sur la maquette mobile. `column-reverse` le remonte sans toucher
       a l'ordre du document, ou l'image reste apres le titre qu'elle illustre. */
    .heros {
        display: flex;
        flex-direction: column-reverse;
    }

    .heros-portrait {
        position: static;
        width: 100%;
        height: 18rem;            /* 288 px */
    }

    .presentation {
        grid-template-columns: minmax(0, 1fr);
        gap: 2.5rem;
    }

    /* Le medaillon de /a-propos/ passe au-dessus du titre. */
    .portrait { order: -1; width: 13.75rem; }

    .duo, .contact { grid-template-columns: minmax(0, 1fr); gap: 2rem; }

    /* Une seule colonne : `grid-column: 2` y creerait une colonne implicite, et le
       texte partirait hors de la page. La variante n'a plus lieu d'etre ici — le
       titre a toute la largeur de toute facon. */
    .duo-titre-large { row-gap: 2rem; }
    .duo-titre-large > div { grid-column: auto; }

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

    .appel {
        grid-template-columns: minmax(0, 1fr);
        gap: 2rem;
        padding: 2.5rem;
        border-radius: 3rem;
    }

    .panneau { padding: 2.5rem; border-radius: 3rem; }

    /* Plusieurs mois cote a cote deviennent illisibles avant meme le point d'arret
       mobile : les colonnes du tableau tombent sous la largeur d'un chiffre. La bande
       de semaines, elle, n'a jamais eu qu'une colonne — la regle ne la touche pas. */
    .calendrier { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .calendrier-apercu { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* Sept colonnes de cases a cocher ne tiennent plus : quatre puis deux. */
    .semaine-type { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
    :root { --marge: 1.5rem; }   /* 24 px */

    .section { padding-bottom: 2.5rem; }   /* 40 px */

    body { font-size: 1rem; }              /* 16 px */

    .entete .contenu {
        padding-top: 0.875rem;
        padding-bottom: 0.875rem;
        gap: 1rem;
    }

    .identite { gap: 0.75rem; }
    .identite img { width: 3.25rem; height: 3.25rem; }   /* 52 px */
    .identite-nom { font-size: 1.0625rem; }              /* 17 px */
    .identite-role { font-size: 0.59375rem; letter-spacing: .09em; }  /* 9,5 px */

    /* La bascule du menu : la case reste dans le flux, focalisable, mais
       transparente — c'est le trait dessine par le label qu'on voit. */
    .menu-bascule {
        display: block;
        position: absolute;
        width: 2.75rem;
        height: 2.75rem;
        margin: 0;
        opacity: 0;
        cursor: pointer;
        z-index: 2;
    }

    .menu-bouton {
        display: flex;
        flex-direction: column;
        justify-content: center;
        gap: 5px;
        width: 2.75rem;         /* 44 px de cible tactile pour 24 px de dessin */
        height: 2.75rem;
        margin: 0 0 0 auto;
        padding: 0 0.375rem;
        cursor: pointer;
    }

    .menu-bouton span {
        display: block;
        height: 2px;
        background: var(--encre);
        border-radius: 2px;
    }

    .menu-bascule:focus-visible + .menu-bouton {
        outline: 2px solid var(--orange);
        outline-offset: 2px;
        border-radius: 6px;
    }

    .navigation {
        display: none;
        flex-basis: 100%;
        margin-left: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 1rem;
        padding-bottom: 0.5rem;
    }

    .menu-bascule:checked ~ .navigation { display: flex; }

    .navigation ul {
        flex-direction: column;
        gap: 0;
    }

    .navigation li { border-top: 1px solid var(--trait); }

    .navigation ul a {
        display: block;
        padding: 0.875rem 0;
        font-size: 1rem;
    }

    /* Le soulignement orange deviendrait un trait perdu dans une liste
       verticale : il passe a gauche. */
    .navigation ul a.courante {
        border-bottom: 0;
        border-left: 3px solid var(--orange);
        padding-left: 0.75rem;
    }

    .entete .bouton { width: 100%; padding: 0.875rem 1.375rem; }

    .heros .contenu { padding-top: 2.25rem; padding-bottom: 2.5rem; }
    .heros-portrait { height: 15rem; }           /* 240 px */

    /* ⚠️ Mesure : la ligne entiere fait 346 px en taille de bureau, pour 342 px
       utiles sur un telephone de 390. Elle se replierait sur deux lignes ; 12 px et
       un interlettrage resserre la gardent sur une seule. */
    /* ⚠️ Mesure : la ligne fait 264 px en taille de bureau, pour 342 px utiles sur un
       telephone de 390 — elle tient. L'interlettrage se resserre quand meme, pour
       garder de la marge sur un ecran de 320 px, ou elle passerait sur deux lignes. */
    .heros-surtitre {
        letter-spacing: .08em;
        margin-bottom: 1.25rem;
    }

    .heros-surtitre::before { width: 1.25rem; }  /* 20 px */
    .heros-intro { font-size: 1.03125rem; }      /* 16,5 px */
    .heros-actions { flex-direction: column; gap: 0.625rem; margin-top: 1.75rem; }
    .heros-actions .bouton { width: 100%; }

    .portrait { width: 8.75rem; }                /* 140 px */

    .panneau { padding: 1.75rem 1.375rem; border-radius: 2.5rem; }
    .atouts { gap: 0.75rem; }
    .atout { border-radius: 1.625rem; padding: 1.25rem; }
    .atout h3 { font-size: 1.0625rem; }

    /* ⚠️ 18 px et pas davantage : deux cartes par ligne, et « Retrouver » en
       Caprasimo mesure 95 px sur un ecran de 375 px de large, soit exactement la
       largeur utile de la carte. Au dela, le mot deborde. */
    .atouts-prog .atout h3 { font-size: 1.125rem; }

    /* Sous 24 px, une initiale n'est plus du « gros texte » au sens WCAG : il lui
       faut 4,5:1 et non 3:1. Le vert et le brique de la charte tiennent 4,01 et
       4,21 — justes en bureau ou le mot fait 28 px, insuffisants ici. */
    .atouts-prog .initiale { color: var(--vert-fonce); }
    .atouts-prog .initiale-brique { color: var(--brique-fonce); }
    .atout p { font-size: 0.875rem; }

    /* Cibles tactiles : 48 px minimum sur tout ce qui se touche. */
    .champs { gap: 0.75rem; }
    .champs-paire { grid-template-columns: 1fr; gap: 0.75rem; }
    input, select, textarea { min-height: 3rem; }
    textarea { min-height: 6.25rem; border-radius: 1.625rem; }
    button, input[type="submit"], .bouton { min-height: 3rem; }
    .contact form button { width: 100%; }

    .cabinet { border-radius: 2rem; padding: 1.625rem 1.375rem; }

    .appel { padding: 1.75rem 1.375rem; border-radius: 2.5rem; }
    .appel-actions .bouton { width: 100%; }

    .tableau { border-radius: 1.5rem; }
    .tableau th, .tableau td { padding: 0.875rem 1.125rem; }

    .pied .contenu {
        flex-direction: column;
        align-items: flex-start;
        gap: 1rem;
        padding-top: 1.375rem;
        padding-bottom: 1.75rem;
    }

    .pied ul { margin-left: 0; gap: 1rem; }

    .entete-admin .contenu { gap: 0.75rem; }
    .entete-admin .deconnexion { margin-left: 0; }

    /* Un mois par ecran, et des cases plus hautes : 44 px est la cible tactile
       minimale, un calendrier qu'on rate d'un doigt ne sert a rien. */
    .calendrier, .calendrier-admin { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
    /* La bande de semaines prend toute la largeur du telephone. */
    .calendrier:has(.bande-semaines) { grid-template-columns: minmax(0, 1fr); }
    .admin .champs-paire { grid-template-columns: minmax(0, 1fr); }
    /* Matin et apres-midi s'empilent : deux colonnes de 160 px ne se lisent pas. */
    .demi-journees { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
    .semaine-type { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .calendrier-apercu { grid-template-columns: minmax(0, 1fr); }
    .case-boite { min-height: 2.9rem; }
    .case-jour { font-size: 1rem; }

    .navigation-jour { gap: 0.5rem 1rem; }
    .creneau-jour { padding: 0.85rem 1rem; }
    .creneau-jour button { width: 100%; }
}

/* Le registre est calme : aucune animation au chargement ni au defilement.
   Cette regle ne fait que couvrir ce qui pourrait etre ajoute plus tard. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}
