Nithya Suri · Product designer

Sheet A-03 / 04

Design systems

Talabat Pro

One component, three outcomes, two writing systems, one thumb.

A progress bar docked to the basket that tells a Pro customer how far they are from free delivery. The interesting part is not the bar. It is the specification behind it: anatomy bound to named styles, spacing on a scale, motion written as a rate, acceptance criteria for every branch, and an Arabic mirror drawn beside the English.

Client
Talabat
Product
Pro free delivery, Delivery Hero
Year
2023
Scope
5 anatomy elements · 3 states · LTR and RTL · Flutter handoff
Role
Senior product designer, design system contribution
Team
Product manager, 4 engineers, content design
Timeline
2023
Status
Shipped

Impact at a glance

anatomy elements, each bound to a named style
5
basket states, each with written acceptance criteria
3
progress movement per dirham, specified as a rate
11.4px
both writing systems drawn on the same sheet
LTR + RTL
A Talabat restaurant menu on mobile, showing the Shake Shack page with delivery details, a free delivery with Pro badge, and a docked footer holding a progress bar reading add AED to order and get free delivery above a View basket button.

The problem the component solves

A Pro customer gets free delivery only above a minimum order value. Below it, nothing on the menu says how close they are, and that gap is invisible at the moment it matters: while the basket is being built. The answer is a progress bar docked to the basket bar.

A Talabat restaurant menu on mobile showing the Shake Shack page with delivery details, a free delivery with Pro badge, and a docked footer holding a progress bar reading add AED to order and get free delivery above a View basket button.
The component in place. It lives in the docked footer, under the basket CTA, where the decision is actually being made.

Everything after that is making one small component survive two platforms, two writing systems and every basket value a customer can reach.

The anatomy

The anatomy specification for the progress bar, with five numbered callouts naming each element, its fill style token, its text style and its corner radii, beside the rendered component.
Five elements, each numbered, each bound to a named style rather than a value. Nothing on this sheet states a hex code.

Every element resolves to the global library; nothing on the sheet states a hex. Two of the five are instances of components someone else owns, recorded so a change upstream has a known blast radius.

Spacing is a scale, not a number

The layout and spacing specification, showing redlines marking a 16 pixel side margin labelled with the S spacer token, and vertical spacer instances measuring the gaps between the bar, the message and the button.
Redlined against the spacer scale. The margin is labelled S, so it moves when the scale moves.

The margins are redlined as S, not as 16. A number is a decision someone repeats on every screen. A token is a decision made once.

Acceptance criteria, because a state is not a picture

The written acceptance criteria for the component, in given, when and then form, covering the case where the basket does not meet the minimum after a discount is applied, the case where it still does not meet it, and the case where it does.
The criteria as written for engineering. Three branches, each with what the customer is told and what the basket CTA shows.

Three outcomes, written rather than drawn, because the discount interacts with the threshold:

  • Basket below the minimum after the discount: say how much more to add.
  • Still below after more items: same message, updated number.
  • Basket meets it: say free delivery is unlocked, and the bar vanishes.

That last clause gets missed. A full bar that stays on screen is a component still asking for something it already has.

Motion and the Arabic mirror

The behaviour specification, showing the bar at several fill levels with the rule that it moves 11.4 pixels for every dirham spent, and an Arabic right to left variant where the message and the Pro badge swap sides.
Movement as a rate, and the mirror. Both on the sheet, so neither was invented during the build.

The rate: 11.4px per dirham, so the fill is correct at every basket value, not only the two I happened to draw.

The mirror: message and badge swap sides, the fill runs from the right, and the type moves to the Arabic scale. Specified beside the English, not in a follow-up.

Two hard calls inside one small component

Working with engineering on a release cadence

On mobile the specification is the deliverable, and the release cadence is why.

  • Acceptance criteria written with engineering, not handed to them. The discount interaction surfaced in that conversation rather than in QA.
  • Upstream dependencies named on the sheet, so a change has a known blast radius.
  • One review before the build, one after, against the states, in both writing systems, on a real device.
  • Arabic reviewed by someone who reads Arabic. Part of the definition of done, not a follow-up ticket.
  • The fix lands in the component, never on the screen. Patching the screen is how a component ends up with four versions.

Why this is the sheet I would show

The smallest thing in the project, and the one where every decision is written down: what each part is called, what it binds to, how fast it moves, what it says in three situations, and what it does in a second writing system. A web component can be fixed in an afternoon. A Flutter build ships to an app store and waits.

Revisions

Δ1
Anatomy numbered, every element bound to a named global style.
Δ2
Spacing redlined against the spacer scale rather than typed as numbers.
Δ3
Movement defined as a rate, so engineering did not invent one.
Δ4
Acceptance criteria written for all three basket outcomes.
Δ5
Arabic mirror specified beside the English, not after it.