Add 'Uses' page and update navigation links; enhance layout responsiveness #43

Merged
Latte merged 1 commits from Feature/uses-page into dev 2026-03-07 10:10:49 +00:00
2 changed files with 570 additions and 0 deletions
Showing only changes of commit 4978044d9e - Show all commits
+2
View File
@@ -6,6 +6,7 @@ const links = [
{ href: "/about", label: "about" }, { href: "/about", label: "about" },
{ href: "/projects", label: "projects" }, { href: "/projects", label: "projects" },
{ href: "/now", label: "now" }, { href: "/now", label: "now" },
{ href: "/uses", label: "uses" },
{ href: "/blog", label: "blog" }, { href: "/blog", label: "blog" },
]; ];
@@ -49,6 +50,7 @@ function isActive(href: string, current: string): boolean {
max-width: 700px; max-width: 700px;
margin: 0 auto; margin: 0 auto;
display: flex; display: flex;
flex-wrap: wrap;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: var(--space-xs); gap: var(--space-xs);
+568
View File
@@ -0,0 +1,568 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
---
<BaseLayout
title="Uses — Hidden Den Cafe"
description="The tools, hardware, software, and infrastructure Mats uses to build, self-host, and explore technology."
>
<div class="matrix-bg" aria-hidden="true"></div>
<main class="main">
<div class="container">
<header class="header fade-in">
<h1 class="title">Uses</h1>
<div class="divider">══════════════════════════════</div>
<p class="intro">
This page is a window into the workshop behind Hidden Den Cafe.
It is less about a perfect spec sheet and more about the tools I
actually reach for to write code, run infrastructure, and keep
exploring how much of the internet I can build on my own terms.
Some of it lives on my desk, some of it lives in the homelab,
and some of it lives in carefully chosen external systems.
</p>
</header>
<section class="section fade-in">
<h2>Personal Computing Environment</h2>
<div class="uses-list">
<div class="use-item">
<h3>Windows + Ubuntu on WSL2</h3>
<p>
My day-to-day machine is a Windows workstation with an Ubuntu
environment inside WSL2. It gives me a practical desktop setup
while keeping most of my actual work in a Linux shell where I
can script, build, and debug with less friction.
</p>
</div>
<div class="use-item">
<h3>Terminal + Bash</h3>
<p>
Bash is still where a lot of real work happens for me. If a task
can be expressed as a clean command, script, or container build,
that is usually the route I prefer because it stays close to the
system instead of hiding it behind layers of UI.
</p>
</div>
<div class="use-item">
<h3>Zed</h3>
<p>
<a href="https://zed.dev" target="_blank" rel="noopener noreferrer">Zed</a>
is my primary editor. I like it because it is extremely fast,
modern without feeling bloated, and built for the kind of
collaborative and AI-assisted development workflow I spend a lot
of time experimenting with.
</p>
</div>
<div class="use-item">
<h3>Fast tools, low friction</h3>
<p>
I am happiest when tools respond immediately and get out of the
way. Markdown, plain text configs, and lightweight utilities
matter to me because they keep the system inspectable and make it
easier to move from idea to experiment without losing momentum.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<h2>Development Tools</h2>
<div class="uses-list">
<div class="use-item">
<h3>Python first, Astro on purpose</h3>
<p>
A lot of my background is in Python and Flask-style thinking:
simple services, clear behavior, and tooling I can reason about.
Cozy Den is also where I am learning Astro because it fits the
small-web, static-first approach I want for personal sites.
</p>
</div>
<div class="use-item">
<h3>Git + self-hosted Gitea</h3>
<p>
Version control lives on my own Gitea instance at
<a href="https://git.hiddenden.cafe" target="_blank" rel="noopener noreferrer">git.hiddenden.cafe</a>.
I use it both as a code forge and as part of the deployment path.
</p>
</div>
<div class="use-item">
<h3>Docker</h3>
<p>
Containers are the default way I package and move projects. I
like being able to build something once, understand its runtime,
and ship the same artifact to the machines that need it.
</p>
</div>
<div class="use-item">
<h3>TypeScript, Markdown, and plain files</h3>
<p>
I use typed configs where they help, Markdown where writing
should stay lightweight, and plain files wherever possible so the
project remains durable without a huge stack around it.
</p>
</div>
<div class="use-item">
<h3>Editor-driven exploration</h3>
<p>
A lot of experimentation starts in the editor: quick prototypes,
note fragments, config drafts, and partial implementations. I
prefer tools that make it easy to move between writing, coding,
terminal work, and AI-assisted iteration in one place.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<h2>AI Tools</h2>
<div class="uses-list">
<div class="use-item">
<h3>Model mix, not model worship</h3>
<p>
I actively experiment with multiple AI systems, including OpenAI,
OpenAI Business, Claude, Mistral, Ollama, OpenRouter, and
Microsoft Foundry. Different tools are better at different kinds
of work, so I treat them as instruments rather than as a single
source of truth.
</p>
</div>
<div class="use-item">
<h3>Development and drafting support</h3>
<p>
AI is useful for implementation support, debugging odd edge cases,
brainstorming approaches, writing rough drafts, and pressure-testing
architectural ideas. It helps me move faster, but it does not get
to replace judgment, taste, or authorship.
</p>
</div>
<div class="use-item">
<h3>Local and hosted experimentation</h3>
<p>
Some experiments belong in cloud APIs, some belong in local model
runtimes. I am interested in both, especially where privacy,
controllability, and cost start to matter.
</p>
</div>
<div class="use-item">
<h3>Human ideas stay human</h3>
<p>
The point is not to automate away authorship. The point is to
extend what I can build, test, and think through while keeping
the taste, priorities, and final decisions my own.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<h2>Infrastructure &amp; Homelab</h2>
<div class="uses-list">
<div class="use-item">
<h3>Proxmox cluster</h3>
<p>
A lot of the lab side of my work is built around a Proxmox-based
cluster. It acts as a workshop environment where services and
ideas get built, tested, broken, rebuilt, and slowly turned into
something stable enough to keep.
</p>
</div>
<div class="use-item">
<h3>Multiple nodes, mixed workloads</h3>
<p>
The homelab is not a single-box setup. It spans multiple nodes
running both experimental and production services, which makes it
useful for trying things out without forcing every idea directly
into the same environment.
</p>
</div>
<div class="use-item">
<h3>Self-hosted services</h3>
<p>
Gitea is part of that stack already, and more services tend to
follow the same philosophy: if I can run it myself without making
life worse, I would rather understand the system than outsource
it by default.
</p>
</div>
<div class="use-item">
<h3>Persistent storage</h3>
<p>
Persistent data matters, so storage gets treated as infrastructure,
not an afterthought. That includes self-hosted storage with tools
like OpenMediaVault and the kind of planning that keeps the lab
useful as it grows rather than turning into a graveyard of disks.
</p>
</div>
<div class="use-item">
<h3>Networking foundation</h3>
<p>
The network is built around a UniFi UDM Pro Max, which acts as the
core router and network controller for the environment. I want the
network to be stable first, then segmented where useful, with
secure remote access and reliable routing between local services
and the systems that need to be reachable from the outside.
</p>
</div>
<div class="use-item">
<h3>Tailscale for remote reachability</h3>
<p>
Tailscale is part of the connective tissue that makes the lab feel
usable from anywhere. I like tools that make remote access simple
without turning the whole setup into a networking puzzle.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<h2>Identity &amp; Cloud Services</h2>
<div class="uses-list">
<div class="use-item">
<h3>Microsoft Entra</h3>
<p>
Entra is part of how I think about identity and access in the
broader environment. It is useful where centralized identity,
policy, and account management make sense.
</p>
</div>
<div class="use-item">
<h3>Microsoft Intune</h3>
<p>
Intune fits into the device and policy side of the stack. I do not
see that as a replacement for understanding systems directly, but
it is practical where managed devices and consistent policy matter.
</p>
</div>
<div class="use-item">
<h3>Microsoft Azure</h3>
<p>
Azure is part of the cloud experimentation side of the workshop:
useful for testing ideas, running services that do not belong at
home, and understanding how managed infrastructure behaves in the
real world.
</p>
</div>
<div class="use-item">
<h3>Homelab first, cloud where it helps</h3>
<p>
These Microsoft services complement the homelab rather than
replacing it. I still prefer running and understanding systems
directly whenever possible, but I am not interested in pretending
cloud tooling has no value when it clearly does.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<h2>External Hosting</h2>
<div class="uses-list">
<div class="use-item">
<h3>OVH</h3>
<p>
OVH is part of the external VPS layer I use when a service needs
public accessibility, geographic separation, or a home outside the
local lab.
</p>
</div>
<div class="use-item">
<h3>VPS.play.hosting</h3>
<p>
VPS.play.hosting fills a similar role for additional external
services. I like having more than one place to run things when the
goal is resilience rather than putting every dependency in one box.
</p>
</div>
<div class="use-item">
<h3>Hybrid infrastructure</h3>
<p>
Not everything belongs in the homelab, and not everything belongs
in the cloud. The useful middle ground is a hybrid setup where
local infrastructure and external VPS systems complement each other
instead of competing.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<h2>Security &amp; Identity</h2>
<div class="uses-list">
<div class="use-item">
<h3>Hardware-backed authentication</h3>
<p>
I prefer security that is boring and strong. Hardware keys such as
YubiKeys make more sense to me than pretending a password alone is
enough for important accounts.
</p>
</div>
<div class="use-item">
<h3>GPG and identity hygiene</h3>
<p>
Cryptographic identity is part of the workflow here. I publish my
keys, use GPG where it is useful, and try to keep trust anchored in
things I can verify instead of platforms asking to be trusted.
</p>
</div>
<div class="use-item">
<h3>Password managers and compartmentalization</h3>
<p>
Good security is mostly consistency. Unique secrets, sensible
separation between roles and systems, and fewer scattered accounts
beat dramatic security theater every time.
</p>
</div>
<div class="use-item">
<h3>Privacy as a design constraint</h3>
<p>
I do not chase privacy because it sounds noble. I care about it
because it changes architecture choices: fewer unnecessary
dependencies, less telemetry, tighter control over where data ends
up, and a better understanding of what the system is doing.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<h2>Website Stack</h2>
<div class="uses-list">
<div class="use-item">
<h3>Astro</h3>
<p>
Cozy Den itself is built with Astro because static HTML is still
one of the nicest ways to publish a personal site.
</p>
</div>
<div class="use-item">
<h3>Vanilla CSS + TypeScript</h3>
<p>
Styling stays close to the markup, and the TypeScript that exists
is there to make content and structure safer rather than heavier.
</p>
</div>
<div class="use-item">
<h3>Docker + nginx</h3>
<p>
The site builds in a container and ships as static files served by
nginx, which keeps deployment small, repeatable, and easy to audit.
</p>
</div>
<div class="use-item">
<h3>Gitea-driven deployment path</h3>
<p>
Source, registry, and release flow all stay close to my own
infrastructure instead of depending on a hosted publishing platform.
</p>
</div>
<div class="use-item">
<h3>Secondary to the workshop</h3>
<p>
The site stack matters, but it is only one part of the broader
ecosystem. Cozy Den exists because of the surrounding tools,
machines, services, and habits that make building on my own terms
possible.
</p>
</div>
</div>
</section>
<section class="section fade-in">
<p class="closing-note">
This page is a living snapshot of the tools and systems behind Cozy Den.
It changes from time to time as experiments evolve and the workshop grows.
</p>
</section>
<footer class="footer fade-in">
<p>Made with love by Latte</p>
</footer>
</div>
</main>
</BaseLayout>
<style>
.matrix-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.03;
background:
linear-gradient(var(--color-accent) 1px, transparent 1px),
linear-gradient(90deg, var(--color-accent) 1px, transparent 1px);
background-size: 50px 50px;
animation: grid-move 20s linear infinite;
}
@keyframes grid-move {
0% { transform: translate(0, 0); }
100% { transform: translate(50px, 50px); }
}
.main {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: var(--space-lg) var(--space-md);
padding-top: calc(var(--space-lg) + 3rem);
}
.container {
max-width: 760px;
width: 100%;
background: var(--color-glass);
backdrop-filter: blur(10px);
border: 1px solid var(--color-surface);
border-radius: 8px;
padding: var(--space-xl);
}
.header {
text-align: center;
margin-bottom: var(--space-lg);
}
.title {
font-size: 2rem;
font-weight: 700;
letter-spacing: 2px;
}
.divider {
color: var(--color-surface);
text-align: center;
font-size: 0.75rem;
margin: var(--space-md) 0;
user-select: none;
}
.intro {
max-width: 60ch;
margin: 0 auto;
color: var(--color-text-dim);
line-height: 1.7;
}
.section {
margin: var(--space-xl) 0;
}
.section h2 {
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 2px;
margin-bottom: var(--space-md);
color: var(--color-accent);
}
.uses-list {
display: grid;
gap: var(--space-md);
}
.use-item {
padding: var(--space-md);
border: 1px solid var(--color-surface);
border-radius: 6px;
background: var(--color-bg-light);
}
.use-item h3 {
font-size: 1rem;
color: var(--color-accent-bright);
margin-bottom: var(--space-xs);
}
.use-item p {
color: var(--color-text-dim);
line-height: 1.7;
}
.use-item code {
font-family: inherit;
background: var(--color-bg);
padding: 2px 6px;
border-radius: 4px;
font-size: 0.85em;
color: var(--color-green);
}
.footer {
margin-top: var(--space-xl);
text-align: center;
}
.closing-note {
color: var(--color-text-dim);
line-height: 1.7;
text-align: center;
max-width: 62ch;
margin: 0 auto;
}
.footer p {
color: var(--color-text-dim);
font-size: 0.85rem;
}
.fade-in {
animation: fadeIn 0.6s ease-out forwards;
opacity: 0;
}
.fade-in:nth-child(1) { animation-delay: 0.1s; }
.fade-in:nth-child(2) { animation-delay: 0.2s; }
.fade-in:nth-child(3) { animation-delay: 0.3s; }
.fade-in:nth-child(4) { animation-delay: 0.4s; }
.fade-in:nth-child(5) { animation-delay: 0.5s; }
.fade-in:nth-child(6) { animation-delay: 0.6s; }
.fade-in:nth-child(7) { animation-delay: 0.7s; }
.fade-in:nth-child(8) { animation-delay: 0.8s; }
.fade-in:nth-child(9) { animation-delay: 0.9s; }
.fade-in:nth-child(10) { animation-delay: 1s; }
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 600px) {
.container {
padding: var(--space-md);
}
.title {
font-size: 1.5rem;
}
.divider {
font-size: 0.6rem;
}
.use-item {
padding: var(--space-sm);
}
}
@media (prefers-reduced-motion: reduce) {
.matrix-bg {
animation: none;
}
.fade-in {
animation: none;
opacity: 1;
}
}
</style>