Scaling Multi-Tenant Architecture: Servicing 2 Brands from 1 Codebase
Role: Senior Product Designer – Contract (YNAP via Mindera)
Timeline: 4 months
Team: 5 designers + engineers
Goal: Create a scalable, token-based design system that supports both Net-a-Porter and Mr Porter, aligning navigation, theming, and brand consistency across five platforms.
Overview
YNAP was consolidating Net-A-Porter and Mr Porter onto a single application architecture. Same codebase, two distinct luxury brand identities.
There was no design system. I was hired to build it from scratch—define the token structure, create the component libraries, build page templates, and enable a team to scale it across multiple languages.
The challenge that defined the project: Engineering said they couldn't build a single navigation component that would work for both brands because the visual differences were too significant. I proved them wrong.
My core contribution: Created 35 typography and 3 color decision tokens, architected a navigation component using frame height manipulation to enable brand differentiation at the token level, built the entire component library, and led 5 designers to implement the system across 7 page templates and 3 languages.
Challenge
What I walked into:
Week 1, first engineering sync:
Me: "So we'll build one navigation component that themes for both brands using tokens."
Tech Lead: "That won't work. Look at these mockups—Net-A-Porter has no separator lines, Mr Porter has a horizontal divider and underlines on nav items. These are structurally different. We'll need separate components."
Me: "Give me a week."
The structural differences:
Net-A-Porter navigation:
Clean black header with "HI, [NAME]" personalization
Logo and utility icons in top row
Navigation links in bottom row
No visual separators between rows or under links
Lighter, more minimal aesthetic
Mr Porter navigation:
Cream header with gold "MR WINSTON" branding
Logo and utility icons in top row
4px horizontal line separating top and bottom rows
Navigation links in bottom row
Gray underline beneath each nav link
More editorial, structured aesthetic
Engineering's argument was sound: these aren't just color differences. One brand has structural elements (lines/separators) that the other doesn't. How do you build "one component" that conditionally shows/hides structural layers?
Results
The breakthrough:
I realized the "structural" differences weren't structural at all—they were height differences.
In Figma, I built:
A frame layer between top and bottom rows:
Net-A-Porter: Frame height = 0px (invisible)
Mr Porter: Frame height = 4px (creates the horizontal divider)
An underline frame beneath each nav link:
Net-A-Porter: Frame height = 0px (no underline)
Mr Porter: Frame height = 2px (gray underline)
The reveal:
Week 2, I walked into the engineering meeting and showed them:
One Figma component with consistent layer structure
Toggle between NAP and MRP themes → navigation transforms instantly
No variant swapping, no conditional logic, just token values
The room went quiet. Then the tech lead leaned forward: "Wait... that's it? That actually works?"
They started messaging me during the meeting asking when I could send the designs. Played it cool, but I could tell—they weren't expecting this to be solvable.
That moment defined the project. Once engineering saw that brand differences could be encoded at the token level, they bought into the entire system architecture.
Research & Discovery
Phase 1: Token Architecture (Weeks 1-4)
YNAP had existing component libraries, but no semantic token layer. Everything was hard-coded values.
What I built:
35 typography decision tokens for component-specific type treatments:
--Accordion-title-font
--PRODUCT-CARD-V-PRODUCT-NAME-FONT
--PRODUCT-PRICE-FULL-PRICE-FONT
--BADGE-LABEL-COPY-FONT
--PRODUCTPAGE-TITLE-BADGE
--Dialog-title-font
These weren't generic "heading-1, heading-2" tokens. They were context-specific tokens that encoded brand typography personality at the component level. For example:
Product card price needed heavier weight on MRP (editorial feel) vs lighter on NAP (minimal elegance)
Accordion titles needed different font families between brands
Badge labels had distinct caps treatments
3 color decision tokens for interactive elements:
--COLOR-PRIMARY-BLACK /* Core brand color */
--COLOR-PRIMARY-DEFAULT /* Default interactive state */
--COLOR-PRIMARY-HOVER /* Hover/focus state */
Why decision tokens mattered:
Without them, designers would hard-code #000000 in NAP and #0A0A0A in MRP, creating drift. Decision tokens enforced consistency while enabling brand theming.
The architecture principle:
Semantic tokens (what it means) → Decision tokens (how this component uses it) → Brand theme overrides (NAP vs MRP values)
Design Process
Component Library Build (Weeks 4-12)
With tokens defined, I built the entire component library myself.
What I created:
The complete set of e-commerce components:
Navigation: Header with configurable frame heights, footer, breadcrumbs
Product components: Product cards, image galleries, size selectors, add-to-bag flows
Forms: Inputs, selects, checkboxes, radio buttons, textareas
Interactive elements: Buttons, links, tabs, accordions, modals
Feedback: Alerts, toasts, loading states, error states
Layout: Grids, spacing systems, responsive containers
The Figma library structure:
I organized into 3 separate libraries:
Foundation Library – Typography tokens, color tokens, spacing, grids
Component Library – All components referencing foundation tokens
Template Library – 7 page compositions showing real-world usage
Why separate? If tokens and components lived in one file, designers would accidentally override tokens instead of using them. Separation enforced proper token usage.
Navigation Component Architecture (Weeks 4-6)
Beyond the frame height trick, the navigation needed to handle:
Responsive behavior: Desktop, tablet, mobile breakpoints
Multi-brand theming: Color, typography, spacing differences
Utility navigation: Search, wishlist, bag, account icons
Language support: English, Arabic (RTL), Chinese, Korean
The component structure I built:
Header
{ Top Row {
Logo (brand-specific asset)
Utility Icons (search, wishlist, account, bag) }
Divider Frame { Height: var(--Navigation-divider-height) /* 0px NAP, 4px MRP */ Background: var(--COLOR-PRIMARY-DEFAULT) }
Bottom Row {
Nav Link Button {
Label
Underline Frame {
Height: var(--Navigation-link-underline-height) /* 0px NAP, 2px MRP */ } } } }
The genius of this structure:
Same layer hierarchy for both brands
No variant explosion (not 2 brands × 5 platforms = 10 variants)
Engineers could implement once, theme via CSS variables
Future brands could be added by creating new theme files
Page Templates & Documentation (Weeks 10-14)
With components built, I created 7 e-commerce page templates to show how they compose:
Homepage - Hero, carousels, editorial blocks
Product Listing Page - Filters, grid, pagination
Product Detail Page - Gallery, details, sizing, add-to-bag
Basket - Line items, promo codes, checkout CTA
Checkout - Multi-step form, shipping, payment
My Account - Order history, preferences
Wishlist - Saved items
Why templates mattered:
Components alone don't teach composition. Templates showed:
How product cards arrange in grids
How filters interact with listing layouts
How spacing rhythms create hierarchy
How the system works at page scale
Documentation I created:
Token usage guide: When to use decision tokens vs semantic tokens
Component guidelines: Proper usage, accessibility requirements, responsive behavior
Multi-language guide: RTL layout rules, typography adjustments for Arabic/Chinese/Korean
Contribution process: How to propose new components or tokens
Team Enablement (Weeks 10-16)
Once templates were done, I had 5 designers who needed to:
Build remaining pages (returns, size guides, editorial pages)
Localize everything for Arabic, Chinese, Korean
Apply the system without breaking token architecture
How I led them:
Week 10: Onboarding workshop (4 hours)
Walked through token architecture with live examples
Showed how to use templates as starting points
Demonstrated multi-language switching
Created decision tree: "When to create new components vs. use existing"
Weeks 11-16: Weekly design reviews
1-hour Monday sync reviewing work-in-progress
Caught token misuse early (hard-coded colors instead of tokens)
Ensured consistency across language variants
Provided feedback on composition and hierarchy
The process I established:
Component requests: Designer proposes → I review → we build together → document → add to library
Token contributions: Need a new decision token? Discuss naming, add to foundation
QA checklist: Verify token usage, accessibility, responsive behavior, RTL support before shipping
The Arabic challenge:
Week 13, the designer working on Arabic pages found that product card layouts and filter panels didn't work in RTL. Some components used directional properties (margin-left) instead of logical properties (margin-inline-start).
How I fixed it:
Spent 2 days converting components to logical CSS properties
Created RTL checklist for the team
Established rule: Always design with RTL in mind from first sketch
Lesson learned: Multi-language support isn't a feature you add later. It's architecture you build from day one.
Key Problems & Solutions
What I delivered:
✅ Complete component library built with semantic token architecture
✅ 35 typography + 3 color decision tokens enabling brand theming
✅ Navigation component solving "impossible" brand differentiation
✅ 3 Figma libraries (Foundation, Components, Templates)
✅ 7 page templates across desktop, tablet, mobile
✅ Multi-language support for English, Arabic, Chinese, Korean
✅ Complete documentation + team onboarding materials
The engineering validation:
After seeing the frame height solution, the tech lead said in our retrospective:
"We were ready to build separate navigation components. That would have meant maintaining two codebases forever. The token-level approach saved us months of work and technical debt we would've never paid down."
Team adoption:
All 5 designers successfully used the system without breaking token architecture
New pages shipped using templates as foundations
Arabic, Chinese, and Korean localizations completed on schedule
Zero design debt accumulated at launch
System scalability:
The decision token architecture meant:
One component library serving 2 brands × 3 languages × 5 platforms
Future brands can be added by creating theme files, not rebuilding components
Engineers implement once, theme via CSS variables
Maintenance burden reduced by ~80% compared to separate brand libraries
Conclusion
What I'd Do Differently
1. Build with logical CSS properties from day 1
I initially used directional properties (margin-left, padding-right), assuming I'd "add RTL later." That created 2 days of painful refactoring in week 13. Should have used logical properties (margin-inline-start) from the first component.
2. Establish component contribution process earlier
Didn't formalize the "how to propose new components" workflow until week 10. Before that, designers built one-off components outside the token system. Had to clean up inconsistencies.
3. Document the "why" behind decisions
My style guides explained what to do but not always why I made certain architectural choices. When designers asked "Why decision tokens instead of semantic tokens here?" I had to explain verbally each time.
Key Learnings
Constraints breed creativity
Engineering saying "this can't be done" forced me to find the frame height solution. If they'd said "sure, build two components," I would have. The constraint created the innovation.
Token architecture is architecture
The decision token layer wasn't cosmetic—it was the foundational architecture decision that made everything else possible. Sweat the token structure early.
Showing > telling
I could have written a 10-page document explaining the frame height technique. Instead, I built it and showed it live in a meeting. That 5-minute demo convinced engineering instantly.
Multi-language support compounds complexity
Arabic RTL wasn't an edge case—it revealed architectural flaws. Designing for the hardest constraint first (RTL, character-dense languages) would have saved refactoring time.
Senior design is about unblocking teams
Building components was the easy part. The hard part: establishing governance, creating contribution processes, enabling 5 desig



