diff --git a/index.html b/index.html
index ab05b81..e60ce11 100644
--- a/index.html
+++ b/index.html
@@ -193,12 +193,9 @@
-
- 형상 (벽체·흉벽, 저판, 말뚝)
-
-
+
상세 (계산값)
diff --git a/src/core/abut/edit.ts b/src/core/abut/edit.ts
index 0018a8e..4cd3048 100644
--- a/src/core/abut/edit.ts
+++ b/src/core/abut/edit.ts
@@ -71,7 +71,7 @@ export function applyShapeEdit(rec: AbutRecord, key: keyof AbutShape, value: num
/** 형상 입력 fields on the 교대 카드 (시안 ② 벽체·흉벽, 확대기초·말뚝), in the order of the mockup. */
export const SHAPE_EDIT_FIELDS: { key: keyof AbutShape; label: string }[] = [
- { key: 'wallFrontMm', label: '벽체 전면 (교대축 기준, mm)' },
+ { key: 'wallFrontMm', label: '교좌면 폭 (흉벽 전면 기준, mm)' },
{ key: 'wallThicknessMm', label: '벽체 두께 (mm)' },
{ key: 'parapetHeightMm', label: '흉벽 높이 (mm)' },
{ key: 'parapetThicknessMm', label: '흉벽 두께 (mm)' },
diff --git a/src/core/abut/summary.ts b/src/core/abut/summary.ts
index cdd5cee..e658229 100644
--- a/src/core/abut/summary.ts
+++ b/src/core/abut/summary.ts
@@ -5,7 +5,7 @@
import type { AbutRecord } from './parse';
import { buildAbut, type AbutModel } from './geometry';
import { toAbutInput } from './parse';
-import { buildMembers } from './members';
+import { buildMembers, type AbutMembers } from './members';
import { buildWings } from './wings';
const m3 = (v: number) => `${v.toFixed(3)} m`;
@@ -76,3 +76,20 @@ export const ABUT_DETAIL_LABELS = [
'말뚝 선단 EL',
'접속슬래브 폭',
];
+
+/** 구간 표 of the 벽체·흉벽 card (시안 하단): one row per 교좌면 step (2026-11-03). Values come from the model and members. */
+export const ABUT_SEGMENT_HEADER = ['구간', '시작 (m)', '끝 (m)', '교좌면 EL (m)', '받침블럭 높이 (mm)', '벽체 높이 (m)'];
+
+export function abutSegmentRows(model: AbutModel, members: AbutMembers): string[][] {
+ const circled = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧'];
+ const bearings = [...model.bearings].sort((a, b) => a.s - b.s);
+ return members.wallSegments.map((seg, k) => [
+ circled[k] ?? String(k + 1),
+ seg.sFrom.toFixed(3),
+ seg.sTo.toFixed(3),
+ seg.seatEl.toFixed(3),
+ String(bearings[k]?.blockHeightMm ?? '—'),
+ (seg.seatEl - members.footingTopEl).toFixed(3),
+ ]);
+}
+
diff --git a/src/main.ts b/src/main.ts
index b2a7720..d64a6f2 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -7,7 +7,7 @@ import { parseWorkbook, type SheetReport } from './core/parseWorkbook';
import { parseAbutments, toAbutInput, type AbutRecord } from './core/abut/parse';
import { buildAbut } from './core/abut/geometry';
import { structureOrder } from './core/abut/order';
-import { ABUT_DETAIL_LABELS, abutInputRows, abutSummaryRows } from './core/abut/summary';
+import { ABUT_DETAIL_LABELS, ABUT_SEGMENT_HEADER, abutInputRows, abutSegmentRows, abutSummaryRows } from './core/abut/summary';
import { applyAbutEdit, applyBearingEdit, applyShapeEdit, ABUT_EDIT_FIELDS, SHAPE_EDIT_FIELDS, restoreAbutDefault, setWingForm } from './core/abut/edit';
import { ABUT_SHAPE_DEFAULT, resolveShape } from './core/abut/shape';
import { abutShown, piersShown } from './core/abut/visibility';
@@ -894,6 +894,25 @@ function fillAbutSlot(slot: (typeof ABUT_SLOTS)[keyof typeof ABUT_SLOTS], rec: A
});
shape.append(lab, input, el('span', `기본 ${ABUT_SHAPE_DEFAULT[f.key]}`, 'muted small'));
}
+ // 구간 표 (시안 하단): one row per 교좌면 step, from the model (2026-11-03).
+ if (planCard) {
+ try {
+ const model = buildAbut(toAbutInput(rec));
+ const members = buildMembers(model, { bottomEl: rec.foundationBottomEl, pileLengthMm: rec.pileLengthMm }, rec.shape);
+ const table = document.createElement('table');
+ table.className = 'abut-seg';
+ const thead = table.createTHead().insertRow();
+ for (const h of ABUT_SEGMENT_HEADER) thead.append(el('th', h));
+ const tbody = table.createTBody();
+ for (const row of abutSegmentRows(model, members)) {
+ const tr = tbody.insertRow();
+ for (const cell of row) tr.append(el('td', cell));
+ }
+ shape.append(table);
+ } catch {
+ // A model that does not build shows no 구간 표 (the errors are reported on import).
+ }
+ }
// 확인 필요 (spec_abut, 시안 오른쪽 패널): the open 교대 questions that touch the shape (2026-11-03).
if (planCard) {
const qa = el('div', undefined, 'abut-qa');
diff --git a/src/style.css b/src/style.css
index c61cded..b5741c2 100644
--- a/src/style.css
+++ b/src/style.css
@@ -895,3 +895,9 @@ body { background: #eef1f4; font-family: 'Noto Sans KR', system-ui, sans-serif;
#abut-panel-plan-shape > .abut-section, #abut-panel-shape > .abut-section, #abut-panel-plan-shape > .abut-qa { grid-column: 1 / -1; }
.abut-qa { border-top: 1px solid #d5dbe2; padding-top: 8px; }
.abut-qa p { margin: 3px 0; }
+
+/* 교대 구간 표 (시안 하단) and the 형상 card shown outside the collapsed editor (2026-11-03). */
+#abut-panel-plan-shape.abut-shape-view { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); gap: 6px 10px; align-items: center; }
+#abut-panel-plan-shape > .abut-seg { grid-column: 1 / -1; width: 100%; border-collapse: collapse; font-size: 12px; }
+#abut-panel-plan-shape > .abut-seg th, #abut-panel-plan-shape > .abut-seg td { border-bottom: 1px solid #e6eaef; padding: 4px 6px; text-align: right; font-family: 'JetBrains Mono', ui-monospace, monospace; }
+#abut-panel-plan-shape > .abut-seg th { color: #55606e; font-weight: 500; font-family: inherit; }