:root{
  --bg:#eef1f5;
  --panel:#ffffff;
  --ink:#1b2430;
  --ink-soft:#5b6b7c;
  --line:#d6dee7;
  --accent:#0b6cb1;
  --accent-soft:#e3f0fa;
  --port:#c2410c;
  --port-h:#94a3b8;
  --danger:#b91c1c;
  --board:#fbfcfd;
  --shadow:0 1px 2px rgba(16,32,48,.06),0 4px 12px rgba(16,32,48,.07);
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font:14px/1.45 "Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  overflow:hidden;
}
button{font:inherit;cursor:pointer}

/* ---------------- barre superieure ---------------- */
#topbar{
  height:52px;display:flex;align-items:center;gap:18px;padding:0 16px;
  background:var(--panel);border-bottom:1px solid var(--line);box-shadow:var(--shadow);
  position:relative;z-index:20;
}
.brand{display:flex;align-items:center;gap:9px;font-size:18px;font-weight:600;letter-spacing:-.2px}
/* la marque ne se coupe plus en deux : "Pasteur" est un seul mot */
.brand .sigle{width:28px;height:28px;flex:0 0 auto;display:block}
.langues{display:inline-flex; margin-left:12px; border:1px solid var(--line);
  border-radius:8px; overflow:hidden; background:#fff}
.langues button{border:0; background:transparent; color:var(--ink-soft);
  font:inherit; font-size:11px; letter-spacing:.08em; padding:4px 9px; cursor:pointer}
.langues button+button{border-left:1px solid var(--line)}
.langues button[aria-pressed="true"]{background:var(--accent); color:#fff}
/* L'ADRESSE OU L'ON ECRIT, A GAUCHE DE LA BARRE DU HAUT. ICI, CETTE PAGE *EST*
   LE SITE : sous retrosynthese.com il n'y a pas d'accueil ou poser l'adresse
   comme nestedplay.com et golois.com en ont un, et une page d'application n'a
   pas de pied. ELLE ETAIT A DROITE ET ELLE N'Y SERVAIT A RIEN : une enveloppe
   grise de 25 px, derniere d'une barre qui ne se replie pas et ne descend pas
   sous 924 px -- donc hors de l'ecran des 930 px de fenetre (mesure : 24 px
   dehors a 900, 534 a 390), et introuvable au-dessus. A gauche, derriere la
   marque, c'est la premiere chose que la barre garde.
   TROIS ETATS, ET C'EST LA LARGEUR QUI CHOISIT : l'adresse en clair quand il y
   a la place, le mot seul ensuite, le glyphe seul sur un telephone -- le lien
   ne disparait jamais, et son `title` porte l'adresse dans les trois. */
.contact{display:inline-flex; align-items:center; gap:7px; flex:0 0 auto;
  color:var(--ink-soft); text-decoration:none; font-size:13px; line-height:1;
  padding:5px 9px; border:1px solid var(--line); border-radius:7px;
  background:#fff; white-space:nowrap}
.contact .env{font-size:15px}
.contact:hover{color:var(--ink); border-color:#bcc9d6; background:#f2f6fa}
/* L'ADRESSE EN CLAIR NE SE MONTRE QUE SI ELLE NE POUSSE RIEN DEHORS : la barre
   tient 1 323 px de contenu a elle seule, et l'adresse en pese 170. */
@media (max-width:1520px){ .contact .adr{display:none} }
@media (min-width:1521px){ .contact .mot{display:none} }
/* ET LE LIEN NE DOIT RIEN POUSSER DEHORS. Sous 1 180 px la barre n'a plus de
   place a donner, et elle ne se replie pas (`#app` compte sur une hauteur de
   52 px exactement) : le mot s'efface, il ne reste que le glyphe. Sous
   1 000 px l'ecart entre les blocs se resserre de 18 a 10 px -- 40 px rendus
   pour 26 px pris, si bien que le bout droit de la barre, langues et pastille
   du compte, est MOINS pousse dehors qu'avant l'arrivee du lien. Mesure en
   ligne, pastille comprise : a 900 px, 24 px de debord avant (l'enveloppe
   elle-meme, hors de l'ecran) et 0 apres, tout tient ; a 700 px, 224 avant et
   184 apres ; a 390 px, 534 et 494. */
@media (max-width:1180px){ .contact .mot{display:none} }
@media (max-width:1000px){ #topbar{gap:10px} }
/* ET LE MOT NE DOIT RIEN RETRECIR NON PLUS. Sur un portable de 1 280 px, les
   103 px du lien etaient pris sur le bout droit de la barre : le selecteur de
   langue y perdait son « FR » et la pastille devenait « Se con... », parce que
   tous les blocs d'un `flex` retrecissent ensemble. On rend la place AILLEURS
   -- le conseil passe de 46 a 26 caracteres, il etait deja sur deux lignes a
   cette largeur -- et l'on interdit aux deux blocs de droite de retrecir : ce
   sont des commandes, elles se lisent ou elles ne servent a rien. Mesure a
   1 280 px : 1 257 px de contenu, donc rien ne deborde. */
/* ET SEULEMENT DANS CETTE BANDE-LA : plus bas, le lien n'est plus qu'un
   glyphe, il ne prend plus la place du conseil -- et le conseil serre a
   26 caracteres y passait a trois lignes, qui debordent d'une barre haute de
   52 px. On ne resserre donc que la ou l'on a pris quelque chose. */
@media (min-width:1181px) and (max-width:1440px){ .hint{max-width:26ch} }
/* ET SEULEMENT LA OU LA BARRE TIENT DANS LA FENETRE. Mesure : sans le droit de
   retrecir, le contenu pese 1 150 px au minimum -- interdire le retrecissement
   a 1 100 px poussait la pastille du compte HORS de l'ecran, ce qui est pire
   que de la voir serree. 1 180 px est la largeur ou tout tient, et c'est deja
   le seuil ou la palette et le panneau de droite se resserrent. */
@media (min-width:1181px){ #langues, #lien-compte{flex:0 0 auto} }
.tools{display:flex;align-items:center;gap:8px}
.tool-label{color:var(--ink-soft);font-size:12px;text-transform:uppercase;letter-spacing:.06em}
.tools button{
  padding:6px 11px;border:1px solid var(--line);background:#fff;border-radius:6px;
  color:var(--ink);transition:background .12s,border-color .12s;
}
.tools button:hover{background:#f2f6fa;border-color:#bcc9d6}
.tools button:disabled{opacity:.4;cursor:default;background:#fff}
.tools button.danger{color:var(--danger);border-color:#f0d2d2}
.tools button.danger:hover{background:#fdf2f2}
.seg{display:flex;border:1px solid var(--line);border-radius:6px;overflow:hidden}
.seg button{border:0;border-radius:0;background:#fff;padding:6px 14px;font-size:16px;line-height:1}
.seg button+button{border-left:1px solid var(--line)}
.seg button.on{background:var(--accent);color:#fff}
.seg button.on:hover{background:var(--accent)}
.sep{width:1px;height:24px;background:var(--line)}
.hint{margin-left:auto;color:var(--ink-soft);font-size:13px;max-width:46ch;text-align:right}
.hint.warn{color:var(--danger)}

/* ---------------- disposition ---------------- */
#app{display:flex;height:calc(100% - 52px)}
aside{background:var(--panel);display:flex;flex-direction:column;min-height:0}
#palette{width:268px;border-right:1px solid var(--line)}
#result{width:340px;border-left:1px solid var(--line);padding:14px;gap:12px;overflow-y:auto}

/* ---------------- palette ---------------- */
.pal-search{padding:10px;border-bottom:1px solid var(--line)}
.pal-search input,.pal-custom input{
  width:100%;padding:7px 10px;border:1px solid var(--line);border-radius:6px;
  font:inherit;color:var(--ink);background:#fff;
}
.pal-search input:focus,.pal-custom input:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
#pal-list{flex:1;overflow-y:auto;padding:4px 0 10px}
.cat>summary{
  padding:7px 12px;font-weight:600;font-size:12.5px;color:var(--ink-soft);
  text-transform:uppercase;letter-spacing:.05em;cursor:pointer;user-select:none;
  background:#f7f9fb;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:2;
}
.cat>summary::marker{color:var(--accent)}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:8px}
.frag{
  border:1px solid var(--line);border-radius:8px;background:#fff;padding:4px 2px 2px;
  display:flex;flex-direction:column;align-items:center;cursor:pointer;
  transition:border-color .12s,box-shadow .12s,transform .06s;
}
.frag:hover{border-color:var(--accent);box-shadow:0 2px 8px rgba(11,108,177,.15)}
.frag:active{transform:scale(.97)}
.frag svg{width:100%;height:58px;display:block}
.frag .nm{font-size:10.5px;color:var(--ink-soft);text-align:center;line-height:1.2;
  padding:2px 3px 3px;word-break:break-word}
.pal-custom{border-top:1px solid var(--line);padding:10px;display:flex;flex-direction:column;gap:7px}
.pal-custom label{font-size:12px;font-weight:600;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.05em}
.pal-custom button{
  padding:7px;border:1px solid var(--accent);background:var(--accent);color:#fff;border-radius:6px;
}
.pal-custom button:hover{background:#095c97}
.pal-custom .note{margin:0;font-size:11px;color:var(--ink-soft);line-height:1.35}
.pal-custom code{background:#eef2f6;padding:0 3px;border-radius:3px;font-size:10.5px}

/* ---------------- plan de travail ---------------- */
#board{
  flex:1;position:relative;overflow:hidden;background:var(--board);
  background-image:radial-gradient(#d9e1ea 1px,transparent 1px);
  background-size:22px 22px;cursor:grab;
}
#board.panning{cursor:grabbing}
#world{position:absolute;top:0;left:0;transform-origin:0 0}
#wires{position:absolute;top:0;left:0;width:6000px;height:6000px;pointer-events:none;overflow:visible}
#wires line,#wires path{pointer-events:stroke}
#nodes{position:absolute;top:0;left:0}

.node{
  position:absolute;background:#fff;border:1px solid var(--line);border-radius:10px;
  box-shadow:var(--shadow);user-select:none;cursor:move;
}
.node.sel{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft),var(--shadow)}
.node .body{position:relative}
.node svg{display:block;pointer-events:none}
.node .cap{
  position:absolute;left:0;right:0;bottom:-17px;text-align:center;font-size:10.5px;
  color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.node .del{
  position:absolute;top:-9px;right:-9px;width:19px;height:19px;border-radius:50%;
  border:1px solid var(--line);background:#fff;color:var(--danger);font-size:13px;line-height:1;
  display:none;align-items:center;justify-content:center;padding:0;
}
.node:hover .del{display:flex}
.node .del:hover{background:#fdf2f2;border-color:#f0d2d2}

.port{
  position:absolute;border-radius:50%;transform:translate(-50%,-50%);
  cursor:pointer;transition:transform .1s,background .1s;
}
.port.r{width:15px;height:15px;background:#fff;border:2.5px solid var(--port)}
.port.r:hover{transform:translate(-50%,-50%) scale(1.28);background:#ffe9df}
.port.h{width:9px;height:9px;background:#fff;border:2px solid var(--port-h);opacity:0}
.node:hover .port.h{opacity:.75}
.port.h:hover{opacity:1;transform:translate(-50%,-50%) scale(1.5);border-color:var(--accent)}
.port.used{background:var(--port);border-color:var(--port);cursor:default;opacity:.45}
.port.used:hover{transform:translate(-50%,-50%)}
.node .port.armed{
  background:var(--accent);border-color:var(--accent);opacity:1;
  box-shadow:0 0 0 5px rgba(11,108,177,.22);
}

#board-empty{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:6px;color:var(--ink-soft);pointer-events:none;text-align:center;
}
#board-empty p{margin:0;font-size:17px;font-weight:600}
#board-empty span{max-width:42ch;font-size:13px}
#zoom-badge{
  position:absolute;right:10px;bottom:10px;background:rgba(255,255,255,.92);
  border:1px solid var(--line);border-radius:6px;padding:3px 8px;font-size:11.5px;
  color:var(--ink-soft);pointer-events:none;
}

/* ---------------- panneau resultat ---------------- */
#result h2{margin:0;font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft)}
#preview{
  border:1px solid var(--line);border-radius:10px;background:#fff;min-height:220px;
  display:flex;align-items:center;justify-content:center;overflow:hidden;
}
#preview svg{max-width:100%;height:auto}
#preview .ph{color:#c3ccd6;font-size:32px}
.smiles-block{display:flex;flex-direction:column;gap:5px}
.smiles-head{display:flex;align-items:center;justify-content:space-between}
.smiles-head span{font-size:12px;font-weight:600;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.05em}
.smiles-head button{padding:4px 10px;border:1px solid var(--line);background:#fff;border-radius:6px}
.smiles-head button:hover{background:#f2f6fa}
#smiles{
  width:100%;resize:vertical;border:1px solid var(--line);border-radius:8px;padding:8px 9px;
  font:12.5px/1.45 "SFMono-Regular",Consolas,"Liberation Mono",monospace;
  color:var(--ink);background:#fbfcfd;
}
#msg{font-size:12.5px;color:var(--danger);min-height:1em}
#msg.info{color:var(--ink-soft)}
#props{width:100%;border-collapse:collapse;font-size:12.5px}
#props th{
  text-align:left;font-weight:500;color:var(--ink-soft);padding:5px 0;
  border-bottom:1px solid #eef2f6;width:52%;
}
#props td{text-align:right;padding:5px 0;border-bottom:1px solid #eef2f6;font-variant-numeric:tabular-nums}
.mono{font-family:"SFMono-Regular",Consolas,monospace}
.small{font-size:11px}
.exports{display:flex;gap:8px}
.exports button{
  flex:1;padding:7px;border:1px solid var(--line);background:#fff;border-radius:6px;
}
.exports button:hover{background:#f2f6fa}

@media (max-width:1180px){
  #palette{width:224px}
  #result{width:290px}
}

/* ---------------- retrosynthese ---------------- */
/* en tete du panneau : le trait de separation passe donc en dessous */
.retro-block{margin-bottom:18px; padding-bottom:16px; border-bottom:1px solid var(--line, #d8dbe0)}
.retro-block h2{margin:0 0 8px}
#btn-retro{width:100%; padding:10px; font-weight:600}
#btn-retro:disabled{opacity:.45; cursor:default}
#retro-etat{margin-top:10px; font-size:13px; min-height:18px}
/* tant qu'il n'y a rien a dire, le bloc ne reserve pas de place */
#retro-etat:empty{margin:0; min-height:0}
#retro-route:empty{margin:0}
#retro-etat .barre{height:5px; border-radius:3px; background:#e6e8ec; overflow:hidden; margin:8px 0}
#retro-etat .barre i{display:block; height:100%; width:0; background:#2f6f4f; transition:width .5s linear}
#retro-etat.bon{color:#2f6f4f; font-weight:600}
#retro-etat.mauvais{color:#a2483a}
#retro-route{margin-top:12px; font-size:12.5px}
#retro-route ul{list-style:none; margin:0; padding-left:14px; border-left:1px solid #dfe2e7}
#retro-route > ul{padding-left:0; border-left:0}
#retro-route li{margin:5px 0}
#retro-route .mol{font-family:ui-monospace,Menlo,Consolas,monospace; font-size:11.5px;
  word-break:break-all; line-height:1.45}
#retro-route .stock{color:#2f6f4f}
#retro-route .stock::before{content:"catalogue "; font-family:inherit; font-size:10.5px;
  letter-spacing:.04em; text-transform:uppercase; color:#7b8794; margin-right:4px}
#retro-route .fleche{color:#7b8794; margin:0 4px}
#retro-route .resume{margin:0 0 8px; color:#374151}
#retro-route .resume b{color:#111827}

/* ---------------- la route dans le plan de travail ---------------- */
#route-plan{position:absolute; inset:0; background:var(--bg, #fbfbfc); z-index:5;
  display:flex; flex-direction:column}
#route-plan[hidden]{display:none}
.rp-tete{display:flex; align-items:center; gap:14px; padding:10px 14px;
  border-bottom:1px solid #e3e6ea; background:#fff; flex:0 0 auto}
.rp-titre{font-weight:600; font-size:14px}
.rp-resume{font-size:13px; color:#6b7280; flex:1 1 auto}
#rp-fermer{font-size:13px; padding:6px 12px}
/* "safe center" centre tant que l'arbre tient dans la fenetre et colle a gauche des
   qu'il deborde. Avec un centrage ordinaire, la partie gauche d'un arbre trop large
   passe hors de la zone defilable et devient inatteignable. */
.rp-arbre{flex:1 1 auto; overflow:auto; padding:24px 20px 40px; display:flex;
  justify-content:safe center; align-items:flex-start}

/* un organigramme : chaque molecule au-dessus de ce qui la fabrique */
.rp-arbre ul{list-style:none; margin:0; padding:22px 0 0; display:flex;
  justify-content:center; align-items:flex-start; position:relative}
.rp-arbre > ul{padding-top:0}
.rp-arbre li{position:relative; padding:22px 10px 0; display:flex;
  flex-direction:column; align-items:center}
/* les traits de liaison, en bordures : pas de calcul de coordonnees */
.rp-arbre li::before, .rp-arbre li::after{content:""; position:absolute; top:0;
  width:50%; height:22px; border-top:1px solid #c8ccd2}
.rp-arbre li::before{right:50%; border-right:1px solid #c8ccd2}
.rp-arbre li::after{left:50%}
.rp-arbre li:only-child::before, .rp-arbre li:only-child::after{display:none}
.rp-arbre li:only-child{padding-top:22px}
.rp-arbre li:first-child::before, .rp-arbre li:last-child::after{border-top:0}
.rp-arbre li:last-child::before{border-right-color:#c8ccd2}
.rp-arbre > ul > li{padding-top:0}
.rp-arbre > ul > li::before, .rp-arbre > ul > li::after{display:none}
.rp-arbre ul ul::before{content:""; position:absolute; top:0; left:50%; height:22px;
  border-left:1px solid #c8ccd2}
.rp-mol{position:relative; background:#fff; border:1px solid #dfe3e8; border-radius:10px;
  padding:8px 8px 6px; width:168px; box-shadow:0 1px 2px rgba(20,24,30,.05)}
.rp-mol.rp-stock{border-color:#bcd8c6; background:#f6fbf7}
.rp-mol svg{width:100%; height:104px; display:block}
.rp-mol .rp-vide{height:104px; display:flex; align-items:center; justify-content:center;
  color:#9aa3ad; font-size:20px}
.rp-mol .rp-smiles{margin:4px 0 0; font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:10px; line-height:1.35; color:#5b636d; word-break:break-all; max-height:2.7em;
  overflow:hidden}
.rp-mol .rp-etiq{position:absolute; top:-9px; left:8px; font-size:9.5px; letter-spacing:.04em;
  text-transform:uppercase; background:#2f6f4f; color:#fff; padding:1px 6px; border-radius:6px}
.rp-mol .rp-sans{font-size:11px; color:#a2483a; text-align:center; line-height:1.3; padding:0 6px}

/* RIEN NE ZOOME TOUT SEUL SUR UN ÉCRAN TACTILE. Deux appuis rapprochés sur un
   bouton sont lus par Safari, sur iPhone et iPad, comme un double appui — c'est
   à dire comme un ordre de grossir : le navigateur met alors le BOUTON à la
   largeur de l'écran, et le jeu sort du cadre. Le geste se fait sans y penser
   quand on presse deux fois « Annuler » pour revenir de deux coups en arrière.

   `manipulation` dit au navigateur qu'il n'y a pas de double appui à attendre
   ici : l'appui simple part aussitôt, le défilement reste, et le pincement — le
   zoom VOULU — reste lui aussi. On ne retire que le zoom accidentel, et jamais
   par `user-scalable=no`, qui fermerait les deux.

   Le plateau était protégé depuis longtemps ; les commandes ne l'étaient pas.
   La propriété ne s'hérite pas — le navigateur croise celle de la cible avec
   celle de ses ancêtres, de sorte que la première ligne suffirait —, mais on la
   redit sur les commandes : c'est là que le geste a lieu, et la protection ne
   doit pas dépendre d'un ancêtre qui changerait d'avis. */
html, body { touch-action: manipulation; }
button, select, input, textarea, a, label, summary { touch-action: manipulation; }

/* ET RIEN NE ZOOME NON PLUS EN ENTRANT DANS UN CHAMP : sous seize pixels,
   Safari grossit la page dès qu'un `input`, un `select` ou un `textarea` prend
   le focus — il rend le texte lisible — et il ne la redescend pas en sortant.
   Même symptôme que le double appui, autre cause. Seize pixels sur les écrans
   tactiles SEULEMENT : à la souris, les commandes restent discrètes.

   Mesuré avant d'être posé, sur l'écran d'un téléphone : aucun champ du site ne
   dépassait seize pixels — la règle ne rétrécit donc rien —, et aucune page ne
   déborde. */
@media (pointer: coarse) {
  input, select, textarea { font-size: 16px; }
  /* Ces champs-là tiennent leur taille d'une règle plus précise — une classe,
     un identifiant : la ligne du dessus perdrait la cascade sans les nommer.
     C'est la mesure qui les a trouvés, un par un. */
  #search, #custom-smiles, #smiles { font-size: 16px; }
}
