Compare commits
7 commits
1cf002b8b8
...
350f6f3865
Author | SHA1 | Date | |
---|---|---|---|
|
350f6f3865 | ||
|
c6db8689b4 | ||
|
1da8ae56c4 | ||
|
d5f81c0f81 | ||
|
7d3987f124 | ||
|
afd5f125a7 | ||
|
ed0caf5727 |
8 changed files with 291 additions and 46 deletions
|
@ -1,16 +1,24 @@
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
|
import sitemap from '@astrojs/sitemap';
|
||||||
|
|
||||||
|
import mdx from '@astrojs/mdx';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
site: 'https://terminal-blog.example.com',
|
site: 'https://terminal-blog.example.com',
|
||||||
base: '/',
|
base: '/',
|
||||||
trailingSlash: 'ignore',
|
trailingSlash: 'ignore',
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
format: 'directory'
|
format: 'directory'
|
||||||
},
|
},
|
||||||
|
|
||||||
markdown: {
|
markdown: {
|
||||||
shikiConfig: {
|
shikiConfig: {
|
||||||
theme: 'nord',
|
theme: 'nord',
|
||||||
wrap: true
|
wrap: true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
integrations: [sitemap(), mdx()]
|
||||||
});
|
});
|
|
@ -13,6 +13,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.2.6",
|
"@astrojs/mdx": "^4.2.6",
|
||||||
"@astrojs/rss": "^4.0.1",
|
"@astrojs/rss": "^4.0.1",
|
||||||
|
"@astrojs/sitemap": "^3.3.1",
|
||||||
"astro": "^5.2.5",
|
"astro": "^5.2.5",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"ultrahtml": "^1.6.0"
|
"ultrahtml": "^1.6.0"
|
||||||
|
|
51
pnpm-lock.yaml
generated
51
pnpm-lock.yaml
generated
|
@ -14,6 +14,9 @@ importers:
|
||||||
'@astrojs/rss':
|
'@astrojs/rss':
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.11
|
version: 4.0.11
|
||||||
|
'@astrojs/sitemap':
|
||||||
|
specifier: ^3.3.1
|
||||||
|
version: 3.3.1
|
||||||
astro:
|
astro:
|
||||||
specifier: ^5.2.5
|
specifier: ^5.2.5
|
||||||
version: 5.7.10(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)
|
version: 5.7.10(@types/node@22.15.3)(rollup@4.40.1)(typescript@5.8.3)
|
||||||
|
@ -52,6 +55,9 @@ packages:
|
||||||
'@astrojs/rss@4.0.11':
|
'@astrojs/rss@4.0.11':
|
||||||
resolution: {integrity: sha512-3e3H8i6kc97KGnn9iaZBJpIkdoQi8MmR5zH5R+dWsfCM44lLTszOqy1OBfGGxDt56mpQkYVtZJWoxMyWuUZBfw==}
|
resolution: {integrity: sha512-3e3H8i6kc97KGnn9iaZBJpIkdoQi8MmR5zH5R+dWsfCM44lLTszOqy1OBfGGxDt56mpQkYVtZJWoxMyWuUZBfw==}
|
||||||
|
|
||||||
|
'@astrojs/sitemap@3.3.1':
|
||||||
|
resolution: {integrity: sha512-GRnDUCTviBSNfXJ0Jmur+1/C+z3g36jy79VyYggfe1uNyEYSTcmAfTTCmbytrRvJRNyJJnSfB/77Gnm9PiXRRg==}
|
||||||
|
|
||||||
'@astrojs/telemetry@3.2.1':
|
'@astrojs/telemetry@3.2.1':
|
||||||
resolution: {integrity: sha512-SSVM820Jqc6wjsn7qYfV9qfeQvePtVc1nSofhyap7l0/iakUKywj3hfy3UJAOV4sGV4Q/u450RD4AaCaFvNPlg==}
|
resolution: {integrity: sha512-SSVM820Jqc6wjsn7qYfV9qfeQvePtVc1nSofhyap7l0/iakUKywj3hfy3UJAOV4sGV4Q/u450RD4AaCaFvNPlg==}
|
||||||
engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0}
|
engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0}
|
||||||
|
@ -500,9 +506,15 @@ packages:
|
||||||
'@types/nlcst@2.0.3':
|
'@types/nlcst@2.0.3':
|
||||||
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
|
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
|
||||||
|
|
||||||
|
'@types/node@17.0.45':
|
||||||
|
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
|
||||||
|
|
||||||
'@types/node@22.15.3':
|
'@types/node@22.15.3':
|
||||||
resolution: {integrity: sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==}
|
resolution: {integrity: sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==}
|
||||||
|
|
||||||
|
'@types/sax@1.2.7':
|
||||||
|
resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
|
||||||
|
|
||||||
'@types/unist@2.0.11':
|
'@types/unist@2.0.11':
|
||||||
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
|
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
|
||||||
|
|
||||||
|
@ -541,6 +553,9 @@ packages:
|
||||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
|
arg@5.0.2:
|
||||||
|
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
||||||
|
|
||||||
argparse@2.0.1:
|
argparse@2.0.1:
|
||||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||||
|
|
||||||
|
@ -1289,6 +1304,9 @@ packages:
|
||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
sax@1.4.1:
|
||||||
|
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
|
||||||
|
|
||||||
semver@7.7.1:
|
semver@7.7.1:
|
||||||
resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
|
resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
@ -1307,6 +1325,11 @@ packages:
|
||||||
sisteransi@1.0.5:
|
sisteransi@1.0.5:
|
||||||
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
|
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
|
||||||
|
|
||||||
|
sitemap@8.0.0:
|
||||||
|
resolution: {integrity: sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==}
|
||||||
|
engines: {node: '>=14.0.0', npm: '>=6.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
smol-toml@1.3.4:
|
smol-toml@1.3.4:
|
||||||
resolution: {integrity: sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==}
|
resolution: {integrity: sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==}
|
||||||
engines: {node: '>= 18'}
|
engines: {node: '>= 18'}
|
||||||
|
@ -1322,6 +1345,9 @@ packages:
|
||||||
space-separated-tokens@2.0.2:
|
space-separated-tokens@2.0.2:
|
||||||
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
|
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
|
||||||
|
|
||||||
|
stream-replace-string@2.0.0:
|
||||||
|
resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -1678,6 +1704,12 @@ snapshots:
|
||||||
fast-xml-parser: 4.5.3
|
fast-xml-parser: 4.5.3
|
||||||
kleur: 4.1.5
|
kleur: 4.1.5
|
||||||
|
|
||||||
|
'@astrojs/sitemap@3.3.1':
|
||||||
|
dependencies:
|
||||||
|
sitemap: 8.0.0
|
||||||
|
stream-replace-string: 2.0.0
|
||||||
|
zod: 3.24.3
|
||||||
|
|
||||||
'@astrojs/telemetry@3.2.1':
|
'@astrojs/telemetry@3.2.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
ci-info: 4.2.0
|
ci-info: 4.2.0
|
||||||
|
@ -2031,10 +2063,16 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
|
|
||||||
|
'@types/node@17.0.45': {}
|
||||||
|
|
||||||
'@types/node@22.15.3':
|
'@types/node@22.15.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.21.0
|
undici-types: 6.21.0
|
||||||
|
|
||||||
|
'@types/sax@1.2.7':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 22.15.3
|
||||||
|
|
||||||
'@types/unist@2.0.11': {}
|
'@types/unist@2.0.11': {}
|
||||||
|
|
||||||
'@types/unist@3.0.3': {}
|
'@types/unist@3.0.3': {}
|
||||||
|
@ -2062,6 +2100,8 @@ snapshots:
|
||||||
normalize-path: 3.0.0
|
normalize-path: 3.0.0
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
|
arg@5.0.2: {}
|
||||||
|
|
||||||
argparse@2.0.1: {}
|
argparse@2.0.1: {}
|
||||||
|
|
||||||
aria-query@5.3.2: {}
|
aria-query@5.3.2: {}
|
||||||
|
@ -3343,6 +3383,8 @@ snapshots:
|
||||||
'@rollup/rollup-win32-x64-msvc': 4.40.1
|
'@rollup/rollup-win32-x64-msvc': 4.40.1
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
|
sax@1.4.1: {}
|
||||||
|
|
||||||
semver@7.7.1: {}
|
semver@7.7.1: {}
|
||||||
|
|
||||||
sharp@0.33.5:
|
sharp@0.33.5:
|
||||||
|
@ -3390,6 +3432,13 @@ snapshots:
|
||||||
|
|
||||||
sisteransi@1.0.5: {}
|
sisteransi@1.0.5: {}
|
||||||
|
|
||||||
|
sitemap@8.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 17.0.45
|
||||||
|
'@types/sax': 1.2.7
|
||||||
|
arg: 5.0.2
|
||||||
|
sax: 1.4.1
|
||||||
|
|
||||||
smol-toml@1.3.4: {}
|
smol-toml@1.3.4: {}
|
||||||
|
|
||||||
source-map-js@1.2.1: {}
|
source-map-js@1.2.1: {}
|
||||||
|
@ -3398,6 +3447,8 @@ snapshots:
|
||||||
|
|
||||||
space-separated-tokens@2.0.2: {}
|
space-separated-tokens@2.0.2: {}
|
||||||
|
|
||||||
|
stream-replace-string@2.0.0: {}
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
emoji-regex: 8.0.0
|
emoji-regex: 8.0.0
|
||||||
|
|
27
src/components/BackToTop.astro
Normal file
27
src/components/BackToTop.astro
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
<button id="toTopBtn" title="Go to top">Top</button>
|
||||||
|
<script>
|
||||||
|
// Get the button
|
||||||
|
let toTopButton = document.getElementById("toTopBtn");
|
||||||
|
|
||||||
|
// When the user scrolls down from the top of the document, show the button
|
||||||
|
window.addEventListener("scroll", ()=> {
|
||||||
|
if (window.scrollY < document.documentElement.clientHeight) {
|
||||||
|
toTopButton.classList.remove('fade-in');
|
||||||
|
toTopButton.classList.add('fade-out');
|
||||||
|
toTopButton.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
toTopButton.classList.remove('fade-out');
|
||||||
|
toTopButton.classList.remove('fade-in');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// When the user clicks on the button, scroll to the top of the document
|
||||||
|
toTopButton.addEventListener("click", toTop);
|
||||||
|
function toTop() {
|
||||||
|
document.body.scrollTop = 0;
|
||||||
|
document.documentElement.scrollTop = 0;
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,22 +1,119 @@
|
||||||
---
|
---
|
||||||
---
|
---
|
||||||
<button class="theme-switcher" id="theme-switcher">
|
<div class="theme-dropdown" id="theme-dropdown">
|
||||||
Toggle Theme
|
<button class="theme-switcher" id="theme-switcher">Theme</button>
|
||||||
</button>
|
<div class="menu-body" id="menu-body">
|
||||||
|
<div class="dropdown-item" data-theme="auto">System</div>
|
||||||
|
<div class="dropdown-item" data-theme="dark">Dark</div>
|
||||||
|
<div class="dropdown-item" data-theme="light">Light</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.theme-dropdown {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-body {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
right: 45px;
|
||||||
|
bottom: 70px;
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
min-width: 140px;
|
||||||
|
z-index: 20;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item:hover {
|
||||||
|
background-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item.active {
|
||||||
|
color: var(--accent-color);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-dropdown:hover .menu-body {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const themeSwitcher = document.getElementById('theme-switcher');
|
// Constants for theme options
|
||||||
|
const THEME_AUTO = 'auto';
|
||||||
|
const THEME_DARK = 'dark';
|
||||||
|
const THEME_LIGHT = 'light';
|
||||||
|
|
||||||
|
// DOM elements
|
||||||
|
const themeDropdown = document.getElementById('theme-dropdown');
|
||||||
|
const menuBody = document.getElementById('menu-body');
|
||||||
|
const dropdownItems = document.querySelectorAll('.dropdown-item');
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
|
|
||||||
// Check for saved theme preference or default to dark
|
// Get system preference
|
||||||
const savedTheme = localStorage.getItem('theme') || 'dark';
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
root.setAttribute('data-theme', savedTheme);
|
const systemTheme = prefersDark ? THEME_DARK : THEME_LIGHT;
|
||||||
|
|
||||||
themeSwitcher?.addEventListener('click', () => {
|
// Get saved theme from localStorage or default to auto
|
||||||
const currentTheme = root.getAttribute('data-theme');
|
const savedThemeMode = localStorage.getItem('themeMode') || THEME_AUTO;
|
||||||
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
const savedTheme = localStorage.getItem('theme');
|
||||||
|
|
||||||
root.setAttribute('data-theme', newTheme);
|
// Function to update active state in dropdown menu
|
||||||
localStorage.setItem('theme', newTheme);
|
function updateActiveState(activeTheme) {
|
||||||
|
dropdownItems.forEach(item => {
|
||||||
|
if (item.getAttribute('data-theme') === activeTheme) {
|
||||||
|
item.classList.add('active');
|
||||||
|
} else {
|
||||||
|
item.classList.remove('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to apply theme
|
||||||
|
function applyTheme(themeMode) {
|
||||||
|
// Update active state in dropdown
|
||||||
|
updateActiveState(themeMode);
|
||||||
|
|
||||||
|
// Save theme mode preference
|
||||||
|
localStorage.setItem('themeMode', themeMode);
|
||||||
|
|
||||||
|
// Apply the appropriate theme
|
||||||
|
if (themeMode === THEME_AUTO) {
|
||||||
|
// Follow system
|
||||||
|
localStorage.removeItem('theme');
|
||||||
|
root.removeAttribute('data-theme');
|
||||||
|
} else {
|
||||||
|
// Set to specific theme
|
||||||
|
root.setAttribute('data-theme', themeMode);
|
||||||
|
localStorage.setItem('theme', themeMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize theme
|
||||||
|
applyTheme(savedThemeMode);
|
||||||
|
|
||||||
|
// Add click handlers to dropdown items
|
||||||
|
dropdownItems.forEach(item => {
|
||||||
|
item.addEventListener('click', () => {
|
||||||
|
const selectedTheme = item.getAttribute('data-theme');
|
||||||
|
applyTheme(selectedTheme);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for system preference changes
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
||||||
|
if (savedThemeMode === THEME_AUTO) {
|
||||||
|
// Only update if we're in auto mode
|
||||||
|
root.removeAttribute('data-theme');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
|
@ -2,6 +2,7 @@
|
||||||
import '../styles/global.css';
|
import '../styles/global.css';
|
||||||
import Search from '../components/Search.astro';
|
import Search from '../components/Search.astro';
|
||||||
import ThemeSwitcher from '../components/ThemeSwitcher.astro';
|
import ThemeSwitcher from '../components/ThemeSwitcher.astro';
|
||||||
|
import BackToTop from "../components/BackToTop.astro";
|
||||||
import { siteConfig } from "../config";
|
import { siteConfig } from "../config";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -26,7 +27,6 @@ const { title, path = formattedPath } = Astro.props;
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<ThemeSwitcher />
|
|
||||||
<main>
|
<main>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="terminal-path">
|
<div class="terminal-path">
|
||||||
|
@ -47,6 +47,10 @@ const { title, path = formattedPath } = Astro.props;
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
|
<div class="floating">
|
||||||
|
<BackToTop/>
|
||||||
|
<ThemeSwitcher/>
|
||||||
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
Powered by <a href="https://git.gb0.dev/gb/mercury"><img src="/mercury.svg" width="16px" alt="mercury logo" /> mercury</a>
|
Powered by <a href="https://git.gb0.dev/gb/mercury"><img src="/mercury.svg" width="16px" alt="mercury logo" /> mercury</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -25,16 +25,7 @@ posts.sort((a, b) => new Date(b.data.pubDate).getTime() - new Date(a.data.pubDat
|
||||||
{posts.length === 0 && (
|
{posts.length === 0 && (
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
<span style="color: var(--terminal-yellow);">2025-06-08</span>
|
<span style="color: var(--terminal-yellow);">No posts here yet</span>
|
||||||
<a href="/blog/terminal-setup">My Terminal Setup</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span style="color: var(--terminal-yellow);">2025-06-05</span>
|
|
||||||
<a href="/blog/minimalism">The Art of Minimalism</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span style="color: var(--terminal-yellow);">2025-06-01</span>
|
|
||||||
<a href="/blog/first-post">First Post</a>
|
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -11,7 +11,30 @@
|
||||||
--terminal-red: #ef4444;
|
--terminal-red: #ef4444;
|
||||||
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
}
|
}
|
||||||
|
/* Light theme */
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
--bg-color: #f3f4f6;
|
||||||
|
--text-color: #374151;
|
||||||
|
--accent-color: #3b82f6;
|
||||||
|
--border-color: #d1d5db;
|
||||||
|
--header-color: #1f2937;
|
||||||
|
--terminal-green: #059669;
|
||||||
|
--terminal-yellow: #d97706;
|
||||||
|
--terminal-red: #dc2626;
|
||||||
|
}
|
||||||
|
:root:not([data-theme="light"]) {
|
||||||
|
--bg-color: #1f2937;
|
||||||
|
--text-color: #a5b4cf;
|
||||||
|
--accent-color: #64a0ff;
|
||||||
|
--border-color: #3b4351;
|
||||||
|
--header-color: #83a2ce;
|
||||||
|
--terminal-green: #4ade80;
|
||||||
|
--terminal-yellow: #fbbf24;
|
||||||
|
--terminal-red: #ef4444;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Light theme override (for switch) */
|
||||||
:root[data-theme="light"] {
|
:root[data-theme="light"] {
|
||||||
--bg-color: #f3f4f6;
|
--bg-color: #f3f4f6;
|
||||||
--text-color: #374151;
|
--text-color: #374151;
|
||||||
|
@ -116,6 +139,55 @@ main {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer img {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer .floating {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 30px;
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#toTopBtn {
|
||||||
|
display: none;
|
||||||
|
background: var(--border-color);
|
||||||
|
border: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toTopBtn:hover {
|
||||||
|
background: var(--accent-color);
|
||||||
|
color: var(--bg-color);
|
||||||
|
}
|
||||||
|
/* Theme Switcher */
|
||||||
|
.theme-switcher {
|
||||||
|
background: var(--border-color);
|
||||||
|
border: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-switcher:hover {
|
||||||
|
background: var(--accent-color);
|
||||||
|
color: var(--bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Post styles */
|
/* Post styles */
|
||||||
.post-title {
|
.post-title {
|
||||||
color: var(--header-color);
|
color: var(--header-color);
|
||||||
|
@ -146,24 +218,18 @@ main {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Theme Switcher */
|
/* helper Class */
|
||||||
.theme-switcher {
|
.fade-in {
|
||||||
position: fixed;
|
opacity: 1;
|
||||||
top: 1rem;
|
transition-property: opacity;
|
||||||
right: 1rem;
|
transition-duration: .7s;
|
||||||
background: var(--border-color);
|
transition-timing-function: cubic-bezier(.4,0,1,1);
|
||||||
border: none;
|
|
||||||
color: var(--text-color);
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease, color 0.3s ease;
|
|
||||||
}
|
}
|
||||||
|
.fade-out {
|
||||||
.theme-switcher:hover {
|
opacity: 0;
|
||||||
background: var(--accent-color);
|
transition-property: opacity;
|
||||||
color: var(--bg-color);
|
transition-duration: .7s;
|
||||||
|
transition-timing-function: cubic-bezier(.4,0,1,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Media Queries */
|
/* Media Queries */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue