Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 24, 2025

Addresses three UX improvements: better category naming, hero banner implementation with content overlay, and light/dark mode switching with enhanced accessibility.

Changes

  • Category rename: Generic Julia PackagesUtility Libraries

    • Added emoji icons to all categories (⚛️, 🕸️, 🔧)
  • Hero banner implementation: Integrated banner.svg as a hero section with content overlay

    • Banner serves as background with overlaid hero content
    • Content positioned on left side to avoid overlapping with banner's built-in text (which appears on the right)
    • Scrolls behind the sticky header as user scrolls down
    • Uses Next.js Image component for optimal performance
    • Gradient overlay for better text readability
    • Responsive heights: 400px (mobile), 500px (tablet), 600px (desktop)
    • Hero content includes:
      • Main heading: "Open-Source Quantum Many-Body Physics"
      • Subtitle: "High-quality software tools for researchers and students"
      • Tagline: "From first principles to scalable computation"
  • Theme toggle: Added accessible light/dark mode switcher in header

    • ThemeProvider: React context with lazy state initialization to prevent theme flash
    • ThemeToggle: Button component with sun/moon icons and enhanced accessibility
    • SSR-safe implementation with proper window checks
    • Validates localStorage values before applying theme
    • Accessibility features:
      • aria-pressed attribute indicates current theme state
      • Dynamic aria-label announces the toggle action to screen readers
      • Neutral placeholder background prevents hydration mismatch
// Lazy initialization prevents theme flash on load
const [theme, setTheme] = useState<Theme>(() => {
  if (typeof window === "undefined") return "light";
  
  const savedTheme = window.localStorage.getItem("theme");
  if (savedTheme === "light" || savedTheme === "dark") {
    return savedTheme;
  }
  
  const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
  return isDark ? "dark" : "light";
});

Screenshots

Hero Banner - Light Mode (Content positioned left):

Hero Banner - Dark Mode (Content positioned left):

Original prompt

This section details on the original issue you should resolve

<issue_title>Some changes</issue_title>
<issue_description>1. Find a better name for "generic julia packages"
2. Use this banner in the website:
Image
3. Add a switch between light and dark mode</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

… theme toggle

Co-authored-by: AFeuerpfeil <36232041+AFeuerpfeil@users.noreply.github.com>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 24, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
manybodylabwebsite 866d78c Dec 24 2025, 11:11 PM

Co-authored-by: AFeuerpfeil <36232041+AFeuerpfeil@users.noreply.github.com>
@AFeuerpfeil AFeuerpfeil marked this pull request as ready for review December 24, 2025 22:24
Copilot AI review requested due to automatic review settings December 24, 2025 22:24
Removed icons from categories in packages.ts.
Copilot AI changed the title [WIP] Update website banner and add theme switcher Rename package category, simplify banner, add theme toggle Dec 24, 2025
Copilot AI requested a review from AFeuerpfeil December 24, 2025 22:25
Copy link

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

This pull request implements three key improvements to the ManyBodyLab website: renaming the package category for better clarity, simplifying the banner section, and adding a theme switcher for light/dark mode support.

  • Renamed "Generic Julia Packages" to "Utility Libraries" with corresponding emoji icons added to all categories
  • Simplified the banner from a rotating carousel to a clean, static banner with gradient background
  • Implemented a complete light/dark mode theme system with toggle button, localStorage persistence, and system preference detection

Reviewed changes

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

Show a summary per file
File Description
src/data/packages.ts Updated category name from "Generic Julia Packages" to "Utility Libraries" and added emoji icons (⚛️, 🕸️, 🔧) to all three categories
src/app/theme-provider.tsx Created theme context provider with localStorage persistence, input validation, and system preference fallback
src/app/theme-toggle.tsx Added theme toggle button component with sun/moon icons and hydration safety checks
src/app/page.tsx Simplified rotating banner to static banner, added ThemeToggle to header navigation, and removed banner carousel logic
src/app/layout.tsx Wrapped application in ThemeProvider to enable theme context throughout the app

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 35 to 40
const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
localStorage.setItem("theme", newTheme);
document.documentElement.classList.toggle("dark", newTheme === "dark");
};
Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

The toggleTheme function should check if window is defined before accessing localStorage and document, similar to the useEffect. This prevents potential SSR errors if the function is somehow called during server-side rendering.

Copilot uses AI. Check for mistakes.
<button
onClick={toggleTheme}
className="p-2 rounded-lg bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
aria-label="Toggle theme"
Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

The theme toggle button should have an aria-pressed attribute or similar ARIA attribute to indicate the current theme state to screen readers. Consider adding aria-pressed={theme === "dark"} or updating the aria-label to indicate the current state, such as aria-label={Switch to ${theme === "light" ? "dark" : "light"} mode}.

Suggested change
aria-label="Toggle theme"
aria-pressed={theme === "dark"}
aria-label={`Switch to ${theme === "light" ? "dark" : "light"} mode`}

Copilot uses AI. Check for mistakes.
// Prevent hydration mismatch by not rendering until mounted
if (!mounted) {
return (
<div className="p-2 rounded-lg bg-gray-100 dark:bg-gray-800 w-9 h-9" />
Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

The placeholder div uses dark mode classes (dark:bg-gray-800) but during SSR/initial render, the dark class won't be applied to the html element yet. This could cause a visual inconsistency during hydration. Consider using a neutral background color that works in both themes, or matching the expected initial theme state.

Suggested change
<div className="p-2 rounded-lg bg-gray-100 dark:bg-gray-800 w-9 h-9" />
<div className="p-2 rounded-lg bg-gray-100 w-9 h-9" />

Copilot uses AI. Check for mistakes.
Comment on lines 15 to 39
const [theme, setTheme] = useState<Theme>("light");

useEffect(() => {
// Ensure we're on the client side
if (typeof window === 'undefined') return;

// Check localStorage for saved theme with validation
const savedTheme = localStorage.getItem("theme");
if (savedTheme === "light" || savedTheme === "dark") {
setTheme(savedTheme);
document.documentElement.classList.toggle("dark", savedTheme === "dark");
} else {
// Fall back to system preference
const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const initialTheme = isDark ? "dark" : "light";
setTheme(initialTheme);
document.documentElement.classList.toggle("dark", isDark);
}
}, []);

const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
localStorage.setItem("theme", newTheme);
document.documentElement.classList.toggle("dark", newTheme === "dark");
Copy link

Copilot AI Dec 24, 2025

Choose a reason for hiding this comment

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

The theme state is initialized to "light" (line 15) but then immediately changed in the useEffect based on localStorage or system preference. This could cause a flash of light theme before switching to dark theme. Consider using a lazy initializer or storing the theme in a cookie/header to enable SSR with the correct initial theme, or add a script tag in the HTML head to apply the theme class before React hydration.

Suggested change
const [theme, setTheme] = useState<Theme>("light");
useEffect(() => {
// Ensure we're on the client side
if (typeof window === 'undefined') return;
// Check localStorage for saved theme with validation
const savedTheme = localStorage.getItem("theme");
if (savedTheme === "light" || savedTheme === "dark") {
setTheme(savedTheme);
document.documentElement.classList.toggle("dark", savedTheme === "dark");
} else {
// Fall back to system preference
const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const initialTheme = isDark ? "dark" : "light";
setTheme(initialTheme);
document.documentElement.classList.toggle("dark", isDark);
}
}, []);
const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
localStorage.setItem("theme", newTheme);
document.documentElement.classList.toggle("dark", newTheme === "dark");
const [theme, setTheme] = useState<Theme>(() => {
if (typeof window === "undefined") {
return "light";
}
const savedTheme = window.localStorage.getItem("theme");
if (savedTheme === "light" || savedTheme === "dark") {
return savedTheme;
}
const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
return isDark ? "dark" : "light";
});
useEffect(() => {
if (typeof window === "undefined") return;
document.documentElement.classList.toggle("dark", theme === "dark");
}, [theme]);
const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
if (typeof window !== "undefined") {
window.localStorage.setItem("theme", newTheme);
}

Copilot uses AI. Check for mistakes.
@AFeuerpfeil
Copy link
Member

@copilot
Use the new banner.svg file

Co-authored-by: AFeuerpfeil <36232041+AFeuerpfeil@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 24, 2025

@copilot
Use the new banner.svg file

Done! The website now uses the banner.svg file. The banner displays beautifully with "From First Principles to Scalable Computation" and the wave visualization. Changes committed in e0cdf48.

Light Mode:
Light Mode

Dark Mode:
Dark Mode

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • workers.cloudflare.com
    • Triggering command: /usr/local/bin/node node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/.bin/next build (dns block)
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/next/dist/compiled/jest-worker/processChild.js (dns block)
    • Triggering command: /usr/local/bin/node node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/.bin/next dev (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@AFeuerpfeil
Copy link
Member

@copilot
Please don't just put the banner in, use it either as a background of some of the content, as a banner that by scrolling down disappears below the header or just use it as a background of the header.

Copilot AI changed the title Rename package category, simplify banner, add theme toggle Rename package category, add banner.svg, and implement accessible theme toggle Dec 24, 2025
Co-authored-by: AFeuerpfeil <36232041+AFeuerpfeil@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 24, 2025

@copilot
Please don't just put the banner in, use it either as a background of some of the content, as a banner that by scrolling down disappears below the header or just use it as a background of t...

Done! The banner is now integrated as a hero section with content overlaid on it. The banner scrolls behind the sticky header as you scroll down the page. Changes committed in c3f7b5f.

Hero section at top of page:
Hero Banner

Banner scrolling behind the sticky header:
Scrolled View

Dark mode:
Dark Mode

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • workers.cloudflare.com
    • Triggering command: /usr/local/bin/node node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/.bin/next build (dns block)
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/next/dist/compiled/jest-worker/processChild.js (dns block)
    • Triggering command: /usr/local/bin/node node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/.bin/next dev (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@AFeuerpfeil
Copy link
Member

@copilot
This looks very good, but the content on top of the image interferes with the text of the image.
You can probably solve this easily: The text of the image is mostly on the right side, so there is space in the middle for the content on top.

Copilot AI changed the title Rename package category, add banner.svg, and implement accessible theme toggle Rename package category, create hero section with banner.svg, and implement accessible theme toggle Dec 24, 2025
Co-authored-by: AFeuerpfeil <36232041+AFeuerpfeil@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 24, 2025

@copilot
This looks very good, but the content on top of the image interferes with the text of the image.
You can probably solve this easily: The text of the image is mostly on the right side, so t...

Fixed! The hero content is now positioned on the left side, leaving the middle and right areas clear for the banner's text. The overlaid content no longer interferes with the banner's "From First Principles to Scalable Computation" text. Changes committed in 866d78c.

Light mode:
Light Mode

Dark mode:
Dark Mode

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • workers.cloudflare.com
    • Triggering command: /usr/local/bin/node node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/.bin/next build (dns block)
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/next/dist/compiled/jest-worker/processChild.js (dns block)
    • Triggering command: /usr/local/bin/node node /home/REDACTED/work/manybodylabwebsite/manybodylabwebsite/node_modules/.bin/next dev (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@AFeuerpfeil AFeuerpfeil merged commit 253976d into main Dec 25, 2025
3 of 4 checks passed
@AFeuerpfeil AFeuerpfeil deleted the copilot/update-website-banner-and-themes branch December 25, 2025 09:50
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.

Some changes

2 participants