Tokenly Marketing Site Design & Development by Henry TochukwuTokenly Marketing Site Design & Development by Henry Tochukwu

Tokenly Marketing Site Design & Development

Henry Tochukwu

Henry Tochukwu

Tokenly website

The marketing site for Tokenly, an AI spend-control product. I designed it in Figma, then built it in Framer with custom React code components for the motion and effects.
Role: UI/UX designer, Framer designer & developer
Duration: 2 days of build, Oct 14–15, 2026, plus polish on Nov 1–2

What the site needs to do

Teams paying several AI providers only find out what they spent when the invoices arrive. The site positions Tokenly as the control layer between a team and its providers: one prepaid balance, budgets and alerts that act before the bill, and one record for engineering and finance.
“See what your AI really costs, before the bill arrives.”
Primary conversion: Free sign-up: “Get started for free”, 14 days, no card needed
Secondary: “Book a demo” and “See how it works” for buyers who want proof first
Audience: Engineering leads, finance & ops, agencies, and founders
Proof: The product itself: live dashboard widgets sit in every section instead of stock illustrations

Design direction

Two ideas carry the whole site. The UI is strictly monochrome so the product reads as calm and precise, while classical paintings behind the product widgets give it warmth and set it apart from the usual dark, neon AI look. Every painting gets the same soft grade so it supports the product rather than competing with it.
Eight pages: Home, Product, How it works, Solutions, Pricing, Customers, About & Contact, FAQ.
Three breakpoints: desktop, tablet and phone, with a 24px gutter and a working mobile menu.
A blueprint hero: hairline grids with “+” markers and small mono labels, used on every page header.
Plain-spoken copy: full sentences, with one primary call to action per section.

The Framer build

I built the pages from the Figma frames, then added interactions natively where Framer handles them well and as code where it doesn’t. Moving repeated visuals into code components also kept the desktop layout under Framer’s publishing size limit.
Hero load-inCount-up metricsAnimated bar & line chartsImage zoom on hoverInvert-on-hover cardsSolutions tabsMonthly / yearly billing toggleFAQ accordionsSticky navMobile menu

Interactions in code

Each one is a small React component or override in the Framer project, with controls exposed in Framer’s properties panel and reduced-motion respected.

Dashboard numbers that count up, then keep ticking

Balance and spend figures count up when they scroll into view, then drift slightly so the dashboard feels live. In the Framer canvas they show the final value so the design stays easy to edit.
const inView = useInView(ref, { once: true })
const [n, setN] = useState(isCanvas ? value : from)

useEffect(() => {
if (isCanvas) { setN(value); return }
if (!inView) return
let timer: ReturnType<typeof setInterval> | undefined
let base = value
const controls = animate(from, value, {
duration, delay, ease: [0.22, 1, 0.36, 1],
onUpdate: (v) => setN(v),
onComplete: () => {
if (!drift && !jitter) return
// Keep ticking like live data after the count-up lands.
timer = setInterval(() => {
base += drift * (0.6 + Math.random() * 0.8)
setN(base + (jitter ? (Math.random() * 2 - 1) * jitter : 0))
}, Math.max(0.5, interval) * 1000)
},
})
return () => { controls.stop(); if (timer) clearInterval(timer) }
}, [inView, isCanvas, value, from, duration, delay, drift, jitter, interval])

Usage bars that rise one by one

The stacked usage chart is drawn as SVG from the product’s real chart geometry. Each day’s column rises in sequence when 30% of the chart is visible.
{COLS.map((x, i) => (
<motion.g
key={x}
initial={isCanvas ? false : { y: 150 }}
animate={show ? { y: 0 } : { y: 150 }}
transition={{ duration, delay: delay + i * stagger, ease: [0.22, 1, 0.36, 1] }}
>
{SEGS.filter((s) => s[0] === x).map((s, j) => (
<rect key={j} x={s[0]} y={s[1]} width={BAR_W} height={s[2]} fill={s[3]} />
))}
</motion.g>
))}

One tone and a slow zoom for every painting

A single override grades every painting the same way and zooms it gently on hover. Only the image is affected, never the product widget on top of it.
// Less saturation, a touch less contrast. Blacks aren't lifted, so images stay rich.
const TONE = "saturate(0.72) contrast(0.96) brightness(0.98)"
const CSS =
`${IMG}{filter:${TONE};transform:scale(1);transition:transform 1.1s cubic-bezier(0.22,1,0.36,1)}` +
`.tk-bgzoom:hover>${W} img{transform:scale(1.08)}` +
`@media (prefers-reduced-motion: reduce){${IMG}{transition:none}}`

export function withBackgroundZoom(Component: ComponentType<any>): ComponentType<any> {
return forwardRef<any, any>(function BackgroundZoom(props, ref) {
const { className, ...rest } = props
useZoomStyles() // injects CSS once per page
return <Component {...rest} ref={ref} className={className ? className + " tk-bgzoom" : "tk-bgzoom"} />
})
}

Feature cards that invert on hover

Cards flip from white to black and their icons invert with them, giving a strong hover state while staying inside the black-and-white palette.
const CSS =
".tk-invert,.tk-invert *{transition:background-color .35s cubic-bezier(.22,1,.36,1),color .35s cubic-bezier(.22,1,.36,1)}" +
".tk-invert:hover{background-color:rgb(10,10,10)!important}" +
".tk-invert:hover *{--framer-text-color:rgb(255,255,255)!important;color:rgb(255,255,255)}" +
".tk-invert:hover>svg,.tk-invert:hover>:first-child svg{filter:invert(1)}" +
"@media (prefers-reduced-motion: reduce){.tk-invert,.tk-invert *{transition:none}}"

The blueprint hero grid

Hairlines with “+” markers where they cross, plus mono corner labels such as “Fig. 01 · AI spend”. It replaced dozens of separate layers with one component that every hero shares.
const plus = (pos: React.CSSProperties, key: string) => (
<div key={key} style={{ position: "absolute", width: 11, height: 11, ...pos }}>
<div style={{ position: "absolute", left: 0, top: 5, width: 11, height: 1, background: markColor }} />
<div style={{ position: "absolute", left: 5, top: 0, width: 1, height: 11, background: markColor }} />
</div>
)
// Markers on the outer edges and on the inner guide lines, top and bottom.
{xs.map((x, i) => plus({ ...x, top: -5 }, "t" + i))}
{xs.map((x, i) => plus({ ...x, bottom: -5 }, "b" + i))}
Like this project

Posted Nov 2, 2026

Marketing site for an AI spend-control product, designed in Figma and built in Framer in two days, with custom React code for motion and live-feeling data.

Likes

1

Views

3

Timeline

Oct 13, 2026 - Nov 1, 2026