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.*