# Lunar Calendar App (万年历) Chinese almanac/perpetual calendar app with Bazi calculation, daily fortune, divination tools, and beautiful UI. ## Documentation Detailed docs live in `docs/` — read them before starting any task: - **docs/ARCHITECTURE.md** — tech stack, layered design, API surface, routes, stores - **docs/REQUIREMENTS.md** — full feature inventory with completion status - **docs/PROGRESS.md** — milestones, current state, prioritized backlog - **docs/BUGS.md** — known bugs, algorithmic approximations, dead code - **docs/CHANGELOG.md** — version history ## Tech Stack - **Monorepo**: pnpm workspaces - **Core**: TypeScript + tyme4ts (calendar engine) - **Web**: React 19 + Vite + TailwindCSS v4 + Framer Motion + Zustand + React Router v7 - **PWA**: vite-plugin-pwa (configured and built — autoUpdate + Workbox) ## Project Structure ``` lunar/ ├── docs/ # Architecture / Requirements / Progress / Bugs / Changelog ├── packages/ │ ├── core/ # @lunar/core — Pure TS, no UI deps │ │ └── src/ │ │ ├── types/ # calendar.ts, bazi.ts, almanac.ts, fortune.ts │ │ ├── transformers/ # tyme4ts → plain objects (day.ts, bazi.ts, almanac.ts) │ │ └── calculators/ # dailyMatch.ts, relationship.ts, elementStrength.ts, plumBlossom.ts, boneWeight.ts │ └── web/ # @lunar/web — React app │ └── src/ │ ├── stores/ # Zustand: calendar, user, settings, ui, bookmarks │ ├── hooks/ # useCalendar, useDayDetail, useBazi, useDailyFortune │ ├── components/ # calendar/, layout/, ui/ │ └── pages/ # Home, Calendar, DayDetail, Bazi, DailyFortune, Settings, Divination, SolarTerms ``` ## Key Architecture Principles 1. **tyme4ts objects never enter React** — all transformed to plain JS objects in @lunar/core 2. **@lunar/core has zero UI deps** — works in any JS runtime (web, Node, RN, mini-program) 3. **Mobile-first responsive** — phone first, desktop sidebar layout 4. **Dark mode via CSS custom properties** — theme toggle with system preference detection ## Commands - `pnpm dev` — Start Vite dev server (port 4258) - `pnpm build` — Build core (ESM+CJS) + web - `pnpm --filter @lunar/core build` — Build core only (tsup) - `pnpm --filter @lunar/web dev` — Start web dev server - `pnpm preview` — Preview production build - `pnpm test` — Run core unit tests (vitest) - `pnpm lint` — Run ESLint on all packages ## Core API (from @lunar/core) - `getDayInfo(year, month, day)` → DayInfo - `getTodayInfo()` → DayInfo - `getMonthCalendar(year, month, weekStart?)` → DayInfo[][] - `getAlmanacInfo(year, month, day)` → AlmanacInfo - `birthInfoToBazi(params)` → BaziFullResult - `calculateDailyFortune(userBazi, date)` → DailyFortuneResult - `analyzeElementBalance(bazi)` → ElementProfile - `calculatePlumBlossom(y, m, d, hour?)` → PlumBlossomResult - `calculateBoneWeight(...)` → BoneWeightResult - `getBranchRelationship(a, b)` / `getTenStarRelationship(s, o)` / `checkStemCombine` / `checkStemOpposite` - `getBuddhistFestival(lunarMonth, lunarDay)` → string | null - `analyzeShensha(bazi)` → ShenshaInfo[](22 个常见神煞) - `analyzeFortuneGanzhi(ganzhi, dayStem, dayBranch)` → FortuneLuck(大运/流年 vs 日主生克冲合) - `getYearMonths(year)` → YearMonthInfo[](按节气月) ## Known Issues See **docs/BUGS.md** for the current list. Resolved: core CJS export, week-start setting, PWA manifest metadata, tests (50), lint, 称骨 data tables, 八字流派 switching, shensha, 大运流年 explorer. Remaining: simplified 互卦 algorithm, dead code cleanup.