global: add formatter

This commit is contained in:
Agahnim 2026-05-13 14:00:54 +02:00
parent eb6819bb76
commit 6c87abd4fc
Signed by: Agahnim
SSH key fingerprint: SHA256:Zj65PJnE0dRYye8Ltk/qDglynyXUxJngQ9qqx/VI+b4
19 changed files with 3925 additions and 288 deletions

View file

@ -1,17 +1,17 @@
[ [
"The Oracle of the Bibou doth whisper 'neath the moon's pale gaze.", "The Oracle of the Bibou doth whisper 'neath the moon's pale gaze.",
"He who doth watch in the shadow, seeth all.", "He who doth watch in the shadow, seeth all.",
"Verily, even pixels bear a soul, thus speaketh the Bibou.", "Verily, even pixels bear a soul, thus speaketh the Bibou.",
"Dread not the error, for 'tis but the path unto the light.", "Dread not the error, for 'tis but the path unto the light.",
"Let thy heart guide thy mouse, O child of the web.", "Let thy heart guide thy mouse, O child of the web.",
"Each click be a prayer, and the Oracle doth hear.", "Each click be a prayer, and the Oracle doth hear.",
"Rise, and partake of a biscuit, for the road be long.", "Rise, and partake of a biscuit, for the road be long.",
"This day, thou shalt walk upon the feather of a dove.", "This day, thou shalt walk upon the feather of a dove.",
"The owl doth watch thee. Forget not thine duties.", "The owl doth watch thee. Forget not thine duties.",
"A rain of pixels shall fall this very night.", "A rain of pixels shall fall this very night.",
"The neighbours cat doth conspire. Be wary, O soul.", "The neighbours cat doth conspire. Be wary, O soul.",
"Thy click is not in vain, for the Bibou hath seen thee.", "Thy click is not in vain, for the Bibou hath seen thee.",
"Verily, 'tis Monday... and courage thou shalt need.", "Verily, 'tis Monday... and courage thou shalt need.",
"Fear not the dark, for the Bibou lurks there, awaiting food.", "Fear not the dark, for the Bibou lurks there, awaiting food.",
"The Bibou's gaze pierceth the soul..." "The Bibou's gaze pierceth the soul..."
] ]

View file

@ -35,4 +35,4 @@
"artist": "Monodrone", "artist": "Monodrone",
"src": "/static/assets/music/dark.mp3" "src": "/static/assets/music/dark.mp3"
} }
] ]

View file

@ -69,4 +69,4 @@
"src": "/static/assets/music/times.mp3", "src": "/static/assets/music/times.mp3",
"album": "Extinction" "album": "Extinction"
} }
] ]

View file

@ -7,4 +7,4 @@
"date": "2026-03-23", "date": "2026-03-23",
"body": "It's been a long time ! I'm writing this as I am completely overhauling the website, but I won't tell much about it until I'm done with this project ! What I can say though is that this section is far more extensible now thanks to the handy web-articles json file !" "body": "It's been a long time ! I'm writing this as I am completely overhauling the website, but I won't tell much about it until I'm done with this project ! What I can say though is that this section is far more extensible now thanks to the handy web-articles json file !"
} }
] ]

View file

@ -1,17 +1,20 @@
{pkgs ? import <nixpkgs> {}}: {pkgs ? import <nixpkgs> {}}: let
pkgs.mkShell { in
packages = with pkgs; [ pkgs.mkShell {
rustc packages = with pkgs; [
rust-analyzer rustc
rustfmt rust-analyzer
clippy rustfmt
cargo clippy
cargo-watch cargo
]; cargo-watch
treefmt
prettier
];
shellHook = '' shellHook = ''
echo "=========================================================" echo "========================================================="
echo "Pour lancer le projet et avoir les changements en temps réel : " echo "Pour lancer le projet et avoir les changements en temps réel : "
echo "- cargo watch -w content -w src -w templates -w static -x run" echo "- cargo watch -w content -w src -w templates -w static -x run"
''; '';
} }

View file

@ -1,5 +1,5 @@
(function() { (function () {
const menu = document.createElement('helo'); const menu = document.createElement("helo");
menu.innerHTML = ` menu.innerHTML = `
<helo-content> <helo-content>
@ -7,7 +7,7 @@
</helo-content> </helo-content>
`; `;
menu.style.display = 'none'; menu.style.display = "none";
function ensureMenu() { function ensureMenu() {
if (!document.body.contains(menu)) { if (!document.body.contains(menu)) {
@ -18,7 +18,7 @@
const showMenu = (x, y) => { const showMenu = (x, y) => {
ensureMenu(); ensureMenu();
menu.style.display = 'block'; menu.style.display = "block";
menu.style.left = `${x}px`; menu.style.left = `${x}px`;
menu.style.top = `${y}px`; menu.style.top = `${y}px`;
@ -34,20 +34,20 @@
}; };
const hideMenu = () => { const hideMenu = () => {
menu.style.display = 'none'; menu.style.display = "none";
}; };
document.addEventListener('contextmenu', (e) => { document.addEventListener("contextmenu", (e) => {
e.preventDefault(); e.preventDefault();
showMenu(e.clientX, e.clientY); showMenu(e.clientX, e.clientY);
}); });
document.addEventListener('click', hideMenu); document.addEventListener("click", hideMenu);
document.addEventListener('scroll', hideMenu); document.addEventListener("scroll", hideMenu);
document.addEventListener('keydown', (e) => { document.addEventListener("keydown", (e) => {
if (e.key === 'Escape') hideMenu(); if (e.key === "Escape") hideMenu();
}); });
document.body.addEventListener('htmx:historyRestore', ensureMenu); document.body.addEventListener("htmx:historyRestore", ensureMenu);
})(); })();

View file

@ -15,7 +15,6 @@ function initMiniPlayer() {
const trackTitleEl = player.querySelector("track-title"); const trackTitleEl = player.querySelector("track-title");
const trackArtistEl = player.querySelector("track-artist"); const trackArtistEl = player.querySelector("track-artist");
let isTransitioning = false; let isTransitioning = false;
let currentTrackIndex = 0; let currentTrackIndex = 0;
let isPlaying = false; let isPlaying = false;
@ -65,9 +64,13 @@ function initMiniPlayer() {
if (trackArtistEl) trackArtistEl.textContent = tracks[index].artist; if (trackArtistEl) trackArtistEl.textContent = tracks[index].artist;
if (wasPlaying) { if (wasPlaying) {
audio.addEventListener("loadeddata", () => { audio.addEventListener(
audio.play(); "loadeddata",
}, { once: true }); () => {
audio.play();
},
{ once: true },
);
} }
}; };
@ -82,13 +85,15 @@ function initMiniPlayer() {
}; };
const handlePrev = () => { const handlePrev = () => {
const newIndex = currentTrackIndex === 0 ? tracks.length - 1 : currentTrackIndex - 1; const newIndex =
currentTrackIndex === 0 ? tracks.length - 1 : currentTrackIndex - 1;
loadTrack(newIndex); loadTrack(newIndex);
}; };
const handleNext = () => { const handleNext = () => {
isTransitioning = true; isTransitioning = true;
const newIndex = currentTrackIndex === tracks.length - 1 ? 0 : currentTrackIndex + 1; const newIndex =
currentTrackIndex === tracks.length - 1 ? 0 : currentTrackIndex + 1;
loadTrack(newIndex); loadTrack(newIndex);
}; };
@ -124,7 +129,6 @@ function initMiniPlayer() {
} }
}); });
audio.addEventListener("pause", () => { audio.addEventListener("pause", () => {
if (isTransitioning) return; if (isTransitioning) return;

View file

@ -122,7 +122,7 @@ blockquote:before,
blockquote:after, blockquote:after,
q:before, q:before,
q:after { q:after {
content: ''; content: "";
content: none; content: none;
} }
@ -133,7 +133,6 @@ table {
/* Animations */ /* Animations */
@keyframes fadeInNOut { @keyframes fadeInNOut {
0% { 0% {
opacity: 0; opacity: 0;
@ -149,7 +148,6 @@ table {
} }
@keyframes woopwoop { @keyframes woopwoop {
0%, 0%,
100% { 100% {
transform: translateY(0) rotate(-2deg); transform: translateY(0) rotate(-2deg);
@ -160,7 +158,6 @@ table {
} }
} }
@keyframes marquee { @keyframes marquee {
from { from {
transform: translateX(0); transform: translateX(0);
@ -184,7 +181,6 @@ table {
} }
@keyframes boing { @keyframes boing {
0%, 0%,
100% { 100% {
transform: translateY(-25%); transform: translateY(-25%);
@ -202,7 +198,6 @@ table {
src: url("assets/fonts/ah.ttf") format("truetype"); src: url("assets/fonts/ah.ttf") format("truetype");
} }
:root { :root {
--lavender: #cdb4db; --lavender: #cdb4db;
--light-pink: #ffc8dd; --light-pink: #ffc8dd;
@ -219,20 +214,15 @@ table {
text-shadow: 0px 0px 3px var(--darkerer-pink); text-shadow: 0px 0px 3px var(--darkerer-pink);
} }
body { body {
background-size: cover; background-size: cover;
background-position: center; background-position: center;
min-height: 100lvh; min-height: 100lvh;
width: 100lvw; width: 100lvw;
overflow: auto; overflow: auto;
font-family: "DotGothic16", font-family: "DotGothic16", sans-serif;
sans-serif;
font-size: 1rem; font-size: 1rem;
&:has(#content home-content) { &:has(#content home-content) {
background-image: url(assets/images/tiledbgpink.webp); background-image: url(assets/images/tiledbgpink.webp);
} }
@ -302,9 +292,11 @@ crt {
} }
&::before { &::before {
background: linear-gradient(to bottom, background: linear-gradient(
transparent 50%, to bottom,
rgba(0, 0, 0, 0.2) 51%); transparent 50%,
rgba(0, 0, 0, 0.2) 51%
);
background-size: 100% 4px; background-size: 100% 4px;
animation: scanlines 1s steps(60) infinite; animation: scanlines 1s steps(60) infinite;
} }
@ -454,8 +446,6 @@ navbar {
margin-left: auto; margin-left: auto;
padding-right: 0.5rem; padding-right: 0.5rem;
} }
} }
} }
@ -480,7 +470,9 @@ home-content {
box { box {
border-radius: 0.4rem; border-radius: 0.4rem;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); box-shadow:
0 4px 6px -1px rgb(0 0 0 / 0.1),
0 2px 4px -2px rgb(0 0 0 / 0.1);
background-color: white; background-color: white;
padding: 1rem; padding: 1rem;
@ -495,7 +487,7 @@ home-content {
display: flex; display: flex;
gap: 1rem; gap: 1rem;
>socials-header { > socials-header {
color: var(--darkerer-pink); color: var(--darkerer-pink);
} }
@ -507,7 +499,7 @@ home-content {
bibou-message { bibou-message {
font-style: italic; font-style: italic;
color: var(--grey-500) color: var(--grey-500);
} }
bibou-container { bibou-container {
@ -542,9 +534,6 @@ home-content {
font-style: italic; font-style: italic;
text-align: center; text-align: center;
} }
} }
&#newsbox { &#newsbox {
@ -554,7 +543,7 @@ home-content {
justify-content: center; justify-content: center;
gap: 0.6rem; gap: 0.6rem;
&>img { & > img {
margin: auto; margin: auto;
} }
} }
@ -594,16 +583,14 @@ home-content {
flex-wrap: wrap; flex-wrap: wrap;
gap: 1rem; gap: 1rem;
>img { > img {
flex: 1 1 auto; flex: 1 1 auto;
} }
> img:nth-last-child(-n + 3) {
>img:nth-last-child(-n+3) {
flex: 1 1 30%; flex: 1 1 30%;
} }
} }
} }
} }
@ -636,12 +623,23 @@ home-content {
woopwoop span { woopwoop span {
display: inline-block; display: inline-block;
background: linear-gradient(90deg, var(--blue), var(--darker-pink), var(--darkerer-pink), var(--lavender), var(--light-blue), var(--light-pink), var(--pink)); background: linear-gradient(
90deg,
var(--blue),
var(--darker-pink),
var(--darkerer-pink),
var(--lavender),
var(--light-blue),
var(--light-pink),
var(--pink)
);
background-size: 200% auto; background-size: 200% auto;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
animation: woopwoop 1.2s ease-in-out infinite, woopwoopmove 2s linear infinite; animation:
woopwoop 1.2s ease-in-out infinite,
woopwoopmove 2s linear infinite;
} }
chibis { chibis {
@ -667,7 +665,6 @@ home-content {
/* Music */ /* Music */
music { music {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
@ -703,15 +700,16 @@ music {
} }
} }
box { box {
border-radius: 0.4rem; border-radius: 0.4rem;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); box-shadow:
0 4px 6px -1px rgb(0 0 0 / 0.1),
0 2px 4px -2px rgb(0 0 0 / 0.1);
background-color: white; background-color: white;
padding: 1rem; padding: 1rem;
} }
>cute-container { > cute-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-wrap: wrap; flex-wrap: wrap;
@ -734,7 +732,9 @@ katcenkat {
max-width: 100svw; max-width: 100svw;
height: auto; height: auto;
object-fit: contain; object-fit: contain;
transition: opacity 5s ease, transform 5s ease-out; transition:
opacity 5s ease,
transform 5s ease-out;
opacity: 1; opacity: 1;
transform: translateY(0px); transform: translateY(0px);
@ -755,7 +755,9 @@ mini-player {
border: 2px solid; border: 2px solid;
border-color: #ffffff #808080 #808080 #ffffff; border-color: #ffffff #808080 #808080 #ffffff;
box-shadow: 2px 2px 0 #000; box-shadow: 2px 2px 0 #000;
transition: opacity 0.3s, translate 0.3s; transition:
opacity 0.3s,
translate 0.3s;
font-size: clamp(0.625rem, 2svw, 0.75rem); font-size: clamp(0.625rem, 2svw, 0.75rem);
ominous-message { ominous-message {
@ -986,7 +988,6 @@ mini-player {
pink-statusbar { pink-statusbar {
display: none; display: none;
} }
} }
/* Music page */ /* Music page */
@ -1039,7 +1040,7 @@ helo {
padding: 0.5rem 0; padding: 0.5rem 0;
min-width: 150px; min-width: 150px;
z-index: 9999; z-index: 9999;
font-family: 'VT323', monospace; font-family: "VT323", monospace;
font-size: 1.2rem; font-size: 1.2rem;
helo-content { helo-content {
@ -1052,5 +1053,4 @@ helo {
width: 5svw; width: 5svw;
} }
} }
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,91 +1,95 @@
<!-- Welcome!! --> <!-- Welcome!! -->
<!DOCTYPE html> <!doctype html>
<html> <html>
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, interactive-widget=resizes-content"
/>
<link rel="icon" type="image/gif" href="/static/assets/gifs/pcgif.gif" />
<!-- <title></title> -->
<title>Agahnim proto</title>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=DotGothic16&family=VT323&display=swap"
/>
<link rel="stylesheet" href="/static/style.css" />
<script src="/static/vendor/htmx.min.js"></script>
<script>
htmx.config.scrollIntoViewOnBoost = false;
</script>
</head>
<head> <body hx-boost="true" hx-target="#content">
<meta charset="UTF-8" /> <crt>
<meta name="viewport" content="width=device-width, interactive-widget=resizes-content" /> <!-- They won't ever disappear -->
<link rel="icon" type="image/gif" href="/static/assets/gifs/pcgif.gif"> <persistent-ui>
<!-- <title></title> --> {% include "partials/header.html" %}
<title>Agahnim proto</title> <miniplayer-container id="miniplayer-container">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=DotGothic16&family=VT323&display=swap"> {% block miniplayer %}{% endblock %}
<link rel="stylesheet" href="/static/style.css" /> </miniplayer-container>
<script src="/static/vendor/htmx.min.js"></script> </persistent-ui>
<script>
htmx.config.scrollIntoViewOnBoost = false;
</script>
</head>
<body hx-boost="true" hx-target="#content"> <!-- Will get swapped by HTMX-->
<crt> <main id="content">{% block content %}{% endblock %}</main>
<!-- They won't ever disappear --> </crt>
<persistent-ui>
{% include "partials/header.html" %}
<miniplayer-container id="miniplayer-container">
{% block miniplayer %}{% endblock %}
</miniplayer-container>
</persistent-ui>
<!-- Will get swapped by HTMX--> <!-- Noooooooooooooooooooooooooo -->
<main id="content"> <script src="/static/miniplayer.js"></script>
{% block content %}{% endblock %} <script src="/static/contextmenu.js"></script>
</main> <script>
</crt> function updateMiniplayerVisibility() {
const isMusicPage = window.location.pathname === "/music";
<!-- Noooooooooooooooooooooooooo --> const miniplayer = document.getElementById("miniplayer-container");
<script src="/static/miniplayer.js"></script> if (miniplayer) {
<script src="/static/contextmenu.js"></script> miniplayer.style.display = isMusicPage ? "none" : "";
<script> }
function updateMiniplayerVisibility() { if (isMusicPage) {
const isMusicPage = window.location.pathname === '/music'; const audio = document.querySelector("mini-player audio");
const miniplayer = document.getElementById('miniplayer-container'); if (audio) audio.pause();
if (miniplayer) { }
miniplayer.style.display = isMusicPage ? 'none' : '';
} }
if (isMusicPage) {
const audio = document.querySelector('mini-player audio'); function updateNavState() {
if (audio) audio.pause(); const path = window.location.pathname;
document
.querySelectorAll('navbar input[type="radio"]')
.forEach((radio) => {
radio.checked = false;
});
if (path === "/home") {
const homeRadio = document.getElementById("nav-home");
if (homeRadio) homeRadio.checked = true;
} else if (path === "/music") {
const musicRadio = document.getElementById("nav-music");
if (musicRadio) musicRadio.checked = true;
} else if (path === "/blog") {
const blogRadio = document.getElementById("nav-blog");
if (blogRadio) blogRadio.checked = true;
} else if (path === "/about") {
const aboutRadio = document.getElementById("nav-about");
if (aboutRadio) aboutRadio.checked = true;
} else if (path === "/projects") {
const projectsRadio = document.getElementById("nav-projects");
if (projectsRadio) projectsRadio.checked = true;
}
} }
}
function updateNavState() { function closeMobileMenu() {
const path = window.location.pathname; const checkbox = document.getElementById("nav-toggle-checkbox");
document.querySelectorAll('navbar input[type="radio"]').forEach(radio => { if (checkbox) checkbox.checked = false;
radio.checked = false;
});
if (path === '/home') {
const homeRadio = document.getElementById('nav-home');
if (homeRadio) homeRadio.checked = true;
} else if (path === '/music') {
const musicRadio = document.getElementById('nav-music');
if (musicRadio) musicRadio.checked = true;
} else if (path === "/blog") {
const blogRadio = document.getElementById('nav-blog');
if (blogRadio) blogRadio.checked = true;
} else if (path === "/about") {
const aboutRadio = document.getElementById('nav-about');
if (aboutRadio) aboutRadio.checked = true;
} else if (path === "/projects") {
const projectsRadio = document.getElementById('nav-projects');
if (projectsRadio) projectsRadio.checked = true;
} }
}
function closeMobileMenu() {
const checkbox = document.getElementById('nav-toggle-checkbox');
if (checkbox) checkbox.checked = false;
}
updateMiniplayerVisibility();
updateNavState();
document.body.addEventListener('htmx:afterSwap', () => {
updateMiniplayerVisibility(); updateMiniplayerVisibility();
updateNavState(); updateNavState();
closeMobileMenu();
window.scrollTo(0, 0);
});
</script>
</body>
</html> document.body.addEventListener("htmx:afterSwap", () => {
updateMiniplayerVisibility();
updateNavState();
closeMobileMenu();
window.scrollTo(0, 0);
});
</script>
</body>
</html>

View file

@ -1,9 +1,3 @@
{% extends "base.html" %} {% extends "base.html" %} {% block content %} {% include "partials/home.html" %}
{% endblock %} {% block miniplayer %} {% include "partials/miniplayer.html" %}
{% block content %}
{% include "partials/home.html" %}
{% endblock %}
{% block miniplayer %}
{% include "partials/miniplayer.html" %}
{% endblock %} {% endblock %}

View file

@ -1,9 +1,3 @@
{% extends "base.html" %} {% extends "base.html" %} {% block content %} {% include "partials/music.html"
%} {% endblock %} {% block miniplayer %} {% include "partials/miniplayer.html"
{% block content %} %} {% endblock %}
{% include "partials/music.html" %}
{% endblock %}
{% block miniplayer %}
{% include "partials/miniplayer.html" %}
{% endblock %}

View file

@ -1,6 +1,2 @@
{% extends "base.html" %} {% extends "base.html" %} {% block content %} {% include
"partials/notfound.html" %} {% endblock %}
{% block content %}
{% include "partials/notfound.html" %}
{% endblock %}

View file

@ -1,5 +1,5 @@
<navbar> <navbar>
<input type="checkbox" id="nav-toggle-checkbox"> <input type="checkbox" id="nav-toggle-checkbox" />
<navbar-toggle> <navbar-toggle>
<label for="nav-toggle-checkbox" class="hamburger"> <label for="nav-toggle-checkbox" class="hamburger">
<span></span> <span></span>
@ -9,15 +9,15 @@
</navbar-toggle> </navbar-toggle>
<navbar-content> <navbar-content>
<a href="/home">Home</a> <a href="/home">Home</a>
<input type="radio" name="nav" id="nav-home" checked> <input type="radio" name="nav" id="nav-home" checked />
<a href="/about">About me</a> <a href="/about">About me</a>
<input type="radio" name="nav" id="nav-about"> <input type="radio" name="nav" id="nav-about" />
<a href="/blog">Blog</a> <a href="/blog">Blog</a>
<input type="radio" name="nav" id="nav-blog"> <input type="radio" name="nav" id="nav-blog" />
<a href="/projects">Projects</a> <a href="/projects">Projects</a>
<input type="radio" name="nav" id="nav-projects"> <input type="radio" name="nav" id="nav-projects" />
<a href="/music">Music</a> <a href="/music">Music</a>
<input type="radio" name="nav" id="nav-music"> <input type="radio" name="nav" id="nav-music" />
</navbar-content> </navbar-content>
<pink-statusbar> <pink-statusbar>
<status-dot></status-dot> <status-dot></status-dot>
@ -27,18 +27,18 @@
</navbar> </navbar>
<script> <script>
(function() { (function () {
const dateEl = document.querySelector('current-date'); const dateEl = document.querySelector("current-date");
if (dateEl) { if (dateEl) {
const update = () => { const update = () => {
const now = new Date(); const now = new Date();
const h = String(now.getHours()).padStart(2, '0'); const h = String(now.getHours()).padStart(2, "0");
const m = String(now.getMinutes()).padStart(2, '0'); const m = String(now.getMinutes()).padStart(2, "0");
const s = String(now.getSeconds()).padStart(2, '0'); const s = String(now.getSeconds()).padStart(2, "0");
dateEl.textContent = `${h}:${m}:${s}`; dateEl.textContent = `${h}:${m}:${s}`;
}; };
update(); update();
setInterval(update, 1000); setInterval(update, 1000);
} }
})(); })();
</script> </script>

View file

@ -1,85 +1,142 @@
<home-content> <home-content>
<welcome> <welcome>
<img src="/static/assets/images/welcome.webp" width="400px" alt="A welcome text in pink" /> <img
src="/static/assets/images/welcome.webp"
width="400px"
alt="A welcome text in pink"
/>
<marquee> <marquee>
{% for _ in 0..12 %} {% for _ in 0..12 %} &nbsp;彡★Welcome to my little corner of the
&nbsp;彡★Welcome to my little corner of the Web★彡&nbsp; Web★彡&nbsp; {% endfor %}
{% endfor %}
</marquee> </marquee>
</welcome> </welcome>
<boxes> <boxes>
<box id="bigbox"> <box id="bigbox">
Thank you for visiting my <woopwoop>brand new</woopwoop> website ! Thank you for visiting my <woopwoop>brand new</woopwoop> website ! For now
For now it's still a <darkerer-pink>work in progress</darkerer-pink> but I'm sure you will see it's still a <darkerer-pink>work in progress</darkerer-pink> but I'm sure
changes if you come back from time to time :) you will see changes if you come back from time to time :) <br /><br />
<br /><br />
My name is <darkerer-pink>Agahnim</darkerer-pink> My name is <darkerer-pink>Agahnim</darkerer-pink>
<pronouns>she/her</pronouns>, <pronouns>she/her</pronouns>, I'm a
I'm a <darkerer-pink>developer</darkerer-pink> and <darkerer-pink>music producer</darkerer-pink> from <darkerer-pink>developer</darkerer-pink> and
<darkerer-pink>France</darkerer-pink> ! <darkerer-pink>music producer</darkerer-pink> from
<br /><br /> <darkerer-pink>France</darkerer-pink> ! <br /><br />
I created this website not just to <darkerer-pink>improve</darkerer-pink> my I created this website not just to
web development <darkerer-pink>improve</darkerer-pink> my web development skills, but also
skills, but also because it's <boing>fun</boing> because it's <boing>fun</boing> to build a project like this. It's a
to small, personal space on the internet, away from the social climate, which
build a project like this. It's a small, personal space on the internet, away from the social climate, which is is getting <shitty>worse and worse.</shitty> <br /><br />
getting <shitty>worse and worse.</shitty> This website is inspired by the
<br /><br /> <darkerer-pink>vaporwave aesthetic</darkerer-pink> and the old PCs I used
This website is inspired by the <darkerer-pink>vaporwave to tinker with when I was a kid. I always liked this type of aesthetic and
aesthetic</darkerer-pink> and the mix of melancholy of comfort it brings me. It feels good to bring that
the old vibe into one of my projects.
PCs I used to tinker with when I was a kid.
I always liked this type of aesthetic and the mix of melancholy of comfort it brings me.
It feels good to bring that vibe into one of my projects.
<badges> <badges>
<img src="/static/assets/badges/88x31computer.gif" alt="88x31 pixel art badge with a retro computer" /> <img
<img src="/static/assets/badges/cssisawesome.webp" alt="Badge with text 'CSS is Awesome'" /> src="/static/assets/badges/88x31computer.gif"
<img src="/static/assets/badges/queer.webp" alt="Queer pride flag badge" /> alt="88x31 pixel art badge with a retro computer"
<img width="100px" src="/static/assets/badges/skywardsword.webp" />
alt="Cover art for The Legend of Zelda Skyward Sword" /> <img
<img src="/static/assets/badges/transrightsnow.webp" alt="Trans rights badge with text 'Trans Rights Now'" /> src="/static/assets/badges/cssisawesome.webp"
<img width="30%" src="/static/assets/badges/kirby.gif" alt="Kirby character animated GIF" /> alt="Badge with text 'CSS is Awesome'"
<img width="30%" src="/static/assets/badges/pink.gif" alt="Pink animated pixel art badge" /> />
<img width="30%" src="/static/assets/badges/trans.gif" alt="Trans pride flag animated badge" /> <img
src="/static/assets/badges/queer.webp"
alt="Queer pride flag badge"
/>
<img
width="100px"
src="/static/assets/badges/skywardsword.webp"
alt="Cover art for The Legend of Zelda Skyward Sword"
/>
<img
src="/static/assets/badges/transrightsnow.webp"
alt="Trans rights badge with text 'Trans Rights Now'"
/>
<img
width="30%"
src="/static/assets/badges/kirby.gif"
alt="Kirby character animated GIF"
/>
<img
width="30%"
src="/static/assets/badges/pink.gif"
alt="Pink animated pixel art badge"
/>
<img
width="30%"
src="/static/assets/badges/trans.gif"
alt="Trans pride flag animated badge"
/>
</badges> </badges>
</box> </box>
<box id="smallbox"> <box id="smallbox">
<socials-header> Socials ! </socials-header> <socials-header> Socials ! </socials-header>
<socials> <socials>
<a href="https://github.com/naguiagahnim" target="_blank"><img src="/static/assets/icons/github.webp" <a href="https://github.com/naguiagahnim" target="_blank"
width="30px" alt="GitHub logo" /></a> ><img
<a href="https://open.spotify.com/intl-fr/artist/4BPUhsH6krKkCNFrdMZnZF?si=E3luyIf0S_yfJRmm82S5OA" src="/static/assets/icons/github.webp"
target="_blank"><img src="/static/assets/icons/spotify.webp" width="30px" alt="Spotify logo" /></a> width="30px"
<a href="https://www.instagram.com/agahnim_music/" target="_blank"><img src="/static/assets/icons/insta.webp" alt="GitHub logo"
width="30px" alt="Instagram logo" /></a> /></a>
<a
href="https://open.spotify.com/intl-fr/artist/4BPUhsH6krKkCNFrdMZnZF?si=E3luyIf0S_yfJRmm82S5OA"
target="_blank"
><img
src="/static/assets/icons/spotify.webp"
width="30px"
alt="Spotify logo"
/></a>
<a href="https://www.instagram.com/agahnim_music/" target="_blank"
><img
src="/static/assets/icons/insta.webp"
width="30px"
alt="Instagram logo"
/></a>
</socials> </socials>
<img width="200px" src="/static/assets/gifs/divider2.gif" alt="Decorative divider" /> <img
<bibou-message>Consult the wisdom of the Bibou, if thou darest...</bibou-message> width="200px"
src="/static/assets/gifs/divider2.gif"
alt="Decorative divider"
/>
<bibou-message
>Consult the wisdom of the Bibou, if thou darest...</bibou-message
>
<bibou-container> <bibou-container>
<img class="boubou" src="/static/assets/images/boubou.webp" alt="Bibou endormi" /> <img
<img class="bibou" src="/static/assets/images/bibou.webp" alt="Bibou éveillé" /> class="boubou"
src="/static/assets/images/boubou.webp"
alt="Bibou endormi"
/>
<img
class="bibou"
src="/static/assets/images/bibou.webp"
alt="Bibou éveillé"
/>
</bibou-container> </bibou-container>
<bibou-text> <bibou-text> </bibou-text>
</bibou-text>
</box> </box>
<box id="newsbox"> <box id="newsbox">
<website-news> <website-news>
<img width="70%" src="/static/assets/gifs/updates.gif" alt="Animated text 'Updates'" /> <img
width="70%"
src="/static/assets/gifs/updates.gif"
alt="Animated text 'Updates'"
/>
{% for article in news %} {% for article in news %}
<article-entry> <article-entry>
<time datetime="{{ article.date }}"> <time datetime="{{ article.date }}">
{{ article.date.format("%d/%m/%Y") }} {{ article.date.format("%d/%m/%Y") }}
</time> </time>
<article-body> <article-body> {{ article.body }} </article-body>
{{ article.body }} <img
</article-body> width="300px"
<img width="300px" src="/static/assets/gifs/divider2.gif" alt="Decorative divider" /> src="/static/assets/gifs/divider2.gif"
alt="Decorative divider"
/>
</article-entry> </article-entry>
{% else %} {% else %}
<ominous-message> <ominous-message> Nothing to see here, for now... </ominous-message>
Nothing to see here, for now...
</ominous-message>
{% endfor %} {% endfor %}
</website-news> </website-news>
</box> </box>
@ -127,4 +184,4 @@
ttText(quote); ttText(quote);
}); });
}) (); }) ();
</script> </script>

View file

@ -13,31 +13,78 @@
</title-bar> </title-bar>
<progress-bar-container> <progress-bar-container>
<input class="progress-input" type="range" min="0" max="0" value="0" step="0.01" /> <input
class="progress-input"
type="range"
min="0"
max="0"
value="0"
step="0.01"
/>
</progress-bar-container> </progress-bar-container>
<controls-bar> <controls-bar>
<transport-controls> <transport-controls>
<button data-action="prev" aria-label="Previous"> <button data-action="prev" aria-label="Previous">
<img src="/static/assets/svgs/skip-back.svg" width="12" height="12" alt="Skip back" /> <img
src="/static/assets/svgs/skip-back.svg"
width="12"
height="12"
alt="Skip back"
/>
</button> </button>
<button data-action="play" aria-label="Play/Pause"> <button data-action="play" aria-label="Play/Pause">
<img class="play-icon" src="/static/assets/svgs/play.svg" width="12" height="12" alt="Play" /> <img
<img class="pause-icon" src="/static/assets/svgs/pause.svg" width="12" height="12" alt="Pause" style="display: none;" /> class="play-icon"
src="/static/assets/svgs/play.svg"
width="12"
height="12"
alt="Play"
/>
<img
class="pause-icon"
src="/static/assets/svgs/pause.svg"
width="12"
height="12"
alt="Pause"
style="display: none"
/>
</button> </button>
<button data-action="next" aria-label="Next"> <button data-action="next" aria-label="Next">
<img src="/static/assets/svgs/skip-forward.svg" width="12" height="12" alt="Skip forward" /> <img
src="/static/assets/svgs/skip-forward.svg"
width="12"
height="12"
alt="Skip forward"
/>
</button> </button>
</transport-controls> </transport-controls>
<volume-controls> <volume-controls>
<img src="/static/assets/svgs/volume-2.svg" width="12" height="12" alt="Volume" /> <img
<input class="volume-input" type="range" min="0" max="1" step="0.01" value="0.7" /> src="/static/assets/svgs/volume-2.svg"
width="12"
height="12"
alt="Volume"
/>
<input
class="volume-input"
type="range"
min="0"
max="1"
step="0.01"
value="0.7"
/>
</volume-controls> </volume-controls>
</controls-bar> </controls-bar>
<audio hidden> <audio hidden>
{% for track in tracks %} {% for track in tracks %}
<source src="{{ track.src }}" data-index="{{ loop.index0 }}" data-title="{{ track.title }}" data-artist="{{ track.artist }}" /> <source
src="{{ track.src }}"
data-index="{{ loop.index0 }}"
data-title="{{ track.title }}"
data-artist="{{ track.artist }}"
/>
{% endfor %} {% endfor %}
</audio> </audio>
{% endif %} {% endif %}

View file

@ -6,20 +6,20 @@
</music> </music>
<script> <script>
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const container = document.getElementById('bg-text'); const container = document.getElementById("bg-text");
const colWidth = 20; const colWidth = 20;
const rowHeight = 24; const rowHeight = 24;
const cols = Math.ceil(window.innerWidth / colWidth); const cols = Math.ceil(window.innerWidth / colWidth);
const rows = Math.ceil(window.innerHeight / rowHeight); const rows = Math.ceil(window.innerHeight / rowHeight);
for (let c = 0; c < cols; c++) { for (let c = 0; c < cols; c++) {
const col = document.createElement('vertical-marquee-inner'); const col = document.createElement("vertical-marquee-inner");
col.style.left = (c * colWidth) + 'px'; col.style.left = c * colWidth + "px";
for (let r = 0; r < rows; r++) { for (let r = 0; r < rows; r++) {
const span = document.createElement('text'); const span = document.createElement("text");
span.textContent = chars[Math.floor(Math.random() * chars.length)]; span.textContent = chars[Math.floor(Math.random() * chars.length)];
col.appendChild(span); col.appendChild(span);
} }
container.appendChild(col); container.appendChild(col);
} }
</script> </script>

View file

@ -1,4 +1,10 @@
<katcenkat> <katcenkat>
<img src="/static/assets/images/notfound.webp" alt="Pink text, 404 Not Found" /> <img
<img src="/static/assets/images/leuf.webp" alt="A drawing depicting a cute but fat cat" /> src="/static/assets/images/notfound.webp"
</katcenkat> alt="Pink text, 404 Not Found"
/>
<img
src="/static/assets/images/leuf.webp"
alt="A drawing depicting a cute but fat cat"
/>
</katcenkat>

9
treefmt.toml Normal file
View file

@ -0,0 +1,9 @@
[formatter.rustfmt]
command = "rustfmt"
options = ["--edition", "2024"]
includes = ["*.rs"]
[formatter.prettier]
command = "prettier"
options = ["--write"]
includes = ["*.html", "*.css", "*.js", "*.ts", "*.json", "*.md"]