From 0dcb99f926d4af88c0f9ef509dadebec3d6466fc Mon Sep 17 00:00:00 2001 From: cinereal Date: Sun, 4 Oct 2026 15:45:10 +0200 Subject: [PATCH] ndg: add a theme toggle to the page header A click selects the light or the dark theme. The page keeps the selection in `localStorage` and applies it before the first paint. When the selected theme is the same as the system theme, the page follows the system theme again. The style sheet applies each `prefers-color-scheme` rule also when `data-theme` on `` selects that theme, and does not apply it when `data-theme` selects the other theme. The toggle also selects the matching `` of a `` with a `prefers-color-scheme` media query, and sends an `ndg:themechange` event on `document`. Assisted-by: Claude:claude-opus-5-5 Claude-Session: https://claude.ai/code/session_01RJvbghuj5GtCBiCjmBepNJ --- CHANGELOG.md | 7 + crates/ndg-templates/templates/default.css | 318 +++++++++++++++++--- crates/ndg-templates/templates/default.html | 39 ++- crates/ndg-templates/templates/lib.html | 39 ++- crates/ndg-templates/templates/main.js | 110 +++++++ crates/ndg-templates/templates/main.test.js | 56 +++- crates/ndg-templates/templates/options.html | 39 ++- crates/ndg-templates/templates/search.html | 39 ++- 8 files changed, 596 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de2a65376..4f27efcdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,13 @@ changes. `sidebar.group_by_dir` report errors ([#290](https://github.com/feel-co/ndg/issues/290)). +- A theme toggle in the page header. A click selects the light or the dark + theme, and the page keeps the selection in `localStorage`. When the selected + theme is the same as the system theme, the page follows the system theme + again. The toggle also selects the matching `` of a `` with a + `prefers-color-scheme` media query. The page sends an `ndg:themechange` event + on `document` when the theme changes. + ### Changed - `ndg init` now generates configuration from the config types and defaults, diff --git a/crates/ndg-templates/templates/default.css b/crates/ndg-templates/templates/default.css index b19f6e502..afc8c4d26 100644 --- a/crates/ndg-templates/templates/default.css +++ b/crates/ndg-templates/templates/default.css @@ -129,7 +129,7 @@ } @media (prefers-color-scheme: dark) { - :root { + :root:not([data-theme="light"]) { /* Dark Mode Colors */ --bg-color: var(--neutral-950); --bg-surface: var(--neutral-900); @@ -171,6 +171,47 @@ } } +:root[data-theme="dark"] { + /* Dark Mode Colors */ + --bg-color: var(--neutral-950); + --bg-surface: var(--neutral-900); + --bg-surface-2: #334155; + --text-color: #e2e8f0; + --text-muted: #94a3b8; + --heading-color: var(--neutral-100); + --link-color: #60a5fa; + --link-hover-color: #93c5fd; + + --brand: var(--link-color); + --brand-hover: var(--link-hover-color); + --focus-ring: rgba(96, 165, 250, 0.4); + --border-strong: var(--neutral-700); + + --border-color: var(--neutral-800); + --code-bg: #111827; + --code-border: var(--neutral-800); + --header-bg: color-mix(in oklch, var(--neutral-950) 80%, transparent); + --header-text: var(--neutral-100); + --header-muted: var(--neutral-400); + --header-border: var(--neutral-800); + --sidebar-bg: var(--neutral-900); + --sidebar-hover: var(--neutral-800); + --sidebar-active: var(--neutral-700); + --footer-bg: var(--neutral-900); + --shadow-color: rgba(0, 0, 0, 0.25); + --shadow-color-darker: rgba(0, 0, 0, 0.35); + + /* Admonition Colors */ + --admonition-note-color: #3b82f6; + --admonition-tip-color: #10b981; + --admonition-warning-color: #f59e0b; + --admonition-danger-color: #ef4444; + --admonition-info-color: #6366f1; + --admonition-important-color: #8b5cf6; + --admonition-example-color: #06b6d4; + --admonition-caution-color: #f97316; +} + /* Smooth scrolling */ html { scroll-behavior: smooth; @@ -684,27 +725,45 @@ th { } @media (prefers-color-scheme: light) { - :root { + :root:not([data-theme="dark"]) { --table-border-color: #cbd5e1; } - th, - td { + :where(:root:not([data-theme="dark"])) th, + :where(:root:not([data-theme="dark"])) td { border-color: var(--table-border-color); } } +:root[data-theme="light"] { + --table-border-color: #cbd5e1; +} + +:where(:root[data-theme="light"]) th, +:where(:root[data-theme="light"]) td { + border-color: var(--table-border-color); +} + @media (prefers-color-scheme: dark) { - :root { + :root:not([data-theme="light"]) { --table-border-color: var(--neutral-800); } - th, - td { + :where(:root:not([data-theme="light"])) th, + :where(:root:not([data-theme="light"])) td { border-color: var(--table-border-color); } } +:root[data-theme="dark"] { + --table-border-color: var(--neutral-800); +} + +:where(:root[data-theme="dark"]) th, +:where(:root[data-theme="dark"]) td { + border-color: var(--table-border-color); +} + /* Images */ img { max-width: 100%; @@ -721,6 +780,75 @@ img { margin-left: auto; } +/* Theme toggle */ +.theme-toggle { + margin-left: auto; + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + padding: 0; + flex-shrink: 0; + color: var(--header-muted); + background: none; + border: 1px solid transparent; + border-radius: var(--radius-md); + cursor: pointer; + transition: + color var(--transition-fast), + border-color var(--transition-fast); + + &:hover { + color: var(--header-text); + border-color: var(--border-color); + } + + &:focus-visible { + outline: 2px solid var(--focus-ring); + outline-offset: 2px; + } + + svg { + fill: none; + stroke: currentColor; + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; + } + + /* The icon shows the theme that a click selects. */ + .theme-icon-sun { + display: none; + } +} + +.search-container ~ .theme-toggle { + margin-left: 0; +} + +@media (prefers-color-scheme: dark) { + :where(:root:not([data-theme="light"])) .theme-toggle { + .theme-icon-moon { + display: none; + } + + .theme-icon-sun { + display: block; + } + } +} + +:where(:root[data-theme="dark"]) .theme-toggle { + .theme-icon-moon { + display: none; + } + + .theme-icon-sun { + display: block; + } +} + /* Desktop search input */ #search-input { padding: var(--space-2) var(--space-3); @@ -833,11 +961,15 @@ img { } @media (prefers-color-scheme: dark) { - .mobile-search-popup { + :where(:root:not([data-theme="light"])) .mobile-search-popup { background-color: rgba(0, 0, 0, 0.7); } } +:where(:root[data-theme="dark"]) .mobile-search-popup { + background-color: rgba(0, 0, 0, 0.7); +} + .mobile-search-popup.active { display: flex; } @@ -972,11 +1104,15 @@ img { } @media (prefers-color-scheme: dark) { - #search-page-input { + :where(:root:not([data-theme="light"])) #search-page-input { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } } +:where(:root[data-theme="dark"]) #search-page-input { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); +} + #search-page-input:focus { outline: none; border-color: var(--brand); @@ -1014,13 +1150,19 @@ img { } @media (prefers-color-scheme: dark) { - .search-keyboard-hints kbd { + :where(:root:not([data-theme="light"])) .search-keyboard-hints kbd { background-color: var(--sidebar-bg); border-color: var(--border-color); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } } +:where(:root[data-theme="dark"]) .search-keyboard-hints kbd { + background-color: var(--sidebar-bg); + border-color: var(--border-color); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} + @media (max-width: 800px) { .search-keyboard-hints { display: none; @@ -1084,12 +1226,17 @@ mark { } @media (prefers-color-scheme: dark) { - mark { + :where(:root:not([data-theme="light"])) mark { background-color: rgba(59, 130, 246, 0.3); color: #60a5fa; } } +:where(:root[data-theme="dark"]) mark { + background-color: rgba(59, 130, 246, 0.3); + color: #60a5fa; +} + @media (max-width: 800px) { .search-page-results { margin-top: var(--space-4); @@ -1251,74 +1398,138 @@ mark { /* Dark mode SVG icon adjustments */ @media (prefers-color-scheme: dark) { - .admonition.note .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.note .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2360a5fa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'%3E%3C/line%3E%3C/svg%3E"); } - .admonition.tip .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.tip .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2334d399' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); } - .admonition.warning .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.warning .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23fbbf24' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'%3E%3C/path%3E%3Cline x1='12' y1='9' x2='12' y2='13'%3E%3C/line%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'%3E%3C/line%3E%3C/svg%3E"); } - .admonition.danger .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.danger .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23f87171' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2'%3E%3C/polygon%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); } - .admonition.info .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.info .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23818cf8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 16v-4'%3E%3C/path%3E%3Cpath d='M12 8h.01'%3E%3C/path%3E%3C/svg%3E"); } - .admonition.important .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.important .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23a78bfa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 8v4'%3E%3C/path%3E%3Cpath d='M12 16h.01'%3E%3C/path%3E%3C/svg%3E"); } - .admonition.example .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.example .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2322d3ee' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 17 10 11 4 5'%3E%3C/polyline%3E%3Cpolyline points='12 19 20 19'%3E%3C/polyline%3E%3C/svg%3E"); } - .admonition.caution .admonition-title::before { + :where(:root:not([data-theme="light"])) .admonition.caution .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23fb923c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'%3E%3C/path%3E%3C/svg%3E"); } } +:where(:root[data-theme="dark"]) .admonition.note .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2360a5fa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'%3E%3C/line%3E%3C/svg%3E"); +} + +:where(:root[data-theme="dark"]) .admonition.tip .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2334d399' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); +} + +:where(:root[data-theme="dark"]) .admonition.warning .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23fbbf24' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'%3E%3C/path%3E%3Cline x1='12' y1='9' x2='12' y2='13'%3E%3C/line%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'%3E%3C/line%3E%3C/svg%3E"); +} + +:where(:root[data-theme="dark"]) .admonition.danger .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23f87171' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2'%3E%3C/polygon%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); +} + +:where(:root[data-theme="dark"]) .admonition.info .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23818cf8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 16v-4'%3E%3C/path%3E%3Cpath d='M12 8h.01'%3E%3C/path%3E%3C/svg%3E"); +} + +:where(:root[data-theme="dark"]) .admonition.important .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23a78bfa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 8v4'%3E%3C/path%3E%3Cpath d='M12 16h.01'%3E%3C/path%3E%3C/svg%3E"); +} + +:where(:root[data-theme="dark"]) .admonition.example .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2322d3ee' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 17 10 11 4 5'%3E%3C/polyline%3E%3Cpolyline points='12 19 20 19'%3E%3C/polyline%3E%3C/svg%3E"); +} + +:where(:root[data-theme="dark"]) .admonition.caution .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23fb923c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'%3E%3C/path%3E%3C/svg%3E"); +} + /* Light mode SVG icon adjustments */ @media (prefers-color-scheme: light) { - .admonition.note .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.note .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%233b82f6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'%3E%3C/line%3E%3C/svg%3E"); } - .admonition.tip .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.tip .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2310b981' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); } - .admonition.warning .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.warning .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23f59e0b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'%3E%3C/path%3E%3Cline x1='12' y1='9' x2='12' y2='13'%3E%3C/line%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'%3E%3C/line%3E%3C/svg%3E"); } - .admonition.danger .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.danger .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23ef4444' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2'%3E%3C/polygon%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); } - .admonition.info .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.info .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%236366f1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 16v-4'%3E%3C/path%3E%3Cpath d='M12 8h.01'%3E%3C/path%3E%3C/svg%3E"); } - .admonition.important .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.important .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%238b5cf6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 8v4'%3E%3C/path%3E%3Cpath d='M12 16h.01'%3E%3C/path%3E%3C/svg%3E"); } - .admonition.example .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.example .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2306b6d4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 17 10 11 4 5'%3E%3C/polyline%3E%3Cpolyline points='12 19 20 19'%3E%3C/polyline%3E%3C/svg%3E"); } - .admonition.caution .admonition-title::before { + :where(:root:not([data-theme="dark"])) .admonition.caution .admonition-title::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23f97316' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'%3E%3C/path%3E%3C/svg%3E"); } } +:where(:root[data-theme="light"]) .admonition.note .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%233b82f6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'%3E%3C/line%3E%3C/svg%3E"); +} + +:where(:root[data-theme="light"]) .admonition.tip .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2310b981' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); +} + +:where(:root[data-theme="light"]) .admonition.warning .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23f59e0b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'%3E%3C/path%3E%3Cline x1='12' y1='9' x2='12' y2='13'%3E%3C/line%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'%3E%3C/line%3E%3C/svg%3E"); +} + +:where(:root[data-theme="light"]) .admonition.danger .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23ef4444' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2'%3E%3C/polygon%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); +} + +:where(:root[data-theme="light"]) .admonition.info .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%236366f1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 16v-4'%3E%3C/path%3E%3Cpath d='M12 8h.01'%3E%3C/path%3E%3C/svg%3E"); +} + +:where(:root[data-theme="light"]) .admonition.important .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%238b5cf6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpath d='M12 8v4'%3E%3C/path%3E%3Cpath d='M12 16h.01'%3E%3C/path%3E%3C/svg%3E"); +} + +:where(:root[data-theme="light"]) .admonition.example .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%2306b6d4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 17 10 11 4 5'%3E%3C/polyline%3E%3Cpolyline points='12 19 20 19'%3E%3C/polyline%3E%3C/svg%3E"); +} + +:where(:root[data-theme="light"]) .admonition.caution .admonition-title::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' fill='none' stroke='%23f97316' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'%3E%3C/path%3E%3C/svg%3E"); +} + @keyframes highlight-pulse { 0% { background-color: rgba(59, 130, 246, 0.1); @@ -1358,11 +1569,15 @@ mark { } @media (prefers-color-scheme: dark) { - .copy-link { + :where(:root:not([data-theme="light"])) .copy-link { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='16' height='16' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71'%3E%3C/path%3E%3Cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71'%3E%3C/path%3E%3C/svg%3E"); } } +:where(:root[data-theme="dark"]) .copy-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='16' height='16' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71'%3E%3C/path%3E%3Cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71'%3E%3C/path%3E%3C/svg%3E"); +} + h1:hover .copy-link, h2:hover .copy-link, h3:hover .copy-link, @@ -1579,6 +1794,7 @@ h6:hover .copy-link { .sidebar, .sidebar-toggle, .search-container, + .theme-toggle, footer, .copy-link { display: none !important; @@ -2528,34 +2744,44 @@ h6:hover .copy-link { } } +@keyframes highlight-fade-dark { + 0% { + background-color: rgba(255, 193, 7, 0.4); + } + 100% { + background-color: rgba(255, 193, 7, 0.15); + } +} + +@keyframes highlight-pulse-active-dark { + 0% { + background-color: rgba(255, 152, 0, 0.4); + } + 100% { + background-color: rgba(255, 152, 0, 0.6); + } +} + @media (prefers-color-scheme: dark) { - .search-highlight { + :where(:root:not([data-theme="light"])) .search-highlight { background-color: rgba(255, 193, 7, 0.3); animation: highlight-fade-dark 3s ease-out forwards; } - .search-highlight-active { + :where(:root:not([data-theme="light"])) .search-highlight-active { background-color: rgba(255, 152, 0, 0.5); animation: highlight-pulse-active-dark 1s ease-in-out infinite alternate; } +} - @keyframes highlight-fade-dark { - 0% { - background-color: rgba(255, 193, 7, 0.4); - } - 100% { - background-color: rgba(255, 193, 7, 0.15); - } - } +:where(:root[data-theme="dark"]) .search-highlight { + background-color: rgba(255, 193, 7, 0.3); + animation: highlight-fade-dark 3s ease-out forwards; +} - @keyframes highlight-pulse-active-dark { - 0% { - background-color: rgba(255, 152, 0, 0.4); - } - 100% { - background-color: rgba(255, 152, 0, 0.6); - } - } +:where(:root[data-theme="dark"]) .search-highlight-active { + background-color: rgba(255, 152, 0, 0.5); + animation: highlight-pulse-active-dark 1s ease-in-out infinite alternate; } /* Sidebar directory groups */ diff --git a/crates/ndg-templates/templates/default.html b/crates/ndg-templates/templates/default.html index f0d1c4e09..c1768114c 100644 --- a/crates/ndg-templates/templates/default.html +++ b/crates/ndg-templates/templates/default.html @@ -9,12 +9,18 @@