Skip to content

Conversation

@White-Devil2839
Copy link

Summary

This PR adds comprehensive CSS improvements to the Mongoose documentation, including dark mode support, accessibility enhancements, and responsive design improvements. The changes improve the user experience across all devices and provide users with manual control over their preferred theme.

Motivation

The Mongoose documentation currently only supports light mode and lacks some modern accessibility features. This PR addresses:

  • User requests for dark mode support
  • Accessibility improvements (WCAG compliance)
  • Better mobile/tablet experience
  • Enhanced code readability with improved syntax highlighting

Changes Made

  • Dark Mode Support: Added automatic dark mode detection via prefers-color-scheme media query
  • Theme Toggle Button: Added manual theme toggle button in top-left corner with localStorage persistence
  • CSS Custom Properties: Implemented CSS variables for easy theming and maintenance
  • Accessibility Improvements: Enhanced focus states, contrast ratios, and ARIA support
  • Responsive Design: Improved breakpoints for mobile, tablet, and desktop
  • Code Block Styling: Better syntax highlighting with dark mode support
  • Print Stylesheet: Optimized styles for printing
  • Mobile Navigation: Enhanced mobile menu styling and interactions
  • API Navigation: Improved sidebar responsiveness

Examples

Before:

  • Only light mode available
  • No manual theme control
  • Basic focus states
  • Limited responsive breakpoints

After:

  • Automatic dark mode based on system preference
  • Manual theme toggle button (top-left)
  • Enhanced accessibility with visible focus indicators
  • Better responsive design across all screen sizes
  • Improved code block readability in both themes

Files Changed

  • docs/css/mongoose5.css - Main documentation styles with dark mode and theme toggle
  • docs/css/api.css - API page styles with responsive improvements
  • docs/css/github.css - Syntax highlighting with dark mode support
  • docs/css/style.css - Homepage styles with dark mode
  • docs/js/theme-toggle.js - Theme toggle functionality (new file)
  • docs/layout.pug - Added theme toggle button to documentation pages
  • index.pug - Added theme toggle button and mongoose5.css to homepage
  • docs/api_split.pug - Added cache-busting query parameters

Testing

  • Tested on homepage (index.pug)
  • Tested on documentation pages (layout.pug)
  • Tested on API pages (api_split.pug)
  • Tested in light mode
  • Tested in dark mode
  • Tested theme toggle functionality (3-state: system/dark/light)
  • Tested localStorage persistence
  • Tested responsive design on mobile devices
  • Tested responsive design on tablet devices
  • Tested keyboard navigation (Tab through elements)
  • Tested focus states visibility
  • Verified no console errors
  • Verified CSS variables are accessible
  • Tested print stylesheet

Notes

  • All changes are backward compatible
  • CSS variables include fallbacks for older browsers
  • Theme preference persists across page reloads via localStorage
  • Follows existing code style guidelines (2 spaces, no trailing whitespace)
  • No generated HTML files included (ran npm run docs:clean)
  • Only source files (CSS, JS, PUG) are modified

- Add CSS custom properties for theming
- Implement dark mode with prefers-color-scheme and manual toggle
- Add theme toggle button in top-left corner with localStorage persistence
- Improve accessibility with focus states and contrast ratios
- Enhance responsive design with better breakpoints
- Improve code block styling with dark mode syntax highlighting
- Add print stylesheet optimizations
- Improve mobile navigation styling
- Enhance API navigation sidebar responsiveness
@White-Devil2839
Copy link
Author

@vkarpov15 can you approve this please.

@White-Devil2839
Copy link
Author

@vkarpov15 ???

@White-Devil2839
Copy link
Author

@vkarpov15

Copilot finished reviewing on behalf of vkarpov15 November 25, 2025 21:49
Copy link
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

This PR adds comprehensive dark mode support to the Mongoose documentation with a manual theme toggle, improving accessibility and user experience. The implementation uses CSS custom properties for theming, supports both system preferences and manual selection, and includes responsive design improvements across all device sizes.

Key Changes:

  • Dark mode implementation with three-state theme toggle (system/dark/light) using localStorage persistence
  • CSS custom properties system for consistent theming across light and dark modes
  • Enhanced accessibility with improved focus states, WCAG-compliant contrast ratios, and keyboard navigation support

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
index.pug Added theme toggle button, mongoose5.css inclusion, and cache-busting query parameters to homepage
docs/layout.pug Added theme toggle button and theme-toggle.js script to documentation layout with cache-busting
docs/js/theme-toggle.js New file implementing three-state theme toggle with localStorage persistence
docs/css/style.css Added dark mode support, theme toggle button styles, and enhanced code block styling for homepage
docs/css/mongoose5.css Comprehensive theming system with CSS custom properties, dark mode support, responsive improvements, and print styles
docs/css/github.css Added dark mode syntax highlighting colors and improved code block styling with transitions
docs/css/api.css Enhanced API navigation with dark mode support, custom scrollbars, and responsive breakpoints
docs/api_split.pug Added cache-busting query parameter to API CSS
Comments suppressed due to low confidence (1)

docs/js/theme-toggle.js:29

  • Unused variable theme.
    const theme = document.documentElement.getAttribute('data-theme');

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

Comment on lines 23 to 38
updateThemeIcon();
}

// Update theme icon visibility
function updateThemeIcon() {
// CSS handles the icon visibility, but we can ensure proper state
const theme = document.documentElement.getAttribute('data-theme');
const lightIcon = document.getElementById('theme-icon-light'); // Sun icon
const darkIcon = document.getElementById('theme-icon-dark'); // Moon icon

if (lightIcon && darkIcon) {
// In dark mode: show sun icon (to switch to light)
// In light mode: show moon icon (to switch to dark)
// CSS handles the actual visibility via opacity
}
}
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The updateThemeIcon() function retrieves DOM elements but doesn't do anything with them. The comment states "CSS handles the icon visibility," making this function's logic unnecessary. The function body (lines 29-37) can be simplified or removed since CSS already manages icon visibility based on the data-theme attribute.

Consider either removing this function entirely (since CSS handles visibility) or implementing meaningful JavaScript-based icon state management if needed.

Suggested change
updateThemeIcon();
}
// Update theme icon visibility
function updateThemeIcon() {
// CSS handles the icon visibility, but we can ensure proper state
const theme = document.documentElement.getAttribute('data-theme');
const lightIcon = document.getElementById('theme-icon-light'); // Sun icon
const darkIcon = document.getElementById('theme-icon-dark'); // Moon icon
if (lightIcon && darkIcon) {
// In dark mode: show sun icon (to switch to light)
// In light mode: show moon icon (to switch to dark)
// CSS handles the actual visibility via opacity
}
}
}

Copilot uses AI. Check for mistakes.
color: var(--code-text, #e0e0e0);
background-color: var(--code-bg, #2d2d2d);
}
}
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

This media query for dark mode (lines 188-197) only applies when prefers-color-scheme: dark, but it doesn't account for the manual [data-theme="dark"] override. This creates an inconsistency where manually selected dark mode might not style code blocks correctly.

Consider adding a corresponding body[data-theme="dark"] selector or using a CSS custom property approach to ensure consistency between system and manual dark mode.

Suggested change
}
}
/* Manual dark mode for homepage code blocks */
body[data-theme="dark"] pre {
background: var(--code-bg, #2d2d2d);
border-color: var(--border-color, #444);
}
body[data-theme="dark"] code {
color: var(--code-text, #e0e0e0);
background-color: var(--code-bg, #2d2d2d);
}

Copilot uses AI. Check for mistakes.
color: #808080;
}
}

Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

Similar to other files, the dark mode syntax highlighting styles are only applied via @media (prefers-color-scheme: dark) and don't account for manual [data-theme="dark"] selection. Users who manually select dark mode may not see the intended syntax highlighting colors.

Consider adding a [data-theme="dark"] selector alongside the media query to ensure consistency.

Suggested change
/* Manual dark mode support for syntax highlighting */
[data-theme="dark"] {
/* Copy of dark mode syntax highlighting styles */
.hljs {
background: #22272e;
color: #c9d1d9;
}
.hljs-comment,
.hljs-quote {
color: #8b949e;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-section,
.hljs-link {
color: #ff7b72;
}
.hljs-function .hljs-keyword {
color: #d2a8ff;
}
.hljs-string,
.hljs-title,
.hljs-name,
.hljs-type,
.hljs-attribute,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #a5d6ff;
}
.hljs-meta,
.hljs-subst,
.hljs-regexp,
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-template-tag,
.hljs-template-variable,
.hljs-variable,
.hljs-class .hljs-title {
color: #d2a8ff;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-deletion {
background: #5a1d1d;
color: #f48771;
}
.hljs-addition {
background: #1e3a1e;
color: #b5cea8;
}
.diff .hljs-change {
background: #2d4d2d;
color: #4ec9b0;
}
.hljs-chunk {
color: #808080;
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +198 to +202
.pure-menu-link:hover,
.pure-menu-link.selected {
background-color: var(--menu-hover);
}

Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

[nitpick] The selector .pure-menu-link:hover, .pure-menu-link.selected is split across two lines (198-199), which is fine, but line 199 appears to duplicate functionality with the .pure-menu-link.selected rule at line 209-211. While not technically wrong, having separate rules for the same selector could lead to confusion.

Consider consolidating these rules or adding a comment explaining why they're separate if there's a specific cascade reason.

Suggested change
.pure-menu-link:hover,
.pure-menu-link.selected {
background-color: var(--menu-hover);
}
.pure-menu-link:hover {
background-color: var(--menu-hover);
}

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +10
link(href="docs/css/mongoose5.css?v=" + Date.now(), rel="stylesheet")
link(href="docs/css/style.css?v=" + Date.now(), rel="stylesheet")
link(href="docs/css/github.css?v=" + Date.now(), rel="stylesheet")
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

Using Date.now() for cache-busting creates a new URL on every page render, which defeats browser caching entirely. This forces clients to re-download CSS files on every page load, negating the benefits of HTTP caching.

Consider using a build-time constant (e.g., package version, git commit hash, or build timestamp) instead of Date.now() to ensure cache-busting only occurs when files actually change.

Suggested change
link(href="docs/css/mongoose5.css?v=" + Date.now(), rel="stylesheet")
link(href="docs/css/style.css?v=" + Date.now(), rel="stylesheet")
link(href="docs/css/github.css?v=" + Date.now(), rel="stylesheet")
link(href="docs/css/mongoose5.css?v=" + package.version, rel="stylesheet")
link(href="docs/css/style.css?v=" + package.version, rel="stylesheet")
link(href="docs/css/github.css?v=" + package.version, rel="stylesheet")

Copilot uses AI. Check for mistakes.
block layout
#layout
#theme-toggle
button#theme-toggle-btn(aria-label="Toggle dark mode" title="Toggle dark/light theme")
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The button's aria-label says "Toggle dark mode" but the button actually cycles through three states (system/dark/light), not just dark/light. This can confuse screen reader users who expect a simple toggle but get different behavior.

Consider updating to aria-label="Cycle theme preferences" or aria-label="Switch theme (system/dark/light)" to better reflect the three-state functionality.

Suggested change
button#theme-toggle-btn(aria-label="Toggle dark mode" title="Toggle dark/light theme")
button#theme-toggle-btn(aria-label="Switch theme (system/dark/light)" title="Switch theme (system/dark/light)")

Copilot uses AI. Check for mistakes.
Comment on lines 41 to 51
function toggleTheme() {
const currentTheme = document.documentElement.getAttribute('data-theme');
if (currentTheme === 'dark') {
applyTheme('light');
} else if (currentTheme === 'light') {
applyTheme(null); // Reset to system preference
} else {
// Currently using system preference, switch to dark
applyTheme('dark');
}
}
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The three-state toggle behavior (dark → light → system → dark) isn't communicated to screen reader users. When the button is clicked, assistive technology users won't know which state is now active.

Consider updating the button's aria-label dynamically to reflect the current state, e.g., "Theme: Dark mode" or "Theme: System preference", or add aria-live="polite" announcements when the theme changes.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +14
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/mongoose5.css?v=${Date.now()}`)
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/github.css?v=${Date.now()}`)
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

Using Date.now() for cache-busting creates a new URL on every page render, which defeats browser caching entirely. This forces clients to re-download CSS files on every page load, negating the benefits of HTTP caching.

Consider using a build-time constant (e.g., package version, git commit hash, or build timestamp) instead of Date.now() to ensure cache-busting only occurs when files actually change.

Suggested change
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/mongoose5.css?v=${Date.now()}`)
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/github.css?v=${Date.now()}`)
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/mongoose5.css?v=${package.version}`)
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/github.css?v=${package.version}`)

Copilot uses AI. Check for mistakes.

append style
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/api.css`)
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/api.css?v=${Date.now()}`)
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

Using Date.now() for cache-busting creates a new URL on every page render, which defeats browser caching entirely. This forces clients to re-download CSS files on every page load, negating the benefits of HTTP caching.

Consider using a build-time constant (e.g., package version, git commit hash, or build timestamp) instead of Date.now() to ensure cache-busting only occurs when files actually change.

Suggested change
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/api.css?v=${Date.now()}`)
link(rel="stylesheet", href=`${versions.versionedPath}/docs/css/api.css?v=${versions.version}`)

Copilot uses AI. Check for mistakes.
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.

2 participants