feat(frontend): add dark mode support with ThemeToggle closes #29 - #47
Merged
dark-sarge merged 2 commits intoAug 11, 2026
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request — Dark Mode Support (Closes #29)
Summary
Adds full dark mode support to the AirFlex frontend using Tailwind CSS's
classstrategy andnext-themesfor theme management, persistence, and FOUC prevention.Changes
New Files
frontend/app/layout.tsxThemeProvider, sets<html suppressHydrationWarning>frontend/app/globals.css@tailwinddirectives andcolor-schemetokensfrontend/tailwind.config.tsdarkMode: "class"frontend/postcss.config.jsfrontend/next.config.tsfrontend/tsconfig.jsonfrontend/package.jsonnext-themes@0.3.0frontend/components/ThemeToggle.tsxModified Files
frontend/app/page.tsxdark:variants to all elements +ThemeTogglein navbarfrontend/app/error.tsxdark:variants throughoutfrontend/app/loading.tsxdark:variants to skeleton bones and containersfrontend/app/not-found.tsxdark:variants throughoutfrontend/app/auth/layout.tsxdark:variants +ThemeTogglein headerfrontend/app/auth/signup/page.tsxdark:variants to form, inputs, labels, errorsfrontend/app/auth/verify/page.tsxdark:variants to form, inputs, bannersfrontend/app/sell/layout.tsxdark:variants +ThemeTogglein headerfrontend/app/sell/page.tsxdark:variants to form, cards, badges, alertsfrontend/app/trades/[id]/layout.tsxdark:variants +ThemeTogglein headerfrontend/app/trades/[id]/TradeDetailClient.tsxdark:variants to all UI statesHow It Works
Theme Strategy
tailwind.config.tsusesdarkMode: "class"— thedarkclass on<html>activates alldark:variants.next-themesmanages the class, persists the choice inlocalStorage, and injects an inline<script>before first paint to apply the correct theme synchronously — this prevents any flash of unstyled content (FOUC).First Visit Behaviour
defaultTheme="system"+enableSystemmeans the OSprefers-color-schemeis respected on first visit with no stored preference.ThemeToggle Component
/,/sell,/trades/[id],/auth/*).aria-labeldescribes the next action:"Switch to dark mode"/"Switch to light mode".mountedguard prevents SSR hydration mismatch — renders an invisible placeholder of the same size until the client resolves the theme.Dark Colour Mapping
bg-whitedark:bg-gray-800bg-gray-50dark:bg-gray-900text-gray-900dark:text-gray-100text-gray-700dark:text-gray-300text-gray-500dark:text-gray-400border-gray-100dark:border-gray-700bg-violet-50dark:bg-violet-900/20text-violet-700dark:text-violet-400dark:bg-*/20with lighter textAcceptance Criteria Checklist
tailwind.config.tsusesdarkMode: 'class'ThemeTogglebutton added to every navbar — togglesdarkclass on<html>localStoragevianext-themesprefers-color-schemedark:variants added for readable contrastaria-labeldescribes the current action ("Switch to dark mode" / "Switch to light mode")Testing
/,/sell,/trades/[id],/auth/signup,/auth/verify,/not-found, error boundary.Related
closes #29