# instructions.py
from dash import html, dcc
def build_instructions_layout() -> html.Div:
"""
~1-page Quick Start Guide layout for the Extraction Condition Comparison Tool.
Intended audience: analytical chemists & toxicologists.
"""
page_style = {
"fontFamily": "Arial, Helvetica, sans-serif",
"padding": "20px",
}
card_style = {
"maxWidth": "950px",
"margin": "0 auto",
"padding": "18px 22px",
"border": "1px solid #e5e5e5",
"borderRadius": "8px",
"boxShadow": "0 1px 4px rgba(0,0,0,0.06)",
"backgroundColor": "white",
"lineHeight": "1.45",
}
h1_style = {"margin": "0 0 10px 0", "fontSize": "28px"}
h2_style = {"margin": "18px 0 8px 0", "fontSize": "18px"}
h3_style = {"margin": "12px 0 6px 0", "fontSize": "15px"}
p_style = {"margin": "8px 0", "color": "#333"}
small_style = {"margin": "6px 0", "color": "#555", "fontSize": "13px"}
ul_style = {"margin": "8px 0 8px 22px"}
li_style = {"marginBottom": "6px"}
callout_style = {
"marginTop": "10px",
"padding": "10px 12px",
"borderLeft": "4px solid #999",
"backgroundColor": "#fafafa",
"color": "#333",
"fontSize": "13.5px",
}
table_header_style = {
"border": "1px solid #ccc",
"padding": "5px 8px",
"textAlign": "left",
"backgroundColor": "#f2f2f2",
}
table_cell_style = {
"border": "1px solid #ccc",
"padding": "5px 8px",
"textAlign": "left",
}
return html.Div(
style=page_style,
children=[
html.Div(
style=card_style,
children=[
# ---------------------------------------------------------
# Header
# ---------------------------------------------------------
html.H1("Quick Start Guide", style=h1_style),
html.P(
"Use this tool to compare predicted fractional release of "
"boundary chemicals from a polymer under two scenarios "
"(Condition #1 vs Condition #2). Results can be viewed either "
"as predicted fractional release for each condition or as the "
"ratio of Condition 1 to Condition 2.",
style=p_style,
),
html.P(
["Return to the tool: ", dcc.Link("Main page", href="/")],
style=small_style,
),
# ---------------------------------------------------------
# 1. Polymer properties
# ---------------------------------------------------------
html.H2("1) Choose polymer properties", style=h2_style),
html.P(
"Start in the “Polymer component” section. These inputs define "
"the material and geometry used in the transport calculations.",
style=p_style,
),
html.Ul(
style=ul_style,
children=[
html.Li(
[
html.B("Matrix: "),
"Select the polymer type (e.g., PP).",
],
style=li_style,
),
html.Li(
[
html.B(
"Tg (°C), Crystallinity (%), Density (g/cm³): "
),
"Enter polymer properties using the best available "
"values. Defaults may be useful for screening when "
"measured values are unavailable.",
],
style=li_style,
),
html.Li(
[
html.B("Volume (cm³) and Surface area (cm²): "),
"Define the polymer amount and exposed area for the "
"scenario being evaluated.",
],
style=li_style,
),
],
),
# ---------------------------------------------------------
# 2. Solutes
# ---------------------------------------------------------
html.H2("2) Choose solutes", style=h2_style),
html.P(
"Select the set of chemicals to evaluate in the “Solutes” section. "
"You can use the default representative boundary chemicals or upload "
"a user-defined Excel file.",
style=p_style,
),
html.Ul(
style=ul_style,
children=[
html.Li(
[
html.B("Default boundary chemicals: "),
"Uses the predefined set of representative chemicals included "
"with the tool.",
],
style=li_style,
),
html.Li(
[
html.B("User-defined chemicals: "),
"Upload an Excel file containing the chemicals you want to evaluate.",
],
style=li_style,
),
],
),
html.Div(
style=callout_style,
children=[
html.B("Required Excel columns"),
html.Br(),
"A user-defined Excel file must contain the following three columns, "
"with the column names written exactly as shown:",
html.Br(),
html.Br(),
html.Table(
[
html.Thead(
html.Tr(
[
html.Th("CASRN", style=table_header_style),
html.Th("MW", style=table_header_style),
html.Th("LogP", style=table_header_style),
]
)
),
html.Tbody(
[
html.Tr(
[
html.Td(
"Chemical Abstracts Service Registry Number",
style=table_cell_style,
),
html.Td(
"Molecular weight",
style=table_cell_style,
),
html.Td(
"Octanol/water partition coefficient (log10)",
style=table_cell_style,
),
]
)
]
),
],
style={
"borderCollapse": "collapse",
"width": "100%",
"marginTop": "6px",
"marginBottom": "6px",
},
),
html.Br(),
"The MW and LogP columns must contain numeric values. "
"LogP values greater than 10 are limited to 10 for use in the model.",
],
),
html.P(
"After a valid file is uploaded, the tool will use the uploaded chemical "
"properties in place of the default boundary-chemical set when Calculate "
"is selected.",
style=small_style,
),
# ---------------------------------------------------------
# 2. Conditions
# ---------------------------------------------------------
html.H2(
"3) Define Condition #1 and Condition #2",
style=h2_style,
),
html.P(
"Each condition can represent either an extraction experiment "
"(in vitro) or an in vivo exposure case.",
style=p_style,
),
html.Ul(
style=ul_style,
children=[
html.Li(
[
html.B("In vitro: "),
"Enables solvent and extraction settings including "
"solvent, solvent volume, swelling ratio (final mass "
"divided by initial mass), extraction temperature, "
"and iterations. Use this mode to mimic or design "
"extraction conditions.",
],
style=li_style,
),
html.Li(
[
html.B("In vivo (conservative): "),
"Uses a screening-level release assumption that may "
"produce higher predicted release.",
],
style=li_style,
),
html.Li(
[
html.B("In vivo (representative tissue): "),
"Represents tissue-limited release using literature-based thermodynamic "
"properties considered representative of typical soft tissue and relatively "
"slow tissue-diffusion properties associated with barrier-like behavior. "
"This scenario is intended to represent tissue that may encapsulate an implanted device."
"The selected parameterization was also found to be broadly consistent with "
"the limited published clinical leaching data available.",
],
style=li_style,
),
],
),
html.P(
"For all modes, set “Extraction time (h)” to match the scenario "
"duration of interest.",
style=small_style,
),
html.Div(
style=callout_style,
children=[
html.B("Note on swelling uncertainty"),
html.Br(),
"Treat the swelling ratio as an uncertain experimental "
"input. For low-swelling or highly crystalline polymers, "
"small mass-measurement differences can cause large relative "
"uncertainty, and modest swelling may materially affect "
"predicted release. Consider sensitivity checks using "
"plausible lower and upper swelling values, and document "
"replicate variability and measurement assumptions.",
],
),
# ---------------------------------------------------------
# 3. Monte Carlo
# ---------------------------------------------------------
html.H2("4) Monte Carlo settings", style=h2_style),
html.P(
"Set the number of samples under “Monte Carlo → Samples” and "
"choose how the comparison should be displayed.",
style=p_style,
),
html.Ul(
style=ul_style,
children=[
html.Li(
[
html.B("Samples: "),
"500–2000 is generally suitable for routine "
"comparisons.",
],
style=li_style,
),
html.Li(
[
html.B("Larger sample sizes: "),
"More than 5000 samples can provide more stable "
"estimates of the median and IQR, but calculations "
"will take longer.",
],
style=li_style,
),
html.Li(
[
html.B("Absolute: "),
"Displays predicted fractional release for Condition "
"1 and Condition 2 separately.",
],
style=li_style,
),
html.Li(
[
html.B("Ratio: "),
"Displays the ratio of predicted fractional release "
"for Condition 1 relative to Condition 2 (C1 / C2).",
],
style=li_style,
),
],
),
# ---------------------------------------------------------
# 4. Results
# ---------------------------------------------------------
html.H2("5) Run and interpret results", style=h2_style),
html.P(
[
"Click ",
html.B("Calculate"),
". Results are shown for each representative boundary "
"chemical (CASRN).",
],
style=p_style,
),
# Absolute
html.H3("Absolute comparison", style=h3_style),
html.P(
"When “Absolute” is selected, the chart displays predicted "
"fractional release for both conditions.",
style=p_style,
),
html.Ul(
style=ul_style,
children=[
html.Li(
[
html.B("Light red bars: "),
"Condition 1.",
],
style=li_style,
),
html.Li(
[
html.B("Light blue bars: "),
"Condition 2.",
],
style=li_style,
),
html.Li(
[
html.B("Bar height: "),
"Median predicted fractional release from the "
"Monte Carlo distribution.",
],
style=li_style,
),
html.Li(
[
html.B("Error bars: "),
"IQR (25th to 75th percentile) of the Monte Carlo "
"distribution.",
],
style=li_style,
),
],
),
# Ratio
html.H3("Ratio comparison", style=h3_style),
html.P(
"When “Ratio” is selected, the tool calculates the C1 / C2 "
"ratio for the Monte Carlo realizations and summarizes the "
"resulting ratio distribution.",
style=p_style,
),
html.Ul(
style=ul_style,
children=[
html.Li(
[
html.B("Ratio = 1: "),
"Condition 1 and Condition 2 predict the same "
"fractional release.",
],
style=li_style,
),
html.Li(
[
html.B("Ratio > 1: "),
"Condition 1 predicts greater fractional release "
"than Condition 2.",
],
style=li_style,
),
html.Li(
[
html.B("Ratio < 1: "),
"Condition 1 predicts lower fractional release "
"than Condition 2.",
],
style=li_style,
),
html.Li(
[
html.B("Bar height: "),
"Median of the C1 / C2 Monte Carlo ratio "
"distribution.",
],
style=li_style,
),
html.Li(
[
html.B("Error bars: "),
"IQR (25th to 75th percentile) of the C1 / C2 "
"ratio distribution.",
],
style=li_style,
),
html.Li(
[
html.B("Dashed horizontal line at 1: "),
"Reference indicating equal predicted release for "
"the two conditions.",
],
style=li_style,
),
],
),
html.Div(
style=callout_style,
children=[
html.B("Interpreting the log scale"),
html.Br(),
"Both Absolute and Ratio plots use a logarithmic y-axis. "
"Equal vertical distances therefore represent multiplicative "
"rather than additive differences. For example, on the Ratio "
"plot, values of 0.5 and 2 represent reciprocal two-fold "
"differences from a ratio of 1.",
],
),
# ---------------------------------------------------------
# Chemical list interpretation
# ---------------------------------------------------------
html.Div(
style=callout_style,
children=[
html.B("How to interpret the chemical list"),
html.Br(),
"The default CASRNs provided are a representative boundary set selected "
"to span the range of molecular weight and hydrophobicity "
"(logP) expected in a chemical characterization study. "
"Because this set covers the anticipated chemical space, "
"tool-supported conclusions (for example, which condition is "
"more or less conservative) are intended to be applicable "
"broadly to chemicals expected in that study context.",
],
),
# ---------------------------------------------------------
# Troubleshooting
# ---------------------------------------------------------
html.H2("Common tips & troubleshooting", style=h2_style),
html.Ul(
style=ul_style,
children=[
html.Li(
"For test articles with multiple components comprised "
"of different polymers, run the tool separately for each "
"component.",
style=li_style,
),
html.Li(
"If in vitro fields appear disabled, ensure the "
"condition mode is set to “In vitro”.",
style=li_style,
),
html.Li(
"If results look unexpected, double-check units "
"(cm³, cm², °C, hours) and polymer geometry inputs.",
style=li_style,
),
html.Li(
"Use the Absolute view to examine predicted release for "
"each condition and the Ratio view to directly assess "
"the magnitude and direction of the difference between "
"Condition 1 and Condition 2.",
style=li_style,
),
html.Li(
"When using the Ratio view, very large or very small "
"ratios can span several orders of magnitude. Use the "
"logarithmic y-axis and the reference line at C1 / C2 = 1 "
"when interpreting these comparisons.",
style=li_style,
),
html.Li(
"If you need a defensible justification, document the "
"polymer geometry, exposure duration, and rationale for "
"choosing in vitro versus in vivo modes.",
style=li_style,
),
],
),
html.Hr(style={"margin": "16px 0"}),
html.P(
"Note: Outputs are model-based predictions intended to support "
"comparisons and study design. Interpret results alongside "
"analytical data, scenario context, and uncertainty "
"considerations.",
style=small_style,
),
],
)
],
)