Files
Pier_v1/DOC/01_기획/웹앱디자인시안/design.md
T
ahnyongjooandClaude Sonnet 5.5 964a841de1 chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환
- Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용
- pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관)
- worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md)
- D:\Rhino-MCP 경로 참조를 새 위치로 치환

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 11:20:18 +09:00

741 lines
39 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# T형 교각 모델링 앱 디자인 시스템 — Prism 앱 프로파일
| 버전 | 수정일 | 수정자 | 주요 변경 내용 | 비고 |
| :--- | :--- | :--- | :--- | :--- |
| v0.1.00 | 2026-10-15 | 심영표 | 신규 작성 — Prism Design System v0.1.1을 교각 모델링 앱에 적용하는 프로파일(토큰·상태 체계·조합 컴포넌트·문안·점검표) | 초안 `[미확정]`. PRD v0.1.00의 화면 13종이 소비한다 |
| v0.1.01 | 2026-10-15 | 심영표 | PRD UX1~UX6 결정 반영: R8 대체 확정, Pretendard 내장 파일 지정, 마커 도형 승인, 다크 시험 제외 | 사용자 결정 |
| 메타 | 값 |
| :--- | :--- |
| 문서 | 앱 프로파일 (Prism 4계층 중 **Layer 3 모듈의 앱 한정 보강**) |
| 상위 | `RAG/design system_v0.1.1/` — `Design.md` 0.1.1 · `design.tokens.json` 0.1.1 · `design.foundations.md` · `design.medium.screen.md` · `design.components.md` · `webapp/module.webapp.md` 0.1.0 |
| 브랜드 | `saman` (활성). 앱 전용 브랜드를 새로 만들지 않는다 |
| 매체 | `screen.web` (로컬 데스크톱, 1280px 이상) |
| 독자 | 화면을 구현하는 에이전트와 개발자(1차), 디자이너(2차) |
| 짝 문서 | `PRD.md` (같은 폴더) — 이 문서의 규칙이 어느 화면에서 쓰이는지는 PRD 5장이 정한다 |
---
## 1. 위치와 우선순위
### 1.1 목적
PRD의 13개 화면을 **같은 부품과 같은 규칙으로** 만들도록 디자인을 시스템으로 묶는다. 이 문서는 Prism을 대체하지 않고, Prism이 정하지 않은 앱 고유의 부분(상태 어휘의 형태 부호, 조합 컴포넌트, 문안)만 더한다.
### 1.2 값 충돌 우선순위
Prism `Design.md` 1.4절을 그대로 따른다.
| 순위 | 출처 |
| :-: | :--- |
| 1 | 사용자의 명시적 지시(해당 화면 한정) |
| 2 | `design.tokens.json` 정식값 |
| 3 | Prism 각 `.md`의 표·수치 |
| 4 | **이 문서** — Prism과 충돌하면 Prism이 이긴다 |
> 이 문서의 어느 규칙이 Prism과 충돌하면 이 문서를 고친다. 충돌을 해소하려고 Prism 값을 바꾸지 않는다.
### 1.3 기존 기준(R8)과의 관계
`context-migration/디자인지침_경로.md`의 R8(2026-10-12)은 조직 디자인 지침이 없던 때의 대체 수용 기준이다(맑은 고딕 14px, 흰 배경, 철근 팔레트 판정색). R8은 2026-10-15에 **대체되었다**(PRD 11.2절 UX1, `디자인지침_경로.md` 갱신). 두 기준이 같이 적용되는 기간을 두지 않는다.
R8에서 **유지하는** 조건은 세 가지이다.
| R8 조건 | 이 문서에서 |
| :--- | :--- |
| 색과 글자를 함께 쓴다(색만으로 구분 금지) | 6장으로 강화(형태 부호 추가) |
| 1280px 폭에서 표 외 가로 스크롤 없음 | 4.2절 |
| 화면 문구 한국어 | 9장 |
철근 팔레트(D32 적·D29 주황 등)는 **Rhino 모델 철근과 범례 전용**이다. 화면의 판정·상태 표시에는 쓰지 않는다.
---
## 2. 모듈 선언
```yaml
module:
id: pier-app
name: T형 교각 모델링 앱
base_module: webapp # RAG/design system_v0.1.1/webapp/module.webapp.md
brand: saman
medium: screen
medium_variant: screen.web
dual_medium: false
format: desktop-first # lg(1240~1599) 기준 설계, md 이하는 지원하되 시험 제외
min_width_px: 1280
columns: 12
type_set: compact
patterns: [w1-shell, w2-dashboard, w3-form, w4-document, w5-list-detail]
color_theme: [light, dark] # light 기본, dark는 토큰만 정의
accessibility: WCAG 2.2 AA
depends_on: { design_system: 0.1.1, webapp_module: 0.1.0 }
```
화면별 패턴 배정(Prism webapp 10절 1단계)은 PRD 3.2절 일람의 '패턴' 열을 따른다.
---
## 3. 토큰
### 3.1 원칙
| ID | 규칙 |
| :--- | :--- |
| **TK-1** | 산출물 CSS는 **변수 정의부 밖에 HEX·px 리터럴을 두지 않는다** (Prism W1·W2). 보더·헤어라인도 stroke 토큰을 쓴다 |
| **TK-2** | 3.2절 `prism.sys` 블록은 Prism `webapp` 3절의 정본을 **그대로** 옮긴 것이다. 값을 고치지 않는다 |
| **TK-3** | 3.3절 `comp` 토큰은 `sys`·`ref`만 참조한다. 리터럴을 두지 않는다 |
| **TK-4** | `ref` 토큰(원색)은 컴포넌트에서 직접 참조하지 않는다 |
| **TK-5** | 철근 팔레트는 UI 토큰이 아니다. Rhino 범례 이미지로만 쓴다 |
| **TK-6** | 새 토큰이 필요하면 `comp` 계층에 추가하고 이 문서의 버전을 올린다. `sys` 이하는 건드리지 않는다 |
### 3.2 sys 토큰 (Prism 정본, 수정 금지)
```css
:root {
/* color (light) */
--prism-bg-canvas: #F4F3F0;
--prism-bg-card: #FFFFFF;
--prism-text-body: #474235;
--prism-text-heading: #1F524B;
--prism-text-subtle: #474235;
--prism-text-accent: #D05C26; /* 대형 전용(24px 이상 또는 19px 이상 Bold) */
--prism-border-default: #474235;
--prism-border-strong: #1F524B;
--prism-status-do: #005A4E; --prism-status-do-bg: #DCEAE6;
--prism-status-dont: #8F2A11; --prism-status-dont-bg: #F6DFDA;
--prism-status-caution: #6B4A00; --prism-status-caution-bg: #F5E7CC;
--prism-status-tip: #0A4E86; --prism-status-tip-bg: #DDE8F3;
/* space (기본 8px = 0.5rem) */
--prism-space-025: 0.125rem; --prism-space-050: 0.25rem; --prism-space-100: 0.5rem;
--prism-space-150: 0.75rem; --prism-space-200: 1rem; --prism-space-300: 1.5rem;
--prism-space-400: 2rem; --prism-space-600: 3rem; --prism-space-800: 4rem;
/* type */
--prism-type-caption: 0.8125rem; --prism-lh-caption: 1.55;
--prism-type-body-sm: 0.875rem; --prism-lh-body: 1.70;
--prism-type-body: 1rem; --prism-type-body-lg: 1.125rem;
--prism-type-title-sm: 1.25rem; --prism-lh-title: 1.50;
--prism-type-title: 1.625rem; --prism-type-title-lg: 2rem;
/* radius · stroke · z · motion · focus · measure */
--prism-radius-sm: 4px; --prism-radius-md: 8px; --prism-radius-lg: 12px; --prism-radius-pill: 9999px;
--prism-stroke-hairline: 1px; --prism-stroke-regular: 2px; --prism-stroke-bold: 3px;
--prism-z-raised: 100; --prism-z-sticky: 200; --prism-z-dropdown: 300; --prism-z-scrim: 400;
--prism-z-modal: 500; --prism-z-popover: 600; --prism-z-toast: 700; --prism-z-tooltip: 800;
--prism-scrim: rgba(0, 0, 0, 0.32);
--prism-motion-fast: 100ms; --prism-motion-moderate: 200ms; --prism-motion-slow: 300ms;
--prism-ease-standard: cubic-bezier(0.2, 0, 0, 1);
--prism-focus-ring: 3px; --prism-focus-offset: 2px;
--prism-measure-max: 38em;
}
:root[data-theme="dark"] {
--prism-bg-canvas: #111111; --prism-bg-card: #111111;
--prism-text-body: #F4F3F0; --prism-text-heading: #F4F3F0; /* 다크에서 그린 텍스트 금지 */
--prism-text-subtle: #D3D3D3; --prism-text-accent: #D05C26;
--prism-border-default: #D3D3D3; --prism-border-strong: #F4F3F0;
--prism-status-do: #DCEAE6; --prism-status-do-bg: #005A4E;
--prism-status-dont: #F6DFDA; --prism-status-dont-bg: #8F2A11;
--prism-status-caution: #F5E7CC; --prism-status-caution-bg: #6B4A00;
--prism-status-tip: #DDE8F3; --prism-status-tip-bg: #0A4E86;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) { /* data-theme dark 블록과 같은 값 세트를 적용 */ }
}
```
Prism 토큰 파일에 있는 `--prism-dv-*`(데이터 시각화 6색), `--prism-type-display*`, `--prism-ease-enter/exit`는 이 앱에서 쓰지 않아 옮기지 않는다. 쓰게 되면 정본에서 그대로 옮긴다.
### 3.3 comp 토큰 (앱 전용, 이 문서가 정의)
모두 `sys`를 참조한다. 라이트·다크 전환은 `sys` 값이 바뀌므로 `comp`는 두 번 정의하지 않는다.
```css
:root {
/* 표면 */
--prism-comp-surface-page: var(--prism-bg-canvas);
--prism-comp-surface-card: var(--prism-bg-card);
--prism-comp-surface-sunken: var(--prism-bg-canvas);
--prism-comp-line: var(--prism-border-default);
--prism-comp-line-strong: var(--prism-border-strong);
/* 상태색 4쌍의 앱 의미 */
--prism-comp-state-good-fg: var(--prism-status-do); --prism-comp-state-good-bg: var(--prism-status-do-bg);
--prism-comp-state-bad-fg: var(--prism-status-dont); --prism-comp-state-bad-bg: var(--prism-status-dont-bg);
--prism-comp-state-warn-fg: var(--prism-status-caution); --prism-comp-state-warn-bg: var(--prism-status-caution-bg);
--prism-comp-state-info-fg: var(--prism-status-tip); --prism-comp-state-info-bg: var(--prism-status-tip-bg);
/* 배지 */
--prism-comp-badge-pad-y: var(--prism-space-025);
--prism-comp-badge-pad-x: var(--prism-space-100);
--prism-comp-badge-radius: var(--prism-radius-sm);
--prism-comp-badge-font: var(--prism-type-caption);
--prism-comp-badge-line-solid: var(--prism-stroke-regular);
--prism-comp-badge-line-bold: var(--prism-stroke-bold);
/* 표 */
--prism-comp-table-cell-pad-y: var(--prism-space-100);
--prism-comp-table-cell-pad-x: var(--prism-space-150);
--prism-comp-table-font: var(--prism-type-body-sm);
--prism-comp-table-head-bg: var(--prism-bg-canvas);
--prism-comp-table-rule: var(--prism-stroke-hairline);
/* 레이아웃 */
--prism-comp-rail-width: 15rem; /* 240px */
--prism-comp-header-height: 3.5rem; /* 56px */
--prism-comp-hit-min: 2.75rem; /* 44px */
/* 도면 이미지 */
--prism-comp-drawing-frame-line: var(--prism-border-default);
}
```
### 3.4 상태 시프트 토큰 (공백 — 산출 필요)
Prism은 hover ±4·active ±8·selected ±12의 **GRADE 시프트**를 정하지만(screen 6.2절), 시프트된 HEX 표는 토큰 파일에 없다. 이 문서는 값을 지어내지 않는다.
| 처리 | 내용 |
| :--- | :--- |
| 지금 | hover는 보강일 뿐이므로(HV-3) 색 변화 없이도 모든 기능이 성립한다. 시안 단계에서는 hover에 밑줄 또는 보더 굵기 변화만 쓴다 |
| 구현 전 | `design.foundations.md` 2장의 GRADE 산출식으로 green·brown·white 면의 ±4·±8·±12 HEX를 산출해 `comp` 토큰(`--prism-comp-*-hover/-active/-selected`)으로 추가한다 |
| 책임 | 산출은 Prism 담당자 승인 사항(공백 목록 10장 G7) |
---
## 4. 레이아웃
### 4.1 브레이크포인트
Prism webapp 2절을 따른다. 임의 브레이크포인트를 두지 않는다(WA-1).
| BP | 범위(px) | 컬럼 | 마진 | 거터 | 이 앱에서 |
| :--- | :--- | :-: | ---: | ---: | :--- |
| `lg` | 1240–1599 | 12 | 32 | 24 | **설계 기준.** 1280px에서 모든 화면이 성립해야 한다 |
| `xl` | 1600– | 12 | 24 | 24 | 컨테이너 1440 고정 |
| `md` | 904–1239 | 8 | 32 | 24 | 지원하되 시험 제외. 레일은 상단으로 접힌다 |
| `sm` `xs` | 0–903 | 8 · 4 | 24 · 16 | 16 | 비대상. 가로 스크롤 없이 단일 열로만 표시 |
### 4.2 1280px 규칙
| ID | 규칙 |
| :--- | :--- |
| **LY-1** | 1280px 폭에서 **표 외** 가로 스크롤이 없다 |
| **LY-2** | 표는 가로 스크롤을 허용한다(MS-3 예외). 스크롤 시 첫 열(묶음 이름)과 헤더를 고정한다 |
| **LY-3** | 연속 문장 블록은 `max-width: var(--prism-measure-max)`. 표·도면 이미지·근거 표는 제외 |
| **LY-4** | 최상위 영역만 그리드에 맞춘다. 영역 내부는 간격 토큰으로 배치한다 (WA-4) |
### 4.3 앱 셸 (W1)
```
┌ header (sticky, comp-header-height) ──────────────────────────────────────────┐
│ 서비스명 │ 화면 ID · 교각 │ │ 저장 시각 · 환경(로컬) │ 테마 │
├ rail (comp-rail-width) ┬ main ────────────────────────────────────────────────┤
│ 교각 목록 │ 화면 제목 (h1) │
│ ─ 교각 이름 │ 결론 영역 (요약 띠 · 판정) │
│ 1 도면 │ 본문 영역 (표 · 비교 · 폼) │
│ 2 입력 묶음 │ │
│ 3 게이트 │ │
│ 4 보고서 │ │
└─────────────────────────┴──────────────────────────────────────────────────────┘
```
| 요소 | 규칙 |
| :--- | :--- |
| header | 메타 4슬롯(화면 ID·권한·갱신 시각·환경)을 쓴다. 권한 슬롯은 로컬 앱에서 "담당자"로 고정 표시한다 |
| rail | `stepper` 컴포넌트(단계 3~7개 규칙, SP-2)로 구현한다. 완료·현재·미완을 형태로 구분한다(SP-3) |
| main | 첫 영역이 결론이다(PD-1). 결론 영역은 viewport당 1개 |
| skip link | 모든 화면 첫 요소가 "본문 바로가기"다 |
### 4.4 패턴 적용
| 패턴 | 화면 | 이 앱에서의 구체화 |
| :--- | :--- | :--- |
| W1 앱 셸 | 전 화면 | 4.3절 |
| W2 대시보드 | S03, S11 | 카드 그리드. 존당 stat 3개 이하. 1280px에서 3열 |
| W3 폼 | S02, S06, S09 검색 | 1열 수직, 다열 폼 금지, 본문 폭 38em, 주 버튼 1개. 단 `S06`의 값 편집창(JSON)은 38em 예외를 둔다(코드 영역) |
| W4 문서 | S12, S13 | 좌측 목차 4col + 본문 8col, 본문 38em |
| W5 목록-상세 | S01, S04, S05, S07 | 목록이 7열 이상의 표이면 분할 뷰를 쓰지 않고 **전폭 표 + 별도 상세 화면**으로 나눈다. S05만 `4:8` 분할 |
---
## 5. 타이포그래피
### 5.1 서체
| 슬롯 | 값 |
| :--- | :--- |
| 패밀리 | Pretendard. 폴백 `-apple-system, BlinkMacSystemFont, "Noto Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif` |
| 웨이트 | 400 · 500 · 700 |
| 숫자 | `font-variant-numeric: tabular-nums` 전 화면 적용 (표의 수치 열은 필수) |
| 내장 | `web/static/fonts/PretendardVariable.woff2`(OFL, 가변 폰트)를 `@font-face`로 불러온다 (PRD UX3 결정). 파일이 없으면 폴백 맑은 고딕으로 렌더되며, 이 경우에도 5.2절 크기는 유지한다 |
`html { font-size: ... }` 선언을 금지한다(CSS-1).
### 5.2 크기 사용표
| 용도 | 토큰 | 웨이트 | 비고 |
| :--- | :--- | :-: | :--- |
| 화면 제목(h1) | `type-title` | 700 | 한 화면에 1개. 20자 이내 |
| 영역 제목(h2) | `type-title-sm` | 500 | 규정문체 명사형 |
| 소영역 제목(h3) | `type-body-lg` | 700 | |
| 본문 | `type-body` | 400 | 38em 이내 |
| **표 셀** | `type-body-sm` | 400 | 표 최소 13px (TB 규정) |
| 배지·캡션·출처 | `type-caption` | 500 | |
| 큰 숫자(요약 띠) | `type-title` | 700 | 숫자만 키운다 |
### 5.3 기술 표기 (해시·핸들·좌표·키)
해시 앞 16자, DXF 핸들, 좌표, JSON 키는 **본문과 구분**해야 한다. Prism에는 등폭 서체가 없다(공백 G3). 임시 규칙은 다음과 같다.
| 규칙 | 내용 |
| :--- | :--- |
| 형태 | 보더 1px(hairline)이 있는 인라인 칩. 폰트는 본문과 같고 `tabular-nums` |
| 복사 | 칩을 누르면 복사한다. 키보드로 접근 가능하다 |
| 줄바꿈 | 칩 내부에서 줄바꿈하지 않는다. 길면 앞 16자만 보이고 전체는 `title` 대신 도움말로 연다 |
| 금지 | 등폭 서체 임의 지정 금지(토큰 외 서체). 승인 후 `sys` 토큰으로 편입 |
---
## 6. 상태 표시 체계
PRD 4.2절의 어휘를 **글자 + 형태 + 색** 세 신호로 부호화한다. 한 열에서 같은 신호를 두 상태가 공유하지 않는다.
### 6.1 형태 신호
| 신호 | 의미 |
| :--- | :--- |
| 선행 마커 `●` | 정상·완료·충족 |
| 선행 마커 `▲` | 주의·확인 필요 |
| 선행 마커 `■` | 실패·불일치 |
| 선행 마커 `◆` | 변경됨·재실행 필요 |
| 선행 마커 `◇` | 근거 없음(빈 마름모) |
| 보더 실선 2px | 확정된 상태 |
| 보더 점선 2px | 근거·확정이 없는 상태 |
| 보더 굵게 3px | 실패 |
마커는 CSS로 그리는 도형이며 아이콘이 아니다(PRD UX4: 2026-10-15 승인). 이모지와 아이콘 폰트를 쓰지 않는다 (IC-3).
### 6.2 앱 확인
| 값 | 글자 | 마커 | 보더 | 전경·배경 |
| :--- | :--- | :-: | :--- | :--- |
| 일치 | 일치 | ● | 실선 2px | good-fg / good-bg |
| 주의 | 주의 | ▲ | 실선 2px | warn-fg / warn-bg |
| 불일치 | 불일치 | ■ | 굵게 3px | bad-fg / bad-bg |
| 근거 없음 | 근거 없음 | ◇ | 점선 2px | text-body / 투명 |
| 해당 없음 | `—` | — | — | text-body (배지 아님) |
| 확인 안 함 | [확인 실행] 버튼 | — | — | (배지 아님) |
### 6.3 사람 확정
| 값 | 글자 | 마커 | 보더 | 전경·배경 |
| :--- | :--- | :-: | :--- | :--- |
| 확정 | 확정 | ● | 실선 2px | `surface-emphasis`: green 면 + white 글자 |
| 미확정 | 미확정 | — | 점선 2px | text-body / 투명 |
| 변경됨 | 변경됨 | ◆ | 실선 2px | warn-fg / warn-bg |
앱 확인(6.2)이 상태색 면을 쓰고 사람 확정(6.3)이 green 면을 쓰므로, 한 행 안에서 두 배지가 **색·형태 모두 다르다**.
### 6.4 변수 등급
| 값 | 글자 | 보더 | 면 |
| :--- | :--- | :--- | :--- |
| V1 | V1 값 | 실선 2px | 없음 |
| V2 | V2 목록 | 실선 2px | 없음 |
| V3 | V3 생성 | 점선 2px | 없음 |
| F | F 고정 | 실선 2px | green 면 + white 글자 |
편집 가능(V1·V2) → 스크립트 필요(V3, 점선) → 편집 불가(F, 면 채움)의 순서로 시각 무게가 커진다.
### 6.5 신뢰 등급
| 값 | 글자 | 보더 |
| :--- | :--- | :--- |
| A | 등급 A | 실선 2px |
| B | 등급 B | 실선 2px + 마커 ▲ |
| C | 등급 C | 점선 2px |
| 없음 | 후보 구역에 행으로 나오지 않는다. '근거 없음' 목록에만 나온다 | — |
### 6.6 게이트 판정
| 값 | 글자 | 마커 | 보더 | 전경·배경 |
| :--- | :--- | :-: | :--- | :--- |
| PASS | PASS | ● | 실선 2px | good-fg / good-bg |
| FAIL | FAIL | ■ | 굵게 3px | bad-fg / bad-bg |
| 계획 FAIL | 계획 FAIL | ▲ | 실선 2px | warn-fg / warn-bg |
| 재실행 필요 | 재실행 | ◆ | 실선 2px | info-fg / info-bg |
### 6.7 규칙
| ID | 규칙 |
| :--- | :--- |
| **ST-1** | 배지 텍스트는 6자 이내(BD-3). 문장을 넣지 않는다 |
| **ST-2** | 한 열의 배지 종류는 4종 이내(BD-2). 5종 이상이 필요하면 열을 나눈다 |
| **ST-3** | 색을 지우고(그레이스케일) 읽어도 모든 상태가 구분되어야 한다 |
| **ST-4** | 배지 색은 악센트 경제에 세지 않는다(BD-4). 그러나 **orange는 상태에 쓰지 않는다** |
| **ST-5** | 다크 테마에서 상태색 쌍은 `sys` 정의대로 전경·배경이 반전된다. `comp`가 따로 정의하지 않는다 |
| **ST-6** | 배지 안에 `aria-label`로 "앱 확인: 일치"처럼 열 이름을 포함해 낭독하게 한다 |
---
## 7. 컴포넌트
### 7.1 Prism 컴포넌트 사용표
Prism이 정한 20종 중 이 앱이 쓰는 것과 쓰는 곳이다. 카탈로그에 있는 변형만 쓴다.
| 컴포넌트 | 변형 | 쓰는 곳 | 비고 |
| :--- | :--- | :--- | :--- |
| `header` | 1 | 전 화면 셸 | 메타 4슬롯 |
| `eyebrow` | 2 | 화면 제목 위 단계 표기("2단계") | |
| `rule` | 1 | 영역 구분 | |
| `card` | 4 | S03 단계 카드, S05 값 비교 | |
| `table` | `base` `compact` | S01, S04, S05, S07, S11 | S04는 `compact` + sticky |
| `stat` | 1 | S03·S04 요약 띠의 숫자 | 존당 3개 이하 |
| `specsheet` | 1 | S05 결론(묶음 메타), S03 도면 목록 | |
| `directive` | `caution` `tip` 등 3 | 형식 불일치 경고, 원본값 경고, 한계 문장 | |
| `badge` | 4 | 6장의 모든 상태 | |
| `scope` | 1 | 각 화면 최상단 "적용 조건/제외 조건" | 해당 없음 즉시 이탈 |
| `toc` | 1 | S13 좌측 목차 | |
| `stepper` | 1 | 레일의 1~4단계 | |
| `xref` | 1 | 화면 간 링크(S05 → S06 등) | 방향어 금지 |
| `mediaframe` | 1 | S08 도면 이미지 | 캡션 필수 |
| `button` | `primary` `secondary` `quiet` `danger` | 전 화면 | 화면당 primary 1개 |
| `input` | 1 | 이름·확정자·사유·검색 | 레이블 필수 |
| `modal` | 1 | S08, S10 | 포커스 트랩·Esc |
| `toast` | 1 | 보조 알림 | 단독 전달 금지 |
| `disclosure` | 1 | 참고 묶음 접기, 제외 목록 | 인쇄 시 전개 |
| `chartframe` | — | **쓰지 않는다** | |
`hero`, `footer`는 미선별이며 이 앱에서 쓰지 않는다.
### 7.2 조합 컴포넌트 (이 문서가 정의)
Prism 카탈로그의 컴포넌트를 **조합·제약**해 만든 앱 전용 구성이다. 새 원시 컴포넌트가 아니므로 카탈로그 외 0건 원칙(webapp A-검증)에 어긋나지 않는다. 단, 조합이 반복되므로 이름을 붙여 일관성을 보장한다.
#### C-1 요약 띠 (`summary-strip`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | `stat`(숫자 3개 이하의 강조) + `badge`(상태별 개수) + 갱신 시각 캡션 |
| 해부 | 결론 문장 → 상태별 개수 → 시각·버전 |
| 규칙 | 각 개수는 필터 버튼이다(`button quiet`). 합계는 표와 같은 집계를 쓴다(PRD 수용 기준). 숫자는 등폭 |
| 접근성 | 전체를 `role="group"` + 요약 문장 `aria-label`. 개수 변경은 `aria-live="polite"` |
| 쓰는 곳 | S03, S04, S07 |
#### C-2 묶음 표 (`section-table`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | `table compact` + sticky 헤더 + 첫 열 고정 + 행 선택 |
| 열 | 묶음 · 변수 등급 · 값 출처 · 앱 확인 · 사람 확정 · 확인 |
| 규칙 | 값 출처 열은 배지가 아닌 글자다(5종, ST-2). 단 '원본값'만 `badge marked`(▲ warn)를 단다. 정렬 기본값 불일치 → 근거 없음 → 주의 → 일치. 빈 셀은 `—` (TB-4) |
| 행 상태 | hover(보강), selected(GRADE 시프트), focus(링). 행 전체가 링크가 아니라 **묶음 이름만** 링크다 |
| 접근성 | `caption` "입력 묶음", `th scope="col"`, 정렬 가능 열은 `aria-sort` |
| 쓰는 곳 | S04 |
#### C-3 근거 행 (`evidence-row`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | 검사 ID(C1~C8) · 검사 이름 · 결과 배지 · 근거 문장 · 도면 위치 칩 · [도면 보기] |
| 규칙 | 근거 문장은 40어절 이내, **비교한 두 값과 출처를 모두 쓴다**. 문장 끝에 독립성(낮음)이 있으면 괄호로 쓴다. 해당 없는 검사는 한 줄로 접는다 |
| 한계 문장 | 표 하단에 고정 `directive tip`: "일치는 후보를 만든 규칙과 값이 같다는 뜻이다. 도면이 맞다는 판정이 아니다." |
| 쓰는 곳 | S05, S10 근거표 |
#### C-4 값 비교 (`diff-row`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | 항목 이름 · 현재 값 · 비교 값(후보/원본) · 차이 표시 |
| 규칙 | 차이는 색이 아닌 **글자(`다름`) + 마커 `▲`**로 표시한다. 같은 항목은 기본으로 접는다. 수치는 우측 정렬·등폭, 단위는 열 헤더에 1회(TB-6) |
| 쓰는 곳 | S05, S07 |
#### C-5 확정 폼 (`confirm-form`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | `input`(확정자) + `input`(사유, 조건부 필수) + `button primary` |
| 규칙 | 필수 표시는 `*`가 아니라 글자 "필수"(IN-4). 조건이 모자라도 버튼은 활성이고 클릭 시 오류 메시지를 낸다(BT-6). 오류는 무엇이·왜·어떻게 + 색·기호·텍스트 3중(IN-2·IN-3) |
| 사유 필수 조건 | 앱 확인이 주의·불일치·근거 없음이거나 F 항목 변경일 때 |
| 쓰는 곳 | S05, S06(F 변경 사유), S10(확정자만) |
#### C-6 일괄 확정 대화상자 (`bulk-confirm-dialog`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | `modal` + 결론 문장 + 근거표(스크롤 영역) + `disclosure`(제외 묶음) + `confirm-form` |
| 규칙 | 근거표 스크롤 끝 도달 여부를 기록하고, 도달 전 [확정]은 오류 메시지를 낸다(비활성 아님). 포커스 트랩·Esc 닫기·배경 스크롤 잠금 (MD-1~5). 모달 안에 모달을 열지 않는다. 제외 묶음 링크는 모달을 닫고 S05로 이동한다 |
| 쓰는 곳 | S10 |
#### C-7 도면 뷰 (`drawing-view`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | `mediaframe` + 캡션(도면·뷰·좌표·핸들 칩) + 확대·축소·이동 버튼 |
| 규칙 | 이미지 대체 텍스트는 대상 설명, 캡션은 필수. 대상 위치 표시는 **링 + 십자선**(색 단독 금지). 이동은 방향키 지원. 새 윈도우 이미지 생성은 `dxftools.render`와 같은 결과를 쓴다 |
| 쓰는 곳 | S08, S05(축소 보기) |
#### C-8 경고 띠 (`state-banner`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | `directive` (`caution`) + 한 문장 + 조치 링크 |
| 종류 | 형식 불일치(닫을 수 없음) · 원본값 포함 · 값 변경됨(재확인 필요) · 앱 확인 규칙 버전 변경 |
| 규칙 | 한 viewport에 2개를 넘기지 않는다. 겹치면 가장 심각한 한 개 + "외 N건" |
| 쓰는 곳 | S03, S04, S05 |
#### C-9 진행 표시 (`run-progress`)
| 항목 | 내용 |
| :--- | :--- |
| 구성 | 단계 문장("11/27 묶음 확인 중") + 막대 + [중단] |
| 규칙 | 색이 아닌 **길이와 숫자**로 읽는다. `role="progressbar"` + `aria-valuenow`. 완료는 토스트가 아니라 결과 영역에 남긴다. 모션은 `transform`만 쓴다 |
| 쓰는 곳 | S04 전체 확인, S11 게이트 실행 |
### 7.3 버튼 배치
| 규칙 | 내용 |
| :--- | :--- |
| 화면당 `primary` 1개 | 다음에 할 일을 가리키는 한 개. S04는 [일치분 확정], S05는 [확정], S10은 [확정] |
| 위험 동작 | `danger` + 확인 절차. 교각 삭제, 반려, 형식 변경 확정 |
| 순서 | 취소·보조 → 주 버튼(우측 끝). 키보드 순서도 같다 |
| 레이블 | 동사로 시작, 8자 이내, 결과를 말한다 (9.2절 표) |
| 면 | `primary`는 `surface-emphasis`(green 면 + white 글자), `secondary`는 보더만, `quiet`는 보더 없는 텍스트, `danger`는 `bad` 상태색 보더 + 확인 절차. hover·active의 면 변화는 3.4절 산출 뒤에 적용한다 |
---
## 8. 인터랙션과 접근성
### 8.1 상태와 포커스
| 항목 | 규칙 |
| :--- | :--- |
| 상태 | default · hover(보강) · focus(링만) · active · selected · disabled(저강조 토큰, 불투명도 금지) · loading(진행 표시, 색 유지) |
| 포커스 링 | 3px 이중 링 + 오프셋 2px, `:focus-visible`. 대체 없는 `outline: none` 금지 (FC-1·FC-2) |
| disabled | 가능하면 활성 + 오류 메시지. 비활성은 권한·물리적 불가능일 때만 |
| hover | `@media (hover: hover)`에 격리. hover 없이 전 기능이 성립해야 한다 |
| 히트 영역 | 44px 이상, 인접 간격 8px 이상 |
### 8.2 키보드
| 화면 | 필수 동작 |
| :--- | :--- |
| S04 | Tab으로 필터 → 도구 줄 → 표(행의 링크·[확인 실행]) 순. 열 머리 Enter로 정렬. 요약 띠 필터는 Enter·Space |
| S05 | 좌측 목록은 위/아래 방향키 이동, Enter로 묶음 전환. [이전][다음] 단축 버튼 제공 |
| S08 | 방향키 이동, `+`/`-` 확대·축소, Esc 닫기 |
| S10 | 포커스 트랩. 근거표는 방향키·PageDown으로 끝까지 내릴 수 있다 |
### 8.3 오류 메시지
3요소(무엇이·왜·어떻게)를 한 문장군으로 쓴다. 색·기호·텍스트를 함께 쓴다.
| 상황 | 문구 예시(60자 이내) |
| :--- | :--- |
| 확정자 없음 | "확정자 이름이 비어 있다. 확정은 사람의 기록이다. 이름을 입력한다" |
| 근거표 미열람 | "근거표를 읽지 않았다. 일치 묶음의 근거를 읽어야 확정한다. 근거표를 끝까지 내린다" |
| 사유 없음 | "사유가 비어 있다. 주의 묶음은 사유가 있어야 확정된다. 사유를 입력한다" |
| 도면 없음 | "도면이 없다. 앱 확인에 쓸 색인이 없다. 1단계에서 도면을 올린다" |
### 8.4 모션
`transform`·`opacity`만 애니메이션한다. `prefers-reduced-motion`에서는 모션을 제거하고 상태 변화는 즉시 반영한다 (MT-3·RM-1). 진행 표시는 정지 상태에서도 숫자로 읽혀야 한다.
---
## 9. 문안 규정
### 9.1 보이스
Prism `saman` 인스턴스를 따른다.
| 속성 | 규칙 | 금지 예 |
| :--- | :--- | :--- |
| 자세 | 단정적·3인칭 | "~인 것 같습니다" → "~이다" 또는 `[추론]` |
| 거리 | 전문가 대 전문가 | "우리 모두", "여러분" |
| 격 | 규정문체(평서 종결). 조작 안내도 같다 | "꼭 확인해 주세요!" → "확인한다" |
| 절제 | 과장·감탄·마케팅 어휘 금지 | "혁신적", "간편하게" |
어미는 4종만 쓴다: `~한다`(의무) · `~할 수 있다`(재량) · `~를 권장한다`(권고) · `~하지 않는다`(금지).
### 9.2 버튼 레이블 (동사로 시작, 8자 이내)
| 동작 | 레이블 | 근거 |
| :--- | :--- | :--- |
| 앱 확인 한 묶음 | 확인 실행 | 검사한다 ≠ 확정한다 |
| 앱 확인 전체 | 전체 확인 | |
| 일치 묶음 확정 | 일치분 확정 | "확정"은 사람의 기록임을 명시. 대상을 앞에 둔다 |
| 확정 | 확정 | |
| 후보 반영 | 후보 반영 | 반영 = 기존 문서에 편입(동사 판별표) |
| 값 저장 | 저장 | |
| 도면 확대 | 도면 보기 | |
| 교각 만들기 | 교각 만들기 | |
| 삭제 | 삭제 | `danger` |
'변경'과 '수정'을 구분한다: 승인 효력에 영향이 있으면 **변경**, 오기 정정이면 **수정**(동사 판별표). 형식 불일치 확정은 "변경"이다.
### 9.3 상태 문구
| 대상 | 문구 |
| :--- | :--- |
| 일치 근거 | "<항목>은 <출처>의 <대상>과 같다" |
| 주의 근거 | "<항목>이 <기준>과 <차이>만큼 다르다. 허용 범위 안이다" |
| 불일치 근거 | "<항목>이 <출처>의 <대상>과 다르다 (현재 <값>, 도면 <값>)" |
| 근거 없음 | "<항목>의 출처를 찾지 못했다. 사람이 도면에서 직접 확인한다" |
| 원본값 | "템플릿 원본과 같다. 새 도면 근거가 없다" |
| 값 변경됨 | "값이 바뀌었다. 이전 확인과 확정이 무효가 되었다" |
### 9.4 금지 목록
| # | 금지 | 근거 |
| :-: | :--- | :--- |
| 1 | 이모지 | IC-3 |
| 2 | 순백 전면 배경 (캔버스는 sand, 카드만 white) | 브랜드 금지 |
| 3 | 오렌지 본문 텍스트, 오렌지 상태 표시 | 브랜드 금지, ST-4 |
| 4 | 다크 배경 위 그린 텍스트 | CSS-4 |
| 5 | 악센트 3개 이상(viewport당) | 악센트 경제 |
| 6 | 그라디언트 배경, 장식 이미지 | 브랜드 금지 |
| 7 | 방향어("위의 표", "아래 버튼", "앞서") | 5.7. 절 번호·항목 이름으로 참조한다 |
| 8 | "100% 자동", "완벽", "간편" 등 과장 표현 | 절제 |
| 9 | 앱이 "확정했다"고 쓰는 문장 | PP-1 |
| 10 | 상태를 색만으로 알리는 표현 | PP-4 |
---
## 10. 디자인 시스템의 공백과 제안
PRD 구현에 필요하지만 Prism에 없는 요소이다. 승인 전에는 **조합 컴포넌트(7.2절)와 임시 규칙**으로 대신한다. 새 아이콘과 새 서체는 Prism 거버넌스(제안 → 승인 대기 → 등재)를 따른다.
| ID | 공백 | 쓰는 곳 | 임시 처리 | 제안 |
| :-: | :--- | :--- | :--- | :--- |
| G1 | 라디오·체크박스·셀렉트 (`input` 변형) | S02 6문항, 필터, S07 반영 선택 | 네이티브 요소 + 토큰 보더·포커스 링 | `input` 변형 3종 신설 |
| G2 | 파일 선택 | 도면 올리기 | 네이티브 `input[type=file]` + 레이블·도움말 | `input` 변형 |
| G3 | 등폭 서체 | 해시·핸들·좌표·JSON | 5.3절 칩 | 등폭 패밀리를 `ref.type`에 편입 |
| G4 | 진행 표시 | 앱 확인, 게이트 실행 | C-9 | `progress` 컴포넌트 신설 |
| G5 | 행 선택·정렬이 있는 표 | S04, S07 | C-2 | `table` 변형 `selectable` |
| G6 | 확대 뷰어 | S08 | C-7 | `mediaframe` 변형 `zoomable` |
| G7 | 상태 시프트 HEX | 전 상호작용 | 3.4절 | foundations 산출표 등재 |
| G8 | 상태 마커 도형(●▲■◆◇) | 6장 | CSS 도형 | 아이콘 거버넌스 승인 (PRD UX4) |
| G9 | 코드·로그 블록 | S11 로그, S06 편집창 | 본문 서체 + 보더 | `codeblock` 신설 |
| G10 | 탭 | (사용하지 않음) | 별도 화면으로 분리 | 필요 시 제안 |
---
## 11. 적용 점검표
PRD 수용 기준 7번의 근거이다. 시안·구현 모두 전항을 확인한다.
### 11.1 자동
| # | 항목 | 기준 |
| :-: | :--- | :--- |
| A1 | 색·치수 리터럴 | 변수 정의부 밖 0건 |
| A2 | root font-size 고정 | 0건 |
| A3 | `outline: none` (대체 없음) | 0건 |
| A4 | z-index, tabindex | 토큰 외 0건 / 양수 0건 |
| A5 | 그리드 정합 | 전 BP 잔차 0 |
| A6 | axe 대비·이름·alt | 위반 0건 |
| A7 | 헤딩 레벨 건너뜀 | 0건 |
| A8 | `prefers-reduced-motion` | 구현 존재 |
| A9 | 히트 영역 | 44px 이상 |
| A10 | 본문 max-width | 38em 이하 |
| A11 | 다크 페어 | green 텍스트 0건 |
| A12 | 텍스트 알파·hover 의존 | 0건 |
| **A13** | **상태 셀 글자** | 모든 상태 셀에 글자 100% |
| **A14** | **배지 길이** | 6자 초과 0건 |
| **A15** | **primary 버튼** | 화면당 1개 |
| **A16** | **orange 사용** | 상태·본문 0건 |
### 11.2 수동
| # | 항목 |
| :-: | :--- |
| V1 | 키보드만으로 PRD 5장 모든 화면의 모든 행동 수행 |
| V2 | 스크린리더로 S04 → S05 → S10 흐름 낭독 |
| V3 | 200% 확대 시 손실·가로 스크롤 없음(표 제외) |
| V4 | 그레이스케일로 6장 모든 상태 구분 |
| V5 | 1280px에서 가로 스크롤(표 외) 0 |
| V6 | 9.4절 금지 목록 0건 |
| V7 | 도면 이미지 캡션 100% |
| V8 | '앱이 확정했다'로 읽히는 문장 0건 |
---
## 12. 거버넌스
| 항목 | 내용 |
| :--- | :--- |
| 변경 | 이 문서의 개정은 버전표에 기록한다. Prism 개정은 이 문서에 자동 소급되지 않는다 (Prism DC-1) |
| 소유 | 앱 화면 규칙은 담당자(심영표). 공백 G1~G10의 Prism 반영은 Prism 소유자가 결정한다 |
| 드리프트 | 3.2절 sys 블록이 `design.tokens.json`·`webapp` 3절과 달라지면 이 문서를 고친다. 정합은 구현 시 빌드 게이트(A1)로 검증한다 |
| R8 | 확정 시 `디자인지침_경로.md`의 R8 행을 대체 표기하고 '디자인 지침 폴더 경로'를 `RAG/design system_v0.1.1`로 갱신한다 (사용자 결정 UX1 후) |
| 면책 | 이 프로파일 준수가 서비스의 접근성·적합성을 보증하지 않는다 (Prism DC-3). 서비스 단위 검증은 별도로 한다 |
---
## 부록 A. 핵심 컴포넌트 스타일 골격
토큰만 참조하는 CSS 골격이다. 값은 3장 변수에서 온다.
```css
.pier-badge {
display: inline-flex; align-items: center; gap: var(--prism-space-050);
padding: var(--prism-comp-badge-pad-y) var(--prism-comp-badge-pad-x);
font-size: var(--prism-comp-badge-font); font-weight: 500;
border: var(--prism-comp-badge-line-solid) solid var(--prism-comp-line);
border-radius: var(--prism-comp-badge-radius);
color: var(--prism-text-body); background: transparent; white-space: nowrap;
}
.pier-badge[data-kind="good"] { color: var(--prism-comp-state-good-fg); background: var(--prism-comp-state-good-bg); border-color: var(--prism-comp-state-good-fg); }
.pier-badge[data-kind="warn"] { color: var(--prism-comp-state-warn-fg); background: var(--prism-comp-state-warn-bg); border-color: var(--prism-comp-state-warn-fg); }
.pier-badge[data-kind="info"] { color: var(--prism-comp-state-info-fg); background: var(--prism-comp-state-info-bg); border-color: var(--prism-comp-state-info-fg); }
.pier-badge[data-kind="bad"] { color: var(--prism-comp-state-bad-fg); background: var(--prism-comp-state-bad-bg); border-color: var(--prism-comp-state-bad-fg);
border-width: var(--prism-comp-badge-line-bold); }
.pier-badge[data-kind="none"] { border-style: dashed; }
.pier-badge[data-kind="fixed"] { color: var(--prism-bg-card); background: var(--prism-text-heading); border-color: var(--prism-text-heading); }
/* 선행 마커: CSS 도형, 아이콘이 아님 */
.pier-badge[data-mark]::before { content: attr(data-mark); aria-hidden: true; }
.pier-table { width: 100%; border-collapse: collapse; font-size: var(--prism-comp-table-font); font-variant-numeric: tabular-nums; }
.pier-table caption { text-align: left; font-weight: 700; padding-block: var(--prism-space-100); }
.pier-table th, .pier-table td { padding: var(--prism-comp-table-cell-pad-y) var(--prism-comp-table-cell-pad-x);
border-bottom: var(--prism-comp-table-rule) solid var(--prism-comp-line); text-align: left; vertical-align: top; }
.pier-table thead th { position: sticky; top: 0; z-index: var(--prism-z-sticky); background: var(--prism-comp-table-head-bg); }
.pier-table td.num { text-align: right; }
:focus-visible { outline: var(--prism-focus-ring) solid var(--prism-comp-line-strong); outline-offset: var(--prism-focus-offset); }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }
```
`.pier-badge[data-mark]::before`의 `aria-hidden`은 CSS 속성이 아니므로 구현 시 마커를 `<span aria-hidden="true">`로 둔다(골격 단순화를 위해 표기).
## 부록 B. 화면별 소비 매트릭스
| 화면 | 패턴 | 주요 컴포넌트 (7.1·7.2절) |
| :--- | :--- | :--- |
| S01 | W5 | table, button, badge, xref |
| S02 | W3 | input(G1), directive, button, scope |
| S03 | W2 | card, stat, summary-strip, stepper, state-banner, button |
| S04 | W5 | summary-strip, section-table, badge, state-banner, disclosure, button |
| S05 | W5 | evidence-row, diff-row, confirm-form, specsheet, directive, xref |
| S06 | W3 | input, confirm-form, state-banner, button, codeblock(G9) |
| S07 | W5 | summary-strip, table(selectable), diff-row, badge, button |
| S08 | 모달 | modal, drawing-view, mediaframe |
| S09 | W3 + W5 | input, table, button |
| S10 | 모달 | bulk-confirm-dialog, evidence-row, disclosure, confirm-form |
| S11 | W2 | card, table, badge, run-progress, button |
| S12 | W4 | toc, table, badge, directive |
| S13 | W4 | toc, table, badge, directive, scope |
## 부록 C. 근거 파일
| 구분 | 경로 |
| :--- | :--- |
| Prism 진입점 | `RAG/design system_v0.1.1/Design.md` |
| 토큰 정본 | `RAG/design system_v0.1.1/design.tokens.json` |
| 웹앱 모듈 | `RAG/design system_v0.1.1/webapp/module.webapp.md` |
| 컴포넌트·브랜드 | `RAG/design system_v0.1.1/design.components.md`, `design.brand.md` |
| 화면 요구사항 | `DOC/01_기획/웹앱디자인시안/PRD.md` |
| 기존 디자인 기준 | `context-migration/디자인지침_경로.md` (R8) |