Miscellaneous code and documentation updates
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
---
|
||||
---
|
||||
title: "After the Silence"
|
||||
description: "Reflections on what remains after a meaningful relationship ends, and how love can transform without disappearing."
|
||||
pubDate: 2026-03-04
|
||||
tags: ["love", "reflection", "healing", "relationships", "personal"]
|
||||
category: "reflection"
|
||||
featuredEssay: true
|
||||
audio: true
|
||||
---
|
||||
|
||||
When a relationship ends, the world does not become quiet immediately.
|
||||
|
||||
@@ -6,6 +6,7 @@ tags: ["reflection", "identity", "intimacy", "self-knowledge", "personal", "nuan
|
||||
category: "reflection"
|
||||
featuredEssay: false
|
||||
draft: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
*A quiet reflection on BDSM, nuance, and why my answers are rarely simple*
|
||||
|
||||
@@ -6,6 +6,7 @@ tags: ["reflection", "personal", "internet", "building", "devlog"]
|
||||
category: "reflection"
|
||||
featuredEssay: false
|
||||
draft: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
*by LATTE*
|
||||
|
||||
@@ -9,6 +9,7 @@ readingOrder: 2
|
||||
series:
|
||||
name: "Coffee & Code"
|
||||
part: 1
|
||||
audio: true
|
||||
---
|
||||
|
||||
The modern internet is loud in a way that can be hard to notice until you step away from it.
|
||||
|
||||
@@ -7,6 +7,7 @@ category: "building"
|
||||
featuredEssay: true
|
||||
readingOrder: 1
|
||||
draft: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
So I finally got around to setting up a proper blog. Welcome.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
---
|
||||
title: "Love Without Access"
|
||||
description: "A reflection on a first love - what it meant, what it cost, and why distance was the most loving thing left."
|
||||
pubDate: 2026-03-01
|
||||
tags: ["love", "reflection", "healing", "relationships", "personal"]
|
||||
audio: true
|
||||
---
|
||||
|
||||
*by LATTE*
|
||||
|
||||
@@ -3,6 +3,7 @@ title: "Rebuilding Without Rushing"
|
||||
description: "On slowing down after loss, choosing clarity over urgency, and learning that rebuilding does not have to be loud to be real."
|
||||
pubDate: 2026-03-22
|
||||
tags: ["reflection", "healing", "personal", "rebuilding", "growth"]
|
||||
audio: true
|
||||
---
|
||||
|
||||
## The idea of rebuilding
|
||||
|
||||
@@ -6,6 +6,7 @@ tags: ["games", "reflection", "relationships", "internet", "personal"]
|
||||
category: "reflection"
|
||||
featuredEssay: false
|
||||
draft: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
*by LATTE*
|
||||
|
||||
@@ -6,6 +6,7 @@ tags: ["reflection", "personal", "love", "healing"]
|
||||
category: "reflection"
|
||||
featuredEssay: false
|
||||
draft: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
*by LATTE*
|
||||
|
||||
@@ -5,6 +5,7 @@ pubDate: 2026-03-19
|
||||
tags: ["love", "grief", "reflection", "personal", "relationships"]
|
||||
category: "personal"
|
||||
featuredEssay: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
*by LATTE*
|
||||
|
||||
@@ -6,6 +6,7 @@ tags: ["self-hosting", "privacy", "digital minimalism", "cozy web", "personal in
|
||||
category: "reflection"
|
||||
featuredEssay: false
|
||||
draft: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
There is a certain kind of quiet that has become rare on the internet.
|
||||
|
||||
@@ -6,6 +6,7 @@ tags: ["love", "grief", "reflection", "personal"]
|
||||
category: "personal"
|
||||
featuredEssay: false
|
||||
draft: false
|
||||
audio: true
|
||||
---
|
||||
|
||||
*by LATTE*
|
||||
|
||||
@@ -6,6 +6,7 @@ tags: ["love", "relationships", "reflection", "emotional growth", "intimacy"]
|
||||
category: "personal"
|
||||
featuredEssay: true
|
||||
readingOrder: 3
|
||||
audio: true
|
||||
---
|
||||
|
||||
Some relationships change you in quiet but permanent ways.
|
||||
|
||||
@@ -4,6 +4,7 @@ description: "On suddenly carrying too much, being seen by the wrong person at t
|
||||
pubDate: 2026-04-04
|
||||
tags: ["personal", "work", "reflection", "healing", "life"]
|
||||
category: "reflection"
|
||||
audio: true
|
||||
---
|
||||
|
||||
Some weeks arrive with more variables than expected.
|
||||
@@ -17,7 +18,7 @@ And then, quietly, the configuration changes.
|
||||
|
||||
## Suddenly, Everything Is Your Problem
|
||||
|
||||
I work in tech support. Helpdesk.
|
||||
I work in tech support - Helpdesk.
|
||||
|
||||
Hardware. Laptops. Phones. SIM cards. Loaner devices.
|
||||
Accounts across multiple platforms and software.
|
||||
@@ -273,4 +274,4 @@ And smiling a little, quietly, when he says good morning anyway.
|
||||
*More work. More weight. More responsibility.*
|
||||
*And occasionally, more feeling than you had space for.*
|
||||
|
||||
*The only thing to do is keep going.*
|
||||
*The only thing to do is keep going.*
|
||||
|
||||
+121
-17
@@ -119,17 +119,22 @@ const readingTime = getReadingTime(post.body);
|
||||
|
||||
{
|
||||
post.data.audio && (
|
||||
<div class="audio-player">
|
||||
<audio
|
||||
controls
|
||||
preload="none"
|
||||
aria-label={`Luister naar: ${post.data.title}`}
|
||||
>
|
||||
<source
|
||||
src={`https://audio.hiddenden.cafe/${post.slug}.mp3`}
|
||||
type="audio/mpeg"
|
||||
/>
|
||||
</audio>
|
||||
<div class="ap">
|
||||
<audio id="ap-audio" preload="none" src={`/audio/${post.slug}.mp3`}></audio>
|
||||
<button class="ap-btn" id="ap-btn" aria-label="Afspelen">
|
||||
<svg class="ap-icon ap-play" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M8 5v14l11-7z"/>
|
||||
</svg>
|
||||
<svg class="ap-icon ap-pause" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M6 19h4V5H6zm8-14v14h4V5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="ap-waveform" id="ap-waveform">
|
||||
{[38,55,72,88,65,92,78,58,82,96,68,52,86,100,74,60,90,80,63,84,70,94,58,80,74,90,63,84,70,54,80,63,90,74,58,84].map((h, i) => (
|
||||
<span class="ap-bar" style={`height:${h}%;animation-delay:${((i * 73) % 600)}ms`}></span>
|
||||
))}
|
||||
</div>
|
||||
<span class="ap-time" id="ap-time">0:00</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -247,6 +252,33 @@ const readingTime = getReadingTime(post.body);
|
||||
</footer>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
const ap = document.querySelector(".ap") as HTMLElement | null;
|
||||
const audio = document.getElementById("ap-audio") as HTMLAudioElement | null;
|
||||
const btn = document.getElementById("ap-btn");
|
||||
const timeEl = document.getElementById("ap-time");
|
||||
|
||||
function fmt(s: number) {
|
||||
const m = Math.floor(s / 60);
|
||||
const sec = String(Math.floor(s % 60)).padStart(2, "0");
|
||||
return `${m}:${sec}`;
|
||||
}
|
||||
|
||||
btn?.addEventListener("click", () => {
|
||||
if (!audio) return;
|
||||
audio.paused ? audio.play() : audio.pause();
|
||||
});
|
||||
|
||||
audio?.addEventListener("play", () => ap?.setAttribute("data-playing", ""));
|
||||
audio?.addEventListener("pause", () => ap?.removeAttribute("data-playing"));
|
||||
audio?.addEventListener("ended", () => {
|
||||
ap?.removeAttribute("data-playing");
|
||||
if (timeEl) timeEl.textContent = "0:00";
|
||||
});
|
||||
audio?.addEventListener("timeupdate", () => {
|
||||
if (timeEl && audio) timeEl.textContent = fmt(audio.currentTime);
|
||||
});
|
||||
</script>
|
||||
</BaseLayout>
|
||||
|
||||
<style>
|
||||
@@ -362,15 +394,87 @@ const readingTime = getReadingTime(post.body);
|
||||
border-color: color-mix(in srgb, var(--color-accent) 45%, transparent);
|
||||
}
|
||||
|
||||
.audio-player {
|
||||
.ap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
margin-top: var(--space-md);
|
||||
padding: 10px 14px;
|
||||
background: color-mix(in srgb, var(--color-accent) 8%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--color-accent) 22%, transparent);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.audio-player audio {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
accent-color: var(--color-accent);
|
||||
border-radius: 4px;
|
||||
.ap-btn {
|
||||
flex-shrink: 0;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-accent);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-bg);
|
||||
transition: background 0.2s, transform 0.15s;
|
||||
}
|
||||
|
||||
.ap-btn:hover {
|
||||
background: var(--color-accent-bright);
|
||||
transform: scale(1.07);
|
||||
}
|
||||
|
||||
.ap-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.ap-pause {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ap[data-playing] .ap-play {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ap[data-playing] .ap-pause {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ap-waveform {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.ap-bar {
|
||||
flex: 1;
|
||||
background: var(--color-accent);
|
||||
border-radius: 999px;
|
||||
opacity: 0.35;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.ap[data-playing] .ap-bar {
|
||||
opacity: 0.85;
|
||||
animation: ap-wave 0.55s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes ap-wave {
|
||||
from { transform: scaleY(0.25); }
|
||||
to { transform: scaleY(1); }
|
||||
}
|
||||
|
||||
.ap-time {
|
||||
flex-shrink: 0;
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-text-dim);
|
||||
min-width: 2.2rem;
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
||||
Reference in New Issue
Block a user