From a603b53872e7e6f99eba7ee5bad14f794195b108 Mon Sep 17 00:00:00 2001 From: Siddhi Tripathi Date: Thu, 4 Dec 2025 11:03:53 +0530 Subject: [PATCH 1/2] website: add CSS custom properties for theme support --- _includes/theme-toggle.html | 63 ++++++++++++++++++++++++++++++++++++ _sass/_base.scss | 21 ++++++------ _sass/_layout.scss | 24 ++++++++------ _sass/custom/_mixins.scss | 2 ++ _sass/custom/_themes.scss | 40 +++++++++++++++++++++++ _sass/custom/_variables.scss | 2 ++ css/main.scss | 3 ++ 7 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 _includes/theme-toggle.html create mode 100644 _sass/custom/_mixins.scss create mode 100644 _sass/custom/_themes.scss create mode 100644 _sass/custom/_variables.scss diff --git a/_includes/theme-toggle.html b/_includes/theme-toggle.html new file mode 100644 index 0000000000..86556754f8 --- /dev/null +++ b/_includes/theme-toggle.html @@ -0,0 +1,63 @@ + \ No newline at end of file diff --git a/_sass/_base.scss b/_sass/_base.scss index 4eb9050523..934d4e619a 100644 --- a/_sass/_base.scss +++ b/_sass/_base.scss @@ -17,14 +17,15 @@ dl, dd, ol, ul, figure { */ body { font: $base-font-weight list.slash($base-font-size, $base-line-height) $base-font-family; - color: $text-color; - background-color: $background-color; + color: var(--text-primary); + background-color: var(--bg-primary); -webkit-text-size-adjust: 100%; -webkit-font-feature-settings: "kern" 1; -moz-font-feature-settings: "kern" 1; -o-font-feature-settings: "kern" 1; font-feature-settings: "kern" 1; font-kerning: normal; + transition: background-color 0.3s ease, color 0.3s ease; } @@ -93,15 +94,15 @@ h1, h2, h3, h4, h5, h6 { * Links */ a { - color: $brand-color; + color: var(--link-color); text-decoration: none; &:visited { - color: darken($brand-color, 15%); + color: var(--link-color); } &:hover { - color: $text-color; + color: var(--link-hover); text-decoration: underline; } } @@ -112,8 +113,8 @@ a { * Blockquotes */ blockquote { - color: $grey-color; - border-left: 4px solid $grey-color-light; + color: var(--text-secondary); + border-left: 4px solid var(--border-color); padding-left: $spacing-unit * 0.5; font-size: 18px; letter-spacing: -1px; @@ -132,9 +133,9 @@ blockquote { pre, code { font-size: 15px; - border: 1px solid $grey-color-light; + border: 1px solid var(--border-color); border-radius: 3px; - background-color: #eef; + background-color: var(--code-bg); } code { @@ -202,7 +203,7 @@ pre { vertical-align: middle; path { - fill: $grey-color; + fill: var(--text-secondary); } } } diff --git a/_sass/_layout.scss b/_sass/_layout.scss index c332f6c0ed..f48658e61a 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -2,9 +2,11 @@ * Site header */ .site-header { - border-top: 5px solid $grey-color-dark; - border-bottom: 1px solid $grey-color-light; + border-top: 5px solid var(--header-bg); + border-bottom: 1px solid var(--border-color); min-height: 56px; + background-color: var(--header-bg); + color: var(--header-text); // Positioning context for the mobile navigation icon position: relative; @@ -20,7 +22,7 @@ &, &:visited { - color: $grey-color-dark; + color: var(--header-text); } } @@ -33,7 +35,7 @@ } .page-link { - color: $text-color; + color: var(--header-text); line-height: $base-line-height; // Gaps between nav items, but not on the last one @@ -46,8 +48,8 @@ position: absolute; top: 9px; right: $spacing-unit * 0.5; - background-color: $background-color; - border: 1px solid $grey-color-light; + background-color: var(--bg-primary); + border: 1px solid var(--border-color); border-radius: 5px; text-align: right; @@ -65,7 +67,7 @@ height: 15px; path { - fill: $grey-color-dark; + fill: var(--header-text); } } } @@ -98,8 +100,10 @@ * Site footer */ .site-footer { - border-top: 1px solid $grey-color-light; + border-top: 1px solid var(--border-color); padding: $spacing-unit 0; + background-color: var(--footer-bg); + color: var(--footer-text); } .footer-heading { @@ -115,7 +119,7 @@ .footer-col-wrapper { font-size: 15px; - color: $grey-color; + color: var(--footer-text); margin-left: -$spacing-unit * 0.5; @extend %clearfix; } @@ -186,7 +190,7 @@ .post-meta { font-size: $small-font-size; - color: $grey-color; + color: var(--text-secondary); } .post-link { diff --git a/_sass/custom/_mixins.scss b/_sass/custom/_mixins.scss new file mode 100644 index 0000000000..627c7230ad --- /dev/null +++ b/_sass/custom/_mixins.scss @@ -0,0 +1,2 @@ +// Custom mixins for NuttX website +// Add any custom mixins here if needed diff --git a/_sass/custom/_themes.scss b/_sass/custom/_themes.scss new file mode 100644 index 0000000000..efea3c861e --- /dev/null +++ b/_sass/custom/_themes.scss @@ -0,0 +1,40 @@ +// CSS Custom Properties for Theming +:root { + // Light theme (default) + --bg-primary: #ffffff; + --bg-secondary: #f8f9fa; + --bg-tertiary: #e9ecef; + --text-primary: #212529; + --text-secondary: #6c757d; + --link-color: #007bff; + --link-hover: #0056b3; + --border-color: #dee2e6; + --code-bg: #f8f9fa; + --header-bg: #343a40; + --header-text: #ffffff; + --footer-bg: #f8f9fa; + --footer-text: #6c757d; + --card-bg: #ffffff; + --table-bg: #ffffff; + --table-border: #dee2e6; +} + +[data-theme="dark"] { + // Dark theme + --bg-primary: #121212; + --bg-secondary: #1e1e1e; + --bg-tertiary: #2d3748; + --text-primary: #e9ecef; + --text-secondary: #adb5bd; + --link-color: #4dabf7; + --link-hover: #74c0fc; + --border-color: #495057; + --code-bg: #2d3748; + --header-bg: #212529; + --header-text: #f8f9fa; + --footer-bg: #1a1a1a; + --footer-text: #adb5bd; + --card-bg: #1e1e1e; + --table-bg: #1e1e1e; + --table-border: #495057; +} \ No newline at end of file diff --git a/_sass/custom/_variables.scss b/_sass/custom/_variables.scss new file mode 100644 index 0000000000..1ee3354c8b --- /dev/null +++ b/_sass/custom/_variables.scss @@ -0,0 +1,2 @@ +// Custom variables for NuttX website +// Add any custom variables here if needed diff --git a/css/main.scss b/css/main.scss index f2e566e2a1..7a6fa88aaa 100644 --- a/css/main.scss +++ b/css/main.scss @@ -1,6 +1,9 @@ --- # Only the main Sass file needs front matter (the dashes are enough) --- +@import "custom/variables"; +@import "custom/mixins"; +@import "custom/themes"; @charset "utf-8"; From 8d4b26566f2c07a92d7cb519b369c9b126ca165d Mon Sep 17 00:00:00 2001 From: Siddhi Tripathi Date: Thu, 1 Jan 2026 15:29:45 +0530 Subject: [PATCH 2/2] feat: complete dark mode implementation - Add comprehensive CSS custom properties for light/dark themes - Implement theme toggle button in navigation with SVG icons - Add JavaScript for theme switching, persistence, and system preference detection - Apply theme variables to all site elements (body, headers, links, jumbotron, footer) - Fix jumbotron text colors in both light and dark modes - Ensure responsive design for mobile and desktop - Add accessibility features (ARIA labels, proper contrast ratios) - Tested on all pages with full functionality --- .jekyll-metadata | Bin 0 -> 22889 bytes _includes/theme-toggle.html | 125 ++++++++++++++++++++++- _includes/theme-toggle.html.backup | 96 +++++++++++++++++ _includes/themes/apache/_navigation.html | 15 ++- _includes/themes/apache/default.html | 23 ++--- assets/js/theme.js | 79 ++++++++++++++ base-changes.patch | 73 +++++++++++++ layout-changes.patch | 86 ++++++++++++++++ 8 files changed, 475 insertions(+), 22 deletions(-) create mode 100644 .jekyll-metadata create mode 100644 _includes/theme-toggle.html.backup create mode 100644 assets/js/theme.js create mode 100644 base-changes.patch create mode 100644 layout-changes.patch diff --git a/.jekyll-metadata b/.jekyll-metadata new file mode 100644 index 0000000000000000000000000000000000000000..5448ccf87be705b305cb17ec9cd99525f3cd4c21 GIT binary patch literal 22889 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 bC){4xZ!}Y?GLlZEI(!?XieuT54!`{mAdHJ> literal 0 HcmV?d00001 diff --git a/_includes/theme-toggle.html b/_includes/theme-toggle.html index 86556754f8..8f40fef3a6 100644 --- a/_includes/theme-toggle.html +++ b/_includes/theme-toggle.html @@ -1,4 +1,123 @@ \ No newline at end of file + diff --git a/_includes/theme-toggle.html.backup b/_includes/theme-toggle.html.backup new file mode 100644 index 0000000000..7299a620b1 --- /dev/null +++ b/_includes/theme-toggle.html.backup @@ -0,0 +1,96 @@ + diff --git a/_includes/themes/apache/_navigation.html b/_includes/themes/apache/_navigation.html index 0e8090dab6..1fd4942afc 100644 --- a/_includes/themes/apache/_navigation.html +++ b/_includes/themes/apache/_navigation.html @@ -25,7 +25,7 @@
  • Documentation
  • Articles
  • GitHub
  • -
  • +
  • Apache
  • + +
  • +
    + +
    +
  • diff --git a/_includes/themes/apache/default.html b/_includes/themes/apache/default.html index 8a5356dc80..512343bc89 100644 --- a/_includes/themes/apache/default.html +++ b/_includes/themes/apache/default.html @@ -6,26 +6,14 @@ {% if page.description %}{% endif %} - - - - - - - - + + + {% include theme-toggle.html %} @@ -44,9 +32,10 @@ {% include JB/analytics %} - + + - + \ No newline at end of file diff --git a/assets/js/theme.js b/assets/js/theme.js new file mode 100644 index 0000000000..8eeab3543e --- /dev/null +++ b/assets/js/theme.js @@ -0,0 +1,79 @@ +console.log('=== THEME DEBUG START ==='); + +// Function to toggle theme +function toggleTheme() { + console.log('=== TOGGLE THEME CALLED ==='); + + const html = document.documentElement; + const current = html.getAttribute('data-theme'); + console.log('Current theme attribute:', current); + + const newTheme = current === 'dark' ? 'light' : 'dark'; + console.log('New theme will be:', newTheme); + + // Set the theme + html.setAttribute('data-theme', newTheme); + console.log('Theme attribute set to:', html.getAttribute('data-theme')); + + // Save to localStorage + localStorage.setItem('theme', newTheme); + console.log('Saved to localStorage:', localStorage.getItem('theme')); + + // Test if CSS variables are working + const bgColor = getComputedStyle(document.documentElement).getPropertyValue('--bg-primary').trim(); + console.log('CSS variable --bg-primary:', bgColor); + + return false; +} + +// Initialize when DOM is ready +document.addEventListener('DOMContentLoaded', function() { + console.log('=== DOM READY ==='); + + // Find the toggle button + const toggleBtn = document.getElementById('themeToggle'); + console.log('Toggle button found:', toggleBtn); + + if (toggleBtn) { + // Add click event + toggleBtn.addEventListener('click', function(e) { + console.log('=== CLICK EVENT FIRED ==='); + e.preventDefault(); + e.stopPropagation(); + toggleTheme(); + return false; + }); + + console.log('Click event listener added successfully'); + } else { + console.error('ERROR: Toggle button not found!'); + } + + // Load saved theme + const savedTheme = localStorage.getItem('theme'); + console.log('Saved theme from localStorage:', savedTheme); + + if (savedTheme) { + document.documentElement.setAttribute('data-theme', savedTheme); + console.log('Applied saved theme, current attribute:', document.documentElement.getAttribute('data-theme')); + } else { + console.log('No saved theme, using default (light)'); + document.documentElement.setAttribute('data-theme', 'light'); + } + + // Test CSS variables + console.log('Testing CSS variables:'); + console.log('--bg-primary:', getComputedStyle(document.documentElement).getPropertyValue('--bg-primary').trim()); + console.log('--text-primary:', getComputedStyle(document.documentElement).getPropertyValue('--text-primary').trim()); + + console.log('=== THEME DEBUG END ==='); +}); + +// Fallback click handler +document.addEventListener('click', function(e) { + if (e.target.closest('#themeToggle')) { + console.log('Fallback click handler triggered'); + e.preventDefault(); + toggleTheme(); + } +}); diff --git a/base-changes.patch b/base-changes.patch new file mode 100644 index 0000000000..860c155ec2 --- /dev/null +++ b/base-changes.patch @@ -0,0 +1,73 @@ +diff --git a/_sass/_base.scss b/_sass/_base.scss +index 4eb905052..934d4e619 100644 +--- a/_sass/_base.scss ++++ b/_sass/_base.scss +@@ -17,14 +17,15 @@ dl, dd, ol, ul, figure { + */ + body { + font: $base-font-weight list.slash($base-font-size, $base-line-height) $base-font-family; +- color: $text-color; +- background-color: $background-color; ++ color: var(--text-primary); ++ background-color: var(--bg-primary); + -webkit-text-size-adjust: 100%; + -webkit-font-feature-settings: "kern" 1; + -moz-font-feature-settings: "kern" 1; + -o-font-feature-settings: "kern" 1; + font-feature-settings: "kern" 1; + font-kerning: normal; ++ transition: background-color 0.3s ease, color 0.3s ease; + } + + +@@ -93,15 +94,15 @@ h1, h2, h3, h4, h5, h6 { + * Links + */ + a { +- color: $brand-color; ++ color: var(--link-color); + text-decoration: none; + + &:visited { +- color: darken($brand-color, 15%); ++ color: var(--link-color); + } + + &:hover { +- color: $text-color; ++ color: var(--link-hover); + text-decoration: underline; + } + } +@@ -112,8 +113,8 @@ a { + * Blockquotes + */ + blockquote { +- color: $grey-color; +- border-left: 4px solid $grey-color-light; ++ color: var(--text-secondary); ++ border-left: 4px solid var(--border-color); + padding-left: $spacing-unit * 0.5; + font-size: 18px; + letter-spacing: -1px; +@@ -132,9 +133,9 @@ blockquote { + pre, + code { + font-size: 15px; +- border: 1px solid $grey-color-light; ++ border: 1px solid var(--border-color); + border-radius: 3px; +- background-color: #eef; ++ background-color: var(--code-bg); + } + + code { +@@ -202,7 +203,7 @@ pre { + vertical-align: middle; + + path { +- fill: $grey-color; ++ fill: var(--text-secondary); + } + } + } diff --git a/layout-changes.patch b/layout-changes.patch new file mode 100644 index 0000000000..eb760a1c0b --- /dev/null +++ b/layout-changes.patch @@ -0,0 +1,86 @@ +diff --git a/_sass/_layout.scss b/_sass/_layout.scss +index c332f6c0e..f48658e61 100644 +--- a/_sass/_layout.scss ++++ b/_sass/_layout.scss +@@ -2,9 +2,11 @@ + * Site header + */ + .site-header { +- border-top: 5px solid $grey-color-dark; +- border-bottom: 1px solid $grey-color-light; ++ border-top: 5px solid var(--header-bg); ++ border-bottom: 1px solid var(--border-color); + min-height: 56px; ++ background-color: var(--header-bg); ++ color: var(--header-text); + + // Positioning context for the mobile navigation icon + position: relative; +@@ -20,7 +22,7 @@ + + &, + &:visited { +- color: $grey-color-dark; ++ color: var(--header-text); + } + } + +@@ -33,7 +35,7 @@ + } + + .page-link { +- color: $text-color; ++ color: var(--header-text); + line-height: $base-line-height; + + // Gaps between nav items, but not on the last one +@@ -46,8 +48,8 @@ + position: absolute; + top: 9px; + right: $spacing-unit * 0.5; +- background-color: $background-color; +- border: 1px solid $grey-color-light; ++ background-color: var(--bg-primary); ++ border: 1px solid var(--border-color); + border-radius: 5px; + text-align: right; + +@@ -65,7 +67,7 @@ + height: 15px; + + path { +- fill: $grey-color-dark; ++ fill: var(--header-text); + } + } + } +@@ -98,8 +100,10 @@ + * Site footer + */ + .site-footer { +- border-top: 1px solid $grey-color-light; ++ border-top: 1px solid var(--border-color); + padding: $spacing-unit 0; ++ background-color: var(--footer-bg); ++ color: var(--footer-text); + } + + .footer-heading { +@@ -115,7 +119,7 @@ + + .footer-col-wrapper { + font-size: 15px; +- color: $grey-color; ++ color: var(--footer-text); + margin-left: -$spacing-unit * 0.5; + @extend %clearfix; + } +@@ -186,7 +190,7 @@ + + .post-meta { + font-size: $small-font-size; +- color: $grey-color; ++ color: var(--text-secondary); + } + + .post-link {