@hanology/cham-browser 0.4.28 → 0.4.30
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 +1 -1
- package/template/src/components/AnnotationPane.vue +76 -34
- package/template/src/components/AnnotationTooltip.vue +52 -3
- package/template/src/components/BackToTop.vue +8 -6
- package/template/src/components/HorizontalDisplay.vue +30 -10
- package/template/src/components/PoemCard.vue +7 -4
- package/template/src/components/ReadingProgress.vue +7 -7
- package/template/src/components/SectionBlock.vue +2 -2
- package/template/src/components/VerticalScroll.vue +30 -10
- package/template/src/styles/main.css +19 -1
- package/template/src/views/LibraryHome.vue +6 -3
- package/template/src/views/PieceView.vue +14 -10
package/package.json
CHANGED
|
@@ -384,6 +384,12 @@ onBeforeUnmount(() => {
|
|
|
384
384
|
justify-content: center;
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
+
.ann-pane.vertical .ann-pane-handle {
|
|
388
|
+
right: auto;
|
|
389
|
+
left: -6px;
|
|
390
|
+
cursor: col-resize;
|
|
391
|
+
}
|
|
392
|
+
|
|
387
393
|
.ann-handle-grip {
|
|
388
394
|
display: block;
|
|
389
395
|
width: 3px;
|
|
@@ -411,7 +417,7 @@ onBeforeUnmount(() => {
|
|
|
411
417
|
}
|
|
412
418
|
|
|
413
419
|
@media (max-width: 768px) {
|
|
414
|
-
.ann-pane {
|
|
420
|
+
.ann-pane:not(.vertical) {
|
|
415
421
|
width: 100% !important;
|
|
416
422
|
height: auto;
|
|
417
423
|
max-height: 55vh;
|
|
@@ -422,70 +428,90 @@ onBeforeUnmount(() => {
|
|
|
422
428
|
border-radius: 14px 14px 0 0;
|
|
423
429
|
box-shadow: 0 -4px 24px rgba(var(--shadow-rgb), 0.08);
|
|
424
430
|
}
|
|
425
|
-
.ann-pane-handle {
|
|
431
|
+
.ann-pane:not(.vertical) .ann-pane-handle {
|
|
426
432
|
display: none;
|
|
427
433
|
}
|
|
428
|
-
.ann-pane-enter-from,
|
|
429
|
-
.ann-pane-leave-to {
|
|
434
|
+
.ann-pane:not(.vertical).ann-pane-enter-from,
|
|
435
|
+
.ann-pane:not(.vertical).ann-pane-leave-to {
|
|
430
436
|
transform: translateY(100%);
|
|
431
437
|
}
|
|
432
438
|
}
|
|
433
439
|
|
|
434
440
|
/* ─── Vertical mode ─── */
|
|
435
|
-
|
|
441
|
+
|
|
442
|
+
.ann-pane.vertical {
|
|
443
|
+
writing-mode: vertical-rl;
|
|
444
|
+
text-orientation: mixed;
|
|
445
|
+
border-right: none;
|
|
446
|
+
border-left: 1px solid var(--border);
|
|
447
|
+
box-shadow: -4px 0 24px rgba(var(--shadow-rgb), 0.06);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.ann-pane.vertical .ann-pane-header {
|
|
451
|
+
writing-mode: vertical-rl;
|
|
452
|
+
text-orientation: mixed;
|
|
453
|
+
border-bottom: none;
|
|
454
|
+
border-left: 1px solid var(--border-light);
|
|
455
|
+
padding: 16px 12px;
|
|
456
|
+
flex-direction: row;
|
|
457
|
+
align-items: center;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.ann-pane.vertical .ann-pane-body {
|
|
461
|
+
overflow-y: hidden;
|
|
462
|
+
overflow-x: auto;
|
|
463
|
+
overscroll-behavior: contain;
|
|
464
|
+
}
|
|
436
465
|
|
|
437
466
|
.ann-pane.vertical .ann-pane-entry {
|
|
467
|
+
padding: 12px 0;
|
|
468
|
+
border-bottom: none;
|
|
469
|
+
border-right: 1px solid var(--border-light);
|
|
470
|
+
border-left: none;
|
|
438
471
|
display: flex;
|
|
439
|
-
flex-direction: row
|
|
440
|
-
gap: 8px;
|
|
472
|
+
flex-direction: row;
|
|
441
473
|
align-items: flex-start;
|
|
442
|
-
|
|
443
|
-
|
|
474
|
+
gap: 0;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.ann-pane.vertical .ann-pane-entry:last-child {
|
|
478
|
+
border-right: none;
|
|
444
479
|
}
|
|
445
480
|
|
|
446
481
|
.ann-pane.vertical .ann-pane-entry.active {
|
|
482
|
+
border-left-color: transparent;
|
|
447
483
|
border-right-color: var(--vermillion);
|
|
448
484
|
}
|
|
449
485
|
|
|
450
486
|
.ann-pane.vertical .ann-pane-entry.active.pronunciation {
|
|
487
|
+
border-left-color: transparent;
|
|
451
488
|
border-right-color: var(--jade);
|
|
452
489
|
}
|
|
453
490
|
|
|
454
|
-
.ann-pane.vertical .ann-pane-
|
|
455
|
-
flex: 1;
|
|
456
|
-
min-width: 0;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/* Vertical headword — only this element uses vertical writing */
|
|
460
|
-
.ann-pane-v-word {
|
|
491
|
+
.ann-pane.vertical .ann-pane-v-word {
|
|
461
492
|
writing-mode: vertical-rl;
|
|
462
493
|
text-orientation: upright;
|
|
463
494
|
display: flex;
|
|
464
|
-
flex-direction:
|
|
495
|
+
flex-direction: column;
|
|
465
496
|
align-items: center;
|
|
466
|
-
gap:
|
|
467
|
-
padding: 0
|
|
497
|
+
gap: 4px;
|
|
498
|
+
padding: 0 6px;
|
|
468
499
|
border-left: 1px solid var(--border-light);
|
|
469
500
|
flex-shrink: 0;
|
|
470
501
|
}
|
|
471
502
|
|
|
472
|
-
.ann-pane-
|
|
473
|
-
|
|
474
|
-
font-size: 20px;
|
|
475
|
-
font-weight: 900;
|
|
476
|
-
letter-spacing: 6px;
|
|
477
|
-
color: var(--ink);
|
|
503
|
+
.ann-pane.vertical .ann-pane-entry-main {
|
|
504
|
+
padding: 0 8px;
|
|
478
505
|
}
|
|
479
506
|
|
|
480
|
-
.ann-pane-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
color: var(--vermillion);
|
|
507
|
+
.ann-pane.vertical .ann-pane-entry-head {
|
|
508
|
+
flex-direction: column;
|
|
509
|
+
align-items: flex-start;
|
|
510
|
+
gap: 4px;
|
|
485
511
|
}
|
|
486
512
|
|
|
487
|
-
.ann-pane
|
|
488
|
-
|
|
513
|
+
.ann-pane.vertical .ann-pane-entry-body {
|
|
514
|
+
padding-left: 0;
|
|
489
515
|
}
|
|
490
516
|
|
|
491
517
|
.ann-pane.vertical .ann-pane-text {
|
|
@@ -493,6 +519,21 @@ onBeforeUnmount(() => {
|
|
|
493
519
|
letter-spacing: 1px;
|
|
494
520
|
}
|
|
495
521
|
|
|
522
|
+
.ann-pane.vertical .ann-pane-close {
|
|
523
|
+
margin-left: 0;
|
|
524
|
+
margin-top: auto;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.ann-pane.vertical .ann-pane-count,
|
|
528
|
+
.ann-pane.vertical .ann-pane-kind,
|
|
529
|
+
.ann-pane.vertical .ann-pane-layer {
|
|
530
|
+
writing-mode: horizontal-tb;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.ann-pane.vertical .ann-pane-pron {
|
|
534
|
+
writing-mode: horizontal-tb;
|
|
535
|
+
}
|
|
536
|
+
|
|
496
537
|
@media (max-width: 768px) {
|
|
497
538
|
.ann-pane.vertical {
|
|
498
539
|
width: 80vw !important;
|
|
@@ -500,10 +541,11 @@ onBeforeUnmount(() => {
|
|
|
500
541
|
max-height: none !important;
|
|
501
542
|
top: 0 !important;
|
|
502
543
|
bottom: auto !important;
|
|
503
|
-
border-
|
|
544
|
+
border-left: 1px solid var(--border) !important;
|
|
545
|
+
border-right: none !important;
|
|
504
546
|
border-top: none !important;
|
|
505
547
|
border-radius: 0 !important;
|
|
506
|
-
box-shadow: 4px 0 24px rgba(var(--shadow-rgb), 0.06) !important;
|
|
548
|
+
box-shadow: -4px 0 24px rgba(var(--shadow-rgb), 0.06) !important;
|
|
507
549
|
}
|
|
508
550
|
.ann-pane.vertical .ann-pane-handle {
|
|
509
551
|
display: flex !important;
|
|
@@ -417,6 +417,30 @@ onBeforeUnmount(() => {
|
|
|
417
417
|
.ann-sheet { display: none; }
|
|
418
418
|
}
|
|
419
419
|
|
|
420
|
+
/* ─── Mobile sheet vertical mode ─── */
|
|
421
|
+
.ann-sheet.vertical {
|
|
422
|
+
left: 0;
|
|
423
|
+
right: auto;
|
|
424
|
+
bottom: auto;
|
|
425
|
+
top: 0;
|
|
426
|
+
width: 85vw;
|
|
427
|
+
max-height: none;
|
|
428
|
+
height: 100vh;
|
|
429
|
+
border-top: none;
|
|
430
|
+
border-radius: 0;
|
|
431
|
+
border-right: 1px solid var(--border);
|
|
432
|
+
box-shadow: 4px 0 32px rgba(var(--shadow-rgb), 0.15);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.ann-sheet.vertical .ann-sheet-handle {
|
|
436
|
+
display: none;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.ann-sheet.vertical.ann-sheet-enter-from,
|
|
440
|
+
.ann-sheet.vertical.ann-sheet-leave-to {
|
|
441
|
+
transform: translateX(-100%);
|
|
442
|
+
}
|
|
443
|
+
|
|
420
444
|
/* ─── Vertical mode ─── */
|
|
421
445
|
.ann-card.vertical {
|
|
422
446
|
writing-mode: vertical-rl;
|
|
@@ -427,10 +451,19 @@ onBeforeUnmount(() => {
|
|
|
427
451
|
}
|
|
428
452
|
|
|
429
453
|
.ann-card.vertical .ann-card-head {
|
|
430
|
-
writing-mode:
|
|
431
|
-
|
|
454
|
+
writing-mode: vertical-rl;
|
|
455
|
+
text-orientation: upright;
|
|
456
|
+
padding: 6px 10px;
|
|
432
457
|
border-bottom: none;
|
|
433
458
|
border-left: 1px solid var(--border-light);
|
|
459
|
+
flex-direction: row;
|
|
460
|
+
align-items: center;
|
|
461
|
+
}
|
|
462
|
+
.ann-card.vertical .ann-headword {
|
|
463
|
+
letter-spacing: 6px;
|
|
464
|
+
}
|
|
465
|
+
.ann-card.vertical .ann-badge-count {
|
|
466
|
+
writing-mode: horizontal-tb;
|
|
434
467
|
}
|
|
435
468
|
|
|
436
469
|
.ann-card.vertical .ann-card-scroll {
|
|
@@ -482,7 +515,7 @@ onBeforeUnmount(() => {
|
|
|
482
515
|
}
|
|
483
516
|
|
|
484
517
|
.ann-sheet-body.vertical {
|
|
485
|
-
flex-direction: row
|
|
518
|
+
flex-direction: row;
|
|
486
519
|
}
|
|
487
520
|
|
|
488
521
|
.ann-sheet-body.vertical > .ann-sheet-head {
|
|
@@ -527,8 +560,13 @@ onBeforeUnmount(() => {
|
|
|
527
560
|
}
|
|
528
561
|
|
|
529
562
|
.ann-sheet-body.vertical .ann-sheet-scroll {
|
|
563
|
+
writing-mode: vertical-rl;
|
|
564
|
+
text-orientation: mixed;
|
|
530
565
|
flex: 1;
|
|
531
566
|
min-width: 0;
|
|
567
|
+
overflow-x: auto;
|
|
568
|
+
overflow-y: hidden;
|
|
569
|
+
padding: 4px 12px 24px;
|
|
532
570
|
}
|
|
533
571
|
|
|
534
572
|
.ann-sheet-body.vertical .ann-pron-h {
|
|
@@ -538,5 +576,16 @@ onBeforeUnmount(() => {
|
|
|
538
576
|
.ann-sheet-body.vertical .ann-text {
|
|
539
577
|
white-space: pre-line;
|
|
540
578
|
line-height: 2;
|
|
579
|
+
letter-spacing: 1px;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.ann-sheet-body.vertical .ann-entry {
|
|
583
|
+
border-bottom: none;
|
|
584
|
+
border-right: 1px solid var(--border-light);
|
|
585
|
+
padding: 0 10px;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
.ann-sheet-body.vertical .ann-entry:last-child {
|
|
589
|
+
border-right: none;
|
|
541
590
|
}
|
|
542
591
|
</style>
|
|
@@ -48,18 +48,20 @@ onUnmounted(() => window.removeEventListener('scroll', onScroll))
|
|
|
48
48
|
align-items: center;
|
|
49
49
|
justify-content: center;
|
|
50
50
|
box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.1);
|
|
51
|
-
transition: all 0.
|
|
51
|
+
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
52
|
+
backdrop-filter: blur(8px);
|
|
53
|
+
-webkit-backdrop-filter: blur(8px);
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
@media (max-width: 768px) {
|
|
55
57
|
.btt { bottom: 88px; right: 16px; width: 36px; height: 36px; }
|
|
56
58
|
}
|
|
57
59
|
.btt:hover {
|
|
58
|
-
background: var(--
|
|
59
|
-
color:
|
|
60
|
-
border-color: var(--
|
|
61
|
-
transform: translateY(-
|
|
62
|
-
box-shadow: 0 8px 24px rgba(
|
|
60
|
+
background: var(--vermillion);
|
|
61
|
+
color: #fff;
|
|
62
|
+
border-color: var(--vermillion);
|
|
63
|
+
transform: translateY(-3px);
|
|
64
|
+
box-shadow: 0 8px 24px rgba(194, 58, 43, 0.2);
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
.btt-enter-active { transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }
|
|
@@ -44,7 +44,8 @@ function onTap(event: MouseEvent) {
|
|
|
44
44
|
<div
|
|
45
45
|
v-for="(_, i) in verses"
|
|
46
46
|
:key="i"
|
|
47
|
-
class="h-display-line"
|
|
47
|
+
class="h-display-line h-verse-anim"
|
|
48
|
+
:style="{ animationDelay: (0.15 + i * 0.08) + 's' }"
|
|
48
49
|
v-html="verseHtml(i)"
|
|
49
50
|
/>
|
|
50
51
|
</div>
|
|
@@ -59,6 +60,7 @@ function onTap(event: MouseEvent) {
|
|
|
59
60
|
padding: 40px 56px;
|
|
60
61
|
box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.08);
|
|
61
62
|
text-align: center;
|
|
63
|
+
animation: poemReveal 0.5s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
|
62
64
|
}
|
|
63
65
|
.h-display-title {
|
|
64
66
|
font-size: 32px; font-weight: 900;
|
|
@@ -71,20 +73,32 @@ function onTap(event: MouseEvent) {
|
|
|
71
73
|
}
|
|
72
74
|
.h-display-line {
|
|
73
75
|
font-size: var(--main-font-size, 24px); line-height: 2.6;
|
|
74
|
-
letter-spacing: 4px; color: var(--ink);
|
|
76
|
+
letter-spacing: 4px; color: var(--ink); white-space: pre-wrap;
|
|
77
|
+
}
|
|
78
|
+
.h-verse-anim {
|
|
79
|
+
animation: verseFade 0.45s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
|
80
|
+
}
|
|
81
|
+
@keyframes poemReveal {
|
|
82
|
+
from { opacity: 0; transform: translateY(16px) scale(0.98); }
|
|
83
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
84
|
+
}
|
|
85
|
+
@keyframes verseFade {
|
|
86
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
87
|
+
to { opacity: 1; transform: translateY(0); }
|
|
75
88
|
}
|
|
76
89
|
|
|
77
90
|
:deep(.ann-target) {
|
|
78
91
|
border-bottom: 2px solid var(--vermillion);
|
|
79
92
|
cursor: help;
|
|
80
|
-
transition: background 0.
|
|
93
|
+
transition: background 0.2s ease, box-shadow 0.2s ease;
|
|
81
94
|
}
|
|
82
95
|
:deep(.ann-target.ann-overlap) {
|
|
83
96
|
border-bottom-width: 3px;
|
|
84
97
|
border-bottom-style: double;
|
|
85
98
|
}
|
|
86
99
|
:deep(.ann-target:hover) {
|
|
87
|
-
background: rgba(194, 58, 43, 0.
|
|
100
|
+
background: rgba(194, 58, 43, 0.1);
|
|
101
|
+
box-shadow: 0 2px 8px rgba(194, 58, 43, 0.08);
|
|
88
102
|
}
|
|
89
103
|
:deep(.ann-num) {
|
|
90
104
|
font-size: 10px;
|
|
@@ -96,7 +110,8 @@ function onTap(event: MouseEvent) {
|
|
|
96
110
|
letter-spacing: 0;
|
|
97
111
|
}
|
|
98
112
|
:deep(.ann-target.pronunciation:hover) {
|
|
99
|
-
background: rgba(58, 107, 94, 0.
|
|
113
|
+
background: rgba(58, 107, 94, 0.1);
|
|
114
|
+
box-shadow: 0 2px 8px rgba(58, 107, 94, 0.08);
|
|
100
115
|
}
|
|
101
116
|
:deep(.ann-target.pronunciation) {
|
|
102
117
|
border-bottom-color: var(--jade);
|
|
@@ -117,19 +132,24 @@ function onTap(event: MouseEvent) {
|
|
|
117
132
|
border-bottom-color: var(--ann-allusion);
|
|
118
133
|
}
|
|
119
134
|
:deep(.ann-target.person:hover) {
|
|
120
|
-
background: rgba(58, 90, 140, 0.
|
|
135
|
+
background: rgba(58, 90, 140, 0.1);
|
|
136
|
+
box-shadow: 0 2px 8px rgba(58, 90, 140, 0.08);
|
|
121
137
|
}
|
|
122
138
|
:deep(.ann-target.place:hover) {
|
|
123
|
-
background: rgba(139, 105, 20, 0.
|
|
139
|
+
background: rgba(139, 105, 20, 0.1);
|
|
140
|
+
box-shadow: 0 2px 8px rgba(139, 105, 20, 0.08);
|
|
124
141
|
}
|
|
125
142
|
:deep(.ann-target.event:hover) {
|
|
126
|
-
background: rgba(107, 76, 138, 0.
|
|
143
|
+
background: rgba(107, 76, 138, 0.1);
|
|
144
|
+
box-shadow: 0 2px 8px rgba(107, 76, 138, 0.08);
|
|
127
145
|
}
|
|
128
146
|
:deep(.ann-target.date:hover) {
|
|
129
|
-
background: rgba(42, 122, 122, 0.
|
|
147
|
+
background: rgba(42, 122, 122, 0.1);
|
|
148
|
+
box-shadow: 0 2px 8px rgba(42, 122, 122, 0.08);
|
|
130
149
|
}
|
|
131
150
|
:deep(.ann-target.allusion:hover) {
|
|
132
|
-
background: rgba(181, 101, 29, 0.
|
|
151
|
+
background: rgba(181, 101, 29, 0.1);
|
|
152
|
+
box-shadow: 0 2px 8px rgba(181, 101, 29, 0.08);
|
|
133
153
|
}
|
|
134
154
|
|
|
135
155
|
@media (max-width: 768px) {
|
|
@@ -40,15 +40,16 @@ const preview = computed(() => {
|
|
|
40
40
|
position: absolute;
|
|
41
41
|
top: 0; left: 0;
|
|
42
42
|
width: 3px; height: 0;
|
|
43
|
-
background: var(--vermillion);
|
|
44
|
-
transition: height 0.
|
|
43
|
+
background: linear-gradient(180deg, var(--vermillion), var(--gold));
|
|
44
|
+
transition: height 0.35s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
|
|
45
45
|
}
|
|
46
46
|
.pc-root:hover {
|
|
47
|
-
transform: translateY(-
|
|
48
|
-
box-shadow: 0 8px
|
|
47
|
+
transform: translateY(-3px);
|
|
48
|
+
box-shadow: 0 8px 28px rgba(var(--shadow-rgb), 0.1);
|
|
49
49
|
border-color: var(--gold);
|
|
50
50
|
}
|
|
51
51
|
.pc-root:hover .pc-accent { height: 100%; }
|
|
52
|
+
.pc-root:hover .pc-title { color: var(--vermillion); }
|
|
52
53
|
.pc-root:active { transform: scale(0.98); }
|
|
53
54
|
.pc-body { padding: 24px; }
|
|
54
55
|
.pc-num {
|
|
@@ -67,6 +68,7 @@ const preview = computed(() => {
|
|
|
67
68
|
font-size: 20px; font-weight: 700;
|
|
68
69
|
letter-spacing: 2px; margin-bottom: 6px;
|
|
69
70
|
color: var(--ink);
|
|
71
|
+
transition: color 0.25s ease;
|
|
70
72
|
}
|
|
71
73
|
.pc-author {
|
|
72
74
|
font-size: 13px; color: var(--ink-light);
|
|
@@ -130,6 +132,7 @@ const preview = computed(() => {
|
|
|
130
132
|
.pc-vertical .pc-accent {
|
|
131
133
|
top: auto; left: 0; bottom: 0;
|
|
132
134
|
width: 0; height: 3px;
|
|
135
|
+
background: linear-gradient(90deg, var(--gold), var(--vermillion));
|
|
133
136
|
transition: width 0.35s ease;
|
|
134
137
|
}
|
|
135
138
|
.pc-vertical:hover {
|
|
@@ -69,18 +69,18 @@ onUnmounted(detach)
|
|
|
69
69
|
z-index: 1001;
|
|
70
70
|
pointer-events: none;
|
|
71
71
|
will-change: width, height;
|
|
72
|
-
transition: width 0.
|
|
72
|
+
transition: width 0.08s linear, height 0.08s linear;
|
|
73
73
|
}
|
|
74
74
|
.rp:not(.rp-v) {
|
|
75
75
|
top: 0; left: 0;
|
|
76
|
-
height:
|
|
77
|
-
background: var(--vermillion);
|
|
78
|
-
box-shadow: 0 0 8px rgba(194, 58, 43, 0.
|
|
76
|
+
height: 3px;
|
|
77
|
+
background: linear-gradient(90deg, var(--vermillion), var(--gold));
|
|
78
|
+
box-shadow: 0 0 8px rgba(194, 58, 43, 0.2);
|
|
79
79
|
}
|
|
80
80
|
.rp-v {
|
|
81
81
|
top: 0; left: 0;
|
|
82
|
-
width:
|
|
83
|
-
background: var(--vermillion);
|
|
84
|
-
box-shadow: 0 0 8px rgba(194, 58, 43, 0.
|
|
82
|
+
width: 3px;
|
|
83
|
+
background: linear-gradient(180deg, var(--vermillion), var(--gold));
|
|
84
|
+
box-shadow: 0 0 8px rgba(194, 58, 43, 0.2);
|
|
85
85
|
}
|
|
86
86
|
</style>
|
|
@@ -89,8 +89,8 @@ const paragraphsHtml = computed(() => {
|
|
|
89
89
|
.sb-root {
|
|
90
90
|
margin-bottom: 40px;
|
|
91
91
|
opacity: 0;
|
|
92
|
-
transform: translateY(
|
|
93
|
-
transition: opacity 0.
|
|
92
|
+
transform: translateY(16px);
|
|
93
|
+
transition: opacity 0.6s ease, transform 0.6s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
|
|
94
94
|
}
|
|
95
95
|
.sb-root.sb-visible {
|
|
96
96
|
opacity: 1;
|
|
@@ -47,7 +47,8 @@ function onTap(event: MouseEvent) {
|
|
|
47
47
|
<span
|
|
48
48
|
v-for="(_, i) in verses"
|
|
49
49
|
:key="i"
|
|
50
|
-
class="v-scroll-line"
|
|
50
|
+
class="v-scroll-line v-verse-anim"
|
|
51
|
+
:style="{ animationDelay: (0.2 + i * 0.06) + 's' }"
|
|
51
52
|
v-html="verseHtml(i)"
|
|
52
53
|
/>
|
|
53
54
|
</div>
|
|
@@ -68,6 +69,7 @@ function onTap(event: MouseEvent) {
|
|
|
68
69
|
position: relative;
|
|
69
70
|
scrollbar-width: thin;
|
|
70
71
|
scrollbar-color: var(--gold) transparent;
|
|
72
|
+
animation: poemRevealV 0.5s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
|
71
73
|
}
|
|
72
74
|
.v-scroll::-webkit-scrollbar { height: 3px; }
|
|
73
75
|
.v-scroll::-webkit-scrollbar-thumb { background: var(--gold); border-radius: 2px; }
|
|
@@ -87,14 +89,25 @@ function onTap(event: MouseEvent) {
|
|
|
87
89
|
.v-scroll-body { margin-left: 24px; }
|
|
88
90
|
.v-scroll-line {
|
|
89
91
|
font-size: var(--main-font-size, 24px); line-height: 2.4; letter-spacing: 6px;
|
|
90
|
-
color: var(--ink); display: block;
|
|
92
|
+
color: var(--ink); display: block; white-space: pre-wrap;
|
|
93
|
+
}
|
|
94
|
+
.v-verse-anim {
|
|
95
|
+
animation: verseFadeV 0.4s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
|
|
96
|
+
}
|
|
97
|
+
@keyframes poemRevealV {
|
|
98
|
+
from { opacity: 0; transform: translateX(12px); }
|
|
99
|
+
to { opacity: 1; transform: translateX(0); }
|
|
100
|
+
}
|
|
101
|
+
@keyframes verseFadeV {
|
|
102
|
+
from { opacity: 0; }
|
|
103
|
+
to { opacity: 1; }
|
|
91
104
|
}
|
|
92
105
|
|
|
93
106
|
:deep(.ann-target) {
|
|
94
107
|
border-left: 2px solid var(--vermillion);
|
|
95
108
|
padding-left: 2px;
|
|
96
109
|
cursor: help;
|
|
97
|
-
transition: background 0.
|
|
110
|
+
transition: background 0.2s ease, box-shadow 0.2s ease;
|
|
98
111
|
}
|
|
99
112
|
:deep(.ann-target.ann-overlap) {
|
|
100
113
|
border-left-width: 3px;
|
|
@@ -115,10 +128,12 @@ function onTap(event: MouseEvent) {
|
|
|
115
128
|
letter-spacing: -1px;
|
|
116
129
|
}
|
|
117
130
|
:deep(.ann-target:hover) {
|
|
118
|
-
background: rgba(194, 58, 43, 0.
|
|
131
|
+
background: rgba(194, 58, 43, 0.1);
|
|
132
|
+
box-shadow: 0 -2px 8px rgba(194, 58, 43, 0.08);
|
|
119
133
|
}
|
|
120
134
|
:deep(.ann-target.pronunciation:hover) {
|
|
121
|
-
background: rgba(58, 107, 94, 0.
|
|
135
|
+
background: rgba(58, 107, 94, 0.1);
|
|
136
|
+
box-shadow: 0 -2px 8px rgba(58, 107, 94, 0.08);
|
|
122
137
|
}
|
|
123
138
|
:deep(.ann-target.pronunciation) {
|
|
124
139
|
border-left-color: var(--jade);
|
|
@@ -142,18 +157,23 @@ function onTap(event: MouseEvent) {
|
|
|
142
157
|
border-left-color: var(--ann-allusion);
|
|
143
158
|
}
|
|
144
159
|
:deep(.ann-target.person:hover) {
|
|
145
|
-
background: rgba(58, 90, 140, 0.
|
|
160
|
+
background: rgba(58, 90, 140, 0.1);
|
|
161
|
+
box-shadow: 0 -2px 8px rgba(58, 90, 140, 0.08);
|
|
146
162
|
}
|
|
147
163
|
:deep(.ann-target.place:hover) {
|
|
148
|
-
background: rgba(139, 105, 20, 0.
|
|
164
|
+
background: rgba(139, 105, 20, 0.1);
|
|
165
|
+
box-shadow: 0 -2px 8px rgba(139, 105, 20, 0.08);
|
|
149
166
|
}
|
|
150
167
|
:deep(.ann-target.event:hover) {
|
|
151
|
-
background: rgba(107, 76, 138, 0.
|
|
168
|
+
background: rgba(107, 76, 138, 0.1);
|
|
169
|
+
box-shadow: 0 -2px 8px rgba(107, 76, 138, 0.08);
|
|
152
170
|
}
|
|
153
171
|
:deep(.ann-target.date:hover) {
|
|
154
|
-
background: rgba(42, 122, 122, 0.
|
|
172
|
+
background: rgba(42, 122, 122, 0.1);
|
|
173
|
+
box-shadow: 0 -2px 8px rgba(42, 122, 122, 0.08);
|
|
155
174
|
}
|
|
156
175
|
:deep(.ann-target.allusion:hover) {
|
|
157
|
-
background: rgba(181, 101, 29, 0.
|
|
176
|
+
background: rgba(181, 101, 29, 0.1);
|
|
177
|
+
box-shadow: 0 -2px 8px rgba(181, 101, 29, 0.08);
|
|
158
178
|
}
|
|
159
179
|
</style>
|
|
@@ -141,6 +141,23 @@ html[dir="rtl"] ::-webkit-scrollbar-thumb { background: var(--gold); }
|
|
|
141
141
|
a { color: inherit; text-decoration: none; }
|
|
142
142
|
button { font-family: inherit; }
|
|
143
143
|
|
|
144
|
+
/* ===== FOCUS STYLES ===== */
|
|
145
|
+
:focus-visible {
|
|
146
|
+
outline: 2px solid var(--vermillion);
|
|
147
|
+
outline-offset: 2px;
|
|
148
|
+
}
|
|
149
|
+
button:focus-visible {
|
|
150
|
+
outline: 2px solid var(--vermillion);
|
|
151
|
+
outline-offset: 2px;
|
|
152
|
+
border-radius: 4px;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* ===== ACTIVE ANNOTATION FLASH ===== */
|
|
156
|
+
@keyframes ann-flash-anim {
|
|
157
|
+
0% { background: rgba(194, 58, 43, 0.25); box-shadow: 0 0 12px rgba(194, 58, 43, 0.15); }
|
|
158
|
+
100% { background: transparent; box-shadow: none; }
|
|
159
|
+
}
|
|
160
|
+
|
|
144
161
|
/* ===== LOADING SCREEN ===== */
|
|
145
162
|
#app-loading {
|
|
146
163
|
position: fixed; inset: 0;
|
|
@@ -148,10 +165,11 @@ button { font-family: inherit; }
|
|
|
148
165
|
display: flex; flex-direction: column;
|
|
149
166
|
align-items: center; justify-content: center;
|
|
150
167
|
z-index: 9999;
|
|
151
|
-
transition: opacity 0.
|
|
168
|
+
transition: opacity 0.5s ease, transform 0.5s ease;
|
|
152
169
|
}
|
|
153
170
|
#app-loading.fade-out {
|
|
154
171
|
opacity: 0;
|
|
172
|
+
transform: scale(1.02);
|
|
155
173
|
pointer-events: none;
|
|
156
174
|
}
|
|
157
175
|
#app-loading .seal {
|
|
@@ -354,15 +354,17 @@ function openBook(bookId: string) {
|
|
|
354
354
|
from { opacity: 0; transform: translateY(12px); }
|
|
355
355
|
to { opacity: 1; transform: translateY(0); }
|
|
356
356
|
}
|
|
357
|
-
.lib-card:hover { border-color: var(--gold); box-shadow: 0
|
|
357
|
+
.lib-card:hover { border-color: var(--gold); box-shadow: 0 6px 24px rgba(var(--shadow-rgb), 0.1); transform: translateY(-2px); }
|
|
358
|
+
.lib-card:active { transform: scale(0.98); }
|
|
358
359
|
.lib-card-accent {
|
|
359
360
|
position: absolute;
|
|
360
361
|
top: 0; left: 0;
|
|
361
362
|
width: 3px; height: 0;
|
|
362
|
-
background: var(--vermillion);
|
|
363
|
-
transition: height 0.35s ease;
|
|
363
|
+
background: linear-gradient(180deg, var(--vermillion), var(--gold));
|
|
364
|
+
transition: height 0.35s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
|
|
364
365
|
}
|
|
365
366
|
.lib-card:hover .lib-card-accent { height: 100%; }
|
|
367
|
+
.lib-card:hover .lib-card-title { color: var(--vermillion); }
|
|
366
368
|
.lib-card-top {
|
|
367
369
|
display: flex;
|
|
368
370
|
align-items: baseline;
|
|
@@ -372,6 +374,7 @@ function openBook(bookId: string) {
|
|
|
372
374
|
.lib-card-title {
|
|
373
375
|
font-size: 22px; font-weight: 900;
|
|
374
376
|
letter-spacing: 4px; color: var(--ink);
|
|
377
|
+
transition: color 0.25s ease;
|
|
375
378
|
}
|
|
376
379
|
.lib-card-genre {
|
|
377
380
|
font-size: 11px;
|
|
@@ -846,13 +846,15 @@ function tcy(n: number): string {
|
|
|
846
846
|
border: 1px solid var(--border-light);
|
|
847
847
|
border-radius: 6px;
|
|
848
848
|
cursor: pointer;
|
|
849
|
-
transition: all 0.
|
|
849
|
+
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
850
850
|
line-height: 1.6;
|
|
851
|
+
position: relative;
|
|
851
852
|
}
|
|
852
853
|
.v-nav-btn:hover {
|
|
853
854
|
border-color: var(--gold);
|
|
854
|
-
box-shadow: 0 4px
|
|
855
|
+
box-shadow: 0 4px 20px rgba(var(--shadow-rgb), 0.1);
|
|
855
856
|
}
|
|
857
|
+
.v-nav-btn:hover .v-nav-title { color: var(--vermillion); }
|
|
856
858
|
.v-nav-dir {
|
|
857
859
|
font-size: 16px; color: var(--vermillion);
|
|
858
860
|
margin-bottom: 0.5em;
|
|
@@ -865,6 +867,7 @@ function tcy(n: number): string {
|
|
|
865
867
|
.v-nav-title {
|
|
866
868
|
font-size: 18px; font-weight: 700;
|
|
867
869
|
letter-spacing: 3px; color: var(--ink);
|
|
870
|
+
transition: color 0.25s ease;
|
|
868
871
|
}
|
|
869
872
|
|
|
870
873
|
/* ═══════ 橫排模式 ═══════ */
|
|
@@ -950,7 +953,7 @@ function tcy(n: number): string {
|
|
|
950
953
|
.h-nav-arrow {
|
|
951
954
|
width: 32px; height: 32px;
|
|
952
955
|
border: 1px solid var(--border);
|
|
953
|
-
border-radius:
|
|
956
|
+
border-radius: 6px;
|
|
954
957
|
background: none;
|
|
955
958
|
font-family: var(--sans);
|
|
956
959
|
font-size: 16px;
|
|
@@ -1026,20 +1029,21 @@ function tcy(n: number): string {
|
|
|
1026
1029
|
position: absolute;
|
|
1027
1030
|
bottom: 0; left: 0; right: 0;
|
|
1028
1031
|
height: 2px;
|
|
1029
|
-
background: var(--vermillion);
|
|
1032
|
+
background: linear-gradient(90deg, var(--vermillion), var(--gold));
|
|
1030
1033
|
transform: scaleX(0);
|
|
1031
|
-
transition: transform 0.
|
|
1034
|
+
transition: transform 0.35s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
|
|
1032
1035
|
}
|
|
1033
1036
|
.h-nav-btn:hover {
|
|
1034
1037
|
border-color: var(--gold);
|
|
1035
1038
|
box-shadow: 0 8px 32px rgba(var(--shadow-rgb), 0.1);
|
|
1036
|
-
transform: translateY(-
|
|
1039
|
+
transform: translateY(-3px);
|
|
1037
1040
|
}
|
|
1038
1041
|
.h-nav-btn:hover::after { transform: scaleX(1); }
|
|
1042
|
+
.h-nav-btn:hover .h-nav-title { color: var(--vermillion); }
|
|
1039
1043
|
.h-nav-btn:active { transform: scale(0.98); }
|
|
1040
1044
|
.h-nav-btn.h-nav-next { text-align: right; }
|
|
1041
1045
|
.h-nav-label { font-size: 11px; color: var(--ink-faint); font-family: var(--sans); letter-spacing: 2px; margin-bottom: 4px; }
|
|
1042
|
-
.h-nav-title { font-size: 16px; font-weight: 600; letter-spacing: 1px; color: var(--ink); }
|
|
1046
|
+
.h-nav-title { font-size: 16px; font-weight: 600; letter-spacing: 1px; color: var(--ink); transition: color 0.25s ease; }
|
|
1043
1047
|
|
|
1044
1048
|
.h-overlay {
|
|
1045
1049
|
position: fixed; inset: 0;
|
|
@@ -1335,11 +1339,11 @@ function tcy(n: number): string {
|
|
|
1335
1339
|
|
|
1336
1340
|
/* ─── 注釋閃爍 ─── */
|
|
1337
1341
|
:deep(.ann-flash) {
|
|
1338
|
-
animation: ann-flash-anim 1.
|
|
1342
|
+
animation: ann-flash-anim 1.5s ease-out;
|
|
1339
1343
|
}
|
|
1340
1344
|
@keyframes ann-flash-anim {
|
|
1341
|
-
0% { background: rgba(194, 58, 43, 0.
|
|
1342
|
-
100% { background: transparent; }
|
|
1345
|
+
0% { background: rgba(194, 58, 43, 0.25); box-shadow: 0 0 12px rgba(194, 58, 43, 0.15); }
|
|
1346
|
+
100% { background: transparent; box-shadow: none; }
|
|
1343
1347
|
}
|
|
1344
1348
|
|
|
1345
1349
|
/* ═══════ 行動裝置適配 ═══════ */
|