/*
  Charte graphique — Faire-part Lucie & Valentin
  Palette « sauge & dorures » (eucalyptus / blush neutre) et typographie
  option 1b : Parisienne (script) + EB Garamond (accents) + Jost (texte).
  Reprise fidèle de la maquette Claude Design.
*/

:root {
    --sauge: #9caa8f;        /* vert sauge (accent moyen)  */
    --sauge-clair: #607150;  /* vert sauge clair (dégradé footer) — foncé pour rester lisible sous le texte crème (contraste AA 2026-09-17) */
    --sauge-fonce: #4f5d43;  /* vert profond (titres)      */
    --creme: #f4efe4;        /* fond crème                 */
    --sable: #c9a877;        /* doré doux (bordures)       */
    --bordure: #a1936c;      /* bordure de champ/séparateur — contraste non-textuel 3:1 (2026-09-17) */
    --or: #83692e;           /* doré soutenu (ornements) — foncé pour rester lisible en texte (contraste AA 2026-09-17) */
    --texte: #2e2a22;
    --texte-clair: #746c60;  /* foncé pour rester lisible en texte (contraste AA 2026-09-17) */
    --blanc: #ffffff;
    --erreur: #b24c4b;       /* foncé pour repasser sous 4.5:1 (2026-09-17) */

    --font-script: 'Parisienne', cursive;
    --font-serif: 'EB Garamond', serif;
    --font-sans: 'Jost', sans-serif;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font-sans);
    color: var(--texte);
    background: var(--creme);
    -webkit-font-smoothing: antialiased;
}

/* ---------- ORNEMENT DORÉ (ligne · point · ligne) ---------- */

.ornement {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 0.6rem 0;
}

.ornement__ligne {
    height: 1px;
    width: 28px;
    background: var(--or);
    opacity: 0.8;
}

.ornement__point {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--or);
}

/* ---------- ÉCRAN D'ACCUEIL / ENVELOPPE CACHETÉE ---------- */

/* L'enveloppe et son ouverture sont une vidéo pré-rendue (HyperFrames,
   source video/ouverture-enveloppe/), en deux formats : portrait sur écran
   plus haut que large, paysage sinon (même règle dans main.js). Cadrée en
   cover et centrée : le centre du cachet est au centre exact de la vidéo,
   donc de l'écran. Au repos, la première image de la vidéo sert de fond
   (.webp extrait par render.sh) : rien à charger d'autre pour l'afficher.

   --px vaut un pixel de la vidéo à l'écran (échelle du cover). Les cotes
   ci-dessous viennent de la composition (index.html du projet vidéo) :
   pli → cachet, cachet → bas de l'enveloppe, diamètre du cachet. Si la
   composition change, les recaler ici. Déclarées sur .accueil mais
   résolues chez les enfants, d'où les unités cq (conteneur = .accueil). */
.accueil {
    position: fixed;
    inset: 0;
    z-index: 50;
    container-type: size;
    text-align: center;
    background: var(--creme) url("../assets/ouverture-portrait.webp") center / cover no-repeat;
    transition: opacity 0.6s ease;
    overflow: hidden;
    --px: max(calc(100cqw / 1080), calc(100cqh / 1920));
    --env-haut: calc(var(--px) * 272);
    --env-bas: calc(var(--px) * 252);
    --cachet: calc(var(--px) * 190);
}

@media (min-aspect-ratio: 1/1) {
    .accueil {
        background-image: url("../assets/ouverture-paysage.webp");
        --px: max(calc(100cqw / 1920), calc(100cqh / 1080));
        --env-haut: calc(var(--px) * 244);
        --env-bas: calc(var(--px) * 225);
        --cachet: calc(var(--px) * 170);
    }
}

.accueil.accueil--fermeture {
    opacity: 0;
    pointer-events: none;
}

/* Le fondu ci-dessus ne suffit pas sans cette règle : une règle d'affichage
   de l'auteur l'emporterait sur `[hidden] { display: none }` du navigateur
   (même spécificité, feuille de l'auteur chargée après celle du
   user-agent), et #cachet resterait dans l'ordre de tabulation après
   l'ouverture — premier Tab mort pour tout utilisateur clavier/lecteur
   d'écran, à chaque visite (audit 2026-09-17). main.js pose `hidden` une
   fois le fondu terminé. */
#ecran-accueil[hidden] {
    display: none;
}

.accueil__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    z-index: 0;
    pointer-events: none;
}

/* Texte au-dessus et au-dessous de l'enveloppe, calé sur ses bords. */
.accueil__haut,
.accueil__bas {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 1.5rem;
}

.accueil__haut {
    bottom: calc(50% + var(--env-haut) + clamp(1rem, 3cqh, 2.25rem));
    gap: clamp(0.5rem, 1.6cqh, 1.1rem);
}

.accueil__bas {
    top: calc(50% + var(--env-bas) + clamp(1rem, 3cqh, 2rem));
    gap: 0.6rem;
}

/* Feuillage aquarelle en coin d'écran : deux planches distinctes déjà
   orientées (1073 = gauche, 1079 = droite, extraite le 2026-09-17 du bundle
   standalone Claude Design — la version listée dans le projet Design était
   un fichier vide) — bas-gauche et haut-droite, un cadre en diagonale
   plutôt qu'un encadrement symétrique du bloc de prénoms. */
.accueil__euca {
    position: absolute;
    z-index: 1;
    width: clamp(220px, 38vw, 420px);
    height: auto;
    pointer-events: none;
    user-select: none;
    transition: opacity 0.6s ease, transform 0.6s cubic-bezier(.16, 1, .3, 1);
}

/* Tablette en portrait : le bloc des prénoms remonte au-dessus de
   l'enveloppe, le feuillage pleine taille le chevauchait. */
@media (max-aspect-ratio: 1/1) and (min-width: 481px) {
    .accueil__euca { width: clamp(160px, 26vw, 260px); }
}

.accueil__euca--gauche { bottom: 0; left: 0; }
.accueil__euca--droite { top: 0; right: 0; }

/* Pendant l'ouverture, les feuillages se dérobent avec le reste du décor :
   la gauche part vers le bas-extérieur, la droite vers le haut-extérieur. */
.accueil--ouverture .accueil__euca--gauche { transform: translate(-6%, 6%) scale(0.85); }
.accueil--ouverture .accueil__euca--droite { transform: translate(6%, -6%) scale(0.85); }

.accueil__foyer {
    font-family: var(--font-serif);
    font-style: italic;
    font-weight: 600;
    font-size: 1.1rem;
    color: var(--sauge-fonce);
    margin: 0;
    transition: opacity 0.15s ease;
}

.accueil__accroche {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 1rem;
    color: var(--texte-clair);
    margin: 0;
    transition: opacity 0.15s ease;
}

.accueil__prenoms {
    font-family: var(--font-script);
    font-size: clamp(2.75rem, 11vw, 4.5rem);
    font-weight: 400;
    line-height: 1.1;
    color: var(--sauge-fonce);
    margin: 0;
    transition: opacity 0.15s ease;
}

/* Même feuillage qu'à l'accueil (1073 = gauche, 1079 = droite, déjà orientés
   — aucun miroir CSS), en filigrane derrière le titre du bloc plutôt qu'en
   pleine page. z-index négatif : suffisant pour passer sous le texte en
   flux normal du bloc (positionné), sans avoir besoin d'un wrapper dédié
   pour le texte. */
.bloc__euca {
    position: absolute;
    z-index: -1;
    height: auto;
    pointer-events: none;
    user-select: none;
}

.bloc__euca--titre-gauche {
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: clamp(210px, 26vw, 340px);
}

.bloc__euca--titre-droite {
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    width: clamp(200px, 24vw, 320px);
}

.bloc__euca--haut-gauche,
.bloc__euca--haut-droite {
    top: 4.5rem;
    width: clamp(180px, 20vw, 260px);
}

.bloc__euca--haut-gauche { left: 0; transform: translateY(-50%); }
.bloc__euca--haut-droite { right: 0; transform: translateY(-50%); }

/* Sous 480px (le gabarit de la grande majorité des invités), les planchers
   ci-dessus ne rétrécissaient plus avec le viewport et l'illustration
   recouvrait le texte (accroche d'accueil, "Save the date") au lieu de rester
   un accent de coin — audit du 2026-09-17. */
@media (max-width: 480px) {
    .accueil__euca { width: clamp(110px, 30vw, 180px); }
    .bloc__euca--titre-gauche,
    .bloc__euca--titre-droite { width: clamp(100px, 22vw, 160px); }
    .bloc__euca--haut-gauche,
    .bloc__euca--haut-droite { width: clamp(90px, 18vw, 140px); }
}

.accueil__date {
    font-family: var(--font-sans);
    font-size: 0.85rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--or);
    margin: 0.1rem 0 0;
    transition: opacity 0.15s ease;
}

.ornement {
    transition: opacity 0.15s ease;
}

/* Paysage de faible hauteur (fenêtre de portable, ~860 px utiles) : il ne
   reste qu'environ 190 px au-dessus de l'enveloppe, le bloc du haut (nom du
   foyer compris) dépassait de l'écran. On le compacte et on retire l'ornement. */
@media (min-aspect-ratio: 1/1) and (max-height: 1000px) {
    .accueil__haut { bottom: calc(50% + var(--env-haut) + clamp(0.5rem, 1.5cqh, 2.25rem)); gap: clamp(0.25rem, 1cqh, 1.1rem); }
    .accueil__haut .ornement { display: none; }
    .accueil__foyer { font-size: clamp(0.9rem, 2.4cqh, 1.1rem); }
    .accueil__accroche { font-size: clamp(0.85rem, 2.2cqh, 1rem); }
    .accueil__prenoms { font-size: clamp(2rem, min(11vw, 6cqh), 4.5rem); line-height: 1; }
    .accueil__date { font-size: clamp(0.7rem, 1.8cqh, 0.85rem); }
}

.accueil--ouverture .accueil__foyer,
.accueil--ouverture .accueil__accroche,
.accueil--ouverture .accueil__prenoms,
.accueil--ouverture .accueil__date,
.accueil--ouverture .accueil__euca,
.accueil--ouverture .ornement {
    opacity: 0;
}

/* Le regard suit le cachet : le texte autour s'efface en premier, les
   prénoms (l'élément display) s'attardent un instant de plus. */
.accueil--ouverture .ornement { transition-delay: 0.03s; }
.accueil--ouverture .accueil__prenoms { transition-delay: 0.06s; }
.accueil--ouverture .accueil__date { transition-delay: 0.09s; }

/* Le cachet visible est dans la vidéo : le bouton est une zone de tap
   transparente posée exactement dessus (centre de l'écran). */
.cachet {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 3;
    width: max(var(--cachet), 64px);
    height: max(var(--cachet), 64px);
    transform: translate(-50%, -50%);
    border: none;
    border-radius: 50%;
    background: none;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.cachet:focus-visible {
    outline: 2px solid var(--or);
    outline-offset: 6px;
}

.cachet.cachet--ouvert { pointer-events: none; }

.accueil__consigne {
    font-size: 0.85rem;
    color: var(--texte-clair);
    letter-spacing: 0.03em;
    margin: 0;
    transition: opacity 0.15s ease;
}

.accueil__mention {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    color: var(--texte-clair);
    margin: 0;
    transition: opacity 0.15s ease;
}

.accueil--ouverture .accueil__consigne,
.accueil--ouverture .accueil__mention {
    opacity: 0;
    transition-delay: 0.1s;
}

/* ---------- CONTENU ---------- */

.contenu {
    max-width: 1180px;
    margin: 0 auto;
    position: relative;
    background: var(--creme);
}

.contenu::before,
.contenu::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    width: min(210px, 42%);
    background-image: url("../assets/eucalyptus.webp");
    background-repeat: no-repeat;
    background-size: 100% auto;
    background-position: top left;
    opacity: 0.16;
    pointer-events: none;
    z-index: 0;
}

.contenu::before { left: 0; }
/* Côté droit : autre planche (1073), décalée plus bas — le miroir exact de
   la gauche donnait un header trop symétrique. */
.contenu::after {
    right: 0;
    background-image: url("../assets/1073.webp");
    background-position: right 5.5rem;
}

.contenu > .bloc,
.contenu > .footer {
    position: relative;
    z-index: 1;
}

.toggle-musique {
    position: fixed;
    bottom: 1.25rem;
    right: 1.25rem;
    z-index: 10;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: none;
    background: var(--sauge);
    color: var(--texte);
    font-size: 1.1rem;
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.18);
    cursor: pointer;
    opacity: 1;
    transform: scale(1.05);
    transition: opacity 0.3s ease, transform 0.3s ease;
}

.toggle-musique:hover { transform: scale(1.12); }

.toggle-musique.toggle-musique--coupee {
    opacity: 0.55;
    transform: scale(1);
}

/* ---------- BLOCS + RÉVÉLATION AU SCROLL ---------- */

.bloc {
    padding: 3.25rem 1.75rem;
    text-align: center;
    border-bottom: 1px solid rgba(201, 168, 119, 0.33);
    position: relative;
    z-index: 0;
}

.bloc--titre { padding-top: 4.5rem; overflow: visible; }

.reveal {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity 0.7s cubic-bezier(.16, 1, .3, 1), transform 0.7s cubic-bezier(.16, 1, .3, 1);
}

.reveal.reveal--visible {
    opacity: 1;
    transform: none;
}

/* Chaque bloc se pose comme le précédent, mais ce qu'il contient se révèle
   différemment selon sa nature : l'ornement se dessine comme un second
   cachet, le titre sort du flou comme une encre qui sèche, la photo se
   découvre comme on sort un tirage de son enveloppe, le programme s'énumère
   ligne à ligne. Un seul geste d'ensemble (le bloc qui se pose), plusieurs
   signatures à l'intérieur — jamais le même fondu répété tel quel. */
.bloc .ornement__ligne {
    transform: scaleX(0);
    transition: transform 0.45s cubic-bezier(.16, 1, .3, 1);
}
.bloc .ornement__ligne:first-child { transform-origin: right center; }
.bloc .ornement__ligne:last-child { transform-origin: left center; }
.bloc .ornement__point {
    transform: scale(0);
    transition: transform 0.3s cubic-bezier(.16, 1, .3, 1);
}
.reveal--visible .ornement__ligne { transition-delay: 0.15s; }
.reveal--visible .ornement__point { transition-delay: 0.5s; }
.reveal--visible .ornement__ligne,
.reveal--visible .ornement__point {
    transform: none;
}

.bloc__label {
    font-family: var(--font-serif);
    font-style: italic;
    color: var(--texte-clair);
    font-size: 0.95rem;
    margin: 0 0 0.5rem;
}

.bloc__titre {
    margin: 0 0 0.5rem;
    color: var(--sauge-fonce);
}

/* Masque de lisibilité, sur tous les titres de bloc : le feuillage en
   filigrane (.contenu::before/::after pleine page, plus .bloc__euca en gros
   plan sur certains blocs) traverse le script — halo crème serré derrière
   chaque titre pour rester lisible sans dégager toute la largeur du bloc.
   display:inline-block : le h2 (bloc pleine largeur par défaut) se resserre
   sur le texte — sinon inset ci-dessous s'ancre sur toute la largeur du
   bloc plutôt que sur les lettres, d'où un halo bien trop large. .bloc a
   déjà text-align:center, hérité ici pour garder le h2 centré malgré le
   passage en inline. Portée visuelle plafonnée à 10px de chaque côté du
   texte : le flou déborde visuellement au-delà du inset (halo doux, pas un
   bord net), donc inset + blur ne doivent pas dépasser 10px ensemble. */
.bloc__titre--script {
    display: inline-block;
    position: relative;
    isolation: isolate;
    font-family: var(--font-script);
    font-size: clamp(2rem, 6vw, 2.8rem);
    font-weight: 400;
    filter: blur(6px);
    transition: filter 0.6s cubic-bezier(.16, 1, .3, 1);
    transition-delay: 0.05s;
}

.bloc__titre--script::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: -10px;
    border-radius: 50%;
    background: var(--creme);
    filter: blur(6px);
}

/* Save the date reprend la taille héroïque du prénom d'accueil : premier
   titre rencontré après l'ouverture du cachet, il doit peser autant. */
.bloc--titre .bloc__titre--script {
    font-size: clamp(2.25rem, 7vw, 3.1rem);
}

.reveal--visible .bloc__titre--script {
    filter: blur(0);
}

.bloc__sous-titre {
    font-family: var(--font-serif);
    font-style: italic;
    color: var(--texte-clair);
    margin: 0 0 1.5rem;
}

.bloc__texte {
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--texte);
}

.bloc__note {
    font-size: 0.8rem;
    color: var(--texte-clair);
    margin-top: 1.25rem;
}

.bloc__note--type {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 0.95rem;
    color: var(--sauge-fonce);
    margin: 0 0 1.5rem;
}

.bloc__lien-maps {
    display: inline-block;
    margin-top: 0.75rem;
    font-family: var(--font-sans);
    font-size: 0.85rem;
    letter-spacing: 0.02em;
    color: var(--or);
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: transform 160ms cubic-bezier(.16, 1, .3, 1);
}
.bloc__lien-maps:active { transform: scale(0.97); }

.date-bloc {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--font-serif);
    font-size: 1.1rem;
    letter-spacing: 0.08em;
    color: var(--texte);
}

.date-bloc__sep { color: var(--sauge); }

.lieu-grille {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 2rem;
    align-items: center;
    max-width: 1000px;
    margin: 0 auto;
}

/* Le tirage (la photo) sort de l'enveloppe en premier ; la légende se pose
   juste après, comme on repose un tirage à côté de sa lettre — signature
   propre plutôt que le fondu de bloc générique partagé avec tout le reste. */
.lieu-info {
    text-align: center;
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.5s ease 0.35s, transform 0.5s cubic-bezier(.16, 1, .3, 1) 0.35s;
}

.reveal--visible .lieu-info {
    opacity: 1;
    transform: none;
}

.lieu-photo {
    width: 100%;
    height: 280px;
    object-fit: cover;
    object-position: center 35%;
    border-radius: 14px;
    margin: 1.25rem 0;
    display: block;
    box-shadow: 0 10px 24px -8px rgba(46, 42, 34, 0.35);
    outline: 1px solid var(--or);
    outline-offset: -1px;
    /* Le tirage sort de l'enveloppe : le cadrage se découvre de gauche à
       droite plutôt que d'apparaître d'un coup avec le reste du bloc. */
    clip-path: inset(0 100% 0 0 round 14px);
    transition: clip-path 0.9s cubic-bezier(.16, 1, .3, 1);
    transition-delay: 0.15s;
}

.reveal--visible .lieu-photo {
    clip-path: inset(0 0 0 0 round 14px);
}

/* ---------- PROGRAMME ---------- */

.programme {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    text-align: left;
    max-width: 320px;
    margin: 0 auto;
}

.programme__ligne {
    display: flex;
    justify-content: space-between;
    font-size: 0.9rem;
    color: var(--texte);
    border-bottom: 1px dashed var(--bordure);
    padding-bottom: 0.5rem;
    opacity: 0;
    transform: translateX(-10px);
    transition: opacity 0.45s ease, transform 0.45s cubic-bezier(.16, 1, .3, 1);
}

.programme__ligne:last-child { border-bottom: none; }
.programme__ligne[hidden] { display: none; }
.programme__heure { color: var(--texte-clair); }

/* Le déroulé s'énumère ligne à ligne plutôt que d'apparaître en bloc. */
.reveal--visible .programme__ligne {
    opacity: 1;
    transform: none;
}
.reveal--visible .programme__ligne:nth-child(1) { transition-delay: 0.15s; }
.reveal--visible .programme__ligne:nth-child(2) { transition-delay: 0.25s; }
.reveal--visible .programme__ligne:nth-child(3) { transition-delay: 0.35s; }
.reveal--visible .programme__ligne:nth-child(4) { transition-delay: 0.45s; }

/* ---------- FORMULAIRE RSVP ---------- */

.form-rsvp__foyer {
    text-align: center;
    font-family: var(--font-serif);
    font-style: italic;
    color: var(--sauge-fonce);
    margin: 0.5rem 0 1.25rem;
}

.form-rsvp__foyer--nom {
    font-size: clamp(1.45rem, 6vw, 1.85rem);
    font-weight: 600;
    line-height: 1.2;
}

.form-rsvp__note {
    margin: 0;
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 1rem;
    line-height: 1.45;
    text-align: center;
    color: var(--sauge-fonce);
}

.form-rsvp {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1.1rem;
    text-align: left;
    margin: 0.5rem auto 0;
    max-width: 760px;
}

.champ--pleine-largeur { grid-column: 1 / -1; }

/* Le formulaire s'énumère lui aussi, mais verticalement (on le lit de haut
   en bas, pas de gauche à droite comme le programme) : chaque champ se pose
   à son tour plutôt que le bloc entier d'un coup — signature distincte de
   celle du programme (translateX) tout en restant dans la même famille
   « énumération ». Délai plafonné à 0.52s sur les 7 enfants (pas de champ
   supplémentaire) pour rester une confirmation de lecture, pas une
   chorégraphie. */
.form-rsvp > * {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.4s ease, transform 0.4s cubic-bezier(.16, 1, .3, 1);
}

.reveal--visible .form-rsvp > * {
    opacity: 1;
    transform: none;
}

.reveal--visible .form-rsvp > *:nth-child(1) { transition-delay: 0.1s; }
.reveal--visible .form-rsvp > *:nth-child(2) { transition-delay: 0.17s; }
.reveal--visible .form-rsvp > *:nth-child(3) { transition-delay: 0.24s; }
.reveal--visible .form-rsvp > *:nth-child(4) { transition-delay: 0.31s; }
.reveal--visible .form-rsvp > *:nth-child(5) { transition-delay: 0.38s; }
.reveal--visible .form-rsvp > *:nth-child(6) { transition-delay: 0.45s; }
.reveal--visible .form-rsvp > *:nth-child(7) { transition-delay: 0.52s; }

.champ {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    font-size: 0.9rem;
}

.champ--checkbox {
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
}

.champ__label {
    color: var(--texte);
    transition: transform 120ms cubic-bezier(.16, 1, .3, 1);
}
.champ--checkbox:active .champ__label { transform: scale(0.99); }

/* Sépare visuellement le trio requis (personnes / végétariens / hébergement)
   des deux champs facultatifs, pour que l'œil découpe le formulaire en deux
   groupes plutôt qu'en 5 champs à plat (audit 2026-09-17). */
.form-rsvp__separateur {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 0.85rem;
    color: var(--texte-clair);
    text-align: center;
    margin: 0.5rem 0 -0.25rem;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--bordure);
}

.champ__erreur {
    color: var(--erreur);
    font-size: 0.8rem;
    animation: apparition-douce 180ms cubic-bezier(.16, 1, .3, 1);
}

@keyframes apparition-douce {
    from { opacity: 0; transform: translateY(-4px); }
}

@keyframes apparition-fondu {
    from { opacity: 0; }
}

@keyframes apparition-merci {
    from { opacity: 0; transform: translateY(8px) scale(0.97); }
}

.champ input[type="number"],
.champ input[type="text"],
.champ textarea {
    font-family: var(--font-sans);
    font-size: 0.95rem;
    padding: 0.65rem 0.8rem;
    border: 1px solid var(--bordure);
    border-radius: 8px;
    background: var(--blanc);
    color: var(--texte);
}

.champ input:focus,
.champ textarea:focus {
    outline: none;
    border-color: var(--sauge-fonce);
}

.champ input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--sauge);
}

.bouton-envoyer {
    margin-top: 0.5rem;
    padding: 0.95rem;
    border: none;
    border-radius: 999px;
    background: var(--sauge);
    color: var(--texte);
    font-family: var(--font-sans);
    font-weight: 600;
    font-size: 0.95rem;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 0.2s ease, transform 0.1s ease, color 0.2s ease;
}

/* Le fond passe au sauge foncé au survol : le texte repasse en crème pour
   rester lisible (le texte foncé, correct sur le sauge clair, ne passerait
   plus le contraste AA sur ce fond sombre). */
.bouton-envoyer:hover { background: var(--sauge-fonce); color: var(--creme); }
.bouton-envoyer:active { transform: scale(0.98); }

.bouton-envoyer:disabled {
    background: var(--sable);
    cursor: default;
}

.rsvp-merci {
    text-align: center;
    padding: 1.5rem 0;
    animation: apparition-merci 400ms cubic-bezier(.16, 1, .3, 1);
}

.rsvp-merci p {
    font-size: 1rem;
    color: var(--texte);
}

.lien-texte {
    margin-top: 0.75rem;
    background: none;
    border: none;
    text-decoration: underline;
    color: var(--texte-clair);
    font-size: 0.85rem;
    cursor: pointer;
}

/* ---------- FOOTER ---------- */

.footer {
    padding: 4.5rem 1.75rem;
    text-align: center;
    background: radial-gradient(120% 140% at 50% 0%, var(--sauge-clair), var(--sauge-fonce) 70%);
    color: var(--creme);
    border-top: 2px solid var(--or);
    border-bottom: none;
}

.footer__mot {
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 1.3rem;
    opacity: 0.9;
    margin: 0;
    display: inline-block;
    transform: scale(0.8);
    transition: transform 0.5s cubic-bezier(.16, 1, .3, 1);
    transition-delay: 0.2s;
}

/* Le mot d'accueil se pose comme un dernier cachet — clin d'œil à celui
   qu'on a brisé pour entrer, sans reprendre le même geste. */
.reveal--visible .footer__mot {
    transform: scale(1);
}

.footer__prenoms {
    font-family: var(--font-script);
    font-size: 2rem;
    margin: 1.25rem 0 0;
}

@media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; transition: none; }
    .accueil { transition: none; }

    /* Merci et erreurs : fondu seul, sans glissement ni échelle. */
    .rsvp-merci { animation-name: apparition-fondu; }
    .champ__erreur { animation-name: apparition-fondu; }
    .bloc__lien-maps:active,
    .champ--checkbox:active .champ__label { transform: none; }

    /* La vidéo d'ouverture n'est pas jouée (main.js) : l'appui sur le cachet
       mène directement au contenu. */
    .accueil__foyer,
    .accueil__accroche,
    .accueil__prenoms,
    .accueil__date,
    .accueil__euca,
    .ornement,
    .accueil__consigne,
    .accueil__mention {
        transition-delay: 0s !important;
    }

    /* Le feuillage d'accueil s'efface sans le glissement d'ouverture. */
    .accueil--ouverture .accueil__euca--gauche { transform: none !important; }
    .accueil--ouverture .accueil__euca--droite { transform: none !important; }

    /* Contenu : tout apparaît net et en place avec le bloc, sans les
       signatures de révélation (dessin d'ornement, flou d'encre, tirage
       qui glisse, énumération, cachet final). */
    .bloc .ornement__ligne,
    .bloc .ornement__point,
    .bloc__titre--script,
    .lieu-photo,
    .lieu-info,
    .programme__ligne,
    .form-rsvp > *,
    .footer__mot {
        transform: none !important;
        filter: none !important;
        clip-path: none !important;
        opacity: 1 !important;
        transition: none !important;
        transition-delay: 0s !important;
    }

    /* Feuillages de filigrane : plaqués sans transition, à leur position
       fixe (translateY de centrage vertical conservé, ce n'est pas une
       animation à réduire). */
    .bloc__euca {
        transition: none !important;
    }
}

/* Easter egg « Dress code » : l'invité surgit du bas à droite. */
.easter-egg {
    position: fixed;
    right: 0;
    bottom: 0;
    z-index: 60;
    width: clamp(110px, 30vw, 160px);
    pointer-events: none;
    transform: translateX(110%);
    transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.easter-egg--visible { transform: translateX(0); }
.easter-egg img { display: block; width: 100%; height: auto; image-rendering: pixelated; }
.easter-egg__bulle {
    position: absolute;
    right: 100%;
    top: 12%;
    margin-right: 0.4rem;
    padding: 0.4rem 0.7rem;
    background: #fff;
    border: 1px solid var(--sauge, #8a9a7b);
    border-radius: 12px;
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 1rem;
    white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
    .easter-egg { transform: none; opacity: 0; transition: opacity 0.2s; }
    .easter-egg--visible { opacity: 1; }
}
