Portfolio / digital garden

active active deadline none last tended 2026-05-28

A public-facing website that doubles as portfolio and digital garden, fed by the second-brain. New Obsidian notes flagged publish: true flow automatically into pages on the site.

Goal

A live site at a real domain that:

  1. Functions as a portfolio (about, projects, now, contact)
  2. Functions as a digital garden — notes from the second-brain that I’ve explicitly marked publishable appear here, with backlinks preserved
  3. Has a build-time workflow so adding/editing a note in Obsidian and flipping publish: true is enough to make it live; no separate editing in the site repo

Success markers:

  • Deployed on Vercel under a real domain
  • At least 5 garden notes + 3 projects + a /now page live
  • I never have to edit code to publish a new piece of writing — just flip the frontmatter flag

Why

Emre’s body of writing already exists in the second-brain. The garden makes it legible to the outside world without duplicating writing surfaces. It’s also the natural complement to the instagram-warmup — short-form on IG drives people somewhere, and that somewhere should be his garden, not a generic link-tree.

Architecture

  • Repo: ~/Documents/GitHub/emre-garden/ (sibling to second-brain — separate so the second-brain’s auto-commit hook doesn’t thrash the site)
  • Stack: Astro + MDX + Tailwind. Astro chosen over Next.js for content-first simplicity and the strongest digital-garden ecosystem.
  • Source of truth: second-brain is canonical. Garden is a projection of it.
  • Sync: build-time script reads ~/Documents/GitHub/second-brain, filters notes by frontmatter publish: true, transforms wikilinks → real URLs, writes into Astro’s src/content/ directory.
  • Publish gate: publish: true in frontmatter. Default = private.
  • Deploy: Vercel. GitHub Action rebuilds the garden when second-brain pushes (since 99% of changes live there).

Status

2026-05-28 — v1 shipped, live at https://emre-garden.vercel.app/

What’s deployed:

  • Astro 6 site with content collections, hand-coded vanilla CSS, pixel-art SVG sprites
  • Sync pipeline (scripts/sync.mjs) that walks the vault, filters publish: true, transforms wikilinks → URLs, computes backlinks, runs a force-directed layout for the graph
  • Pages: /, /garden, /garden/[slug], /projects, /projects/[slug], /graph, /now, /about
  • Network view at /graph — pixel-art nodes, dotted edges, hover-to-isolate-neighbors
  • 5 published notes seeded as the first content (3 in topics/content/, 2 projects including this one)
  • Vercel deploys on every push to garden master; production alias is public, hash URLs are SSO-protected
  • npm run ship = one-command sync + commit + push from the garden repo
  • Second-brain added as a git submodule at vendor/second-brain (local only — Vercel auto-fetch needs a follow-up)

Open loops

  • Scaffold Astro repo at ~/Documents/GitHub/emre-garden/
  • Write sync script + wikilink transformer + content schemas
  • Page layouts (home, garden, projects, graph, now, about) — lo-fi pixel-art direction in place
  • Pixel-art sprite system (seed, evergreen, flame, tomb, house, moc, star, brand)
  • Connect to Vercel + first production deploy
  • First 5 notes marked publish: true to seed the network
  • npm run ship one-command publish flow
  • Decide eventual domain name (current: emre-garden.vercel.app)
  • Choose the auto-deploy upgrade path (A or B) — decision pending:
    • (A) Give Vercel GitHub-app access to second-brain repo, re-enable submodule fetch in vercel.json, add a Vercel Deploy Hook + GH Action in second-brain that pings it on push
    • (B) GH Action in second-brain that clones the garden repo, runs sync, commits + pushes (needs a deploy key)
  • Design pass beyond v1 — custom typography, mobile polish, possibly graph-as-landing
  • Publish more notes (MOCs as hub pages? more topics/content/ notes?)
  • Add tag filtering on /graph

Decisions log

  • 2026-05-28 — separate repo, not subdirectory of second-brain. Reason: auto-commit hooks in the vault would noise-up the code repo, and Node projects pollute the notebook.
  • 2026-05-28 — Astro over Next.js. Reason: content-first, simpler build, strong digital-garden patterns already established in the ecosystem.
  • 2026-05-28 — publish: true opt-in over private: true opt-out. Reason: default-private is safer for a personal vault with sensitive notes.
  • 2026-05-28 — vanilla CSS over Tailwind. Reason: tiny page, one designer (Claude), no shared component library to enforce — vanilla is faster to write and zero deps.
  • 2026-05-28 — hand-coded SVG pixel art over an icon library. Reason: distinctive aesthetic, total color control, scales crisply, no runtime cost. Easy to extend — new sprites are ASCII grids in src/components/sprites.ts.
  • 2026-05-28 — force-directed layout precomputed at sync time, not at runtime. Reason: small graph (~5 nodes), deterministic output, no client JS for layout, ships as static SVG.
  • 2026-05-28 — committed synced content to garden repo for v1 deploy. Reason: Vercel build needs source to build from; submodule auto-fetch on Vercel needs additional GH-app permission setup. Trade-off: synced markdown is duplicated in git. Workflow remains: npm run ship in garden after vault edits. Upgrade path tracked in open loops.

Notes

  • wikilink-spec(seed — how Obsidian wikilinks map to URLs)
  • publish-conventions(seed — what fields are required for a publishable note)

Touches

  • content — the publishing arm; complements instagram-warmup (short-form) with long-form
  • coding — the build itself is a coding project
  • (none yet)