/* formulaires.css : devis, devis bateau, contact et merci, système Arche.

   Feuille différée (inc/head.php) : la grille du héros (.fm-hero : titre,
   baie, texte) est dans core.css, critique, et ne se redéfinit pas ici,
   sinon le titre sauterait à l'arrivée de cette feuille. On n'ajoute ici que
   ce qui ne déplace rien : moulure, rameau, textes du héros, colonnade des
   étapes, colonne de côté, niches du contact.

   Les champs, choix, dépôt de photos et numéros d'étape sont dans rest.css.
   Aucune règle n'attend le JavaScript pour montrer un contenu : le mouvement
   (data-arche, data-lignes, data-monte, data-cascade) part de l'état final. */

@layer components {
  /* ======================================================================
     Le héros des formulaires
     ====================================================================== */
  .fm-hero__titre { font-size: var(--fs-h1); }
  .fm-hero--merci .fm-hero__titre { max-width: 12em; }
  /* Le rameau passe sous le texte : il n'est qu'une ombre sur l'enduit. */
  .fm-hero > .fm-hero__rameau { z-index: -1; }
  .fm-hero__panneau { max-width: 34rem; }
  .fm-hero__lead { font-size: var(--fs-lead); line-height: 1.65; color: var(--encre-doux); }
  .fm-hero__repere { display: grid; gap: .45rem; padding-top: var(--esp-m); border-top: var(--filet); }
  .fm-hero__repere-nom { font: italic 1.2rem / 1.3 var(--serif); color: var(--argile); }
  .fm-hero__prix { font-size: var(--fs-prix); }
  /* Le montant en Jost léger : un chiffre doux, jamais un gras qui crie.
     L'unité (« / m² ») suit à la même graisse légère, en encre douce : en
     Jost 400 plein, elle paraissait plus grasse que le prix. */
  .fm-hero__prix .prix .u-num { font-weight: 300; font-size: 1.25em; color: var(--encre); }
  .fm-hero__unite { font-weight: 300; color: var(--encre-doux); }
  .fm-hero__repere-texte { font-size: var(--fs-petit); color: var(--encre-doux); }
  /* Le montant et son complément sur une même ligne, alignés sur la ligne de
     base ; le complément ne passe dessous que faute de place. */
  .fm-hero__prix { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .55rem; }
  .fm-hero__prix-quoi { font-size: var(--fs-petit); color: var(--encre-doux); }
  .fm-hero__prix-quoi > [aria-hidden] { color: var(--argile); }
  /* Téléphone : la ligne ne tient pas, le complément passe dessous. Il y
     devient une phrase à part entière : sans le point médian, et avec sa
     majuscule (« Le minimum d'intervention, prix TTC »), jamais un fragment. */
  @media (max-width: 599px) {
    .fm-hero__prix-quoi { flex-basis: 100%; }
    .fm-hero__prix-quoi > [aria-hidden] { display: none; }
    .fm-hero__prix-quoi::first-letter { text-transform: uppercase; }
  }

  /* Le surtitre est au-dessus du titre, hors du panneau : sa place est dans
     la grille critique (core.css), rien ne bouge à l'arrivée de cette feuille. */
  .fm-hero__liens { padding-top: var(--esp-s); }
  .fm-hero__repere .fm-hero__liens { padding-top: .2rem; }
  .fm-merci__actions { padding-top: var(--esp-s); }
  /* Le téléphone dans un bouton : l'icône à la taille du libellé. */
  .fm-hero .btn .icon, .fm-cote .btn .icon { width: 17px; height: 17px; }

  /* Cadrages : chaque image garde son sujet au centre de la baie, y compris
     en bandeau sur tablette et téléphone (le devis pose le sien en ligne,
     il dépend de la prestation). */
  .fm-hero__image--port { --cadrage: 50% 62%; }
  .fm-hero__image--chaises { --cadrage: 46% 56%; }
  .fm-hero__image--mer { --cadrage: 30% 64%; }
  /* Sur une teinte presque unie (le ciel du port, la mer de la terrasse), la
     lumière de persienne se lisait comme des bandes de compression : on
     l'adoucit. */
  :is(.fm-hero__image--port, .fm-hero__image--mer) .arche__ombre { opacity: .35; mix-blend-mode: soft-light; }

  /* La moulure de pierre qui suit la baie à 16 px, base ouverte, comme sur
     l'accueil. Élément vide de la même cellule de grille que la baie : tant
     que cette feuille n'est pas arrivée, il ne mesure rien. */
  .fm-hero__moulure { display: none; }
  /* Tablette : la baie est large et basse ; le plein cintre y ferait un dôme
     coupé. L'anse de panier, l'arc surbaissé, lui va mieux. */
  @media (min-width: 600px) and (max-width: 899px) { .fm-hero__image { border-radius: var(--anse); } }
  @media (min-width: 900px) {
    .fm-hero__moulure {
      display: block; grid-column: 2; grid-row: 1 / -1; justify-self: end; align-self: start;
      width: calc(100% + 32px); height: calc(clamp(440px, 72svh, 700px) + 16px); margin: -16px -16px 0 0;
      border: 1px solid var(--pierre); border-bottom: 0; border-radius: var(--cintre); pointer-events: none;
    }
    /* La légende fine sous la baie, comme sur l'accueil : une amorce en
       italique d'argile (data-amorce), puis la suite en encre douce
       (data-legende). Elle décrit la scène, jamais « photo d'ambiance »
       (l'alt le dit). Ses deux morceaux sont les pseudo-éléments de la
       moulure (élément décoratif, aria-hidden), rangés côte à côte en bas de
       sa boîte puis descendus sous la baie : sans cette feuille, rien ne
       s'affiche, et rien ne pèse dans la grille. */
    .fm-hero__moulure[data-legende] { display: flex; align-items: flex-end; gap: .3em; padding-inline: 16px; }
    .fm-hero__moulure[data-legende]::before,
    .fm-hero__moulure[data-legende]::after { translate: 0 calc(100% + .9rem); font: 1.02rem / 1.3 var(--serif); white-space: nowrap; }
    .fm-hero__moulure[data-amorce]::before { content: attr(data-amorce); flex: none; font-style: italic; color: var(--argile); }
    .fm-hero__moulure[data-legende]::after { content: attr(data-legende); min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--encre-doux); }
  }

  /* Téléphone : le titre, la baie, le chapo et le bouton tiennent dans le
     premier écran. Le bouton passe donc avant le repère de prix. */
  @media (max-width: 899px) {
    .fm-hero__titre { font-size: clamp(2.2rem, 1.2rem + 4.6vw, 3rem); }
    .fm-hero__panneau { display: flex; flex-direction: column; gap: var(--esp-s); }
    .fm-hero__panneau > * + * { margin-block-start: 0; }
    .fm-hero__lead { font-size: 1rem; }
    .fm-hero__panneau > .fm-hero__liens { order: 1; padding-top: 0; }
    .fm-hero__panneau > .fm-hero__repere { order: 2; padding-top: var(--esp-s); }
    .fm-hero__panneau > .fm-merci__actions { order: 3; }
  }

  /* ======================================================================
     Le formulaire et sa colonne de côté
     ====================================================================== */
  .fm-section { padding-block: var(--section-y-s) var(--section-y); }
  .fm-form { max-width: none; display: grid; gap: var(--esp-xl) clamp(2.5rem, 6vw, 6rem); align-items: start; }
  .fm-form__corps { display: grid; gap: var(--esp-xl); min-width: 0; max-width: 46rem; }
  .fm-form__erreur { grid-column: 1 / -1; }
  .fm-form__cote { display: grid; gap: var(--esp-m); min-width: 0; }
  @media (min-width: 1000px) { .fm-form { grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); } }
  /* Sur bureau, la colonne de côté accompagne le long formulaire au lieu de
     laisser 1 500 px de vide à droite des champs. Toute la colonne (760 px
     environ sur le devis) ne tenait que sur un écran de 880 px de haut et
     plus : sur un portable de 900 px, elle défilait et laissait le vide. Ici
     la colonne s'étire sur la hauteur du formulaire et seul son DERNIER
     encadré (« Une urgence, une question ? », 260 px environ) colle sous
     l'en-tête : les encadrés du dessus défilent normalement, et rien ne
     passe jamais sur un champ ni sur un autre encadré (le défaut de l'audit
     était un menu d'étapes collé au-dessus du contenu). */
  @media (min-width: 1000px) {
    .fm-form__cote { align-self: stretch; align-content: start; }
  }
  @media (min-width: 1000px) and (min-height: 560px) {
    .fm-form__cote > :last-child { position: sticky; top: calc(var(--h-entete) + 24px); }
  }
  /* Un champ amené à l'écran (tabulation, focus après une erreur) garde son
     libellé visible sous l'en-tête fixe, en plus du scroll-padding global. */
  .form :is(input, select, textarea) { scroll-margin-top: 3.5rem; }
  /* Le consentement en erreur : le message sous le libellé, la case cerclée. */
  .field--consent .field__error { grid-column: 2; }
  .field--consent.is-error input { outline: 2px solid var(--erreur); outline-offset: 3px; }

  /* Les étapes : le numéro dans une petite arche de pierre de 40 × 48. */
  .fm-etape { display: flex; align-items: center; gap: 1rem; }
  .fm-etape__num { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 40px; height: 48px; padding-top: 6px; border: 1px solid var(--pierre); border-radius: 999px 999px 4px 4px; background: var(--chaux-clair); font-size: .9rem; color: var(--argile); }
  .fm-etape__titre { font: 400 var(--fs-h3) / 1.15 var(--serif); }
  /* Quand la colonnade est là (JS), elle numérote déjà les étapes : la
     pastille « 01 » sous « 1 Vos articles » faisait doublon. Sans JS, la
     colonnade reste masquée et la pastille numérote les trois blocs. */
  .fm-progress:not([hidden]) ~ fieldset .fm-etape__num { display: none; }
  /* Après « Étape suivante », l'étape s'aligne sous la colonnade, qui reste
     visible au-dessus d'elle (form-devis.js appelle scrollIntoView). */
  .fm-form [data-step] { scroll-margin-top: 10.5rem; }

  /* ---- La colonnade des étapes : le geste de la famille ----
     Trois arches de pierre reliées par un fil. Le fil d'argile se tend
     d'une arche à l'autre à mesure que la demande avance (CSS seul, et
     immobile en mouvement réduit : la règle globale coupe les transitions). */
  .fm-progress { gap: 8px; padding-bottom: var(--esp-m); border-bottom: var(--filet); }
  .fm-progress::before, .fm-progress::after {
    content: ""; position: absolute; z-index: 0; top: 24px; height: 1px;
    left: calc((100% - 16px) / 6); right: calc((100% - 16px) / 6);
  }
  .fm-progress::before { background: var(--pierre); }
  .fm-progress::after { background: var(--argile); transform: scaleX(0); transform-origin: left center; transition: transform 1.6s var(--doux); }
  .fm-progress:has(> li:nth-child(2):is(.is-current, .is-done))::after { transform: scaleX(.5); }
  .fm-progress:has(> li:nth-child(3):is(.is-current, .is-done))::after { transform: scaleX(1); }
  .fm-progress li { position: relative; z-index: 1; gap: .6rem; font: italic 1.05rem / 1.25 var(--serif); }
  .fm-progress li::before { width: 40px; height: 48px; padding-top: 6px; font-size: .9rem; font-style: normal; transition: background-color var(--dur-survol) var(--doux), color var(--dur-survol) var(--doux), border-color var(--dur-survol) var(--doux); }
  /* Une étape franchie porte une coche d'argile à la place de son chiffre. */
  .fm-progress li.is-done::before {
    content: ""; background: var(--chaux-clair) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='11' viewBox='0 0 14 11'%3E%3Cpath d='M1.5 5.8l3.6 3.4L12.5 1.5' stroke='%238A5236' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 50% 60% / 14px 11px no-repeat;
  }

  /* Le rang de l'article : « Article » en italique, le chiffre en Jost à la
     même valeur visuelle (corps réduit, graisse du texte). */
  .article__rang .u-num { font-size: .84em; font-weight: 400; font-style: normal; }
  .articles__ajout .lien { min-height: 52px; }
  /* L'article est un fieldset : « .form fieldset » (rest.css) lui retirait son
     marge intérieure, et « Article 1 » collait au bord de l'encadré. */
  .form fieldset.article { gap: var(--esp-m); padding: var(--esp-m) clamp(1rem, 3vw, 1.75rem) var(--esp-l); }
  /* Un fieldset en grille sans gabarit de colonnes : sa piste implicite
     prenait la largeur EXTÉRIEURE du fieldset, et dès qu'un article était
     choisi, ses champs débordaient de l'encadré de 16 px à droite (390 px).
     Une colonne explicite, bornée à la boîte de contenu. */
  .form fieldset, .form fieldset.article, .article__champs { grid-template-columns: minmax(0, 1fr); }
  /* Même cause pour le champ des photos : le sélecteur de fichier imposait sa
     largeur minimale à la piste du .field, et la zone de dépôt sortait de
     l'encadré. Le consentement garde sa grille à deux colonnes (rest.css). */
  .form .field:not(.field--consent) { grid-template-columns: minmax(0, 1fr); }
  /* Les options de dimensions (« 160 × 200 ») en Jost, chiffres alignés. */
  .form select { font-family: var(--sans); font-variant-numeric: lining-nums tabular-nums; }
  .form fieldset.article .article__tete { margin-bottom: 0; }

  /* Le dépôt de photos. Sans JavaScript, le sélecteur natif, son bouton en
     pilule de 44 px. Avec JavaScript (html.js), le sélecteur est masqué à
     l'œil (il reste focalisable et garde son name) : une pilule de lin
     « Choisir des photos », son second libellé, ouvre le choix, et une ligne
     d'état tenue par form-devis.js dit « Aucune photo pour l'instant » ou
     « 2 photos », au lieu du « Aucun fi…er choisi » tronqué du navigateur. */
  .dropzone input[type="file"] { width: auto; min-height: 0; padding: 0; border: 0; background: none; box-shadow: none; color: var(--encre-doux); }
  .dropzone input[type="file"]::file-selector-button,
  .dropzone__bouton {
    min-height: 48px; margin-right: .8rem; padding: 0 1.5rem; border: 0; border-radius: var(--pill);
    background: var(--lin); color: var(--encre); font: 450 .95rem / 1.2 var(--sans); letter-spacing: .02em; cursor: pointer;
    transition: background-color var(--dur-survol) var(--doux);
  }
  .dropzone input[type="file"]:hover::file-selector-button, .dropzone__bouton:hover { background: var(--sable); }
  .dropzone__bouton, .dropzone__etat { display: none; }
  .js .dropzone input[type="file"] { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .js .dropzone__bouton { display: inline-flex; align-items: center; justify-content: center; margin: var(--esp-s) 0 0; }
  .js .dropzone input[type="file"]:focus-visible + .dropzone__bouton { outline: 2px solid var(--argile); outline-offset: 3px; }
  .js .dropzone__etat { display: block; margin-top: .6rem; font-size: var(--fs-petit); font-weight: 400; color: var(--encre-doux); }
  .dropzone { position: relative; }

  /* Le type de bateau : le nom, puis sa taille en dessous, plus discrète. */
  .choice__texte { display: grid; gap: .15rem; }
  .choice__texte small { font-size: var(--fs-mini); color: var(--encre-doux); }

  /* ---- La colonne de côté : encadrés d'enduit ---- */
  .fm-cote { display: grid; gap: .7rem; padding: 1.7rem 1.6rem; border-radius: var(--rayon); background: var(--enduit); }
  .fm-cote__titre { font: italic 1.2rem / 1.35 var(--serif); color: var(--encre); }
  .fm-cote p:not([class]) { font-size: var(--fs-petit); color: var(--encre-doux); }
  /* Les deux pilules du contact direct sont jumelles : même contour, même
     corps, même graisse, chacune son icône d'argile. */
  .fm-cote__liens { display: flex; flex-wrap: wrap; gap: 10px; padding-top: .3rem; }
  .fm-cote__liens > a { max-width: 100%; }
  .fm-cote .btn { padding: 0 1.25rem; font-size: .95rem; letter-spacing: .02em; }
  .fm-cote .btn .u-num { letter-spacing: .02em; }
  /* L'adresse e-mail est longue : elle peut se couper plutôt que déborder. */
  .fm-cote__mail span { overflow-wrap: anywhere; }
  /* Le numéro, lui, ne se coupe jamais entre deux paires de chiffres. */
  .fm-cote__tel .u-num { white-space: nowrap; }

  /* Les liens pris dans une phrase (consentement, aide) : argile et graisse
     500, comme « formulaire de devis », et un filet au survol et au focus.
     Sans cela, « politique de confidentialité » avait la couleur et la
     graisse de la phrase et ne se voyait pas comme un lien. */
  :is(.field--consent label, .form__aide) a {
    color: var(--argile); font-weight: 500;
    text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: .2em;
    transition: text-decoration-color var(--dur-survol) var(--doux);
  }
  :is(.field--consent label, .form__aide) a:is(:hover, :focus-visible) { text-decoration-color: currentColor; }

  /* ---- Le crédit d'impôt compact, dans la colonne du devis ---- */
  .fm-credit { display: grid; gap: .8rem; padding: 1.8rem 1.6rem; border-radius: var(--rayon); background: var(--enduit); }
  .fm-credit__taux { font: 300 3rem / 1 var(--sans); color: var(--argile); }
  .fm-credit__taux .u-num { font-weight: inherit; }
  .fm-credit__titre { font: 400 1.5rem / 1.15 var(--serif); }
  .fm-credit__titre em { font-style: italic; color: var(--argile); }
  .fm-credit > p:not([class]) { font-size: var(--fs-petit); color: var(--encre-doux); }
  .fm-credit__points { display: grid; gap: .45rem; }
  .fm-credit__points li { position: relative; padding-left: 1.5rem; font-size: var(--fs-petit); max-width: none; }
  .fm-credit__points li::before { content: ""; position: absolute; left: 2px; top: .45em; width: 8px; height: 13px; border-radius: 0 100% 0 100%; background: var(--olive); opacity: .75; transform: rotate(28deg); }
  /* Le logo Urssaf est blanc : il vit dans son cartouche d'encre (.logo-sap). */
  .fm-credit .logo-sap { justify-self: start; }
  .fm-credit__logos { width: 168px; }
  .fm-credit__legal { font-size: var(--fs-mini); color: var(--encre-doux); }
  /* Sur bureau, le cartouche Urssaf se range à droite du « 50 % » : la
     colonne gagne une rangée et tient dans un écran de 900 px de haut, ce
     qui lui permet de rester collée le long du formulaire (voir .fm-form__cote). */
  @media (min-width: 1000px) {
    .fm-credit { grid-template-columns: minmax(0, 1fr) auto; column-gap: 1rem; }
    .fm-credit > * { grid-column: 1 / -1; }
    .fm-credit > .fm-credit__taux { grid-column: 1; grid-row: 1; align-self: center; }
    .fm-credit > .logo-sap { grid-column: 2; grid-row: 1; align-self: center; }
    .fm-credit .logo-sap img { width: 150px; }
  }

  /* ======================================================================
     Devis bateau : les trente ports
     ====================================================================== */
  /* Après le formulaire, avant le pied : la bande se clôt elle-même. */
  .fm-ports { padding: 0 var(--marge) var(--section-y); text-align: center; }
  .fm-ports__surtitre { justify-content: center; }
  /* Sur bureau, les trente noms en ligne, séparés d'un point médian
     d'argile ; un nom ne se coupe jamais, la ligne se coupe entre deux. */
  .fm-ports__liste { margin-inline: auto; max-width: 70rem; font: italic 400 clamp(1.15rem, .95rem + .6vw, 1.5rem) / 1.65 var(--serif); color: var(--encre-doux); text-wrap: balance; }
  .fm-ports__liste > li { display: inline; max-width: none; white-space: nowrap; }
  .fm-ports__liste > li:not(:last-child)::after { content: "\00a0·"; color: var(--argile); }
  .fm-ports__note { justify-content: center; margin: var(--esp-l) auto 0; font-size: var(--fs-petit); color: var(--encre-doux); }
  /* Sous 900 px, la même liste en deux colonnes compactes : le contenu est
     le même qu'au bureau, jamais masqué (indexation sur la version mobile). */
  @media (max-width: 899px) {
    .fm-ports__liste { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .3rem 1.2rem; max-width: 34rem; font-size: 1rem; line-height: 1.35; text-align: left; }
    .fm-ports__liste > li { display: block; white-space: normal; }
    .fm-ports__liste > li:not(:last-child)::after { content: none; }
  }

  /* ======================================================================
     Contact : les trois niches, la base, le formulaire court
     ====================================================================== */
  .fm-section--voies { padding-bottom: var(--section-y-s); }
  .fm-voies__tete { margin-bottom: var(--esp-xl); }
  .fm-voies { display: grid; gap: var(--gouttiere); }
  /* Trois niches côte à côte seulement quand chacune a la place de son
     bouton sur une ligne ; en dessous, elles s'empilent sur une colonne
     mesurée, pour ne pas devenir des dômes de toute la largeur. */
  @media (min-width: 700px) { .fm-voies { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  .fm-voies > li { max-width: none; }
  /* Une niche cintrée : haut en plein cintre, bas arrondi, qui se soulève. */
  .fm-voie {
    display: flex; flex-direction: column; align-items: center; gap: .55rem; height: 100%; min-height: 19rem;
    padding: 3.2rem 1.8rem 2rem; border-radius: var(--niche); background: var(--chaux-clair); text-align: center;
    box-shadow: inset 0 0 0 1px rgba(205, 184, 149, .6);
    transition: translate var(--dur-survol) var(--doux), box-shadow var(--dur-survol) var(--doux);
  }
  .fm-voie:is(:hover, :focus-visible) { translate: 0 -5px; box-shadow: inset 0 0 0 1px var(--argile), var(--ombre-douce); }
  .fm-voie__icone { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 52px; margin-bottom: .6rem; padding-top: 6px; border: 1px solid var(--pierre); border-radius: 999px 999px 4px 4px; color: var(--argile); }
  .fm-voie__icone .icon { width: 20px; height: 20px; }
  .fm-voie__titre { font: 400 1.6rem / 1.2 var(--serif); }
  .fm-voie__texte { max-width: 22em; font-size: var(--fs-petit); color: var(--encre-doux); }
  /* Une vraie forme de bouton dans la niche (la niche entière est le lien). */
  .fm-voie__suite {
    display: inline-flex; align-items: center; gap: .6em; min-height: 46px; margin-top: auto; padding: 0 1.3rem;
    border-radius: var(--pill); box-shadow: inset 0 0 0 1px var(--contour); font: 450 .92rem / 1.2 var(--sans); letter-spacing: .02em; color: var(--encre); white-space: nowrap;
    transition: background-color var(--dur-survol) var(--doux);
  }
  .fm-voie__suite::after { content: ""; width: .95em; height: .6em; background: var(--fleche) center / contain no-repeat; transition: transform var(--dur-survol) var(--doux); }
  .fm-voie:is(:hover, :focus-visible) .fm-voie__suite { background: var(--lin); }
  .fm-voie:is(:hover, :focus-visible) .fm-voie__suite::after { transform: translateX(5px); }
  .fm-voie__texte + .fm-voie__suite { margin-top: auto; }
  .fm-voie > .fm-voie__texte { margin-bottom: var(--esp-s); }
  /* Tablette : trois niches plus étroites, sur une seule rangée. */
  @media (min-width: 700px) and (max-width: 999px) {
    .fm-voie { min-height: 0; padding: 2.4rem 1.1rem 1.6rem; }
    .fm-voie__titre { font-size: 1.35rem; }
    .fm-voie__suite { padding: 0 1rem; font-size: .86rem; }
  }
  /* Téléphone : chaque niche devient une rangée compacte de 88 px environ,
     petite arche et icône à gauche, titre et texte au centre, flèche à
     droite, au lieu de trois cartes d'un tiers d'écran presque vides. */
  @media (max-width: 699px) {
    .fm-voies { gap: 12px; }
    .fm-voie {
      display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 1rem; row-gap: .15rem;
      min-height: 88px; padding: .9rem 1.1rem; border-radius: var(--rayon); text-align: left;
    }
    .fm-voie__icone { grid-row: 1 / span 2; margin: 0; }
    .fm-voie__titre { grid-column: 2; font-size: 1.3rem; }
    .fm-voie__texte { grid-column: 2; margin: 0; font-size: .9rem; }
    .fm-voie > .fm-voie__texte { margin-bottom: 0; }
    /* Le libellé de la pilule cède la place à sa seule flèche (la rangée
       entière est le lien, et elle dit déjà où elle mène). */
    .fm-voie__suite { grid-column: 3; grid-row: 1 / span 2; width: 44px; min-height: 44px; margin: 0; padding: 0; justify-content: center; font-size: 0; }
    .fm-voie__suite::after { width: 18px; height: 12px; }
  }

  .fm-base { padding-block: var(--section-y); }
  .fm-base__grille { display: grid; gap: var(--esp-xl) clamp(2.5rem, 6vw, 6rem); align-items: start; }
  .fm-base__infos > * + * { margin-block-start: var(--esp-l); }
  /* La côte en large bande : réduite à 34 rem dans la colonne, ses noms de
     ville tombaient à 9 px. Ici, ils restent à 12 px et plus à toute largeur. */
  .fm-base__cote { width: 100%; max-width: 64rem; justify-self: center; }
  .fm-base__cote .coastline__point text { font-size: 24px; stroke-width: 6px; }
  @media (max-width: 699px) {
    /* Tracé réduit : les escales clés seules gardent leur nom, en plus grand
       (32 unités, puis 46 sous 500 px : 12 px et plus à l'écran). */
    .fm-base__cote .coastline__point:not(.is-cle, .coastline__point--base) text { display: none; }
    .fm-base__cote .coastline__point text { font-size: 32px; stroke-width: 8px; }
  }
  @media (max-width: 499px) { .fm-base__cote .coastline__point text { font-size: 46px; stroke-width: 10px; } }
  .fm-base__cote-legende { display: flex; align-items: center; gap: .7rem; margin-top: var(--esp-s); font: italic 1.1rem / 1.35 var(--serif); color: var(--argile); }
  .fm-base__anneau { flex: none; width: 10px; height: 10px; border: 1.5px solid var(--argile); border-radius: 50%; }
  .fm-base__form { padding: clamp(1.5rem, 4vw, 3rem); border-radius: var(--rayon); background: var(--chaux-clair); scroll-margin-top: 2rem; }
  .fm-base__reseaux { display: flex; flex-wrap: wrap; gap: 12px; }
  /* Les liens de la fiche (e-mail, téléphone) sont seuls dans leur ligne :
     argile, et 44 px de haut, jamais un texte qu'on ne voit pas cliquable. */
  .fm-base .fiche dd > a { display: inline-flex; align-items: center; min-height: var(--cible); color: var(--argile); font-weight: var(--fw-appui); }
  .fm-base .fiche dd > a.lien { color: var(--encre); font-weight: 450; }
  .fm-base__zone { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem; }
  @media (min-width: 900px) {
    .fm-base__grille { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
    .fm-base__infos { grid-column: 1; grid-row: 1; }
    .fm-base__form { grid-column: 2; grid-row: 1; }
    .fm-base__cote { grid-column: 1 / -1; grid-row: 2; }
  }
  /* Sur téléphone, le formulaire vient avant la côte : on écrit d'abord. */
  @media (max-width: 899px) {
    .fm-base__cote { order: 3; }
  }

  /* Blocs de structure des formulaires. */
  .form--devis { min-width: 0; }
}
