// Shared presentational primitives for the playground sections (MixPlayground // and the raw-messaging demo) so they share one look. Theme-neutral inline // styles (rgba greys read on light and dark Nextra themes), a per-section log // store, and an autoscrolling log panel. import React, { useCallback, useEffect, useRef, useState } from 'react'; export type Colour = 'green' | 'red' | 'orange' | 'gray' | undefined; export const COLOURS: Record = { green: '#16a34a', red: '#dc2626', orange: '#d97706', gray: '#9ca3af', }; export interface LogEntry { ts: string; msg: string; colour?: Colour; } // One append-only buffer per section, keyed by section name. Red entries mirror // to console.error so they sit alongside the Rust-side `[smolmix] ...` logs. export function useLogs() { const [store, setStore] = useState>({}); const log = useCallback((section: string, msg: string, colour?: Colour) => { const ts = new Date().toISOString().slice(11, 23); if (colour === 'red') console.error(`[smolmix-playground:${section}]`, msg); setStore((s) => ({ ...s, [section]: [...(s[section] ?? []), { ts, msg, colour }] })); }, []); const lines = useCallback((section: string) => store[section] ?? [], [store]); return { log, lines }; } export const box: React.CSSProperties = { border: '1px solid rgba(127,127,127,0.3)', borderRadius: 8, padding: '1rem', margin: '1rem 0', }; export const row: React.CSSProperties = { display: 'flex', gap: '0.5rem', alignItems: 'center', flexWrap: 'wrap', marginBottom: '0.5rem', }; export const btn: React.CSSProperties = { padding: '0.35rem 0.8rem', borderRadius: 6, border: '1px solid rgba(127,127,127,0.4)', background: 'transparent', cursor: 'pointer', fontSize: 14, }; export const input: React.CSSProperties = { padding: '0.35rem 0.6rem', borderRadius: 6, border: '1px solid rgba(127,127,127,0.4)', background: 'transparent', fontSize: 14, flex: '1 1 14rem', minWidth: 0, }; export const num: React.CSSProperties = { ...input, flex: '0 0 5rem' }; export const legend: React.CSSProperties = { fontWeight: 600, marginBottom: '0.6rem' }; export const sub: React.CSSProperties = { fontSize: 12, opacity: 0.65 }; export function Button(props: React.ButtonHTMLAttributes) { return (