diff --git a/A00_Common/design/design_page.ts b/A00_Common/design/design_page.ts
index bfa6f04c4..dfff7f67f 100644
--- a/A00_Common/design/design_page.ts
+++ b/A00_Common/design/design_page.ts
@@ -49,6 +49,12 @@ import {
peekSectionDetail,
} from "../../B06_Section/B06_Section_Section_Store";
import "./design_page.css";
+// 클래스로 붙이는 부품(체크 · 빈 상태 · 범례 · 보조 글 · 표)의 CSS — B05 · B06 화면 파일이 시험 때문에 import 없이 클래스만 씀(553-2)
+import "@ui/ui_template_checkbox";
+import "@ui/ui_template_empty";
+import "@ui/ui_template_flow_legend";
+import "@ui/ui_template_table";
+import "@ui/ui_template_text";
export type { DesignPageShared } from "./design_shared";
diff --git a/B05_Profile/B05_Profile_UI_IrregularStations.ts b/B05_Profile/B05_Profile_UI_IrregularStations.ts
index ba28b9afb..c5678d42e 100644
--- a/B05_Profile/B05_Profile_UI_IrregularStations.ts
+++ b/B05_Profile/B05_Profile_UI_IrregularStations.ts
@@ -249,7 +249,7 @@ export function createIrregularStationsSection(
const list = document.createElement("ul");
list.className = "b05-route__irregular-list";
const help = document.createElement("p");
- help.className = "b05-route__note";
+ help.className = "ui-text ui-text--muted b05-route__note"; // 부품 보조 글(553-2)
help.textContent =
"구조물을 설치할 위치를 측점번호+잔여거리로 추가합니다. 목록에서 고르면 수정·삭제할 수 있습니다.";
@@ -307,9 +307,13 @@ export function createIrregularStationsSection(
function renderList(): void {
list.replaceChildren();
if (!stations.length) {
+ // 부품 빈 상태 작은 꼴(553-2)
const empty = document.createElement("li");
- empty.className = "b05-route__irregular-empty";
- empty.textContent = "추가된 비정규 측점이 없습니다.";
+ empty.className = "ui-empty ui-empty--small b05-route__irregular-empty";
+ const text = document.createElement("p");
+ text.className = "ui-empty__text";
+ text.textContent = "추가된 비정규 측점이 없습니다.";
+ empty.append(text);
list.append(empty);
return;
}
diff --git a/B05_Profile/B05_Profile_UI_Panel_Fields.ts b/B05_Profile/B05_Profile_UI_Panel_Fields.ts
index 066ca8a4a..7c886b8b3 100644
--- a/B05_Profile/B05_Profile_UI_Panel_Fields.ts
+++ b/B05_Profile/B05_Profile_UI_Panel_Fields.ts
@@ -74,12 +74,17 @@ export function numberField(label: string, value = ""): WrappedInput {
}
export function checkbox(label: string, checked: boolean): WrappedInput {
+ // 부품 「체크」 클래스(553-2) — 시험이 별칭 없이 이 파일을 돌려 클래스로 붙임
const wrapper = document.createElement("label");
- wrapper.className = "b05-route__check";
+ wrapper.className = "ui-checkbox b05-route__check";
const input = document.createElement("input");
input.type = "checkbox";
+ input.className = "ui-checkbox__input";
input.checked = checked;
- wrapper.append(input, document.createTextNode(label));
+ const caption = document.createElement("span");
+ caption.className = "ui-checkbox__text";
+ caption.textContent = label;
+ wrapper.append(input, caption);
return Object.assign(input, { wrapper });
}
diff --git a/B05_Profile/B05_Profile_UI_Panel_Settings.ts b/B05_Profile/B05_Profile_UI_Panel_Settings.ts
index daf80e9aa..d23861941 100644
--- a/B05_Profile/B05_Profile_UI_Panel_Settings.ts
+++ b/B05_Profile/B05_Profile_UI_Panel_Settings.ts
@@ -133,7 +133,7 @@ export function createSettingsPart(callbacks: SettingsPartCallbacks) {
});
});
const criteriaNote = document.createElement("p");
- criteriaNote.className = "b05-route__note";
+ criteriaNote.className = "ui-text ui-text--muted b05-route__note"; // 부품 보조 글(553-2)
const gradeAdvanced = document.createElement("details");
const gradeSummary = document.createElement("summary");
gradeSummary.textContent = "기준값 직접 지정";
diff --git a/B05_Profile/B05_Profile_UI_Profile_CrossModal.css b/B05_Profile/B05_Profile_UI_Profile_CrossModal.css
index 4f7cff4dc..3c5316050 100644
--- a/B05_Profile/B05_Profile_UI_Profile_CrossModal.css
+++ b/B05_Profile/B05_Profile_UI_Profile_CrossModal.css
@@ -10,7 +10,7 @@
width: min(380px, calc(100% - 24px));
padding: var(--spacing-12, 12px);
border: 1px solid var(--color-border);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-cards);
background: var(--color-surface-raised);
color: var(--color-text-body);
box-shadow: 0 4px 16px color-mix(in srgb, var(--color-text-body) 18%, transparent);
@@ -39,7 +39,7 @@
height: 200px;
overflow: hidden;
border: 1px solid var(--color-border);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-inputs);
background: var(--color-surface);
}
diff --git a/B05_Profile/B05_Profile_UI_Profile_MassHaul.ts b/B05_Profile/B05_Profile_UI_Profile_MassHaul.ts
index 33f9f2a81..6f98cb611 100644
--- a/B05_Profile/B05_Profile_UI_Profile_MassHaul.ts
+++ b/B05_Profile/B05_Profile_UI_Profile_MassHaul.ts
@@ -293,9 +293,13 @@ export function createRouteMassHaulPanel(
bar.replaceChildren();
scroll.replaceChildren();
legendLayer.replaceChildren();
- const empty = document.createElement("span");
- empty.className = "b05-profile__masshaul-empty";
- empty.textContent = message;
+ // 부품 빈 상태 작은 꼴(553-2)
+ const empty = document.createElement("div");
+ empty.className = "ui-empty ui-empty--small b05-profile__masshaul-empty";
+ const text = document.createElement("p");
+ text.className = "ui-empty__text";
+ text.textContent = message;
+ empty.append(text);
bar.append(empty);
}
diff --git a/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts b/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts
index f79b34212..bd281e2dc 100644
--- a/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts
+++ b/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts
@@ -135,9 +135,11 @@ export function createRouteEditChrome(
${[
- item("is-ground", "지반선"),
- hasPlan ? item("is-plan", "균형 계획선") : "",
- hasInitial ? item("is-initial", "적용될 초기 종단") : "",
+ const item = (cls: string, kind: string, color: string, name: string): string =>
+ `
${name}`;
+ return `
${[
+ item("is-ground", "line", "var(--draw-text-secondary)", "지반선"),
+ hasPlan ? item("is-plan", "line", "var(--draw-primary)", "균형 계획선") : "",
+ hasInitial ? item("is-initial", "dash", "var(--map-route)", "적용될 초기 종단") : "",
].join("")}
`;
}
-const CANDIDATE_COLUMNS: DataColumn[] = [
- { key: "name", label: "후보" },
- { key: "cut", label: "절토" },
- { key: "fill", label: "성토" },
- { key: "mass", label: "누가토량" },
- { key: "grade", label: "최대 종단경사" },
-];
+const CANDIDATE_COLUMNS = ["후보", "절토", "성토", "누가토량", "최대 종단경사"];
-/** 이 모달에서 셈한 후보들 — 갈래 이름 · 절 · 성 · 누가토량(±) · 최대 종단경사 표. 비면 빈 글. */
+const escapeHtml = (text: string): string =>
+ text.replace(/&/g, "&").replace(//g, ">");
+
+/** 이 모달에서 셈한 후보들 — 갈래 이름 · 절 · 성 · 누가토량(±) · 최대 종단경사 표. 비면 빈 글.
+ * 꼴 = 부품 「표」 데이터표(`ui-table--data` · 553-2) — 이름 칸 왼쪽 · 수 칸 오른쪽. */
export function candidatesTable(rows: Array<[string, BalanceProfile]>): string {
if (!rows.length) return "";
- return renderDataTableHtml({
- columns: CANDIDATE_COLUMNS,
- rows: rows.map(([name, b]) => ({
- name,
- cut: m3(b.cutM3),
- fill: m3(b.fillM3),
- mass: signedM3(b.massEndM3),
- grade: pct(b.maxGradePct),
- })),
+ const end = (i: number): string => (i ? ' class="is-end"' : "");
+ const head = CANDIDATE_COLUMNS.map((label, i) => `
${label} | `);
+ const body = rows.map(([name, b]) => {
+ const cells = [
+ escapeHtml(name),
+ m3(b.cutM3),
+ m3(b.fillM3),
+ signedM3(b.massEndM3),
+ pct(b.maxGradePct),
+ ];
+ return `
${cells.map((cell, i) => `| ${cell} | `).join("")}
`;
});
+ return `
${head.join("")}
${body.join("")}
`;
}
diff --git a/B05_Profile/B05_Profile_UI_Structures_List.ts b/B05_Profile/B05_Profile_UI_Structures_List.ts
index 2570cf353..755186369 100644
--- a/B05_Profile/B05_Profile_UI_Structures_List.ts
+++ b/B05_Profile/B05_Profile_UI_Structures_List.ts
@@ -177,9 +177,13 @@ export function renderStructureList(params: StructureListParams): void {
].sort((left, right) => left.anchor - right.anchor);
if (!rows.length) {
+ // 부품 빈 상태 작은 꼴(553-2)
const empty = document.createElement("li");
- empty.className = "b05-route__irregular-empty";
- empty.textContent = "배치된 구조물이 없습니다.";
+ empty.className = "ui-empty ui-empty--small b05-route__irregular-empty";
+ const text = document.createElement("p");
+ text.className = "ui-empty__text";
+ text.textContent = "배치된 구조물이 없습니다.";
+ empty.append(text);
list.append(empty);
return;
}
diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts b/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts
index aaa4756b0..7ffd8e5dc 100644
--- a/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts
+++ b/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts
@@ -243,7 +243,7 @@ export function markRequired(
const box = entry.input.closest
("[data-option-keys]")?.parentElement;
if (!box || box.querySelector(":scope > .b05-structure__required-note")) continue;
const note = document.createElement("p");
- note.className = "b05-structure__required-note";
+ note.className = "ui-text ui-text--error b05-structure__required-note"; // 부품 상태 글(553-2)
note.textContent = "필수 칸 비어 있음 — [저장] 전 채움";
box.append(note);
}
diff --git a/B05_Profile/B05_Profile_UI_Style.css b/B05_Profile/B05_Profile_UI_Style.css
index ae4585097..b60d85b8b 100644
--- a/B05_Profile/B05_Profile_UI_Style.css
+++ b/B05_Profile/B05_Profile_UI_Style.css
@@ -295,8 +295,7 @@ html.is-bm-route .b05-route__view-controls {
}
.b05-route__panel-body,
-.b05-route__field,
-.b05-route__metrics {
+.b05-route__field {
display: flex;
flex-direction: column;
min-width: 0;
@@ -325,16 +324,14 @@ html.is-bm-route .b05-route__view-controls {
}
.b05-route__field,
-.b05-route__check,
-.b05-route__metrics {
+.b05-route__check {
color: var(--color-text-body);
font-size: var(--text-caption);
}
.b05-route__field input,
.b05-route__field select,
-.b05-route__panel-section > select,
-.b05-route__textarea {
+.b05-route__panel-section > select {
width: 100%;
min-width: 0;
padding: var(--spacing-8);
@@ -392,12 +389,12 @@ html.is-bm-route .b05-route__view-controls {
}
.b05-route__irregular-item:hover {
- border-color: var(--color-royal-amethyst, rgb(109 40 217));
+ border-color: var(--color-accent);
}
.b05-route__irregular-item.is-selected {
- border-color: var(--color-royal-amethyst, rgb(109 40 217));
- background: color-mix(in srgb, var(--color-royal-amethyst, rgb(109 40 217)) 12%, transparent);
+ border-color: var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}
.b05-route__irregular-item strong {
@@ -417,10 +414,8 @@ html.is-bm-route .b05-route__view-controls {
white-space: nowrap;
}
+/* 빈 목록 = 부품 빈 상태 작은 꼴(553-2) */
.b05-route__irregular-empty {
- padding: var(--spacing-4) 0;
- color: var(--color-text-muted);
- font-size: var(--text-caption);
list-style: none;
}
@@ -440,38 +435,6 @@ html.is-bm-route .b05-route__view-controls {
gap: var(--spacing-8);
}
-.b05-route__button-grid,
-.b05-route__palette {
- display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
- min-width: 0;
- gap: var(--spacing-8);
-}
-
-.b05-route__chip {
- padding: var(--spacing-8);
- border: 1px solid var(--color-border);
- border-radius: var(--radius-inputs);
- background: var(--color-surface);
- color: var(--color-text-body);
- font-size: var(--text-caption);
- cursor: pointer;
-}
-
-.b05-route__chip.is-ep,
-.b05-route__chip.is-fp {
- color: var(--color-danger);
-}
-
-.b05-route__chip.is-bp {
- color: var(--color-success);
-}
-
-.b05-route__chip.is-cp,
-.b05-route__stale {
- color: var(--color-warning);
-}
-
/* 사이드 최하단 고정 영역 — 공용 ui-sidebar-actions(sticky·배경·상단 구분선)를 그대로
쓰되, 안쪽은 [구조물 목록][중간 구분선][액션 버튼 행] 세로 배치로 되돌린다
(2026-08-18 사용자 지시). */
@@ -494,23 +457,12 @@ html.is-bm-route .b05-route__view-controls {
flex: 1;
}
-.b05-route__stale {
- font-size: var(--text-caption);
- font-weight: var(--font-weight-medium);
-}
-
.b05-route__panel details {
color: var(--color-text-body);
font-size: var(--text-caption);
}
-/* 계획선 설계 폼 안내문 */
-.b05-route__note {
- margin: 0;
- color: var(--color-text-muted, var(--color-plum-velvet));
- font-size: var(--text-caption);
- line-height: 1.4;
-}
+/* 계획선 설계 폼 안내문 = 부품 보조 글(553-2) */
/* 종단면도 상단 절·성토 균형 지표 바 */
.b05-route-profile__balance {
@@ -536,31 +488,31 @@ html.is-bm-route .b05-route__view-controls {
}
.b05-route-profile__balance-item em {
- color: var(--color-text-muted, var(--color-plum-velvet));
+ color: var(--color-text-muted);
font-style: normal;
}
.b05-route-profile__balance-item.is-cut em {
- color: rgb(220 38 38);
+ color: var(--color-danger);
}
.b05-route-profile__balance-item.is-fill em {
- color: rgb(37 99 235);
+ color: var(--color-info);
}
.b05-route-profile__balance-item.is-over,
.b05-route-profile__balance-item.is-unsaved {
- color: rgb(180 83 9);
+ color: var(--color-warning);
font-weight: var(--font-weight-medium);
}
.b05-route-profile__balance-item.is-edited em {
- color: var(--color-royal-amethyst, rgb(109 40 217));
+ color: var(--color-accent);
}
.b05-route-profile__balance-warning {
overflow: hidden;
- color: rgb(180 83 9);
+ color: var(--color-warning);
text-overflow: ellipsis;
}
diff --git a/B05_Profile/B05_Profile_UI_Style_MassHaul.css b/B05_Profile/B05_Profile_UI_Style_MassHaul.css
index 81aa3736b..e912ce858 100644
--- a/B05_Profile/B05_Profile_UI_Style_MassHaul.css
+++ b/B05_Profile/B05_Profile_UI_Style_MassHaul.css
@@ -62,7 +62,7 @@
height: var(--b05-masshaul-height, 280px);
border-top: 1px solid var(--color-border);
background: var(--color-surface-raised);
- box-shadow: 0 -4px 12px rgb(0 0 0 / 18%);
+ box-shadow: var(--shadow-lg);
}
/* 공용 리사이저는 절대배치라 오버레이 위 경계에 그대로 앉는다. */
@@ -134,10 +134,9 @@
pointer-events: none;
}
+/* 빈 곡선 = 부품 빈 상태 작은 꼴(553-2) · 옆 여백만 */
.b05-profile__masshaul-empty {
- padding: var(--spacing-8) var(--spacing-16);
- color: var(--color-text-secondary);
- font-size: var(--text-caption);
+ padding-inline: var(--spacing-16);
}
/* 2차 슬라이드 손잡이 — 다른 패널들과 **같은 표준 삼각형 손잡이**를 그대로 쓴다
@@ -174,7 +173,7 @@
height: var(--b05-table-height, 204px);
border-top: 1px solid var(--color-border);
background: var(--color-surface-raised);
- box-shadow: 0 -4px 12px rgb(0 0 0 / 18%);
+ box-shadow: var(--shadow-lg);
}
.b05-profile__table-overlay > .ui-resizer--vertical {
diff --git a/B05_Profile/B05_Profile_UI_Style_RouteEdit.css b/B05_Profile/B05_Profile_UI_Style_RouteEdit.css
index f0b92666f..a7da0314e 100644
--- a/B05_Profile/B05_Profile_UI_Style_RouteEdit.css
+++ b/B05_Profile/B05_Profile_UI_Style_RouteEdit.css
@@ -46,7 +46,7 @@
.b05-routeedit__hint-body,
.b05-routeedit__info {
border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-cards);
background: color-mix(in srgb, var(--color-surface-raised) 72%, transparent);
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
@@ -153,20 +153,9 @@
white-space: nowrap;
}
-.b05-routeedit__legend i {
- display: inline-block;
- width: 22px;
- height: 0;
- margin-right: 2px;
- vertical-align: middle;
-}
-
-.b05-routeedit__legend i.is-expected {
- border-top: 2px dashed var(--color-text-secondary, #9ca3af);
-}
-
-.b05-routeedit__legend i.is-planned {
- border-top: 2px solid var(--map-route, #f97316);
+/* 범례 = 부품 「범례」 세로(553-2) · 줄 사이만 붙임 */
+.b05-routeedit__legend.ui-legend {
+ gap: 0;
}
/* 오른쪽 덮는 판 — 패널 양식(382-1 · `ui_template_side_panels` · 손잡이 · 머리 · 폭 끌기) 을 지도 위에 얹음 ·
@@ -193,7 +182,7 @@
}
.b05-routeedit__side-wrap .ui-side-panels__panel {
- box-shadow: 0 12px 40px rgb(0 0 0 / 45%);
+ box-shadow: var(--shadow-lg);
}
.b05-routeedit__side-wrap .ui-side-panels__body {
@@ -261,7 +250,7 @@
overflow: hidden;
width: 100%;
border: 1px solid var(--color-border);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-cards);
background: var(--color-surface);
}
@@ -363,7 +352,7 @@
height: 32px;
padding: 0 var(--spacing-8);
border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-cards);
background: color-mix(in srgb, var(--color-surface-raised) 72%, transparent);
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
@@ -395,8 +384,8 @@
gap: var(--spacing-8);
max-width: var(--b05-bottom-half);
padding: var(--spacing-8) var(--spacing-12);
- border: 1px solid color-mix(in srgb, #22c55e 60%, transparent);
- border-radius: var(--radius-8, 6px);
+ border: 1px solid color-mix(in srgb, var(--color-success) 60%, transparent);
+ border-radius: var(--radius-cards);
background: color-mix(in srgb, var(--color-surface-raised) 82%, transparent);
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
@@ -430,7 +419,7 @@
align-items: center;
justify-content: center;
padding: var(--spacing-16);
- background: rgb(0 0 0 / 55%);
+ background: var(--color-scrim);
color: #fff;
text-align: center;
}
@@ -448,12 +437,12 @@
min-width: 12rem;
padding: var(--spacing-8);
border: 1px solid var(--color-border);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-cards);
/* 모달 본체와 **같은 토큰**을 쓴다 — `--color-surface-2` 는 이 테마에 없어 밝은
기본값으로 떨어지면서 다크 화면에서 글자가 안 읽혔다(2026-09-07 실화면). */
background: var(--color-surface-raised);
color: var(--color-text-body);
- box-shadow: 0 4px 14px rgb(0 0 0 / 45%);
+ box-shadow: var(--shadow-lg);
font-size: var(--text-caption);
}
diff --git a/B05_Profile/B05_Profile_UI_Style_RouteRecommend.css b/B05_Profile/B05_Profile_UI_Style_RouteRecommend.css
index 55ccb906e..2a3cd930a 100644
--- a/B05_Profile/B05_Profile_UI_Style_RouteRecommend.css
+++ b/B05_Profile/B05_Profile_UI_Style_RouteRecommend.css
@@ -76,7 +76,7 @@
margin-bottom: var(--spacing-8);
padding: var(--spacing-8);
border: 1px solid transparent;
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-inputs);
}
/* 고른 갈래 — 알약과 같은 강조색 테두리. */
@@ -227,7 +227,7 @@
height: 460px;
overflow: hidden;
border: 1px solid var(--color-border);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-inputs);
background: var(--color-surface);
}
@@ -244,34 +244,11 @@
font-size: var(--text-body-sm);
}
-.b05-routerec__legend {
- display: flex;
- flex-wrap: wrap;
- gap: var(--spacing-12);
- color: var(--color-text-secondary);
- font-size: var(--text-body-sm);
-}
-
-.b05-routerec__legend i {
- display: inline-block;
- width: 22px;
- margin-right: 6px;
- vertical-align: middle;
-}
-
-.b05-routerec__legend i.is-expected {
- border-top: 2px dashed var(--color-text-secondary, #9ca3af);
-}
-
-.b05-routerec__legend i.is-current {
- border-top: 2px solid var(--map-route, #f97316);
+/* 범례 = 부품 「범례」(553-2) · 창을 연 노선은 지도처럼 흐림 */
+.b05-routerec__legend .is-current {
opacity: 0.55;
}
-.b05-routerec__legend i.is-preview {
- border-top: 3px solid var(--color-primary);
-}
-
/* 옵션 겹창 — 지도 왼쪽 위 작은 칸(회전 단추는 오른쪽 위 · PLAN 77-4). 지도 끌기를 막지 않게 제 칸만. */
.b05-routerec__side {
position: absolute;
@@ -286,9 +263,9 @@
overflow: auto;
padding: var(--spacing-8);
border: 1px solid var(--color-border);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-inputs);
background: color-mix(in srgb, var(--color-surface) 92%, transparent);
- box-shadow: var(--shadow-sm, 0 2px 6px rgb(0 0 0 / 0.15));
+ box-shadow: var(--shadow-sm);
color: var(--color-text-body);
font-size: var(--text-caption);
}
@@ -326,16 +303,11 @@
accent-color: var(--color-primary);
}
-/* 값 칸 — 슬라이더 옆에서 숫자를 직접 넣는다. 합 100 을 못 맞추면 빨간 테두리. */
-.b05-routerec__num {
+/* 값 칸 = 부품 입력 단 32(553-2) — 슬라이더 옆에서 숫자를 직접 넣는다. 합 100 을 못 맞추면 빨간 테두리. */
+.b05-routerec__num.ui-input {
width: 100%;
min-width: 3.2em;
- padding: 2px 4px;
- border: 1px solid var(--color-border);
- border-radius: var(--radius-4, 4px);
- background: var(--color-surface);
- color: var(--color-text-body);
- font-size: var(--text-body);
+ padding-inline: 4px;
font-weight: 600;
text-align: center;
appearance: textfield;
@@ -353,8 +325,8 @@
}
.b05-routerec__num.is-invalid {
- border-color: var(--color-danger, #dc2626);
- box-shadow: 0 0 0 1px var(--color-danger, #dc2626);
+ border-color: var(--color-danger);
+ box-shadow: 0 0 0 1px var(--color-danger);
}
/* 저절로 정해진 비중은 고정 단추가 눌린 채 꺼져(잠김 표시) — 색은 공용 꼴(`ui-btn--glass`)을 쓴다. */
@@ -401,15 +373,10 @@
color: var(--color-text-body);
}
-.b05-routerec__criteria input,
-.b05-routerec__target input {
+/* 제약 칸 = 부품 입력 단 32(553-2) — 자리 · 오른쪽 맞춤만 */
+.b05-routerec__criteria input.ui-input,
+.b05-routerec__target input.ui-input {
width: 100%;
- padding: 4px 8px;
- border: 1px solid var(--color-border);
- border-radius: var(--radius-4, 4px);
- background: var(--color-surface);
- color: var(--color-text-body);
- font-size: var(--text-body);
text-align: right;
}
@@ -497,7 +464,7 @@
width: 100%;
height: 96px;
border: 1px solid var(--color-border);
- border-radius: var(--radius-8, 6px);
+ border-radius: var(--radius-inputs);
background: var(--color-surface);
}
@@ -521,47 +488,17 @@
stroke-dasharray: 6 3;
}
+/* 그림 범례 = 부품 「범례」(553-2) */
.b05-routerec__plegend {
- display: flex;
- gap: var(--spacing-12);
- margin-top: var(--spacing-4, 4px);
- color: var(--color-text-secondary);
- font-size: var(--text-caption);
-}
-
-.b05-routerec__plegend i {
- display: inline-block;
- width: 16px;
- margin-right: var(--spacing-4, 4px);
- vertical-align: middle;
- border-top: 2px solid var(--color-text-secondary);
-}
-
-.b05-routerec__plegend i.is-plan {
- border-top-color: var(--color-primary);
-}
-
-.b05-routerec__plegend i.is-initial {
- border-top: 2px dashed var(--map-route, #f97316);
+ margin-top: var(--spacing-4);
}
/* 이 모달에서 셈한 후보 표 — 절 · 성 · 반입 · 최대 종단경사. */
-.b05-routerec__cands table {
- width: 100%;
- border-collapse: collapse;
- font-size: var(--text-caption);
+/* 후보 표 = 부품 표 데이터표(553-2) — 수 칸 자리 맞춤 · 한 줄 */
+.b05-routerec__cands .ui-table {
font-variant-numeric: tabular-nums;
}
-.b05-routerec__cands th,
-.b05-routerec__cands td {
- padding: 2px var(--spacing-8);
- border-bottom: 1px solid var(--color-border);
- text-align: right;
+.b05-routerec__cands .ui-table td {
white-space: nowrap;
}
-
-.b05-routerec__cands th[scope="row"],
-.b05-routerec__cands thead th:first-child {
- text-align: left;
-}
diff --git a/B05_Profile/B05_Profile_UI_Style_Structures.css b/B05_Profile/B05_Profile_UI_Style_Structures.css
index 28c3d3d71..46e035862 100644
--- a/B05_Profile/B05_Profile_UI_Style_Structures.css
+++ b/B05_Profile/B05_Profile_UI_Style_Structures.css
@@ -51,7 +51,7 @@
padding: 0 7px;
border-radius: 9px;
border: 1.5px solid currentColor;
- background: var(--color-surface, #fff);
+ background: var(--color-surface);
font-size: 10px;
font-weight: 700;
line-height: 1;
@@ -117,8 +117,8 @@
padding: 4px 8px;
border: 1.5px solid currentColor;
border-radius: 6px;
- background: var(--color-surface, #fff);
- box-shadow: 0 2px 6px rgb(0 0 0 / 18%);
+ background: var(--color-surface);
+ box-shadow: var(--shadow-sm);
font-size: 11px;
line-height: 1.35;
white-space: nowrap;
@@ -161,7 +161,7 @@
.b05-structure__group {
margin: 0;
padding: 6px 8px 8px;
- border: 1px solid var(--border-color, #3a3f4a);
+ border: 1px solid var(--color-border);
border-radius: 6px;
}
@@ -197,7 +197,7 @@
height: 0;
margin: 2px 0;
border: 0;
- border-top: 1px solid var(--color-border, #3a3f4a);
+ border-top: 1px solid var(--color-border);
}
/* 「제원·수량은 다른 화면이 냅니다」 안내 — 경고가 아니라 안내라 색은 흐리게,
@@ -205,9 +205,9 @@
.b05-structure__owner-note {
margin: 0;
padding: 4px 0 4px 8px;
- border-left: 2px solid var(--color-border, #3a3f4a);
- color: var(--color-text-muted, #9aa1ad);
- font-size: var(--text-caption, 12px);
+ border-left: 2px solid var(--color-border);
+ color: var(--color-text-muted);
+ font-size: var(--text-caption);
line-height: 1.5;
}
@@ -236,20 +236,18 @@
/* 측점 입력이 형식에 안 맞을 때(예: "3+18.0"도 숫자도 아님) 칸을 붉힌다. */
.b05-route__field input.is-invalid {
- border-color: #e05b5b;
- background: rgba(224, 91, 91, 0.08);
+ border-color: var(--color-danger);
+ background: color-mix(in srgb, var(--color-danger) 8%, transparent);
}
/* 빈 필수 칸 — 칸 테두리 + 그 칸이 든 상자 안 안내 한 줄(54-12) */
.b05-route__field .is-required-empty {
- border-color: #e05b5b;
+ border-color: var(--color-danger);
}
+/* 상태 글 = 부품 보조 글 오류 꼴(553-2) */
.b05-structure__required-note {
grid-column: 1 / -1;
- margin: 0;
- color: #e05b5b;
- font-size: var(--text-caption, 12px);
}
/* 측점 범위(계산 표시) — C군 등 길이 옵션 기반 구간 타입. 입력 칸이 아니라 기준
@@ -365,15 +363,6 @@
font-size: var(--text-caption);
}
-/* 물넘이·세월교 개략 단면 결과 — 읽어 보는 안내문이라 입력 칸보다 작게 둔다
- (2026-08-30 사용자: 글자가 너무 크다). */
-.b05-drainage__facility-note {
- margin: 0;
- font-size: 10px;
- line-height: 1.4;
- opacity: 0.75;
-}
-
/* 스텝 묶음과 그 안의 버튼·숫자칸도 같은 높이로 선다. */
.b05-structure__stepper {
height: var(--b05-control-h);
@@ -419,7 +408,7 @@
/* 전면 기울기가 품셈 표준경사 표(0.20~0.50) 밖일 때 — 실무가 S0.7 을 쓰므로 **막지 않고**
테두리로만 알린다(2026-09-09). 말풍선에 까닭이 들어 있다. */
.is-outside-standard {
- border-color: var(--color-warning, #c98a00);
+ border-color: var(--color-warning);
}
/* 구조물 조합 잇기 줄(PLAN 21-4 · 54-17) — 옵션 칸 꼴(`b05-route__field`) 2행 · 아래 줄은
diff --git a/B05_Profile/B05_Profile_UI_Style_Table.css b/B05_Profile/B05_Profile_UI_Style_Table.css
index 6dd46cdc8..d74f1f7b3 100644
--- a/B05_Profile/B05_Profile_UI_Style_Table.css
+++ b/B05_Profile/B05_Profile_UI_Style_Table.css
@@ -18,7 +18,7 @@
flex: 0 0 auto;
flex-direction: column;
min-height: 0;
- border-top: 2px solid var(--color-text-muted, var(--color-plum-velvet));
+ border-top: 2px solid var(--color-text-muted);
color: var(--color-text-body);
/* 행 높이와 셀 폭에 맞춰 렌더러가 계산해 넣는다 (createProfileTable). */
font-size: var(--b05-table-font, 11px);
@@ -37,7 +37,7 @@
/* 구배 / 측점값 / 곡선 묶음의 시작 행은 굵은 선으로 그룹을 구분한다. */
.b05-profile-table__row.is-group-start {
- border-top: 2px solid var(--color-text-muted, var(--color-plum-velvet));
+ border-top: 2px solid var(--color-text-muted);
}
.b05-profile-table__row--grade {
@@ -62,7 +62,7 @@
width: var(--b05-table-label-width, 60px);
height: 100%;
padding-inline: var(--spacing-16) var(--spacing-4);
- border-right: 2px solid var(--color-text-muted, var(--color-plum-velvet));
+ border-right: 2px solid var(--color-text-muted);
background: var(--color-surface-raised);
color: var(--color-text);
font-size: var(--b05-table-label-font, inherit);
@@ -121,15 +121,15 @@
}
.b05-profile-table__row.is-cut .b05-profile-table__cell {
- color: rgb(220 38 38);
+ color: var(--color-danger);
}
.b05-profile-table__row.is-fill .b05-profile-table__cell {
- color: rgb(37 99 235);
+ color: var(--color-info);
}
.b05-profile-table__row.is-plan .b05-profile-table__cell {
- color: var(--color-royal-amethyst, rgb(109 40 217));
+ color: var(--color-accent);
font-weight: var(--font-weight-medium);
}
@@ -146,8 +146,8 @@
}
.b05-profile-table__segment.is-violation {
- background: color-mix(in srgb, rgb(220 38 38) 12%, transparent);
- color: rgb(180 83 9);
+ background: color-mix(in srgb, var(--color-danger) 12%, transparent);
+ color: var(--color-warning);
}
/* 구배 블록 값. 가로로 안 들어가면 90도 회전해 좁은 블록에도 값을 표기한다. */
@@ -223,12 +223,8 @@
display: flex;
flex-direction: column;
box-sizing: border-box;
- border-inline: 1px solid var(--color-royal-amethyst, rgb(109 40 217));
- background: color-mix(
- in srgb,
- var(--color-royal-amethyst, rgb(109 40 217)) 14%,
- var(--color-surface)
- );
+ border-inline: 1px solid var(--color-accent);
+ background: color-mix(in srgb, var(--color-accent) 14%, var(--color-surface));
transform: translateX(-50%);
/* 열 자체는 클릭을 통과시키고, 입력 셀만 pointer-events를 되살린다(작업6). */
pointer-events: none;
@@ -240,7 +236,7 @@
border-inline-width: 2px;
box-shadow:
0 0 0 1px var(--color-surface-raised),
- 0 4px 12px rgb(0 0 0 / 28%);
+ var(--shadow-lg);
}
.b05-profile-table__irregular-col-cell {
@@ -281,11 +277,11 @@
}
.b05-profile-table__irregular-col-cell.is-cut {
- color: rgb(220 38 38);
+ color: var(--color-danger);
}
.b05-profile-table__irregular-col-cell.is-fill {
- color: rgb(37 99 235);
+ color: var(--color-info);
}
/* MC 측점 이름(507-3 덧) — 굵게 · 경고색 */
@@ -315,7 +311,7 @@
.b05-profile-table__irregular-input:focus,
.b05-profile-table__irregular-input:hover {
- border-color: var(--color-royal-amethyst, rgb(109 40 217));
+ border-color: var(--color-accent);
background: var(--color-surface);
}
diff --git a/resources/tester/helper_349_drainage_live_flow.cjs b/resources/tester/helper_349_drainage_live_flow.cjs
index 894f40bcc..55c7f7cd3 100644
--- a/resources/tester/helper_349_drainage_live_flow.cjs
+++ b/resources/tester/helper_349_drainage_live_flow.cjs
@@ -34,6 +34,9 @@ function el(tag) {
replaceChildren(...kids) {
this.children = kids;
},
+ setAttribute(name, value) {
+ (this.attrs ??= {})[name] = String(value);
+ },
addEventListener(type, fn) {
(this.listeners[type] ??= []).push(fn);
},
diff --git a/resources/tester/helper_510_propose.cjs b/resources/tester/helper_510_propose.cjs
index 539268144..ad3608fe1 100644
--- a/resources/tester/helper_510_propose.cjs
+++ b/resources/tester/helper_510_propose.cjs
@@ -24,6 +24,9 @@ function el(tag) {
node.children = [];
node.append(...items);
},
+ setAttribute(name, value) {
+ (this.attrs ??= {})[name] = String(value);
+ },
addEventListener(type, fn) {
(listeners[type] ??= []).push(fn);
},
diff --git a/resources/tester/test_63_4_route_profile.py b/resources/tester/test_63_4_route_profile.py
index 3f77662cf..03193841d 100644
--- a/resources/tester/test_63_4_route_profile.py
+++ b/resources/tester/test_63_4_route_profile.py
@@ -122,6 +122,6 @@ def test_균형_종단은_캐시에_안_남는다() -> None:
assert result["svg"].count("토공 최소" in result["table"]
assert (
- '누가토량 | ' in result["table"]
+ '누가토량 | ' in result["table"] # 부품 표(553-2)
and "반입" not in result["table"]
)