Case study·Design system·B2B SaaS·2021 — ongoing

When I joined GRESB there was one report and no design system — not in Figma, not in the code. I built the first one as the second report was starting, and build time fell from four months to one.

My role
  • Inventoried the components already shipping in the Benchmark Report, the only product that existed
  • Built the foundations first — tokens, then components, then documented patterns
  • Design system lead, working with UX, development and data science
  • Treated adoption as the deliverable, not the library
  • Later led the move off Bootstrap to a Svelte component library documented in Storybook
Impact
  • Report build time down from over four months to one — 75% faster
  • 90% fewer post-launch bugs, measured in GitHub issues
  • 84% CSAT on assessment submission — a platform-level measure the system feeds into
  • Design, development and data science working from one shared vocabulary
Overview of the GRESB design system: tokens, components and patterns

One report, plain Bootstrap, and a second one starting.

GRESB is the global standard for ESG benchmarking in real assets — used by investors and asset managers to assess sustainability performance. When I joined there was a single reporting product, the Benchmark Report, built directly on Bootstrap. No component library in Figma, no shared foundation in the code, no documented patterns.

Then a second report was commissioned. Building it the way the first one had been built meant a second set of near-identical components, and a third after that — one more every time the product suite grew. The duplication had not happened yet. It was about to, once per product line.

The question How might we give GRESB users a seamless reporting experience — and give our product teams a way to ship each new report without rebuilding the same patterns from scratch?

Start from the report that already shipped.

I started not with components, but with evidence. I ran an interface inventory in Figma of the Benchmark Report — the one product in production — cataloguing every UI element it used and organising them into atomic groups (atoms → molecules → organisms → templates). Even inside a single report it surfaced several variants of the "same" button, form and table. Working from something already in production meant the first library was grounded in patterns that had survived real use, rather than in what I imagined a reporting product might need.

I then interviewed engineers, business stakeholders and data scientists to understand where the existing build hurt and what the incoming report would need — turning anecdotal complaints into a concrete picture of which patterns to standardise first. I built the Figma library and the front-end code alongside the developers rather than handing a file over.

Foundations first, components second, adoption always.

I structured the work as three layered tracks rather than a single Big Bang release:

  • Foundations — colour (a base palette consistent across reports, plus theme palettes that distinguish product lines), typography (consistent sizes and a clear hierarchy), tokens for spacing and borders, and accessibility (colour contrast and text sizing to keep the system inclusive).
  • Core components — buttons, forms, tables, navigation — picked by frequency of use, not by what was most fun to design. Standardised and merged in the Figma library; integrated into Bootstrap on the front-end, which is what the codebase ran on at the time.
  • Patterns & docs — opinionated, examples-first documentation, written with the developers who had to follow it.
The GRESB colour tokens: five business lines - Real Estate, Infrastructure, Light Blue, Acid Green and Data Center - each with primary1, primary2, secondary and a 10% tint
Fig 1 — The colour foundations. One structure — primary1, primary2, secondary and a 10% tint — repeated across five business lines, so a report could be themed without leaving the system.
Form, table and navigation components from the GRESB library: table rows, tabs, buttons, filters and a score dial
Fig 2 — Form, table and navigation components — the patterns every report needed, standardised once.
The GRESB table standard: each cell variant beside an example and the rule for when to use it
Fig 3 — How a table gets built. A GRESB table is generated from cells rather than drawn — the cell is picked by what the column holds, never by how it should look — and each variant carries the rule for when to reach for it.
A modal component annotated with its spacing, type, border and radius tokens
Fig 4 — A component specced in tokens rather than pixel values: spacing, type scale, border and radius each named, so an engineer could read them straight off the drawing.

A design system is a product. It needs users.

The hardest part of design-system work isn't designing — it's getting teams to stop rolling their own. I treated adoption as a product launch: start in one report, prove the library in production, then expand from there.

I worked closely with engineering to make the system the path of least resistance — if reaching for a system component was easier than building one, adoption took care of itself. The Figma library reached full adoption on the design side. On the development side, each new report adopted it readily, because it arrived before their patterns had set. The original Benchmark build was the hard one: developers were reluctant to refactor code that already worked, so it migrated piece by piece.

Measurable lift across delivery, quality and satisfaction.

  • 75%faster time-to-market — report creation down from over 4 months to 1 month
  • 90%fewer post-launch bugs (measured via GitHub issues)
  • 84%CSAT on assessment submission (4.35/5, 554 responses) — a platform-level measure the design system feeds into, not one it produced alone

The system now backs six reporting products — the Benchmark Report (Real Estate and Infrastructure), SFDR, Transition Risk, TCFD Alignment, Public Disclosure and Portfolio Analysis. What I noticed beyond the numbers was a cultural shift: design, development and data science started sharing a vocabulary, decisions got debated against agreed foundations rather than personal taste, and new reports were built against documented patterns instead of tribal knowledge.

The system outgrew its first stack.

Bootstrap got the system into production fast, but it capped what the components could do and tied the library to markup the team no longer wanted. I led the move off it — a Svelte component library, documented in Storybook, replacing the docs site I had written by hand.

There is no design-systems team at GRESB and no role dedicated to one. I have carried the system alongside my end-to-end product work since 2021, so it grows alongside the products rather than on its own roadmap.

The migration was the real test of how the foundations had been built. The tokens carried over almost untouched — colour, type, spacing, and the naming that went with them — because none of it had ever belonged to Bootstrap. The markup did not survive, and did not need to. The gap between what transferred and what did not is the clearest evidence I have that sequencing foundations before components was the right call.

The GRESB component library in Storybook: the component list alongside a documented set of button properties
Fig 5 — The library in Storybook.

What I took from it.

Five palettes, one system. Keeping everything consistent while giving each product line its own colour taught me how much flexibility a system can absorb before it stops being a system.

Old code doesn't move. Design adopted the library fully, and so did every new report. The original Bootstrap build was the one still catching up, because developers didn't want to touch code that already worked. Honestly, fair enough — but it means adoption is still going, years after launch.

Deleting was harder than adding. Collapsing the near-duplicates the inventory turned up — the three buttons that should only ever have been one — was the part I found most difficult. It is also what made the library usable.

I under-invested in documentation. I wrote down the process but not enough of the reasoning. People joining later had to ask me things they should have been able to look up. Storybook is what eventually fixed that — docs that sit next to the code and cannot quietly drift out of date.

The hard conversation. It was never about tokens. It was asking engineers to refactor working code for a consistency they hadn't asked for. I lost that on the original build and won it on every report after, by making the system easier to use than to ignore instead of mandating it. That choice is why the numbers hold up and the migration still isn't finished.

Lesson The Figma file was the easy part. Getting people to use it, and writing docs good enough that they could, was the actual work — and it took far longer than building the library.

Next case study

GO APP PET — Redesigning a two-sided marketplace →