From c656945518fa360e05e337643f30704992b68351 Mon Sep 17 00:00:00 2001 From: Tom Herni Date: Tue, 16 Jun 2026 22:24:20 +0200 Subject: [PATCH 1/2] chore: replace clean-css with lightningcss --- package-lock.json | 287 +++++++++++++++++++++++++++-- package.json | 3 +- src/generator/optimize/optimize.ts | 9 +- 3 files changed, 280 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8415773..61bd911 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,18 +9,17 @@ "version": "1.0.0", "devDependencies": { "@eslint/js": "^10.0.1", - "@types/clean-css": "^4.2.11", "@types/html-minifier-terser": "^7.0.2", "@types/js-yaml": "^4.0.9", "@types/node": "^24.13.2", "@types/prismjs": "^1.26.3", "canvas": "^3.0.1", - "clean-css": "^5.3.3", "eslint": "^10.5.0", "globals": "^17.6.0", "html-minifier-terser": "^7.2.0", "husky": "^9.1.7", "js-yaml": "^4.1.0", + "lightningcss": "^1.32.0", "lint-staged": "^17.0.7", "marked": "^11.1.0", "prettier": "^3.8.4", @@ -1029,17 +1028,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/clean-css": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/@types/clean-css/-/clean-css-4.2.11.tgz", - "integrity": "sha512-Y8n81lQVTAfP2TOdtJJEsCoYl1AnOkqDqMvXb9/7pfgZZ7r8YrEyurrAvAoAjHOGXKRybay+5CsExqIH6liccw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "source-map": "^0.6.0" - } - }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -2763,6 +2751,279 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", diff --git a/package.json b/package.json index a2abe29..5317afd 100644 --- a/package.json +++ b/package.json @@ -20,18 +20,17 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", - "@types/clean-css": "^4.2.11", "@types/html-minifier-terser": "^7.0.2", "@types/js-yaml": "^4.0.9", "@types/node": "^24.13.2", "@types/prismjs": "^1.26.3", "canvas": "^3.0.1", - "clean-css": "^5.3.3", "eslint": "^10.5.0", "globals": "^17.6.0", "html-minifier-terser": "^7.2.0", "husky": "^9.1.7", "js-yaml": "^4.1.0", + "lightningcss": "^1.32.0", "lint-staged": "^17.0.7", "marked": "^11.1.0", "prettier": "^3.8.4", diff --git a/src/generator/optimize/optimize.ts b/src/generator/optimize/optimize.ts index dfb9195..48c7620 100644 --- a/src/generator/optimize/optimize.ts +++ b/src/generator/optimize/optimize.ts @@ -1,4 +1,4 @@ -import CleanCSS from 'clean-css'; +import { transform } from 'lightningcss'; import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; @@ -32,9 +32,10 @@ export async function optimize(): Promise { */ function optimizeCssFiles(): void { for (const file of findFilesByExtension('css', DIR_DIST)) { - const input = fs.readFileSync(file, 'utf8'); - const minified = new CleanCSS().minify(input).styles; - fs.writeFileSync(file, minified); + const input = fs.readFileSync(file); + // `filename` is required but unused. + const { code } = transform({ filename: 'foo', code: input, minify: true }); + fs.writeFileSync(file, code); } } From 0af8a2786560c5106daf79d93b2e985111bd59eb Mon Sep 17 00:00:00 2001 From: Tom Herni Date: Wed, 17 Jun 2026 20:03:26 +0200 Subject: [PATCH 2/2] feat: use CSS nesting --- src/static/assets/css/styles-lazy.css | 116 +++-- src/static/assets/css/styles.css | 720 +++++++++++++------------- 2 files changed, 416 insertions(+), 420 deletions(-) diff --git a/src/static/assets/css/styles-lazy.css b/src/static/assets/css/styles-lazy.css index 6d2aaf7..569cdab 100644 --- a/src/static/assets/css/styles-lazy.css +++ b/src/static/assets/css/styles-lazy.css @@ -12,76 +12,78 @@ --prism-property: #871094; --prism-regex: #264eff; --prism-tag: #0033b3; -} -:root[data-theme='dark'] { - --prism-font: #bcbec4; - --prism-string: #6aab73; - --prism-comment: #7a7e85; - --prism-function: #56a8f5; - --prism-keyword: #cf8e6d; - --prism-number: #2aacb8; - --prism-property: #c77dbb; - --prism-regex: #42c3d4; - --prism-tag: #d5b778; + &[data-theme='dark'] { + --prism-font: #bcbec4; + --prism-string: #6aab73; + --prism-comment: #7a7e85; + --prism-function: #56a8f5; + --prism-keyword: #cf8e6d; + --prism-number: #2aacb8; + --prism-property: #c77dbb; + --prism-regex: #42c3d4; + --prism-tag: #d5b778; + } } code[class*='language-'] { color: var(--prism-font); } -.token.attr-name, -.token.punctuation, -.token.operator, -.token.doctype .token.name { - color: var(--prism-font); -} - -.token.attr-value, -.token.string { - color: var(--prism-string); -} - -.token.comment { - color: var(--prism-comment); -} - -.token.function { - color: var(--prism-function); -} - -.token.keyword, -.token.rule { - color: var(--prism-keyword); -} - -.token.number { - color: var(--prism-number); -} - -.token.property { - color: var(--prism-property); -} - -.token.regex { - color: var(--prism-regex); -} - -.token.doctype, -.token.tag { - color: var(--prism-tag); +.token { + &.attr-name, + &.punctuation, + &.operator, + &.doctype .token.name { + color: var(--prism-font); + } + + &.attr-value, + &.string { + color: var(--prism-string); + } + + &.comment { + color: var(--prism-comment); + } + + &.function { + color: var(--prism-function); + } + + &.keyword, + &.rule { + color: var(--prism-keyword); + } + + &.number { + color: var(--prism-number); + } + + &.property { + color: var(--prism-property); + } + + &.regex { + color: var(--prism-regex); + } + + &.doctype, + &.tag { + color: var(--prism-tag); + } } /* Language overwrites */ code[class='language-css'] { color: var(--prism-string); -} -code[class='language-css'] .token.property { - color: var(--prism-font); -} + .token.property { + color: var(--prism-font); + } -code[class='language-css'] .token.selector { - color: var(--prism-tag); + .token.selector { + color: var(--prism-tag); + } } diff --git a/src/static/assets/css/styles.css b/src/static/assets/css/styles.css index bee681f..8f68251 100644 --- a/src/static/assets/css/styles.css +++ b/src/static/assets/css/styles.css @@ -17,19 +17,19 @@ /* Effects */ --hover-transition-duration: 150ms; --theme-transition-duration: 250ms; -} - -:root[data-theme='dark'] { - color-scheme: dark; - /* Colors */ - --color-font: hsl(30deg 27% 91%); - --color-background: hsl(0deg 5% 9%); - --color-shade-7: hsl(30deg 27% 91% / 7%); - --color-shade-10: hsl(30deg 27% 91% / 10%); - --color-shade-40: hsl(30deg 27% 91% / 45%); - --color-shade-55: hsl(30deg 27% 91% / 55%); - --color-shade-75: hsl(30deg 27% 91% / 70%); + &[data-theme='dark'] { + color-scheme: dark; + + /* Colors */ + --color-font: hsl(30deg 27% 91%); + --color-background: hsl(0deg 5% 9%); + --color-shade-7: hsl(30deg 27% 91% / 7%); + --color-shade-10: hsl(30deg 27% 91% / 10%); + --color-shade-40: hsl(30deg 27% 91% / 45%); + --color-shade-55: hsl(30deg 27% 91% / 55%); + --color-shade-75: hsl(30deg 27% 91% / 70%); + } } @font-face { @@ -60,10 +60,8 @@ html { font-size: 9px; -} -@media (min-width: 768px) { - html { + @media (min-width: 768px) { font-size: 10px; } } @@ -164,54 +162,52 @@ h3 { justify-content: space-between; font-weight: 600; margin-bottom: 6.4rem; -} -.site-header a { - text-decoration-color: transparent; -} - -.site-header ul { - display: flex; - align-items: center; - margin: 0; - padding: 0; - list-style: none; -} + a { + text-decoration-color: transparent; + } -.site-header .logo { - margin-right: 1.6rem; - font-size: 2.4rem; -} + ul { + display: flex; + align-items: center; + margin: 0; + padding: 0; + list-style: none; + } -.site-header .logo span { - color: var(--color-highlight); -} + .logo { + margin-right: 1.6rem; + font-size: 2.4rem; -.site-header .link { - margin-right: 0.8rem; - padding: 0.4rem 1rem; - border-radius: 0.4rem; -} + @media (min-width: 480px) { + margin-right: 2.8rem; + } + } -@media (min-width: 480px) { - .site-header .logo { - margin-right: 2.8rem; + .logo span { + color: var(--color-highlight); } - .site-header .link { - margin-right: 1.2rem; - padding: 0.6rem 1.4rem; + .link { + margin-right: 0.8rem; + padding: 0.4rem 1rem; + border-radius: 0.4rem; + + @media (min-width: 480px) { + margin-right: 1.2rem; + padding: 0.6rem 1.4rem; + } } -} -@media (hover: hover) and (pointer: fine) { - .site-header a:hover { - text-decoration-color: var(--color-highlight); + @media (hover: hover) and (pointer: fine) { + a:hover { + text-decoration-color: var(--color-highlight); + } } -} -.site-header .link.active { - background-color: var(--color-shade-10); + .link.active { + background-color: var(--color-shade-10); + } } /* Profile picture */ @@ -222,14 +218,14 @@ h3 { border: 0.2rem solid var(--color-highlight); border-radius: 50%; overflow: hidden; -} -.profile-picture img { - display: block; - width: 100%; - height: 100%; - max-width: 100%; - border-radius: 50%; + img { + display: block; + width: 100%; + height: 100%; + max-width: 100%; + border-radius: 50%; + } } /* Tag list */ @@ -240,324 +236,320 @@ h3 { padding: 0; font-size: 1.6rem; list-style: none; -} -.tag-list li { - flex: 0 0 auto; - display: block; - margin: 1.6rem 1.6rem 0 0; -} + li { + flex: 0 0 auto; + display: block; + margin: 1.6rem 1.6rem 0 0; + } -.tag-list.condensed li { - margin: 0.8rem 0.8rem 0 0; -} + &.condensed li { + margin: 0.8rem 0.8rem 0 0; + } -.tag-list a { - display: block; - padding: 0.7rem 1.4rem 0.7rem 1.2rem; - color: var(--color-shade-75); - line-height: normal; - text-decoration: none; - border-radius: 0.4rem; - background-color: var(--color-shade-7); -} + a { + display: block; + padding: 0.7rem 1.4rem 0.7rem 1.2rem; + color: var(--color-shade-75); + line-height: normal; + text-decoration: none; + border-radius: 0.4rem; + background-color: var(--color-shade-7); + } -.tag-list.condensed a { - padding: 0.6rem 1.4rem 0.6rem 1.2rem; -} + &.condensed a { + padding: 0.6rem 1.4rem 0.6rem 1.2rem; + } -.tag-list .hashtag { - margin-right: 0.1rem; - pointer-events: none; - opacity: 0.7; -} + .hashtag { + margin-right: 0.1rem; + pointer-events: none; + opacity: 0.7; + } -.tag-list .link-effect { - text-decoration-color: transparent; - text-decoration-thickness: 0.1rem; -} + .link-effect { + text-decoration-color: transparent; + text-decoration-thickness: 0.1rem; + } -@media (hover: hover) and (pointer: fine) { - .tag-list a:hover .link-effect { - text-decoration-color: var(--color-highlight); + @media (hover: hover) and (pointer: fine) { + a:hover .link-effect { + text-decoration-color: var(--color-highlight); + } } } /* Formatted content */ .formatted-content { font-size: 2.2rem; -} - -.formatted-content ol, -.formatted-content ul, -.formatted-content p { - margin: 2.2rem 0 0; -} - -.formatted-content h2 { - margin: 4.8rem 0 -1.2rem; - font-size: 2.8rem; -} - -.formatted-content h3 { - margin: 3.2rem 0 -1.6rem; - font-size: 2.2rem; -} -/* Regular links */ -.formatted-content a:not(.anchor) { - font-weight: 600; -} + ol, + ul, + p { + margin: 2.2rem 0 0; + } -.formatted-content a.anchor { - margin-left: 0.2rem; - padding: 0 0.6rem; - color: var(--color-shade-40); - font-size: 0.8em; - text-decoration: none; -} + h2 { + margin: 4.8rem 0 -1.2rem; + font-size: 2.8rem; + } -@media (hover: hover) and (pointer: fine) { - .formatted-content a.anchor:hover { - color: var(--color-highlight); + h3 { + margin: 3.2rem 0 -1.6rem; + font-size: 2.2rem; } -} -.formatted-content blockquote { - margin-block: 3.2rem; - margin-inline: calc(var(--wrapper-gutter-inline) * -1); - padding-block: 2.4rem; - padding-inline: var(--wrapper-gutter-inline); - font-weight: 300; - font-size: 2.6rem; - text-align: center; - background-color: var(--color-shade-7); - border-radius: 0.4rem; -} + /* Regular links */ + a:not(.anchor) { + font-weight: 600; + } -@media (min-width: 480px) { - .formatted-content blockquote { - margin-inline: 0; - padding-inline: 3.2rem; + a.anchor { + margin-left: 0.2rem; + padding: 0 0.6rem; + color: var(--color-shade-40); + font-size: 0.8em; + text-decoration: none; + + @media (hover: hover) and (pointer: fine) { + &:hover { + color: var(--color-highlight); + } + } } -} -.formatted-content pre { - margin-block: 3.2rem; - margin-inline: calc(var(--wrapper-gutter-inline) * -1); - padding-block: 1.6rem; - padding-inline: var(--wrapper-gutter-inline); - font-size: 1.5rem; - line-height: 1.7; - background-color: var(--color-shade-7); - border-radius: 0.4rem; - white-space: pre; - overflow: auto; -} + blockquote { + margin-block: 3.2rem; + margin-inline: calc(var(--wrapper-gutter-inline) * -1); + padding-block: 2.4rem; + padding-inline: var(--wrapper-gutter-inline); + font-weight: 300; + font-size: 2.6rem; + text-align: center; + background-color: var(--color-shade-7); + border-radius: 0.4rem; + + @media (min-width: 480px) { + margin-inline: 0; + padding-inline: 3.2rem; + } + } -@media (min-width: 480px) { - .formatted-content pre { - margin-inline: 0; - padding-inline: 2.4rem; + pre { + margin-block: 3.2rem; + margin-inline: calc(var(--wrapper-gutter-inline) * -1); + padding-block: 1.6rem; + padding-inline: var(--wrapper-gutter-inline); + font-size: 1.5rem; + line-height: 1.7; + background-color: var(--color-shade-7); + border-radius: 0.4rem; + white-space: pre; + overflow: auto; + + @media (min-width: 480px) { + margin-inline: 0; + padding-inline: 2.4rem; + } } -} -.formatted-content pre code { - font-size: inherit; - line-height: inherit; -} + pre code { + font-size: inherit; + line-height: inherit; + } -.formatted-content code { - font-family: Menlo, monospace; - text-shadow: 0.1rem 0.1rem 0 var(--color-background); - word-spacing: normal; - word-break: normal; - tab-size: 2; - hyphens: none; -} + code { + font-family: Menlo, monospace; + text-shadow: 0.1rem 0.1rem 0 var(--color-background); + word-spacing: normal; + word-break: normal; + tab-size: 2; + hyphens: none; + } -/* Inline code */ -.formatted-content code:not(pre code) { - display: inline-block; - padding: 0 0.6rem; - font-size: 1.7rem; - background-color: var(--color-shade-10); - border-radius: 0.4rem; -} + /* Inline code */ + code:not(pre code) { + display: inline-block; + padding: 0 0.6rem; + font-size: 1.7rem; + background-color: var(--color-shade-10); + border-radius: 0.4rem; + } -.formatted-content code::selection, -.formatted-content code *::selection { - text-shadow: none !important; -} + code::selection, + code *::selection { + text-shadow: none !important; + } -.formatted-content blockquote p:first-of-type { - margin-top: 0; -} + blockquote p:first-of-type { + margin-top: 0; + } -.formatted-content blockquote p:last-of-type { - margin-bottom: 0; -} + blockquote p:last-of-type { + margin-bottom: 0; + } -.formatted-content hr { - position: relative; - margin: 4rem 0 5.6rem; - color: currentcolor; - text-align: center; - border: none; -} + hr { + position: relative; + margin: 4rem 0 5.6rem; + color: currentcolor; + text-align: center; + border: none; + } -.formatted-content hr::after { - content: '...'; - display: inline-block; - font-size: 3.2rem; - letter-spacing: 1.6rem; + hr::after { + content: '...'; + display: inline-block; + font-size: 3.2rem; + letter-spacing: 1.6rem; + } } /* Post preview */ .post-preview { margin-top: 5.6rem; -} -.post-preview h2 { - margin: 0 0 0.2rem; - font-size: 3.4rem; - line-height: 1.2; -} + h2 { + margin: 0 0 0.2rem; + font-size: 3.4rem; + line-height: 1.2; -.post-preview h2 a { - display: inline-block; - text-decoration-thickness: 0.3rem; -} + a { + display: inline-block; + text-decoration-thickness: 0.3rem; + } + } -.post-preview time { - display: inline-block; - color: var(--color-shade-55); + time { + display: inline-block; + color: var(--color-shade-55); - /* font-variant:all-small-caps is bugged in iOS (spacing issue) */ - font-size: 0.8em; - text-transform: uppercase; -} + /* font-variant:all-small-caps is bugged in iOS (spacing issue) */ + font-size: 0.8em; + text-transform: uppercase; + } -.post-preview p { - margin: 0.8rem 0 0.4rem !important; + p { + margin: 0.8rem 0 0.4rem !important; + } } /* Page: homepage */ .page-home { text-align: center; -} -.page-home .profile-picture { - margin: 0 auto; -} + .profile-picture { + margin: 0 auto; + } -.page-home h1 { - margin: 2.8rem 0 0; - font-size: 4.4rem; - line-height: normal; -} + h1 { + margin: 2.8rem 0 0; + font-size: 4.4rem; + line-height: normal; -.page-home h1 span { - color: var(--color-highlight); -} + span { + color: var(--color-highlight); + } + } -.page-home p { - margin: 2.4rem 0 0; - font-size: 2.6rem; -} + p { + margin: 2.4rem 0 0; + font-size: 2.6rem; -@media (min-width: 480px) { - .page-home p span { - display: block; + @media (min-width: 480px) { + span { + display: block; + } + } } } /* Page: post */ -.page-post h1 { - margin: 0; - font-size: 4.8rem; - line-height: 1.2; -} - -.page-post .datetime { - margin: 1.4rem 0 -1rem; - color: var(--color-shade-55); -} - -.page-post .tag-list { - margin-top: 1.6rem; -} - -.page-post .author { - display: flex; - margin: 8rem 0 9.6rem; -} - -.page-post .author .picture { - flex: 0 0 auto; - padding-top: 0.8rem; -} - -.page-post .author .profile-picture { - width: 10rem; - height: 10rem; -} - -.page-post .author .description { - flex: 1 1 auto; - padding-left: 2rem; -} - -@media (min-width: 480px) { - .page-post .author .profile-picture { - width: 12rem; - height: 12rem; +.page-post { + h1 { + margin: 0; + font-size: 4.8rem; + line-height: 1.2; } - .page-post .author .description { - padding-left: 4rem; + .datetime { + margin: 1.4rem 0 -1rem; + color: var(--color-shade-55); } -} - -.page-post .author .name { - font-weight: 600; - font-size: 2rem; -} - -.page-post .author p { - margin: 0 0 0.8rem; - font-size: 2rem; -} - -.page-post .author .get-in-touch { - display: flex; - margin: 0; - padding: 0; - list-style: none; -} - -.page-post .author .get-in-touch li { - display: block; - margin-right: 1.2rem; -} - -.page-post .author .get-in-touch a { - display: flex; - align-items: center; - text-decoration: none; -} -.page-post .author .get-in-touch a .img { - flex: 1 1 auto; - width: 2rem; - height: 2rem; - fill: currentcolor; -} + .tag-list { + margin-top: 1.6rem; + } -.page-post .author .get-in-touch a span { - margin-left: 0.4rem; + .author { + display: flex; + margin: 8rem 0 9.6rem; + + .picture { + flex: 0 0 auto; + padding-top: 0.8rem; + } + + .profile-picture { + width: 10rem; + height: 10rem; + + @media (min-width: 480px) { + width: 12rem; + height: 12rem; + } + } + + .description { + flex: 1 1 auto; + padding-left: 2rem; + + @media (min-width: 480px) { + padding-left: 4rem; + } + } + + .name { + font-weight: 600; + font-size: 2rem; + } + + p { + margin: 0 0 0.8rem; + font-size: 2rem; + } + + .get-in-touch { + display: flex; + margin: 0; + padding: 0; + list-style: none; + + li { + display: block; + margin-right: 1.2rem; + } + + a { + display: flex; + align-items: center; + text-decoration: none; + + .img { + flex: 1 1 auto; + width: 2rem; + height: 2rem; + fill: currentcolor; + } + + span { + margin-left: 0.4rem; + } + } + } + } } /* Theme switch */ @@ -574,52 +566,54 @@ h3 { border-radius: 50%; box-sizing: content-box; cursor: pointer; -} - -.theme-switch.loaded { - display: block; -} -.theme-switch:focus-visible { - outline: 0.2rem dashed var(--color-highlight); -} - -.theme-switch .icon { - position: absolute; - display: block; - top: var(--theme-switch-extra-click-area); - width: var(--theme-switch-size); - height: var(--theme-switch-size); - background-color: transparent; - background-repeat: no-repeat; - background-size: 100%; - background-position: 50%; - transform: rotate(50deg); - transition: - opacity 250ms, - transform 1s; -} + &.loaded { + display: block; + } -.theme-switch .icon.sun { - background-image: url('data:image/svg+xml;utf8,'); - opacity: 1; -} + &:focus-visible { + outline: 0.2rem dashed var(--color-highlight); + } -.theme-switch .icon.moon { - background-image: url('data:image/svg+xml;utf8,'); - opacity: 0; -} + .icon { + position: absolute; + display: block; + top: var(--theme-switch-extra-click-area); + width: var(--theme-switch-size); + height: var(--theme-switch-size); + background-color: transparent; + background-repeat: no-repeat; + background-size: 100%; + background-position: 50%; + transform: rotate(50deg); + transition: + opacity 250ms, + transform 1s; + + &.sun { + background-image: url('data:image/svg+xml;utf8,'); + opacity: 1; + } + + &.moon { + background-image: url('data:image/svg+xml;utf8,'); + opacity: 0; + } + } -.theme-switch[checked] .icon { - transform: rotate(10deg); -} + &[checked] { + .icon { + transform: rotate(10deg); -.theme-switch[checked] .icon.sun { - opacity: 0; -} + &.sun { + opacity: 0; + } -.theme-switch[checked] .icon.moon { - opacity: 1; + &.moon { + opacity: 1; + } + } + } } /* Misc. styles */ @@ -628,13 +622,13 @@ h3 { margin: 0 0 4rem; font-size: 4.8rem; line-height: 1; /* Looks better on mobile and on individual tag pages */ -} -.page h1.special span:first-of-type { - display: block; - margin-bottom: 0.8rem; - color: var(--color-shade-55); - font-weight: 400; - font-size: 1.8rem; - line-height: 1; + &.special span:first-of-type { + display: block; + margin-bottom: 0.8rem; + color: var(--color-shade-55); + font-weight: 400; + font-size: 1.8rem; + line-height: 1; + } }