/* ============================================================================
   ONGLET « PROGRAMME MIXER »

   Aucune valeur de dessin ici qui ne vienne de `tokens.css`. Les seules
   exceptions sont les dimensions posées EN LIGNE par le JS — la position et la
   taille de chaque bloc, la hauteur d'un canevas — qui sont des surfaces
   calculées à l'échelle et n'ont rien à faire dans une feuille de style.
   ========================================================================= */

.mix{position:relative}

/* Le rail et sa grille sont ceux du Massing (`massing.css` — .mass-grid,
   .mass-rail, .mass-etape). */
.mix-main{min-width:0}

/* --- le bandeau de chiffres --------------------------------------------- */
.mix-sum{
  display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-6);
  padding-bottom:var(--s-4);border-bottom:1px solid var(--border);margin-bottom:var(--s-4);
}
.mix-fig{display:grid;gap:1px}
.mix-fig b{
  font-family:var(--font-mono);font-size:var(--t-num-md);font-weight:500;
  font-variant-numeric:tabular-nums;line-height:var(--lh-tight);
}
.mix-fig__l{font-size:var(--t-2xs);color:var(--soft-foreground)}
.mix-fig__s{font-size:var(--t-3xs);color:var(--muted-foreground)}

/* --- la pile -------------------------------------------------------------
   Le niveau le plus haut en tête, le rez en bas, les sous-sols dessous : c'est
   la convention de coupe. Une rangée horizontale disait l'inverse d'un endroit
   à l'autre de la même vue. */
.mix-stack{display:flex;flex-direction:column;gap:var(--s-3)}
.mix-ground{height:2px;background:var(--faint-foreground);margin-top:var(--s-1)}

.mix-fl{
  border:1px solid var(--border);border-radius:var(--radius-lg);
  background:var(--card);overflow:hidden;
}
/* posés l'un sur l'autre : un seul cadre pour la pile, un filet entre deux niveaux */
.mix-pile{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}
.mix-pile>.mix-fl{border:0;border-radius:0}
.mix-pile>.mix-fl+.mix-fl{border-top:1px solid var(--border-strong)}
.mix-fl.is-drop{border-color:var(--ring);box-shadow:inset 0 0 0 1px var(--ring)}
.mix-fl__bar{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2) var(--s-3);
  padding:var(--s-2) var(--s-3);border-bottom:1px solid var(--border-soft);
}
.mix-fl__bar .spacer{flex:1 1 var(--s-4)}
.mix-fl__n{font-size:var(--t-sm);font-weight:600;font-variation-settings:"wdth" 104}
.mix-fl__plate{display:inline-flex;align-items:center;gap:var(--s-2)}
.mix-fl__plate input{
  width:5.5em;font:inherit;font-family:var(--font-mono);font-size:var(--t-xs);
  text-align:right;padding:var(--s-1) var(--s-2);min-height:var(--tap-min);
  border:1px solid var(--border);border-radius:var(--radius-md);
  background:var(--background);color:var(--foreground);
}
.mix-fl__u,.mix-fl__meta,.mix-fl__h{font-size:var(--t-2xs);color:var(--muted-foreground)}
/* La hauteur de niveau est une autre nature de chiffre que le décompte des
   pièces : un filet les sépare, sinon « 0 m² bâtis 3,25 m » se lit d'un trait. */
.mix-fl__h{padding-left:var(--s-3);border-left:1px solid var(--border)}
.mix-fl__hors{margin-left:var(--s-2);color:var(--faint-foreground)}
.mix-fl__pct{font-size:var(--t-xs);color:var(--soft-foreground)}
.mix-fl__pct.is-over{color:var(--destructive);font-weight:600}

/* --- le canevas d'un niveau --------------------------------------------- */
.mix-fl__canvas{position:relative;overflow:hidden;background:var(--background)}
.mix-empty{
  position:absolute;inset:0;margin:0;display:flex;align-items:center;justify-content:center;
  font-size:var(--t-2xs);color:var(--faint-foreground);
}
/* La ligne de plateau et la bande de dépassement : on voit qu'un niveau déborde
   avant d'avoir lu le chiffre qui le dit. Elles passent AU-DESSUS des blocs —
   posées dessous, elles étaient intégralement recouvertes par le pavage, qui
   remplit son rectangle sans laisser un pixel. La bande ne porte pas d'aplat :
   elle se marque par ses deux bords, sinon elle effacerait ce qu'elle désigne. */
.mix-cap{
  position:absolute;left:0;right:0;height:0;z-index:3;
  border-top:1px dashed var(--destructive);pointer-events:none;
}
.mix-cap span{
  position:absolute;right:var(--s-1);top:2px;
  font-size:var(--t-3xs);color:var(--destructive);
  background:var(--card-veil);padding:0 var(--s-1);border-radius:var(--radius-sm);
}
.mix-over{
  position:absolute;left:0;right:0;z-index:2;pointer-events:none;
  box-shadow:inset 3px 0 0 var(--destructive),inset -3px 0 0 var(--destructive);
}

/* --- un bloc = une part de poste, à sa surface exacte -------------------- */
.mixblk{
  position:absolute;overflow:hidden;cursor:grab;touch-action:none;
  border:1px solid var(--foreground);border-radius:var(--radius-sm);
  padding:2px var(--s-1);
  display:flex;flex-direction:column;justify-content:center;
  font-size:var(--t-3xs);line-height:var(--lh-tight);color:var(--foreground);
}
.mixblk b{
  font-weight:600;font-size:var(--t-3xs);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  mix-blend-mode:normal;
}
.mixblk__a{font-family:var(--font-mono);font-size:var(--t-3xs);opacity:.82}
.mixblk.is-tiny b,.mixblk.is-tiny .mixblk__a{display:none}
/* Le nom est la PRISE DU BLOC ENTIER ; sous lui, les cellules sont les prises
   des pièces. Deux prises distinctes valent mieux qu'un modificateur à
   retenir : on tire le nom pour emmener les dix-huit salles, une cellule pour
   n'en détacher qu'une. */
.mixblk__lb{flex:0 0 auto;min-height:0}
/* Bloc ouvert, le nom et les m² tiennent sur UNE ligne : chaque ligne reprise
   au titre est une rangée de cellules rendue visible. */
.mixblk.has-pcs .mixblk__lb{
  display:flex;gap:var(--s-1);align-items:baseline;justify-content:space-between;
}
.mixblk.has-pcs .mixblk__lb b{min-width:0}
.mixblk.has-pcs{justify-content:flex-start;gap:2px}
/* Le bloc N'EST PAS une boîte contenant des boîtes : c'est une surface DIVISÉE.
   Les pièces étaient dessinées en petits rectangles cernés, posés dans le bloc
   avec un jour entre eux — on lisait dix-huit objets rangés là, au lieu d'un
   poste découpé. Le trait tireté est le trait de division du plan : il sépare
   sans clore. La trame va donc d'un bord à l'autre du bloc, ses lignes de
   rive tombant exactement sur le cadre qui la borde — d'où les marges
   négatives, que `overflow:hidden` rattrape. */
.mixblk__pcs{
  flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:0;
  margin-inline:calc(-1 * var(--s-1));margin-bottom:-2px;
}
/* Une cellule = une pièce, à la surface unitaire du poste. Elle ne porte que
   ses deux traits de refend : celui de droite et celui du bas. Les quatre côtés
   auraient doublé chaque séparation, et le tireté d'une surface « à préciser »
   — même trait, autre sens — s'y serait perdu. */
.mixpc__row{display:flex;flex:1 1 0;min-height:0;gap:inherit}
.mixpc{
  flex:1 1 0;
  border-right:1px dashed color-mix(in srgb, currentColor 50%, transparent);
  border-bottom:1px dashed color-mix(in srgb, currentColor 50%, transparent);
  cursor:grab;touch-action:none;
}
.mixpc:hover{background:color-mix(in srgb, var(--foreground) 14%, transparent)}
/* Une surface à préciser porte le trait tireté, partout, sur tous les dessins. */
.mixblk.is-est{border-style:dashed}
.mixblk.is-sel{outline:2px solid var(--ring);outline-offset:-2px}
.mixblk.is-dragging{opacity:.4}
.mixblk:hover{border-width:2px}

.mix-ghost{
  position:fixed;z-index:var(--z-tip);pointer-events:none;
  background:var(--primary);color:var(--primary-foreground);
  padding:var(--s-1) var(--s-2);border-radius:var(--radius-md);
  font-size:var(--t-2xs);box-shadow:var(--shadow-lg);
}

/* --- modifier la pile ---------------------------------------------------- */
.mix-edit{margin-top:var(--s-3)}
.mix-edit__row{display:flex;flex-wrap:wrap;gap:var(--s-2)}
.mix-act{
  flex-direction:column;align-items:flex-start;gap:0;
  height:auto;padding-block:var(--s-2);text-align:left;white-space:normal;
}
.mix-why{font-size:var(--t-3xs);color:var(--muted-foreground);font-weight:400;line-height:var(--lh-snug)}

/* --- les corps des étapes du rail : circulation, contrôle, bac --------- */
.mix-circ__v{
  margin:0;font-family:var(--font-mono);font-size:var(--t-num-md);font-weight:500;
  font-variant-numeric:tabular-nums;
}
.mix-circ__v .u{font-size:var(--t-2xs);color:var(--muted-foreground);margin-left:var(--s-2);font-weight:400}
.mix-circ__n{margin:var(--s-1) 0 var(--s-2);font-size:var(--t-2xs);color:var(--soft-foreground)}
.mix-circ__go{font-size:var(--t-2xs);padding:var(--s-1) var(--s-2);min-height:var(--tap-min)}

.mix-issues__hd{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s-2);margin-bottom:var(--s-2);
}
.mix-issues__hd h3{margin:0}
.mix-ok{margin:0;font-size:var(--t-2xs);color:var(--ok)}

.mix-list{margin:0;padding:0;list-style:none;display:grid;gap:var(--s-2)}
.mix-list li{
  /* La pastille et le texte sont désormais DANS le bouton, qui porte ses deux
     colonnes : laissée en grille, la ligne envoyait le panneau déplié dans la
     deuxième colonne, sur trois caractères de large. */
  font-size:var(--t-2xs);color:var(--soft-foreground);line-height:var(--lh-snug);
}
.mix-list li i{
  font-style:normal;font-family:var(--font-mono);font-size:var(--t-3xs);
  padding:1px var(--s-1);border-radius:var(--radius-sm);white-space:nowrap;
}
.mix-list li.e i{background:var(--danger-fill);color:var(--on-fill)}
.mix-list li.w i{background:var(--accent);color:var(--muted-foreground);border:1px solid var(--border)}
.mix-list li span{color:var(--muted-foreground)}

.mix-tray.is-drop{outline:2px solid var(--ring);outline-offset:var(--s-2);border-radius:var(--radius-md)}
.mix-cat{margin-bottom:var(--s-3)}
.mix-cat__h{
  display:flex;justify-content:space-between;gap:var(--s-2);
  font-size:var(--t-3xs);color:var(--muted-foreground);
  padding-bottom:2px;border-bottom:1px solid var(--border-soft);margin-bottom:var(--s-2);
}
.mix-chips{display:flex;flex-wrap:wrap;gap:var(--s-1)}
.mixchip{
  appearance:none;display:inline-flex;align-items:center;gap:var(--s-1);
  font:inherit;font-size:var(--t-3xs);color:var(--soft-foreground);
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);
  padding:var(--s-1) var(--s-2);min-height:var(--tap-min);
  cursor:grab;touch-action:none;
}
.mixchip:hover{color:var(--foreground);border-color:var(--border-strong)}
.mixchip .sw{width:9px;height:9px;border-radius:var(--radius-sm);flex:none}
.mixchip .mono{color:var(--muted-foreground)}
.mixchip.is-dragging{opacity:.4}
.mix-tray__note{
  margin:var(--s-3) 0 0;padding-top:var(--s-2);border-top:1px dashed var(--border);
  font-size:var(--t-3xs);color:var(--muted-foreground);line-height:var(--lh-snug);
}
.mix-tray__note b{color:var(--soft-foreground);font-weight:500}
.mix-tray__note span{display:block;margin-top:2px}

/* Le filet qui sépare l'enveloppe scolaire de ce qui est posé au terrain sans
   peser sur le plateau : cour, piscine, chauffage à distance. */
.mix-hors{
  position:absolute;left:0;right:0;height:0;z-index:3;
  border-top:1px solid var(--faint-foreground);pointer-events:none;
}
.mix-hors span{
  position:absolute;left:var(--s-1);top:2px;
  font-size:var(--t-3xs);color:var(--muted-foreground);
  background:var(--card-veil);padding:0 var(--s-1);border-radius:var(--radius-sm);
}


/* --- un écart se clique, et propose son remède -----------------------------
   La liste ne faisait que dire. Chaque ligne est maintenant une commande : elle
   s'ouvre sur le geste qui résoudrait l'écart, ou sur « laisser comme ça » —
   une décision de projet, qui mérite d'être prise et non subie. */
.mix-iss{
  display:grid;grid-template-columns:auto 1fr;gap:var(--s-2);align-items:baseline;
  width:100%;text-align:left;padding:var(--s-1) var(--s-2) var(--s-1) 0;
  background:none;border:0;border-radius:var(--radius-sm);cursor:pointer;
  font:inherit;color:inherit;
}
.mix-iss:hover{background:var(--accent)}
.mix-list li.is-open{background:var(--accent);border-radius:var(--radius-md);padding:var(--s-1)}
.mix-list li.is-open .mix-iss:hover{background:none}
.mix-list li.ok{opacity:.72}
.mix-list li.ok i{background:none;border:1px dashed var(--border-strong);color:var(--muted-foreground)}
.mix-iss__p{display:grid;gap:var(--s-2);padding:var(--s-2) var(--s-2) var(--s-1)}
.mix-iss__w{margin:0;font-size:var(--t-3xs);color:var(--muted-foreground);line-height:var(--lh-snug)}
.mix-issues__hd--soft{margin-top:var(--s-4)}
.chip--soft{background:var(--border);color:var(--soft-foreground)}
.mix-reprendre{margin-left:auto}

/* --- ajouter un niveau, là où il apparaîtra --------------------------------
   Un rang discret en tête et au pied de la pile : le geste est au bord qu'il
   prolonge, et non dans une barre d'outils à quatre cents pixels de là. */
.mix-add{display:flex;justify-content:center;padding:var(--s-2) 0}
.mix-add__b{border-style:dashed;color:var(--muted-foreground)}
.mix-add__b:hover{color:var(--foreground);border-style:solid}

/* La corbeille d'un niveau : sur le niveau, jamais ailleurs. */
.mix-fl__del{margin-left:var(--s-2);color:var(--muted-foreground);font-size:var(--t-md);line-height:1}
.mix-fl__del:hover{color:var(--destructive);border-color:var(--destructive)}

/* --- ce que l'écart ouvert désigne -----------------------------------------
   Le niveau visé prend le filet de l'écart, les pièces en cause le portent.
   Lire un conflit et devoir ensuite chercher ses coupables dans la pile, c'est
   tout le travail laissé à faire. */
.mix-fl.is-flagged{outline:2px solid var(--warn);outline-offset:-2px;border-radius:var(--radius-md)}
.mix-fl.is-flagged.is-e{outline-color:var(--destructive)}
.mixblk.is-flag{outline:2px solid var(--warn);outline-offset:-2px;z-index:2}
.mixblk.is-flag.is-e{outline-color:var(--destructive)}
.mixblk.is-flag b{color:var(--foreground)}
.mix-fl__del svg{display:block}

/* La circulation, dessinée à l'échelle sous les locaux du niveau. Hachurée et
   sans couleur de famille : elle n'est d'aucune famille, et c'est exactement
   ainsi qu'elle se lit au volet Surfaces. Le niveau ne montrait que ses
   locaux — mille deux cents mètres carrés de couloirs manquaient au dessin
   alors qu'ils étaient comptés dans le pourcentage écrit à côté. */
.mix-circband{
  position:absolute;left:0;right:0;z-index:1;
  border-block:1px solid var(--faint-foreground);
}
.mix-circband span{
  position:absolute;left:var(--s-1);top:2px;
  font-size:var(--t-3xs);color:var(--muted-foreground);
  background:var(--card-veil);padding:0 var(--s-1);border-radius:var(--radius-sm);
}
/* L'addition du niveau : utile + circulation = bâti. */
.mix-fl__circ{color:var(--muted-foreground);padding-inline:var(--s-1)}

/* --- le dé d'un réglage, et le lien d'un poste ------------------------------
   Des commandes discrètes, qui reviennent sur chaque niveau et chaque bloc :
   elles ne prennent pas l'aplat noir d'un bouton enfoncé, qui ferait de la
   pile une rangée de pastilles. Allumé, le dé est cerné d'encre ; éteint, il
   devient un cadenas, en retrait. */
.btn.mix-de,.btn.mix-lien{
  min-height:var(--tap-min);padding:0 var(--s-2);gap:var(--s-1);
  font-size:var(--t-2xs);color:var(--muted-foreground);background:var(--card);
}
.btn.mix-de svg,.btn.mix-lien svg{display:block;flex:none}
.btn.mix-de[aria-pressed="true"],.btn.mix-de[aria-pressed="mixed"]{
  background:var(--card);color:var(--foreground);border-color:var(--foreground);
}
.btn.mix-de[aria-pressed="mixed"]{border-style:dashed}
.btn.mix-lien[aria-pressed="true"]{background:var(--card);color:var(--foreground);border-color:var(--muted-foreground)}
.btn.mix-de--compact,.btn.mix-lien--compact{min-width:var(--tap-min);padding:0 var(--s-1)}

/* La pile porte son propre dé, en tête. */
.mix-pilehd{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2) var(--s-3);
  padding-bottom:var(--s-2);
}
.mix-pilehd .label{margin:0}
.mix-pilehd__n{font-size:var(--t-xs);color:var(--soft-foreground)}
.mix-pilehd__h{font-size:var(--t-2xs);color:var(--muted-foreground)}

/* Sur un bloc, le lien et le dé se posent en haut à droite, au-dessus de tout. */
.mixblk__ctl{
  position:absolute;top:2px;right:2px;z-index:1;display:flex;gap:2px;
}
.mixblk__ctl .btn{min-height:calc(var(--tap-min) - var(--s-1));background:var(--card-veil)}
.mixblk.has-pcs .mixblk__lb{padding-right:calc(2 * var(--tap-min) + var(--s-1))}
.mixblk:not(.has-pcs) .mixblk__lb{padding-right:calc(2 * var(--tap-min))}

/* DÉLIÉ : le bloc n'est plus une surface divisée mais un rang de pièces
   séparées, chacune dans son cadre et sa couleur, côte à côte parce qu'elles
   sont au même niveau — le « détaillé » du cahier des charges. Le bloc
   lui-même ne garde que son nom, qui reste la prise de toute la part. */
.mixblk.is-delie{background:none;border-color:transparent}
.mixblk.is-delie.is-hatched{background-image:none}
.mixblk.is-delie.is-delie-plein{border-style:dotted;background:none}
.mixblk.is-delie .mixblk__pcs{gap:2px;margin:0}
.mixblk.is-delie .mixpc{
  border:1px solid var(--c);border-radius:var(--radius-sm);
  background-color:color-mix(in srgb, var(--c) calc(var(--fill-op) * 100%), var(--background));
}
.mixblk.is-delie.is-hatched .mixpc{
  background-image:repeating-linear-gradient(45deg,
    var(--hatch-ink) 0 1.5px, transparent 1.5px 5px);
}
.mixblk.is-delie.is-est .mixpc{border-style:dashed}
.mixblk.is-delie:hover{border-width:1px}
.mixblk.is-delie .mixpc:hover{border-width:2px}

/* --- ce que tire le Shuffle ------------------------------------------------ */
.mix-regl__n{margin:0 0 var(--s-2);font-size:var(--t-2xs);color:var(--muted-foreground);line-height:var(--lh-snug)}
.mix-regl__l{list-style:none;margin:0;padding:0;display:grid}
.mix-regl__l li{
  display:grid;grid-template-columns:1fr auto;align-items:center;gap:var(--s-1) var(--s-2);
  padding:var(--s-2) 0;border-top:1px solid var(--border-soft);
}
.mix-regl__t b{display:block;font-size:var(--t-xs);font-weight:500}
.mix-regl__t span{display:block;font-size:var(--t-3xs);color:var(--muted-foreground)}
.mix-regl__g{grid-column:1 / -1;width:max-content}
.mix-regl__g .btn{min-height:var(--tap-min);font-size:var(--t-2xs)}
.mix-regl__det{margin-top:var(--s-2)}
.mix-postes{list-style:none;margin:var(--s-2) 0 0;padding:0;display:grid}
.mix-postes li{
  display:grid;grid-template-columns:9px 1fr auto auto;align-items:center;gap:var(--s-2);
  padding:var(--s-1) 0;border-top:1px solid var(--border-soft);font-size:var(--t-2xs);
}
.mix-postes .sw{width:9px;height:9px;border-radius:var(--radius-sm)}
.mix-postes__n{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* --- les adjacences -------------------------------------------------------- */
.mix-adj__g{width:max-content;margin-bottom:var(--s-2)}
.mix-adj__g .btn{min-height:var(--tap-min);font-size:var(--t-2xs)}
.mix-adj__l{list-style:none;margin:0;padding:0;display:grid}
.mix-adj__l li{
  display:grid;grid-template-columns:auto 1fr auto;align-items:start;gap:var(--s-2);
  padding:var(--s-2) 0;border-top:1px solid var(--border-soft);
}
.mix-adj__l li:not(.is-on) .mix-adj__t{color:var(--muted-foreground)}
.mix-adj__t{min-width:0;font-size:var(--t-2xs);line-height:var(--lh-snug)}
.mix-adj__t b{font-weight:500;margin-right:var(--s-1)}
.mix-adj__t q{display:block;font-size:var(--t-3xs);color:var(--muted-foreground);font-style:italic;quotes:"«\00a0" "\00a0»"}
.mix-adj__l li.is-bad{box-shadow:inset 2px 0 0 var(--destructive);padding-left:var(--s-2)}
.mix-adj__bad{display:block;font-size:var(--t-3xs);color:var(--destructive)}

/* L'interrupteur d'une adjacence : un rail et son curseur. L'état se lit aussi
   à la couleur du nom, et dans le libellé accessible. */
.mix-sw{
  appearance:none;position:relative;flex:none;cursor:pointer;
  width:calc(var(--s-5) + var(--s-2));height:var(--s-4);margin-top:1px;
  border:1px solid var(--border-strong);border-radius:var(--radius-full);background:var(--accent);
  transition:background-color var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease);
}
.mix-sw__k{
  position:absolute;top:1px;left:1px;width:calc(var(--s-4) - 4px);height:calc(var(--s-4) - 4px);
  border-radius:var(--radius-full);background:var(--card);box-shadow:var(--shadow-sm);
  transition:transform var(--dur-2) var(--ease);
}
.mix-sw[aria-checked="true"]{background:var(--primary);border-color:var(--primary)}
.mix-sw[aria-checked="true"] .mix-sw__k{transform:translateX(var(--s-4))}
@media (prefers-reduced-motion:reduce){.mix-sw,.mix-sw__k{transition:none}}
/* À l'échelle : la trame des pièces couvre tout le bloc, à ses cotes ; le
   nom se pose dessus. */
.mixblk.has-pcs .mixblk__pcs{position:absolute;inset:0;margin:0}
.mixblk__lb{position:relative;z-index:1}
.mixblk__dims{display:block;margin-top:2px;max-width:100%;font-size:var(--t-3xs);
  padding:1px 2px;border:1px solid var(--border);border-radius:var(--radius-sm);
  background:var(--background);color:var(--foreground);cursor:pointer}
.mixblk__a{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Les poignées d'un bloc choisi : tirer le bord droit élargit les pièces, le
   bord bas les approfondit. */
