Compare commits

...

5 commits

10 changed files with 728 additions and 214 deletions

View file

@ -1,9 +1,11 @@
--- ---
# vim: spell spelllang=en
title: '{{ replace .File.ContentBaseName "-" " " | title }}' title: '{{ replace .File.ContentBaseName "-" " " | title }}'
slug: '{{ .File.ContentBaseName }}' slug: '{{ .File.ContentBaseName }}'
date: '{{ .Date }}' date: '{{ .Date }}'
draft: true draft: true
categories: [] categories:
-
tags: tags:
- -
summary: | summary: |

View file

@ -92,14 +92,19 @@ header nav [role="link"]:is([aria-current]:not([aria-current="false"]),:hover,:a
--pico-text-decoration: none; --pico-text-decoration: none;
} }
.container { article :where(a:not([role="button"])) {
--pico-text-decoration: none;
}
body > :is(main, footer) {
max-width: 40em; max-width: 40em;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
}
article :where(a:not([role="button"])) { @media (width >= 1024px) {
--pico-text-decoration: none; margin-right: 0;
margin-left: 18em;
}
} }
/* /*
@ -115,10 +120,19 @@ article :where(a:not([role="button"])) {
backdrop-filter: blur(3px); backdrop-filter: blur(3px);
font-family: var(--pico-font-family-sans-serif); font-family: var(--pico-font-family-sans-serif);
font-weight: bold; font-weight: bold;
@media (width >= 1024px) {
display: none;
}
img {
height: 2em;
}
} }
.mobile-header img { #menu-close {
height: 2em; float: right;
padding: 0 1.5em;
} }
#menu-close, #menu-close:hover, #menu-toggle { #menu-close, #menu-close:hover, #menu-toggle {
@ -126,98 +140,89 @@ article :where(a:not([role="button"])) {
background-color: inherit; background-color: inherit;
border: none; border: none;
text-decoration: none; text-decoration: none;
@media (width >= 1024px) {
display: none;
}
} }
body { body {
background-color: var(--pico-background-color); background-color: var(--pico-background-color);
}
body > header { & > header {
width: 100vw; width: 100dvw;
text-align: center; text-align: center;
height: 100vh; height: 100dvh;
position: fixed; position: fixed;
left: -100vw; left: -100vw;
top: 0; top: 0;
background-color: var(--pico-background-color); background-color: var(--pico-background-color);
z-index: 100; z-index: 100;
transition: left 0.5s; transition: left 0.5s;
overflow: hidden auto; overflow: hidden auto;
}
body > header.active { &.active {
left: 0; left: 0;
} }
body > header nav, body > header nav ul { @media (width >= 1024px) {
flex-direction: column; position: sticky;
} top: 0;
left: 0;
width: 15em;
float: left;
}
body > header .u-logo { .u-logo {
width: 5em; width: 5em;
} }
.title {
font-size: 1.5rem;
font-weight: bold;
font-family: var(--pico-font-family-sans-serif);
margin-top: 1em;
}
body > header .title { a {
font-size: 1.5rem; color: var(--pico-color);
font-weight: bold; padding: 0;
font-family: var(--pico-font-family-sans-serif);
margin-top: 1em;
}
body > header nav { .menu-primary & {
font-size: 1rem; font-weight: bold;
font-family: var(--pico-font-family-sans-serif); }
width: 100%; }
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
body > header nav li { nav {
padding: 0; font-size: 1rem;
padding: calc( var(--pico-nav-element-spacing-vertical) / 4) font-family: var(--pico-font-family-sans-serif);
calc( var(--pico-nav-element-spacing-horizontal) / 4); width: 100%;
} height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
body > header a { ul {
color: var(--pico-color); flex-direction: column;
padding: 0; }
}
body > header > a { li {
float: right; padding: 0;
padding: 0 1.5em; padding: calc( var(--pico-nav-element-spacing-vertical) / 4)
} calc( var(--pico-nav-element-spacing-horizontal) / 4);
}
}
}
.menu-primary { & > footer{
font-weight: bold; p {
} font-size: 0.7em;
text-align: center;
body > footer p { }
font-size: 0.7em; }
text-align: center;
} }
@media (width >= 1024px) { @media (width >= 1024px) {
.mobile-header, #menu-close {
display: none;
}
body > header {
position: sticky;
top: 0;
left: 0;
width: 15em;
float: left;
}
.container {
margin-right: 0;
margin-left: 18em;
}
.metadata p { .metadata p {
display: inline; display: inline;
} }
@ -228,134 +233,130 @@ body > footer p {
* Content Styling * Content Styling
*/ */
.translations { main {
text-align: end; .translations {
margin-bottom: 0.3em; text-align: end;
} margin-bottom: 0.3em;
.translations a { a {
text-decoration: none; text-decoration: none;
} }
}
main > article { & > article {
text-align: justify; text-align: justify;
}
main > article > header { & > header {
margin-bottom: calc(2 * var(--pico-block-spacing-vertical)); margin-bottom: calc(2 * var(--pico-block-spacing-vertical));
}
ul.tags, ul.tags li { h1, p {
list-style-type: none; margin-bottom: calc(0.1 * var(--pico-typography-spacing-vertical));
display: inline; margin-top: 0.3em;
padding-left: 0; }
margin-bottom: 0;
}
ul > li {
list-style-type: disc;
}
h1, h2, h3, h4, h5, h6 {
font-family: var(--pico-font-family-sans-serif);
text-align: left;
}
h1 {
font-size: 1.7rem;
}
h2 {
font-size: 1.3rem;
}
h2::before {
content: "## ";
color: var(--markup-color);
}
h3 {
font-size: 1.2rem;
}
h3::before {
content: "### ";
color: var(--markup-color);
}
h4 {
font-size: 1.1rem;
}
h4::before {
content: "#### ";
color: var(--markup-color);
}
h5 {
font-size: 1rem;
}
h5::before {
content: "##### ";
color: var(--markup-color);
}
h6 {
font-size: 1rem;
}
h6::before {
content: "###### ";
color: var(--markup-color);
}
article header h1, article header p {
margin-bottom: calc(0.1 * var(--pico-typography-spacing-vertical));
margin-top: 0.3em;
}
article header .category a { .category a {
font-family: var(--pico-font-family-sans-serif); font-family: var(--pico-font-family-sans-serif);
font-weight: 700; font-weight: 700;
line-height: var(--pico-line-height); line-height: var(--pico-line-height);
color: var(--pico-muted-color); color: var(--pico-muted-color);
text-decoration: none; text-decoration: none;
font-size: 1rem; font-size: 1rem;
margin-bottom: 0.5em; margin-bottom: 0.5em;
}
}
ul > li {
list-style-type: disc;
}
h1, h2, h3, h4, h5, h6 {
font-family: var(--pico-font-family-sans-serif);
text-align: left;
a {
color: var(--pico-muted-color);
text-decoration: none;
margin-left: 0.4rem;
font-size: 1rem;
}
}
h1 {
font-size: 1.7rem;
}
h2 {
font-size: 1.3rem;
&::before {
content: "## ";
color: var(--markup-color);
}
}
h3 {
font-size: 1.2rem;
&::before {
content: "### ";
color: var(--markup-color);
}
}
h4 {
font-size: 1.1rem;
&::before {
content: "#### ";
color: var(--markup-color);
}
}
h5 {
font-size: 1rem;
&::before {
content: "##### ";
color: var(--markup-color);
}
}
h6 {
font-size: 1rem;
&::before {
content: "###### ";
color: var(--markup-color);
}
}
pre {
margin-bottom: calc(1.5 * var(--pico-spacing));
}
code, kbd, pre {
font-size: 0.8em;
}
a[rel="external"]::after {
content: "\ecae";
font-size: 0.7em;
margin-left: 0.2em;
font-family: 'remixicon' !important;
font-style: normal;
color: var(--pico-muted-color);
text-decoration: none;
}
figure {
max-width: 50%;
text-align: center;
margin: var(--pico-block-spacing-vertical) auto;
}
}
} }
h2 a, h3 a, h4 a, h5 a, h6 a {
color: var(--pico-muted-color);
text-decoration: none;
margin-left: 0.4rem;
font-size: 1rem;
}
pre {
margin-bottom: calc(1.5 * var(--pico-spacing));
}
code, kbd, pre {
font-size: 0.8em;
}
a[rel="external"]::after {
content: "\ecae";
font-size: 0.7em;
margin-left: 0.2em;
font-family: 'remixicon' !important;
font-style: normal;
color: var(--pico-muted-color);
text-decoration: none;
}
figure {
max-width: 50%;
text-align: center;
margin: var(--pico-block-spacing-vertical) auto;
}
/* /*
* Admonitions * Admonitions
@ -374,16 +375,20 @@ figure {
* Post lists * Post lists
*/ */
.h-feed article:not(:last-child) { .h-feed {
border-bottom: var(--pico-border-width) solid var(--pico-card-border-color); article{
margin-bottom: 0; &:not(:last-child) {
} border-bottom: var(--pico-border-width) solid var(--pico-card-border-color);
margin-bottom: 0;
}
.h-feed article p { p {
margin-bottom: calc(0.2 * var(--pico-typography-spacing-vertical)); margin-bottom: calc(0.2 * var(--pico-typography-spacing-vertical));
} }
.h-feed article .p-summary { .p-summary {
font-size: 0.9em; font-size: 0.9em;
font-style: italic; font-style: italic;
}
}
} }

View file

@ -5,7 +5,7 @@ date: '2025-06-14T04:05:48+02:00'
categories: categories:
- DevOps - DevOps
tags: tags:
- architecture, - architecture
- cloud - cloud
summary: > summary: >
A reflection on recent internet outages and my takeways to build more A reflection on recent internet outages and my takeways to build more

View file

@ -0,0 +1,412 @@
---
# vim: spell spelllang=en
title: 'Embracing Modern Css'
slug: 'embracing-modern-css'
date: '2025-07-06T14:29:26+02:00'
draft: true
categories:
- dev
tags:
- CSS
summary: |
entrer le résumé
description: |
entrer la description
---
I recently stumbled upon a note on a page of [Plain Vanilla] in which I learned
that nested CSS is a thing. It's a thing that's been around for quite some time,
but I did not know about it (I'm quite late in my RSS reader).
This allowed me to catch up on some of the recent evolutions of CSS.
[Plain Vanilla]: https://plainvanillaweb.com/pages/styling.html
## Nested CSS
Nesting CSS rules is one of the main reasons I've been using [SASS] for 15
years.
I've always preferred to write nested rules to group together coherent units of
CSS. For example,
```scss
a {
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
header {
nav {
ul {
list-style: none;
li {
text-align: center;
}
}
}
}
```
makes more sense to me than
```css
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
header nav ul {
list-style: none;
}
header nav ul li {
text-align: center;
}
```
I have a few reasons for this:
* It's easier to read because selectors are sorter and the hierarchy is easier
to grasp;
* I can move around a group of selector without forgetting a declaration;
* I can use my IDE code folding based on indent to close a group and navigate
long CSS files;
Since the [CSS Nesting Module] is [Baseline Widely Available] and is supported
by [90% of users], It can be used to write nested CSS. So now, this is a thing in
CSS:
```css
a {
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
header {
nav {
ul {
list-style: none;
li {
text-align: center;
}
}
}
}
```
The [CSS file] of this site has been rewritten using nested CSS.
[SASS]: https://sass-lang.com
[CSS Nesting Module]: https://drafts.csswg.org/css-nesting/
[Baseline Widely Available]: https://webstatus.dev/features/Nesting
[90% of users]: https://caniuse.com/css-nesting
[CSS file]: https://bcarlin.net/static/css/bcarlin.css
## CSS Variables
To me, variables are essential to ensure a coherent user interface. They allow to
reuse colors, sizes, spacing, and so on.
This is also a reason why I've been using [SASS]. It allowed me to write CSS
with reusable variables :
```scss
$color-error: red;
$color-success: green;
label {
&.error {
color: $color-error;
}
&.success {
color: $color-success;
}
}
.notification {
&.error {
background-color: $color-error;
}
&.success {
background-color: $color-success;
}
}
```
I missed the [CSS Custom Properties] module from 2017, which allowed me to write
the same thing in pure CSS:
```css
:root {
--color-error: red;
--color-success: green;
}
label {
&.error {
color: var(--color-error);
}
}
.notification {
&.error {
background-color: var(--color-error);
}
}
```
[CSS Custom Properties]: https://www.w3.org/TR/css-variables/
## Classless CSS
Maybe I an going backwards here, given the popularity of utility-first CSS
frameworks like [TailwindCSS].
This one is not really a CSS feature *per se*, but it is a way to write CSS,
where semantically correct HTML is automatically styled correctly. To some
extent, it is, however, backed by some [CSS Selectors Level 4] which are now
Widely implemented across browsers, such as `:has`, `:is`, `:where`, `:not` and
so on.
I used to use [BootstrapCSS] in my projects because it is complete and easy to
use, but I never liked the way it imposed a heavy CSS Structure on my source. For
this site, I was looking for something lighter and came across [PicoCSS] which
styles 90% of my site without changing anything to my templates.
I already had a meaningful semantic HTML base structure:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h1>Page Title</h1>
</header>
<section>
<!-- ... -->
</section>
</article>
</main>
<footer>
<!-- ... -->
</footer>
</body>
</html>
```
And I really like the way it works: the content is styled based on its semantic
markup, and not on a HTML imposed structure.
For example, here is [Bootstrap Modal component]:
```html
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal Title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
Modal Body
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
```
Here is the [Modal component from Tailwind Plus]:
```HTML
<div>
<button class="rounded-md bg-gray-950/5 px-2.5 py-1.5 text-sm font-semibold text-gray-900 hover:bg-gray-950/10">Open dialog</button>
<div class="relative z-10" aria-labelledby="dialog-title" role="dialog" aria-modal="true">
<div class="fixed inset-0 bg-gray-500/75 transition-opacity" aria-hidden="true"></div>
<div class="fixed inset-0 z-10 w-screen overflow-y-auto">
<div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<div class="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex size-12 shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:size-10">
<svg class="size-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
</svg>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-base font-semibold text-gray-900" id="dialog-title">Modal Title</h3>
<div class="mt-2">
Modal Body
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
<button type="button" class="inline-flex w-full justify-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-xs hover:bg-red-500 sm:ml-3 sm:w-auto">Save changes</button>
<button type="button" class="mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-xs ring-1 ring-gray-300 ring-inset hover:bg-gray-50 sm:mt-0 sm:w-auto">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
```
Compare those with [PicoCSS Modal component]:
```html
<dialog open>
<article>
<header>
<button aria-label="Close" rel="prev"></button>
<p>
<strong>Modal Title</strong>
</p>
</header>
Modal Body
<footer>
<button class="secondary">Close</button>
<button>Save changes</button>
</footer>
</article>
</dialog>
```
It makes a huge difference in simplicity, readability and accessibility (note
that the ARIA attributes are rendered useless because the semantic markup
already carries that information).
[TailwindCSS]: https://tailwindcss.com
[CSS Selectors Level 4]: https://drafts.csswg.org/selectors-4/
[BootstrapCSS]: https://getbootstrap.com
[PicoCSS]: https://picocss.com
[Bootstrap Modal Component]: https://getbootstrap.com/docs/4.3/components/modal/#live-demo
[Modal component from Tailwind Plus]: https://tailwindcss.com/plus/ui-blocks/application-ui/overlays/modal-dialogs
[PicoCSS Modal component]: https://picocss.com/docs/modal
## `@import` to split CSS files
One last thing I liked to use SASS for was the possibility to split CSS files
into smaller ones to make them easier to grasp. For example:
```scss
@use 'reset';
@use 'typography';
@use 'layout';
@use 'content';
```
With the [CSS Cascading and Inheritance Level 5] module, CSS has that natively:
```css
@import url('reset.css');
@import url('typography.css');
@import url('layout.css');
@import url('content.css');
```
From my understanding, the `@import`ed CSS files are downloaded in parallel,
which reduces the penalty of having several files to download.
CSS `@import` rules even have the benefit of being conditional. For example:
```css
@import url("light.css") only screen and (prefers-color-scheme: light);
@import url('dark.css') only screen and (prefers-color-scheme: dark);
```
[CSS Cascading and Inheritance Level 5]: https://drafts.csswg.org/css-cascade-5/
## Things I'm looking forward to
Those are some things I'm looking forward to using. I do not use them yet
because of browser support or because I did not have a use for them yet. But I'm
excited to try them out.
### CSS Mixins
CSS Mixins are also a major feature of SASS, and foster a cleaner and more
reusable CSS code.
CSS will have them with the [CSS Functions and Mixins Module], which is still a
draft where mixins are not specified yet.
In the meantime, here is an example from [SASS Mixin Guide]:
```scss
@mixin rtl($property, $ltr-value, $rtl-value) {
#{$property}: $ltr-value;
[dir=rtl] & {
#{$property}: $rtl-value;
}
}
.sidebar {
@include rtl(float, left, right);
}
```
Though in some cases, it can easily be replaced with CSS variables:
```css
:root {
--sidebar-float: left;
}
[dir=rtl] {
--sidebar-float: right;
}
.sidebar {
float: var(--sidebar-float);
}
```
[SASS Mixin Guide]: https://sass-lang.com/documentation/at-rules/mixin/#arguments
[CSS Functions and Mixins Module]: https://www.w3.org/TR/2025/WD-css-mixins-1-20250515/
### CSS Scopes
### CSS Custom Properties

View file

@ -0,0 +1,36 @@
---
title: 'Going Dark'
slug: 'going-dark'
date: '2025-07-01T00:10:19+02:00'
draft: true
categories:
- Tooling
tags:
- darkman
- vivaldi
- waybar
- wofi
summary: |
entrer le résumé
description: |
entrer la description
---
I usually live in the terminal for most things: edit text files (neovim),
read and write emails (aerc), chat on Mattermost (matterhorn), browse files
(vifm), and so on. I might write on that later. My terminal and everything in it
is themed with Solarized Dark. That will not change.
For the few GUI applications I use, the light theme is ery aggressive at night.
Here are some tips to automatically switch a few of them between light and dark
mode.
## Automate with darkman
## GTK Apps
## Vivaldi
## Add A Switcher To Waybar
## Switch Wofi Theme

View file

@ -0,0 +1,13 @@
---
title: 'Hugo Translating Taxonomy Terms'
slug: 'hugo-translating-taxonomy-terms'
date: '2025-07-02T22:35:43+02:00'
draft: true
categories: []
tags:
-
summary: |
entrer le résumé
description: |
entrer la description
---

View file

@ -0,0 +1,36 @@
---
title: 'I Use jj as my Main VCS'
slug: 'i-use-jj-as-my-main-vcs'
date: '2025-07-02T18:04:31+02:00'
draft: true
categories:
- Tooling
tags:
- jj
- git
summary: |
entrer le résumé
description: |
entrer la description
resources:
- src: jj-logo.svg
params:
legend: jj logo
---
I stumbled upon [jj] sometimes last year but I decided to give it a real go a
few month ago. It has already become my main VCS for all my code, even as a
replacement of git.
![JJ Logo](jj-logo.svg)
does things right:
- undo that works
- versioned working copy (restore a deleted file to a previous version)
- jj git fetch removes local branches when the remote is removed
- jj log shows what is useful by default without noise
- rebase of trees
- rebase of multiple branches
[jj]: https://github.com/jj-vcs/jj

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -30,10 +30,12 @@
</li> </li>
</ul> </ul>
</nav> </nav>
<header id="menu" class="h-card"> <header id="menu" class="h-card">
{{ partial "header.html" . }} {{ partial "header.html" . }}
</header> </header>
<main class="container">
<main>
{{- if .IsTranslated }} {{- if .IsTranslated }}
{{- range .Translations }} {{- range .Translations }}
<div class="translations"> <div class="translations">
@ -47,7 +49,8 @@
{{ block "main" . }}{{ end }} {{ block "main" . }}{{ end }}
</main> </main>
<footer class="container">
<footer>
{{ partial "footer.html" . }} {{ partial "footer.html" . }}
</footer> </footer>
</body> </body>

6
stylelint.config.js Normal file
View file

@ -0,0 +1,6 @@
/** @type {import('stylelint').Config} */
export default {
rules: {
"no-descending-specificity": false
}
};