Skip to content
Ulaş AlyeşilProduct designer · Istanbul

GetirFinansDark mode shipped; spacing, radius and size published; type still open

Rebuilding GetirFinans's design system around intent

Dark mode shipped across the app in two months. By September 2026, 8.5% of users had adopted it without a promotion.

Role
Product Design, Design Systems
Timeline
November 2025 — Present
Team
The core development team, iOS and Android
Platforms
iOS and Android, plus a documentation site
The GetirFinans home screen split diagonally, light mode on the left and dark on the right. Five elements are marked, with their light values in a column on the left and dark values on the right: the account card gradient, an icon and the page background change; the yellow rate pill and the purple pay button sit on the split and keep one value in both modes.
One screen, split by mode. The card, the icon and the page resolve to new values. The rate pill and the pay button sit on the split and keep theirs.

The old colors were named after how they looked, which said nothing about what each one should become in the dark. I rebuilt the foundation around what each color is for, documented it, and worked with engineering until dark mode shipped across the app.

Delivery

Dark mode had to work everywhere

Two months with the core development team, finished before the standalone app went out. Every screen got light and dark, not a handful of them.

No banner promoted it. By September 2026, 8.5% of users run the app in dark mode and 11% of screen views are dark, and the share has grown every month. Of the people who set a theme by hand, 54.5% pick dark.

The Findeks reports screen in light mode on the left and dark mode on the right, with a credit score gauge and a row of past reports.
Findeks reports, light and dark.
The video call handoff screen in light mode on the left and dark mode on the right: a phone illustration with a camera badge, the message that a representative is being connected, and a security note with a blue shield.
The video call handoff. The illustration has its own dark version: the camera badge turns from purple to grey. The blue shield keeps its value.

The decision

Name what a color is for

The old foundation named colors after how they looked. That is fine with one light theme. In dark mode it meant every screen became a fresh decision: which grey is this grey now?

So we named roles instead: surface, content, border, action. A role keeps its meaning in both modes. Only the value underneath changes.

Production buttons in light mode on the left and dark mode on the right: a filled purple primary button, an outlined secondary button, and a disabled primary button.
Buttons from the production component library, light and dark. The primary purple stays. The outline and the disabled state change.
Production checkboxes in light mode on the left and dark mode on the right, in four states: unchecked, checked, checked and disabled, unchecked and disabled.
Checkboxes from the same library, in four states. The checked purple gets lighter in dark mode.

In light mode the primary button and the checked box use the same purple. They are different roles, so dark mode treats them differently.

That purple appears in 23 tokens. In dark mode they resolve to six different values, and only five keep the purple. All six yellow tokens hold, and so does every shadow. Keeping a value is a decision too.

An asset breakdown sheet with a ring chart, in light mode on the left and dark mode on the right. The purple TL segment is lighter in dark mode, the yellow USD segment is unchanged.
The asset breakdown sheet. The TL slice takes the lighter purple in dark mode. The USD yellow does not change.

148 tokens, 32 fixed

Background9 of 40 fixed
Icon6 of 27 fixed
Text5 of 23 fixed
Border3 of 22 fixed
Gradient1 of 20 fixed
Chart2 of 10 fixed
Shadow6 of 6 fixed
Every color token in the shipped app, read from the production color catalog. Outlined swatches keep one value in both modes.

This was slower than picking a dark twin for every color we already had. It also stopped us re-deciding the same color every time a surface moved.

Handoff

Other people had to be able to use it

The token naming convention page on the GetirFinans design-system documentation site, showing category, concept, and role guidance.
The naming page from the documentation site.

Every token name has three parts:

  • Category: the property that changes, such as background or text.
  • Concept: where that property is used, such as a surface or an action.
  • Role: its place in the hierarchy, so a team can agree on intent before picking a value.

The documentation site made the model something you could read and check. I used it in working sessions with design and engineering, so tokens were reviewed in context instead of buried in a Figma file.

Beyond color

Spacing had to be supplied, not synced

Production had four radii, two border widths and one spacing value. Everything else was a number typed inline. There was no ladder to reconcile with, so the spacing, radius and size tokens we published are the first the product has had.

Each one is scoped to the properties it may bind to. A gap token only appears where Figma offers a gap, a radius token only on corners. The primitives underneath stay unpublished, so a designer can reach a role but never a raw number.

Components

A component is a contract

Feature Area promotes features people already have but haven't found. It is three components: an illustration, a content block, and the master that composes them. The content block only exposes valid combinations, three entries at most with the active one inside the range, so a designer cannot build a state the app cannot show.

After automatic payments got a slot, the share of payments-dashboard users who reach it went from 2.4% to 5.6%. The other promoted features did not move. A slot surfaces a feature people want. It does not create the want.

Its motion never lived in Figma. I measured the reference recording frame by frame, marked every value as measured or chosen, and checked it against a SwiftUI prototype before engineering picked it up. It corrected a transition the app had shipped wrong.

Feature Area in the SwiftUI prototype. The card stays still while its text slides and the illustration dissolves in place.

Two rules came out of the component work:

  • Fix it at the source. The page indicator only worked on purple, so designers repainted it screen by screen. It now has a color variant for purple, gray and light surfaces, driven by tokens.
  • Extend, never detach. When a kit component needs content it doesn't expose, use its slots and swap its hidden instances. A detached copy stops receiving the kit's updates, once for every place it was pasted.

Governance

Measure the drift before arguing about it

I read the production iOS component package against the Figma library: 165 components and 252 color sets. All 102 color primitives matched exactly, and 126 of 134 semantics. That made the call simple. Production is the record, and the eight differences became a list with one decision each, not a rewrite.

The same habit went into the library. A script walked every component through the Figma Plugin API and counted bindings that skipped the semantic layer: 3,177, most of them color. The button sets went first, 288 bindings rebound with no visual change.

What remains

Type is still forked

Production's type ladder and ours share four sizes. Adopting production's would regress every screen already drawn against ours; keeping ours needs someone on the engineering side to own the migration. That call is still open.

So is the icon rebuild: 447 icons audited and a naming convention written, not yet applied.