|
77 | 77 | .kv{display:grid;grid-template-columns:auto 1fr;gap:6px 16px;margin-bottom:10px} |
78 | 78 | .kv .k{font-weight:600;font-size:13px} |
79 | 79 | .kv .v{font-family:var(--mono);font-size:13px;color:var(--muted)} |
| 80 | + .bsub{font-size:11px;font-weight:650;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:14px 0 6px} |
80 | 81 | .structure{text-align:center;margin:0 0 14px;background:#fff;border:1px solid var(--line);border-radius:8px;padding:6px} |
81 | 82 | .structure svg{max-width:100%;height:auto} |
82 | 83 | .structure:empty{display:none} |
@@ -281,26 +282,48 @@ <h2>Aroma</h2> |
281 | 282 | } |
282 | 283 |
|
283 | 284 | function renderBehavior(p){ |
284 | | - const pc = p.physchem||{}, sf = p.safety||{}; |
285 | | - const comp = pc.computed||{}, meas = pc.measured||{}, qual = pc.qualitative||{}; |
286 | | - const MEAS = ' <span class="tag measured">measured</span>'; |
287 | | - const rows = []; |
288 | | - if(typeof comp.mol_weight==='number') rows.push(['MW', comp.mol_weight+' g/mol']); |
289 | | - if(typeof comp.logP==='number') rows.push(['logP', comp.logP]); |
| 285 | + const pc=p.physchem||{}, sf=p.safety||{}, st=p.stability||{}, ch=p.chemesthesis||{}, lb=p.labeling||{}; |
| 286 | + const comp=pc.computed||{}, est=pc.estimate||{}, meas=pc.measured||{}, qual=pc.qualitative||{}; |
| 287 | + const MEAS=' <span class="tag measured">measured</span>', EST=' <span class="tag predicted">estimate</span>'; |
| 288 | + const kv = rows => '<div class="kv">'+rows.map(r=>`<div class="k">${r[0]}</div><div class="v">${r[1]}</div>`).join('')+'</div>'; |
| 289 | + const chips = (arr,style)=> '<div class="chips">'+arr.map(x=>`<span class="chip" ${style||''}>${x}</span>`).join('')+'</div>'; |
| 290 | + const WARN='style="background:#FBEDE9;color:#8A3A22;border-color:#E7C4B8"'; |
| 291 | + |
| 292 | + const rows=[]; |
| 293 | + if(typeof comp.mol_weight==='number') rows.push(['Molecular weight', comp.mol_weight+' g/mol']); |
| 294 | + if(typeof comp.logP==='number') rows.push(['logP (lipophilicity)', comp.logP]); |
| 295 | + if(typeof comp.tpsa==='number') rows.push(['Polar surface area', comp.tpsa+' Ų']); |
| 296 | + if(typeof comp.h_bond_donors==='number') rows.push(['H-bond donors / acceptors', comp.h_bond_donors+' / '+comp.h_bond_acceptors]); |
| 297 | + if(typeof comp.rotatable_bonds==='number') rows.push(['Rotatable bonds', comp.rotatable_bonds]); |
| 298 | + if(typeof est.water_solubility_logS==='number') rows.push(['Water solubility (logS)', est.water_solubility_logS+EST]); |
290 | 299 | if(typeof meas.boiling_point_c==='number'){ |
291 | | - const atP = (typeof meas.boiling_point_pressure_mmhg==='number') ? ` (at ${meas.boiling_point_pressure_mmhg} mmHg)` : ''; |
| 300 | + const atP=(typeof meas.boiling_point_pressure_mmhg==='number')?` (at ${meas.boiling_point_pressure_mmhg} mmHg)`:''; |
292 | 301 | rows.push(['Boiling point', meas.boiling_point_c+' °C'+atP+MEAS]); |
293 | 302 | } |
294 | 303 | if(qual.aroma_volatility) rows.push(['Volatility', qual.aroma_volatility]); |
295 | 304 | if(typeof meas.vapor_pressure_pa==='number') rows.push(['Vapor pressure', meas.vapor_pressure_pa+' Pa'+MEAS]); |
296 | | - if(sf.gras_status) rows.push(['Food-use status', sf.gras_status]); |
297 | | - if(sf.ttc_hint && sf.ttc_hint.preliminary_tier) rows.push(['TTC tier (prelim.)', sf.ttc_hint.preliminary_tier]); |
298 | | - let html = '<div class="kv">'+rows.map(r=>`<div class="k">${r[0]}</div><div class="v">${r[1]}</div>`).join('')+'</div>'; |
299 | | - const alerts = sf.structural_alerts||[]; |
300 | | - if(alerts.length) html += '<div class="chips">'+alerts.map(a=>`<span class="chip" style="background:#FBEDE9;color:#8A3A22;border-color:#E7C4B8">⚠ ${a}</span>`).join('')+'</div>'; |
301 | | - const tox = sf.tox_screen||{}; |
302 | | - if((p.applicability||{}).in_domain!==false && tox.available && (tox.flags||[]).length) html += '<div class="chips">'+tox.flags.map(f=>`<span class="chip" style="background:#FBEDE9;color:#8A3A22;border-color:#E7C4B8">⚠ tox-assay: ${f}</span>`).join('')+'</div>'; |
303 | | - html += '<div class="empty" style="font-size:12px">Defensive screen — flags for review, never a clearance.</div>'; |
| 305 | + const ions=(qual.ionizable_groups||[]).map(g=>`${g.group} (pKa≈${g.typical_pKa})`).join(', '); |
| 306 | + if(ions) rows.push(['Ionizable groups', ions]); |
| 307 | + let html = kv(rows); |
| 308 | + |
| 309 | + const cc=ch.classes||[]; |
| 310 | + if(cc.length) html += '<div class="bsub">Chemesthesis (trigeminal)</div>'+chips(cc,'style="background:var(--aroma);color:#fff;border-color:transparent"'); |
| 311 | + |
| 312 | + const sw=[...(st.oxidation_watch||[]).map(x=>'oxidation: '+x),...(st.hydrolysis_watch||[]).map(x=>'hydrolysis: '+x),...(st.photodegradation_watch||[]).map(x=>'photo: '+x)]; |
| 313 | + if(sw.length) html += '<div class="bsub">Stability watch</div>'+chips(sw); |
| 314 | + |
| 315 | + if(lb.eu_declarable_allergen) html += '<div class="bsub">Regulatory</div>'+chips(['EU declarable allergen'+(lb.allergen_name?': '+lb.allergen_name:'')],'style="background:#FFF6E6;border-color:#E8D38A;color:#7A5A12"'); |
| 316 | + |
| 317 | + html += '<div class="bsub">Safety (defensive, caution-only)</div>'; |
| 318 | + const srows=[]; |
| 319 | + if(sf.gras_status) srows.push(['Food-use status', sf.gras_status]); |
| 320 | + if(sf.ttc_hint && sf.ttc_hint.preliminary_tier) srows.push(['TTC tier (prelim.)', sf.ttc_hint.preliminary_tier]); |
| 321 | + if(srows.length) html += kv(srows); |
| 322 | + const alerts=sf.structural_alerts||[]; |
| 323 | + if(alerts.length) html += chips(alerts.map(a=>'⚠ '+a), WARN); |
| 324 | + const tox=sf.tox_screen||{}; |
| 325 | + if((p.applicability||{}).in_domain!==false && tox.available && (tox.flags||[]).length) html += chips(tox.flags.map(f=>'⚠ tox-assay: '+f), WARN); |
| 326 | + html += '<div class="empty" style="font-size:12px">'+(sf.disclaimer||'Defensive screen — flags for review, never a clearance.')+'</div>'; |
304 | 327 | $('behavior').innerHTML = html; |
305 | 328 | } |
306 | 329 |
|
|
0 commit comments