/* ============================================================================
   L'ONGLET MASSING

   Deux vues côte à côte — le plan et le volume — et un rail de commandes à
   gauche. La disposition est celle du mixer : ce qui agit sur l'ENSEMBLE est
   rangé sur un bord, ce qu'on regarde tient tout le reste.

   Le rail est une CHAÎNE : « Proposer » en tête, puis les étapes dans l'ordre
   du générateur, chacune repliable et portant son état. Ce qu'on regarde se
   règle dans la barre posée sur les vues ; le volume choisi, dans une carte
   posée sur le plan.

   Aucune valeur de dessin ici qui ne vienne de `tokens.css`. Les couleurs de
   famille des volumes sont posées en ligne par le JS parce qu'elles sortent du
   programme, comme dans le mixer ; le trait, lui, est au style.
   ========================================================================= */
.mass{ padding-block: var(--s-4) var(--s-6); }
.mass-grid{
  display:grid; gap:var(--s-5);
  grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
  align-items:start;
}
@media (max-width: 960px){
  .mass-grid{ grid-template-columns: minmax(0,1fr); }
  /* En une seule colonne, le rail n'a plus de raison de défiler tout seul :
     un ascenseur dans un ascenseur ne se manœuvre pas au doigt. */
  .mass-rail{ max-height:none; overflow:visible; padding-right:0; }
}

/* --- le rail ------------------------------------------------------------- */
.mass-rail{
  display:flex; flex-direction:column; gap:var(--s-4);
  max-height: calc(100vh - 120px); overflow:auto;
  padding-right: var(--s-2);
}
.mass-note{
  margin:0; font-size:var(--t-2xs); line-height:var(--lh-base);
  color:var(--muted-foreground);
}
.mass-note.is-bas{ color:var(--destructive); }
.mass-deux{ display:grid; grid-template-columns:1fr 1fr; gap:var(--s-2); }
.mass-deux .btn{ width:100%; }

/* --- proposer : le geste de l'onglet, toujours visible ------------------------ */
.mass-prop{ display:flex; flex-direction:column; gap:var(--s-2); }
.mass-prop__h{ margin:0; font-size:var(--t-sm); font-weight:600; color:var(--foreground); }
/* Le grand bouton de l'Atelier : l'icône, ce qu'il fait, ce qu'il garde. */
.btn.mass-tir{
  justify-content:flex-start; gap:var(--s-3); width:100%; text-align:left;
  padding:var(--s-2) var(--s-3); white-space:normal;
}
.mass-tir__t{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.mass-tir__t b{ font-size:var(--t-sm); font-weight:600; color:var(--foreground); }
.mass-tir__t span{ font-size:var(--t-2xs); color:var(--muted-foreground); }
.btn--primary.mass-tir .mass-tir__t b{ color:var(--primary-foreground); }
.btn--primary.mass-tir .mass-tir__t span{ color:color-mix(in srgb, var(--primary-foreground) 68%, transparent); }
.mass-nav{ display:flex; align-items:center; gap:var(--s-1); }
.mass-nav__r{
  flex:1 1 auto; display:flex; align-items:center; justify-content:center; gap:var(--s-1);
  min-height:var(--ctl-h); border-radius:var(--radius-md); background:var(--muted);
  font-size:var(--t-xs); color:var(--muted-foreground); white-space:nowrap;
}
.mass-nav__r b{ color:var(--foreground); font-weight:600; }
/* La seed, à côté du classement qu'elle a produit : le champ du mixer, au même dessin. */
.mass-seed{ display:flex; align-items:center; gap:var(--s-1);
  padding-inline:var(--s-2); min-height:var(--ctl-h);
  border:1px solid var(--border); border-radius:var(--radius-md); background:var(--card); }
.mass-seed .segcap{ padding:0; font-size:var(--t-2xs); color:var(--muted-foreground); }
.mass-seed input{
  inline-size:4.5em; min-width:0; border:0; background:none; padding:0;
  font:inherit; font-family:var(--font-mono); font-size:var(--t-xs); color:var(--foreground);
}
.mass-seed input:focus-visible{ outline:none; }
.mass-seed:focus-within{ border-color:var(--ring); }

/* --- la chaîne : une étape par temps du générateur ----------------------------- */
.mass-etapes{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--s-2); }
.mass-etape > details{
  border:1px solid var(--border); border-radius:var(--radius-lg); background:var(--card);
}
.mass-etape > details[open]{ border-color:var(--border-strong); }
.mass-etape__s{
  display:flex; align-items:center; gap:var(--s-3); list-style:none; cursor:pointer;
  padding:var(--s-2) var(--s-3); min-height:var(--s-7); box-sizing:border-box;
  border-radius:var(--radius-lg);
}
.mass-etape__s::-webkit-details-marker{ display:none; }
.mass-etape__s:hover{ background:var(--accent); }
.mass-etape__s:focus-visible{ outline:2px solid var(--ring); outline-offset:-2px; }
.mass-etape__num{
  flex:none; inline-size:var(--s-5); block-size:var(--s-5); display:grid; place-items:center;
  border:1px solid var(--border-strong); border-radius:var(--radius-full);
  font-size:var(--t-2xs); color:var(--soft-foreground);
}
details[open] > .mass-etape__s .mass-etape__num{
  background:var(--primary); border-color:var(--primary); color:var(--primary-foreground);
}
.mass-etape__t{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:1px; }
.mass-etape__t b{ font-size:var(--t-sm); font-weight:600; color:var(--foreground); }
.mass-etape__t span{ font-size:var(--t-2xs); color:var(--muted-foreground);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mass-etape__e{ flex:none; display:flex; align-items:center; gap:var(--s-1); }
.mass-etape__s > .ic--chevron{ flex:none; color:var(--muted-foreground);
  transition:transform var(--dur-2) var(--ease-out); }
details[open] > .mass-etape__s > .ic--chevron{ transform:rotate(180deg); }
.mass-etape__note{ font-size:var(--t-md); color:var(--ok); }
.mass-etape__note.is-bas{ color:var(--destructive); }
.mass-etape__b{
  display:flex; flex-direction:column; gap:var(--s-2);
  padding:var(--s-3); border-top:1px solid var(--border-soft);
}
.mass-etape__b:empty{ display:none; }
/* Le renvoi au volet Contraintes, en pied d'étape. */
.btn.mass-renvoi{ align-self:flex-start; padding-inline:var(--s-1); font-size:var(--t-2xs); color:var(--muted-foreground); }
@media (prefers-reduced-motion: reduce){ .mass-etape__s > .ic--chevron{ transition:none; } }

/* Les partis : une tuile par parti, sa figure en plein. On les compare du
   regard, et l'on voit d'un coup combien il y en a. */
.mass-partis{ display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:var(--s-1); }
.mass-parti{
  position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--s-1); min-block-size:calc(var(--s-7) + var(--s-1)); padding:var(--s-1);
  font:inherit; font-size:var(--t-2xs); color:var(--soft-foreground); cursor:pointer;
  background:var(--background); border:1px solid var(--border); border-radius:var(--radius-md);
  transition:color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.mass-parti:hover{ color:var(--foreground); border-color:var(--border-strong); }
.mass-parti[aria-pressed="true"]{ color:var(--foreground); background:var(--accent); border-color:var(--foreground); }
.mass-parti:focus-visible{ outline:2px solid var(--ring); outline-offset:1px; }
/* En Auto, le parti retenu : un point, et son cadre à la couleur de la sélection. */
.mass-parti.is-retenu{ color:var(--foreground); border-color:var(--ring); }
.mass-parti.is-retenu::after{
  content:""; position:absolute; inset-block-start:var(--s-1); inset-inline-end:var(--s-1);
  inline-size:calc(var(--s-1) * 1.5); block-size:calc(var(--s-1) * 1.5); border-radius:var(--radius-full); background:var(--ring);
}
/* Les étages montrés : une piste fine, la plage pleine entre deux poignées, un
   cran par étage et son nom dessous — rien d'autre. Tout glisse par transform :
   la plage se pose d'un cran à l'autre sans rien remettre en page. La piste et
   les crans sont rentrés d'une demi-étiquette, pour que « S-sol » et « R+2 »
   se centrent sur leur cran sans déborder du rail. */
.mass-plage{ --lo:0; --hi:1; margin-top:var(--s-3); }
.mass-plage__piste{
  position:relative; block-size:var(--s-5); margin-inline:var(--s-4);
  cursor:pointer; touch-action:none;
}
.mass-plage__piste::before,.mass-plage__fil{
  content:""; position:absolute; inset-inline:0; inset-block-start:calc(50% - var(--s-1) / 2);
  block-size:var(--s-1); border-radius:var(--radius-full); background:var(--muted);
}
.mass-plage__fil{
  background:var(--foreground); transform-origin:left center;
  transform:translateX(calc(var(--lo) * 100%)) scaleX(calc(var(--hi) - var(--lo)));
  transition:transform var(--dur-2) var(--ease-out);
}
.mass-plage__glis{
  position:absolute; inset:0; pointer-events:none;
  transition:transform var(--dur-2) var(--ease-out);
}
.mass-plage__glis--bas{ transform:translateX(calc(var(--lo) * 100%)); }
.mass-plage__glis--haut{ transform:translateX(calc(var(--hi) * 100%)); }
.mass-plage__poi{
  position:absolute; inset-inline-start:0; inset-block-start:50%;
  inline-size:var(--s-4); block-size:var(--s-4); margin:calc(var(--s-4) / -2);
  box-sizing:border-box; border:2px solid var(--foreground); border-radius:var(--radius-full);
  background:var(--background); outline:none;
  transition:transform var(--dur-2) var(--ease-out);
}
.mass-plage__piste:hover .mass-plage__poi{ transform:scale(1.08); }
.mass-plage__poi.is-tenu{ transform:scale(1.2); }
.mass-plage__poi:focus-visible{ box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 45%, transparent); }
.mass-plage__crans{
  position:relative; block-size:1.5em; margin-inline:var(--s-4);
  font-size:var(--t-3xs); color:var(--muted-foreground);
}
.mass-plage__crans span{
  position:absolute; inset-inline-start:calc(var(--t) * 100%); transform:translateX(-50%);
  white-space:nowrap; transition:color var(--dur-1) var(--ease);
}
.mass-plage__crans .is-vu{ color:var(--foreground); }

/* Un réglage porte son CHIFFRE : un curseur sans valeur ne se règle pas, il se
   tâtonne. */
.mass-par{
  display:flex; align-items:center; gap:var(--s-2); margin-top:var(--s-2);
  font-size:var(--t-2xs);
}
.mass-par__n{ flex:1 1 auto; color:var(--soft-foreground); }
.mass-par input{
  width:5.5em; height:var(--ctl-h); text-align:right;
  background:var(--card); color:var(--foreground);
  border:1px solid var(--border); border-radius:var(--radius-sm);
  padding-inline:var(--s-2); font-size:var(--t-xs);
}
.mass-par__u{ width:1.6em; color:var(--muted-foreground); font-size:var(--t-3xs); }
/* Un curseur porte son CHIFFRE et ses deux bornes : sans elles on ne sait pas
   ce qu'on règle, et sans lui on tâtonne. */
.mass-cur{ display:block; margin-top:var(--s-3); font-size:var(--t-2xs); }
.mass-cur__h{ display:flex; align-items:baseline; gap:var(--s-2); }
.mass-cur__h .mono{ margin-left:auto; color:var(--foreground); font-size:var(--t-xs); }
.mass-cur input[type="range"]{ width:100%; margin-top:2px; accent-color:var(--ring); }
.mass-cur__p{
  display:flex; justify-content:space-between; gap:var(--s-2);
  font-size:var(--t-3xs); color:var(--muted-foreground);
}
/* Un groupe dans une étape : Composition, Architecture. */
.mass-sous{ margin:0; font-size:var(--t-2xs); font-weight:600; color:var(--soft-foreground); }
.mass-bloc__h--soft{ display:flex; align-items:baseline; gap:var(--s-2); margin-top:var(--s-2); }
.mass-bloc__h--soft .btn{ margin-left:auto; }
.mass-sel__l{ margin:0; font-size:var(--t-2xs); color:var(--soft-foreground); }
/* Les infos du contrôle, repliées : elles n'attendent aucune correction. */
.mass-infos > summary{ cursor:pointer; font-size:var(--t-2xs); color:var(--muted-foreground); padding-block:var(--s-1); }
.mass-infos > summary:hover{ color:var(--foreground); }

/* L'orientation : une pastille d'état, le nom, ce qu'elle lit. */
.mass-ori{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--s-2); }
.mass-ori__i{ display:flex; gap:var(--s-2); align-items:baseline; }
.mass-ori__p{
  flex:none; inline-size:calc(var(--s-1) * 2); block-size:calc(var(--s-1) * 2); border-radius:var(--radius-full);
  background:var(--ok); transform:translateY(1px);
}
.mass-ori__i.is-warn .mass-ori__p{ background:var(--warn); }
.mass-ori__i.is-soft .mass-ori__p{ background:none; border:1.5px solid var(--muted-foreground); box-sizing:border-box; }
.mass-ori__t{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.mass-ori__t b{ font-size:var(--t-xs); font-weight:500; color:var(--foreground); }
.mass-ori__t span{ font-size:var(--t-2xs); color:var(--muted-foreground); }

/* Le jugement : une barre par axe, à l'échelle de 0 à 100 %. */
.mass-axe{ display:grid; grid-template-columns:minmax(0, 1fr) 30% 3.2em; align-items:center; gap:var(--s-2);
  font-size:var(--t-2xs); color:var(--soft-foreground); }
.mass-axe__n{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mass-axe__b{ block-size:var(--s-1); border-radius:var(--radius-full); background:var(--muted); overflow:hidden; }
.mass-axe__b i{ display:block; block-size:100%; background:var(--foreground); border-radius:inherit; }
.mass-axe__s{ text-align:right; color:var(--foreground); }



/* Le bilan : demandé, posé, écart. Trois colonnes de chiffres alignés — c'est
   la question à laquelle l'outil doit répondre à tout moment. */
.mass-bil{ width:100%; border-collapse:collapse; font-size:var(--t-3xs); }
.mass-bil th{
  text-align:right; font-weight:600; color:var(--muted-foreground);
  padding:2px 0; border-bottom:1px solid var(--border);
  letter-spacing:var(--track-caps); text-transform:uppercase;
}
.mass-bil th:first-child, .mass-bil td:first-child{ text-align:left; }
.mass-bil td{ text-align:right; padding:2px 0; border-bottom:1px solid var(--border-soft); }
.mass-bil__e{ color:var(--muted-foreground); }
.mass-bil__e.is-off{ color:var(--warn); font-weight:600; }

/* Les alertes : trois niveaux, et la frontière entre eux se lit à la pastille. */
.mass-al{ list-style:none; margin:0; padding:0; display:grid; gap:2px; }
.mass-al__b{
  display:block; width:100%; text-align:left; cursor:pointer;
  background:none; border:0; border-radius:var(--radius-sm);
  padding:var(--s-1) var(--s-2);
  font:inherit; font-size:var(--t-2xs); line-height:var(--lh-base); color:var(--soft-foreground);
}
.mass-al__b:hover{ background:var(--accent); }
.mass-al__i.is-open > .mass-al__b{ background:var(--accent); }

/* Le panneau d'une alerte : ce qui la résoudrait, et « laisser comme ça ». Les
   deux se présentent de la même façon, parce qu'assumer un écart est une
   décision de projet et non un renoncement. */
.mass-al__p{
  margin:2px 0 var(--s-2) var(--s-2);
  padding-left:var(--s-2); border-left:2px solid var(--border);
  display:grid; gap:2px;
}
.mass-al__w{
  margin:0 0 var(--s-1); font-size:var(--t-3xs); line-height:var(--lh-base);
  color:var(--muted-foreground);
}
.mass-act{
  display:block; width:100%; text-align:left; height:auto;
  padding:var(--s-1) var(--s-2); font-size:var(--t-2xs);
}
.mass-why{
  display:block; margin-top:1px;
  font-size:var(--t-3xs); font-weight:400; color:var(--muted-foreground);
  white-space:normal;
}
.mass-al__b .chip{ margin-right:var(--s-2); vertical-align:1px; }
.mass-al__r{ color:var(--muted-foreground); font-size:var(--t-3xs); }

/* --- les deux vues ------------------------------------------------------- */
.mass-main{ min-width:0; display:flex; flex-direction:column; gap:var(--s-3); }
/* La barre de ce qu'on regarde : couleurs, étages montrés, recadrage. */
.mass-barre{ display:flex; align-items:center; flex-wrap:wrap; gap:var(--s-2) var(--s-4); }
.mass-barre__et{ display:flex; align-items:center; gap:var(--s-2); }
.mass-barre__l{ font-size:var(--t-2xs); color:var(--muted-foreground); }
.mass-barre .mass-plage{ margin-top:0; inline-size:13rem; }
.mass-vues{ display:grid; gap:var(--s-4); }
@media (min-width: 1180px){
  .mass-vues{ grid-template-columns:1fr 1fr; }
}
/* Une seule vue montrée : l'autre s'efface, celle-ci prend toute la largeur. */
.mass-vues--plan > .mass-vue:last-child, .mass-vues--trois > .mass-vue:first-child{ display:none; }
@media (min-width: 1180px){
  .mass-vues--plan, .mass-vues--trois{ grid-template-columns:minmax(0, 1fr); }
}
/* Emporter : deux boutons au pied du rail, sans étape à déplier. */
.mass-emporter{ display:flex; flex-direction:column; gap:var(--s-2);
  padding-top:var(--s-3); border-top:1px solid var(--border); }
.mass-vue{ min-width:0; }
.mass-vue__cadre{ position:relative; }
.mass-barre .spacer{ flex:1 1 auto; }

/* Le volume choisi : une carte posée sur le plan, dans le coin opposé au
   volume (`is-droite`, `is-haut`). Elle défile si l'Architecture dépliée la
   rend plus haute que le plan. */
.mass-carte{
  position:absolute; inset-inline-start:var(--s-2); inset-block-end:var(--s-2);
  inline-size:min(20rem, calc(100% - var(--s-4)));
  max-block-size:calc(min(62vh, 560px) - var(--s-4)); overflow:auto;
  background:var(--popover); color:var(--popover-foreground);
  border:1px solid var(--ring); border-radius:var(--radius-lg); box-shadow:var(--shadow-lg);
}
.mass-carte.is-droite{ inset-inline-start:auto; inset-inline-end:var(--s-2); }
.mass-carte.is-haut{ inset-block-end:auto; inset-block-start:var(--s-2); }
.mass-carte__c{ display:flex; flex-direction:column; gap:var(--s-2); padding:var(--s-2) var(--s-3) var(--s-3); }
.mass-carte__h{ display:flex; align-items:center; gap:var(--s-2); }
.mass-carte__h .btn--icon:first-of-type{ margin-left:auto; }
.mass-carte__id{
  padding:1px var(--s-2); border-radius:var(--radius-sm); font-size:var(--t-xs); font-weight:600;
  background:color-mix(in srgb, var(--ring) 22%, transparent); color:var(--foreground);
}
.mass-carte .mass-par{ margin-top:0; }
.mass-carte__ar > summary{ cursor:pointer; font-size:var(--t-2xs); font-weight:600; color:var(--soft-foreground);
  padding-block:var(--s-1); border-top:1px solid var(--border-soft); }
.mass-carte__ar[open] > summary{ margin-bottom:var(--s-1); }
.mass-vue__h{
  display:flex; align-items:baseline; gap:var(--s-2); margin-bottom:var(--s-2);
}
.mass-cam{ font-size:var(--t-3xs); color:var(--muted-foreground); }

.plan, .vue3d{
  position:relative; background:var(--card);
  border:1px solid var(--border); border-radius:var(--radius-md);
  overflow:hidden; height:min(62vh, 560px);
}
.plan__svg{ display:block; width:100%; height:100%; touch-action:none; cursor:grab; }
.vue3d__c{ display:block; width:100%; height:100%; touch-action:none; cursor:grab; }
.vue3d__fail{
  margin:0; padding:var(--s-5); font-size:var(--t-2xs); color:var(--muted-foreground);
}

/* --- le relevé, en plan --------------------------------------------------
   Un rendu d'architecte : le terrain en traits fins, le bâti en aplat léger,
   le périmètre du concours seul en trait fort. La hiérarchie des traits EST le
   dessin. */
/* Trois forces de trait pour les courbes de niveau, comme sur un plan
   topographique : la demi-courbe, le mètre plein, les cinq mètres. Le relevé
   les donne tous les 50 cm — c'est la hiérarchie qui les rend lisibles, pas
   le fait d'en cacher. */
.plan-ctr{ fill:none; stroke:var(--faint-foreground); stroke-width:.14; opacity:.42; }
.plan-ctr.is-maitre{ stroke-width:.26; opacity:.72; }
.plan-ctr.is-cinq{ stroke-width:.42; opacity:.95; }
.plan-par{ fill:none; stroke:var(--faint-foreground); stroke-width:.22; opacity:.7; stroke-dasharray:2.4 1.6; }
.plan-rou{ fill:none; stroke:var(--faint-foreground); stroke-width:.45; opacity:.9; }
.plan-foo{ fill:none; stroke:var(--faint-foreground); stroke-width:.3; opacity:.6; }
.plan-mur{ fill:none; stroke:var(--muted-foreground); stroke-width:.3; opacity:.7; }
.plan-bat{
  fill:var(--faint-foreground); fill-opacity:.24; stroke:var(--muted-foreground); stroke-width:.35;
}
.plan-enq{ fill:none; stroke:var(--warn); stroke-width:.4; stroke-dasharray:2 1.6; }
.plan-per{
  fill:none; stroke:var(--site-perimetre); stroke-width:1; stroke-linejoin:round;
}

/* --- les volumes, en plan ------------------------------------------------- */
.plan-vol{ cursor:move; }
.plan-vol__et{ fill:none; stroke:var(--muted-foreground); stroke-width:.25; stroke-dasharray:1.6 1.2; }
.plan-vol__p{ fill:var(--site-emprise); fill-opacity:.55; stroke:var(--foreground); stroke-width:.5; }
.plan-vol__p.is-fix{ stroke-dasharray:none; fill-opacity:.7; }
.plan-cel{ fill-opacity:var(--fill-op); stroke:var(--background); stroke-width:.12; }
.plan-vol__c{ fill:none; stroke:var(--foreground); stroke-width:.55; stroke-linejoin:round; }
/* Les cotes du volume choisi. */
.plan-cote{ pointer-events:none; }
.plan-cote__l{ fill:none; stroke:var(--ring); stroke-width:inherit; }
.plan-cote__t{ font-size:inherit; fill:var(--ring); font-weight:600; paint-order:stroke;
  stroke:var(--card); stroke-width:.6; stroke-linejoin:round; }
/* Les murs extérieurs, en poché : 50 cm autour de la surface utile. */
.plan-mur{ fill:var(--foreground); stroke:none; }
/* Les passerelles : une connexion, pas un volume — hachurée, bord fin. */
.plan-pont{ fill:var(--site-emprise); fill-opacity:.35; stroke:var(--foreground); stroke-width:.35;
  stroke-dasharray:1.2 .8; }
.plan-vol.is-sel .plan-vol__c,
.plan-vol.is-sel .plan-vol__p{ stroke:var(--ring); stroke-width:.9; }
/* Le second temps, en pointillé : la piscine et le chauffage à distance sont
   des ouvrages indépendants, réalisés plus tard — art. 2.2. */
.plan-vol.is-ph .plan-vol__c,
.plan-vol.is-ph .plan-vol__p{ stroke-dasharray:2.4 1.8; }
.plan-vol.is-ph .plan-cel{ fill-opacity:calc(var(--fill-op) * .55); }
/* Un corps posé sur un corps du même bâtiment se peint en morceaux (`dessinDe`) :
   sans trait — le bord qui reste est tracé à part. */
.plan-vol .plan-vol__p.is-morceau,
.plan-cel.is-morceau{ stroke:none; }
.plan-cel__b{ fill:none; stroke:var(--background); stroke-width:.12; }
.plan-vol__n{
  font-size:2.6px; fill:var(--foreground); font-weight:600; paint-order:stroke;
  stroke:var(--card); stroke-width:.7; stroke-linejoin:round;
}
.plan-poi__l{ stroke:var(--ring); stroke-width:.3; stroke-dasharray:1 .8; }
.plan-poi__c{ fill:var(--card); stroke:var(--ring); stroke-width:.5; cursor:grab; }

.plan-ech, .plan-nord{ fill:none; stroke:var(--muted-foreground); stroke-width:.35; }
.plan-ech__t{ font-size:2.6px; fill:var(--muted-foreground); font-family:var(--font-mono); }


/* --- les leviers du massing : le dé du mixer, et la valeur quand elle est figée */
.mass-lev{ list-style:none; margin:0 0 var(--s-2); padding:0; display:flex; flex-direction:column; gap:var(--s-1); }
.mass-lev li{ display:flex; align-items:center; gap:var(--s-2); flex-wrap:wrap; }
.mass-lev__n{ flex:1; min-width:9em; font-size:var(--t-xs); color:var(--soft-foreground); }
.mass-lev__s{
  min-block-size:var(--tap-min); padding:0 var(--s-2); font:inherit; font-size:var(--t-xs);
  color:var(--foreground); background:var(--card); border:1px solid var(--input); border-radius:var(--radius-md);
}
input.mass-lev__s{ inline-size:5.5em; text-align:right; }
/* les tirettes : étirer un côté du volume choisi, à surface constante */
.plan-tir__c{ fill:var(--card); stroke:var(--ring); stroke-width:.45; cursor:ew-resize; }
.plan-tir__c:hover{ fill:var(--ring); }

/* L'architecture d'un volume au plan : un trait fin, le sous-passage en tireté. */
.plan-ar{ fill:none; stroke:var(--foreground); stroke-width:.25; pointer-events:none; }
.plan-ar--puits{ fill:var(--f-eau); fill-opacity:.35; }
.plan-ar--sous{ stroke-dasharray:1.2 .8; }
.mass-archi{ display:grid; gap:var(--s-1); }
