'use client' import { useMemo } from 'react' import katex from 'katex' import 'katex/dist/katex.min.css' import { intentColor } from '@/lib/interactive-demo/intent-colors' import type { IntentId } from '@/lib/interactive-demo/types' import { useDarkMode } from '@/components/interactive-demo/demo-speak' import { cn } from '@/lib/utils' export function SimKaTeX({ tex, className }: { tex: string; className?: string }) { const html = useMemo(() => { try { // output:'html' avoids MathML annotation leaking as visible "mathrm{…}" in flex layouts return katex.renderToString(tex, { throwOnError: false, output: 'html' }) } catch { return tex } }, [tex]) return ( ) } export function SimSlider({ symbol, label, unit, min, max, step, value, intent, onChange, }: { symbol: string label: string unit?: string min: number max: number step: number value: number intent?: IntentId onChange: (v: number) => void }) { const dark = useDarkMode() const accent = intentColor(intent, dark) return ( ) } export function SimOutputCard({ symbol, label, value, unit, intent, digits = 2, }: { symbol: string label: string value: number unit?: string intent?: IntentId digits?: number }) { const dark = useDarkMode() const accent = intentColor(intent, dark) const finite = Number.isFinite(value) return (
{label}
{finite ? value.toFixed(digits) : '—'} {finite && unit ? ` ${unit}` : ''}
) } /** Small section heading inside a simulator card. */ export function SimHeading({ children, className, }: { children: React.ReactNode className?: string }) { return (

{children}

) }