Skip to content

notification banner

A slide-down system-style toast that surfaces a background update with sound and haptic feedback. Modeled on iOS/Android notification banners — pinned to the top of the device, dismissible by tap or auto-hide.

Background work the user previously parked has reached an actionable state — and the user might be looking at an unrelated screen or talking to a customer. They need a peripheral signal that pulls focus without blocking what they’re doing.

Companion to [[parked-queue]]: the queue card shows the persistent state, the banner surfaces the moment of change.

Not for: success confirmations of in-flight actions (use a [[bottom-sheet]] success modal), validation errors (use [[inline-alert]]), persistent state (use a [[status-card]]).

┌──────────────────────────────────────────┐
│ [✓] Adekunle just funded ₦12,000 › │
│ Tap to resume swap │
└──────────────────────────────────────────┘
  • Banner pinned at top: 38px (below status bar), left/right: 10px, z-index: 90.
  • Surface: rgba(20, 20, 20, 0.95) with backdrop-filter: blur(12px). White text. 14px radius (--r-xl). Shadow 0 8px 24px rgba(0,0,0,0.18).
  • Icon container: 32px rounded square (8px radius) — exception to the global “circular icon containers” rule, matches the platform notification idiom. Background var(--g-primary), white 14px icon.
  • Title: 12.5px / 700 white. Subtitle: 11px / 400, rgba(255,255,255,0.7).
  • Trailing chevron: rgba(255,255,255,0.5), 14px.
  • Enter: transform: translateY(-150%) → translateY(0), transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1).
  • Sound: Two-tone web-audio beep on appear (880Hz + 1108Hz, 0.15s apart, sine wave). Wrap in try { … } catch {} — autoplay restrictions vary.
  • Haptic: navigator.vibrate([60, 40, 60]) if available.
  • Auto-hide: 8 seconds.
  • Tap: dismiss + perform the implied action (e.g. resume the parked swap).
  • Stacking multiple banners — collapse to the most recent. The queue is the durable record; the banner is just the prod.
  • Persistent banners that don’t auto-dismiss — that’s a [[inline-alert]] in disguise.
  • Banner-only updates without a corresponding queue/status update somewhere — the banner is a notice, not the state.
  • Loud / multi-tone alarm sounds — keep beeps short and pitched, not aggressive.

See .notif-banner + JS showNotification() / playBeep() in products/rechaj-swap-app/prototypes/support-cases-v2.html.