Case study

ADCenter Design System: co-building the foundations

Our Capgemini centre had no design system. I joined the effort to build one, to learn how systems are made from the inside, and ended up co-owning a part of it: the colour foundations, the contrast work behind them, and the components that live inside dense tables.

Role
Product Designer, co-builder
Timeline
2023–2024, in parallel with Center360
Tools
Figma variables, Ubuntu type
Scope
3 themes · 50+ components

01 · Context

One centre, many products, no shared language

Before AI tooling2023. AI existed, but not for building components, not in Figma, not anywhere in this workflow. Everything on this page was defined and checked by hand.

The centre built internal products for itself and for clients, each with its own team, its own stack (Angular here, React there) and its own buttons. Developers rebuilt the same components for every project and accessibility was whatever each designer remembered to check. Valeria made the case for a system. I asked to build it with her, partly because the centre needed it and partly because I wanted to learn how systems are made from the inside.

Honest framing

Valeria led the system and designed most of it. This page covers the parts that were mine, and names hers where they touch. Her case study tells the whole story from the lead's seat.

02 · My part

What I worked on

Co-owned with Valeria. The foundations were defined together, in the same file, in the same weeks; the components below were the ones I took on and brought to her for review.

Foundations · co-ownedColour tokens

Ten scales, a semantic layer on top, and three themes that resolve from it: Light, Brand and Dark. Defined together with Valeria.

Accessibility · co-ownedContrast

Every text, icon and border token checked against its background in each theme. Where a pair failed, the token changed, not the rule.

Components · mineTags, tables, tabs, calendar

The components dense products are built from. Tags alone: four types, nine colours, six states, two sizes.

PrototypesVariable-driven prototypes

Figma prototypes wired to variables, so a theme switch or a state change could be tested before a line was coded.

03 · Colour

Ten scales, three themes

These are not screenshots. The swatches below are painted from the system's own values, as documented in the Figma file, and the number on each step is the contrast of the best text colour on it. Brand primary is Capgemini's blue.

Brand primary12 steps
0 15.96:1
05 15.75:1
10 14.37:1
20 12.53:1
30 9.95:1
40 5.70:1
50 5.36:1
60 7.10:1
70 8.96:1
80 11.41:1
90 13.58:1
100 15.86:1
Brand secondary11 steps
0 15.17:1
10 11.84:1
20 10.47:1
30 9.32:1
40 8.15:1
50 6.39:1
60 4.50:1
70 5.02:1
80 6.82:1
90 9.28:1
100 12.38:1
Brand tertiary7 steps
0 13.15:1
5 9.65:1
10 5.66:1
20 5.12:1
30 7.98:1
40 12.63:1
50 17.31:1
Neutral16 steps
0 17.04:1
10 16.33:1
15 15.22:1
20 14.43:1
25 12.67:1
30 10.61:1
40 8.04:1
60 5.07:1
65 4.74:1
70 6.69:1
75 9.29:1
80 12.63:1
85 15.13:1
90 17.04:1
95 18.42:1
100 19.44:1
Green10 steps
0 14.43:1
10 12.30:1
30 8.99:1
40 7.78:1
50 6.46:1
60 4.47:1
70 4.94:1
80 6.67:1
90 9.29:1
100 13.50:1
Teal10 steps
0 13.71:1
10 12.34:1
20 11.31:1
30 10.17:1
50 8.14:1
60 5.58:1
70 4.18:1
80 5.80:1
90 8.22:1
100 11.36:1
Pink11 steps
0 14.41:1
10 11.53:1
20 8.66:1
30 6.23:1
40 4.72:1
50 4.47:1
60 6.22:1
70 7.99:1
80 10.70:1
90 13.02:1
100 15.32:1
Yellow11 steps
0 16.04:1
10 15.22:1
20 14.38:1
30 13.68:1
40 12.95:1
50 12.90:1
60 11.07:1
70 8.78:1
80 4.73:1
90 7.38:1
100 14.29:1
Orange11 steps
0 13.20:1
10 12.10:1
20 10.50:1
30 9.53:1
40 8.86:1
50 7.22:1
60 6.05:1
70 4.62:1
80 5.64:1
90 8.72:1
100 10.46:1
Red13 steps
0 15.26:1
05 12.58:1
10 9.07:1
15 6.84:1
20 6.05:1
30 5.51:1
40 4.21:1
50 4.33:1
60 5.32:1
70 6.87:1
80 8.81:1
90 11.57:1
100 15.65:1

The semantic layer

Components never point at a scale step directly. They point at a semantic token, and the token resolves differently in each theme. One component, three looks, zero overrides.

Default / Background LightBrandDark
bg neutral-0 brand-primary-50* neutral-90
bg-10 neutral-10 brand-primary-50* neutral-90
bg-10-hover brand-primary-0 brand-primary-0 brand-primary-0
bg-10-focus brand-primary-10 (60%) brand-primary-10 (60%) brand-primary-10 (60%)
bg-10-activeCurrent brand-primary-10 brand-primary-10 neutral-10 (50%)
bg-20 neutral-15 neutral-0 neutral-0

04 · Accessibility

Text on its real background

Contrast is a property of a pair, not of a colour. So the check was always the same question: this text, on this background, in this theme, is it readable? The tag is the component where this mattered most, nine colours on nine tints inside dense rows, so here are its variables as the component binds them, with the text measured on each background on this page. Body text needs 4.5:1; large text and UI, 3:1. The component itself is further down.

Colour Background Background, hover Text Text on each Live
Yellowchart/yellow/ yellow-bgyellow-10 · #FFF2C5 yellow-bg-hoveryellow-20 · #FFEBAA yellow-textyellow-90 · #6C5205 6.59:1 · AA 6.22:1 · AA on hover German
Orangechart/orange/ orange-bgorange-0 · #FFDCC2 orange-bg-hoverorange-10 · #FFD0B1 orange-textorange-90 · #813300 6.76:1 · AA 6.19:1 · AA on hover Rotation
Redchart/red/ red-bgred-05 · #FCD4D4 red-bg-hoverred-10 · #F3AAAF red-textred-80 · #94151D 6.50:1 · AA 4.69:1 · AA on hover Urgent
Pinkchart/pink/ pink-bgpink-0 · #FFE5F3 pink-bg-hoverpink-10 · #F7C7E1 pink-textpink-80 · #6C2249 9.05:1 · AAA 7.24:1 · AAA on hover French
Purplechart/purple/ purple-bgbrand-tertiary-0 · #ECDDF3 purple-bg-hoverbrand-tertiary-5 · #DDB4F3 purple-textbrand-tertiary-40 · #4E1471 9.75:1 · AAA 7.16:1 · AAA on hover Prospective
Tealchart/teal/ teal-bgteal-0 · #C7EEEE teal-bg-hoverteal-10 · #B1E5E5 teal-textteal-100 · #0C4141 9.14:1 · AAA 8.23:1 · AAA on hover Bench
Bluechart/blue/ blue-bgbrand-primary-10 · #D4F0FF blue-bg-hoverbrand-primary-20 · #B2E4FF blue-textbrand-primary-100 · #002539 13.38:1 · AAA 11.66:1 · AAA on hover Angular
Greenchart/green/ green-bggreen-0 · #D6F3E2 green-bg-hovergreen-10 · #AEE8C6 green-textgreen-90 · #19512F 7.87:1 · AAA 6.71:1 · AA on hover Released
Greychart/grey/ grey-bgneutral-20 · #ECECEC grey-bg-hoverneutral-25 · #DEDEDE grey-textneutral-90 · #1C1C1C 14.43:1 · AAA 12.67:1 · AAA on hover .NET
Close buttonchart/<colour>/ <colour>-bg-icon-hoverthe text colour at 10–15% alpha, drawn behind the cross on hover; neutral-30 for grey no text, no rule behind the cross
Selectable Background Border Text Text on background Live
Default default/background/bgneutral-0 · #FFFFFF default/border/border-mediumneutral-30 · #CCCCCC default/text/text-strongneutral-90 · #1C1C1C 17.04:1 · AAA Remote
Hover chart/grey/grey-bg-selectable-hoverneutral-20 · #ECECEC default/border/border-mediumneutral-30 · #CCCCCC default/text/text-strongneutral-90 · #1C1C1C 14.43:1 · AAA Remote
Selected chart/grey/grey-bg-selectable-activeneutral-90 · #1C1C1C chart/grey/grey-bg-selectable-activeneutral-90 · #1C1C1C chart/grey/grey-text-selectable-activeneutral-0 · #FFFFFF 17.04:1 · AAA Remote
Disabled chart/grey/grey-bg-selectable-disabledneutral-10 · #FAFAFA default/border/border-mediumneutral-30 · #CCCCCC default/text/text-disabledneutral-40 · #B2B2B2 2.03:1 · Fail · disabled text is exempt Remote
Focus default/border/border-focusbrand-primary-40 · #009CF1 2px ring, 1px offset, on the whole tag or only on the close button. Against white it measures 2.99:1, a hair under the 3:1 asked of non-text UI; the ring relies on its width and on sitting outside the tag more than on its colour. tab into any tag

Every variable the tag binds, by its name in the Figma collection, the primitive it points at and its value, with the contrast of the text variable on each background variable and the real tag beside it. All nine colours pass AA on the default and the hover background, and six clear AAA; yellow, orange and red sit between 6.5:1 and 6.8:1. The pattern is the same in every colour: the lightest tint of the scale is the background, one of the darkest is the text. Tags are small and sit inside dense rows, so the margin matters more than it would on a heading.

05 · Component

The tag component

Tags label, categorise and filter. To cover those jobs without one component doing everything badly, they come in four types: read-only for labelling, dismissible for active filters, operational for overflow ("+3"), and selectable for toggling filters in place. Nine colours, six states, two sizes. The close button is its own component, so its focus ring and hit area are the same everywhere.

Type
Size
Colour
Hover, click, and Tab through them. Tab twice on a dismissible tag to reach its close button.

Rebuilt from the Figma component, not pasted from it: colours, sizes, radius and the Ubuntu type are the system's values, and every state is the real one, reachable with your own mouse and keyboard.

When to use
  • To categorise content people filter by.
  • For attributes such as "Urgent", "Featured" or "Deprecated".
  • To show secondary status, "New" or "Updated", that is useful but not essential.
When not to use
  • For actions. "Submit" and "Delete" are buttons.
  • For navigation. Links and menus do that.
  • For anything essential to completing a task, or in quantities that clutter.

06 · More examples

Tables, tabs and the calendar, among others

After tags I defined the components that dense internal products are made of: tables with sortable headers, inline status and pagination; tabs in line and contained styles; and the calendar, from the day cell up to the twelve-month year view. Rendered below from the system's tokens. If they look familiar, it is because Center360 is built with them: the system and the product were designed in the same months, each pushing the other.

07 · After

Where it went, and where I went with it

The system was a work in progress by design, and it was in use while it was being built: Center360 and several other internal applications of the centre were assembled from it, so every component shipped to a real product soon after it was defined. Then client work took over my weeks and I moved on to ASML.

One thing about this system is worth saying plainly: it was built before AI tooling could do any of it. Every scale, every variable name, every contrast pair in this page was defined and checked by hand, in Figma, by two people. Today I build systems with AI in the loop, much faster and with far more documentation, and that speed is only useful because I learned what the output has to look like without it.

The systems so far

  1. 2023–2024 Before AI tooling

    ADCenter Design System

    Co-built with Valeria Lamicq

    • Colour foundations and contrast, defined together.
    • Tags, tables, tabs and the calendar, mine.
    • Every pair measured by hand, every variable named by hand.
  2. 2024–2026

    ASML

    Contributor to a system in production

    • A much larger organisation and a system already shipping.
    • Components and patterns added for the four applications I owned.
    • Details under NDA.
  3. 2026 –

    Hello Customer

    Built from scratch, alone

    • First inside the existing product, adapting to what was there.
    • Now a new system for the new navigation and the new version of the platform.
    • Built with AI in the loop, documented as it goes, live from day one.