import Link from 'next/link'; import type { ReactNode } from 'react'; import { cn } from '@/lib/format'; export interface ExplainerRow { /** component name, e.g. "Sales per month" */ label: ReactNode; /** the asset's actual input, or null when RareIndex does not have it (rendered "not available") */ value: ReactNode | null; /** weight in the formula, e.g. "40 %" */ weight?: ReactNode; /** how the input maps to 0–1, e.g. "30 / month → 1" */ note?: ReactNode; } /** * §204 "Explain every score": a native
(no client JS) that opens the components of a score * with the asset's real inputs and links to the matching Methodology section. Inputs RareIndex does * not store are shown as "not available" — a component is never filled with a guessed value. */ export function ScoreExplainer({ summary, title, anchor, formula, rows, footnote, className }: { summary?: ReactNode; title: ReactNode; anchor: string; formula?: ReactNode; rows: ExplainerRow[]; footnote?: ReactNode; className?: string }) { return (
▸ {summary ?? 'How is this computed?'}

{title}

Methodology →
{formula ?

{formula}

: null} {rows.some((r) => r.weight !== undefined) ? : null} {rows.some((r) => r.note !== undefined) ? : null} {rows.map((r, i) => ( {rows.some((x) => x.weight !== undefined) ? : null} {rows.some((x) => x.note !== undefined) ? : null} ))}
Component This assetWeightScale
{r.label} {r.value === null || r.value === undefined ? not available : r.value}{r.weight ?? ''}{r.note ?? ''}
{footnote ?

{footnote}

: null}
); }