Update Theme Version to v7.2.0
Some checks failed
Build and Deploy Test Version (with Drafts) - next.asandikci.com / build-drafts-and-deploy (push) Failing after 1m4s

This commit is contained in:
Aliberk Sandıkçı 2024-11-29 23:43:36 +03:00
commit b120aed842
Signed by: asandikci
GPG key ID: A3B47D76845BEDF3
78 changed files with 3060 additions and 1443 deletions

3
.gitignore vendored
View file

@ -23,4 +23,5 @@ package-lock.json
!.vscode/tasks.json !.vscode/tasks.json
# Misc # 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

@ -20,8 +20,8 @@ webfonts: https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Sour
# Libraries # Libraries
toc: toc:
css: https://cdn.jsdelivr.net/npm/tocbot@4.29.0/dist/tocbot.min.css css: https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.css
js: https://cdn.jsdelivr.net/npm/tocbot@4.29.0/dist/tocbot.min.js js: https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.js
fontlogos: fontlogos:
css: https://cdn.jsdelivr.net/npm/font-logos@1/assets/font-logos.css css: https://cdn.jsdelivr.net/npm/font-logos@1/assets/font-logos.css
@ -30,7 +30,7 @@ forkawesome:
css: https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css css: https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css
fontawesome: 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
ballooncss: ballooncss:
css: https://unpkg.com/balloon-css/balloon.min.css css: https://unpkg.com/balloon-css/balloon.min.css
@ -39,7 +39,7 @@ 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.10.0/dest/simple-jekyll-search.min.js
mermaid: 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: dayjs:
js: js:

View file

@ -4,4 +4,3 @@
src="https://static.cloudflareinsights.com/beacon.min.js" src="https://static.cloudflareinsights.com/beacon.min.js"
data-cf-beacon='{"token": "{{ site.analytics.cloudflare.id }}"}' data-cf-beacon='{"token": "{{ site.analytics.cloudflare.id }}"}'
></script> ></script>
<!-- End Cloudflare Web Analytics -->

View file

@ -2,6 +2,5 @@
<script <script
src="https://cdn.usefathom.com/script.js" src="https://cdn.usefathom.com/script.js"
data-site="{{ site.analytics.fathom.id }}" data-site="{{ site.analytics.fathom.id }}"
defer> defer
</script> ></script>
<!-- End Fathom Code -->

View file

@ -1,7 +1,7 @@
<!-- Global site tag (gtag.js) - Google Analytics --> <!-- Global site tag (gtag.js) - Google Analytics -->
<script defer src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics.google.id }}"></script> <script defer src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics.google.id }}"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', function (event) { document.addEventListener('DOMContentLoaded', () => {
window.dataLayer = window.dataLayer || []; window.dataLayer = window.dataLayer || [];
function gtag() { function gtag() {
dataLayer.push(arguments); dataLayer.push(arguments);

View file

@ -1,14 +1,13 @@
<!-- Matomo --> <!-- Matomo -->
<script type="text/javascript"> <script>
var _paq = window._paq = window._paq || []; document.addEventListener('DOMContentLoaded', () => {
var _paq = (window._paq = window._paq || []);
_paq.push(['trackPageView']); _paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']); _paq.push(['enableLinkTracking']);
(function() {
var u="//{{ site.analytics.matomo.domain }}/"; var u="//{{ site.analytics.matomo.domain }}/";
_paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', {{ site.analytics.matomo.id }}]); _paq.push(['setSiteId', {{ site.analytics.matomo.id }}]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})(); });
</script> </script>
<!-- End Matomo Code -->

View file

@ -1,38 +1,25 @@
<!-- The Disqus lazy loading. --> <script>
<div id="disqus_thread">
<p class="text-center text-muted small">Comments powered by <a href="https://disqus.com/">Disqus</a>.</p>
</div>
<script type="text/javascript">
var disqus_config = function () { var disqus_config = function () {
this.page.url = '{{ page.url | absolute_url }}'; this.page.url = '{{ page.url | absolute_url }}';
this.page.identifier = '{{ page.url }}'; this.page.identifier = '{{ page.url }}';
}; };
{%- comment -%} Lazy loading {%- endcomment -%} function addDisqus() {
var disqus_observer = new IntersectionObserver( let disqusThread = document.createElement('div');
function (entries) { let paragraph = document.createElement('p');
if (entries[0].isIntersecting) {
(function () {
var d = document,
s = d.createElement('script');
s.src = 'https://{{ site.comments.disqus.shortname }}.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
disqus_observer.disconnect(); disqusThread.id = 'disqus_thread';
paragraph.className = 'text-center text-muted small';
paragraph.innerHTML = 'Comments powered by <a href="https://disqus.com/">Disqus</a>.';
disqusThread.appendChild(paragraph);
const footer = document.querySelector('footer');
footer.insertAdjacentElement("beforebegin", disqusThread);
} }
},
{ threshold: [0] }
);
disqus_observer.observe(document.getElementById('disqus_thread'));
{%- comment -%} Auto switch theme {%- endcomment -%} {%- comment -%} Auto switch theme {%- endcomment -%}
function reloadDisqus() { function reloadDisqus(event) {
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) { if (event.source === window && event.data && event.data.id === Theme.ID) {
{%- comment -%} Disqus hasn't been loaded {%- endcomment -%} {%- comment -%} Disqus hasn't been loaded {%- endcomment -%}
if (typeof DISQUS === 'undefined') { if (typeof DISQUS === 'undefined') {
return; return;
@ -44,7 +31,27 @@
} }
} }
if (document.getElementById('mode-toggle')) { addDisqus();
window.addEventListener('message', reloadDisqus);
if (Theme.switchable) {
addEventListener('message', reloadDisqus);
} }
{%- comment -%} Lazy loading {%- endcomment -%}
var disqusObserver = new IntersectionObserver(
function (entries) {
if (entries[0].isIntersecting) {
var d = document,
s = d.createElement('script');
s.src = 'https://{{ site.comments.disqus.shortname }}.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
disqusObserver.disconnect();
}
},
{ threshold: [0] }
);
disqusObserver.observe(document.getElementById('disqus_thread'));
</script> </script>

View file

@ -1,21 +1,8 @@
<!-- https://giscus.app/ --> <!-- https://giscus.app/ -->
<script type="text/javascript"> <script>
(function () { (function () {
const origin = 'https://giscus.app'; const themeMapper = Theme.getThemeMapper('light', 'dark_dimmed');
const lightTheme = 'light'; const initTheme = themeMapper[Theme.visualState];
const darkTheme = 'dark_dimmed';
let initTheme = lightTheme;
const html = document.documentElement;
if (
(html.hasAttribute('data-mode') &&
html.getAttribute('data-mode') === 'dark') ||
(!html.hasAttribute('data-mode') &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
initTheme = darkTheme;
}
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 -%}
@ -41,30 +28,27 @@
async: '' async: ''
}; };
let giscusScript = document.createElement('script'); let giscusNode = document.createElement('script');
Object.entries(giscusAttributes).forEach(([key, value]) => Object.entries(giscusAttributes).forEach(([key, value]) =>
giscusScript.setAttribute(key, value) giscusNode.setAttribute(key, value)
); );
document.getElementById('tail-wrapper').appendChild(giscusScript);
const $footer = document.querySelector('footer');
$footer.insertAdjacentElement("beforebegin", giscusNode);
addEventListener('message', (event) => { addEventListener('message', (event) => {
if ( if (event.source === window && event.data && event.data.id === Theme.ID) {
event.source === window && const newTheme = themeMapper[Theme.visualState];
event.data &&
event.data.direction === ModeToggle.ID
) {
{%- comment -%} global theme mode changed {%- endcomment -%}
const mode = event.data.message;
const theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
const message = { const message = {
setConfig: { setConfig: {
theme: theme theme: newTheme
} }
}; };
const giscus = document.getElementsByClassName('giscus-frame')[0].contentWindow; const giscus =
giscus.postMessage({ giscus: message }, origin); document.getElementsByClassName('giscus-frame')[0].contentWindow;
giscus.postMessage({ giscus: message }, 'https://giscus.app');
} }
}); });
})(); })();

View file

@ -1,49 +1,38 @@
<!-- https://utteranc.es/ --> <!-- https://utteranc.es/ -->
<script <script>
src="https://utteranc.es/client.js"
repo="{{ site.comments.utterances.repo }}"
issue-term="{{ site.comments.utterances.issue_term }}"
crossorigin="anonymous"
async
></script>
<script type="text/javascript">
(function () { (function () {
const origin = 'https://utteranc.es'; const origin = 'https://utteranc.es';
const lightTheme = 'github-light'; const themeMapper = Theme.getThemeMapper('github-light', 'github-dark');
const darkTheme = 'github-dark'; const initTheme = themeMapper[Theme.visualState];
let initTheme = lightTheme;
const html = document.documentElement;
if ( let script = document.createElement('script');
(html.hasAttribute('data-mode') && html.getAttribute('data-mode') === 'dark') || script.src = 'https://utteranc.es/client.js';
(!html.hasAttribute('data-mode') && window.matchMedia('(prefers-color-scheme: dark)').matches) script.setAttribute('repo', '{{ site.comments.utterances.repo }}');
) { script.setAttribute('issue-term', '{{ site.comments.utterances.issue_term }}');
initTheme = darkTheme; script.setAttribute('theme', initTheme);
} script.crossOrigin = 'anonymous';
script.async = true;
const $footer = document.querySelector('footer');
$footer.insertAdjacentElement('beforebegin', script);
addEventListener('message', (event) => { addEventListener('message', (event) => {
let theme; let newTheme;
{%- comment -%} credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> {%- endcomment -%} {%- comment -%}
if (event.origin === origin) { Credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347>
{%- comment -%} page initial {%- endcomment -%} {%- endcomment -%}
theme = initTheme; if (event.source === window && event.data && event.data.id === Theme.ID) {
} else if (event.source === window && event.data && event.data.direction === ModeToggle.ID) { newTheme = themeMapper[Theme.visualState];
{%- comment -%} global theme mode changed {%- endcomment -%}
const mode = event.data.message;
theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
} else {
return;
}
const message = { const message = {
type: 'set-theme', type: 'set-theme',
theme: theme theme: newTheme
}; };
const utterances = document.getElementsByClassName('utterances-frame')[0].contentWindow; const utterances = document.querySelector('.utterances-frame').contentWindow;
utterances.postMessage(message, origin); utterances.postMessage(message, origin);
}
}); });
})(); })();
</script> </script>

View file

@ -57,12 +57,22 @@
endfor %} {% endfor %} {% endunless %} endfor %} {% endfor %} {% endunless %}
<!-- Bootstrap --> <!-- Bootstrap -->
{% unless jekyll.environment == 'production' %} {% unless jekyll.environment == 'production' %} <<<<<<< HEAD
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
/> />
{% endunless %} ||||||| d51345e
<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"
/>
>>>>>>> upstream_master {% endunless %}
<!-- Font Logos --> <!-- Font Logos -->
<link <link
@ -121,8 +131,24 @@
/> />
{% endif %} {% endif %}
<!-- JavaScript --> <!-- Scripts -->
{% unless site.theme_mode %} {% include mode-toggle.html %} {% endunless %} {% {% unless site.theme_mode %}
include metadata-hook.html %} <script src="{{ '/assets/js/dist/theme.min.js' | relative_url }}"></script>
{% endunless %} {% include js-selector.html lang=lang %} {% if
jekyll.environment == 'production' %}
<!-- PWA -->
{% if site.pwa.enabled %}
<script
defer
src="{{ '/app.min.js' | relative_url }}?baseurl={{ site.baseurl | default: '' }}&register={{ site.pwa.cache.enabled }}"
></script>
{% endif %}
<!-- Web Analytics -->
{% for analytics in site.analytics %} {% capture str %}{{ analytics }}{%
endcapture %} {% assign platform = str | split: '{' | first %} {% if
site.analytics[platform].id and site.analytics[platform].id != empty %} {%
include analytics/{{ platform }}.html %} {% endif %} {% endfor %} {% endif %}
{% include metadata-hook.html %}
</head> </head>

View file

@ -63,12 +63,12 @@
{% capture script %}/assets/js/dist/{{ js }}.min.js{% endcapture %} {% capture script %}/assets/js/dist/{{ js }}.min.js{% endcapture %}
<script src="{{ script | relative_url }}"></script> <script defer src="{{ script | relative_url }}"></script>
{% if page.math %} {% if page.math %}
<!-- MathJax --> <!-- MathJax -->
<script src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script> <script async src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script>
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></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 %}
@ -85,26 +85,3 @@
{% endcase %} {% endcase %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if page.mermaid %}
{% include mermaid.html %}
{% endif %}
{% if jekyll.environment == 'production' %}
<!-- PWA -->
{% if site.pwa.enabled %}
<script
defer
src="{{ 'app.min.js' | relative_url }}?baseurl={{ site.baseurl | default: '' }}&register={{ site.pwa.cache.enabled }}"
></script>
{% endif %}
<!-- Web Analytics -->
{% for analytics in site.analytics %}
{% capture str %}{{ analytics }}{% endcapture %}
{% assign type = str | split: '{' | first %}
{% if site.analytics[type].id and site.analytics[type].id != empty %}
{% include analytics/{{ type }}.html %}
{% endif %}
{% endfor %}
{% endif %}

View file

@ -1,6 +1,6 @@
{% assign urls = include.urls | split: ',' %} {% assign urls = include.urls | split: ',' %}
{% assign combined_urls = nil %} {% assign combined_urls = null %}
{% assign domain = 'https://cdn.jsdelivr.net/' %} {% assign domain = 'https://cdn.jsdelivr.net/' %}
@ -15,12 +15,12 @@
{% endif %} {% endif %}
{% elsif url contains '//' %} {% elsif url contains '//' %}
<script src="{{ url }}"></script> <script defer src="{{ url }}"></script>
{% else %} {% else %}
<script src="{{ url | relative_url }}"></script> <script defer src="{{ url | relative_url }}"></script>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% if combined_urls %} {% if combined_urls %}
<script src="{{ combined_urls }}"></script> <script defer src="{{ combined_urls }}"></script>
{% endif %} {% endif %}

View file

@ -1,62 +0,0 @@
<!-- mermaid-js loader -->
<script type="text/javascript">
function updateMermaid(event) {
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
const mode = event.data.message;
if (typeof mermaid === 'undefined') {
return;
}
let expectedTheme = mode === ModeToggle.DARK_MODE ? 'dark' : 'default';
let config = { theme: expectedTheme };
{%- comment -%}
Re-render the SVG <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344>
{%- endcomment -%}
const mermaidList = document.getElementsByClassName('mermaid');
[...mermaidList].forEach((elem) => {
const svgCode = elem.previousSibling.children.item(0).innerHTML;
elem.innerHTML = svgCode;
elem.removeAttribute('data-processed');
});
mermaid.initialize(config);
mermaid.init(undefined, '.mermaid');
}
}
(function () {
let initTheme = 'default';
const html = document.documentElement;
if (
(html.hasAttribute('data-mode') && html.getAttribute('data-mode') === 'dark') ||
(!html.hasAttribute('data-mode') && window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
initTheme = 'dark';
}
let mermaidConf = {
theme: initTheme {%- comment -%} <default | dark | forest | neutral> {%- endcomment -%}
};
{%- comment -%} Create mermaid tag {%- endcomment -%}
const basicList = document.getElementsByClassName('language-mermaid');
[...basicList].forEach((elem) => {
const svgCode = elem.textContent;
const backup = elem.parentElement;
backup.classList.add('d-none');
{%- comment -%} create mermaid node {%- endcomment -%}
let mermaid = document.createElement('pre');
mermaid.classList.add('mermaid');
const text = document.createTextNode(svgCode);
mermaid.appendChild(text);
backup.after(mermaid);
});
mermaid.initialize(mermaidConf);
window.addEventListener('message', updateMermaid);
})();
</script>

View file

@ -1,116 +0,0 @@
<!-- Switch the mode between dark and light. -->
<script type="text/javascript">
class ModeToggle {
static get MODE_KEY() {
return 'mode';
}
static get MODE_ATTR() {
return 'data-mode';
}
static get DARK_MODE() {
return 'dark';
}
static get LIGHT_MODE() {
return 'light';
}
static get ID() {
return 'mode-toggle';
}
constructor() {
let self = this;
{%- comment -%} always follow the system prefers {%- endcomment -%}
this.sysDarkPrefers.addEventListener('change', () => {
if (self.hasMode) {
self.clearMode();
}
self.notify();
});
if (!this.hasMode) {
return;
}
if (this.isDarkMode) {
this.setDark();
} else {
this.setLight();
}
}
get sysDarkPrefers() {
return window.matchMedia('(prefers-color-scheme: dark)');
}
get isPreferDark() {
return this.sysDarkPrefers.matches;
}
get isDarkMode() {
return this.mode === ModeToggle.DARK_MODE;
}
get hasMode() {
return this.mode != null;
}
get mode() {
return sessionStorage.getItem(ModeToggle.MODE_KEY);
}
{%- comment -%} get the current mode on screen {%- endcomment -%}
get modeStatus() {
if (this.hasMode) {
return this.mode;
} else {
return this.isPreferDark ? ModeToggle.DARK_MODE : ModeToggle.LIGHT_MODE;
}
}
setDark() {
document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
}
setLight() {
document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
}
clearMode() {
document.documentElement.removeAttribute(ModeToggle.MODE_ATTR);
sessionStorage.removeItem(ModeToggle.MODE_KEY);
}
{%- comment -%}
Notify another plugins that the theme mode has changed
{%- endcomment -%}
notify() {
window.postMessage(
{
direction: ModeToggle.ID,
message: this.modeStatus
},
'*'
);
}
flipMode() {
if (this.hasMode) {
this.clearMode();
} else {
if (this.isPreferDark) {
this.setLight();
} else {
this.setDark();
}
}
this.notify();
}
}
const modeToggle = new ModeToggle();
</script>

View file

@ -19,7 +19,8 @@
{% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %} {% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %}
<script> <script>
{%- comment -%} Note: dependent library will be loaded in `js-selector.html` {%- endcomment -%} {% comment %} Note: dependent library will be loaded in `js-selector.html` {% endcomment %}
document.addEventListener('DOMContentLoaded', () => {
SimpleJekyllSearch({ SimpleJekyllSearch({
searchInput: document.getElementById('search-input'), searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('search-results'), resultsContainer: document.getElementById('search-results'),
@ -44,4 +45,5 @@
} }
} }
}); });
});
</script> </script>

View file

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

View file

@ -1,5 +1,5 @@
import { basic, initSidebar, initTopbar } from './modules/layouts'; import { basic, initSidebar, initTopbar } from './modules/layouts';
import { categoryCollapse } from './modules/plugins'; import { categoryCollapse } from './modules/components';
basic(); basic();
initSidebar(); initSidebar();

View file

@ -1,5 +1,5 @@
import { basic, initSidebar, initTopbar } from './modules/layouts'; import { basic, initSidebar, initTopbar } from './modules/layouts';
import { initLocaleDatetime, loadImg } from './modules/plugins'; import { initLocaleDatetime, loadImg } from './modules/components';
loadImg(); loadImg();
initLocaleDatetime(); initLocaleDatetime();

View file

@ -1,5 +1,5 @@
import { basic, initSidebar, initTopbar } from './modules/layouts'; import { basic, initSidebar, initTopbar } from './modules/layouts';
import { initLocaleDatetime } from './modules/plugins'; import { initLocaleDatetime } from './modules/components';
initSidebar(); initSidebar();
initTopbar(); initTopbar();

View file

@ -4,3 +4,7 @@ export { loadImg } from './components/img-loading';
export { imgPopup } from './components/img-popup'; export { imgPopup } from './components/img-popup';
export { initLocaleDatetime } from './components/locale-datetime'; export { initLocaleDatetime } from './components/locale-datetime';
export { initToc } from './components/toc'; export { initToc } from './components/toc';
export { loadMermaid } from './components/mermaid';
export { modeWatcher } from './components/mode-toggle';
export { back2top } from './components/back-to-top';
export { loadTooptip } from './components/tooltip-loader';

View file

@ -4,7 +4,6 @@
* Dependencies: https://github.com/biati-digital/glightbox * Dependencies: https://github.com/biati-digital/glightbox
*/ */
const html = document.documentElement;
const lightImages = '.popup:not(.dark)'; const lightImages = '.popup:not(.dark)';
const darkImages = '.popup:not(.light)'; const darkImages = '.popup:not(.light)';
let selector = lightImages; let selector = lightImages;
@ -33,26 +32,17 @@ export function imgPopup() {
document.querySelector('.popup.dark') === null document.querySelector('.popup.dark') === null
); );
if ( if (Theme.visualState === Theme.DARK) {
(html.hasAttribute('data-mode') &&
html.getAttribute('data-mode') === 'dark') ||
(!html.hasAttribute('data-mode') &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
selector = darkImages; selector = darkImages;
} }
let current = GLightbox({ selector: `${selector}` }); let current = GLightbox({ selector: `${selector}` });
if (hasDualImages && document.getElementById('mode-toggle')) { if (hasDualImages && Theme.switchable) {
let reverse = null; let reverse = null;
window.addEventListener('message', (event) => { window.addEventListener('message', (event) => {
if ( if (event.source === window && event.data && event.data.id === Theme.ID) {
event.source === window &&
event.data &&
event.data.direction === ModeToggle.ID
) {
updateImages(current, reverse); updateImages(current, reverse);
} }
}); });

View file

@ -0,0 +1,60 @@
/**
* Mermaid-js loader
*/
const MERMAID = 'mermaid';
const themeMapper = Theme.getThemeMapper('default', 'dark');
function refreshTheme(event) {
if (event.source === window && event.data && event.data.id === Theme.ID) {
// Re-render the SVG <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344>
const mermaidList = document.getElementsByClassName(MERMAID);
[...mermaidList].forEach((elem) => {
const svgCode = elem.previousSibling.children.item(0).innerHTML;
elem.textContent = svgCode;
elem.removeAttribute('data-processed');
});
const newTheme = themeMapper[Theme.visualState];
mermaid.initialize({ theme: newTheme });
mermaid.init(null, `.${MERMAID}`);
}
}
function setNode(elem) {
const svgCode = elem.textContent;
const backup = elem.parentElement;
backup.classList.add('d-none');
// Create mermaid node
const mermaid = document.createElement('pre');
mermaid.classList.add(MERMAID);
const text = document.createTextNode(svgCode);
mermaid.appendChild(text);
backup.after(mermaid);
}
export function loadMermaid() {
if (
typeof mermaid === 'undefined' ||
typeof mermaid.initialize !== 'function'
) {
return;
}
const initTheme = themeMapper[Theme.visualState];
let mermaidConf = {
theme: initTheme
};
const basicList = document.getElementsByClassName('language-mermaid');
[...basicList].forEach(setNode);
mermaid.initialize(mermaidConf);
if (Theme.switchable) {
window.addEventListener('message', refreshTheme);
}
}

View file

@ -0,0 +1,15 @@
/**
* Add listener for theme mode toggle
*/
const $toggle = document.getElementById('mode-toggle');
export function modeWatcher() {
if (!$toggle) {
return;
}
$toggle.addEventListener('click', () => {
Theme.flip();
});
}

View file

@ -1,14 +0,0 @@
/**
* Add listener for theme mode toggle
*/
const toggle = document.getElementById('mode-toggle');
export function modeWatcher() {
if (!toggle) {
return;
}
toggle.addEventListener('click', () => {
modeToggle.flipMode();
});
}

View file

@ -1,22 +0,0 @@
/**
* Expand or close the sidebar in mobile screens.
*/
const $sidebar = document.getElementById('sidebar');
const $trigger = document.getElementById('sidebar-trigger');
const $mask = document.getElementById('mask');
class SidebarUtil {
static #isExpanded = false;
static toggle() {
this.#isExpanded = !this.#isExpanded;
document.body.toggleAttribute('sidebar-display', this.#isExpanded);
$sidebar.classList.toggle('z-2', this.#isExpanded);
$mask.classList.toggle('d-none', !this.#isExpanded);
}
}
export function sidebarExpand() {
$trigger.onclick = $mask.onclick = () => SidebarUtil.toggle();
}

View file

@ -1,7 +1,7 @@
import { back2top } from '../components/back-to-top'; import { back2top, loadTooptip, modeWatcher } from '../components';
import { loadTooptip } from '../components/tooltip-loader';
export function basic() { export function basic() {
modeWatcher();
back2top(); back2top();
loadTooptip(); loadTooptip();
} }

View file

@ -1,7 +1,19 @@
import { modeWatcher } from '../components/mode-watcher'; const ATTR_DISPLAY = 'sidebar-display';
import { sidebarExpand } from '../components/sidebar'; const $sidebar = document.getElementById('sidebar');
const $trigger = document.getElementById('sidebar-trigger');
const $mask = document.getElementById('mask');
class SidebarUtil {
static #isExpanded = false;
static toggle() {
this.#isExpanded = !this.#isExpanded;
document.body.toggleAttribute(ATTR_DISPLAY, this.#isExpanded);
$sidebar.classList.toggle('z-2', this.#isExpanded);
$mask.classList.toggle('d-none', !this.#isExpanded);
}
}
export function initSidebar() { export function initSidebar() {
modeWatcher(); $trigger.onclick = $mask.onclick = () => SidebarUtil.toggle();
sidebarExpand();
} }

View file

@ -0,0 +1,135 @@
/**
* Theme management class
*
* To reduce flickering during page load, this script should be loaded synchronously.
*/
class Theme {
static #modeKey = 'mode';
static #modeAttr = 'data-mode';
static #darkMedia = window.matchMedia('(prefers-color-scheme: dark)');
static switchable = !document.documentElement.hasAttribute(this.#modeAttr);
static get DARK() {
return 'dark';
}
static get LIGHT() {
return 'light';
}
/**
* @returns {string} Theme mode identifier
*/
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,
* or the system dark mode state ('dark' or 'light').
*/
static get visualState() {
if (this.#hasMode) {
return this.#mode;
} else {
return this.#sysDark ? this.DARK : this.LIGHT;
}
}
static get #mode() {
return sessionStorage.getItem(this.#modeKey);
}
static get #isDarkMode() {
return this.#mode === this.DARK;
}
static get #hasMode() {
return this.#mode !== null;
}
static get #sysDark() {
return this.#darkMedia.matches;
}
/**
* Maps theme modes to provided values
* @param {string} light Value for light mode
* @param {string} dark Value for dark mode
* @returns {Object} Mapped values
*/
static getThemeMapper(light, dark) {
return {
[this.LIGHT]: light,
[this.DARK]: dark
};
}
/**
* Initializes the theme based on system preferences or stored mode
*/
static init() {
if (!this.switchable) {
return;
}
this.#darkMedia.addEventListener('change', () => {
const lastMode = this.#mode;
this.#clearMode();
if (lastMode !== this.visualState) {
this.#notify();
}
});
if (!this.#hasMode) {
return;
}
if (this.#isDarkMode) {
this.#setDark();
} else {
this.#setLight();
}
}
/**
* Flips the current theme mode
*/
static flip() {
if (this.#hasMode) {
this.#clearMode();
} else {
this.#sysDark ? this.#setLight() : this.#setDark();
}
this.#notify();
}
static #setDark() {
document.documentElement.setAttribute(this.#modeAttr, this.DARK);
sessionStorage.setItem(this.#modeKey, this.DARK);
}
static #setLight() {
document.documentElement.setAttribute(this.#modeAttr, this.LIGHT);
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 }, '*');
}
}
Theme.init();
export default Theme;

View file

@ -1,9 +1,15 @@
import { basic, initSidebar, initTopbar } from './modules/layouts'; import { basic, initSidebar, initTopbar } from './modules/layouts';
import { loadImg, imgPopup, initClipboard } from './modules/plugins'; import {
loadImg,
imgPopup,
initClipboard,
loadMermaid
} from './modules/components';
loadImg(); loadImg();
imgPopup(); imgPopup();
initSidebar(); initSidebar();
initTopbar(); initTopbar();
initClipboard(); initClipboard();
loadMermaid();
basic(); basic();

View file

@ -5,8 +5,9 @@ import {
imgPopup, imgPopup,
initLocaleDatetime, initLocaleDatetime,
initClipboard, initClipboard,
initToc initToc,
} from './modules/plugins'; loadMermaid
} from './modules/components';
loadImg(); loadImg();
initToc(); initToc();
@ -15,4 +16,5 @@ initSidebar();
initLocaleDatetime(); initLocaleDatetime();
initClipboard(); initClipboard();
initTopbar(); initTopbar();
loadMermaid();
basic(); basic();

View file

@ -33,7 +33,7 @@ layout: compress
</main> </main>
<!-- panel --> <!-- 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"> <div class="access">
{% include_cached update-list.html lang=lang %} {% include_cached update-list.html lang=lang %}
{% include_cached trending-tags.html lang=lang %} {% include_cached trending-tags.html lang=lang %}
@ -74,8 +74,12 @@ layout: compress
{% include_cached notification.html lang=lang %} {% include_cached notification.html lang=lang %}
{% endif %} {% endif %}
<!-- JavaScripts --> <!-- Embedded scripts -->
{% include js-selector.html lang=lang %}
{% for _include in layout.script_includes %}
{% assign _include_path = _include | append: '.html' %}
{% include {{ _include_path }} %}
{% endfor %}
{% include_cached search-loader.html lang=lang %} {% include_cached search-loader.html lang=lang %}
</body> </body>

View file

@ -6,7 +6,8 @@ panel_includes:
tail_includes: tail_includes:
- related-posts - related-posts
- post-nav - post-nav
- comments script_includes:
- comment
--- ---
{% include lang.html %} {% include lang.html %}

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 @@
/* @use 'variables' as v;
* Mainly scss modules, only imported to `assets/css/main.scss` @use 'mixins' as mx;
*/
/* ---------- scss placeholder --------- */
%heading { %heading {
color: var(--heading-color); color: var(--heading-color);
font-weight: 400; font-weight: 400;
font-family: $font-family-heading; font-family: v.$font-family-heading;
scroll-margin-top: 3.5rem; scroll-margin-top: 3.5rem;
} }
@ -82,7 +79,7 @@
} }
%rounded { %rounded {
border-radius: $radius-lg; border-radius: v.$radius-lg;
} }
%img-caption { %img-caption {
@ -112,14 +109,8 @@
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
@mixin text-ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
%text-ellipsis { %text-ellipsis {
@include text-ellipsis; @include mx.text-ellipsis;
} }
%text-highlight { %text-highlight {
@ -151,65 +142,19 @@
} }
} }
/* ---------- scss mixin --------- */ %code-snippet-bg {
background-color: var(--highlight-bg-color);
@mixin mt-mb($value) {
margin-top: $value;
margin-bottom: $value;
} }
@mixin ml-mr($value) { %code-snippet-padding {
margin-left: $value; padding-left: 1rem;
margin-right: $value; padding-right: 1.5rem;
} }
@mixin pt-pb($val) { %max-w-100 {
padding-top: $val; max-width: 100%;
padding-bottom: $val;
} }
@mixin pl-pr($val, $important: false) { %panel-border {
@if $important { border-left: 1px solid var(--main-border-color);
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);
}
}
}
} }

View file

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

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 @@
/* @use '../abstracts/variables' as v;
* The syntax highlight. @use '../abstracts/breakpoints' as bp;
*/ @use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
@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;
}
.highlighter-rouge { .highlighter-rouge {
color: var(--highlighter-rouge-color); color: var(--highlighter-rouge-color);
@ -59,7 +22,7 @@ html {
pre { pre {
margin-bottom: 0; margin-bottom: 0;
font-size: $code-font-size; font-size: v.$code-font-size;
line-height: 1.4rem; line-height: 1.4rem;
word-wrap: normal; /* Fixed Safari overflow-x */ word-wrap: normal; /* Fixed Safari overflow-x */
} }
@ -101,10 +64,10 @@ code {
color: var(--code-color); color: var(--code-color);
&.highlighter-rouge { &.highlighter-rouge {
font-size: $code-font-size; font-size: v.$code-font-size;
padding: 3px 5px; padding: 3px 5px;
word-break: break-word; word-break: break-word;
border-radius: $radius-sm; border-radius: v.$radius-sm;
background-color: var(--inline-code-bg); background-color: var(--inline-code-bg);
} }
@ -150,9 +113,42 @@ div[class^='language-'] {
box-shadow: var(--language-border-color) 0 0 0 1px; box-shadow: var(--language-border-color) 0 0 0 1px;
.content > & { .content > & {
@include ml-mr(-1rem); @include mx.ml-mr(-1rem);
border-radius: 0; 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 { .highlight {
@ -184,18 +180,18 @@ div {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
height: $code-header-height; height: v.$code-header-height;
margin-left: 0.75rem; margin-left: 0.75rem;
margin-right: 0.25rem; margin-right: 0.25rem;
/* the label block */ /* the label block */
span { span {
line-height: $code-header-height; line-height: v.$code-header-height;
/* label icon */ /* label icon */
i { i {
font-size: 1rem; font-size: 1rem;
width: $code-icon-width; width: v.$code-icon-width;
color: var(--code-header-icon-color); color: var(--code-header-icon-color);
&.small { &.small {
@ -223,8 +219,8 @@ div {
@extend %rounded; @extend %rounded;
border: 1px solid transparent; border: 1px solid transparent;
height: $code-header-height; height: v.$code-header-height;
width: $code-header-height; width: v.$code-header-height;
padding: 0; padding: 0;
background-color: inherit; 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'; @use 'vendors/bootstrap';
@import 'main'; @use 'main';

View file

@ -1,13 +1,4 @@
@import 'colors/typography-light'; @forward 'base';
@import 'colors/typography-dark'; @forward 'components';
@import 'addon/variables'; @forward 'layout';
@import 'variables-hook'; @forward 'pages';
@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';

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* @use '../abstracts/breakpoints' as bp;
Style for page Category and Tag @use '../abstracts/mixins' as mx;
*/ @use '../abstracts/placeholders';
.dash { .dash {
margin: 0 0.5rem 0.6rem 0.5rem; margin: 0 0.5rem 0.6rem 0.5rem;
@ -24,6 +24,10 @@
position: relative; position: relative;
top: 0.6rem; top: 0.6rem;
margin-right: 0.5rem; margin-right: 0.5rem;
@include bp.lt(bp.get(sm)) {
margin: 0 0.5rem;
}
} }
/* post's title */ /* post's title */
@ -31,6 +35,10 @@
@extend %no-bottom-border; @extend %no-bottom-border;
font-size: 1.1rem; font-size: 1.1rem;
@include bp.lt(bp.get(sm)) {
@include mx.text-ellipsis;
}
} }
} }
} }
@ -53,18 +61,3 @@
margin-bottom: -1px; /* Avoid jumping */ 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 @@
/* @use '../abstracts/variables' as v;
Style for Homepage @use '../abstracts/breakpoints' as bp;
*/ @use '../abstracts/placeholders';
#post-list { #post-list {
margin-top: 2rem; margin-top: 2rem;
@include bp.lg {
margin-top: 2.5rem;
}
.card-wrapper { .card-wrapper {
&:hover { &:hover {
text-decoration: none; text-decoration: none;
@ -20,7 +24,11 @@
background: none; background: none;
%img-radius { %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 { .preview-img {
@ -35,6 +43,10 @@
height: 100%; height: 100%;
padding: 1rem; padding: 1rem;
@include bp.md {
padding: 1.75rem 1.75rem 1.25rem;
}
.card-title { .card-title {
@extend %text-clip; @extend %text-clip;
@ -46,7 +58,12 @@
color: var(--text-muted-color) !important; color: var(--text-muted-color) !important;
} }
.card-text.content { .card-text {
@include bp.md {
display: inherit !important;
}
&.content {
@extend %muted; @extend %muted;
p { p {
@ -56,6 +73,7 @@
margin: 0; margin: 0;
} }
} }
}
.post-meta { .post-meta {
@extend %muted; @extend %muted;
@ -63,6 +81,10 @@
i { i {
&:not(:first-child) { &:not(:first-child) {
margin-left: 1.5rem; margin-left: 1.5rem;
@include bp.md {
margin-left: 1.75rem;
}
} }
} }
@ -87,11 +109,28 @@
font-family: Lato, sans-serif; font-family: Lato, sans-serif;
justify-content: space-evenly; justify-content: space-evenly;
@include bp.lg {
font-size: 0.85rem;
justify-content: center;
}
a:hover { a:hover {
text-decoration: none; text-decoration: none;
} }
.page-item { .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 { .page-link {
color: var(--btn-patinator-text-color); color: var(--btn-patinator-text-color);
padding: 0 0.6rem; padding: 0 0.6rem;
@ -125,64 +164,10 @@
} }
} }
} /* .page-item */ } /* .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; 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 @@
/** @use '../abstracts/variables' as v;
* Post-specific styles @use '../abstracts/breakpoints' as bp;
*/ @use '../abstracts/mixins' as mx;
@use '../abstracts/placeholders';
%btn-post-nav { %-btn-post-nav {
width: 50%; width: 50%;
position: relative; position: relative;
border-color: var(--btn-border-color); border-color: var(--btn-border-color);
} }
@mixin dot($pl: 0.25rem, $pr: 0.25rem) { @mixin -dot($pl: 0.25rem, $pr: 0.25rem) {
content: '\2022'; content: '\2022';
padding-left: $pl; padding-left: $pl;
padding-right: $pr; padding-right: $pr;
@ -24,7 +25,7 @@ header {
.post-meta { .post-meta {
span + span::before { span + span::before {
@include dot; @include -dot;
} }
em, em,
@ -113,9 +114,20 @@ header {
} /* .share-wrapper */ } /* .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 { .share-mastodon {
/* See: https://github.com/justinribeiro/share-to-mastodon#properties */ /* 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-dialog-background-color: var(--card-bg);
--wc-stm-form-button-border: 1px solid var(--btn-border-color); --wc-stm-form-button-border: 1px solid var(--btn-border-color);
--wc-stm-form-submit-background-color: var(--sidebar-btn-bg); --wc-stm-form-submit-background-color: var(--sidebar-btn-bg);
@ -139,8 +151,13 @@ header {
} }
.post-navigation { .post-navigation {
@include bp.lt(bp.get(lg)) {
@include mx.pl-pr(0);
@include mx.ml-mr(-0.5rem);
}
.btn { .btn {
@extend %btn-post-nav; @extend %-btn-post-nav;
&:not(:hover) { &:not(:hover) {
color: var(--link-color); color: var(--link-color);
@ -153,7 +170,7 @@ header {
} }
&.disabled { &.disabled {
@extend %btn-post-nav; @extend %-btn-post-nav;
pointer-events: auto; pointer-events: auto;
cursor: not-allowed; cursor: not-allowed;
@ -173,12 +190,12 @@ header {
} }
&:first-child { &:first-child {
border-radius: $radius-lg 0 0 $radius-lg; border-radius: v.$radius-lg 0 0 v.$radius-lg;
left: 0.5px; left: 0.5px;
} }
&:last-child { &:last-child {
border-radius: 0 $radius-lg $radius-lg 0; border-radius: 0 v.$radius-lg v.$radius-lg 0;
right: 0.5px; right: 0.5px;
} }
} }
@ -229,14 +246,26 @@ header {
} }
/* TOC panel */ /* TOC panel */
#toc-wrapper {
border-left: 1px solid rgba(158, 158, 158, 0.17); %top-cover {
position: -webkit-sticky; content: '';
display: block;
position: sticky; 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; transition: top 0.2s ease-in-out;
-webkit-animation: fade-up 0.8s; -webkit-animation: fade-up 0.8s;
animation: fade-up 0.8s; animation: fade-up 0.8s;
overflow-y: auto;
max-height: calc(100vh - 2rem);
scrollbar-width: none;
margin-top: 2rem;
ul { ul {
list-style: none; list-style: none;
@ -249,6 +278,10 @@ header {
margin: 0.4rem 0; margin: 0.4rem 0;
} }
&:first-child {
margin-top: 0;
}
a { a {
padding: 0.2rem 0 0.2rem 1.25rem; padding: 0.2rem 0 0.2rem 1.25rem;
} }
@ -278,7 +311,6 @@ header {
&::before { &::before {
display: inline-block; display: inline-block;
width: 1px; width: 1px;
left: -1px;
height: 1.25rem; height: 1.25rem;
background-color: var(--toc-highlight) !important; background-color: var(--toc-highlight) !important;
} }
@ -288,6 +320,30 @@ header {
padding-left: 0.75rem; 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: 3.25rem;
margin-left: -1px;
background: linear-gradient(transparent, var(--main-bg) 70%);
}
> * {
@extend %panel-border;
}
} }
/* --- TOC button, bar and popup in mobile/tablet --- */ /* --- TOC button, bar and popup in mobile/tablet --- */
@ -298,23 +354,27 @@ header {
top: 0; top: 0;
z-index: 1; z-index: 1;
margin: 0 -1rem; margin: 0 -1rem;
height: $topbar-height; height: v.$topbar-height;
background: var(--main-bg); background: var(--main-bg);
border-bottom: 1px solid var(--main-border-color); border-bottom: 1px solid var(--main-border-color);
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
@extend %btn-color; @extend %btn-color;
@include bp.xl {
display: none !important;
}
.label { .label {
@extend %heading; @extend %heading;
margin-left: 0.25rem; margin-left: 0.375rem;
padding: 0 0.75rem; padding: 0 0.75rem;
color: inherit; color: inherit;
} }
&.invisible { &.invisible {
top: -$topbar-height; top: -#{v.$topbar-height};
transition: none; transition: none;
} }
} }
@ -322,11 +382,15 @@ header {
#toc-solo-trigger { #toc-solo-trigger {
color: var(--text-muted-color); color: var(--text-muted-color);
border-color: var(--btn-border-color); border-color: var(--btn-border-color);
border-radius: $radius-lg; border-radius: v.$radius-lg;
@include bp.xl {
display: none !important;
}
.label { .label {
font-size: 1rem; font-size: 1rem;
font-family: $font-family-heading; font-family: v.$font-family-heading;
} }
&:hover { &:hover {
@ -338,7 +402,7 @@ header {
@mixin slide-in { @mixin slide-in {
from { from {
opacity: 0.7; opacity: 0.7;
transform: translateY(-$topbar-height); transform: translateY(-#{v.$topbar-height});
} }
to { to {
@ -354,7 +418,7 @@ header {
} }
100% { 100% {
transform: translateY(-$topbar-height); transform: translateY(-#{v.$topbar-height});
opacity: 0; opacity: 0;
} }
} }
@ -375,129 +439,11 @@ header {
@include slide-out; @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 --- */
#related-posts { #related-posts {
> h3 { > h3 {
@include label(1.1rem, 600); @include mx.label(1.1rem, 600);
} }
time { time {
@ -532,6 +478,7 @@ header {
.utterances { .utterances {
max-width: 100%; max-width: 100%;
min-height: 269px;
} }
%btn-share-hover { %btn-share-hover {
@ -539,47 +486,23 @@ header {
} }
.share-label { .share-label {
@include label(inherit, 400, inherit); @include mx.label(inherit, 400, inherit);
&::after { &::after {
content: ':'; 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); 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, h2,
h3, h3,
h4 { h4 {
@include bp.xl {
scroll-margin-top: 2rem; 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 @@
/* @use '../abstracts/breakpoints' as bp;
Styles for Tab Tags
*/
.tag { .tag {
border-radius: 0.7em; border-radius: 0.7em;
@ -17,3 +15,9 @@
font-family: Oswald, sans-serif; font-family: Oswald, sans-serif;
} }
} }
#tags {
@include bp.lt(bp.get(lg)) {
justify-content: center !important;
}
}

View file

@ -1,8 +1,6 @@
/* @mixin styles {
* The main dark mode styles color-scheme: dark;
*/
@mixin dark-scheme {
/* Framework color */ /* Framework color */
--main-bg: rgb(27, 27, 30); --main-bg: rgb(27, 27, 30);
--mask-bg: rgb(68, 69, 70); --mask-bg: rgb(68, 69, 70);
@ -100,7 +98,18 @@
--timeline-color: rgb(63, 65, 68); --timeline-color: rgb(63, 65, 68);
--timeline-year-dot-color: var(--timeline-color); --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 { .light {
display: none; display: none;
@ -144,4 +153,151 @@
#disqus_thread { #disqus_thread {
color-scheme: none; 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' -%} {%- if jekyll.environment == 'production' -%}
.bundle .bundle
{%- endif -%} {%- endif -%}

@ -1 +1 @@
Subproject commit a231bc7e2c67198e604950cb2be9147a0b2020c0 Subproject commit b9e18a1510e3be5de250ed34205da318b76474e0

View file

@ -1,5 +1,21 @@
# Changelog # Changelog
## [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) ## [7.1.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.1.0...v7.1.1) (2024-09-23)
### Bug Fixes ### Bug Fixes

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.1.1" spec.version = "7.2.0"
spec.authors = ["Cotes Chung"] spec.authors = ["Cotes Chung"]
spec.email = ["cotes.chung@gmail.com"] spec.email = ["cotes.chung@gmail.com"]

View file

@ -1,6 +1,6 @@
{ {
"name": "jekyll-theme-chirpy", "name": "jekyll-theme-chirpy",
"version": "7.1.1", "version": "7.2.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",
@ -15,7 +15,7 @@
"homepage": "https://github.com/cotes2020/jekyll-theme-chirpy/", "homepage": "https://github.com/cotes2020/jekyll-theme-chirpy/",
"scripts": { "scripts": {
"build": "concurrently npm:build:*", "build": "concurrently npm:build:*",
"build:css": "purgecss -c purgecss.config.js", "build:css": "node purgecss.js",
"build:js": "rollup -c --bundleConfigAsCjs --environment BUILD:production", "build:js": "rollup -c --bundleConfigAsCjs --environment BUILD:production",
"watch:js": "rollup -c --bundleConfigAsCjs -w", "watch:js": "rollup -c --bundleConfigAsCjs -w",
"lint:scss": "stylelint _sass/**/*.scss", "lint:scss": "stylelint _sass/**/*.scss",
@ -28,24 +28,25 @@
"bootstrap": "^5.3.3" "bootstrap": "^5.3.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.26.0",
"@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-class-properties": "^7.25.9",
"@babel/preset-env": "^7.25.4", "@babel/plugin-transform-private-methods": "^7.25.9",
"@commitlint/cli": "^19.5.0", "@babel/preset-env": "^7.26.0",
"@commitlint/config-conventional": "^19.5.0", "@commitlint/cli": "^19.6.0",
"@commitlint/config-conventional": "^19.6.0",
"@rollup/plugin-babel": "^6.0.4", "@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", "@rollup/plugin-terser": "^0.4.4",
"@semantic-release/changelog": "^6.0.3", "@semantic-release/changelog": "^6.0.3",
"@semantic-release/exec": "^6.0.3", "@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"concurrently": "^9.0.1", "concurrently": "^9.1.0",
"conventional-changelog-conventionalcommits": "^8.0.0", "conventional-changelog-conventionalcommits": "^8.0.0",
"husky": "^9.1.6", "husky": "^9.1.7",
"purgecss": "^6.0.0", "purgecss": "^7.0.2",
"rollup": "^4.21.3", "rollup": "^4.27.4",
"semantic-release": "^24.1.1", "semantic-release": "^24.2.0",
"stylelint": "^16.9.0", "stylelint": "^16.10.0",
"stylelint-config-standard-scss": "^13.1.0" "stylelint-config-standard-scss": "^13.1.0"
}, },
"prettier": { "prettier": {
@ -67,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": { "release": {
"branches": [ "branches": [
"production" "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

@ -34,24 +34,32 @@ function insertFrontmatter() {
}; };
} }
function build(filename, { src = SRC_DEFAULT, jekyll = false } = {}) { function build(
filename,
{ src = SRC_DEFAULT, jekyll = false, outputName = null } = {}
) {
const input = `${src}/${filename}.js`;
return { return {
input: `${src}/${filename}.js`, input,
output: { output: {
file: `${DIST}/${filename}.min.js`, file: `${DIST}/${filename}.min.js`,
format: 'iife', format: 'iife',
name: 'Chirpy', ...(outputName !== null && { name: outputName }),
banner, banner,
sourcemap: !isProd && !jekyll sourcemap: !isProd && !jekyll
}, },
watch: { watch: {
include: `${src}/**` include: input
}, },
plugins: [ plugins: [
babel({ babel({
babelHelpers: 'bundled', babelHelpers: 'bundled',
presets: ['@babel/env'], presets: ['@babel/env'],
plugins: ['@babel/plugin-transform-class-properties'] plugins: [
'@babel/plugin-transform-class-properties',
'@babel/plugin-transform-private-methods'
]
}), }),
nodeResolve(), nodeResolve(),
isProd && terser(), isProd && terser(),
@ -69,6 +77,7 @@ export default [
build('page'), build('page'),
build('post'), build('post'),
build('misc'), build('misc'),
build('theme', { src: `${SRC_DEFAULT}/modules`, outputName: 'Theme' }),
build('app', { src: SRC_PWA, jekyll: true }), build('app', { src: SRC_PWA, jekyll: true }),
build('sw', { src: SRC_PWA, jekyll: true }) build('sw', { src: SRC_PWA, jekyll: true })
]; ];

View file

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

View file

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