←  back to the desk

COLOUR
PALETTE

Kargo 360 App A2A & D2D UX Redesign Air Cargo Ops

Making Complex Air-Cargo Operations Visible, Predictable, And Easier To Execute.

Kargo360 is a two-sided operational product: A2A for airside flight and manifest operations, and D2D for pickups, trucking and delivery. The redesign focused on the hidden workflow underneath the UI — and on making that workflow legible to the people operating it.

245

screen captures audited

2

apps redesigned

8

workflow rules uncovered

role

UX research, IA, interaction & UI design

scope

2 mobile apps — A2A & D2D

method

Heuristic audit, task analysis, IA rebuild

tools

Figma, ChatGPT

Hand holding a phone with the redesigned Kargo360 home screen against an airport cargo apron at dusk

Brief

Air cargo moves through a chain of custody, and at every handover somebody has to tell a system what just physically happened. A ULD arrives. It gets broken down. Pieces get assigned to a cart, a cart to a flight, a flight to a manifest. On the road, a pickup is assigned, collected, consolidated into a motherbag, trucked, and delivered.

Kargo's two apps cover both halves of that chain — A2A airside and D2D on the road — and the same company's staff move between them.

The brief was not simply to modernise the interface. It was to make the product usable by people wearing gloves, standing up, in a hurry, without relying on training to explain what the system was doing.

119

field captures

126

engineering screens

40+

fields on the worst screen

So the design question

How might we make the workflow visible, so the app stops teaching by punishment?

The core insight

The software already knew the workflow. It just never told anybody.

The Audit

I worked from two independent inventories: 119 captures taken in the field and the engineering team's own 126-screen build deck. Together they covered both apps end to end — crucially including error and success states, where the real evidence turned out to be.

I ran a heuristic evaluation and grouped findings by severity. The same issues repeated across otherwise different modules, which suggested a systemic problem rather than isolated UI defects.

Critical Severity Issues

Visibility of system statusThe app did not show where a shipment or ULD was in its lifecycle. States such as arrived, broken, assigned and manifested only became visible when an action failed.
Error preventionInvalid actions were enabled and rejected afterwards. Eight distinct sequencing rules surfaced only as red toasts.
Match with the real worldScreens were named after database operations such as Break ULD, Re-Assign and Export Manifest. Fields used internal labels such as POL, POU, Flt stat and Rem Cat.
Recognition over recallAirport codes appeared bare, related weight fields were not differentiated, and controlled codes were often typed from memory.

Serious Severity Issues

Aesthetic & minimalist designBooking, HAWB and DGR were long scrolling forms with similarly weighted inputs and little grouping or prioritisation.
Help users recover from errorsValidation could turn multiple fields red at once with generic Required messaging, while feedback toasts could cover the active area.
User control & freedomDestructive actions were buried in text-only menus and confirmed with generic Yes / Cancel language that hid consequences.
Four legacy screens: booking with eight errors, dangerous goods form, hidden delete menu, feedback bar covering the action button
Eight errors at once

Destination, Consignee, Customer, Customer Name, Commodity, SHC, Pieces, Gross Wt — all red, all "Required*".

Dangerous goods

Eleven fields — UNID, SHC, Class, ERG Code, Sub Risk, Rem Cat — with no explanation of any of them.

Delete, hidden

The destructive action lives in a three-item text menu with no icon, colour or separation.

Feedback in the way

The success bar lands on top of the floating action button you just used.

The Root Cause

The error messages were the specification. Auditing the failure states is where the project turned. The errors were not random. Each one encoded a business rule the software already knew, revealed only after the user broke it.

Please arrive first.

The app knows the ULD has not arrived. Surface that state on the card and make Arrive the obvious next step.

Cannot Unarrive Broken Uld

A broken ULD cannot move backward in the lifecycle. That rule should disable the control and explain why.

ULD(s) already arrived.

The desired outcome has already happened. What looks like an error is actually missing status.

Flight must first be manifested

The system already has a sequence: build → manifest → depart. The interface simply never draws it.

Please select VIA ULD(s) only.

The system knows which rows are legal. Filter them, or make the others visibly unavailable.

Select Bulk AWB for Offload

The action needs a prerequisite. Keep the primary action disabled until the missing requirement is satisfied.

what those six rules add up to

Read together, the errors describe a complete state machine. The software enforced it perfectly; the interface rendered it nowhere.
arrivebreakassigncartmanifestdepart

The reframe

I stopped designing screens and started drawing the process the system already runs. That is why the redesign begins with information architecture, not UI.

Who’s holding the Phone

Nobody is sitting down. Both apps are used in the field, and the field is hostile to the interface patterns the old product relied on: tiny two-column inputs, text-only menus and transient toasts. I designed around three recurring operator contexts.

RRamp agentA2A · airside

"i just need to know if this ULD is ready to break."

  • Gloves on; phone in one hand; engine noise
  • Sunlight on the screen
  • Blocked by rules the UI never showed

NEEDStatus at a glance, and only the actions that are legal right now.

DPickup driverD2D · on the road

"accept or reject — and if i reject, why?"

  • Needs the customer address first
  • Jobs arrive one at a time
  • Rejection reasoning matters to operations

NEEDOne decision-ready card, batch actions, structured reasons.

BBooking deskA2A / D2D

"i know the shipper. i don't know the ERG code."

  • Multiple sources of information
  • High call volume
  • Controlled codes typed from memory

NEEDEnter what is known now, and look the rest up.

Environment is the requirement

A two-column input is a desk pattern. On an apron in daylight with gloves on, the usable unit is a card you can read at arm's length and a button you can hit without looking.

What I decided

Four rules, applied to both apps.

name screens after the job, not the table.

Break ULD, Re-Assign and Export Manifest describe system operations. D2D's journey-based vocabulary showed that the company could already speak in user tasks — so the problem was solvable in-house, not inherent to freight.

make the state machine visible.

Status moves onto the object: shipment cards carry a state chip and an ETA, ULD rows carry their lifecycle stage, and actions that are not legal yet are disabled rather than allowed-then-refused. The eight error messages become eight pieces of interface.

split the wall into rooms.

Booking sub-entities become focused sheets layered over the booking, so users keep context. The form is split into find the shipment and describe the shipment.

never make users translate.

Airport codes carry city names underneath. Navigation labels stay visible. Code fields become searchable pickers instead of memory tests.

A2A, the flow end to end: schedule search, named routes, structured re-assignment, cart and ULD building, confirmation, finalisation

Rebuilding A2A

A2A is the harder of the two because the domain genuinely is complex: a cart holds pieces, a ULD holds carts, a flight holds ULDs, and a manifest describes the flight. The old interface flattened those relationships into repeated input rows.

The redesign gives each operational object a clear identity, data hierarchy, state, and set of legal actions.

the object model, drawn once

This is the diagram the old app never showed. Containment runs outside-in, and every level carries its own state — which is exactly what the error messages were policing.
Flighta scheduled departure, DL1 → BO2
plannedmanifesteddeparted
ULDthe container loaded onto the aircraft
in transitarrivedbroken
Carta build unit inside the ULD
emptybuilt
AWB & piecesthe shipment itself — 775-60230715
unassignedassignedoffloaded

Manifest sits alongside rather than inside: it describes a flight's contents at a point in time, which is why "flight must first be manifested" was a sequencing rule and not a property of any one object.

Patterns that Scale

Break ULD is a useful example because the underlying data did not change. The redesign focused on legibility, grouping and interaction quality on a screen that could be used on an apron.

Labels above the field

The same values are presented as a proper form: label, then input, at a size that can be hit confidently.

Selection is an explicit action

The checkbox becomes a real touch target, because selection is the first thing the user needs to do.

Actions leave the overlap zone

Menus open as focused sheets rather than fragments squeezed out from underneath a floating action button.

Destructive action names the consequence

Instead of Yes, the destructive button says what it does. The confirmation explains what happens to the associated AWBs.

Feedback gets out of the way

Success and error states take over the screen or use non-blocking placement, instead of covering the field or action the user needs next.

break uld, before and after

beforeafter
Break ULD screen before and after the redesign
Labels inside the border

Every label is a 10px notch cut into the outline of its own box, and the only action, "Save", escapes from behind the FAB and lands half on top of the navigation.

Labels above the field

The same values, set as a proper form. The card groups what belongs to one AWB; nothing floats over anything; the checkbox is a real target.

and the dialog that appeared everywhere

Legacy delete confirmation: Are you sure you want to delete this Uld? Cancel / Yes
What it said

"Are you sure you want to delete this Uld?" — a default OS alert, with the destructive choice rendered as the plain word Yes, at exactly the same visual weight as Cancel.

What it didn't say

A ULD contains AWBs. Deleting it unassigns all of them — the consequence the person actually needs to weigh. The dialog never mentions them.

What replaced it

The verb replaces "Yes", so the button says what it does. The safe option is outlined, the destructive one filled — equal size, unequal weight. And the outcome takes the whole screen with one way onward.

Rebuilding D2D

D2D was where restraint mattered more than invention. Its information architecture was already correct: Booking, Firstmile, Trucking, Motherbag and Lastmile. Re-architecting it would have destroyed useful muscle memory.

So I kept the structure and changed what the structure could communicate: priority, state, movement and next action.

beforeafter
D2D home before, five identical tiles on a gradient, and after, illustrated cards with active shipments
The right five things

on a magenta-to-orange gradient, as five identical tiles, with no status, no priority and no way to tell what's urgent.

The same five things, able to speak

Illustrated cards you can distinguish at a glance, then the two things the old home never showed: what's moving now, and what just happened.

Redesigned D2D home screen with four annotations: one primary action, journey modules, active shipments, a persistent activity feed
1. One primary action

"What would you like to book today?" and a single Book Now. The old home opened on an unlabelled tile grid with no stated purpose.

2. Journey modules

The inherited modules, now each with an illustration and a subtitle in the driver's language. Same IA — finally distinguishable at arm's length.

3. Active shipments

A state chip, a From→To line and an estimated delivery. The single biggest answer to "visibility of system status".

4. A persistent activity feed

Picked up, in transit, delayed — colour-coded and scrollable. Feedback you can go back to, instead of a bar that disappears.

The pickup card

beforeafter
My Pickup card before and after the redesign
Decode it yourself

Bare codes, uniform grey labels, an address wrapping mid-word, and a success bar parked over the next card.

Read it at a glance

The route is drawn, not encoded; the address gets room to breathe; Reject and Confirm carry equal width but unequal weight.

assignment and structured reasons

Structured reasons and bulk assignment both already existed — more sound thinking buried under its own presentation. The reason picker was an inline block that appeared mid-card, pre-flagged red, before the driver had done anything.

D2D Assign Pickup flow: multi-select, one assignment, a real confirmation

So the redesign keeps the logic and rebuilds the moment: assignment moves into a sheet with its own two decisions and nothing competing; the reason list becomes a clean radio set where remarks appear only for Other; and the outcome takes the whole screen instead of sliding over the card you were reading.

Recognition over recall

Special Handling Codes are controlled operational vocabulary. The legacy experience gave users a text box and expected recall. The redesign makes them searchable and multi-selectable in a focused sheet.

beforeafter
SHC code entry before, a typed field, and after, a searchable multi-select sheet
A text box and a hope

"SHC Code*" sits as a typed field among fourteen others — recalled from memory, validated only on submit.

Search, then select

A searchable checklist in a sheet over the booking you're already in. Multi-select, because shipments routinely carry more than one code.

Why this matters

This is the difference between an interface that assumes expertise and one that supplies it. In a domain where the wrong code can become a safety issue, recognition over recall is not a usability nicety.

The system is visible

The whole project reduces to one change in the order of events.

Before — reacting to mistakes

  1. Attempt action
  2. System rejects it
  3. User interprets error
  4. User tries again

↻ and repeats, once per shift, for years

After — communicating state

  1. System exposes state
  2. Only valid actions are available
  3. User understands the next step
  4. Task is completed

✓ no interpretation required

What changed

Across both apps, the redesign shifts the interface from reacting to mistakes to communicating the operational state that makes those mistakes predictable.

What i’d test next

The redesign is grounded in a 119-screen field audit, the engineering build deck, and domain reasoning. It has not yet been validated on an apron or in a live driving context. I would keep that limitation explicit rather than claiming outcomes the project has not measured.

The next research sprint would watch four ramp agents and two drivers complete real work, then measure the moments where the redesigned state model is expected to matter most.

Illegal-action attempts per shift

~0

Should trend toward zero, because invalid actions are now prevented rather than repeatedly refused.

Break-and-assign completion time

new vs experienced

Compare new and experienced operators on a critical A2A workflow.

Booking abandonment

drop-off

Measure whether structured sub-flows reduce drop-off on the multi-entity booking task.

Time to first successful manifest

new starter

Test whether the visible sequence helps a new starter reach a complete manifest faster.

Closing thought

Good enterprise UX does not remove complexity. It makes the right complexity visible at the right moment.

Kargo360 gave me a useful reminder: complex operational products do not become usable by hiding the domain. They become usable when the interface exposes the domain model clearly enough that people can act without translating the system in their head.

The portfolio takeaway

I did not redesign two apps screen by screen. I audited the evidence, uncovered the hidden state machine, rebuilt the information architecture around the user's work, and used the UI to make the system's existing logic visible.