Files
shihaam 2f5659f3ff
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 8s
document the ui
2026-08-02 18:44:46 +05:00

5.8 KiB

Design System

Everything needed to reproduce the visual look of the SAR Link Portal. The UI is built on shadcn/ui (style: new-york, base color: neutral, icon set: lucide) over Tailwind CSS v4 (CSS-first config — there is no tailwind.config.ts; theming lives in app/globals.css via @theme).

Brand color

Token Value Use
--color-sarLinkOrange / text-sarLinkOrange #f49b5b Primary brand accent — page headings, logo text, highlights, top loader
Pattern orange (dark) #e06f10 Diagonal SVG background pattern (opacity 0.35)
Pattern orange (light) #f49b5b .title-bg SVG background pattern (opacity 0.1)

The brand orange is used mainly as an accent on top of a neutral (grayscale) shadcn palette — it is not the shadcn --primary. Primary/secondary/muted etc. remain the default neutral shadcn tokens.

Theme tokens

Colors use the oklch color space, neutral base. Defined as CSS variables in app/globals.css under :root (light) and .dark (dark). Standard shadcn token set:

--background --foreground --card --card-foreground --popover --popover-foreground --primary --primary-foreground --secondary --secondary-foreground --muted --muted-foreground --accent --accent-foreground --destructive --border --input --ring plus a sidebar group --sidebar --sidebar-foreground --sidebar-primary --sidebar-accent --sidebar-border --sidebar-ring.

Key values:

  • Light: --background: oklch(1 0 0) (white), --foreground: oklch(0.145 0 0) (near-black), --primary: oklch(0.205 0 0).
  • Dark: --background: oklch(0.145 0 0), --foreground: oklch(0.985 0 0), --primary: oklch(0.922 0 0).
  • Radius: --radius: 0.625rem, with sm/md/lg/xl derived (calc(var(--radius) ± n)).
  • App background (body): bg-gray-100 light / bg-black dark (set in root layout).

Dark mode is class-based (@custom-variant dark (&:is(.dark *))) via next-themes (attribute="class", default system).

Custom utility classes (in app/globals.css)

  • .title-bg — subtle diagonal SVG pattern in brand orange at 0.1 opacity. Used behind page-heading blocks and auth/login cards to give the faint textured background.
  • A second diagonal-line SVG pattern using #e06f10 at 0.35 opacity.

Typography

Two Google fonts loaded in app/layout.tsx as CSS variables:

Font Variable Weights Use
Barlow --font-barlow (also the font-sans body font) 100,300,400,500,600,700,800,900 Body text, UI, everything by default
Bokor --font-bokor 400 Display / decorative headings (brand)
mono --font-mono Monospace bits (e.g. "Profile Status" label)

Body element applies ${barlow.variable} ${bokor.variable} antialiased font-sans.

Tailwind plugins in use

tailwindcss-animate, @pyncz/tailwind-mask-image, tailwindcss-motion. Animations also via motion (Framer Motion) — used by the welcome banner and some transitions. TextShimmer component for shimmer loading states.

Status color conventions

These recur across badges and table rows (payments, topups, devices, users). Reproduce consistently:

State Color Typical classes
Paid / Verified / Credit / success green / lime bg-green-500 text-white, bg-lime-*, green row tint
Pending / awaiting yellow bg-yellow-500 text-white, yellow row tint
Failed / Cancelled / Rejected / Debit red bg-red-500 text-white, destructive buttons
Expired gray gray row tint / muted
Unknown yellow bg-yellow-500
Active device (until date) green accent brand/green text
Inactive / blocked red / muted red text, block dialog

Recurring layout patterns

  • Page heading block — a flex row with a dashed border, title-bg background, rounded, text-sarLinkOrange text-2xl heading on the left, optional status/action on the right. (See profile, most list pages.)
  • Dual list layout — every list screen renders an HTML <table> on desktop and a stack of cards on mobile (MobilePaymentDetails, MobileTopupDetails, MobileTransactionDetails, device-card), showing the same data. Footer shows Total N item(s). and pagination.
  • Read-only field grid — labeled read-only values in a responsive grid (grid-cols-1 sm:grid-cols-2 md:grid-cols-3), used by profile & user details.
  • Drawers (shadcn drawer/vaul) — device cart, wallet top-up, and filter panels open as bottom/side drawers.
  • Filter drawer + active-filter chips — filters applied to URL query params (via nuqs), shown as dismissible badges.
  • SkeletonsDevicesTableSkeleton and per-route loading.tsx files provide loading UI; FullPageLoader for full-screen spins.
  • CountdownExpiryTimeCountdown shows Time left: … with a progress bar for unpaid payments/topups, ticking every second.

App shell (authenticated)

Rendered by components/auth/application-layout.tsx:

  • Sidebar (AppSidebar) on the left inside SidebarProvider — see navigation.md.
  • Sticky header (h-16, border-b, sticky top-0, z-10): left = sidebar trigger + separator; right = Wallet balance button, theme toggle, account popover.
  • WelcomeBanner — animated "Welcome, {first} {last}" that auto-hides after 4s.
  • DeviceCartDrawer — floating cart (hidden on payment pages).
  • Main contentp-4, rounded, bg-background, wrapped in NuqsAdapter for URL state.

Auth-page shell

app/(auth)/auth/layout.tsx: centered full-screen container (bg-gray-100 light / bg-black dark) holding a single card. Login card uses title-bg and a border-2 border-sarLinkOrange/50 rounded-lg shadow.

Global chrome

  • NextTopLoader — top progress bar, color #f49d1b (orange), no spinner.
  • Toaster (sonner, richColors) — all success/error toasts.