/* ══════════════════════════════════════════════════
   Simulation pédagogique — Physique-Chimie Lycée
   Auteur  : Mathieu Berdous
   Licence : CC BY-NC 4.0 — https://creativecommons.org/licenses/by-nc/4.0/
══════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════
   style.css — Dissolution du chlorure de sodium
══════════════════════════════════════════════════ */

/* ── Reset & base ─────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

body {
  font-family: 'Segoe UI', Arial, sans-serif;
  background: #e8e4de;
  color: #2c3e50;
  /* dvh tient compte de la barre d'adresse dynamique mobile (100vh déborde
     sous la zone visible réelle sur téléphone) ; vh reste le repli pour les
     navigateurs qui ne supportent pas dvh. */
  height: 100vh;
  max-height: 100vh;
  height: 100dvh;
  max-height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* ── Grille principale ────────────────────────────── */
main {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr clamp(200px, 22vw, 300px);
  min-height: 0;
  max-height: 100%;
  overflow: hidden;
}

/* ══════════════════════════════════════════════════
   COLONNE GAUCHE
══════════════════════════════════════════════════ */

#left-col {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

/* ── Zone animation : grille 2 colonnes ──────────────
   col 1 = panneau image (verre + sel), largeur fixe
   col 2 = 1fr, canvas de l'animation
──────────────────────────────────────────────────── */
#anim-area {
  flex: 1;
  position: relative;
  display: grid;
  grid-template-columns: clamp(110px, 12vw, 170px) 1fr;
  min-height: 0;
  overflow: hidden;
  background: #fdf8f0;
  border-right: 1px solid #c8c0b4;
}

#verre-col {
  grid-column: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(6px, 1vw, 12px);
  border-right: 1px solid #c8c0b4;
  text-align: center;
}

/* #verre-img-wrap : max-width (et non width) + display:inline-block, pour que
   le conteneur se dimensionne exactement sur l'image affichée (nécessaire
   pour que #zoom-frame, positionné en %, colle pile à l'image). */
#verre-img-wrap { position: relative; display: inline-block; max-width: 100%; }
#img-verre { display: none; max-width: 100%; height: auto; }

/* ── Cadre de zoom (élément visuel permanent de la page, calé une fois via
   le panneau dev — cf. devpanel.js). Position/dimensions en % : toujours fixe
   par rapport à l'image, quelle que soit sa taille rendue. Affiché en
   permanence ; seule l'interactivité (déplacer/redimensionner) est réservée
   au mode "Cadre" du panneau dev (dev-frame-edit), pour ne pas gêner les
   autres modes (ex. clics sur le cristal en mode "Scénario"). */
#zoom-frame {
  display: block;
  position: absolute;
  border: 2px solid #1a2744;
  box-sizing: border-box;
  background: rgba(26, 39, 68, 0.08);
  pointer-events: none;
}
body.dev-frame-edit #zoom-frame { cursor: move; pointer-events: auto; }
/* Poignée de redimensionnement : outil d'édition, visible uniquement dans
   le panneau dev (mode "Cadre"). */
#zoom-frame-handle {
  display: none;
  position: absolute;
  right: -6px; bottom: -6px;
  width: 12px; height: 12px;
  background: #1a2744;
  border: 1.5px solid #fff;
  border-radius: 50%;
  cursor: nwse-resize;
  pointer-events: none;
}
body.dev-frame-edit #zoom-frame-handle { display: block; pointer-events: auto; }

/* ── Traits de rappel — élément visuel permanent de la page ───────
   Relient les coins droits du cadre de zoom aux coins gauches de la zone
   d'animation ; géométrie entièrement calculée et recalculée au
   redimensionnement (renderReminderLines(), devpanel.js), donc purement
   décoratif côté CSS/HTML (jamais interactif). */
#lines-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 15;
}
#lines-overlay .dev-line {
  stroke: #1a2744;
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

#verre-placeholder {
  color: #7a8a96;
  font-size: clamp(10px, 1vw, 13px);
  line-height: 1.5;
}
#verre-placeholder-icon { font-size: clamp(22px, 3vw, 34px); display: block; margin-bottom: 4px; }

/* Dégradé bleu (clair en haut, plus profond en bas, près du cristal) pour
   évoquer le fond d'une solution aqueuse. */
#anim-canvas-wrap {
  grid-column: 2;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  position: relative;
  background: linear-gradient(to bottom, #7dd3f7 0%, #29b6e8 100%);
  border: 2px solid #1a2744;
  box-sizing: border-box;
}

/* Taille pilotée par JS (resize() dans ui.js) : la scène a une résolution
   logique fixe, mise à l'échelle et centrée en mode « cover » (remplit
   #anim-canvas-wrap, l'excédent est rogné par son overflow:hidden). */
#anim-canvas {
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* ── Tooltip de coordonnées (temporaire — aide au positionnement) ── */
#coord-tooltip {
  display: none;
  position: absolute;
  z-index: 20;
  background: rgba(44, 62, 80, 0.85);
  color: #fff;
  font-size: 12px;
  font-family: monospace;
  padding: 3px 7px;
  border-radius: 4px;
  pointer-events: none;
  white-space: nowrap;
}

/* ── Chronomètre de la simulation (temporaire) ── */
#sim-timer {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 20;
  background: rgba(44, 62, 80, 0.85);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  font-family: monospace;
  padding: 4px 9px;
  border-radius: 4px;
  pointer-events: none;
  white-space: nowrap;
}

/* ── Panneau de réglage (temporaire — aide au calage de l'animation) ── */
#dev-panel {
  /* position: fixed (et non absolute dans #anim-canvas-wrap) : le panneau
     sort ainsi de la zone recadrée par l'overflow:hidden du canvas. Aligné en
     largeur et en abscisse sur #panel (colonne de droite, cf. grid-template-
     columns de main dans ce fichier) pour s'afficher juste au-dessus de lui. */
  position: fixed;
  top: 8px;
  right: 8px;
  width: clamp(200px, 22vw, 300px);
  max-height: calc(100dvh - 16px);
  overflow-y: auto;
  background: rgba(255, 255, 255, 0.94);
  border: 1.5px solid #b0a898;
  border-radius: 8px;
  font-size: 11px;
  font-family: 'Segoe UI', Arial, sans-serif;
  color: #2c3e50;
  z-index: 30;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}
#dev-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 8px;
  font-weight: 700;
  background: #e8e4de;
  border-bottom: 1px solid #c8c0b4;
  border-radius: 7px 7px 0 0;
}
#dev-panel.collapsed #dev-panel-header { border-radius: 7px; border-bottom: none; }
#dev-panel-toggle {
  background: none; border: none; cursor: pointer; font-size: 13px; color: #5a6a78;
  transition: transform 0.2s;
}
#dev-panel:not(.collapsed) #dev-panel-toggle { transform: rotate(180deg); }
#dev-panel.collapsed #dev-panel-body { display: none; }
#dev-panel-body { padding: 8px; display: flex; flex-direction: column; gap: 8px; }
#dev-panel-body hr { border: none; border-top: 1px solid #c8c0b4; margin: 2px 0; }
.dev-row { display: flex; flex-direction: column; gap: 2px; }
.dev-row-label { display: flex; justify-content: space-between; gap: 6px; color: #2c3e50; }
.dev-row-label span { color: #2a5080; font-weight: 700; }
.dev-row input[type="range"] { width: 100%; accent-color: #2a6aaa; }

#dev-mode-buttons { display: flex; gap: 4px; }
.dev-mode-btn {
  flex: 1; padding: 4px 2px; font-size: 10px; font-weight: 700; font-family: inherit;
  background: #ece8e0; color: #5a6a78; border: 1px solid #c8c0b4; border-radius: 4px; cursor: pointer;
}
.dev-mode-btn:hover { background: #dedad2; }
.dev-mode-btn.active { background: #2a6aaa; color: #fff; border-color: #1a5a9a; }

#dev-script-list { display: flex; flex-direction: column; gap: 3px; margin-top: 4px; }
.dev-script-row { display: flex; align-items: center; gap: 3px; font-size: 10px; }
.dev-script-cell { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dev-script-time { width: 56px; font-size: 10px; padding: 1px 3px; border: 1px solid #c8c0b4; border-radius: 3px; }
.dev-script-speed { width: 40px; font-size: 10px; padding: 1px 3px; border: 1px solid #c8c0b4; border-radius: 3px; }
.dev-script-btn {
  width: 18px; height: 18px; padding: 0; font-size: 10px; line-height: 1;
  background: #ece8e0; color: #5a6a78; border: 1px solid #c8c0b4; border-radius: 3px; cursor: pointer;
}
.dev-script-btn:hover { background: #dedad2; }

#dev-textbox-list { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.dev-textbox-row {
  display: flex; flex-direction: column; gap: 3px;
  padding: 5px; border: 1px solid #c8c0b4; border-radius: 4px; background: #fbf9f5;
}
.dev-textbox-grid { display: flex; flex-wrap: wrap; gap: 4px; }
.dev-textbox-field {
  display: flex; flex-direction: column; gap: 1px; font-size: 9px; color: #5a6a78;
  flex: 1 1 60px;
}
.dev-textbox-field input, .dev-textbox-field select {
  font-size: 10px; padding: 1px 3px; border: 1px solid #c8c0b4; border-radius: 3px;
}
.dev-textbox-checkbox { flex-direction: row; align-items: center; gap: 4px; flex: 0 0 auto; }
.dev-textbox-del { margin-left: auto; }
.dev-textbox-title {
  width: 100%; font-size: 10px; font-weight: 700; font-family: inherit; padding: 3px 4px;
  border: 1px solid #c8c0b4; border-radius: 3px;
}
.dev-textbox-text {
  width: 100%; font-size: 10px; font-family: inherit; padding: 3px 4px;
  border: 1px solid #c8c0b4; border-radius: 3px; resize: vertical;
}

/* ══════════════════════════════════════════════════
   PANNEAU DE CONTRÔLE DROIT
══════════════════════════════════════════════════ */

#panel {
  background: #e8e4de;
  border-left: 1.5px solid #c8c0b4;
  display: flex;
  flex-direction: column;
  height: 100%;
  font-size: clamp(11px, 1.1vw, 14px);
  overflow: hidden;
}

/* ── Onglets principaux ──────────────────────────── */
.panel-main-tabs {
  display: flex;
  flex-shrink: 0;
  border-bottom: 1.5px solid #b0a898;
}

.panel-main-tab {
  flex: 1;
  padding: 9px 4px;
  font-size: clamp(12px, 1.2vw, 15px);
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: #d4d0c8;
  color: #8a9aaa;
  border-right: 1px solid #b0a898;
  transition: background 0.12s, color 0.12s;
}
.panel-main-tab:last-child { border-right: none; }
.panel-main-tab:hover { background: #ccc8c0; color: #2c3e50; }
.panel-main-tab.active {
  background: #e8e4de;
  color: #2a6aaa;
  border-bottom: 1.5px solid #e8e4de;
  margin-bottom: -1.5px;
}

/* ── Corps scrollable du panneau ──────────────────── */
#panel-body {
  flex: 1;
  overflow-y: auto;
  padding: clamp(8px, 1vw, 14px) clamp(8px, 1vw, 12px);
  display: flex;
  flex-direction: column;
  gap: 0;
}

.panel-section { margin-bottom: 8px; }

.section-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: #7a8a96;
  margin-bottom: 7px;
}

.sep { border: none; border-top: 1px solid #c8c0b4; margin: 8px 0; }

/* ── Boutons ──────────────────────────────────────── */
.btn {
  width: 100%;
  border: none;
  border-radius: 6px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  transition: transform 0.1s, background 0.15s;
}
.btn:active { transform: scale(0.97); }

.btn-play {
  background: #2a8a50;
  color: #fff;
  font-size: clamp(14px, 1.4vw, 18px);
  padding: 10px 6px;
}
.btn-play:hover { background: #1a6a38; }

.btn-pause {
  background: #c08020;
  color: #fff;
  font-size: clamp(14px, 1.4vw, 18px);
  padding: 10px 6px;
}
.btn-pause:hover { background: #a06010; }

.btn-raz {
  background: #dedad2;
  color: #5a6a78;
  font-size: clamp(12px, 1.2vw, 15px);
  padding: 9px 6px;
  border: 1.5px solid #c8c0b4;
}
.btn-raz:hover { background: #ccc8c0; }

/* Bouton d'action principale (ex. "+ Ajouter 1 mol de soluté") — même bleu
   d'accent que .btn-primary de titrage/css/style.css, taille de police
   inchangée (clamp actuel de .btn-raz) plutôt que le 18px fixe de titrage. */
.btn-primary {
  background: #2a6aaa;
  color: #fff;
  font-size: clamp(12px, 1.2vw, 15px);
  padding: 9px 6px;
  border: 1.5px solid #1a5a9a;
}
.btn-primary:hover { background: #1a5a9a; }

/* ── Barre de progression + vitesse de lecture ────── */
.progress-row {
  display: flex; align-items: center; gap: 8px; margin-top: 10px;
}
#progress-bar { flex: 1; accent-color: #2a6aaa; }
#progress-time {
  font-family: monospace; font-size: 11px; color: #5a6a78; white-space: nowrap;
}

.speed-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-top: 8px; }
.speed-row-label { font-size: clamp(13px, 1.4vw, 16px); color: #5a6a78; white-space: nowrap; }
#speed-select {
  width: auto; padding: 6px 8px; border: 1px solid #c8c0b4; border-radius: 4px;
  font-size: clamp(12px, 1.25vw, 15px); font-family: inherit;
  background: #faf9f6; color: #2c3e50; cursor: pointer;
}
#speed-select:focus { outline: none; border-color: #2a6aaa; }

.btn-fullscreen {
  background: #dedad2;
  color: #5a6a78;
  font-size: clamp(12px, 1.2vw, 15px);
  padding: 9px 6px;
  border: 1.5px solid #c8c0b4;
}
.btn-fullscreen:hover { background: #ccc8c0; }

/* ── Barre de contrôle du mode plein écran ─────────
   Enfant de #anim-canvas-wrap (seul élément mis en plein écran) : n'affiche
   donc jamais l'image du verre ni le panneau de droite. Masquée hors plein
   écran ; s'estompe (opacity) après quelques secondes d'inactivité de la
   souris une fois en plein écran, comme les lecteurs vidéo type YouTube. */
#fs-controls {
  display: none;
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  align-items: center;
  gap: 10px;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0));
  transition: opacity 0.3s ease;
  opacity: 1;
}
#anim-canvas-wrap.is-fullscreen #fs-controls { display: flex; }
#anim-canvas-wrap.is-fullscreen.fs-controls-hidden #fs-controls {
  opacity: 0;
  pointer-events: none;
}
#anim-canvas-wrap.is-fullscreen.fs-controls-hidden { cursor: none; }

/* ── Symbole play/pause central (flash bref au clic) ── */
#fs-center-icon {
  display: none;
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(0.8);
  z-index: 40;
  width: 84px;
  height: 84px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 38px;
  line-height: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
/* Les glyphes ▶/⏸ ont un empattement (bas, et pour ▶ aussi à gauche) dans la
   plupart des polices système : décalage visuel spécifique à chaque symbole
   pour le recentrer réellement dans le cercle (cf. classes posées par
   _fsFlashCenterIcon() dans fullscreen.js). */
#fs-center-icon.icon-pause { padding-bottom: 6px; }
#fs-center-icon.icon-play { padding-bottom: 6px; padding-left: 8px; }
#anim-canvas-wrap.is-fullscreen #fs-center-icon { display: flex; }
#anim-canvas-wrap.is-fullscreen #fs-center-icon.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  transition: opacity 0.05s ease, transform 0.05s ease;
}

.fs-btn {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  font-size: 16px;
  cursor: pointer;
  transition: background 0.15s;
}
.fs-btn:hover { background: rgba(255, 255, 255, 0.3); }

#fs-progress-bar { flex: 1; accent-color: #2a9ae0; }
#fs-progress-time {
  flex: 0 0 auto;
  font-family: monospace;
  font-size: 12px;
  color: #fff;
  white-space: nowrap;
}

/* ── Placeholder "À venir" (2e onglet) ────────────── */
.coming-soon {
  text-align: center;
  padding: clamp(20px, 3vh, 40px) 10px;
  color: #7a8a96;
}
.coming-soon-icon { font-size: clamp(24px, 3vw, 36px); margin-bottom: 8px; }
.coming-soon-title { font-size: clamp(13px, 1.3vw, 16px); font-weight: 700; color: #5a6a78; margin-bottom: 6px; }
.coming-soon-text { font-size: clamp(11px, 1vw, 13px); font-style: italic; }

/* ══════════════════════════════════════════════════
   BANDEAU INSTRUCTIONS (repliable)
   Même pattern que ondes/ et champ_uniforme/
══════════════════════════════════════════════════ */

.panel-hint {
  flex-shrink: 0;
  color: #5a6a78;
  line-height: 1.5;
  background: #fff;
  border: 1.5px solid #b0a898;
  /* Pas de bordure gauche propre : #panel a déjà la sienne (border-left,
     1.5px) sur ce bord. Avec la largeur de #panel en clamp() (donc
     fractionnaire en px), deux bordures superposées à cet endroit
     arrondissent chacune de leur côté et laissent un décalage d'~1px
     entre elles — en confiant ce bord à #panel seul, une seule bordure
     le trace, sans place pour ce décalage. */
  border-left: none;
  overflow: hidden;
  transition: padding 0.2s;
}

.panel-hint-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  cursor: default;
}

.panel-hint-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: #7a8a96;
  margin-left: auto;
  margin-right: 6px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.panel-hint-menu-btn {
  background: #f0f4f7;
  border: 1px solid #c8d4dc;
  border-radius: 6px;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  color: #4a5a68;
  padding: 4px 9px;
  line-height: 1.2;
  transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}
.panel-hint-menu-btn:hover { background: #dde6ec; color: #2a6aaa; }

.panel-hint-toggle {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 13px;
  color: #7a8a96;
  padding: 0 2px;
  line-height: 1;
  transition: transform 0.2s;
}
.panel-hint-toggle:hover { color: #2a6aaa; }

.panel-hint-body {
  font-size: clamp(12px, 1.15vw, 15px);
  padding: 0 10px 8px;
  overflow: hidden;
  transition: max-height 0.25s ease, padding 0.25s ease;
  max-height: 250px;
}

.panel-hint.collapsed .panel-hint-body { max-height: 0; padding-top: 0; padding-bottom: 0; }
.panel-hint.collapsed .panel-hint-header { padding-bottom: 6px; }

.panel-hint:not(.collapsed) .panel-hint-toggle { transform: rotate(180deg); }

/* ══════════════════════════════════════════════════
   ONGLET DISSOLUTION
══════════════════════════════════════════════════ */

/* ── Zone gauche : coupelle + verre (canvas) + tableau ─── */
#dissolution-area {
  flex: 1;
  display: grid;
  grid-template-columns: clamp(110px, 12vw, 170px) 1fr;
  min-height: 0;
  overflow: hidden;
  background: #fdf8f0;
  border-right: 1px solid #c8c0b4;
}

/* ── Colonne photo (placeholder — même traitement que #verre-col) ── */
#diss-photo-col {
  grid-column: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(6px, 1vw, 12px);
  border-right: 1px solid #c8c0b4;
  text-align: center;
}
.diss-photo-placeholder {
  color: #7a8a96;
  font-size: clamp(10px, 1vw, 13px);
  line-height: 1.5;
}
.diss-photo-placeholder-icon { font-size: clamp(22px, 3vw, 34px); display: block; margin-bottom: 4px; }

/* ── Colonne contenu : scène (2/3) + tableau (1/3) ── */
#diss-content-col {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

#diss-scene-wrap {
  flex: 2 1 0;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  position: relative;
  background: #fdf8f0;
  box-sizing: border-box;
  /* Container query : la légende (#diss-legend) se dimensionne en cqmin
     (le plus petit des deux), càd par rapport à LA TAILLE RÉELLE de ce
     wrapper — pas celle de la fenêtre (vw), qui ne suivait ni un wrapper
     plus étroit que la fenêtre (colonne photo, grille de l'onglet) ni un
     wrapper aplati en hauteur (le vw ignore totalement la hauteur, d'où un
     scale qui suivait la largeur mais jamais la réduction en hauteur).
     `size` (et pas seulement `inline-size`) est nécessaire pour que les
     unités cqb/cqmin captent aussi la hauteur du conteneur. */
  container-type: size;
}
#diss-canvas {
  display: block;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 0);
  cursor: pointer;
}

/* Légende — overlay HTML plutôt que dessinée dans #diss-canvas : celui-ci
   est affiché en mode « cover » recentré (cf. #diss-canvas ci-dessus), donc
   tout contenu dessiné près d'un bord de la scène logique peut se retrouver
   hors cadre selon la fenêtre. Un vrai élément DOM ancré au wrapper (jamais
   recadré) reste toujours dans le coin voulu. */
#diss-legend {
  position: absolute;
  top: 2cqmin;
  left: 2cqmin;
  z-index: 2;
  pointer-events: none;
  background: rgba(255, 255, 255, 0.92);
  border: max(1px, 0.4cqmin) solid #c8ccd4;
  border-radius: 1.6cqmin;
  padding: 2.2cqmin 2.8cqmin;
  font-size: clamp(9px, 2.6cqmin, 18px);
  color: #1c2430;
  /* cqw, pas cqmin : la largeur max de la boîte suit la largeur RÉELLE du
     wrapper, pas le plus petit des deux axes — sinon une réduction en
     hauteur seule resserre aussi la boîte horizontalement sans raison
     (rien ne la contraint dans cet axe-là), au lieu de la laisser
     s'aplatir et utiliser l'espace horizontal encore disponible. */
  max-width: 46cqw;
}
.diss-legend-title {
  font-weight: 700;
  font-size: 1.25em;
  margin-bottom: 0.3em;
}
.diss-legend-sub {
  color: #4a5568;
  margin-bottom: 0.45em;
  line-height: 1.15;
}
.diss-legend-row {
  display: flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.05em 0;
}
.diss-legend-compound {
  margin-top: 0.15em;
  border-top: 1px solid #d8dce2;
  padding-top: 0.2em;
}
.diss-legend-ion, .diss-legend-grain {
  flex: 0 0 auto;
  width: clamp(20px, 9.3cqmin, 60px);
  height: clamp(15px, 7.2cqmin, 46px);
}

#diss-bottom-zone {
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  background: #fdf8f0;
  border-top: 1px solid #c8c0b4;
  padding: clamp(8px, 1.2vh, 16px) clamp(10px, 1.5vw, 20px);
  container-type: inline-size;
}

/* Chaque terme (réactif, flèche, produits) est positionné individuellement
   en absolu, calé sur le centre (ou la bordure séparatrice, pour la flèche)
   de la colonne correspondante du tableau — calcul JS dans
   alignDissEquation() (diss.js), à rappeler à chaque rendu du tableau et à
   chaque redimensionnement puisque les largeurs de colonnes sont
   responsives. #diss-equation sert seulement de repère de coordonnées
   (position: relative) ; sa hauteur est fixée en em pour que les enfants
   absolus (centrés verticalement via top:50%) restent dans le flux normal. */
#diss-equation {
  position: relative;
  height: 1.3em;
  font-size: clamp(30px, 7.2cqw, 44px);
  font-weight: 700;
  color: #2c3e50;
  margin-bottom: clamp(6px, 1vh, 12px);
}
.diss-eq-term, .diss-eq-op {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
}

/* ── Tableau d'avancement (valeurs reprises de reaction/css/style.css,
   redéfinies localement — pas de CSS partagé entre dossiers dans ce dépôt) ── */
#diss-table-wrap {
  margin: 0 clamp(4px, 3cqw, 32px);
}
#diss-table {
  width: 100%;
  border-collapse: collapse;
  font-size: clamp(24px, 4cqw, 34px);
  text-align: center;
}
#diss-table th, #diss-table td {
  border: 1px solid #c8c0b4;
  /* Padding en em (et non px/vh/cqw) : il suit directement le font-size, y
     compris quand celui-ci est réduit dynamiquement par fitDissTable()
     (diss.js) pour éviter tout débordement horizontal du tableau.
     white-space: nowrap — sans quoi le texte passerait simplement à la
     ligne au lieu de forcer le tableau à dépasser sa largeur disponible, ce
     qui empêchait fitDissTable() de détecter le débordement et de réduire
     la police en conséquence. */
  padding: 0.35em 0.45em;
  white-space: nowrap;
}
#diss-table .diss-label {
  /* white-space: normal (contrairement aux autres cellules) : sans ça,
     nowrap forcerait la colonne à s'élargir pour loger tout le texte sur une
     ligne, ignorant purement et simplement la largeur ci-dessous.
     Largeur en ch, dimensionnée pour le mot le plus long parmi les deux
     modes d'affichage (« Concentrations », 14 caractères, contre
     « Quantités », 9) : en table-layout auto, un mot sans espace ne peut de
     toute façon pas être coupé sous sa largeur intrinsèque, donc la colonne
     s'élargirait à ce mot quoi qu'on mette ici — autant fixer d'emblée cette
     largeur-là, qui devient alors la même dans les deux modes. Le ch suit le
     font-size de la cellule, y compris quand fitDissTable() le réduit. */
  white-space: normal;
  text-align: left;
  color: #5a6a78;
  font-weight: 600;
  /* max-width en plus de width : en table-layout auto, une largeur "width"
     seule reste indicative et le navigateur peut reporter ici l'espace
     laissé libre par les autres colonnes (constaté en fixant celles des
     valeurs ci-dessous) ; max-width empêche ce report et garde cette
     colonne à sa taille voulue. */
  width: 15ch;
  max-width: 15ch;
}
/* Largeur minimale en ch (assez large pour « 999,99 mol·L⁻¹ ») : sans ça, la
   colonne suit la longueur du nombre affiché (ex. « 0 mol » vs
   « 12,50 mol·L⁻¹ »), donc le tableau change de taille à chaque ajout de
   soluté — gênant visuellement, alors qu'il y a largement la place pour
   réserver une largeur stable dès le départ. min-width (et non width) pour
   qu'elles absorbent l'espace laissé libre plutôt que la colonne label. */
#diss-table .diss-col-solute, #diss-table .diss-td-solute { background: #e8f0fb; color: #2a6aaa; min-width: 13ch; }
#diss-table .diss-col-ion,    #diss-table .diss-td-ion    { background: #e8f5ee; color: #2a8a50; min-width: 13ch; }
#diss-table .sep-rp { border-right: 2px solid #b0a898; }

/* ══════════════════════════════════════════════════
   Éditeur du tableau (dev) — TEMPORAIRE, cf. js/table-devtool.js.
   Distinct de #dev-panel (onglet Mécanisme).
══════════════════════════════════════════════════ */
#diss-table-wrap { position: relative; }
#diss-table.diss-table-dev-mode th,
#diss-table.diss-table-dev-mode td {
  outline: 1px dashed transparent;
  cursor: text;
}
#diss-table.diss-table-dev-mode th:hover,
#diss-table.diss-table-dev-mode td:hover {
  outline-color: #2a6aaa;
}
#diss-table.diss-table-dev-mode th:focus,
#diss-table.diss-table-dev-mode td:focus {
  outline: 2px solid #2a6aaa;
  outline-offset: -2px;
  background: #fffbe8;
}

#diss-table-resize-overlay { position: absolute; inset: 0; pointer-events: none; }
.diss-col-handle {
  position: absolute;
  width: 7px;
  background: rgba(42, 106, 170, 0.15);
  border-left: 1px dashed #2a6aaa;
  cursor: col-resize;
  pointer-events: auto;
  z-index: 5;
}
.diss-col-handle:hover { background: rgba(42, 106, 170, 0.35); }
.diss-row-handle {
  position: absolute;
  height: 7px;
  background: rgba(42, 106, 170, 0.15);
  border-top: 1px dashed #2a6aaa;
  cursor: row-resize;
  pointer-events: auto;
  z-index: 5;
}
.diss-row-handle:hover { background: rgba(42, 106, 170, 0.35); }
.diss-outer-handle {
  background: rgba(170, 60, 42, 0.18);
  border-color: #aa3c2a;
}
.diss-outer-handle:hover { background: rgba(170, 60, 42, 0.4); }

#diss-table-dev-toggle {
  position: fixed;
  top: 8px;
  right: 8px;
  width: 30px;
  height: 30px;
  font-size: 15px;
  background: rgba(255, 255, 255, 0.94);
  border: 1.5px solid #b0a898;
  border-radius: 8px;
  cursor: pointer;
  z-index: 31;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}
#diss-table-dev-panel {
  position: fixed;
  top: 44px;
  right: 8px;
  width: clamp(200px, 22vw, 300px);
  max-height: calc(100dvh - 52px);
  overflow-y: auto;
  background: rgba(255, 255, 255, 0.94);
  border: 1.5px solid #b0a898;
  border-radius: 8px;
  font-size: 11px;
  font-family: 'Segoe UI', Arial, sans-serif;
  color: #2c3e50;
  z-index: 30;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}
#diss-table-dev-panel.collapsed { display: none; }
#diss-table-dev-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 8px;
  font-weight: 700;
  background: #e8e4de;
  border-bottom: 1px solid #c8c0b4;
  border-radius: 7px 7px 0 0;
}
#diss-table-dev-close {
  background: none; border: none; cursor: pointer; font-size: 13px; color: #5a6a78;
}
#diss-table-dev-body { padding: 8px; display: flex; flex-direction: column; gap: 8px; }
#diss-table-dev-actions { display: flex; gap: 4px; }
#diss-table-dev-actions .dev-mode-btn { flex: 1; }

/* ── Sélecteur de soluté (repris de .titrage-select/.reaction-select) ── */
.diss-select {
  width: 100%;
  padding: 7px 8px;
  border: 1px solid #c8c0b4;
  border-radius: 5px;
  background: #fff;
  color: #2c3e50;
  font-size: clamp(12px, 1.25vw, 15px);
  font-family: inherit;
  cursor: pointer;
}
.diss-select:focus { outline: none; border-color: #2a6aaa; }

/* ── Slider de volume (charte CONTEXTE_PROJET.md §5, cf. pression/) ── */
.param-row { display: flex; flex-direction: column; gap: 3px; margin-bottom: 6px; }
.param-row label { display: flex; justify-content: space-between; align-items: baseline; font-size: 15px; color: #2c3e50; }
.param-value { color: #2a5080; font-weight: 600; }
.param-row input[type="range"] { width: 100%; accent-color: #4a7aaa; cursor: pointer; }

/* ── Bascule d'unité mol / mol·L⁻¹ (façon .mode-tabs/.mode-tab) ── */
.diss-unit-toggle {
  display: flex;
  border: 1px solid #c8c0b4;
  border-radius: 6px;
  overflow: hidden;
}
.diss-unit-btn {
  flex: 1;
  padding: 8px 4px;
  font-size: clamp(12px, 1.2vw, 15px);
  font-weight: 700;
  font-family: inherit;
  border: none;
  background: #dedad2;
  color: #5a6a78;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.diss-unit-btn:not(:last-child) { border-right: 1px solid #c8c0b4; }
.diss-unit-btn:hover { background: #ccc8c0; }
.diss-unit-btn.active { background: #2a6aaa; color: #fff; }
