// Direction A — Storybook Sketch
// Cream paper, hand-drawn wobbly borders (SVG turbulence filter), crayon
// scribble accents. Patrick Hand + Caveat. Drifting sketched leaves.
const sketchSubjects = {
math: { label: 'Math', ink: '#D9602B', fill: '#FFE6D2' },
words: { label: 'Words', ink: '#3E8E5A', fill: '#DDF0DF' },
science: { label: 'Science', ink: '#2E5C8A', fill: '#D6E5F2' },
world: { label: 'World', ink: '#B0431F', fill: '#F4D7C5' },
music: { label: 'Music', ink: '#8A4FB3', fill: '#E8D9F2' },
code: { label: 'Code', ink: '#B8861A', fill: '#F4E6BD' },
focus: { label: 'Focus', ink: '#1F7A7A', fill: '#CFEAEA' },
};
// Tiny crayon doodles — one per subject. Kept abstract on purpose: an
// acorn for math, a quill for words, a beaker for science, a globe for
// world, a music note, a bracket for code.
const sketchDoodles = {
math: (
),
words: (
),
science: (
),
world: (
),
music: (
),
code: (
),
focus: (
),
};
function SketchLogo() {
return (
games
);
}
function SketchLeaf({ x, y, rot, dur, delay, color }) {
return (
);
}
function SketchCard({ game, onClick }) {
const subj = sketchSubjects[game.subject];
const disabled = !game.playable;
return (
);
}
function SketchArtboard() {
const [q, setQ] = React.useState('');
const [active, setActive] = React.useState('all');
const filtered = window.GAMES.filter(g => {
if (active !== 'all' && g.subject !== active) return false;
if (q && !(g.name + ' ' + g.desc).toLowerCase().includes(q.toLowerCase())) return false;
return true;
});
// Random leaves — stable across renders
const leaves = React.useMemo(() => Array.from({ length: 9 }, (_, i) => ({
x: 80 + (i * 137) % 1100,
y: -40 - (i * 73) % 200,
rot: (i * 47) % 360,
dur: 18 + (i % 5) * 4,
delay: -(i * 2.3),
color: ['#D9602B', '#B8861A', '#3E8E5A', '#B0431F'][i % 4],
})), []);
return (
{/* SVG defs: roughen filter */}
{/* Drifting leaves */}
{leaves.map((l, i) => )}
{/* Header */}
setQ(e.target.value)}
placeholder="Find a game…"
style={{
position: 'relative', width: '100%', boxSizing: 'border-box',
padding: '10px 16px 10px 40px', background: 'transparent',
border: 'none', outline: 'none',
fontFamily: '"Patrick Hand", cursive', fontSize: 18, color: '#3a2210',
}}
/>
{/* Hello strip */}
{/* Subject chips */}
{['all', ...Object.keys(sketchSubjects)].map(k => {
const isActive = active === k;
const subj = k === 'all'
? { label: 'All', ink: '#3a2210', fill: '#fffaf0' }
: sketchSubjects[k];
return (
);
})}
{/* Grid */}
{filtered.map(g => { window.location.href = '/' + g.id + '/'; }} />)}
{filtered.length === 0 && (
no games found — try another word
)}
);
}
window.SketchArtboard = SketchArtboard;