@hanology/cham-browser 0.4.57 → 0.4.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanology/cham-browser",
3
- "version": "0.4.57",
3
+ "version": "0.4.58",
4
4
  "description": "CHAM — browser-compatible parser, serializer, and site generator for Classical Han Annotated Markdown",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -91,20 +91,23 @@ function openBook(bookId: string) {
91
91
  <div class="v-divider"></div>
92
92
  </section>
93
93
 
94
- <section class="v-cards-col">
95
- <div
96
- v-for="book in books"
97
- :key="book.id"
98
- class="v-book-card"
99
- @click="openBook(book.id)"
100
- >
101
- <div class="v-book-accent"></div>
102
- <h2 class="v-book-title">{{ book.title }}</h2>
103
- <p v-if="book.subtitle" class="v-book-sub">{{ book.subtitle }}</p>
104
- <div class="v-book-stats">
105
- <span class="v-book-count">{{ t('stat.pieceCount', { count: book.count }) }}</span>
94
+ <section class="v-shelf">
95
+ <template v-for="group in groupedBooks" :key="group.category">
96
+ <div class="v-shelf-cat">
97
+ <span class="v-cat-label">{{ group.category }}</span>
106
98
  </div>
107
- </div>
99
+ <div
100
+ v-for="book in group.books"
101
+ :key="book.id"
102
+ class="v-spine"
103
+ :class="'v-spine-' + bookCategory(book).replace(/\s/g, '-')"
104
+ @click="openBook(book.id)"
105
+ >
106
+ <span class="v-spine-accent"></span>
107
+ <span class="v-spine-title">{{ book.title }}</span>
108
+ <span class="v-spine-badge">{{ book.count }}</span>
109
+ </div>
110
+ </template>
108
111
  </section>
109
112
  </div>
110
113
  </div>
@@ -189,71 +192,126 @@ function openBook(bookId: string) {
189
192
  margin-left: 20px;
190
193
  }
191
194
 
192
- .v-cards-col {
195
+ .v-shelf {
193
196
  writing-mode: vertical-rl;
194
197
  text-orientation: mixed;
195
198
  flex-shrink: 0;
196
199
  display: flex;
197
200
  flex-direction: column;
198
- gap: 0;
199
- padding: 40px 16px;
200
201
  height: 100vh;
201
202
  box-sizing: border-box;
202
203
  overflow-x: auto;
203
204
  overflow-y: hidden;
204
- align-items: flex-start;
205
+ padding: 0;
206
+ scrollbar-width: thin;
207
+ scrollbar-color: var(--gold) transparent;
205
208
  }
209
+ .v-shelf::-webkit-scrollbar { height: 3px; }
210
+ .v-shelf::-webkit-scrollbar-thumb { background: var(--gold); border-radius: 2px; }
206
211
 
207
- .v-book-card {
212
+ /* ─── Category separator ─── */
213
+ .v-shelf-cat {
208
214
  writing-mode: vertical-rl;
209
215
  text-orientation: mixed;
210
216
  display: flex;
211
217
  flex-direction: column;
212
- align-items: flex-start;
213
- padding: 24px 16px;
218
+ align-items: center;
219
+ justify-content: center;
220
+ padding: 16px 6px;
221
+ flex-shrink: 0;
222
+ }
223
+ .v-cat-label {
224
+ writing-mode: vertical-rl;
225
+ text-orientation: mixed;
226
+ font-family: var(--sans);
227
+ font-size: 11px;
228
+ font-weight: 600;
229
+ letter-spacing: 4px;
230
+ color: var(--ink-faint);
231
+ padding: 8px 3px;
232
+ border-left: 1px solid var(--border-light);
233
+ border-right: 1px solid var(--border-light);
234
+ white-space: nowrap;
235
+ }
236
+
237
+ /* ─── Book spine ─── */
238
+ .v-spine {
239
+ writing-mode: vertical-rl;
240
+ text-orientation: mixed;
241
+ display: flex;
242
+ flex-direction: column;
243
+ align-items: center;
244
+ justify-content: flex-start;
245
+ height: 100vh;
246
+ width: 44px;
247
+ padding: 16px 0;
214
248
  border-left: 1px solid var(--border-light);
215
249
  cursor: pointer;
216
- transition: all 0.3s ease;
217
250
  position: relative;
251
+ box-sizing: border-box;
252
+ transition: background 0.25s ease, width 0.3s cubic-bezier(0.16, 1, 0.3, 1);
253
+ overflow: hidden;
254
+ flex-shrink: 0;
218
255
  }
219
- .v-book-card:hover {
220
- background: var(--surface);
256
+ .v-spine:hover {
257
+ background: linear-gradient(90deg, rgba(var(--shadow-rgb), 0.04), rgba(var(--shadow-rgb), 0.01));
258
+ width: 56px;
259
+ }
260
+ .v-spine:active {
261
+ transform: scale(0.97);
221
262
  }
222
- .v-book-accent {
263
+
264
+ .v-spine-accent {
223
265
  position: absolute;
224
- top: 0; right: 0;
225
- width: 0; height: 3px;
226
- background: var(--vermillion);
227
- transition: width 0.35s ease;
228
- }
229
- .v-book-card:hover .v-book-accent { width: 100%; }
230
- .v-book-title {
231
- font-size: 32px; font-weight: 900;
232
- letter-spacing: 8px; color: var(--ink);
233
- margin-left: 16px; padding-left: 16px;
234
- border-left: 3px solid var(--vermillion);
235
- line-height: 1.6;
266
+ top: 0;
267
+ left: 0;
268
+ width: 3px;
269
+ height: 0;
270
+ transition: height 0.4s cubic-bezier(0.16, 1, 0.3, 1);
236
271
  }
237
- .v-book-sub {
272
+ .v-spine:hover .v-spine-accent {
273
+ height: 100%;
274
+ }
275
+
276
+ /* Accent colors per category */
277
+ .v-spine .v-spine-accent { background: var(--vermillion); }
278
+ .v-spine.v-spine-教科書 .v-spine-accent { background: var(--gold); }
279
+ .v-spine.v-spine-四庫全書 .v-spine-accent { background: var(--jade); }
280
+
281
+ .v-spine-title {
282
+ writing-mode: vertical-rl;
283
+ text-orientation: mixed;
238
284
  font-size: 14px;
239
- color: var(--ink-light);
285
+ font-weight: 700;
240
286
  letter-spacing: 3px;
241
- margin-left: 12px;
242
- font-family: var(--sans);
287
+ color: var(--ink);
288
+ line-height: 1.6;
289
+ margin: 12px 0;
290
+ white-space: nowrap;
291
+ transition: color 0.2s ease;
243
292
  }
244
- .v-book-stats {
245
- margin-left: 12px;
246
- padding-left: 12px;
247
- border-left: 1px solid var(--border);
293
+ .v-spine:hover .v-spine-title {
294
+ color: var(--vermillion);
248
295
  }
249
- .v-book-count {
250
- font-size: 13px;
251
- color: var(--ink-faint);
252
- letter-spacing: 2px;
296
+ .v-spine.v-spine-教科書:hover .v-spine-title { color: var(--gold); }
297
+ .v-spine.v-spine-四庫全書:hover .v-spine-title { color: var(--jade); }
298
+
299
+ .v-spine-badge {
300
+ writing-mode: horizontal-tb;
253
301
  font-family: var(--sans);
254
- padding: 2px 8px;
302
+ font-size: 9px;
303
+ font-weight: 700;
304
+ color: var(--ink-faint);
255
305
  background: var(--surface-warm);
256
- border-radius: 4px;
306
+ border: 1px solid var(--border-light);
307
+ border-radius: 8px;
308
+ padding: 1px 6px;
309
+ margin-top: auto;
310
+ opacity: 0;
311
+ transition: opacity 0.25s ease;
312
+ }
313
+ .v-spine:hover .v-spine-badge {
314
+ opacity: 1;
257
315
  }
258
316
 
259
317
  /* ═══════ 橫排模式 ═══════ */
@@ -403,6 +461,9 @@ function openBook(bookId: string) {
403
461
  @media (max-width: 768px) {
404
462
  .v-page { padding: 0 16px; }
405
463
  .v-title { font-size: 36px; letter-spacing: 10px; }
464
+ .v-spine { width: 38px; }
465
+ .v-spine:hover { width: 48px; }
466
+ .v-spine-title { font-size: 13px; letter-spacing: 2px; }
406
467
  .lib-root { padding: 40px 16px 80px; }
407
468
  .lib-hero { margin-bottom: 32px; }
408
469
  .lib-hero h1 { font-size: 28px; letter-spacing: 4px; }