@chinhae/atw-cli 0.2.10 → 0.3.1

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.
Files changed (98) hide show
  1. package/README.md +29 -5
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +243 -123
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/uninstall.d.ts.map +1 -1
  6. package/dist/commands/uninstall.js +18 -3
  7. package/dist/commands/uninstall.js.map +1 -1
  8. package/dist/commands/update.d.ts +0 -3
  9. package/dist/commands/update.d.ts.map +1 -1
  10. package/dist/commands/update.js +45 -0
  11. package/dist/commands/update.js.map +1 -1
  12. package/dist/configurators/index.d.ts +8 -0
  13. package/dist/configurators/index.d.ts.map +1 -1
  14. package/dist/configurators/index.js +19 -0
  15. package/dist/configurators/index.js.map +1 -1
  16. package/dist/migrations/manifests/0.3.0.json +3410 -0
  17. package/dist/migrations/manifests/0.3.1.json +9 -0
  18. package/dist/templates/atw/config.yaml +4 -3
  19. package/dist/templates/atw/index.d.ts +2 -0
  20. package/dist/templates/atw/index.d.ts.map +1 -1
  21. package/dist/templates/atw/index.js +4 -0
  22. package/dist/templates/atw/index.js.map +1 -1
  23. package/dist/templates/atw/scripts/common/noob_mode.py +102 -0
  24. package/dist/templates/atw/scripts/common/session_context.py +7 -0
  25. package/dist/templates/atw/scripts/noob_mode.py +41 -0
  26. package/dist/templates/atw/scripts/tickets.py +66 -10
  27. package/dist/templates/atw/workflow.md +81 -17
  28. package/dist/templates/common/bundled-skills/atw-code-review/SKILL.md +4 -2
  29. package/dist/templates/common/bundled-skills/atw-codebase-design/DESIGN-IT-TWICE.md +1 -1
  30. package/dist/templates/common/bundled-skills/atw-diagnosing-bugs/SKILL.md +2 -2
  31. package/dist/templates/common/bundled-skills/atw-domain-modeling/{CONTEXT-FORMAT.md → GLOSSARY-FORMAT.md} +10 -10
  32. package/dist/templates/common/bundled-skills/atw-domain-modeling/SKILL.md +12 -12
  33. package/dist/templates/common/bundled-skills/atw-handoff/SKILL.md +1 -1
  34. package/dist/templates/common/bundled-skills/atw-implement/SKILL.md +6 -4
  35. package/dist/templates/common/bundled-skills/atw-implement-spec/SKILL.md +79 -0
  36. package/dist/templates/common/bundled-skills/atw-implement-spec/agents/openai.yaml +5 -0
  37. package/dist/templates/common/bundled-skills/atw-improve-codebase-architecture/SKILL.md +5 -5
  38. package/dist/templates/common/bundled-skills/atw-init-repo/SKILL.md +6 -4
  39. package/dist/templates/common/bundled-skills/atw-init-repo/references/domain.md +8 -8
  40. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw-local.md +5 -2
  41. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw.md +5 -2
  42. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-github.md +5 -4
  43. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-gitlab.md +2 -2
  44. package/dist/templates/common/bundled-skills/atw-init-repo/references/triage-labels.md +1 -1
  45. package/dist/templates/common/bundled-skills/atw-interview/SKILL.md +9 -1
  46. package/dist/templates/common/bundled-skills/atw-map/SKILL.md +5 -5
  47. package/dist/templates/common/bundled-skills/atw-noob-mode/SKILL.md +101 -0
  48. package/dist/templates/common/bundled-skills/atw-noob-mode/agents/openai.yaml +3 -0
  49. package/dist/templates/common/bundled-skills/atw-spec/SKILL.md +1 -1
  50. package/dist/templates/common/bundled-skills/atw-tdd/SKILL.md +2 -2
  51. package/dist/templates/common/bundled-skills/atw-tickets/SKILL.md +4 -4
  52. package/dist/templates/common/bundled-skills/atw-triage/SKILL.md +2 -2
  53. package/dist/templates/common/commands/continue.md +1 -1
  54. package/dist/templates/opencode/plugins/inject-workflow-state.js +29 -1
  55. package/dist/templates/shared-hooks/inject-subagent-context.py +29 -3
  56. package/dist/templates/shared-hooks/inject-workflow-state.py +27 -3
  57. package/dist/templates/shared-hooks/session-start.py +23 -0
  58. package/dist/templates/snow/SNOW.md +1 -1
  59. package/dist/utils/file-writer.d.ts.map +1 -1
  60. package/dist/utils/file-writer.js +29 -16
  61. package/dist/utils/file-writer.js.map +1 -1
  62. package/dist/utils/interactive-guard.d.ts +2 -2
  63. package/dist/utils/interactive-guard.js +2 -2
  64. package/dist/utils/lang.d.ts +14 -0
  65. package/dist/utils/lang.d.ts.map +1 -0
  66. package/dist/utils/lang.js +20 -0
  67. package/dist/utils/lang.js.map +1 -0
  68. package/dist/utils/optional-skills.d.ts +90 -0
  69. package/dist/utils/optional-skills.d.ts.map +1 -0
  70. package/dist/utils/optional-skills.js +266 -0
  71. package/dist/utils/optional-skills.js.map +1 -0
  72. package/dist/utils/template-fetcher.d.ts +6 -0
  73. package/dist/utils/template-fetcher.d.ts.map +1 -1
  74. package/dist/utils/template-fetcher.js +1 -1
  75. package/dist/utils/template-fetcher.js.map +1 -1
  76. package/package.json +2 -2
  77. package/dist/templates/common/bundled-skills/atw-merge/SKILL.md +0 -14
  78. package/dist/templates/common/bundled-skills/atw-merge/agents/openai.yaml +0 -3
  79. package/dist/templates/common/bundled-skills/dejargonizer/SKILL.md +0 -133
  80. package/dist/templates/common/bundled-skills/noob-mode/SKILL.md +0 -175
  81. package/dist/templates/common/bundled-skills/noob-mode/references/examples.md +0 -418
  82. package/dist/templates/common/bundled-skills/noob-mode/references/glossary.md +0 -368
  83. package/dist/templates/common/bundled-skills/oxy-explanation/SKILL.md +0 -80
  84. package/dist/templates/common/bundled-skills/oxy-learning-hub/SKILL.md +0 -179
  85. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/course.css +0 -1044
  86. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/course.js +0 -184
  87. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/lesson-template.html +0 -125
  88. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/summary-template.html +0 -659
  89. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/publishing.md +0 -64
  90. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/summary-mode.md +0 -96
  91. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/GLOSSARY-FORMAT.md +0 -30
  92. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/LEARNING-RECORD-FORMAT.md +0 -42
  93. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/MISSION-FORMAT.md +0 -50
  94. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/RESOURCES-FORMAT.md +0 -40
  95. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching-mode.md +0 -251
  96. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/workspace.md +0 -112
  97. package/dist/templates/common/bundled-skills/oxy-learning-hub/scripts/validate_html.py +0 -200
  98. package/dist/templates/common/bundled-skills/show-me/SKILL.md +0 -127
@@ -1,1044 +0,0 @@
1
- /* ─────────────────────────────────────────────────────────────
2
- Oxy Learning Hub · 课程共享样式
3
- 一套 DOM,两套 token:
4
- 浅色 = 静谧极简(近白冷灰 + 靛蓝)
5
- 深色 = 夜间专注(深蓝灰 + 青绿 + 等宽标题)
6
- 除下面两个 token 块外,任何地方都不再出现主题相关的写死颜色;
7
- 换配色只改 :root 与 :root[data-theme="dark"]。
8
- ───────────────────────────────────────────────────────────── */
9
-
10
- :root,
11
- :root[data-theme="light"] {
12
- --bg: oklch(0.985 0.002 260);
13
- --surface: oklch(1 0 0);
14
- --raised: oklch(0.968 0.004 260);
15
- --fg: oklch(0.22 0.014 265);
16
- --muted: oklch(0.53 0.012 265);
17
- --border: oklch(0.912 0.006 265);
18
- --accent: oklch(0.5 0.15 262);
19
- --accent-hover: oklch(0.42 0.15 262);
20
- --on-accent: oklch(0.99 0.005 262);
21
-
22
- --good: oklch(0.46 0.11 155);
23
- --good-bg: color-mix(in oklch, var(--good) 10%, var(--surface));
24
- --on-good: oklch(0.99 0.01 155);
25
- --bad: oklch(0.5 0.16 25);
26
- --bad-bg: color-mix(in oklch, var(--bad) 9%, var(--surface));
27
- --on-bad: oklch(0.99 0.01 25);
28
-
29
- --code-bg: oklch(0.19 0.014 265);
30
- --code-fg: oklch(0.92 0.01 265);
31
- --code-cmt: oklch(0.66 0.03 265);
32
-
33
- --font-display:
34
- system-ui, -apple-system, "Segoe UI", "PingFang SC", sans-serif;
35
- --display-weight: 660;
36
- --display-tracking: -0.03em;
37
-
38
- --shadow:
39
- 0 1px 2px color-mix(in oklch, var(--fg) 6%, transparent),
40
- 0 8px 24px -16px color-mix(in oklch, var(--fg) 22%, transparent);
41
- --heat-factor: 1.15; /* 浅色:整格填色 */
42
- }
43
-
44
- :root[data-theme="dark"] {
45
- --bg: oklch(0.185 0.014 250);
46
- --surface: oklch(0.225 0.016 250);
47
- --raised: oklch(0.265 0.018 250);
48
- --fg: oklch(0.945 0.008 250);
49
- --muted: oklch(0.705 0.014 250);
50
- --border: oklch(0.325 0.018 250);
51
- --accent: oklch(0.8 0.13 178);
52
- --accent-hover: oklch(0.88 0.13 178);
53
- --on-accent: oklch(0.2 0.05 178);
54
-
55
- --good: oklch(0.82 0.15 150);
56
- --good-bg: color-mix(in oklch, var(--good) 15%, var(--surface));
57
- --on-good: oklch(0.2 0.05 150);
58
- --bad: oklch(0.75 0.14 25);
59
- --bad-bg: color-mix(in oklch, var(--bad) 15%, var(--surface));
60
- --on-bad: oklch(0.2 0.05 25);
61
-
62
- --code-bg: oklch(0.155 0.014 250);
63
- --code-fg: oklch(0.9 0.01 250);
64
- --code-cmt: oklch(0.705 0.014 250);
65
-
66
- --font-display: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
67
- --display-weight: 600;
68
- --display-tracking: -0.015em;
69
-
70
- --shadow: 0 1px 2px color-mix(in oklch, black 24%, transparent);
71
- --heat-factor: 0.35; /* 深色:暗底 + 填充权重条,见 .heat .cell::after */
72
- }
73
-
74
- :root {
75
- --accent-soft: color-mix(in oklch, var(--accent) 12%, var(--surface));
76
- --font-body:
77
- "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
78
- --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
79
- --r: 8px;
80
- --r-lg: 12px;
81
- }
82
-
83
- *,
84
- *::before,
85
- *::after {
86
- box-sizing: border-box;
87
- }
88
- html {
89
- scroll-behavior: smooth;
90
- -webkit-text-size-adjust: 100%;
91
- }
92
- body {
93
- margin: 0;
94
- background: var(--bg);
95
- color: var(--fg);
96
- font-family: var(--font-body);
97
- font-size: 16px;
98
- line-height: 1.76;
99
- -webkit-font-smoothing: antialiased;
100
- transition:
101
- background 0.2s ease,
102
- color 0.2s ease;
103
- }
104
- p {
105
- text-wrap: pretty;
106
- }
107
- h1,
108
- h2,
109
- h3 {
110
- text-wrap: balance;
111
- }
112
- a {
113
- color: var(--accent);
114
- text-decoration: none;
115
- }
116
- a:hover {
117
- text-decoration: underline;
118
- text-underline-offset: 0.2em;
119
- }
120
- button,
121
- textarea {
122
- font: inherit;
123
- }
124
- button {
125
- cursor: pointer;
126
- }
127
- :focus-visible {
128
- outline: 2px solid var(--accent);
129
- outline-offset: 2px;
130
- border-radius: 4px;
131
- }
132
-
133
- /* ── 顶栏 ─────────────────────────────────────────────── */
134
- .topbar {
135
- position: sticky;
136
- top: 0;
137
- z-index: 30;
138
- background: color-mix(in oklch, var(--bg) 86%, transparent);
139
- backdrop-filter: saturate(1.3) blur(12px);
140
- border-bottom: 1px solid var(--border);
141
- }
142
- .topbar-inner {
143
- max-width: 84rem;
144
- margin-inline: auto;
145
- padding: 0 32px;
146
- height: 56px;
147
- display: flex;
148
- align-items: center;
149
- gap: 16px;
150
- }
151
- .brand {
152
- display: flex;
153
- align-items: center;
154
- gap: 10px;
155
- font-weight: 620;
156
- letter-spacing: -0.01em;
157
- }
158
- .brand-mark {
159
- width: 22px;
160
- height: 22px;
161
- border-radius: 6px;
162
- background: var(--accent);
163
- display: grid;
164
- place-items: center;
165
- color: var(--on-accent);
166
- font-family: var(--font-mono);
167
- font-size: 11px;
168
- font-weight: 700;
169
- }
170
- .crumb {
171
- color: var(--muted);
172
- font-size: 13px;
173
- font-family: var(--font-mono);
174
- letter-spacing: 0.02em;
175
- }
176
- .crumb::before {
177
- content: "/";
178
- margin: 0 10px;
179
- color: var(--border);
180
- }
181
- .top-right {
182
- margin-left: auto;
183
- display: flex;
184
- align-items: center;
185
- gap: 10px;
186
- }
187
- .status {
188
- display: inline-flex;
189
- align-items: center;
190
- gap: 7px;
191
- font-size: 12.5px;
192
- color: var(--muted);
193
- padding: 5px 11px;
194
- border: 1px solid var(--border);
195
- border-radius: 999px;
196
- background: var(--surface);
197
- }
198
- .status .dot {
199
- width: 6px;
200
- height: 6px;
201
- border-radius: 50%;
202
- background: var(--border);
203
- }
204
- .status.is-done {
205
- color: var(--good);
206
- border-color: color-mix(in oklch, var(--good) 38%, var(--border));
207
- }
208
- .status.is-done .dot {
209
- background: var(--good);
210
- }
211
-
212
- /* 主题切换:图标与文案标的是「点了会切到哪个主题」,不是当前主题 */
213
- .theme-toggle {
214
- display: inline-flex;
215
- align-items: center;
216
- gap: 7px;
217
- height: 32px;
218
- padding: 0 12px;
219
- background: var(--surface);
220
- color: var(--fg);
221
- border: 1px solid var(--border);
222
- border-radius: 999px;
223
- font-size: 12.5px;
224
- transition:
225
- background 0.14s ease,
226
- border-color 0.14s ease;
227
- }
228
- .theme-toggle:hover {
229
- background: var(--raised);
230
- border-color: var(--fg);
231
- }
232
- .theme-toggle svg {
233
- width: 14px;
234
- height: 14px;
235
- display: block;
236
- }
237
- .theme-toggle .icon-sun {
238
- display: none;
239
- }
240
- :root[data-theme="dark"] .theme-toggle .icon-sun {
241
- display: block;
242
- }
243
- :root[data-theme="dark"] .theme-toggle .icon-moon {
244
- display: none;
245
- }
246
-
247
- .progress-track {
248
- height: 2px;
249
- }
250
- .progress-line {
251
- height: 2px;
252
- width: 0;
253
- background: var(--accent);
254
- transition: width 0.1s linear;
255
- }
256
-
257
- /* ── 布局:目录 + 正文 + 随读侧栏 ─────────────────────── */
258
- .layout {
259
- max-width: 84rem;
260
- margin-inline: auto;
261
- padding: 48px 32px 104px;
262
- display: grid;
263
- grid-template-columns: 15rem minmax(0, 42rem) 1fr;
264
- gap: 48px;
265
- align-items: start;
266
- }
267
- main {
268
- min-width: 0;
269
- }
270
-
271
- /* 目录:步骤点 + 连线,条目由 course.js 依据正文小节自动生成 */
272
- .toc {
273
- position: sticky;
274
- top: 88px;
275
- }
276
- .toc-head {
277
- font-family: var(--font-mono);
278
- font-size: 10.5px;
279
- letter-spacing: 0.16em;
280
- text-transform: uppercase;
281
- color: var(--muted);
282
- margin: 0 0 14px;
283
- padding-left: 2px;
284
- }
285
- .toc ol {
286
- list-style: none;
287
- margin: 0;
288
- padding: 0;
289
- }
290
- .toc li {
291
- position: relative;
292
- }
293
- .toc a {
294
- display: flex;
295
- align-items: center;
296
- gap: 12px;
297
- padding: 7px 0;
298
- color: var(--muted);
299
- font-size: 13.5px;
300
- line-height: 1.5;
301
- transition: color 0.15s ease;
302
- }
303
- .toc a::before {
304
- content: "";
305
- width: 7px;
306
- height: 7px;
307
- flex: none;
308
- border-radius: 50%;
309
- border: 1px solid var(--border);
310
- background: var(--bg);
311
- transition:
312
- background 0.15s ease,
313
- border-color 0.15s ease,
314
- box-shadow 0.15s ease;
315
- }
316
- .toc li:not(:last-child)::after {
317
- content: "";
318
- position: absolute;
319
- left: 3px;
320
- top: 24px;
321
- bottom: -4px;
322
- width: 1px;
323
- background: var(--border);
324
- }
325
- .toc a:hover {
326
- color: var(--fg);
327
- text-decoration: none;
328
- }
329
- .toc a:hover::before {
330
- border-color: var(--accent);
331
- }
332
- .toc a.is-active {
333
- color: var(--accent);
334
- }
335
- .toc a.is-active::before {
336
- background: var(--accent);
337
- border-color: var(--accent);
338
- box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 22%, transparent);
339
- }
340
- .toc-meter {
341
- margin-top: 22px;
342
- padding: 12px 14px;
343
- border: 1px solid var(--border);
344
- border-radius: var(--r);
345
- background: var(--surface);
346
- font-size: 12px;
347
- color: var(--muted);
348
- font-family: var(--font-mono);
349
- letter-spacing: 0.04em;
350
- }
351
- .toc-meter .bar {
352
- height: 4px;
353
- border-radius: 2px;
354
- background: var(--raised);
355
- margin-top: 9px;
356
- overflow: hidden;
357
- }
358
- .toc-meter .fill {
359
- height: 100%;
360
- width: 0;
361
- background: var(--accent);
362
- transition: width 0.25s ease;
363
- }
364
-
365
- /* ── 标题区 ───────────────────────────────────────────── */
366
- .kicker {
367
- display: inline-flex;
368
- align-items: center;
369
- gap: 8px;
370
- margin: 0 0 20px;
371
- font-family: var(--font-mono);
372
- font-size: 11.5px;
373
- letter-spacing: 0.1em;
374
- text-transform: uppercase;
375
- color: var(--accent);
376
- background: var(--accent-soft);
377
- padding: 5px 11px;
378
- border-radius: 999px;
379
- }
380
- h1 {
381
- font-family: var(--font-display);
382
- font-weight: var(--display-weight);
383
- font-size: clamp(30px, 3.8vw, 42px);
384
- line-height: 1.18;
385
- letter-spacing: var(--display-tracking);
386
- margin: 0;
387
- }
388
- .subtitle {
389
- margin: 16px 0 0;
390
- color: var(--muted);
391
- font-size: 17.5px;
392
- line-height: 1.68;
393
- }
394
- .facts {
395
- display: flex;
396
- flex-wrap: wrap;
397
- gap: 8px;
398
- margin-top: 24px;
399
- }
400
- .chip {
401
- font-size: 12.5px;
402
- color: var(--muted);
403
- padding: 4px 11px;
404
- border: 1px solid var(--border);
405
- border-radius: 999px;
406
- background: var(--surface);
407
- }
408
-
409
- section {
410
- margin-top: 56px;
411
- scroll-margin-top: 88px;
412
- }
413
- h2 {
414
- font-family: var(--font-display);
415
- font-weight: var(--display-weight);
416
- font-size: 21px;
417
- letter-spacing: var(--display-tracking);
418
- line-height: 1.35;
419
- margin: 0 0 6px;
420
- display: flex;
421
- align-items: center;
422
- gap: 12px;
423
- }
424
- h2 .n {
425
- font-family: var(--font-mono);
426
- font-size: 12px;
427
- color: var(--accent);
428
- font-weight: 400;
429
- letter-spacing: 0.1em;
430
- }
431
- h2::after {
432
- content: "";
433
- flex: 1;
434
- height: 1px;
435
- background: var(--border);
436
- }
437
- h3 {
438
- font-size: 16.5px;
439
- font-weight: 640;
440
- margin: 30px 0 6px;
441
- letter-spacing: -0.005em;
442
- font-family: var(--font-body);
443
- }
444
- p {
445
- margin: 12px 0;
446
- }
447
- ul,
448
- ol {
449
- margin: 12px 0;
450
- padding-left: 1.2em;
451
- }
452
- li {
453
- margin: 7px 0;
454
- }
455
- li::marker {
456
- color: var(--muted);
457
- }
458
- code:not(pre code) {
459
- font-family: var(--font-mono);
460
- font-size: 0.87em;
461
- padding: 2px 6px;
462
- border-radius: 5px;
463
- background: var(--raised);
464
- border: 1px solid var(--border);
465
- }
466
- pre {
467
- margin: 20px 0;
468
- padding: 18px 20px;
469
- overflow-x: auto;
470
- background: var(--code-bg);
471
- color: var(--code-fg);
472
- border: 1px solid var(--border);
473
- border-radius: var(--r);
474
- font-family: var(--font-mono);
475
- font-size: 13px;
476
- line-height: 1.78;
477
- }
478
- pre .cmt {
479
- color: var(--code-cmt);
480
- }
481
-
482
- /* ── 通用块:目标卡片 / 旁注 ──────────────────────────── */
483
- .card {
484
- background: var(--surface);
485
- border: 1px solid var(--border);
486
- border-radius: var(--r-lg);
487
- padding: 22px 24px;
488
- box-shadow: var(--shadow);
489
- }
490
- .goal {
491
- margin-top: 20px;
492
- border-left: 2px solid var(--accent);
493
- }
494
- .goal h3 {
495
- margin: 0 0 8px;
496
- font-size: 16px;
497
- }
498
- .goal p {
499
- margin: 0;
500
- }
501
- .goal .check {
502
- margin-top: 14px;
503
- padding-top: 14px;
504
- border-top: 1px solid var(--border);
505
- font-size: 14px;
506
- color: var(--muted);
507
- }
508
- .note {
509
- margin: 22px 0;
510
- padding: 16px 18px;
511
- background: var(--surface);
512
- border: 1px solid var(--border);
513
- border-radius: var(--r);
514
- font-size: 15px;
515
- line-height: 1.7;
516
- }
517
- .note .label {
518
- display: block;
519
- font-family: var(--font-mono);
520
- font-size: 10.5px;
521
- letter-spacing: 0.12em;
522
- text-transform: uppercase;
523
- color: var(--accent);
524
- margin-bottom: 6px;
525
- }
526
-
527
- figure {
528
- margin: 24px 0;
529
- }
530
- figcaption {
531
- font-size: 13px;
532
- color: var(--muted);
533
- margin-top: 10px;
534
- line-height: 1.6;
535
- }
536
- .formula {
537
- font-family: var(--font-mono);
538
- font-size: 16px;
539
- text-align: center;
540
- padding: 22px;
541
- background: var(--surface);
542
- border: 1px solid var(--border);
543
- border-radius: var(--r);
544
- overflow-x: auto;
545
- white-space: nowrap;
546
- }
547
- .formula em {
548
- font-style: normal;
549
- color: var(--accent);
550
- }
551
-
552
- /* ── 热力图:浅色整格填充 / 深色暗底 + 权重条 ─────────
553
- 深色下中间色调撑不住小字对比度,因此改为固定暗底 + 底部填充条。 */
554
- .heat-wrap {
555
- border: 1px solid var(--border);
556
- border-radius: var(--r-lg);
557
- background: var(--surface);
558
- padding: 20px;
559
- box-shadow: var(--shadow);
560
- }
561
- .heat {
562
- width: 100%;
563
- border-collapse: separate;
564
- border-spacing: 3px;
565
- font-family: var(--font-mono);
566
- font-size: 12px;
567
- }
568
- .heat th {
569
- font-weight: 400;
570
- color: var(--muted);
571
- font-size: 11.5px;
572
- padding: 4px;
573
- }
574
- .heat th[scope="row"] {
575
- text-align: right;
576
- padding-right: 10px;
577
- white-space: nowrap;
578
- }
579
- .heat td {
580
- padding: 0;
581
- }
582
- .heat .cell {
583
- position: relative;
584
- height: 42px;
585
- border-radius: 5px;
586
- display: grid;
587
- place-items: center;
588
- color: var(--fg);
589
- background: color-mix(
590
- in oklch,
591
- var(--accent) calc(var(--w) * var(--heat-factor) * 1%),
592
- var(--raised)
593
- );
594
- }
595
- .heat .cell[data-strong="true"] {
596
- font-weight: 700;
597
- }
598
- :root[data-theme="dark"] .heat .cell {
599
- height: 46px;
600
- padding-bottom: 12px;
601
- border: 1px solid var(--border);
602
- }
603
- :root[data-theme="dark"] .heat .cell::after {
604
- content: "";
605
- position: absolute;
606
- left: 6px;
607
- right: 6px;
608
- bottom: 7px;
609
- height: 5px;
610
- border-radius: 3px;
611
- background: linear-gradient(
612
- to right,
613
- var(--accent) calc(var(--w) * 1.9%),
614
- color-mix(in oklch, var(--fg) 14%, transparent) calc(var(--w) * 1.9%)
615
- );
616
- }
617
- :root[data-theme="dark"] .heat .cell[data-strong="true"] {
618
- color: var(--accent);
619
- border-color: color-mix(in oklch, var(--accent) 45%, var(--border));
620
- }
621
- .legend {
622
- display: flex;
623
- align-items: center;
624
- gap: 10px;
625
- margin-top: 14px;
626
- font-family: var(--font-mono);
627
- font-size: 11px;
628
- color: var(--muted);
629
- letter-spacing: 0.04em;
630
- }
631
- .legend-bar {
632
- width: 140px;
633
- height: 6px;
634
- border-radius: 3px;
635
- background: linear-gradient(90deg, var(--raised), var(--accent));
636
- }
637
-
638
- /* ── 折叠揭晓 ─────────────────────────────────────────── */
639
- details {
640
- margin: 16px 0;
641
- background: var(--surface);
642
- border: 1px solid var(--border);
643
- border-radius: var(--r-lg);
644
- overflow: hidden;
645
- }
646
- details > summary {
647
- list-style: none;
648
- cursor: pointer;
649
- padding: 15px 20px;
650
- font-weight: 600;
651
- display: flex;
652
- align-items: center;
653
- justify-content: space-between;
654
- gap: 14px;
655
- transition: background 0.15s ease;
656
- }
657
- details > summary::-webkit-details-marker {
658
- display: none;
659
- }
660
- details > summary::after {
661
- content: "揭晓";
662
- flex: none;
663
- font-family: var(--font-mono);
664
- font-size: 11px;
665
- letter-spacing: 0.1em;
666
- color: var(--accent);
667
- border: 1px solid color-mix(in oklch, var(--accent) 40%, var(--border));
668
- padding: 3px 10px;
669
- border-radius: 999px;
670
- }
671
- details[open] > summary::after {
672
- content: "收起";
673
- }
674
- details > summary:hover {
675
- background: var(--raised);
676
- }
677
- .details-body {
678
- padding: 0 20px 18px;
679
- border-top: 1px solid var(--border);
680
- }
681
- .details-body > :first-child {
682
- margin-top: 14px;
683
- }
684
-
685
- /* ── 练习 ─────────────────────────────────────────────── */
686
- .quiz {
687
- margin: 20px 0;
688
- padding: 22px 24px;
689
- background: var(--surface);
690
- border: 1px solid var(--border);
691
- border-radius: var(--r-lg);
692
- box-shadow: var(--shadow);
693
- }
694
- .quiz-label {
695
- font-family: var(--font-mono);
696
- font-size: 10.5px;
697
- letter-spacing: 0.12em;
698
- text-transform: uppercase;
699
- color: var(--muted);
700
- margin: 0 0 10px;
701
- }
702
- .quiz-question {
703
- margin: 0 0 14px;
704
- font-weight: 620;
705
- font-size: 16.5px;
706
- }
707
- .quiz-option {
708
- display: flex;
709
- align-items: flex-start;
710
- gap: 12px;
711
- width: 100%;
712
- text-align: left;
713
- margin: 7px 0;
714
- padding: 12px 14px;
715
- background: var(--bg);
716
- color: var(--fg);
717
- border: 1px solid var(--border);
718
- border-radius: var(--r);
719
- line-height: 1.58;
720
- transition:
721
- background 0.15s ease,
722
- border-color 0.15s ease;
723
- }
724
- .quiz-option:hover:enabled {
725
- background: var(--raised);
726
- border-color: var(--accent);
727
- }
728
- .quiz-option:disabled {
729
- cursor: default;
730
- }
731
- .opt-key {
732
- flex: none;
733
- width: 21px;
734
- height: 21px;
735
- border-radius: 5px;
736
- display: grid;
737
- place-items: center;
738
- font-family: var(--font-mono);
739
- font-size: 11px;
740
- background: var(--raised);
741
- color: var(--muted);
742
- border: 1px solid var(--border);
743
- }
744
- .quiz-option.is-correct {
745
- background: var(--good-bg);
746
- border-color: var(--good);
747
- }
748
- .quiz-option.is-correct .opt-key {
749
- background: var(--good);
750
- color: var(--on-good);
751
- border-color: var(--good);
752
- }
753
- .quiz-option.is-wrong {
754
- background: var(--bad-bg);
755
- border-color: var(--bad);
756
- }
757
- .quiz-option.is-wrong .opt-key {
758
- background: var(--bad);
759
- color: var(--on-bad);
760
- border-color: var(--bad);
761
- }
762
- .quiz-feedback {
763
- min-height: 1.4em;
764
- margin: 12px 0 0;
765
- font-size: 14.5px;
766
- line-height: 1.62;
767
- }
768
- .quiz-feedback.ok {
769
- color: var(--good);
770
- }
771
- .quiz-feedback.no {
772
- color: var(--bad);
773
- }
774
-
775
- .response {
776
- margin: 20px 0;
777
- }
778
- .response label {
779
- display: block;
780
- font-weight: 620;
781
- margin-bottom: 8px;
782
- }
783
- .response .hint {
784
- margin: 0 0 10px;
785
- color: var(--muted);
786
- font-size: 14px;
787
- }
788
- textarea {
789
- width: 100%;
790
- min-height: 8.5rem;
791
- padding: 13px 15px;
792
- font-size: 15.5px;
793
- line-height: 1.7;
794
- color: var(--fg);
795
- background: var(--surface);
796
- border: 1px solid var(--border);
797
- border-radius: var(--r);
798
- resize: vertical;
799
- }
800
- textarea::placeholder {
801
- color: var(--muted);
802
- }
803
- textarea:focus {
804
- border-color: var(--accent);
805
- outline: 2px solid color-mix(in oklch, var(--accent) 30%, transparent);
806
- }
807
- .btn-ghost {
808
- margin-top: 10px;
809
- padding: 8px 14px;
810
- font-size: 13.5px;
811
- background: var(--surface);
812
- color: var(--fg);
813
- border: 1px solid var(--border);
814
- border-radius: var(--r);
815
- transition:
816
- background 0.15s ease,
817
- border-color 0.15s ease;
818
- }
819
- .btn-ghost:hover {
820
- background: var(--raised);
821
- border-color: var(--fg);
822
- }
823
- .btn-primary {
824
- display: inline-flex;
825
- align-items: center;
826
- gap: 8px;
827
- padding: 12px 22px;
828
- min-height: 46px;
829
- background: var(--accent);
830
- color: var(--on-accent);
831
- border: 1px solid var(--accent);
832
- border-radius: var(--r);
833
- font-size: 15px;
834
- font-weight: 620;
835
- transition:
836
- background 0.15s ease,
837
- border-color 0.15s ease;
838
- }
839
- .btn-primary:hover {
840
- background: var(--accent-hover);
841
- border-color: var(--accent-hover);
842
- color: var(--on-accent);
843
- }
844
-
845
- /* ── 来源 / 导航 / 收尾 ───────────────────────────────── */
846
- .cite {
847
- font-family: var(--font-mono);
848
- font-size: 0.7em;
849
- vertical-align: super;
850
- padding: 1px 4px;
851
- border-radius: 4px;
852
- background: var(--accent-soft);
853
- color: var(--accent);
854
- }
855
- .cite:hover {
856
- background: color-mix(in oklch, var(--accent) 24%, var(--surface));
857
- text-decoration: none;
858
- }
859
- .sources ol {
860
- padding-left: 1.3em;
861
- }
862
- .sources li {
863
- margin: 12px 0;
864
- font-size: 14.5px;
865
- }
866
- .sources .src-note {
867
- display: block;
868
- color: var(--muted);
869
- font-size: 13.5px;
870
- margin-top: 2px;
871
- }
872
-
873
- .nav-pair {
874
- display: grid;
875
- grid-template-columns: 1fr 1fr;
876
- gap: 12px;
877
- margin-top: 16px;
878
- }
879
- .nav-card {
880
- padding: 16px 18px;
881
- border: 1px solid var(--border);
882
- border-radius: var(--r-lg);
883
- background: var(--surface);
884
- color: var(--fg);
885
- display: block;
886
- transition:
887
- background 0.15s ease,
888
- border-color 0.15s ease;
889
- }
890
- .nav-card:hover {
891
- background: var(--raised);
892
- border-color: var(--accent);
893
- text-decoration: none;
894
- }
895
- .nav-card .k {
896
- display: block;
897
- font-family: var(--font-mono);
898
- font-size: 11px;
899
- color: var(--muted);
900
- margin-bottom: 5px;
901
- letter-spacing: 0.08em;
902
- }
903
- .nav-card .t {
904
- font-weight: 600;
905
- font-size: 15px;
906
- }
907
- .nav-list {
908
- list-style: none;
909
- padding: 0;
910
- margin: 14px 0 0;
911
- border-top: 1px solid var(--border);
912
- }
913
- .nav-list li {
914
- border-bottom: 1px solid var(--border);
915
- margin: 0;
916
- }
917
- .nav-list a {
918
- display: flex;
919
- justify-content: space-between;
920
- gap: 14px;
921
- padding: 12px 2px;
922
- color: var(--fg);
923
- font-size: 15px;
924
- }
925
- .nav-list a:hover {
926
- color: var(--accent);
927
- text-decoration: none;
928
- }
929
- .nav-list .lab {
930
- font-family: var(--font-mono);
931
- font-size: 11px;
932
- color: var(--muted);
933
- letter-spacing: 0.04em;
934
- }
935
-
936
- .finish {
937
- margin-top: 56px;
938
- padding-top: 26px;
939
- border-top: 1px solid var(--border);
940
- display: flex;
941
- flex-wrap: wrap;
942
- align-items: center;
943
- gap: 16px 20px;
944
- }
945
- .finish p {
946
- margin: 0;
947
- color: var(--muted);
948
- font-size: 14px;
949
- max-width: 24rem;
950
- }
951
-
952
- /* ── 右侧随读栏 ───────────────────────────────────────── */
953
- .aside-notes {
954
- position: sticky;
955
- top: 88px;
956
- }
957
- .aside-card {
958
- border: 1px solid var(--border);
959
- border-radius: var(--r-lg);
960
- background: var(--surface);
961
- padding: 18px;
962
- box-shadow: var(--shadow);
963
- }
964
- .aside-card + .aside-card {
965
- margin-top: 14px;
966
- }
967
- .aside-card h4 {
968
- margin: 0 0 8px;
969
- font-size: 12px;
970
- font-family: var(--font-mono);
971
- letter-spacing: 0.1em;
972
- text-transform: uppercase;
973
- color: var(--muted);
974
- font-weight: 500;
975
- }
976
- .aside-card p {
977
- margin: 0;
978
- font-size: 13.5px;
979
- color: var(--fg);
980
- line-height: 1.68;
981
- }
982
- .aside-card ul {
983
- margin: 6px 0 0;
984
- padding-left: 1.1em;
985
- font-size: 13.5px;
986
- color: var(--muted);
987
- }
988
- .aside-card li {
989
- margin: 4px 0;
990
- }
991
-
992
- @media (max-width: 1180px) {
993
- .layout {
994
- grid-template-columns: 14rem minmax(0, 1fr);
995
- }
996
- .aside-notes {
997
- display: none;
998
- }
999
- }
1000
- @media (max-width: 900px) {
1001
- .layout {
1002
- grid-template-columns: 1fr;
1003
- gap: 28px;
1004
- padding: 28px 20px 80px;
1005
- }
1006
- .toc {
1007
- position: static;
1008
- }
1009
- .toc ol {
1010
- display: flex;
1011
- flex-wrap: wrap;
1012
- gap: 2px 16px;
1013
- }
1014
- .toc li:not(:last-child)::after {
1015
- display: none;
1016
- }
1017
- .nav-pair {
1018
- grid-template-columns: 1fr;
1019
- }
1020
- .heat {
1021
- font-size: 10.5px;
1022
- }
1023
- .crumb {
1024
- display: none;
1025
- }
1026
- }
1027
-
1028
- @media print {
1029
- .topbar,
1030
- .toc,
1031
- .aside-notes,
1032
- .finish,
1033
- .btn-ghost {
1034
- display: none;
1035
- }
1036
- body {
1037
- background: white;
1038
- }
1039
- .layout {
1040
- display: block;
1041
- padding: 0;
1042
- max-width: none;
1043
- }
1044
- }