Skip to main content

FlowPOS Frontend PWA — Theming & Styling Guide

Reference for anyone restyling the apps/frontend-pwa/ app in light or dark mode.

Overview

The PWA is built with Vite 6 + React 19 + Shadcn/ui + Tailwind CSS. All colors flow through CSS custom properties (HSL variables) defined once in a single stylesheet and mapped into Tailwind's theme. Because every Shadcn component reads from these variables, a complete restyle is concentrated in just a few files — no component internals need to change.


Primary files — the "big three"

These three files cover ~95% of a full visual overhaul.

1. apps/frontend-pwa/src/index.css — The main file

Defines all design tokens as HSL triplets:

  • :root { ... }light mode variables (starts around line 7)
  • .dark { ... }dark mode overrides (starts around line 48)

Tokens defined here:

GroupVariables
Surfaces--background, --foreground, --card, --card-foreground, --popover, --popover-foreground
Brand--primary, --primary-foreground, --secondary, --secondary-foreground
States--muted, --muted-foreground, --accent, --accent-foreground, --destructive, --destructive-foreground
Chrome--border, --input, --ring
Sidebar--sidebar, --sidebar-foreground, --sidebar-primary, --sidebar-primary-foreground, --sidebar-accent, --sidebar-accent-foreground, --sidebar-border, --sidebar-ring
Shape--radius
Charts--chart-1--chart-5

Changing values here propagates to every Shadcn component automatically.

2. apps/frontend-pwa/tailwind.config.js

  • darkMode: ["class"] — dark mode is toggled by adding/removing the .dark class on the root element (don't change unless switching strategy).
  • theme.extend.colors — maps every token to hsl(var(--...)). Edit here to add new color tokens or change the borderRadius scale.
  • Includes tailwindcss-animate plugin and accordion keyframes.
  • Add a fontFamily extension here when introducing custom typography.

3. apps/frontend-pwa/src/App.css

Legacy Vite starter CSS with a couple of .dark rules (.read-the-docs, #root layout). Audit and trim during a restyle — it can override your new theme in subtle ways.


Secondary files

Touch only if the restyle requires it.

FileWhat it controls
apps/frontend-pwa/components.jsonShadcn generator config: baseColor (currently slate), style, CSS variable mode. Edit only when changing the Shadcn baseline.
apps/frontend-pwa/index.htmlGoogle Material Symbols Rounded font <link> (lines 8–11). Edit when swapping icon or text fonts.
apps/frontend-pwa/src/tours/tours.cssDriver.js tour overlay styles. These are independent of Shadcn tokens — update manually if the restyle needs to cover tour popovers.
apps/frontend-pwa/postcss.config.jsStandard Tailwind + Autoprefixer pipeline. No changes needed for a restyle.

Theme toggle machinery — reference only

These files wire up dark mode correctly and should not need edits during a restyle.

  • apps/frontend-pwa/src/contexts/ThemeProvider.tsx — React context that adds/removes the .dark class on the root element and exposes useTheme().
  • apps/frontend-pwa/src/components/common/ThemeToggle.tsx — Sun/Moon header button that calls useTheme().

  1. Draft your new palette as HSL triplets (e.g. 222 47% 11%).
  2. Replace the values inside :root and .dark in src/index.css.
  3. If adding tokens not already in the set, register them in tailwind.config.js under theme.extend.colors.
  4. Update --radius in index.css for a different corner-roundness feel.
  5. Audit and clean up App.css leftovers.
  6. If typography changes, add the font in index.html and extend fontFamily in tailwind.config.js.

Gotchas

  • HSL triplet format — values in :root/.dark are raw triplets (222 47% 11%), not hsl(...) wrappers and not hex. Tailwind wraps them. Pasting hsl(...) or hex there silently breaks colors.
  • Keep :root and .dark in sync — both blocks must define the same variable names. Adding a token to :root without a .dark counterpart causes dark mode to fall back to inherited/undefined values.
  • components.json path mismatch — it references tailwind.config.ts while the real file is tailwind.config.js. No runtime impact, but the shadcn CLI may warn when running npx shadcn add. Fix opportunistically.
  • Tour overlay is independentsrc/tours/tours.css uses its own Driver.js classes and won't automatically follow your new Shadcn tokens.

Verification

pnpm --filter frontend-pwa run dev   # starts on port 5173
  1. Toggle between light and dark via the header Sun/Moon button.
  2. Confirm all core Shadcn surfaces pick up the new tokens: buttons, cards, dialogs, popovers, inputs, sidebar.
  3. Spot-check screens with custom color usage: sale form, discount modal, tour overlays.