GH GambleHub

Progress and status indicators

1) Principles

1. Instant response (≤ 100 ms). Any action is immediately confirmed visually: pressing the 'busy '/skeleton/microanimation →.
2. Honesty and predictability. Percentages reflect real progress, not "eternal 99%." If evaluation is not possible, use an indeterminate variant and explanation.
3. Context next to the activity. The indicator is where the user is looking/acting (button, card, block), not in the far corner.
4. Stealth after success. Success is a short check/fade and that's it. Error - understandable explanation and safe repetition.
5. Default availability. 'role = "progressbar"', 'aria-valuenow', live regions, contrast ≥ AA.

2) Types of indicators and when to use them

Linear progress (determine/indeterminate). Loading/importing/exporting, steps with clear scope.
Circular progress (usually indeterminate). Short local operations in compact places.
Stepper (step-by-step). Sequential steps ("Step 2 of 4"), KYC, master processes.
Skeleton (skeleton plugs). To substitute the content structure instead of spinners; avoid "shimmer" for users with 'prefers-reduced-motion'.
Status badges (success/warning/danger/info). The state of the object (In Process, Rejected, Ready).
Banner/status toast. Global events: offline, server failure, queue synchronization.

Inline loader (button/line). Local operations: "Save...," "Send...."

3) Definite vs uncertain progress

Determine: the amount of work is known → we show %/stages.
Indeterminate: unknown volume → "Processing in progress..." + context ("Usually up to 1-2 minutes").
State transition - You can start with indeterminate → go to determine when the evaluation appears.

ETA carefully: show the range ("~ 30-60 seconds") and avoid "promises."

4) Placement and patterns

Locally to action: 'aria-busy' button, spinner in table row, card progress.
Above the block/list: linear bar below the section header during batch operations.
Global: top subtle progress (route-change), system banners.
Sticky panel (mobile) : confirmation/progress on CTA in the lower dock.

5) Availability (A11y)

Progress:
html
<div role = "progressbar" aria-valuemin =" 0" aria-valuemax =" 100" aria-valuenow =" 42" aria-label = "Load Report "> </div>

Indeterminate: set 'role = "progressbar"' without 'aria-valuenow', add explanatory text to 'role = "status"'.
Live regions: 'aria-live = "polite"' for regular updates, 'assertive' for critical ones only.
'aria-busy = "true" 'on a container that is temporarily blocked by actions.
Focus does not "jump": when changing the stage, move the focus to the stepper step header.

6) Copywriting and visual semantics

Briefly and in the case: "Loading in progress...," "Processing payment...."

Add "what's next": "Done. Let's refresh the page automatically.
Colors: green - success, orange - warning/attention, red - error. Color ≠ the only medium of meaning: give an icon/text.

7) Upbeat updates and pullbacks

Optimistic: we change the UI immediately (for example, the "Favorites" mark) and quietly confirm it with the server.
In case of error - soft rollback + explanation and'Retry '.
Critical operations (rate/payment): optionally "soft optimistic" (fix "Sent → Waiting for confirmation..."), but without changing the monetary condition before confirmation.

8) Queues and background tasks

Show the queue: 'n' tasks in processing, individual cards with progress.
Pause/cancel for long operations if possible.
Background processing: "In the background" badge, toast upon completion, "Task history" section.

9) Performance and timings

First reaction ≤ 100ms: use skeleton/inline-busy instead of void.
Animations: 120-180 ms (in), 80-140 ms (out), only 'transform/opacity'.
Long processes: updating progress no more than 10-15 times/sec; Group changes.

10) Snippets

Local progress at the button

html
<button id="export" class="btn" aria-busy="false">Экспорт CSV</button>
<script>
const btn = document. getElementById('export');
btn. addEventListener('click', async () => {
btn. setAttribute('aria-busy','true'); btn. disabled = true;
try {
const r = await fetch('/api/export', { method:'POST' });
if(!r.ok) throw new Error();
//show toast "Export has begun. We will notify upon readiness"
} catch {
//toast with cause and Retry
} finally {
btn. disabled = false; btn. setAttribute('aria-busy','false');
}
});
</script>

Linear determine

html
<div class="progress">
<div class="bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"></div>
</div>
<style>
.progress{height:4px; background:var(--bg-muted); border-radius:999px; overflow:hidden}
.progress. bar{height:100%;width:0%;background:var(--accent); transition:width. 16s}
</style>
<script>
const bar = document. querySelector('.progress. bar');
let n=0; const t=setInterval(()=>{ n=Math. min(100, n+5); bar. style. width=n+'%'; bar. setAttribute('aria-valuenow',n); if(n===100) clearInterval(t); },160);
</script>

Stepper

html
<nav aria-label = "Progress">
<ol class="steps">
<li class = "done "> <span> 1 </span> Data </li>
<li class = "current" aria-current = "step "> <span> 2 </span> Documents </li>
<li> <span> 3 </span> Confirmation </li>
</ol>
</nav>

11) Skeleton correct

Use the form of future content (cards/lines), without endless shimmer (or disable with 'prefers-reduced-motion').
Time limit: if loading> 300-500 ms, skeleton is justified; with lower delays, "micro-fade" is enough.

12) Status badges (object states)

Examples are Draft, In Process, Pending Confirmation, Ready, Rejected.

Short text, stable icon/background colors, contrast ≥ AA.
Icon' aria-hidden =" true"' + text label (for SR).

Click - reveal details or open "History."

13) The specifics of iGaming

Rate:
  • Pressing CTA → "Sent...," with a delay of> 3 seconds - "Waiting for confirmation..." (indeterminate).
  • Success - "Bet accepted" + check; error - honest explanation ("market period closed/ratio changed") and safe Retry.
Deposit/withdrawal:
  • Determine by stages: "Check method → Send → Confirm PSP."
  • For output - In process badge, status screen in profile, ETA range; push on completion.
Tournaments/leaderboards:
  • Registration stepper (steps), progress to award (N/points), "Participating" status badge.
  • Real-time update - neat, no blinks, with 'aria-live = "polite"'.
KYC:
  • Stepper + badge "Under Review." Show what is already accepted (tick) and what is left.

14) Colors, contrast and text

Success/Info/Warning/Danger - four stable tones in the design system.
Text contrast to badge background ≥ AA.

Do not use the same color for "in process" and "warning."

15) Metrics

Time-to-First-Feedback (TTFF): click to first visual response.
Completion Time on operations and drop/abort rate for long tasks.
Retry success rate for progress operations.
% of optimists who completed successfully (and the share of rollbacks).
Visible time skeleton/spinner (goal: as little as possible).

16) Anti-patterns

Silent button (no busy/spinner)> 100 ms.
Infinite spinners without explanation or alternative.
False percentage/99% hung slider.
Resets content on failure and cannot be retried.
Only color without text/icons for status.
Progress is far from the action (user does not see).

17) Design system tokens (example)

json
{
"progress": {
"barHeight": 4,
"radius": 999,
"inMs": 160,
"outMs": 120,
"pollHz": 10
},
"status": {
"tones": { "success": "#", "info": "#", "warning": "#", "danger": "#" },
"badge": { "radius": 8, "px": "6 10", "icon": 14 }
},
"skeleton": {
"rowHeight": 16,
"gap": 8,
"reduceMotion": true
},
"a11y": {
"useAriaBusy": true,
"live": "polite",
"contrastAA": true
}
}
CSS presets:
css
.badge{display:inline-flex; gap:6px; align-items:center; padding:6px 10px; border-radius:8px; font-size:.875rem}
.badge--success{background:var(--bg-success); color:var(--on-success)}
.skeleton{background:linear-gradient(90deg, var(--sk1), var(--sk2), var(--sk1)); border-radius:8px}
@media (prefers-reduced-motion: reduce){.skeleton{background:var(--sk1)} }

18) QA checklist

Response and honesty

  • TTFF ≤ 100 ms; there is a local busy/skeleton.
  • Determine - real%; indeterminate - with an explanation.

Availability

  • 'role = "progressbar" '/' aria-valuenow' correct; live regions on updates.
  • Contrast of badges/text ≥ AA; color is not the only bearer of meaning.

Behavior

  • Optimistic with correct rollback and explanation.
  • Queues are displayed; there is a cancellation/pause (if applicable).
  • Progress near the scene does not overlap the CTA.

Performance

  • Updates no more than 10-15 times/sec; 'transform/opacity 'animations.
  • Skeleton does not tease shimmer with'reduce-motion'.

Texts

  • Short, without technical jargon; "what next" after completion.
  • No "promises" of exact time unless guaranteed.

19) Documentation in the design system

Компоненты: `ProgressBar`, `ProgressCircle`, `Stepper`, `StatusBadge`, `InlineLoader`, `Skeleton`.
Rules for selecting type, copywriting and colors for statuses.
Patterns: optimistic, queues, background processing, offline synchronization.
Do/Don't gallery: "perpetual spinner," false percentages, "mute" CTA vs good TTFF.

Brief Summary

Indicators of progress and status should provide timely, honest and accessible feedback. Place them alongside the action, distinguish between definite and uncertain progress, respect a11y and don't abuse animations. In iGaming, this is especially important for betting, payments, tournaments and KYC - calm, predictable progress directly increases trust and conversion.

Contact

Get in Touch

Reach out with any questions or support needs.We are always ready to help!

Telegram
@Gamble_GC
Start Integration

Email is required. Telegram or WhatsApp — optional.

Your Name optional
Email optional
Subject optional
Message optional
Telegram optional
@
If you include Telegram — we will reply there as well, in addition to Email.
WhatsApp optional
Format: +country code and number (e.g., +380XXXXXXXXX).

By clicking this button, you agree to data processing.