Saphyroo loader, usage map

Every placement, side-by-side. Approve before any code changes ship. Two open questions: (a) Allocations empty-state size — currently 72 px (lg), proposed 48 px (md) for system consistency. (b) Table refetch — current is plain overlay (rows full opacity); proposed is row-dim (rows 50% opacity) so the loader pops while data stays readable.

Proposed system (this is the locked outcome — review for the two open Qs in red).
SurfaceVariant + sizeNotes
Inside button (Save, Send, Update mid-flight)utility sm (16 px)Replaces the action icon. Buttons disable submit + cancel.
Inline status text ("Saving…", "Searching…")utility sm (16 px)Sits next to text.
Search input async indicatorutility sm (16 px)Right-side of the input.
Table refetch (data already shown)branded md (48 px) overlay proposed: dim rows 50%Overlay with no scrim. Rows fade to 50% opacity so loader pops, data still readable.
Empty-state during first loadbranded md (48 px) proposed  currently lg on AllocationsLoader on page background, no card. Card is for empty-state copy only.
Section panel / dialog content first loadbranded md (48 px)Centred in the panel.
Full-page first-paint / auth splashbranded lg (72 px)Centred over a calm background.
Heavy compute (route optimise, fatigue rebuild)thinking md or lgOrbit + intermittent kangaroo glitch.

1. Inline + buttons — utility sm (16 px)

Inside-button spinners (Save, Send, etc.) and inline status text. Replaces the action icon during in-flight; sits next to copy.

Light surface
Searching trucks…
Dark surface
Searching trucks…

<Loader variant="utility" size="sm" /> · 16 px · 0.8 s linear

2. Table refetch — the open question approve

When a table is refetching, the existing rows should stay readable but the loader needs to be unmistakable. Three options. We had #1 (full scrim, rejected); current is #2 (no scrim, loader floats on full-opacity rows); proposed is #3 (dim rows to 50%, loader pops, data still legible).

Current — no scrim, rows full opacity
RouteDriverTruckStatus
R-1248Akash B.VFP-194Ready
R-1249Nelson V.VFP-201Ready
R-1250Nikky D.VFP-188Allocated

Loader sits cleanly on top, but on bright rows it can read as "is this thing actually loading or just sitting there?"

Proposed — rows dim to 50%, loader at full
RouteDriverTruckStatus
R-1248Akash B.VFP-194Ready
R-1249Nelson V.VFP-201Ready
R-1250Nikky D.VFP-188Allocated

Rows 50% opacity (200 ms ease) when isLoading flips, loader at full opacity. Linear / Stripe pattern.

Current — dark, no scrim
RouteDriverTruckStatus
R-1248Akash B.VFP-194Ready
R-1249Nelson V.VFP-201Ready
R-1250Nikky D.VFP-188Allocated
Proposed — dark, rows dim
RouteDriverTruckStatus
R-1248Akash B.VFP-194Ready
R-1249Nelson V.VFP-201Ready
R-1250Nikky D.VFP-188Allocated

<Loader variant="branded" size="md" /> · 48 px · loader has pointer-events:none, rows transition opacity 200ms ease

3. Empty-state during first load — the size question approve

When a page has no rows yet AND is fetching for the first time, what loader fires? Allocations currently uses 72 px (lg) which is the splash size, breaking the system. Proposal: 48 px (md) to match every other panel-level empty-state. The card chrome stays for the truly-empty copy ("no_allocations_to_show") but is dropped during the fetch — the page background carries the loader.

Current — branded lg (72 px) live now

Reads slightly oversized for a panel-level empty-state. Fine for full-page first-paint but inconsistent with section panels.

Proposed — branded md (48 px) align

Matches every other panel-level empty-state. Splash-size (lg) reserved for true full-page first-paint only.

Current dark — lg
Proposed dark — md

<Loader variant="branded" size="md" /> · 48 px on a transparent (page-bg) container

4. Empty-state with copy (no fetch) — for reference

When the page is genuinely empty and not loading, the card chrome stays. Loader is gone; copy carries the message.

Light

No allocations to show

Dark

No allocations to show

5. Section panel / dialog content — branded md

Loading inside a panel (route detail, settings panel, dialog body). Loader on the panel surface, no scrim.

Light
Loading route details
Dark
Loading route details

<Loader variant="branded" size="md" /> · 48 px

6. Full-page first-paint / auth splash — branded lg

The big moment. App boot, login splash, the cold start where the brand impression matters. This is the only place lg fires.

Light splash
Loading Drive360
Dark splash
Loading Drive360

<Loader variant="branded" size="lg" /> · 72 px

7. Heavy compute — thinking md / lg

Route optimisation, fatigue rebuild — actual processing. Same orbit as branded, plus a brief 300 ms shake on the kangaroo every 3 s. Reads "the system is reasoning".

Light, thinking md
Optimising route…
Dark, thinking md
Optimising route…

(Glitch effect not rendered in this static preview — see /design/loader/ for the full thinking variant.) <Loader variant="thinking" size="md" />

To approve, two answers needed: