style(B05): 구조물 배치 맨 아래 [추가]·[삭제]·[리셋] 줄 높이 = 상자 안 단추 · 늘 보임(205-1)

- 단추 높이 33 → 26(--b05-control-h) · 스크롤 영역 아래 끝에 붙음
- test_205_1 신규

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015sDZSjFvoiDjdGpgj3muc3
This commit is contained in:
2026-10-10 14:35:29 +09:00
co-authored by Claude Sonnet 5.5
parent d827a15473
commit 8eff5b61e9
2 changed files with 69 additions and 1 deletions
@@ -569,7 +569,7 @@
}
/* 상자 안 작은 단추 템플릿(54-41) — 높이 = 숫자 칸 [-][+](`--b05-control-h`) · 글 · 안 여백도 그 높이에 ·
* 상자 이름표 [삭제]도 같은 틀(136-3) · 상자 밖 [추가] · [삭제] · [리셋]은 제외 */
* 상자 이름표 [삭제]도 같은 틀(136-3) · 상자 밖 [추가] · [삭제] · [리셋]은 아래 205-1 */
.b05-structure__group-body button:not(.b05-structure__step),
.b05-structure__group > legend > button {
box-sizing: border-box;
@@ -580,6 +580,24 @@
line-height: 1;
}
/* 「구조물 배치」 맨 아래 [추가] · [삭제] · [리셋] 줄(205-1) — 단추 높이 = 상자 안 작은 단추(`--b05-control-h`) ·
* 폼이 길어도 스크롤 영역 아래 끝에 붙어 늘 보임(자리 고정 · 뒤 내용이 비치지 않게 불투명 배경) */
.b05-structure-section .b05-route__irregular-actions {
position: sticky;
bottom: 0;
z-index: 1;
background: var(--color-surface-raised);
}
.b05-structure-section .b05-route__irregular-actions > button {
box-sizing: border-box;
height: var(--b05-control-h);
min-height: 0;
padding-block: 0;
font-size: var(--text-caption);
line-height: 1;
}
/* 노면공 「확폭 구간」 상자(PLAN 87-3) — 구간마다 단추 한 줄 */
.b05-structure__widening[hidden] {
display: none;
@@ -0,0 +1,50 @@
"""205-1 「구조물 배치」 맨 아래 [추가] · [삭제] · [리셋] 줄 — 단추 높이 = 상자 안 작은 단추 · 늘 보임.
- 높이 = `--b05-control-h`(상자 안 단추 · 입력 칸과 같은 값) · 상자 이름표 [삭제]와 같은 높이 식
- 줄 = 스크롤 영역 아래 끝에 붙음(sticky · bottom 0) · 단추 · 줄에 hidden · display none · visibility ·
호버 조건이 없음
"""
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
CSS = (ROOT / "B05_Profile/B05_Profile_UI_Style_Structures.css").read_text(encoding="utf-8")
FORM = (ROOT / "B05_Profile/B05_Profile_UI_Structures_Form.ts").read_text(encoding="utf-8")
SECTION = ".b05-structure-section .b05-route__irregular-actions"
def _block(selector: str) -> str:
m = re.search(r"(?m)^" + re.escape(selector) + r"\s*\{([^}]*)\}", CSS)
assert m, selector
return m.group(1)
def _decl(block: str, prop: str) -> str:
m = re.search(r"(?:^|;|\s)" + re.escape(prop) + r"\s*:\s*([^;]+);", block)
assert m, prop
return m.group(1).strip()
def test_buttons_same_height_as_inner_buttons():
outer = _block(SECTION + " > button")
inner = re.search(r"\.b05-structure__group > legend > button\s*\{([^}]*)\}", CSS).group(1)
assert _decl(outer, "height") == "var(--b05-control-h)"
for prop in ("height", "box-sizing", "padding-block", "font-size", "line-height"):
assert _decl(outer, prop) == _decl(inner, prop), prop
assert re.search(r"--b05-control-h:\s*26px;", CSS)
def test_row_always_visible():
row = _block(SECTION)
assert _decl(row, "position") == "sticky"
assert _decl(row, "bottom") == "0"
assert "background" in row
for text in (_block(SECTION), _block(SECTION + " > button")):
assert not re.search(r"display\s*:\s*none|visibility|opacity|overflow", text)
assert not re.search(re.escape(SECTION) + r"[^{]*(:hover|:focus-within|\[hidden\])", CSS)
def test_form_never_hides_buttons():
assert "removeButton.hidden" not in FORM and "resetButton.hidden" not in FORM
assert "actions.hidden" not in FORM