dsh-tingdong 0.5.2 → 0.7.0

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/web/panel.css CHANGED
@@ -1,345 +1,344 @@
1
+ /* 听懂的学习面板。紧凑的工具界面:13px 正文、小圆角、行式列表,常驻在 DSH 的右侧栏(约 420px 宽)里也不挤。
2
+ 尺寸只对触屏放大(pointer: coarse),不按宽度——侧栏很窄,但用的是鼠标。 */
1
3
  :root {
2
- --bg: #f7f6f3;
4
+ --bg: #f6f6f4;
3
5
  --card: #ffffff;
4
- --text: #1d1d1f;
5
- --sub: #6b6b70;
6
- --faint: #9a9aa0;
7
- --line: rgba(0, 0, 0, .09);
6
+ --hover: rgba(0, 0, 0, .035);
7
+ --text: #1c1c1e;
8
+ --sub: #66666c;
9
+ --faint: #98989f;
10
+ --line: rgba(0, 0, 0, .085);
8
11
  --accent: #2f6bff;
9
- --accent-soft: rgba(47, 107, 255, .1);
12
+ --accent-soft: rgba(47, 107, 255, .09);
10
13
  --good: #1f9d55;
11
- --mid: #c98a12;
14
+ --mid: #b97d0c;
12
15
  --bad: #d14343;
13
- --mark: rgba(255, 196, 0, .32);
14
- --radius: 12px;
16
+ --mark: rgba(255, 196, 0, .3);
17
+ --radius: 8px;
18
+ --top-h: 37px;
15
19
  color-scheme: light;
16
20
  }
17
21
  @media (prefers-color-scheme: dark) {
18
22
  :root:not([data-theme="light"]) {
19
- --bg: #17171a;
20
- --card: #222226;
21
- --text: #ececef;
22
- --sub: #a2a2a8;
23
- --faint: #75757c;
24
- --line: rgba(255, 255, 255, .1);
25
- --accent: #6c95ff;
26
- --accent-soft: rgba(108, 149, 255, .16);
27
- --good: #3cc47c;
28
- --mid: #e0a73a;
29
- --bad: #ef6b6b;
30
- --mark: rgba(255, 196, 0, .25);
31
- color-scheme: dark;
23
+ --bg: #18181b; --card: #212124; --hover: rgba(255, 255, 255, .045); --text: #e9e9ec; --sub: #a0a0a7; --faint: #6f6f77;
24
+ --line: rgba(255, 255, 255, .09); --accent: #7098ff; --accent-soft: rgba(112, 152, 255, .14);
25
+ --good: #3cc47c; --mid: #e0a73a; --bad: #ef6b6b; --mark: rgba(255, 196, 0, .22); color-scheme: dark;
32
26
  }
33
27
  }
34
28
  :root[data-theme="dark"] {
35
- --bg: #17171a; --card: #222226; --text: #ececef; --sub: #a2a2a8; --faint: #75757c;
36
- --line: rgba(255, 255, 255, .1); --accent: #6c95ff; --accent-soft: rgba(108, 149, 255, .16);
37
- --good: #3cc47c; --mid: #e0a73a; --bad: #ef6b6b; --mark: rgba(255, 196, 0, .25); color-scheme: dark;
29
+ --bg: #18181b; --card: #212124; --hover: rgba(255, 255, 255, .045); --text: #e9e9ec; --sub: #a0a0a7; --faint: #6f6f77;
30
+ --line: rgba(255, 255, 255, .09); --accent: #7098ff; --accent-soft: rgba(112, 152, 255, .14);
31
+ --good: #3cc47c; --mid: #e0a73a; --bad: #ef6b6b; --mark: rgba(255, 196, 0, .22); color-scheme: dark;
38
32
  }
39
33
 
40
34
  * { box-sizing: border-box; }
41
35
  html, body { margin: 0; }
42
36
  body {
43
- background: var(--bg);
44
- color: var(--text);
45
- font: 14px/1.6 -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", sans-serif;
37
+ background: var(--bg); color: var(--text);
38
+ font: 13px/1.5 -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", sans-serif;
46
39
  -webkit-font-smoothing: antialiased;
47
40
  }
48
- button { font: inherit; color: inherit; }
41
+ button, select, input, textarea { font: inherit; color: inherit; }
49
42
  [hidden] { display: none !important; }
43
+ svg.ico { width: 16px; height: 16px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
50
44
 
45
+ /* —— 顶栏 —— */
51
46
  .top {
52
- position: sticky; top: 0; z-index: 5;
53
- display: flex; align-items: center; gap: 8px;
54
- padding: 10px 16px; background: var(--bg);
55
- border-bottom: 1px solid var(--line);
47
+ position: sticky; top: 0; z-index: 5; height: var(--top-h);
48
+ display: flex; align-items: center; gap: 6px; padding: 0 12px;
49
+ background: var(--bg); border-bottom: 1px solid var(--line);
56
50
  }
57
- .brand { font-weight: 650; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
51
+ .brand { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
58
52
  .spacer { flex: 1; }
59
- .link { color: var(--accent); text-decoration: none; font-size: 12px; white-space: nowrap; }
60
- .icon-btn {
61
- appearance: none; border: 0; background: transparent; cursor: pointer;
62
- font-size: 24px; line-height: 1; padding: 0 6px 2px; color: var(--sub);
63
- }
53
+ .link { color: var(--accent); text-decoration: none; font-size: 12px; white-space: nowrap; cursor: pointer; }
54
+ .link:hover { text-decoration: underline; }
55
+ .icon-btn { appearance: none; border: 0; background: transparent; cursor: pointer; font-size: 18px; line-height: 1; padding: 2px 6px; color: var(--sub); border-radius: 6px; }
56
+ .icon-btn:hover { background: var(--hover); color: var(--text); }
57
+ .manage { display: inline-flex; align-items: center; gap: 6px; margin-left: 2px; }
58
+ .manage .ver { font-variant-numeric: tabular-nums; }
64
59
 
65
- main { padding: 14px 16px 40px; max-width: 760px; margin: 0 auto; }
60
+ main { padding: 10px 12px 32px; max-width: 720px; margin: 0 auto; }
66
61
 
67
- .card {
68
- background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
69
- padding: 14px; margin-bottom: 12px;
70
- }
71
- .card h3 { margin: 0 0 8px; font-size: 14px; }
62
+ /* —— 基础件 —— */
63
+ .card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; }
64
+ .card h3 { margin: 0 0 6px; font-size: 13px; font-weight: 600; }
72
65
  .muted { color: var(--sub); }
73
66
  .faint { color: var(--faint); font-size: 12px; }
74
67
  .small { font-size: 12px; }
75
- .row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
68
+ .row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
69
+ .row.nowrap { flex-wrap: nowrap; }
76
70
  .grow { flex: 1 1 auto; min-width: 0; }
71
+ .ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
72
+ .section-title { font-size: 12px; font-weight: 600; color: var(--sub); margin: 14px 2px 6px; display: flex; align-items: center; gap: 6px; }
73
+ .section-title .n { font-weight: 400; color: var(--faint); }
74
+ .empty { text-align: center; padding: 22px 10px; color: var(--sub); }
77
75
 
78
76
  .btn {
79
- appearance: none; cursor: pointer; white-space: nowrap;
77
+ appearance: none; cursor: pointer; white-space: nowrap; text-decoration: none; display: inline-flex; align-items: center; gap: 4px;
80
78
  border: 1px solid var(--line); background: var(--card); color: var(--text);
81
- border-radius: 8px; padding: 6px 12px; font-size: 13px; line-height: 20px;
79
+ border-radius: 6px; padding: 3px 10px; font-size: 12.5px; line-height: 20px;
82
80
  }
83
81
  .btn:hover { border-color: var(--accent); }
84
- .btn:disabled { opacity: .5; cursor: default; }
82
+ .btn:disabled { opacity: .5; cursor: default; border-color: var(--line); }
85
83
  .btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
84
+ .btn.primary:hover { filter: brightness(1.06); }
86
85
  .btn.ghost { background: transparent; }
87
86
  .btn.danger { color: var(--bad); }
88
- .btn.big { padding: 10px 16px; font-size: 15px; border-radius: 10px; }
87
+ .btn.big { padding: 5px 14px; font-size: 13px; font-weight: 500; }
88
+ .btn.small { padding: 1px 8px; font-size: 12px; line-height: 18px; }
89
89
  .btn.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
90
- .btn kbd { font: 11px ui-monospace, SFMono-Regular, Menlo, monospace; opacity: .55; margin-left: 4px; }
90
+ .btn kbd { font: 10px ui-monospace, SFMono-Regular, Menlo, monospace; opacity: .5; }
91
91
 
92
- input[type=text] {
93
- width: 100%; font: inherit; color: var(--text); background: var(--bg);
94
- border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; outline: none;
92
+ input[type=text], textarea, select {
93
+ color: var(--text); background: var(--bg); border: 1px solid var(--line); border-radius: 6px; outline: none; max-width: 100%;
95
94
  }
96
- input[type=text]:focus { border-color: var(--accent); }
97
-
98
- .drop { border: 1.5px dashed var(--line); border-radius: var(--radius); padding: 14px; text-align: center; }
99
- .drop.over { border-color: var(--accent); background: var(--accent-soft); }
95
+ input[type=text] { width: 100%; padding: 4px 8px; }
96
+ textarea { width: 100%; padding: 6px 8px; resize: vertical; }
97
+ select { padding: 3px 6px; font-size: 12.5px; background: var(--card); }
98
+ input[type=text]:focus, textarea:focus, select:focus { border-color: var(--accent); }
100
99
 
101
- .bar { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
102
- .bar > i { display: block; height: 100%; background: var(--accent); border-radius: 3px; transition: width .3s; }
100
+ .bar { height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; }
101
+ .bar > i { display: block; height: 100%; background: var(--accent); border-radius: 2px; transition: width .3s; }
103
102
  .bar.good > i { background: var(--good); }
103
+ .bar.two { position: relative; }
104
+ .bar.two > i { position: absolute; left: 0; top: 0; }
105
+ .bar.two > i.seen { background: var(--accent-soft); filter: saturate(2); }
106
+ .bar.two > i:not(.seen) { background: var(--good); }
104
107
 
105
- .badge { display: inline-block; font-size: 11px; line-height: 18px; padding: 0 7px; border-radius: 9px; background: var(--accent-soft); color: var(--accent); white-space: nowrap; }
106
- .badge.warn { background: rgba(201, 138, 18, .14); color: var(--mid); }
108
+ .badge { display: inline-block; font-size: 11px; line-height: 16px; padding: 0 6px; border-radius: 8px; background: var(--accent-soft); color: var(--accent); white-space: nowrap; }
109
+ .badge.warn { background: rgba(201, 138, 18, .13); color: var(--mid); }
107
110
  .badge.err { background: rgba(209, 67, 67, .12); color: var(--bad); }
108
111
  .badge.ok { background: rgba(31, 157, 85, .12); color: var(--good); }
109
112
 
110
- .group-title { font-size: 12px; color: var(--sub); margin: 18px 2px 8px; font-weight: 600; }
111
- .lesson { cursor: pointer; }
112
- .lesson:hover { border-color: var(--accent); }
113
- .lesson .t { font-weight: 600; }
114
- .lesson .en { font-size: 12px; color: var(--sub); overflow-wrap: anywhere; }
113
+ .chips { display: flex; gap: 4px; flex-wrap: wrap; margin: 0 0 8px; }
114
+ .chip {
115
+ appearance: none; cursor: pointer; border: 1px solid var(--line); background: transparent; color: var(--sub);
116
+ border-radius: 6px; padding: 1px 9px; font-size: 12px; line-height: 20px;
117
+ }
118
+ .chip:hover { color: var(--text); }
119
+ .chip.on { background: var(--accent-soft); border-color: transparent; color: var(--accent); font-weight: 600; }
120
+ .form { display: grid; grid-template-columns: auto 1fr; gap: 6px 10px; align-items: center; margin-top: 8px; }
121
+ .form label { font-size: 12px; color: var(--sub); white-space: nowrap; }
122
+ .form .chips { margin: 0; }
115
123
 
116
- .tabs { display: flex; gap: 4px; margin: 0 0 12px; overflow-x: auto; scrollbar-width: none; }
124
+ .drop { border: 1px dashed var(--line); border-radius: var(--radius); padding: 10px 12px; text-align: center; }
125
+ .drop.over { border-color: var(--accent); background: var(--accent-soft); }
126
+
127
+ .toast {
128
+ position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 30;
129
+ background: var(--text); color: var(--bg); padding: 6px 12px; border-radius: 6px; font-size: 12.5px; max-width: calc(100% - 24px);
130
+ }
131
+ code.cmd { font: 12px ui-monospace, SFMono-Regular, Menlo, monospace; padding: 4px 8px; border: 1px solid var(--line); border-radius: 6px; user-select: all; overflow-wrap: anywhere; }
132
+ .prompt { white-space: pre-wrap; font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; background: var(--bg); border-radius: 6px; padding: 6px 8px; margin: 6px 0 0; color: var(--sub); max-height: 180px; overflow: auto; }
133
+ details > summary { cursor: pointer; list-style: none; }
134
+ details > summary::-webkit-details-marker { display: none; }
135
+
136
+ /* —— 首页:今日一行 —— */
137
+ .today { display: flex; align-items: center; gap: 10px; padding: 8px 10px 8px 12px; }
138
+ .today .t { font-weight: 600; }
139
+ .today .t b { color: var(--accent); font-variant-numeric: tabular-nums; }
140
+ .spark { display: flex; align-items: flex-end; gap: 2px; height: 18px; }
141
+ .spark i { width: 4px; min-height: 2px; background: var(--line); border-radius: 1px; }
142
+ .spark i.has { background: var(--accent); opacity: .55; }
143
+ .spark i.now { opacity: 1; }
144
+
145
+ /* —— 首页:能做什么(两条流程,点了展开导入) —— */
146
+ .flows { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
147
+ .flow {
148
+ appearance: none; width: 100%; text-align: left; cursor: pointer; border: 0; background: transparent;
149
+ display: flex; align-items: center; gap: 10px; padding: 8px 10px 8px 12px;
150
+ }
151
+ .flow + .flow { border-top: 1px solid var(--line); }
152
+ .flow:hover, .flow.on { background: var(--hover); }
153
+ .flow > .ico { color: var(--accent); width: 18px; height: 18px; }
154
+ .flow-line { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; font-weight: 600; }
155
+ .flow-line .arr { color: var(--faint); font-weight: 400; }
156
+ .flow-line .out { font-weight: 500; color: var(--text); }
157
+ .flow .grow > .faint { display: block; }
158
+ .flow .cta { color: var(--accent); font-size: 12px; white-space: nowrap; }
159
+ .flow.on .cta { font-weight: 600; }
160
+ #newPanel .card { margin: 8px 0 0; }
161
+ #jobs:not(:empty) { margin-top: 8px; }
162
+ .job + .job { margin-top: 6px; }
163
+ .job .bar { margin-top: 3px; }
164
+ #lessonJob:not(:empty) { margin-bottom: 8px; }
165
+ .manage-row { margin: 10px 2px 0; }
166
+ details.card > .steps { margin-top: 8px; }
167
+ details.card[open] > summary .faint { display: none; }
168
+
169
+ /* —— 首页:课程列表(一行一课) —— */
170
+ .list { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin-bottom: 8px; }
171
+ .list-head { display: flex; align-items: center; gap: 8px; padding: 5px 12px; font-size: 12px; color: var(--sub); background: var(--hover); }
172
+ .list-head b { font-weight: 600; }
173
+ .lrow { display: flex; align-items: center; gap: 10px; padding: 7px 10px 7px 12px; cursor: pointer; border-top: 1px solid var(--line); }
174
+ .lrow:hover { background: var(--hover); }
175
+ .lrow > .ico { color: var(--faint); }
176
+ .lrow.doc > .ico { color: var(--mid); }
177
+ .lrow .t { font-weight: 500; }
178
+ .lrow .m { font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
179
+ .lrow .prog { width: 44px; flex: none; }
180
+ .lrow .chev { color: var(--faint); font-size: 14px; }
181
+ .lrow .err { color: var(--bad); font-size: 11.5px; }
182
+
183
+ /* —— 课程页:页签、声音条 —— */
184
+ .tabs { display: flex; gap: 2px; margin: -2px 0 10px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--line); }
185
+ .tabs::-webkit-scrollbar { display: none; }
117
186
  .tab {
118
187
  appearance: none; border: 0; background: transparent; cursor: pointer; white-space: nowrap;
119
- padding: 6px 12px; border-radius: 8px; color: var(--sub); font-size: 13px;
188
+ padding: 5px 9px 6px; color: var(--sub); font-size: 12.5px; border-bottom: 2px solid transparent; margin-bottom: -1px;
120
189
  }
121
- .tab.on { background: var(--card); color: var(--text); font-weight: 600; box-shadow: 0 0 0 1px var(--line); }
190
+ .tab:hover { color: var(--text); }
191
+ .tab.on { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }
192
+ .voicebar { margin: -2px 0 8px; flex-wrap: nowrap; }
193
+ .voicebar select { flex: 1 1 auto; min-width: 0; }
194
+
195
+ /* —— 概览 —— */
196
+ .lesson-head .title { font-size: 15px; font-weight: 600; line-height: 1.35; }
197
+ .summary { white-space: pre-wrap; color: var(--sub); margin: 6px 0 0; }
198
+ .summary.clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
199
+ .statline { display: flex; gap: 12px; flex-wrap: wrap; font-size: 12px; color: var(--sub); margin: 8px 0 5px; }
200
+ .statline b { color: var(--text); font-variant-numeric: tabular-nums; margin-right: 2px; }
201
+ .steps { padding-left: 18px; margin: 6px 0 0; color: var(--sub); font-size: 12.5px; }
202
+ .steps li { margin: 2px 0; }
203
+ .track { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 6px 0; border-top: 1px solid var(--line); }
204
+ .track > .grow { flex: 1 1 0; }
205
+ .track .name { font-weight: 500; }
206
+ .track.on .name { color: var(--accent); font-weight: 600; }
207
+ .track .opts { flex-basis: 100%; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
208
+ .inst { padding: 6px 0; border-top: 1px solid var(--line); }
209
+ .stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; text-align: center; margin: 4px 0 8px; }
210
+ .stat-grid b { display: block; font-size: 16px; font-variant-numeric: tabular-nums; }
211
+ .stat-grid span { font-size: 11px; color: var(--sub); }
122
212
 
123
- /* —— 学习卡片 —— */
124
- .study { text-align: center; padding: 18px 14px; }
125
- .pos { font-size: 12px; color: var(--faint); margin-bottom: 10px; display: flex; justify-content: space-between; }
213
+ /* —— 学习卡片(精听 / 复习 / 磨耳朵) —— */
214
+ .study { text-align: center; padding: 10px 12px 12px; }
215
+ .pos { font-size: 11.5px; color: var(--faint); margin-bottom: 4px; display: flex; justify-content: space-between; align-items: center; }
126
216
  .play {
127
- width: 76px; height: 76px; border-radius: 50%; border: 0; cursor: pointer;
128
- background: var(--accent); color: #fff; font-size: 30px; margin: 6px auto 4px; display: grid; place-items: center;
217
+ width: 52px; height: 52px; border-radius: 50%; border: 0; cursor: pointer;
218
+ background: var(--accent); color: #fff; font-size: 20px; margin: 2px auto 2px; display: grid; place-items: center; padding-left: 3px;
129
219
  }
130
220
  .play.playing { animation: pulse 1.2s ease-in-out infinite; }
131
- @keyframes pulse { 50% { box-shadow: 0 0 0 10px var(--accent-soft); } }
132
- .hint { color: var(--sub); font-size: 13px; margin: 8px 0 14px; }
133
- .en-line { font-size: 19px; line-height: 1.55; font-weight: 500; margin: 12px 0 6px; overflow-wrap: anywhere; }
134
- .en-line mark { background: var(--mark); color: inherit; border-radius: 3px; padding: 0 1px; }
135
- .zh-line { font-size: 16px; margin: 6px 0 10px; }
136
- .asr { font-size: 12px; color: var(--faint); margin-top: -2px; }
137
- .tip { text-align: left; font-size: 13px; background: var(--bg); border-radius: 8px; padding: 8px 10px; margin: 10px 0; }
221
+ @keyframes pulse { 50% { box-shadow: 0 0 0 7px var(--accent-soft); } }
222
+ .controls { display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; margin: 8px 0 2px; }
223
+ .hint { color: var(--sub); font-size: 12.5px; margin: 6px 0 10px; }
224
+ .en-line { font-size: 17px; line-height: 1.5; font-weight: 500; margin: 10px 0 4px; overflow-wrap: anywhere; }
225
+ .en-line .w { cursor: pointer; border-radius: 3px; }
226
+ .en-line .w:hover { background: var(--accent-soft); }
227
+ .en-line .w.hl { background: var(--mark); }
228
+ .zh-line { font-size: 14px; margin: 4px 0 8px; }
229
+ .asr { font-size: 11.5px; color: var(--faint); }
230
+ .tap-hint { font-size: 11px; }
231
+ .tip { text-align: left; font-size: 12.5px; background: var(--bg); border-radius: 6px; padding: 5px 8px; margin: 8px 0; }
138
232
  .tip b { color: var(--mid); font-weight: 600; }
139
- .words { text-align: left; margin: 10px 0 4px; }
140
- .word { display: flex; gap: 8px; align-items: baseline; padding: 5px 0; border-top: 1px solid var(--line); flex-wrap: wrap; }
141
- .word .w { font-weight: 600; }
142
- .word .ipa { color: var(--faint); font-size: 12px; font-family: "Lucida Sans Unicode", "Arial Unicode MS", sans-serif; }
143
- .controls { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin: 12px 0 4px; }
144
- .grades { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 14px; }
145
- .grades .btn { padding: 10px 4px; font-size: 14px; }
233
+ .words { text-align: left; margin: 8px 0 2px; }
234
+ .word { display: flex; gap: 8px; align-items: baseline; padding: 3px 0; border-top: 1px solid var(--line); flex-wrap: wrap; }
235
+ .w0 { font-weight: 600; }
236
+ .word .ipa { color: var(--faint); font-size: 11.5px; font-family: "Lucida Sans Unicode", "Arial Unicode MS", sans-serif; }
237
+ .grades { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 10px; }
238
+ .grades .btn { justify-content: center; padding: 5px 4px; font-size: 13px; }
146
239
  .g0 { color: var(--bad); }
147
240
  .g1 { color: var(--mid); }
148
241
  .g2 { color: var(--good); }
149
- .nav { display: flex; justify-content: space-between; margin-top: 12px; }
150
- .dots { display: flex; flex-wrap: wrap; gap: 3px; margin: 10px 0 0; justify-content: center; }
151
- .dots i { width: 7px; height: 7px; border-radius: 2px; background: var(--line); cursor: pointer; }
242
+ .nav { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; }
243
+ .dots { display: flex; flex-wrap: wrap; gap: 2px; margin: 8px 0 0; justify-content: center; }
244
+ .dots i { width: 6px; height: 6px; border-radius: 1.5px; background: var(--line); cursor: pointer; }
152
245
  .dots i.s1 { background: var(--bad); }
153
246
  .dots i.s2 { background: var(--mid); }
154
247
  .dots i.s3 { background: var(--good); }
155
- .dots i.cur { outline: 2px solid var(--accent); outline-offset: 1px; }
248
+ .dots i.cur { outline: 1.5px solid var(--accent); outline-offset: 1px; }
249
+ .dots i.st { box-shadow: inset 0 -2px 0 var(--mid); }
250
+ .tools { display: inline-flex; gap: 0; }
251
+ .tools .icon-btn { font-size: 15px; padding: 1px 5px; }
252
+ .star.on { color: var(--mid); }
253
+ .swipe-hint { display: none; }
254
+ .speed { font-variant-numeric: tabular-nums; }
156
255
 
157
- /* —— 全文 —— */
158
- .sent { display: flex; gap: 10px; padding: 8px 6px; border-radius: 8px; cursor: pointer; }
159
- .sent:hover { background: var(--accent-soft); }
160
- .sent.cur { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
161
- .sent .tm { font: 11px ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--faint); padding-top: 3px; min-width: 38px; }
256
+ .choices { display: grid; gap: 6px; margin-top: 4px; }
257
+ .choice { text-align: left; white-space: normal; padding: 6px 10px; font-size: 13.5px; line-height: 1.5; justify-content: space-between; }
258
+ .verdict { font-weight: 600; margin-top: 8px; }
259
+ .verdict.ok { color: var(--good); }
260
+ .verdict.mid { color: var(--mid); }
261
+ .verdict.no { color: var(--bad); }
262
+ .dict-diff { font-size: 14.5px; margin: 4px 0; line-height: 1.8; }
263
+ .dict-diff .ok { color: var(--good); }
264
+ .dict-diff .miss { color: var(--bad); text-decoration: underline wavy; text-underline-offset: 4px; }
265
+ .study input[type=text] { font-size: 15px; padding: 7px 10px; }
266
+ .drill-text { min-height: 78px; display: flex; flex-direction: column; justify-content: center; }
267
+ .drill .en-line { font-size: 18px; }
268
+
269
+ /* —— 连续听、词汇 —— */
270
+ .sent { display: flex; gap: 8px; padding: 5px 6px; border-radius: 6px; cursor: pointer; }
271
+ .sent:hover { background: var(--hover); }
272
+ .sent.cur { background: var(--accent-soft); box-shadow: inset 2px 0 0 var(--accent); }
273
+ .sent .tm { font: 10.5px ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--faint); padding-top: 3px; min-width: 34px; }
162
274
  .sent .e { overflow-wrap: anywhere; }
163
- .sent .z { color: var(--sub); font-size: 13px; }
275
+ .sent .z { color: var(--sub); font-size: 12.5px; }
164
276
  .sent.hide-e .e, .sent.hide-z .z { display: none; }
165
277
  .sent .blank { color: var(--faint); font-size: 12px; }
166
- .sticky-ctl { position: sticky; top: 46px; z-index: 3; background: var(--bg); padding: 6px 0 8px; }
167
-
168
- .term { padding: 8px 0; border-top: 1px solid var(--line); }
278
+ .sticky-ctl { position: sticky; top: var(--top-h); z-index: 3; background: var(--bg); padding: 4px 0 6px; }
279
+ .term { padding: 5px 0; border-top: 1px solid var(--line); }
169
280
  .term:first-child { border-top: 0; }
170
- .term .w { font-weight: 600; }
171
- .summary { white-space: pre-wrap; }
172
- .steps { padding-left: 20px; margin: 6px 0 0; color: var(--sub); font-size: 13px; }
173
- .steps li { margin: 2px 0; }
174
- .stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; text-align: center; margin: 4px 0 10px; }
175
- .stat-grid b { display: block; font-size: 20px; font-variant-numeric: tabular-nums; }
176
- .stat-grid span { font-size: 11px; color: var(--sub); }
177
- .empty { text-align: center; padding: 30px 10px; color: var(--sub); }
178
- .toast {
179
- position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 9;
180
- background: var(--text); color: var(--bg); padding: 8px 14px; border-radius: 8px; font-size: 13px; max-width: calc(100% - 32px);
181
- }
182
- .speed { font-variant-numeric: tabular-nums; }
183
- @media (max-width: 380px) {
184
- .stat-grid { grid-template-columns: repeat(2, 1fr); }
185
- .en-line { font-size: 17px; }
186
- }
187
281
 
188
- /* —— 声音 —— */
189
- select {
190
- font: inherit; font-size: 13px; color: var(--text); background: var(--card);
191
- border: 1px solid var(--line); border-radius: 8px; padding: 5px 8px; max-width: 100%;
192
- }
193
- .voicebar { margin: -4px 0 12px; }
194
- .voicebar select { flex: 1 1 auto; min-width: 0; }
195
- .track { padding: 10px 0; border-top: 1px solid var(--line); }
196
- .track:first-of-type { border-top: 0; }
197
- .track.on b { color: var(--accent); }
198
- a.btn { text-decoration: none; display: inline-block; }
199
-
200
- /* —— 今日学习 —— */
201
- .today .big-num { font-size: 18px; font-weight: 600; }
202
- .today .big-num b { font-size: 26px; color: var(--accent); }
203
- .streak { text-align: center; min-width: 64px; }
204
- .streak b { display: block; font-size: 24px; color: var(--mid); font-variant-numeric: tabular-nums; }
205
- .streak span { font-size: 11px; color: var(--sub); }
206
- .week { display: flex; gap: 6px; align-items: flex-end; height: 54px; margin-top: 10px; }
207
- .week .day { flex: 1; display: flex; flex-direction: column; align-items: center; height: 100%; justify-content: flex-end; }
208
- .week .day i { width: 100%; max-width: 26px; min-height: 2px; background: var(--accent-soft); border-radius: 4px 4px 1px 1px; display: block; }
209
- .week .day.now i { background: var(--accent); }
210
- .week .day span { font-size: 10px; color: var(--faint); margin-top: 2px; }
211
- .bar.two { position: relative; }
212
- .bar.two > i { position: absolute; left: 0; top: 0; }
213
- .bar.two > i.seen { background: var(--accent-soft); }
214
- .bar.two > i:not(.seen) { background: var(--good); }
215
- .ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
216
- .inst { padding: 8px 0; border-top: 1px solid var(--line); }
217
-
218
- /* —— 选项小块 —— */
219
- .chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 10px; }
220
- .chip {
221
- appearance: none; cursor: pointer; border: 1px solid var(--line); background: var(--card); color: var(--sub);
222
- border-radius: 16px; padding: 3px 12px; font-size: 13px; line-height: 22px;
223
- }
224
- .chip.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600; }
225
- .form { display: grid; grid-template-columns: auto 1fr; gap: 6px 10px; align-items: start; margin-top: 12px; }
226
- .form label { font-size: 12px; color: var(--sub); padding-top: 5px; }
227
- .form .chips { margin: 0; }
228
-
229
- /* —— 卡片上的工具:收藏、编辑 —— */
230
- .pos { align-items: center; }
231
- .tools { display: inline-flex; gap: 2px; }
232
- .tools .icon-btn { font-size: 18px; padding: 0 6px; }
233
- .star.on { color: var(--mid); }
234
- .dots i.st { box-shadow: inset 0 -2px 0 var(--mid); }
235
-
236
- /* —— 可以点的英文词、查词弹层 —— */
237
- .en-line .w { cursor: pointer; border-radius: 3px; }
238
- .en-line .w:hover { background: var(--accent-soft); }
239
- .en-line .w.hl { background: var(--mark); }
240
- .tap-hint { margin-top: -2px; }
241
- .w0 { font-weight: 600; }
282
+ /* —— 查词弹层、编辑面板 —— */
242
283
  .pop {
243
- position: fixed; z-index: 20; background: var(--card); border: 1px solid var(--line); border-radius: 10px;
244
- padding: 10px 12px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 13px;
245
- }
246
-
247
- /* —— 编辑面板 —— */
248
- .sheet-wrap { position: fixed; inset: 0; z-index: 15; background: rgba(0, 0, 0, .35); display: flex; align-items: center; justify-content: center; padding: 16px; }
249
- .sheet { background: var(--card); border-radius: 14px; padding: 14px; width: 100%; max-width: 520px; max-height: 90vh; overflow: auto; }
250
- .sheet label { display: block; margin-top: 8px; }
251
- textarea {
252
- width: 100%; font: inherit; color: var(--text); background: var(--bg); border: 1px solid var(--line);
253
- border-radius: 8px; padding: 7px 10px; resize: vertical; outline: none;
284
+ position: fixed; z-index: 20; background: var(--card); border: 1px solid var(--line); border-radius: 8px;
285
+ padding: 8px 10px; box-shadow: 0 6px 20px rgba(0, 0, 0, .16); font-size: 12.5px;
254
286
  }
255
- textarea:focus { border-color: var(--accent); }
287
+ .sheet-wrap { position: fixed; inset: 0; z-index: 15; background: rgba(0, 0, 0, .35); display: flex; align-items: center; justify-content: center; padding: 12px; }
288
+ .sheet { background: var(--card); border-radius: 10px; padding: 12px; width: 100%; max-width: 480px; max-height: 90vh; overflow: auto; }
289
+ .sheet label { display: block; margin-top: 6px; }
256
290
  .split-words { display: flex; flex-wrap: wrap; gap: 4px; }
257
- .split-words .btn { padding: 3px 8px; }
258
291
 
259
- /* —— 复习:选意思、听写 —— */
260
- .choices { display: grid; gap: 8px; margin-top: 4px; }
261
- .choice { text-align: left; white-space: normal; padding: 10px 12px; font-size: 15px; line-height: 1.5; }
262
- .verdict { font-weight: 600; margin-top: 12px; }
263
- .verdict.ok { color: var(--good); }
264
- .verdict.mid { color: var(--mid); }
265
- .verdict.no { color: var(--bad); }
266
- .dict-diff { font-size: 16px; margin: 6px 0; line-height: 1.8; }
267
- .dict-diff .ok { color: var(--good); }
268
- .dict-diff .miss { color: var(--bad); text-decoration: underline wavy; text-underline-offset: 4px; }
269
- .study input[type=text] { font-size: 16px; padding: 10px 12px; }
270
-
271
- /* —— 磨耳朵 —— */
272
- .drill-text { min-height: 96px; display: flex; flex-direction: column; justify-content: center; }
273
- .drill .en-line { font-size: 20px; }
292
+ /* —— 导出 —— */
293
+ .pipe { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; color: var(--sub); margin-bottom: 8px; }
294
+ .pipe b { color: var(--text); font-weight: 600; }
295
+ .pipe .arr { color: var(--faint); }
296
+ .exp-h { display: flex; align-items: baseline; gap: 6px; margin: 0 0 4px; }
297
+ .exp-h .num { color: var(--accent); font-weight: 700; font-variant-numeric: tabular-nums; }
298
+ .exp-h b { font-weight: 600; }
299
+ .sub-h { font-size: 13px; font-weight: 600; margin: 4px 0 2px; }
300
+ .row.wrap { flex-wrap: wrap; }
274
301
 
275
- .swipe-hint { display: none; }
276
- @media (pointer: coarse) { .swipe-hint { display: inline; } }
302
+ /* —— 导入文档:确认 —— */
303
+ .doc-confirm .ai-note { margin: 8px 0; padding: 6px 10px; border-radius: 6px; background: var(--accent-soft); line-height: 1.55; font-size: 12.5px; }
304
+ .est { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; text-align: center; margin: 4px 0 6px; }
305
+ .est b { display: block; font-size: 16px; font-variant-numeric: tabular-nums; }
306
+ .est span { font-size: 11px; color: var(--sub); }
277
307
 
278
- /* —— 手机 —— */
279
- @media (max-width: 640px) {
280
- main { padding: 10px 12px calc(40px + env(safe-area-inset-bottom)); }
281
- .btn { padding: 9px 14px; font-size: 15px; }
308
+ /* —— 触屏(手机、平板):手指要点得中 —— */
309
+ @media (pointer: coarse) {
310
+ body { font-size: 14px; }
311
+ .btn { padding: 7px 13px; font-size: 14px; }
312
+ .btn.small { padding: 4px 10px; font-size: 13px; }
313
+ .btn.big { padding: 9px 16px; font-size: 15px; }
282
314
  .btn kbd { display: none; }
283
- .chip { padding: 5px 14px; font-size: 14px; }
284
- .play { width: 88px; height: 88px; font-size: 34px; }
285
- .grades .btn { padding: 14px 4px; font-size: 16px; }
286
- .study { padding: 14px 12px; }
315
+ .chip { padding: 4px 12px; font-size: 13.5px; }
316
+ .tab { padding: 8px 11px 9px; font-size: 14px; }
317
+ .lrow { padding: 10px 10px 10px 12px; }
318
+ .flow { padding: 11px 10px 11px 12px; }
319
+ .play { width: 72px; height: 72px; font-size: 28px; }
320
+ .grades .btn { padding: 12px 4px; font-size: 15px; }
321
+ .en-line { font-size: 18px; }
322
+ .zh-line { font-size: 15px; }
323
+ select, input[type=text] { font-size: 16px; padding: 6px 8px; } /* iOS:小于 16px 聚焦时会放大页面 */
324
+ .tools .icon-btn { font-size: 20px; padding: 2px 9px; }
325
+ .swipe-hint { display: inline; }
326
+ .dots { display: none; }
287
327
  .study .actions {
288
328
  position: sticky; bottom: 0; z-index: 4; background: var(--card);
289
- padding: 10px 0 calc(10px + env(safe-area-inset-bottom)); margin-bottom: -4px;
329
+ padding: 8px 0 calc(8px + env(safe-area-inset-bottom)); margin-bottom: -4px;
290
330
  }
291
- .study .actions .btn.big { width: 100%; }
292
- .dots { display: none; }
293
- .sheet-wrap { align-items: flex-end; padding: 0; }
294
- .sheet { border-radius: 16px 16px 0 0; padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
295
- .tools .icon-btn { font-size: 22px; padding: 2px 10px; }
296
- .form { grid-template-columns: 1fr; }
297
- .form label { padding-top: 0; }
298
- .week { height: 44px; }
331
+ .study .actions .btn.big { width: 100%; justify-content: center; }
332
+ main { padding-bottom: calc(32px + env(safe-area-inset-bottom)); }
299
333
  }
300
-
301
- /* —— 导出 —— */
302
- .sub-h { font-size: 13px; font-weight: 600; margin: 4px 0 2px; }
303
- .row.wrap { flex-wrap: wrap; }
304
-
305
- /* —— 标题旁的版本、更新、卸载 —— */
306
- .manage { display: inline-flex; align-items: center; gap: 6px; margin-left: 4px; flex-wrap: wrap; }
307
- .manage .ver { font-variant-numeric: tabular-nums; }
308
- .btn.small { padding: 2px 9px; font-size: 12px; line-height: 18px; }
309
- code.cmd { font: 12px ui-monospace, SFMono-Regular, Menlo, monospace; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; user-select: all; overflow-wrap: anywhere; }
310
- @media (max-width: 640px) { .btn.small { padding: 4px 10px; font-size: 13px; } .top { flex-wrap: wrap; } }
311
-
312
- /* —— 首页:新建课程 —— */
313
- .section-title { font-size: 13px; font-weight: 600; color: var(--sub); margin: 18px 2px 8px; }
314
- .new-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
315
- .new-card {
316
- appearance: none; cursor: pointer; text-align: left; font: inherit; color: var(--text);
317
- background: var(--card); border: 1.5px solid var(--line); border-radius: var(--radius);
318
- padding: 14px; display: flex; flex-direction: column; gap: 4px;
334
+ /* —— 窄(侧栏、手机):只调布局,不放大 —— */
335
+ @media (max-width: 520px) {
336
+ .sheet-wrap { align-items: flex-end; padding: 0; }
337
+ .sheet { border-radius: 12px 12px 0 0; padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
338
+ .top { flex-wrap: nowrap; }
319
339
  }
320
- .new-card:hover { border-color: var(--accent); }
321
- .new-card.on { border-color: var(--accent); background: var(--accent-soft); }
322
- .new-card b { font-size: 15px; }
323
- .new-card .faint { line-height: 1.5; }
324
- .new-ico { font-size: 22px; }
325
- #newPanel .card { margin-top: 10px; }
326
- .doc-new .step { display: flex; gap: 10px; margin: 12px 0; }
327
- .doc-new .num {
328
- flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--accent); color: #fff;
329
- font-size: 12px; font-weight: 700; display: grid; place-items: center; margin-top: 1px;
340
+ @media (max-width: 360px) {
341
+ .est, .stat-grid { grid-template-columns: repeat(2, 1fr); }
342
+ .form { grid-template-columns: 1fr; gap: 3px; }
343
+ .form label { margin-top: 5px; }
330
344
  }
331
- .doc-new textarea { margin-top: 6px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
332
- .prompt { white-space: pre-wrap; font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; background: var(--bg); border-radius: 8px; padding: 8px 10px; margin: 6px 0 0; color: var(--sub); }
333
- .kind { font-size: 11px; font-weight: 600; padding: 0 6px; border-radius: 4px; margin-right: 6px; vertical-align: 1px; background: var(--accent-soft); color: var(--accent); }
334
- .kind.doc { background: rgba(201, 138, 18, .14); color: var(--mid); }
335
- @media (max-width: 640px) { .new-grid { grid-template-columns: 1fr; } }
336
-
337
- /* —— 导入文档:确认 —— */
338
- #docDrop { padding: 22px 14px; }
339
- #docDrop .new-ico { font-size: 28px; }
340
- .doc-confirm .ai-note { margin: 10px 0; padding: 10px 12px; border-radius: 10px; background: var(--accent-soft); line-height: 1.6; font-size: 13px; }
341
- .doc-confirm .est { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; text-align: center; margin: 6px 0 8px; }
342
- .doc-confirm .est b { display: block; font-size: 20px; font-variant-numeric: tabular-nums; }
343
- .doc-confirm .est span { font-size: 11px; color: var(--sub); }
344
- .doc-confirm .form input[type=text] { margin: 0; }
345
- @media (max-width: 380px) { .doc-confirm .est { grid-template-columns: repeat(2, 1fr); } }