Components · · 3 min read
UI components: BrowserFrame, SystemFlow & Stat — with live examples
Three server-first components used across this site — a browser mockup, a tag-based architecture diagram, and a count-up number — rendered live on this page, with full source code.
AI coverage
Load on 4G
These three small components appear on nearly every page of this site: BrowserFrame (a browser chrome for mockups), SystemFlow (a system-flow diagram), and Stat (a number that counts up when visible). The live example is rendered right above ↑ — not an image. Here’s the source code and the design decisions behind it.
BrowserFrame — a mockup without screenshots
The problem: showing “product” before real screenshots exist. The solution is a minimal browser chrome — three dots, an address bar, then a children slot for any content:
export const BrowserFrame = ({ url, children }: { url: string; children?: Child }) => (
<div class="card overflow-hidden">
<div class="flex items-center gap-3 border-b border-line bg-surface px-4 py-2.5">
<div class="flex gap-1.5" aria-hidden="true">
<span class="h-2 w-2 rounded-full border border-line bg-base"></span>
<span class="h-2 w-2 rounded-full border border-line bg-base"></span>
<span class="h-2 w-2 rounded-full border border-line bg-base"></span>
</div>
<div class="min-w-0 flex-1 truncate rounded-sm border border-line bg-base px-3 py-1
font-mono text-[10px] tracking-[0.06em] text-muted">{url}</div>
</div>
<div class="bg-base">{children}</div>
</div>
);
The detail that matters: min-w-0 + truncate on the address bar. Without it, a long URL forces the content’s minimum width past a phone’s viewport — the page “shrinks” to the left (a real bug this site once had).
SystemFlow — an architecture diagram made of tags
A flow diagram (Storefront → Checkout → AI chat → RAG → Ops) without a diagram library: just a row of tags with animated “beams” between them. On mobile the beams hide and the tags are allowed to wrap:
export const SystemFlow = ({ nodes }: { nodes: string[] }) => (
<div class="flex flex-wrap items-center justify-center gap-2 py-1 md:flex-nowrap md:gap-0"
role="img" aria-label="System flow diagram">
{nodes.map((node, i) => (
<>
{i > 0 && <span class="beam hidden w-10 shrink-0 md:block" aria-hidden="true"></span>}
<span class="tag shrink-0 bg-base">{node}</span>
</>
))}
</div>
);
role="img" + aria-label makes screen readers announce one diagram instead of five random tags.
Stat — the count-up number
The server renders the final value in a data-count attribute (SEO and no-JS users still get the number — the initial prefix + 0 + suffix text is only animated when JS is on). Vanilla JS in site.js animates it when the element enters the viewport via IntersectionObserver:
export const Stat = ({ prefix, count, suffix, label, delay }: StatProps) => (
<div class="text-center" data-reveal style={"--d: " + delay}>
<div class="font-display text-4xl font-semibold tracking-tight md:text-5xl">
<span data-count={count} data-prefix={prefix} data-suffix={suffix}>{prefix}0{suffix}</span>
</div>
<p class="mt-2 font-mono text-[11px] uppercase tracking-[0.18em] text-muted">{label}</p>
</div>
);
The principle behind all three
- Server-first: all content exists in the initial HTML; JavaScript only adds motion.
- Zero dependencies: no carousel/diagram/count-up library — the site’s total JS stays under 20KB.
- Mobile enforced with classes, not JS:
flex-wrap,hidden md:block,min-w-0— layout never depends on runtime measurement.
Want something like this built for your business?