diff --git a/B05_Profile/B05_Profile_UI_Profile_Tools.ts b/B05_Profile/B05_Profile_UI_Profile_Tools.ts
index f14a0b087..b82790a57 100644
--- a/B05_Profile/B05_Profile_UI_Profile_Tools.ts
+++ b/B05_Profile/B05_Profile_UI_Profile_Tools.ts
@@ -16,6 +16,7 @@
import type { StraightRun } from "./logic/B05_Profile_UI_Profile_Straighten";
import { sameRun } from "./logic/B05_Profile_UI_Profile_Straighten";
+import { HISTORY_ICON } from "./B05_Profile_UI_RouteEdit_Chrome";
import type { FreeChartGeom } from "../A00_Common/design/design_profile_free_view";
export type ProfileToolMode = "none" | "straighten" | "shift" | "free";
@@ -174,6 +175,11 @@ export function createProfileTools(callbacks: ProfileToolsCallbacks): ProfileToo
undo.disabled = !callbacks.canUndo();
const redo = toolButton("↷", "다시하기 (Ctrl+Shift+Z)", callbacks.onRedo);
redo.disabled = !callbacks.canRedo();
+ // 평면 편집과 같은 그림(요구 241-9) — 글은 aria-label 로.
+ undo.innerHTML = HISTORY_ICON.undo;
+ undo.setAttribute("aria-label", "되돌리기");
+ redo.innerHTML = HISTORY_ICON.redo;
+ redo.setAttribute("aria-label", "다시하기");
const straighten = toolButton(
"직선화",
diff --git a/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts b/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts
index 13021c9e8..982dde338 100644
--- a/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts
+++ b/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts
@@ -31,6 +31,17 @@ export const HALF_TURN_ICON = {
`,
};
+/** 되돌리기 · 다시하기 아이콘 — **곧은 꼬리 + 갈고리**(↩ ↪ · 요구 241-9). 둥근 화살표(`↶`·`↷`)는
+ * 회전 단추와 헷갈렸다. 종단 도구줄도 같은 그림. */
+export const HISTORY_ICON = {
+ undo: ``,
+ redo: ``,
+};
+
export interface RouteEditChrome {
overlay: HTMLElement;
canvas: HTMLCanvasElement;
@@ -65,9 +76,9 @@ export function createRouteEditChrome(
data-act="hint-toggle" aria-expanded="false" title="조작 도움말 펼치기 · 접기">?
+ title="되돌리기 (Ctrl+Z)" aria-label="되돌리기" disabled>${HISTORY_ICON.undo}
+ title="다시하기 (Ctrl+Y)" aria-label="다시하기" disabled>${HISTORY_ICON.redo}
@@ -79,7 +90,7 @@ export function createRouteEditChrome(
aria-pressed="false" disabled
title="1m 간격 등고선을 얇고 옅게 겹칩니다 (확대하면 보임)">1m 등고선
+ title="도로 끝 · 비탈 끝(깎기 붉음 · 쌓기 청록)을 평면에 겹칩니다">절/성토선
diff --git a/B05_Profile/B05_Profile_UI_RouteEdit_Footprint.ts b/B05_Profile/B05_Profile_UI_RouteEdit_Footprint.ts
index 82faeb7d3..5f10c6989 100644
--- a/B05_Profile/B05_Profile_UI_RouteEdit_Footprint.ts
+++ b/B05_Profile/B05_Profile_UI_RouteEdit_Footprint.ts
@@ -17,14 +17,13 @@ import {
} from "./logic/B05_Profile_Footprint_Strokes";
import "./B05_Profile_UI_Style_RouteEdit_Footprint.css";
-/** 갈래 → 색 토큰 · 대체 색. */
-const STROKE_STYLE: Record = {
- road: ["--b05-footprint-road", "#475569"],
- cut: ["--b05-footprint-cut", "#dc2626"],
- fill: ["--b05-footprint-fill", "#2563eb"],
- slope: ["--b05-footprint-road", "#475569"],
+/** 갈래 → 색 토큰 · 대체 색 · 굵기(px · 비탈 끝이 더 굵음 · 요구 241-10). */
+const STROKE_STYLE: Record = {
+ road: ["--b05-footprint-road", "#475569", 1.8],
+ cut: ["--b05-footprint-cut", "#e11d48", 2.6],
+ fill: ["--b05-footprint-fill", "#0d9488", 2.6],
+ slope: ["--b05-footprint-road", "#475569", 2.6],
};
-const STROKE_WIDTH = 1.4;
let shown = true;
let redraw: (() => void) | null = null;
@@ -77,9 +76,9 @@ export function drawFootprint(
if (!strokes.length) return;
context.save();
context.setLineDash([]);
- context.lineWidth = STROKE_WIDTH;
for (const { kind, points } of strokes) {
- const [token, fallback] = STROKE_STYLE[kind];
+ const [token, fallback, width] = STROKE_STYLE[kind];
+ context.lineWidth = width;
context.strokeStyle = style.getPropertyValue(token).trim() || fallback;
context.beginPath();
points.forEach((vertex, index) => {
diff --git a/B05_Profile/B05_Profile_UI_Style_RouteEdit_Footprint.css b/B05_Profile/B05_Profile_UI_Style_RouteEdit_Footprint.css
index f2e5fa3c0..18781a952 100644
--- a/B05_Profile/B05_Profile_UI_Style_RouteEdit_Footprint.css
+++ b/B05_Profile/B05_Profile_UI_Style_RouteEdit_Footprint.css
@@ -1,20 +1,20 @@
-/* 노선 편집 평면 발자국(PLAN 346-2) — 도로 끝 · 비탈 끝 깎기(붉음) · 쌓기(파랑) */
+/* 노선 편집 평면 발자국(PLAN 346-2) — 도로 끝 · 비탈 끝 깎기(붉음) · 쌓기(청록) */
:root {
--b05-footprint-road: #475569;
- --b05-footprint-cut: #dc2626;
- --b05-footprint-fill: #2563eb;
+ --b05-footprint-cut: #e11d48;
+ --b05-footprint-fill: #0d9488;
}
:root[data-theme="dark"] {
--b05-footprint-road: #cbd5e1;
- --b05-footprint-cut: #f87171;
- --b05-footprint-fill: #60a5fa;
+ --b05-footprint-cut: #ff6b6b;
+ --b05-footprint-fill: #2dd4bf;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--b05-footprint-road: #cbd5e1;
- --b05-footprint-cut: #f87171;
- --b05-footprint-fill: #60a5fa;
+ --b05-footprint-cut: #ff6b6b;
+ --b05-footprint-fill: #2dd4bf;
}
}
diff --git a/resources/tester/helper_282_1_profile_toolbar.cjs b/resources/tester/helper_282_1_profile_toolbar.cjs
index 1fe0671b6..932c18225 100644
--- a/resources/tester/helper_282_1_profile_toolbar.cjs
+++ b/resources/tester/helper_282_1_profile_toolbar.cjs
@@ -103,7 +103,7 @@ const popup = {
// ---- 진짜 도구 묶음 ----
const { createProfileTools } = load(read("B05_Profile", "B05_Profile_UI_Profile_Tools.ts"), {
- require: () => ({ sameRun: () => false }),
+ require: () => ({ sameRun: () => false, HISTORY_ICON: { undo: "", redo: "" } }),
document,
});
const tools = createProfileTools({
diff --git a/resources/tester/test_346_2_footprint_draw.py b/resources/tester/test_346_2_footprint_draw.py
index 26642f4bf..c5c105ba4 100644
--- a/resources/tester/test_346_2_footprint_draw.py
+++ b/resources/tester/test_346_2_footprint_draw.py
@@ -111,3 +111,8 @@ def test_편집기가_발자국을_그리고_단추로_켬끔() -> None:
for token in ("--b05-footprint-road", "--b05-footprint-cut", "--b05-footprint-fill"):
assert token in footprint
assert css.count(f"{token}:") == 3 # 밝음 · 어두움 · 시스템 어두움
+ # 381-1 — 절토 · 성토 테마 색 · 굵게(도로 끝 1.8 · 비탈 끝 2.6)
+ for color in ("#e11d48", "#ff6b6b", "#0d9488", "#2dd4bf"):
+ assert color in css
+ assert '"#e11d48", 2.6]' in footprint and '"#0d9488", 2.6]' in footprint
+ assert 'road: ["--b05-footprint-road", "#475569", 1.8]' in footprint
diff --git a/resources/tester/test_b05_routeedit_chrome_modal.py b/resources/tester/test_b05_routeedit_chrome_modal.py
index 0214f08ef..8cfe246f3 100644
--- a/resources/tester/test_b05_routeedit_chrome_modal.py
+++ b/resources/tester/test_b05_routeedit_chrome_modal.py
@@ -38,8 +38,13 @@ def test_겉틀은_본문_칸():
assert ">저장 전으로" not in chrome and "노선 반영" not in chrome
assert ">취소" not in chrome and ">확인" not in chrome
# 352-2 — 되돌리기 · 다시하기 = 글 없이 기호 + aria-label · title(단축키)
- assert 'aria-label="되돌리기" disabled>↶' in chrome
- assert 'aria-label="다시하기" disabled>↷' in chrome
+ # 381-1 — 곧은 꼬리 + 갈고리 SVG(회전 반 바퀴 그림과 헷갈리지 않게)
+ assert 'aria-label="되돌리기" disabled>${HISTORY_ICON.undo}' in chrome
+ assert 'aria-label="다시하기" disabled>${HISTORY_ICON.redo}' in chrome
+ assert ">↶" not in chrome and ">↷" not in chrome
+ tools = _read("B05_Profile_UI_Profile_Tools.ts")
+ assert "undo.innerHTML = HISTORY_ICON.undo;" in tools
+ assert "redo.innerHTML = HISTORY_ICON.redo;" in tools
assert 'title="되돌리기 (Ctrl+Z)"' in chrome and 'title="다시하기 (Ctrl+Y)"' in chrome
# 시험 · 배선이 집는 자리는 남김
assert "b05-routeedit__measure-close" in chrome