Skip to content

Add dark mode to democracy/desktop#732

Open
Copilot wants to merge 5 commits intomasterfrom
copilot/add-dark-mode-democracy-desktop
Open

Add dark mode to democracy/desktop#732
Copilot wants to merge 5 commits intomasterfrom
copilot/add-dark-mode-democracy-desktop

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 10, 2026

  • Explore democracy/desktop codebase structure
  • Enable darkMode: 'class' in tailwind.config.js
  • Create useTheme hook with localStorage + system preference detection
    • Guard all localStorage access in try/catch (Safari private mode safe)
    • Export STORAGE_KEY constant to share with _document.tsx
    • Remove unused setTheme dead code
    • Add initialized flag; set to true after first effect run
  • Add anti-FOUC blocking script to _document.tsx using shared STORAGE_KEY
  • Add dark mode toggle button (sun/moon icon) to Navigation with dark: variants
    • Render toggle only when initialized === true to avoid hydration icon mismatch
  • Create logo-text-dark.svg — white-text version for dark mode
  • Update Navigation to swap logo in dark mode (light → dark logo)
  • Update Main template with dark mode styles
  • Update Card component with dark mode styles
  • Update FilteredPage template with dark mode styles
  • Update details page with dark mode styles
  • Update Filters component with dark mode styles
  • Update FilterDropdown component with dark mode styles
  • Update DonateDialog with dark mode styles
  • Update ChartPair component with dark mode styles
  • Update global.css with dark mode base HTML background
  • TypeScript type-check passes
  • ESLint passes
Original prompt

Start implementation

The user has attached the following file paths as relevant context:

  • .github/copilot-instructions.md
[Chronological Review: The conversation began with the user requesting the addition of a dark mode to the democracy/desktop project, emphasizing the need for good aesthetics and readability of text. The user was working within the context of the garden.yml file, specifically focusing on the configuration related to the "democracy-desktop" target.]

[Intent Mapping: The explicit user request was to "add a dark mode to democracy/desktop that looks good and ensures all text is readable." This indicates a focus on UI/UX improvements for the desktop application.]

[Technical Inventory: The conversation involved the garden.yml configuration file, which is used for managing build and deployment settings in the project. The user is working with a deployment target named "democracy-desktop."]

[Code Archaeology: The user is currently editing the garden.yml file, particularly lines related to the deployment configuration for "democracy-desktop." The relevant sections include manifest templates, default target settings, sync paths, and resource patches.]

[Progress Assessment: The user has not yet implemented the dark mode feature; the request is still pending. The current state is focused on understanding the existing configuration before proceeding with the dark mode implementation.]

[Context Validation: All critical information for continuation is captured, including the user's request for a dark mode and the specific file being edited.]

[Recent Commands Analysis: The last agent commands involved retrieving the contents of the garden.yml file, specifically focusing on the "democracy-desktop" target. The tool results included the configuration details of the file, which are essential for understanding how to implement the requested dark mode. The agent was actively working on providing context from the garden.yml file when the token budget was exceeded.]

1. Conversation Overview: - Primary Objectives: The user requested to "add a dark mode to democracy/desktop that looks good and ensures all text is readable." - Session Context: The conversation has focused on the user's intention to enhance the UI of the democracy/desktop application by implementing a dark mode, with specific attention to aesthetics and readability. - User Intent Evolution: The user's needs have remained consistent, centered around improving the visual design of the application.
  1. Technical Foundation:
  • Core Technology: Garden (a build and deployment tool) is being used to manage the project.
  • Framework/Library: The project is structured using YAML configuration for deployment settings.
  • Architectural Pattern: The deployment target is defined in the garden.yml file, which includes sync paths and resource patches.
  1. Codebase Status:
  • File Name: garden.yml
  • Purpose: This file is crucial for defining the build and deployment settings for the democracy/desktop application.
  • Current State: The user is currently focused on the section related to the "democracy-desktop" deployment target.
  • Key Code Segments: The file includes settings for manifest templates, default target, sync paths, and resource patches.
  • Dependencies: The configuration directly impacts how the application is built and deployed.
  1. Problem Resolution:
  • Issues Encountered: No specific technical problems have been reported yet; the focus is on the implementation of the dark mode.
  • Solutions Implemented: None yet, as the request is still in the planning phase.
  • Debugging Context: No ongoing troubleshooting efforts have been mentioned.
  • Lessons Learned: The importance of aesthetics and readability in UI design has been highlighted.
  1. Progress Tracking:
  • Completed Tasks: No tasks have been completed regarding the dark mode implementation.
  • Partially Complete Work: The user is in the process of planning the dark mode feature.
  • Validated Outcomes: No features have been confirmed working through testing yet.
  1. Active Work State:
  • Current Focus: The user is working on the garden.yml file to prepare for the dark mode implementation.
  • Recent Context: The user has been reviewing the configuration settings for the "democracy-desktop" target in the garden.yml file.
  • Working Code: The relevant code segments from the garden.yml file have been retrieved for context.
  • Immediate Context: The user is preparing to implement a dark mode feature for the application.
  1. Recent Operations:
  • Last Agent Commands: The agent retrieved the contents of the garden.yml file, focusing on the "democracy-desktop" target.
  • Tool Results Summary: The results included the configuration details for the deployment target, which are essential for understanding how to implement the dark mode.
  • Pre-Summary State: The agent was actively providing context from the garden.yml file when the token budget was exceeded.
  • Operation Context: T...

Created from VS Code.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Add dark mode to democracy desktop for improved readability Add dark mode to democracy/desktop Mar 10, 2026
@ManAnRuck ManAnRuck force-pushed the copilot/add-dark-mode-democracy-desktop branch from 7150a3c to 875d61e Compare March 10, 2026 21:01
@ManAnRuck ManAnRuck marked this pull request as ready for review March 10, 2026 21:17
Copilot AI review requested due to automatic review settings March 10, 2026 21:17
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dark-mode implementation to the democracy/desktop Next.js app using Tailwind’s dark: variants, with pre-paint theme application to avoid FOUC and a UI toggle in the navigation.

Changes:

  • Enable Tailwind darkMode: 'class' and add base background styling for html/html.dark.
  • Introduce a useTheme hook and an inline _document script to apply the theme early and persist preference.
  • Apply dark: variants across key UI components (navigation, cards, filters, details, dialogs, charts).

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
democracy/desktop/tailwind.config.js Enables class-based dark mode for Tailwind.
democracy/desktop/src/utils/useTheme.ts Adds theme hook with persistence + applying dark class.
democracy/desktop/src/styles/global.css Sets base background for html and html.dark.
democracy/desktop/src/pages/_document.tsx Injects blocking inline theme script + dark body background.
democracy/desktop/src/templates/Main.tsx Adds dark-mode text/footer styling.
democracy/desktop/src/components/molecules/Navigation.tsx Adds theme toggle button + dark nav/search styles.
democracy/desktop/src/components/molecules/Card.tsx Adds dark card background/border/text styling.
democracy/desktop/src/components/templates/FilteredPage.tsx Adds dark header + sticky group header background.
democracy/desktop/src/pages/[...details].tsx Adds dark styling for details panel, text, dividers, docs list.
democracy/desktop/src/components/molecules/Filters.tsx Adds dark styling for filter panel, dividers, labels, checkboxes.
democracy/desktop/src/components/molecules/FilterDropdown.tsx Adds dark dropdown/menu item styling.
democracy/desktop/src/components/organisms/DonateDialog.tsx Adds dark dialog background/text + focus ring offset.
democracy/desktop/src/components/molecules/ChartPair.tsx Adds dark chart container + ring background/text styling.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +15 to +20
const getInitialTheme = (): Theme => {
if (typeof window === 'undefined') return 'light';
const stored = localStorage.getItem(STORAGE_KEY) as Theme | null;
if (stored === 'dark' || stored === 'light') return stored;
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
};
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getInitialTheme/toggleTheme call localStorage.getItem/setItem without guarding for unavailable/throwing storage (e.g. Safari private mode, disabled storage). In this codebase donateDialogStorage explicitly checks typeof window !== 'undefined' && window.localStorage and wraps storage calls in try/catch; doing the same here would prevent the theme hook from crashing the app on mount or click.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in a56488b. All localStorage access in useTheme.ts is now wrapped in try/catch (matching the pattern in donateDialogStorage.ts). The STORAGE_KEY constant is now exported and imported into _document.tsx so the key is defined in one place and can't drift.

Comment on lines +108 to +118
<button
type="button"
onClick={toggleTheme}
className="rounded-md p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-ci-blue dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200"
aria-label={theme === 'dark' ? 'Zu hellem Modus wechseln' : 'Zu dunklem Modus wechseln'}
>
{theme === 'dark' ? (
<SunIcon className="h-5 w-5" aria-hidden="true" />
) : (
<MoonIcon className="h-5 w-5" aria-hidden="true" />
)}
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The theme toggle’s icon/aria-label depends on theme from useTheme, but useTheme initializes state to 'light' and only syncs to the real theme in an effect. When the pre-paint _document script applies html.dark, the first render can briefly show the wrong icon/label (e.g. dark theme applied but button says “switch to dark”). Consider exposing an initialized flag from the hook and rendering the toggle only after initialization, or deriving the initial value from document.documentElement.classList in a way that avoids hydration mismatch.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7888c7c. useTheme now exposes an initialized flag that becomes true after the first effect run. The toggle button in Navigation is only rendered when initialized === true, so the icon/aria-label are never shown with stale SSR state — no hydration mismatch.

Comment on lines +5 to +12
const themeScript = `
(function() {
try {
var stored = localStorage.getItem('democracy-theme');
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (stored === 'dark' || (!stored && prefersDark)) {
document.documentElement.classList.add('dark');
}
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The localStorage key 'democracy-theme' is duplicated here and in useTheme.ts (STORAGE_KEY). Consider importing a shared exported constant (or exporting the key from useTheme.ts) so the inline script and hook can’t drift if the key ever changes.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in a56488b_document.tsx imports STORAGE_KEY from useTheme.ts and interpolates it into the inline script, so the key is defined in one place.

@ManAnRuck
Copy link
Copy Markdown
Member

TODO: das democracy logo sollte noch ausgetauscht werden im dark mode damit der Schriftzug nicht schwarz auf dunkel sondern weiß ist.

Copilot AI and others added 3 commits March 10, 2026 23:59
Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
…gation

Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@ManAnRuck ManAnRuck force-pushed the copilot/add-dark-mode-democracy-desktop branch from 2119d3b to 9fc3ca6 Compare March 10, 2026 23:00
…e logo

Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 10, 2026

TODO: das democracy logo sollte noch ausgetauscht werden im dark mode damit der Schriftzug nicht schwarz auf dunkel sondern weiß ist.

Done in a56488b. Added logo-text-dark.svg — a copy of the logo with the text path changed from fill="#000" to fill="#fff". The Navigation now shows the light logo in light mode and the white-text logo in dark mode using Tailwind's dark: display utilities.

…e render

Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants