/* Page publique de demande d'invitations : complète app.css (classes ct-* et form__*).
   Signature : « le fil du labyrinthe » — un filet court dans la gouttière du formulaire et
   traverse, à chaque section, un nœud repris des carrés imbriqués du logo LabyLéo. */

.ct-form-card {
    /* Le rail du fil occupe la gauche de la carte : on rogne son padding de ce côté,
       sinon le contenu se retrouve deux fois plus loin du bord à gauche qu'à droite. */
    padding-left: clamp(0.9rem, 2vw, 1.4rem);
    /* Géométrie du fil. Redéclarées au point de rupture mobile : le calc() du nœud suit. */
    --inv-gutter: 2.5rem;
    --inv-line: 1rem;
    --inv-node-size: 26px;
    /* #f39200 est à 2,3:1 sur blanc : jamais pour du texte. Valeur reprise d'invitation.css. */
    --inv-orange-text: #b35900;
    --inv-muted: rgba(29, 42, 31, 0.62);
    --inv-danger: #c0392b;
}

/* Colonne unique élargie : de quoi loger la gouttière sans rétrécir les champs. */
.ct-main__grid--single {
    grid-template-columns: minmax(0, 1fr);
    max-width: 940px;
}

/* ========== Respiration de l'en-tête ==========
   Sans barre de navigation au-dessus, le padding d'origine (jusqu'à 96 px en haut)
   n'est plus qu'un vide. On resserre l'intro et son raccord avec la carte. */

.ct-intro {
    padding-top: clamp(1.75rem, 3.5vw, 3rem);
    padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

.ct-intro__meta {
    margin-bottom: 0.75rem;
}

.ct-intro__rule {
    margin: 1.25rem 0;
}

.ct-main {
    padding-top: clamp(1.5rem, 3vw, 2.5rem);
}

/* ========== En-tête : logo sur la ligne du titre ==========
   La page n'a pas de navigation : le logo est le seul retour vers l'accueil. */

.inv-masthead {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 3vw, 2.5rem);
}

.inv-masthead__logo {
    flex: 0 0 auto;
    display: block;
    line-height: 0;
    border-radius: 6px;
}

/* Le logo est un verrou horizontal : son texte est petit rapport à sa largeur. Pour qu'il
   tienne tête au titre il lui faut nettement plus de place que sa taille de barre de nav. */
.inv-masthead__logo img {
    display: block;
    width: clamp(120px, 19vw, 230px);
    height: auto;
}

.inv-masthead__logo svg {
    display: block;
    width: clamp(56px, 9vw, 104px);
    height: auto;
}

/* Le pied de page n'a plus que sa barre légale : la marge du bloc supprimé doit partir avec lui. */
.site-footer {
    padding-top: clamp(1.25rem, 3vw, 2rem);
    padding-bottom: clamp(1.25rem, 3vw, 2rem);
}

.site-footer__bottom--only {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.inv-masthead__logo:focus-visible {
    outline: 3px solid var(--color-orange);
    outline-offset: 4px;
}

/* « Demande d'invitation » tient sur une ligne. Mesure faite sur BunaeroPro-BoldUp
   (font-weight 800) : la chaîne fait 9,045 em, moins letter-spacing -0,02em × 20
   caractères, soit 8,65 × la taille de police. Les bornes ci-dessous en découlent. */
.inv-masthead .ct-intro__title {
    max-width: none;
    white-space: nowrap;
    font-size: clamp(1.35rem, 5.4vw, 4rem);
}

/* ========== Structure du formulaire ========== */

/* Les <input type="hidden"> sont des items flex : chacun consomme un gap de 1,1 rem. */
.invitation-request-form > input[type="hidden"] {
    display: none;
}

/* Reset du fieldset. `display: block` volontairement : le statut d'item flex de <legend>
   reste inégal selon les moteurs. `min-width: 0` neutralise le min-inline-size: min-content
   du user-agent, qui provoque des débordements horizontaux sur mobile. */
.invitation-request-form .form__section {
    display: block;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.invitation-request-form .form__section > .form__row + .form__row {
    margin-top: 1.1rem;
}

.invitation-request-form .form__legend {
    position: relative;
    display: block;
    float: none;
    width: 100%;
    margin: 0 0 1.15rem;
    padding: 0;
    font-family: var(--font-title);
    font-weight: 700;
    font-size: clamp(1.05rem, 1.6vw, 1.2rem);
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--ct-ink);
}

/* .ct-form-card__head est une grille « auto 1fr » prévue pour le numéro 01 du contact.
   Ici il n'y a rien à numéroter : une seule colonne. */
.ct-form-card__head {
    grid-template-columns: minmax(0, 1fr);
}

/* Tout le contenu de la carte partage le bord gauche des champs : sans ça, l'en-tête
   et la mention RGPD flottent 44 px à gauche du formulaire. */
.ct-form-card__head,
.ct-form-card__intro,
.invitation-request-form > .form__summary,
.invitation-request-form > .form__notice,
.invitation-request-form > .form__field--turnstile,
.invitation-request-form > .form__error--global,
.invitation-request-form > .form__actions,
.invitation-request-form > .form__privacy {
    margin-left: var(--inv-gutter);
}

/* ========== Le fil ========== */

.inv-thread {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 2rem;
    padding-left: var(--inv-gutter);
}

.inv-thread::before {
    content: "";
    position: absolute;
    top: 0.75rem;
    bottom: 1.75rem;
    left: var(--inv-line);
    width: 2px;
    border-radius: 1px;
    background: repeating-linear-gradient(
        180deg,
        var(--ct-kraft-deep) 0 6px,
        transparent 6px 12px
    );
}

.inv-thread > .form__section {
    position: relative;
}

.inv-node {
    position: absolute;
    top: 50%;
    left: calc(var(--inv-line) - var(--inv-gutter) - var(--inv-node-size) / 2 + 1px);
    width: var(--inv-node-size);
    height: var(--inv-node-size);
    transform: translateY(-50%);
    overflow: visible;
}

.inv-node__outer {
    fill: #fff;
    stroke: var(--ct-kraft-deep);
    stroke-width: 3;
    transition: fill 0.25s ease, stroke 0.25s ease;
}

.inv-node__middle {
    fill: none;
    stroke: var(--ct-kraft-deep);
    stroke-width: 2.5;
    transition: stroke 0.25s ease, opacity 0.25s ease;
}

.inv-node__core {
    fill: var(--color-orange);
    opacity: 0;
    transition: opacity 0.25s ease;
}

.inv-node__check {
    fill: none;
    stroke: #fff;
    stroke-width: 4;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.inv-node[data-state="doing"] .inv-node__outer,
.inv-node[data-state="doing"] .inv-node__middle {
    stroke: var(--color-orange);
}

.inv-node[data-state="doing"] .inv-node__core {
    opacity: 1;
}

.inv-node[data-state="done"] .inv-node__outer {
    fill: var(--color-nature);
    stroke: var(--color-nature);
}

.inv-node[data-state="done"] .inv-node__middle,
.inv-node[data-state="done"] .inv-node__core {
    opacity: 0;
}

.inv-node[data-state="done"] .inv-node__check {
    opacity: 1;
}

.inv-node[data-state="error"] .inv-node__outer,
.inv-node[data-state="error"] .inv-node__middle {
    stroke: var(--inv-danger);
}

.inv-node[data-state="error"] .inv-node__core {
    fill: var(--inv-danger);
    opacity: 1;
}

/* ========== Champs ========== */

.form__label-line {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.form__optional {
    font-family: var(--font-body);
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--inv-muted);
}

/* L'aide est rendue au-dessus du champ : on lit la contrainte avant de saisir. */
.invitation-request-form .form__help,
.invitation-request-form .help-text {
    margin: -0.1rem 0 0.1rem;
    font-family: var(--font-body);
    font-size: 0.85rem;
    line-height: 1.45;
    color: var(--inv-muted);
}

/* Champs un peu plus bas : 0,85rem de padding vertical donnait 52,6 px de haut, ce qui
   pèse sur un formulaire de douze champs. Le corps du texte reste à 1rem — le réduire
   nuirait à la lisibilité, et c'est la hauteur qui était en cause. */
.invitation-request-form .form__input,
.invitation-request-form .form__select,
.invitation-request-form .form__textarea {
    padding: 0.62rem 0.9rem;
}

/* Le code postal annonce sa longueur : plus étroit que la ville. */
.form__row--postal > .form__field:first-child {
    flex: 0 1 190px;
}

/* Lignes dépendant du type de demandeur : app.css déclare .form__row { display: flex },
   qui écraserait le [hidden] posé par le JavaScript. */
.invitation-request-form [data-inv-requester][hidden],
.invitation-request-form [data-inv-reveal][hidden] {
    display: none;
}

/* app.css déclare .form__error { display: block } — une règle auteur écrase le
   [hidden] du user-agent, il faut donc le rétablir explicitement. */
.invitation-request-form .form__error[hidden] {
    display: none;
}

.invitation-request-form .form__error > ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Pré-remplissage depuis l'annuaire officiel : zone `aria-live` sous le SIRET / le RNA. Elle
   reste dans le DOM (une zone live doit exister avant d'être remplie). `data-state` vient du JavaScript. La recherche en cours reste un simple texte
   gris ; un résultat devient un encart (même motif que .form__summary) : orange pour ce qui
   demande d'agir (introuvable, fermé, indisponible), vert pour une structure trouvée. Jamais
   de rouge : il reste réservé aux erreurs de validation. */
.invitation-request-form .form__lookup-status {
    margin: 0.5rem 0 0;
    font-family: var(--font-body);
    font-size: 0.85rem;
    line-height: 1.45;
    color: var(--inv-muted);
}

/* Vide, la zone garde la hauteur d'une ligne : l'annonce « Recherche… », posée quand on quitte
   le champ, ne décale plus rien. Sans cette réserve, le bouton d'envoi descendait sous le
   pointeur entre l'appui et le relâchement, et le clic sur « Envoyer » était perdu. */
.invitation-request-form .form__lookup-status:empty {
    min-height: 1.45em;
}

.invitation-request-form .form__lookup-status[data-state="found"],
.invitation-request-form .form__lookup-status[data-state="not_found"],
.invitation-request-form .form__lookup-status[data-state="closed"],
.invitation-request-form .form__lookup-status[data-state="unavailable"] {
    padding: 0.6rem 0.9rem;
    border-radius: 8px;
    font-size: 0.95rem;
}

/* Texte pierre sur orange très clair : contraste ≈ 9:1. */
.invitation-request-form .form__lookup-status[data-state="not_found"],
.invitation-request-form .form__lookup-status[data-state="closed"],
.invitation-request-form .form__lookup-status[data-state="unavailable"] {
    border-left: 3px solid var(--color-orange);
    background: #fff4e0;
    color: var(--color-pierre);
}

/* Confirmation discrète : vert nature profond sur vert très clair, contraste ≈ 6:1. */
.invitation-request-form .form__lookup-status[data-state="found"] {
    border-left: 3px solid var(--color-nature);
    background: #eef5e6;
    color: var(--color-nature-deep);
}

/* ========== Résumé d'erreurs ========== */

.form__summary {
    padding: 1rem 1.2rem;
    border-radius: 10px;
    border-left: 3px solid var(--inv-danger);
    background: linear-gradient(135deg, #fdecea 0%, #fad4d0 100%);
    color: #922b21;
    font-family: var(--font-body);
}

.form__summary[hidden] {
    display: none;
}

.form__summary-title {
    margin: 0 0 0.5rem;
    font-family: var(--font-title);
    font-weight: 700;
    font-size: 1.02rem;
    color: #7d241c;
}

.form__summary-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.1rem;
    font-size: 0.92rem;
}

.form__summary-list a {
    color: #922b21;
    text-decoration: underline;
    text-decoration-thickness: 1.5px;
    text-underline-offset: 3px;
}

.form__summary-list a:hover {
    color: var(--ct-ink);
}

/* ========== Consigne de distribution ==========
   Note d'information, pas une alerte : le vert du site plutôt que le rouge du résumé
   d'erreurs, et un filet à gauche assez discret pour ne pas concurrencer le fil. */

.form__notice {
    margin: 0 0 1.5rem;
    padding: 0.8rem 1rem;
    border-left: 3px solid var(--color-nature);
    border-radius: 8px;
    background: rgba(45, 102, 57, 0.07);
    font-family: var(--font-body);
    font-size: 0.96rem;
    line-height: 1.55;
    color: var(--ct-ink);
}

/* ========== Bouton, en-tête, confirmation ========== */

.form__submit[disabled] {
    cursor: progress;
    opacity: 0.72;
    box-shadow: none;
}

.form__submit[disabled]:hover {
    background: var(--color-orange);
    transform: none;
}

.inv-confirmation {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: clamp(1.25rem, 3vw, 2.25rem);
    align-items: center;
}

.inv-confirmation--plain {
    grid-template-columns: minmax(0, 1fr);
}

.inv-confirmation__mascot {
    width: clamp(110px, 18vw, 170px);
}

.inv-confirmation__mascot img {
    display: block;
    width: 100%;
    height: auto;
}

.inv-confirmation__title {
    margin: 0 0 0.6rem;
    font-family: var(--font-cursive);
    font-weight: 700;
    font-size: clamp(1.9rem, 4vw, 2.6rem);
    line-height: 1.05;
    color: var(--color-nature-deep);
}

.inv-confirmation__body {
    margin: 0;
    font-family: var(--font-body);
    font-size: 1.02rem;
    line-height: 1.6;
    color: var(--ct-ink);
}

/* Même note d'information que sur le formulaire, en rappel après l'accusé de réception.
   Le filet vert la distingue du bloc orange « Dernière étape » qui peut la suivre. */
.inv-confirmation__notice {
    margin: 0.9rem 0 0;
    padding: 0.7rem 0.9rem;
    border-left: 3px solid var(--color-nature);
    border-radius: 8px;
    background: rgba(45, 102, 57, 0.07);
    font-family: var(--font-body);
    font-size: 0.96rem;
    line-height: 1.55;
    color: var(--ct-ink);
    text-align: left;
}

.inv-confirmation__back {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-top: 1.25rem;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--inv-orange-text);
    text-decoration: underline;
    text-decoration-thickness: 1.5px;
    text-underline-offset: 4px;
}

.inv-confirmation__back:hover {
    color: var(--color-nature-deep);
}

/* app.css n'a aucun anneau de focus global : on le pose au moins ici. */
.invitation-request-form .form__submit:focus-visible,
.form__summary-list a:focus-visible,
.inv-confirmation__back:focus-visible {
    outline: 3px solid var(--color-orange);
    outline-offset: 3px;
    border-radius: 4px;
}

/* ========== Mention RGPD ========== */

.form__privacy {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ct-rule);
    font-family: var(--font-body);
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--color-pierre);
}

/* ========== Choix du canal de remise ==========
   Deux cartes cliquables plutôt que deux puces : la cible est plus grande au doigt, et
   l'état coché se lit sans distinguer un point de 8 px. Le bouton natif reste dans le
   flux (jamais display:none) pour garder le focus clavier et la validation HTML. */

.form__field--delivery > .form__label {
    display: block;
}

.form__choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.35rem;
}

.form__choice {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    flex: 1 1 260px;
    padding: 0.85rem 1rem;
    border: 1px solid var(--ct-rule, rgba(29, 42, 31, 0.18));
    border-radius: 10px;
    background: #fff;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 0.98rem;
    line-height: 1.45;
    color: var(--ct-ink);
    transition: border-color 0.15s ease, background 0.15s ease;
}

.form__choice:hover {
    border-color: var(--color-nature-deep);
}

/* `appearance: none` plutôt qu'un bouton masqué doublé d'une pastille en <span> : le
   contrôle natif reste le seul élément, avec son focus, sa validité et son rôle. */
.form__choice-input {
    appearance: none;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin: 0.12rem 0 0;
    border: 2px solid var(--inv-muted);
    border-radius: 50%;
    background: #fff;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form__choice-input:checked {
    border-color: var(--color-orange);
    /* La pastille intérieure, dessinée sans nœud supplémentaire. En contraste forcé, ni
       `box-shadow` ni `background` ne sont rendus : l'état coché se redit plus bas. */
    box-shadow: inset 0 0 0 4px #fff, inset 0 0 0 10px var(--color-orange);
}

.form__choice-input:focus-visible {
    outline: 3px solid var(--color-orange);
    outline-offset: 3px;
}

.form__choice:has(.form__choice-input:checked) {
    border-color: var(--color-orange);
    background: rgba(243, 146, 0, 0.07);
}

/* En contraste forcé, le système neutralise ombre et fond, et `appearance: none` a déjà
   supprimé le rendu natif : sans ceci, coché et non coché seraient indistinguables. On
   redit l'état par un contour en `CanvasText`, une des couleurs imposées — sur le bouton
   et sur sa carte. `outline` plutôt qu'une bordure : aucun décalage de mise en page. */
@media (forced-colors: active) {
    .form__choice-input:checked {
        outline: 3px solid CanvasText;
        outline-offset: -3px;
    }

    .form__choice:has(.form__choice-input:checked) {
        outline: 2px solid CanvasText;
        outline-offset: 2px;
    }
}

.form__choice:has([aria-invalid="true"]),
.form__choice:has([aria-invalid="true"]) .form__choice-input {
    border-color: var(--inv-danger);
}

/* ========== Dernière étape : l'enveloppe timbrée ==========
   Bloc de rappel sous les messages de succès, quand le demandeur a choisi le courrier. */

.inv-confirmation__postal {
    margin-top: 1.25rem;
    padding: 1rem 1.15rem;
    border-left: 4px solid var(--color-orange);
    border-radius: 8px;
    background: rgba(243, 146, 0, 0.08);
    text-align: left;
}

.inv-confirmation__postal-title {
    margin: 0 0 0.45rem;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--color-nature-deep);
}

.inv-confirmation__postal-body,
.inv-confirmation__postal-note,
.inv-confirmation__postal-outro {
    margin: 0;
    font-family: var(--font-body);
    font-size: 0.98rem;
    line-height: 1.6;
    color: var(--ct-ink);
}

.inv-confirmation__address {
    margin: 0.75rem 0;
    padding: 0.75rem 0.9rem;
    border-radius: 6px;
    background: #fff;
    font-family: var(--font-body);
    font-style: normal;
    font-weight: 600;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--color-nature-deep);
}

.inv-confirmation__postal-note {
    margin-bottom: 0.5rem;
    font-size: 0.9rem;
    color: var(--inv-muted);
}

/* ========== Mobile ========== */

@media (max-width: 560px) {
    .inv-masthead__logo img {
        width: 88px;
    }

    .inv-masthead__logo svg {
        width: 46px;
    }

    .ct-form-card {
        --inv-gutter: 1.75rem;
        --inv-line: 0.5rem;
        --inv-node-size: 20px;
    }

    .inv-thread {
        gap: 1.6rem;
    }

    .form__row--postal > .form__field:first-child {
        flex: 1 1 220px;
    }

    .inv-confirmation {
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        text-align: center;
    }

    /* Une adresse postale se lit alignée à gauche, même quand la carte est centrée. */
    .inv-confirmation__postal {
        text-align: left;
    }

    .form__choice {
        flex: 1 1 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .inv-node__outer,
    .inv-node__middle,
    .inv-node__core,
    .inv-node__check {
        transition: none;
    }
}
