Skip to main content

UI Redesign — Dark/Light Mode + Explorer Page + Slim Sidebar

Date: 2026-04-27
Project: Quantago (projects/quantago/services/frontend)

Summary​

Full UI redesign completing the Questingo-inspired sidebar pattern, dark/light mode support, and a new fullscreen Explorer page with asset selector sidebar.


Changes Made​

1. tailwind.config.js — Fixed & Added Sidebar Tokens​

  • Fixed malformed fontFamily nesting that was inside colors
  • Added sidebar color token group mapping to CSS custom properties:
    • sidebar.DEFAULT, sidebar.fg, sidebar.muted, sidebar.hover, sidebar.accent, sidebar.accent-foreground, sidebar.border

2. src/App.tsx — Slim Sidebar + Theme Application​

  • Complete rewrite of authenticated layout
  • 68px wide fixed sidebar (SIDEBAR_W = 68) — always dark regardless of app theme
  • Logo at top, <MainNav /> in middle, user avatar button at bottom (links to /settings)
  • Theme applied via useEffect on document.documentElement using useThemeStore
  • Mobile: hamburger sheet with full nav, top bar shows current page title
  • Fullscreen routes (/explorer, /trading) get no content header wrapper — they own their own header
  • Non-fullscreen routes get a slim h-12 header with the page title
  • main content area uses ml-[68px] offset on desktop via inline style
  • Removed unused signOut import (sign-out UX to be handled from settings)

3. src/components/charts/TradingViewTickChart.tsx — Theme Prop​

  • Added theme?: 'dark' | 'light' prop (default 'dark')
  • Added flush?: boolean prop — removes border/rounded corners for fullscreen use
  • Defined DARK_OPTS and LIGHT_OPTS constant objects for chart colours
  • Chart re-creates when theme changes (added to useEffect dependency array)
  • Dark: #0c0e14 bg, #181c26 grid, #00d2a8 line
  • Light: #ffffff bg, #e8ecf0 grid, #0070f3 line

4. src/routes/data-explorer/DataExplorerPage.tsx — Full Redesign​

  • Complete rewrite — fullscreen layout (flex flex-col h-full)
  • Asset catalogue with 3 classes: Forex (12 pairs), Crypto (10 coins), Stocks (10 tickers)
  • AssetSidebar component:
    • Collapsible (w-60 open, w-0 closed) with smooth CSS transition
    • Asset class tabs: Forex / Crypto / Stocks with icons
    • Search input (filters symbol label + description)
    • Symbol list with active indicator dot
    • Both dark and light colour modes
  • Slim header bar (h-11):
    • Toggle sidebar button (chevron / layers icon)
    • Symbol display label + description
    • Live Bid / Ask / Spread stat pills
    • Connection badge (RadioTower, green=live, red=offline)
  • Chart area: flex-1 fills remaining height; ResizeObserver keeps chart height accurate
  • TradingViewTickChart with flush + theme props
  • Symbol change also auto-selects the matching asset class

5. src/routes/settings/SettingsPage.tsx — Created​

  • New page at /settings with theme selector
  • 3-way choice: Light / Dark / System
  • "System" reads prefers-color-scheme and applies the matching dark/light value
  • Active option shows primary-colour ring + filled icon badge
  • Responsive sm:grid-cols-3 layout

6. src/router.tsx — Added /settings Route​

  • Import SettingsPage from @/routes/settings/SettingsPage
  • Added <Route path="/settings"><SettingsPage /></Route> before /explorer

Design Decisions​

  • Sidebar always dark: The sidebar CSS vars (--sidebar-bg etc.) are set to dark values in both :root and .dark so the sidebar is invariant to the app theme toggle — matching Questingo's design language.
  • 68px sidebar: Icon + label nav items are 48px wide (w-12) centered inside the sidebar, giving comfortable touch targets while minimising space usage.
  • Explorer fullscreen: Explorer is a special route where the app shell deliberately omits the content header so the page can own 100% of the vertical space.
  • ResizeObserver for chart height: lightweight-charts needs explicit pixel heights; using a ResizeObserver on the flex container ensures the chart always fills available space without overflow.

TypeScript​

  • Zero type errors after all changes (npx tsc --noEmit passes clean)
  • Zero ESLint warnings on modified files