@hanology/cham-browser 0.4.59 → 0.4.60

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.59",
3
+ "version": "0.4.60",
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",
@@ -88,70 +88,17 @@ function onTap(event: MouseEvent) {
88
88
  }
89
89
 
90
90
  :deep(.ann-target) {
91
- border-bottom: 2px solid var(--vermillion);
92
- cursor: help;
93
- transition: background 0.2s ease, box-shadow 0.2s ease;
94
- -webkit-box-decoration-break: clone;
95
- box-decoration-break: clone;
91
+ border-bottom-width: 2px;
92
+ border-bottom-style: solid;
96
93
  }
97
94
  :deep(.ann-target.ann-overlap) {
98
95
  border-bottom-width: 3px;
99
96
  border-bottom-style: double;
100
97
  }
101
- :deep(.ann-target:hover) {
102
- background: rgba(194, 58, 43, 0.1);
103
- box-shadow: 0 2px 8px rgba(194, 58, 43, 0.08);
104
- }
105
98
  :deep(.ann-num) {
106
99
  font-size: 10px;
107
- color: var(--vermillion);
108
- font-family: var(--sans);
109
- font-weight: 600;
110
100
  vertical-align: super;
111
101
  margin-right: 1px;
112
- letter-spacing: 0;
113
- }
114
- :deep(.ann-target.pronunciation:hover) {
115
- background: rgba(58, 107, 94, 0.1);
116
- box-shadow: 0 2px 8px rgba(58, 107, 94, 0.08);
117
- }
118
- :deep(.ann-target.pronunciation) {
119
- border-bottom-color: var(--jade);
120
- }
121
- :deep(.ann-target.person) {
122
- border-bottom-color: var(--ann-person);
123
- }
124
- :deep(.ann-target.place) {
125
- border-bottom-color: var(--ann-place);
126
- }
127
- :deep(.ann-target.event) {
128
- border-bottom-color: var(--ann-event);
129
- }
130
- :deep(.ann-target.date) {
131
- border-bottom-color: var(--ann-date);
132
- }
133
- :deep(.ann-target.allusion) {
134
- border-bottom-color: var(--ann-allusion);
135
- }
136
- :deep(.ann-target.person:hover) {
137
- background: rgba(58, 90, 140, 0.1);
138
- box-shadow: 0 2px 8px rgba(58, 90, 140, 0.08);
139
- }
140
- :deep(.ann-target.place:hover) {
141
- background: rgba(139, 105, 20, 0.1);
142
- box-shadow: 0 2px 8px rgba(139, 105, 20, 0.08);
143
- }
144
- :deep(.ann-target.event:hover) {
145
- background: rgba(107, 76, 138, 0.1);
146
- box-shadow: 0 2px 8px rgba(107, 76, 138, 0.08);
147
- }
148
- :deep(.ann-target.date:hover) {
149
- background: rgba(42, 122, 122, 0.1);
150
- box-shadow: 0 2px 8px rgba(42, 122, 122, 0.08);
151
- }
152
- :deep(.ann-target.allusion:hover) {
153
- background: rgba(181, 101, 29, 0.1);
154
- box-shadow: 0 2px 8px rgba(181, 101, 29, 0.08);
155
102
  }
156
103
 
157
104
  @media (max-width: 768px) {
@@ -75,6 +75,9 @@ const sourceLabel = (() => {
75
75
  .part-block--vertical {
76
76
  writing-mode: vertical-rl;
77
77
  text-orientation: mixed;
78
+ margin-left: 12px;
79
+ padding-left: 12px;
80
+ border-left: 1px dashed var(--border-light);
78
81
  }
79
82
 
80
83
  .part-source {
@@ -125,75 +128,23 @@ const sourceLabel = (() => {
125
128
  }
126
129
 
127
130
  :deep(.ann-target) {
128
- border-bottom: 2px solid var(--vermillion);
129
- cursor: help;
130
- transition: background 0.2s ease, box-shadow 0.2s ease;
131
- -webkit-box-decoration-break: clone;
132
- box-decoration-break: clone;
131
+ border-bottom-width: 2px;
132
+ border-bottom-style: solid;
133
133
  }
134
134
  :deep(.ann-target.ann-overlap) {
135
135
  border-bottom-width: 3px;
136
136
  border-bottom-style: double;
137
137
  }
138
- :deep(.ann-target:hover) {
139
- background: rgba(194, 58, 43, 0.1);
140
- box-shadow: 0 2px 8px rgba(194, 58, 43, 0.08);
141
- }
142
138
  :deep(.ann-num) {
143
139
  font-size: 10px;
144
- color: var(--vermillion);
145
- font-family: var(--sans);
146
- font-weight: 600;
147
140
  vertical-align: super;
148
141
  margin-right: 1px;
149
- letter-spacing: 0;
150
- }
151
- :deep(.ann-target.pronunciation) {
152
- border-bottom-color: var(--jade);
153
- }
154
- :deep(.ann-target.pronunciation:hover) {
155
- background: rgba(58, 107, 94, 0.1);
156
- box-shadow: 0 2px 8px rgba(58, 107, 94, 0.08);
157
- }
158
- :deep(.ann-target.person) {
159
- border-bottom-color: var(--ann-person);
160
- }
161
- :deep(.ann-target.place) {
162
- border-bottom-color: var(--ann-place);
163
- }
164
- :deep(.ann-target.event) {
165
- border-bottom-color: var(--ann-event);
166
- }
167
- :deep(.ann-target.date) {
168
- border-bottom-color: var(--ann-date);
169
- }
170
- :deep(.ann-target.allusion) {
171
- border-bottom-color: var(--ann-allusion);
172
- }
173
- :deep(.ann-target.person:hover) {
174
- background: rgba(58, 90, 140, 0.1);
175
- box-shadow: 0 2px 8px rgba(58, 90, 140, 0.08);
176
- }
177
- :deep(.ann-target.place:hover) {
178
- background: rgba(139, 105, 20, 0.1);
179
- box-shadow: 0 2px 8px rgba(139, 105, 20, 0.08);
180
- }
181
- :deep(.ann-target.event:hover) {
182
- background: rgba(107, 76, 138, 0.1);
183
- box-shadow: 0 2px 8px rgba(107, 76, 138, 0.08);
184
- }
185
- :deep(.ann-target.date:hover) {
186
- background: rgba(42, 122, 122, 0.1);
187
- box-shadow: 0 2px 8px rgba(42, 122, 122, 0.08);
188
- }
189
- :deep(.ann-target.allusion:hover) {
190
- background: rgba(181, 101, 29, 0.1);
191
- box-shadow: 0 2px 8px rgba(181, 101, 29, 0.08);
192
142
  }
193
143
 
194
144
  .part-block--vertical :deep(.ann-target) {
195
145
  border-bottom: none;
196
- border-left: 2px solid var(--vermillion);
146
+ border-left-width: 2px;
147
+ border-left-style: solid;
197
148
  padding-left: 2px;
198
149
  }
199
150
  .part-block--vertical :deep(.ann-target.ann-overlap) {
@@ -201,59 +152,9 @@ const sourceLabel = (() => {
201
152
  border-left-style: double;
202
153
  padding-left: 3px;
203
154
  }
204
- .part-block--vertical :deep(.ann-target.pronunciation) {
205
- border-left-color: var(--jade);
206
- }
207
- .part-block--vertical :deep(.ann-target.pronunciation.semantic) {
208
- border-left-color: var(--gold);
209
- }
210
- .part-block--vertical :deep(.ann-target.person) {
211
- border-left-color: var(--ann-person);
212
- }
213
- .part-block--vertical :deep(.ann-target.place) {
214
- border-left-color: var(--ann-place);
215
- }
216
- .part-block--vertical :deep(.ann-target.event) {
217
- border-left-color: var(--ann-event);
218
- }
219
- .part-block--vertical :deep(.ann-target.date) {
220
- border-left-color: var(--ann-date);
221
- }
222
- .part-block--vertical :deep(.ann-target.allusion) {
223
- border-left-color: var(--ann-allusion);
224
- }
225
- .part-block--vertical :deep(.ann-target:hover) {
226
- background: rgba(194, 58, 43, 0.1);
227
- box-shadow: 0 -2px 8px rgba(194, 58, 43, 0.08);
228
- }
229
- .part-block--vertical :deep(.ann-target.pronunciation:hover) {
230
- background: rgba(58, 107, 94, 0.1);
231
- box-shadow: 0 -2px 8px rgba(58, 107, 94, 0.08);
232
- }
233
- .part-block--vertical :deep(.ann-target.person:hover) {
234
- background: rgba(58, 90, 140, 0.1);
235
- box-shadow: 0 -2px 8px rgba(58, 90, 140, 0.08);
236
- }
237
- .part-block--vertical :deep(.ann-target.place:hover) {
238
- background: rgba(139, 105, 20, 0.1);
239
- box-shadow: 0 -2px 8px rgba(139, 105, 20, 0.08);
240
- }
241
- .part-block--vertical :deep(.ann-target.event:hover) {
242
- background: rgba(107, 76, 138, 0.1);
243
- box-shadow: 0 -2px 8px rgba(107, 76, 138, 0.08);
244
- }
245
- .part-block--vertical :deep(.ann-target.date:hover) {
246
- background: rgba(42, 122, 122, 0.1);
247
- box-shadow: 0 -2px 8px rgba(42, 122, 122, 0.08);
248
- }
249
- .part-block--vertical :deep(.ann-target.allusion:hover) {
250
- background: rgba(181, 101, 29, 0.1);
251
- box-shadow: 0 -2px 8px rgba(181, 101, 29, 0.08);
252
- }
253
155
  .part-block--vertical :deep(.ann-num) {
254
156
  font-size: 0.45em;
255
157
  text-align: end;
256
- letter-spacing: 0;
257
158
  vertical-align: baseline;
258
159
  }
259
160
 
@@ -85,8 +85,8 @@ const preview = computed(() => {
85
85
  writing-mode: vertical-rl;
86
86
  text-orientation: mixed;
87
87
  direction: ltr;
88
- width: 180px;
89
- min-height: 240px;
88
+ width: 140px;
89
+ min-height: 180px;
90
90
  flex-shrink: 0;
91
91
  align-self: start;
92
92
  justify-self: start;
@@ -121,13 +121,7 @@ const preview = computed(() => {
121
121
  display: block;
122
122
  }
123
123
  .pc-vertical .pc-preview {
124
- margin-top: 0;
125
- margin-left: 6px;
126
- font-size: 12px;
127
- letter-spacing: 1px;
128
- line-height: 2;
129
- display: block;
130
- overflow: hidden;
124
+ display: none;
131
125
  }
132
126
  .pc-vertical .pc-accent {
133
127
  top: auto; left: 0; bottom: 0;
@@ -57,22 +57,18 @@ function onTap(event: MouseEvent) {
57
57
 
58
58
  <style scoped>
59
59
  .v-scroll {
60
+ --ann-shadow-y: -2px;
60
61
  writing-mode: vertical-rl;
61
62
  text-orientation: mixed;
62
63
  height: calc(100vh - 100px);
63
- overflow-x: auto; overflow-y: hidden;
64
64
  padding: 32px 24px;
65
65
  background: var(--surface);
66
66
  border: 1px solid var(--border);
67
67
  border-radius: 8px;
68
68
  box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.08);
69
69
  position: relative;
70
- scrollbar-width: thin;
71
- scrollbar-color: var(--gold) transparent;
72
70
  animation: poemRevealV 0.5s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
73
71
  }
74
- .v-scroll::-webkit-scrollbar { height: 3px; }
75
- .v-scroll::-webkit-scrollbar-thumb { background: var(--gold); border-radius: 2px; }
76
72
 
77
73
  .v-scroll-title {
78
74
  font-size: 36px; font-weight: 900; color: var(--ink);
@@ -104,12 +100,9 @@ function onTap(event: MouseEvent) {
104
100
  }
105
101
 
106
102
  :deep(.ann-target) {
107
- border-left: 2px solid var(--vermillion);
103
+ border-left-width: 2px;
104
+ border-left-style: solid;
108
105
  padding-left: 2px;
109
- cursor: help;
110
- transition: background 0.2s ease, box-shadow 0.2s ease;
111
- -webkit-box-decoration-break: clone;
112
- box-decoration-break: clone;
113
106
  }
114
107
  :deep(.ann-target.ann-overlap) {
115
108
  border-left-width: 3px;
@@ -118,63 +111,9 @@ function onTap(event: MouseEvent) {
118
111
  }
119
112
  :deep(.ann-num) {
120
113
  font-size: 0.45em;
121
- font-family: var(--sans);
122
- font-weight: 600;
123
- color: var(--vermillion);
124
114
  text-align: end;
125
- letter-spacing: 0;
126
115
  }
127
116
  :deep(.ann-num-long) {
128
117
  font-size: 0.38em;
129
- letter-spacing: -1px;
130
- }
131
- :deep(.ann-target:hover) {
132
- background: rgba(194, 58, 43, 0.1);
133
- box-shadow: 0 -2px 8px rgba(194, 58, 43, 0.08);
134
- }
135
- :deep(.ann-target.pronunciation:hover) {
136
- background: rgba(58, 107, 94, 0.1);
137
- box-shadow: 0 -2px 8px rgba(58, 107, 94, 0.08);
138
- }
139
- :deep(.ann-target.pronunciation) {
140
- border-left-color: var(--jade);
141
- }
142
- :deep(.ann-target.pronunciation.semantic) {
143
- border-left-color: var(--gold);
144
- }
145
- :deep(.ann-target.person) {
146
- border-left-color: var(--ann-person);
147
- }
148
- :deep(.ann-target.place) {
149
- border-left-color: var(--ann-place);
150
- }
151
- :deep(.ann-target.event) {
152
- border-left-color: var(--ann-event);
153
- }
154
- :deep(.ann-target.date) {
155
- border-left-color: var(--ann-date);
156
- }
157
- :deep(.ann-target.allusion) {
158
- border-left-color: var(--ann-allusion);
159
- }
160
- :deep(.ann-target.person:hover) {
161
- background: rgba(58, 90, 140, 0.1);
162
- box-shadow: 0 -2px 8px rgba(58, 90, 140, 0.08);
163
- }
164
- :deep(.ann-target.place:hover) {
165
- background: rgba(139, 105, 20, 0.1);
166
- box-shadow: 0 -2px 8px rgba(139, 105, 20, 0.08);
167
- }
168
- :deep(.ann-target.event:hover) {
169
- background: rgba(107, 76, 138, 0.1);
170
- box-shadow: 0 -2px 8px rgba(107, 76, 138, 0.08);
171
- }
172
- :deep(.ann-target.date:hover) {
173
- background: rgba(42, 122, 122, 0.1);
174
- box-shadow: 0 -2px 8px rgba(42, 122, 122, 0.08);
175
- }
176
- :deep(.ann-target.allusion:hover) {
177
- background: rgba(181, 101, 29, 0.1);
178
- box-shadow: 0 -2px 8px rgba(181, 101, 29, 0.08);
179
118
  }
180
119
  </style>
@@ -0,0 +1,58 @@
1
+ /* ─── Annotation target base ─── */
2
+ .ann-target {
3
+ cursor: help;
4
+ border-color: var(--vermillion);
5
+ transition: background 0.2s ease, box-shadow 0.2s ease;
6
+ -webkit-box-decoration-break: clone;
7
+ box-decoration-break: clone;
8
+ }
9
+
10
+ /* ─── Annotation kind border colors ─── */
11
+ .ann-target.pronunciation { border-color: var(--jade); }
12
+ .ann-target.pronunciation.semantic { border-color: var(--gold); }
13
+ .ann-target.person { border-color: var(--ann-person); }
14
+ .ann-target.place { border-color: var(--ann-place); }
15
+ .ann-target.event { border-color: var(--ann-event); }
16
+ .ann-target.date { border-color: var(--ann-date); }
17
+ .ann-target.allusion { border-color: var(--ann-allusion); }
18
+
19
+ /* ─── Annotation kind hover states ─── */
20
+ .ann-target:hover {
21
+ background: rgba(194, 58, 43, 0.1);
22
+ box-shadow: 0 var(--ann-shadow-y, 2px) 8px rgba(194, 58, 43, 0.08);
23
+ }
24
+ .ann-target.pronunciation:hover {
25
+ background: rgba(58, 107, 94, 0.1);
26
+ box-shadow: 0 var(--ann-shadow-y, 2px) 8px rgba(58, 107, 94, 0.08);
27
+ }
28
+ .ann-target.person:hover {
29
+ background: rgba(58, 90, 140, 0.1);
30
+ box-shadow: 0 var(--ann-shadow-y, 2px) 8px rgba(58, 90, 140, 0.08);
31
+ }
32
+ .ann-target.place:hover {
33
+ background: rgba(139, 105, 20, 0.1);
34
+ box-shadow: 0 var(--ann-shadow-y, 2px) 8px rgba(139, 105, 20, 0.08);
35
+ }
36
+ .ann-target.event:hover {
37
+ background: rgba(107, 76, 138, 0.1);
38
+ box-shadow: 0 var(--ann-shadow-y, 2px) 8px rgba(107, 76, 138, 0.08);
39
+ }
40
+ .ann-target.date:hover {
41
+ background: rgba(42, 122, 122, 0.1);
42
+ box-shadow: 0 var(--ann-shadow-y, 2px) 8px rgba(42, 122, 122, 0.08);
43
+ }
44
+ .ann-target.allusion:hover {
45
+ background: rgba(181, 101, 29, 0.1);
46
+ box-shadow: 0 var(--ann-shadow-y, 2px) 8px rgba(181, 101, 29, 0.08);
47
+ }
48
+
49
+ /* ─── Annotation number ─── */
50
+ .ann-num {
51
+ color: var(--vermillion);
52
+ font-family: var(--sans);
53
+ font-weight: 600;
54
+ letter-spacing: 0;
55
+ }
56
+ .ann-num-long {
57
+ letter-spacing: -1px;
58
+ }
@@ -1,3 +1,5 @@
1
+ @import './annotation-targets.css';
2
+
1
3
  /* ===== THEME DEFINITIONS ===== */
2
4
  :root,
3
5
  [data-theme="light"] {
@@ -259,13 +259,11 @@ function scrollToCatalog() {
259
259
  flex-shrink: 0;
260
260
  display: grid;
261
261
  grid-auto-flow: column;
262
- grid-template-rows: repeat(auto-fill, 240px);
263
- gap: 12px;
262
+ grid-template-rows: repeat(auto-fill, 180px);
263
+ gap: 10px;
264
264
  padding: 24px 16px;
265
265
  height: 100vh;
266
266
  box-sizing: border-box;
267
- overflow-x: auto;
268
- overflow-y: hidden;
269
267
  direction: rtl;
270
268
  align-items: start;
271
269
  }
@@ -97,10 +97,11 @@ function openBook(bookId: string) {
97
97
  <span class="v-cat-label">{{ group.category }}</span>
98
98
  </div>
99
99
  <div
100
- v-for="book in group.books"
100
+ v-for="(book, bi) in group.books"
101
101
  :key="book.id"
102
- class="v-spine"
102
+ class="v-spine v-spine-anim"
103
103
  :class="'v-spine-' + bookCategory(book).replace(/\s/g, '-')"
104
+ :style="{ animationDelay: bi * 0.04 + 's' }"
104
105
  @click="openBook(book.id)"
105
106
  >
106
107
  <span class="v-spine-accent"></span>
@@ -261,6 +262,14 @@ function openBook(bookId: string) {
261
262
  transform: scale(0.97);
262
263
  }
263
264
 
265
+ .v-spine-anim {
266
+ animation: spineEnter 0.4s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
267
+ }
268
+ @keyframes spineEnter {
269
+ from { opacity: 0; transform: scaleX(0.6); }
270
+ to { opacity: 1; transform: scaleX(1); }
271
+ }
272
+
264
273
  .v-spine-accent {
265
274
  position: absolute;
266
275
  top: 0;
@@ -791,16 +791,9 @@ function tcy(n: number): string {
791
791
  gap: 0;
792
792
  height: 100vh;
793
793
  box-sizing: border-box;
794
- overflow-x: auto;
795
- overflow-y: hidden;
796
794
  padding: 20px 16px;
797
- scrollbar-width: thin;
798
- scrollbar-color: var(--gold) transparent;
799
795
  }
800
796
 
801
- .v-multipart::-webkit-scrollbar { height: 3px; }
802
- .v-multipart::-webkit-scrollbar-thumb { background: var(--gold); border-radius: 2px; }
803
-
804
797
  .v-section {
805
798
  flex-shrink: 0;
806
799
  }