Skip to content
Closed
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
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ dark atmosphere. Everything respects `prefers-reduced-motion`.
Per the design bible there are **no counts anywhere** — quantity is expressed by form,
never a number badge — and cinnabar, the colour of the human hand, is used sparingly.

## 千年书架 · 源氏物語

A second book is now fully implemented end to end, alongside 我的树:

- **`/books`** — 千年书架, a small bookshelf listing every book on the site (道德經,
still a placeholder; 源氏物語, live).
- **`/books/genji`** — 源氏物語's book biography (「一本书的传记」): a real textual
history from 紫式部's 1008 diary entry, through the 青表纸本/河内本 manuscript
split, 本居宣长's 物哀 theory, the Waley/Seidensticker/Tyler English translations,
down to today's reader annotations (入木/青芽 rings).
- **`/books/genji/read`** — the reading page for 第一帖「桐壺」: the same signature
time-slider interaction as the design's 阅读页, dragged or stepped across 1000–2026,
opening a sentence into a "地层" (stratum) drawer of annotations that reveal
themselves as the slider passes their year — commentary (四辻善成, 本居宣长),
translations, and reader annotations, plus a hover-revealed 青表纸本/河内本
wording-variant comparison.

There is no server-side routing — `src/router.tsx` is a tiny client-side path
router (no dependency added) used only to switch between these pages.

## Develop

```bash
Expand All @@ -44,13 +64,18 @@ npm run preview # serve the production build
| --- | --- |
| `src/MyTree.tsx` | The 我的树 page component + its branch/annotation data |
| `src/MyTree.css` | Page layout, the SVG tree, hover reveal, growth rings |
| `src/router.tsx` | Minimal client-side path router + `<Link>` |
| `src/Header.tsx` / `.css` | Shared header chrome for the bookshelf/book/reader pages |
| `src/Bookshelf.tsx` / `.css` | `/books` — 千年书架 |
| `src/BookGenji.tsx` / `.css` | `/books/genji` — 源氏物語's book biography |
| `src/GenjiReader.tsx` / `.css` | `/books/genji/read` — 源氏物語 reading page + time slider |
| `src/theme.css` | Design tokens (墨字朱批 palette), day/night themes, keyframes |
| `APP_NOTES.md` | Detailed notes on this page |
| `design/` | The original Claude Design handoff bundle — chat transcript + all page prototypes. The source of truth for the pages not yet built. |

## Not yet built

`design/project/` holds prototypes for the rest of the product: 首页书架, 书籍详情页,
阅读页 (the design's stated priority — its "signature" screen with the time-slider),
`design/project/` also holds prototypes for 道德經's own book/reading pages,
落笔流程, 句子房间, 考据, 分享卡, 守树人. `我的树` links out to `/read` and `/inscribe`
as placeholders for those routes.
as placeholders for those routes; the bookshelf's 道德經 card is likewise still a
placeholder pending its own port.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500&family=Noto+Sans+SC:wght@400;500&family=Spectral:ital,wght@0,400;0,500;1,400&display=swap"
href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500&family=Noto+Sans+SC:wght@400;500&family=Noto+Serif+JP:wght@400;500&family=Spectral:ital,wght@0,400;0,500;1,400&display=swap"
rel="stylesheet"
/>
</head>
Expand Down
251 changes: 251 additions & 0 deletions src/BookGenji.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
.genji-page {
min-height: 100vh;
font-family: 'Noto Sans SC', sans-serif;
color: var(--ink);
}

.genji-hero {
max-width: 720px;
margin: 0 auto;
padding: 88px 44px 96px 44px;
position: relative;
box-sizing: border-box;
}

.genji-hero-quote {
position: absolute;
right: 44px;
top: 80px;
writing-mode: vertical-rl;
font-family: 'Noto Serif JP', 'Noto Serif SC', serif;
font-size: 15px;
letter-spacing: 0.5em;
color: var(--ink-light);
opacity: 0.55;
line-height: 2;
}

.genji-shelf {
font-size: 12px;
color: var(--ink-light);
letter-spacing: 0.3em;
margin-bottom: 32px;
}

.genji-title {
font-family: 'Noto Serif SC', serif;
font-size: 52px;
font-weight: 400;
letter-spacing: 0.18em;
line-height: 1.3;
}

.genji-meta {
margin-top: 20px;
font-family: Spectral, 'Noto Sans SC', serif;
font-feature-settings: 'onum';
font-size: 13px;
color: var(--ink-light);
letter-spacing: 0.06em;
}

.genji-lead {
margin-top: 40px;
font-family: 'Noto Serif SC', serif;
font-size: 21px;
letter-spacing: 0.05em;
}

.genji-cta {
margin-top: 36px;
font-size: 13px;
letter-spacing: 0.14em;
}

.genji-timeline {
max-width: 720px;
margin: 0 auto;
padding: 0 44px 60px 44px;
box-sizing: border-box;
}

.genji-timeline-label {
font-size: 12px;
letter-spacing: 0.5em;
color: var(--ink-light);
margin-bottom: 56px;
}

.genji-nodes {
position: relative;
padding-left: 140px;
}
.genji-nodes::before {
content: '';
position: absolute;
left: 120px;
top: 8px;
bottom: 8px;
width: 1px;
background: var(--line);
}

.genji-node {
position: relative;
margin-bottom: 76px;
transition: opacity 0.7s ease, transform 0.7s ease;
}

.genji-node-year {
position: absolute;
left: -140px;
top: 3px;
width: 106px;
text-align: right;
font-family: Spectral, 'Noto Sans SC', serif;
font-feature-settings: 'onum';
font-size: 13px;
letter-spacing: 0.04em;
}

.genji-node-dot {
position: absolute;
left: -24px;
top: 6px;
width: 7px;
height: 7px;
border-radius: 50%;
}

.genji-node-who {
font-size: 14px;
font-weight: 500;
letter-spacing: 0.04em;
margin-bottom: 10px;
}

.genji-node-story {
font-family: 'Noto Serif SC', serif;
font-size: 14.5px;
line-height: 2.05;
letter-spacing: 0.02em;
color: var(--ink);
}

.genji-node-anchor {
margin-top: 16px;
font-family: 'Noto Serif JP', 'Noto Serif SC', serif;
font-size: 15px;
line-height: 1.9;
color: var(--ink);
border-left: 2px solid var(--u-soft);
padding-left: 14px;
}

.genji-special {
margin-top: 20px;
border: 0.5px solid var(--line);
border-radius: 8px;
padding: 20px 22px;
}

.genji-special-label {
font-size: 11.5px;
letter-spacing: 0.24em;
color: var(--cinnabar);
margin-bottom: 16px;
}

.genji-special-body {
font-family: 'Noto Serif SC', serif;
font-size: 13.5px;
line-height: 1.9;
color: var(--ink);
}

.genji-rings {
margin-top: 20px;
display: flex;
flex-direction: column;
gap: 14px;
}

.genji-ring {
border: 0.5px solid var(--line);
border-radius: 8px;
padding: 16px 18px;
}

.genji-ring-head {
display: flex;
align-items: baseline;
gap: 10px;
margin-bottom: 8px;
flex-wrap: wrap;
}

.genji-ring-name {
font-size: 13px;
font-weight: 500;
}

.genji-ring-badge {
font-size: 11px;
border: 0.5px solid;
border-radius: 4px;
padding: 1px 6px;
line-height: 1.5;
}

.genji-ring-tag {
font-size: 11px;
letter-spacing: 0.1em;
}

.genji-ring-date {
font-family: Spectral, serif;
font-feature-settings: 'onum';
font-size: 12px;
color: var(--ink-light);
margin-left: auto;
}

.genji-ring-text {
font-family: 'Noto Serif SC', serif;
font-size: 13.5px;
line-height: 1.9;
color: var(--ink);
}

.genji-foot {
text-align: center;
padding: 0 44px 96px 44px;
font-size: 12px;
letter-spacing: 0.2em;
color: var(--ink-light);
}

@media (max-width: 640px) {
.genji-hero,
.genji-timeline {
padding-left: 24px;
padding-right: 24px;
}
.genji-hero-quote {
display: none;
}
.genji-title {
font-size: 38px;
}
.genji-nodes {
padding-left: 96px;
}
.genji-nodes::before {
left: 80px;
}
.genji-node-year {
left: -96px;
width: 68px;
font-size: 11px;
}
}
Loading