/* ============================================================
   ERP+ : Coquille atelier-commande (V1.3)

   Coquille des surfaces de commande : /new (commande unitaire, authentifiee)
   et /buy (commande visiteur, guest). Refonte presentationnelle #389 (refs
   #364). Header focus marine + carte plein ecran a gauche + panneau formulaire
   fixe a droite, mono-ecran.

   Portee du kit docs/design/system-v1.3/system/system.css (section atelier) et
   tokenisee sur erp-tokens.css / erp-typography.css / erp-components.css. Cette
   feuille est SCANNEE par check_design.sh (DEFAULT_TARGETS) : zero hex, var(--erp-*)
   ou color-mix uniquement, box-shadow via --shadow-* ou focus-visible, radius <= 4px
   hors cercles, polices DA2.

   Frontiere carto : les internes du widget de carte (rendu Leaflet, tuiles,
   controles, attribution, mini satellite) NE sont PAS stylises ici. Ils vivent
   dans public/css/atelier-carto.css (hors DEFAULT_TARGETS). Cette feuille
   n'habille QUE le chrome autour du widget. Voir #389 Phase A.
   ============================================================ */

/* ---------------------------------------------------------------
   Coquille : colonne flex pleine hauteur (dvh iOS Safari)
   --------------------------------------------------------------- */
/* Plein cadre : pas de gouttiere creme. La coquille porte sur <body> ; on annule
   la marge UA par defaut du body (le socle ne reset que box-sizing). 100dvh pour
   iOS Safari (barre d'adresse dynamique). overflow hidden : mono-ecran sans
   scroll de page (le panneau scrolle en interne). */
.atelier { display: flex; flex-direction: column; margin: 0; width: 100vw; height: 100vh; height: 100dvh; background: var(--erp-cream); overflow: hidden; }

/* ---------------------------------------------------------------
   Header focus (PAS une top nav de sections)
   --------------------------------------------------------------- */
.atelier__header {
  flex: none; min-height: 60px; display: flex; align-items: center; gap: var(--sp-5);
  padding: 0 var(--sp-6); background: var(--erp-marine); color: var(--erp-fg-on-marine);
  border-bottom: 1px solid var(--erp-marine-line); z-index: 1100;
}
.atelier__brand { display: flex; align-items: center; gap: var(--sp-5); }
.atelier__logo {
  font-family: var(--erp-font-serif); font-weight: 500; font-size: 22px; line-height: 1;
  letter-spacing: 0.02em; text-decoration: none; color: var(--erp-fg-on-marine);
}
.atelier__logo .erp-plus { color: var(--erp-terracotta-lt); font-weight: 600; }

/* Lien retour tableau de bord (header focus, passe 4 #389). adminLink reutilise
   le meme traitement (lien discret marine, filet gauche, masque par defaut). */
.atelier__back {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--erp-font-sans); font-size: 13px; font-weight: 500;
  color: var(--erp-fg-on-marine); opacity: 0.75; text-decoration: none;
  padding-left: var(--sp-5); border-left: 1px solid var(--erp-marine-line);
  transition: opacity 100ms ease;
}
.atelier__back:hover { opacity: 1; }

.atelier__spacer { flex: 1; }

/* Bloc utilisateur (variante authentifiee) */
.atelier__user { display: flex; align-items: center; gap: var(--sp-4); }
.atelier__user-block { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.25; }
.atelier__user-name { font-family: var(--erp-font-sans); font-size: 13px; font-weight: 600; color: var(--erp-fg-on-marine); }
.atelier__user-email { font-family: var(--erp-font-sans); font-size: 11px; color: var(--erp-fg-on-marine); opacity: 0.6; }
.atelier__credits {
  display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap;
  font-family: var(--erp-font-sans); font-size: 12px; color: var(--erp-fg-on-marine); opacity: 0.8;
  padding-left: var(--sp-4); border-left: 1px solid var(--erp-marine-line);
}
.atelier__credits strong { font-family: var(--erp-font-mono); font-weight: 500; color: var(--erp-terracotta-lt); opacity: 1; }
/* Solde bas (<= 2) : emphase par graisse. Pas de token rouge dans la palette
   doctrine ; la differenciation reste terracotta-lt en gras (ex hex #e74c3c retire). */
.atelier__credits strong.is-low { font-weight: 700; }
.atelier__logout {
  display: inline-flex; align-items: center;
  font-family: var(--erp-font-sans); font-size: 13px; color: var(--erp-fg-on-marine);
  opacity: 0.7; text-decoration: none; padding-left: var(--sp-4);
  border-left: 1px solid var(--erp-marine-line); transition: opacity 100ms ease;
}
.atelier__logout:hover { opacity: 1; }

/* Lien compte (variante guest) */
.atelier__guest-link {
  font-family: var(--erp-font-sans); font-size: 14px; font-weight: 600; color: var(--erp-terracotta-lt);
  text-decoration: none; border-bottom: 1px solid var(--erp-terracotta-lt); padding-bottom: 2px;
  transition: color 100ms ease, border-color 100ms ease;
}
.atelier__guest-link:hover { color: var(--erp-fg-on-marine); border-color: var(--erp-fg-on-marine); }

/* ---------------------------------------------------------------
   Corps : carte (gauche) + panneau formulaire (droite)
   --------------------------------------------------------------- */
/* Cadre editorial V1.3 (issue #401) : gouttieres en --sp-5 (24px) qui laissent
   respirer le fond --erp-cream de .atelier entre/autour des deux cartes. */
.atelier__body { flex: 1; display: grid; grid-template-columns: minmax(0,1fr) 420px; gap: var(--sp-5); padding: var(--sp-5); min-height: 0; }

/* Panneau formulaire fixe a droite, mono-ecran, colonne flex. Cadre editorial
   V1.3 (issue #401) : carte blanche pleine (idiome .erp-card) au lieu du seul
   border-left. overflow hidden clippe les coins arrondis ; la chaine min-height:0
   (body -> panel -> panel-scroll) est preservee, le scroll reste sur panel-scroll. */
.atelier__panel {
  display: flex; flex-direction: column; min-height: 0;
  background: var(--erp-white);
  border: 1px solid color-mix(in srgb, var(--erp-marine) 6%, transparent);
  border-radius: var(--radius-2); box-shadow: var(--shadow-2); overflow: hidden; z-index: 900;
}
.atelier__panel-head { flex: none; padding: var(--sp-5) var(--sp-6) 0; }
/* Conteneur d'accordeon (#469 correctif D2) : colonne flex, overflow HIDDEN (le
   panneau ne defile JAMAIS, sinon les en-tetes sortent du champ). Les 3 en-tetes
   d'etape restent epingles ; seul le corps de l'etape ouverte defile en interne
   (max-height calculee par layoutStepper). La paybar (.atelier__paybar) est un
   frere persistant, hors de ce conteneur. */
/* #469 polish D2 : la gouttiere horizontale passe sur les items (en-tetes +
   corps + eyebrow), plus sur le conteneur (padding lateral 0). Les filets de
   separation et le survol des en-tetes portent ainsi de bord a bord, fidele a la
   maquette D2 (.acc padding 8px 0 0). Vertical : 8px en tete, 0 en pied (le
   padding bas de l'en-tete du dernier item respire avant la paybar). */
.atelier__panel-scroll { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; -webkit-overflow-scrolling: touch; padding: var(--sp-2) 0 0; }
/* Eyebrow de tete de panneau : reprend la gouttiere des items (le conteneur n'en
   porte plus). */
.atelier__panel-scroll > .erp-eyebrow { padding: var(--sp-3) var(--sp-5) 0; }
/* Paybar fine persistante (#469 correctif D2, remplace l'ancien pied lourd) : barre
   marine epinglee en bas du panneau, prix TTC (/buy) ou indicateur de credits
   (/new) plus le CTA RELOCALISE (btn-pay / btn-generate, id inchange). ~70 px. */
.atelier__paybar {
  flex: none; display: flex; align-items: center; gap: var(--sp-4);
  background: var(--erp-marine); color: var(--erp-fg-on-marine);
  border-top: 1px solid var(--erp-marine-line); padding: var(--sp-4) var(--sp-6);
}
/* flex: none + white-space:nowrap : la colonne montant ne se compresse pas sous
   son contenu (min-width:0 laissait "1 credit" se replier sur deux lignes, /new,
   #469 polish) ; elle epouse sa valeur, qui tient toujours sur une seule ligne. */
.atelier__paybar-sum { display: flex; flex-direction: column; gap: 2px; flex: none; }
.atelier__paybar-lab { font-family: var(--erp-font-sans); font-size: 10px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--erp-terracotta-lt); white-space: nowrap; }
.atelier__paybar-val { font-family: var(--erp-font-mono); font-weight: 500; font-size: 22px; color: var(--erp-terracotta-lt); line-height: 1; white-space: nowrap; }
/* CTA dans la paybar : garde l'idiome btn-commander mais ne s'etire pas (pousse a
   droite, largeur auto au lieu du 100% pleine largeur) et reste sur une ligne. */
.atelier__paybar .btn-tooltip-wrap { margin-left: auto; width: auto; }
.atelier__paybar .btn-commander { width: auto; white-space: nowrap; }
/* Indicateur de solde (/new) : EMPILE sous le montant a debiter, dans la colonne
   .atelier__paybar-sum (#469 polish). A 420px, montant + solde + CTA ne tiennent pas
   cote a cote : on regroupe cout (libelle + valeur) et solde a gauche, le CTA pleine
   frappe a droite, comme la paybar /buy a deux blocs. Texte clair sur marine, etats
   bas en saumon, compact et sur une ligne. */
.atelier__paybar .credits-remaining { margin: 2px 0 0; text-align: left; color: var(--erp-fg-on-marine); white-space: nowrap; font-size: 12px; }
.atelier__paybar .credits-remaining.warning, .atelier__paybar .credits-remaining.danger { color: var(--erp-terracotta-lt); }

/* ---------------------------------------------------------------
   Repere de remplissage en temps (fill-step) : sommaire vertical, PAS une nav.
   Porte du kit (system.css), tokenise.
   --------------------------------------------------------------- */
.fill-step { position: relative; }
/* #469 polish D2 : separation des items par un simple filet (border-top), sans
   margin/padding sp-6 (64px de vide mort par jointure, qui volait la hauteur du
   corps ouvert et clippait #input-address). Fidele a la maquette : .accitem
   border-top 1px, .accitem:first-child border-top 0. Le rythme vertical des items
   replies vient desormais du seul padding de l'en-tete. */
.fill-step + .fill-step { border-top: 1px solid var(--erp-rule); }
.fill-step__head { display: flex; align-items: center; gap: 10px; margin-bottom: var(--sp-4); }
.fill-step__num {
  display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  border-radius: 50%; flex: none; font-family: var(--erp-font-sans); font-weight: 600; font-size: 12px;
  background: var(--erp-terracotta); color: var(--erp-white);
  border: 1px solid transparent; transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
/* Grammaire des puces unifiee (#469, refs #364), invariant FIXE pilote par
   order-*.js (filled[1..3], lot B) : terracotta (base ci-dessus) = etape courante,
   premiere NON remplie ; marine plein (--done) = etapes remplies, en amont ; gris
   vide (--todo) = etapes a venir, en aval. L'etape 3 (Revue) passe terracotta des
   que 1 et 2 sont remplies, jamais marine. Remplace le couple --active/--quiet.
   Le JS ne fait que basculer ces classes (aucun hex inline). */
.fill-step__num--done { background: var(--erp-marine); color: var(--erp-white); border-color: var(--erp-marine); }
.fill-step__num--todo { background: transparent; color: var(--erp-fg-4); border-color: var(--erp-rule-strong); }
/* transition color : pour le hover des en-tetes accordeon (#469, lot A). */
.fill-step__title { font-family: var(--erp-font-serif); font-weight: 500; font-size: 18px; color: var(--erp-fg-1); transition: color 120ms ease; }
.fill-step__opt { font-family: var(--erp-font-sans); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--erp-fg-4); margin-left: auto; }
@media (prefers-reduced-motion: reduce) { .fill-step__num { transition: none; } }

/* ---------------------------------------------------------------
   Stepper accordeon (#469, refs #364) : les en-tetes des etapes 1 et 2 (dans
   .atelier__panel-scroll) deviennent des boutons repliables ; l'etape 3 (Revue)
   reste la barre persistante .atelier__panel-foot, inchangee. Les 3 en-tetes
   restent visibles a TOUTE hauteur : ils sont EPINGLES (le panneau ne defile pas)
   et c'est le corps OUVERT qui defile en interne (overflow-y:auto) dans l'espace
   disponible, calcule par order-*.js (layoutStepper). Un seul volet ouvert a la
   fois (machine order-*.js). AUCUN media query de hauteur, aucun switch de mode :
   modele unique. Le corps se replie via max-height animee (jamais height:auto),
   transition de HAUTEUR SEULE 200 ms, neutralisee sous prefers-reduced-motion
   (precedent valide : le depli de la doc a 200 ms). Le chevron reprend le motif
   .collapsible-header.
   --------------------------------------------------------------- */
/* En-tete devenu bouton : reset du chrome natif, conserve le layout flex herite
   de .fill-step__head (num + titre). margin:0 annule le margin-bottom de base. */
/* #469 polish D2 : frappe d'en-tete calee sur la maquette (.acchead padding
   13px 24px, align-items:center). Le bloc titre + resume (.fill-step__head-main)
   est centre verticalement ; plus aucun vide sous le resume (il venait du
   margin/padding sp-6 entre items, supprime ci-dessus). */
.fill-step__head--toggle {
  width: 100%; margin: 0; padding: 13px var(--sp-5); border: none; background: none;
  cursor: pointer; -webkit-appearance: none; appearance: none;
  font-family: var(--erp-font-sans); transition: color 120ms ease, background-color 120ms ease;
}
.fill-step__head--toggle:hover { background: var(--erp-cream-soft); }
.fill-step__head--toggle:hover .fill-step__title { color: var(--erp-marine); }
/* Colonne titre + resume (le resume d'une ligne ne s'affiche que volet replie). */
.fill-step__head-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.fill-step__summary {
  font-family: var(--erp-font-sans); font-size: 12px; color: var(--erp-fg-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left;
}
.fill-step.is-open .fill-step__summary { display: none; }
/* Chevron : motif .collapsible-header (SVG Lucide inline currentColor), rotation
   90deg a l'ouverture. Transition de transform seule, neutralisee reduced-motion. */
.fill-step__chev { display: inline-flex; flex: none; margin-left: auto; color: var(--erp-fg-4); transition: transform 200ms ease; }
.fill-step.is-open .fill-step__chev { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .fill-step__chev { transition: none; } }
/* Corps repliable : max-height animee 0 (replie) vers l'espace disponible
   (ouvert, valeur posee en inline par layoutStepper). Le corps ouvert defile en
   interne (overflow-y:auto) : c'est ce qui EPINGLE les en-tetes. Replie hors
   transition, le corps porte aussi l'attribut [hidden] (JS) : il sort de l'ordre
   de tabulation. La valeur 75vh n'est qu'un repli sans JS (degrade en defilement
   du panneau) ; layoutStepper la remplace toujours par la hauteur calculee. */
.fill-step__body { max-height: 0; overflow: hidden; transition: max-height 200ms ease; }
/* Corps OUVERT : defile en interne (c'est ce qui epingle les en-tetes). max-height
   posee par layoutStepper (l'espace restant) ; 75vh = repli sans JS. Plus de mode
   degrade (le pied est desormais une paybar fine, l'espace ne manque plus). */
.fill-step.is-open > .fill-step__body { overflow-y: auto; max-height: 75vh; }
/* #469 polish D2 : gouttiere du corps ouvert calee sur l'en-tete (.accbody__inner
   padding 2px 24px 22px). Horizontal porte ici (le conteneur n'en a plus), aligne
   sur le texte de l'en-tete. */
.fill-step__body-inner { padding: var(--sp-1) var(--sp-5) var(--sp-5); }
@media (prefers-reduced-motion: reduce) { .fill-step__body { transition: none; } }

/* ---------------------------------------------------------------
   Recap de pied de panneau (Revue) : porte du kit, tokenise.
   --------------------------------------------------------------- */
.atelier-recap { display: flex; flex-direction: column; gap: var(--sp-3); margin: 0; }
.atelier-recap__line { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); font-family: var(--erp-font-sans); font-size: 14px; color: var(--erp-fg-2); }
.atelier-recap__line dt { color: var(--erp-fg-3); margin: 0; }
.atelier-recap__line dd { margin: 0; text-align: right; }
.atelier-recap__total { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--erp-rule-strong); }
.atelier-recap__total dt { font-family: var(--erp-font-sans); font-size: 13px; font-weight: 600; color: var(--erp-fg-1); margin: 0; }
.atelier-recap__total dd { margin: 0; font-family: var(--erp-font-mono); font-size: 22px; color: var(--erp-terracotta); }
.atelier-recap__note { font-family: var(--erp-font-sans); font-size: 12px; line-height: 1.4; color: var(--erp-fg-3); }

/* ---------------------------------------------------------------
   Encart prix (commande visiteur)
   --------------------------------------------------------------- */
.price-header {
  background: var(--erp-marine); color: var(--erp-fg-on-marine);
  border-radius: var(--radius-2); padding: var(--sp-4) var(--sp-5); margin-bottom: var(--sp-5);
}
.price-header__title { font-family: var(--erp-font-serif); font-weight: 500; font-size: 18px; color: var(--erp-fg-on-marine); margin: 0; }
.price-header__price { font-family: var(--erp-font-mono); font-weight: 500; font-size: 26px; color: var(--erp-terracotta-lt); margin-top: 4px; }
.price-header__sub { font-family: var(--erp-font-sans); font-size: 12px; opacity: 0.85; margin-top: 2px; }

/* ---------------------------------------------------------------
   Selecteur de mode de recherche (Adresse / Parcelle / GPS)
   parcel-selector.js bascule .active sur .search-mode et .search-panel.
   --------------------------------------------------------------- */
.search-modes { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.search-mode {
  flex: 1; padding: 8px 4px; border: 1px solid var(--erp-rule-strong); border-radius: var(--radius-1);
  background: var(--erp-white); color: var(--erp-fg-3); font-family: var(--erp-font-sans);
  font-size: 12px; font-weight: 600; cursor: pointer; text-align: center;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.search-mode:hover { border-color: var(--erp-marine); color: var(--erp-marine); }
/* Etat actif : aplat marine plein SEUL (pas de contour terracotta). */
.search-mode.active { background: var(--erp-marine); color: var(--erp-cream); border-color: var(--erp-marine); }
/* Accessibilite : outline distinct au focus clavier uniquement. */

.search-panel { display: none; }
.search-panel.active { display: block; }

/* ---------------------------------------------------------------
   Lignes de champs et rangees (panneaux de recherche, sur .erp-field)
   --------------------------------------------------------------- */
.field-row { display: flex; gap: var(--sp-3); }
.field-row > .erp-field { flex: 1; }

/* ---------------------------------------------------------------
   Autocomplete BAN / commune (DOM genere par parcel-selector.js)
   --------------------------------------------------------------- */
.autocomplete-host { position: relative; }
/* #469 correctif D2 : position FIXED (et non plus absolute dans .autocomplete-host)
   pour echapper a l'overflow:auto du corps d'etape ouvert (sinon la liste BAN est
   rognee). Position (top/left/width) posee en live par order-*.js (anchorAutocomplete)
   depuis le rect de l'input. z-index au-dessus de la paybar. */
.autocomplete-list {
  position: fixed; background: var(--erp-white);
  border: 1px solid var(--erp-rule-strong);
  border-radius: 0 0 var(--radius-1) var(--radius-1); box-shadow: var(--shadow-2);
  z-index: 1200; max-height: 220px; overflow-y: auto; display: none;
}
.autocomplete-list.open { display: block; }
.autocomplete-item {
  padding: 9px 12px; cursor: pointer; font-family: var(--erp-font-sans); font-size: 12px;
  border-bottom: 1px solid var(--erp-rule); display: flex; align-items: flex-start; gap: 8px;
}
.autocomplete-item:last-child { border-bottom: none; }
.autocomplete-item:hover, .autocomplete-item.highlighted { background: var(--erp-cream-soft); }
.autocomplete-item .ac-icon { color: var(--erp-terracotta); font-size: 13px; flex-shrink: 0; }
.autocomplete-item .ac-main { font-weight: 600; color: var(--erp-fg-1); }
.autocomplete-item .ac-context { font-size: 11px; color: var(--erp-fg-3); margin-top: 1px; }

/* ---------------------------------------------------------------
   Recap parcelle selectionnee (parcel-selector.js bascule .visible)
   --------------------------------------------------------------- */
/* Traitement erp-alert--confirme (kit) : fond blanc, filet marine gauche 3px,
   icone circle-check en tete, recapAddress = titre, recapDetails = corps. Hooks
   parcel-selector.js (recapAddress, recapDetails, recapClear, .visible) intacts. */
.parcelle-recap {
  display: none; position: relative; background: var(--erp-white);
  border: 1px solid var(--erp-rule-strong); border-left: 3px solid var(--erp-marine);
  border-radius: var(--radius-1); padding: var(--sp-3) var(--sp-4) var(--sp-3) calc(var(--sp-4) + 26px);
  margin-bottom: var(--sp-4); font-family: var(--erp-font-sans); font-size: 13px;
}
.parcelle-recap.visible { display: block; }
.parcelle-recap__icon { position: absolute; left: var(--sp-4); top: calc(var(--sp-3) + 4px); color: var(--erp-marine); display: inline-flex; }
.parcelle-recap .recap-address {
  font-family: var(--erp-font-sans); font-weight: 600; color: var(--erp-fg-1); margin-bottom: 4px;
  width: 100%; border: 1px solid transparent; border-radius: var(--radius-1); padding: 4px 8px;
  font-size: inherit; background: transparent; transition: border-color 120ms ease, background-color 120ms ease;
}
.parcelle-recap .recap-address:hover { border-color: var(--erp-rule-strong); background: var(--erp-white); }
/* VERDICT 111, LOT 2 SUR 4 DU DISPOSITIF DE FOCUS. La suppression nue est
   retiree, la primitive d'erp-components.css reprend d'elle meme, et rien
   d'autre n'est touche. Deux elements, deux surfaces.
   CAS FONDATEUR DE LA REGLE R111.1, et c'est pourquoi ce champ fait lot a lui
   seul : il PASSE D'UN FOND TRANSPARENT A UN FOND BLANC AU FOCUS, donc il
   modifie le fond contre lequel son propre contraste se mesure. Lire le
   contraste de l'anneau contre le fond de repos rendrait une valeur qui
   n'existe a aucun moment. Toute recette portant sur ce champ lit le fond DANS
   L'ETAT MESURE.
   LE FOND QUI CHANGE N'EST PAS TOUCHE : le verdict 111 a tranche qu'il ne
   qualifie pas au titre de la seconde grandeur du verdict 105, n'etant ni
   epaisseur, ni decalage, ni style. Il reste, comme le changement de bordure,
   un signal second et gratuit. */
.parcelle-recap .recap-address:focus { border-color: var(--erp-terracotta); background: var(--erp-white); }
.parcelle-recap .recap-address::placeholder { color: var(--erp-fg-4); font-weight: 400; }
.parcelle-recap .recap-details { color: var(--erp-fg-3); font-size: 12px; line-height: 1.6; }
.parcelle-recap .recap-details span { display: inline-block; margin-right: 12px; }
.recap-clear {
  position: absolute; top: 6px; right: 8px; background: none; border: none; font-size: 18px;
  color: var(--erp-fg-4); cursor: pointer; padding: 2px 6px; line-height: 1; border-radius: var(--radius-1);
}
.recap-clear:hover { color: var(--erp-terracotta-dk); }

/* ---------------------------------------------------------------
   Sections repliables (Informations nominatives)
   --------------------------------------------------------------- */
.collapsible-header {
  display: flex; align-items: center; gap: 8px; padding: 10px 0; cursor: pointer;
  font-family: var(--erp-font-sans); font-size: 13px; font-weight: 600; color: var(--erp-fg-2);
  border: none; background: none; width: 100%; text-align: left; transition: color 120ms ease;
}
.collapsible-header:hover { color: var(--erp-marine); }
.collapsible-header .chevron { display: inline-flex; color: var(--erp-fg-4); transition: transform 120ms ease; }
.collapsible-header.open .chevron { transform: rotate(90deg); }
.collapsible-body { display: none; padding-bottom: 8px; }
.collapsible-body.open { display: block; }

.separator { border: none; border-top: 1px solid var(--erp-rule); margin: var(--sp-2) 0; }

/* ---------------------------------------------------------------
   Toggle transaction (Vente / Location) : RADIOS preserves
   (name="transaction_type", contrat JS), habilles en segment carre.
   .erp-segment (socle) est button/aria-selected et incompatible avec les
   radios requis ; segment radio-based local conserve donc le contrat.
   --------------------------------------------------------------- */
/* align-self:flex-start : le segment epouse ses 2 options (Vente/Location) au lieu
   de s'etirer a la largeur de .erp-field (flex column, stretch par defaut) ; plus
   d'espace mort a droite (passe 4 #389). */
.tx-segment { display: inline-flex; align-self: flex-start; border: 1px solid var(--erp-marine); border-radius: var(--radius-1); overflow: hidden; margin-bottom: var(--sp-3); }
.tx-segment label {
  display: inline-flex; align-items: center; cursor: pointer;
  font-family: var(--erp-font-sans); font-size: 14px; font-weight: 600;
  padding: 9px 18px; color: var(--erp-marine); background: var(--erp-white);
  transition: background-color 120ms ease, color 120ms ease;
}
.tx-segment label + label { border-left: 1px solid var(--erp-marine); }
.tx-segment input { position: absolute; opacity: 0; width: 0; height: 0; }
/* Etat coche : aplat marine plein SEUL (pas de contour terracotta). */
.tx-segment label:has(input:checked) { background: var(--erp-marine); color: var(--erp-cream); }
/* Accessibilite : outline UNIQUEMENT au focus clavier (:focus-visible), distinct
   de l'etat coche. Le clic souris ne declenche pas l'outline (vs :focus-within). */
.tx-segment label:has(input:focus-visible) { outline: 2px solid var(--erp-focus-ring); outline-offset: -2px; }

/* ---------------------------------------------------------------
   Bloc B2B (case pro) : filet marine a gauche
   --------------------------------------------------------------- */
.pro-block { padding: var(--sp-2) 0 0 var(--sp-3); border-left: 2px solid var(--erp-rule-strong); margin: 0 0 var(--sp-3); }
.pro-hint { font-family: var(--erp-font-sans); font-size: 11px; margin-top: 4px; color: var(--erp-fg-3); }
.pro-hint--error { color: var(--erp-terracotta-dk); }
.pro-hint--ok { color: var(--erp-marine); }

/* ---------------------------------------------------------------
   L'ETIQUETTE DE CONSENTEMENT ET SA NOTICE ONT QUITTE CE FICHIER.

   .check-block et .notice-block vivaient ici tant que l'ecran de commande sans
   compte etait leur seule surface. Le lot de consentement a l'inscription les
   emploie sur une seconde surface, servie par une autre coquille : le verdict
   176 en fait des primitives du kit. Elles sont desormais .erp-check-block et
   .erp-notice-block dans public/css/erp-components.css, declarations
   inchangees.

   Ne pas les reposer ici, meme pour un besoin local : ce serait la recopie que
   le verdict refuse, et la surface d'inscription ne charge pas atelier.css.
   --------------------------------------------------------------- */
.guest-email-block {
  background: var(--erp-cream-soft); border: 1px solid var(--erp-rule-strong);
  border-radius: var(--radius-1); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-3);
}

/* ---------------------------------------------------------------
   Panier multi-parcelles (/new) : DOM genere par parcel-selector.js
   --------------------------------------------------------------- */
.parcelle-basket {
  background: var(--erp-cream-soft); border: 1px solid var(--erp-rule-strong);
  border-radius: var(--radius-1); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
}
.basket-header {
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--erp-font-sans); font-size: 11px; font-weight: 700; color: var(--erp-fg-3);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 8px;
}
.basket-clear-all { background: none; border: none; color: var(--erp-fg-4); cursor: pointer; padding: 2px 4px; border-radius: var(--radius-1); line-height: 1; transition: color 120ms ease; }
.basket-clear-all:hover { color: var(--erp-terracotta-dk); }
.basket-items { display: flex; flex-direction: column; gap: 4px; }
.basket-item {
  display: flex; align-items: center; justify-content: space-between; padding: 6px 8px;
  background: var(--erp-white); border: 1px solid var(--erp-rule-strong); border-radius: var(--radius-1);
  font-family: var(--erp-font-sans); font-size: 12px;
}
.basket-item-info { display: flex; align-items: center; gap: 6px; color: var(--erp-fg-2); font-weight: 500; }
.basket-item-commune { color: var(--erp-fg-3); font-weight: 400; }
.basket-badge { font-size: 9px; font-weight: 700; background: var(--erp-marine); color: var(--erp-cream); padding: 1px 5px; border-radius: var(--radius-1); flex-shrink: 0; }
.basket-remove { background: none; border: none; color: var(--erp-fg-4); cursor: pointer; font-size: 16px; padding: 0 4px; line-height: 1; flex-shrink: 0; }
.basket-remove:hover { color: var(--erp-terracotta-dk); }
.generation-mode { border-top: 1px solid var(--erp-rule); margin-top: 8px; padding-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.generation-mode label { display: flex; align-items: center; gap: 6px; font-family: var(--erp-font-sans); font-size: 12px; cursor: pointer; color: var(--erp-fg-2); }
.generation-mode input[type="radio"] { accent-color: var(--erp-marine); }

/* ---------------------------------------------------------------
   Notices (BAN imprecise, credits insuffisants)
   --------------------------------------------------------------- */
.ban-imprecise-notice {
  display: none; align-items: flex-start; gap: 8px; background: var(--erp-white);
  border: 1px solid var(--erp-rule-strong); border-left: 3px solid var(--erp-terracotta);
  border-radius: var(--radius-1); padding: var(--sp-3) var(--sp-4); margin-bottom: 8px;
  font-family: var(--erp-font-sans); font-size: 13px; color: var(--erp-fg-2); line-height: 1.4;
}
.ban-imprecise-notice .notice-icon { color: var(--erp-terracotta); flex-shrink: 0; display: inline-flex; }
.ban-imprecise-notice .notice-text { flex: 1; }
.credits-remaining { text-align: center; font-family: var(--erp-font-sans); font-size: 14px; color: var(--erp-fg-3); margin-top: 8px; }
.credits-remaining.warning { color: var(--erp-terracotta-dk); font-weight: 600; }
.credits-remaining.danger { color: var(--erp-terracotta-dk); font-weight: 700; }
.credits-insufficient {
  display: none; align-items: center; gap: 8px; background: var(--erp-white);
  border: 1px solid var(--erp-rule-strong); border-left: 3px solid var(--erp-terracotta);
  border-radius: var(--radius-1); padding: 10px 12px; margin-top: 8px;
  font-family: var(--erp-font-sans); font-size: 13px; color: var(--erp-fg-2);
}
.credits-insufficient.visible { display: flex; }
.credits-insufficient .notice-icon { color: var(--erp-terracotta); display: inline-flex; flex-shrink: 0; }
.credits-insufficient .notice-text { flex: 1; }
.credits-insufficient .notice-link { color: var(--erp-marine); font-weight: 700; text-decoration: underline; cursor: pointer; margin-left: 4px; }
.credits-insufficient .notice-link:hover { color: var(--erp-terracotta-dk); }

/* ---------------------------------------------------------------
   Boutons utilitaires (recherche cadastre/GPS)
   --------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 18px; border: none; border-radius: var(--radius-1);
  font-family: var(--erp-font-sans); font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease; text-decoration: none;
}
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--erp-marine); color: var(--erp-cream); }
.btn-primary:hover:not(:disabled) { background: var(--erp-marine-soft); }
/* P2 #389 : hauteur calee sur les champs .erp-input au-dessus (etait trop bas). */
.btn-sm { padding: 11px 16px; font-size: 13px; }

/* ---------------------------------------------------------------
   CTA principal (btn-commander) : pleine largeur terracotta.
   JS ajoute .success et injecte un spinner ; etats preserves.
   --------------------------------------------------------------- */
.btn-commander { width: 100%; justify-content: center; }
.btn-commander:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-commander.success { background: var(--erp-marine); pointer-events: none; }
.secure-note { text-align: center; font-family: var(--erp-font-sans); font-size: 11px; color: var(--erp-fg-3); margin-top: 8px; }

/* Tooltip sur bouton disabled (le title natif ne s'affiche pas sur :disabled) */
.btn-tooltip-wrap { position: relative; display: block; }
.btn-tooltip-wrap[data-tooltip]:not([data-tooltip=""])::after {
  content: attr(data-tooltip); position: absolute; bottom: calc(100% + 6px); left: 50%;
  transform: translateX(-50%); background: var(--erp-marine); color: var(--erp-fg-on-marine);
  padding: 7px 11px; border-radius: var(--radius-1); font-family: var(--erp-font-sans);
  font-size: 12px; line-height: 1.3; white-space: nowrap; max-width: 90vw;
  opacity: 0; pointer-events: none; transition: opacity 150ms ease; z-index: 100; box-shadow: var(--shadow-2);
}
.btn-tooltip-wrap[data-tooltip]:not([data-tooltip=""])::before {
  content: ""; position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: var(--erp-marine);
  opacity: 0; pointer-events: none; transition: opacity 150ms ease; z-index: 100;
}
.btn-tooltip-wrap[data-tooltip]:not([data-tooltip=""]):hover::after,
.btn-tooltip-wrap[data-tooltip]:not([data-tooltip=""]):hover::before { opacity: 1; }

/* ---------------------------------------------------------------
   L'EMPLACEMENT du controle de la paybar (verdict 175, lot C2 passe 2).

   /buy rend, a cet endroit et dans cet ordre, un controle, puis rien, puis un
   controle : commander, la jauge de generation, payer. La jauge n'est PAS un
   controle et ne prend aucun rang : elle ne porte aucune action, rien ne se
   passe si le client la presse. Elle est l'absence de controle rendue visible.
   Les deux controles, eux, prennent le MEME rang, .erp-btn--primary, parce que
   commander et payer sont deux actions principales que la surface execute elle
   meme, chacune unique a son moment.

   CE QUI EST TENU D'UN ETAT A L'AUTRE EST LA PLACE, PAS LE RANG, et la place se
   declare UNE FOIS, ici, sur le conteneur. Jamais sur chacun des trois objets :
   trois hauteurs egales obtenues par trois declarations sont une coincidence
   entretenue a la main, une hauteur de conteneur est une garantie. align-items:
   stretch fait le reste, les trois objets epousant la hauteur de l'emplacement
   sans en declarer aucune.

   La hauteur minimale est celle du bouton qu'elle accueille, et elle s'en
   derive : 14 px de gouttiere verticale de part et d'autre (.erp-btn) plus la
   ligne de 16 px de son icone Lucide. Aucun etat ne fait donc bouger la barre,
   ni le contenu qui la precede.

   Le conteneur porte aussi .btn-tooltip-wrap : l'infobulle du bouton desactive
   se pose sur ce meme element, plutot que sur un emballage de plus a l'interieur
   de l'emplacement, qui aurait rompu la chaine de hauteur.

   AUCUNE DECLARATION DE .gauge ICI, ni sous ce selecteur ni ailleurs dans cette
   feuille (verdict 176). Son accueil sur surface marine est une correction du
   kit, faite une fois dans erp-components.css.
   --------------------------------------------------------------- */
.atelier__paybar-slot { display: flex; align-items: stretch; min-height: 44px; }

/* ---------------------------------------------------------------
   Toast d'erreur (parcel-selector.js et JS soumission basculent .visible)
   --------------------------------------------------------------- */
.error-toast {
  display: none; background: var(--erp-white); border: 1px solid var(--erp-rule-strong);
  border-left: 3px solid var(--erp-terracotta-dk); color: var(--erp-terracotta-dk);
  padding: 10px 14px; border-radius: var(--radius-1); font-family: var(--erp-font-sans);
  font-size: 13px; margin-bottom: 12px;
}
.error-toast.visible { display: block; }

/* ---------------------------------------------------------------
   LES DEUX ANNONCES (registre, verdicts 242 a 248)

   Une primitive, deux variantes, deux places. AUCUN JETON NOUVEAU :
   tout vient de erp-tokens.css, comme le reste de cette feuille.

   DEGRADATION : au ras du bord bas de la carte, dans son cadre, jamais
   en tete de page. Elle est POSEE EN ABSOLU, donc hors flux : son
   retrait ne deplace pas la surface autour d'elle, ce qui est une
   exigence du registre et non un detail de mise en page.

   INDISPONIBILITE : bandeau en tete de la surface de commande, dans le
   flux, parce qu'un bandeau qui recouvre ce qu'il commente se lit mal.
   Sa marge basse n'existe que lorsqu'il est visible.
   --------------------------------------------------------------- */
.annonce { display: none; font-family: var(--erp-font-sans); font-size: 13px; }
.annonce.is-visible { display: block; }

.annonce--degradation {
  /* Au ras du bord HAUT du cadre : en bas, l'encart satellite en recouvrait la
     fin, ce qui a ete constate sur capture. A gauche, on laisse la place aux
     commandes de zoom de la bibliotheque plutot que de passer devant elles. */
  position: absolute; left: 88px; right: 12px; top: 12px; z-index: 900;
  background: var(--erp-white); border: 1px solid var(--erp-rule-strong);
  border-left: 3px solid var(--erp-marine-soft); color: var(--erp-marine);
  padding: 8px 12px; border-radius: var(--radius-1);
}

.annonce--indisponibilite {
  background: var(--erp-white); border: 1px solid var(--erp-rule-strong);
  border-left: 3px solid var(--erp-terracotta-dk); color: var(--erp-terracotta-dk);
  padding: 10px 14px; border-radius: var(--radius-1);
}
.annonce--indisponibilite.is-visible { margin-bottom: var(--sp-4); }

/* ---------------------------------------------------------------
   Spinner (injecte par le JS dans le CTA)
   --------------------------------------------------------------- */
.spinner-sm {
  width: 16px; height: 16px; border: 2px solid color-mix(in srgb, var(--erp-white) 30%, transparent);
  border-top-color: var(--erp-white); border-radius: 50%; animation: atelier-spin 0.7s linear infinite; flex-shrink: 0;
}
@keyframes atelier-spin { to { transform: rotate(360deg); } }

/* Modales : la primitive socle public/css/erp-modal.css (#399) remplace l'ancien
   bloc ad hoc .modal-* (retire ici). Le banner reste cible par .modal-banner dans
   erp-modal.css (contrat JS gele order-new.js::showModalBanner). */

/* ---------------------------------------------------------------
   Responsive : carte au-dessus, panneau dessous
   --------------------------------------------------------------- */
@media (max-width: 1024px) {
  /* Cartes empilees (carte au-dessus, panneau dessous). Le panneau etant
     desormais une carte a bordure pleine (issue #401), l'ancien override
     border-left -> border-top est sans objet et retire.
     #472 (Lot D passe 1) : la carte cede la hauteur (seul element compressible,
     verdict Claude Design Q1). La rangee carte passe de 45% fixe a
     clamp(132px, 22vh, 240px) : re-clee sur la hauteur du viewport (terme 22vh),
     plancher 132px, plafond 240px. Le panneau (1fr) prend le reste ; layoutStepper
     gere le corps avec son plancher 96px. */
  .atelier__body { grid-template-columns: 1fr; grid-template-rows: clamp(132px, 22vh, 240px) 1fr; }
}
@media (max-width: 600px) {
  .atelier__user-block { display: none; }
  .atelier__header { padding: 0 var(--sp-4); }
  .atelier__panel-head { padding: var(--sp-4) var(--sp-4) 0; }
  /* #469 polish D2 : la gouttiere horizontale est portee par les items (en-tetes /
     corps / eyebrow), pas par le conteneur, y compris en colonne etroite. */
  .atelier__panel-scroll { padding: var(--sp-2) 0 0; }
  .atelier__panel-foot { padding: var(--sp-4); }
}

/* ---------------------------------------------------------------
   #472 (Lot D passe 1) : re-cle sur la hauteur, independamment du seuil 1024.
   Sur un ecran court, la paybar passe en variante compacte une ligne (cible
   ~56px) : SEUL le padding vertical est resserre (hauteur/padding uniquement, le
   contrat #469 polish D2 et les id/name/payload du CTA Stripe restent intouches).
   Un ecran large-court garde ses deux colonnes : la bascule empile reste
   gouvernee par max-width:1024, la paybar vit dans le panneau et se compacte sans
   effet de bord sur la grille deux colonnes.
   --------------------------------------------------------------- */
@media (max-height: 720px) {
  .atelier__paybar { padding: var(--sp-2) var(--sp-6); }
}
/* Ecran court ET empile : on resserre encore la rangee carte (plancher abaisse,
   terme vh plus serre) pour liberer davantage le corps du formulaire. La carte
   reste le seul element a ceder ; le panneau (1fr) et son corps gardent leur
   priorite. Gardee sous max-width:1024 : en deux colonnes la carte est un cote,
   pas une rangee, et n'a pas a se compacter (verdict large-court). */
@media (max-width: 1024px) and (max-height: 720px) {
  .atelier__body { grid-template-rows: clamp(116px, 16vh, 200px) 1fr; }
}

/* ---------------------------------------------------------------
   #472 (Lot D (B)) : fallback page-scroll sous le seuil. Seuil = H_PAGESCROLL
   dans order-new.js et order-buy.js, GARDER SYNCHRONISE.
   Sous ~600px de hauteur, l'atelier cesse d'etre un mono-ecran epingle et
   redevient un DOCUMENT qui defile : carte a hauteur confortable, formulaire
   dessous, paybar en flux. Au-dessus du seuil, la passe 1 (deux colonnes
   epinglees) reste strictement inchangee.
   Place en fin de feuille : les regles ci-dessus (max-width:1024) sont de meme
   specificite, l'ordre source tranche.
   --------------------------------------------------------------- */
@media (max-height: 600px) {
  /* .atelier porte sur <body> (layout-atelier.hbs) : c'est son couple
     height:100dvh + overflow:hidden qui interdit le scroll de page. */
  /* width:auto et pas le 100vw du regime epingle : 100vw inclut la gouttiere de
     l'ascenseur (unite viewport, par specification), or ici la page defile donc
     un ascenseur vertical CLASSIQUE (Windows, ~15px) est present. La coque
     depassait alors le clientWidth d'autant et faisait apparaitre un ascenseur
     HORIZONTAL. En regime epingle le probleme existait deja mais restait masque
     par l'overflow:hidden ci-dessous, que ce bloc releve. Mesure : 1017 contre
     1002 de clientWidth a 1017x534. width:auto se resout sur le bloc conteneur,
     gouttiere exclue. */
  .atelier { width: auto; height: auto; min-height: 0; overflow: visible; }
  /* La coque cesse de s'etirer et ses rangees suivent leur contenu (la rangee
     carte figee des ecrans courts empiles produisait le sliver). */
  .atelier__body { flex: none; grid-template-columns: 1fr; grid-template-rows: auto auto; min-height: 0; }
  /* La hauteur de la carte n'est PAS posee ici : .atelier__map-card porte
     flex:1 1 0% dans atelier-carto.css, chargee APRES cette feuille et de meme
     specificite, donc gagnante ; et un flex-basis:0% se resout contre une
     hauteur nulle des que le frame devient content-sized (rangee auto ci-dessus).
     La regle vit donc sur .atelier__map-frame dans atelier-carto.css, MEME
     @media (max-height: 600px). GARDER LES DEUX BLOCS SYNCHRONISES. */
  .atelier__panel { height: auto; }
  .atelier__panel-scroll { flex: none; overflow: visible; max-height: none; }
  /* Sans cela le repli CSS 75vh reprendrait la main des que layoutStepper
     relache sa max-height inline : le corps ouvert redefilerait en interne. */
  .fill-step.is-open > .fill-step__body { max-height: none; overflow-y: visible; }
  .atelier__paybar { position: static; }
}
