App patterns
Not everything reusable belongs in the kit. These shapes were audited during the library build and deliberately left where they are — coupled to an app's router, store, or copy. They are documented here so the next builder finds them instead of reinventing them.
AnimatedNumber
Odometer number via NumberFlow. Auditioning for the kit — held out only because it would add @number-flow/react tointernal-ui dependencies. Renders live from the console source below.
apps/ui/src/components/patterns/animated-number.tsx (vendored from console)"use client";
// Vendored from apps/console/src/components/animated-number.tsx for the
// /patterns showcase (kept in sync by hand until internal-ui takes the
// `@number-flow/react` dependency and promotes it — see patterns page).
import NumberFlow, { type Format } from "@number-flow/react";
import { cn } from "@general-design-company/internal-ui/lib/utils";
/** Full-cents USD, the same output shape as `formatUsd`. */
export const USD: Format = {
style: "currency",
currency: "USD",
};
/** Whole-dollar USD for headline figures, matching `formatUsdCompact`. */
export const USD_COMPACT: Format = {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
};
type AnimatedNumberProps = {
/** The value to display. Changing this rolls each digit to the new value. */
value: number;
/** Intl format options for the rendered figure (e.g. `USD`, `USD_COMPACT`). */
format?: Format;
prefix?: string;
suffix?: string;
className?: string;
};
/**
* A figure whose digits roll in place (odometer style) whenever the value
* changes, via NumberFlow. NumberFlow honors `prefers-reduced-motion` on its
* own, so a reduced-motion user sees the target value with no animation.
*/
export function AnimatedNumber({
value,
format,
prefix,
suffix,
className,
}: AnimatedNumberProps) {
return (
<NumberFlow
value={value}
format={format}
prefix={prefix}
suffix={suffix}
className={cn("tabular-nums", className)}
/>
);
}
Kept app-specific
Audited, documented, staying put.
Console domain components apps/console/src/components/…
~195 components bound to tickets, ledgers, records, and agent loops. The kit's RecordLink provider seam is the one piece extracted so library controls never import the router.
AgentAvatar apps/console/src/components/data-view/agent-avatar.tsx
Coupled to the console's Phosphor icon catalog. Promote together with the catalog or not at all.
Marketing site chrome & configs apps/*/src/components/chrome/*-config.tsx, wordmark.tsx
Thin wiring over the kit's SiteHeader/Footer plus brand wordmarks. Configuration, not components.
Billing portal apps/main-street-ad-agency/src/portal/
Stripe/D1 checkout flows. Page logic, not a kit.
Console showcase wrappers removed with the /kit route
Card + row wrappers for the console's internal /kit page. This site's DemoCard is their public successor.
Promotion log
What moved into the kit for this site.
- console → primitives: page-header, stat-tile, prompt-loading, highlighted-text, record-link, dialog-form, error-state (+ lib/friendly-error)
- console → layout: glass-section
- general-design-company → layout: dvd-bounce