Skip to content

Full-width desktop layout, improved light/dark mode theming across all pages#1309

Merged
pethers merged 16 commits intomainfrom
copilot/improve-css-light-dark-mode
Mar 20, 2026
Merged

Full-width desktop layout, improved light/dark mode theming across all pages#1309
pethers merged 16 commits intomainfrom
copilot/improve-css-light-dark-mode

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 20, 2026

  • Inspect current review feedback and reproduce any test/lint issues
  • Update tests/theme-toggle.test.js to guarantee timer cleanup (afterEach) and remove potential pending timers
  • Re-run targeted lint/tests for theme-toggle changes
  • Check CI workflow status/logs for the mentioned quality-check context
  • Run final code review and security scan, then reply on PR comment with commit hash and screenshot URL

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@github-actions github-actions Bot added the size-xs Extra small change (< 10 lines) label Mar 20, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🏷️ Automatic Labeling Summary

This PR has been automatically labeled based on the files changed and PR metadata.

Applied Labels: size-xs

Label Categories

  • 🗳️ Content: news, dashboard, visualization, intelligence
  • 💻 Technology: html-css, javascript, workflow, security
  • 📊 Data: cia-data, riksdag-data, data-pipeline, schema
  • 🌍 I18n: i18n, translation, rtl
  • 🔒 ISMS: isms, iso-27001, nist-csf, cis-controls
  • 🏗️ Infrastructure: ci-cd, deployment, performance, monitoring
  • 🔄 Quality: testing, accessibility, documentation, refactor
  • 🤖 AI: agent, skill, agentic-workflow

For more information, see .github/labeler.yml.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…ling

- Remove max-width: 1200px constraint from body (use full viewport width)
- Update all container elements to max-width: 100%
- Improve light theme: better card elevation, background, borders
- Improve dark theme: better card hover effects, backdrop blur, footer styling
- Dashboard: full-width container, improved metric card hover effects
- Cards grid: use auto-fit with 1fr for natural full-width expansion

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions github-actions Bot added dashboard Interactive dashboards (Chart.js/D3.js) html-css HTML/CSS changes size-m Medium change (50-250 lines) labels Mar 20, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…, consistent hover effects

- Restore vertical padding on body (var(--spacing-md))
- Cap cards grid max column width to 480px to prevent ultra-wide cards
- Cap value-metrics grid max column width to 420px
- Add consistent translateY hover effect to dark theme metric cards

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copilot AI changed the title [WIP] Improve CSS for light and dark mode on desktop and mobile Full-width desktop layout, improved light & dark mode CSS Mar 20, 2026
Copilot AI requested a review from pethers March 20, 2026 10:17
… article dark/light mode

- Tighten breadcrumb spacing (padding, margin, font-size)
- Reduce header bottom margin for better vertical rhythm
- Reduce dashboard section margins for tighter layout
- Add smooth theme transition for body, header, footer, cards, breadcrumb, nav
- Add light mode subtle section backgrounds for visual hierarchy
- Add comprehensive news article dark/light mode overrides
- Add light mode AI newsroom section and footer overrides
- Improve mobile body padding for small screens
- Optimize footer padding/margins
- Reduce dashboard metrics-grid margin

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions github-actions Bot added the size-l Large change (250-1000 lines) label Mar 20, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…ard border transition, simplify dark gradients

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copilot AI changed the title Full-width desktop layout, improved light & dark mode CSS Full-width desktop layout, improved light/dark mode theming across all pages Mar 20, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers pethers marked this pull request as ready for review March 20, 2026 10:39
Copilot AI review requested due to automatic review settings March 20, 2026 10:39
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 20, 2026

@copilot analyse and improve code quality and test [Quality Checks / typescript-lint (pull_request)](https://github.com/Hack23/riksdagsmonitor/actions/runs/23341947676/job/67897450696?...

Fixed in 33e75a8. The no-useless-assignment error was in tests/theme-toggle.test.js:401 — the second timer = setTimeout(...) in the rapid-toggle test was never read afterward. Removed the unnecessary assignment since the timer ID is only needed for the preceding clearTimeout check, not captured again. All 37 theme-toggle tests pass, 0 lint errors.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Comment on lines +353 to +362
it('adds theme-transition class on toggle', () => {
buildButton();
applyTheme('light', false, storage);
const current = document.documentElement.getAttribute('data-theme') || LIGHT;
const next = current === DARK ? LIGHT : DARK;
document.documentElement.classList.add('theme-transition');
applyTheme(next, undefined, storage);
updateButton(next);
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
});
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

This test doesn't verify that the toggle behavior adds the theme-transition class because it adds the class manually (line 358) and never invokes the toggle/click handler. As written, it will pass even if the production code stops adding the class. Suggested fix: start with the class absent, trigger the same path users do (e.g., dispatch a click on the toggle button or call the toggle handler), and then assert that theme-transition is present.

Copilot uses AI. Check for mistakes.
Comment thread tests/theme-toggle.test.js Outdated
Comment on lines +401 to +406
setTimeout(function () {
document.documentElement.classList.remove('theme-transition');
}, 350);

// After 350ms from second toggle, class should be removed
vi.advanceTimersByTime(350);
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

This test can't fail if the clearTimeout guard is removed from production code: even if the first timer fires at t=350ms and removes the class prematurely, the final assertion still passes because the second timer also removes the class before the final check. Suggested fix: add an assertion at the moment the first timer would have fired (e.g., advance to ~350ms total time and assert the class is still present), then advance to 350ms after the second toggle and assert removal. Also consider assigning the second setTimeout(...) handle to timer so it mirrors the implementation and remains extensible for additional rapid toggles.

Suggested change
setTimeout(function () {
document.documentElement.classList.remove('theme-transition');
}, 350);
// After 350ms from second toggle, class should be removed
vi.advanceTimersByTime(350);
timer = setTimeout(function () {
document.documentElement.classList.remove('theme-transition');
timer = null;
}, 350);
// After 350ms from first toggle (i.e. 250ms after the second), class should still be present
vi.advanceTimersByTime(250);
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
// After 350ms from second toggle, class should be removed
vi.advanceTimersByTime(100);

Copilot uses AI. Check for mistakes.
Comment thread public/js/theme-toggle.js Outdated
const STORAGE_KEY = 'riksdagsmonitor-theme';
const DARK = 'dark';
const LIGHT = 'light';
var _transitionTimer = null;
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

In this file the surrounding declarations use const, but the new timer uses var. Using let _transitionTimer = null; avoids function-scope hoisting pitfalls and keeps the scoping consistent with modern JS patterns used elsewhere in the file.

Suggested change
var _transitionTimer = null;
let _transitionTimer = null;

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

pethers commented Mar 20, 2026

@copilot apply changes based on the comments in this thread

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 20, 2026

@copilot apply changes based on the comments in this thread

Implemented in 45ec8fa.

Applied all requested fixes from the review thread:

  • Updated tests/theme-toggle.test.js so transition tests now exercise toggle-path behavior (not manual class add/remove).
  • Strengthened rapid-toggle test with an intermediate assertion to catch premature class removal (250ms after second toggle).
  • Updated public/js/theme-toggle.js to use let _transitionTimer = null.

Validation run:

  • npx eslint tests/theme-toggle.test.js public/js/theme-toggle.js
  • npx vitest run tests/theme-toggle.test.js
  • codeql_checker (0 alerts)

Screenshot (dashboard light mode): https://github.com/user-attachments/assets/7cc6de80-0ca0-464a-8372-9e2be59d997c

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Comment on lines +369 to +377
it('adds theme-transition class on toggle', () => {
buildButton();
applyTheme('light', false, storage);
const toggle = createToggleHandler();

expect(document.documentElement.classList.contains('theme-transition')).toBe(false);
toggle();
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
});
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

The "adds theme-transition class on toggle" test schedules a real setTimeout (350ms) without using fake timers or clearing it afterward. That leaves a pending timer that can keep the event loop alive and/or mutate documentElement during later tests, causing flakiness/open-handle warnings. Use vi.useFakeTimers() for this test too (and advance/flush timers), or cancel any outstanding transition timer in an afterEach for this describe block.

Copilot uses AI. Check for mistakes.
Comment on lines +379 to +390
it('removes theme-transition class after timeout', () => {
vi.useFakeTimers();
buildButton();
applyTheme('light', false, storage);
const toggle = createToggleHandler();

toggle();
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
vi.advanceTimersByTime(350);
expect(document.documentElement.classList.contains('theme-transition')).toBe(false);
vi.useRealTimers();
});
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

These tests switch to fake timers and then manually call vi.useRealTimers() at the end. If an assertion throws before that line, the suite can stay in fake-timer mode and cascade failures into later tests. Prefer moving timer restore/cleanup into an afterEach (and consider vi.clearAllTimers()/vi.runOnlyPendingTimers()) within this describe block to guarantee cleanup even on failure.

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

pethers commented Mar 20, 2026

@copilot apply changes based on the comments in this thread

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 20, 2026

@copilot apply changes based on the comments in this thread

Implemented in 03ba07b.

Updated tests/theme-toggle.test.js to make timer handling deterministic and failure-safe:

  • Added afterEach in the theme-transition class suite to always run pending timers, clear timers, restore real timers, and reset theme-transition class.
  • Switched the “adds theme-transition class on toggle” test to fake timers to avoid leaking real setTimeout handles.
  • Removed per-test vi.useRealTimers() and centralized timer restore in afterEach so cleanup still runs if an assertion fails.

Validation run:

  • npx eslint tests/theme-toggle.test.js
  • npx vitest run tests/theme-toggle.test.js
  • codeql_checker (0 alerts)

Screenshot: https://github.com/user-attachments/assets/7cc6de80-0ca0-464a-8372-9e2be59d997c

@pethers pethers requested a review from Copilot March 20, 2026 13:21
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

@pethers pethers merged commit 041498c into main Mar 20, 2026
28 checks passed
@pethers pethers deleted the copilot/improve-css-light-dark-mode branch March 20, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dashboard Interactive dashboards (Chart.js/D3.js) html-css HTML/CSS changes javascript JavaScript code changes refactor Code refactoring size-l Large change (250-1000 lines) size-m Medium change (50-250 lines) size-xs Extra small change (< 10 lines) testing Test coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants