"use client";
import { useId, useRef, useState } from "react";
import { ParamKey } from "./paramHelpContent";
import { useParamHelp } from "./ParamHelpProvider";
/**
* "How these parameters relate" — a collapsed disclosure with a clean
* HTML/flex pipeline diagram inside. Presentation only.
*
* Centered single-column layout, max-width 460px, width 100% — never
* wider than the panel, never overflowing. Each step is a neutral box;
* between consecutive boxes sits a coloured "pill" naming the
* parameter(s) that govern that transition, with a calm ↓ between
* pill and the next box.
*/
export default function ParameterFlow() {
const [open, setOpen] = useState(false);
const panelId = useId();
return (
{open && (
)}
);
}
// ---------- diagram model ------------------------------------------------
type PillKind = "SPACE" | "EFFORT" | "VALIDATION";
interface Box {
title: string;
sub?: string;
amber?: boolean;
}
/** A pill is a list of inline fragments: either a plain string or a
* {bold} fragment so we can highlight just the parameter name. The
* bold fragments carry an optional ``paramKey`` — when present, that
* fragment is rendered as a button that opens the ParamHelp modal. */
type Frag = string | { bold: string; paramKey?: ParamKey };
interface Pill {
kind: PillKind;
/** Optional small text prefix (e.g. "↻ " for the loop pill). */
prefix?: string;
fragments: Frag[];
}
const PILL_STYLES: Record = {
SPACE: { bg: "#E7EFF1", fg: "#2C5563" },
EFFORT: { bg: "#F6ECE0", fg: "#8A4E20" },
VALIDATION: { bg: "#ECEBE6", fg: "#5A6670" },
};
const BOXES: Box[] = [
{ title: "~20,000 genes", sub: "every gene measured" },
{ title: "Gene pool — N genes", sub: "the shortlist the engine draws from" },
{ title: "One program", sub: "Select → Reduce → Fit" },
{ title: "One generation", sub: "every program scored & ranked" },
{ title: "Winning program" },
{ title: "permutation p", sub: "could this be luck?", amber: true },
];
const PILLS: Pill[] = [
{
kind: "SPACE",
fragments: [
{ bold: "Prefilter top-N", paramKey: "prefilter_n" },
" — keep the N most promising genes (off by default = all ~20,000)",
],
},
{
kind: "SPACE",
fragments: [
{ bold: "Max sets", paramKey: "max_sets" },
" × ",
{ bold: "Genes/set", paramKey: "genes_per_set" },
" — pick 1–2 sets, each ≤ G genes",
],
},
{
kind: "EFFORT",
fragments: [
{ bold: "Population", paramKey: "population" },
" — programs compete each round · ",
{ bold: "λ", paramKey: "lambda" },
" — taxes extra genes",
],
},
{
kind: "EFFORT",
prefix: "↻ ",
fragments: [
"× ",
{ bold: "Generations", paramKey: "generations" },
" — breed the best, repeat · ",
{ bold: "Seed", paramKey: "seed" },
" — fixes the randomness",
],
},
{
kind: "VALIDATION",
fragments: [
{ bold: "Permutations", paramKey: "permutations" },
" — re-run on N shuffled-label sets",
],
},
];
// ---------- render -------------------------------------------------------
function Pipeline() {
return (