diff --git a/.cursor/environment.json b/.cursor/environment.json new file mode 100644 index 0000000..8a24b76 --- /dev/null +++ b/.cursor/environment.json @@ -0,0 +1,17 @@ +{ + "name": "gh-blog (Astro)", + "install": "bash .cursor/install.sh", + "terminals": [ + { + "name": "astro-dev", + "command": "export PATH=\"$HOME/.bun/bin:$PATH\" && bun run dev --host", + "description": "Astro dev server on http://localhost:4321" + } + ], + "ports": [ + { + "name": "astro-dev", + "port": 4321 + } + ] +} diff --git a/.cursor/install.sh b/.cursor/install.sh new file mode 100755 index 0000000..3a5fbcc --- /dev/null +++ b/.cursor/install.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Install the pinned bun (matches packageManager in package.json) if missing. +BUN_VERSION="1.4.2" +if ! command -v bun >/dev/null 2>&1; then + curl -fsSL https://bun.sh/install | bash -s "bun-v${BUN_VERSION}" +fi +export PATH="$HOME/.bun/bin:$PATH" + +bun install --frozen-lockfile diff --git a/.tasks/ROADMAP.md b/.tasks/ROADMAP.md index a907c87..b903eb3 100644 --- a/.tasks/ROADMAP.md +++ b/.tasks/ROADMAP.md @@ -11,11 +11,12 @@ | ----- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | 0 | Foundation: 브랜치·툴체인·지식기반 | `main` 전환, Node 22 + **bun** 고정 (yarn classic 잔재 제거), Astro Docs MCP + Astro 스킬 1개 + StyleX ESLint 룰 확정, StyleX 스파이크(o) | `main`이 default, `bun run dev`+StyleX 샘플 빌드 그린, 스킬 목록 `SPEC`에 핀 | [SPEC](phase-0-foundation/SPEC.md) · [PLAN](phase-0-foundation/PLAN.md) | | 1 | Scaffold + Design System + Home/Tags 껍데기 + 배포 | Astro v7 스캐폴드(static), StyleX 토큰/프리미티브, Home·Tags 라우트, GH Pages Actions 배포 | `main` 푸시→Pages 자동배포, Lighthouse perf≥90·a11y≥95, 스타일런타임 주입 0 | [SPEC](phase-1-scaffold-design-system/SPEC.md) · [PLAN](phase-1-scaffold-design-system/PLAN.md) | +| 1.5 | Visual design 적용 | 컨셉 PNG + `docs/conventions/design.md` 토큰·타이포·레이아웃. Prism.js Vitesse Light 계열 코드 블록. Home/목업 기사·위키 | 코드 블록이 다크가 아님, a11y≥95, 런타임 스타일 주입 0 | [SPEC](phase-1.5-visual-design/SPEC.md) · [PLAN](phase-1.5-visual-design/PLAN.md) | | 2 | Content Routes + MDX 마이그레이션 | `articles`(가변 테마) + `til`(통일) + `tags/[tag]`, Content Collections(Zod), 기존 6개 + `llm-wiki-template/wiki` 선별 이식 | 기존글 100% 렌더(깨진 링크 0), 스키마 위반 0, articles≥2 colorway 데모 | [SPEC](phase-2-content-routes/SPEC.md) · [PLAN](phase-2-content-routes/PLAN.md) | | 3 | Wiki Quiz (flash cards) | 랜덤 객관식/주관식, 덱·세션·채점·localStorage 진척, island로 SSG 무해화 | 퀴즈 20문항 시드, 키보드 조작·채점 단위테스트 그린 | [SPEC](phase-3-wiki-quiz/SPEC.md) · [PLAN](phase-3-wiki-quiz/PLAN.md) | | 4 | Hardening + 운영 | Pagefind 검색, SEO/RSS/OG/sitemap, 404, CI 가드(lint·link·schema·공개안전), 구 `gh-pages` 정리 | 검색 Top-3 적중 수동체크, CI 그린, 구배포 경로 제거 | [SPEC](phase-4-hardening-ops/SPEC.md) · [PLAN](phase-4-hardening-ops/PLAN.md) | -의존성: 0 → 1 → 2 → 3 → 4 순차. 3·4는 2 승인 후 병렬 검토 가능. +의존성: 0 → 1 → 1.5 → 2 → 3 → 4 순차. 3·4는 2 승인 후 병렬 검토 가능. ## 정보구조 (1차 범위) @@ -23,7 +24,7 @@ - 고도화: `/wiki/quiz` — flash cards, 랜덤 객관식/주관식 (Phase 3, islands) - `articles`: 페이지별 자유 구성 — frontmatter(`theme`, `layout`, `colorway`, `components`)로 컬러셋·레이아웃 분기, MDX 안에서 자유 조립 - `til`/`wiki`: 단일 `WikiLayout` + 단일 스키마로 통일감 -- 스타일: minimalism + light theme + "적당한 고급스러움" (타이포·여백·헤어라인·절제된 액센트) +- 스타일: [`docs/conventions/design.md`](../docs/conventions/design.md) — 따뜻한 베이지 캔버스, 민트 액센트, Prism Vitesse Light 계열. 컨셉: `.tasks/visual-concept-by-gpt-09-10.png`. - UI: 재활용 가능한 design-system 컴포넌트, **StyleX** 기반 (`tokens → primitives → patterns`) ## 코드 스타일 (전 Phase 공통) @@ -34,7 +35,7 @@ - Phase 0에서 `master`→`main` (이력 유지 rename, GitHub default 전환, Pages 소스 재지정, `deploy.yml`의 `branches:[master]` 제거가 Phase 1에서). - Phase별 스택 (base 체인, 아래→위 순서로 머지): - `main` ← `feat/ci-gates` ← `feat/phase-0-foundation` ← `feat/phase-1-scaffold` ← `feat/phase-2-content` ← + `main` ← `feat/ci-gates` ← `feat/phase-0-foundation` ← `feat/phase-1-scaffold` ← `feat/phase-1.5-visual` ← `feat/phase-2-content` ← `feat/phase-3-quiz` ← `feat/phase-4-hardening` - 생성: 페이즈 완료 즉시 `gh pr create --draft --base ` (draft). planner/verifier 리뷰 통과 후 `gh pr ready`. CI는 PR마다 자동 실행 (CI 선행 머지 후). - 머지는 아래부터 순서대로 (GitHub "Merge" + base 자동전환 확인). `gh` 2.100.0 설치 확인됨. @@ -46,7 +47,7 @@ - Cursor (Cline 한도 소진 시 기본): [harness/cursor.md](playbook/harness/cursor.md) — 부모 Grok 4.6 (orchestrator+leader), planner·verifier 서브에이전트, Composer 2.5 implementer는 worktree. 정의: `.cursor/agents/`. - Cline + Herdr: [harness/cline-herdr.md](playbook/harness/cline-herdr.md) — pane 3개, muse-spark / glm-5.3-flash (2026-09-10 실측). - Claude Code / Codex: 스텁. 첫 실사용 때 `_template.md`로 승격. - 흐름: leader 추적 → planner가 PLAN 정제 → developer 구현 + **draft** PR → verifier 리뷰 (Cursor: GPT 5.6 Sol medium) → ready 전환 → **사람 머지**. + 흐름: leader 추적 → planner가 PLAN 정제 → developer 구현 + **draft** PR → verifier 리뷰 (Cursor: Sol → 막히면 Opus 5 → 비용 크면 Grok·Kimi K3) → ready 전환 → **사람 머지**. **미사용:** Paseo, opencode-go 모델. ## 승인 플로우 diff --git a/.tasks/phase-1.5-visual-design/LOG.md b/.tasks/phase-1.5-visual-design/LOG.md new file mode 100644 index 0000000..e5ae6d5 --- /dev/null +++ b/.tasks/phase-1.5-visual-design/LOG.md @@ -0,0 +1,10 @@ +# Phase 1.5 LOG + +- Harness: cursor +- Started: 2026-09-10 +- Status: SPEC+PLAN 작성. 구현은 승인 후. + +## Notes + +- 컨셉 PNG와 `docs/conventions/design.md`를 대조해 코드 블록만 라이트 Prism으로 뒤집음. +- 스택: `feat/phase-1-scaffold` ← `feat/phase-1.5-visual`. diff --git a/.tasks/phase-1.5-visual-design/PLAN.md b/.tasks/phase-1.5-visual-design/PLAN.md new file mode 100644 index 0000000..d494a10 --- /dev/null +++ b/.tasks/phase-1.5-visual-design/PLAN.md @@ -0,0 +1,29 @@ +# Phase 1.5 PLAN — Visual design 적용 + +> 상태: SPEC 대응 초안. 브랜치 `feat/phase-1.5-visual`, **base = `feat/phase-1-scaffold`**. + +정본: [`docs/conventions/design.md`](../../docs/conventions/design.md). +목업: [`.tasks/visual-concept-by-gpt-09-10.png`](../visual-concept-by-gpt-09-10.png). + +## 순서 + +1. **토큰** — `src/styles/tokens.stylex.ts`를 design.md §3·6·7로 교체 (canvas, surface, ink, accent `#16A36A`, space 4px, radius). Phase 1 `#3F6B5A` / `#FAFAF8` 제거. 컴포넌트가 시맨틱 토큰만 쓰게 맞춤. + - 수용: `bun run check` 그린, Storybook에서 paper가 `#F7F5EE`에 가깝다. +2. **폰트** — Pretendard 또는 Noto Sans KR, Geist Mono. 디스플레이는 라이선스 확인 후 1개만(히어로·기사 제목). `Base.astro`에서 로드. 본문·nav에 손글씨 금지. +3. **Prism** — `bun add @astrojs/prism prismjs`. `astro.config.mjs` `markdown: { syntaxHighlight: 'prism' }`. `src/styles/prism-vitesse-light.css` (design.md §11 토큰). `Base.astro`에서 import. `src/components/content/CodeBlock` (lang, copy). 다크 테마 CSS 없음. + - 수용: 빌드 HTML에 `class="language-*"`, `pre` 배경이 `#F1EFE6` 근처. `grep -l okaidia` 없음. +4. **Home** — 컨셉 01: 작은 라벨, 손글씨 문장, 짧은 소개, CTA, 반대편 장식(WebGL island 또는 CSS 폴백). 최신글은 리스트(날짜·제목·요약·태그). `prefers-reduced-motion`이면 정적 민트 형태만. +5. **목업 기사·위키** — `src/pages/articles/mock.astro`, `src/pages/til/mock.astro` (Phase 2 라우트와 맞출 이름). 기사: 메타 + 손글씨 제목 + 본문 폭 `--reading-max` + 우측 TOC(데스크탑) + Prism 예시 + Tip callout. 위키: 좌측 가벼운 사이드바 + 본문. Collections 없음. +6. **스토리** — 토큰·CodeBlock·Header·PostCard 갱신. `bun run build-storybook`. +7. **게이트** — `check` / oxfmt / oxlint / vitest / build / Lighthouse Home+mock article / 런타임 JS 스타일 주입 0. +8. **draft PR** — `--base feat/phase-1-scaffold --assignee @me --label phase-1.5 --label astro --label conventions`. 머지는 사람. Phase 1(#56)이 먼저 머지돼야 디프가 맞다. + +## 검증 + +- Prism: mock 페이지 소스에 `token keyword` 등이 있고, 스크린샷에서 코드 블록이 베이지다 (차콜 아님). +- `bunx oxfmt --check .` · `bunx oxlint .` 그린. + +## 승인 요청 + +- [ ] 다크 코드 블록을 버리고 Prism Vitesse Light 계열로 가는 것 동의? +- [ ] 실 콘텐츠 없이 mock article/wiki로 레이아웃을 먼저 고정하는 것 동의? (Phase 2에서 교체) diff --git a/.tasks/phase-1.5-visual-design/SPEC.md b/.tasks/phase-1.5-visual-design/SPEC.md new file mode 100644 index 0000000..4d74d73 --- /dev/null +++ b/.tasks/phase-1.5-visual-design/SPEC.md @@ -0,0 +1,49 @@ +# Phase 1.5 — Visual design 적용 + +> 상태: SPEC+PLAN 작성됨 / 승인 대기. 브랜치 `feat/phase-1.5-visual`, base `feat/phase-1-scaffold`. + +## 1. 배경 + +Phase 1은 스캐폴드·토큰 자리·Home/Tags 껍데기까지다. 토큰은 아직 paper `#FAFAF8` / sage accent `#3F6B5A`다. + +2026-09-10 컨셉 [`.tasks/visual-concept-by-gpt-09-10.png`](../visual-concept-by-gpt-09-10.png)과 계약 [`docs/conventions/design.md`](../../docs/conventions/design.md)이 생긴다. 콘텐츠 이식(Phase 2) 전에 **보이는 페이지를 이 계약에 맞춘다.** + +검토 결론 (구현은 계약 파일): + +- 따뜻한 베이지 캔버스 + 민트 액센트 + 손글씨 디스플레이(희소) + Geist Mono — 컨셉과 문서가 같다. +- 컨셉 목업 헥스(`#FBF6EF`, `#10B981`, 카드 `#FFF`)는 Tailwind에 가깝다. 구현은 design.md (`#F7F5EE`, `#16A36A`, surface `#FCFBF7`). +- 컨셉·초안 design.md의 **다크 코드 블록은 버린다.** Prism.js + Vitesse Light 계열, 배경은 캔버스에 한 단계만 낮춘 `#F1EFE6`, 키워드는 액센트. + +## 2. 목표 + +1. StyleX 시맨틱 토큰을 `docs/conventions/design.md` §3·§6·§7에 맞춘다. Phase 1 자리 토큰을 덮어쓴다. +2. 타이포: Pretendard/Noto Sans KR 본문, Geist Mono 코드·메타, 디스플레이 손글씨(히어로·기사 제목만). +3. Home을 컨셉 01에 가깝게: 손글씨 히어로, CTA, 최신글은 빽빽한 그리드가 아니라 에디토리얼 리스트. WebGL은 island + 정적 폴백 + `prefers-reduced-motion`. +4. 목업 기사(`/articles/mock`)와 위키(`/til/mock` 또는 `/wiki/mock`): 우측 TOC / 좌측 사이드바, Callout, **Prism 코드 블록**. 실 Collections는 Phase 2. +5. 코드: `markdown.syntaxHighlight: 'prism'`, `@astrojs/prism`, `src/styles/prism-vitesse-light.css`를 `Base.astro`에서 로드. 다크 Prism 테마 금지. +6. 해당 UI `*.stories.ts` 갱신. + +## 3. 비목표 + +- MDX 6편 이식, Collections, `colorway` 다중 테마 (Phase 2). +- Quiz, Pagefind, 다크모드. +- 컨셉의 “Was this helpful?” / Three.js를 전 페이지에 깔기. + +## 4. 산출물 + +- 갱신된 `src/styles/tokens.stylex.ts`, `prism-vitesse-light.css`, `CodeBlock` (+ copy). +- Home / mock article / mock wiki가 컨셉 레이아웃을 따른다. +- Storybook 스토리 갱신. + +## 5. 종료 게이트 + +- [ ] `bun run check` · `bunx oxfmt --check .` · `bunx oxlint .` · `bunx vitest run` 그린. +- [ ] `bun run build` 그린. 런타임 스타일 주입 0. Prism 클래스가 HTML에 있고, 코드 `pre` 배경이 다크(`#171A18` 등)가 아님. +- [ ] Home·mock article Lighthouse a11y ≥ 95. `prefers-reduced-motion`에서 WebGL 미로드. +- [ ] `bun run build-storybook` 그린. +- [ ] 본문 대비: canvas 위 ink가 WCAG AA. + +## 6. 리스크 + +- 웹폰트 + WebGL이 Lighthouse perf를 깎음 → 서브셋, lazy island, 모바일에서 WebGL 생략. +- Gmarket Sans 라이선스: 컨셉에만 등장. 구현은 라이선스 확인된 디스플레이 페이스(또는 시스템 손글씨 폴백). diff --git a/.tasks/playbook/README.md b/.tasks/playbook/README.md index cf984c5..15213eb 100644 --- a/.tasks/playbook/README.md +++ b/.tasks/playbook/README.md @@ -21,7 +21,7 @@ Message verbs (`DONE`, `BLOCKED`, `PLAN-CHANGE`, `PLAN-READY`, `PR-DRAFT`, `PR-READY`, `REVIEW`) are identical across harnesses. Append every report to `.tasks/phase-N-*/LOG.md`. -PR lifecycle: developer opens `--draft` immediately at phase complete (`PR-DRAFT`) → verifier review (Cursor: GPT 5.6 Sol medium) → on `REVIEW APPROVE`, `gh pr ready` (`PR-READY`) → **human merges**. +PR lifecycle: developer opens `--draft` immediately at phase complete (`PR-DRAFT`) → verifier review (Cursor: Sol → Opus 5 if blocked → Grok·Kimi if expensive) → on `REVIEW APPROVE`, `gh pr ready` (`PR-READY`) → **human merges**. A harness **may fold** orchestrator + leader into one parent session (Cursor default). That is a mapping, not a license to drop LOG or gates. diff --git a/.tasks/playbook/harness/cursor.md b/.tasks/playbook/harness/cursor.md index 5f38da6..06857c1 100644 --- a/.tasks/playbook/harness/cursor.md +++ b/.tasks/playbook/harness/cursor.md @@ -46,7 +46,7 @@ Never two write-capable agents on the same checkout. | orchestrator / leader | Grok 4.6 in the parent picker | long tool loops, instruction following | | planner | `inherit` | same judgment as parent | | developer | `composer-2.5` (`composer-2.5-fast` if the Fast variant is the picker name) | edits + terminal | -| verifier | `gpt-5.6-sol-medium` | draft review (SPEC + gates). OpenAI models in Cursor: proposed shutoff **2026-11-12** ([OpenAI](https://openai.com/index/our-decision-on-cursor-following-its-acquisition-by-spacex/)). After that, fallback `inherit` (Grok) and LOG it. | +| verifier | `gpt-5.6-sol-medium` | Default review. Blocked → Opus 5. Expensive → Grok then Kimi K3. OpenAI shutoff 2026-11-12. | On **legacy request-based plans without Max Mode**, Cursor may ignore `model:` and run subagents as Composer. If that happens, run planner/verifier in the parent Grok chat instead of Task, and LOG the fallback. @@ -54,20 +54,30 @@ If Grok quota is exhausted: keep this harness, switch the **parent** picker to w ## OpenAI / GPT window and usage -- Official proposed shutoff of OpenAI models in Cursor: **2026-11-12**. Do not start a Sol review on or after that date; switch verifier to Grok (`inherit`) first. -- After **every** Sol review, append to `.tasks/phase-N-*/LOG.md`: - - `model: gpt-5.6-sol-medium` - - start/end timestamps - - Cursor usage if the UI shows it (request cost on the review turn, or Settings → Usage delta). There is no billing API in this harness — if the number is not visible, write `usage: not visible` and still record the model + time. - - verdict (`REVIEW APPROVE|CHANGES`) -- If one review looks expensive relative to a Grok/Composer pass, **stop** and ask the human before the next Sol review. Candidate fallbacks: Grok (`inherit`), then Composer. +- Default review model: `gpt-5.6-sol-medium`. Proposed OpenAI Cursor shutoff **2026-11-12** ([OpenAI](https://openai.com/index/our-decision-on-cursor-following-its-acquisition-by-spacex/)). +- After **every** review spawn, append to `.tasks/phase-N-*/LOG.md`: model slug, start/end, `usage` (UI cost or `not visible`), verdict. +- Fallback (do not ask the human first — this is the pin): + +```mermaid +flowchart TD + S["verifier spawn"] --> Sol["gpt-5.6-sol-medium"] + Sol -->|"blocked: resource_exhausted / 404 / after 2026-11-12"| Opus["claude-opus-5-thinking-high"] + Sol -->|"completed but expensive"| Cheap{"cheaper reviewer"} + Opus -->|"expensive or blocked"| Cheap + Cheap --> Grok["inherit Grok / cursor-grok-4.6-high"] + Cheap --> Kimi["kimi-k3-max"] +``` + +- **Blocked** = spawn error, quota, or shutoff. Next try is Opus 5. +- **Expensive** = the human or a huge usage delta vs a Grok pass. Next try is Grok, then Kimi K3. LOG the substitution. +- `.cursor/agents/verifier.md` `model:` stays Sol. Parent Task overrides `model` on fallback. ## Spawn sequence (per phase) 1. Parent (Grok) reads SPEC + PLAN + this file. Creates or updates `.tasks/phase-N-*/LOG.md` (leader duties). 2. `Use the planner subagent` (or `/planner`) with the Part A brief. Wait for `PLAN-READY`. Human may still be asked to approve PLAN deltas. Planner is **not** `readonly` (it writes PLAN.md); treat product-code edits as a bug. 3. After PLAN-READY: `Run the implementer subagent on Composer in its own worktree` with the developer brief (`../developer.md`). Isolation phrase is mandatory. Implementer must open `--draft` and stop at `PR-DRAFT`. -4. On `PR-DRAFT`: `/verifier` on **GPT 5.6 Sol medium** (covers planner Part B). Do not spawn a second reviewer. Record usage in LOG. Do not mark the PR ready yet. +4. On `PR-DRAFT`: `/verifier` on **GPT 5.6 Sol medium**. If spawn is blocked, retry Opus 5 (`claude-opus-5-thinking-high`). If a review is expensive, next ones use Grok then Kimi K3. Record usage in LOG. Do not mark the PR ready yet. 5. On `REVIEW APPROVE`: implementer (or parent) runs `gh pr ready`, then `PR-READY`. 6. Parent records ready + asks the **human to merge**. Do not `gh pr merge` unless the human explicitly asked for that phase (Phase 0 was that exception). @@ -77,7 +87,8 @@ Parent prompt (copy): Harness: cursor. Fold leader into this chat. Use the planner subagent first (PLAN.md only). After PLAN-READY and human ack, run the implementer subagent on Composer in its own worktree. -Implementer opens a draft PR (PR-DRAFT). Then run verifier on GPT 5.6 Sol medium. +Implementer opens a draft PR (PR-DRAFT). Then run verifier on GPT 5.6 Sol medium +(Opus 5 if Sol is blocked; Grok then Kimi K3 if a review is expensive). After REVIEW APPROVE, gh pr ready. Do not merge. Do not implement product code in this chat. ``` diff --git a/.tasks/visual-concept-by-gpt-09-10.png b/.tasks/visual-concept-by-gpt-09-10.png new file mode 100644 index 0000000..56903c2 Binary files /dev/null and b/.tasks/visual-concept-by-gpt-09-10.png differ diff --git a/AGENTS.md b/AGENTS.md index b3dc0b5..3c2ee88 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,7 +34,7 @@ - Multi-agent: role contracts in `.tasks/playbook/`; spawn/models in `.tasks/playbook/harness/` (one harness per phase). Cursor default: [harness/cursor.md](.tasks/playbook/harness/cursor.md). - Commits: [`docs/conventions/commits.md`](docs/conventions/commits.md) — logical units, conventional, Korean. Body 1–2 lines, max 3. - PRs: [`docs/conventions/prs.md`](docs/conventions/prs.md) — why / effect / design diagrams / scope. Assignee `@me`. Labels from that doc. Comments in Korean. -- Cursor review: GPT 5.6 Sol medium until OpenAI Cursor shutoff (**2026-11-12**). Then Grok. Human merges from Phase 1. +- Cursor review: GPT 5.6 Sol medium. If Sol is blocked → Opus 5. If a review is expensive → Grok then Kimi K3. OpenAI Cursor shutoff **2026-11-12**. Human merges from Phase 1. - Test titles in Korean (`describe` = symbol name). ## 6. Links diff --git a/design.md b/design.md new file mode 100644 index 0000000..8775e30 --- /dev/null +++ b/design.md @@ -0,0 +1,6 @@ +# Design System + +Canonical: [`docs/conventions/design.md`](docs/conventions/design.md). + +Visual mock: [`.tasks/visual-concept-by-gpt-09-10.png`](.tasks/visual-concept-by-gpt-09-10.png). +This root file is a pointer only — edit the conventions doc. diff --git a/docs/README.md b/docs/README.md index 358ab59..3d5c03b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ | [`conventions/code-style.md`](conventions/code-style.md) | 사람 + 에이전트 | 코드 스타일 규칙 (공유 정본 + 본 블로그 델타 + 언어 규칙) | | [`conventions/commits.md`](conventions/commits.md) | 사람 + 에이전트 | 커밋: atomic · conventional · 짧은 한국어 본문 | | [`conventions/prs.md`](conventions/prs.md) | 사람 + 에이전트 | PR: 왜·효과·설계 다이어그램·범위. 표 없이 Mermaid | -| `conventions/design.md` | 사람 + 에이전트 | 디자인 토큰·타이포·컬러 원칙 (Phase 1에서 작성 예정) | +| [`conventions/design.md`](conventions/design.md) | 사람 + 에이전트 | 비주얼 계약. 컨셉 PNG + Prism Vitesse Light. Phase 1.5 | | [`research/astro-migration.md`](research/astro-migration.md) | 사람 + 에이전트 | Astro 이주 배경·리서치·기술 판단 근거 | | `../.tasks/ROADMAP.md` | 에이전트 (작업) | 전체 로드맵·게이트·승인 플로우 | | `../.tasks/playbook/` | 에이전트 (작업) | subagent 역할·모델·프로토콜 | diff --git a/docs/conventions/code-style.md b/docs/conventions/code-style.md index 00083c9..60298a3 100644 --- a/docs/conventions/code-style.md +++ b/docs/conventions/code-style.md @@ -129,3 +129,4 @@ These differ **on purpose**. Each repo follows its own column; the difference co - 본 `.tasks/*.md` 협업 문서는 한국어 유지 + 코드 식별자 원문. - 커밋: [`commits.md`](commits.md). - PR 본문: [`prs.md`](prs.md) — 한국어, 사람 대상. 표 없이 Mermaid. +- 비주얼: [`design.md`](design.md). diff --git a/docs/conventions/design.md b/docs/conventions/design.md new file mode 100644 index 0000000..5989640 --- /dev/null +++ b/docs/conventions/design.md @@ -0,0 +1,1011 @@ +# Design System — gitgitwi Technical Blog + +> Visual direction and implementation contract for `gitgitwi.github.io`. +> Source mock: [`.tasks/visual-concept-by-gpt-09-10.png`](../../.tasks/visual-concept-by-gpt-09-10.png) (2026-09-10). +> Phase that applies this: [`.tasks/phase-1.5-visual-design/`](../../.tasks/phase-1.5-visual-design/). +> This file is the canonical `docs/conventions/design.md`. Do not keep a second copy at repo root. + +The mock is a layout north star. Where it disagrees with this contract, **this file wins** — except code blocks: the mock is dark; implementation uses **Prism.js + a Vitesse Light–like theme** on the warm canvas (see §11). + +--- + +## 1. Design Intent + +### Core feeling + +The site should feel: + +- **Elegant** — refined rather than decorative. +- **Warm** — soft beige instead of a cold white canvas. +- **Technical** — modern developer-tool aesthetics, code, diagrams, and experimental WebGL are welcome. +- **Editorial** — typography and whitespace should make long-form writing feel intentional. +- **Personal** — handwriting/brush typography is used selectively to create a recognizable author identity. +- **Quietly experimental** — advanced visual effects may appear as accents, but never interfere with reading. + +### Design keywords + +`warm` · `editorial` · `minimal` · `technical` · `organic` · `precise` · `experimental` + +### Avoid + +- Generic SaaS dashboard aesthetics. +- Excessive rounded cards. +- Heavy gradients everywhere. +- Excessive shadows. +- Neon/cyberpunk styling. +- Dense layouts with little whitespace. +- Decorative animation that competes with article content. +- Using the handwritten typeface for ordinary UI text. + +--- + +## 2. Visual Concept + +The visual system is built around a contrast between: + +1. **Warm editorial canvas** — bright beige background. +2. **Mint-green technical accent** — the primary brand signal. +3. **Neutral typography** — Pretendard or Noto Sans for readable UI/body text. +4. **Geist Mono** — code, metadata, technical labels, and machine-like details. +5. **Handwritten display type** — article titles, hero statements, and selected section headings. +6. **Generative visuals** — Three.js/WebGL shaders can provide subtle identity moments. + +The intended result is a technical blog that feels closer to an independent editorial publication than a documentation portal. + +--- + +## 3. Color + +### Core palette + +Use a warm neutral base rather than pure white. + +```css +:root { + --color-canvas: #F7F5EE; + --color-surface: #FCFBF7; + --color-surface-muted: #EFEEE7; + + --color-ink: #171A18; + --color-ink-secondary: #4D534E; + --color-ink-tertiary: #7A807B; + + --color-border: #DDDCD3; + --color-border-strong: #C9C9BF; + + --color-accent: #16A36A; + --color-accent-hover: #108A59; + --color-accent-soft: #DDF4E9; + --color-accent-ink: #087044; + + --color-code-bg: #F1EFE6; + --color-code-ink: #393a34; + --color-code-border: #DDDCD3; +} +``` + +### Color roles + +| Role | Token | Purpose | +|---|---|---| +| Canvas | `--color-canvas` | Global page background | +| Surface | `--color-surface` | Cards, elevated content | +| Muted surface | `--color-surface-muted` | Secondary sections | +| Ink | `--color-ink` | Primary text | +| Secondary ink | `--color-ink-secondary` | Supporting text | +| Tertiary ink | `--color-ink-tertiary` | Metadata/placeholders | +| Border | `--color-border` | Default separators | +| Strong border | `--color-border-strong` | Active/important boundaries | +| Accent | `--color-accent` | Mintlify-inspired primary accent | +| Accent soft | `--color-accent-soft` | Callouts, selected states | +| Code background | `--color-code-bg` | Prism block canvas — warm, near page background | +| Code ink | `--color-code-ink` | Prism default text | + +### Rules + +- Do not use pure `#000` for normal text. +- Do not use pure `#FFF` as the global background. +- Mint green should be a **signal**, not the dominant page color. +- Most pages should remain visually neutral until the accent appears. +- Green should communicate interaction, emphasis, selection, or identity. +- Maintain sufficient contrast for all body text and controls. + +Concept mock hex vs this contract (implementation uses **this contract**): + +- Canvas `#FBF6EF` (mock) → `#F7F5EE` here (slightly greener paper). +- Accent `#10B981` (Tailwind emerald on the mock) → `#16A36A` here (less saturated mint). +- Surface `#FFFFFF` (mock cards) → `#FCFBF7` here (not pure white). +- Code blocks: mock is charcoal. **Do not ship that.** Prism + Vitesse Light–like on `--color-code-bg`. + +--- + +## 4. Typography + +### Primary font + +Preferred order: + +```css +font-family: + "Pretendard", + "Noto Sans KR", + "Noto Sans", + system-ui, + sans-serif; +``` + +Use the primary sans-serif font for: + +- Navigation +- Body text +- Buttons +- Cards +- Forms +- Metadata when readability is more important than technical character + +### Monospace + +Use **Geist Mono** for: + +- Code +- Tags +- Technical metadata +- Dates when presented as a technical label +- File paths +- Version numbers +- Keyboard shortcuts +- Small technical UI elements + +```css +font-family: "Geist Mono", ui-monospace, monospace; +``` + +### Display / handwritten font + +Use a handwriting or brush-calligraphy typeface for: + +- Homepage hero statement +- Article title +- Major editorial headings +- Occasional visual annotations + +The display face must remain **sparse**. + +Never use it for: + +- Body copy +- Navigation +- Buttons +- Form controls +- Code +- Dense technical content + +### Typography hierarchy + +```text +Display / Hero +↓ +Article Title +↓ +Section Heading +↓ +Body +↓ +Metadata / Caption +↓ +Technical Label +``` + +The hierarchy should come primarily from **scale, weight, and whitespace**, not many different colors. + +--- + +## 5. Layout + +### Mobile-first + +Design the smallest viewport first. + +The mobile layout should be a complete design, not a collapsed desktop layout. + +Primary priorities: + +1. Reading width +2. Typography +3. Navigation +4. Touch targets +5. Progressive visual decoration + +### Content width + +Desktop content should be centered and constrained. + +Recommended maximum widths: + +```css +--layout-max: 1180px; +--reading-max: 720px; +--wide-reading-max: 900px; +``` + +Use: + +- `1180px` for site-level layouts. +- `720px` for article prose. +- `900px` for diagrams, tables, media, and wide technical examples. + +Never allow normal article text to span the entire desktop viewport. + +### Horizontal padding + +```text +Mobile: 20px +Tablet: 28px +Desktop: 32px +Large desktop: 40px +``` + +### Grid philosophy + +Use generous whitespace. + +Prefer: + +```text +content + whitespace +content +``` + +over: + +```text +[card][card][card][card] +``` + +The site should feel composed, not densely packed. + +--- + +## 6. Spacing + +Use a consistent 4px-based scale. + +```css +--space-1: 4px; +--space-2: 8px; +--space-3: 12px; +--space-4: 16px; +--space-5: 20px; +--space-6: 24px; +--space-8: 32px; +--space-10: 40px; +--space-12: 48px; +--space-16: 64px; +--space-20: 80px; +--space-24: 96px; +--space-32: 128px; +``` + +Use larger spacing to separate **ideas**, not just components. + +A major section should feel significantly separated from the previous section. + +--- + +## 7. Radius, Borders & Elevation + +### Radius + +Prefer restrained rounding. + +```css +--radius-sm: 6px; +--radius-md: 10px; +--radius-lg: 16px; +--radius-pill: 999px; +``` + +Use: + +- `sm` for controls and small UI. +- `md` for cards and code containers. +- `lg` only for prominent visual surfaces. +- Pill radius only for tags, badges, and compact controls. + +Avoid making every component pill-shaped. + +### Borders + +Borders should be subtle and slightly warm. + +```css +border: 1px solid var(--color-border); +``` + +Use borders more often than shadows. + +### Shadows + +Default state: + +```text +No shadow. +``` + +Use extremely subtle elevation only when a surface genuinely needs separation from the canvas. + +--- + +## 8. Navigation + +The header should be visually quiet. + +### Desktop + +```text +┌────────────────────────────────────────────────────────────┐ +│ gitgitwi Blog Wiki About ··· │ +└────────────────────────────────────────────────────────────┘ +``` + +- Keep the header compact. +- Logo/wordmark on the left. +- Primary navigation on the right. +- Avoid large application-style navigation bars. +- A thin border or whitespace may separate the header from content. + +### Mobile + +Use a compact header with: + +- Wordmark/logo +- Menu trigger +- Optional theme/search action + +Navigation should never consume excessive vertical space. + +--- + +## 9. Homepage + +The homepage is the strongest expression of the site's identity. + +### Hero + +Recommended composition: + +```text +small technical label + +A handwritten, +personal statement. + +Short explanation of +what this blog is about. + +[ Browse posts ] [ Wiki ] + + generative / shader visual +``` + +The handwritten headline should be the visual focal point. + +A subtle shader, generative object, or abstract green form can occupy the opposite side on desktop and move below the text on mobile. + +### Latest posts + +Use editorial list/card patterns rather than a SaaS card grid. + +Each post should expose: + +- Date +- Title +- Short description +- Tags +- Optional reading time + +Keep cards visually light. + +--- + +## 10. Article Page + +Article pages are the most important part of the system. + +### Structure + +```text +Header + ↓ +Article metadata + ↓ +Handwritten article title + ↓ +Description / introduction + ↓ +Hero visual or cover + ↓ +Article content + ↓ +Related / next articles + ↓ +Footer +``` + +### Reading experience + +The article body should be optimized for long-form reading: + +- Narrow measure +- Generous line-height +- Clear heading hierarchy +- Strong paragraph rhythm +- Minimal distractions +- Wide media can escape the prose column when useful + +### Article title + +Use the display/handwritten font selectively. + +The title should feel authored, not like a documentation heading. + +### Metadata + +Metadata uses Geist Mono or a restrained sans-serif style. + +Example: + +```text +2026.09.10 · 8 min read · TYPESCRIPT +``` + +--- + +## 11. Article Components + +### Paragraph + +Readable, calm, and high contrast. + +### Headings + +Headings should create hierarchy through: + +- Size +- Weight +- Vertical spacing + +Avoid excessive accent color. + +### Inline code + +Use a subtle muted surface. + +```text +background: var(--color-surface-muted) +font-family: Geist Mono +``` + +### Code block + +Highlighter: **Prism.js** (`markdown.syntaxHighlight: 'prism'` + `@astrojs/prism`). Not Shiki. + +Theme: **Vitesse Light–like**, retinted to canvas + accent — not a dark terminal, not `github-dark`. + +```text +canvas #F7F5EE + → code bg #F1EFE6 (one step quieter) + → keyword / function #16A36A (accent) + → ink #393a34 (Vitesse Light foreground) +``` + +Prism token colors (custom CSS, `src/styles/prism-vitesse-light.css`): + +```css +code[class*="language-"], +pre[class*="language-"] { + background: var(--color-code-bg); + color: var(--color-code-ink); + font-family: "Geist Mono", ui-monospace, monospace; +} +.token.comment, +.token.prolog { color: #a0ada0; } +.token.keyword { color: var(--color-accent-ink); } +.token.function { color: var(--color-accent); } +.token.string { color: #b56959; } +.token.number, +.token.boolean { color: #2f798a; } +.token.punctuation { color: #7A807B; } +``` + +Code blocks should support: + +- Language label +- Copy action +- Line numbers when useful +- Highlighted lines +- Horizontal scrolling on mobile + +Do not load a dark Prism theme (`prism-okaidia`, `tomorrow-night`, default `prism.css` on black). + +### Blockquote + +Editorial rather than heavy. + +Use a subtle left accent border and generous spacing. + +### Callout + +Use the accent color sparingly. + +Recommended variants: + +- Note +- Tip +- Warning +- Important + +The default note should feel like part of the article, not a dashboard alert. + +### Images / Figures + +Images should have: + +- Captions when useful +- Clear relationship to surrounding prose +- Optional wide layout +- Lazy loading +- Appropriate alt text + +### Tables + +Tables may use the wide-reading width and horizontal scrolling on mobile. + +--- + +## 12. Wiki + +The wiki should feel related to the blog but more systematic. + +### Visual relationship + +Blog: + +> Editorial + personal + +Wiki: + +> Structured + technical + +Reuse: + +- Same canvas +- Same typography +- Same green accent +- Same code styling +- Same spacing system + +But allow the wiki to use more conventional documentation patterns. + +### Desktop + +```text +┌───────────────────────────────────────────────────────────┐ +│ Header │ +├──────────────┬────────────────────────────────────────────┤ +│ Sidebar │ Content │ +│ │ │ +│ Getting │ Handwritten / editorial page title │ +│ Started │ │ +│ TypeScript │ Intro │ +│ React │ │ +│ Architecture│ Sections │ +│ │ Code │ +└──────────────┴────────────────────────────────────────────┘ +``` + +The sidebar should remain visually lightweight. + +### Mobile + +Sidebar becomes: + +- Drawer +- Collapsible navigation +- Or top-level section selector + +Never let documentation navigation push the actual content too far down. + +--- + +## 13. Design System Components + +Initial component inventory: + +### Foundations + +- Typography +- Color +- Spacing +- Container +- Divider +- Icon + +### Navigation + +- Header +- Navigation +- MobileMenu +- Breadcrumb +- TableOfContents +- Sidebar + +### Content + +- Article +- PostCard +- PostList +- Tag +- Category +- Metadata +- Figure +- CodeBlock +- InlineCode +- Blockquote +- Callout +- Table +- Footnote + +### Interaction + +- Button +- Link +- IconButton +- CopyButton +- Search +- Tooltip +- Toast + +### Wiki + +- WikiLayout +- WikiSidebar +- WikiSearch +- WikiSection + +### Visual + +- ShaderBackground +- GenerativeOrb +- DecorativeGrid +- NoiseTexture + +--- + +## 14. Motion + +Motion should reinforce the technical/editorial character. + +### Principles + +- Subtle +- Fast +- Purposeful +- Never required for comprehension + +Recommended timing: + +```css +--duration-fast: 120ms; +--duration-normal: 200ms; +--duration-slow: 400ms; +``` + +Use motion for: + +- Link hover +- Button feedback +- Navigation transitions +- Card reveal +- Copy confirmation +- Page entrance +- Shader interaction + +Avoid: + +- Constant bouncing +- Excessive parallax +- Long page transitions +- Animation on every element + +### Reduced motion + +Respect: + +```css +@media (prefers-reduced-motion: reduce) +``` + +Disable or substantially reduce non-essential animation. + +--- + +## 15. Three.js / WebGL + +Generative visuals are allowed and encouraged as part of the site's technical identity. + +### Good uses + +- Homepage hero visual +- Article cover +- Ambient background +- Interactive experiment +- Visualization accompanying a technical article + +### Visual direction + +Prefer: + +- Organic forms +- Soft mint/green light +- Grain/noise +- Fluid shader movement +- Abstract geometry +- Subtle depth + +Avoid: + +- Generic spinning 3D cubes +- Neon cyberpunk palettes +- Overly saturated gradients +- Full-screen effects behind readable text + +### Performance rules + +WebGL must be progressive enhancement. + +Requirements: + +- Never block article rendering. +- Provide a static fallback. +- Lazy-load heavy scenes when possible. +- Respect reduced-motion preferences. +- Avoid unnecessary GPU work on mobile. +- Ensure text remains readable if WebGL fails. + +--- + +## 16. Responsive Behavior + +### Mobile + +Priority: + +```text +Reading > Navigation > Content > Decoration +``` + +Characteristics: + +- Single-column layout +- 20px horizontal padding +- Full-width code blocks with horizontal scroll +- Reduced decorative effects +- Smaller display typography +- Touch-friendly controls + +### Tablet + +Introduce: + +- More generous horizontal padding +- Wider media +- Optional two-column sections + +### Desktop + +Introduce: + +- Centered max-width container +- Wider visual compositions +- Article prose + optional side TOC +- Hero split layouts +- Larger decorative WebGL elements + +--- + +## 17. Accessibility + +Accessibility is part of the design system. + +Requirements: + +- Keyboard-accessible interactions +- Visible focus states +- Semantic HTML +- Correct heading hierarchy +- Sufficient color contrast +- Meaningful alt text +- Reduced-motion support +- Touch targets of approximately 44px where practical +- Do not communicate meaning through color alone + +Decorative visuals must not contain essential information. + +--- + +## 18. Content Density + +The blog should feel spacious. + +Prefer: + +```text +short paragraph + + whitespace + +heading + +short paragraph + + whitespace + +code +``` + +Avoid: + +```text +heading +paragraph paragraph paragraph paragraph +table card card card +paragraph paragraph +``` + +Whitespace is a structural element. + +--- + +## 19. Brand Expression + +The site's strongest brand signals should be: + +1. Warm beige canvas +2. Mint-green accent +3. Handwritten editorial typography +4. Geist Mono technical details +5. Generative/WebGL visual moments +6. Calm, generous whitespace + +If a future component does not fit these principles, reconsider the component before adding more decoration. + +--- + +## 20. Do / Don't + +### Do + +- Use warm neutrals. +- Keep green accents intentional. +- Give articles generous reading width. +- Mix editorial typography with technical monospace. +- Use generative visuals as identity. +- Prefer whitespace over extra UI. +- Keep the interface quiet so content can be expressive. +- Make mobile the baseline. + +### Don't + +- Turn the blog into a SaaS dashboard. +- Use cards for everything. +- Make every heading green. +- Use handwritten fonts everywhere. +- Put WebGL behind dense text. +- Use giant shadows. +- Overuse rounded corners. +- Sacrifice performance for visual effects. + +--- + +## 21. Design Token Architecture + +Keep tokens layered. + +### Primitive + +Raw values: + +```text +color.green.500 +color.neutral.100 +space.4 +radius.md +``` + +### Semantic + +Meaningful roles: + +```text +color.canvas +color.surface +color.ink +color.accent +color.border +``` + +### Component + +Component-specific decisions: + +```text +button.background +article.code.background +header.border +callout.note.background +``` + +Components should consume semantic tokens whenever possible rather than raw color values. + +--- + +## 22. Astro Implementation Principles + +The design system should remain framework-friendly. + +Recommended structure: + +```text +src/ + components/ + ui/ + layout/ + content/ + CodeBlock/ # Prism wrapper: lang, copy, optional line numbers + wiki/ + styles/ + tokens.stylex.ts + globals.css + prism-vitesse-light.css +``` + +Astro: `markdown.syntaxHighlight: 'prism'`. Install `@astrojs/prism`. Load `prism-vitesse-light.css` from `Base.astro` (same hole as StyleX CSS — a `` or import, not Vite-html injection). + +Keep visual primitives independent from page-specific content. + +Prefer composable components over page-level styling. + +--- + +## 23. Future Design-System Documentation + +When the visual direction stabilizes, expand this file into: + +```text +01 Philosophy +02 Color +03 Typography +04 Spacing +05 Layout +06 Radius +07 Borders & Elevation +08 Motion +09 Iconography +10 Components +11 Article UX +12 Wiki UX +13 Accessibility +14 Responsive Behavior +15 Performance +16 Do / Don't +``` + +This document is intentionally a **design direction + implementation contract**, not a pixel-perfect specification. Exact values should evolve after the first implementation pass and real article content is rendered. + +--- + +## 24. North Star + +> **A warm, personal editorial space for technical ideas — precise enough for code, expressive enough to feel authored.** diff --git a/docs/conventions/prs.md b/docs/conventions/prs.md index 6f0a320..eb3700f 100644 --- a/docs/conventions/prs.md +++ b/docs/conventions/prs.md @@ -181,6 +181,7 @@ flowchart LR subgraph PHASE["phase — 검색 키"] P0["phase-0"] P1["phase-1"] + P15["phase-1.5"] P2["phase-2"] P3["phase-3"] P4["phase-4"] @@ -199,6 +200,7 @@ flowchart LR - `phase-0` — Foundation: `main`, bun, 스킬, StyleX 스파이크 - `phase-1` — Scaffold: Astro, StyleX DS, Pages +- `phase-1.5` — Visual: design.md, Prism Vitesse Light, Home/목업 레이아웃 - `phase-2` — Content: collections, MDX, wiki - `phase-3` — Wiki quiz - `phase-4` — Hardening: Pagefind, SEO, leak-guard