// TechniqueDetail — full guide panel function TechniqueDetail({ technique, onClose, inCart, onToggleCart, ctx, isMobile }) { const [tab, setTab] = React.useState('overview'); const [proposalLen, setProposalLen] = React.useState('s80'); const c = technique.color || COLORS.indigo[600]; const s = technique.sections; const p = technique.proposal; const extras = window.PROPOSAL_EXTRAS ? window.PROPOSAL_EXTRAS[technique.id] : null; const fill = txt => window.fillProposalTokens ? window.fillProposalTokens(txt, ctx) : txt; const tabs = [ { id:'overview', label:'Overview' }, { id:'questionnaire', label:'Questionnaire' }, { id:'data', label:'Sample Data' }, { id:'analysis', label:'Analysis' }, { id:'decisions', label:'Decisions' }, { id:'proposal', label:'Proposal' }, ]; return (
{/* Header */}
{/* On mobile the detail replaces the list entirely, so it needs a way back */} {isMobile && onClose && ( )}
{technique.icon}

{technique.name}

{technique.tagline}
{onClose && !isMobile && ( )}
{/* Tags row */}
{(technique.tags.businessProblems||[]).slice(0,5).map((t,i) => )}
{/* Scrollable body */}
{/* OVERVIEW TAB */} {tab === 'overview' && (
What It Is

{s.whatItIs}

When to Use
    {(s.whenToUse||[]).map((item,i) => (
  • {item}
  • ))}
When Not to Use
    {(s.whenNotToUse||[]).map((item,i) => (
  • {item}
  • ))}
Business Questions It Answers
{(s.businessQuestions||[]).map((q,i) => (
Q {q}
))}
Ideal Problem Statements
{(s.idealProblemStatements||[]).map((ps,i) => (
"{ps}"
))}
Input Data Required
REQUIRED
{(s.inputData?.required||[]).map((item,i) => (
{item}
))}
{(s.inputData?.optional||[]).length > 0 && (
OPTIONAL / ENHANCES
{(s.inputData?.optional||[]).map((item,i) => (
+ {item}
))}
)}
Caveats & Assumptions
{(s.caveats||[]).map((item,i) => (
{item}
))}
{technique.alternatives?.length > 0 && ( <> Use This Instead Of…
{technique.alternatives.map((alt,i) => (
{alt.technique}
{alt.reason}
))}
)}
)} {/* QUESTIONNAIRE TAB */} {tab === 'questionnaire' && s.questionnaire && (
Question Stem

"{s.questionnaire.stem}"

Sample Task / Question Format
{s.questionnaire.sampleTask}
Variations by Use Case {(s.questionnaire.variations||[]).map((v,i) => (
{v}
))}
Modifiable Parts {(s.questionnaire.modifiableParts||[]).map((m,i) => (
{m}
))}
Healthcare / Pharma Adaptation Notes
{s.questionnaire.healthcareAdaptation}
)} {/* SAMPLE DATA TAB */} {tab === 'data' && s.sampleData && (
Note: All data below is fictional and for illustrative purposes only. It does not represent any real study, product, or organisation.
Study Description

{s.sampleData.description}

{/* Conjoint-specific */} {s.sampleData.table && technique.id === 'conjoint' && ( <> Utility Scores (Part-Worth Estimates) [r.attribute, r.level, 0 ? COLORS.green[600] : COLORS.rose[600] }}> {r.utility > 0 ? '+' : ''}{r.utility} ])} />
Relative Attribute Importance )} {/* MaxDiff-specific */} {s.sampleData.table && technique.id === 'maxdiff' && ( <> MaxDiff Importance Scores (0–100 scale) ({ ...r, score: r.score })) .sort((a,b) => b.score - a.score)} valueKey="score" labelKey="item" maxValue={100} /> )} {/* TURF-specific */} {s.sampleData.table && technique.id === 'turf' && ( <> Reach Curve — Unduplicated Reach by Bundle Size ({ label: r.bundle, reach: r.reach }))} valueKey="reach" labelKey="label" maxValue={100} unit="%" />
[r.bundle, r.messages.join(', '), `${r.reach}%`])} />
)} {/* Van Westendorp-specific */} {s.sampleData.keyPoints && technique.id === 'vanwestendorp' && ( <> Key Price Points
{s.sampleData.keyPoints.map((kp,i) => (
{kp.value}
{kp.label}
{kp.description}
))}
)} {/* KDA-specific */} {s.sampleData.table && technique.id === 'keydriver' && ( <> Driver Importance vs Performance { const priority = r.derivedImportance >= 20 && r.performance < 5 ? '🔴 High priority' : r.derivedImportance >= 20 ? '🟡 Defend strength' : r.performance >= 5.5 ? '🟢 Low priority' : '⚪ Monitor'; return [r.driver, `${r.derivedImportance}%`, r.performance, priority]; })} /> )} {/* Cluster-specific */} {s.sampleData.table && technique.id === 'cluster' && ( <> Segment Solution (4 Clusters)
{s.sampleData.table.map((seg,i) => (
{seg.segment}
{seg.profile}
))}
)} {/* Logistic-specific */} {s.sampleData.table && technique.id === 'logistic' && ( <> Model Output — Odds Ratios [ r.predictor, {r.OR}, r.CI, r.pValue, parseFloat(r.pValue) < 0.05 || r.pValue === '<0.001' ? : ])} /> )} {/* CHAID-specific */} {s.sampleData.tree && technique.id === 'chaid' && ( <> Decision Tree Path Summary
{s.sampleData.tree.map((node,i) => (
{i > 0 && } Split on: {node.variable}
Split: {node.split}
High group: {node.adoptionHigh}% adoption Low group: {node.adoptionLow}% adoption
))}
)} How to Interpret These Results
{s.interpretation}
)} {/* ANALYSIS TAB */} {tab === 'analysis' && (
Step-by-Step Analysis Process
{(s.analysisProcess||[]).map((step,i) => ( ))}
Outputs Delivered to Client
{(s.outputs||[]).map((output,i) => (
{output}
))}
)} {/* DECISIONS TAB */} {tab === 'decisions' && (
Interpretation Guide
{s.interpretation}
Business Decisions Enabled
{(s.businessDecisions||[]).map((d,i) => (
{i+1}
{d}
))}
{technique.alternatives?.length > 0 && ( <> Method Comparison Guidance {technique.alternatives.map((alt,i) => (
vs {alt.technique}
{alt.reason}
))} )}
)} {/* PROPOSAL TAB */} {tab === 'proposal' && (
{/* Add to builder banner */} {onToggleCart && (
{inCart ? <>Added to your proposal. Open the Proposal Builder to assemble a client-ready document. : <>Build a client-ready proposal — add this method and combine it with others.}
)} {/* Sample size + timeline */} {extras && (
Sample Size Guidance
{extras.sampleSize.recommended}
RECOMMENDED
{extras.sampleSize.min}
MINIMUM
{extras.sampleSize.note}
Indicative Timeline · ~{extras.timeline.reduce((s,p)=>s+p.weeks,0)} weeks
{extras.timeline.map((p,i) => { const total = extras.timeline.reduce((s,x)=>s+x.weeks,0); return (
{p.weeks} wk
{p.phase}
); })}
Fieldwork: {extras.fieldwork}
)} Proposal-Ready Text {ctx && (ctx.productName || ctx.indication) ? '· auto-filled with your project context' : ''}
{[ { id:'s30', label:'30-word' }, { id:'s80', label:'80-word' }, { id:'s150', label:'150-word' }, { id:'full', label:'Full Method' }, ].map(opt => ( ))}
{fill(p[proposalLen])}
Scope of Work
{fill(p.scopeOfWork)}
Why This vs Alternatives
{p.whyThisVsAlternatives}
Deliverables List {(p.deliverables||[]).map((d,i) => (
{d}
))}
Assumptions {(p.assumptions||[]).map((a,i) => (
• {a}
))}
Risks / Dependencies {(p.risks||[]).map((r,i) => (
⚠ {r}
))}
)}
); } Object.assign(window, { TechniqueDetail });