Skip to content

Case study · Android + iOS

Shikhar

Rebuilding the order flow of Hindustan Unilever's direct-to-retailer app around how a shopkeeper actually buys.

Catalogue and offers, cart, order summary and assisted ordering, for the kirana owners who restock 20 to 40 lines between customers.

Client
Hindustan UnileverThrough Red Baton
Industry
B2B commerceFMCG · Kirana retail
Role
Product DesignerInteraction · UX flows · UI
Year
2025–26Android + iOS
Offers in one row
Margin first
Built for forty lines
Points per distributor
Shikhar home screen with a persistent green call button in the bottom corner

Shikhar had the surface of a consumer shopping app and the workload of a wholesale order desk.

Nearly every friction point I found came out of that one mismatch.

1 Mn+

App installs

$100 Mn+

Transactions processed

Platform figures published by Red Baton: scale context, not outcomes of this work.

Scope
Catalogue & offers, cart,
order summary, assisted ordering
Context
Red Baton, for Hindustan Unilever
Through to development handoff
Note
All data shown is placeholder,
used for demonstration
.01

Context

The person on the other end is restocking a shop, not shopping.

Shikhar is HUL’s ordering app for kirana stores, the small neighbourhood shops that sell most of India’s FMCG. The owner opens it to restock: detergent, shampoo sachets, tea, soap, the inventory his shop runs on. He orders directly from the brand instead of waiting on a distributor’s salesman.

He is not browsing. He has a rough list in his head, a margin he needs to hit, and a customer at the counter. Three things about him shaped every decision on this project:

  1. .01

    He buys to resell

    The first number he reads is not the price. It’s the margin. Price only matters relative to what he can charge for it.

  2. .02

    His basket is 20–40 lines

    Not three. Every consumer cart pattern I inherited was designed for a basket a tenth of that size, and it showed.

  3. .03

    He is interrupted constantly

    He orders between customers, one-handed, mid-shift. Any flow that needs two uninterrupted minutes gets abandoned.

Thread 01 · Catalogue & offers

The promotions were eating the catalogue.

On the listing screen every product carried its schemes as stacked full-width rows underneath it: “Get additional 3% off per unit”, “Get Flat Rs.50 OFF on Bill of Rs.500”. Two schemes roughly doubled the height of a product card. Merchandising adds schemes weekly, so the layout got worse over time and no designer was in that loop.

The effect on a 360px screen: a retailer scanning for one SKU saw barely two products at a time, and most of what he scrolled past was promotional copy rather than products. The offers were not helping him decide. They were standing between him and the decision.

The old product listing: every scheme stacked as a full-width row under the product, so two products fill the screen
≈ 310 px

Before

Two schemes per product, stacked full width. Card height varies with promotion count.

25%

shorter card pitch, so more catalogue per screen

The new product listing: offers sit in one horizontal row inside each card, and every card is the same height
231 px

After

Schemes collapsed into one horizontal row. Card height is now constant at 231 px.

The new product listing: offers sit in one horizontal row inside each card, and every card is the same height

Schemes collapsed into one horizontal row. Card height is now constant.

The decision

Make the card height independent of how many schemes a product carries.

Offers move into a single horizontal carousel inside the card. One row, fixed height, whether the SKU has one scheme or five. The generic “APPLY” link becomes a selectable chip with a tick, because a retailer stacking three schemes needs to see which ones he has already taken, not re-read the terms each time.

The property I actually cared about: merchandising can now add promotions without changing the layout. That removes a recurring design dependency, which is the same problem I was solving on the campaign dashboard side of this account.

Thread 02 · Cart

A cart built for three items, holding forty.

The cart used the pattern every shopping app uses: one long vertical list of line items, with everything else stacked below it. That works when the basket is three products. A kirana restock is thirty.

At that size, everything the retailer actually needs before paying (his redeemable points, the bill breakdown, the total) sat several thousand pixels down the page. Functionally they did not exist. He was being asked to scroll past his own order to find out what it cost.

The cart: the order list scrolls inside a fixed-height region, with a pill counting five more products, suggestions and shop points below
  1. .01

    The order list scrolls inside itself

    A fixed-height region holds the line items. The page below it stays short and reachable, no matter how many products are in the basket.

  2. .02

    A count, not just a gradient

    A floating “5 more products ↓” pill sits over the bottom edge. A scroll region nested in a scrolling page is easy to miss entirely. The pill announces it and says how much is left.

  3. .03

    Points surface in the first fold

    Because the list no longer runs the length of the page, the retailer can see unspent Shop points before he pays rather than after. Previously that was unreachable without deliberate scrolling.

  4. .04

    Suggestions placed after commitment

    “You may also like” sits below the order, not inside the catalogue. The cart is the one screen where he has already decided and is reviewing: the right moment to offer an adjacent SKU. The wrong one is mid-search.

Thread 03 · Order summary

For this buyer, the bill is the product.

A retailer’s question at checkout is not “what does this cost”. It is “what do I make on this, and what did I actually save”. That information already existed in the system (retailer margin, scheme discounts, platform discounts, points earned) but it arrived as a single number with no working shown.

So the summary became an expandable ledger: total MRP, items total, retailer margin, scheme discount with a count of how many offers fired, Shikhar discount, total savings, total payable, points earned.

Order summary collapsed: points, per-distributor balances and the amount to pay, visible without expanding

Points and payable visible without expanding. Per-distributor balances sit directly under the redemption row.

Order summary

7 items · 2 distributors

Total MRP
₹7,440
Items total
₹7,440
Retailer margin
₹636
Scheme discount(3 offers applied)
₹83
Shikhar discount
₹200
Total savings
₹919
Total payable
₹6,701
Points earned(4 offers applied)
200

You are saving ₹836 on this order

Why expandable

Collapsed by default, because the routine reorder should stay fast. Expandable, because the retailer who wants to audit the arithmetic really wants to audit it. If the app will not show him, he will rebuild it on paper.

The detail I’d defend hardest

Loyalty points are shown per distributor, not pooled.

A kirana owner buys through more than one distributor, and his points balance is held separately with each of them. A single pooled figure would have been cleaner, calmer, and wrong: he would have tried to redeem against a distributor where the balance was not there, and discovered it at payment.

So the sheet splits it: MS Distributor and Laxmi Enterprises, each with points used and balance remaining. It is a denser row than I would have liked. It is also the row that keeps the number trustworthy, and in a margin-driven purchase, trust in the number is the whole thing.

Balance held by MS DistributorBalance held by Laxmi Enterprises

Thread 04 · Assisted ordering

The interface was competing with a phone call, and losing.

A real share of retailers were not ordering in the app at all. Some were not comfortable with it. Many more were simply too busy to assemble a thirty-line order on a phone between customers. Their fallback was to call the distributor’s sales rep, who knew the catalogue and could take the order in a minute of speech.

The tempting fix was to make the app easier until the call stopped happening. I did not believe that would work. The call is faster than any interface, forgiving of a half-remembered SKU, and happens in the retailer’s own language. What the call lacked was a record: an order placed by a rep left the retailer with nothing to check.

So rather than compete with it, I brought the call inside the product and gave it the one thing it was missing.

Shikhar home screen with a persistent green call button in the bottom corner

Step 1 of 4, Entry: Shikhar home screen with a persistent green call button in the bottom corner

What is actually in the sheet

Four lines that each remove one reason not to press the button.

That last line is a promise made on one screen and kept on another. It is why the My Orders screen got a phone marker and a Shikhar / Sales Rep filter, and why I would treat those two screens as a single piece of work rather than two tickets.

  1. So he knows whether to wait or try tomorrow.

  2. Removes the single biggest reason people avoid calling a helpline.

  3. So he is not holding.

  4. The trust clause. Someone else is about to place an order on his account, and he needs to know he can check it afterwards.

Interlude · Seasonal identity

The icon changes for Holi.

A festival variant of the app icon: a rangoli ring and gulal bowls around the existing mountain mark.

This is the smallest piece of work in the project and one of the few that touches the retailer before he opens anything. The icon sits on a home screen next to WhatsApp and a payments app, in a business relationship that is otherwise entirely transactional: stock in, margin out.

Marking the festival is the cheapest affinity gesture available to a supply-chain product, and it is legible at 60px without touching the brand mark's geometry. The constraint I set was that the base logo does not change, only what surrounds it, so the variant never competes with recognition.

The Holi icon on an iPhone home screen, next to everyday appsOn a home screen
Shikhar's Holi app icon: the mountain mark inside a rangoli ring, with bowls of gulal in front
.05

Trade-offs

What I chose not to do.

The decisions I argued against are a better description of the work than the ones I shipped.

  • Didn’t hide margin behind a tap

    It is the retailer’s primary decision input, and the most common request from the business was to give that space to promotional messaging. Margin stays on the card at rest.

  • Didn’t leave the offer carousel on autoplay

    Only first-time users see it rotate. Permanent motion sitting two centimetres from a price is a legibility problem, and this is a screen people read numbers off.

  • Didn’t rebuild the catalogue’s information architecture

    It was the obvious big-ticket redesign and it was not where the friction was. The friction was card density and checkout comprehension.

  • Didn’t build voice ordering

    The obvious answer for low digital literacy in India. But a callback to a human who already knows the catalogue was cheaper to build, more reliable with mixed Hindi-English SKU names, and, crucially, already the behaviour retailers had. I would rather formalise an existing habit than train a new one.

.06

Outcomes

What shipped, and what changed.

All four flows were live business requirements, went into development, and shipped. The changes below are structural: you can verify every one of them against the screens above without taking my word for it.

  1. 01

    4 flows, end to end

    Catalogue and offers, cart, order summary, and assisted ordering, specified through to development handoff, including empty, applied, confirmed and error states.

  2. 02

    231 px

    Fixed product card height, down from a card that grew with every scheme attached to a SKU. Merchandising can now add promotions without the layout degrading.

  3. 03

    25% shorter card pitch

    Vertical distance between products fell from roughly 310px to 231px, so more of the catalogue is visible per screen at the same scroll cost.

  4. 04

    Constant, not linear

    Scroll depth to reach the bill and points used to grow with every line item added. It is now fixed regardless of whether the basket holds five products or forty.

    BeforeAfterDepth to the bill, by line items
  5. 05

    2 taps to reach a human

    Requesting assisted ordering went from leaving the app to find and dial a rep, to a persistent button and a single confirmation.

  6. 06

    One order history, two sources

    Rep-placed and app-placed orders now land in the same list with a source filter, so an order placed on the retailer’s behalf is auditable by him.

What I’d hold it to

Three numbers would settle whether the structural wins became behavioural ones.

Products viewed per catalogue session, points-redemption rate at checkout, and cart abandonment above twenty line items. The last is the one I’d watch hardest: the entire cart argument rests on large baskets failing, and that is where it would show.

.07

What I took from it

In consumer products the interface competes with another interface. In B2B it usually competes with a phone call.

The phone call is fast, forgiving of a half-remembered name, and conducted in the user’s own language. Anything that loses on those three gets routed around, and no amount of visual polish changes that. The parts of this project I am most confident about are the ones that either beat the call on its own terms (density, arithmetic you can check) or stopped trying to and absorbed it instead.

All interface data shown is placeholder, used to demonstrate the design. Some details simplified for confidentiality.

Next case study

Steer: the design system behind Readywire's showroom floor

Read it
The Readywire Home screen on a laptop against a warm red backdrop

Facing a similar problem?

Start a project