From eae4dafd1214ea72cdaa7880291fd8b77e066bc1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 11:44:48 +0000 Subject: [PATCH 1/3] Initial plan From 09da5a4a97ecb1bc10b91a7323352cee0759b2da Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 11:54:56 +0000 Subject: [PATCH 2/3] Implement dark/light mode toggle with WHO color palette Co-authored-by: litlfred <662242+litlfred@users.noreply.github.com> --- input/includes/dmn.css | 165 +++++++++++- input/scripts/includes/dmn.css | 165 +++++++++++- local-template/DARK_MODE.md | 72 +++++ .../package/content/assets/css/dmn.css | 249 ++++++++++++++---- .../package/content/assets/js/theme-toggle.js | 136 ++++++++++ .../includes/_append.fragment-script.html | 1 + 6 files changed, 725 insertions(+), 63 deletions(-) create mode 100644 local-template/DARK_MODE.md create mode 100644 local-template/package/content/assets/js/theme-toggle.js create mode 100644 local-template/package/includes/_append.fragment-script.html diff --git a/input/includes/dmn.css b/input/includes/dmn.css index ac1e983182..7717d147f5 100644 --- a/input/includes/dmn.css +++ b/input/includes/dmn.css @@ -3,6 +3,119 @@ --who-blue: #0093d0; --who-header: #f0f9fc; --who-table-border: #007ab7; + + /* Light mode colors (default) */ + --bg-color: #ffffff; + --text-color: #222222; + --border-color: #007ab7; + --table-stripe: #f7fafc; + --row-label-bg: #f6fafd; + --row-label-text: #555555; + --input-bg: #e5f4fa; + --output-bg: #dff7ea; + --annotation-bg: #fffbe5; + --link-color: #0066cc; + --link-hover-color: #004499; +} + +/* Dark mode colors */ +[data-theme="dark"] { + --who-blue: #0093d0; + --who-header: #1a2332; + --who-table-border: #4a90a4; + --bg-color: #1a1a1a; + --text-color: #e0e0e0; + --border-color: #4a90a4; + --table-stripe: #2a2a2a; + --row-label-bg: #2d3748; + --row-label-text: #cbd5e0; + --input-bg: #2c5282; + --output-bg: #2f855a; + --annotation-bg: #744210; + --link-color: #66b3ff; + --link-hover-color: #99ccff; +} + +/* Apply dark mode based on system preference if no explicit theme is set */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) { + --who-header: #1a2332; + --who-table-border: #4a90a4; + --bg-color: #1a1a1a; + --text-color: #e0e0e0; + --border-color: #4a90a4; + --table-stripe: #2a2a2a; + --row-label-bg: #2d3748; + --row-label-text: #cbd5e0; + --input-bg: #2c5282; + --output-bg: #2f855a; + --annotation-bg: #744210; + --link-color: #66b3ff; + --link-hover-color: #99ccff; + } +} + +/* General dark mode styles for common elements */ +body { + background-color: var(--bg-color); + color: var(--text-color); + transition: background-color 0.3s ease, color 0.3s ease; +} + +a { + color: var(--link-color); + transition: color 0.3s ease; +} + +a:hover { + color: var(--link-hover-color); +} + +/* Apply to common Bootstrap/FHIR IG elements */ +.table { + background-color: var(--bg-color); + color: var(--text-color); +} + +.table th, +.table td { + border-color: var(--border-color); +} + +.table-bordered { + border-color: var(--border-color); +} + +.thead-dark th { + background-color: var(--who-blue); + border-color: var(--border-color); +} + +/* Code blocks and pre elements */ +pre, code { + background-color: var(--table-stripe); + color: var(--text-color); + border-color: var(--border-color); +} + +/* Cards and panels */ +.card { + background-color: var(--bg-color); + border-color: var(--border-color); +} + +.card-header { + background-color: var(--who-header); + border-color: var(--border-color); +} + +/* Navbar elements */ +.navbar { + background-color: var(--who-header) !important; +} + +.navbar-light .navbar-nav .nav-link { + color: var(--text-color); } table.decision { @@ -10,6 +123,8 @@ table.decision { width: 100%; margin: 2em 0; font-family: Arial, sans-serif; + background-color: var(--bg-color); + color: var(--text-color); } table.decision tr.decision-header { @@ -20,7 +135,7 @@ table.decision tr.decision-header { table.decision tr.io-row { background: var(--who-header); - color: #222; + color: var(--text-color); font-weight: 600; } @@ -31,22 +146,58 @@ table.decision td, table.decision th { .row-label { font-weight: bold; - background: #f6fafd; - color: #555; + background: var(--row-label-bg); + color: var(--row-label-text); } .input, .inputEntry { - background: #e5f4fa; + background: var(--input-bg); + color: var(--text-color); } .output, .outputEntry { - background: #dff7ea; + background: var(--output-bg); + color: var(--text-color); } .annotation, .annotationEntry { - background: #fffbe5; + background: var(--annotation-bg); + color: var(--text-color); } tr.rule:nth-child(even) { - background: #f7fafc; + background: var(--table-stripe); +} + +/* Dark mode image handling - set white background for images that may be transparent */ +[data-theme="dark"] img, +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) img { + background-color: white; + border-radius: 4px; + padding: 2px; + } +} + +/* Dark mode toggle button styling */ +.theme-toggle { + background: none; + border: 1px solid var(--border-color, #007ab7); + border-radius: 4px; + color: var(--text-color, #222); + cursor: pointer; + font-size: 14px; + margin-left: 10px; + padding: 5px 10px; + transition: all 0.3s ease; +} + +.theme-toggle:hover { + background-color: var(--who-blue, #0093d0); + color: white; +} + +.theme-toggle:focus { + outline: 2px solid var(--who-blue, #0093d0); + outline-offset: 2px; } \ No newline at end of file diff --git a/input/scripts/includes/dmn.css b/input/scripts/includes/dmn.css index ac1e983182..7717d147f5 100644 --- a/input/scripts/includes/dmn.css +++ b/input/scripts/includes/dmn.css @@ -3,6 +3,119 @@ --who-blue: #0093d0; --who-header: #f0f9fc; --who-table-border: #007ab7; + + /* Light mode colors (default) */ + --bg-color: #ffffff; + --text-color: #222222; + --border-color: #007ab7; + --table-stripe: #f7fafc; + --row-label-bg: #f6fafd; + --row-label-text: #555555; + --input-bg: #e5f4fa; + --output-bg: #dff7ea; + --annotation-bg: #fffbe5; + --link-color: #0066cc; + --link-hover-color: #004499; +} + +/* Dark mode colors */ +[data-theme="dark"] { + --who-blue: #0093d0; + --who-header: #1a2332; + --who-table-border: #4a90a4; + --bg-color: #1a1a1a; + --text-color: #e0e0e0; + --border-color: #4a90a4; + --table-stripe: #2a2a2a; + --row-label-bg: #2d3748; + --row-label-text: #cbd5e0; + --input-bg: #2c5282; + --output-bg: #2f855a; + --annotation-bg: #744210; + --link-color: #66b3ff; + --link-hover-color: #99ccff; +} + +/* Apply dark mode based on system preference if no explicit theme is set */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) { + --who-header: #1a2332; + --who-table-border: #4a90a4; + --bg-color: #1a1a1a; + --text-color: #e0e0e0; + --border-color: #4a90a4; + --table-stripe: #2a2a2a; + --row-label-bg: #2d3748; + --row-label-text: #cbd5e0; + --input-bg: #2c5282; + --output-bg: #2f855a; + --annotation-bg: #744210; + --link-color: #66b3ff; + --link-hover-color: #99ccff; + } +} + +/* General dark mode styles for common elements */ +body { + background-color: var(--bg-color); + color: var(--text-color); + transition: background-color 0.3s ease, color 0.3s ease; +} + +a { + color: var(--link-color); + transition: color 0.3s ease; +} + +a:hover { + color: var(--link-hover-color); +} + +/* Apply to common Bootstrap/FHIR IG elements */ +.table { + background-color: var(--bg-color); + color: var(--text-color); +} + +.table th, +.table td { + border-color: var(--border-color); +} + +.table-bordered { + border-color: var(--border-color); +} + +.thead-dark th { + background-color: var(--who-blue); + border-color: var(--border-color); +} + +/* Code blocks and pre elements */ +pre, code { + background-color: var(--table-stripe); + color: var(--text-color); + border-color: var(--border-color); +} + +/* Cards and panels */ +.card { + background-color: var(--bg-color); + border-color: var(--border-color); +} + +.card-header { + background-color: var(--who-header); + border-color: var(--border-color); +} + +/* Navbar elements */ +.navbar { + background-color: var(--who-header) !important; +} + +.navbar-light .navbar-nav .nav-link { + color: var(--text-color); } table.decision { @@ -10,6 +123,8 @@ table.decision { width: 100%; margin: 2em 0; font-family: Arial, sans-serif; + background-color: var(--bg-color); + color: var(--text-color); } table.decision tr.decision-header { @@ -20,7 +135,7 @@ table.decision tr.decision-header { table.decision tr.io-row { background: var(--who-header); - color: #222; + color: var(--text-color); font-weight: 600; } @@ -31,22 +146,58 @@ table.decision td, table.decision th { .row-label { font-weight: bold; - background: #f6fafd; - color: #555; + background: var(--row-label-bg); + color: var(--row-label-text); } .input, .inputEntry { - background: #e5f4fa; + background: var(--input-bg); + color: var(--text-color); } .output, .outputEntry { - background: #dff7ea; + background: var(--output-bg); + color: var(--text-color); } .annotation, .annotationEntry { - background: #fffbe5; + background: var(--annotation-bg); + color: var(--text-color); } tr.rule:nth-child(even) { - background: #f7fafc; + background: var(--table-stripe); +} + +/* Dark mode image handling - set white background for images that may be transparent */ +[data-theme="dark"] img, +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) img { + background-color: white; + border-radius: 4px; + padding: 2px; + } +} + +/* Dark mode toggle button styling */ +.theme-toggle { + background: none; + border: 1px solid var(--border-color, #007ab7); + border-radius: 4px; + color: var(--text-color, #222); + cursor: pointer; + font-size: 14px; + margin-left: 10px; + padding: 5px 10px; + transition: all 0.3s ease; +} + +.theme-toggle:hover { + background-color: var(--who-blue, #0093d0); + color: white; +} + +.theme-toggle:focus { + outline: 2px solid var(--who-blue, #0093d0); + outline-offset: 2px; } \ No newline at end of file diff --git a/local-template/DARK_MODE.md b/local-template/DARK_MODE.md new file mode 100644 index 0000000000..6830ea0da5 --- /dev/null +++ b/local-template/DARK_MODE.md @@ -0,0 +1,72 @@ +# Dark Mode Implementation + +This document describes the dark/light mode toggle feature implemented for the SMART Guidelines base template. + +## Features + +- **Automatic Detection**: Respects user's system preference (`prefers-color-scheme`) +- **Manual Toggle**: Button in the top-right corner to manually switch themes +- **Persistence**: Theme choice is saved in localStorage and persists across page reloads +- **WHO Color Palette**: Maintains WHO branding while providing optimal contrast for dark mode +- **Transparent Image Handling**: Automatically adds white background to images in dark mode for better visibility + +## Implementation + +### CSS Custom Properties + +The implementation uses CSS custom properties (variables) to create a flexible theming system: + +```css +:root { + /* Light mode colors (default) */ + --bg-color: #ffffff; + --text-color: #222222; + --who-blue: #0093d0; + /* ... more variables */ +} + +[data-theme="dark"] { + /* Dark mode colors */ + --bg-color: #1a1a1a; + --text-color: #e0e0e0; + /* ... dark mode overrides */ +} +``` + +### JavaScript Toggle + +The theme toggle is implemented with vanilla JavaScript that: + +1. Detects system preference on page load +2. Applies saved theme from localStorage if available +3. Creates and positions the toggle button dynamically +4. Handles theme switching and persistence + +### Template Integration + +The feature is integrated into the FHIR IG template system via: + +- `_append.fragment-css.html`: Includes the dark mode CSS +- `_append.fragment-script.html`: Includes the theme toggle JavaScript +- CSS files in multiple locations for compatibility: + - `local-template/package/content/assets/css/dmn.css` + - `input/includes/dmn.css` + - `input/scripts/includes/dmn.css` + +## Usage + +The dark mode toggle appears automatically in the top-right corner of pages. Users can: + +1. Click the toggle button to switch between light and dark modes +2. The system will remember their choice +3. If no choice is made, the system preference is used + +## Customization + +To customize colors, modify the CSS custom properties in the `:root` and `[data-theme="dark"]` selectors in the CSS files. + +## Browser Support + +- Modern browsers with CSS custom properties support +- Graceful fallback to light mode for older browsers +- LocalStorage support for theme persistence \ No newline at end of file diff --git a/local-template/package/content/assets/css/dmn.css b/local-template/package/content/assets/css/dmn.css index 623a2286ef..b875d11d6d 100644 --- a/local-template/package/content/assets/css/dmn.css +++ b/local-template/package/content/assets/css/dmn.css @@ -1,52 +1,203 @@ -/* WHO color palette: Example blue */ -:root { - --who-blue: #0093d0; - --who-header: #f0f9fc; - --who-table-border: #007ab7; +/* WHO color palette: Example blue */ +:root { + --who-blue: #0093d0; + --who-header: #f0f9fc; + --who-table-border: #007ab7; + + /* Light mode colors (default) */ + --bg-color: #ffffff; + --text-color: #222222; + --border-color: #007ab7; + --table-stripe: #f7fafc; + --row-label-bg: #f6fafd; + --row-label-text: #555555; + --input-bg: #e5f4fa; + --output-bg: #dff7ea; + --annotation-bg: #fffbe5; + --link-color: #0066cc; + --link-hover-color: #004499; +} + +/* Dark mode colors */ +[data-theme="dark"] { + --who-blue: #0093d0; + --who-header: #1a2332; + --who-table-border: #4a90a4; + --bg-color: #1a1a1a; + --text-color: #e0e0e0; + --border-color: #4a90a4; + --table-stripe: #2a2a2a; + --row-label-bg: #2d3748; + --row-label-text: #cbd5e0; + --input-bg: #2c5282; + --output-bg: #2f855a; + --annotation-bg: #744210; + --link-color: #66b3ff; + --link-hover-color: #99ccff; +} + +/* Apply dark mode based on system preference if no explicit theme is set */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) { + --who-header: #1a2332; + --who-table-border: #4a90a4; + --bg-color: #1a1a1a; + --text-color: #e0e0e0; + --border-color: #4a90a4; + --table-stripe: #2a2a2a; + --row-label-bg: #2d3748; + --row-label-text: #cbd5e0; + --input-bg: #2c5282; + --output-bg: #2f855a; + --annotation-bg: #744210; + --link-color: #66b3ff; + --link-hover-color: #99ccff; + } +} + +/* General dark mode styles for common elements */ +body { + background-color: var(--bg-color); + color: var(--text-color); + transition: background-color 0.3s ease, color 0.3s ease; +} + +a { + color: var(--link-color); + transition: color 0.3s ease; +} + +a:hover { + color: var(--link-hover-color); +} + +/* Apply to common Bootstrap/FHIR IG elements */ +.table { + background-color: var(--bg-color); + color: var(--text-color); +} + +.table th, +.table td { + border-color: var(--border-color); +} + +.table-bordered { + border-color: var(--border-color); +} + +.thead-dark th { + background-color: var(--who-blue); + border-color: var(--border-color); +} + +/* Code blocks and pre elements */ +pre, code { + background-color: var(--table-stripe); + color: var(--text-color); + border-color: var(--border-color); +} + +/* Cards and panels */ +.card { + background-color: var(--bg-color); + border-color: var(--border-color); +} + +.card-header { + background-color: var(--who-header); + border-color: var(--border-color); +} + +/* Navbar elements */ +.navbar { + background-color: var(--who-header) !important; +} + +.navbar-light .navbar-nav .nav-link { + color: var(--text-color); } -table.decision { - border-collapse: collapse; - width: 100%; - margin: 2em 0; - font-family: Arial, sans-serif; -} - -table.decision tr.decision-header { - background: var(--who-blue); - color: white; - font-weight: bold; -} - -table.decision tr.io-row { - background: var(--who-header); - color: #222; - font-weight: 600; -} - -table.decision td, table.decision th { - border: 1px solid var(--who-table-border); - padding: 0.5em 1em; -} - -.row-label { - font-weight: bold; - background: #f6fafd; - color: #555; -} - -.input, .inputEntry { - background: #e5f4fa; -} - -.output, .outputEntry { - background: #dff7ea; -} - -.annotation, .annotationEntry { - background: #fffbe5; -} - -tr.rule:nth-child(even) { - background: #f7fafc; +table.decision { + border-collapse: collapse; + width: 100%; + margin: 2em 0; + font-family: Arial, sans-serif; + background-color: var(--bg-color); + color: var(--text-color); +} + +table.decision tr.decision-header { + background: var(--who-blue); + color: white; + font-weight: bold; +} + +table.decision tr.io-row { + background: var(--who-header); + color: var(--text-color); + font-weight: 600; +} + +table.decision td, table.decision th { + border: 1px solid var(--who-table-border); + padding: 0.5em 1em; +} + +.row-label { + font-weight: bold; + background: var(--row-label-bg); + color: var(--row-label-text); +} + +.input, .inputEntry { + background: var(--input-bg); + color: var(--text-color); +} + +.output, .outputEntry { + background: var(--output-bg); + color: var(--text-color); +} + +.annotation, .annotationEntry { + background: var(--annotation-bg); + color: var(--text-color); +} + +tr.rule:nth-child(even) { + background: var(--table-stripe); +} + +/* Dark mode image handling - set white background for images that may be transparent */ +[data-theme="dark"] img, +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) img { + background-color: white; + border-radius: 4px; + padding: 2px; + } +} + +/* Dark mode toggle button styling */ +.theme-toggle { + background: none; + border: 1px solid var(--border-color, #007ab7); + border-radius: 4px; + color: var(--text-color, #222); + cursor: pointer; + font-size: 14px; + margin-left: 10px; + padding: 5px 10px; + transition: all 0.3s ease; +} + +.theme-toggle:hover { + background-color: var(--who-blue, #0093d0); + color: white; +} + +.theme-toggle:focus { + outline: 2px solid var(--who-blue, #0093d0); + outline-offset: 2px; } \ No newline at end of file diff --git a/local-template/package/content/assets/js/theme-toggle.js b/local-template/package/content/assets/js/theme-toggle.js new file mode 100644 index 0000000000..a4dfdc09a1 --- /dev/null +++ b/local-template/package/content/assets/js/theme-toggle.js @@ -0,0 +1,136 @@ +/** + * Dark/Light mode theme toggle functionality + * Handles theme switching and persistence across page loads + */ +(function() { + 'use strict'; + + // Get current theme from localStorage or detect system preference + function getCurrentTheme() { + const savedTheme = localStorage.getItem('theme'); + if (savedTheme) { + return savedTheme; + } + + // Check system preference + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + return 'dark'; + } + + return 'light'; + } + + // Apply theme to the document + function applyTheme(theme) { + if (theme === 'dark') { + document.documentElement.setAttribute('data-theme', 'dark'); + } else { + document.documentElement.removeAttribute('data-theme'); + } + } + + // Toggle between light and dark themes + function toggleTheme() { + const currentTheme = getCurrentTheme(); + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + + localStorage.setItem('theme', newTheme); + applyTheme(newTheme); + updateToggleButton(); + } + + // Update the toggle button text/icon + function updateToggleButton() { + const button = document.getElementById('theme-toggle'); + if (button) { + const currentTheme = getCurrentTheme(); + button.textContent = currentTheme === 'dark' ? '☀️ Light' : '🌙 Dark'; + button.setAttribute('aria-label', `Switch to ${currentTheme === 'dark' ? 'light' : 'dark'} mode`); + } + } + + // Create and insert the theme toggle button + function createToggleButton() { + const button = document.createElement('button'); + button.id = 'theme-toggle'; + button.className = 'theme-toggle'; + button.type = 'button'; + button.addEventListener('click', toggleTheme); + + // Try to find a good location for the button (near language selector or in header) + const possibleLocations = [ + '.navbar-nav', + '.navbar', + '#segment-header', + '.segment-header', + 'header', + '.container-fluid', + 'body' + ]; + + let inserted = false; + for (const selector of possibleLocations) { + const container = document.querySelector(selector); + if (container && !inserted) { + // If it's a nav container, append to it + if (selector.includes('nav')) { + container.appendChild(button); + } else { + // For other containers, create a wrapper div and position it appropriately + const wrapper = document.createElement('div'); + wrapper.style.cssText = 'position: absolute; top: 10px; right: 10px; z-index: 1000;'; + wrapper.appendChild(button); + + if (container.style.position === '' || container.style.position === 'static') { + container.style.position = 'relative'; + } + container.appendChild(wrapper); + } + inserted = true; + break; + } + } + + // Fallback: create a floating button if no suitable container found + if (!inserted) { + const wrapper = document.createElement('div'); + wrapper.style.cssText = 'position: fixed; top: 10px; right: 10px; z-index: 9999;'; + wrapper.appendChild(button); + document.body.appendChild(wrapper); + } + + return button; + } + + // Initialize theme functionality + function initTheme() { + // Apply the current theme immediately + const currentTheme = getCurrentTheme(); + applyTheme(currentTheme); + + // Create the toggle button when DOM is ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', function() { + createToggleButton(); + updateToggleButton(); + }); + } else { + createToggleButton(); + updateToggleButton(); + } + + // Listen for system theme changes + if (window.matchMedia) { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) { + // Only update if user hasn't explicitly set a theme + if (!localStorage.getItem('theme')) { + applyTheme(e.matches ? 'dark' : 'light'); + updateToggleButton(); + } + }); + } + } + + // Start initialization + initTheme(); +})(); \ No newline at end of file diff --git a/local-template/package/includes/_append.fragment-script.html b/local-template/package/includes/_append.fragment-script.html new file mode 100644 index 0000000000..5ec637cdc2 --- /dev/null +++ b/local-template/package/includes/_append.fragment-script.html @@ -0,0 +1 @@ + \ No newline at end of file From 844d6750e1284703f16faea77526fdf0f5ee84f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 16:42:50 +0000 Subject: [PATCH 3/3] Refactor implementation to complement WHO template dark mode Co-authored-by: litlfred <662242+litlfred@users.noreply.github.com> --- input/includes/dmn.css | 203 ----------------- input/scripts/includes/dmn.css | 203 ----------------- local-template/DARK_MODE.md | 72 ------ local-template/DMN_STYLING.md | 68 ++++++ .../package/content/assets/css/dmn.css | 205 ++++-------------- .../package/content/assets/js/theme-toggle.js | 136 ------------ .../includes/_append.fragment-script.html | 1 - 7 files changed, 115 insertions(+), 773 deletions(-) delete mode 100644 input/includes/dmn.css delete mode 100644 input/scripts/includes/dmn.css delete mode 100644 local-template/DARK_MODE.md create mode 100644 local-template/DMN_STYLING.md delete mode 100644 local-template/package/content/assets/js/theme-toggle.js delete mode 100644 local-template/package/includes/_append.fragment-script.html diff --git a/input/includes/dmn.css b/input/includes/dmn.css deleted file mode 100644 index 7717d147f5..0000000000 --- a/input/includes/dmn.css +++ /dev/null @@ -1,203 +0,0 @@ -/* WHO color palette: Example blue */ -:root { - --who-blue: #0093d0; - --who-header: #f0f9fc; - --who-table-border: #007ab7; - - /* Light mode colors (default) */ - --bg-color: #ffffff; - --text-color: #222222; - --border-color: #007ab7; - --table-stripe: #f7fafc; - --row-label-bg: #f6fafd; - --row-label-text: #555555; - --input-bg: #e5f4fa; - --output-bg: #dff7ea; - --annotation-bg: #fffbe5; - --link-color: #0066cc; - --link-hover-color: #004499; -} - -/* Dark mode colors */ -[data-theme="dark"] { - --who-blue: #0093d0; - --who-header: #1a2332; - --who-table-border: #4a90a4; - --bg-color: #1a1a1a; - --text-color: #e0e0e0; - --border-color: #4a90a4; - --table-stripe: #2a2a2a; - --row-label-bg: #2d3748; - --row-label-text: #cbd5e0; - --input-bg: #2c5282; - --output-bg: #2f855a; - --annotation-bg: #744210; - --link-color: #66b3ff; - --link-hover-color: #99ccff; -} - -/* Apply dark mode based on system preference if no explicit theme is set */ -@media (prefers-color-scheme: dark) { - :root:not([data-theme]) { - --who-header: #1a2332; - --who-table-border: #4a90a4; - --bg-color: #1a1a1a; - --text-color: #e0e0e0; - --border-color: #4a90a4; - --table-stripe: #2a2a2a; - --row-label-bg: #2d3748; - --row-label-text: #cbd5e0; - --input-bg: #2c5282; - --output-bg: #2f855a; - --annotation-bg: #744210; - --link-color: #66b3ff; - --link-hover-color: #99ccff; - } -} - -/* General dark mode styles for common elements */ -body { - background-color: var(--bg-color); - color: var(--text-color); - transition: background-color 0.3s ease, color 0.3s ease; -} - -a { - color: var(--link-color); - transition: color 0.3s ease; -} - -a:hover { - color: var(--link-hover-color); -} - -/* Apply to common Bootstrap/FHIR IG elements */ -.table { - background-color: var(--bg-color); - color: var(--text-color); -} - -.table th, -.table td { - border-color: var(--border-color); -} - -.table-bordered { - border-color: var(--border-color); -} - -.thead-dark th { - background-color: var(--who-blue); - border-color: var(--border-color); -} - -/* Code blocks and pre elements */ -pre, code { - background-color: var(--table-stripe); - color: var(--text-color); - border-color: var(--border-color); -} - -/* Cards and panels */ -.card { - background-color: var(--bg-color); - border-color: var(--border-color); -} - -.card-header { - background-color: var(--who-header); - border-color: var(--border-color); -} - -/* Navbar elements */ -.navbar { - background-color: var(--who-header) !important; -} - -.navbar-light .navbar-nav .nav-link { - color: var(--text-color); -} - -table.decision { - border-collapse: collapse; - width: 100%; - margin: 2em 0; - font-family: Arial, sans-serif; - background-color: var(--bg-color); - color: var(--text-color); -} - -table.decision tr.decision-header { - background: var(--who-blue); - color: white; - font-weight: bold; -} - -table.decision tr.io-row { - background: var(--who-header); - color: var(--text-color); - font-weight: 600; -} - -table.decision td, table.decision th { - border: 1px solid var(--who-table-border); - padding: 0.5em 1em; -} - -.row-label { - font-weight: bold; - background: var(--row-label-bg); - color: var(--row-label-text); -} - -.input, .inputEntry { - background: var(--input-bg); - color: var(--text-color); -} - -.output, .outputEntry { - background: var(--output-bg); - color: var(--text-color); -} - -.annotation, .annotationEntry { - background: var(--annotation-bg); - color: var(--text-color); -} - -tr.rule:nth-child(even) { - background: var(--table-stripe); -} - -/* Dark mode image handling - set white background for images that may be transparent */ -[data-theme="dark"] img, -@media (prefers-color-scheme: dark) { - :root:not([data-theme]) img { - background-color: white; - border-radius: 4px; - padding: 2px; - } -} - -/* Dark mode toggle button styling */ -.theme-toggle { - background: none; - border: 1px solid var(--border-color, #007ab7); - border-radius: 4px; - color: var(--text-color, #222); - cursor: pointer; - font-size: 14px; - margin-left: 10px; - padding: 5px 10px; - transition: all 0.3s ease; -} - -.theme-toggle:hover { - background-color: var(--who-blue, #0093d0); - color: white; -} - -.theme-toggle:focus { - outline: 2px solid var(--who-blue, #0093d0); - outline-offset: 2px; -} \ No newline at end of file diff --git a/input/scripts/includes/dmn.css b/input/scripts/includes/dmn.css deleted file mode 100644 index 7717d147f5..0000000000 --- a/input/scripts/includes/dmn.css +++ /dev/null @@ -1,203 +0,0 @@ -/* WHO color palette: Example blue */ -:root { - --who-blue: #0093d0; - --who-header: #f0f9fc; - --who-table-border: #007ab7; - - /* Light mode colors (default) */ - --bg-color: #ffffff; - --text-color: #222222; - --border-color: #007ab7; - --table-stripe: #f7fafc; - --row-label-bg: #f6fafd; - --row-label-text: #555555; - --input-bg: #e5f4fa; - --output-bg: #dff7ea; - --annotation-bg: #fffbe5; - --link-color: #0066cc; - --link-hover-color: #004499; -} - -/* Dark mode colors */ -[data-theme="dark"] { - --who-blue: #0093d0; - --who-header: #1a2332; - --who-table-border: #4a90a4; - --bg-color: #1a1a1a; - --text-color: #e0e0e0; - --border-color: #4a90a4; - --table-stripe: #2a2a2a; - --row-label-bg: #2d3748; - --row-label-text: #cbd5e0; - --input-bg: #2c5282; - --output-bg: #2f855a; - --annotation-bg: #744210; - --link-color: #66b3ff; - --link-hover-color: #99ccff; -} - -/* Apply dark mode based on system preference if no explicit theme is set */ -@media (prefers-color-scheme: dark) { - :root:not([data-theme]) { - --who-header: #1a2332; - --who-table-border: #4a90a4; - --bg-color: #1a1a1a; - --text-color: #e0e0e0; - --border-color: #4a90a4; - --table-stripe: #2a2a2a; - --row-label-bg: #2d3748; - --row-label-text: #cbd5e0; - --input-bg: #2c5282; - --output-bg: #2f855a; - --annotation-bg: #744210; - --link-color: #66b3ff; - --link-hover-color: #99ccff; - } -} - -/* General dark mode styles for common elements */ -body { - background-color: var(--bg-color); - color: var(--text-color); - transition: background-color 0.3s ease, color 0.3s ease; -} - -a { - color: var(--link-color); - transition: color 0.3s ease; -} - -a:hover { - color: var(--link-hover-color); -} - -/* Apply to common Bootstrap/FHIR IG elements */ -.table { - background-color: var(--bg-color); - color: var(--text-color); -} - -.table th, -.table td { - border-color: var(--border-color); -} - -.table-bordered { - border-color: var(--border-color); -} - -.thead-dark th { - background-color: var(--who-blue); - border-color: var(--border-color); -} - -/* Code blocks and pre elements */ -pre, code { - background-color: var(--table-stripe); - color: var(--text-color); - border-color: var(--border-color); -} - -/* Cards and panels */ -.card { - background-color: var(--bg-color); - border-color: var(--border-color); -} - -.card-header { - background-color: var(--who-header); - border-color: var(--border-color); -} - -/* Navbar elements */ -.navbar { - background-color: var(--who-header) !important; -} - -.navbar-light .navbar-nav .nav-link { - color: var(--text-color); -} - -table.decision { - border-collapse: collapse; - width: 100%; - margin: 2em 0; - font-family: Arial, sans-serif; - background-color: var(--bg-color); - color: var(--text-color); -} - -table.decision tr.decision-header { - background: var(--who-blue); - color: white; - font-weight: bold; -} - -table.decision tr.io-row { - background: var(--who-header); - color: var(--text-color); - font-weight: 600; -} - -table.decision td, table.decision th { - border: 1px solid var(--who-table-border); - padding: 0.5em 1em; -} - -.row-label { - font-weight: bold; - background: var(--row-label-bg); - color: var(--row-label-text); -} - -.input, .inputEntry { - background: var(--input-bg); - color: var(--text-color); -} - -.output, .outputEntry { - background: var(--output-bg); - color: var(--text-color); -} - -.annotation, .annotationEntry { - background: var(--annotation-bg); - color: var(--text-color); -} - -tr.rule:nth-child(even) { - background: var(--table-stripe); -} - -/* Dark mode image handling - set white background for images that may be transparent */ -[data-theme="dark"] img, -@media (prefers-color-scheme: dark) { - :root:not([data-theme]) img { - background-color: white; - border-radius: 4px; - padding: 2px; - } -} - -/* Dark mode toggle button styling */ -.theme-toggle { - background: none; - border: 1px solid var(--border-color, #007ab7); - border-radius: 4px; - color: var(--text-color, #222); - cursor: pointer; - font-size: 14px; - margin-left: 10px; - padding: 5px 10px; - transition: all 0.3s ease; -} - -.theme-toggle:hover { - background-color: var(--who-blue, #0093d0); - color: white; -} - -.theme-toggle:focus { - outline: 2px solid var(--who-blue, #0093d0); - outline-offset: 2px; -} \ No newline at end of file diff --git a/local-template/DARK_MODE.md b/local-template/DARK_MODE.md deleted file mode 100644 index 6830ea0da5..0000000000 --- a/local-template/DARK_MODE.md +++ /dev/null @@ -1,72 +0,0 @@ -# Dark Mode Implementation - -This document describes the dark/light mode toggle feature implemented for the SMART Guidelines base template. - -## Features - -- **Automatic Detection**: Respects user's system preference (`prefers-color-scheme`) -- **Manual Toggle**: Button in the top-right corner to manually switch themes -- **Persistence**: Theme choice is saved in localStorage and persists across page reloads -- **WHO Color Palette**: Maintains WHO branding while providing optimal contrast for dark mode -- **Transparent Image Handling**: Automatically adds white background to images in dark mode for better visibility - -## Implementation - -### CSS Custom Properties - -The implementation uses CSS custom properties (variables) to create a flexible theming system: - -```css -:root { - /* Light mode colors (default) */ - --bg-color: #ffffff; - --text-color: #222222; - --who-blue: #0093d0; - /* ... more variables */ -} - -[data-theme="dark"] { - /* Dark mode colors */ - --bg-color: #1a1a1a; - --text-color: #e0e0e0; - /* ... dark mode overrides */ -} -``` - -### JavaScript Toggle - -The theme toggle is implemented with vanilla JavaScript that: - -1. Detects system preference on page load -2. Applies saved theme from localStorage if available -3. Creates and positions the toggle button dynamically -4. Handles theme switching and persistence - -### Template Integration - -The feature is integrated into the FHIR IG template system via: - -- `_append.fragment-css.html`: Includes the dark mode CSS -- `_append.fragment-script.html`: Includes the theme toggle JavaScript -- CSS files in multiple locations for compatibility: - - `local-template/package/content/assets/css/dmn.css` - - `input/includes/dmn.css` - - `input/scripts/includes/dmn.css` - -## Usage - -The dark mode toggle appears automatically in the top-right corner of pages. Users can: - -1. Click the toggle button to switch between light and dark modes -2. The system will remember their choice -3. If no choice is made, the system preference is used - -## Customization - -To customize colors, modify the CSS custom properties in the `:root` and `[data-theme="dark"]` selectors in the CSS files. - -## Browser Support - -- Modern browsers with CSS custom properties support -- Graceful fallback to light mode for older browsers -- LocalStorage support for theme persistence \ No newline at end of file diff --git a/local-template/DMN_STYLING.md b/local-template/DMN_STYLING.md new file mode 100644 index 0000000000..ffbed5abf3 --- /dev/null +++ b/local-template/DMN_STYLING.md @@ -0,0 +1,68 @@ +# Decision Table Enhancements for SMART Guidelines + +This local template enhancement provides **decision table specific styling** that complements the WHO FHIR IG template's dark/light mode functionality. + +## Integration with WHO Template + +The WHO FHIR IG template (smart-ig-template) now includes comprehensive dark/light mode theming with: +- Theme toggle button in the navbar +- System preference detection +- Theme persistence +- General template theming + +This enhancement focuses specifically on **DMN decision table styling** with WHO color palette integration. + +## Features + +### 🎨 WHO Color Palette for Decision Tables +- **Input columns**: Light blue (`#e5f4fa` / `#2c5282`) +- **Output columns**: Light green (`#dff7ea` / `#2f855a`) +- **Annotation columns**: Light yellow (`#fffbe5` / `#744210`) +- **Header rows**: WHO blue (`#0093d0`) +- **Border colors**: WHO blue tones + +### 🌓 Automatic Theme Integration +- Respects the WHO template's theme system +- Uses `[data-theme="dark"]` selector for consistency +- Supports system preference via `@media (prefers-color-scheme: dark)` + +### 📊 Decision Table Enhancement +- Enhanced styling for `.decision` tables +- Color-coded columns for better readability +- Proper contrast ratios in both themes +- WHO branding compliance + +## Usage + +The enhancement automatically applies to decision tables when using these CSS classes: + +```html +
| Rule | +Input 1 | +Output | +Notes | +
|---|---|---|---|
| 1 | +Condition | +Action | +Comment | +