1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2026-06-23 08:18:40 +00:00

Compare commits

..

21 Commits

Author SHA1 Message Date
semantic-release-bot 152093879e chore(release): 7.6.0
## [7.6.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.5.0...v7.6.0) (2026-06-20)

### Features

* add edit this post link ([#2517](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2517)) ([6bd446c](https://github.com/cotes2020/jekyll-theme-chirpy/commit/6bd446ccdedbe37752cf24b1866e1e2dd9cb82c8))
* **theme:** persist user theme preferences ([#2756](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2756)) ([7496dd4](https://github.com/cotes2020/jekyll-theme-chirpy/commit/7496dd41fa053c4636a82027fe3fb3e38357e385))
* **ui:** optimize design of PWA update notification ([#2757](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2757)) ([5cc9dc6](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5cc9dc66acb1eb9213988d3ac6de5cf5adf1a6f6))

### Bug Fixes

* **giscus:** synchronize theme state during lazy loading ([#2742](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2742)) ([ceb2a41](https://github.com/cotes2020/jekyll-theme-chirpy/commit/ceb2a41463cbb6251fa257b640990a8d9717b0bb))
* prevent Firefox from opening blank page on `mailto` links ([#2642](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2642)) ([2685b91](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2685b91957d0207c2d31dab828430c78a2fcc3d0))
* **pwa:** avoid iOS status bar overlapping PWA content ([#2173](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2173)) ([3823212](https://github.com/cotes2020/jekyll-theme-chirpy/commit/38232120b729de653bfb42909a8dad047559438d))

### Improvements

* **ui:** prevent vertical flickering caused by subtitle loading ([2db0535](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2db053553bcf9606fc80c4a86959d0dd25d0446a))
2026-06-20 13:35:41 +00:00
Cotes Chung 0bf1c724d8 Merge branch 'master' into production 2026-06-20 21:30:15 +08:00
Cotes Chung 2ec2036d37 chore(deps): upgrade static assets 2026-06-20 21:29:37 +08:00
Cotes Chung cd1fb15481 ci(deps): bump the gh-actions group across 2 directories with 5 updates
Updates `actions/checkout` from 6 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

Updates `actions/github-script` from 8 to 9
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v8...v9)

Updates `actions/checkout` from 6 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

Updates `actions/checkout` from 6 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

Updates `actions/checkout` from 6 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

Updates `actions/configure-pages` from 5 to 6
- [Release notes](https://github.com/actions/configure-pages/releases)
- [Commits](https://github.com/actions/configure-pages/compare/v5...v6)

Updates `actions/upload-pages-artifact` from 4 to 5
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v4...v5)

Updates `actions/deploy-pages` from 4 to 5
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v4...v5)
2026-06-20 21:26:10 +08:00
Cotes Chung 9ea9dcf930 chore(deps-dev): update dependencies
@babel/core                                 ^7.29.0  →   ^7.29.7
 @babel/preset-env                           ^7.29.0  →   ^7.29.7
 @commitlint/cli                             ^20.4.4  →   ^21.0.2
 @commitlint/config-conventional             ^20.4.4  →   ^21.0.2
 @eslint/js                                  ^10.0.0  →   ^10.0.1
 @rollup/plugin-babel                         ^7.0.0  →    ^7.1.0
 concurrently                                 ^9.2.1  →   ^10.0.3
 conventional-changelog-conventionalcommits   ^9.3.0  →    ^9.3.1
 eslint                                      ^10.0.3  →   ^10.5.0
 globals                                     ^17.4.0  →   ^17.6.0
 rollup                                      ^4.59.0  →   ^4.62.2
 semantic-release                            ^25.0.3  →   ^25.0.5
 stylelint                                   ^17.4.0  →  ^17.13.0
2026-06-20 21:22:58 +08:00
Cotes Chung 2db053553b perf(ui): prevent vertical flickering caused by subtitle loading 2026-06-20 20:23:58 +08:00
Cotes Chung 18cf79bdac refactor(ui): reduce the size of the 'close' and 'copy' buttons
- The close button in the TOC popup
- The copy button in the code block
2026-06-20 20:23:33 +08:00
Cotes Chung 5cc9dc66ac feat(ui): optimize design of PWA update notification (#2757) 2026-06-20 05:42:07 +08:00
Cotes Chung 7496dd41fa feat(theme): persist user theme preferences (#2756)
- Migrate theme persistence from `sessionStorage` to `localStorage`
- Rename theme HTML attribute to `data-bs-theme` for Bootstrap compatibility
- Trim and compile CSS according to the chosen theme mode
2026-06-17 23:20:12 +08:00
Cotes Chung ceb2a41463 fix(giscus): synchronize theme state during lazy loading (#2742)
Previously, theme switch events were lost if triggered before the
Giscus iframe was fully loaded (e.g., when deferred by lazy loading
or before the client script executed). This resulted in Giscus
rendering with the outdated initial theme once it finally appeared
in the viewport.

This commit handles these edge cases by:
1. Updating the `data-theme` attribute on the Giscus script node
   if the iframe hasn't been created yet.
2. Modifying the `theme` query parameter in the iframe's `src` URL
   if it is currently in a pending/lazy-loading state.
2026-05-23 23:00:48 +08:00
Cotes Chung 38232120b7 fix(pwa): avoid iOS status bar overlapping PWA content (#2173)
Fixes #2173
2026-05-16 14:39:58 +08:00
Cotes Chung fb3aa94c1f chore: remove funding 2026-05-16 14:37:04 +08:00
Cotes Chung 832b24729d refactor(deps): update CDN URLs to follow production best practices (#2740) 2026-05-15 15:38:08 +08:00
Cotes Chung 97a537e692 chore(deps): bump mathjax from 3.2.2 to 4.x 2026-05-15 15:22:19 +08:00
Cotes Chung 1344e90246 docs: update readme 2026-05-15 15:17:06 +08:00
Cotes Chung 2cfb4bba88 chore: update github issue template 2026-05-15 15:01:34 +08:00
Alexander Fuks 6bd446ccde feat: add edit this post link (#2517) 2026-05-06 22:31:32 +08:00
lynkos 2685b91957 fix: prevent Firefox from opening blank page on mailto links (#2642) 2026-04-10 00:29:33 +08:00
Cotes Chung 6245dec754 docs: improve readme 2026-04-04 02:08:24 +08:00
Shen Lin f20ed1c4b1 chore: ignore hidden system files and editor backups (#2704) 2026-03-28 10:44:48 +08:00
semantic-release-bot 9adb7e352b Merge branch 'production' 2026-03-15 20:14:45 +00:00
78 changed files with 825 additions and 338 deletions
-1
View File
@@ -1 +0,0 @@
ko_fi: coteschung
+1 -1
View File
@@ -53,7 +53,7 @@ body:
value: | value: |
- Ruby: <!-- run `ruby -v` --> - Ruby: <!-- run `ruby -v` -->
- Jekyll: <!-- run `bundle exec jekyll -v` --> - Jekyll: <!-- run `bundle exec jekyll -v` -->
- Chirpy: <!-- run `bundle info jekyll-theme-chirpy` --> - Chirpy: <!-- run `bundle info --version jekyll-theme-chirpy` -->
validations: validations:
required: true required: true
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1 - uses: ruby/setup-ruby@v1
with: with:
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
with: with:
fetch-depth: 0 # for posts's lastmod fetch-depth: 0 # for posts's lastmod
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v6 uses: actions/checkout@v7
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
+1 -1
View File
@@ -11,5 +11,5 @@ jobs:
commitlint: commitlint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: wagoid/commitlint-github-action@v6 - uses: wagoid/commitlint-github-action@v6
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
lint-js: lint-js:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v6
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
lint-scss: lint-scss:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v6
+2 -2
View File
@@ -13,11 +13,11 @@ jobs:
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v6 uses: actions/checkout@v7
- name: Check PR Content - name: Check PR Content
id: intercept id: intercept
uses: actions/github-script@v8 uses: actions/github-script@v9
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
script: | script: |
+4 -4
View File
@@ -28,7 +28,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7
with: with:
fetch-depth: 0 fetch-depth: 0
# submodules: true # submodules: true
@@ -37,7 +37,7 @@ jobs:
- name: Setup Pages - name: Setup Pages
id: pages id: pages
uses: actions/configure-pages@v5 uses: actions/configure-pages@v6
- name: Setup Ruby - name: Setup Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
@@ -57,7 +57,7 @@ jobs:
\-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/" \-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
- name: Upload site artifact - name: Upload site artifact
uses: actions/upload-pages-artifact@v4 uses: actions/upload-pages-artifact@v5
with: with:
path: "_site${{ steps.pages.outputs.base_path }}" path: "_site${{ steps.pages.outputs.base_path }}"
@@ -70,4 +70,4 @@ jobs:
steps: steps:
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment
uses: actions/deploy-pages@v4 uses: actions/deploy-pages@v5
+5
View File
@@ -25,3 +25,8 @@ package-lock.json
# Misc # Misc
_sass/vendors _sass/vendors
assets/js/dist assets/js/dist
# Hidden system files
*~
.DS_Store
Thumbs.db
+33 -40
View File
@@ -6,11 +6,11 @@
A minimal, responsive, and feature-rich Jekyll theme for technical writing. A minimal, responsive, and feature-rich Jekyll theme for technical writing.
[![CI](https://img.shields.io/github/actions/workflow/status/cotes2020/jekyll-theme-chirpy/ci.yml?logo=github)][ci]&nbsp; [![CI][badge-ci]][ci]&nbsp;
[![Codacy Badge](https://img.shields.io/codacy/grade/4e556876a3c54d5e8f2d2857c4f43894?logo=codacy)][codacy]&nbsp; [![Codacy Badge][badge-codacy]][codacy]&nbsp;
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy?color=goldenrod)][license]&nbsp; [![GitHub license][badge-license]][license]&nbsp;
[![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?&logo=RubyGems&logoColor=ghostwhite&label=gem&color=orange)][gem]&nbsp; [![Gem Version][badge-gem]][gem]&nbsp;
[![Open in Dev Containers](https://img.shields.io/badge/Dev_Containers-Open-deepskyblue?logo=linuxcontainers)][open-container] [![Open in Dev Containers][badge-open-container]][open-container]
[**Live Demo** →][demo] [**Live Demo** →][demo]
@@ -20,54 +20,48 @@
## Features ## Features
- Dark Theme - **Design & UX** - Responsive layout, Dark/Light modes, Localized UI language,
- Localized UI language and Dark mode images.
- Pinned Posts on Home Page - **Content Management** - Pinned posts, Hierarchical categories, Trending tags,
- Hierarchical Categories Auto-generated Table of Contents, and Last modified dates.
- Trending Tags - **Rich Text Support** - Syntax highlighting, Mathematical expressions, Mermaid
- Table of Contents diagrams & flowcharts, and Embedded media.
- Last Modified Date - **Interactivity & Outreach** - Built-in search, Multiple comment systems, and
- Syntax Highlighting Atom feeds.
- Mathematical Expressions - **System & Optimization** - PWA support, integrated Web analytics, and
- Mermaid Diagrams & Flowcharts advanced SEO performance.
- Dark Mode Images
- Embed Media
- Comment Systems
- Built-in Search
- Atom Feeds
- PWA
- Web Analytics
- SEO & Performance Optimization
## Documentation ## Documentation
To learn how to use, develop, and upgrade the project, please refer to the [Wiki][wiki]. To learn how to use, develop, and upgrade the project, please refer to the
[Wiki][wiki].
## Contributing ## Contributing
Contributions (_pull requests_, _issues_, and _discussions_) are what make the open-source community such an amazing place Contributions (_pull requests_, _issues_, and _discussions_) are what make the
to learn, inspire, and create. Any contributions you make are greatly appreciated. open-source community such an amazing place to learn, inspire, and create. Any
For details, see the "[Contributing Guidelines][contribute-guide]". contributions you make are greatly appreciated.
For details, please refer to our [Contributing Guidelines][contribute-guide].
## Credits ## Credits
### Contributors This project is built on the [Jekyll][jekyllrb] ecosystem and integrates a
collection of [excellent libraries][lib]. Its avatar and favicon are sourced
from [ClipartMAX][clipartmax].
Thanks to [all the contributors][contributors] involved in the development of the project! Furthermore, thanks to everyone who contributed to the development of this project!
[![all-contributors](https://contrib.rocks/image?repo=cotes2020/jekyll-theme-chirpy&columns=16)][contributors] [![all-contributors][contributors-avatar]][contributors]
<sub> — Made with [contrib.rocks](https://contrib.rocks)</sub>
### Third-Party Assets
This project is built on the [Jekyll][jekyllrb] ecosystem and some [great libraries][lib], and is developed using [VS Code][vscode] as well as tools provided by [JetBrains][jetbrains] under a non-commercial open-source software license.
The avatar and favicon for the project's website are from [ClipartMAX][clipartmax].
## License ## License
This project is published under [MIT License][license]. This project is licensed under the [MIT License][license].
[badge-ci]: https://img.shields.io/github/actions/workflow/status/cotes2020/jekyll-theme-chirpy/ci.yml?logo=github
[badge-codacy]: https://img.shields.io/codacy/grade/4e556876a3c54d5e8f2d2857c4f43894?logo=codacy
[badge-license]: https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy?color=goldenrod
[badge-gem]: https://img.shields.io/gem/v/jekyll-theme-chirpy?&logo=RubyGems&logoColor=ghostwhite&label=gem&color=orange
[badge-open-container]: https://img.shields.io/badge/Dev_Containers-Open-deepskyblue?logo=linuxcontainers
[gem]: https://rubygems.org/gems/jekyll-theme-chirpy [gem]: https://rubygems.org/gems/jekyll-theme-chirpy
[ci]: https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml?query=event%3Apush+branch%3Amaster [ci]: https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml?query=event%3Apush+branch%3Amaster
[codacy]: https://app.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade [codacy]: https://app.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade
@@ -79,6 +73,5 @@ This project is published under [MIT License][license].
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki [wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
[contribute-guide]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md [contribute-guide]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md
[contributors]: https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors [contributors]: https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors
[contributors-avatar]: https://contrib.rocks/image?repo=cotes2020/jekyll-theme-chirpy&columns=16&max=112
[lib]: https://github.com/cotes2020/chirpy-static-assets [lib]: https://github.com/cotes2020/chirpy-static-assets
[vscode]: https://code.visualstudio.com/
[jetbrains]: https://www.jetbrains.com/?from=jekyll-theme-chirpy
+10
View File
@@ -108,6 +108,16 @@ social_preview_image: # string, local or CORS resources
# boolean type, the global switch for TOC in posts. # boolean type, the global switch for TOC in posts.
toc: true toc: true
actions:
# Display "Edit this post" action on each post page to encourage contributions.
edit_post:
enabled: false # set to true to display the "Edit this post" action.
url: "" # repository base URL, e.g. https://github.com/cotes2020/jekyll-theme-chirpy/edit/master
# Use dynamic or static URL for the edit link.
# If `static_url` is false, the post's path will be appended to the `url` above as the final edit link.
# Set to true if the URL should remain unchanged, which means each post will share the same edit link.
static_url: false # [ true | false ]
comments: comments:
# Global switch for the post-comment system. Keeping it empty means disabled. # Global switch for the post-comment system. Keeping it empty means disabled.
provider: # [disqus | utterances | giscus] provider: # [disqus | utterances | giscus]
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: عذرا, الرابط التالي غير صالح أو انه يشير إلى صفحة غير موجودة. statement: عذرا, الرابط التالي غير صالح أو انه يشير إلى صفحة غير موجودة.
notification: notification:
update_found: يتوفر اصدار جديد للمحتوى. update_found: يتوفر محتوى جديد
update: تحديث update: تحديث
theme:
light: فاتح
dark: داكن
system: النظام
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: دقيقة unit: دقيقة
prompt: قراءة prompt: قراءة
edit: حرر هذا المنشور
relate_posts: إقرأ المزيد relate_posts: إقرأ المزيد
share: شارك share: شارك
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Съжалявам, но на този URL адрес няма налично съдържание. statement: Съжалявам, но на този URL адрес няма налично съдържание.
notification: notification:
update_found: Налична е нова версия на съдържанието. update_found: Има ново съдържание
update: Обнови update: Обнови
theme:
light: Светла
dark: Тъмна
system: Системна
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: мин unit: мин
prompt: четиво prompt: четиво
edit: Редактирай тази публикация
relate_posts: Още за четене relate_posts: Още за четене
share: Споделете share: Споделете
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Ho sentim, hem perdut aquesta URL o apunta a alguna cosa que no existeix. statement: Ho sentim, hem perdut aquesta URL o apunta a alguna cosa que no existeix.
notification: notification:
update_found: Hi ha una nova versió de contingut disponible. update_found: Hi ha contingut nou disponible
update: Actualitzar update: Actualitzar
theme:
light: Clar
dark: Fosc
system: Sistema
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: " de lectura" prompt: " de lectura"
edit: Edita aquesta entrada
relate_posts: Entrades relacionades relate_posts: Entrades relacionades
share: Compartir share: Compartir
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Omlouváme se, adresu URL jsme špatně umístili nebo odkazuje na něco, co neexistuje. statement: Omlouváme se, adresu URL jsme špatně umístili nebo odkazuje na něco, co neexistuje.
notification: notification:
update_found: Je k dispozici nová verze obsahu. update_found: Je tu nový obsah
update: Aktualizace update: Aktualizace
theme:
light: Světlý
dark: Tmavý
system: Systém
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: minut unit: minut
prompt: čtení prompt: čtení
edit: Uprav tento příspěvek
relate_posts: Další čtení relate_posts: Další čtení
share: Sdílet share: Sdílet
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Beklager, vi har malpaceret denne URL, eller den peger på et sted, som ikke findes. statement: Beklager, vi har malpaceret denne URL, eller den peger på et sted, som ikke findes.
notification: notification:
update_found: En ny version af indholdet er fundet! update_found: Der er nyt indhold
update: Opdater update: Opdater
theme:
light: Lys
dark: Mørk
system: System
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: læsetid prompt: læsetid
edit: Rediger dette opslag
relate_posts: Læs videre relate_posts: Læs videre
share: Del share: Del
button: button:
+7 -1
View File
@@ -45,9 +45,14 @@ not_found:
statement: Entschuldigung, dieser Link verweist auf keine vorhandene Ressource. statement: Entschuldigung, dieser Link verweist auf keine vorhandene Ressource.
notification: notification:
update_found: Eine neue Version ist verfügbar. update_found: Neue Inhalte verfügbar
update: Neue Version update: Neue Version
theme:
light: Hell
dark: Dunkel
system: System
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: Minuten unit: Minuten
prompt: Lesezeit prompt: Lesezeit
edit: Diesen Eintrag bearbeiten
relate_posts: Weiterlesen relate_posts: Weiterlesen
share: Teilen share: Teilen
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: ސޯރީ، މި ޔޫ.އާރއެލް މަށެވެއްނެ ނުވަތަ އެކަމެއް ނުވެއެވެ. statement: ސޯރީ، މި ޔޫ.އާރއެލް މަށެވެއްނެ ނުވަތަ އެކަމެއް ނުވެއެވެ.
notification: notification:
update_found: ޔޫ ވާރޝަން ހުރިހާ. update_found: އައު ކޮންޓެންޓެއް ފެނިއްޖެ
update: އޮޕްޑޭޓް update: އޮޕްޑޭޓް
theme:
light: އަލި
dark: އަނދިރި
system: ސިސްޓަމް
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: މިނެޓް unit: މިނެޓް
prompt: އިސްކާރު prompt: އިސްކާރު
edit: މި ޕޯސްޓް އެޑިޓް ކުރު
relate_posts: އެއްޗެހި ފަހުރަށްދަން relate_posts: އެއްޗެހި ފަހުރަށްދަން
share: ސެއާރް share: ސެއާރް
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Συγνώμη, έχουμε τοποθετήσει λάθος αυτήν την διεύθυνση URL ή υποδεικνύει κάτι που δεν υπάρχει. statement: Συγνώμη, έχουμε τοποθετήσει λάθος αυτήν την διεύθυνση URL ή υποδεικνύει κάτι που δεν υπάρχει.
notification: notification:
update_found: Υπάρχει διαθέσιμη μια νέα έκδοση του περιεχομένου. update_found: Νέο περιεχόμενο διαθέσιμο
update: Ενημέρωση update: Ενημέρωση
theme:
light: Φωτεινό
dark: Σκοτεινό
system: Σύστημα
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: Λεπτά unit: Λεπτά
prompt: διαβάσματος prompt: διαβάσματος
edit: Επεξεργασία αυτής της δημοσίευσης
relate_posts: Περισσότερα relate_posts: Περισσότερα
share: Κοινοποιήστε share: Κοινοποιήστε
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. statement: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
notification: notification:
update_found: A new version of content is available. update_found: New content available
update: Update update: Update
theme:
light: Light
dark: Dark
system: System
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: read prompt: read
edit: Edit this post
relate_posts: Further Reading relate_posts: Further Reading
share: Share share: Share
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Lo sentimos, hemos perdido esa URL o apunta a algo que no existe. statement: Lo sentimos, hemos perdido esa URL o apunta a algo que no existe.
notification: notification:
update_found: Hay una nueva versión de contenido disponible. update_found: Hay contenido nuevo
update: Actualizar update: Actualizar
theme:
light: Claro
dark: Oscuro
system: Sistema
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: " de lectura" prompt: " de lectura"
edit: Edita esta entrada
relate_posts: Lecturas adicionales relate_posts: Lecturas adicionales
share: Compartir share: Compartir
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: متأسفیم، لینک زیر معتبر نیست یا به صفحه‌ای که وجود ندارد اشاره می‌کند. statement: متأسفیم، لینک زیر معتبر نیست یا به صفحه‌ای که وجود ندارد اشاره می‌کند.
notification: notification:
update_found: نسخه جدیدی از محتوا موجود است. update_found: محتوای جدیدی پیدا شد
update: به‌روزرسانی update: به‌روزرسانی
theme:
light: روشن
dark: تیره
system: سیستم
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: "دقیقه " unit: "دقیقه "
prompt: " زمان مطالعه" prompt: " زمان مطالعه"
edit: ویرایش این پست
relate_posts: بیشتر بخوانید relate_posts: بیشتر بخوانید
share: اشتراک‌گذاری share: اشتراک‌گذاری
button: button:
+7 -1
View File
@@ -45,9 +45,14 @@ not_found:
statement: Valitettavasti tällä URL-osoitteella ei ole saatavilla sisältöä. statement: Valitettavasti tällä URL-osoitteella ei ole saatavilla sisältöä.
notification: notification:
update_found: Uusi versio sisällöstä on saatavilla. update_found: Uutta sisältöä löytyi
update: Päivitä update: Päivitä
theme:
light: Vaalea
dark: Tumma
system: Järjestelmä
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: minuuttia unit: minuuttia
prompt: lukea prompt: lukea
edit: Muokkaa tätä julkaisua
relate_posts: Jatka lukemista relate_posts: Jatka lukemista
share: Jaa share: Jaa
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Désolé, nous avons égaré cette URL ou elle pointe vers quelque chose qui n'existe pas. statement: Désolé, nous avons égaré cette URL ou elle pointe vers quelque chose qui n'existe pas.
notification: notification:
update_found: Une nouvelle version du contenu est disponible. update_found: Nouveau contenu trouvé
update: Mise à jour update: Mise à jour
theme:
light: Clair
dark: Sombre
system: Système
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: lire prompt: lire
edit: Modifier cet article
relate_posts: Autres lectures relate_posts: Autres lectures
share: Partager share: Partager
button: button:
+7 -1
View File
@@ -47,9 +47,14 @@ not_found:
statement: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat. statement: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat.
notification: notification:
update_found: Elérhető a tartalom új verziója. update_found: Új tartalom található
update: Frissítés update: Frissítés
theme:
light: Világos
dark: Sötét
system: Rendszer
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -61,6 +66,7 @@ post:
read_time: read_time:
unit: perc unit: perc
prompt: elolvasni prompt: elolvasni
edit: Szerkesztés
relate_posts: További olvasnivaló relate_posts: További olvasnivaló
share: Megosztás share: Megosztás
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Maaf, kami gagal menemukan URL itu atau memang mengarah ke sesuatu yang tidak ada. statement: Maaf, kami gagal menemukan URL itu atau memang mengarah ke sesuatu yang tidak ada.
notification: notification:
update_found: Versi konten baru tersedia. update_found: Konten baru tersedia
update: Perbarui update: Perbarui
theme:
light: Terang
dark: Gelap
system: Sistem
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: menit unit: menit
prompt: baca prompt: baca
edit: Sunting entri ini
relate_posts: Postingan Lainya relate_posts: Postingan Lainya
share: Bagikan share: Bagikan
button: button:
+7 -1
View File
@@ -45,9 +45,14 @@ not_found:
statement: Ci scusiamo, non è stato possibile trovare l'URL in questione. Potrebbe puntare ad una pagina non esistente. statement: Ci scusiamo, non è stato possibile trovare l'URL in questione. Potrebbe puntare ad una pagina non esistente.
notification: notification:
update_found: Nuova versione del contenuto disponibile. update_found: Nuovi contenuti trovati
update: Aggiornamento update: Aggiornamento
theme:
light: Chiaro
dark: Scuro
system: Sistema
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: lettura prompt: lettura
edit: Modifica questo post
relate_posts: Continua a leggere relate_posts: Continua a leggere
share: Condividi share: Condividi
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: このURLは存在しないものを指し示しています。 statement: このURLは存在しないものを指し示しています。
notification: notification:
update_found: 新しいバージョンが利用可能です。 update_found: 新しいコンテンツがあります
update: 更新 update: 更新
theme:
light: ライト
dark: ダーク
system: システム
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: unit:
prompt: で読めます prompt: で読めます
edit: この投稿を編集
relate_posts: さらに読む relate_posts: さらに読む
share: シェア share: シェア
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: 해당 URL은 존재하지 않습니다. statement: 해당 URL은 존재하지 않습니다.
notification: notification:
update_found: 버전의 콘텐츠를 사용할 수 있습니다. update_found: 콘텐츠가 있습니다
update: 업데이트 update: 업데이트
theme:
light: 라이트
dark: 다크
system: 시스템
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: unit:
prompt: 읽는 시간 prompt: 읽는 시간
edit: 이 글 편집
relate_posts: 관련된 글 relate_posts: 관련된 글
share: 공유하기 share: 공유하기
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: ببوورە، ئەم بەستەرە نادۆزرێتەوە یان ئاماژە بە شتێک دەکات کە بوونی نییە. statement: ببوورە، ئەم بەستەرە نادۆزرێتەوە یان ئاماژە بە شتێک دەکات کە بوونی نییە.
notification: notification:
update_found: وەشانێکی نوێی ناوەڕۆک بەردەستە. update_found: ناوەڕۆکی نوێ بەردەستە
update: نوێکردنەوە update: نوێکردنەوە
theme:
light: ڕووناک
dark: تاریک
system: سیستەم
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: خولەک unit: خولەک
prompt: خوێندنەوە prompt: خوێندنەوە
edit: ئەم بابەتە دەستکاری بکە
relate_posts: بابەتی پەیوەندیدار relate_posts: بابەتی پەیوەندیدار
share: بڵاوکردنەوە share: بڵاوکردنەوە
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: ဝမ်းနည်းပါသည်၊ ကျွန်ုပ်တို့သည် အဆိုပါ URL ကို မှားယွင်းစွာ နေရာချထားခြင်း သို့မဟုတ် ၎င်းသည် မရှိသောအရာကို ညွှန်ပြနေပါသည်။ statement: ဝမ်းနည်းပါသည်၊ ကျွန်ုပ်တို့သည် အဆိုပါ URL ကို မှားယွင်းစွာ နေရာချထားခြင်း သို့မဟုတ် ၎င်းသည် မရှိသောအရာကို ညွှန်ပြနေပါသည်။
notification: notification:
update_found: အကြောင်းအရာဗားရှင်းအသစ်ကို ရနိုင်ပါပြီ။ update_found: အကြောင်းအရာအသစ် တွေ့ရှိပါသည်
update: အပ်ဒိတ် update: အပ်ဒိတ်
theme:
light: အလင်း
dark: အမှောင်
system: စနစ်
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: မိနစ် unit: မိနစ်
prompt: ဖတ်ပါမည် prompt: ဖတ်ပါမည်
edit: ဤပို့စ်ကို တည်းဖြတ်ပါ
relate_posts: နောက်ထပ်ဖတ်ရန် relate_posts: နောက်ထပ်ဖတ်ရန်
share: မျှဝေရန် share: မျှဝေရန်
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Sorry, we hebben de URL verkeerd geplaatst of hij verwijst naar iets dat niet bestaat. statement: Sorry, we hebben de URL verkeerd geplaatst of hij verwijst naar iets dat niet bestaat.
notification: notification:
update_found: Nieuwe versie van inhoud beschikbaar. update_found: Nieuwe inhoud gevonden
update: Update update: Update
theme:
light: Licht
dark: Donker
system: Systeem
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
written_by: Door written_by: Door
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: lees prompt: lees
edit: Bewerk dit bericht
relate_posts: Verder Lezen relate_posts: Verder Lezen
share: Deel share: Deel
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: بښنه غواړو، دغه URL ناسم دی یا هغه څه ته اشاره کوي چې شتون نه لري. statement: بښنه غواړو، دغه URL ناسم دی یا هغه څه ته اشاره کوي چې شتون نه لري.
notification: notification:
update_found: نوې نسخه شتون لري. update_found: نوې منځپانګه شتون لري
update: تازه update: تازه
theme:
light: روښانه
dark: تیاره
system: سیستم
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: دقیقې unit: دقیقې
prompt: لوستل prompt: لوستل
edit: دغه لیکنه سمول
relate_posts: نوره لوستنه relate_posts: نوره لوستنه
share: شریکول share: شریکول
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Desculpe, a página não foi encontrada. statement: Desculpe, a página não foi encontrada.
notification: notification:
update_found: Uma nova versão do conteúdo está disponível. update_found: Novo conteúdo encontrado
update: atualização update: atualização
theme:
light: Claro
dark: Escuro
system: Sistema
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: " de leitura" prompt: " de leitura"
edit: Editar esta postagem
relate_posts: Leia também relate_posts: Leia também
share: Compartilhar share: Compartilhar
button: button:
+7 -1
View File
@@ -45,9 +45,14 @@ not_found:
statement: Извините, мы перепутали URL-адрес или он указывает на что-то несуществующее. statement: Извините, мы перепутали URL-адрес или он указывает на что-то несуществующее.
notification: notification:
update_found: Доступна новая версия контента. update_found: Найден новый контент
update: Обновить update: Обновить
theme:
light: Светлая
dark: Темная
system: Системная
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: мин. unit: мин.
prompt: чтения prompt: чтения
edit: Редактировать этот пост
relate_posts: Похожие посты relate_posts: Похожие посты
share: Поделиться share: Поделиться
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Oprostite, hiperpovezava je neustrezna ali vsebina ne obstajata. #Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. statement: Oprostite, hiperpovezava je neustrezna ali vsebina ne obstajata. #Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
notification: notification:
update_found: Novejša različica vsebine je na voljo. #A new version of content is available. update_found: Nova vsebina je na voljo
update: Posodobi #Update update: Posodobi #Update
theme:
light: Svetla
dark: Temna
system: Sistemska
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: beri #read prompt: beri #read
edit: Uredi to objavo #Edit this post
relate_posts: Nadaljnje branje #Further Reading relate_posts: Nadaljnje branje #Further Reading
share: Deli #Share share: Deli #Share
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Ursäkta, vi har tappat bort den här webbadressen eller så pekar den på något som inte längre finns. statement: Ursäkta, vi har tappat bort den här webbadressen eller så pekar den på något som inte längre finns.
notification: notification:
update_found: Det finns en ny version av innehållet. update_found: Nytt innehåll hittades
update: Uppdatera sidan update: Uppdatera sidan
theme:
light: Ljust
dark: Mörkt
system: System
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: min unit: min
prompt: läsning prompt: läsning
edit: Redigera detta inlägg
relate_posts: Mer läsning relate_posts: Mer läsning
share: Dela share: Dela
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: ขออภัย เราวาง URL นั้นไว้ผิดที่ หรือมันชี้ไปยังสิ่งที่ไม่มีอยู่ statement: ขออภัย เราวาง URL นั้นไว้ผิดที่ หรือมันชี้ไปยังสิ่งที่ไม่มีอยู่
notification: notification:
update_found: มีเวอร์ชันใหม่ของเนื้อหา update_found: พบเนื้อหาใหม่
update: อัปเดต update: อัปเดต
theme:
light: สว่าง
dark: มืด
system: ระบบ
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: นาที unit: นาที
prompt: อ่าน prompt: อ่าน
edit: แก้ไขโพสต์นี้
relate_posts: อ่านต่อ relate_posts: อ่านต่อ
share: แชร์ share: แชร์
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Üzgünüz, bu linki yanlış yerleştirdik veya var olmayan bir şeye işaret ediyor. statement: Üzgünüz, bu linki yanlış yerleştirdik veya var olmayan bir şeye işaret ediyor.
notification: notification:
update_found: İçeriğin yeni bir sürümü mevcut. update_found: Yeni içerik bulundu
update: Güncelle update: Güncelle
theme:
light: Açık
dark: Koyu
system: Sistem
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: dakikada unit: dakikada
prompt: okunabilir prompt: okunabilir
edit: Bu gönderiyi düzenle
relate_posts: Benzer Gönderiler relate_posts: Benzer Gönderiler
share: Paylaş share: Paylaş
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: Вибачте, це посилання вказує на ресурс, що не існує. statement: Вибачте, це посилання вказує на ресурс, що не існує.
notification: notification:
update_found: Доступна нова версія вмісту. update_found: Знайдено новий вміст
update: Оновлення update: Оновлення
theme:
light: Світла
dark: Темна
system: Системна
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: хвилин unit: хвилин
prompt: читання prompt: читання
edit: Редагувати цей пост
relate_posts: Вас також може зацікавити relate_posts: Вас також може зацікавити
share: Поділитися share: Поділитися
button: button:
+7 -1
View File
@@ -46,9 +46,14 @@ not_found:
statement: معذرت، یہ URL غلط ہے یا جس چیز کی طرف اشارہ کر رہا ہے وہ موجود نہیں۔ statement: معذرت، یہ URL غلط ہے یا جس چیز کی طرف اشارہ کر رہا ہے وہ موجود نہیں۔
notification: notification:
update_found: نیا مواد دستیاب ہے۔ update_found: نیا مواد مل گیا
update: اپ ڈیٹ update: اپ ڈیٹ
theme:
light: روشن
dark: تاریک
system: سسٹم
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -60,6 +65,7 @@ post:
read_time: read_time:
unit: منٹ unit: منٹ
prompt: پڑھیں prompt: پڑھیں
edit: اس تحریر میں ترمیم کریں
relate_posts: مزید مطالعہ relate_posts: مزید مطالعہ
share: شیئر share: شیئر
button: button:
+7 -1
View File
@@ -45,9 +45,14 @@ not_found:
statement: Xin lỗi, chúng tôi đã đặt nhầm URL hoặc đường dẫn trỏ đến một trang nào đó không tồn tại. statement: Xin lỗi, chúng tôi đã đặt nhầm URL hoặc đường dẫn trỏ đến một trang nào đó không tồn tại.
notification: notification:
update_found: Đã có phiên bản mới của nội dung. update_found: Đã tìm thấy nội dung mới
update: Cập nhật update: Cập nhật
theme:
light: Sáng
dark: Tối
system: Hệ thống
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: phút unit: phút
prompt: đọc prompt: đọc
edit: Chỉnh sửa bài viết này
relate_posts: Bài viết liên quan relate_posts: Bài viết liên quan
share: Chia sẻ share: Chia sẻ
button: button:
+7 -1
View File
@@ -45,9 +45,14 @@ not_found:
statement: 抱歉,我们放错了该 URL,或者它指向了不存在的内容。 statement: 抱歉,我们放错了该 URL,或者它指向了不存在的内容。
notification: notification:
update_found: 发现新版本的内容 update_found: 发现新内容
update: 更新 update: 更新
theme:
light: 浅色
dark: 深色
system: 跟随系统
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: 分钟 unit: 分钟
prompt: 阅读 prompt: 阅读
edit: 编辑此文
relate_posts: 相关文章 relate_posts: 相关文章
share: 分享 share: 分享
button: button:
+7 -1
View File
@@ -45,9 +45,14 @@ not_found:
statement: 抱歉,您可能正在存取一個已被移動的 URL,或者它從未存在。 statement: 抱歉,您可能正在存取一個已被移動的 URL,或者它從未存在。
notification: notification:
update_found: 發現新版本更新。 update_found: 發現新內容
update: 更新 update: 更新
theme:
light: 淺色
dark: 深色
system: 跟隨系統
# ----- Posts related labels ----- # ----- Posts related labels -----
post: post:
@@ -59,6 +64,7 @@ post:
read_time: read_time:
unit: 分鐘 unit: 分鐘
prompt: 閱讀 prompt: 閱讀
edit: 編輯此文
relate_posts: 相關文章 relate_posts: 相關文章
share: 分享 share: 分享
button: button:
+18 -15
View File
@@ -19,36 +19,39 @@ webfonts: https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Sour
# Libraries # Libraries
bootstrap:
css: https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css
toc: toc:
css: https://cdn.jsdelivr.net/npm/tocbot@4.36.4/dist/tocbot.min.css css: https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.css
js: https://cdn.jsdelivr.net/npm/tocbot@4.36.4/dist/tocbot.min.js js: https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.js
fontawesome: fontawesome:
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.2.0/css/all.min.css css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7/css/all.min.css
search: search:
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1/dest/simple-jekyll-search.min.js
mermaid: mermaid:
js: https://cdn.jsdelivr.net/npm/mermaid@11.13.0/dist/mermaid.min.js js: https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js
dayjs: dayjs:
js: js:
common: https://cdn.jsdelivr.net/npm/dayjs@1.11.20/dayjs.min.js common: https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js
locale: https://cdn.jsdelivr.net/npm/dayjs@1.11.20/locale/:LOCALE.js locale: https://cdn.jsdelivr.net/npm/dayjs@1/locale/:LOCALE.js
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1.11.20/plugin/relativeTime.js relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1/plugin/relativeTime.js
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.20/plugin/localizedFormat.js localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1/plugin/localizedFormat.js
glightbox: glightbox:
css: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css css: https://cdn.jsdelivr.net/npm/glightbox@3/dist/css/glightbox.min.css
js: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/js/glightbox.min.js js: https://cdn.jsdelivr.net/npm/glightbox@3/dist/js/glightbox.min.js
lazy-polyfill: lazy-polyfill:
css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2/dist/loading-attribute-polyfill.min.css
js: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.umd.min.js js: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2/dist/loading-attribute-polyfill.umd.min.js
clipboard: clipboard:
js: https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js js: https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js
mathjax: mathjax:
js: https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-chtml.js js: https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-chtml.js
+2 -2
View File
@@ -19,7 +19,7 @@
{%- comment -%} Auto switch theme {%- endcomment -%} {%- comment -%} Auto switch theme {%- endcomment -%}
function reloadDisqus(event) { function reloadDisqus(event) {
if (event.source === window && event.data && event.data.id === Theme.ID) { if (event.source === window && event.data && event.data.id === Theme.eventId) {
{%- comment -%} Disqus hasn't been loaded {%- endcomment -%} {%- comment -%} Disqus hasn't been loaded {%- endcomment -%}
if (typeof DISQUS === 'undefined') { if (typeof DISQUS === 'undefined') {
return; return;
@@ -33,7 +33,7 @@
addDisqus(); addDisqus();
if (Theme.switchable) { if (Theme.isToggleable) {
addEventListener('message', reloadDisqus); addEventListener('message', reloadDisqus);
} }
+17 -7
View File
@@ -1,8 +1,8 @@
<!-- https://giscus.app/ --> <!-- https://giscus.app/ -->
<script> <script>
(function () { (function () {
const themeMapper = Theme.getThemeMapper('light', 'dark_dimmed'); const themeMap = Theme.newThemeMap('light', 'dark_dimmed');
const initTheme = themeMapper[Theme.visualState]; const initTheme = themeMap[Theme.resolvedTheme];
let lang = '{{ site.comments.giscus.lang | default: lang }}'; let lang = '{{ site.comments.giscus.lang | default: lang }}';
{%- comment -%} https://github.com/giscus/giscus/tree/main/locales {%- endcomment -%} {%- comment -%} https://github.com/giscus/giscus/tree/main/locales {%- endcomment -%}
@@ -37,8 +37,8 @@
$footer.insertAdjacentElement("beforebegin", giscusNode); $footer.insertAdjacentElement("beforebegin", giscusNode);
addEventListener('message', (event) => { addEventListener('message', (event) => {
if (event.source === window && event.data && event.data.id === Theme.ID) { if (event.source === window && event.data && event.data.id === Theme.eventId) {
const newTheme = themeMapper[Theme.visualState]; const newTheme = themeMap[Theme.resolvedTheme];
const message = { const message = {
setConfig: { setConfig: {
@@ -46,9 +46,19 @@
} }
}; };
const giscus = const iframe = document.querySelector('.giscus-frame');
document.getElementsByClassName('giscus-frame')[0].contentWindow;
giscus.postMessage({ giscus: message }, 'https://giscus.app'); if (!iframe) {
return;
}
if (iframe.classList.contains('giscus-frame--loading')) {
let url = new URL(iframe.src);
url.searchParams.set('theme', newTheme);
iframe.src = url.toString();
}
iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
} }
}); });
})(); })();
+4 -4
View File
@@ -2,8 +2,8 @@
<script> <script>
(function () { (function () {
const origin = 'https://utteranc.es'; const origin = 'https://utteranc.es';
const themeMapper = Theme.getThemeMapper('github-light', 'github-dark'); const themeMap = Theme.newThemeMap('github-light', 'github-dark');
const initTheme = themeMapper[Theme.visualState]; const initTheme = themeMap[Theme.resolvedTheme];
let script = document.createElement('script'); let script = document.createElement('script');
script.src = 'https://utteranc.es/client.js'; script.src = 'https://utteranc.es/client.js';
@@ -22,8 +22,8 @@
{%- comment -%} {%- comment -%}
Credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> Credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347>
{%- endcomment -%} {%- endcomment -%}
if (event.source === window && event.data && event.data.id === Theme.ID) { if (event.source === window && event.data && event.data.id === Theme.eventId) {
newTheme = themeMapper[Theme.visualState]; newTheme = themeMap[Theme.resolvedTheme];
const message = { const message = {
type: 'set-theme', type: 'set-theme',
+1 -3
View File
@@ -2,8 +2,6 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7"> <meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e"> <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta <meta
name="viewport" name="viewport"
content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover" content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
@@ -83,7 +81,7 @@
<!-- Bootstrap --> <!-- Bootstrap -->
{% unless jekyll.environment == 'production' %} {% unless jekyll.environment == 'production' %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="{{ site.data.origin.cors.bootstrap.css }}">
{% endunless %} {% endunless %}
<!-- Theme style --> <!-- Theme style -->
-1
View File
@@ -67,7 +67,6 @@
{% if page.math %} {% if page.math %}
<!-- MathJax --> <!-- MathJax -->
<script src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script> <script src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script>
<script async src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="{{ site.data.origin[type].mathjax.js | relative_url }}"></script> <script id="MathJax-script" async src="{{ site.data.origin[type].mathjax.js | relative_url }}"></script>
{% endif %} {% endif %}
+13 -9
View File
@@ -1,24 +1,28 @@
<aside <aside
id="notification" id="notification"
class="toast" class="toast w-auto rounded-5 text-nowrap"
role="alert" role="alert"
aria-live="assertive" aria-live="assertive"
aria-atomic="true" aria-atomic="true"
data-bs-animation="true" data-bs-animation="true"
data-bs-autohide="false" data-bs-autohide="false"
> >
<div class="toast-header"> <div class="d-flex align-items-center">
<div class="toast-body ps-3">
{{- site.data.locales[include.lang].notification.update_found -}}
</div>
<button <button
type="button" type="button"
class="btn-close ms-auto" class="btn btn-primary btn-sm rounded-2 py-0"
aria-label="Update"
>
{{- site.data.locales[include.lang].notification.update -}}
</button>
<button
type="button"
class="btn-close mx-3 ms-2"
data-bs-dismiss="toast" data-bs-dismiss="toast"
aria-label="Close" aria-label="Close"
></button> ></button>
</div> </div>
<div class="toast-body text-center pt-0">
<p class="px-2 mb-3">{{ site.data.locales[include.lang].notification.update_found }}</p>
<button type="button" class="btn btn-primary" aria-label="Update">
{{ site.data.locales[include.lang].notification.update }}
</button>
</div>
</aside> </aside>
+23
View File
@@ -0,0 +1,23 @@
<!-- Link to edit the post to contribute. -->
{% assign enabled = site.actions.edit_post.enabled %}
{% assign url = site.actions.edit_post.url %}
{% assign static_url = site.actions.edit_post.static_url %}
{% unless static_url %}
{% assign url = url | append: '/' | append: page.path %}
{% endunless %}
{% if enabled %}
<div class="post-edit">
{% assign edit = site.data.locales[include.lang].post.edit %}
<a
href="{{ url }}"
target="_blank"
rel="noopener"
>
<i class="fa fa-pen fa-fw me-1"></i>
<span>{{ edit }}</span>
</a>
</div>
{% endif %}
+46 -4
View File
@@ -41,10 +41,52 @@
</nav> </nav>
<div class="sidebar-bottom d-flex flex-wrap align-items-center w-100"> <div class="sidebar-bottom d-flex flex-wrap align-items-center w-100">
{% unless site.theme_mode %} {% unless site.theme_mode == 'light' or site.theme_mode == 'dark' %}
<button type="button" class="btn btn-link nav-link" aria-label="Switch Mode" id="mode-toggle"> {%- capture icon_system -%}
<i class="fas fa-adjust"></i> <i class="fa-solid fa-display" data-theme-mode="system"></i>
{%- endcapture -%}
{%- capture icon_light -%}
<i class="fa-regular fa-sun" data-theme-mode="light"></i>
{%- endcapture -%}
{%- capture icon_dark -%}
<i class="fa-regular fa-moon" data-theme-mode="dark"></i>
{%- endcapture -%}
<div class="btn-group dropup">
<button
type="button"
class="btn btn-link nav-link"
aria-label="Switch Mode"
id="mode-toggle"
data-bs-toggle="dropdown"
>
{{- icon_light -}}
{{- icon_dark -}}
{{- icon_system -}}
</button> </button>
<ul class="dropdown-menu rounded-3 mb-1 p-1">
<li>
<button class="dropdown-item d-flex align-items-center" type="button" data-theme-mode="light">
{{- icon_light -}}
{{- site.data.locales[lang].theme.light -}}
</button>
</li>
<li>
<button class="dropdown-item d-flex align-items-center" type="button" data-theme-mode="dark">
{{- icon_dark -}}
{{- site.data.locales[lang].theme.dark -}}
</button>
</li>
<li>
<button class="dropdown-item d-flex align-items-center" type="button" data-theme-mode="system">
{{- icon_system -}}
{{- site.data.locales[lang].theme.system -}}
</button>
</li>
</ul>
</div>
{% if site.data.contact.size > 0 %} {% if site.data.contact.size > 0 %}
<span class="icon-border"></span> <span class="icon-border"></span>
@@ -68,7 +110,7 @@
{%- endunless -%} {%- endunless -%}
{%- assign email = site.social.email | split: '@' -%} {%- assign email = site.social.email | split: '@' -%}
{%- capture url -%} {%- capture url -%}
javascript:location.href = 'mailto:' + ['{{ email[0] }}','{{ email[1] }}'].join('@') javascript:void(location.href = 'mailto:' + ['{{ email[0] }}','{{ email[1] }}'].join('@'))
{%- endcapture -%} {%- endcapture -%}
{% when 'rss' %} {% when 'rss' %}
{% assign url = '/feed.xml' | relative_url %} {% assign url = '/feed.xml' | relative_url %}
+7 -3
View File
@@ -32,17 +32,21 @@ export function imgPopup() {
document.querySelector('.popup.dark') === null document.querySelector('.popup.dark') === null
); );
if (Theme.visualState === Theme.DARK) { if (Theme.isDark) {
selector = darkImages; selector = darkImages;
} }
let current = GLightbox({ selector: `${selector}` }); let current = GLightbox({ selector: `${selector}` });
if (hasDualImages && Theme.switchable) { if (hasDualImages && Theme.isToggleable) {
let reverse = null; let reverse = null;
window.addEventListener('message', (event) => { window.addEventListener('message', (event) => {
if (event.source === window && event.data && event.data.id === Theme.ID) { if (
event.source === window &&
event.data &&
event.data.id === Theme.eventId
) {
[current, reverse] = swapImages(current, reverse); [current, reverse] = swapImages(current, reverse);
} }
}); });
+9 -5
View File
@@ -3,10 +3,14 @@
*/ */
const MERMAID = 'mermaid'; const MERMAID = 'mermaid';
const themeMapper = Theme.getThemeMapper('default', 'dark'); const themeMap = Theme.newThemeMap('default', 'dark');
function refreshTheme(event) { function refreshTheme(event) {
if (event.source === window && event.data && event.data.id === Theme.ID) { if (
event.source === window &&
event.data &&
event.data.id === Theme.eventId
) {
// Re-render the SVG <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344> // Re-render the SVG <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344>
const mermaidList = document.getElementsByClassName(MERMAID); const mermaidList = document.getElementsByClassName(MERMAID);
@@ -16,7 +20,7 @@ function refreshTheme(event) {
elem.removeAttribute('data-processed'); elem.removeAttribute('data-processed');
}); });
const newTheme = themeMapper[Theme.visualState]; const newTheme = themeMap[Theme.resolvedTheme];
mermaid.initialize({ theme: newTheme }); mermaid.initialize({ theme: newTheme });
mermaid.init(null, `.${MERMAID}`); mermaid.init(null, `.${MERMAID}`);
@@ -43,7 +47,7 @@ export function loadMermaid() {
return; return;
} }
const initTheme = themeMapper[Theme.visualState]; const initTheme = themeMap[Theme.resolvedTheme];
let mermaidConf = { let mermaidConf = {
theme: initTheme theme: initTheme
@@ -54,7 +58,7 @@ export function loadMermaid() {
mermaid.initialize(mermaidConf); mermaid.initialize(mermaidConf);
if (Theme.switchable) { if (Theme.isToggleable) {
window.addEventListener('message', refreshTheme); window.addEventListener('message', refreshTheme);
} }
} }
+36 -5
View File
@@ -1,15 +1,46 @@
/** /**
* Add listener for theme mode toggle * Sets up the mode toggle dropdown, allowing users to switch between light, dark, and system themes.
*
* Dependencies:
* - Theme (${JS_ROOT}/theme.js)
*/ */
const $toggle = document.getElementById('mode-toggle'); import 'bootstrap/js/src/dropdown.js';
const ACTIVE_CLASS = 'active';
const dropdown = document.querySelector('#mode-toggle + .dropdown-menu');
const activeMode = Theme.isSystemTheme
? Theme.Mode.SYSTEM
: Theme.resolvedTheme;
export function modeWatcher() { export function modeWatcher() {
if (!$toggle) { if (!Theme.isToggleable) {
return; return;
} }
$toggle.addEventListener('click', () => { dropdown.querySelectorAll('.dropdown-item').forEach((option) => {
Theme.flip(); const mode = option.dataset.themeMode;
if (mode === activeMode) {
option.classList.add(ACTIVE_CLASS);
return;
}
});
dropdown.addEventListener('click', (event) => {
const current = event.target.closest('.dropdown-item');
if (!current) {
return;
}
const lastActive = dropdown.querySelector(`.${ACTIVE_CLASS}`);
if (lastActive === current) {
return;
}
lastActive.classList.remove(ACTIVE_CLASS);
current.classList.add(ACTIVE_CLASS);
Theme.update(current.dataset.themeMode);
}); });
} }
@@ -62,6 +62,7 @@ export class TocMobile {
static showPopup() { static showPopup() {
this.lockScroll(true); this.lockScroll(true);
$popup.showModal(); $popup.showModal();
$btnClose.blur();
const activeItem = $popup.querySelector('li.is-active-li'); const activeItem = $popup.querySelector('li.is-active-li');
activeItem.scrollIntoView({ block: 'center' }); activeItem.scrollIntoView({ block: 'center' });
} }
+4 -4
View File
@@ -8,9 +8,9 @@ if ('serviceWorker' in navigator) {
if (register) { if (register) {
const swUrl = `${baseUrl}/sw.min.js`; const swUrl = `${baseUrl}/sw.min.js`;
const notification = document.getElementById('notification'); const $notification = document.getElementById('notification');
const btnRefresh = notification.querySelector('.toast-body>button'); const $btnUpdate = $notification.querySelector('[aria-label="Update"]');
const popupWindow = Toast.getOrCreateInstance(notification); const popupWindow = Toast.getOrCreateInstance($notification);
navigator.serviceWorker.register(swUrl).then((registration) => { navigator.serviceWorker.register(swUrl).then((registration) => {
// Restore the update window that was last manually closed by the user // Restore the update window that was last manually closed by the user
@@ -28,7 +28,7 @@ if ('serviceWorker' in navigator) {
}); });
}); });
btnRefresh.addEventListener('click', () => { $btnUpdate.addEventListener('click', () => {
if (registration.waiting) { if (registration.waiting) {
registration.waiting.postMessage('SKIP_WAITING'); registration.waiting.postMessage('SKIP_WAITING');
} }
+105 -87
View File
@@ -1,135 +1,153 @@
/** /**
* Theme management class * A utility class that manages the site's theme mode.
* *
* To reduce flickering during page load, this script should be loaded synchronously. * Concepts:
* - Mode: dark, light, or system. The latter follows the operating system's preference.
* - Theme: The actual theme applied to the DOM, either dark or light. Determined by the mode or system preference.
*/ */
class Theme { class Theme {
static #modeKey = 'mode'; /** @type {string} LocalStorage key for the selected theme mode. */
static #modeAttr = 'data-mode'; static #storageKey = 'theme';
static #darkMedia = window.matchMedia('(prefers-color-scheme: dark)');
static switchable = !document.documentElement.hasAttribute(this.#modeAttr);
static get DARK() { static Mode = Object.freeze({
return 'dark'; DARK: 'dark',
LIGHT: 'light',
SYSTEM: 'system'
});
static #root = document.documentElement;
/** @type {MediaQueryList} System dark-mode preference query. */
static #mediaDark = window.matchMedia('(prefers-color-scheme: dark)');
/** @returns {string|null} The theme currently set on the DOM. */
static get #domTheme() {
return this.#root.dataset.bsTheme || null;
} }
static get LIGHT() { /** @returns {string|null} The theme stored on the client. */
return 'light'; static get #storedTheme() {
return localStorage.getItem(this.#storageKey);
}
/** @returns {string} The theme preferred by the operating system. */
static get #systemTheme() {
return this.#prefersDark ? this.Mode.DARK : this.Mode.LIGHT;
}
/** @returns {boolean} Whether the operating system prefers dark mode. */
static get #prefersDark() {
return this.#mediaDark.matches;
} }
/** /**
* @returns {string} Theme mode identifier * Applies a theme and optionally persists it as a user preference.
*/
static get ID() {
return 'theme-mode';
}
/**
* Gets the current visual state of the theme.
* *
* @returns {string} The current visual state, either the mode if it exists, * @param {'light'|'dark'} theme
* or the system dark mode state ('dark' or 'light'). * @param {{ persist?: boolean, domPersist?: boolean }} [options]
* - `persist`: Whether the theme is persisted in localStorage.
* - `domPersist`: Whether the theme is persisted in data attributes on the DOM.
*/ */
static get visualState() { static #apply(theme, { persist = false, domPersist = false } = {}) {
if (this.#hasMode) { this.#root.dataset.bsTheme = theme;
return this.#mode;
} else { if (persist) {
return this.#sysDark ? this.DARK : this.LIGHT; localStorage.setItem(this.#storageKey, theme);
}
if (domPersist || persist) {
this.#root.toggleAttribute('data-theme-persisted', true);
} }
} }
static get #mode() { /** Removes the stored user preference. */
return ( static #clearStorage() {
sessionStorage.getItem(this.#modeKey) || localStorage.removeItem(this.#storageKey);
document.documentElement.getAttribute(this.#modeAttr) this.#root.toggleAttribute('data-theme-persisted', false);
);
} }
static get #isDarkMode() { /** Broadcasts a theme change event to dependent modules. */
return this.#mode === this.DARK; static #notify() {
window.postMessage({ id: this.eventId }, '*');
} }
static get #hasMode() { /** @type {boolean} Whether the current page allows theme toggling. */
return this.#mode !== null; static isToggleable = this.#domTheme === null;
static eventId = 'theme-updated';
/** @returns {string} Resolved theme, falling back to the system preference. */
static get resolvedTheme() {
return this.#storedTheme || this.#systemTheme;
} }
static get #sysDark() { /** @returns {boolean} Whether the theme is determined by the system preference. */
return this.#darkMedia.matches; static get isSystemTheme() {
return this.#storedTheme === null;
}
/** @returns {boolean} Whether the resolved theme is dark. */
static get isDark() {
return this.resolvedTheme === this.Mode.DARK;
} }
/** /**
* Maps theme modes to provided values * Creates a mode-indexed value map.
* @param {string} light Value for light mode *
* @param {string} dark Value for dark mode * @template T
* @returns {Object} Mapped values * @param {T} light Value for light mode.
* @param {T} dark Value for dark mode.
* @returns {{ light: T, dark: T }}
*/ */
static getThemeMapper(light, dark) { static newThemeMap(light, dark) {
return { return {
[this.LIGHT]: light, [this.Mode.LIGHT]: light,
[this.DARK]: dark [this.Mode.DARK]: dark
}; };
} }
/** /** Initializes the theme from the stored value or system preference. */
* Initializes the theme based on system preferences or stored mode
*/
static init() { static init() {
if (!this.switchable) { if (!this.isToggleable) {
this.#clearStorage();
return; return;
} }
this.#darkMedia.addEventListener('change', () => { const storedTheme = this.#storedTheme;
const lastMode = this.#mode;
this.#clearMode();
if (lastMode !== this.visualState) { if (storedTheme) {
this.#notify(); this.#apply(storedTheme, { domPersist: true });
} else {
this.#apply(this.#systemTheme);
} }
this.#mediaDark.addEventListener('change', () => {
if (this.#storedTheme) {
return;
}
this.#apply(this.#systemTheme);
this.#notify();
}); });
if (!this.#hasMode) {
return;
}
if (this.#isDarkMode) {
this.#setDark();
} else {
this.#setLight();
}
} }
/** /**
* Flips the current theme mode * Updates the theme by the specified mode.
*
* @param {'light'|'dark'|'system'} mode
*/ */
static flip() { static update(mode) {
if (this.#hasMode) { const newTheme = mode === this.Mode.SYSTEM ? this.#systemTheme : mode;
this.#clearMode();
} else { if (newTheme !== this.resolvedTheme) {
this.#sysDark ? this.#setLight() : this.#setDark();
}
this.#notify(); this.#notify();
} }
static #setDark() { this.#apply(newTheme, { persist: mode !== this.Mode.SYSTEM });
document.documentElement.setAttribute(this.#modeAttr, this.DARK);
sessionStorage.setItem(this.#modeKey, this.DARK);
}
static #setLight() { if (mode === this.Mode.SYSTEM) {
document.documentElement.setAttribute(this.#modeAttr, this.LIGHT); this.#clearStorage();
sessionStorage.setItem(this.#modeKey, this.LIGHT);
} }
static #clearMode() {
document.documentElement.removeAttribute(this.#modeAttr);
sessionStorage.removeItem(this.#modeKey);
}
/**
* Notifies other plugins that the theme mode has changed
*/
static #notify() {
window.postMessage({ id: this.ID }, '*');
} }
} }
+6 -5
View File
@@ -8,12 +8,13 @@ layout: compress
{% include lang.html %} {% include lang.html %}
{% if site.theme_mode %}
{% capture prefer_mode %}data-mode="{{ site.theme_mode }}"{% endcapture %}
{% endif %}
<!-- `site.alt_lang` can specify a language different from the UI --> <!-- `site.alt_lang` can specify a language different from the UI -->
<html lang="{{ page.lang | default: site.alt_lang | default: site.lang }}" {{ prefer_mode }}> <html
lang="{{ page.lang | default: site.alt_lang | default: site.lang }}"
{%- if site.theme_mode == 'light' or site.theme_mode == 'dark' -%}
data-bs-theme="{{ site.theme_mode }}"
{%- endif -%}
>
{% include head.html lang=lang %} {% include head.html lang=lang %}
<body> <body>
+7 -4
View File
@@ -113,9 +113,7 @@ script_includes:
<dialog id="toc-popup" class="p-0"> <dialog id="toc-popup" class="p-0">
<div class="header d-flex flex-row align-items-center justify-content-between"> <div class="header d-flex flex-row align-items-center justify-content-between">
<div class="label text-truncate py-2 ms-4">{{- page.title -}}</div> <div class="label text-truncate py-2 ms-4">{{- page.title -}}</div>
<button id="toc-popup-close" type="button" class="btn mx-1 my-1 opacity-75"> <button id="toc-popup-close" type="button" class="btn-close btn-sm mx-3" aria-label="Close"></button>
<i class="fas fa-close"></i>
</button>
</div> </div>
<div id="toc-popup-content" class="px-4 py-3 pb-4"></div> <div id="toc-popup-content" class="px-4 py-3 pb-4"></div>
</dialog> </dialog>
@@ -126,9 +124,10 @@ script_includes:
</div> </div>
<div class="post-tail-wrapper text-muted"> <div class="post-tail-wrapper text-muted">
<div class="d-flex justify-content-between align-items-center gap-3 mb-3">
<!-- categories --> <!-- categories -->
{% if page.categories.size > 0 %} {% if page.categories.size > 0 %}
<div class="post-meta mb-3"> <div class="post-meta">
<i class="far fa-folder-open fa-fw me-1"></i> <i class="far fa-folder-open fa-fw me-1"></i>
{% for category in page.categories %} {% for category in page.categories %}
<a href="{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/">{{ category }}</a> <a href="{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/">{{ category }}</a>
@@ -137,6 +136,10 @@ script_includes:
</div> </div>
{% endif %} {% endif %}
<!-- "Edit this post" link -->
{% include post-edit.html lang=lang %}
</div>
<!-- tags --> <!-- tags -->
{% if page.tags.size > 0 %} {% if page.tags.size > 0 %}
<div class="post-tags"> <div class="post-tags">
+6
View File
@@ -1,3 +1,9 @@
@mixin color-scheme($mode) {
@media (prefers-color-scheme: #{$mode}) {
@content;
}
}
@mixin text-ellipsis { @mixin text-ellipsis {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
+6
View File
@@ -28,3 +28,9 @@ $code-icon-width: 1.75rem !default;
$font-family-base: 'Source Sans Pro', 'Microsoft Yahei', sans-serif !default; $font-family-base: 'Source Sans Pro', 'Microsoft Yahei', sans-serif !default;
$font-family-heading: Lato, 'Microsoft Yahei', sans-serif !default; $font-family-heading: Lato, 'Microsoft Yahei', sans-serif !default;
/* Theme mode settings */
$theme-attr: 'data-bs-theme'; /* the attribute used to indicate the resolved theme */
$theme-options: light, dark;
$theme: null !default; /* set by Jekyll site configuration */
+35 -27
View File
@@ -1,3 +1,4 @@
@use 'sass:list';
@use '../abstracts/variables' as v; @use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp; @use '../abstracts/breakpoints' as bp;
@use '../abstracts/mixins' as mx; @use '../abstracts/mixins' as mx;
@@ -5,32 +6,36 @@
@use '../themes/light'; @use '../themes/light';
@use '../themes/dark'; @use '../themes/dark';
$enable-dual: not list.index(v.$theme-options, v.$theme);
$enable-light: v.$theme == light or $enable-dual;
$enable-dark: v.$theme == dark or $enable-dual;
@if $enable-light {
:root[#{v.$theme-attr}='light'] {
@include light.styles;
}
}
@if $enable-dark {
:root[#{v.$theme-attr}='dark'] {
@include dark.styles;
}
}
@if $enable-dual {
:root:not([#{v.$theme-attr}]) {
@include mx.color-scheme(light) {
@include light.styles;
}
@include mx.color-scheme(dark) {
@include dark.styles;
}
}
}
:root { :root {
font-size: 16px; font-size: 16px;
}
html {
@media (prefers-color-scheme: light) {
&:not([data-mode]),
&[data-mode='light'] {
@include light.styles;
}
&[data-mode='dark'] {
@include dark.styles;
}
}
@media (prefers-color-scheme: dark) {
&:not([data-mode]),
&[data-mode='dark'] {
@include dark.styles;
}
&[data-mode='light'] {
@include light.styles;
}
}
@include bp.lg { @include bp.lg {
overflow-y: scroll; overflow-y: scroll;
@@ -369,7 +374,9 @@ main {
box-shadow: none; box-shadow: none;
border-color: var(--input-focus-border-color) !important; border-color: var(--input-focus-border-color) !important;
background: center !important; background: center !important;
transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; transition:
background-color 0.15s ease-in-out,
border-color 0.15s ease-in-out;
} }
.left { .left {
@@ -391,8 +398,9 @@ main {
/* MathJax */ /* MathJax */
mjx-container { mjx-container {
overflow-y: hidden; a {
min-width: auto !important; display: inline-block;
}
} }
@media (hover: hover) { @media (hover: hover) {
+4 -2
View File
@@ -219,8 +219,9 @@ div {
@extend %rounded; @extend %rounded;
border: 1px solid transparent; border: 1px solid transparent;
height: v.$code-header-height; height: 2rem;
width: v.$code-header-height; width: 2rem;
margin-right: 0.125rem;
padding: 0; padding: 0;
background-color: inherit; background-color: inherit;
@@ -234,6 +235,7 @@ div {
} }
i { i {
font-size: 90%;
color: var(--clipboard-checked-color); color: var(--clipboard-checked-color);
} }
} }
+17 -28
View File
@@ -7,49 +7,41 @@
@-webkit-keyframes popup { @-webkit-keyframes popup {
from { from {
opacity: 0; opacity: 0;
bottom: 0; bottom: 10%;
} }
} }
@keyframes popup { @keyframes popup {
from { from {
opacity: 0; opacity: 0;
bottom: 0; bottom: 10%;
}
}
.toast-header {
background: none;
border-bottom: none;
color: inherit;
}
.toast-body {
font-family: Lato, sans-serif;
line-height: 1.25rem;
button {
font-size: 90%;
min-width: 4rem;
} }
} }
&.toast { &.toast {
&.show { &.show {
display: block;
min-width: 20rem;
border-radius: 0.5rem;
-webkit-backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
background-color: rgb(255 255 255 / 50%);
color: #1b1b1eba;
position: fixed; position: fixed;
left: 50%; left: 50%;
bottom: 20%; bottom: 30%;
transform: translateX(-50%); transform: translateX(-50%);
-webkit-animation: popup 0.8s; -webkit-animation: popup 0.8s;
animation: popup 0.8s; animation: popup 0.8s;
} }
.toast-body {
line-height: 1.25rem;
font-family: v.$font-family-heading;
}
button[aria-label='Update'] {
font-size: 0.8rem;
}
.btn-close {
font-size: 0.625rem;
}
} }
} }
@@ -101,10 +93,7 @@
} }
button { button {
> i { font-size: 0.75rem;
font-size: 1.25rem;
vertical-align: middle;
}
&:focus-visible { &:focus-visible {
box-shadow: none; box-shadow: none;
+97 -9
View File
@@ -17,7 +17,6 @@ $sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
overflow-y: auto; overflow-y: auto;
width: v.$sidebar-width; width: v.$sidebar-width;
background: var(--sidebar-bg); background: var(--sidebar-bg);
border-right: 1px solid var(--sidebar-border-color);
/* Hide scrollbar for IE, Edge and Firefox */ /* Hide scrollbar for IE, Edge and Firefox */
-ms-overflow-style: none; /* IE and Edge */ -ms-overflow-style: none; /* IE and Edge */
@@ -76,11 +75,12 @@ $sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
} }
.profile-wrapper { .profile-wrapper {
@include mx.mt-mb(2.5rem);
@extend %clickable-transition; @extend %clickable-transition;
padding-left: 2.5rem; padding-left: 2.5rem;
padding-right: 1.25rem; padding-right: 1.25rem;
margin-top: 2.5rem;
margin-bottom: 1rem;
width: 100%; width: 100%;
@include bp.lg { @include bp.lg {
@@ -105,6 +105,8 @@ $sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
letter-spacing: 0.25px; letter-spacing: 0.25px;
margin-top: 1.25rem; margin-top: 1.25rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content; width: fit-content;
color: var(--site-title-color); color: var(--site-title-color);
} }
@@ -114,6 +116,7 @@ $sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
color: var(--site-subtitle-color); color: var(--site-subtitle-color);
margin-top: 0.25rem; margin-top: 0.25rem;
word-spacing: 1px; word-spacing: 1px;
height: 3rem;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
@@ -207,7 +210,7 @@ $sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
} }
} }
a { > a {
@extend %button; @extend %button;
@extend %sidebar-link-hover; @extend %sidebar-link-hover;
@extend %clickable-transition; @extend %clickable-transition;
@@ -227,13 +230,102 @@ $sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
#mode-toggle { #mode-toggle {
@extend %button; @extend %button;
@extend %sidebar-links;
@extend %sidebar-link-hover; @extend %sidebar-link-hover;
@extend %clickable-transition;
> i {
display: none;
@at-root :root[data-bs-theme='light'][data-theme-persisted]
&[data-theme-mode='light'] {
display: block;
}
@at-root :root[data-bs-theme='dark'][data-theme-persisted]
&[data-theme-mode='dark'] {
display: block;
}
@at-root :root:not([data-theme-persisted]) &[data-theme-mode='system'] {
display: block;
}
}
@-webkit-keyframes menu-pop {
from {
opacity: 0;
translate: 0 0.5rem;
}
to {
opacity: 1;
translate: 0 0;
}
}
@keyframes menu-pop {
from {
opacity: 0;
translate: 0 0.5rem;
}
to {
opacity: 1;
translate: 0 0;
}
}
+ .dropdown-menu {
background-color: var(--menu-bg);
border-color: var(--menu-border-color);
box-shadow: var(--menu-shadow-color) 0 1px 4px;
border-radius: 0.75rem !important;
&.show {
display: flex;
flex-direction: column;
gap: 0.25rem;
left: -0.25rem !important;
-webkit-animation: menu-pop 0.2s ease-out;
animation: menu-pop 0.2s ease-out;
}
.dropdown-item {
border-radius: 0.5rem;
color: var(--sidebar-muted-color);
font-size: 90%;
&.active {
font-weight: 600;
color: var(--menu-active-color);
&::after {
content: '\f00c';
font: var(--fa-font-solid);
font-size: 0.75rem;
color: var(--sidebar-btn-color);
margin-left: auto;
padding-left: 1rem;
}
}
&:active,
&:hover,
&.active {
background-color: var(--menu-highlight-bg);
}
> i {
color: var(--sidebar-btn-color);
margin-right: 0.5rem;
}
}
}
} }
.icon-border { .icon-border {
@extend %no-cursor; @extend %no-cursor;
@include mx.ml-mr(calc((v.$sb-btn-gap - $btn-border-width) / 2)); @include mx.ml-mr(0.6rem);
background-color: var(--sidebar-btn-color); background-color: var(--sidebar-btn-color);
content: ''; content: '';
@@ -241,10 +333,6 @@ $sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
height: $btn-border-width; height: $btn-border-width;
border-radius: 50%; border-radius: 50%;
margin-bottom: $btn-mb; margin-bottom: $btn-mb;
@include bp.xxxl {
@include mx.ml-mr(calc((v.$sb-btn-gap-lg - $btn-border-width) / 2));
}
} }
} /* .sidebar-bottom */ } /* .sidebar-bottom */
} /* #sidebar */ } /* #sidebar */
+10
View File
@@ -148,6 +148,16 @@ header {
} }
} }
.post-edit {
line-height: 1.2rem;
> a {
&:hover {
@extend %link-hover;
}
}
}
.post-navigation { .post-navigation {
@include bp.lt(bp.get(lg)) { @include bp.lt(bp.get(lg)) {
@include mx.pl-pr(0); @include mx.pl-pr(0);
+7 -2
View File
@@ -30,6 +30,11 @@
rgb(58 55 55 / 40%) 50%, rgb(58 55 55 / 40%) 50%,
rgb(255 255 255 / 0%) 100% rgb(255 255 255 / 0%) 100%
); );
--menu-bg: rgb(30 30 30);
--menu-border-color: rgb(77 77 77 / 60%);
--menu-shadow-color: rgb(4 4 4 / 42%);
--menu-active-color: rgb(240 248 255 / 63%);
--menu-highlight-bg: rgb(90 91 92 / 12%);
/* Sidebar */ /* Sidebar */
--site-title-color: #717070; --site-title-color: #717070;
@@ -67,8 +72,8 @@
--btn-share-hover-color: #bfc1ca; --btn-share-hover-color: #bfc1ca;
--card-bg: #1e1e1e; --card-bg: #1e1e1e;
--card-hover-bg: #464d51; --card-hover-bg: #464d51;
--card-shadow: rgb(21 21 21 / 72%) 0 6px 18px 0, --card-shadow:
rgb(137 135 135 / 24%) 0 0 0 1px; rgb(21 21 21 / 72%) 0 6px 18px 0, rgb(137 135 135 / 24%) 0 0 0 1px;
--kbd-wrap-color: #6a6a6a; --kbd-wrap-color: #6a6a6a;
--kbd-text-color: #d3d3d3; --kbd-text-color: #d3d3d3;
--kbd-bg-color: #242424; --kbd-bg-color: #242424;
+7 -2
View File
@@ -27,6 +27,11 @@
rgb(232 230 230 / 100%) 50%, rgb(232 230 230 / 100%) 50%,
rgb(250 250 250 / 0%) 100% rgb(250 250 250 / 0%) 100%
); );
--menu-bg: white;
--menu-border-color: white;
--menu-shadow-color: rgb(0 0 0 / 16%);
--menu-active-color: rgb(91 91 91);
--menu-highlight-bg: rgb(243 244 245 / 50%);
/* Sidebar */ /* Sidebar */
--site-title-color: rgb(113 113 113); --site-title-color: rgb(113 113 113);
@@ -59,8 +64,8 @@
--btn-share-hover-color: #0d6efd; --btn-share-hover-color: #0d6efd;
--card-bg: white; --card-bg: white;
--card-hover-bg: #e2e2e2; --card-hover-bg: #e2e2e2;
--card-shadow: rgb(104 104 104 / 5%) 0 2px 6px 0, --card-shadow:
rgb(211 209 209 / 15%) 0 0 0 1px; rgb(104 104 104 / 5%) 0 2px 6px 0, rgb(211 209 209 / 15%) 0 0 0 1px;
--footnote-target-bg: lightcyan; --footnote-target-bg: lightcyan;
--tb-odd-bg: #fbfcfd; --tb-odd-bg: #fbfcfd;
--tb-border-color: #eaeaea; --tb-border-color: #eaeaea;
+4
View File
@@ -1,6 +1,10 @@
--- ---
--- ---
@use 'abstracts/variables' with (
$theme: '{{ site.theme_mode }}'
);
/* prettier-ignore */ /* prettier-ignore */
@use 'main @use 'main
{%- if jekyll.environment == 'production' -%} {%- if jekyll.environment == 'production' -%}
+1 -1
View File
@@ -24,5 +24,5 @@ layout: compress
"start_url": "{{ '/index.html' | relative_url }}", "start_url": "{{ '/index.html' | relative_url }}",
"theme_color": "#2a1e6b", "theme_color": "#2a1e6b",
"background_color": "#ffffff", "background_color": "#ffffff",
"display": "fullscreen" "display": "standalone"
} }
+18
View File
@@ -1,5 +1,23 @@
# Changelog # Changelog
## [7.6.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.5.0...v7.6.0) (2026-06-20)
### Features
* add edit this post link ([#2517](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2517)) ([6bd446c](https://github.com/cotes2020/jekyll-theme-chirpy/commit/6bd446ccdedbe37752cf24b1866e1e2dd9cb82c8))
* **theme:** persist user theme preferences ([#2756](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2756)) ([7496dd4](https://github.com/cotes2020/jekyll-theme-chirpy/commit/7496dd41fa053c4636a82027fe3fb3e38357e385))
* **ui:** optimize design of PWA update notification ([#2757](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2757)) ([5cc9dc6](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5cc9dc66acb1eb9213988d3ac6de5cf5adf1a6f6))
### Bug Fixes
* **giscus:** synchronize theme state during lazy loading ([#2742](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2742)) ([ceb2a41](https://github.com/cotes2020/jekyll-theme-chirpy/commit/ceb2a41463cbb6251fa257b640990a8d9717b0bb))
* prevent Firefox from opening blank page on `mailto` links ([#2642](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2642)) ([2685b91](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2685b91957d0207c2d31dab828430c78a2fcc3d0))
* **pwa:** avoid iOS status bar overlapping PWA content ([#2173](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2173)) ([3823212](https://github.com/cotes2020/jekyll-theme-chirpy/commit/38232120b729de653bfb42909a8dad047559438d))
### Improvements
* **ui:** prevent vertical flickering caused by subtitle loading ([2db0535](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2db053553bcf9606fc80c4a86959d0dd25d0446a))
## [7.5.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.4.1...v7.5.0) (2026-03-15) ## [7.5.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.4.1...v7.5.0) (2026-03-15)
### Features ### Features
+1 -1
View File
@@ -2,7 +2,7 @@
Gem::Specification.new do |spec| Gem::Specification.new do |spec|
spec.name = "jekyll-theme-chirpy" spec.name = "jekyll-theme-chirpy"
spec.version = "7.5.0" spec.version = "7.6.0"
spec.authors = ["Cotes Chung"] spec.authors = ["Cotes Chung"]
spec.email = ["cotes.chung@gmail.com"] spec.email = ["cotes.chung@gmail.com"]
+14 -14
View File
@@ -1,6 +1,6 @@
{ {
"name": "jekyll-theme-chirpy", "name": "jekyll-theme-chirpy",
"version": "7.5.0", "version": "7.6.0",
"description": "A minimal, responsive, and feature-rich Jekyll theme for technical writing.", "description": "A minimal, responsive, and feature-rich Jekyll theme for technical writing.",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -30,28 +30,28 @@
"bootstrap": "^5.3.8" "bootstrap": "^5.3.8"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.29.0", "@babel/core": "^7.29.7",
"@babel/plugin-transform-class-properties": "^7.28.6", "@babel/plugin-transform-class-properties": "^7.28.6",
"@babel/plugin-transform-private-methods": "^7.28.6", "@babel/plugin-transform-private-methods": "^7.28.6",
"@babel/preset-env": "^7.29.0", "@babel/preset-env": "^7.29.7",
"@commitlint/cli": "^20.4.4", "@commitlint/cli": "^21.0.2",
"@commitlint/config-conventional": "^20.4.4", "@commitlint/config-conventional": "^21.0.2",
"@eslint/js": "^10.0.0", "@eslint/js": "^10.0.1",
"@rollup/plugin-babel": "^7.0.0", "@rollup/plugin-babel": "^7.1.0",
"@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-terser": "^1.0.0", "@rollup/plugin-terser": "^1.0.0",
"@semantic-release/changelog": "^6.0.3", "@semantic-release/changelog": "^6.0.3",
"@semantic-release/exec": "^7.1.0", "@semantic-release/exec": "^7.1.0",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"concurrently": "^9.2.1", "concurrently": "^10.0.3",
"conventional-changelog-conventionalcommits": "^9.3.0", "conventional-changelog-conventionalcommits": "^9.3.1",
"eslint": "^10.0.3", "eslint": "^10.5.0",
"globals": "^17.4.0", "globals": "^17.6.0",
"husky": "^9.1.7", "husky": "^9.1.7",
"purgecss": "^8.0.0", "purgecss": "^8.0.0",
"rollup": "^4.59.0", "rollup": "^4.62.2",
"semantic-release": "^25.0.3", "semantic-release": "^25.0.5",
"stylelint": "^17.4.0", "stylelint": "^17.13.0",
"stylelint-config-standard-scss": "^17.0.0" "stylelint-config-standard-scss": "^17.0.0"
}, },
"prettier": { "prettier": {