@hanology/cham-browser 0.3.5 → 0.3.7
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/dist/cli.js +0 -0
- package/package.json +1 -1
- package/template/src/components/AnnotationTooltip.vue +11 -3
- package/template/src/components/BackToTop.vue +65 -0
- package/template/src/components/PoemCard.vue +7 -0
- package/template/src/components/ReadingToolbar.vue +19 -0
- package/template/src/styles/main.css +26 -1
- package/template/src/views/AboutView.vue +2 -0
- package/template/src/views/BookHome.vue +8 -1
- package/template/src/views/LibraryHome.vue +7 -1
- package/template/src/views/PieceView.vue +66 -39
package/dist/cli.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -198,10 +198,18 @@ onBeforeUnmount(() => {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
/* ─── Transition ─── */
|
|
201
|
-
.ann-fade-enter-active
|
|
202
|
-
transition: opacity 0.15s ease;
|
|
201
|
+
.ann-fade-enter-active {
|
|
202
|
+
transition: opacity var(--dur-fast, 0.15s) ease, transform var(--dur-mid, 0.25s) cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
203
203
|
}
|
|
204
|
-
.ann-fade-
|
|
204
|
+
.ann-fade-leave-active {
|
|
205
|
+
transition: opacity var(--dur-fast, 0.15s) ease, transform var(--dur-fast, 0.15s) ease;
|
|
206
|
+
}
|
|
207
|
+
.ann-fade-enter-from {
|
|
208
|
+
opacity: 0;
|
|
209
|
+
transform: scale(0.92) translateY(4px);
|
|
210
|
+
}
|
|
211
|
+
.ann-fade-leave-to {
|
|
205
212
|
opacity: 0;
|
|
213
|
+
transform: scale(0.96);
|
|
206
214
|
}
|
|
207
215
|
</style>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, onMounted, onUnmounted } from 'vue'
|
|
3
|
+
|
|
4
|
+
const visible = ref(false)
|
|
5
|
+
let ticking = false
|
|
6
|
+
|
|
7
|
+
function onScroll() {
|
|
8
|
+
if (ticking) return
|
|
9
|
+
ticking = true
|
|
10
|
+
requestAnimationFrame(() => {
|
|
11
|
+
visible.value = window.scrollY > 400
|
|
12
|
+
ticking = false
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function scrollToTop() {
|
|
17
|
+
window.scrollTo({ top: 0, behavior: 'smooth' })
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
onMounted(() => window.addEventListener('scroll', onScroll, { passive: true }))
|
|
21
|
+
onUnmounted(() => window.removeEventListener('scroll', onScroll))
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<Transition name="btt">
|
|
26
|
+
<button v-if="visible" class="btt" @click="scrollToTop" aria-label="回到頂部">
|
|
27
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
28
|
+
<path d="M12 19V5M5 12l7-7 7 7"/>
|
|
29
|
+
</svg>
|
|
30
|
+
</button>
|
|
31
|
+
</Transition>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<style scoped>
|
|
35
|
+
.btt {
|
|
36
|
+
position: fixed;
|
|
37
|
+
bottom: 80px;
|
|
38
|
+
right: 24px;
|
|
39
|
+
width: 40px;
|
|
40
|
+
height: 40px;
|
|
41
|
+
border-radius: 50%;
|
|
42
|
+
border: 1px solid var(--border);
|
|
43
|
+
background: var(--surface);
|
|
44
|
+
color: var(--ink-light);
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
z-index: 400;
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.1);
|
|
51
|
+
transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
52
|
+
}
|
|
53
|
+
.btt:hover {
|
|
54
|
+
background: var(--ink);
|
|
55
|
+
color: var(--paper);
|
|
56
|
+
border-color: var(--ink);
|
|
57
|
+
transform: translateY(-2px);
|
|
58
|
+
box-shadow: 0 8px 24px rgba(var(--shadow-rgb), 0.16);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.btt-enter-active { transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }
|
|
62
|
+
.btt-leave-active { transition: all 0.15s ease; }
|
|
63
|
+
.btt-enter-from { opacity: 0; transform: translateY(12px) scale(0.8); }
|
|
64
|
+
.btt-leave-to { opacity: 0; transform: translateY(8px) scale(0.9); }
|
|
65
|
+
</style>
|
|
@@ -54,6 +54,13 @@ const preview = computed(() => {
|
|
|
54
54
|
font-size: 11px; color: var(--ink-faint);
|
|
55
55
|
font-family: var(--sans); letter-spacing: 2px;
|
|
56
56
|
margin-bottom: 10px;
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
padding: 2px 6px;
|
|
61
|
+
border: 1px solid var(--border-light);
|
|
62
|
+
border-radius: 2px;
|
|
63
|
+
background: var(--surface-warm);
|
|
57
64
|
}
|
|
58
65
|
.pc-title {
|
|
59
66
|
font-size: 20px; font-weight: 700;
|
|
@@ -155,6 +155,25 @@ function close() { open.value = false }
|
|
|
155
155
|
transition: all 0.15s;
|
|
156
156
|
}
|
|
157
157
|
.rt-opt:hover { border-color: var(--ink); color: var(--ink); }
|
|
158
|
+
.rt-opt.rt-theme {
|
|
159
|
+
position: relative;
|
|
160
|
+
padding-left: 22px;
|
|
161
|
+
}
|
|
162
|
+
.rt-opt.rt-theme::before {
|
|
163
|
+
content: '';
|
|
164
|
+
position: absolute;
|
|
165
|
+
left: 8px;
|
|
166
|
+
top: 50%;
|
|
167
|
+
transform: translateY(-50%);
|
|
168
|
+
width: 8px;
|
|
169
|
+
height: 8px;
|
|
170
|
+
border-radius: 50%;
|
|
171
|
+
border: 1px solid var(--border);
|
|
172
|
+
}
|
|
173
|
+
.rt-opt.theme-light::before { background: #faf6ee; }
|
|
174
|
+
.rt-opt.theme-sepia::before { background: #f0e4c8; }
|
|
175
|
+
.rt-opt.theme-dark::before { background: #1c1c1e; border-color: #48484a; }
|
|
176
|
+
.rt-opt.theme-oled::before { background: #000; border-color: #333; }
|
|
158
177
|
.rt-opt.active {
|
|
159
178
|
background: var(--ink);
|
|
160
179
|
color: var(--paper);
|
|
@@ -90,23 +90,36 @@
|
|
|
90
90
|
--sans: 'Noto Sans TC', 'PingFang TC', sans-serif;
|
|
91
91
|
--nav-width: 56px;
|
|
92
92
|
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
|
93
|
+
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
94
|
+
--dur-fast: 0.15s;
|
|
95
|
+
--dur-mid: 0.25s;
|
|
96
|
+
--dur-slow: 0.4s;
|
|
93
97
|
}
|
|
94
98
|
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
95
|
-
html {
|
|
99
|
+
html {
|
|
100
|
+
scroll-behavior: smooth;
|
|
101
|
+
-webkit-font-smoothing: antialiased;
|
|
102
|
+
-moz-osx-font-smoothing: grayscale;
|
|
103
|
+
text-rendering: optimizeLegibility;
|
|
104
|
+
hanging-punctuation: first last;
|
|
105
|
+
}
|
|
96
106
|
body {
|
|
97
107
|
font-family: var(--serif);
|
|
98
108
|
background: var(--paper);
|
|
99
109
|
color: var(--ink);
|
|
100
110
|
line-height: 1.8;
|
|
101
111
|
min-height: 100vh;
|
|
112
|
+
overflow-x: hidden;
|
|
102
113
|
}
|
|
103
114
|
::selection { background: var(--vermillion); color: var(--selection-text); }
|
|
104
115
|
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
105
116
|
::-webkit-scrollbar-track { background: transparent; }
|
|
106
117
|
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
|
107
118
|
::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); }
|
|
119
|
+
html[dir="rtl"] ::-webkit-scrollbar-thumb { background: var(--gold); }
|
|
108
120
|
|
|
109
121
|
a { color: inherit; text-decoration: none; }
|
|
122
|
+
button { font-family: inherit; }
|
|
110
123
|
|
|
111
124
|
/* ===== LOADING SCREEN ===== */
|
|
112
125
|
#app-loading {
|
|
@@ -166,6 +179,18 @@ a { color: inherit; text-decoration: none; }
|
|
|
166
179
|
from { opacity: 0; transform: translateY(16px); }
|
|
167
180
|
to { opacity: 1; transform: translateY(0); }
|
|
168
181
|
}
|
|
182
|
+
@keyframes cardEnter {
|
|
183
|
+
from { opacity: 0; transform: translateY(12px); }
|
|
184
|
+
to { opacity: 1; transform: translateY(0); }
|
|
185
|
+
}
|
|
186
|
+
@keyframes fadeIn {
|
|
187
|
+
from { opacity: 0; }
|
|
188
|
+
to { opacity: 1; }
|
|
189
|
+
}
|
|
190
|
+
@keyframes scaleIn {
|
|
191
|
+
from { opacity: 0; transform: scale(0.92); }
|
|
192
|
+
to { opacity: 1; transform: scale(1); }
|
|
193
|
+
}
|
|
169
194
|
|
|
170
195
|
/* ===== RESPONSIVE ===== */
|
|
171
196
|
@media (max-width: 768px) {
|
|
@@ -5,6 +5,7 @@ import { useReadingMode } from '../composables/useReadingMode'
|
|
|
5
5
|
import { useHorizontalScroll } from '../composables/useHorizontalScroll'
|
|
6
6
|
import SideNav from '../components/SideNav.vue'
|
|
7
7
|
import ReadingToolbar from '../components/ReadingToolbar.vue'
|
|
8
|
+
import BackToTop from '../components/BackToTop.vue'
|
|
8
9
|
import { useSiteConfig } from '../composables/useSiteConfig'
|
|
9
10
|
import { ref, computed } from 'vue'
|
|
10
11
|
import { useRouter } from 'vue-router'
|
|
@@ -63,6 +64,7 @@ function goHome() { router.push('/') }
|
|
|
63
64
|
<p>Hanology is a digital library for classical Chinese texts. We believe that the wisdom of antiquity should not be locked behind impenetrable editions or forgotten in dusty shelves. By combining rigorous scholarship with thoughtful design, we make the classics accessible, beautiful, and alive for every reader.</p>
|
|
64
65
|
</div>
|
|
65
66
|
</div>
|
|
67
|
+
<BackToTop />
|
|
66
68
|
<ReadingToolbar />
|
|
67
69
|
</div>
|
|
68
70
|
</template>
|
|
@@ -8,6 +8,7 @@ import { useHorizontalScroll } from '../composables/useHorizontalScroll'
|
|
|
8
8
|
import PoemCard from '../components/PoemCard.vue'
|
|
9
9
|
import SideNav from '../components/SideNav.vue'
|
|
10
10
|
import ReadingToolbar from '../components/ReadingToolbar.vue'
|
|
11
|
+
import BackToTop from '../components/BackToTop.vue'
|
|
11
12
|
|
|
12
13
|
const props = defineProps<{ bookId: string }>()
|
|
13
14
|
const router = useRouter()
|
|
@@ -128,14 +129,17 @@ function scrollToCatalog() {
|
|
|
128
129
|
</div>
|
|
129
130
|
<div class="h-grid">
|
|
130
131
|
<PoemCard
|
|
131
|
-
v-for="piece in filtered"
|
|
132
|
+
v-for="(piece, idx) in filtered"
|
|
132
133
|
:key="piece.num"
|
|
133
134
|
:poem="piece"
|
|
135
|
+
:style="{ animationDelay: Math.min(idx * 0.04, 0.8) + 's' }"
|
|
136
|
+
class="h-card-anim"
|
|
134
137
|
@click="openPiece(piece.num)"
|
|
135
138
|
/>
|
|
136
139
|
</div>
|
|
137
140
|
</section>
|
|
138
141
|
|
|
142
|
+
<BackToTop />
|
|
139
143
|
<ReadingToolbar />
|
|
140
144
|
</div>
|
|
141
145
|
</template>
|
|
@@ -359,6 +363,9 @@ function scrollToCatalog() {
|
|
|
359
363
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
|
360
364
|
gap: 16px;
|
|
361
365
|
}
|
|
366
|
+
.h-card-anim {
|
|
367
|
+
animation: cardEnter 0.4s var(--ease-out-expo) both;
|
|
368
|
+
}
|
|
362
369
|
|
|
363
370
|
@media (max-width: 768px) {
|
|
364
371
|
.h-stats { gap: 24px; }
|
|
@@ -9,6 +9,7 @@ import { useHorizontalScroll } from '../composables/useHorizontalScroll'
|
|
|
9
9
|
import BookCard from '../components/BookCard.vue'
|
|
10
10
|
import SideNav from '../components/SideNav.vue'
|
|
11
11
|
import ReadingToolbar from '../components/ReadingToolbar.vue'
|
|
12
|
+
import BackToTop from '../components/BackToTop.vue'
|
|
12
13
|
import { useSiteConfig } from '../composables/useSiteConfig'
|
|
13
14
|
import type { BookMeta } from '../types'
|
|
14
15
|
|
|
@@ -127,7 +128,7 @@ function openBook(bookId: string) {
|
|
|
127
128
|
<div
|
|
128
129
|
v-for="(book, bi) in group.books"
|
|
129
130
|
:key="book.id"
|
|
130
|
-
class="lib-card"
|
|
131
|
+
class="lib-card lib-card-anim"
|
|
131
132
|
:style="{ animationDelay: bi * 0.06 + 's' }"
|
|
132
133
|
@click="openBook(book.id)"
|
|
133
134
|
>
|
|
@@ -146,6 +147,7 @@ function openBook(bookId: string) {
|
|
|
146
147
|
</div>
|
|
147
148
|
</div>
|
|
148
149
|
<ReadingToolbar />
|
|
150
|
+
<BackToTop />
|
|
149
151
|
</div>
|
|
150
152
|
</div>
|
|
151
153
|
</template>
|
|
@@ -385,6 +387,10 @@ function openBook(bookId: string) {
|
|
|
385
387
|
gap: 12px;
|
|
386
388
|
}
|
|
387
389
|
|
|
390
|
+
.lib-card-anim {
|
|
391
|
+
animation: cardEnter 0.4s var(--ease-out-expo) both;
|
|
392
|
+
}
|
|
393
|
+
|
|
388
394
|
.lib-card {
|
|
389
395
|
display: flex;
|
|
390
396
|
flex-direction: column;
|
|
@@ -15,6 +15,7 @@ import AnnotationControlBar from '../components/AnnotationControlBar.vue'
|
|
|
15
15
|
import SideNav from '../components/SideNav.vue'
|
|
16
16
|
import PartGroup from '../components/PartGroup.vue'
|
|
17
17
|
import ReadingProgress from '../components/ReadingProgress.vue'
|
|
18
|
+
import BackToTop from '../components/BackToTop.vue'
|
|
18
19
|
import type { Piece, Annotation, AnnotationLayer, Part } from '../types'
|
|
19
20
|
|
|
20
21
|
const props = defineProps<{ bookId: string; num: string | number }>()
|
|
@@ -387,19 +388,21 @@ function tcy(n: number): string {
|
|
|
387
388
|
/>
|
|
388
389
|
|
|
389
390
|
<Teleport to="body">
|
|
390
|
-
<
|
|
391
|
-
<div class="v-
|
|
392
|
-
<
|
|
393
|
-
|
|
394
|
-
<div class="v-pane-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
<div v-
|
|
398
|
-
|
|
391
|
+
<Transition name="overlay">
|
|
392
|
+
<div v-if="authorPaneOpen" class="v-overlay" @click="closeAuthorPane">
|
|
393
|
+
<div class="v-author-pane" @click.stop>
|
|
394
|
+
<button class="v-pane-close" @click="closeAuthorPane">✕</button>
|
|
395
|
+
<div class="v-pane-header">
|
|
396
|
+
<div class="v-pane-name">{{ selectedAuthorName }}</div>
|
|
397
|
+
</div>
|
|
398
|
+
<div v-if="selectedAuthorBio" class="v-pane-bio">
|
|
399
|
+
<div v-for="p in selectedAuthorBio.split('\n').filter(l => l.trim())" :key="p" class="v-pane-p">
|
|
400
|
+
{{ p.trim() }}
|
|
401
|
+
</div>
|
|
399
402
|
</div>
|
|
400
403
|
</div>
|
|
401
404
|
</div>
|
|
402
|
-
</
|
|
405
|
+
</Transition>
|
|
403
406
|
</Teleport>
|
|
404
407
|
</div>
|
|
405
408
|
|
|
@@ -530,23 +533,27 @@ function tcy(n: number): string {
|
|
|
530
533
|
@tooltip-leave="interaction.onTooltipLeave"
|
|
531
534
|
/>
|
|
532
535
|
|
|
536
|
+
<BackToTop />
|
|
537
|
+
|
|
533
538
|
<Teleport to="body">
|
|
534
|
-
<
|
|
535
|
-
<div class="h-
|
|
536
|
-
<
|
|
537
|
-
|
|
538
|
-
<div>
|
|
539
|
-
<div
|
|
540
|
-
|
|
539
|
+
<Transition name="overlay">
|
|
540
|
+
<div v-if="authorPaneOpen" class="h-overlay" @click="closeAuthorPane">
|
|
541
|
+
<div class="h-pane" @click.stop>
|
|
542
|
+
<button class="h-pane-close" @click="closeAuthorPane">✕</button>
|
|
543
|
+
<div class="h-pane-header">
|
|
544
|
+
<div>
|
|
545
|
+
<div class="h-pane-name">{{ selectedAuthorName }}</div>
|
|
546
|
+
<div class="h-pane-meta">{{ piece.title }} 等</div>
|
|
547
|
+
</div>
|
|
541
548
|
</div>
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
549
|
+
<div v-if="selectedAuthorBio" class="h-pane-bio">
|
|
550
|
+
<div v-for="p in selectedAuthorBio.split('\n').filter(l => l.trim())" :key="p" class="h-pane-p">
|
|
551
|
+
{{ p.trim() }}
|
|
552
|
+
</div>
|
|
546
553
|
</div>
|
|
547
554
|
</div>
|
|
548
555
|
</div>
|
|
549
|
-
</
|
|
556
|
+
</Transition>
|
|
550
557
|
</Teleport>
|
|
551
558
|
</div>
|
|
552
559
|
</div>
|
|
@@ -791,40 +798,63 @@ function tcy(n: number): string {
|
|
|
791
798
|
.h-nav-bottom {
|
|
792
799
|
max-width: min(680px, calc(100vw - 80px));
|
|
793
800
|
margin: 0 auto 60px;
|
|
794
|
-
display:
|
|
801
|
+
display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
|
|
795
802
|
}
|
|
796
803
|
.h-nav-btn {
|
|
797
|
-
|
|
804
|
+
padding: 20px 24px;
|
|
798
805
|
background: var(--surface); border: 1px solid var(--border-light);
|
|
799
806
|
border-radius: 8px; cursor: pointer;
|
|
800
|
-
transition: all 0.
|
|
807
|
+
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
808
|
+
font-family: var(--serif);
|
|
801
809
|
text-align: left;
|
|
810
|
+
position: relative;
|
|
811
|
+
overflow: hidden;
|
|
812
|
+
}
|
|
813
|
+
.h-nav-btn::after {
|
|
814
|
+
content: '';
|
|
815
|
+
position: absolute;
|
|
816
|
+
bottom: 0; left: 0; right: 0;
|
|
817
|
+
height: 2px;
|
|
818
|
+
background: var(--vermillion);
|
|
819
|
+
transform: scaleX(0);
|
|
820
|
+
transition: transform 0.3s ease;
|
|
821
|
+
}
|
|
822
|
+
.h-nav-btn:hover {
|
|
823
|
+
border-color: var(--gold);
|
|
824
|
+
box-shadow: 0 8px 32px rgba(var(--shadow-rgb), 0.1);
|
|
825
|
+
transform: translateY(-2px);
|
|
802
826
|
}
|
|
803
|
-
.h-nav-btn:hover {
|
|
827
|
+
.h-nav-btn:hover::after { transform: scaleX(1); }
|
|
804
828
|
.h-nav-btn.h-nav-next { text-align: right; }
|
|
805
829
|
.h-nav-label { font-size: 11px; color: var(--ink-faint); font-family: var(--sans); letter-spacing: 2px; margin-bottom: 4px; }
|
|
806
830
|
.h-nav-title { font-size: 16px; font-weight: 600; letter-spacing: 1px; color: var(--ink); }
|
|
807
831
|
|
|
808
832
|
.h-overlay {
|
|
809
833
|
position: fixed; inset: 0;
|
|
810
|
-
background: rgba(var(--shadow-rgb), 0.
|
|
811
|
-
backdrop-filter: blur(
|
|
812
|
-
-webkit-backdrop-filter: blur(
|
|
834
|
+
background: rgba(var(--shadow-rgb), 0.24);
|
|
835
|
+
backdrop-filter: blur(12px);
|
|
836
|
+
-webkit-backdrop-filter: blur(12px);
|
|
813
837
|
z-index: 200;
|
|
814
838
|
display: flex; justify-content: flex-end;
|
|
815
|
-
animation: fadeIn 0.2s ease;
|
|
816
839
|
}
|
|
817
|
-
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
818
840
|
.h-pane {
|
|
819
841
|
width: min(420px, 90vw);
|
|
820
842
|
height: 100vh;
|
|
821
843
|
background: var(--paper);
|
|
822
844
|
padding: 32px;
|
|
823
845
|
overflow-y: auto;
|
|
824
|
-
animation: slideIn 0.25s ease;
|
|
825
846
|
box-shadow: -8px 0 32px rgba(var(--shadow-rgb), 0.1);
|
|
826
847
|
}
|
|
827
|
-
|
|
848
|
+
|
|
849
|
+
/* Overlay transition */
|
|
850
|
+
.overlay-enter-active { transition: opacity var(--dur-mid, 0.25s) ease; }
|
|
851
|
+
.overlay-enter-active .h-pane { transition: transform var(--dur-mid, 0.25s) cubic-bezier(0.34, 1.56, 0.64, 1); }
|
|
852
|
+
.overlay-leave-active { transition: opacity var(--dur-fast, 0.15s) ease; }
|
|
853
|
+
.overlay-leave-active .h-pane { transition: transform var(--dur-fast, 0.15s) ease; }
|
|
854
|
+
.overlay-enter-from { opacity: 0; }
|
|
855
|
+
.overlay-enter-from .h-pane { transform: translateX(100%); }
|
|
856
|
+
.overlay-leave-to { opacity: 0; }
|
|
857
|
+
.overlay-leave-to .h-pane { transform: translateX(40px); }
|
|
828
858
|
.h-pane-close {
|
|
829
859
|
display: block; margin-left: auto;
|
|
830
860
|
width: 36px; height: 36px;
|
|
@@ -856,12 +886,11 @@ function tcy(n: number): string {
|
|
|
856
886
|
|
|
857
887
|
.v-overlay {
|
|
858
888
|
position: fixed; inset: 0;
|
|
859
|
-
background: rgba(var(--shadow-rgb), 0.
|
|
860
|
-
backdrop-filter: blur(
|
|
861
|
-
-webkit-backdrop-filter: blur(
|
|
889
|
+
background: rgba(var(--shadow-rgb), 0.24);
|
|
890
|
+
backdrop-filter: blur(12px);
|
|
891
|
+
-webkit-backdrop-filter: blur(12px);
|
|
862
892
|
z-index: 200;
|
|
863
893
|
display: flex; justify-content: flex-start;
|
|
864
|
-
animation: fadeIn 0.2s ease;
|
|
865
894
|
}
|
|
866
895
|
.v-author-pane {
|
|
867
896
|
writing-mode: vertical-rl;
|
|
@@ -871,9 +900,7 @@ function tcy(n: number): string {
|
|
|
871
900
|
padding: 32px 24px;
|
|
872
901
|
overflow-x: auto;
|
|
873
902
|
box-shadow: 8px 0 32px rgba(var(--shadow-rgb), 0.1);
|
|
874
|
-
animation: slideInV 0.25s ease;
|
|
875
903
|
}
|
|
876
|
-
@keyframes slideInV { from { transform: translateX(-100%); } to { transform: translateX(0); } }
|
|
877
904
|
.v-pane-close {
|
|
878
905
|
display: block;
|
|
879
906
|
width: 32px; height: 32px;
|