From 77b5eb86c862e9b92aaf9029dce00ff2fb734b34 Mon Sep 17 00:00:00 2001 From: latte Date: Wed, 6 May 2026 20:58:38 +0200 Subject: [PATCH] Add CLAUDE guide and publish blog posts Add CLAUDE.md with repo guidance and architecture notes Add new post "The Haircut Nobody Mentioned" Adjust pubDate for Clearing the Queue and Knowing Your Worth Remove draft flag from Knowing Your Worth Fix frontmatter in Building as Avoidance --- CLAUDE.md | 37 +++++ src/content/blog/building-as-avoidance.md | 2 +- src/content/blog/clearing-the-queue.md | 2 +- src/content/blog/knowing-your-worth.md | 3 +- .../blog/the-haircut-nobody-mentioned.md | 140 ++++++++++++++++++ 5 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 CLAUDE.md create mode 100644 src/content/blog/the-haircut-nobody-mentioned.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..530c372 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,37 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Commands + +```bash +npm run dev # Start dev server (http://localhost:4321) +npm run build # Type-check (astro check) + production build +npm run preview # Preview the production build locally +``` + +There are no test or lint commands beyond `astro check` (run as part of `build`). + +## Architecture + +**Cozy Den** is the personal site for hiddenden.cafe. It's an Astro 4 project in `hybrid` output mode with a Node.js standalone adapter, which means most pages are statically generated at build time but API routes under `src/pages/api/` run as server-side handlers at runtime. + +### Key directories + +- `src/content/` — Astro Content Collections (blog, coffee, links, guestbook). Schemas and Zod validation live in `src/content/config.ts`. Blog posts support frontmatter fields for tags, categories, series, audio URLs, and featured-essay flags. +- `src/pages/api/` — SSR API endpoints. `api/guestbook/submit.ts` handles guestbook POST submissions; `api/admin/` handles admin session auth. +- `src/lib/` — All shared TypeScript utilities: `db.ts` (SQLite setup/schema), `auth.ts` (admin sessions), `guestbook.ts` (submission logic), `spam.ts` (honeypot + keyword pattern detection + input sanitization), `blog.ts`, `readingTime.ts`. +- `src/layouts/BaseLayout.astro` — Root layout; defines all global CSS custom properties (Catppuccin Mocha palette, typography, spacing). +- `src/components/` — Reusable `.astro` components (Card, Nav, Section, ServiceItem, SupportItem). + +### Database + +SQLite via `better-sqlite3`. Tables: `guestbook_entries` (moderated submissions), `admin_sessions` (expiring tokens), `rate_limit` (per-IP), `audit_log`. The schema is initialized in `src/lib/db.ts` on first run — no separate migration step. + +### Styling + +Vanilla CSS only — no Tailwind. All colour tokens are CSS variables on `:root` using the Catppuccin Mocha palette, with `prefers-color-scheme` overrides for light mode. Animations respect `prefers-reduced-motion`. Fonts are monospace (JetBrains Mono / Fira Code / SF Mono). + +### Deployment + +The site runs as a Docker container (standalone Node on port 3000) behind Nginx. The image is pushed to `git.hiddenden.cafe`. Copy `.env.example` to `.env` for TTS API keys (Google / Mistral / OpenAI) used by `scripts/tts_generate.py` when generating audio versions of blog posts. diff --git a/src/content/blog/building-as-avoidance.md b/src/content/blog/building-as-avoidance.md index d717912..4dc07df 100644 --- a/src/content/blog/building-as-avoidance.md +++ b/src/content/blog/building-as-avoidance.md @@ -1,4 +1,4 @@ ---- +e--- title: "Building as Avoidance" description: "On the honest reason I open a terminal at the end of a hard day, and what I am not looking at when I do." pubDate: 2026-05-07 diff --git a/src/content/blog/clearing-the-queue.md b/src/content/blog/clearing-the-queue.md index 97712f3..d757202 100644 --- a/src/content/blog/clearing-the-queue.md +++ b/src/content/blog/clearing-the-queue.md @@ -1,7 +1,7 @@ --- title: "Clearing the Queue" description: "On finally getting backup, letting someone go, and what's left when you stop running from yourself." -pubDate: 2026-05-07 +pubDate: 2026-05-06 tags: ["personal", "work", "reflection", "healing", "loneliness"] category: "reflection" --- diff --git a/src/content/blog/knowing-your-worth.md b/src/content/blog/knowing-your-worth.md index 4db4422..f53da05 100644 --- a/src/content/blog/knowing-your-worth.md +++ b/src/content/blog/knowing-your-worth.md @@ -1,10 +1,9 @@ --- title: "Knowing Your Worth (And Saying Nothing)" description: "On the particular silence of someone who already knows exactly what they're worth, having already talked themselves out of saying it before anyone else gets the chance." -pubDate: 2026-05-07 +pubDate: 2026-04-24 tags: ["personal", "work", "reflection", "self-worth", "honesty"] category: "reflection" -draft: true --- *by LATTE* diff --git a/src/content/blog/the-haircut-nobody-mentioned.md b/src/content/blog/the-haircut-nobody-mentioned.md new file mode 100644 index 0000000..ba99808 --- /dev/null +++ b/src/content/blog/the-haircut-nobody-mentioned.md @@ -0,0 +1,140 @@ +--- +title: "The Haircut Nobody Mentioned" +description: "On showing something new about yourself, hearing from everyone, and noticing the one silence that mattered more than all the rest." +pubDate: 2026-04-18 +tags: ["personal", "reflection", "healing", "loneliness", "self-worth"] +category: "reflection" +--- + +*by LATTE* + +I got a new haircut. + +That is the whole setup. +New style. Different than before. +The kind of change that is visible from across a room. + +--- + +## Everyone noticed + +Colleagues. +People in the office. +People online. + +Unprompted. Genuine. Real reactions. + +*It looks great.* +*That really suits you.* +*I almost didn't recognize you.* + +And I smiled and said thank you +and meant it. + +It felt good. +I am not going to pretend it didn't. + +--- + +## But + +There is always a but. + +Out of everyone who said something, +there was one person who didn't. + +And I noticed. + +The way you notice something that should be small +and isn't. + +Not because he is obligated to say anything. +Not because a comment about a haircut means something on its own. + +But because I knew, somewhere underneath all of it, +that his was the one I was waiting for. + +--- + +## What you do when you notice that + +You keep walking. + +That is it. +That is the whole answer. + +You do not stop. +You do not make it mean something out loud. +You do not let your face change. + +You just keep going. +Down the hallway. +Back to your desk. +Back to the tickets. + +And you file it somewhere quiet +and you do not look at it again. + +At least not until you are alone. + +--- + +## The thing about wanting to be seen + +I have been thinking about why that silence landed the way it did. + +It is not really about the haircut. + +It is about the specific ache of wanting one particular person to notice you +and having everyone else notice instead. + +All the right reactions from all the wrong directions. + +You are seen. Genuinely. +Just not by the one set of eyes that would have meant something different. + +And you cannot explain that to anyone +without it sounding like more than it is. +Or exactly as much as it is. +Which is also too much to say out loud. + +So you say thank you to everyone who said something. +And you keep walking past the one who didn't. + +--- + +## Why I am writing this + +Not because a haircut matters. + +It doesn't. + +But because that moment does. + +The specific feeling of showing something new about yourself +and scanning, without meaning to, for the one face that hasn't reacted yet. + +I think most people know that feeling. +The involuntary search. +The small, quiet hope. +The noticing when it doesn't come. + +And then the walking away. +Normally. +Like nothing happened. + +Because nothing did happen. +Not really. + +Just a haircut. +Just a hallway. +Just someone who didn't say anything. + +And you, +walking past, +already knowing you would write about it later. + +--- + +*the silence wasn't loud.* +*it didn't need to be.*