1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-18 21:53:26 +00:00

Compare commits

..

17 Commits

Author SHA1 Message Date
semantic-release-bot
7630356a94 chore(release): 7.2.1
## [7.2.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.2.0...v7.2.1) (2024-12-05)

### Bug Fixes

* **build:** exclude `purgecss.js` from output files ([#2090](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2090)) ([976e1a1](976e1a184b))
* correct the import condition for theme script ([#2075](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2075)) ([a16aa7d](a16aa7d41e))
* ensure pageviews are fetched after DOM is loaded ([#2071](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2071)) ([b4019f3](b4019f3517))
* **toc:** resume fade up animation in desktop mode ([#2085](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2085)) ([8280adb](8280adb901))
2024-12-05 13:33:44 +00:00
Cotes Chung
6c112c641a Merge branch 'master' into production 2024-12-05 21:32:17 +08:00
Cotes Chung
976e1a184b fix(build): exclude purgecss.js from output files (#2090) 2024-12-05 21:28:37 +08:00
Cotes Chung
7ea3545ba3 refactor: reduce the height of the TOC bottom overlay in desktop mode 2024-12-05 21:09:07 +08:00
Cotes Chung
8280adb901 fix(toc): resume fade up animation in desktop mode (#2085) 2024-12-03 22:41:28 +08:00
Cotes Chung
4180992272 style: add indentation to js code 2024-12-03 22:22:20 +08:00
Alexander Fuks
a16aa7d41e fix: correct the import condition for theme script (#2075) 2024-12-01 04:34:12 +08:00
Cotes Chung
8e55e4dcb2 build: correct the js rollup watch path (#2074)
1. Correct the rollup watch path
2. Avoid registering watch listeners redundantly across multiple tasks
2024-12-01 04:20:47 +08:00
Alexander Fuks
b4019f3517 fix: ensure pageviews are fetched after DOM is loaded (#2071) 2024-11-30 23:07:53 +03:00
semantic-release-bot
2966fc174d Merge branch 'production' 2024-11-28 08:59:03 +00:00
semantic-release-bot
3df83fd0d9 chore(release): 7.2.0
## [7.2.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.1.1...v7.2.0) (2024-11-28)

### Features

* show toc on mobile screens ([#1964](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1964)) ([8a064a5](8a064a5e5a))
* support vertical scrolling for toc in desktop mode ([#2064](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2064)) ([5265b03](5265b03974))

### Bug Fixes

* pagination error when pinned posts exceed the page size ([#1965](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1965)) ([93f616b](93f616b25d))

### Improvements

* modular sass architecture ([#2052](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2052)) ([35c794c](35c794cf58))
* speed up page rendering and jekyll build process ([#2034](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2034)) ([65f960c](65f960c31a))
2024-11-28 08:58:47 +00:00
Cotes Chung
82ba82e6da Merge branch 'master' into production 2024-11-28 16:56:02 +08:00
Cotes Chung
5265b03974 feat: support vertical scrolling for toc in desktop mode (#2064) 2024-11-28 05:40:57 +08:00
Cotes Chung
11647697bb build(deps): update dependencies version 2024-11-25 03:55:11 +08:00
Cotes Chung
5756b8fc26 build(deps-dev): upgrade dependencies
Close #2058
2024-11-25 00:19:56 +08:00
Cotes Chung
35c794cf58 perf: modular sass architecture (#2052)
- Modularized the Sass architecture to enhance code maintainability and reduce the output file size
- Replaced deprecated `@import` with `@use` / `@forward`
2024-11-25 00:05:28 +08:00
Cotes Chung
c69914effc ci: avoid repeated runs of stylelint (#2057) 2024-11-24 04:33:46 +08:00
58 changed files with 2690 additions and 2627 deletions

View File

@@ -1,25 +0,0 @@
name: Style Lint
on:
push:
branches:
- master
- "hotfix/*"
paths: ["_sass/**/*.scss"]
pull_request:
paths: ["_sass/**/*.scss"]
jobs:
stylelint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
- run: npm i
- run: npm test

2
.gitignore vendored
View File

@@ -23,5 +23,5 @@ package-lock.json
!.vscode/tasks.json
# Misc
_sass/dist
_sass/vendors
assets/js/dist

31
.stylelintrc.json Normal file
View File

@@ -0,0 +1,31 @@
{
"ignoreFiles": ["_sass/vendors/**"],
"extends": "stylelint-config-standard-scss",
"rules": {
"no-descending-specificity": null,
"shorthand-property-no-redundant-values": null,
"at-rule-no-vendor-prefix": null,
"property-no-vendor-prefix": null,
"selector-no-vendor-prefix": null,
"value-no-vendor-prefix": null,
"color-function-notation": "legacy",
"alpha-value-notation": "number",
"selector-not-notation": "simple",
"color-hex-length": "long",
"declaration-block-single-line-max-declarations": 3,
"scss/operator-no-newline-after": null,
"rule-empty-line-before": [
"always",
{
"ignore": ["after-comment", "first-nested"]
}
],
"value-keyword-case": [
"lower",
{
"ignoreProperties": ["/^\\$/"]
}
],
"media-feature-range-notation": "prefix"
}
}

View File

@@ -212,8 +212,8 @@ exclude:
- tools
- README.md
- LICENSE
- "*.config.js"
- package*.json
- "*.js"
- "package*.json"
jekyll-archives:
enabled: [categories, tags]

View File

@@ -20,17 +20,17 @@ webfonts: https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Sour
# Libraries
toc:
css: https://cdn.jsdelivr.net/npm/tocbot@4.29.0/dist/tocbot.min.css
js: https://cdn.jsdelivr.net/npm/tocbot@4.29.0/dist/tocbot.min.js
css: https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.css
js: https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.js
fontawesome:
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/all.min.css
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7.1/css/all.min.css
search:
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js
mermaid:
js: https://cdn.jsdelivr.net/npm/mermaid@11.0.2/dist/mermaid.min.js
js: https://cdn.jsdelivr.net/npm/mermaid@11.4.0/dist/mermaid.min.js
dayjs:
js:

View File

@@ -70,7 +70,7 @@
<!-- Bootstrap -->
{% unless jekyll.environment == 'production' %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
{% endunless %}
<!-- Theme style -->
@@ -99,9 +99,7 @@
<!-- Scripts -->
{% unless site.theme_mode %}
<script src="{{ '/assets/js/dist/theme.min.js' | relative_url }}"></script>
{% endunless %}
<script src="{{ '/assets/js/dist/theme.min.js' | relative_url }}"></script>
{% include js-selector.html lang=lang %}

View File

@@ -1,19 +1,21 @@
<!-- Display GoatCounter pageviews -->
<script>
let pv = document.getElementById('pageviews');
document.addEventListener('DOMContentLoaded', () => {
const pv = document.getElementById('pageviews');
if (pv !== null) {
const uri = location.pathname.replace(/\/$/, '');
const url = `https://{{ site.analytics.goatcounter.id }}.goatcounter.com/counter/${encodeURIComponent(uri)}.json`;
if (pv !== null) {
const uri = location.pathname.replace(/\/$/, '');
const url = `https://{{ site.analytics.goatcounter.id }}.goatcounter.com/counter/${encodeURIComponent(uri)}.json`;
fetch(url)
.then((response) => response.json())
.then((data) => {
const count = data.count.replace(/\s/g, '');
pv.innerText = new Intl.NumberFormat().format(count);
})
.catch((error) => {
pv.innerText = '1';
});
}
fetch(url)
.then((response) => response.json())
.then((data) => {
const count = data.count.replace(/\s/g, '');
pv.innerText = new Intl.NumberFormat().format(count);
})
.catch((error) => {
pv.innerText = '1';
});
}
});
</script>

View File

@@ -1,8 +1,9 @@
{% include toc-status.html %}
{% if enable_toc %}
<section id="toc-wrapper" class="ps-0 pe-4">
<h2 class="panel-heading ps-3 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
<div class="toc-border-cover z-3"></div>
<section id="toc-wrapper" class="invisible position-sticky ps-0 pe-4 pb-4">
<h2 class="panel-heading ps-3 pb-2 mb-0">{{- site.data.locales[include.lang].panel.toc -}}</h2>
<nav id="toc"></nav>
</section>
{% endif %}

View File

@@ -15,8 +15,11 @@ export class TocDesktop {
}
static init() {
if (document.getElementById('toc-wrapper')) {
const $tocWrapper = document.getElementById('toc-wrapper');
if ($tocWrapper) {
tocbot.init(this.options);
$tocWrapper.classList.remove('invisible');
}
}
}

View File

@@ -33,7 +33,7 @@ layout: compress
</main>
<!-- panel -->
<aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 mb-5 text-muted">
<aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 text-muted">
<div class="access">
{% include_cached update-list.html lang=lang %}
{% include_cached trending-tags.html lang=lang %}

View File

@@ -45,15 +45,12 @@ script_includes:
{%- capture lqip -%}lqip="{{ page.image.lqip }}"{%- endcapture -%}
{% endif %}
{% if page.image.show_image_in_post != false %}
<div class="mt-3 mb-3">
<img {{ src }} {{ class }} {{ alt }} w="1200" h="630" {{ lqip }}>
{%- if page.image.alt -%}
<figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
{%- endif -%}
</div>
{% endif %}
<div class="mt-3 mb-3">
<img {{ src }} {{ class }} {{ alt }} w="1200" h="630" {{ lqip }}>
{%- if page.image.alt -%}
<figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
{%- endif -%}
</div>
{% endif %}
<div class="d-flex justify-content-between">

View File

@@ -227,7 +227,6 @@ image:
```
Note that the [`media_subpath`](#url-prefix) can also be passed to the preview image, that is, when it has been set, the attribute `path` only needs the image file name.
Additionally, `image.show_image_in_post` can be added and set to `false` which will hide the image from being displayed at the top of the post. However, the image will still be displayed on the homepage next to the post and whenever sharing the post in social media. `image.show_image_in_post` is `true` by default.
For simple use, you can also just use `image` to define the path.

View File

@@ -93,8 +93,6 @@ Social contact options are displayed at the bottom of the sidebar. You can enabl
To customize the stylesheet, copy the theme's `assets/css/jekyll-theme-chirpy.scss`{: .filepath} file to the same path in your Jekyll site, and add your custom styles at the end of the file.
Starting with version `6.2.0`, if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`{: .filepath}, copy the main SASS file `_sass/main.scss`{: .filepath} to the `_sass`{: .filepath} directory in your site's source, then create a new file `_sass/variables-hook.scss`{: .filepath} and assign your new values there.
### Customizing Static Assets
Static assets configuration was introduced in version `5.1.0`. The CDN of the static assets is defined in `_data/origin/cors.yml`{: .filepath }. You can replace some of them based on the network conditions in the region where your website is published.

View File

@@ -0,0 +1,73 @@
@use 'sass:map';
$-breakpoints: (
// 1 column
sm: 576px,
md: 768px,
// 2 columns
lg: 850px,
// 3 columns
xl: 1200px,
xxl: 1400px,
xxxl: 1650px
);
@function get($breakpoint) {
@return map.get($-breakpoints, $breakpoint);
}
/* Less than the given width */
@mixin lt($width) {
@media all and (max-width: calc(#{$width} - 1px)) {
@content;
}
}
/* Less than or equal to the given width */
@mixin lte($width) {
@media all and (max-width: $width) {
@content;
}
}
@mixin sm {
@media all and (min-width: get(sm)) {
@content;
}
}
@mixin md {
@media all and (min-width: get(md)) {
@content;
}
}
@mixin lg {
@media all and (min-width: get(lg)) {
@content;
}
}
@mixin xl {
@media all and (min-width: get(xl)) {
@content;
}
}
@mixin xxl {
@media all and (min-width: get(xxl)) {
@content;
}
}
@mixin xxxl {
@media all and (min-width: get(xxxl)) {
@content;
}
}
@mixin between($min, $max) {
@media all and (min-width: $min) and (max-width: $max) {
@content;
}
}

View File

@@ -0,0 +1,4 @@
@forward 'variables';
@forward 'mixins';
@forward 'placeholders';
@forward 'breakpoints';

View File

@@ -0,0 +1,80 @@
@mixin text-ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@mixin mt-mb($value) {
margin-top: $value;
margin-bottom: $value;
}
@mixin ml-mr($value) {
margin-left: $value;
margin-right: $value;
}
@mixin pt-pb($val) {
padding-top: $val;
padding-bottom: $val;
}
@mixin pl-pr($val, $important: false) {
@if $important {
padding-left: $val !important;
padding-right: $val !important;
} @else {
padding-left: $val;
padding-right: $val;
}
}
@mixin placeholder {
color: var(--text-muted-color) !important;
}
@mixin placeholder-focus {
opacity: 0.6;
}
@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) {
color: $color;
font-size: $font-size;
font-weight: $font-weight;
}
@mixin align-center {
position: relative;
left: 50%;
transform: translateX(-50%);
}
@mixin prompt($type, $fa-content, $fa-style: 'solid', $rotate: 0) {
&.prompt-#{$type} {
background-color: var(--prompt-#{$type}-bg);
&::before {
content: $fa-content;
color: var(--prompt-#{$type}-icon-color);
font: var(--fa-font-#{$fa-style});
@if $rotate != 0 {
transform: rotate(#{$rotate}deg);
}
}
}
}
@mixin slide($append: null) {
$basic: transform 0.4s ease;
@if $append {
transition: $basic, $append;
} @else {
transition: $basic;
}
}
@mixin max-w-100 {
max-width: 100%;
}

View File

@@ -1,13 +1,10 @@
/*
* Mainly scss modules, only imported to `assets/css/main.scss`
*/
/* ---------- scss placeholder --------- */
@use 'variables' as v;
@use 'mixins' as mx;
%heading {
color: var(--heading-color);
font-weight: 400;
font-family: $font-family-heading;
font-family: v.$font-family-heading;
scroll-margin-top: 3.5rem;
}
@@ -82,7 +79,7 @@
}
%rounded {
border-radius: $radius-lg;
border-radius: v.$radius-lg;
}
%img-caption {
@@ -112,14 +109,8 @@
-webkit-box-orient: vertical;
}
@mixin text-ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
%text-ellipsis {
@include text-ellipsis;
@include mx.text-ellipsis;
}
%text-highlight {
@@ -151,65 +142,19 @@
}
}
/* ---------- scss mixin --------- */
@mixin mt-mb($value) {
margin-top: $value;
margin-bottom: $value;
%code-snippet-bg {
background-color: var(--highlight-bg-color);
}
@mixin ml-mr($value) {
margin-left: $value;
margin-right: $value;
%code-snippet-padding {
padding-left: 1rem;
padding-right: 1.5rem;
}
@mixin pt-pb($val) {
padding-top: $val;
padding-bottom: $val;
%max-w-100 {
max-width: 100%;
}
@mixin pl-pr($val, $important: false) {
@if $important {
padding-left: $val !important;
padding-right: $val !important;
} @else {
padding-left: $val;
padding-right: $val;
}
}
@mixin placeholder {
color: var(--text-muted-color) !important;
}
@mixin placeholder-focus {
opacity: 0.6;
}
@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) {
color: $color;
font-size: $font-size;
font-weight: $font-weight;
}
@mixin align-center {
position: relative;
left: 50%;
transform: translateX(-50%);
}
@mixin prompt($type, $fa-content, $fa-style: 'solid', $rotate: 0) {
&.prompt-#{$type} {
background-color: var(--prompt-#{$type}-bg);
&::before {
content: $fa-content;
color: var(--prompt-#{$type}-icon-color);
font: var(--fa-font-#{$fa-style});
@if $rotate != 0 {
transform: rotate(#{$rotate}deg);
}
}
}
%panel-border {
border-left: 1px solid var(--main-border-color);
}

View File

@@ -1,7 +1,3 @@
/*
* The SCSS variables
*/
/* sidebar */
$sidebar-width: 260px !default; /* the basic width */

File diff suppressed because it is too large Load Diff

476
_sass/base/_base.scss Normal file
View File

@@ -0,0 +1,476 @@
@use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
@use '../themes/light';
@use '../themes/dark';
:root {
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 {
overflow-y: scroll;
}
}
body {
background: var(--main-bg);
padding: env(safe-area-inset-top) env(safe-area-inset-right)
env(safe-area-inset-bottom) env(safe-area-inset-left);
color: var(--text-color);
-webkit-font-smoothing: antialiased;
font-family: v.$font-family-base;
}
h1.dynamic-title {
@include bp.lt(bp.get(lg)) {
display: none;
~ .content {
margin-top: 2.5rem;
}
}
}
main {
&.col-12 {
@include bp.xxxl {
padding-right: 4.5rem !important;
}
}
}
.preview-img {
aspect-ratio: 40 / 21;
width: 100%;
height: 100%;
overflow: hidden;
@extend %rounded;
&:not(.no-bg) {
background: var(--img-bg);
}
img {
height: 100%;
-o-object-fit: cover;
object-fit: cover;
@extend %rounded;
@at-root #post-list & {
width: 100%;
}
}
}
.post-preview {
@extend %rounded;
border: 0;
background: var(--card-bg);
box-shadow: var(--card-shadow);
&::before {
@extend %rounded;
content: '';
width: 100%;
height: 100%;
position: absolute;
background-color: var(--card-hovor-bg);
opacity: 0;
transition: opacity 0.35s ease-in-out;
}
&:hover {
&::before {
opacity: 0.3;
}
}
}
.post-meta {
@extend %text-sm;
a {
&:not([class]):hover {
@extend %link-hover;
}
}
em {
@extend %normal-font-style;
}
}
.content {
font-size: 1.08rem;
margin-top: 2rem;
overflow-wrap: break-word;
@include bp.xl {
font-size: 1.03rem;
}
a {
&.popup {
@extend %no-cursor;
@extend %img-caption;
@include mx.mt-mb(0.5rem);
cursor: zoom-in;
}
&:not(.img-link) {
@extend %link-underline;
&:hover {
@extend %link-hover;
}
}
}
ol,
ul {
&:not([class]),
&.task-list {
-webkit-padding-start: 1.75rem;
padding-inline-start: 1.75rem;
li {
margin: 0.25rem 0;
padding-left: 0.25rem;
}
ol,
ul {
-webkit-padding-start: 1.25rem;
padding-inline-start: 1.25rem;
margin: 0.5rem 0;
}
}
}
ul.task-list {
-webkit-padding-start: 1.25rem;
padding-inline-start: 1.25rem;
li {
list-style-type: none;
padding-left: 0;
/* checkbox icon */
> i {
width: 2rem;
margin-left: -1.25rem;
color: var(--checkbox-color);
&.checked {
color: var(--checkbox-checked-color);
}
}
ul {
-webkit-padding-start: 1.75rem;
padding-inline-start: 1.75rem;
}
}
input[type='checkbox'] {
margin: 0 0.5rem 0.2rem -1.3rem;
vertical-align: middle;
}
} /* ul */
dl > dd {
margin-left: 1rem;
}
::marker {
color: var(--text-muted-color);
}
.table-wrapper > table {
@include bp.lg {
min-width: 70%;
}
}
} /* .content */
.tag:hover {
@extend %tag-hover;
}
.post-tag {
display: inline-block;
min-width: 2rem;
text-align: center;
border-radius: 0.5rem;
border: 1px solid var(--btn-border-color);
padding: 0 0.4rem;
color: var(--text-muted-color);
line-height: 1.3rem;
&:not(:last-child) {
margin-right: 0.2rem;
}
}
.rounded-10 {
border-radius: 10px !important;
}
.img-link {
color: transparent;
display: inline-flex;
}
.shimmer {
overflow: hidden;
position: relative;
background: var(--img-bg);
&::before {
content: '';
position: absolute;
background: var(--shimmer-bg);
height: 100%;
width: 100%;
-webkit-animation: shimmer 1.3s infinite;
animation: shimmer 1.3s infinite;
}
@-webkit-keyframes shimmer {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
@keyframes shimmer {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
}
.embed-video {
width: 100%;
height: 100%;
margin-bottom: 1rem;
aspect-ratio: 16 / 9;
@extend %rounded;
&.twitch {
aspect-ratio: 310 / 189;
}
&.file {
display: block;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
margin: auto;
margin-bottom: 0;
}
@extend %img-caption;
}
.embed-audio {
width: 100%;
display: block;
@extend %img-caption;
}
/* --- Effects classes --- */
.flex-grow-1 {
flex-grow: 1 !important;
}
.btn-box-shadow {
box-shadow: var(--card-shadow);
}
/* overwrite bootstrap muted */
.text-muted {
color: var(--text-muted-color) !important;
}
/* Overwrite bootstrap tooltip */
.tooltip-inner {
font-size: 0.7rem;
max-width: 220px;
text-align: left;
}
/* Overwrite bootstrap outline button */
.btn.btn-outline-primary {
&:not(.disabled):hover {
border-color: #007bff !important;
}
}
.disabled {
color: rgb(206, 196, 196);
pointer-events: auto;
cursor: not-allowed;
}
.hide-border-bottom {
border-bottom: none !important;
}
.input-focus {
box-shadow: none;
border-color: var(--input-focus-border-color) !important;
background: center !important;
transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
}
.left {
float: left;
margin: 0.75rem 1rem 1rem 0;
}
.right {
float: right;
margin: 0.75rem 0 1rem 1rem;
}
/* --- Overriding --- */
/* mermaid */
.mermaid {
text-align: center;
}
/* MathJax */
mjx-container {
overflow-y: hidden;
min-width: auto !important;
}
@media (hover: hover) {
#sidebar ul > li:last-child::after {
transition: top 0.5s ease;
}
.nav-link {
transition: background-color 0.3s ease-in-out;
}
.post-preview {
transition: background-color 0.35s ease-in-out;
}
}
#mask {
inset: 0 0 0 0;
}
#main-wrapper {
position: relative;
@include mx.pl-pr(0);
@include bp.lt(bp.get(lg)) {
@include mx.slide;
}
@include bp.lg {
margin-left: v.$sidebar-width;
}
@include bp.xxxl {
margin-left: v.$sidebar-width-large;
}
> .container {
min-height: 100vh;
@include bp.lte(bp.get(md)) {
@include mx.max-w-100;
@include mx.pl-pr(0);
}
@include bp.lt(bp.get(lg)) {
max-width: 100%;
}
/* Pad horizontal */
@include bp.between(992px, calc(#{bp.get(xl)} - 1px)) {
.col-lg-11 {
flex: 0 0 96%;
max-width: 96%;
}
}
@include bp.lt(bp.get(xl)) {
> .row {
justify-content: center !important;
}
}
@include bp.xxxl {
max-width: v.$main-content-max-width;
@include mx.pl-pr(1.75rem, true);
}
}
}
/* --- basic wrappers --- */
#topbar-wrapper.row,
#main-wrapper > .container > .row,
#search-result-wrapper > .row {
@include mx.ml-mr(0);
}
#tail-wrapper {
@include bp.xxxl {
padding-right: 4.5rem !important;
}
> :not(script) {
margin-top: 3rem;
}
}

4
_sass/base/_index.scss Normal file
View File

@@ -0,0 +1,4 @@
@forward 'reset';
@forward 'base';
@forward 'typography';
@forward 'syntax';

41
_sass/base/_reset.scss Normal file
View File

@@ -0,0 +1,41 @@
@use '../abstracts/mixins' as *;
::-webkit-input-placeholder {
@include placeholder;
}
::-moz-placeholder {
@include placeholder;
}
:-ms-input-placeholder {
@include placeholder;
}
::-ms-input-placeholder {
@include placeholder;
}
::placeholder {
@include placeholder;
}
:focus::-webkit-input-placeholder {
@include placeholder-focus;
}
:focus::-moz-placeholder {
@include placeholder-focus;
}
:focus:-ms-input-placeholder {
@include placeholder-focus;
}
:focus::-ms-input-placeholder {
@include placeholder-focus;
}
:focus::placeholder {
@include placeholder-focus;
}

View File

@@ -1,44 +1,7 @@
/*
* The syntax highlight.
*/
@import 'colors/syntax-light';
@import 'colors/syntax-dark';
html {
@media (prefers-color-scheme: light) {
&:not([data-mode]),
&[data-mode='light'] {
@include light-syntax;
}
&[data-mode='dark'] {
@include dark-syntax;
}
}
@media (prefers-color-scheme: dark) {
&:not([data-mode]),
&[data-mode='dark'] {
@include dark-syntax;
}
&[data-mode='light'] {
@include light-syntax;
}
}
}
/* -- code snippets -- */
%code-snippet-bg {
background-color: var(--highlight-bg-color);
}
%code-snippet-padding {
padding-left: 1rem;
padding-right: 1.5rem;
}
@use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
.highlighter-rouge {
color: var(--highlighter-rouge-color);
@@ -59,7 +22,7 @@ html {
pre {
margin-bottom: 0;
font-size: $code-font-size;
font-size: v.$code-font-size;
line-height: 1.4rem;
word-wrap: normal; /* Fixed Safari overflow-x */
}
@@ -101,10 +64,10 @@ code {
color: var(--code-color);
&.highlighter-rouge {
font-size: $code-font-size;
font-size: v.$code-font-size;
padding: 3px 5px;
word-break: break-word;
border-radius: $radius-sm;
border-radius: v.$radius-sm;
background-color: var(--inline-code-bg);
}
@@ -150,9 +113,42 @@ div[class^='language-'] {
box-shadow: var(--language-border-color) 0 0 0 1px;
.content > & {
@include ml-mr(-1rem);
@include mx.ml-mr(-1rem);
border-radius: 0;
@include bp.sm {
@include mx.ml-mr(0);
border-radius: v.$radius-lg;
}
}
.code-header {
@include bp.sm {
@include mx.ml-mr(0);
$dot-margin: 1rem;
&::before {
content: '';
display: inline-block;
margin-left: $dot-margin;
width: v.$code-dot-size;
height: v.$code-dot-size;
border-radius: 50%;
background-color: var(--code-header-muted-color);
box-shadow: (v.$code-dot-size + v.$code-dot-gap) 0 0
var(--code-header-muted-color),
(v.$code-dot-size + v.$code-dot-gap) * 2 0 0
var(--code-header-muted-color);
}
span {
// center the text of label
margin-left: calc(($dot-margin + v.$code-dot-size) / 2 * -1);
}
}
}
.highlight {
@@ -184,18 +180,18 @@ div {
display: flex;
justify-content: space-between;
align-items: center;
height: $code-header-height;
height: v.$code-header-height;
margin-left: 0.75rem;
margin-right: 0.25rem;
/* the label block */
span {
line-height: $code-header-height;
line-height: v.$code-header-height;
/* label icon */
i {
font-size: 1rem;
width: $code-icon-width;
width: v.$code-icon-width;
color: var(--code-header-icon-color);
&.small {
@@ -223,8 +219,8 @@ div {
@extend %rounded;
border: 1px solid transparent;
height: $code-header-height;
width: $code-header-height;
height: v.$code-header-height;
width: v.$code-header-height;
padding: 0;
background-color: inherit;
@@ -255,38 +251,3 @@ div {
}
}
}
@media all and (min-width: 576px) {
div[class^='language-'] {
.content > & {
@include ml-mr(0);
border-radius: $radius-lg;
}
.code-header {
@include ml-mr(0);
$dot-margin: 1rem;
&::before {
content: '';
display: inline-block;
margin-left: $dot-margin;
width: $code-dot-size;
height: $code-dot-size;
border-radius: 50%;
background-color: var(--code-header-muted-color);
box-shadow: ($code-dot-size + $code-dot-gap) 0 0
var(--code-header-muted-color),
($code-dot-size + $code-dot-gap) * 2 0 0
var(--code-header-muted-color);
}
span {
// center the text of label
margin-left: calc(($dot-margin + $code-dot-size) / 2 * -1);
}
}
}
}

266
_sass/base/_typography.scss Normal file
View File

@@ -0,0 +1,266 @@
@use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
@for $i from 1 through 5 {
h#{$i} {
@extend %heading;
@if $i > 1 {
@extend %anchor;
}
@if $i < 5 {
$size-factor: 0.25rem;
@if $i > 1 {
$size-factor: 0.18rem;
main & {
@if $i == 2 {
margin: 2.5rem 0 1.25rem;
} @else {
margin: 2rem 0 1rem;
}
}
}
& {
font-size: 1rem + (5 - $i) * $size-factor;
}
} @else {
font-size: 1.05rem;
}
}
}
a {
@extend %link-color;
text-decoration: none;
}
img {
max-width: 100%;
height: auto;
transition: all 0.35s ease-in-out;
.blur & {
$blur: 20px;
-webkit-filter: blur($blur);
filter: blur($blur);
}
}
blockquote {
border-left: 0.125rem solid var(--blockquote-border-color);
padding-left: 1rem;
color: var(--blockquote-text-color);
margin-top: 0.5rem;
> p:last-child {
margin-bottom: 0;
}
&[class^='prompt-'] {
border-left: 0;
position: relative;
padding: 1rem 1rem 1rem 3rem;
color: var(--prompt-text-color);
@extend %rounded;
&::before {
text-align: center;
width: 3rem;
position: absolute;
left: 0.25rem;
margin-top: 0.4rem;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
}
@include mx.prompt('tip', '\f0eb', $fa-style: 'regular');
@include mx.prompt('info', '\f06a', $rotate: 180);
@include mx.prompt('warning', '\f06a');
@include mx.prompt('danger', '\f071');
}
kbd {
font-family: Lato, sans-serif;
display: inline-block;
vertical-align: middle;
line-height: 1.3rem;
min-width: 1.75rem;
text-align: center;
margin: 0 0.3rem;
padding-top: 0.1rem;
color: var(--kbd-text-color);
background-color: var(--kbd-bg-color);
border-radius: v.$radius-sm;
border: solid 1px var(--kbd-wrap-color);
box-shadow: inset 0 -2px 0 var(--kbd-wrap-color);
}
hr {
border-color: var(--main-border-color);
opacity: 1;
}
footer {
background-color: var(--main-bg);
height: v.$footer-height;
border-top: 1px solid var(--main-border-color);
@extend %text-xs;
a {
@extend %text-highlight;
&:hover {
@extend %link-hover;
}
}
em {
@extend %text-highlight;
}
p {
text-align: center;
margin-bottom: 0;
}
}
/* fontawesome icons */
i {
&.far,
&.fas {
@extend %no-cursor;
}
}
sup {
@extend %sup-fn-target;
}
main {
line-height: 1.75;
h1 {
margin-top: 2rem;
@include bp.lg {
margin-top: 3rem;
}
}
p {
> a.popup {
&:not(.normal):not(.left):not(.right) {
@include mx.align-center;
}
}
}
.categories,
#tags,
#archives {
a:not(:hover) {
@extend %no-bottom-border;
}
}
@include bp.lte(bp.get(sm)) {
.content {
> blockquote[class^='prompt-'] {
@include mx.ml-mr(-1rem);
border-radius: 0;
max-width: none;
}
}
}
}
.footnotes > ol {
padding-left: 2rem;
margin-top: 0.5rem;
> li {
&:not(:last-child) {
margin-bottom: 0.3rem;
}
@extend %sup-fn-target;
> p {
margin-left: 0.25em;
@include mx.mt-mb(0);
}
}
}
.footnote {
@at-root a#{&} {
@include mx.ml-mr(1px);
@include mx.pl-pr(2px);
border-bottom-style: none !important;
}
}
.reversefootnote {
@at-root a#{&} {
font-size: 0.6rem;
line-height: 1;
position: relative;
bottom: 0.25em;
margin-left: 0.25em;
border-bottom-style: none !important;
}
}
/* --- Begin of Markdown table style --- */
/* it will be created by Liquid */
.table-wrapper {
overflow-x: auto;
margin-bottom: 1.5rem;
> table {
min-width: 100%;
overflow-x: auto;
border-spacing: 0;
thead {
border-bottom: solid 2px rgba(210, 215, 217, 0.75);
th {
@extend %table-cell;
}
}
tbody {
tr {
border-bottom: 1px solid var(--tb-border-color);
&:nth-child(2n) {
background-color: var(--tb-even-bg);
}
&:nth-child(2n + 1) {
background-color: var(--tb-odd-bg);
}
td {
@extend %table-cell;
}
}
} /* tbody */
} /* table */
}

View File

@@ -1,164 +0,0 @@
/*
* The syntax dark mode styles.
*/
@mixin dark-syntax {
--language-border-color: #2d2d2d;
--highlight-bg-color: #151515;
--highlighter-rouge-color: #c9def1;
--highlight-lineno-color: #808080;
--inline-code-bg: rgba(255, 255, 255, 0.05);
--code-color: #b0b0b0;
--code-header-text-color: #6a6a6a;
--code-header-muted-color: #353535;
--code-header-icon-color: #565656;
--clipboard-checked-color: #2bcc2b;
--filepath-text-color: #cacaca;
.highlight .gp {
color: #87939d;
}
/* --- Syntax highlight theme from `rougify style base16.dark` --- */
.highlight table td {
padding: 5px;
}
.highlight table pre {
margin: 0;
}
.highlight,
.highlight .w {
color: #d0d0d0;
background-color: #151515;
}
.highlight .err {
color: #151515;
background-color: #ac4142;
}
.highlight .c,
.highlight .ch,
.highlight .cd,
.highlight .cm,
.highlight .cpf,
.highlight .c1,
.highlight .cs {
color: #848484;
}
.highlight .cp {
color: #f4bf75;
}
.highlight .nt {
color: #f4bf75;
}
.highlight .o,
.highlight .ow {
color: #d0d0d0;
}
.highlight .p,
.highlight .pi {
color: #d0d0d0;
}
.highlight .gi {
color: #90a959;
}
.highlight .gd {
color: #f08a8b;
background-color: #320000;
}
.highlight .gh {
color: #6a9fb5;
background-color: #151515;
font-weight: bold;
}
.highlight .k,
.highlight .kn,
.highlight .kp,
.highlight .kr,
.highlight .kv {
color: #aa759f;
}
.highlight .kc {
color: #d28445;
}
.highlight .kt {
color: #d28445;
}
.highlight .kd {
color: #d28445;
}
.highlight .s,
.highlight .sb,
.highlight .sc,
.highlight .dl,
.highlight .sd,
.highlight .s2,
.highlight .sh,
.highlight .sx,
.highlight .s1 {
color: #90a959;
}
.highlight .sa {
color: #aa759f;
}
.highlight .sr {
color: #75b5aa;
}
.highlight .si {
color: #b76d45;
}
.highlight .se {
color: #b76d45;
}
.highlight .nn {
color: #f4bf75;
}
.highlight .nc {
color: #f4bf75;
}
.highlight .no {
color: #f4bf75;
}
.highlight .na {
color: #6a9fb5;
}
.highlight .m,
.highlight .mb,
.highlight .mf,
.highlight .mh,
.highlight .mi,
.highlight .il,
.highlight .mo,
.highlight .mx {
color: #90a959;
}
.highlight .ss {
color: #90a959;
}
}

View File

@@ -1,210 +0,0 @@
/*
* The syntax light mode code snippet colors.
*/
@mixin light-syntax {
/* --- custom light colors --- */
--language-border-color: #ececec;
--highlight-bg-color: #f6f8fa;
--highlighter-rouge-color: #3f596f;
--highlight-lineno-color: #9e9e9e;
--inline-code-bg: rgba(25, 25, 28, 0.05);
--code-color: #3a3a3a;
--code-header-text-color: #a3a3a3;
--code-header-muted-color: #e5e5e5;
--code-header-icon-color: #c9c8c8;
--clipboard-checked-color: #43c743;
/* --- Syntax highlight theme from `rougify style github` --- */
.highlight table td {
padding: 5px;
}
.highlight table pre {
margin: 0;
}
.highlight,
.highlight .w {
color: #24292f;
background-color: #f6f8fa;
}
.highlight .k,
.highlight .kd,
.highlight .kn,
.highlight .kp,
.highlight .kr,
.highlight .kt,
.highlight .kv {
color: #cf222e;
}
.highlight .gr {
color: #f6f8fa;
}
.highlight .gd {
color: #82071e;
background-color: #ffebe9;
}
.highlight .nb {
color: #953800;
}
.highlight .nc {
color: #953800;
}
.highlight .no {
color: #953800;
}
.highlight .nn {
color: #953800;
}
.highlight .sr {
color: #116329;
}
.highlight .na {
color: #116329;
}
.highlight .nt {
color: #116329;
}
.highlight .gi {
color: #116329;
background-color: #dafbe1;
}
.highlight .kc {
color: #0550ae;
}
.highlight .l,
.highlight .ld,
.highlight .m,
.highlight .mb,
.highlight .mf,
.highlight .mh,
.highlight .mi,
.highlight .il,
.highlight .mo,
.highlight .mx {
color: #0550ae;
}
.highlight .sb {
color: #0550ae;
}
.highlight .bp {
color: #0550ae;
}
.highlight .ne {
color: #0550ae;
}
.highlight .nl {
color: #0550ae;
}
.highlight .py {
color: #0550ae;
}
.highlight .nv,
.highlight .vc,
.highlight .vg,
.highlight .vi,
.highlight .vm {
color: #0550ae;
}
.highlight .o,
.highlight .ow {
color: #0550ae;
}
.highlight .gh {
color: #0550ae;
font-weight: bold;
}
.highlight .gu {
color: #0550ae;
font-weight: bold;
}
.highlight .s,
.highlight .sa,
.highlight .sc,
.highlight .dl,
.highlight .sd,
.highlight .s2,
.highlight .se,
.highlight .sh,
.highlight .sx,
.highlight .s1,
.highlight .ss {
color: #0a3069;
}
.highlight .nd {
color: #8250df;
}
.highlight .nf,
.highlight .fm {
color: #8250df;
}
.highlight .err {
color: #f6f8fa;
background-color: #82071e;
}
.highlight .c,
.highlight .ch,
.highlight .cd,
.highlight .cm,
.highlight .cp,
.highlight .cpf,
.highlight .c1,
.highlight .cs {
color: #68717a;
}
.highlight .gl {
color: #68717a;
}
.highlight .gt {
color: #68717a;
}
.highlight .ni {
color: #24292f;
}
.highlight .si {
color: #24292f;
}
.highlight .ge {
color: #24292f;
font-style: italic;
}
.highlight .gs {
color: #24292f;
font-weight: bold;
}
} /* light-syntax */

View File

@@ -1,112 +0,0 @@
/*
* The syntax light mode typography colors
*/
@mixin light-scheme {
/* Framework color */
--main-bg: white;
--mask-bg: #c1c3c5;
--main-border-color: #f3f3f3;
/* Common color */
--text-color: #34343c;
--text-muted-color: #757575;
--text-muted-highlight-color: inherit;
--heading-color: #2a2a2a;
--label-color: #585858;
--blockquote-border-color: #eeeeee;
--blockquote-text-color: #757575;
--link-color: #0056b2;
--link-underline-color: #dee2e6;
--button-bg: #ffffff;
--btn-border-color: #e9ecef;
--btn-backtotop-color: #686868;
--btn-backtotop-border-color: #f1f1f1;
--checkbox-color: #c5c5c5;
--checkbox-checked-color: #07a8f7;
--img-bg: radial-gradient(
circle,
rgb(255, 255, 255) 0%,
rgb(239, 239, 239) 100%
);
--shimmer-bg: linear-gradient(
90deg,
rgba(250, 250, 250, 0) 0%,
rgba(232, 230, 230, 1) 50%,
rgba(250, 250, 250, 0) 100%
);
/* Sidebar */
--site-title-color: rgb(113, 113, 113);
--site-subtitle-color: #717171;
--sidebar-bg: #f6f8fa;
--sidebar-border-color: #efefef;
--sidebar-muted-color: #545454;
--sidebar-active-color: #1d1d1d;
--sidebar-hover-bg: rgb(223, 233, 241, 0.64);
--sidebar-btn-bg: white;
--sidebar-btn-color: #8e8e8e;
--avatar-border-color: white;
/* Topbar */
--topbar-bg: rgb(255, 255, 255, 0.7);
--topbar-text-color: rgb(78, 78, 78);
--search-border-color: rgb(240, 240, 240);
--search-icon-color: #c2c6cc;
--input-focus-border-color: #b8b8b8;
/* Home page */
--post-list-text-color: dimgray;
--btn-patinator-text-color: #555555;
--btn-paginator-hover-color: var(--sidebar-bg);
/* Posts */
--toc-highlight: #0550ae;
--toc-popup-border-color: lightgray;
--btn-share-color: gray;
--btn-share-hover-color: #0d6efd;
--card-bg: white;
--card-hovor-bg: #e2e2e2;
--card-shadow: rgb(104, 104, 104, 0.05) 0 2px 6px 0,
rgba(211, 209, 209, 0.15) 0 0 0 1px;
--footnote-target-bg: lightcyan;
--tb-odd-bg: #fbfcfd;
--tb-border-color: #eaeaea;
--dash-color: silver;
--kbd-wrap-color: #bdbdbd;
--kbd-text-color: var(--text-color);
--kbd-bg-color: white;
--prompt-text-color: rgb(46, 46, 46, 0.77);
--prompt-tip-bg: rgb(123, 247, 144, 0.2);
--prompt-tip-icon-color: #03b303;
--prompt-info-bg: #e1f5fe;
--prompt-info-icon-color: #0070cb;
--prompt-warning-bg: rgb(255, 243, 205);
--prompt-warning-icon-color: #ef9c03;
--prompt-danger-bg: rgb(248, 215, 218, 0.56);
--prompt-danger-icon-color: #df3c30;
/* Tags */
--tag-border: #dee2e6;
--tag-shadow: var(--btn-border-color);
--tag-hover: rgb(222, 226, 230);
--search-tag-bg: #f8f9fa;
/* Categories */
--categories-border: rgba(0, 0, 0, 0.125);
--categories-hover-bg: var(--btn-border-color);
--categories-icon-hover-color: darkslategray;
/* Archive */
--timeline-color: rgba(0, 0, 0, 0.075);
--timeline-node-bg: #c2c6cc;
--timeline-year-dot-color: #ffffff;
[class^='prompt-'] {
--link-underline-color: rgb(219, 216, 216);
}
.dark {
display: none;
}
} /* light-scheme */

View File

@@ -0,0 +1,51 @@
@use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp;
#back-to-top {
visibility: hidden;
opacity: 0;
z-index: 1;
cursor: pointer;
position: fixed;
right: 1rem;
bottom: calc(v.$footer-height-large - v.$back2top-size / 2);
background: var(--button-bg);
color: var(--btn-backtotop-color);
padding: 0;
width: v.$back2top-size;
height: v.$back2top-size;
border-radius: 50%;
border: 1px solid var(--btn-backtotop-border-color);
transition: opacity 0.5s ease-in-out, transform 0.2s ease-out;
@include bp.lg {
right: 5%;
bottom: calc(v.$footer-height - v.$back2top-size / 2);
}
@include bp.xxl {
right: calc((100vw - v.$sidebar-width - 1140px) / 2 + 3rem);
}
@include bp.xxxl {
right: calc(
(100vw - v.$sidebar-width-large - v.$main-content-max-width) / 2 + 2rem
);
}
&:hover {
transform: translate3d(0, -5px, 0);
-webkit-transform: translate3d(0, -5px, 0);
}
i {
line-height: v.$back2top-size;
position: relative;
bottom: 2px;
}
&.show {
opacity: 1;
visibility: visible;
}
}

View File

@@ -0,0 +1,2 @@
@forward 'buttons';
@forward 'popups';

View File

@@ -0,0 +1,172 @@
@use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/placeholders';
/* PWA update popup */
#notification {
@-webkit-keyframes popup {
from {
opacity: 0;
bottom: 0;
}
}
@keyframes popup {
from {
opacity: 0;
bottom: 0;
}
}
.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 {
&.show {
display: block;
min-width: 20rem;
border-radius: 0.5rem;
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
background-color: rgba(255, 255, 255, 0.5);
color: #1b1b1eba;
position: fixed;
left: 50%;
bottom: 20%;
transform: translateX(-50%);
-webkit-animation: popup 0.8s;
animation: popup 0.8s;
}
}
}
#toc-popup {
$slide-in: slide-in 0.3s ease-out;
$slide-out: slide-out 0.3s ease-out;
$curtain-height: 2rem;
$backdrop: blur(5px);
border-color: var(--toc-popup-border-color);
border-width: 1px;
border-radius: v.$radius-lg;
color: var(--text-color);
background: var(--card-bg);
margin-top: v.$topbar-height;
min-width: 20rem;
font-size: 1.05rem;
@include bp.sm {
max-width: 32rem;
}
&[open] {
-webkit-animation: $slide-in;
animation: $slide-in;
}
&[closing] {
-webkit-animation: $slide-out;
animation: $slide-out;
}
@include bp.lg {
left: v.$sidebar-width;
}
.header {
@extend %btn-color;
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: inherit;
border-bottom: 1px solid var(--main-border-color);
.label {
font-family: v.$font-family-heading;
}
}
button {
> i {
font-size: 1.25rem;
vertical-align: middle;
}
&:focus-visible {
box-shadow: none;
}
}
ul {
list-style-type: none;
padding-left: 0;
li {
ul,
& + li {
margin-top: 0.25rem;
}
a {
display: flex;
line-height: 1.5;
padding: 0.375rem 0;
padding-right: 1.125rem;
&.toc-link::before {
display: none;
}
}
}
}
@for $i from 2 through 4 {
.node-name--H#{$i} {
padding-left: 1.125rem * ($i - 1);
}
}
.is-active-link {
color: var(--toc-highlight) !important;
font-weight: 600;
}
&::-webkit-backdrop {
-webkit-backdrop-filter: $backdrop;
backdrop-filter: $backdrop;
}
&::backdrop {
-webkit-backdrop-filter: $backdrop;
backdrop-filter: $backdrop;
}
&::after {
display: flex;
content: '';
position: relative;
background: linear-gradient(transparent, var(--card-bg) 70%);
height: $curtain-height;
}
#toc-popup-content {
overflow: auto;
max-height: calc(100vh - 4 * v.$topbar-height);
font-family: v.$font-family-heading;
margin-bottom: -$curtain-height;
}
}

36
_sass/layout/_footer.scss Normal file
View File

@@ -0,0 +1,36 @@
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/variables' as v;
@use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
footer {
background-color: var(--main-bg);
height: v.$footer-height;
border-top: 1px solid var(--main-border-color);
@extend %text-xs;
@include bp.lt(bp.get(lg)) {
@include mx.slide;
height: v.$footer-height-large;
padding: 1.5rem 0;
}
a {
@extend %text-highlight;
&:hover {
@extend %link-hover;
}
}
em {
@extend %text-highlight;
}
p {
text-align: center;
margin-bottom: 0;
}
}

4
_sass/layout/_index.scss Normal file
View File

@@ -0,0 +1,4 @@
@forward 'sidebar';
@forward 'topbar';
@forward 'panel';
@forward 'footer';

70
_sass/layout/_panel.scss Normal file
View File

@@ -0,0 +1,70 @@
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
.access {
top: 2rem;
transition: top 0.2s ease-in-out;
margin-top: 3rem;
&:only-child {
position: -webkit-sticky;
position: sticky;
}
> section {
@extend %panel-border;
padding-left: 1rem;
&:not(:first-child) {
margin-top: 4rem;
}
}
.content {
font-size: 0.9rem;
}
}
#panel-wrapper {
/* the headings */
.panel-heading {
font-family: inherit;
line-height: inherit;
@include mx.label(inherit);
}
.post-tag {
line-height: 1.05rem;
font-size: 0.85rem;
border-radius: 0.8rem;
padding: 0.3rem 0.5rem;
margin: 0 0.35rem 0.5rem 0;
&:hover {
transition: all 0.3s ease-in;
}
}
> :last-child {
margin-bottom: 4rem;
}
@include bp.lt(bp.get(xl)) {
display: none;
}
}
#access-lastmod {
a {
color: inherit;
&:hover {
@extend %link-hover;
}
@extend %no-bottom-border;
}
}

258
_sass/layout/_sidebar.scss Normal file
View File

@@ -0,0 +1,258 @@
@use '../abstracts/variables' as v;
@use '../abstracts/mixins' as mx;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/placeholders';
$btn-border-width: 3px;
$btn-mb: 0.5rem;
$sidebar-display: 'sidebar-display'; /* the attribute for sidebar display */
#sidebar {
@include mx.pl-pr(0);
position: fixed;
top: 0;
left: 0;
height: 100%;
overflow-y: auto;
width: v.$sidebar-width;
background: var(--sidebar-bg);
border-right: 1px solid var(--sidebar-border-color);
/* Hide scrollbar for IE, Edge and Firefox */
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
/* Hide scrollbar for Chrome, Safari and Opera */
&::-webkit-scrollbar {
display: none;
}
@include bp.lt(bp.get(lg)) {
@include mx.slide;
transform: translateX(-#{v.$sidebar-width}); /* hide */
-webkit-transform: translateX(-#{v.$sidebar-width});
[#{$sidebar-display}] & {
transform: translateX(0);
}
}
@include bp.xxxl {
width: v.$sidebar-width-large;
}
%sidebar-link-hover {
&:hover {
color: var(--sidebar-active-color);
}
}
a {
@extend %sidebar-links;
}
#avatar {
display: block;
width: 6.5rem;
height: 6.5rem;
overflow: hidden;
box-shadow: var(--avatar-border-color) 0 0 0 2px;
transform: translateZ(0); /* fixed the zoom in Safari */
@include bp.sm {
width: 7rem;
height: 7rem;
}
img {
transition: transform 0.5s;
&:hover {
transform: scale(1.2);
}
}
}
.profile-wrapper {
@include mx.mt-mb(2.5rem);
@extend %clickable-transition;
padding-left: 2.5rem;
padding-right: 1.25rem;
width: 100%;
@include bp.lg {
margin-top: 3rem;
}
@include bp.xxxl {
margin-top: 3.5rem;
margin-bottom: 2.5rem;
padding-left: 3.5rem;
}
}
.site-title {
@extend %clickable-transition;
@extend %sidebar-link-hover;
font-family: inherit;
font-weight: 900;
font-size: 1.75rem;
line-height: 1.2;
letter-spacing: 0.25px;
margin-top: 1.25rem;
margin-bottom: 0.5rem;
width: fit-content;
color: var(--site-title-color);
}
.site-subtitle {
font-size: 95%;
color: var(--site-subtitle-color);
margin-top: 0.25rem;
word-spacing: 1px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
ul {
margin-bottom: 2rem;
li.nav-item {
opacity: 0.9;
width: 100%;
@include mx.pl-pr(1.5rem);
@include bp.xxxl {
@include mx.pl-pr(2.75rem);
}
a.nav-link {
@include mx.pt-pb(0.6rem);
display: flex;
align-items: center;
border-radius: 0.75rem;
font-weight: 600;
&:hover {
background-color: var(--sidebar-hover-bg);
}
i {
font-size: 95%;
opacity: 0.8;
margin-right: 1.5rem;
}
span {
font-size: 90%;
letter-spacing: 0.2px;
}
}
&.active {
.nav-link {
color: var(--sidebar-active-color);
background-color: var(--sidebar-hover-bg);
span {
opacity: 1;
}
}
}
&:not(:first-child) {
margin-top: 0.25rem;
}
}
}
.sidebar-bottom {
padding-left: 2rem;
padding-right: 1rem;
margin-bottom: 1.5rem;
@include bp.xxxl {
padding-left: 2.75rem;
margin-bottom: 1.75rem;
}
$btn-size: 1.75rem;
%button {
width: $btn-size;
height: $btn-size;
margin-bottom: $btn-mb; // multi line gap
border-radius: 50%;
color: var(--sidebar-btn-color);
background-color: var(--sidebar-btn-bg);
text-align: center;
display: flex;
align-items: center;
justify-content: center;
&:not(:focus-visible) {
box-shadow: var(--sidebar-border-color) 0 0 0 1px;
}
&:hover {
background-color: var(--sidebar-hover-bg);
}
}
a {
@extend %button;
@extend %sidebar-link-hover;
@extend %clickable-transition;
&:not(:last-child) {
margin-right: v.$sb-btn-gap;
@include bp.xxxl {
margin-right: v.$sb-btn-gap-lg;
}
}
}
i {
line-height: $btn-size;
}
#mode-toggle {
@extend %button;
@extend %sidebar-links;
@extend %sidebar-link-hover;
}
.icon-border {
@extend %no-cursor;
@include mx.ml-mr(calc((v.$sb-btn-gap - $btn-border-width) / 2));
background-color: var(--sidebar-btn-color);
content: '';
width: $btn-border-width;
height: $btn-border-width;
border-radius: 50%;
margin-bottom: $btn-mb;
@include bp.xxxl {
@include mx.ml-mr(calc((v.$sb-btn-gap-lg - $btn-border-width) / 2));
}
}
} /* .sidebar-bottom */
} /* #sidebar */
[#{$sidebar-display}] {
#main-wrapper {
@include bp.lt(bp.get(lg)) {
transform: translateX(v.$sidebar-width);
}
}
}

86
_sass/layout/_topbar.scss Normal file
View File

@@ -0,0 +1,86 @@
@use '../abstracts/variables' as v;
@use '../abstracts/mixins' as mx;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/placeholders';
#topbar-wrapper {
height: v.$topbar-height;
background-color: var(--topbar-bg);
@include bp.lt(bp.get(lg)) {
@include mx.slide(top 0.2s ease);
left: 0;
}
}
#topbar {
@extend %btn-color;
#breadcrumb {
font-size: 1rem;
color: var(--text-muted-color);
padding-left: 0.5rem;
a:hover {
@extend %link-hover;
}
span {
&:not(:last-child) {
&::after {
content: '';
padding: 0 0.3rem;
}
}
}
@include bp.lt(bp.get(lg)) {
display: none;
}
@include bp.between(bp.get(lg), calc(#{bp.get(xl)} - 1px)) {
width: 65%;
overflow: hidden;
text-overflow: ellipsis;
word-break: keep-all;
white-space: nowrap;
}
}
@include bp.lte(bp.get(md)) {
@include mx.max-w-100;
}
@include bp.lt(bp.get(lg)) {
max-width: 100%;
}
}
#topbar-title {
display: none;
font-size: 1.1rem;
font-weight: 600;
font-family: sans-serif;
color: var(--topbar-text-color);
text-align: center;
width: 70%;
word-break: keep-all;
@include bp.lt(bp.get(lg)) {
display: block;
}
@include bp.lg {
text-align: left;
}
}
#sidebar-trigger,
#search-trigger {
display: none;
@include bp.lt(bp.get(lg)) {
display: block;
}
}

View File

@@ -1,2 +1,2 @@
@import 'dist/bootstrap';
@import 'main';
@use 'vendors/bootstrap';
@use 'main';

View File

@@ -1,13 +1,4 @@
@import 'colors/typography-light';
@import 'colors/typography-dark';
@import 'addon/variables';
@import 'variables-hook';
@import 'addon/module';
@import 'addon/syntax';
@import 'addon/commons';
@import 'layout/home';
@import 'layout/post';
@import 'layout/tags';
@import 'layout/archives';
@import 'layout/categories';
@import 'layout/category-tag';
@forward 'base';
@forward 'components';
@forward 'layout';
@forward 'pages';

View File

@@ -1,10 +1,17 @@
/*
Style for Archives
*/
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/placeholders';
#archives {
letter-spacing: 0.03rem;
@include bp.lt(bp.get(sm)) {
margin-top: -1rem;
ul {
letter-spacing: 0;
}
}
$timeline-width: 4px;
%timeline {
@@ -131,13 +138,3 @@
}
}
} /* #archives */
@media all and (max-width: 576px) {
#archives {
margin-top: -1rem;
ul {
letter-spacing: 0;
}
}
}

View File

@@ -1,8 +1,7 @@
/*
Style for Tab Categories
*/
@use '../abstracts/variables' as v;
@use '../abstracts/placeholders';
%category-icon-color {
%-category-icon-color {
color: gray;
}
@@ -16,7 +15,7 @@
}
.card-header {
$radius: calc($radius-lg - 1px);
$radius: calc(v.$radius-lg - 1px);
padding: 0.75rem;
border-radius: $radius;
@@ -29,7 +28,7 @@
}
i {
@extend %category-icon-color;
@extend %-category-icon-color;
font-size: 86%; /* fontawesome icons */
}

View File

@@ -1,6 +1,6 @@
/*
Style for page Category and Tag
*/
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
.dash {
margin: 0 0.5rem 0.6rem 0.5rem;
@@ -24,6 +24,10 @@
position: relative;
top: 0.6rem;
margin-right: 0.5rem;
@include bp.lt(bp.get(sm)) {
margin: 0 0.5rem;
}
}
/* post's title */
@@ -31,6 +35,10 @@
@extend %no-bottom-border;
font-size: 1.1rem;
@include bp.lt(bp.get(sm)) {
@include mx.text-ellipsis;
}
}
}
}
@@ -53,18 +61,3 @@
margin-bottom: -1px; /* Avoid jumping */
}
}
@media all and (max-width: 576px) {
#page-category,
#page-tag {
ul > li {
&::before {
margin: 0 0.5rem;
}
> a {
@include text-ellipsis;
}
}
}
}

View File

@@ -1,10 +1,14 @@
/*
Style for Homepage
*/
@use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/placeholders';
#post-list {
margin-top: 2rem;
@include bp.lg {
margin-top: 2.5rem;
}
.card-wrapper {
&:hover {
text-decoration: none;
@@ -20,7 +24,11 @@
background: none;
%img-radius {
border-radius: $radius-lg $radius-lg 0 0;
border-radius: v.$radius-lg v.$radius-lg 0 0;
@include bp.md {
border-radius: 0 v.$radius-lg v.$radius-lg 0;
}
}
.preview-img {
@@ -35,6 +43,10 @@
height: 100%;
padding: 1rem;
@include bp.md {
padding: 1.75rem 1.75rem 1.25rem;
}
.card-title {
@extend %text-clip;
@@ -46,14 +58,20 @@
color: var(--text-muted-color) !important;
}
.card-text.content {
@extend %muted;
.card-text {
@include bp.md {
display: inherit !important;
}
p {
@extend %text-clip;
&.content {
@extend %muted;
line-height: 1.5;
margin: 0;
p {
@extend %text-clip;
line-height: 1.5;
margin: 0;
}
}
}
@@ -63,6 +81,10 @@
i {
&:not(:first-child) {
margin-left: 1.5rem;
@include bp.md {
margin-left: 1.75rem;
}
}
}
@@ -87,11 +109,28 @@
font-family: Lato, sans-serif;
justify-content: space-evenly;
@include bp.lg {
font-size: 0.85rem;
justify-content: center;
}
a:hover {
text-decoration: none;
}
.page-item {
@include bp.lt(bp.get(lg)) {
&:not(:first-child):not(:last-child) {
display: none;
}
}
@include bp.lg {
&:not(:last-child) {
margin-right: 0.7rem;
}
}
.page-link {
color: var(--btn-patinator-text-color);
padding: 0 0.6rem;
@@ -125,64 +164,10 @@
}
}
} /* .page-item */
} /* .pagination */
/* Tablet */
@media all and (min-width: 768px) {
%img-radius {
border-radius: 0 $radius-lg $radius-lg 0;
}
#post-list {
.card {
.card-body {
padding: 1.75rem 1.75rem 1.25rem 1.75rem;
.card-text {
display: inherit !important;
}
.post-meta {
i {
&:not(:first-child) {
margin-left: 1.75rem;
}
}
}
}
}
}
}
/* Hide SideBar and TOC */
@media all and (max-width: 830px) {
.pagination {
.page-item {
&:not(:first-child):not(:last-child) {
display: none;
}
}
}
}
/* Sidebar is visible */
@media all and (min-width: 831px) {
#post-list {
margin-top: 2.5rem;
}
.pagination {
font-size: 0.85rem;
justify-content: center;
.page-item {
&:not(:last-child) {
margin-right: 0.7rem;
}
}
.page-index {
.page-index {
@include bp.lg {
display: none;
}
} /* .pagination */
}
}

7
_sass/pages/_index.scss Normal file
View File

@@ -0,0 +1,7 @@
@forward 'search';
@forward 'home';
@forward 'post';
@forward 'categories';
@forward 'tags';
@forward 'archives';
@forward 'category-tag';

View File

@@ -1,14 +1,15 @@
/**
* Post-specific styles
*/
@use '../abstracts/variables' as v;
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
%btn-post-nav {
%-btn-post-nav {
width: 50%;
position: relative;
border-color: var(--btn-border-color);
}
@mixin dot($pl: 0.25rem, $pr: 0.25rem) {
@mixin -dot($pl: 0.25rem, $pr: 0.25rem) {
content: '\2022';
padding-left: $pl;
padding-right: $pr;
@@ -24,7 +25,7 @@ header {
.post-meta {
span + span::before {
@include dot;
@include -dot;
}
em,
@@ -113,9 +114,20 @@ header {
} /* .share-wrapper */
}
.post-tail-bottom {
@include bp.lte(bp.get(sm)) {
flex-wrap: wrap-reverse !important;
> div:first-child {
width: 100%;
margin-top: 1rem;
}
}
}
.share-mastodon {
/* See: https://github.com/justinribeiro/share-to-mastodon#properties */
--wc-stm-font-family: $font-family-base;
--wc-stm-font-family: v.$font-family-base;
--wc-stm-dialog-background-color: var(--card-bg);
--wc-stm-form-button-border: 1px solid var(--btn-border-color);
--wc-stm-form-submit-background-color: var(--sidebar-btn-bg);
@@ -139,8 +151,13 @@ header {
}
.post-navigation {
@include bp.lt(bp.get(lg)) {
@include mx.pl-pr(0);
@include mx.ml-mr(-0.5rem);
}
.btn {
@extend %btn-post-nav;
@extend %-btn-post-nav;
&:not(:hover) {
color: var(--link-color);
@@ -153,7 +170,7 @@ header {
}
&.disabled {
@extend %btn-post-nav;
@extend %-btn-post-nav;
pointer-events: auto;
cursor: not-allowed;
@@ -173,12 +190,12 @@ header {
}
&:first-child {
border-radius: $radius-lg 0 0 $radius-lg;
border-radius: v.$radius-lg 0 0 v.$radius-lg;
left: 0.5px;
}
&:last-child {
border-radius: 0 $radius-lg $radius-lg 0;
border-radius: 0 v.$radius-lg v.$radius-lg 0;
right: 0.5px;
}
}
@@ -217,26 +234,35 @@ header {
@keyframes fade-up {
from {
opacity: 0;
position: relative;
top: 2rem;
margin-top: 4rem;
}
to {
opacity: 1;
position: relative;
top: 0;
}
}
/* TOC panel */
#toc-wrapper {
border-left: 1px solid rgba(158, 158, 158, 0.17);
position: -webkit-sticky;
%top-cover {
content: '';
display: block;
position: sticky;
top: 4rem;
top: 0;
width: 100%;
height: 3rem;
background: linear-gradient(var(--main-bg) 50%, transparent);
}
#toc-wrapper {
top: 0;
transition: top 0.2s ease-in-out;
-webkit-animation: fade-up 0.8s;
animation: fade-up 0.8s;
overflow-y: auto;
max-height: 100vh;
scrollbar-width: none;
margin-top: 2rem;
ul {
list-style: none;
@@ -249,6 +275,10 @@ header {
margin: 0.4rem 0;
}
&:first-child {
margin-top: 0;
}
a {
padding: 0.2rem 0 0.2rem 1.25rem;
}
@@ -278,7 +308,6 @@ header {
&::before {
display: inline-block;
width: 1px;
left: -1px;
height: 1.25rem;
background-color: var(--toc-highlight) !important;
}
@@ -288,6 +317,30 @@ header {
padding-left: 0.75rem;
}
}
@at-root .toc-border-cover {
@extend %top-cover;
margin-bottom: -4rem;
}
&::before {
@extend %top-cover;
}
&::after {
content: '';
position: fixed;
bottom: 0;
width: 15%;
height: 2.25rem;
margin-left: -1px;
background: linear-gradient(transparent, var(--main-bg) 70%);
}
> * {
@extend %panel-border;
}
}
/* --- TOC button, bar and popup in mobile/tablet --- */
@@ -298,23 +351,27 @@ header {
top: 0;
z-index: 1;
margin: 0 -1rem;
height: $topbar-height;
height: v.$topbar-height;
background: var(--main-bg);
border-bottom: 1px solid var(--main-border-color);
transition: all 0.2s ease-in-out;
@extend %btn-color;
@include bp.xl {
display: none !important;
}
.label {
@extend %heading;
margin-left: 0.25rem;
margin-left: 0.375rem;
padding: 0 0.75rem;
color: inherit;
}
&.invisible {
top: -$topbar-height;
top: -#{v.$topbar-height};
transition: none;
}
}
@@ -322,11 +379,15 @@ header {
#toc-solo-trigger {
color: var(--text-muted-color);
border-color: var(--btn-border-color);
border-radius: $radius-lg;
border-radius: v.$radius-lg;
@include bp.xl {
display: none !important;
}
.label {
font-size: 1rem;
font-family: $font-family-heading;
font-family: v.$font-family-heading;
}
&:hover {
@@ -338,7 +399,7 @@ header {
@mixin slide-in {
from {
opacity: 0.7;
transform: translateY(-$topbar-height);
transform: translateY(-#{v.$topbar-height});
}
to {
@@ -354,7 +415,7 @@ header {
}
100% {
transform: translateY(-$topbar-height);
transform: translateY(-#{v.$topbar-height});
opacity: 0;
}
}
@@ -375,129 +436,11 @@ header {
@include slide-out;
}
#toc-popup {
$slide-in: slide-in 0.3s ease-out;
$slide-out: slide-out 0.3s ease-out;
$curtain-height: 2rem;
$backdrop: blur(5px);
border-color: var(--toc-popup-border-color);
border-width: 1px;
border-radius: $radius-lg;
color: var(--text-color);
background: var(--card-bg);
margin-top: $topbar-height;
min-width: 20rem;
font-size: 1.05rem;
@media all and (min-width: 576px) {
max-width: 32rem;
}
&[open] {
-webkit-animation: $slide-in;
animation: $slide-in;
}
&[closing] {
-webkit-animation: $slide-out;
animation: $slide-out;
}
@media all and (min-width: 850px) {
left: $sidebar-width;
}
.header {
@extend %btn-color;
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: inherit;
border-bottom: 1px solid var(--main-border-color);
.label {
font-family: $font-family-heading;
}
}
button {
> i {
font-size: 1.25rem;
vertical-align: middle;
}
&:focus-visible {
box-shadow: none;
}
}
ul {
list-style-type: none;
padding-left: 0;
li {
ul,
& + li {
margin-top: 0.25rem;
}
a {
display: flex;
line-height: 1.5;
padding: 0.375rem 0;
padding-right: 1.125rem;
&.toc-link::before {
display: none;
}
}
}
}
@for $i from 2 through 4 {
.node-name--H#{$i} {
padding-left: 1.125rem * ($i - 1);
}
}
.is-active-link {
color: var(--toc-highlight) !important;
font-weight: 600;
}
&::-webkit-backdrop {
-webkit-backdrop-filter: $backdrop;
backdrop-filter: $backdrop;
}
&::backdrop {
-webkit-backdrop-filter: $backdrop;
backdrop-filter: $backdrop;
}
&::after {
display: flex;
content: '';
position: relative;
background: linear-gradient(transparent, var(--card-bg) 70%);
height: $curtain-height;
}
#toc-popup-content {
overflow: auto;
max-height: calc(100vh - 4 * $topbar-height);
font-family: $font-family-heading;
margin-bottom: -$curtain-height;
}
}
/* --- Related Posts --- */
#related-posts {
> h3 {
@include label(1.1rem, 600);
@include mx.label(1.1rem, 600);
}
time {
@@ -540,47 +483,23 @@ header {
}
.share-label {
@include label(inherit, 400, inherit);
@include mx.label(inherit, 400, inherit);
&::after {
content: ':';
}
}
@media all and (max-width: 576px) {
.post-tail-bottom {
flex-wrap: wrap-reverse !important;
> div:first-child {
width: 100%;
margin-top: 1rem;
}
}
}
@media all and (max-width: 768px) {
.content > p > img {
.content > p > img {
@include bp.lte(bp.get(md)) {
max-width: calc(100% + 1rem);
}
}
/* Hide SideBar and TOC */
@media all and (max-width: 849px) {
.post-navigation {
@include pl-pr(0);
@include ml-mr(-0.5rem);
}
}
@media all and (min-width: 1200px) {
h2,
h3,
h4 {
h2,
h3,
h4 {
@include bp.xl {
scroll-margin-top: 2rem;
}
#toc-bar,
#toc-solo-trigger {
display: none !important;
}
}

184
_sass/pages/_search.scss Normal file
View File

@@ -0,0 +1,184 @@
@use '../abstracts/breakpoints' as bp;
@use '../abstracts/variables' as v;
@use '../abstracts/placeholders';
search {
display: flex;
width: 100%;
border-radius: 1rem;
border: 1px solid var(--search-border-color);
background: var(--main-bg);
padding: 0 0.5rem;
i {
z-index: 2;
font-size: 0.9rem;
color: var(--search-icon-color);
}
@include bp.lt(bp.get(lg)) {
display: none;
}
@include bp.lg {
max-width: v.$search-max-width;
}
@include bp.xl {
margin-right: 4rem;
}
@include bp.xxxl {
margin-right: calc(
v.$main-content-max-width / 4 - v.$search-max-width - 0.75rem
);
}
}
#search-result-wrapper {
display: none;
height: 100%;
width: 100%;
overflow: auto;
.content {
margin-top: 2rem;
}
@include bp.lt(bp.get(lg)) {
width: 100%;
.content {
letter-spacing: 0;
}
}
@include bp.lg {
max-width: v.$main-content-max-width;
justify-content: start !important;
}
}
#search-results {
padding-bottom: 3rem;
@include bp.between(bp.get(lg), calc(#{bp.get(xl)} - 1px)) {
> div {
max-width: 700px;
}
}
a {
font-size: 1.4rem;
line-height: 1.5rem;
&:hover {
@extend %link-hover;
}
@extend %link-color;
@extend %no-bottom-border;
@extend %heading;
}
> article {
width: 100%;
&:not(:last-child) {
margin-bottom: 1rem;
}
@include bp.xl {
width: 45%;
&:nth-child(odd) {
margin-right: 1.5rem;
}
&:nth-child(even) {
margin-left: 1.5rem;
}
&:last-child:nth-child(odd) {
position: relative;
right: 24.3%;
}
}
h2 {
line-height: 2.5rem;
}
/* icons */
i {
color: #818182;
margin-right: 0.15rem;
font-size: 80%;
}
> p {
@extend %text-ellipsis;
white-space: break-spaces;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
}
}
/* 'Cancel' link */
#search-cancel {
color: var(--link-color);
display: none;
white-space: nowrap;
@extend %cursor-pointer;
}
#search-input {
background: center;
border: 0;
border-radius: 0;
padding: 0.18rem 0.3rem;
color: var(--text-color);
height: auto;
&:focus {
box-shadow: none;
}
@include bp.xl {
transition: all 0.3s ease-in-out;
}
}
#search-hints {
padding: 0 1rem;
@include bp.lg {
display: none;
}
h4 {
margin-bottom: 1.5rem;
}
.post-tag {
display: inline-block;
line-height: 1rem;
font-size: 1rem;
background: var(--search-tag-bg);
border: none;
padding: 0.5rem;
margin: 0 1.25rem 1rem 0;
&::before {
content: '#';
color: var(--text-muted-color);
padding-right: 0.2rem;
}
@extend %link-color;
}
}

View File

@@ -1,6 +1,4 @@
/*
Styles for Tab Tags
*/
@use '../abstracts/breakpoints' as bp;
.tag {
border-radius: 0.7em;
@@ -17,3 +15,9 @@
font-family: Oswald, sans-serif;
}
}
#tags {
@include bp.lt(bp.get(lg)) {
justify-content: center !important;
}
}

View File

@@ -1,8 +1,6 @@
/*
* The main dark mode styles
*/
@mixin styles {
color-scheme: dark;
@mixin dark-scheme {
/* Framework color */
--main-bg: rgb(27, 27, 30);
--mask-bg: rgb(68, 69, 70);
@@ -100,7 +98,18 @@
--timeline-color: rgb(63, 65, 68);
--timeline-year-dot-color: var(--timeline-color);
color-scheme: dark;
/* Code highlight colors */
--language-border-color: #2d2d2d;
--highlight-bg-color: #151515;
--highlighter-rouge-color: #c9def1;
--highlight-lineno-color: #808080;
--inline-code-bg: rgba(255, 255, 255, 0.05);
--code-color: #b0b0b0;
--code-header-text-color: #6a6a6a;
--code-header-muted-color: #353535;
--code-header-icon-color: #565656;
--clipboard-checked-color: #2bcc2b;
--filepath-text-color: #cacaca;
.light {
display: none;
@@ -144,4 +153,151 @@
#disqus_thread {
color-scheme: none;
}
} /* dark-scheme */
/* --- Syntax highlight theme from `rougify style base16.dark` --- */
.highlight .gp {
color: #87939d;
}
.highlight table td {
padding: 5px;
}
.highlight table pre {
margin: 0;
}
.highlight,
.highlight .w {
color: #d0d0d0;
background-color: #151515;
}
.highlight .err {
color: #151515;
background-color: #ac4142;
}
.highlight .c,
.highlight .ch,
.highlight .cd,
.highlight .cm,
.highlight .cpf,
.highlight .c1,
.highlight .cs {
color: #848484;
}
.highlight .cp {
color: #f4bf75;
}
.highlight .nt {
color: #f4bf75;
}
.highlight .o,
.highlight .ow {
color: #d0d0d0;
}
.highlight .p,
.highlight .pi {
color: #d0d0d0;
}
.highlight .gi {
color: #90a959;
}
.highlight .gd {
color: #f08a8b;
background-color: #320000;
}
.highlight .gh {
color: #6a9fb5;
background-color: #151515;
font-weight: bold;
}
.highlight .k,
.highlight .kn,
.highlight .kp,
.highlight .kr,
.highlight .kv {
color: #aa759f;
}
.highlight .kc {
color: #d28445;
}
.highlight .kt {
color: #d28445;
}
.highlight .kd {
color: #d28445;
}
.highlight .s,
.highlight .sb,
.highlight .sc,
.highlight .dl,
.highlight .sd,
.highlight .s2,
.highlight .sh,
.highlight .sx,
.highlight .s1 {
color: #90a959;
}
.highlight .sa {
color: #aa759f;
}
.highlight .sr {
color: #75b5aa;
}
.highlight .si {
color: #b76d45;
}
.highlight .se {
color: #b76d45;
}
.highlight .nn {
color: #f4bf75;
}
.highlight .nc {
color: #f4bf75;
}
.highlight .no {
color: #f4bf75;
}
.highlight .na {
color: #6a9fb5;
}
.highlight .m,
.highlight .mb,
.highlight .mf,
.highlight .mh,
.highlight .mi,
.highlight .il,
.highlight .mo,
.highlight .mx {
color: #90a959;
}
.highlight .ss {
color: #90a959;
}
}

313
_sass/themes/_light.scss Normal file
View File

@@ -0,0 +1,313 @@
@mixin styles {
/* Framework color */
--main-bg: white;
--mask-bg: #c1c3c5;
--main-border-color: #f3f3f3;
/* Common color */
--text-color: #34343c;
--text-muted-color: #757575;
--text-muted-highlight-color: inherit;
--heading-color: #2a2a2a;
--label-color: #585858;
--blockquote-border-color: #eeeeee;
--blockquote-text-color: #757575;
--link-color: #0056b2;
--link-underline-color: #dee2e6;
--button-bg: #ffffff;
--btn-border-color: #e9ecef;
--btn-backtotop-color: #686868;
--btn-backtotop-border-color: #f1f1f1;
--checkbox-color: #c5c5c5;
--checkbox-checked-color: #07a8f7;
--img-bg: radial-gradient(
circle,
rgb(255, 255, 255) 0%,
rgb(239, 239, 239) 100%
);
--shimmer-bg: linear-gradient(
90deg,
rgba(250, 250, 250, 0) 0%,
rgba(232, 230, 230, 1) 50%,
rgba(250, 250, 250, 0) 100%
);
/* Sidebar */
--site-title-color: rgb(113, 113, 113);
--site-subtitle-color: #717171;
--sidebar-bg: #f6f8fa;
--sidebar-border-color: #efefef;
--sidebar-muted-color: #545454;
--sidebar-active-color: #1d1d1d;
--sidebar-hover-bg: rgb(223, 233, 241, 0.64);
--sidebar-btn-bg: white;
--sidebar-btn-color: #8e8e8e;
--avatar-border-color: white;
/* Topbar */
--topbar-bg: rgb(255, 255, 255, 0.7);
--topbar-text-color: rgb(78, 78, 78);
--search-border-color: rgb(240, 240, 240);
--search-icon-color: #c2c6cc;
--input-focus-border-color: #b8b8b8;
/* Home page */
--post-list-text-color: dimgray;
--btn-patinator-text-color: #555555;
--btn-paginator-hover-color: var(--sidebar-bg);
/* Posts */
--toc-highlight: #0550ae;
--toc-popup-border-color: lightgray;
--btn-share-color: gray;
--btn-share-hover-color: #0d6efd;
--card-bg: white;
--card-hovor-bg: #e2e2e2;
--card-shadow: rgb(104, 104, 104, 0.05) 0 2px 6px 0,
rgba(211, 209, 209, 0.15) 0 0 0 1px;
--footnote-target-bg: lightcyan;
--tb-odd-bg: #fbfcfd;
--tb-border-color: #eaeaea;
--dash-color: silver;
--kbd-wrap-color: #bdbdbd;
--kbd-text-color: var(--text-color);
--kbd-bg-color: white;
--prompt-text-color: rgb(46, 46, 46, 0.77);
--prompt-tip-bg: rgb(123, 247, 144, 0.2);
--prompt-tip-icon-color: #03b303;
--prompt-info-bg: #e1f5fe;
--prompt-info-icon-color: #0070cb;
--prompt-warning-bg: rgb(255, 243, 205);
--prompt-warning-icon-color: #ef9c03;
--prompt-danger-bg: rgb(248, 215, 218, 0.56);
--prompt-danger-icon-color: #df3c30;
/* Tags */
--tag-border: #dee2e6;
--tag-shadow: var(--btn-border-color);
--tag-hover: rgb(222, 226, 230);
--search-tag-bg: #f8f9fa;
/* Categories */
--categories-border: rgba(0, 0, 0, 0.125);
--categories-hover-bg: var(--btn-border-color);
--categories-icon-hover-color: darkslategray;
/* Archive */
--timeline-color: rgba(0, 0, 0, 0.075);
--timeline-node-bg: #c2c6cc;
--timeline-year-dot-color: #ffffff;
/* --- Custom code light mode colors --- */
--language-border-color: #ececec;
--highlight-bg-color: #f6f8fa;
--highlighter-rouge-color: #3f596f;
--highlight-lineno-color: #9e9e9e;
--inline-code-bg: rgba(25, 25, 28, 0.05);
--code-color: #3a3a3a;
--code-header-text-color: #a3a3a3;
--code-header-muted-color: #e5e5e5;
--code-header-icon-color: #c9c8c8;
--clipboard-checked-color: #43c743;
[class^='prompt-'] {
--link-underline-color: rgb(219, 216, 216);
}
.dark {
display: none;
}
/* --- Syntax highlight theme from `rougify style github` --- */
.highlight table td {
padding: 5px;
}
.highlight table pre {
margin: 0;
}
.highlight,
.highlight .w {
color: #24292f;
background-color: #f6f8fa;
}
.highlight .k,
.highlight .kd,
.highlight .kn,
.highlight .kp,
.highlight .kr,
.highlight .kt,
.highlight .kv {
color: #cf222e;
}
.highlight .gr {
color: #f6f8fa;
}
.highlight .gd {
color: #82071e;
background-color: #ffebe9;
}
.highlight .nb {
color: #953800;
}
.highlight .nc {
color: #953800;
}
.highlight .no {
color: #953800;
}
.highlight .nn {
color: #953800;
}
.highlight .sr {
color: #116329;
}
.highlight .na {
color: #116329;
}
.highlight .nt {
color: #116329;
}
.highlight .gi {
color: #116329;
background-color: #dafbe1;
}
.highlight .kc {
color: #0550ae;
}
.highlight .l,
.highlight .ld,
.highlight .m,
.highlight .mb,
.highlight .mf,
.highlight .mh,
.highlight .mi,
.highlight .il,
.highlight .mo,
.highlight .mx {
color: #0550ae;
}
.highlight .sb {
color: #0550ae;
}
.highlight .bp {
color: #0550ae;
}
.highlight .ne {
color: #0550ae;
}
.highlight .nl {
color: #0550ae;
}
.highlight .py {
color: #0550ae;
}
.highlight .nv,
.highlight .vc,
.highlight .vg,
.highlight .vi,
.highlight .vm {
color: #0550ae;
}
.highlight .o,
.highlight .ow {
color: #0550ae;
}
.highlight .gh {
color: #0550ae;
font-weight: bold;
}
.highlight .gu {
color: #0550ae;
font-weight: bold;
}
.highlight .s,
.highlight .sa,
.highlight .sc,
.highlight .dl,
.highlight .sd,
.highlight .s2,
.highlight .se,
.highlight .sh,
.highlight .sx,
.highlight .s1,
.highlight .ss {
color: #0a3069;
}
.highlight .nd {
color: #8250df;
}
.highlight .nf,
.highlight .fm {
color: #8250df;
}
.highlight .err {
color: #f6f8fa;
background-color: #82071e;
}
.highlight .c,
.highlight .ch,
.highlight .cd,
.highlight .cm,
.highlight .cp,
.highlight .cpf,
.highlight .c1,
.highlight .cs {
color: #68717a;
}
.highlight .gl {
color: #68717a;
}
.highlight .gt {
color: #68717a;
}
.highlight .ni {
color: #24292f;
}
.highlight .si {
color: #24292f;
}
.highlight .ge {
color: #24292f;
font-style: italic;
}
.highlight .gs {
color: #24292f;
font-weight: bold;
}
}

View File

@@ -1,3 +0,0 @@
/*
Appending custom SCSS variables will override the default ones in `_sass/addon/variables.scsss`
*/

View File

@@ -1,7 +1,7 @@
---
---
@import 'main
@use 'main
{%- if jekyll.environment == 'production' -%}
.bundle
{%- endif -%}

View File

@@ -1,5 +1,30 @@
# Changelog
## [7.2.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.2.0...v7.2.1) (2024-12-05)
### Bug Fixes
* **build:** exclude `purgecss.js` from output files ([#2090](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2090)) ([976e1a1](https://github.com/cotes2020/jekyll-theme-chirpy/commit/976e1a184b3dbe08991e8a50db4d5d7f8a0b7090))
* correct the import condition for theme script ([#2075](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2075)) ([a16aa7d](https://github.com/cotes2020/jekyll-theme-chirpy/commit/a16aa7d41e3c3cb28649bfa1361e8bcb91b9ca47))
* ensure pageviews are fetched after DOM is loaded ([#2071](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2071)) ([b4019f3](https://github.com/cotes2020/jekyll-theme-chirpy/commit/b4019f3517e4a3284df51567d29938cb12bf3acc))
* **toc:** resume fade up animation in desktop mode ([#2085](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2085)) ([8280adb](https://github.com/cotes2020/jekyll-theme-chirpy/commit/8280adb901b9d15cc1bc18009553aae8746121d8))
## [7.2.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.1.1...v7.2.0) (2024-11-28)
### Features
* show toc on mobile screens ([#1964](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1964)) ([8a064a5](https://github.com/cotes2020/jekyll-theme-chirpy/commit/8a064a5e5a95cd22aa654f7c80da09d107262508))
* support vertical scrolling for toc in desktop mode ([#2064](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2064)) ([5265b03](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5265b039741555943f9a6f0451287aefb6810f28))
### Bug Fixes
* pagination error when pinned posts exceed the page size ([#1965](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1965)) ([93f616b](https://github.com/cotes2020/jekyll-theme-chirpy/commit/93f616b25d7ed6c4f090c50c8663f8c1f59947f4))
### Improvements
* modular sass architecture ([#2052](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2052)) ([35c794c](https://github.com/cotes2020/jekyll-theme-chirpy/commit/35c794cf5896565430389f35c660b88a93cebb17))
* speed up page rendering and jekyll build process ([#2034](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2034)) ([65f960c](https://github.com/cotes2020/jekyll-theme-chirpy/commit/65f960c31a734b5306a8b919040c3aae9b783efd))
## [7.1.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.1.0...v7.1.1) (2024-09-23)
### Bug Fixes

View File

@@ -2,7 +2,7 @@
Gem::Specification.new do |spec|
spec.name = "jekyll-theme-chirpy"
spec.version = "7.1.1"
spec.version = "7.2.1"
spec.authors = ["Cotes Chung"]
spec.email = ["cotes.chung@gmail.com"]

View File

@@ -1,6 +1,6 @@
{
"name": "jekyll-theme-chirpy",
"version": "7.1.1",
"version": "7.2.1",
"description": "A minimal, responsive, and feature-rich Jekyll theme for technical writing.",
"repository": {
"type": "git",
@@ -15,7 +15,7 @@
"homepage": "https://github.com/cotes2020/jekyll-theme-chirpy/",
"scripts": {
"build": "concurrently npm:build:*",
"build:css": "purgecss -c purgecss.config.js",
"build:css": "node purgecss.js",
"build:js": "rollup -c --bundleConfigAsCjs --environment BUILD:production",
"watch:js": "rollup -c --bundleConfigAsCjs -w",
"lint:scss": "stylelint _sass/**/*.scss",
@@ -28,25 +28,25 @@
"bootstrap": "^5.3.3"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-transform-class-properties": "^7.25.4",
"@babel/plugin-transform-private-methods": "^7.25.7",
"@babel/preset-env": "^7.25.4",
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@babel/core": "^7.26.0",
"@babel/plugin-transform-class-properties": "^7.25.9",
"@babel/plugin-transform-private-methods": "^7.25.9",
"@babel/preset-env": "^7.26.0",
"@commitlint/cli": "^19.6.0",
"@commitlint/config-conventional": "^19.6.0",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-terser": "^0.4.4",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"concurrently": "^9.0.1",
"concurrently": "^9.1.0",
"conventional-changelog-conventionalcommits": "^8.0.0",
"husky": "^9.1.6",
"purgecss": "^6.0.0",
"rollup": "^4.21.3",
"semantic-release": "^24.1.1",
"stylelint": "^16.9.0",
"husky": "^9.1.7",
"purgecss": "^7.0.2",
"rollup": "^4.27.4",
"semantic-release": "^24.2.0",
"stylelint": "^16.10.0",
"stylelint-config-standard-scss": "^13.1.0"
},
"prettier": {
@@ -68,41 +68,6 @@
]
}
},
"stylelint": {
"extends": "stylelint-config-standard-scss",
"rules": {
"no-descending-specificity": null,
"shorthand-property-no-redundant-values": null,
"at-rule-no-vendor-prefix": null,
"property-no-vendor-prefix": null,
"selector-no-vendor-prefix": null,
"value-no-vendor-prefix": null,
"color-function-notation": "legacy",
"alpha-value-notation": "number",
"selector-not-notation": "simple",
"color-hex-length": "long",
"declaration-block-single-line-max-declarations": 3,
"scss/operator-no-newline-after": null,
"rule-empty-line-before": [
"always",
{
"ignore": [
"after-comment",
"first-nested"
]
}
],
"value-keyword-case": [
"lower",
{
"ignoreProperties": [
"/^\\$/"
]
}
],
"media-feature-range-notation": "prefix"
}
},
"release": {
"branches": [
"production"

View File

@@ -1,23 +0,0 @@
const fs = require('fs');
const DIST_PATH = '_sass/dist';
fs.rm(DIST_PATH, { recursive: true, force: true }, (err) => {
if (err) {
throw err;
}
fs.mkdirSync(DIST_PATH);
});
module.exports = {
content: ['_includes/**/*.html', '_layouts/**/*.html', '_javascript/**/*.js'],
css: ['node_modules/bootstrap/dist/css/bootstrap.min.css'],
keyframes: true,
variables: true,
output: `${DIST_PATH}/bootstrap.css`,
// The `safelist` should be changed appropriately for future development
safelist: {
standard: [/^collaps/, /^w-/, 'shadow', 'border', 'kbd'],
greedy: [/^col-/, /tooltip/]
}
};

30
purgecss.js Normal file
View File

@@ -0,0 +1,30 @@
const fs = require('fs').promises;
const { PurgeCSS } = require('purgecss');
const DIST_PATH = '_sass/vendors';
const output = `${DIST_PATH}/_bootstrap.scss`;
const config = {
content: ['_includes/**/*.html', '_layouts/**/*.html', '_javascript/**/*.js'],
css: ['node_modules/bootstrap/dist/css/bootstrap.min.css'],
keyframes: true,
variables: true,
// The `safelist` should be changed appropriately for future development
safelist: {
standard: [/^collaps/, /^w-/, 'shadow', 'border', 'kbd'],
greedy: [/^col-/, /tooltip/]
}
};
function main() {
fs.rm(DIST_PATH, { recursive: true, force: true })
.then(() => fs.mkdir(DIST_PATH))
.then(() => new PurgeCSS().purge(config))
.then((result) => {
return fs.writeFile(output, result[0].css);
})
.catch((err) => {
console.error('Error during PurgeCSS process:', err);
});
}
main();

View File

@@ -11,11 +11,11 @@ const DIST = 'assets/js/dist';
const banner = `/*!
* ${pkg.name} v${pkg.version} | © ${pkg.since} ${pkg.author} | ${pkg.license} Licensed | ${pkg.homepage}
*/`;
const frontmatter = `---\npermalink: /:basename\n---\n`;
const isProd = process.env.BUILD === 'production';
let hasWatched = false;
function cleanup() {
fs.rmSync(DIST, { recursive: true, force: true });
console.log(`> Directory "${DIST}" has been cleaned.`);
@@ -39,6 +39,11 @@ function build(
{ src = SRC_DEFAULT, jekyll = false, outputName = null } = {}
) {
const input = `${src}/${filename}.js`;
const shouldWatch = hasWatched ? false : true;
if (!hasWatched) {
hasWatched = true;
}
return {
input,
@@ -49,9 +54,7 @@ function build(
banner,
sourcemap: !isProd && !jekyll
},
watch: {
include: input
},
...(shouldWatch && { watch: { include: `${SRC_DEFAULT}/**/*.js` } }),
plugins: [
babel({
babelHelpers: 'bundled',

View File

@@ -92,7 +92,8 @@ init_files() {
npm i && npm run build
# track the CSS/JS output
_sedi "/.*\/dist$/d" .gitignore
_sedi "/^_sass\/vendors/d" .gitignore
_sedi "/^assets\/js\/dist/d" .gitignore
}
commit() {

View File

@@ -15,7 +15,7 @@ NODE_SPEC="package.json"
CHANGELOG="docs/CHANGELOG.md"
CONFIG="_config.yml"
CSS_DIST="_sass/dist"
CSS_DIST="_sass/vendors"
JS_DIST="assets/js/dist"
FILES=(