/* ============================================================================
   base.css — Reset, mise en page générale, en-tête applicatif
   ============================================================================ */

*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }

body{
  margin:0;
  min-height:100dvh;
  background:var(--bg);
  color:var(--text);
  font-family:var(--font-body-family);
  font-size:var(--font-body-size);
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}

/* Halo décoratif : donne de la profondeur sans dépendre d'une image */
body::before{
  content:"";
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(60rem 30rem at 12% -10%, var(--accent-14), transparent 62%),
    radial-gradient(48rem 26rem at 108% 4%, var(--accent-08), transparent 60%);
}

h1,h2,h3,h4{ font-family:var(--font-title-family); line-height:1.2; margin:0; }
p{ margin:0; }
img{ max-width:100%; display:block; }
button,input,select,textarea{ font:inherit; color:inherit; }
a{ color:var(--accent-strong); text-decoration:none; }
a:hover{ text-decoration:underline; }

:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:3px;
  border-radius:var(--r-sm);
}

/* Masquage accessible : l'élément reste lisible par les lecteurs d'écran
   et reste pilotable par le JS (indispensable pour les <select> natifs
   remplacés visuellement par des segmented controls). */
.sr-only{
  position:absolute !important;
  width:1px; height:1px;
  padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); clip-path:inset(50%);
  white-space:nowrap; border:0;
}
.hidden{ display:none !important; }

/* ============================ Coque applicative ========================== */
.shell{
  position:relative; z-index:1;
  max-width:var(--shell-max);
  margin:0 auto;
  padding:var(--sp-4) var(--sp-4) var(--sp-9);
}
@media (max-width:640px){ .shell{ padding:var(--sp-3) var(--sp-3) 128px; } }

/* ---------------------------- En-tête ----------------------------------- */
/* ===========================================================================
   LE CADRE DU PROFESSIONNEL — pas celui du client
   ---------------------------------------------------------------------------
   Cette page montre DEUX interfaces superposées : le formulaire, qui appartient
   au déménageur et porte SES couleurs, et la barre d'outils, qui appartient à
   OFA Web et n'a aucune raison de changer de teinte selon le client.

   Elles partageaient une seule palette. Résultat : le bouton « Configurer » du
   professionnel virait au rose chez un client rose, et la page où il travaille
   ne ressemblait jamais à son espace client, d'un module à l'autre.

   La correction tient en une idée : on REDÉFINIT les jetons localement, ici.
   Les variables CSS étant héritées, tout ce qui vit dans la barre — boutons,
   pastilles, icônes — bascule sur la palette produit sans qu'une seule règle
   de composant ait à être touchée. applyTheme() continue d'écrire les couleurs
   du client sur <html> ; elles s'appliquent partout ailleurs, et cette
   redéfinition les emporte à l'intérieur de la barre.

   Les valeurs viennent de styles.css, la feuille de l'espace client : c'est
   elle la référence de l'identité produit. Les garder synchronisées à la main
   est le prix à payer pour que les deux modules n'aient pas à partager une
   feuille commune — décision prise pour qu'un module puisse évoluer sans
   casser son voisin.
   =========================================================================== */
.appbar,
.appfoot{
  --card:#ffffff;
  --surface:#ffffff;
  --surface-sunken:#f4f6fb;
  --surface-hover:#eef1f7;
  --text:#111827;
  --muted:#5b6472;
  --muted-strong:#3f4854;
  --faint:#68717f;
  --border:#e4e8f0;
  --border-soft:#e4e8f0;
  --border-strong:#cfd6e2;
  --accent:#0e7490;
  --accent-contrast:#ffffff;
  --degrade-accent:linear-gradient(135deg,#0b7f9e,#0e7490);
  --shadow-pop:0 12px 24px -8px rgba(14,116,144,.55);
}

.appbar{
  position:sticky; top:0; z-index:30;
  display:flex; align-items:center; gap:var(--sp-4);
  margin:0 0 var(--sp-5);
  padding:var(--sp-3) var(--sp-4);
  background:color-mix(in oklab, var(--card) 82%, transparent);
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  border:1px solid var(--border-soft);
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);
}
.appbar__brand{ display:flex; align-items:center; gap:var(--sp-3); min-width:0; flex:1 1 auto; }
#brandLogo{
  height:44px; width:auto; max-width:180px; object-fit:contain;
  flex:0 0 auto; border-radius:var(--r-sm);
}
#brandLogo:not([src]),#brandLogo[src=""]{ display:none; }
.siteTitle{
  font-family:var(--font-title-family);
  font-size:var(--font-title-size);
  font-weight:800;
  letter-spacing:-.01em;
  margin:0; min-width:0;
  overflow-wrap:anywhere;
}
/* flex-wrap : sur un telephone, deux boutons et un badge ne tiennent pas sur
   une ligne. Sans cela, ils depassent la fenetre au lieu de descendre. */
.appbar__actions{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--sp-2); flex:0 0 auto; }

@media (max-width:720px){
  .appbar{ flex-wrap:wrap; gap:var(--sp-2); padding:var(--sp-3); }
  .appbar__brand{ flex:1 1 100%; }
  .appbar__actions{ flex:1 1 100%; justify-content:flex-end; }
  #brandLogo{ height:36px; }
}

/* Mode embed : pas de barre d'application, on gagne de la place */
body.embed .appbar{ display:none; }
body.embed .shell{ padding-top:var(--sp-3); }

/* ------------------------------ Grille ---------------------------------- */
.layout{
  display:grid;
  grid-template-columns:1fr var(--rail-w);
  align-items:start;
  gap:var(--sp-5);
}
@media (max-width:1040px){
  .layout{ grid-template-columns:1fr; }
  .layout__rail{ order:-1; }
}
/* Le prix masqué, ou gardé pour le récapitulatif (cfg.showPrice, cfg.prixFin) :
   la colonne de droite restait vide, le formulaire en gardait la place. */
.layout.layout--sansPrix{ grid-template-columns:1fr; }
.layout--sansPrix > .layout__rail{ display:none; }

/* [hidden] vient de la feuille du navigateur : n'importe quel display: pose
   par une classe d'auteur le neutralise sans bruit. Le module s'appuie sur cet
   attribut pour masquer les etapes et les avertissements : il doit gagner. */
[hidden]{ display:none !important; }

.stack{ display:flex; flex-direction:column; gap:var(--sp-4); }
.row{ display:flex; flex-wrap:wrap; gap:var(--sp-3); }
.col-12{ flex:1 1 100%; }
.col-6{ flex:1 1 calc(50% - var(--sp-3)/2); min-width:200px; }
.col-4{ flex:1 1 calc(33.333% - var(--sp-3)*2/3); min-width:170px; }
@media (max-width:640px){ .col-6,.col-4{ flex:1 1 100%; min-width:0; } }

.between{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--sp-2); }
.grid-2{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--sp-3); }
@media (max-width:640px){ .grid-2{ grid-template-columns:1fr; } }

/* -------------------------- Pied de page -------------------------------- */
.appfoot{
  margin-top:var(--sp-7);
  text-align:center;
  color:var(--muted);
  font-size:var(--fs-sm);
}
/* La mention OFA Web (embed.php) : discrète, mais son lien se voit et se
   touche — c'est la publicité du module, pas une note de bas de page. Une
   pastille claire aux couleurs d'OFA Web (les jetons de .appfoot, plus haut) :
   elle reste lisible sur le fond d'un site sombre comme en mode sombre, où un
   texte gris posé à même la page disparaissait. */
.embedMark{
  width:fit-content; max-width:calc(100% - 2 * var(--sp-3));
  margin:var(--sp-5) auto var(--sp-4);
  padding:var(--sp-2) var(--sp-4);
  background:var(--card); color:var(--muted-strong);
  border:1px solid var(--border-soft); border-radius:999px;
  line-height:1.5;
  color-scheme:light;
}
.embedMark a{ font-weight:700; color:var(--accent); text-decoration:underline; text-underline-offset:2px; white-space:nowrap; }
.embedMark[hidden]{ display:none; }

/* ===========================================================================
   LA BARRE DU PROFESSIONNEL
   ---------------------------------------------------------------------------
   Trois zones : la marque à gauche, la navigation au centre, les outils à
   droite. La navigation centrale est ce qui manquait — sans elle, chaque page
   affichait sa propre liste de boutons, et l'œil devait relire la barre à
   chaque fois pour retrouver où aller.

   L'onglet courant est marqué par un aplat ET un trait sous le libellé : la
   couleur seule ne suffit pas à quelqu'un qui la distingue mal.
   =========================================================================== */
.navPro{ flex-wrap:wrap; gap:var(--sp-3) var(--sp-4); }

/* Au-dessus de 620 px, la barre ne se replie JAMAIS. Sans cette règle, flexbox
   préfère renvoyer un groupe à la ligne plutôt que de rétrécir le rail : à
   1280 px les trois groupes demandaient 1182 px pour 1176 disponibles, six
   pixels de trop, et les outils tombaient sur une deuxième ligne — la barre
   passait de 69 à 123 px et reprenait son air de pied de page. En `nowrap`,
   c'est le rail qui se réduit et défile, ce qu'il sait déjà faire.
   Le repli reste autorisé sous 620 px : c'est là qu'il est voulu, le rail
   prenant alors une ligne entière (voir plus bas). */
@media (min-width:621px){
  .navPro{ flex-wrap:nowrap; }
}

/* Le bloc de marque hérite d'un `flex:1 1 auto` de .appbar__brand : il prenait
   640 px sur une barre de 1068, et poussait les outils à la ligne. Il ne prend
   plus que sa place — mesuré : 1444 px demandés contre 1068 disponibles avant,
   tout tient après. Le logo du client garde une largeur bornée pour la même
   raison : un logo panoramique ne doit pas manger la navigation. */
.navPro .appbar__brand{ flex:0 1 auto; min-width:0; }
.navPro #brandLogo{ max-width:150px; max-height:34px; width:auto; object-fit:contain; }
.navPro .siteTitle{
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  max-width:min(38vw, 300px);
}

/* ─── LA MÊME BARRE QUE « MES MODULES » ────────────────────────────────────
   Le déménageur arrive de listmodule.php, dont l'en-tête est une barre plate,
   collante, bordée en bas — pas une carte flottante à coins ronds. Deux
   traitements différents à une seconde d'intervalle donnent l'impression de
   deux produits ; on reprend donc exactement le sien. Les marges négatives
   annulent le retrait de .shell pour que la barre file d'un bord à l'autre,
   et le rembourrage intérieur remet le contenu à sa place. */
.navPro{
  /* La barre est posée AVANT .shell dans chaque page, exactement comme
     l'en-tête de listmodule.php est posé avant .wrap : elle occupe donc toute
     la largeur de la fenêtre, quel que soit le plafond du contenu. Tenter de
     l'élargir depuis l'intérieur de .shell (marges négatives, 100vw) la faisait
     soit s'arrêter au plafond — 13 px de fond visible à gauche, 28 à droite —
     soit déborder de la largeur de la barre de défilement. */
  margin:0;
  padding:14px 22px;
  border:0;
  border-bottom:1px solid var(--border-soft);
  border-radius:0;
  box-shadow:none;
}
@media (max-width:640px){
  .navPro{ padding-inline:var(--sp-3); }
}

/* « Module Déménagement » (David, 31/10/2026, à la place d'« OFA Web ») : un
   peu plus petit que l'ancien nom, deux mots plus longs sur la même ligne. */
.navPro__marque{
  font-weight:800; font-size:.94rem; letter-spacing:-.01em;
  color:var(--text);
  display:inline-flex; align-items:center; gap:9px;
  white-space:nowrap; min-width:0;
}
/* Le repère de marque de listmodule.php, au trait près : une barrette verticale
   en dégradé turquoise. C'est le seul élément vraiment coloré de son en-tête,
   et donc ce qui le rend reconnaissable. */
.navPro__marque::before{
  content:""; flex:0 0 auto;
  width:9px; height:22px; border-radius:var(--r-pill);
  background:linear-gradient(180deg, #0891b2, #22d3ee);
}

.navPro__liens{
  display:flex; align-items:center; gap:2px;
  /* `1 1 auto` lui faisait prendre toute la largeur restante et repoussait les
     outils à la ligne dès 1100 px. Elle ne prend plus que ce qu'elle occupe, et
     se rétrécit avant de passer à la ligne. */
  flex:0 1 auto; min-width:0;
  margin-inline:auto;
  padding:3px;
  background:var(--surface-sunken);
  border-radius:var(--r-pill);
  overflow-x:auto; scrollbar-width:none;
}
.navPro__liens::-webkit-scrollbar{ display:none; }

/* Quand le rail défile, une pastille coupée net au bord se lit comme un défaut
   d'affichage. Le dégradé de masque la fait disparaître progressivement : on
   comprend qu'il y a d'autres onglets à côté. Le masque n'est posé que sur les
   bords réellement débordants — inutile de faire pâlir un rail qui tient. */
@supports (mask-image: linear-gradient(#000, #000)){
  .navPro__liens{
    mask-image:linear-gradient(to right, transparent 0, #000 18px,
                                          #000 calc(100% - 18px), transparent 100%);
    -webkit-mask-image:linear-gradient(to right, transparent 0, #000 18px,
                                          #000 calc(100% - 18px), transparent 100%);
  }
}

.navPro__lien{
  display:inline-flex; align-items:center; gap:7px;
  flex:0 0 auto;
  padding:8px 14px;
  border-radius:var(--r-pill);
  color:var(--muted-strong);
  font-size:var(--fs-sm); font-weight:700;
  text-decoration:none; white-space:nowrap;
  transition:background var(--dur-fast), color var(--dur-fast);
}
.navPro__lien:hover{ background:var(--surface-hover); color:var(--text); text-decoration:none; }
.navPro__lien.est-actif{
  background:var(--card);
  color:var(--text);
  box-shadow:var(--shadow-xs);
}
.navPro__lien svg{ width:1.05em; height:1.05em; flex:0 0 auto; }

/* La couronne d'une entrée Premium : un repère, pas un panneau. Elle prend la
   couleur d'accent et s'efface au profit du libellé, qui reste l'information. */
.navPro__verrou{ display:inline-flex; color:var(--accent); opacity:.85; flex:0 0 auto; }
.navPro__verrou svg{ width:12px; height:12px; }

.navPro__outils{ display:flex; align-items:center; gap:var(--sp-2); flex:0 0 auto; }

/* Sous 900 px, les outils gardent leurs icônes et perdent leurs mots : la
   navigation centrale prime, c'est elle qu'on utilise dix fois par jour. */
/* Bouton carré : l'icône seule, avec sa zone de clic entière. */
.navPro__icone{ padding-inline:11px; }
/* Se déconnecter : en rouge, comme dans tous les modules — le seul bouton de
   la barre qui ferme la session, pas une icône de plus parmi celles qui
   mènent ailleurs. `.navPro .btn` l'emporte sur `.btn.secondary`, que
   components.css, chargé après, déclare au même poids. */
.navPro .btn.navPro__deconnexion{
  --btn-bg: var(--danger); --btn-fg: #fff;
  border-color:var(--danger);
}
.navPro .btn.navPro__deconnexion:hover{
  background:color-mix(in oklab, var(--danger) 80%, #000); color:#fff;
  border-color:color-mix(in oklab, var(--danger) 80%, #000);
}

/* Sous 780 px, « Configurer » et « Abonnement » perdent aussi leurs mots :
   la navigation centrale prime, c'est elle qu'on utilise sans arrêt. */
@media (max-width:780px){
  .navPro__outils .btn span{ display:none; }
  .navPro__outils .btn{ padding-inline:11px; }
}
@media (max-width:620px){
  .navPro__liens{ order:3; width:100%; }
  .navPro__outils{ margin-left:auto; }
}

/* ===========================================================================
   SUR TÉLÉPHONE (≤ 900 px) : LE MENU LATÉRAL ET LA BARRE DU BAS
   ---------------------------------------------------------------------------
   La barre du haut tenait sur trois lignes et mangeait un quart de l'écran :
   marque, cinq icônes sans mot, puis des onglets qui défilaient de côté. Elle
   se réduit à une ligne — ☰, la marque, la formule — et tout le reste passe
   dans un menu qui glisse depuis la gauche, rangé par groupes.

   En bas, une barre fixe : les quatre gestes utiles à LA PAGE où l'on est,
   plus le menu (partials/nav-pro.php, $basParPage). Le pouce y arrive sans
   lâcher le téléphone ; c'est là que vit la navigation d'une application.

   Le menu, le volet Configurer et la barre du bas sont dessinés dans
   /nav-mobile.css, commun aux trois modules (chargé par partials/nav-pro.php) :
   ici, seulement la barre du haut du déménageur.

   Ce qui est déjà collé en bas d'écran se pose AU-DESSUS de la barre :
   le prix du formulaire (calculator.css), le total du devis rapide
   (dashboard.css), « Enregistrer » de Configurer (admin.css), les messages
   (components.css), l'assistant (assistant.css). Tous lisent --barreBas-h,
   qui ne vaut quelque chose que là où la barre existe.
   =========================================================================== */
.navPro__burger,
.navPro__configurer{ display:none; }


@media (max-width:900px){
  /* --- La barre du haut : une ligne ------------------------------------- */
  .navPro{ flex-wrap:nowrap; gap:10px; padding:8px 12px; }
  .navPro .appbar__brand{ flex:1 1 auto; min-width:0; gap:10px; }
  .navPro__liens,
  .navPro__outils{ display:none; }
  .navPro__burger{
    display:inline-grid; place-items:center; flex:0 0 auto;
    width:44px; height:44px;
    border:1px solid var(--border-soft); border-radius:12px;
    background:var(--surface); color:var(--text);
    cursor:pointer; -webkit-tap-highlight-color:transparent;
  }
  .navPro__burger:active,
  .navPro__configurer:active{ transform:scale(.94); }
  .navPro__burger:focus-visible,
  .navPro__configurer:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
  .navPro .siteTitle{ max-width:none; font-size:1.05rem; overflow:hidden; text-overflow:ellipsis; }
  .navPro__marque{ font-size:.9rem; overflow:hidden; text-overflow:ellipsis; }
  .navPro__marque::before{ height:18px; width:7px; }

  /* Configurer, en haut à droite : le même bouton carré que ☰, en face. */
  .navPro__configurer{
    display:inline-grid; place-items:center; flex:0 0 auto; margin-left:auto;
    width:44px; height:44px;
    border:1px solid var(--border-soft); border-radius:12px;
    background:var(--surface); color:var(--text);
    text-decoration:none; -webkit-tap-highlight-color:transparent;
  }
  /* Les couleurs d'OFA Web, comme le reste de la barre : celles du
     déménageur ne sont pas définies ici. */
  .navPro__configurer.est-actif{ background:#e6f3f6; color:#0b5f75; border-color:#9fcfdb; }
}
/* Un petit téléphone : la formule garde sa couronne, perd son mot. La ligne
   ☰ · Module Déménagement · ⚙ tient alors sans rien couper. */
@media (max-width:420px){
  .navPro .appbar__brand .badge{ padding-inline:7px; }
  .navPro__formule{ display:none; }
}
