diff --git a/apps/server/src/archive/archive-report.exam.spec.ts b/apps/server/src/archive/archive-report.exam.spec.ts
new file mode 100644
index 0000000..8ae3c69
--- /dev/null
+++ b/apps/server/src/archive/archive-report.exam.spec.ts
@@ -0,0 +1,14 @@
+import { renderScoreTrendChart } from './archive-report.exam';
+
+describe('renderScoreTrendChart', () => {
+ it('places the first y-axis label 4px below the top gridline using numeric addition', () => {
+ const html = renderScoreTrendChart([
+ { examType: '文化', score: 60, examDate: '2026-01-01' },
+ { examType: '文化', score: 90, examDate: '2026-02-01' },
+ { examType: '文化', score: 70, examDate: '2026-03-01' },
+ ] as never);
+
+ expect(html).toContain('y="154.0"');
+ expect(html).not.toContain('y="150.04"');
+ });
+});
diff --git a/apps/server/src/archive/archive-report.exam.ts b/apps/server/src/archive/archive-report.exam.ts
index f099c5d..47da985 100644
--- a/apps/server/src/archive/archive-report.exam.ts
+++ b/apps/server/src/archive/archive-report.exam.ts
@@ -146,7 +146,7 @@ export function renderScoreTrendChart(exams: ExamScore[]): string {
for (let i = 0; i <= ySteps; i++) {
const val = minScore + (scoreRange * i) / ySteps;
const y = scaleY(val);
- yLabels += `${val.toFixed(0)}`;
+ yLabels += `${val.toFixed(0)}`;
if (i > 0) {
yLabels += ``;
}