From 703831f6ea72d52888754fcea0035b5ddf867a39 Mon Sep 17 00:00:00 2001 From: nbats <44333466+nbats@users.noreply.github.com> Date: Sun, 4 Jan 2026 00:22:37 -0800 Subject: [PATCH 1/8] updated 3 pages --- docs/ai.md | 6 +++--- docs/linux-macos.md | 2 +- docs/mobile.md | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/ai.md b/docs/ai.md index c4b6d2810..5227b468c 100644 --- a/docs/ai.md +++ b/docs/ai.md @@ -310,7 +310,7 @@ * [AIFreeVideo](https://aifreevideo.com/) - Unlimited / MiniMax Video-01 / Sign-Up Required * [Google Whisk](https://labs.google/fx/en/tools/whisk) - Veo 3 / 10 Monthly * [Google Flow](https://labs.google/fx/tools/flow) - Veo 2 (10 Monthly) / Veo 3.1 (5 Monthly) -* [Dreamina](https://dreamina.capcut.com/ai-tool/home) - Seedream 4.5 / Nano Banana / 129 Credits Daily +* [Dreamina](https://dreamina.capcut.com/ai-tool/home) - 120 Credits Daily * [PixVerse](https://pixverse.ai/) - 3 Daily / [Discord](https://discord.com/invite/MXHErdJHMg) * [Opal Veo 3](https://opal.withgoogle.com/?flow=drive:/16qMbrhlc7gjTfI1zpnKbyoBxEcDRi4om&shared&mode=app) - Veo 3 / Use Alt Account * [Genmo](https://www.genmo.ai/) - 30 Monthly / [GitHub](https://github.com/genmoai/mochi) @@ -348,8 +348,8 @@ * [Z-Image](https://huggingface.co/spaces/Tongyi-MAI/Z-Image-Turbo) - z-Image / [GitHub](https://github.com/Tongyi-MAI/Z-Image) * [⁠Ernie](https://ernie.baidu.com/) - Unlimited / Editing / Sign-Up Required * [LongCat AI](https://longcat.chat/) - 100 Daily / Editing -* [Pollinations Play](https://pollinations.ai/play) - Z-Image Turbo / 5K Daily ⁠Pollinations -* [Mage](https://www.mage.space/) / [Discord](https://discord.com/invite/GT9bPgxyFP), [⁠Tater AI](https://taterai.github.io/Text2Image-Generator.html), [Loras](https://www.loras.dev/) / [X](https://x.com/tater_ai) / [GitHub](https://github.com/Nutlope/loras-dev), [ToolBaz](https://toolbaz.com/image/ai-image-generator), [Genspark](https://www.genspark.ai/) / [Discord](https://discord.com/invite/CsAQ6F4MPy), [AI Gallery](https://aigallery.app/) / [Telegram](https://t.me/aigalleryapp), [Seedream](https://seedream.pro/) or [Art Genie](https://artgenie.pages.dev/) - Flux Schnell +* [Pollinations Play](https://pollinations.ai/play) - Unlimted / Nano Banana / Z-Image Turbo / 5K Daily ⁠Pollinations +* [Mage](https://www.mage.space/) / [Discord](https://discord.com/invite/GT9bPgxyFP), [⁠Tater AI](https://taterai.github.io/Text2Image-Generator.html), [Loras](https://www.loras.dev/) / [X](https://x.com/tater_ai) / [GitHub](https://github.com/Nutlope/loras-dev), [ToolBaz](https://toolbaz.com/image/ai-image-generator), [AI Gallery](https://aigallery.app/) / [Telegram](https://t.me/aigalleryapp), [Seedream](https://seedream.pro/) or [Art Genie](https://artgenie.pages.dev/) - Flux Schnell * [Khoj](https://app.khoj.dev/) - Nano Banana / Imagen 4 / Reset Limits w/ Temp Mail * [⁠Coze](https://space.coze.cn/) - Seadream 4.0 / SoTA Image Gen / 50 Daily / Sign-Up with Phone # Required / US Select CA * [AIImagetoImage](https://aiimagetoimage.io/) or [⁠Image-Editor](https://image-editor.org/) - Nano Banana / Editing / No Sign-Up diff --git a/docs/linux-macos.md b/docs/linux-macos.md index 37572b714..be114b2d1 100644 --- a/docs/linux-macos.md +++ b/docs/linux-macos.md @@ -391,7 +391,7 @@ * [Self Managed Life](https://wiki.futo.org/) - FOSS / Self-Hosting Guide / [Video](https://youtu.be/Et5PPMYuOc8), [2](https://youtu.be/3fW9TV1WQi8) * [Server World](https://www.server-world.info/en/) - Network Server Guides * [HowtoForge](https://www.howtoforge.com/) / [GitHub](https://github.com/lollipopkit/flutter_server_box) or [Comfy.Guide](https://comfy.guide/) - Linux Server Software Guides -* [serverbox](https://cdn.lpkt.cn/serverbox/), [EasyPanel](https://easypanel.io/), [Webmin](https://webmin.com/) / [GitHub](https://github.com/webmin/webmin), [Cockpit Project](https://cockpit-project.org/), [CasaOS](https://casaos.zimaspace.com/) / [GitHub](https://github.com/IceWhaleTech/CasaOS) or [1Panel](https://1panel.pro/) / [GitHub](https://github.com/1Panel-dev/1Panel) - Linux Server Managers / Status +* [serverbox](https://cdn.lpkt.cn/serverbox/), [⁠Termix](https://github.com/Termix-SSH/Termix) / [Discord](https://discord.gg/jVQGdvHDrf)), [EasyPanel](https://easypanel.io/), [Webmin](https://webmin.com/) / [GitHub](https://github.com/webmin/webmin), [Cockpit Project](https://cockpit-project.org/), [CasaOS](https://casaos.zimaspace.com/) / [GitHub](https://github.com/IceWhaleTech/CasaOS) or [1Panel](https://1panel.pro/) / [GitHub](https://github.com/1Panel-dev/1Panel) - Linux Server Managers / Status * [⁠LXD UI](https://github.com/canonical/lxd-ui) - Linux Container + Virtual Machine Manager * [Proxmox](https://www.proxmox.com/) - Self-Hosted Server Tools / Virtual Environment * [yet another bench script](https://github.com/masonr/yet-another-bench-script) - Server Performance Script diff --git a/docs/mobile.md b/docs/mobile.md index eedd567b6..c9934b7d7 100644 --- a/docs/mobile.md +++ b/docs/mobile.md @@ -795,6 +795,7 @@ * ↪️ **[Song Identification Apps](https://www.reddit.com/r/FREEMEDIAHECKYEAH/wiki/audio#wiki_.25B7_song_identification)** * ⭐ **[Seal](https://github.com/JunkFood02/Seal)** - Multi-Site Audio Downloader +* ⭐ **[SpotiFLAC-Mobile](https://github.com/zarzet/SpotiFLAC-Mobile)** - Multi-Site Audio Downloader * ⭐ **[Seeker](https://github.com/jackBonadies/SeekerAndroid)** - Audio Downloader / Soulseek Frontend * ⭐ **[Poweramp Equalizer](https://www.reddit.com/r/FREEMEDIAHECKYEAH/wiki/android#wiki_.25B7_modded_apks)** (search) / [Forum](https://forum.powerampapp.com/), **[RootlessJamesDSP](https://github.com/timschneeb/RootlessJamesDSP)** / [Guide](https://rentry.co/rootlessjamesdsp-guide), [FlowEQ](https://play.google.com/store/apps/details?id=com.floweq.equalizer), [⁠Echo Equalizer](https://play.google.com/store/apps/details?id=com.hapibits.soundlift), [Wavelet](https://play.google.com/store/apps/details?id=com.pittvandewitt.wavelet) or [Flat Equalizer](https://play.google.com/store/apps/details?id=com.jazibkhan.equalizer) - Audio Equalizers * ⭐ **[AutomaTag](http://automatag.com/)** - Metadata Organizer @@ -1250,6 +1251,7 @@ * ⭐ **[SpotC++](https://spotc.yodaluca.dev/)** - Ad-Free Spotify / Sideloaded / [GitHub](https://github.com/SpotCompiled/SpotilifeC/) * ⭐ **[YTMusicUltimate](https://github.com/dayanch96/YTMusicUltimate)** - Ad-Free / Modded YouTube Music / [Discord](https://discord.gg/BhdUyCbgkZ) +* [SpotiFLAC-Mobile](https://github.com/zarzet/SpotiFLAC-Mobile) - Multi-Site Audio Downloader * [Cosmos Music Player](https://github.com/clquwu/Cosmos-Music-Player), [VOX](https://apps.apple.com/app/id916215494), [Jewelcase](https://jewelcase.app/), [FooBar](https://apps.apple.com/us/app/foobar2000/id1072807669) or [Melodista](https://apps.apple.com/app/id1293175325) - Audio Players * [Soundcloud](https://soundcloud.com/download) - Streaming / [Tweak](https://github.com/Rov3r/scmusicplus) * [Audiomack](https://apps.apple.com/app/id921765888) - Streaming From bfc15e81415364bc49a702fe253a75b8f648a9a2 Mon Sep 17 00:00:00 2001 From: Zenith Rifle <84105075+eli32-vlc@users.noreply.github.com> Date: Sun, 4 Jan 2026 16:22:51 +0800 Subject: [PATCH 2/8] feat: add monochrome theme support (#4537) * feat: add monochrome theme support * refactor: implement dedicated monochrome mode --- .../theme/components/ThemeDropdown.vue | 22 ++++-- docs/.vitepress/theme/style.scss | 35 ++++++--- docs/.vitepress/theme/themes/themeHandler.ts | 71 ++++++++++++++----- docs/.vitepress/theme/themes/types.ts | 2 +- 4 files changed, 96 insertions(+), 34 deletions(-) diff --git a/docs/.vitepress/theme/components/ThemeDropdown.vue b/docs/.vitepress/theme/components/ThemeDropdown.vue index e7f2d6994..465946360 100644 --- a/docs/.vitepress/theme/components/ThemeDropdown.vue +++ b/docs/.vitepress/theme/components/ThemeDropdown.vue @@ -18,11 +18,15 @@ interface ModeChoice { const modeChoices: ModeChoice[] = [ { mode: 'light', label: 'Light', icon: 'i-ph-sun-duotone' }, { mode: 'dark', label: 'Dark', icon: 'i-ph-moon-duotone' }, - { mode: 'dark', label: 'AMOLED', icon: 'i-ph-moon-stars-duotone', isAmoled: true } + { mode: 'dark', label: 'AMOLED', icon: 'i-ph-moon-stars-duotone', isAmoled: true }, + { mode: 'monochrome', label: 'Monochrome', icon: 'i-ph-circle-half-tilt-duotone' } ] const currentChoice = computed(() => { const current = (mode && (mode as any).value) ? (mode as any).value : 'light' + if (current === 'monochrome') { + return modeChoices[3] // Monochrome option + } if (current === 'dark' && amoledEnabled.value) { return modeChoices[2] // AMOLED option } @@ -34,18 +38,28 @@ const toggleDropdown = () => { } const selectMode = (choice: ModeChoice) => { + setMode(choice.mode) + if (choice.isAmoled) { - setMode('dark') setAmoledEnabled(true) } else { - setMode(choice.mode) - setAmoledEnabled(false) + // Only disable AMOLED if we are explicitly switching away from it + // But wait, if we switch to 'monochrome', 'amoled' flag might still be true? + // It doesn't matter because amoled is only checked if mode is 'dark'. + // However, if we switch back to 'dark', should it be amoled or not? + // Standard behavior: clicking 'Dark' (non-amoled) disables amoled. + if (choice.mode === 'dark') { + setAmoledEnabled(false) + } } isOpen.value = false } const isActiveChoice = (choice: ModeChoice) => { const current = (mode && (mode as any).value) ? (mode as any).value : 'light' + if (choice.mode === 'monochrome') { + return current === 'monochrome' + } if (choice.isAmoled) { return current === 'dark' && amoledEnabled.value } diff --git a/docs/.vitepress/theme/style.scss b/docs/.vitepress/theme/style.scss index 6c1b54432..8ca7d8560 100644 --- a/docs/.vitepress/theme/style.scss +++ b/docs/.vitepress/theme/style.scss @@ -138,17 +138,13 @@ */ :root { --vp-home-hero-name-color: transparent; - --vp-home-hero-name-background: -webkit-linear-gradient( - 120deg, - #c4b5fd 30%, - #7bc5e4 - ); + --vp-home-hero-name-background: -webkit-linear-gradient(120deg, + #c4b5fd 30%, + #7bc5e4); - --vp-home-hero-image-background-image: linear-gradient( - -45deg, - #c4b5fd 50%, - #47caff 50% - ); + --vp-home-hero-image-background-image: linear-gradient(-45deg, + #c4b5fd 50%, + #47caff 50%); --vp-home-hero-image-filter: blur(44px); } @@ -223,6 +219,7 @@ animation: nprogress-spinner 400ms linear infinite; } } + .nprogress-custom-parent { overflow: hidden; position: relative; @@ -253,7 +250,7 @@ } } -#VPContent strong > a { +#VPContent strong>a { font-weight: bold; } @@ -358,4 +355,20 @@ mask-size: 100% 100%; background-color: currentColor; color: inherit; +} + +/* Monochrome Specifics */ +html.monochrome { + filter: grayscale(100%); + + img, + video, + iframe { + filter: grayscale(100%); + } + + ::selection { + background-color: #333; + color: #fff; + } } \ No newline at end of file diff --git a/docs/.vitepress/theme/themes/themeHandler.ts b/docs/.vitepress/theme/themes/themeHandler.ts index 9016cec48..487429693 100644 --- a/docs/.vitepress/theme/themes/themeHandler.ts +++ b/docs/.vitepress/theme/themes/themeHandler.ts @@ -66,8 +66,8 @@ export class ThemeHandler { if (!localStorage.getItem(STORAGE_KEY_MODE)) { this.state.value.currentMode = e.matches ? 'dark' : 'light' this.applyTheme() - } - else { + } + else { this.applyTheme() } }) @@ -80,11 +80,17 @@ export class ThemeHandler { // Is this the WORST fix of all time??? const root = document.documentElement - const bgColor = currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#1A1A1A' : '#f8fafc' + const isMonochrome = currentMode === 'monochrome' + + // Monochrome overrides everything to pure black/white + // Standard Dark/Amoled logic applies otherwise + const bgColor = isMonochrome ? '#000000' : currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#1A1A1A' : '#f8fafc' root.style.setProperty('--vp-c-bg', bgColor) - const bgAltColor = currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#171717' : '#eef2f5' + + const bgAltColor = isMonochrome ? '#000000' : currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#171717' : '#eef2f5' root.style.setProperty('--vp-c-bg-alt', bgAltColor) - const bgElvColor = currentMode === 'dark' && this.amoledEnabled.value ? 'rgba(0, 0, 0, 0.9)' : currentMode === 'dark' ? '#1a1a1acc' : 'rgba(255, 255, 255, 0.8)' + + const bgElvColor = isMonochrome ? 'rgba(0, 0, 0, 0.9)' : currentMode === 'dark' && this.amoledEnabled.value ? 'rgba(0, 0, 0, 0.9)' : currentMode === 'dark' ? '#1a1a1acc' : 'rgba(255, 255, 255, 0.8)' root.style.setProperty('--vp-c-bg-elv', bgElvColor) this.applyDOMClasses(currentMode) @@ -99,17 +105,24 @@ export class ThemeHandler { private applyDOMClasses(mode: DisplayMode) { const root = document.documentElement - + // Remove all mode classes - root.classList.remove('dark', 'light', 'amoled') - + root.classList.remove('dark', 'light', 'amoled', 'monochrome') + // Add current mode class root.classList.add(mode) - + // Add amoled class if enabled in dark mode if (mode === 'dark' && this.amoledEnabled.value) { root.classList.add('amoled') } + + // Add monochrome class if enabled + if (mode === 'monochrome') { + root.classList.add('monochrome') + // Also add dark class because monochrome is effectively a high contrast dark mode + root.classList.add('dark') + } } private applyCSSVariables(colors: ModeColors, theme: Theme) { @@ -127,16 +140,32 @@ export class ThemeHandler { let bgColor = colors.bg let bgAltColor = colors.bgAlt let bgElvColor = colors.bgElv - + + const isMonochrome = this.state.value.currentMode === 'monochrome' + if (this.state.value.currentMode === 'dark' && this.amoledEnabled.value) { bgColor = '#000000' bgAltColor = '#000000' bgElvColor = 'rgba(0, 0, 0, 0.9)' } - // Apply brand colors only if theme specifies them - // Otherwise, remove inline styles to let ColorPicker CSS take effect - if (colors.brand && (colors.brand[1] || colors.brand[2] || colors.brand[3] || colors.brand.soft)) { + if (isMonochrome) { + bgColor = '#000000' + bgAltColor = '#000000' + bgElvColor = 'rgba(0, 0, 0, 0.9)' + } + + // Apply brand colors only if theme specifies them OR if monochrome to override + if (isMonochrome) { + root.style.setProperty('--vp-c-brand-1', '#d4d4d4') + root.style.setProperty('--vp-c-brand-2', '#a3a3a3') + root.style.setProperty('--vp-c-brand-3', '#737373') + root.style.setProperty('--vp-c-brand-soft', '#525252') + + root.style.setProperty('--vp-c-text-1', '#ffffff') + root.style.setProperty('--vp-c-text-2', '#a3a3a3') + root.style.setProperty('--vp-c-text-3', '#737373') + } else if (colors.brand && (colors.brand[1] || colors.brand[2] || colors.brand[3] || colors.brand.soft)) { if (colors.brand[1]) root.style.setProperty('--vp-c-brand-1', colors.brand[1]) if (colors.brand[2]) root.style.setProperty('--vp-c-brand-2', colors.brand[2]) if (colors.brand[3]) root.style.setProperty('--vp-c-brand-3', colors.brand[3]) @@ -158,11 +187,12 @@ export class ThemeHandler { } // Apply text colors - always set them to ensure proper theme switching - if (colors.text) { + // Except whenever Monochrome is active, we handled text colors above + if (!isMonochrome && colors.text) { if (colors.text[1]) root.style.setProperty('--vp-c-text-1', colors.text[1]) if (colors.text[2]) root.style.setProperty('--vp-c-text-2', colors.text[2]) if (colors.text[3]) root.style.setProperty('--vp-c-text-3', colors.text[3]) - } else { + } else if (!isMonochrome) { // Remove inline styles if theme doesn't specify text colors // This allows CSS variables from style.scss to take effect root.style.removeProperty('--vp-c-text-1') @@ -284,7 +314,7 @@ export class ThemeHandler { this.state.value.theme = themeRegistry[themeName] localStorage.setItem(STORAGE_KEY_THEME, themeName) this.applyTheme() - + // Force re-apply ColorPicker colors if theme doesn't specify brand colors this.ensureColorPickerColors() } @@ -297,10 +327,10 @@ export class ThemeHandler { public toggleMode() { const currentMode = this.state.value.currentMode - + // Toggle between light and dark const newMode: DisplayMode = currentMode === 'light' ? 'dark' : 'light' - + this.setMode(newMode) } @@ -368,6 +398,10 @@ export class ThemeHandler { public isAmoledMode() { return this.state.value.currentMode === 'dark' && this.amoledEnabled.value } + + public isMonochromeMode() { + return this.state.value.currentMode === 'monochrome' + } } // Global theme handler instance @@ -403,6 +437,7 @@ export function useTheme() { amoledEnabled: handler.getAmoledEnabledRef(), setAmoledEnabled: (enabled: boolean) => handler.setAmoledEnabled(enabled), toggleAmoled: () => handler.toggleAmoled(), + isMonochromeMode: () => handler.isMonochromeMode(), state } } \ No newline at end of file diff --git a/docs/.vitepress/theme/themes/types.ts b/docs/.vitepress/theme/themes/types.ts index de54fa80a..9709c020d 100644 --- a/docs/.vitepress/theme/themes/types.ts +++ b/docs/.vitepress/theme/themes/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -export type DisplayMode = 'light' | 'dark' +export type DisplayMode = 'light' | 'dark' | 'monochrome' export interface ModeColors { // Brand colors (optional - if not specified, ColorPicker values are used) From 1ce78cec8caabca8be832bc6e08f10f67df830d9 Mon Sep 17 00:00:00 2001 From: nbats <44333466+nbats@users.noreply.github.com> Date: Sun, 4 Jan 2026 00:43:48 -0800 Subject: [PATCH 3/8] Revert "feat: add monochrome theme support (#4537)" (#4538) This reverts commit bfc15e81415364bc49a702fe253a75b8f648a9a2. --- .../theme/components/ThemeDropdown.vue | 22 ++---- docs/.vitepress/theme/style.scss | 35 +++------ docs/.vitepress/theme/themes/themeHandler.ts | 71 +++++-------------- docs/.vitepress/theme/themes/types.ts | 2 +- 4 files changed, 34 insertions(+), 96 deletions(-) diff --git a/docs/.vitepress/theme/components/ThemeDropdown.vue b/docs/.vitepress/theme/components/ThemeDropdown.vue index 465946360..e7f2d6994 100644 --- a/docs/.vitepress/theme/components/ThemeDropdown.vue +++ b/docs/.vitepress/theme/components/ThemeDropdown.vue @@ -18,15 +18,11 @@ interface ModeChoice { const modeChoices: ModeChoice[] = [ { mode: 'light', label: 'Light', icon: 'i-ph-sun-duotone' }, { mode: 'dark', label: 'Dark', icon: 'i-ph-moon-duotone' }, - { mode: 'dark', label: 'AMOLED', icon: 'i-ph-moon-stars-duotone', isAmoled: true }, - { mode: 'monochrome', label: 'Monochrome', icon: 'i-ph-circle-half-tilt-duotone' } + { mode: 'dark', label: 'AMOLED', icon: 'i-ph-moon-stars-duotone', isAmoled: true } ] const currentChoice = computed(() => { const current = (mode && (mode as any).value) ? (mode as any).value : 'light' - if (current === 'monochrome') { - return modeChoices[3] // Monochrome option - } if (current === 'dark' && amoledEnabled.value) { return modeChoices[2] // AMOLED option } @@ -38,28 +34,18 @@ const toggleDropdown = () => { } const selectMode = (choice: ModeChoice) => { - setMode(choice.mode) - if (choice.isAmoled) { + setMode('dark') setAmoledEnabled(true) } else { - // Only disable AMOLED if we are explicitly switching away from it - // But wait, if we switch to 'monochrome', 'amoled' flag might still be true? - // It doesn't matter because amoled is only checked if mode is 'dark'. - // However, if we switch back to 'dark', should it be amoled or not? - // Standard behavior: clicking 'Dark' (non-amoled) disables amoled. - if (choice.mode === 'dark') { - setAmoledEnabled(false) - } + setMode(choice.mode) + setAmoledEnabled(false) } isOpen.value = false } const isActiveChoice = (choice: ModeChoice) => { const current = (mode && (mode as any).value) ? (mode as any).value : 'light' - if (choice.mode === 'monochrome') { - return current === 'monochrome' - } if (choice.isAmoled) { return current === 'dark' && amoledEnabled.value } diff --git a/docs/.vitepress/theme/style.scss b/docs/.vitepress/theme/style.scss index 8ca7d8560..6c1b54432 100644 --- a/docs/.vitepress/theme/style.scss +++ b/docs/.vitepress/theme/style.scss @@ -138,13 +138,17 @@ */ :root { --vp-home-hero-name-color: transparent; - --vp-home-hero-name-background: -webkit-linear-gradient(120deg, - #c4b5fd 30%, - #7bc5e4); + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #c4b5fd 30%, + #7bc5e4 + ); - --vp-home-hero-image-background-image: linear-gradient(-45deg, - #c4b5fd 50%, - #47caff 50%); + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #c4b5fd 50%, + #47caff 50% + ); --vp-home-hero-image-filter: blur(44px); } @@ -219,7 +223,6 @@ animation: nprogress-spinner 400ms linear infinite; } } - .nprogress-custom-parent { overflow: hidden; position: relative; @@ -250,7 +253,7 @@ } } -#VPContent strong>a { +#VPContent strong > a { font-weight: bold; } @@ -355,20 +358,4 @@ mask-size: 100% 100%; background-color: currentColor; color: inherit; -} - -/* Monochrome Specifics */ -html.monochrome { - filter: grayscale(100%); - - img, - video, - iframe { - filter: grayscale(100%); - } - - ::selection { - background-color: #333; - color: #fff; - } } \ No newline at end of file diff --git a/docs/.vitepress/theme/themes/themeHandler.ts b/docs/.vitepress/theme/themes/themeHandler.ts index 487429693..9016cec48 100644 --- a/docs/.vitepress/theme/themes/themeHandler.ts +++ b/docs/.vitepress/theme/themes/themeHandler.ts @@ -66,8 +66,8 @@ export class ThemeHandler { if (!localStorage.getItem(STORAGE_KEY_MODE)) { this.state.value.currentMode = e.matches ? 'dark' : 'light' this.applyTheme() - } - else { + } + else { this.applyTheme() } }) @@ -80,17 +80,11 @@ export class ThemeHandler { // Is this the WORST fix of all time??? const root = document.documentElement - const isMonochrome = currentMode === 'monochrome' - - // Monochrome overrides everything to pure black/white - // Standard Dark/Amoled logic applies otherwise - const bgColor = isMonochrome ? '#000000' : currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#1A1A1A' : '#f8fafc' + const bgColor = currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#1A1A1A' : '#f8fafc' root.style.setProperty('--vp-c-bg', bgColor) - - const bgAltColor = isMonochrome ? '#000000' : currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#171717' : '#eef2f5' + const bgAltColor = currentMode === 'dark' && this.amoledEnabled.value ? '#000000' : currentMode === 'dark' ? '#171717' : '#eef2f5' root.style.setProperty('--vp-c-bg-alt', bgAltColor) - - const bgElvColor = isMonochrome ? 'rgba(0, 0, 0, 0.9)' : currentMode === 'dark' && this.amoledEnabled.value ? 'rgba(0, 0, 0, 0.9)' : currentMode === 'dark' ? '#1a1a1acc' : 'rgba(255, 255, 255, 0.8)' + const bgElvColor = currentMode === 'dark' && this.amoledEnabled.value ? 'rgba(0, 0, 0, 0.9)' : currentMode === 'dark' ? '#1a1a1acc' : 'rgba(255, 255, 255, 0.8)' root.style.setProperty('--vp-c-bg-elv', bgElvColor) this.applyDOMClasses(currentMode) @@ -105,24 +99,17 @@ export class ThemeHandler { private applyDOMClasses(mode: DisplayMode) { const root = document.documentElement - + // Remove all mode classes - root.classList.remove('dark', 'light', 'amoled', 'monochrome') - + root.classList.remove('dark', 'light', 'amoled') + // Add current mode class root.classList.add(mode) - + // Add amoled class if enabled in dark mode if (mode === 'dark' && this.amoledEnabled.value) { root.classList.add('amoled') } - - // Add monochrome class if enabled - if (mode === 'monochrome') { - root.classList.add('monochrome') - // Also add dark class because monochrome is effectively a high contrast dark mode - root.classList.add('dark') - } } private applyCSSVariables(colors: ModeColors, theme: Theme) { @@ -140,32 +127,16 @@ export class ThemeHandler { let bgColor = colors.bg let bgAltColor = colors.bgAlt let bgElvColor = colors.bgElv - - const isMonochrome = this.state.value.currentMode === 'monochrome' - + if (this.state.value.currentMode === 'dark' && this.amoledEnabled.value) { bgColor = '#000000' bgAltColor = '#000000' bgElvColor = 'rgba(0, 0, 0, 0.9)' } - if (isMonochrome) { - bgColor = '#000000' - bgAltColor = '#000000' - bgElvColor = 'rgba(0, 0, 0, 0.9)' - } - - // Apply brand colors only if theme specifies them OR if monochrome to override - if (isMonochrome) { - root.style.setProperty('--vp-c-brand-1', '#d4d4d4') - root.style.setProperty('--vp-c-brand-2', '#a3a3a3') - root.style.setProperty('--vp-c-brand-3', '#737373') - root.style.setProperty('--vp-c-brand-soft', '#525252') - - root.style.setProperty('--vp-c-text-1', '#ffffff') - root.style.setProperty('--vp-c-text-2', '#a3a3a3') - root.style.setProperty('--vp-c-text-3', '#737373') - } else if (colors.brand && (colors.brand[1] || colors.brand[2] || colors.brand[3] || colors.brand.soft)) { + // Apply brand colors only if theme specifies them + // Otherwise, remove inline styles to let ColorPicker CSS take effect + if (colors.brand && (colors.brand[1] || colors.brand[2] || colors.brand[3] || colors.brand.soft)) { if (colors.brand[1]) root.style.setProperty('--vp-c-brand-1', colors.brand[1]) if (colors.brand[2]) root.style.setProperty('--vp-c-brand-2', colors.brand[2]) if (colors.brand[3]) root.style.setProperty('--vp-c-brand-3', colors.brand[3]) @@ -187,12 +158,11 @@ export class ThemeHandler { } // Apply text colors - always set them to ensure proper theme switching - // Except whenever Monochrome is active, we handled text colors above - if (!isMonochrome && colors.text) { + if (colors.text) { if (colors.text[1]) root.style.setProperty('--vp-c-text-1', colors.text[1]) if (colors.text[2]) root.style.setProperty('--vp-c-text-2', colors.text[2]) if (colors.text[3]) root.style.setProperty('--vp-c-text-3', colors.text[3]) - } else if (!isMonochrome) { + } else { // Remove inline styles if theme doesn't specify text colors // This allows CSS variables from style.scss to take effect root.style.removeProperty('--vp-c-text-1') @@ -314,7 +284,7 @@ export class ThemeHandler { this.state.value.theme = themeRegistry[themeName] localStorage.setItem(STORAGE_KEY_THEME, themeName) this.applyTheme() - + // Force re-apply ColorPicker colors if theme doesn't specify brand colors this.ensureColorPickerColors() } @@ -327,10 +297,10 @@ export class ThemeHandler { public toggleMode() { const currentMode = this.state.value.currentMode - + // Toggle between light and dark const newMode: DisplayMode = currentMode === 'light' ? 'dark' : 'light' - + this.setMode(newMode) } @@ -398,10 +368,6 @@ export class ThemeHandler { public isAmoledMode() { return this.state.value.currentMode === 'dark' && this.amoledEnabled.value } - - public isMonochromeMode() { - return this.state.value.currentMode === 'monochrome' - } } // Global theme handler instance @@ -437,7 +403,6 @@ export function useTheme() { amoledEnabled: handler.getAmoledEnabledRef(), setAmoledEnabled: (enabled: boolean) => handler.setAmoledEnabled(enabled), toggleAmoled: () => handler.toggleAmoled(), - isMonochromeMode: () => handler.isMonochromeMode(), state } } \ No newline at end of file diff --git a/docs/.vitepress/theme/themes/types.ts b/docs/.vitepress/theme/themes/types.ts index 9709c020d..de54fa80a 100644 --- a/docs/.vitepress/theme/themes/types.ts +++ b/docs/.vitepress/theme/themes/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -export type DisplayMode = 'light' | 'dark' | 'monochrome' +export type DisplayMode = 'light' | 'dark' export interface ModeColors { // Brand colors (optional - if not specified, ColorPicker values are used) From 8b53fe3833a567ab58f86ef8d3e0ad9f01fbc7e3 Mon Sep 17 00:00:00 2001 From: WildeBeast2521 <182007783+WildeBeast2521@users.noreply.github.com> Date: Sun, 4 Jan 2026 13:53:43 +0500 Subject: [PATCH 4/8] Several changes (#4536) 1. Separated Podman as it's a Docker competitor. 2. Updated WatchTower (archived) link with active, popular fork. --- docs/developer-tools.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/developer-tools.md b/docs/developer-tools.md index cf0a255cb..0fa327432 100644 --- a/docs/developer-tools.md +++ b/docs/developer-tools.md @@ -301,20 +301,19 @@ * 🌐 **[Awesome Docker](https://moistcatawumpus.github.io/awesome-docker/)** - Docker Services Index * 🌐 **[Selfhosted-Apps-Docker](https://github.com/DoTheEvo/selfhosted-apps-docker)** - Self-Hosted Docker Apps / Guides -* ⭐ **[Docker](https://www.docker.com/)** - Build, Manage and Run Apps in Containers -* ⭐ **[portainer](https://portainer.io/)**, [DockGE](https://dockge.kuma.pet/), [moncho](https://moncho.github.io/dry/) or [podman](https://podman.io/) / [2](https://podman-desktop.io/) - Container Managers +* ⭐ **[Docker](https://www.docker.com/)** / [Desktop App](https://www.docker.com/products/docker-desktop/) - Build, Manage and Run Apps in Containers +* ⭐ **[Podman](https://podman.io/)** / [2](https://podman-desktop.io/) / [GitHub](https://github.com/containers/podman) / [Compose](https://github.com/containers/podman-compose) / [Playground](https://labs.play-with-docker.com/) - Rootless, Daemon-less, Open Source Docker Alternative +* ⭐ **[Portainer](https://portainer.io/)**, [DockGE](https://dockge.kuma.pet/) or [moncho](https://moncho.github.io/dry/) - Container Managers * ⭐ **[Composerize](https://www.composerize.com/)**, [2](https://github.com/irbigdata/data-dockerfiles) - Compose Docker Files * ⭐ **[Hub Docker](https://hub.docker.com/)**, [2](https://linuxserver.io/), [3](https://hotio.dev/) - Docker Images -* [Docker Desktop](https://www.docker.com/products/docker-desktop/) - Docker Desktop App * [LazyDocker](https://github.com/jesseduffield/lazydocker), [oxker](https://github.com/mrjackwills/oxker) or [Isaiah](https://github.com/will-moss/isaiah) - Docker Managers / TUIs * [Dockerized](https://github.com/datastack-net/dockerized) - Docker Command-Line * [Dockle](https://github.com/goodwithtech/dockle) - Image Linter * [Dive](https://github.com/wagoodman/dive) - Analyze Images -* [WatchTower](https://containrrr.dev/watchtower/) - Container Automation +* [WatchTower](http://watchtower.nickfedor.com/) / [GitHub](https://github.com/nicholas-fedor/watchtower) - Container Automation * [Dozzle](https://dozzle.dev/) - Log Viewer * [Docker AutoHeal](https://github.com/willfarrell/docker-autoheal) - Container Monitor * [Diun](https://crazymax.dev/diun/) - Docker Notifications -* [Podman Compose](https://github.com/containers/podman-compose) / [Playground](https://labs.play-with-docker.com/) - Podman Compose * [Termible](https://termible.io/) - Docker Powered Site Terminals *** @@ -1232,4 +1231,4 @@ * [MSTG](https://mas.owasp.org/) or [DVIA-v2](https://github.com/prateek147/DVIA-v2) - App Security Testing / Reverse Engineering * [Malimite](https://github.com/LaurieWired/Malimite) - iOS / macOS Decompiler * [challenges.re](https://challenges.re/) - Reverse Engineer Code -* [horsicq](https://horsicq.github.io/) - File Type Identification Tools / [GitHub](https://github.com/horsicq/) \ No newline at end of file +* [horsicq](https://horsicq.github.io/) - File Type Identification Tools / [GitHub](https://github.com/horsicq/) From 802f4183464eba95bc78564370335a43f76f2bb0 Mon Sep 17 00:00:00 2001 From: litekin Date: Sun, 4 Jan 2026 09:27:55 +0000 Subject: [PATCH 5/8] Add Discord link (#4533) --- docs/beginners-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/beginners-guide.md b/docs/beginners-guide.md index 70b958c68..755807c6c 100644 --- a/docs/beginners-guide.md +++ b/docs/beginners-guide.md @@ -16,7 +16,7 @@ For mobile **[AdGuard Premium](https://www.reddit.com/r/FREEMEDIAHECKYEAH/wiki/a > How can I safely scan files, and determine if detections are false positives? -Before installing any file, it's recommended to scan the setup / install with **[VirusTotal](https://www.virustotal.com/)**. If you're having trouble determining if something is a false positive, refer to the **[Scan Guide](https://claraiscute.neocities.org/Guides/vtguide)** / [2](https://claraiscute.pages.dev/Guides/vtguide), or send it to us in Discord and we'll take a look for you. For Android Apps, it's best to analyze them in a sandbox like [Triage](https://tria.ge/). +Before installing any file, it's recommended to scan the setup / install with **[VirusTotal](https://www.virustotal.com/)**. If you're having trouble determining if something is a false positive, refer to the **[Scan Guide](https://claraiscute.neocities.org/Guides/vtguide)** / [2](https://claraiscute.pages.dev/Guides/vtguide), or send it to us in [Discord](https://github.com/fmhy/FMHY/wiki/FMHY-Discord) and we'll take a look for you. For Android Apps, it's best to analyze them in a sandbox like [Triage](https://tria.ge/). !!!note Most antivirus programs are unnecessary and can cause slow down. If you use trusted websites, Windows Defender should be all you need to stay safe, and you can run a [Malwarebytes](https://www.malwarebytes.com/) scan from time to time for extra protection. From 28d58ed18f38f29cc19479fba11470b524fe9766 Mon Sep 17 00:00:00 2001 From: nbats <44333466+nbats@users.noreply.github.com> Date: Sun, 4 Jan 2026 01:50:37 -0800 Subject: [PATCH 6/8] updated AI page --- docs/ai.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/ai.md b/docs/ai.md index 5227b468c..375f612fc 100644 --- a/docs/ai.md +++ b/docs/ai.md @@ -301,7 +301,7 @@ * 🌐 **[VBench](https://huggingface.co/spaces/Vchitect/VBench_Leaderboard)** - Video Generation Model Leaderboard * ⭐ **[Grok Imagine](https://grok.com/imagine)** - 30 Daily / Imagine 0.9 / [Subreddit](https://www.reddit.com/r/grok/) / [Discord](https://discord.com/invite/kqCc86jM55) -* [⁠GeminiGen AI](https://geminigen.ai/) - Unlimited / Sora 2 / Veo 3.1 / [Discord](https://discord.gg/vJnYe86T8F) +* [⁠GeminiGen AI](https://geminigen.ai/) - Sora 2 / Veo 3.1 / Grok / Google Login Required / [Discord](https://discord.gg/vJnYe86T8F) * [Bing Create](https://www.bing.com/images/create) - Sora 1 / No Image Input * [Sora](https://openai.com/index/sora/) - 6 Daily / [Signup Guide](https://github.com/fmhy/FMHY/wiki/FMHY%E2%80%90Notes.md#sora) / [Remove Watermarks](https://unmarkit.app/sora) * [Qwen](https://chat.qwen.ai/) - 10 Daily / [Discord](https://discord.com/invite/CV4E9rpNSD) / [GitHub](https://github.com/QwenLM) @@ -331,12 +331,11 @@ * ⭐ **[PigenAI](https://pigenai.art/)** - Unlimited / Imagen 4 / Qwen / Nano Banana * ⭐ **[Dreamina](https://dreamina.capcut.com/ai-tool/home)** - 120 Credits Daily / Seedream 4.0 / Sign-Up Required * [Yupp.ai](https://yupp.ai/) - Nano Banana Pro / GPT Image 1.5 / Seedream 4.5 Max / Qwen-Image / Google Login / [Discord](https://discord.com/invite/yuppai) -* [Pollinations](https://chat.pollinations.ai/) - Nano Banana Pro / GPT Image 1.5 / Multiple Generators / No Sign-Up +* [Pollinations](https://chat.pollinations.ai/) - Nano Banana Pro / GPT Image 1.5 / Multiple Generators / No Sign-Up / [Limit Tips](https://github.com/fmhy/FMHY/wiki/FMHY%E2%80%90Notes.md#pollinations-limits) * [⁠Hunyuan Image Generation](https://hunyuan.tencent.com/image/en) - Hunyuan Image 3.0 / Unlimited * [⁠ISH](https://ish.chat/) - Unlimited / GPT Image 1 mini / Dall-E 3 / Flux Kontext (dev) / Editing / No Sign-Up / [Discord](https://discord.gg/cwDTVKyKJz) * [Grok](https://grok.com/) - 96 Daily / Editing / Sign-Up Required / [Subreddit](https://www.reddit.com/r/grok/) / [Discord](https://discord.com/invite/kqCc86jM55) * [Qwen](https://chat.qwen.ai/) - 30 Per 24 Hours / Editing / Sign-Up Required / [Discord](https://discord.com/invite/CV4E9rpNSD) / [GitHub](https://github.com/QwenLM) -* [⁠GeminiGen AI](https://geminigen.ai/app/imagen) - Unlimited / Nano Banana Pro / Sign-Up Required / [Discord](https://discord.gg/vJnYe86T8F) * [Recraft](https://www.recraft.ai/) - 30 Daily / Sign-Up Required / [Discord](https://discord.gg/recraft) * [Reve Image](https://app.reve.com) - 20 Daily / Editing / Sign-Up Required / [X](https://x.com/reve) / [Discord](https://discord.gg/Nedxp9fYUZ) * [ImageFX](https://labs.google/fx/tools/image-fx) - Imagen 4 / Unlimited / Region-Based / Sign-Up Required / [Discord](https://discord.com/invite/googlelabs) From 10fa9f6d17894e63e1ddafe8e4adac1a7fa8d102 Mon Sep 17 00:00:00 2001 From: nbats <44333466+nbats@users.noreply.github.com> Date: Sun, 4 Jan 2026 04:35:42 -0800 Subject: [PATCH 7/8] added annas backups --- docs/reading.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reading.md b/docs/reading.md index ec70cefb7..8be22ad79 100644 --- a/docs/reading.md +++ b/docs/reading.md @@ -7,7 +7,7 @@ # ► Ebooks * 🌐 **[Open Slum](https://open-slum.org/)**, [2](https://open-slum.pages.dev/) - Book Site Index / Uptime Tracking -* ⭐ **[Anna's Archive](https://annas-archive.org/)**, [2](https://annas-archive.li/), [3](https://annas-archive.se/) - Books / Comics / [Auto-Expand](https://greasyfork.org/en/scripts/494262) / [Matrix](https://matrix.to/#/#annas:archivecommunication.org) / [Subreddit](https://www.reddit.com/r/Annas_Archive/) +* ⭐ **[Anna's Archive](https://annas-archive.org/)**, [2](https://annas-archive.li/), [3](https://annas-archive.se/), [4](https://annas-archive.pm/), [5](https://annas-archive.in/) - Books / Comics / [Auto-Expand](https://greasyfork.org/en/scripts/494262) / [Matrix](https://matrix.to/#/#annas:archivecommunication.org) / [Subreddit](https://www.reddit.com/r/Annas_Archive/) * ⭐ **[Z-Library](https://z-lib.gd/)**, [2](https://articles.sk/), [3](https://1lib.sk/), [4](https://z-lib.fm/) - Books / Comics / [Apps / Extensions](https://go-to-library.sk/), [2](https://playtorrio.xyz/) / [.onion](http://loginzlib2vrak5zzpcocc3ouizykn6k5qecgj2tzlnab5wcbqhembyd.onion/), [2](http://bookszlibb74ugqojhzhg2a63w5i2atv5bqarulgczawnbmsb6s6qead.onion/) / [Subreddit](https://www.reddit.com/r/zlibrary/) * ⭐ **[Mobilism](https://forum.mobilism.org)**, [2](https://forum.mobilism.me/) - Books / Audiobooks / Magazines / Newspapers / Comics / [Ranks](https://github.com/fmhy/FMHY/wiki/FMHY%E2%80%90Notes.md#mobilism-ranks) * ⭐ **[MyAnonaMouse](https://www.myanonamouse.net/)** - Books / Audiobooks / Comics / Sheet Music / [Invite Required](https://www.myanonamouse.net/inviteapp.php) From 46b6ae53bb989c0137145bf8d47bdb5e2331fc54 Mon Sep 17 00:00:00 2001 From: Zenith Rifle <84105075+eli32-vlc@users.noreply.github.com> Date: Sun, 4 Jan 2026 21:32:51 +0800 Subject: [PATCH 8/8] Add monochrome theme with grayscale filter (#4541) --- .../theme/components/ColorPicker.vue | 4 - docs/.vitepress/theme/style.scss | 28 ++-- docs/.vitepress/theme/themes/configs/index.ts | 4 +- .../theme/themes/configs/monochrome.ts | 151 ++++++++++++++++++ docs/.vitepress/theme/themes/themeHandler.ts | 38 ++--- 5 files changed, 186 insertions(+), 39 deletions(-) create mode 100644 docs/.vitepress/theme/themes/configs/monochrome.ts diff --git a/docs/.vitepress/theme/components/ColorPicker.vue b/docs/.vitepress/theme/components/ColorPicker.vue index 607043b75..8cf98c059 100644 --- a/docs/.vitepress/theme/components/ColorPicker.vue +++ b/docs/.vitepress/theme/components/ColorPicker.vue @@ -211,12 +211,8 @@ watch(selectedColor, async (color) => { if (!color) return; const theme = generateThemeFromColor(color) themeRegistry[`color-${color}`] = theme - // Explicitly set the theme to override any previous selection await nextTick() - console.log('Setting theme to:', `color-${color}`) - console.log('Current themeName:', themeName ? themeName.value : undefined, 'mode:', mode ? (mode as any).value : undefined) setTheme(`color-${color}`) - console.log('After setTheme, themeName:', themeName ? themeName.value : undefined) }) const toggleAmoled = () => { diff --git a/docs/.vitepress/theme/style.scss b/docs/.vitepress/theme/style.scss index 6c1b54432..8dac12032 100644 --- a/docs/.vitepress/theme/style.scss +++ b/docs/.vitepress/theme/style.scss @@ -81,6 +81,15 @@ --vp-custom-block-danger-text-deep: theme('colors.carnation.200'); } +.monochrome { + + [class*='i-'], + svg, + img:not(.VPImage) { + filter: grayscale(100%); + } +} + .vp-doc a { color: var(--vp-c-brand-1); text-decoration: underline; @@ -138,17 +147,13 @@ */ :root { --vp-home-hero-name-color: transparent; - --vp-home-hero-name-background: -webkit-linear-gradient( - 120deg, - #c4b5fd 30%, - #7bc5e4 - ); + --vp-home-hero-name-background: -webkit-linear-gradient(120deg, + #c4b5fd 30%, + #7bc5e4); - --vp-home-hero-image-background-image: linear-gradient( - -45deg, - #c4b5fd 50%, - #47caff 50% - ); + --vp-home-hero-image-background-image: linear-gradient(-45deg, + #c4b5fd 50%, + #47caff 50%); --vp-home-hero-image-filter: blur(44px); } @@ -223,6 +228,7 @@ animation: nprogress-spinner 400ms linear infinite; } } + .nprogress-custom-parent { overflow: hidden; position: relative; @@ -253,7 +259,7 @@ } } -#VPContent strong > a { +#VPContent strong>a { font-weight: bold; } diff --git a/docs/.vitepress/theme/themes/configs/index.ts b/docs/.vitepress/theme/themes/configs/index.ts index b8f90fec3..c0e67b5e4 100644 --- a/docs/.vitepress/theme/themes/configs/index.ts +++ b/docs/.vitepress/theme/themes/configs/index.ts @@ -14,10 +14,12 @@ * limitations under the License. */ import { catppuccinTheme } from './catppuccin' +import { monochromeTheme } from './monochrome' import type { ThemeRegistry } from '../types' export const themeRegistry: ThemeRegistry = { catppuccin: catppuccinTheme, + monochrome: monochromeTheme, } -export { catppuccinTheme } +export { catppuccinTheme, monochromeTheme } diff --git a/docs/.vitepress/theme/themes/configs/monochrome.ts b/docs/.vitepress/theme/themes/configs/monochrome.ts new file mode 100644 index 000000000..b9659d78d --- /dev/null +++ b/docs/.vitepress/theme/themes/configs/monochrome.ts @@ -0,0 +1,151 @@ +import type { Theme } from '../types' + +export const monochromeTheme: Theme = { + name: 'monochrome', + displayName: 'Monochrome', + preview: '#808080', + modes: { + light: { + brand: { + 1: '#000000', + 2: '#1a1a1a', + 3: '#333333', + soft: '#666666' + }, + bg: '#FFFFFF', + bgAlt: '#F5F5F5', + bgElv: 'rgba(255, 255, 255, 0.95)', + bgMark: '#E0E0E0', + text: { + 1: '#000000', + 2: '#333333', + 3: '#808080' + }, + button: { + brand: { + bg: '#000000', + border: '#000000', + text: '#FFFFFF', + hoverBorder: '#333333', + hoverText: '#FFFFFF', + hoverBg: '#333333', + activeBorder: '#000000', + activeText: '#FFFFFF', + activeBg: '#000000' + }, + alt: { + bg: '#808080', + text: '#FFFFFF', + hoverBg: '#666666', + hoverText: '#FFFFFF' + } + }, + customBlock: { + info: { + bg: '#F5F5F5', + border: '#000000', + text: '#000000', + textDeep: '#000000' + }, + tip: { + bg: '#F5F5F5', + border: '#333333', + text: '#1a1a1a', + textDeep: '#000000' + }, + warning: { + bg: '#F5F5F5', + border: '#666666', + text: '#333333', + textDeep: '#1a1a1a' + }, + danger: { + bg: '#F5F5F5', + border: '#000000', + text: '#000000', + textDeep: '#000000' + } + }, + selection: { + bg: '#CCCCCC' + }, + home: { + heroNameColor: '#000000', + heroNameBackground: '#FFFFFF', + heroImageBackground: 'linear-gradient(135deg, #E0E0E0 0%, #FFFFFF 100%)', + heroImageFilter: 'blur(44px)' + } + }, + dark: { + brand: { + 1: '#FFFFFF', + 2: '#E0E0E0', + 3: '#CCCCCC', + soft: '#999999' + }, + bg: '#000000', + bgAlt: '#0A0A0A', + bgElv: 'rgba(0, 0, 0, 0.95)', + bgMark: '#1A1A1A', + text: { + 1: '#FFFFFF', + 2: '#CCCCCC', + 3: '#808080' + }, + button: { + brand: { + bg: '#FFFFFF', + border: '#FFFFFF', + text: '#000000', + hoverBorder: '#CCCCCC', + hoverText: '#000000', + hoverBg: '#CCCCCC', + activeBorder: '#FFFFFF', + activeText: '#000000', + activeBg: '#FFFFFF' + }, + alt: { + bg: '#808080', + text: '#000000', + hoverBg: '#999999', + hoverText: '#000000' + } + }, + customBlock: { + info: { + bg: '#1A1A1A', + border: '#FFFFFF', + text: '#FFFFFF', + textDeep: '#FFFFFF' + }, + tip: { + bg: '#1A1A1A', + border: '#CCCCCC', + text: '#E0E0E0', + textDeep: '#FFFFFF' + }, + warning: { + bg: '#1A1A1A', + border: '#999999', + text: '#CCCCCC', + textDeep: '#E0E0E0' + }, + danger: { + bg: '#1A1A1A', + border: '#FFFFFF', + text: '#FFFFFF', + textDeep: '#FFFFFF' + } + }, + selection: { + bg: '#333333' + }, + home: { + heroNameColor: '#FFFFFF', + heroNameBackground: '#000000', + heroImageBackground: 'linear-gradient(135deg, #1A1A1A 0%, #000000 100%)', + heroImageFilter: 'blur(44px)' + } + } + } +} diff --git a/docs/.vitepress/theme/themes/themeHandler.ts b/docs/.vitepress/theme/themes/themeHandler.ts index 9016cec48..c11c1601d 100644 --- a/docs/.vitepress/theme/themes/themeHandler.ts +++ b/docs/.vitepress/theme/themes/themeHandler.ts @@ -66,8 +66,8 @@ export class ThemeHandler { if (!localStorage.getItem(STORAGE_KEY_MODE)) { this.state.value.currentMode = e.matches ? 'dark' : 'light' this.applyTheme() - } - else { + } + else { this.applyTheme() } }) @@ -95,17 +95,23 @@ export class ThemeHandler { this.applyDOMClasses(currentMode) this.applyCSSVariables(modeColors, theme) + + if (theme.name === 'monochrome') { + root.classList.add('monochrome') + } else { + root.classList.remove('monochrome') + } } private applyDOMClasses(mode: DisplayMode) { const root = document.documentElement - + // Remove all mode classes root.classList.remove('dark', 'light', 'amoled') - + // Add current mode class root.classList.add(mode) - + // Add amoled class if enabled in dark mode if (mode === 'dark' && this.amoledEnabled.value) { root.classList.add('amoled') @@ -127,7 +133,7 @@ export class ThemeHandler { let bgColor = colors.bg let bgAltColor = colors.bgAlt let bgElvColor = colors.bgElv - + if (this.state.value.currentMode === 'dark' && this.amoledEnabled.value) { bgColor = '#000000' bgAltColor = '#000000' @@ -170,20 +176,6 @@ export class ThemeHandler { root.style.removeProperty('--vp-c-text-3') } - // Debug: log applied text color variables so we can inspect in console - try { - // eslint-disable-next-line no-console - console.log('[ThemeHandler] applied text vars', { - theme: theme.name, - mode: this.state.value.currentMode, - vp_text_1: root.style.getPropertyValue('--vp-c-text-1'), - vp_text_2: root.style.getPropertyValue('--vp-c-text-2'), - vp_text_3: root.style.getPropertyValue('--vp-c-text-3') - }) - } catch (e) { - // ignore - } - // Apply button colors root.style.setProperty('--vp-button-brand-bg', colors.button.brand.bg) root.style.setProperty('--vp-button-brand-border', colors.button.brand.border) @@ -284,7 +276,7 @@ export class ThemeHandler { this.state.value.theme = themeRegistry[themeName] localStorage.setItem(STORAGE_KEY_THEME, themeName) this.applyTheme() - + // Force re-apply ColorPicker colors if theme doesn't specify brand colors this.ensureColorPickerColors() } @@ -297,10 +289,10 @@ export class ThemeHandler { public toggleMode() { const currentMode = this.state.value.currentMode - + // Toggle between light and dark const newMode: DisplayMode = currentMode === 'light' ? 'dark' : 'light' - + this.setMode(newMode) }