The Lab
Widgets
Real, working instruments. Drag a control, watch the thing respond live. Nothing here is a screenshot.
Easing Curve Visualizer
Shape a real cubic-bézier with the sliders below; the dot animates on the exact curve, live, via Framer Motion.
src/components/lab/widgets/EasingCurveVisualizer.jsx
"use client";
import { useMemo, useState } from "react";
import { motion } from "framer-motion";
import InstrumentShell from "../InstrumentShell";
import LabSlider from "../LabSlider";
import ReadoutMono from "../ReadoutMono";
export default function EasingCurveVisualizer({ code, filename }) {
const [x1, setX1] = useState(0.42);
const [y1, setY1] = useState(0);
const [x2, setX2] = useState(0.58);
const [y2, setY2] = useState(1);
const curveString = `cubic-bezier(${x1.toFixed(2)}, ${y1.toFixed(2)}, ${x2.toFixed(2)}, ${y2.toFixed(2)})`;
const path = useMemo(() => {
const toSvg = (x, y) => `${(x * 100).toFixed(1)},${(100 - y * 100).toFixed(1)}`;
return `M 0,100 C ${toSvg(x1, y1)} ${toSvg(x2, y2)} 100,0`;
}, [x1, y1, x2, y2]);
return (
<InstrumentShell
code={code}
filename={filename}
id="easing-curve"
title="Easing Curve Visualizer"
note="Shape a real cubic-bézier with the sliders below; the dot animates on the exact curve, live, via Framer Motion."
specimen={
<div className="flex flex-col md:flex-row items-center gap-8 md:gap-12 w-full">
<svg viewBox="0 0 100 100" className="w-40 h-40 md:w-48 md:h-48 shrink-0" aria-hidden="true">
<rect x="0" y="0" width="100" height="100" fill="none" stroke="#ffffff1f" strokeWidth="1" />
<line x1="0" y1="100" x2="100" y2="100" stroke="#ffffff1f" strokeWidth="1" />
<path d={path} fill="none" stroke="#00FFD1" strokeWidth="2" />
<circle cx={x1 * 100} cy={100 - y1 * 100} r="3" fill="#00FFD1" />
<circle cx={x2 * 100} cy={100 - y2 * 100} r="3" fill="#00FFD1" />
</svg>
<div className="w-full max-w-sm h-16 relative rounded-xl border border-default_border bg-[#02050ead] overflow-hidden">
<motion.div
key={curveString}
className="absolute top-1/2 -translate-y-1/2 w-6 h-6 rounded-full bg-active_hover"
initial={{ left: "4%" }}
animate={{ left: "88%" }}
transition={{
duration: 1.4,
ease: [x1, y1, x2, y2],
repeat: Infinity,
repeatType: "mirror",
}}
/>
</div>
</div>
}
controls={
<>
<LabSlider label="x1" value={x1} min={0} max={1} step={0.01} onChange={setX1} />
<LabSlider label="y1" value={y1} min={-0.5} max={1.5} step={0.01} onChange={setY1} />
<LabSlider label="x2" value={x2} min={0} max={1} step={0.01} onChange={setX2} />
<LabSlider label="y2" value={y2} min={-0.5} max={1.5} step={0.01} onChange={setY2} />
</>
}
readout={<ReadoutMono label="ease" value={curveString} />}
/>
);
}Contrast & Palette Checker
Drag hue and lightness; the ratio below is the real WCAG contrast against Void Navy, this site's actual background color.
src/components/lab/widgets/ContrastPaletteChecker.jsx
"use client";
import { useMemo, useState } from "react";
import InstrumentShell from "../InstrumentShell";
import LabSlider from "../LabSlider";
import ReadoutMono from "../ReadoutMono";
const VOID_NAVY = [2, 5, 14];
function hslToRgb(h, s, l) {
s /= 100;
l /= 100;
const k = (n) => (n + h / 30) % 12;
const a = s * Math.min(l, 1 - l);
const f = (n) =>
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
return [255 * f(0), 255 * f(8), 255 * f(4)];
}
function relativeLuminance([r, g, b]) {
const [rs, gs, bs] = [r, g, b].map((c) => {
const v = c / 255;
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
});
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
}
function contrastRatio(rgbA, rgbB) {
const lA = relativeLuminance(rgbA);
const lB = relativeLuminance(rgbB);
const [lighter, darker] = lA > lB ? [lA, lB] : [lB, lA];
return (lighter + 0.05) / (darker + 0.05);
}
export default function ContrastPaletteChecker({ code, filename }) {
const [hue, setHue] = useState(165);
const [lightness, setLightness] = useState(50);
const rgb = useMemo(() => hslToRgb(hue, 100, lightness), [hue, lightness]);
const hex = `#${rgb
.map((c) => Math.round(c).toString(16).padStart(2, "0"))
.join("")}`;
const ratio = useMemo(
() => contrastRatio(rgb, VOID_NAVY),
[rgb]
);
const passesAA = ratio >= 4.5;
const passesLargeAA = ratio >= 3;
return (
<InstrumentShell
code={code}
filename={filename}
id="contrast-checker"
title="Contrast & Palette Checker"
note="Drag hue and lightness; the ratio below is the real WCAG contrast against Void Navy, this site's actual background color."
specimen={
<div className="flex flex-col items-center gap-6 w-full">
<div
className="w-full max-w-sm rounded-2xl border border-default_border p-8 flex items-center justify-center"
style={{ backgroundColor: `rgb(${VOID_NAVY.join(",")})` }}
>
<span
className="text-2xl md:text-3xl font-bold text-center"
style={{ color: hex }}
>
Signal preview
</span>
</div>
<div className="flex items-center gap-3">
<span
className="w-8 h-8 rounded-full border border-default_border shrink-0"
style={{ backgroundColor: hex }}
aria-hidden="true"
/>
<span
style={{ fontFamily: "var(--font-geist-mono)" }}
className="text-text_normal text-sm"
>
{hex}
</span>
</div>
</div>
}
controls={
<>
<LabSlider
label="hue"
value={hue}
min={0}
max={360}
step={1}
onChange={setHue}
unit="°"
/>
<LabSlider
label="lightness"
value={lightness}
min={10}
max={90}
step={1}
onChange={setLightness}
unit="%"
/>
</>
}
readout={
<div className="flex flex-wrap gap-3 justify-center">
<ReadoutMono
label="contrast"
value={`${ratio.toFixed(2)}:1`}
tone={passesAA ? "active" : "error"}
/>
<ReadoutMono
label="AA body"
value={passesAA ? "pass" : "fail"}
tone={passesAA ? "active" : "error"}
/>
<ReadoutMono
label="AA large"
value={passesLargeAA ? "pass" : "fail"}
tone={passesLargeAA ? "active" : "error"}
/>
</div>
}
/>
);
}Matrix Rain Playground
A tunable rebuild of a background effect that was sitting unused in this codebase. Now a real, controllable instrument.
src/components/lab/widgets/MatrixRainPlayground.jsx
"use client";
import { useEffect, useRef, useState } from "react";
import InstrumentShell from "../InstrumentShell";
import LabSlider from "../LabSlider";
import LabToggleGroup from "../LabToggleGroup";
import ReadoutMono from "../ReadoutMono";
const CHARSETS = {
binary: "01",
alphanumeric: "01ABCDEFGHIJKLMNOPQRSTUVWXYZ",
symbols: "!@#$%^&*()_+-=[]{}<>?/",
};
const IDLE_CLASS = "transition-all duration-200 opacity-20 text-active_hover text-xs md:text-sm";
const ACTIVE_CLASS = "transition-all duration-200 opacity-100 text-active_hover text-xs md:text-sm";
export default function MatrixRainPlayground({ code, filename }) {
const containerRef = useRef(null);
const rafRef = useRef(null);
const spansRef = useRef([]);
const activeRef = useRef(new Set());
const [speed, setSpeed] = useState(60);
const [density, setDensity] = useState(20);
const [charsetKey, setCharsetKey] = useState("binary");
useEffect(() => {
const container = containerRef.current;
if (!container) return undefined;
container.innerHTML = "";
const rows = 8;
const cols = 24;
const spans = [];
for (let i = 0; i < rows; i++) {
const row = document.createElement("div");
row.className = "flex justify-between";
for (let j = 0; j < cols; j++) {
const span = document.createElement("span");
span.className = IDLE_CLASS;
span.style.fontFamily = "var(--font-geist-mono)";
span.textContent = "0";
row.appendChild(span);
spans.push(span);
}
container.appendChild(row);
}
spansRef.current = spans;
activeRef.current = new Set();
return () => {
container.innerHTML = "";
};
}, []);
useEffect(() => {
let last = 0;
const chars = CHARSETS[charsetKey];
const tick = (t) => {
if (t - last >= speed) {
last = t;
const spans = spansRef.current;
const active = activeRef.current;
if (active.size > density) {
const oldest = [...active][0];
oldest.className = IDLE_CLASS;
oldest.textContent = "0";
active.delete(oldest);
}
const span = spans[Math.floor(Math.random() * spans.length)];
span.className = ACTIVE_CLASS;
span.textContent = chars[Math.floor(Math.random() * chars.length)];
active.add(span);
}
rafRef.current = requestAnimationFrame(tick);
};
rafRef.current = requestAnimationFrame(tick);
return () => cancelAnimationFrame(rafRef.current);
}, [speed, density, charsetKey]);
return (
<InstrumentShell
code={code}
filename={filename}
id="matrix-rain"
title="Matrix Rain Playground"
note="A tunable rebuild of a background effect that was sitting unused in this codebase. Now a real, controllable instrument."
specimen={
<div
ref={containerRef}
className="w-full max-w-2xl h-48 md:h-56 rounded-xl border border-default_border bg-[#02050ead] p-4 overflow-hidden flex flex-col justify-between"
/>
}
controls={
<>
<LabSlider
label="speed"
value={speed}
min={20}
max={200}
step={10}
onChange={setSpeed}
unit="ms"
/>
<LabSlider
label="density"
value={density}
min={2}
max={60}
step={2}
onChange={setDensity}
/>
<LabToggleGroup
label="charset"
value={charsetKey}
onChange={setCharsetKey}
options={[
{ value: "binary", label: "Binary" },
{ value: "alphanumeric", label: "Alnum" },
{ value: "symbols", label: "Symbols" },
]}
/>
</>
}
readout={<ReadoutMono label="charset" value={CHARSETS[charsetKey]} />}
/>
);
}Coming next
Queued, not built yet. Shown so the roadmap stays honest.
- Glassmorphism / gradient generator
- Box-shadow / blob generator
- JSON formatter & validator
- Regex tester
- Markdown live previewer
- Command palette (⌘K)
- Mini Kanban board
- Sorting algorithm visualizer
- Pathfinding visualizer (A*/Dijkstra)
- Prompt / token counter
Everything above is real and running
No mockups, no screenshots: working code you just used. If you need something like this built, or you're hiring, get in touch.