Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ body:
- "Not sure"
- "Frontend / UI"
- "API routes"
- "Content / MDX"
- "Content / data"
- "Docs / DX"
- "CI / tooling"
- "Other"
Expand Down
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

## Checklist

- [ ] I have read [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
- [ ] I have read **[CONTRIBUTING.md](../CONTRIBUTING.md)** and **[CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md)**.
- [ ] No secrets, `.env.local`, or production tokens are included in this PR.
- [ ] **[README.md](../README.md)** / **[`.env.example`](../.env.example)** updated if routes, APIs, user-facing behavior, or env vars changed.
- [ ] **[CLAUDE.md](../CLAUDE.md)** updated if architecture, main data flows, or important paths changed (keeps AI / editor context aligned with README).
Expand Down
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Config: [`app/lib/spotify-playlists.ts`](app/lib/spotify-playlists.ts) (`CURATED
- **Mount:** [`app/components/subpage-enter.tsx`](app/components/subpage-enter.tsx) — portaled to `document.body`, `position: fixed` (does not affect layout flow)
- **Discovery order:** explicit `TocSection` (`data-toc-item`) → `.mag-label` → `.mag-card h1/h2`
- **Shown when:** ≥2 entries, viewport gutter ≥28px right of content column, not on excluded paths (`/music-for-life/map`)
- **Home `/`:** `TocSection` labels — Kai T. Chen, Greeting, Contact; `.mag-label` — Listening, Location, Projects. Identity row uses **`md:flex-row-reverse`** + mobile `order-*` so TOC DOM order matches reading order **without** CSS Grid row-height gaps under the social column.
- **Home `/`:** `TocSection` labels — Kai T. Chen, Greeting, Contact; `.mag-label` — Listening, Location. Identity row uses a responsive **CSS Grid** (`md:grid-cols-[36%_1fr]`) plus mobile `order-*`; the intro stays first in DOM so TOC order matches reading order while the photo/social column renders first on mobile.
- **Playlist pages:** index = Music for Life + each playlist name (`level={1}`); detail = playlist name + **Tracks** — never one TOC entry per song.

### Performance / loading (recent)
Expand All @@ -136,4 +136,3 @@ Config: [`app/lib/spotify-playlists.ts`](app/lib/spotify-playlists.ts) (`CURATED
| Human contribution process | [CONTRIBUTING.md](CONTRIBUTING.md) |
| Short Claude Code stack summary | [CLAUDE.md](CLAUDE.md) |
| Security reporting | [SECURITY.md](SECURITY.md) |
| Cursor IDE git reminder | [`.cursor/rules/git-workflow.mdc`](.cursor/rules/git-workflow.mdc) |
17 changes: 9 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@ Canonical documentation: **[README.md](README.md)** (setup, routes, APIs, env, C
| **Now playing** | `GET /api/spotify/now-playing` — Spotify Web API; optional Supabase writes (`listening_*`) with service role |
| **Last month top** | `GET /api/spotify/last-month-top` — Spotify top tracks (`short_term`, needs `user-top-read`) |
| **Client polling** | `app/hooks/use-now-playing.ts` — polls every **10s** (`cache: "no-store"`) |
| **GitHub** | `GET /api/github/contributions` — GraphQL calendar; hand-maintained project list in `app/lib/personal-projects.ts` (stars fetched live) |
| **Weather** | `GET /api/weather` — Open-Meteo (Berkeley); `berkeley-time.tsx` |
| **Home UI** | Identity + social links; **Listening** / **Location** cards; **Projects** outer card with nested Course + Personal (`projects-split.tsx`); **PageToc** (Kai T. Chen, Greeting, Contact, Listening, Location, Projects) |
| **GitHub** | `GET /api/github/contributions` — GraphQL calendar endpoint; hand-maintained course/personal lists merge descriptions, topics, stars, and archive state from GitHub |
| **Weather** | `app/lib/weather.ts` fetches Open-Meteo for home SSR; `GET /api/weather` mirrors it; `berkeley-time.tsx` renders local time |
| **Home UI** | Identity + Email/GitHub/LinkedIn/X links; **Listening** / server-rendered **Location** cards; **PageToc** (Kai T. Chen, Greeting, Contact, Listening, Location) |
| **Music for Life** | `/music-for-life` — curated Spotify playlists ([`MUSIC_FOR_LIFE_BASE`](lib/spotify-playlists.ts)); `[id]` detail; `/map` Mapbox viewer; old `/playlists` → 301 redirect |
| **Page TOC** | [`page-toc.tsx`](app/components/page-toc.tsx) + [`toc-section.tsx`](app/components/toc-section.tsx) — fixed right rail on `/`, `/about`, `/projects`, `/misc`, `/music-for-life` (not map); auto `.mag-label` + explicit `TocSection` |
| **Course Projects** | `app/lib/course-projects.ts` — Oxford DUL (`/projects/oxford-dul-2025`) + Notion notes |
| **Course Projects** | `app/lib/course-projects.ts` — Kai Course Notes entry backed by GitHub metadata; Oxford DUL remains at `/projects/oxford-dul-2025` |
| **Oxford portfolio** | `app/lib/oxford-dul-projects.ts` + `app/projects/oxford-dul-2025/` + `app/components/oxford-dul/` |
| **Nav** | Bold labels; active link = accent + pill underline (`.nav-link` in `globals.css`) |
| **Nav** | Desktop/mobile text links use the shared blue/yellow palette with no decorative underline (`.nav-link` in `globals.css`) |
| **List link pattern** | `hover-link-hint.tsx` — leading ↗ on hover, trailing `Label ↗`; row hover bg on list rows |
| **Misc** | Watching / Remembrance / Things I Love (nested `mag-card-inset` categories) |
| **Typography** | Geist on `body`; **Nunito** for nav + `.mag-card` / `.mag-label` |
| **Theme** | `theme-provider.tsx` — default **light** when unset |
| **Misc** | Things I Love (nested `mag-card-inset` categories) / Resources / Watching / Remembrance |
| **Typography** | Geist Sans / Mono is the base system; **Nunito** is used across the editorial UI (nav, headings, cards, lists, controls) |
| **Theme** | White/black page bases; structural blue `#628ea7`; hover yellow `#f8b364`; layered blue card borders/shadows |
| **Theme mode** | `theme-provider.tsx` — default **light** when unset |

---

Expand Down
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ reporter of any incident.

For this repository, contact the maintainer:

- Via the email on the [About](https://kaichen.dev/about) page, or
- Via [kaichen.dev.37@gmail.com](mailto:kaichen.dev.37@gmail.com) (also available from the homepage Contact links), or
- Through GitHub ([@kaiiiichen](https://github.com/kaiiiichen)) for non-sensitive matters.

For **security vulnerabilities**, do not use a public issue — follow [SECURITY.md](SECURITY.md) instead.
Expand Down
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Before you contribute:
| Human contributors | This file + [README](README.md) |
| AI coding agents (Cursor, Claude Code, etc.) | [AGENTS.md](AGENTS.md) — **branch + PR workflow** and commit conventions are mandatory |

Maintainers use **pull requests to `main`**; direct pushes to `main` are discouraged even when permissions allow.
All changes go through **pull requests to `main`**; do not push directly to `main`, even when permissions allow.

---

Expand Down Expand Up @@ -94,11 +94,13 @@ npm run build

- **Next.js 16** App Router, **React 19**, **TypeScript**, **Tailwind CSS 4**, **Vitest 4** for unit tests.
- `dev` and `build` use Next.js' default **Turbopack** bundler (no MDX in this repo).
- **Fonts:** Geist Sans/Mono on `<html>` / default `body`; **Nunito** for nav and magazine-style cards (see [`app/globals.css`](app/globals.css), [`app/layout.tsx`](app/layout.tsx)).
- **Fonts:** Geist Sans/Mono provide the base type system; **Nunito** is used across the editorial UI (nav, headings, cards, lists, and controls). See [`app/globals.css`](app/globals.css), [`app/layout.tsx`](app/layout.tsx), and [`app/fonts.ts`](app/fonts.ts).

### Style

- Match existing component patterns, naming, and Tailwind usage.
- Preserve the shared interaction palette: structural/link blue (`--link-color`), yellow hover/focus (`--link-hover-color`), and the layered blue `.mag-card` border/shadow hierarchy.
- Keep `PageToc` discovery intact when restructuring pages: prefer explicit `TocSection` targets or existing `.mag-label` sections, and exclude fullscreen routes such as `/music-for-life/map`.
- Prefer **small, reviewable diffs** over large refactors unless discussed in an issue first.
- **Dark mode:** new UI should work in light and dark (`dark:` variants and existing theme patterns).

Expand Down
Loading