1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
This time I made some improvements to the website.
## Watch out, construction site!
Ever since I've bought my domain, I've been putting all the actual content of my website to thematic subdomains. Since I had nothing to put to the main domain I just used it as a sort of dead-end for the website, with the following game over text from the [Legend of Zelda: Majora's Mask](https://en.wikipedia.org/wiki/The_Legend_of_Zelda:_Majora%27s_Mask):
"""You've met with a terrible fate, haven't you? "" Majora's Mask, 2000 """
After creating more and more silly little projects on the site, I soon realized it was time for me to **create** at least **some sort of menu** where a random visitor can check all the subdomains out (especially since I myself was starting to forget just _what_ all the current projects/subdomains were).
So a few days ago I've put together this horrible abomination of a webpage for my main domain. I'm going to include a screenshot of it, in case I ever decide to change it to something less a crime against humanity:
![an image with a very basic menu with ugly colored buttons and an UNDER CONSTRUCTION banner](main_domain.webp "No, thank you, IT companies, I'm not interested in frontend design, you can stop sending me job offers!" "https://wazul.moe" "It was a fun exercise for hand-coded svg at least...")
## Starting to feel like an icon (would look good on the sidebar)
I also added a few more links to the sidebar, like my Mastodon which I'm planning to start using more frequently again. So I had to add a few **icons for these entries** (and the Arch Linux logo btw). Luckily [iconify](https://icon-sets.iconify.design) had some really cute Apache license icons which suited my purpose perfectly.
## Return of the light theme
Though the first iteration of the blog had white background, it was hardly what you could call a *light theme*. You can check out how it looked in the [first blogpost](/posts/2024/let-there-be-light-theme). After I received some advice that I should actually **implement a light theme** (and I myself experienced just how hard it is to read anything on the blog while sitting outdoors on a platform of the train station with my laptop on my lap during daytime), I've felt it might actually be a good idea to do it.
My first question was _how_ to do it. Luckily I was already working with a predefined **palette of colors** for the 8 ANSI color (plus foreground and background). These were defined in the <span class="code-block-wrap"><span class="yellow">:root</span></span> of the css file, so the only thing I had to do was change those when another theme was set.
I know that <span class="code-block-wrap"><span class="magenta">prefers-color-scheme</span>: <span class="green">light</span></span> is a thing in css, but I was not fond of only using that for setting the preferred theme for multiple reasons:
- I may want to change the theme **manually** even if I have a system preference (like on the train station; see above); dark mode is sometimes called night mode for a _reason_
- {{foreshadowing}} I might want **more than two** color schemes {{}}; let's get the most out of the system if I implement it anyway
- totally personal reason: I prefer dark mode, but I use Firefox with **fingerprintingProtection**, so my agent always lies light mode preference :)
So of course my other choice was good old **javascript**. I wanted to avoid using javascript on the blog for as long as I can. Three blogposts was the limit as it turns out.
### Setting theme with "shell scripts"
I wanted the theme changing section of the sidebar to look thematically similar to the rest of the blog. So just like the tag listing, I went with a listing of **"shell scripts"** for the themes, and colored them green (the color for files with execute permission in ls). So while they essentially **work like buttons**, they **look more like links**. That's because they are:
<div class="code-block">
<p><span class="cyan"><</span><span class="yellow">a</span> <span class="green">href</span><span class="cyan">=</span><span class="red">"javascript:void(0);"</span> <span class="green">class</span><span class="cyan">=</span><span class="red">"icon-text theme-selector-light"</span> <span class="green">onclick</span><span class="cyan">=</span><span class="red">"setTheme('light')"</span><span class="cyan">></span>
<span class="cyan"><</span><span class="yellow">img</span> <span class="green">src</span><span class="cyan">=</span><span class="red">"/assets/image/sun.svg"</span> <span class="green">class</span><span class="cyan">=</span><span class="red">"svg-icon"</span><span class="cyan">></span>
<span class="cyan"><</span><span class="yellow">span</span><span class="cyan">></span>sweet-celestial.sh<span class="cyan"></</span><span class="yellow">span</span><span class="cyan">></span>
<span class="cyan"></</span><span class="yellow">a</span><span class="cyan">></span></p>
</div>
I know this goes a bit against visual clarity, but I liked the idea, so I went with it anyway.
The current theme is stored in <span class="code-block-wrap"><span class="yellow">localStorage</span></span> and the <span class="code-block-wrap"><span class="yellow">data-theme</span></span> attribute is applied to the **root html element** when loading the page or changing the theme:
<div class="code-block">
<p><span class="yellow">const</span> <span class="magenta">THEME_KEY</span> = <span class="green">"data-theme"</span>;</p>
<br>
<p><span class="yellow">function</span> <span class="blue">updateTheme</span>() {
<span class="yellow">let</span> theme = <span class="magenta">localStorage</span>.<span class="blue">getItem</span>(<span class="magenta">THEME_KEY</span>);
<span class="yellow">if</span> (theme != <span class="yellow">null</span>) {
<span class="magenta">document</span>.<span class="magenta">documentElement</span>.<span class="blue">setAttribute</span>(<span class="magenta">THEME_KEY</span>, theme)
}
}</p>
<br>
<p><span class="yellow">function</span> <span class="blue">setTheme</span>(theme) {
<span class="magenta">localStorage</span>.<span class="blue">setItem</span>(<span class="magenta">THEME_KEY</span>, theme);
<span class="blue">updateTheme</span>();
}</p>
</div>
The root colors in the **.css** file are then looked up in the <span class="code-block-wrap">[<span class="yellow">data-theme</span>=<span class="red">"light"</span>]</span> section, if light theme was selected.
### Coloring the icons
Some of the svg icons on the blog use specific **"hardcoded" colors**. For example the Arch Linux logo has the official <span class="code-block-wrap"><span style="color: #1793d1">#1793d1</span></span> blue color. But other icons, like the ones for the Website and the E-mail are using the same color scheme as the rest of the blog. So when changing theme, **I need them to change color** as well. I was able to achieve this with tagging them with the <span class="code-block-wrap"><span class="yellow">filter-yellow</span></span> class, and then **styling it** for each theme separately:
<div class="code-block">
<p>.<span class="yellow">filter-yellow</span> {
<span class="green">filter</span>: <span class="magenta">brightness</span>(<span class="blue">0</span>) <span class="magenta">saturate</span>(<span class="blue">100%</span>) <span class="magenta">invert</span>(<span class="blue">91%</span>) <span class="magenta">sepia</span>(<span class="blue">86%</span>) <span class="magenta">saturate</span>(<span class="blue">596%</span>) <span class="magenta">hue-rotate</span>(<span class="blue">314deg</span>) <span class="magenta">brightness</span>(<span class="blue">96%</span>) <span class="magenta">contrast</span>(<span class="blue">97%</span>);
}</p>
</div>
For the conversion from **hex color to css filter**, I used the tool on [Isotropic's website](https://isotropic.co/tool/hex-color-to-css-filter). I only have yellow colored icons now, obviously I will need to generate the rest of the palette if I want to use them.
### Flash bang out!
After this... everything was ready. Or so I thought. I was getting the good old **white flickering effect** on almost every page load. In the end I realized I was only applying the theme on <span class="code-block-wrap"><span class="magenta">window</span>.<span class="magenta">onload</span></span>, instead of **just calling it immediately** at the end of the script file. I changed it and this solved the bulk of the problem. Also, the **font was loading a bit slow**, but separating it into a **different .css file** and loading it first seemed to help with that as well.
### Theme summary
Light theme is opt-in currently. I may use <span class="code-block-wrap"><span class="magenta">prefers-color-scheme</span>: <span class="green">light</span></span> later as a fallback, if no preference was set by the user, but **luna-eclipsed** (dark mode) is the default color scheme for now. If however you are one of _those guys_ who like their retinas burned to crisp, feel free to use **sweet-celestial** (light mode). Both of them can be found on the side panel under <span class="magenta">I want different colors</span>.
While I was making the light theme, I just had to reuse the system and make a hidden easter egg theme as well. It's not really usable for reading, but it's fun. Try finding it!
- Hint 1: ||spoiler1||Try looking around where the rest of the theme selectors are.||
- Hint 2: ||spoiler2||You have to click on a specific spot.||
- Hint 3: ||spoiler3||It's to the right of "ls ~/themes/"||
## Blogpostception
I also had to implement a few things for _writing_ this post. For example, I **styled some new elements**, like lists or the quote at the top of the post. I made marko extensions for the quote, the fake html tags ({{whisper}}psst... hey... like this one!{{}}), and for the spoiler tags||, spoiler4||, which almost made me lose my mind. The css just didn't want to work||.
The **spoiler text** was tricky, because I wanted them to be clickable (rather than using some hover event) without the usage of javascript. In the end I used a **hidden checkbox with two labels**, of which only one is displayed at a time. This way for the hidden text I could display a series of rectangles <span class="nobr">(▉ [<- this is not a spoiler])</span>, so you can't accidentally spoil yourself with selection. Try selecting the following text, without clicking on it: ||spoiler5||Now you see me!||
However I had to **keep the whitespaces** so that the lines still wrap the same way as if they had normal content.
Here's the **html** code for the spoiler above:
<div class="code-block">
<p><span class="cyan"><</span><span class="yellow">span</span><span class="cyan">></span>
<span class="cyan"><</span><span class="yellow">input</span> <span class="yellow">type</span><span class="cyan">=</span><span class="red">"checkbox"</span> <span class="yellow">class</span><span class="cyan">=</span><span class="red">"spoiler"</span> <span class="yellow">id</span><span class="cyan">=</span><span class="red">"spoiler5"</span><span class="cyan">></span>
<span class="cyan"><</span><span class="yellow">label</span> <span class="yellow">class</span><span class="cyan">=</span><span class="red">"spoiler-on"</span> <span class="yellow">for</span><span class="cyan">=</span><span class="red">"spoiler5"</span><span class="cyan">></span>
<span class="cyan"><</span><span class="yellow">span</span><span class="cyan">></span>▉▉▉ ▉▉▉ ▉▉▉ ▉▉▉<span class="cyan"></</span><span class="yellow">span</span><span class="cyan">></span>
<span class="cyan"></</span><span class="yellow">label</span><span class="cyan">></span>
<span class="cyan"><</span><span class="yellow">label</span> <span class="yellow">class</span><span class="cyan">=</span><span class="red">"spoiler-off"</span> <span class="yellow">for</span><span class="cyan">=</span><span class="red">"spoiler5"</span><span class="cyan">></span>
<span class="cyan"><</span><span class="yellow">span</span><span class="cyan">></span>Now you see me!<span class="cyan"></</span><span class="yellow">span</span><span class="cyan">></span>
<span class="cyan"></</span><span class="yellow">label</span><span class="cyan">></span>
<span class="cyan"></</span><span class="yellow">span</span><span class="cyan">></span></p>
</div>
And the **css**:
<div class="code-block">
<p>.<span class="yellow">spoiler</span> {
<span class="green">position</span>: <span class="red">absolute</span>;
<span class="green">left</span>: <span class="blue">-10000px</span>;
}</p>
<br>
<p>.<span class="yellow">spoiler</span>:<span class="magenta">checked</span> ~ <span class="yellow">label</span>.<span class="yellow">spoiler-on</span>,
.<span class="yellow">spoiler</span>:<span class="magenta">not</span>(:<span class="magenta">checked</span>) ~ <span class="yellow">label</span>.<span class="yellow">spoiler-off</span> {
<span class="green">display</span>: <span class="red">none</span>;
}</p>
<br>
<p><span class="yellow">label</span>.<span class="yellow">spoiler-on</span> {
<span class="green">background-color</span>: <span class="magenta">var</span>(<span class="blue">--term-fg</span>);
}</p>
<br>
<p><span class="yellow">label</span>.<span class="yellow">spoiler-off</span> {
<span class="green">background-color</span>: <span class="magenta">var</span>(<span class="blue">--term-black</span>);
}</p>
</div>
I had to use an ugly workaround for the checkbox (<span class="code-block-wrap">.<span class="yellow">spoiler</span></span>). When I set it to <span class="code-block-wrap"><span class="green">display</span>: <span class="red">none</span></span> it was sometimes **scrolling around** on the page, trying to find the position of the checkbox. By keeping it "visible" (just -10000 pixels to the left of the screen), the browser **thinks it's on the screen**, so it does not start to jump around.
## Afterwords
I still have some things to do on the blog, and especially on the other subdomains, but this blogpost is getting too long already. And I'm tired.
So see you in the next one, I guess!
|