
A lightweight product that sacrifices neither design nor architecture.
Linkims. Link-in-bio platform for Lemonims artists. In production since the first artist, with 0 production dependencies and a total bundle size of 18.2 KB.
A Linktree doesn't represent a record label
Lemonims needed a centralized hub where each artist had a profile with links to their platforms: Spotify, YouTube, Instagram. Existing solutions like Linktree fell short on the only thing that mattered here: zero brand control, zero visual identity per artist, and a third party's branding on top of a product that represents a label.
The constraint wasn't technical, it was product: every profile has to feel like an extension of the artist's brand, not a generic template with swapped colors. That ruled out any solution based on predefined themes or surface-level configuration.
Today the hub hosts three profiles in production (my own, Marces, and Blanca Ferrer), with Blanca Ferrer serving as the edge case: its own serif typeface (Prociono), different weights, different CTA padding. All solved without touching the component CSS.
The decision that defines everything else: no framework
Before any component or token, the first decision was architectural: vanilla TypeScript, no framework.
Why.
The product has no state, no reactivity, no composition at scale. These are static pages rendered from JSON. Adding a framework would have added ~40 KB of runtime to solve something that document.createElement covers in 227 lines. The result is a project with zero production dependencies, only 4 devDependencies for the build.
Tokens that adapt on their own.
Spacing (4px base), typography, radii, motion, and blur are defined as custom properties on :root. Tokens change at breakpoints, and the components consuming them adapt without additional CSS. The token is the contract between design and component: not a reference, a single source of truth.
One theme per artist, without touching components.
Each artist (.theme--marces, .theme--arodav, .theme--blanca-ferrer) overrides a set of custom properties: palette, gradient, typography, glass effects. Adding the complete visual identity of a new artist takes 6 custom properties, not a component rewrite.
The layout is also data, not code.
6x5 CSS grid. Each card defines its position (row, col, rowSpan, colSpan) directly in the profile JSON, and TypeScript injects those coordinates as custom properties. Adding a new artist is a JSON file and an HTML file, not a development session.
Real multi-page, not a disguised SPA.
Four entry points in Vite. Each artist has their own index.html with dedicated <title>, meta tags, and favicon. Clean URLs (/arodav/), native SEO, no routing logic to maintain.
The details that don't show in a diff
A product in production for real clients shows in what you don't see at first glance:
- Double requestAnimationFrame on entry animations, to ensure the browser paints the initial state before firing the transition.
- Animated favicon with the Page Visibility API: alternates colors every 2s when the tab is hidden, and clears the interval on return.
- Icons via CSS mask + currentColor: they inherit the theme color automatically, no inline SVG to maintain per artist.
- prefers-reduced-motion respected across all animations.
- Progressive enhancement: semantic HTML works without JavaScript, with skip link, <nav>, ARIA labels, and lang attribute.
None of this was part of the brief. It's what separates a link-in-bio made for an artist from a generic template with a swapped logo.
Measurable Impact
18.2 KB
total minified bundle, with zero production dependencies
3
brand identities in production on a single component system
6
custom properties needed to onboard a new artist's complete visual identity
14
ARIA attributes and skip links, accessibility solved from the ground up
What this unlocks
Adding a new artist to Lemonims is no longer a project: it's a profile JSON and an index.html. The token system absorbs the visual identity without touching a component, and edge cases (like Blanca Ferrer) are solved with custom properties, not CSS forks.
This first version is deliberately an MVP: the token architecture already proves that a complete theme reduces to a handful of variables, but that tuning is still done by me, by hand, for each artist. The next step isn't optimizing that process, it's eliminating it as a bottleneck: turning the same token system into a configurable product, with a panel where each artist can adjust their own design within a system with thoughtful constraints, not a free editor that breaks visual coherence.
It's the difference between an internal tool for Lemonims and a product any independent artist can use to have an online presence with their own identity, not just another template. The technical foundation (tokens as contract, themes as data, zero dependencies) is already in place to support that leap without rewriting.