A personal notes site: essays and notes on fatherhood, masculinity, culture, and modern life. Raw reflections on thinking, consciousness, and the soft heart inside the hard world.
- ~75 posts in
src/content/p/(Markdown/MDX) - 10 content categories (e.g. Parenting, Psychology, Politics, Metaspace)
- Bilingual content with translation linking (English/Spanish)
- Dark/light mode with system preference detection
- Responsive layout for mobile and desktop
- Structured data (Schema.org) for search discoverability
- Reading progress with completion detection and optional toast; stored in
localStorageonly - Reading time computed at build time via a remark plugin
- Guided Path – seasonal reading with progress tracked locally
- Astro 5.17 – static site generator
- TypeScript 5.9 – type-safe development
- Tailwind CSS 3.4 – utility-first CSS
- MDX – Markdown with JSX
- Sharp – image optimization
- Remark42 – self-hosted comments (optional)
- Vercel – deployment (optional)
git clone https://github.com/antoniwan/notes.git
cd notes
pnpm install
pnpm run devOpen http://localhost:4321.
Note: The project uses pnpm as the primary package manager. The commands below assume pnpm; if you prefer
npmoryarn, adjust accordingly.
| Command | Action |
|---|---|
pnpm run dev |
Start development server |
pnpm run build |
Production build |
pnpm run preview |
Preview production build |
pnpm run generate-favicons |
Generate favicon assets |
pnpm run validate-feeds |
Validate RSS and JSON feeds |
pnpm run audit-frontmatter |
Audit frontmatter consistency |
pnpm run standardize-frontmatter |
Standardize frontmatter format |
pnpm run remove-legacy-reading-time |
Remove legacy reading time fields |
pnpm run validate-structured-data |
Validate structured data implementation |
pnpm run fix:hr-spacing |
Fix horizontal rule spacing in content |
pnpm run format |
Format with Prettier |
pnpm run format:check |
Check formatting |
pnpm run analyze |
Build then run Vercel static-build |
pnpm run lighthouse |
Run Lighthouse on localhost (dev server must be up) |
pnpm run performance |
Build and analyze |
pnpm run audit-performance |
Build then Lighthouse performance-only JSON report |
notes/
├── public/ # Static assets
├── src/
│ ├── components/ # UI (40+ Astro components)
│ ├── config/ # Storage, comments, assets
│ ├── content/p/ # Blog posts (Markdown/MDX)
│ ├── data/ # Categories, nav, tags, quotes
│ ├── layouts/ # BaseLayout, BlogLayout, etc.
│ ├── pages/ # Routes
│ │ ├── api/ # API (e.g. quotes)
│ │ ├── brain-science/ # Analytics-style pages
│ │ └── p/ # Post pages
│ ├── styles/ # Global CSS, fonts
│ ├── types/ # TypeScript types
│ └── utils/ # Utilities
├── scripts/ # Build/content automation
├── docs/ # Project documentation
└── astro.config.mjs
- Feature-specific components: Components that belong to a specific feature area (for example
brain-science) live undersrc/components/<feature>/and are only imported by pages in the matching route segment (for examplesrc/pages/brain-science/). Shared, reusable UI lives at the root ofsrc/components/and can be imported anywhere. This keeps feature internals from leaking into unrelated routes and helps avoid circular dependencies as new features are added.
Posts use a shared frontmatter format. See docs/frontmatter-spec.md.
Example:
---
title: 'Post Title'
description: 'Short description for SEO'
pubDate: '2025-01-01T00:00:00.000Z'
language: ['en']
heroImage: '/images/hero-image.jpg'
category: ['integration-growth']
tags: ['tag1', 'tag2']
featured: true
translationGroup: 'unique-group-id'
draft: false
---Reading time is computed by a remark plugin at build time and exposed as minutesRead. No manual field in frontmatter.
- Completion is considered at ~75% of article content (before comments/footer).
- Data is stored only in the browser (
localStorage); no server tracking. - Optional toast and cross-tab sync. Config in
src/config/storage.ts.
- Use the same
translationGroupon both language versions. - Set
featured: truefor the primary (e.g. English) andfeatured: falsefor the other so only one appears in main listings. - Language toggles link to the other version. See docs/multilingual-setup.md.
Defined in src/data/categories.ts. Examples: Art & Expression, Culture, DIY & Creation, Integration & Growth, Learning Projects, Metaspace, Parenting, Politics, Psychology, Systems & Strategy.
- Theme – Dark/light with system preference
- Search – Client-side search over posts
- Homepage – Featured posts and highlights
- Archive – Chronological list with lazy loading
- Guided Path – Themed reading path with local progress
- Tags – Filtering and tag analytics (brain-science)
- Brain Science – Writing analytics (insights, evolution, topics, cadence, patterns, meta)
- Comments – Remark42 (self-hosted); requires setup
- RSS/JSON – Feeds for syndication
- Quotes API –
GET /api/quotesfor random Stoic quotes (see docs/quotes-api.md) - Structured data – Schema.org types (e.g. WebSite, Organization, Person, BlogPosting, BreadcrumbList, FAQ where applicable). See docs/structured-data-optimization.md.
- Endpoint:
GET /api/quotes - Returns: One random Stoic quote plus metadata.
- Docs: docs/quotes-api.md
| Doc | Description |
|---|---|
| Frontmatter spec | Post frontmatter format |
| Roadmap | Upcoming features and ideas |
| Comments setup | Remark42 configuration |
| Quotes API | Quotes endpoint |
| Multilingual setup | Translation linking |
| Structured data | Schema.org implementation |
| Performance | Performance notes |
| Technical audit | Codebase audit (point-in-time) |
- Content: CC BY-NC-SA 4.0 — see CONTENT_LICENSE.md.
- Code: MIT — see LICENSE.