mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 11:41:17 +02:00
Merge pull request #24 from radishzzz/dev
✨ feat: optimize performance, enhance animations and improve accessibility
- perf: replace overlayscrollbars with native scrollbar to fix page loading lag
- feat: implement GSAP animations throughout the site with optimized curves and durations
- style: refine scrollbar styling and heading margins for better visual consistency
- fix: resolve accessibility issues with footer links and improve mobile responsiveness
- refactor: reorganize CSS files and optimize DOM selectors for better performance
- chore: update dependencies and implement astro-compress
- docs: update README and theme guides
This commit is contained in:
commit
3d3e422ef2
63 changed files with 1697 additions and 2027 deletions
81
.vscode/settings.json
vendored
81
.vscode/settings.json
vendored
|
@ -57,84 +57,5 @@
|
||||||
"typescript.tsdk": "node_modules/typescript/lib",
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.mdx": "markdown"
|
"*.mdx": "markdown"
|
||||||
},
|
}
|
||||||
"cSpell.words": [
|
|
||||||
"abbrlink",
|
|
||||||
"antfu",
|
|
||||||
"apiflash",
|
|
||||||
"apos",
|
|
||||||
"Artículos",
|
|
||||||
"astrodotbuild",
|
|
||||||
"astrojs",
|
|
||||||
"attributify",
|
|
||||||
"backref",
|
|
||||||
"belleza",
|
|
||||||
"Beze",
|
|
||||||
"Blockquotes",
|
|
||||||
"blurhash",
|
|
||||||
"bmoji",
|
|
||||||
"canvaskit",
|
|
||||||
"Cpath",
|
|
||||||
"Csvg",
|
|
||||||
"Disqus",
|
|
||||||
"Etiquetas",
|
|
||||||
"figcaption",
|
|
||||||
"Frontmatter",
|
|
||||||
"Fuwriu",
|
|
||||||
"Giscus",
|
|
||||||
"GSAP",
|
|
||||||
"gtag",
|
|
||||||
"hètí",
|
|
||||||
"Heti",
|
|
||||||
"katex",
|
|
||||||
"Lightbox",
|
|
||||||
"Macbook",
|
|
||||||
"mdast",
|
|
||||||
"Moeyua",
|
|
||||||
"msrc",
|
|
||||||
"msvalidate",
|
|
||||||
"noopener",
|
|
||||||
"noreferrer",
|
|
||||||
"Noto",
|
|
||||||
"oklch",
|
|
||||||
"opengraph",
|
|
||||||
"overlayscrollbars",
|
|
||||||
"pagefind",
|
|
||||||
"partytown",
|
|
||||||
"photoswipe",
|
|
||||||
"pswp",
|
|
||||||
"radishzz",
|
|
||||||
"rashomon",
|
|
||||||
"rehype",
|
|
||||||
"reimagines",
|
|
||||||
"Retipografía",
|
|
||||||
"Retypeset",
|
|
||||||
"Reviviendo",
|
|
||||||
"Roundhand",
|
|
||||||
"Segoe",
|
|
||||||
"Sentimentalisme",
|
|
||||||
"Servetus",
|
|
||||||
"shiki",
|
|
||||||
"Sobre",
|
|
||||||
"srcset",
|
|
||||||
"STIX",
|
|
||||||
"stylesheet",
|
|
||||||
"tipográfica",
|
|
||||||
"titlebar",
|
|
||||||
"Twikoo",
|
|
||||||
"Umami",
|
|
||||||
"unocss",
|
|
||||||
"unpic",
|
|
||||||
"vite",
|
|
||||||
"waline",
|
|
||||||
"walinejs",
|
|
||||||
"weibo",
|
|
||||||
"Возрождая",
|
|
||||||
"красоту",
|
|
||||||
"Переверстка",
|
|
||||||
"Посты",
|
|
||||||
"себе",
|
|
||||||
"Теги",
|
|
||||||
"типографики"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
26
README.md
26
README.md
|
@ -42,7 +42,6 @@ Retypeset is a static blog theme based on the [Astro](https://astro.build/) fram
|
||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://pagespeed.web.dev/analysis?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fen%2F">
|
<a href="https://pagespeed.web.dev/analysis?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fen%2F">
|
||||||
<img width="710" alt="Retypeset Lighthouse Score" src="images/retypeset-lighthouse-score.svg">
|
<img width="710" alt="Retypeset Lighthouse Score" src="images/retypeset-lighthouse-score.svg">
|
||||||
|
@ -52,15 +51,13 @@ Retypeset is a static blog theme based on the [Astro](https://astro.build/) fram
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
1. [Fork](https://github.com/radishzzz/astro-theme-retypeset/fork) this repository, or use this template to create a new repository.
|
1. [Fork](https://github.com/radishzzz/astro-theme-retypeset/fork) this repository, or use this template to create a new repository.
|
||||||
|
2. Run the following commands in your terminal:
|
||||||
2. Click the `Code` button, copy the `HTTPS` URL, and run the following commands in your terminal:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
git clone repository-url
|
git clone <repository-url>
|
||||||
|
|
||||||
# Navigate to the project directory
|
# Navigate to the project directory
|
||||||
cd repository-name
|
cd <repository-name>
|
||||||
|
|
||||||
# Install pnpm globally (if not already installed)
|
# Install pnpm globally (if not already installed)
|
||||||
npm install -g pnpm
|
npm install -g pnpm
|
||||||
|
@ -71,23 +68,14 @@ Retypeset is a static blog theme based on the [Astro](https://astro.build/) fram
|
||||||
# Start the development server
|
# Start the development server
|
||||||
pnpm dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
3. Refer to the [Theme Guide](https://retypeset.radishzz.cc/en/posts/theme-guide/) to customize your blog and create new articles.
|
||||||
|
4. Refer to the [Astro Deployment Guides](https://docs.astro.build/en/guides/deploy/) to deploy your blog to Netlify, Vercel, or other platforms.
|
||||||
|
|
||||||
3. Open [localhost:4321](http://localhost:4321/) in your browser to see a live preview of your website.
|
 [](https://app.netlify.com/start) [](https://vercel.com/new)
|
||||||
|
|
||||||
4. Refer to the [Theme Guide](https://retypeset.radishzz.cc/en/posts/theme-guide/) to customize your blog and create new articles.
|
|
||||||
|
|
||||||
5. Refer to the [Astro Deployment Guides](https://docs.astro.build/en/guides/deploy/) to deploy your blog to Netlify, Vercel, or other platforms.
|
|
||||||
|
|
||||||
 [](https://app.netlify.com/start)
|
|
||||||
[](https://vercel.com/new)
|
|
||||||
|
|
||||||
## Updates
|
## Updates
|
||||||
|
|
||||||
- Retypeset releases [new features](https://github.com/radishzzz/astro-theme-retypeset/issues/18) from time to time, which can be updated as follows.
|
Retypeset releases [new features](https://github.com/radishzzz/astro-theme-retypeset/issues/18) from time to time. You can refer to the [GitHub Docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) and run `Sync fork` in your repository to sync with the latest branch. Do not click `Discard Changes`, or you will lose your modifications.
|
||||||
|
|
||||||
- Refer to the [GitHub Docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) to run `Sync fork` in your repository to sync with the latest branch.
|
|
||||||
|
|
||||||
- Do not click `Discard Changes`, or you will lose your modifications.
|
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
|
|
28
README.zh.md
28
README.zh.md
|
@ -2,7 +2,7 @@
|
||||||
<img alt="Cover Image" src="images/retypeset-zh-mobile.webp"/>
|
<img alt="Cover Image" src="images/retypeset-zh-mobile.webp"/>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a title="en" href="README.md">
|
<a title="en" href="https://github.com/radishzzz/astro-theme-retypeset?tab=readme-ov-file#retypeset">
|
||||||
<img src="https://img.shields.io/badge/-English-545759?style=for-the-badge" alt="English">
|
<img src="https://img.shields.io/badge/-English-545759?style=for-the-badge" alt="English">
|
||||||
</a>
|
</a>
|
||||||
<picture>
|
<picture>
|
||||||
|
@ -42,7 +42,6 @@ Retypeset 是一款基于 [Astro](https://astro.build/) 框架的静态博客主
|
||||||
## 性能
|
## 性能
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://pagespeed.web.dev/analysis?url=https%3A%2F%2Fretypeset.radishzz.cc%2F">
|
<a href="https://pagespeed.web.dev/analysis?url=https%3A%2F%2Fretypeset.radishzz.cc%2F">
|
||||||
<img width="710" alt="Retypeset Lighthouse Score" src="images/retypeset-lighthouse-score.svg">
|
<img width="710" alt="Retypeset Lighthouse Score" src="images/retypeset-lighthouse-score.svg">
|
||||||
|
@ -52,15 +51,13 @@ Retypeset 是一款基于 [Astro](https://astro.build/) 框架的静态博客主
|
||||||
## 开始
|
## 开始
|
||||||
|
|
||||||
1. [Fork](https://github.com/radishzzz/astro-theme-retypeset/fork) 此仓库,或使用此模版创建新仓库。
|
1. [Fork](https://github.com/radishzzz/astro-theme-retypeset/fork) 此仓库,或使用此模版创建新仓库。
|
||||||
|
2. 在终端执行以下指令:
|
||||||
2. 点击 `Code` 按钮,复制 `HTTPS` 地址,在终端执行:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 克隆仓库
|
# 克隆仓库
|
||||||
git clone 仓库地址
|
git clone <仓库地址>
|
||||||
|
|
||||||
# 进入项目目录
|
# 进入项目目录
|
||||||
cd 仓库名称
|
cd <仓库名称>
|
||||||
|
|
||||||
# 全局安装 pnpm(如果未安装)
|
# 全局安装 pnpm(如果未安装)
|
||||||
npm install -g pnpm
|
npm install -g pnpm
|
||||||
|
@ -71,23 +68,14 @@ Retypeset 是一款基于 [Astro](https://astro.build/) 框架的静态博客主
|
||||||
# 启动开发服务器
|
# 启动开发服务器
|
||||||
pnpm dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
3. 参考 [主题上手指南](https://retypeset.radishzz.cc/posts/theme-guide/),自定义你的博客并创建新文章。
|
||||||
|
4. 参考 [Astro 部署指南](https://docs.astro.build/zh-cn/guides/deploy/),将博客部署至 Netlify、Vercel 等平台。
|
||||||
|
|
||||||
3. 在浏览器中打开 [localhost:4321](http://localhost:4321/),查看网站的实时预览。
|
 [](https://app.netlify.com/start) [](https://vercel.com/new)
|
||||||
|
|
||||||
4. 参考 [主题上手指南](https://retypeset.radishzz.cc/posts/theme-guide/),自定义你的博客并创建新文章。
|
|
||||||
|
|
||||||
5. 参考 [Astro 部署指南](https://docs.astro.build/zh-cn/guides/deploy/),将博客部署至 Netlify、Vercel 等平台。
|
|
||||||
|
|
||||||
 [](https://app.netlify.com/start)
|
|
||||||
[](https://vercel.com/new)
|
|
||||||
|
|
||||||
## 更新
|
## 更新
|
||||||
|
|
||||||
- Retypeset 会不定期发布 [新功能](https://github.com/radishzzz/astro-theme-retypeset/issues/18),更新方法如下。
|
Retypeset 会不定期发布 [新功能](https://github.com/radishzzz/astro-theme-retypeset/issues/18)。你可以参考 [GitHub 文档](https://docs.github.com/zh/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork),在仓库中执行 `Sync fork` 以同步最新分支。不要点击 `Discard Changes`,否则会丢失你的更改。
|
||||||
|
|
||||||
- 参考 [GitHub 文档](https://docs.github.com/zh/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork),在仓库中执行 `Sync fork` 同步最新分支。
|
|
||||||
|
|
||||||
- 不要点击 `Discard Changes`,否则会丢失你的更改。
|
|
||||||
|
|
||||||
## 鸣谢
|
## 鸣谢
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import type { Element } from 'hast'
|
||||||
import mdx from '@astrojs/mdx'
|
import mdx from '@astrojs/mdx'
|
||||||
import partytown from '@astrojs/partytown'
|
import partytown from '@astrojs/partytown'
|
||||||
import sitemap from '@astrojs/sitemap'
|
import sitemap from '@astrojs/sitemap'
|
||||||
|
import Compress from 'astro-compress'
|
||||||
import robotsTxt from 'astro-robots-txt'
|
import robotsTxt from 'astro-robots-txt'
|
||||||
import { defineConfig } from 'astro/config'
|
import { defineConfig } from 'astro/config'
|
||||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
||||||
|
@ -15,6 +16,7 @@ import UnoCSS from 'unocss/astro'
|
||||||
import { themeConfig } from './src/config'
|
import { themeConfig } from './src/config'
|
||||||
import { langMap } from './src/i18n/config'
|
import { langMap } from './src/i18n/config'
|
||||||
import { rehypeImgToFigure } from './src/plugins/rehype-img-to-figure.mjs'
|
import { rehypeImgToFigure } from './src/plugins/rehype-img-to-figure.mjs'
|
||||||
|
import { rehypeUnwrapImg } from './src/plugins/rehype-unwrap-img.mjs'
|
||||||
import { remarkAdmonitions } from './src/plugins/remark-admonitions.mjs'
|
import { remarkAdmonitions } from './src/plugins/remark-admonitions.mjs'
|
||||||
import { remarkGithubCard } from './src/plugins/remark-github-card.mjs'
|
import { remarkGithubCard } from './src/plugins/remark-github-card.mjs'
|
||||||
import { remarkReadingTime } from './src/plugins/remark-reading-time.mjs'
|
import { remarkReadingTime } from './src/plugins/remark-reading-time.mjs'
|
||||||
|
@ -57,6 +59,13 @@ export default defineConfig({
|
||||||
}),
|
}),
|
||||||
sitemap(),
|
sitemap(),
|
||||||
robotsTxt(),
|
robotsTxt(),
|
||||||
|
Compress({
|
||||||
|
CSS: false,
|
||||||
|
HTML: true, // Enable HTML compression only to remove comments
|
||||||
|
Image: false,
|
||||||
|
JavaScript: false,
|
||||||
|
SVG: false,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
markdown: {
|
markdown: {
|
||||||
remarkPlugins: [
|
remarkPlugins: [
|
||||||
|
@ -70,6 +79,7 @@ export default defineConfig({
|
||||||
rehypeKatex,
|
rehypeKatex,
|
||||||
rehypeSlug,
|
rehypeSlug,
|
||||||
rehypeImgToFigure,
|
rehypeImgToFigure,
|
||||||
|
rehypeUnwrapImg, // Must be after rehypeImgToFigure
|
||||||
[
|
[
|
||||||
rehypeAutolinkHeadings,
|
rehypeAutolinkHeadings,
|
||||||
{
|
{
|
||||||
|
|
25
package.json
25
package.json
|
@ -2,7 +2,7 @@
|
||||||
"name": "astro-theme-retypeset",
|
"name": "astro-theme-retypeset",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"packageManager": "pnpm@10.10.0",
|
"packageManager": "pnpm@10.11.0",
|
||||||
"repository": "https://github.com/radishzzz/astro-theme-retypeset",
|
"repository": "https://github.com/radishzzz/astro-theme-retypeset",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro check && astro dev",
|
"dev": "astro check && astro dev",
|
||||||
|
@ -10,23 +10,24 @@
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro",
|
"astro": "astro",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"lint:fix": "eslint . --fix"
|
"lint:fix": "eslint . --fix",
|
||||||
|
"comments": "curl -L https://unpkg.com/@waline/client@latest/dist/waline.css -o public/assets/waline/waline.css && curl -L https://unpkg.com/@waline/client@latest/dist/waline.js -o public/assets/waline/waline.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.2.6",
|
"@astrojs/mdx": "^4.2.6",
|
||||||
"@astrojs/partytown": "^2.1.4",
|
"@astrojs/partytown": "^2.1.4",
|
||||||
"@astrojs/sitemap": "^3.4.0",
|
"@astrojs/sitemap": "^3.4.0",
|
||||||
"@waline/client": "^3.5.7",
|
|
||||||
"astro": "^5.7.13",
|
"astro": "^5.7.13",
|
||||||
|
"astro-compress": "^2.3.8",
|
||||||
"astro-og-canvas": "^0.7.0",
|
"astro-og-canvas": "^0.7.0",
|
||||||
"astro-robots-txt": "^1.0.0",
|
"astro-robots-txt": "^1.0.0",
|
||||||
"canvaskit-wasm": "^0.40.0",
|
"canvaskit-wasm": "^0.40.0",
|
||||||
"feed": "^5.0.1",
|
"feed": "^5.0.1",
|
||||||
|
"gsap": "^3.13.0",
|
||||||
"katex": "^0.16.22",
|
"katex": "^0.16.22",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"mdast-util-to-string": "^4.0.0",
|
"mdast-util-to-string": "^4.0.0",
|
||||||
"node-html-parser": "^7.0.1",
|
"node-html-parser": "^7.0.1",
|
||||||
"overlayscrollbars": "^2.11.2",
|
|
||||||
"photoswipe": "^5.4.4",
|
"photoswipe": "^5.4.4",
|
||||||
"reading-time": "^1.5.0",
|
"reading-time": "^1.5.0",
|
||||||
"rehype-autolink-headings": "^7.1.0",
|
"rehype-autolink-headings": "^7.1.0",
|
||||||
|
@ -35,26 +36,26 @@
|
||||||
"rehype-slug": "^6.0.0",
|
"rehype-slug": "^6.0.0",
|
||||||
"remark-directive": "^4.0.0",
|
"remark-directive": "^4.0.0",
|
||||||
"remark-math": "^6.0.0",
|
"remark-math": "^6.0.0",
|
||||||
"sanitize-html": "^2.16.0",
|
"sanitize-html": "^2.17.0",
|
||||||
"sharp": "^0.34.1",
|
"sharp": "^0.34.1",
|
||||||
"unist-util-visit": "^5.0.0"
|
"unist-util-visit": "^5.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^4.13.0",
|
"@antfu/eslint-config": "^4.13.1",
|
||||||
"@astrojs/check": "^0.9.4",
|
"@astrojs/check": "^0.9.4",
|
||||||
"@types/hast": "^3.0.4",
|
"@types/hast": "^3.0.4",
|
||||||
"@types/markdown-it": "^14.1.2",
|
"@types/markdown-it": "^14.1.2",
|
||||||
"@types/node": "^22.15.17",
|
"@types/node": "^22.15.18",
|
||||||
"@types/sanitize-html": "^2.16.0",
|
"@types/sanitize-html": "^2.16.0",
|
||||||
"@unocss/eslint-plugin": "66.1.1",
|
"@unocss/eslint-plugin": "66.1.2",
|
||||||
"@unocss/preset-attributify": "66.1.1",
|
"@unocss/preset-attributify": "66.1.2",
|
||||||
"@unocss/reset": "66.1.1",
|
"@unocss/reset": "66.1.2",
|
||||||
"astro-eslint-parser": "^1.2.2",
|
"astro-eslint-parser": "^1.2.2",
|
||||||
"eslint": "^9.26.0",
|
"eslint": "^9.27.0",
|
||||||
"eslint-plugin-astro": "^1.3.1",
|
"eslint-plugin-astro": "^1.3.1",
|
||||||
"lint-staged": "^16.0.0",
|
"lint-staged": "^16.0.0",
|
||||||
"typescript": "~5.8.3",
|
"typescript": "~5.8.3",
|
||||||
"unocss": "66.1.1",
|
"unocss": "66.1.2",
|
||||||
"unocss-preset-theme": "^0.14.1"
|
"unocss-preset-theme": "^0.14.1"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
|
|
2169
pnpm-lock.yaml
generated
2169
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
1
public/assets/waline/waline.css
Normal file
1
public/assets/waline/waline.css
Normal file
File diff suppressed because one or more lines are too long
84
public/assets/waline/waline.js
Normal file
84
public/assets/waline/waline.js
Normal file
File diff suppressed because one or more lines are too long
91
public/fonts/EarlySummer-Split/EarlySummerSerif License.txt
Normal file
91
public/fonts/EarlySummer-Split/EarlySummerSerif License.txt
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -28,9 +28,9 @@ const nextUrl = useSupportedLangs
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class:list={[
|
class:list={[
|
||||||
'absolute flex gap-6 top-14.6 right-7.25vw min-[823px]:max-[1024px]:right-[calc(50vw-22rem)]',
|
'absolute right-7.25vw top-14.6 flex gap-6 min-[823px]:max-[1024px]:right-[calc(50vw-22rem)]',
|
||||||
'[@supports(-webkit-touch-callout:none)]:top-13.6', // fix position issue on ios
|
'[@supports(-webkit-touch-callout:none)]:top-13.6', // fix position issue on ios
|
||||||
'lg:(fixed w-14rem top-auto bottom-47 right-[max(5.625rem,calc(50vw-34.375rem))])',
|
'lg:(fixed bottom-47 right-[max(5rem,calc(50vw-35rem))] top-auto w-14rem)',
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<!-- Language Switcher -->
|
<!-- Language Switcher -->
|
||||||
|
@ -49,8 +49,9 @@ const nextUrl = useSupportedLangs
|
||||||
|
|
||||||
<!-- Theme Toggle -->
|
<!-- Theme Toggle -->
|
||||||
<button
|
<button
|
||||||
|
id="theme-toggle-button"
|
||||||
aria-label="Switch light/dark theme"
|
aria-label="Switch light/dark theme"
|
||||||
class="button-theme-toggle aspect-square w-4 c-secondary active:scale-90 hover:c-primary"
|
class="aspect-square w-4 c-secondary active:scale-90 hover:c-primary"
|
||||||
>
|
>
|
||||||
<ThemeToggleIcon
|
<ThemeToggleIcon
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
@ -69,7 +70,7 @@ function updateTheme() {
|
||||||
// Get current theme
|
// Get current theme
|
||||||
const isDark = document.documentElement.classList.contains('dark')
|
const isDark = document.documentElement.classList.contains('dark')
|
||||||
// Update meta theme color
|
// Update meta theme color
|
||||||
const metaThemeColor = document.querySelector('meta[name="theme-color"]')
|
const metaThemeColor = document.head.querySelector('meta[name="theme-color"]')
|
||||||
if (metaThemeColor) {
|
if (metaThemeColor) {
|
||||||
metaThemeColor.setAttribute('content', isDark ? darkMode : lightMode)
|
metaThemeColor.setAttribute('content', isDark ? darkMode : lightMode)
|
||||||
}
|
}
|
||||||
|
@ -82,10 +83,10 @@ function updateTheme() {
|
||||||
// Bind click event to the button
|
// Bind click event to the button
|
||||||
function setupThemeToggle() {
|
function setupThemeToggle() {
|
||||||
// Locate theme toggle button
|
// Locate theme toggle button
|
||||||
const themeToggleButtons = document.querySelectorAll('.button-theme-toggle')
|
const themeToggleButton = document.getElementById('theme-toggle-button')
|
||||||
// Add click listener to each button
|
// Add click listener to the button
|
||||||
themeToggleButtons.forEach((button) => {
|
if (themeToggleButton) {
|
||||||
button.addEventListener('click', () => {
|
themeToggleButton.addEventListener('click', () => {
|
||||||
// If browser doesn't support View Transitions API, update theme directly
|
// If browser doesn't support View Transitions API, update theme directly
|
||||||
if (!document.startViewTransition) {
|
if (!document.startViewTransition) {
|
||||||
updateTheme()
|
updateTheme()
|
||||||
|
@ -93,18 +94,18 @@ function setupThemeToggle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporarily add markers during animation to implement view transition and disable CSS transitions
|
// Temporarily add markers during animation to implement view transition and disable CSS transitions
|
||||||
document.documentElement.style.setProperty('view-transition-name', 'theme-transition')
|
document.documentElement.style.setProperty('view-transition-name', 'animation-theme-toggle')
|
||||||
document.documentElement.setAttribute('data-theme-transition', '')
|
document.documentElement.setAttribute('data-theme-changing', '')
|
||||||
|
|
||||||
// If browser supports View Transitions API, use it to update theme
|
// If browser supports View Transitions API, use it to update theme
|
||||||
const themeTransition = document.startViewTransition(updateTheme)
|
const themeTransition = document.startViewTransition(updateTheme)
|
||||||
// Remove markers after animation
|
// Remove markers after animation
|
||||||
themeTransition.finished.then(() => {
|
themeTransition.finished.then(() => {
|
||||||
document.documentElement.style.removeProperty('view-transition-name')
|
document.documentElement.style.removeProperty('view-transition-name')
|
||||||
document.documentElement.removeAttribute('data-theme-transition')
|
document.documentElement.removeAttribute('data-theme-changing')
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize click event (on first load or page transition)
|
// Initialize click event (on first load or page transition)
|
||||||
|
|
|
@ -2,13 +2,6 @@
|
||||||
import { defaultLocale, themeConfig } from '@/config'
|
import { defaultLocale, themeConfig } from '@/config'
|
||||||
import { walineLocaleMap } from '@/i18n/config'
|
import { walineLocaleMap } from '@/i18n/config'
|
||||||
|
|
||||||
const {
|
|
||||||
serverURL = '',
|
|
||||||
emoji = [],
|
|
||||||
search = false,
|
|
||||||
imageUploader = false,
|
|
||||||
} = themeConfig.comment?.waline ?? {}
|
|
||||||
|
|
||||||
// Get the language code of Waline
|
// Get the language code of Waline
|
||||||
function getWalineLang(currentPath: string, defaultLocale: string): string {
|
function getWalineLang(currentPath: string, defaultLocale: string): string {
|
||||||
// Extract language code from path
|
// Extract language code from path
|
||||||
|
@ -20,43 +13,46 @@ function getWalineLang(currentPath: string, defaultLocale: string): string {
|
||||||
return walineLocaleMap[lang as keyof typeof walineLocaleMap]
|
return walineLocaleMap[lang as keyof typeof walineLocaleMap]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Waline language and generate configuration json
|
|
||||||
const walineLang = getWalineLang(Astro.url.pathname, defaultLocale)
|
const walineLang = getWalineLang(Astro.url.pathname, defaultLocale)
|
||||||
const walineConfigJson = JSON.stringify({
|
const { waline: { serverURL = '', emoji = [], search = false, imageUploader = false } = {} } = themeConfig.comment ?? {}
|
||||||
serverURL,
|
|
||||||
lang: walineLang,
|
|
||||||
emoji,
|
|
||||||
search,
|
|
||||||
imageUploader,
|
|
||||||
})
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="waline"
|
id="waline"
|
||||||
class="mt-16"
|
class="mt-16"
|
||||||
data-config={walineConfigJson}
|
></div>
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Not use is:inline or define:vars >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
<!-- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||||
<script>
|
|
||||||
import { init } from '@waline/client'
|
<script
|
||||||
import '@waline/client/style'
|
is:inline
|
||||||
|
define:vars={{
|
||||||
|
walineLang,
|
||||||
|
serverURL,
|
||||||
|
emoji,
|
||||||
|
search,
|
||||||
|
imageUploader,
|
||||||
|
}}
|
||||||
|
type="module"
|
||||||
|
>
|
||||||
|
import { init } from '/assets/waline/waline.js'
|
||||||
|
|
||||||
function initWaline() {
|
function initWaline() {
|
||||||
const walineEl = document.getElementById('waline')
|
|
||||||
const walineConfig = JSON.parse(walineEl?.dataset.config || '{}')
|
|
||||||
|
|
||||||
init({
|
init({
|
||||||
el: '#waline',
|
el: '#waline',
|
||||||
|
serverURL,
|
||||||
|
// Share comments on posts in different languages
|
||||||
path: window.location.pathname.replace(/^\/([a-z]{2}(-[a-z]{2})?)\//, '/'),
|
path: window.location.pathname.replace(/^\/([a-z]{2}(-[a-z]{2})?)\//, '/'),
|
||||||
|
lang: walineLang,
|
||||||
|
emoji,
|
||||||
dark: 'html.dark',
|
dark: 'html.dark',
|
||||||
requiredMeta: ['nick', 'mail'],
|
requiredMeta: ['nick', 'mail'],
|
||||||
highlighter: false,
|
highlighter: false,
|
||||||
texRenderer: false,
|
texRenderer: false,
|
||||||
|
imageUploader,
|
||||||
|
search,
|
||||||
noCopyright: true,
|
noCopyright: true,
|
||||||
reaction: [],
|
reaction: [],
|
||||||
...walineConfig,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,13 +75,13 @@ document.addEventListener('astro:page-load', initWaline)
|
||||||
--at-apply: 'leading-3.6 mt-1.4';
|
--at-apply: 'leading-3.6 mt-1.4';
|
||||||
}
|
}
|
||||||
#waline .wl-panel {
|
#waline .wl-panel {
|
||||||
--at-apply: 'm-0 rounded border-secondary/25'
|
--at-apply: 'm-0 rounded-lg border-secondary/25'
|
||||||
}
|
}
|
||||||
#waline .wl-header {
|
#waline .wl-header {
|
||||||
--at-apply: 'p-0';
|
--at-apply: 'p-0';
|
||||||
}
|
}
|
||||||
#waline .wl-header-item {
|
#waline .wl-header-item {
|
||||||
border-bottom: 1px solid var(--waline-border-color);
|
--at-apply: 'border-b border-solid border-primary/25';
|
||||||
}
|
}
|
||||||
#waline .wl-header label {
|
#waline .wl-header label {
|
||||||
--at-apply: 'text-3';
|
--at-apply: 'text-3';
|
||||||
|
@ -104,14 +100,11 @@ document.addEventListener('astro:page-load', initWaline)
|
||||||
--at-apply: 'min-h-24';
|
--at-apply: 'min-h-24';
|
||||||
}
|
}
|
||||||
#waline .wl-editor::placeholder {
|
#waline .wl-editor::placeholder {
|
||||||
color: var(--waline-light-grey);
|
--at-apply: 'c-primary/25';
|
||||||
}
|
}
|
||||||
#waline .wl-footer {
|
#waline .wl-footer {
|
||||||
--at-apply: 'm-2';
|
--at-apply: 'm-2';
|
||||||
}
|
}
|
||||||
#waline .wl-info .wl-btn {
|
|
||||||
--at-apply: 'rounded';
|
|
||||||
}
|
|
||||||
#waline .wl-text-number,
|
#waline .wl-text-number,
|
||||||
#waline .wl-action[title="Markdown Guide"],
|
#waline .wl-action[title="Markdown Guide"],
|
||||||
#waline .wl-sort,
|
#waline .wl-sort,
|
||||||
|
@ -119,16 +112,10 @@ document.addEventListener('astro:page-load', initWaline)
|
||||||
--at-apply: 'hidden';
|
--at-apply: 'hidden';
|
||||||
}
|
}
|
||||||
#waline .wl-emoji-popup {
|
#waline .wl-emoji-popup {
|
||||||
--at-apply: 'start-0 rounded border-secondary/25';
|
--at-apply: 'start-0 border-secondary/25 max-w-532px';
|
||||||
}
|
}
|
||||||
#waline .wl-emoji-popup .wl-tab-wrapper::-webkit-scrollbar {
|
#waline .wl-emoji-popup .wl-tab-wrapper {
|
||||||
--at-apply: 'w-1.2';
|
scrollbar-width: thin;
|
||||||
}
|
|
||||||
#waline .wl-emoji-popup .wl-tab-wrapper::-webkit-scrollbar-thumb {
|
|
||||||
background: oklch(var(--un-preset-theme-colors-secondary) / 0.25);
|
|
||||||
}
|
|
||||||
#waline .wl-emoji-popup .wl-tab-wrapper::-webkit-scrollbar-track-piece {
|
|
||||||
--at-apply: 'bg-transparent';
|
|
||||||
}
|
}
|
||||||
#waline .wl-gif-popup {
|
#waline .wl-gif-popup {
|
||||||
--at-apply: 'border-secondary/25';
|
--at-apply: 'border-secondary/25';
|
||||||
|
@ -155,7 +142,7 @@ document.addEventListener('astro:page-load', initWaline)
|
||||||
--at-apply: 'leading-6 text-3.5';
|
--at-apply: 'leading-6 text-3.5';
|
||||||
}
|
}
|
||||||
#waline .wl-time {
|
#waline .wl-time {
|
||||||
color: oklch(var(--un-preset-theme-colors-primary) / 0.75);
|
--at-apply: 'c-primary/75';
|
||||||
}
|
}
|
||||||
#waline .wl-edit,
|
#waline .wl-edit,
|
||||||
#waline .wl-delete {
|
#waline .wl-delete {
|
||||||
|
@ -167,7 +154,6 @@ document.addEventListener('astro:page-load', initWaline)
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Official CSS Variables >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
<!-- Official CSS Variables >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||||
<!-- https://waline.js.org/reference/client/style.html -->
|
|
||||||
<style>
|
<style>
|
||||||
#waline {
|
#waline {
|
||||||
/* Regular Colors */
|
/* Regular Colors */
|
||||||
|
|
|
@ -10,39 +10,46 @@ const year = Number(startYear) === currentYear
|
||||||
? startYear
|
? startYear
|
||||||
: `${startYear}-${currentYear}`
|
: `${startYear}-${currentYear}`
|
||||||
|
|
||||||
// i18n RSS Path
|
// i18n RSS Feed Path
|
||||||
const currentLang = getLangFromPath(Astro.url.pathname)
|
const currentLang = getLangFromPath(Astro.url.pathname)
|
||||||
const links = socialLinks.map((link) => {
|
const links = socialLinks.map((link) => {
|
||||||
if (link.name === 'RSS') {
|
if (link.name === 'RSS') {
|
||||||
return {
|
return {
|
||||||
...link,
|
...link,
|
||||||
url: currentLang === defaultLocale ? link.url : `/${currentLang}${link.url}`,
|
url: currentLang === defaultLocale
|
||||||
|
? link.url
|
||||||
|
: `/${currentLang}${link.url}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (link.name === 'Email') {
|
||||||
|
return {
|
||||||
|
...link,
|
||||||
|
url: `mailto:${link.url}`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return link
|
return link
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const footerLinkClass = 'highlight-hover footer-highlight-position-fix py-0.8 transition-colors after:bottom-0.15em hover:c-primary'
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer
|
<footer
|
||||||
class="text-3 leading-4.75 font-navbar lg:text-3.5"
|
class="mb-4 text-3 leading-1.25em font-navbar lg:(mb-0 text-3.5)"
|
||||||
lg="uno-desktop-column bottom-20"
|
lg="uno-desktop-column bottom-20"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
{links.map((link, index) => (
|
{links.map((link, index) => (
|
||||||
<>
|
<>
|
||||||
<a class="highlight-hover transition-colors hover:c-primary after:bottom-0!" href={link.url} target="_blank" rel="noopener noreferrer">
|
<a class={footerLinkClass} href={link.url} target="_blank" rel="noopener noreferrer">{link.name}</a> {index < links.length - 1 && '/'}
|
||||||
{link.name}
|
|
||||||
</a>
|
|
||||||
{index < links.length - 1 && ' / '}
|
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Powered by <a class="highlight-hover transition-colors hover:c-primary after:bottom-0!" href="https://astro.build/" target="_blank" rel="noopener noreferrer">Astro</a> and <a class="highlight-hover transition-colors hover:c-primary after:bottom-0!" href="https://github.com/radishzzz/astro-theme-retypeset" target="_blank" rel="noopener noreferrer">Retypeset</a>
|
© {year} {author}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
© {year} {author}
|
Powered by <a class={footerLinkClass} href="https://astro.build/" target="_blank" rel="noopener noreferrer">Astro</a> and <a class={footerLinkClass} href="https://github.com/radishzzz/astro-theme-retypeset" target="_blank" rel="noopener noreferrer">Retypeset</a>
|
||||||
</p>
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -32,7 +32,7 @@ const SubtitleTag = isPost ? 'div' : 'h2'
|
||||||
<div
|
<div
|
||||||
class="box-content inline-block pr-1"
|
class="box-content inline-block pr-1"
|
||||||
transition:name={`site-title-${currentLang}`}
|
transition:name={`site-title-${currentLang}`}
|
||||||
data-disable-transition-on-theme
|
data-disable-theme-transition
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
id="site-title-link"
|
id="site-title-link"
|
||||||
|
|
|
@ -10,7 +10,9 @@ const isTagActive = isTag
|
||||||
const isAboutActive = isAbout
|
const isAboutActive = isAbout
|
||||||
|
|
||||||
function getNavItemClass(isActive: boolean) {
|
function getNavItemClass(isActive: boolean) {
|
||||||
return isActive ? 'font-bold c-primary highlight-static' : 'hover:(c-primary font-bold) transition-all highlight-hover'
|
return isActive
|
||||||
|
? 'highlight-static c-primary font-bold after:bottom-0.5em'
|
||||||
|
: 'highlight-hover transition-colors transition-font-weight after:bottom-0.5em hover:(c-primary font-bold)'
|
||||||
}
|
}
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
|
@ -36,8 +38,8 @@ const navItems = [
|
||||||
aria-label="Site Navigation"
|
aria-label="Site Navigation"
|
||||||
class:list={[
|
class:list={[
|
||||||
isPost ? 'hidden lg:block' : '',
|
isPost ? 'hidden lg:block' : '',
|
||||||
'mb-10.5 text-3.6 font-semibold leading-8.75 font-navbar',
|
'mb-10.5 text-3.6 font-semibold leading-2.45em font-navbar',
|
||||||
'lg:(uno-desktop-column text-4 leading-9.72 bottom-50) cjk:tracking-0.02em',
|
'lg:(uno-desktop-column text-4 bottom-50) cjk:tracking-0.02em',
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -45,7 +47,7 @@ const navItems = [
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href={getLocalizedPath(item.href)}
|
href={getLocalizedPath(item.href)}
|
||||||
class={item.className}
|
class={`${item.className} navbar-highlight-position-fix`}
|
||||||
>
|
>
|
||||||
{item.label}
|
{item.label}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -37,13 +37,13 @@ function getPostPath(post: Post) {
|
||||||
>
|
>
|
||||||
|
|
||||||
{/* post title */}
|
{/* post title */}
|
||||||
<h3 class="inline">
|
<h3 class="inline transition-colors hover:c-primary">
|
||||||
<a
|
<a
|
||||||
class="hover:c-primary cjk:tracking-0.02em"
|
class="cjk:tracking-0.02em"
|
||||||
lg={isHome ? 'font-medium text-4.5' : ''}
|
lg={isHome ? 'font-medium text-4.5' : ''}
|
||||||
href={getPostPath(post)}
|
href={getPostPath(post)}
|
||||||
transition:name={`post-${post.data.abbrlink || post.id}-${lang}`}
|
transition:name={`post-${post.data.abbrlink || post.id}-${lang}`}
|
||||||
data-disable-transition-on-theme
|
data-disable-theme-transition
|
||||||
>
|
>
|
||||||
{post.data.title}
|
{post.data.title}
|
||||||
</a>
|
</a>
|
||||||
|
@ -60,9 +60,9 @@ function getPostPath(post: Post) {
|
||||||
|
|
||||||
{/* mobile post time */}
|
{/* mobile post time */}
|
||||||
<div
|
<div
|
||||||
class="text-3.5 leading-6.875 font-time lg:hidden"
|
class="py-0.8 text-3.5 font-time lg:hidden"
|
||||||
transition:name={`time-${post.data.abbrlink || post.id}-${lang}`}
|
transition:name={`time-${post.data.abbrlink || post.id}-${lang}`}
|
||||||
data-disable-transition-on-theme
|
data-disable-theme-transition
|
||||||
>
|
>
|
||||||
<PostDate
|
<PostDate
|
||||||
date={post.data.published}
|
date={post.data.published}
|
||||||
|
@ -71,7 +71,7 @@ function getPostPath(post: Post) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* desktop post time */}
|
{/* desktop post time */}
|
||||||
<div class="hidden text-3.65 leading-6.875 font-time lg:(ml-2.5 inline)">
|
<div class="hidden text-3.65 font-time lg:(ml-2.5 inline)">
|
||||||
<PostDate
|
<PostDate
|
||||||
date={post.data.published}
|
date={post.data.published}
|
||||||
minutes={post.remarkPluginFrontmatter.minutes}
|
minutes={post.remarkPluginFrontmatter.minutes}
|
||||||
|
@ -82,7 +82,7 @@ function getPostPath(post: Post) {
|
||||||
{isHome && (
|
{isHome && (
|
||||||
<div
|
<div
|
||||||
class="heti hidden"
|
class="heti hidden"
|
||||||
lg="mt-2 block"
|
lg="mt-2.25 block"
|
||||||
>
|
>
|
||||||
<p>{generateDescription(post, 'list')}</p>
|
<p>{generateDescription(post, 'list')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import GoBackIcon from '@/assets/icons/go-back.svg';
|
||||||
<button
|
<button
|
||||||
id="back-button"
|
id="back-button"
|
||||||
class="hidden"
|
class="hidden"
|
||||||
lg="block absolute c-secondary/40 left--10 top-1/2 aspect-square w-4.5 translate-y--1/2 transition-colors ease-out c-secondary active:scale-90 hover:c-primary/80"
|
lg="block absolute c-secondary/40 left--10 top-1/2 aspect-square w-4.5 translate-y--1/2 transition-colors ease-out c-secondary active:scale-90! hover:c-secondary/80"
|
||||||
aria-label="Go back"
|
aria-label="Go back"
|
||||||
>
|
>
|
||||||
<GoBackIcon
|
<GoBackIcon
|
|
@ -8,7 +8,7 @@
|
||||||
<button
|
<button
|
||||||
id="back-to-top-button"
|
id="back-to-top-button"
|
||||||
aria-label="Back to top"
|
aria-label="Back to top"
|
||||||
class="fixed bottom-8 right-8 h-10 w-10 rounded-full bg-background transition-all duration-300 ease-out"
|
class="fixed bottom-8 right-8 h-10 w-10 rounded-full bg-background transition-all ease-out"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
function setupGithubCards() {
|
function setupGithubCards() {
|
||||||
const githubCards = document.querySelectorAll('.gc-container')
|
const githubCards = document.getElementsByClassName('gc-container')
|
||||||
if (githubCards.length === 0)
|
if (githubCards.length === 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
// Create an intersection observer to lazy load GitHub repo data when cards enter viewport
|
||||||
const observer = new IntersectionObserver((entries) => {
|
const observer = new IntersectionObserver((entries) => {
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
|
@ -13,7 +14,7 @@ function setupGithubCards() {
|
||||||
})
|
})
|
||||||
}, { rootMargin: '400px' })
|
}, { rootMargin: '400px' })
|
||||||
|
|
||||||
githubCards.forEach(card => observer.observe(card))
|
Array.from(githubCards).forEach(card => observer.observe(card))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadCardData(card: HTMLElement) {
|
async function loadCardData(card: HTMLElement) {
|
||||||
|
@ -21,11 +22,11 @@ async function loadCardData(card: HTMLElement) {
|
||||||
if (!repo)
|
if (!repo)
|
||||||
return
|
return
|
||||||
|
|
||||||
const avatarEl = card.querySelector('.gc-owner-avatar') as HTMLElement
|
const avatarEl = card.getElementsByClassName('gc-owner-avatar')[0] as HTMLElement
|
||||||
const descEl = card.querySelector('.gc-repo-description') as HTMLElement
|
const descEl = card.getElementsByClassName('gc-repo-description')[0] as HTMLElement
|
||||||
const starsEl = card.querySelector('.gc-stars-count') as HTMLElement
|
const starsEl = card.getElementsByClassName('gc-stars-count')[0] as HTMLElement
|
||||||
const forksEl = card.querySelector('.gc-forks-count') as HTMLElement
|
const forksEl = card.getElementsByClassName('gc-forks-count')[0] as HTMLElement
|
||||||
const licenseEl = card.querySelector('.gc-license-info') as HTMLElement
|
const licenseEl = card.getElementsByClassName('gc-license-info')[0] as HTMLElement
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`https://api.github.com/repos/${repo}`)
|
const response = await fetch(`https://api.github.com/repos/${repo}`)
|
||||||
|
|
99
src/components/Widgets/GsapAnimation.astro
Normal file
99
src/components/Widgets/GsapAnimation.astro
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<script>
|
||||||
|
import { gsap } from 'gsap'
|
||||||
|
|
||||||
|
function setupPostPageAnimation() {
|
||||||
|
const allElements = Array.from(document.querySelectorAll('#gsap-post-page-content > *, #gsap-post-page-tags, #waline'))
|
||||||
|
const tocList = document.getElementById('toc-list')
|
||||||
|
const tocListChildren = tocList ? Array.from(tocList.children) : []
|
||||||
|
const dateElement = document.getElementById('gsap-post-page-date')
|
||||||
|
const backButton = document.getElementById('back-button')
|
||||||
|
const tocIcon = document.getElementById('toc-icon')
|
||||||
|
const tocContainer = document.getElementById('toc-container')
|
||||||
|
|
||||||
|
const isLargeScreen = window.matchMedia('(min-width: 1024px)').matches
|
||||||
|
const isSmallScreen = window.matchMedia('(max-width: 1535px)').matches
|
||||||
|
|
||||||
|
// Post Content + Tags + Comments
|
||||||
|
// First 15 elements
|
||||||
|
gsap.from(allElements.slice(0, 15), {
|
||||||
|
opacity: 0,
|
||||||
|
y: '2rem',
|
||||||
|
duration: 0.3,
|
||||||
|
delay: 0.1,
|
||||||
|
ease: 'power2.out',
|
||||||
|
stagger: 0.05,
|
||||||
|
})
|
||||||
|
// Rest elements as the 16 element
|
||||||
|
if (allElements.length > 15) {
|
||||||
|
gsap.from(allElements.slice(15), {
|
||||||
|
opacity: 0,
|
||||||
|
y: '2rem',
|
||||||
|
duration: 0.3,
|
||||||
|
delay: 0.1 + 0.05 * 15,
|
||||||
|
ease: 'power2.out',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Desktop Animations
|
||||||
|
if (isLargeScreen) {
|
||||||
|
// Post Date
|
||||||
|
if (dateElement) {
|
||||||
|
gsap.from(dateElement, {
|
||||||
|
opacity: 0,
|
||||||
|
y: '1rem',
|
||||||
|
duration: 0.3,
|
||||||
|
delay: 0.1,
|
||||||
|
ease: 'power2.out',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOC Icon
|
||||||
|
if (tocIcon) {
|
||||||
|
gsap.from(tocIcon, {
|
||||||
|
opacity: 0,
|
||||||
|
y: '0.5rem',
|
||||||
|
duration: 0.3,
|
||||||
|
delay: 0.125,
|
||||||
|
ease: 'power2.out',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toc List
|
||||||
|
if (tocListChildren.length > 0) {
|
||||||
|
gsap.from(tocListChildren, {
|
||||||
|
opacity: 0,
|
||||||
|
y: '1rem',
|
||||||
|
duration: 0.3,
|
||||||
|
delay: 0.15,
|
||||||
|
ease: 'power2.out',
|
||||||
|
stagger: 0.025,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Back Button
|
||||||
|
if (backButton) {
|
||||||
|
gsap.from(backButton, {
|
||||||
|
opacity: 0,
|
||||||
|
x: '0.5rem',
|
||||||
|
duration: 0.3,
|
||||||
|
delay: 0.15,
|
||||||
|
ease: 'power2.out',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mobile Animation (for screens smaller than 1536px)
|
||||||
|
if (isSmallScreen && tocContainer) {
|
||||||
|
gsap.from(tocContainer, {
|
||||||
|
opacity: 0,
|
||||||
|
y: '2rem',
|
||||||
|
duration: 0.3,
|
||||||
|
delay: 0.1,
|
||||||
|
ease: 'power2.out',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setupPostPageAnimation()
|
||||||
|
document.addEventListener('astro:after-swap', setupPostPageAnimation)
|
||||||
|
</script>
|
|
@ -10,7 +10,8 @@ function setupPhotoSwipe() {
|
||||||
if (bodyElement.hasAttribute('data-photoswipe-initialized'))
|
if (bodyElement.hasAttribute('data-photoswipe-initialized'))
|
||||||
return
|
return
|
||||||
|
|
||||||
const images = document.querySelectorAll('article.heti img')
|
const article = document.querySelector('article.heti')
|
||||||
|
const images = article ? article.getElementsByTagName('img') : []
|
||||||
if (images.length === 0)
|
if (images.length === 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
<script>
|
|
||||||
import { OverlayScrollbars } from 'overlayscrollbars'
|
|
||||||
|
|
||||||
function setupScrollbar() {
|
|
||||||
// Add scrollbar to body
|
|
||||||
const bodyElement = document.body
|
|
||||||
if (!bodyElement.hasAttribute('data-scrollbar-initialized')) {
|
|
||||||
OverlayScrollbars({
|
|
||||||
target: bodyElement,
|
|
||||||
cancel: {
|
|
||||||
nativeScrollbarsOverlaid: true,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
scrollbars: {
|
|
||||||
theme: 'scrollbar-body',
|
|
||||||
autoHide: 'scroll',
|
|
||||||
autoHideDelay: 800,
|
|
||||||
},
|
|
||||||
overflow: {
|
|
||||||
x: 'hidden',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
bodyElement.setAttribute('data-scrollbar-initialized', 'true')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add scrollbar to TOC content
|
|
||||||
const tocElement = document.getElementById('toc-content')
|
|
||||||
if (tocElement && !tocElement.hasAttribute('data-scrollbar-initialized')) {
|
|
||||||
OverlayScrollbars({
|
|
||||||
target: tocElement,
|
|
||||||
}, {
|
|
||||||
scrollbars: {
|
|
||||||
theme: 'scrollbar-widget',
|
|
||||||
autoHide: 'never',
|
|
||||||
},
|
|
||||||
overflow: {
|
|
||||||
x: 'hidden',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
tocElement.setAttribute('data-scrollbar-initialized', 'true')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add scrollbar to code blocks
|
|
||||||
const preElements = document.querySelectorAll('pre')
|
|
||||||
preElements.forEach((pre) => {
|
|
||||||
if (!pre.hasAttribute('data-scrollbar-initialized')) {
|
|
||||||
OverlayScrollbars({
|
|
||||||
target: pre,
|
|
||||||
}, {
|
|
||||||
scrollbars: {
|
|
||||||
theme: 'scrollbar-widget',
|
|
||||||
autoHide: 'leave',
|
|
||||||
autoHideDelay: 500,
|
|
||||||
},
|
|
||||||
overflow: {
|
|
||||||
y: 'hidden',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
pre.setAttribute('data-scrollbar-initialized', 'true')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
setupScrollbar()
|
|
||||||
document.addEventListener('astro:after-swap', setupScrollbar)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style is:global>
|
|
||||||
@import 'overlayscrollbars/overlayscrollbars.css';
|
|
||||||
|
|
||||||
.scrollbar-body {
|
|
||||||
--os-size: 0.8rem;
|
|
||||||
--os-padding-perpendicular: 0.15rem;
|
|
||||||
--os-padding-axis: 0.2rem;
|
|
||||||
--os-handle-border-radius: 99rem;
|
|
||||||
--os-handle-perpendicular-size: 75%;
|
|
||||||
--os-handle-perpendicular-size-hover: 100%;
|
|
||||||
--os-handle-perpendicular-size-active: 100%;
|
|
||||||
--os-handle-interactive-area-offset: 0.2rem;
|
|
||||||
--os-handle-bg: oklch(var(--un-preset-theme-colors-secondary) / 0.25);
|
|
||||||
--os-handle-bg-hover: oklch(var(--un-preset-theme-colors-secondary) / 0.40);
|
|
||||||
--os-handle-bg-active: oklch(var(--un-preset-theme-colors-secondary) / 0.40);
|
|
||||||
--os-handle-max-size: 80%;
|
|
||||||
--os-handle-min-size: 12%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrollbar-widget {
|
|
||||||
--os-size: 0.4rem;
|
|
||||||
--os-padding-perpendicular: 0;
|
|
||||||
--os-padding-axis: 0.05rem;
|
|
||||||
--os-handle-border-radius: 99rem;
|
|
||||||
--os-handle-perpendicular-size: 75%;
|
|
||||||
--os-handle-perpendicular-size-hover: 100%;
|
|
||||||
--os-handle-perpendicular-size-active: 100%;
|
|
||||||
--os-handle-interactive-area-offset: 0.2rem;
|
|
||||||
--os-handle-bg: oklch(var(--un-preset-theme-colors-secondary) / 0.15);
|
|
||||||
--os-handle-bg-hover: oklch(var(--un-preset-theme-colors-secondary) / 0.30);
|
|
||||||
--os-handle-bg-active: oklch(var(--un-preset-theme-colors-secondary) / 0.30);
|
|
||||||
--os-handle-min-size: 12%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1536px) {
|
|
||||||
#toc-content .os-scrollbar {
|
|
||||||
--at-apply: 'hidden';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -19,38 +19,51 @@ const filteredHeadings = headings.filter(heading =>
|
||||||
---
|
---
|
||||||
|
|
||||||
{filteredHeadings.length > 0 && (
|
{filteredHeadings.length > 0 && (
|
||||||
<div class="mb-4 uno-round-border bg-secondary/5 2xl:(fixed left-0 top-43.5 max-w-[min(calc(50vw-38rem),13rem)] border-none bg-transparent)">
|
// TOC Container
|
||||||
|
<div
|
||||||
|
id="toc-container"
|
||||||
|
class="mb-4 uno-round-border bg-secondary/5 2xl:(fixed left-0 top-43.5 max-w-[min(calc(50vw-38rem),13rem)] border-none bg-secondary/0)"
|
||||||
|
>
|
||||||
|
{/* Hidden Checkbox */}
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="toc-toggle"
|
id="toc-toggle"
|
||||||
class="accordion-toggle"
|
class="accordion-toggle"
|
||||||
hidden
|
hidden
|
||||||
/>
|
/>
|
||||||
<div class="relative h-12 w-full bg-transparent">
|
{/* TOC Toggle */}
|
||||||
|
<div class="relative h-12 w-full">
|
||||||
<label
|
<label
|
||||||
for="toc-toggle"
|
for="toc-toggle"
|
||||||
class="absolute inset-0 flex cursor-pointer items-center 2xl:(static flex c-secondary/40 transition-colors ease-out hover:c-secondary/80)"
|
class="absolute inset-0 flex cursor-pointer items-center 2xl:(static flex c-secondary/40 transition-colors ease-out hover:c-secondary/80)"
|
||||||
>
|
>
|
||||||
|
{/* Title on Mobile */}
|
||||||
<span class="toc-title">
|
<span class="toc-title">
|
||||||
{currentUI.toc}
|
{currentUI.toc}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
{/* Icon on Desktop */}
|
||||||
<TocIcon
|
<TocIcon
|
||||||
|
id="toc-icon"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="ml-4 hidden aspect-square w-4.2 2xl:(mt-4 block origin-center active:scale-90)"
|
class="ml-1 hidden aspect-square w-4.2 2xl:(mt-4 block origin-center active:scale-90!)"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Expandable content wrapper */}
|
{/* Expandable Content Wrapper with Accordion Animation */}
|
||||||
<div class="accordion-wrapper">
|
<div class="accordion-wrapper">
|
||||||
<nav
|
<nav
|
||||||
id="toc-content"
|
id="toc-content"
|
||||||
class="accordion-content"
|
class="accordion-content"
|
||||||
aria-label="Table of Contents"
|
aria-label="Table of Contents"
|
||||||
>
|
>
|
||||||
<ul class="toc-list">
|
{/* TOC List */}
|
||||||
|
<ul
|
||||||
|
id="toc-list"
|
||||||
|
class="toc-list"
|
||||||
|
>
|
||||||
{filteredHeadings.map(heading => (
|
{filteredHeadings.map(heading => (
|
||||||
<li
|
<li
|
||||||
class:list={{
|
class:list={{
|
||||||
|
@ -80,21 +93,21 @@ const filteredHeadings = headings.filter(heading =>
|
||||||
<!-- Override heti default styles >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
<!-- Override heti default styles >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||||
<style>
|
<style>
|
||||||
.toc-title {
|
.toc-title {
|
||||||
--at-apply: 'font-semibold ml-4 select-none 2xl:hidden';
|
--at-apply: 'font-semibold ml-4 2xl:hidden';
|
||||||
}
|
}
|
||||||
.toc-list {
|
.toc-list {
|
||||||
--at-apply: 'list-none pl-0 space-y-2 mt-1 mb-4 2xl:space-y-1.2';
|
--at-apply: 'list-none pb-3.3 pl-0 space-y-2 mt-1 mb-4 2xl:space-y-1.2';
|
||||||
}
|
}
|
||||||
.toc-link-h2, .toc-link-h3, .toc-link-h4 {
|
.toc-link-h2, .toc-link-h3, .toc-link-h4 {
|
||||||
--at-apply: 'text-sm no-underline font-normal text-balance select-none 2xl:(text-3.2 c-secondary/60 transition-colors ease-in hover:(c-secondary font-medium))';
|
--at-apply: 'text-sm no-underline font-normal text-balance 2xl:(text-3.2 c-secondary/60 transition-colors transition-font-weight duration-300 ease-out hover:(c-secondary font-medium))';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initial collapsed state with zero height grid row */
|
/* Initial collapsed state with zero height grid row */
|
||||||
.accordion-wrapper {
|
.accordion-wrapper {
|
||||||
--at-apply: 'grid rows-[0fr] duration-300 ease-in-out';
|
--at-apply: 'grid rows-[0fr] transition-all duration-350 ease-in-out';
|
||||||
}
|
}
|
||||||
.accordion-content {
|
.accordion-content {
|
||||||
--at-apply: 'overflow-hidden max-h-66 2xl:(max-h-[calc(100vh-21.5rem)]) pl-4 pr-6';
|
--at-apply: 'max-h-66 overflow-hidden pl-4 pr-6 2xl:(max-h-[calc(100vh-26rem)] pl-1)';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When toggle is checked, expand the wrapper to show content */
|
/* When toggle is checked, expand the wrapper to show content */
|
||||||
|
@ -104,6 +117,10 @@ const filteredHeadings = headings.filter(heading =>
|
||||||
.accordion-toggle:checked ~ .accordion-wrapper .accordion-content {
|
.accordion-toggle:checked ~ .accordion-wrapper .accordion-content {
|
||||||
--at-apply: 'overflow-y-auto';
|
--at-apply: 'overflow-y-auto';
|
||||||
}
|
}
|
||||||
|
#toc-content {
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0.15) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 1536px) {
|
@media (min-width: 1536px) {
|
||||||
.accordion-wrapper {
|
.accordion-wrapper {
|
||||||
|
@ -121,6 +138,12 @@ const filteredHeadings = headings.filter(heading =>
|
||||||
.toc-link-active {
|
.toc-link-active {
|
||||||
--at-apply: 'c-secondary font-medium';
|
--at-apply: 'c-secondary font-medium';
|
||||||
}
|
}
|
||||||
|
#toc-content {
|
||||||
|
--at-apply: 'scrollbar-hidden';
|
||||||
|
}
|
||||||
|
#toc-content::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -131,7 +154,7 @@ function setupTOCHighlight() {
|
||||||
if (!tocContent)
|
if (!tocContent)
|
||||||
return
|
return
|
||||||
|
|
||||||
const tocLinks = tocContent.querySelectorAll('a')
|
const tocLinks = tocContent.getElementsByTagName('a')
|
||||||
if (tocLinks.length === 0)
|
if (tocLinks.length === 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -140,7 +163,7 @@ function setupTOCHighlight() {
|
||||||
|
|
||||||
// Build mapping from heading IDs to TOC links
|
// Build mapping from heading IDs to TOC links
|
||||||
const headingMap = new Map<string, HTMLAnchorElement>()
|
const headingMap = new Map<string, HTMLAnchorElement>()
|
||||||
tocLinks.forEach((link) => {
|
Array.from(tocLinks).forEach((link) => {
|
||||||
const id = link.getAttribute('href')?.substring(1)
|
const id = link.getAttribute('href')?.substring(1)
|
||||||
if (id)
|
if (id)
|
||||||
headingMap.set(id, link as HTMLAnchorElement)
|
headingMap.set(id, link as HTMLAnchorElement)
|
||||||
|
|
|
@ -60,6 +60,8 @@ export const themeConfig: ThemeConfig = {
|
||||||
dateFormat: 'YYYY-MM-DD', // YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
dateFormat: 'YYYY-MM-DD', // YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
|
||||||
// enable KaTeX for mathematical formulas rendering
|
// enable KaTeX for mathematical formulas rendering
|
||||||
katex: true, // true, false
|
katex: true, // true, false
|
||||||
|
// enable table of contents for all posts by default
|
||||||
|
toc: true, // true, false
|
||||||
},
|
},
|
||||||
// GLOBAL SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
// GLOBAL SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
||||||
|
|
||||||
|
@ -139,16 +141,16 @@ export const themeConfig: ThemeConfig = {
|
||||||
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'X',
|
name: 'Email',
|
||||||
url: 'https://x.com/radishzz_',
|
url: 'email@radishzz.cc',
|
||||||
},
|
}
|
||||||
// {
|
// {
|
||||||
// name: 'Email',
|
// name: 'X',
|
||||||
// url: 'https://example@gmail.com',
|
// url: 'https://x.com/radishzz_',
|
||||||
// }
|
// },
|
||||||
],
|
],
|
||||||
// year of website start
|
// year of website start
|
||||||
startYear: 2024,
|
startYear: 2025,
|
||||||
},
|
},
|
||||||
// FOOTER SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
// FOOTER SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
|
||||||
|
|
||||||
|
@ -157,8 +159,6 @@ export const themeConfig: ThemeConfig = {
|
||||||
// link prefetch
|
// link prefetch
|
||||||
// docs: https://docs.astro.build/en/guides/prefetch/#prefetch-strategies
|
// docs: https://docs.astro.build/en/guides/prefetch/#prefetch-strategies
|
||||||
linkPrefetch: 'viewport', // hover, tap, viewport, load
|
linkPrefetch: 'viewport', // hover, tap, viewport, load
|
||||||
// comment server url
|
|
||||||
commentURL: 'https://retypeset-comment.radishzz.cc',
|
|
||||||
// image hosting url
|
// image hosting url
|
||||||
imageHostURL: 'https://image.radishzz.cc',
|
imageHostURL: 'https://image.radishzz.cc',
|
||||||
// custom google analytics js
|
// custom google analytics js
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { allLocales } from '@/config'
|
|
||||||
import { glob } from 'astro/loaders'
|
import { glob } from 'astro/loaders'
|
||||||
import { defineCollection, z } from 'astro:content'
|
import { defineCollection, z } from 'astro:content'
|
||||||
|
import { allLocales, themeConfig } from '@/config'
|
||||||
|
|
||||||
const posts = defineCollection({
|
const posts = defineCollection({
|
||||||
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/posts' }),
|
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/posts' }),
|
||||||
|
@ -15,7 +15,7 @@ const posts = defineCollection({
|
||||||
// Advanced
|
// Advanced
|
||||||
draft: z.boolean().optional().default(false),
|
draft: z.boolean().optional().default(false),
|
||||||
pin: z.number().int().min(0).max(99).optional().default(0),
|
pin: z.number().int().min(0).max(99).optional().default(0),
|
||||||
toc: z.boolean().optional().default(true),
|
toc: z.boolean().optional().default(themeConfig.global.toc),
|
||||||
lang: z.enum(['', ...allLocales]).optional().default(''),
|
lang: z.enum(['', ...allLocales]).optional().default(''),
|
||||||
abbrlink: z.string().optional().default('').refine(
|
abbrlink: z.string().optional().default('').refine(
|
||||||
abbrlink => !abbrlink || /^[a-z0-9\-]*$/.test(abbrlink),
|
abbrlink => !abbrlink || /^[a-z0-9\-]*$/.test(abbrlink),
|
||||||
|
|
|
@ -17,7 +17,7 @@ $$
|
||||||
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
||||||
$$
|
$$
|
||||||
|
|
||||||
For each integer $n\ge2$, the quotient group $\mathbb{Z}/n\mathbb{Z}$ is a cyclic group generated by $1+n\mathbb{Z}$ and so $\color{red}{\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n}$.
|
For each integer $n\ge2$, the quotient group $\mathbb{Z}/n\mathbb{Z}$ is a cyclic group generated by $1+n\mathbb{Z}$ and so $\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n$.
|
||||||
|
|
||||||
The quotient group $\mathbb{R}/\mathbb{Z}$ is isomorphic to $([0,1),+_1)$, the group of real numbers in the interval $[0,1)$, under addition modulo 1.
|
The quotient group $\mathbb{R}/\mathbb{Z}$ is isomorphic to $([0,1),+_1)$, the group of real numbers in the interval $[0,1)$, under addition modulo 1.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ $$
|
||||||
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
||||||
$$
|
$$
|
||||||
|
|
||||||
Para cada entero $n\ge2$, el grupo cociente $\mathbb{Z}/n\mathbb{Z}$ es un grupo cíclico generado por $1+n\mathbb{Z}$ y por tanto $\color{red}{\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n}$.
|
Para cada entero $n\ge2$, el grupo cociente $\mathbb{Z}/n\mathbb{Z}$ es un grupo cíclico generado por $1+n\mathbb{Z}$ y por tanto $\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n$.
|
||||||
|
|
||||||
El grupo cociente $\mathbb{R}/\mathbb{Z}$ es isomorfo a $([0,1),+_1)$, el grupo de números reales en el intervalo $[0,1)$, bajo la adición módulo 1.
|
El grupo cociente $\mathbb{R}/\mathbb{Z}$ es isomorfo a $([0,1),+_1)$, el grupo de números reales en el intervalo $[0,1)$, bajo la adición módulo 1.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ $$
|
||||||
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
||||||
$$
|
$$
|
||||||
|
|
||||||
各整数 $n\ge2$ に対して、商群 $\mathbb{Z}/n\mathbb{Z}$ は $1+n\mathbb{Z}$ によって生成される巡回群であり、したがって $\color{red}{\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n}$ となります。
|
各整数 $n\ge2$ に対して、商群 $\mathbb{Z}/n\mathbb{Z}$ は $1+n\mathbb{Z}$ によって生成される巡回群であり、したがって $\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n$ となります。
|
||||||
|
|
||||||
商群 $\mathbb{R}/\mathbb{Z}$ は $([0,1),+_1)$ と同型です。これは区間 $[0,1)$ 上の実数のモジュロ1の加法群です。
|
商群 $\mathbb{R}/\mathbb{Z}$ は $([0,1),+_1)$ と同型です。これは区間 $[0,1)$ 上の実数のモジュロ1の加法群です。
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ $$
|
||||||
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
||||||
$$
|
$$
|
||||||
|
|
||||||
Для каждого целого числа $n\ge2$ фактор-группа $\mathbb{Z}/n\mathbb{Z}$ является циклической группой, порождённой элементом $1+n\mathbb{Z}$, и поэтому $\color{red}{\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n}$.
|
Для каждого целого числа $n\ge2$ фактор-группа $\mathbb{Z}/n\mathbb{Z}$ является циклической группой, порождённой элементом $1+n\mathbb{Z}$, и поэтому $\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n$.
|
||||||
|
|
||||||
Фактор-группа $\mathbb{R}/\mathbb{Z}$ изоморфна $([0,1),+_1)$, группе вещественных чисел в интервале $[0,1)$ с операцией сложения по модулю 1.
|
Фактор-группа $\mathbb{R}/\mathbb{Z}$ изоморфна $([0,1),+_1)$, группе вещественных чисел в интервале $[0,1)$ с операцией сложения по модулю 1.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ $$
|
||||||
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
||||||
$$
|
$$
|
||||||
|
|
||||||
對於每個整數 $n\ge2$,商群 $\mathbb{Z}/n\mathbb{Z}$ 是由 $1+n\mathbb{Z}$ 生成的循環群,因此 $\color{red}{\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n}$。
|
對於每個整數 $n\ge2$,商群 $\mathbb{Z}/n\mathbb{Z}$ 是由 $1+n\mathbb{Z}$ 生成的循環群,因此 $\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n$。
|
||||||
|
|
||||||
商群 $\mathbb{R}/\mathbb{Z}$ 同構於 $([0,1),+_1)$,即區間 $[0,1)$ 上以 1 為模的實數加法群。
|
商群 $\mathbb{R}/\mathbb{Z}$ 同構於 $([0,1),+_1)$,即區間 $[0,1)$ 上以 1 為模的實數加法群。
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ $$
|
||||||
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
t=\frac{1}{|G|}\sum_{g\in G}|\text{Fix}(g)|
|
||||||
$$
|
$$
|
||||||
|
|
||||||
对于每个整数 $n\ge2$,商群 $\mathbb{Z}/n\mathbb{Z}$ 是由 $1+n\mathbb{Z}$ 生成的循环群,因此 $\color{red}{\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n}$。
|
对于每个整数 $n\ge2$,商群 $\mathbb{Z}/n\mathbb{Z}$ 是由 $1+n\mathbb{Z}$ 生成的循环群,因此 $\mathbb{Z}/n\mathbb{Z}\cong\mathbb{Z}_n$。
|
||||||
|
|
||||||
商群 $\mathbb{R}/\mathbb{Z}$ 同构于 $([0,1),+_1)$,即区间 $[0,1)$ 上以 1 为模的实数加法群。
|
商群 $\mathbb{R}/\mathbb{Z}$ 同构于 $([0,1),+_1)$,即区间 $[0,1)$ 上以 1 为模的实数加法群。
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ To create automatic figure captions, use the standard Markdown image syntax `
|

|
||||||
|
|
||||||

|

|
||||||
```
|
```
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
|
|
|
@ -17,9 +17,9 @@ Para crear leyendas automáticas para figuras, utilice la sintaxis estándar de
|
||||||
### Sintaxis
|
### Sintaxis
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
```
|
```
|
||||||
|
|
||||||
### Resultado
|
### Resultado
|
||||||
|
|
|
@ -17,9 +17,9 @@ abbrlink: markdown-extended-features
|
||||||
### 構文
|
### 構文
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
```
|
```
|
||||||
|
|
||||||
### 効果
|
### 効果
|
||||||
|
|
|
@ -17,9 +17,9 @@ abbrlink: markdown-extended-features
|
||||||
### Синтаксис
|
### Синтаксис
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
```
|
```
|
||||||
|
|
||||||
### Результат
|
### Результат
|
||||||
|
|
|
@ -17,9 +17,9 @@ abbrlink: markdown-extended-features
|
||||||
### 語法
|
### 語法
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
```
|
```
|
||||||
|
|
||||||
### 效果
|
### 效果
|
||||||
|
|
|
@ -17,9 +17,9 @@ abbrlink: markdown-extended-features
|
||||||
### 语法
|
### 语法
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
```
|
```
|
||||||
|
|
||||||
### 效果
|
### 效果
|
||||||
|
|
|
@ -61,7 +61,9 @@ To add an image, add an exclamation mark `!`, followed by alt text in brackets `
|
||||||
### Syntax
|
### Syntax
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
```
|
```
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
|
@ -211,51 +213,3 @@ To create a code block, add three backticks ```` ``` ```` at the start and end o
|
||||||
- Milk
|
- Milk
|
||||||
- Cheese
|
- Cheese
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Output
|
|
||||||
|
|
||||||
- Fruit
|
|
||||||
- Apple
|
|
||||||
- Orange
|
|
||||||
- Banana
|
|
||||||
- Dairy
|
|
||||||
- Milk
|
|
||||||
- Cheese
|
|
||||||
|
|
||||||
## Other Elements
|
|
||||||
|
|
||||||
Including `<sup>` superscript, `<sub>` subscript, `<abbr>` abbreviation, `<del>` strikethrough, `<u>` wavy underline, `<kbd>` keyboard input, and `<mark>` highlight.
|
|
||||||
|
|
||||||
### Syntax
|
|
||||||
|
|
||||||
```html
|
|
||||||
H<sub>2</sub>O
|
|
||||||
|
|
||||||
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
|
|
||||||
|
|
||||||
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
|
|
||||||
|
|
||||||
Good writers always check for <u title="spelling">speling</u> mistakes.
|
|
||||||
|
|
||||||
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
|
|
||||||
|
|
||||||
There is <del>nothing</del> no code either good or bad, but running it makes it so.
|
|
||||||
|
|
||||||
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output
|
|
||||||
|
|
||||||
H<sub>2</sub>O
|
|
||||||
|
|
||||||
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
|
|
||||||
|
|
||||||
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
|
|
||||||
|
|
||||||
Good writers always check for <u title="spelling">speling</u> mistakes.
|
|
||||||
|
|
||||||
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
|
|
||||||
|
|
||||||
There is <del>nothing</del> no code either good or bad, but running it makes it so.
|
|
||||||
|
|
||||||
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
|
|
||||||
|
|
|
@ -61,7 +61,9 @@ Para agregar una imagen, añada un signo de exclamación `!`, seguido de texto a
|
||||||
### Sintaxis
|
### Sintaxis
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
```
|
```
|
||||||
|
|
||||||
### Resultado
|
### Resultado
|
||||||
|
|
|
@ -61,7 +61,9 @@ abbrlink: markdown-style-guide
|
||||||
### 構文
|
### 構文
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
```
|
```
|
||||||
|
|
||||||
### 効果
|
### 効果
|
||||||
|
|
|
@ -61,7 +61,9 @@ Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sap
|
||||||
### Синтаксис
|
### Синтаксис
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
```
|
```
|
||||||
|
|
||||||
### Результат
|
### Результат
|
||||||
|
|
|
@ -61,7 +61,9 @@ abbrlink: markdown-style-guide
|
||||||
### 語法
|
### 語法
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
```
|
```
|
||||||
|
|
||||||
### 效果
|
### 效果
|
||||||
|
|
|
@ -61,7 +61,9 @@ abbrlink: markdown-style-guide
|
||||||
### 语法
|
### 语法
|
||||||
|
|
||||||
```
|
```
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
```
|
```
|
||||||
|
|
||||||
### 效果
|
### 效果
|
||||||
|
|
|
@ -86,6 +86,8 @@ global: {
|
||||||
dateFormat: 'YYYY-MM-DD'
|
dateFormat: 'YYYY-MM-DD'
|
||||||
// enable KaTeX for mathematical formulas rendering
|
// enable KaTeX for mathematical formulas rendering
|
||||||
katex: true // true, false
|
katex: true // true, false
|
||||||
|
// enable table of contents for all posts by default
|
||||||
|
toc: true // true, false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -163,16 +165,16 @@ footer: {
|
||||||
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'X',
|
name: 'Email',
|
||||||
url: 'https://x.com/radishzz_',
|
url: 'email@radishzz.cc',
|
||||||
},
|
}
|
||||||
// {
|
// {
|
||||||
// name: 'Email',
|
// name: 'X',
|
||||||
// url: 'https://example@gmail.com',
|
// url: 'https://x.com/radishzz_',
|
||||||
// }
|
// },
|
||||||
]
|
]
|
||||||
// year of website start
|
// year of website start
|
||||||
startYear: 2024
|
startYear: 2025
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -182,8 +184,6 @@ footer: {
|
||||||
preload: {
|
preload: {
|
||||||
// link prefetch strategies
|
// link prefetch strategies
|
||||||
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
||||||
// comment server url
|
|
||||||
commentURL: 'https://retypeset-comment.radishzz.cc'
|
|
||||||
// image hosting url
|
// image hosting url
|
||||||
imageHostURL: 'https://image.radishzz.cc'
|
imageHostURL: 'https://image.radishzz.cc'
|
||||||
// custom google analytics js
|
// custom google analytics js
|
||||||
|
@ -236,7 +236,7 @@ const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
||||||
|
|
||||||
### Open Graph
|
### Open Graph
|
||||||
|
|
||||||
Open Graph social image styles.
|
[Open Graph social card](https://orcascan.com/tools/open-graph-validator?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fen%2Fposts%2Ftheme-guide%2F) styles.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/pages/og/[...image].ts
|
// src/pages/og/[...image].ts
|
||||||
|
@ -265,7 +265,7 @@ getImageOptions: (_path, page) => ({
|
||||||
|
|
||||||
### RSS Feed
|
### RSS Feed
|
||||||
|
|
||||||
RSS feed page styles.
|
[RSS feed page](https://retypeset.radishzz.cc/en/rss.xml) styles.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- public/rss/rss-style.xsl -->
|
<!-- public/rss/rss-style.xsl -->
|
||||||
|
@ -317,7 +317,7 @@ Pins the article to the top. The higher the number, the higher the priority of t
|
||||||
|
|
||||||
#### toc
|
#### toc
|
||||||
|
|
||||||
Generate table of contents. Shows h2 to h4 headings. Default is true.
|
Generate table of contents. Shows h2 to h4 headings. Uses the global `global.toc` configuration by default, but can be overridden individually in each article.
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ global: {
|
||||||
dateFormat: 'YYYY-MM-DD'
|
dateFormat: 'YYYY-MM-DD'
|
||||||
// habilitar KaTeX para renderizar fórmulas matemáticas
|
// habilitar KaTeX para renderizar fórmulas matemáticas
|
||||||
katex: true // true, false
|
katex: true // true, false
|
||||||
|
// habilitar tabla de contenidos para todos los artículos por defecto
|
||||||
|
toc: true // true, false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -163,16 +165,16 @@ footer: {
|
||||||
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'X',
|
name: 'Email',
|
||||||
url: 'https://x.com/radishzz_',
|
url: 'email@radishzz.cc',
|
||||||
},
|
}
|
||||||
// {
|
// {
|
||||||
// name: 'Email',
|
// name: 'X',
|
||||||
// url: 'https://example@gmail.com',
|
// url: 'https://x.com/radishzz_',
|
||||||
// }
|
// },
|
||||||
]
|
]
|
||||||
// año de inicio del sitio web
|
// año de inicio del sitio web
|
||||||
startYear: 2024
|
startYear: 2025
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -182,8 +184,6 @@ footer: {
|
||||||
preload: {
|
preload: {
|
||||||
// estrategias de precarga de enlaces
|
// estrategias de precarga de enlaces
|
||||||
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
||||||
// URL del servidor de comentarios
|
|
||||||
commentURL: 'https://retypeset-comment.radishzz.cc'
|
|
||||||
// URL de alojamiento de imágenes
|
// URL de alojamiento de imágenes
|
||||||
imageHostURL: 'https://image.radishzz.cc'
|
imageHostURL: 'https://image.radishzz.cc'
|
||||||
// js personalizado de google analytics
|
// js personalizado de google analytics
|
||||||
|
@ -236,7 +236,7 @@ const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
||||||
|
|
||||||
### Open Graph
|
### Open Graph
|
||||||
|
|
||||||
Estilos de imágenes sociales Open Graph.
|
Estilos de [tarjetas sociales Open Graph](https://orcascan.com/tools/open-graph-validator?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fes%2Fposts%2Ftheme-guide%2F).
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/pages/og/[...image].ts
|
// src/pages/og/[...image].ts
|
||||||
|
@ -265,7 +265,7 @@ getImageOptions: (_path, page) => ({
|
||||||
|
|
||||||
### Canal RSS
|
### Canal RSS
|
||||||
|
|
||||||
Estilos de página del feed RSS.
|
Estilos de [página del feed RSS](https://retypeset.radishzz.cc/es/rss.xml).
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- public/rss/rss-style.xsl -->
|
<!-- public/rss/rss-style.xsl -->
|
||||||
|
@ -317,7 +317,7 @@ Fija el artículo en la parte superior. Cuanto mayor sea el número, mayor será
|
||||||
|
|
||||||
#### toc
|
#### toc
|
||||||
|
|
||||||
Genera tabla de contenidos. Muestra encabezados h2 a h4. El valor predeterminado es true.
|
Genera tabla de contenidos. Muestra encabezados de h2 a h4. Utiliza la configuración global `global.toc` por defecto, pero puede ser modificada individualmente en cada artículo.
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ global: {
|
||||||
dateFormat: 'YYYY-MM-DD'
|
dateFormat: 'YYYY-MM-DD'
|
||||||
// 数式表示のためのKaTeXを有効化
|
// 数式表示のためのKaTeXを有効化
|
||||||
katex: true // true, false
|
katex: true // true, false
|
||||||
|
// デフォルトですべての記事に目次を表示
|
||||||
|
toc: true // true, false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -163,16 +165,16 @@ footer: {
|
||||||
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'X',
|
name: 'Email',
|
||||||
url: 'https://x.com/radishzz_',
|
url: 'email@radishzz.cc',
|
||||||
},
|
}
|
||||||
// {
|
// {
|
||||||
// name: 'Email',
|
// name: 'X',
|
||||||
// url: 'https://example@gmail.com',
|
// url: 'https://x.com/radishzz_',
|
||||||
// }
|
// },
|
||||||
]
|
]
|
||||||
// サイト開始年
|
// サイト開始年
|
||||||
startYear: 2024
|
startYear: 2025
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -182,8 +184,6 @@ footer: {
|
||||||
preload: {
|
preload: {
|
||||||
// リンクプリフェッチ戦略
|
// リンクプリフェッチ戦略
|
||||||
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
||||||
// コメントサーバー URL
|
|
||||||
commentURL: 'https://retypeset-comment.radishzz.cc'
|
|
||||||
// 画像ホスティング URL
|
// 画像ホスティング URL
|
||||||
imageHostURL: 'https://image.radishzz.cc'
|
imageHostURL: 'https://image.radishzz.cc'
|
||||||
// カスタム Google Analytics JS
|
// カスタム Google Analytics JS
|
||||||
|
@ -236,7 +236,7 @@ const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
||||||
|
|
||||||
### Open Graph
|
### Open Graph
|
||||||
|
|
||||||
Open Graphソーシャル画像スタイル。
|
[Open Graphソーシャルカード](https://orcascan.com/tools/open-graph-validator?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fja%2Fposts%2Ftheme-guide%2F)スタイル。
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/pages/og/[...image].ts
|
// src/pages/og/[...image].ts
|
||||||
|
@ -265,7 +265,7 @@ getImageOptions: (_path, page) => ({
|
||||||
|
|
||||||
### RSSフィード
|
### RSSフィード
|
||||||
|
|
||||||
RSSフィードページスタイル。
|
[RSSフィードページ](https://retypeset.radishzz.cc/ja/rss.xml)スタイル。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- public/rss/rss-style.xsl -->
|
<!-- public/rss/rss-style.xsl -->
|
||||||
|
@ -317,7 +317,7 @@ abbrlink: theme-guide
|
||||||
|
|
||||||
#### toc
|
#### toc
|
||||||
|
|
||||||
目次を自動生成するかどうか。h2からh4までの見出しを表示します。デフォルトは true。
|
目次を生成するかどうか。h2からh4までの見出しを表示します。デフォルトではグローバル設定 `global.toc` を使用しますが、記事ごとに個別に設定することも可能です。
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ global: {
|
||||||
dateFormat: 'YYYY-MM-DD'
|
dateFormat: 'YYYY-MM-DD'
|
||||||
// включить KaTeX для отображения математических формул
|
// включить KaTeX для отображения математических формул
|
||||||
katex: true // true, false
|
katex: true // true, false
|
||||||
|
// включить оглавление для всех статей по умолчанию
|
||||||
|
toc: true // true, false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -163,16 +165,16 @@ footer: {
|
||||||
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'X',
|
name: 'Email',
|
||||||
url: 'https://x.com/radishzz_',
|
url: 'email@radishzz.cc',
|
||||||
},
|
}
|
||||||
// {
|
// {
|
||||||
// name: 'Email',
|
// name: 'X',
|
||||||
// url: 'https://example@gmail.com',
|
// url: 'https://x.com/radishzz_',
|
||||||
// }
|
// },
|
||||||
]
|
]
|
||||||
// год начала работы веб-сайта
|
// год начала работы веб-сайта
|
||||||
startYear: 2024
|
startYear: 2025
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -182,8 +184,6 @@ footer: {
|
||||||
preload: {
|
preload: {
|
||||||
// стратегии предзагрузки ссылок
|
// стратегии предзагрузки ссылок
|
||||||
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
||||||
// URL сервера комментариев
|
|
||||||
commentURL: 'https://retypeset-comment.radishzz.cc'
|
|
||||||
// URL хостинга изображений
|
// URL хостинга изображений
|
||||||
imageHostURL: 'https://image.radishzz.cc'
|
imageHostURL: 'https://image.radishzz.cc'
|
||||||
// пользовательский скрипт Google Analytics
|
// пользовательский скрипт Google Analytics
|
||||||
|
@ -236,7 +236,7 @@ const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
||||||
|
|
||||||
### Open Graph
|
### Open Graph
|
||||||
|
|
||||||
Стили изображений Open Graph для социальных сетей.
|
Стили [карточек Open Graph для социальных сетей](https://orcascan.com/tools/open-graph-validator?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fru%2Fposts%2Ftheme-guide%2F).
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/pages/og/[...image].ts
|
// src/pages/og/[...image].ts
|
||||||
|
@ -265,7 +265,7 @@ getImageOptions: (_path, page) => ({
|
||||||
|
|
||||||
### RSS-лента
|
### RSS-лента
|
||||||
|
|
||||||
Стили страницы RSS-ленты.
|
Стили [страницы RSS-ленты](https://retypeset.radishzz.cc/ru/rss.xml).
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- public/rss/rss-style.xsl -->
|
<!-- public/rss/rss-style.xsl -->
|
||||||
|
@ -317,7 +317,7 @@ abbrlink: theme-guide
|
||||||
|
|
||||||
#### toc
|
#### toc
|
||||||
|
|
||||||
Генерировать оглавление. Показывает заголовки от h2 до h4. По умолчанию — true.
|
Генерировать оглавление. Показывает заголовки от h2 до h4. По умолчанию использует глобальный параметр `global.toc`, но может быть изменен индивидуально в каждой статье.
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ global: {
|
||||||
dateFormat: 'YYYY-MM-DD'
|
dateFormat: 'YYYY-MM-DD'
|
||||||
// 啟用 KaTeX 數學公式渲染
|
// 啟用 KaTeX 數學公式渲染
|
||||||
katex: true // true, false
|
katex: true // true, false
|
||||||
|
// 預設為所有文章開啟目錄
|
||||||
|
toc: true // true, false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -163,16 +165,16 @@ footer: {
|
||||||
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'X',
|
name: 'Email',
|
||||||
url: 'https://x.com/radishzz_',
|
url: 'email@radishzz.cc',
|
||||||
},
|
}
|
||||||
// {
|
// {
|
||||||
// name: 'Email',
|
// name: 'X',
|
||||||
// url: 'https://example@gmail.com',
|
// url: 'https://x.com/radishzz_',
|
||||||
// }
|
// },
|
||||||
]
|
]
|
||||||
// 建站年份
|
// 建站年份
|
||||||
startYear: 2024
|
startYear: 2025
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -182,8 +184,6 @@ footer: {
|
||||||
preload: {
|
preload: {
|
||||||
// 鏈接預加載策略
|
// 鏈接預加載策略
|
||||||
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
||||||
// 評論服務器地址
|
|
||||||
commentURL: 'https://retypeset-comment.radishzz.cc'
|
|
||||||
// 圖床地址
|
// 圖床地址
|
||||||
imageHostURL: 'https://image.radishzz.cc'
|
imageHostURL: 'https://image.radishzz.cc'
|
||||||
// 定制 google analytics js
|
// 定制 google analytics js
|
||||||
|
@ -236,7 +236,7 @@ const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
||||||
|
|
||||||
### Open Graph
|
### Open Graph
|
||||||
|
|
||||||
Open Graph 社交圖片樣式。
|
[Open Graph 社交卡片](https://orcascan.com/tools/open-graph-validator?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fzh-tw%2Fposts%2Ftheme-guide%2F) 樣式。
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/pages/og/[...image].ts
|
// src/pages/og/[...image].ts
|
||||||
|
@ -265,7 +265,7 @@ getImageOptions: (_path, page) => ({
|
||||||
|
|
||||||
### RSS 訂閱
|
### RSS 訂閱
|
||||||
|
|
||||||
RSS 訂閱頁配色。
|
[RSS 訂閱頁](https://retypeset.radishzz.cc/zh-tw/rss.xml) 配色。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- public/rss/rss-style.xsl -->
|
<!-- public/rss/rss-style.xsl -->
|
||||||
|
@ -317,7 +317,7 @@ abbrlink: theme-guide
|
||||||
|
|
||||||
#### toc
|
#### toc
|
||||||
|
|
||||||
是否生成目錄。顯示 h2 至 h4 標題。預設為 true。
|
是否生成目錄。顯示 h2 至 h4 標題。預設為全域配置 `global.toc` 的選項,可在文章中單獨設定以覆蓋全域配置。
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ global: {
|
||||||
dateFormat: 'YYYY-MM-DD'
|
dateFormat: 'YYYY-MM-DD'
|
||||||
// 启用 KaTeX 数学公式渲染
|
// 启用 KaTeX 数学公式渲染
|
||||||
katex: true // true, false
|
katex: true // true, false
|
||||||
|
// 默认为所有文章开启目录
|
||||||
|
toc: true // true, false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -163,16 +165,16 @@ footer: {
|
||||||
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
url: 'https://github.com/radishzzz/astro-theme-retypeset',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'X',
|
name: 'Email',
|
||||||
url: 'https://x.com/radishzz_',
|
url: 'email@radishzz.cc',
|
||||||
},
|
}
|
||||||
// {
|
// {
|
||||||
// name: 'Email',
|
// name: 'X',
|
||||||
// url: 'https://example@gmail.com',
|
// url: 'https://x.com/radishzz_',
|
||||||
// }
|
// },
|
||||||
]
|
]
|
||||||
// 建站年份
|
// 建站年份
|
||||||
startYear: 2024
|
startYear: 2025
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -182,8 +184,6 @@ footer: {
|
||||||
preload: {
|
preload: {
|
||||||
// 链接预加载策略
|
// 链接预加载策略
|
||||||
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
linkPrefetch: 'viewport' // hover, tap, viewport, load
|
||||||
// 评论服务器地址
|
|
||||||
commentURL: 'https://retypeset-comment.radishzz.cc'
|
|
||||||
// 图床地址
|
// 图床地址
|
||||||
imageHostURL: 'https://image.radishzz.cc'
|
imageHostURL: 'https://image.radishzz.cc'
|
||||||
// 定制 google analytics js
|
// 定制 google analytics js
|
||||||
|
@ -236,7 +236,7 @@ const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
||||||
|
|
||||||
### Open Graph
|
### Open Graph
|
||||||
|
|
||||||
Open Graph 社交图片样式。
|
[Open Graph 社交卡片](https://orcascan.com/tools/open-graph-validator?url=https%3A%2F%2Fretypeset.radishzz.cc%2Fposts%2Ftheme-guide%2F) 样式。
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// src/pages/og/[...image].ts
|
// src/pages/og/[...image].ts
|
||||||
|
@ -265,7 +265,7 @@ getImageOptions: (_path, page) => ({
|
||||||
|
|
||||||
### RSS 订阅
|
### RSS 订阅
|
||||||
|
|
||||||
RSS 订阅页配色。
|
[RSS 订阅页](https://retypeset.radishzz.cc/rss.xml) 配色。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- public/rss/rss-style.xsl -->
|
<!-- public/rss/rss-style.xsl -->
|
||||||
|
@ -317,7 +317,7 @@ abbrlink: theme-guide
|
||||||
|
|
||||||
#### toc
|
#### toc
|
||||||
|
|
||||||
是否生成目录。显示 h2 至 h4 标题。默认为 true。
|
是否生成目录。显示 h2 至 h4 标题。默认为全局配置 `global.toc` 的选项,可在文章中单独设置以覆盖全局配置。
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,11 @@ const langCode = currentLang === defaultLocale ? '' : `${currentLang}/`
|
||||||
|
|
||||||
const { title, subtitle, description, author, url, favicon, i18nTitle } = themeConfig.site
|
const { title, subtitle, description, author, url, favicon, i18nTitle } = themeConfig.site
|
||||||
const { mode, light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
const { mode, light: { background: lightMode }, dark: { background: darkMode } } = themeConfig.color
|
||||||
const { katex } = themeConfig.global
|
const { katex: katexEnabled } = themeConfig.global
|
||||||
|
const { enabled: commentEnabled = false, waline: { serverURL: walineServerURL = '' } = {} } = themeConfig.comment ?? {}
|
||||||
const { verification = {}, twitterID = '', googleAnalyticsID = '', umamiAnalyticsID = '', apiflashKey = '' } = themeConfig.seo ?? {}
|
const { verification = {}, twitterID = '', googleAnalyticsID = '', umamiAnalyticsID = '', apiflashKey = '' } = themeConfig.seo ?? {}
|
||||||
const { google = '', bing = '', yandex = '', baidu = '' } = verification
|
const { google = '', bing = '', yandex = '', baidu = '' } = verification
|
||||||
const { commentURL = '', customGoogleAnalyticsJS = '', customUmamiAnalyticsJS = '' } = themeConfig.preload
|
const { customGoogleAnalyticsJS = '', customUmamiAnalyticsJS = '' } = themeConfig.preload
|
||||||
|
|
||||||
const initMetaTheme = mode === 'dark' ? darkMode : lightMode
|
const initMetaTheme = mode === 'dark' ? darkMode : lightMode
|
||||||
const siteTitle = i18nTitle ? currentUI.title : title
|
const siteTitle = i18nTitle ? currentUI.title : title
|
||||||
|
@ -54,9 +55,9 @@ const pageImage = postSlug
|
||||||
<link rel="preload" href="/fonts/EarlySummer-Subset.woff2" as="font" type="font/woff2" crossorigin />
|
<link rel="preload" href="/fonts/EarlySummer-Subset.woff2" as="font" type="font/woff2" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Snell-Black.woff2" as="font" type="font/woff2" crossorigin />
|
<link rel="preload" href="/fonts/Snell-Black.woff2" as="font" type="font/woff2" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Snell-Bold.woff2" as="font" type="font/woff2" crossorigin />
|
<link rel="preload" href="/fonts/Snell-Bold.woff2" as="font" type="font/woff2" crossorigin />
|
||||||
{katex && <link rel="stylesheet" href={katexCSS} />}
|
<link rel="preload" href="/fonts/STIX-Italic.woff2" as="font" type="font/woff2" crossorigin />
|
||||||
{commentURL && <link rel="preconnect" href={commentURL} crossorigin />}
|
{commentEnabled && walineServerURL && <link rel="stylesheet" href="/assets/waline/waline.css" />}
|
||||||
{commentURL && <link rel="dns-prefetch" href={commentURL} />}
|
{katexEnabled && <link rel="stylesheet" href={katexCSS} />}
|
||||||
<link rel="alternate" href="/rss.xml" type="application/rss+xml" title="RSS Feed" />
|
<link rel="alternate" href="/rss.xml" type="application/rss+xml" title="RSS Feed" />
|
||||||
<link rel="alternate" href="/atom.xml" type="application/atom+xml" title="Atom Feed" />
|
<link rel="alternate" href="/atom.xml" type="application/atom+xml" title="Atom Feed" />
|
||||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
<link rel="sitemap" href="/sitemap-index.xml" />
|
||||||
|
@ -111,7 +112,7 @@ function isCurrentDark() {
|
||||||
function initTheme(doc = document) {
|
function initTheme(doc = document) {
|
||||||
const isDark = isCurrentDark()
|
const isDark = isCurrentDark()
|
||||||
doc.documentElement.classList.toggle('dark', isDark)
|
doc.documentElement.classList.toggle('dark', isDark)
|
||||||
const metaTheme = doc.querySelector('meta[name="theme-color"]')
|
const metaTheme = doc.head.querySelector('meta[name="theme-color"]')
|
||||||
if (metaTheme) {
|
if (metaTheme) {
|
||||||
metaTheme.setAttribute('content', isDark ? darkMode : lightMode)
|
metaTheme.setAttribute('content', isDark ? darkMode : lightMode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,16 @@ import Footer from '@/components/Footer.astro'
|
||||||
import Header from '@/components/Header.astro'
|
import Header from '@/components/Header.astro'
|
||||||
import Navbar from '@/components/Navbar.astro'
|
import Navbar from '@/components/Navbar.astro'
|
||||||
import GithubCard from '@/components/Widgets/GithubCard.astro'
|
import GithubCard from '@/components/Widgets/GithubCard.astro'
|
||||||
|
import GsapAnimation from '@/components/Widgets/GsapAnimation.astro'
|
||||||
import PhotoSwipe from '@/components/Widgets/PhotoSwipe.astro'
|
import PhotoSwipe from '@/components/Widgets/PhotoSwipe.astro'
|
||||||
import Scrollbar from '@/components/Widgets/Scrollbar.astro'
|
|
||||||
import themeConfig from '@/config'
|
import themeConfig from '@/config'
|
||||||
import Head from '@/layouts/Head.astro'
|
import Head from '@/layouts/Head.astro'
|
||||||
import { getPageInfo } from '@/utils/page'
|
import { getPageInfo } from '@/utils/page'
|
||||||
import '@/styles/global.css'
|
|
||||||
import '@/styles/font.css'
|
|
||||||
import '@/styles/heti.css'
|
|
||||||
import '@/styles/extend.css'
|
import '@/styles/extend.css'
|
||||||
|
import '@/styles/font.css'
|
||||||
|
import '@/styles/global.css'
|
||||||
|
import '@/styles/markdown.css'
|
||||||
|
import '@/styles/transition.css'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
postTitle?: string
|
postTitle?: string
|
||||||
|
@ -25,22 +26,20 @@ const { postTitle, postDescription, postSlug, supportedLangs = [] } = Astro.prop
|
||||||
const { isPost } = getPageInfo(Astro.url.pathname)
|
const { isPost } = getPageInfo(Astro.url.pathname)
|
||||||
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
|
||||||
const MarginBottom = isPost && themeConfig.comment?.enabled
|
const MarginBottom = isPost && themeConfig.comment?.enabled
|
||||||
? 'mb-10' // Post page with comment system
|
? 'mb-10' // Post page with comments
|
||||||
: 'mb-12' // Other pages without comment system
|
: 'mb-12' // Other pages without comments
|
||||||
---
|
---
|
||||||
|
|
||||||
<html
|
<html
|
||||||
lang={Astro.currentLocale}
|
lang={Astro.currentLocale}
|
||||||
class:list={[fontStyle, { 'scroll-smooth': isPost }]}
|
class:list={[fontStyle, { 'scroll-smooth': isPost }]}
|
||||||
data-overlayscrollbars-initialize
|
|
||||||
>
|
>
|
||||||
<Head {postTitle} {postDescription} {postSlug} />
|
<Head {postTitle} {postDescription} {postSlug} />
|
||||||
<body data-overlayscrollbars-initialize>
|
<body>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="mx-auto max-w-205.848 min-h-vh w-full min-h-dvh"
|
class="mx-auto max-w-205.848 min-h-vh w-full min-h-dvh"
|
||||||
p="x-[min(7.25vw,3.731rem)] y-9"
|
p="x-[min(7.25vw,3.731rem)] y-9"
|
||||||
lg="p-0 min-h-full max-w-[min(calc(75vw-16rem),44rem)] mx-[max(5.625rem,calc(50vw-34.375rem))] my-20"
|
lg="mx-[max(5rem,calc(50vw-35rem))] my-20 max-w-[min(calc(75vw-16rem),44rem)] min-h-full p-0"
|
||||||
>
|
>
|
||||||
<Header />
|
<Header />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
@ -49,8 +48,8 @@ const MarginBottom = isPost && themeConfig.comment?.enabled
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
<GsapAnimation />
|
||||||
<Button supportedLangs={supportedLangs} />
|
<Button supportedLangs={supportedLangs} />
|
||||||
<Scrollbar />
|
|
||||||
<GithubCard />
|
<GithubCard />
|
||||||
<PhotoSwipe />
|
<PhotoSwipe />
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -6,8 +6,15 @@ import Layout from '@/layouts/Layout.astro'
|
||||||
<!-- Decorative Line -->
|
<!-- Decorative Line -->
|
||||||
<div class="uno-decorative-line"></div>
|
<div class="uno-decorative-line"></div>
|
||||||
<!-- Page Not Found -->
|
<!-- Page Not Found -->
|
||||||
<h3 class="mt--1.3 text-8 text-primary font-bold leading-1.2em font-navbar lg:text-9">PAGE<br>NOT<br>FOUND</h3>
|
<h3 class="mt--1.3 flex flex-col text-8 text-primary font-bold leading-1.2em font-navbar lg:text-9">
|
||||||
<p class="mt-3.6 text-3.6 leading-1.4em font-navbar lg:(mt-4 text-4)">It looks like the page you're looking for<br>does not exist or has been moved.</p>
|
<span>PAGE</span>
|
||||||
|
<span>NOT</span>
|
||||||
|
<span>FOUND</span>
|
||||||
|
</h3>
|
||||||
|
<p class="mt-3.6 flex flex-col text-3.6 leading-1.4em font-navbar lg:(mt-4 text-4)">
|
||||||
|
<span>It looks like the page you're looking for</span>
|
||||||
|
<span>does not exist or has been moved.</span>
|
||||||
|
</p>
|
||||||
<!-- Unused Div -->
|
<!-- Unused Div -->
|
||||||
<div class=""></div>
|
<div class=""></div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { CollectionEntry } from 'astro:content'
|
||||||
import { getCollection, render } from 'astro:content'
|
import { getCollection, render } from 'astro:content'
|
||||||
import Comments from '@/components/Comments/index.astro'
|
import Comments from '@/components/Comments/index.astro'
|
||||||
import PostDate from '@/components/PostDate.astro'
|
import PostDate from '@/components/PostDate.astro'
|
||||||
import GoBack from '@/components/Widgets/GoBack.astro'
|
import BackButton from '@/components/Widgets/BackButton.astro'
|
||||||
import TOC from '@/components/Widgets/TOC.astro'
|
import TOC from '@/components/Widgets/TOC.astro'
|
||||||
import { allLocales, defaultLocale, moreLocales } from '@/config'
|
import { allLocales, defaultLocale, moreLocales } from '@/config'
|
||||||
import { getTagPath } from '@/i18n/path'
|
import { getTagPath } from '@/i18n/path'
|
||||||
|
@ -109,12 +109,12 @@ const { Content, headings, remarkPluginFrontmatter } = await render(post)
|
||||||
<article class="heti mb-12.6">
|
<article class="heti mb-12.6">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<!-- Go Back Button On Desktop -->
|
<!-- Go Back Button On Desktop -->
|
||||||
<GoBack />
|
<BackButton />
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<h1 class="post-title">
|
<h1 class="post-title">
|
||||||
<span
|
<span
|
||||||
transition:name={`post-${post.data.abbrlink || post.id}-${lang}`}
|
transition:name={`post-${post.data.abbrlink || post.id}-${lang}`}
|
||||||
data-disable-transition-on-theme
|
data-disable-theme-transition
|
||||||
>
|
>
|
||||||
{post.data.title}
|
{post.data.title}
|
||||||
</span>
|
</span>
|
||||||
|
@ -123,9 +123,10 @@ const { Content, headings, remarkPluginFrontmatter } = await render(post)
|
||||||
|
|
||||||
<!-- Date -->
|
<!-- Date -->
|
||||||
<div
|
<div
|
||||||
|
id="gsap-post-page-date"
|
||||||
class="mb-16.3 block c-primary font-time"
|
class="mb-16.3 block c-primary font-time"
|
||||||
transition:name={`time-${post.data.abbrlink || post.id}-${lang}`}
|
transition:name={`time-${post.data.abbrlink || post.id}-${lang}`}
|
||||||
data-disable-transition-on-theme
|
data-disable-theme-transition
|
||||||
>
|
>
|
||||||
<PostDate
|
<PostDate
|
||||||
date={post.data.published}
|
date={post.data.published}
|
||||||
|
@ -136,11 +137,14 @@ const { Content, headings, remarkPluginFrontmatter } = await render(post)
|
||||||
<!-- TOC -->
|
<!-- TOC -->
|
||||||
{post.data.toc && <TOC headings={headings} />}
|
{post.data.toc && <TOC headings={headings} />}
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
|
<div id="gsap-post-page-content">
|
||||||
<Content />
|
<Content />
|
||||||
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<!-- Tags -->
|
<!-- Tags -->
|
||||||
{post.data.tags && post.data.tags.length > 0 && (
|
{post.data.tags && post.data.tags.length > 0 && (
|
||||||
|
<div id="gsap-post-page-tags">
|
||||||
<div class="uno-decorative-line"></div>
|
<div class="uno-decorative-line"></div>
|
||||||
<div class="uno-tags-wrapper">
|
<div class="uno-tags-wrapper">
|
||||||
{post.data.tags.map((tag: string) => (
|
{post.data.tags.map((tag: string) => (
|
||||||
|
@ -152,6 +156,7 @@ const { Content, headings, remarkPluginFrontmatter } = await render(post)
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
<!-- Comments -->
|
<!-- Comments -->
|
||||||
<Comments />
|
<Comments />
|
||||||
|
|
|
@ -52,7 +52,7 @@ const supportedLangs = await getTagSupportedLangs(tag)
|
||||||
href={getTagPath(tagName, lang)}
|
href={getTagPath(tagName, lang)}
|
||||||
class={`uno-tags-style ${
|
class={`uno-tags-style ${
|
||||||
tag === tagName
|
tag === tagName
|
||||||
? 'border-secondary/75 text-primary'
|
? 'border-secondary/80 text-primary'
|
||||||
: ''
|
: ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|
23
src/plugins/rehype-unwrap-img.mjs
Normal file
23
src/plugins/rehype-unwrap-img.mjs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { visit } from 'unist-util-visit'
|
||||||
|
|
||||||
|
export function rehypeUnwrapImg() {
|
||||||
|
return (tree) => {
|
||||||
|
visit(tree, 'element', (node, index, parent) => {
|
||||||
|
if (
|
||||||
|
node.tagName === 'p'
|
||||||
|
&& node.children
|
||||||
|
&& parent
|
||||||
|
&& node.children.every(child =>
|
||||||
|
child.tagName === 'img'
|
||||||
|
|| (child.type === 'text' && child.value.trim() === ''),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
|
||||||
|
const imgNodes = node.children.filter(child => child.tagName === 'img')
|
||||||
|
if (imgNodes.length > 0) {
|
||||||
|
parent.children.splice(index, 1, ...imgNodes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +1,47 @@
|
||||||
/* KaTeX Overflow Fix */
|
/* GitHub Card */
|
||||||
.katex-display {
|
.gc-container {
|
||||||
--at-apply: 'overflow-x-auto overflow-y-hidden scrollbar-hidden';
|
--at-apply: 'block mb-4 px-5 py-4 overflow-x-auto uno-round-border bg-secondary/5';
|
||||||
}
|
--at-apply: 'transition-colors ease-out lg:(px-6 py-5) hover:(bg-secondary/10 c-primary)';
|
||||||
.katex-display::-webkit-scrollbar {
|
scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0.15) transparent;
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Heading Anchor Link */
|
/* Title Bar */
|
||||||
.heading-anchor-link {
|
.gc-title-bar {
|
||||||
--at-apply: 'inline-block translate-y-0.1em c-secondary/0';
|
--at-apply: 'flex items-center gap-2.5 lg:gap-3';
|
||||||
}
|
}
|
||||||
h1:hover .heading-anchor-link,
|
.gc-owner-avatar {
|
||||||
h2:hover .heading-anchor-link,
|
--at-apply: 'flex-shrink-0 w-5.5 aspect-square rounded-full bg-secondary/20';
|
||||||
h3:hover .heading-anchor-link,
|
|
||||||
h4:hover .heading-anchor-link {
|
|
||||||
--at-apply: 'c-secondary/40';
|
|
||||||
}
|
}
|
||||||
.heading-anchor-link svg {
|
.gc-repo-title {
|
||||||
--at-apply: 'ml-0.4em aspect-square w-0.9em transition-colors active:scale-90 hover:c-secondary/80';
|
--at-apply: 'flex items-center leading-normal lg:text-lg';
|
||||||
|
}
|
||||||
|
.gc-slash {
|
||||||
|
--at-apply: 'mx-1 op-40 lg:mx-1.2';
|
||||||
|
}
|
||||||
|
.gc-github-icon {
|
||||||
|
--at-apply: 'flex-shrink-0 ml-auto w-5.5 lg:w-6';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Video */
|
/* Repo Description */
|
||||||
iframe {
|
.gc-repo-description.gc-repo-description {
|
||||||
--at-apply: 'mb-4 w-full aspect-video';
|
--at-apply: 'mt-2.45 mb-3.5 text-sm text-start lg:(mt-2.8 mb-4 text-base)';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Info Bar */
|
||||||
|
.gc-info-bar {
|
||||||
|
--at-apply: 'flex items-center gap-1.75 text-xs lg:(gap-2 text-sm)';
|
||||||
|
}
|
||||||
|
.gc-info-icon {
|
||||||
|
--at-apply: 'flex-shrink-0';
|
||||||
|
}
|
||||||
|
.gc-stars-count {
|
||||||
|
--at-apply: 'mr-3 lg:mr-4';
|
||||||
|
}
|
||||||
|
.gc-forks-count {
|
||||||
|
--at-apply: 'mr-3.75 lg:mr-5';
|
||||||
|
}
|
||||||
|
.gc-license-info {
|
||||||
|
--at-apply: 'ml-0.5 mr-4';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Admonition >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
/* Admonition >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
||||||
|
@ -93,55 +112,12 @@ iframe {
|
||||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E");
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GitHub Card >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
|
||||||
.gc-container {
|
|
||||||
--at-apply: 'block mb-4 px-5 py-4 overflow-x-auto uno-round-border bg-secondary/5 scrollbar-hidden';
|
|
||||||
--at-apply: 'transition-colors lg:(px-6 py-5) hover:(bg-secondary/10 c-primary)';
|
|
||||||
}
|
|
||||||
.gc-container::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Title Bar */
|
|
||||||
.gc-title-bar {
|
|
||||||
--at-apply: 'flex items-center gap-2.5 lg:gap-3';
|
|
||||||
}
|
|
||||||
.gc-owner-avatar {
|
|
||||||
--at-apply: 'flex-shrink-0 w-5.5 aspect-square rounded-full bg-secondary/20';
|
|
||||||
}
|
|
||||||
.gc-repo-title {
|
|
||||||
--at-apply: 'flex items-center leading-normal lg:text-lg';
|
|
||||||
}
|
|
||||||
.gc-slash {
|
|
||||||
--at-apply: 'mx-1 op-40 lg:mx-1.2';
|
|
||||||
}
|
|
||||||
.gc-github-icon {
|
|
||||||
--at-apply: 'flex-shrink-0 ml-auto w-5.5 lg:w-6';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Repo Description */
|
|
||||||
.gc-repo-description.gc-repo-description {
|
|
||||||
--at-apply: 'mt-2.45 mb-3.5 text-sm text-start lg:(mt-2.8 mb-4 text-base)';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Info Bar */
|
|
||||||
.gc-info-bar {
|
|
||||||
--at-apply: 'flex items-center gap-1.75 text-xs lg:(gap-2 text-sm)';
|
|
||||||
}
|
|
||||||
.gc-info-icon {
|
|
||||||
--at-apply: 'flex-shrink-0';
|
|
||||||
}
|
|
||||||
.gc-stars-count {
|
|
||||||
--at-apply: 'mr-3 lg:mr-4';
|
|
||||||
}
|
|
||||||
.gc-forks-count {
|
|
||||||
--at-apply: 'mr-3.75 lg:mr-5';
|
|
||||||
}
|
|
||||||
.gc-license-info {
|
|
||||||
--at-apply: 'ml-0.5 mr-4';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
||||||
|
/* Video */
|
||||||
|
/* iframe {
|
||||||
|
--at-apply: 'mb-4 w-full aspect-video';
|
||||||
|
} */
|
||||||
|
|
||||||
/* :where(details) {
|
/* :where(details) {
|
||||||
--at-apply: 'my-4 px-4 py-3 border border-solid border-secondary/25 rounded cursor-pointer';
|
--at-apply: 'my-4 px-4 py-3 border border-solid border-secondary/25 rounded cursor-pointer';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,41 @@
|
||||||
|
/* Snell Roundhand Static Font */
|
||||||
|
@font-face {
|
||||||
|
font-family: "Snell-Bold";
|
||||||
|
src: url("/fonts/Snell-Bold.woff2") format("woff2");
|
||||||
|
font-display: swap;
|
||||||
|
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Snell-Black";
|
||||||
|
src: url("/fonts/Snell-Black.woff2") format("woff2");
|
||||||
|
font-display: swap;
|
||||||
|
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* STIXTwoText Variable Font */
|
||||||
|
@font-face {
|
||||||
|
font-family: "STIX";
|
||||||
|
src: url("/fonts/STIX.woff2") format("woff2-variations");
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400 700;
|
||||||
|
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "STIX-Italic";
|
||||||
|
src: url("/fonts/STIX-Italic.woff2") format("woff2-variations");
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400 700;
|
||||||
|
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Minimal Subset of EarlySummerSerif Variable Font */
|
||||||
|
@font-face {
|
||||||
|
font-family: "EarlySummer-Subset";
|
||||||
|
src: url("/fonts/EarlySummer-Subset.woff2") format("woff2-variations");
|
||||||
|
font-display: swap;
|
||||||
|
font-weight: 400 700;
|
||||||
|
}
|
||||||
|
|
||||||
/* EarlySummerSerif Variable Font */
|
/* EarlySummerSerif Variable Font */
|
||||||
@font-face {font-family:"EarlySummer";src:url("/fonts/EarlySummer-Split/264097d8d9da16491b480a1c46afe035.woff2") format("woff2-variations");font-display: swap;font-weight: 400 700;unicode-range:U+B7,U+9F2C,U+9F3B,U+9F3E,U+9F84,U+9F99,U+9F9F;}
|
@font-face {font-family:"EarlySummer";src:url("/fonts/EarlySummer-Split/264097d8d9da16491b480a1c46afe035.woff2") format("woff2-variations");font-display: swap;font-weight: 400 700;unicode-range:U+B7,U+9F2C,U+9F3B,U+9F3E,U+9F84,U+9F99,U+9F9F;}
|
||||||
@font-face {font-family:"EarlySummer";src:url("/fonts/EarlySummer-Split/c0df1afa44c13da520351e6aa9be3d9a.woff2") format("woff2-variations");font-display: swap;font-weight: 400 700;unicode-range:U+9711,U+9784,U+97A6,U+97C1,U+97C6,U+982C,U+983C,U+9854-9855,U+98B1,U+98B3,U+98BA,U+9935,U+993D,U+9951,U+99C4-99C6,U+9A12-9A13,U+9AEA,U+9AEE,U+9B06,U+9B0D,U+9B1A,U+9B28,U+9D12,U+9E78,U+9EB5,U+9EBA,U+9ED2,U+9ED9,U+9F07,U+9F15,U+9F62-9F63,U+FF01,U+FF08-FF09,U+FF0C,U+FF1A-FF1B,U+FF1F;}
|
@font-face {font-family:"EarlySummer";src:url("/fonts/EarlySummer-Split/c0df1afa44c13da520351e6aa9be3d9a.woff2") format("woff2-variations");font-display: swap;font-weight: 400 700;unicode-range:U+9711,U+9784,U+97A6,U+97C1,U+97C6,U+982C,U+983C,U+9854-9855,U+98B1,U+98B3,U+98BA,U+9935,U+993D,U+9951,U+99C4-99C6,U+9A12-9A13,U+9AEA,U+9AEE,U+9B06,U+9B0D,U+9B1A,U+9B28,U+9D12,U+9E78,U+9EB5,U+9EBA,U+9ED2,U+9ED9,U+9F07,U+9F15,U+9F62-9F63,U+FF01,U+FF08-FF09,U+FF0C,U+FF1A-FF1B,U+FF1F;}
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
}
|
}
|
||||||
html {
|
html {
|
||||||
--at-apply: 'bg-background c-secondary antialiased';
|
--at-apply: 'bg-background c-secondary antialiased';
|
||||||
}
|
scrollbar-width: thin;
|
||||||
::selection {
|
scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0.25) transparent;
|
||||||
--at-apply: 'bg-mark';
|
scrollbar-gutter: stable both-edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix Flash Issue On iOS */
|
/* Fix Flash Issue On iOS */
|
||||||
|
@ -15,6 +15,37 @@ body {
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
-webkit-backface-visibility: hidden;
|
-webkit-backface-visibility: hidden;
|
||||||
}
|
}
|
||||||
|
body::selection {
|
||||||
|
--at-apply: 'bg-highlight';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix KaTeX Overflow Issue */
|
||||||
|
.katex-display {
|
||||||
|
--at-apply: 'overflow-x-auto overflow-y-hidden scrollbar-hidden';
|
||||||
|
}
|
||||||
|
.katex-display::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Heading Anchor Link */
|
||||||
|
.heading-anchor-link {
|
||||||
|
--at-apply: 'inline-block translate-y-0.1em';
|
||||||
|
}
|
||||||
|
h1:hover .heading-anchor-link svg,
|
||||||
|
h2:hover .heading-anchor-link svg,
|
||||||
|
h3:hover .heading-anchor-link svg,
|
||||||
|
h4:hover .heading-anchor-link svg {
|
||||||
|
--at-apply: 'op-80';
|
||||||
|
}
|
||||||
|
.heading-anchor-link svg {
|
||||||
|
--at-apply: 'ml-0.4em aspect-square w-0.9em op-0 transition-opacity ease-out active:scale-90';
|
||||||
|
}
|
||||||
|
h1:hover .heading-anchor-link svg:hover,
|
||||||
|
h2:hover .heading-anchor-link svg:hover,
|
||||||
|
h3:hover .heading-anchor-link svg:hover,
|
||||||
|
h4:hover .heading-anchor-link svg:hover {
|
||||||
|
--at-apply: 'op-80';
|
||||||
|
}
|
||||||
|
|
||||||
/* Highlight Hover Animation */
|
/* Highlight Hover Animation */
|
||||||
.highlight-static,
|
.highlight-static,
|
||||||
|
@ -23,85 +54,22 @@ body {
|
||||||
}
|
}
|
||||||
.highlight-static::after,
|
.highlight-static::after,
|
||||||
.highlight-hover::after {
|
.highlight-hover::after {
|
||||||
--at-apply: 'content-[""] absolute bottom-0.5em left-0 z--1 h-0.5em w-full bg-mark';
|
--at-apply: 'content-[""] absolute left-0 z--1 h-0.5em w-full bg-highlight';
|
||||||
}
|
}
|
||||||
.highlight-static::after,
|
.highlight-static::after,
|
||||||
.highlight-hover:hover::after {
|
.highlight-hover:hover::after {
|
||||||
--at-apply: 'origin-bottom-left scale-x-100';
|
--at-apply: 'origin-bottom-left scale-x-100';
|
||||||
}
|
}
|
||||||
.highlight-hover::after {
|
.highlight-hover::after {
|
||||||
--at-apply: 'origin-bottom-right scale-x-0 transition-transform duration-300 ease-out';
|
--at-apply: 'origin-bottom-right scale-x-0 transition-transform ease-out lg:duration-225';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* View Transition with Theme Toggle >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
/* Fix Highlight Position Issue on iOS */
|
||||||
::view-transition-new(theme-transition) {
|
@supports (-webkit-touch-callout: none) {
|
||||||
animation: reveal 1s cubic-bezier(0.4, 0, 0.2, 1);
|
.navbar-highlight-position-fix {
|
||||||
clip-path: inset(0 0 0 0);
|
--at-apply: 'after:bottom-0.68em';
|
||||||
z-index: 99;
|
}
|
||||||
}
|
.footer-highlight-position-fix {
|
||||||
::view-transition-old(theme-transition) {
|
--at-apply: 'after:bottom-0.39em';
|
||||||
animation: none;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
@keyframes reveal {
|
|
||||||
from {
|
|
||||||
clip-path: inset(var(--from));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.dark {
|
|
||||||
--from: 0 0 100% 0;
|
|
||||||
}
|
|
||||||
html:not(.dark) {
|
|
||||||
--from: 100% 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable animations for other elements during theme switching */
|
|
||||||
html[data-theme-transition] [data-disable-transition-on-theme] {
|
|
||||||
view-transition-name: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fallback animation when view-transition-name is not supported */
|
|
||||||
@supports not (view-transition-name: none) {
|
|
||||||
html:not([data-restore-theme]) {
|
|
||||||
--at-apply: 'transition-colors duration-300 ease-out';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Snell Roundhand Static Font >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
|
||||||
@font-face {
|
|
||||||
font-family: "Snell-Bold";
|
|
||||||
src: url("/fonts/Snell-Bold.woff2") format("woff2");
|
|
||||||
font-display: swap;
|
|
||||||
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Snell-Black";
|
|
||||||
src: url("/fonts/Snell-Black.woff2") format("woff2");
|
|
||||||
font-display: swap;
|
|
||||||
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STIXTwoText Variable Font */
|
|
||||||
@font-face {
|
|
||||||
font-family: "STIX";
|
|
||||||
src: url("/fonts/STIX.woff2") format("woff2-variations");
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 400 700;
|
|
||||||
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "STIX-Italic";
|
|
||||||
src: url("/fonts/STIX-Italic.woff2") format("woff2-variations");
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 400 700;
|
|
||||||
unicode-range: U+0030-0039,U+0041-005A,U+0061-007A,U+00C1,U+00C9,U+00CD,U+00D3,U+00DA,U+00DC,U+00D1,U+00E1,U+00E9,U+00ED,U+00F3,U+00FA,U+00FC,U+00F1,U+0410-044F,U+0401,U+0451,U+0021-002F,U+003A-0040,U+00A9;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Minimal Subset of EarlySummerSerif Variable Font */
|
|
||||||
@font-face {
|
|
||||||
font-family: "EarlySummer-Subset";
|
|
||||||
src: url("/fonts/EarlySummer-Subset.woff2") format("woff2-variations");
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 400 700;
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,52 +7,41 @@
|
||||||
|
|
||||||
/* Global Styles */
|
/* Global Styles */
|
||||||
.heti {
|
.heti {
|
||||||
--at-apply: 'break-words leading-1.5em hyphens-auto cjk:tracking-0.02em';
|
--at-apply: 'break-words leading-normal hyphens-auto cjk:tracking-0.02em';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Customized Post Title */
|
/* Customized Post Title */
|
||||||
.heti .post-title {
|
.heti .post-title {
|
||||||
--at-apply: 'mb-2 text-8.6 c-primary font-bold leading-12 lg:text-9';
|
--at-apply: 'mb-2 text-8.6 font-bold lg:text-9';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Headings */
|
/* Headings */
|
||||||
.heti :where(h1),
|
.heti :where(h1, h2, h3, h4, h5, h6) {
|
||||||
.heti :where(h2),
|
--at-apply: 'mb-4 font-semibold';
|
||||||
.heti :where(h3),
|
}
|
||||||
.heti :where(h4),
|
.heti :where(h1, h2, h3) {
|
||||||
.heti :where(h5),
|
--at-apply: 'text-balance leading-1.33em cjk:text-pretty cjk:tracking-0.05em';
|
||||||
.heti :where(h6) {
|
|
||||||
--at-apply: 'mb-3 mt-6 font-semibold';
|
|
||||||
}
|
}
|
||||||
.heti :where(h1) {
|
.heti :where(h1) {
|
||||||
--at-apply: 'text-7 leading-12';
|
--at-apply: 'mt-9.6 text-7 text-primary';
|
||||||
}
|
}
|
||||||
.heti :where(h2) {
|
.heti :where(h2) {
|
||||||
--at-apply: 'text-6 leading-9';
|
--at-apply: 'mt-9.6 text-6 text-primary';
|
||||||
}
|
}
|
||||||
.heti :where(h3) {
|
.heti :where(h3) {
|
||||||
--at-apply: 'text-5 leading-9';
|
--at-apply: 'mt-6.5 text-5';
|
||||||
}
|
}
|
||||||
.heti :where(h4) {
|
.heti :where(h4) {
|
||||||
--at-apply: 'text-4.5 leading-6';
|
--at-apply: 'mt-6 text-4.5';
|
||||||
}
|
}
|
||||||
.heti :where(h5) {
|
.heti :where(h5) {
|
||||||
--at-apply: 'text-4 leading-6';
|
--at-apply: 'mt-6 text-4';
|
||||||
}
|
}
|
||||||
.heti :where(h6) {
|
.heti :where(h6) {
|
||||||
--at-apply: 'text-3.5 leading-6';
|
--at-apply: 'mt-6 font-normal';
|
||||||
}
|
}
|
||||||
.heti :where(h1),
|
.heti :where(h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6) {
|
||||||
.heti :where(h2),
|
--at-apply: 'mt-4';
|
||||||
.heti :where(h3) {
|
|
||||||
--at-apply: 'text-balance cjk:text-pretty cjk:tracking-0.05em';
|
|
||||||
}
|
|
||||||
.heti :where(h1 + h2),
|
|
||||||
.heti :where(h2 + h3),
|
|
||||||
.heti :where(h3 + h4),
|
|
||||||
.heti :where(h4 + h5),
|
|
||||||
.heti :where(h5 + h6) {
|
|
||||||
--at-apply: 'mt-3';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paragraphs */
|
/* Paragraphs */
|
||||||
|
@ -62,26 +51,33 @@
|
||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
.heti :where(a:not(.gc-container)) {
|
.heti :where(a:not(.gc-container)) {
|
||||||
--at-apply: 'break-all font-medium tracking-0 underline underline-0.075em decoration-secondary/40 underline-offset-0.2em';
|
--at-apply: 'break-all font-semibold tracking-0 underline underline-0.075em decoration-secondary/80 underline-offset-0.1em';
|
||||||
--at-apply: 'transition-colors hover:(c-primary decoration-secondary/80) lg:underline-0.1em';
|
--at-apply: 'transition-colors ease-out hover:(c-primary decoration-primary/80) lg:underline-0.1em';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Images */
|
/* Images */
|
||||||
.heti :where(img) {
|
.heti :where(img) {
|
||||||
--at-apply: 'mx-auto cursor-zoom-in';
|
--at-apply: 'mb-4 mx-auto cursor-zoom-in';
|
||||||
transform: translateZ(0);
|
|
||||||
-webkit-transform: translateZ(0);
|
|
||||||
}
|
}
|
||||||
.heti :where(figure) {
|
.heti :where(figure) {
|
||||||
--at-apply: 'mx-auto mb-4';
|
--at-apply: 'mx-auto mb-4';
|
||||||
}
|
}
|
||||||
|
.heti figure img {
|
||||||
|
--at-apply: 'mb-0';
|
||||||
|
}
|
||||||
.heti :where(figcaption) {
|
.heti :where(figcaption) {
|
||||||
--at-apply: 'mt-2 text-center text-sm text-secondary/80';
|
--at-apply: 'mt-3 text-center text-sm text-secondary/80';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code Blocks */
|
/* Code Blocks */
|
||||||
.heti :where(pre) {
|
.heti :where(pre) {
|
||||||
--at-apply: 'mb-4 overflow-auto uno-round-border px-4 py-3 bg-secondary/5!';
|
--at-apply: 'mb-4 overflow-auto uno-round-border px-4 py-3 bg-secondary/5!';
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0) transparent;
|
||||||
|
transition: scrollbar-color 0.3s ease-out;
|
||||||
|
}
|
||||||
|
.heti :where(pre:hover) {
|
||||||
|
scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0.15) transparent;
|
||||||
}
|
}
|
||||||
.heti pre :where(code) {
|
.heti pre :where(code) {
|
||||||
--at-apply: 'border-none bg-transparent p-0';
|
--at-apply: 'border-none bg-transparent p-0';
|
||||||
|
@ -124,10 +120,13 @@ html.dark .heti pre :where(span) {
|
||||||
|
|
||||||
/* Tables */
|
/* Tables */
|
||||||
.heti :where(table) {
|
.heti :where(table) {
|
||||||
--at-apply: 'mb-4 box-border block max-w-full table-fixed overflow-x-auto scrollbar-hidden';
|
--at-apply: 'mb-4 box-border block max-w-full table-fixed overflow-x-auto';
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0) transparent;
|
||||||
|
transition: scrollbar-color 0.3s ease-out;
|
||||||
}
|
}
|
||||||
.heti :where(table)::-webkit-scrollbar {
|
.heti :where(table:hover) {
|
||||||
--at-apply: 'hidden';
|
scrollbar-color: oklch(var(--un-preset-theme-colors-secondary) / 0.15) transparent;
|
||||||
}
|
}
|
||||||
.heti :where(th),
|
.heti :where(th),
|
||||||
.heti :where(td) {
|
.heti :where(td) {
|
||||||
|
@ -182,7 +181,7 @@ html.dark .heti pre :where(span) {
|
||||||
/* Superscript and Subscript >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
/* Superscript and Subscript >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
|
||||||
.heti :where(sub),
|
.heti :where(sub),
|
||||||
.heti :where(sup) {
|
.heti :where(sup) {
|
||||||
--at-apply: 'relative mx-0.1em align-baseline text-0.75em leading-1';
|
--at-apply: 'relative mx-0.1em align-baseline text-0.75em';
|
||||||
}
|
}
|
||||||
.heti :where(sub) {
|
.heti :where(sub) {
|
||||||
--at-apply: 'bottom--0.25em';
|
--at-apply: 'bottom--0.25em';
|
||||||
|
@ -212,7 +211,7 @@ html.dark .heti :where(u) {
|
||||||
|
|
||||||
/* Highlighted Text */
|
/* Highlighted Text */
|
||||||
.heti :where(mark) {
|
.heti :where(mark) {
|
||||||
--at-apply: 'bg-mark py-0.65 text-inherit';
|
--at-apply: 'bg-highlight py-0.65 text-inherit';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Footnotes */
|
/* Footnotes */
|
||||||
|
@ -222,7 +221,7 @@ html.dark .heti :where(u) {
|
||||||
}
|
}
|
||||||
.heti sup:target,
|
.heti sup:target,
|
||||||
.heti sup a:target {
|
.heti sup a:target {
|
||||||
--at-apply: 'bg-mark';
|
--at-apply: 'bg-highlight';
|
||||||
}
|
}
|
||||||
.heti .data-footnote-backref {
|
.heti .data-footnote-backref {
|
||||||
--at-apply: 'font-serif no-underline';
|
--at-apply: 'font-serif no-underline';
|
||||||
|
@ -253,4 +252,3 @@ html.dark .heti :where(u) {
|
||||||
.heti :where(q:is(:lang(zh), :lang(ja), :lang(ko))) {
|
.heti :where(q:is(:lang(zh), :lang(ja), :lang(ko))) {
|
||||||
quotes: "「" "」" "『" "』";
|
quotes: "「" "」" "『" "』";
|
||||||
}
|
}
|
||||||
|
|
34
src/styles/transition.css
Normal file
34
src/styles/transition.css
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/* View Transition */
|
||||||
|
::view-transition-new(animation-theme-toggle) {
|
||||||
|
animation: reveal 0.8s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
clip-path: inset(0 0 0 0);
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
::view-transition-old(animation-theme-toggle) {
|
||||||
|
animation: none;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
@keyframes reveal {
|
||||||
|
from {
|
||||||
|
clip-path: inset(var(--from));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark {
|
||||||
|
--from: 0 0 100% 0;
|
||||||
|
}
|
||||||
|
html:not(.dark) {
|
||||||
|
--from: 100% 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable animations for special elements during theme switching */
|
||||||
|
html[data-theme-changing] [data-disable-theme-transition] {
|
||||||
|
view-transition-name: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback animation when view-transition-name is not supported */
|
||||||
|
@supports not (view-transition-name: none) {
|
||||||
|
html {
|
||||||
|
--at-apply: 'transition-colors duration-300 ease-out';
|
||||||
|
}
|
||||||
|
}
|
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
|
@ -34,6 +34,7 @@ export interface ThemeConfig {
|
||||||
fontStyle: 'sans' | 'serif'
|
fontStyle: 'sans' | 'serif'
|
||||||
dateFormat: 'YYYY-MM-DD' | 'MM-DD-YYYY' | 'DD-MM-YYYY' | 'MONTH DAY YYYY' | 'DAY MONTH YYYY'
|
dateFormat: 'YYYY-MM-DD' | 'MM-DD-YYYY' | 'DD-MM-YYYY' | 'MONTH DAY YYYY' | 'DAY MONTH YYYY'
|
||||||
katex: boolean
|
katex: boolean
|
||||||
|
toc: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
comment: {
|
comment: {
|
||||||
|
@ -73,7 +74,6 @@ export interface ThemeConfig {
|
||||||
|
|
||||||
preload: {
|
preload: {
|
||||||
linkPrefetch: 'hover' | 'tap' | 'viewport' | 'load'
|
linkPrefetch: 'hover' | 'tap' | 'viewport' | 'load'
|
||||||
commentURL?: string
|
|
||||||
imageHostURL?: string
|
imageHostURL?: string
|
||||||
customGoogleAnalyticsJS?: string
|
customGoogleAnalyticsJS?: string
|
||||||
customUmamiAnalyticsJS?: string
|
customUmamiAnalyticsJS?: string
|
||||||
|
|
|
@ -54,7 +54,7 @@ const getOptimizedImageUrl = memoize(async (srcPath: string, baseUrl: string) =>
|
||||||
*/
|
*/
|
||||||
async function fixRelativeImagePaths(htmlContent: string, baseUrl: string): Promise<string> {
|
async function fixRelativeImagePaths(htmlContent: string, baseUrl: string): Promise<string> {
|
||||||
const htmlDoc = htmlParser(htmlContent)
|
const htmlDoc = htmlParser(htmlContent)
|
||||||
const images = htmlDoc.querySelectorAll('img')
|
const images = htmlDoc.getElementsByTagName('img')
|
||||||
const imagePromises = []
|
const imagePromises = []
|
||||||
|
|
||||||
for (const img of images) {
|
for (const img of images) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default defineConfig({
|
||||||
dark: {
|
dark: {
|
||||||
colors: {
|
colors: {
|
||||||
...dark,
|
...dark,
|
||||||
mark: 'oklch(0.93 0.195089 103.2532 / 0.2)', // rgba(255,235,0,0.5)
|
highlight: 'oklch(0.93 0.195089 103.2532 / 0.2)', // rgba(255,235,0,0.5)
|
||||||
note: 'oklch(70.7% 0.165 254.624 / 0.8)', // blue-400
|
note: 'oklch(70.7% 0.165 254.624 / 0.8)', // blue-400
|
||||||
tip: 'oklch(76.5% 0.177 163.223 / 0.8)', // emerald-400
|
tip: 'oklch(76.5% 0.177 163.223 / 0.8)', // emerald-400
|
||||||
important: 'oklch(71.4% 0.203 305.504 / 0.8)', // purple-400
|
important: 'oklch(71.4% 0.203 305.504 / 0.8)', // purple-400
|
||||||
|
@ -34,7 +34,7 @@ export default defineConfig({
|
||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
...light,
|
...light,
|
||||||
mark: 'oklch(0.93 0.195089 103.2532 / 0.5)', // rgba(255,235,0,0.5)
|
highlight: 'oklch(0.93 0.195089 103.2532 / 0.5)', // rgba(255,235,0,0.5)
|
||||||
note: 'oklch(48.8% 0.243 264.376 / 0.8)', // blue-700
|
note: 'oklch(48.8% 0.243 264.376 / 0.8)', // blue-700
|
||||||
tip: 'oklch(50.8% 0.118 165.612 / 0.8)', // emerald-700
|
tip: 'oklch(50.8% 0.118 165.612 / 0.8)', // emerald-700
|
||||||
important: 'oklch(49.6% 0.265 301.924 / 0.8)', // purple-700
|
important: 'oklch(49.6% 0.265 301.924 / 0.8)', // purple-700
|
||||||
|
@ -55,11 +55,11 @@ export default defineConfig({
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
shortcuts: {
|
shortcuts: {
|
||||||
'uno-desktop-column': 'fixed w-14rem right-[max(5.625rem,calc(50vw-34.375rem))]',
|
'uno-desktop-column': 'fixed right-[max(5rem,calc(50vw-35rem))] w-14rem',
|
||||||
'uno-tags-style': 'inline-block whitespace-nowrap border border-secondary/25 rounded-full px-3.2 py-0.7 c-secondary transition-colors hover:(border-secondary/75 text-primary)',
|
'uno-tags-style': 'inline-block whitespace-nowrap border border-secondary/25 rounded-full px-3.2 py-0.7 c-secondary transition-colors ease-out hover:(border-secondary/80 text-primary)',
|
||||||
'uno-decorative-line': 'h-0.25 w-10 bg-secondary/25 mb-4.5 lg:(w-11 mb-6)',
|
'uno-decorative-line': 'mb-4.5 h-0.25 w-10 bg-secondary/25 lg:(mb-6 w-11)',
|
||||||
'uno-tags-wrapper': 'flex flex-wrap gap-x-3 gap-y-3.2',
|
'uno-tags-wrapper': 'flex flex-wrap gap-x-3 gap-y-3.2',
|
||||||
'uno-round-border': 'rounded border border-solid border-secondary/5',
|
'uno-round-border': 'border border-secondary/5 rounded border-solid',
|
||||||
},
|
},
|
||||||
variants: [
|
variants: [
|
||||||
(matcher) => {
|
(matcher) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue