15,209 lines of CSS, and no way to restyle it
LINEAR was VYNE Creative’s internal Webflow template, used as the base for a lot of client work, but it was extremely bad at that job because it was never intended for that purpose. In practice, it was one exported stylesheet of 15,209 lines with no theming and no upward scaling for larger screens. It carried 1,990 classes and variables, and more than 1,000 of them existed just for spacing.
For the system, the team wanted dark mode, embedded icons that are easy to reconfigure, and a new ultrawide breakpoint. It also had to map cleanly from Figma to Webflow, so the team could build in either without me.
Five decisions that turned it into a system
Delete, don’t translate
My first move was mapping every v1 class to a v2 equivalent. A few hours in, it was obvious that a 1:1 map just preserves the mess with new names. I ran a duplication audit, dropped the translation approach, and rebuilt from what the pages actually used. The first pass came in under 300 classes while covering over 90% of real usage.
Components read semantic tokens only
The token system has three tiers: primitives hold raw values, semantic tokens are named by role (like
--radius-cardand--color-surface-canvas), and components only ever read the semantic tier. That rule is what makes the theming work. Switch the radius mode, and every corner in the project changes at once. Across five axes (radius, icon stroke, stroke caps, shadow, and light/dark), that adds up to 360 combinations, or “skins,” for one set of components.Naming for Figma and Webflow
Standard BEM naming clashes with Webflow’s base-class-plus-combo-class model. I switched to a hybrid convention (
card_body,container is-default,u-hidden@tablet) where every Figma layer name matches its Webflow class exactly. After pruning, I added 543 classes and combos in Webflow so every component in Figma had a working counterpart. The cost: it isn’t pure BEM or pure Client-First, so new team members have one more convention to learn. In return, design and build never drift apart.Semantics built into components
Each Webflow component carries its own semantics and ARIA out of the box. Switches are announced as switches, field errors are live regions, and decorative icons are hidden from screen readers. That structure serves two audiences: it’s what screen readers rely on, and it’s what AI agents use to understand a page, which is the core of my Machine Experience (MX) framework. On the color side, contrast fixes moved the system from 69 of 86 token pairings passing WCAG 2.2 AA to all 86, so pages built from LINEAR start accessible and machine-readable.
Icons drawn with strokes, not shapes
Early on, I went looking for a diverse icon set that used strokes instead of filled shapes. Lucide worked extremely well for the project, because the VYNE team can adjust the stroke and end-cap tokens instead of re-exporting every icon each time.
Results
| 266 tokens | 360 skins | 86 of 86 |
|---|---|---|
| In three tiers, down from 1,990 classes and variables | Across five theme axes, from one set of components | Color pairings meeting WCAG 2.2 AA |
| Measure | Before: Template (1.0) | After: Design system (2.0) |
|---|---|---|
| Classes and variables | 1,990 in one stylesheet | 266 tokens in 3 tiers |
| Reusable components | – | 75+ |
| Component variants (icons excluded) | – | 930+ |
| Button variants | 693 | 216 |
| Theme axes | – | 5 (360 combinations) |
| Color pairings meeting WCAG 2.2 AA | 69 of 86 | 86 of 86 |
| Project ramp-up | Long and complicated | Considerably faster (reported) |
Takeaways
The biggest win was ruthlessly cutting duplicates and giving every token one clear job. Next, the library expands past marketing and dashboard UI into ecommerce and more complex CMS patterns, following the 16 templates and 20 patterns I’ve already scoped.