# Prompt — Rich parameter help (click-to-open explainers with diagrams)
Upgrade the "?" help for the 8 Parameters in the Lab from a one-line tooltip into a rich, click-to-open explainer (text + examples + diagrams), aimed at a non-expert reviewer. Presentation/read-only — no logic changes. Reuse the calm theme (bg #FAFAF7, card #FCFBF8, ink #23303A, muted #6E7F8C, border #ECEAE4, accent #3A6B7E, highlight #BC6B2E) and the existing monospace for gene IDs.
## Interaction
- Build ONE reusable component `` so wording can't drift. The "?" button:
- on **hover/focus**, shows the SHORT one-liner (a small tooltip — keep the current text as the short summary);
- on **click**, opens a MODAL dialog with the DETAILED content (text + any diagram).
- Modal: `role="dialog"`, `aria-modal="true"`, labelled by its title; ~640px wide on desktop, full-width with padding and vertical scroll on narrow screens; close on X, Esc, and backdrop click; return focus to the "?" button on close. Calm card styling (border #ECEAE4, fill #FCFBF8, ~14px radius, generous padding). Headings in #23303A, body readable (~14px), muted captions #6E7F8C.
- Apply this ONLY to the 8 Parameters "?" icons. Leave other "?" icons elsewhere (objectives, run id/status) as the existing InfoTip — do not touch them.
- Diagrams are embedded as small SVG components, `width:100%; height:auto` (viewBox scales). Each diagram is used once, in its own parameter.
## Detailed content per parameter
For each: SHORT = hover text; DETAILED = modal body (use the wording below; render line breaks and bullet/example blocks cleanly).
### Generations
SHORT: "How many rounds of 'keep the best, breed, mutate' the engine runs. More rounds refine further, but take longer."
DETAILED:
- What it is: one "generation" is a single round of the engine's loop — score every program, keep the best, then breed and mutate them into the next batch. Generations is how many rounds it runs.
- How it works: the engine starts with random programs (mostly poor) and each round nudges the population toward better ones — like selective breeding.
- More vs fewer: more rounds refine the winners further, but with diminishing returns once it has converged. The harder part is usually *discovering* the right genes in the first place (driven by Population and mutation), not polishing — so extra generations help less once the curve flattens.
- Typical: 30–60.
- Small inline illustration: a 4-step loop "random programs → score each → keep the best → breed & mutate → (back to score)", calm style, arrows; the loop arrow labelled "× Generations".
### Population
SHORT: "How many candidate programs compete in each round. A 'program' is a small pipeline built by composing the DSL operators (Select → Reduce → Fit) over the gene data. More programs explores more options, but is slower."
DETAILED:
- What it is: how many candidate programs compete each round. A "program" is a small pipeline built from the DSL operators — Select (pick genes) → Reduce (average them into one score) → Fit (use the score to separate the groups).
- Why it matters: a bigger population samples more genes and structures each round, so it's the main lever for *discovery* — finding the right genes at all. Generations then refine what was found.
- Example — three random programs in a population (opaque gene IDs, monospace):
- `average(g04823, g11201, g00917) → score`
- `average(g15522, g02013) − average(g08840, g00231) → score`
- `average(g07788, g13002, g05340) → score`
- More vs fewer: more explores more options, but each round is slower.
- Typical: 150–300.
### Genes / set
SHORT: "The most genes a single score may use. Smaller keeps programs simple and readable."
DETAILED:
- What it is: a "set" is the group of genes averaged together into a single score. Genes/set is the maximum size of that group.
- Example: `Select(g05347, g00048, g06271) → average → one score` (uses 3; the cap might be 8).
- Smaller vs larger: smaller keeps each score simple and readable; larger lets one score blend more genes.
- It pairs with Max sets: Genes/set is the *width* of each group; Max sets is *how many* groups.
### Max sets
SHORT: "How many separate gene-scores a program may combine (1 or 2). 2 lets it build a small 'score made of scores'."
DETAILED:
- What it is: how many *separate* gene groups a program may build and then combine (1 or 2). They use different genes — not the same ones reused.
- Example (2 sets):
- Set 1: `average(g05347, g00048, g06271) → scoreA`
- Set 2: `average(g15522, g02013) → scoreB`
- Combine: `scoreA − scoreB → final score`
- Why two: to capture a *contrast* — e.g. one group that's low in MSI-H and one that's high; the gap between them can separate better than either alone (like "repair activity minus immune activity"). One set can't express that; two can.
- If one group is enough, the engine can still use 1.
- Diagram (small): two short chains — `matrix → Select → Reduce → scoreA` and `matrix → Select → Reduce → scoreB` — both feeding a `Combine (sub)` node, then a final `score`. Verbs = accent-bordered boxes, scores = amber pills, calm style.
### λ (size penalty)
SHORT: "How hard the engine is penalised for using more genes. Higher pushes it toward fewer genes (simpler answers)."
DETAILED:
- What it is: a "price per gene" that discourages bloated programs. Every program is graded on a single number:
- `fitness = separation − λ × (number of genes)`
- so the engine ranks by accuracy *minus* a size tax.
- The key idea — λ is the admission price each gene must beat: with λ = 0.005, a gene is only worth keeping if it adds more than 0.005 of separation.
- Worked example: a 3-gene program scores 0.90 → net 0.90 − 0.015 = 0.885. Add a 4th gene that lifts it to 0.903 (only +0.003) → net 0.883, *lower*, so it's rejected. A 4th gene that lifts it to 0.91 (+0.01) → net 0.890, *higher*, so it's kept.
- Turning the knob: λ = 0 → genes free → bloated, overfit programs. λ small (0.005) → trims useless genes, keeps useful ones. λ large → very lean programs, but may drop useful genes.
- Diagram: the accuracy-vs-genes trade-off (embed the SVG in "DIAGRAMS" below).
### Seed
SHORT: "The starting point for the engine's randomness. The same seed reproduces the exact same run; change it to see a different run."
DETAILED:
- Why randomness: the space of possible programs is astronomically large (picking even 8 genes out of 20,000 is ~10^29 combinations), so the engine can't try them all — it explores with randomness: random starting programs, random mutations, random breeding.
- What the seed is: computers don't make true randomness; a formula generates a sequence of numbers, each from the previous one. The seed is the *starting number* fed into that formula — everything random flows from it. (One common formula: `next = (1664525 × current + 1013904223) mod 2³²`; with seed 42 the first value is 1,083,814,273, then mapped onto a gene position.)
- What it does: think of the seed as one fixed list of dice rolls used in order across the whole run — early rolls pick the starting genes, later rolls drive mutations. Same seed → same list → identical run. Different seed → a different list → a different run.
- Why vary it: because the search has luck in it, run a few seeds (42, 7, 123) and see whether the same genes keep appearing — that tells you a finding is real, not a fluke.
- Diagram: the seed-as-a-fixed-list-of-dice-rolls (embed the SVG below).
### Permutations
SHORT: "How many times we re-run on deliberately scrambled labels to check the result isn't luck. The real result must beat these chance runs (that's the 'permutation p')."
DETAILED:
- What it checks: whether the winning score is real signal or could have come up by luck. The engine searches so hard that some programs separate the groups well by pure coincidence, so a high score alone isn't proof.
- How it works: shuffle the MSI-H / MSS labels across patients at random — this breaks any real gene↔label link, creating a "no-signal world". Re-score there: any score above 0.5 is pure chance. Repeat many times (this knob = how many) to build a picture of what luck looks like.
- Reading it: permutation p = the fraction of shuffled runs that scored ≥ the real winner. p = 0.005 means only 0.5% of chance runs matched it → very unlikely a fluke. Conventionally p < 0.05 is the "unlikely to be luck" line.
- The knob: with 200 shuffles the smallest p you can report is about 1/200 ≈ 0.005; more permutations give a finer, more trustworthy p.
- Diagram: the "luck pile" vs the real result (embed the SVG below).
### Prefilter top-N
SHORT: "By default the engine searches all ~20,000 genes, so nothing is pre-excluded. Turning this on narrows to the N most promising genes first — faster, but it can drop a real gene that only shows signal in combination."
DETAILED:
- Default (off): the engine searches all ~20,000 genes, so nothing is pre-excluded — the most honest setting for a discovery demo.
- Turning it on: first narrows to the N genes most individually associated with the target (computed name-blind, on the training split only), then searches within that shortlist. Faster, because the space is ~10× smaller.
- The trade-off: speed and focus vs completeness. A univariate shortlist can drop a gene that only matters *in combination* (no signal on its own), and it sets a ceiling — if a gene isn't in the shortlist, the engine can never find it.
- Small inline illustration (funnel): "~20,000 genes → keep the N most individually associated → search within N", with a muted note "off by default = no funnel".
## DIAGRAMS (embed verbatim; wrap each so it scales: width:100%, height auto)
### Seed diagram
```svg
```
### λ trade-off diagram
```svg
```
### Permutations diagram
```svg
```
## "How these parameters relate" chart
- Keep the neat (HTML/flex, wrapping) version already built.
- Enhancement: make each parameter NAME in the chart's pills a button that opens that parameter's ParamHelp modal (same content). So the chart becomes a map into the detailed help.
## Constraints
- Presentation-only; do not change any GP logic or other tooltips.
- One reusable `ParamHelp` component + one reusable modal; diagrams are separate small components used once each.
- Accessible: "?" is a real button (keyboard-activatable); modal has role/aria, Esc + backdrop + X close, focus trap and focus return.
- Responsive: modal scrolls on small screens; diagrams scale to container width.
- These are Client Components ("use client") since they manage open/close state.